diff --git a/yabause/src/CMakeLists.txt b/yabause/src/CMakeLists.txt deleted file mode 100644 index a825f2f0a2..0000000000 --- a/yabause/src/CMakeLists.txt +++ /dev/null @@ -1,492 +0,0 @@ -project(yabause) - -include(CheckFunctionExists) -include(CheckIncludeFile) - -set(yabause_SOURCES - bios.c - cdbase.c cheat.c coffelf.c cs0.c cs1.c cs2.c - debug.c - error.c - m68kcore.c m68kd.c memory.c movie.c - netlink.c - osdcore.c - peripheral.c profile.c - scu.c sh2core.c sh2d.c sh2idle.c sh2int.c sh2trace.c smpc.c snddummy.c - titan/titan.c - vdp1.c vdp2.c vdp2debug.c vidogl.c vidshared.c vidsoft.c - yabause.c ygl.c yglshader.c) - -# new SCSP -option(YAB_USE_SCSP2 "Use the new SCSP implementation.") -if (YAB_USE_SCSP2) - add_definitions(-DUSE_SCSP2=1) - set(yabause_SOURCES ${yabause_SOURCES} scsp2.c) -else() - set(yabause_SOURCES ${yabause_SOURCES} scsp.c) -endif() - -# disable strdup warning in MSVC -if (MSVC) - add_definitions(/wd4996) -endif () - -# math library -if (UNIX) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} "m") -endif() - -# Bigendian -include(TestBigEndian) -test_big_endian(WORDS_BIGENDIAN) -if (WORDS_BIGENDIAN) - add_definitions(-DWORDS_BIGENDIAN=1) -endif (WORDS_BIGENDIAN) - -include(CheckCSourceCompiles) - -# variadic macros -check_c_source_compiles("#define MACRO(...) puts(__VA_ARGS__) - int main(int argc, char ** argv) { MACRO(\"foo\"); }" - VARIADIC_MACROS_OK) -if (VARIADIC_MACROS_OK) - add_definitions(-DHAVE_C99_VARIADIC_MACROS=1) -endif (VARIADIC_MACROS_OK) - -# gettimeofday -check_function_exists(gettimeofday GETTIMEOFDAY_OK) -if (GETTIMEOFDAY_OK) - add_definitions(-DHAVE_GETTIMEOFDAY=1) -endif () - -# floorf -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} "-lm") -check_function_exists(floorf FLOORF_OK) -if (FLOORF_OK) - add_definitions(-DHAVE_FLOORF=1) -endif () - -# sys/time.h -check_include_file("sys/time.h" SYSTIME_OK) -if (SYSTIME_OK) - add_definitions(-DHAVE_SYS_TIME_H=1) -endif() - -# Find stdint.h -check_include_file("stdint.h" STDINT_H_FOUND) -if (STDINT_H_FOUND) - add_definitions(-DHAVE_STDINT_H=1) -endif() - -# OpenGL -option(YAB_WANT_OPENGL "use OpenGL for video output (most ports require it)" ON) -if (YAB_WANT_OPENGL) - include(FindOpenGL) - if (OPENGL_FOUND) - add_definitions(-DHAVE_LIBGL=1) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${OPENGL_LIBRARIES}) - - include(FindGLUT) - if (GLUT_FOUND) - include_directories(${GLUT_INCLUDE_DIR}) - add_definitions(-DHAVE_LIBGLUT=1) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${GLUT_LIBRARIES}) - endif() - - # glXGetProcAddress - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OPENGL_LIBRARIES}) - check_function_exists(glXGetProcAddress GLXGETPROCADDRESS_OK) - if (GLXGETPROCADDRESS_OK) - add_definitions(-DHAVE_GLXGETPROCADDRESS=1) - endif() - endif(OPENGL_FOUND) -endif (YAB_WANT_OPENGL) - -# SDL -option(YAB_WANT_SDL "use SDL cores if available" ON) -if (YAB_WANT_SDL) - include(FindSDL) - if (SDL_FOUND) - add_definitions(-DHAVE_LIBSDL=1) - include_directories(${SDL_INCLUDE_DIR}) - set(yabause_SOURCES ${yabause_SOURCES} persdljoy.c sndsdl.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${SDL_LIBRARY}) - endif (SDL_FOUND) -endif (YAB_WANT_SDL) - -# OpenAL -option(YAB_WANT_OPENAL "use OpenAL sound core if available" ON) -if (YAB_WANT_OPENAL) - include(FindOpenAL) - if (OPENAL_FOUND) - find_package(Threads) - add_definitions(-DHAVE_LIBAL=1) - include_directories(${OPENAL_INCLUDE_DIR}) - set(yabause_SOURCES ${yabause_SOURCES} sndal.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${OPENAL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) - endif (OPENAL_FOUND) -endif (YAB_WANT_OPENAL) - -# mini18n -find_path(MINI18N_INCLUDE_DIR mini18n.h) -find_library(MINI18N_LIBRARY mini18n) -if (NOT MINI18N_INCLUDE_DIR STREQUAL "MINI18N_INCLUDE_DIR-NOTFOUND" AND NOT MINI18N_LIBRARY STREQUAL "MINI18N_LIBRARY-NOTFOUND") - set(MINI18N_FOUND TRUE) - include_directories(${MINI18N_INCLUDE_DIR}) - add_definitions(-DHAVE_LIBMINI18N=1) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${MINI18N_LIBRARY}) -endif (NOT MINI18N_INCLUDE_DIR STREQUAL "MINI18N_INCLUDE_DIR-NOTFOUND" AND NOT MINI18N_LIBRARY STREQUAL "MINI18N_LIBRARY-NOTFOUND") - -if (MINI18N_FOUND) - if (UNIX) - add_definitions(-DYTSDIR=\"${CMAKE_INSTALL_PREFIX}/share/${YAB_PACKAGE}/yts\") - elseif (WIN32) - add_definitions(-DYTSDIR=\"trans\") - endif() -endif() - -# APPLE // not necessary mac os x, but i don't care ;) -if (APPLE) - FIND_LIBRARY(COREFOUNDATION_LIBRARY NAMES CoreFoundation ) - FIND_LIBRARY(IOKIT_LIBRARY NAMES IOKit ) - set(yabause_SOURCES ${yabause_SOURCES} macjoy.c permacjoy.c cd-macosx.c sndmac.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${COREFOUNDATION_LIBRARY} ${IOKIT_LIBRARY}) - - check_function_exists(glBindRenderbuffer HAVE_FBO) - if (HAVE_FBO) - add_definitions(-DHAVE_FBO=1) - endif() -endif (APPLE) - -# Visual Studio -if (MSVC) - # Find DDK - if (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") - set(DDK_DIR "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") - elseif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/6000/") - set(DDK_DIR "$ENV{SYSTEMDRIVE}/WINDDK/6000/") - elseif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/7600.16385.0/") - set(DDK_DIR "$ENV{SYSTEMDRIVE}/WINDDK/7600.16385.0/") - endif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") - - add_definitions(-DHAVE_C99_VARIADIC_MACROS -D_CRT_SECURE_NO_WARNINGS -DC68K_NO_JUMP_TABLE - -D_UNICODE -DUNICODE) -endif (MSVC) - -# Windows ddk -if (WIN32) - option(YAB_WANT_DDK "Use the real DDK instead of the built-in one") - if(YAB_WANT_DDK) - # Find ntddcdrm.h - find_path(ntddcdrm_INCLUDE_DIR ntddcdrm.h - PATHS "${DDK_DIR}" "${DDK_DIR}/inc" PATH_SUFFIXES ddk api) - - if (ntddcdrm_INCLUDE_DIR) - include_directories(${ntddcdrm_INCLUDE_DIR}) - message(STATUS "Found ntddcdrm.h: ${ntddcdrm_INCLUDE_DIR}") - add_definitions(-DHAVE_NTDDCDRM=1) - else (ntddcdrm_INCLUDE_DIR) - message(STATUS "Could not find ntddcdrm.h") - endif (ntddcdrm_INCLUDE_DIR) - endif(YAB_WANT_DDK) - - set(yabause_SOURCES ${yabause_SOURCES} cd-windows.c) - - option(YAB_WANT_DIRECTSOUND "use DirectX sound core if available") - option(YAB_WANT_DIRECTINPUT "use DirectX input core if available") - - if (YAB_WANT_DIRECTSOUND OR YAB_WANT_DIRECTINPUT) - find_path(DirectX_INCLUDE_DIR dxerr9.h "$ENV{DXSDK_DIR}/Include") - if (NOT DirectX_INCLUDE_DIR) - find_path(DirectX_INCLUDE_DIR "dxerr.h" "$ENV{DXSDK_DIR}/Include") - if (DirectX_INCLUDE_DIR) - set(DXERRH_IS_BROKEN 1 CACHE INTERNAL "dxerr is broken") - endif (DirectX_INCLUDE_DIR) - endif(NOT DirectX_INCLUDE_DIR) - - find_library(DirectX_GUID_LIBRARY dxguid "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - if (YAB_WANT_DIRECTINPUT) - find_library(DirectX_INPUT8_LIBRARY dinput8 "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - endif(YAB_WANT_DIRECTINPUT) - if (YAB_WANT_DIRECTSOUND) - find_library(DirectX_SOUND_LIBRARY dsound "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - endif(YAB_WANT_DIRECTSOUND) - - if (DXERRH_IS_BROKEN) - find_library(DirectX_ERR_LIBRARY dxerr "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - elseif(MINGW) - find_library(DirectX_ERR_LIBRARY dxerr8 "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - else() - find_library(DirectX_ERR_LIBRARY dxerr9 "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - endif() - - if (DirectX_INCLUDE_DIR AND DirectX_GUID_LIBRARY AND DirectX_ERR_LIBRARY) - set(DIRECTX_FOUND "found") - include_directories(${DirectX_INCLUDE_DIR}) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${DirectX_GUID_LIBRARY} ${DirectX_ERR_LIBRARY}) - - if (DirectX_SOUND_LIBRARY AND DirectX_INPUT8_LIBRARY) - add_definitions(-DHAVE_DIRECTINPUT) - set(yabause_SOURCES ${yabause_SOURCES} snddx.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${DirectX_INPUT8_LIBRARY}) - endif (DirectX_SOUND_LIBRARY AND DirectX_INPUT8_LIBRARY) - if (YAB_WANT_DIRECTSOUND AND DirectX_SOUND_LIBRARY) - add_definitions(-DHAVE_DIRECTSOUND) - set(yabause_SOURCES ${yabause_SOURCES} perdx.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${DirectX_SOUND_LIBRARY}) - endif (YAB_WANT_DIRECTSOUND AND DirectX_SOUND_LIBRARY) - - if (DXERRH_IS_BROKEN) - add_definitions(-DDXERRH_IS_BROKEN) - message(STATUS "Using work-around for dxerr.h") - endif(DXERRH_IS_BROKEN) - endif (DirectX_INCLUDE_DIR AND DirectX_GUID_LIBRARY AND DirectX_ERR_LIBRARY) - endif (YAB_WANT_DIRECTSOUND OR YAB_WANT_DIRECTINPUT) -endif (WIN32) - -if (WII) - set(CMAKE_C_FLAGS "-mrvl -mcpu=750 -meabi -mhard-float") - add_definitions(-DGEKKO=1) - # that shouldn't be hardcoded, either use an ENV variable or try to detect it... - include_directories(/opt/devkitpro/libogc/include/) -endif() - -option(YAB_WANT_ARM7 "Build a binary with arm7 support") - -# SH2 dynamic recompiler -message(STATUS "CMAKE_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}") -message(STATUS "CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") -option(SH2_DYNAREC "SH2 dynamic recompiler" ON) -if (SH2_DYNAREC) - if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x86.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x64.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1 -DHAVE_ARMv6=1 -DHAVE_ARMv7=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - if (ANDROID) - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - add_definitions(-DANDROID=1) - if (YAB_WANT_ARM7) - add_definitions(-DHAVE_ARMv6=1 -DHAVE_ARMv7=1) - endif() - endif () - endif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") -endif (SH2_DYNAREC) - -# c68k -option(YAB_WANT_C68K "enable c68k compilation" ON) -if (YAB_WANT_C68K) - include(ExternalProject) - ExternalProject_Add(c68kinc - DOWNLOAD_COMMAND "" - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/c68k - CMAKE_GENERATOR "${CMAKE_GENERATOR}" - INSTALL_COMMAND "" - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/c68k - ) - - add_definitions(-DHAVE_C68K=1) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/c68k) - set(yabause_SOURCES ${yabause_SOURCES} c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c m68kc68k.c) - if (MSVC) - set_source_files_properties(c68k/c68kexec.c PROPERTIES COMPILE_FLAGS "/Od /wd4146") - else() - set_source_files_properties(c68k/c68kexec.c PROPERTIES COMPILE_FLAGS "-O0") - endif() -endif(YAB_WANT_C68K) - -# q68 -option(YAB_WANT_Q68 "enable q68 compilation" OFF) -if (YAB_WANT_Q68) - add_definitions(-DHAVE_Q68=1) - set(yabause_SOURCES ${yabause_SOURCES} - m68kq68.c q68/q68.c q68/q68-core.c q68/q68-disasm.c - q68/q68-const.h q68/q68.h q68/q68-internal.h q68/q68-jit.h q68/q68-jit-psp.h q68/q68-jit-x86.h) -endif() - -# *DEBUG -set(YAB_DEBUG "" CACHE STRING "List of enabled debug information") -foreach(DEBUG IN LISTS YAB_DEBUG) - if (${DEBUG} STREQUAL "main") - add_definitions(-DDEBUG=1) - elseif (${DEBUG} STREQUAL "cd") - add_definitions(-DCDDEBUG=1) - elseif (${DEBUG} STREQUAL "idle") - add_definitions(-DIDLE_DETECT_VERBOSE=1) - else (${DEBUG} STREQUAL "main") - string(TOUPPER ${DEBUG} UPDEBUG) - add_definitions(-D${UPDEBUG}_DEBUG=1) - endif (${DEBUG} STREQUAL "main") -endforeach(DEBUG) - -# Network -option(YAB_NETWORK "Enable network") -if (YAB_NETWORK) - add_definitions(-DUSESOCKET=1) -endif() - -# Peripheral key name -option(YAB_PERKEYNAME "Try to display key names instead of cryptic values" OFF) -if (YAB_PERKEYNAME) - add_definitions(-DPERKEYNAME=1) -endif() - -option(YAB_PORT_OSD "Let ports provides their own OSD core list" OFF) -if (YAB_PORT_OSD) - add_definitions(-DYAB_PORT_OSD=1) -endif() - -# Exec from cache -option(YAB_EXEC_FROM_CACHE "Allow code execution from 0xC0000000" OFF) -if (YAB_EXEC_FROM_CACHE) - add_definitions(-DEXEC_FROM_CACHE=1) -endif() - -# Optimized DMA -option(YAB_OPTIMIZED_DMA "Use optimized DMA when possible" OFF) -if (YAB_OPTIMIZED_DMA) - add_definitions(-DOPTIMIZED_DMA=1) -endif() - -# Yabause Arch -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - add_definitions(-DARCH_IS_MACOSX=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - add_definitions(-DARCH_IS_FREEBSD=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c cd-freebsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - add_definitions(-DARCH_IS_LINUX=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-linux.c cd-linux.c) - - check_include_file("linux/joystick.h" LINUX_HAS_JOYSTICK) - if (LINUX_HAS_JOYSTICK) - set(yabause_SOURCES ${yabause_SOURCES} perlinuxjoy.c) - endif() - - check_c_source_compiles(" - #include - int main(int argc, char ** argv) { int i = CDSL_CURRENT; } - " LINUX_CDROM_H_OK) - if (NOT LINUX_CDROM_H_OK) - add_definitions(-DLINUX_CDROM_H_IS_BROKEN) - endif (NOT LINUX_CDROM_H_OK) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - add_definitions(-DARCH_IS_NETBSD=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c cd-netbsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - add_definitions(-DARCH_IS_NETBSD=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c cd-netbsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - add_definitions(-DARCH_IS_WINDOWS=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c) -else () - add_definitions(-DUNKNOWN_ARCH=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c) -endif () - -set(YAB_OPTIMIZATION "-O3" CACHE STRING "Override optimization level") - -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION} -march=i686 -msse") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") -if(ANDROID) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif() - -# Warnings defined to know when we're breaking compilation with MSVC -if (CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdeclaration-after-statement") -endif () - -if (MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4018 /wd4244") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244") -endif () - -add_definitions(-DPACKAGE=\"${YAB_PACKAGE}\") -add_definitions(-DVERSION=\"${YAB_VERSION}\") - -add_library(yabause ${yabause_SOURCES}) - -if (YAB_WANT_C68K) - add_dependencies(yabause c68kinc) -endif(YAB_WANT_C68K) - -macro(yab_port_start) - if (YAB_PORT_BUILT AND NOT YAB_MULTIBUILD) - return() - endif () -endmacro(yab_port_start) - -macro(yab_port_stop) - set(YAB_PORT_BUILT TRUE PARENT_SCOPE) -endmacro(yab_port_stop) - -macro(yab_port_success YAB_TARGET) - if (NOT YAB_MULTIBUILD) - set_target_properties(${YAB_TARGET} PROPERTIES OUTPUT_NAME yabause) - set(YAB_PORT_NAME "yabause") - else () - set(YAB_PORT_NAME ${YAB_TARGET}) - endif () - set(YAB_PORT_BUILT TRUE PARENT_SCOPE) -endmacro(yab_port_success) - -set(YAB_MAN_DIR "share/man") -if (NOT $ENV{PKGMANDIR} STREQUAL "") - set(YAB_MAN_DIR $ENV{PKGMANDIR}) -endif () - -option(YAB_MULTIBUILD "Choose wether to build all ports or only a single one") -set(YAB_PORT_BUILT FALSE) -set(YAB_PORTS "gtk;qt;windows;dreamcast;wii;carbon;cocoa" CACHE STRING "List of ports to build") -foreach(PORT IN LISTS YAB_PORTS) - add_subdirectory(${PORT}) -endforeach(PORT) - -# this is stupid, but CMake automatic definitions are based on variables... -if (YAB_WANT_C68K) - set(HAVE_C68K ON) -endif() -if (YAB_WANT_Q68) - set(HAVE_Q68 ON) -endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/yabause/src/Makefile.am b/yabause/src/Makefile.am deleted file mode 100644 index d7c32ca174..0000000000 --- a/yabause/src/Makefile.am +++ /dev/null @@ -1,117 +0,0 @@ -EXTRA_DIST = Makefile.dc Makefile.mng logo.bmp logo.png Makefile.wii logo.svg - -if COMPILE_C68K -SUBDIRS = c68k . $(YUI_SUBDIR) -else -SUBDIRS = . $(YUI_SUBDIR) -endif -if YUI_IS_CARBON -YUI_SUBDIR=carbon -endif -if YUI_IS_DREAMCAST -YUI_SUBDIR=dreamcast -endif -if YUI_IS_GTK -YUI_SUBDIR=gtk -endif -if YUI_IS_PSP -YUI_SUBDIR=psp -endif -if YUI_IS_QT -YUI_SUBDIR=qt -endif -if YUI_IS_WII -YUI_SUBDIR=wii -endif -if YUI_IS_WINDOWS -YUI_SUBDIR=windows -endif - -noinst_LIBRARIES = libyabause.a -libyabause_a_SOURCES = \ - bios.c bios.h cdbase.c cdbase.h cheat.c cheat.h coffelf.c coffelf.h \ - core.h cs0.c cs0.h cs1.c cs1.h cs2.c cs2.h \ - debug.c debug.h error.c error.h memory.c memory.h \ - m68kcore.c m68kcore.h m68kd.c m68kd.h movie.c movie.h \ - netlink.c netlink.h \ - osdcore.c osdcore.h \ - peripheral.h peripheral.c \ - persdljoy.c persdljoy.h profile.c profile.h \ - scu.c scu.h sh2core.c sh2core.h sh2d.c sh2d.h \ - sh2idle.c sh2idle.h sh2int.c sh2int.h sh2trace.c sh2trace.h \ - smpc.c smpc.h sndal.c sndal.h snddummy.c sndsdl.c sndsdl.h sndwav.c \ - threads.h titan/titan.c titan/titan.h vdp1.c vdp1.h vdp2.c vdp2.h \ - vdp2debug.c vdp2debug.h vidogl.c vidogl.h vidshared.c vidshared.h \ - vidsoft.c vidsoft.h yabause.c yabause.h ygl.h ygl.c yglshader.c yui.h - -if USE_SCSP2 -libyabause_a_SOURCES += scsp2.c scsp2.h -else -libyabause_a_SOURCES += scsp.c scsp.h -endif - -if COMPILE_C68K -libyabause_a_SOURCES += c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c m68kc68k.c m68kc68k.h -c68kexec.o: c68k/c68kexec.c - $(COMPILE) -Ic68k -O0 $(srcdir)/c68k/c68kexec.c -c -o c68kexec.o -endif - -if COMPILE_Q68 -libyabause_a_SOURCES += m68kq68.c q68/q68.c q68/q68-core.c q68/q68-disasm.c \ - q68/q68-const.h q68/q68.h q68/q68-internal.h q68/q68-jit.h q68/q68-jit-psp.h q68/q68-jit-x86.h -if Q68_USE_JIT -libyabause_a_SOURCES += q68/q68-jit.c -if CPU_IS_X86 -libyabause_a_SOURCES += q68/q68-jit-x86.S -endif -if CPU_IS_X64 -libyabause_a_SOURCES += q68/q68-jit-x86.S -endif -if CPU_IS_PSP -libyabause_a_SOURCES += q68/q68-jit-psp.S -endif -endif -endif - -if ARCH_IS_FREEBSD -libyabause_a_SOURCES += cd-freebsd.c thr-dummy.c -endif -if ARCH_IS_LINUX -libyabause_a_SOURCES += cd-linux.c perlinuxjoy.c perlinuxjoy.h thr-linux.c -if USE_DYNAREC -if CPU_IS_X64 -libyabause_a_SOURCES += sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x64.s -AM_CFLAGS = -DSH2_DYNAREC=1 -endif -if CPU_IS_X86 -libyabause_a_SOURCES += sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x86.s -AM_CFLAGS = -DSH2_DYNAREC=1 -endif -if CPU_IS_ARM -libyabause_a_SOURCES += sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s -AM_CFLAGS = -DSH2_DYNAREC=1 -mcpu=cortex-a8 -mfpu=vfp -mfloat-abi=softfp -endif -endif -endif -if ARCH_IS_MACOSX -libyabause_a_SOURCES += cd-macosx.c macjoy.c macjoy.h permacjoy.c permacjoy.h thr-dummy.c -endif -if ARCH_IS_NETBSD -libyabause_a_SOURCES += cd-netbsd.c thr-dummy.c -endif -if ARCH_IS_WINDOWS -libyabause_a_SOURCES += cd-windows.c thr-dummy.c -endif -if YUI_IS_DREAMCAST -libyabause_a_SOURCES += thr-dummy.c -endif -if YUI_IS_WII -libyabause_a_SOURCES += thr-dummy.c -endif - -if TEST_PSP_SH2 -libyabause_a_SOURCES += psp/psp-sh2.c psp/rtl.c psp/rtlexec.c psp/rtlinsn.c \ - psp/rtlopt.c psp/rtlunit.c psp/satopt-sh2.c psp/sh2.c \ - psp/sh2-interpret.c psp/sh2-opcodeinfo.c \ - psp/sh2-optimize.c -endif diff --git a/yabause/src/Makefile.dc b/yabause/src/Makefile.dc deleted file mode 100644 index 5110a387fb..0000000000 --- a/yabause/src/Makefile.dc +++ /dev/null @@ -1,67 +0,0 @@ -# Makefile.dc -# Dreamcast Makefile -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Lawrence Sebald -# Based on KOS makefiles (C) by Dan Potter -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -all: yabause.bin - -include $(KOS_BASE)/Makefile.rules - -KOS_CFLAGS += -I. -DDEBUG -DNO_CLI -DVERSION="0.9.11" -KOS_ASFLAGS += -g - -OBJS = bios.o cdbase.o cheat.o cs0.o cs1.o cs2.o debug.o error.o m68kd.o \ - memory.o netlink.o peripheral.o profile.o scsp.o scu.o sh2core.o sh2idle.o \ - sh2int.o sh2d.o smpc.o vdp1.o vdp2.o yabause.o m68kcore.o coffelf.o \ - m68kc68k.o movie.o snddummy.o -C68K_OBJS = c68k/c68k.o c68k/c68kexec.o c68k/gen68k.o -ARCH_OBJS = dreamcast/yui.o dreamcast/perdc.o dreamcast/viddc.o \ - dreamcast/localtime.o dreamcast/cd.o dreamcast/sh2rec/sh2rec.o \ - dreamcast/sh2rec/sh2rec_htab.o dreamcast/sh2rec/sh2exec.o \ - dreamcast/sh2rec/sh2rec_mem.o - -c68k/c68kexec.o: c68k/gen68k - -c68k/gen68k: c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c - $(CC) $(CFLAGS) -DC68K_GEN -o $@ $^ - cd c68k && ./gen68k - -yabause.elf: $(OBJS) $(ARCH_OBJS) $(C68K_OBJS) - kos-cc -o $@ $^ -lm - -yabause.bin: yabause.elf - $(KOS_OBJCOPY) -R .stack -O binary yabause.elf yabause.bin - -cdtest.elf: dreamcast/cd.o tools/cdtest.o - kos-cc -o $@ $^ - -cdtest.bin: cdtest.elf - $(KOS_OBJCOPY) -R .stack -O binary cdtest.elf cdtest.bin - -run: yabause.bin - $(KOS_LOADER) yabause.bin - -clean: - rm -f $(OBJS) $(ARCH_OBJS) - rm -f tools/cdtest.o - rm -f yabause.elf - rm -f cdtest.elf - rm -f cdtest.bin - -distclean: clean - rm -f yabause.bin diff --git a/yabause/src/Makefile.mng b/yabause/src/Makefile.mng deleted file mode 100644 index a637e62614..0000000000 --- a/yabause/src/Makefile.mng +++ /dev/null @@ -1,86 +0,0 @@ -# Makefile.mng -# Mingw makefile -# Copyright (C) 2002, 2003, 2004 Lawrence Sebald -# Copyright (C) 2004-2007 Theo Berkau -# Based on KOS makefiles (C) by Dan Potter -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -TARGET = yabause.exe -CC = gcc -RC = windres -#DDEFINES=-DDEBUG -VERSION=0.9.10 -DDEFINES= -VDEFINES=-DPACKAGE=\"yabause-win\" -DVERSION=\"$(VERSION)\" -DHAVE_LIBGLUT -DHAVE_LIBGL \ - -D_WIN32_IE=0x0500 -D_UNICODE -DUNICODE -DHAVE_LIBMINI18N -CFLAGS=$(VDEFINES) $(DDEFINES) -O3 -fomit-frame-pointer -fno-strict-aliasing -Wall -#CFLAGS=$(VDEFINES) $(DDEFINES) -O3 -fno-strict-aliasing -Wall -g -CFLAGS2= -fomit-frame-pointer -fno-strict-aliasing -Wall -#CFLAGS2= -fno-strict-aliasing -Wall -g -LDFLAGS=-lmingw32 -lopengl32 -lglut32 -lkernel32 -lgdi32 -lcomctl32 -lcomdlg32 -lwinmm \ - -lws2_32 -ldxguid -ldinput8 -ldxerr8 -ldsound -lmini18n -lvfw32 -mwindows -mthreads -OBJS = bios.o cdbase.o cheat.o coffelf.o cs0.o cs1.o cs2.o debug.o error.o m68kcore.o \ - m68kc68k.o m68kd.o memory.o movie.o netlink.o peripheral.o profile.o scsp.o scu.o sh2core.o \ - sh2idle.o sh2int.o sh2d.o smpc.o vdp1.o vdp2.o vdp2debug.o vidogl.o vidshared.o \ - vidsoft.o yabause.o ygl.o cd-windows.o c68k/c68k.o c68k/c68kexec.o c68k/gen68k.o \ - windows/perdx.o windows/snddx.o windows/yui.o windows/cheats.o windows/resource.o \ - windows/custctl.o windows/disasm.o windows/hexedit.o windows/cpudebug/yuidebug.o \ - windows/cpudebug/debug-68k.o windows/cpudebug/debug-scsp.o windows/cpudebug/debug-scu.o \ - windows/cpudebug/debug-sh2.o windows/cpudebug/debug-smpc.o windows/cpudebug/debug-vdp1.o \ - windows/cpudebug/debug-vdp2.o windows/settings/settings.o windows/settings/settings-basic.o \ - windows/settings/settings-input.o windows/settings/settings-log.o windows/settings/settings-netlink.o \ - windows/settings/settings-sound.o windows/settings/settings-video.o windows\bup-manager.o windows\aviout.o windows\ramwatch.o - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -.c.o: - $(CC) $(CFLAGS) -c $< -o $@ - -windows/resource.o: windows/resource.rc windows/resource.h - cd windows && $(RC) $(VDEFINES) $(DDEFINES) resource.rc -o resource.o - cd .. -clean: - rm -f $(OBJS) - rm -f $(TARGET) - -installer: - makensis "/XOutFile ..\..\yabause-$(VERSION)-win.exe" windows\installer\installer.nsi - -release: - zip -9 yabause-$(VERSION)-win.zip * -i *.dll -i yabause.exe - cd .. && zip -9 src\yabause-$(VERSION)-win.zip * -i AUTHORS -i Changelog -i COPYING -i README -i README.WIN - -cdbase.o: cdbase.h -cs0.o: cs0.h core.h -cs1.o: cs1.h core.h -debug.o: debug.h -memory.o: debug.h memory.h -scu.o: scu.h debug.h core.h -sh2core.o: sh2core.h core.h -sh2int.o: sh2core.h sh2int.h core.h -vdp1.o: vdp1.h debug.h memory.h -c68k/c68k.o: c68k/c68k.h -c68k/c68kexec.o: c68k/c68k.h c68k/c68k_ini.inc - $(CC) $(CFLAGS2) -c c68k/c68kexec.c -o $@ -c68k/c68k_ini.inc: c68k/gen68k.exe -c68k/gen68k.exe: c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c - $(CC) $(CFLAGS) -DC68K_GEN -o $@ $^ - cd c68k && gen68k - - diff --git a/yabause/src/Makefile.wii b/yabause/src/Makefile.wii deleted file mode 100644 index 028d7c10d9..0000000000 --- a/yabause/src/Makefile.wii +++ /dev/null @@ -1,53 +0,0 @@ -# Makefile.wii -# Wii makefile -# Copyright (C) 2002, 2003, 2004 Lawrence Sebald -# Copyright (C) 2004-2008 Theo Berkau -# Based on KOS makefiles (C) by Dan Potter -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) -endif - -include $(DEVKITPPC)/wii_rules - -TARGET = yabause.elf -DDEFINES= -VDEFINES=-DPACKAGE=\"yabause-wii\" -DVERSION=\"0.9.6\" -DWORDS_BIGENDIAN -DREENTRANT_SYSCALLS_PROVIDED -MACHDEP = -DGEKKO -mcpu=750 -meabi -mhard-float -CFLAGS=$(VDEFINES) $(DDEFINES) -g -O2 -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -LDFLAGS= -g $(MACHDEP) -mrvl -Wl,-Map,$(notdir $@).map -LIBS := -lfat -lwiiuse -lbte -logc -lm -OBJS = bios.o cdbase.o cheat.o coffelf.o cs0.o cs1.o cs2.o debug.o \ -error.o m68kcore.o m68kc68k.o m68kd.o memory.o netlink.o peripheral.o \ -profile.o scsp.o scu.o sh2core.o sh2idle.o sh2int.o sh2d.o smpc.o vdp1.o \ -vdp2.o vidshared.o vidsoft.o yabause.o ygl.o c68k/c68k.o c68k/c68kexec.o \ -wii/yui.o wii/perwii.o wii/sndwii.o -DEPSDIR = $(CURDIR) -export LD := $(CC) -export LIBPATHS := -L$(LIBOGC_LIB) - -all: $(TARGET) - -$(TARGET): $(OBJS) - -clean: - rm -f $(OBJS) - rm -f $(TARGET) - -c68k/c68kexec.o: - $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c c68k/c68kexec.c -o $@ diff --git a/yabause/src/android/AndroidManifest.xml b/yabause/src/android/AndroidManifest.xml deleted file mode 100644 index 15ad60ee95..0000000000 --- a/yabause/src/android/AndroidManifest.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - diff --git a/yabause/src/android/CMakeLists.txt b/yabause/src/android/CMakeLists.txt deleted file mode 100644 index 4e10702f76..0000000000 --- a/yabause/src/android/CMakeLists.txt +++ /dev/null @@ -1,114 +0,0 @@ -find_program(NDK_BUILD ndk-build) - -if(NOT NDK_BUILD) - message(FATAL_ERROR "ndk build not found, bye") -endif() - -find_program(SDK_ANDROID android) - -if(NOT SDK_ANDROID) - message(FATAL_ERROR "sdk android tool not found, bye") -endif() - -if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - set(yabause_android_SHADOW - AndroidManifest.xml - project.properties - jni/yui.c - jni/miniegl.h - jni/sndaudiotrack.c - jni/sndaudiotrack.h - src/org/yabause/android/Yabause.java - src/org/yabause/android/YabauseView.java - res/drawable/pad.png - res/drawable-hdpi/icon.png - res/drawable-ldpi/icon.png - res/drawable-mdpi/icon.png - res/layout/main.xml - res/menu/emulation.xml - res/values/strings.xml - ) - - foreach(item IN LISTS yabause_android_SHADOW) - message(STATUS ${item}) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${item}" - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${item}" "${CMAKE_CURRENT_BINARY_DIR}/${item}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${item}" - ) - endforeach() -endif() - -set(YABAUSE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/jni/Android.mk.in - ${CMAKE_CURRENT_BINARY_DIR}/jni/Android.mk - @ONLY -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/local.properties" - COMMAND ${SDK_ANDROID} update project -p "${CMAKE_CURRENT_BINARY_DIR}" - DEPENDS - "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" - "${CMAKE_CURRENT_BINARY_DIR}/project.properties" - "${CMAKE_CURRENT_BINARY_DIR}/jni/Android.mk" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/jni/libyabause.a" - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/../libyabause.a ${CMAKE_CURRENT_BINARY_DIR}/jni/libyabause.a - DEPENDS yabause "${CMAKE_CURRENT_BINARY_DIR}/../config.h" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/local.properties" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libs/armeabi/libyabause.so" - COMMAND "${NDK_BUILD}" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/libyabause.a" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/yui.c" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/miniegl.h" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/sndaudiotrack.c" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/sndaudiotrack.h" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) - -set(yabause_android_RES - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable/pad.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable-hdpi/icon.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable-ldpi/icon.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable-mdpi/icon.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/layout/main.xml" - "${CMAKE_CURRENT_BINARY_DIR}/res/menu/emulation.xml" - "${CMAKE_CURRENT_BINARY_DIR}/res/values/strings.xml" -) -set(yabause_android_SRC - "${CMAKE_CURRENT_BINARY_DIR}/src/org/yabause/android/Yabause.java" - "${CMAKE_CURRENT_BINARY_DIR}/src/org/yabause/android/YabauseView.java" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-debug.apk" - COMMAND "ant" ARGS "debug" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libs/armeabi/libyabause.so" - DEPENDS ${yabause_android_SRC} - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" - DEPENDS ${yabause_android_RES} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-release-unsigned.apk" - COMMAND "ant" ARGS "release" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libs/armeabi/libyabause.so" - DEPENDS ${yabause_android_SRC} - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" - DEPENDS ${yabause_android_RES} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) - -if(CMAKE_BUILD_TYPE STREQUAL "Release") - add_custom_target(yabause-android ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-release-unsigned.apk") -else() - add_custom_target(yabause-android ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-debug.apk") -endif() diff --git a/yabause/src/android/android.cmake b/yabause/src/android/android.cmake deleted file mode 100644 index d5640bad92..0000000000 --- a/yabause/src/android/android.cmake +++ /dev/null @@ -1,14 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Linux) -SET(CMAKE_SYSTEM_VERSION 1) - -SET(CMAKE_C_COMPILER arm-linux-androideabi-gcc) -SET(CMAKE_CXX_COMPILER arm-linux-androideabi-g++) -SET(CMAKE_ASM-ATT_COMPILER arm-linux-androideabi-as) - -SET(CMAKE_FIND_ROOT_PATH /home/guillaume/projects/android/toolchain/sysroot/usr/) - -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -SET(ANDROID ON) diff --git a/yabause/src/android/build.xml b/yabause/src/android/build.xml deleted file mode 100644 index ecb9624556..0000000000 --- a/yabause/src/android/build.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/yabause/src/android/jni/Android.mk.in b/yabause/src/android/jni/Android.mk.in deleted file mode 100644 index 6cfe1fbde7..0000000000 --- a/yabause/src/android/jni/Android.mk.in +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := yabause -LOCAL_SRC_FILES := yui.c sndaudiotrack.c -LOCAL_STATIC_LIBRARIES := yabause-prebuilt -LOCAL_LDLIBS := -llog -ljnigraphics -lGLESv1_CM -include $(BUILD_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := yabause-prebuilt -LOCAL_SRC_FILES := libyabause.a -LOCAL_EXPORT_C_INCLUDES := @YABAUSE_INCLUDE_DIR@ -include $(PREBUILT_STATIC_LIBRARY) diff --git a/yabause/src/android/jni/miniegl.h b/yabause/src/android/jni/miniegl.h deleted file mode 100644 index a1a11b9f75..0000000000 --- a/yabause/src/android/jni/miniegl.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _MINIEGL_ -#define _MINIEGL_ - -typedef int EGLint; -typedef unsigned int EGLBoolean; -typedef unsigned int EGLenum; -typedef void *EGLConfig; -typedef void *EGLContext; -typedef void *EGLDisplay; -typedef void *EGLSurface; -typedef void *EGLClientBuffer; - -/* EGL aliases */ -#define EGL_FALSE 0 -#define EGL_TRUE 1 - -/* Out-of-band handle values */ -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_SURFACE ((EGLSurface)0) - -/* GetCurrentSurface targets */ -#define EGL_DRAW 0x3059 -#define EGL_READ 0x305A - -/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */ -#define EGL_HEIGHT 0x3056 -#define EGL_WIDTH 0x3057 - -/* QueryString targets */ -#define EGL_VENDOR 0x3053 -#define EGL_VERSION 0x3054 -#define EGL_EXTENSIONS 0x3055 -#define EGL_CLIENT_APIS 0x308D - -EGLContext (*eglGetCurrentContext)(void); -EGLSurface (*eglGetCurrentSurface)(EGLint readdraw); -EGLDisplay (*eglGetCurrentDisplay)(void); -EGLBoolean (*eglQuerySurface)(EGLDisplay dpy, EGLSurface surface,EGLint attribute, EGLint *value); -EGLBoolean (*eglSwapInterval)(EGLDisplay dpy, EGLint interval); -EGLBoolean (*eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw,EGLSurface read, EGLContext ctx); -EGLBoolean (*eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); -const char * (*eglQueryString)(EGLDisplay dpy, EGLint name); -EGLint (*eglGetError)(void); - - -#endif // _MINIEGL_ \ No newline at end of file diff --git a/yabause/src/android/jni/sndaudiotrack.c b/yabause/src/android/jni/sndaudiotrack.c deleted file mode 100644 index 3232062216..0000000000 --- a/yabause/src/android/jni/sndaudiotrack.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include "sndaudiotrack.h" -#include "debug.h" - -static int SNDAudioTrackInit(void); -static void SNDAudioTrackDeInit(void); -static int SNDAudioTrackReset(void); -static int SNDAudioTrackChangeVideoFormat(int vertfreq); -static void SNDAudioTrackUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples); -static u32 SNDAudioTrackGetAudioSpace(void); -static void SNDAudioTrackMuteAudio(void); -static void SNDAudioTrackUnMuteAudio(void); -static void SNDAudioTrackSetVolume(int volume); - -SoundInterface_struct SNDAudioTrack = { -SNDCORE_AUDIOTRACK, -"Audio Track Sound Interface", -SNDAudioTrackInit, -SNDAudioTrackDeInit, -SNDAudioTrackReset, -SNDAudioTrackChangeVideoFormat, -SNDAudioTrackUpdateAudio, -SNDAudioTrackGetAudioSpace, -SNDAudioTrackMuteAudio, -SNDAudioTrackUnMuteAudio, -SNDAudioTrackSetVolume -}; - -extern JavaVM * yvm; - -jobject gtrack = NULL; - -jclass cAudioTrack = NULL; - -jmethodID mWrite = NULL; - -int mbufferSizeInBytes; - -static u16 *stereodata16; -static u8 soundvolume; -static u8 soundmaxvolume; -static u8 soundbufsize; -static int soundoffset; - -////////////////////////////////////////////////////////////////////////////// - -static int SNDAudioTrackInit(void) -{ - int sampleRateInHz = 44100; - int channelConfig = 12; //AudioFormat.CHANNEL_OUT_STEREO - int audioFormat = 2; //AudioFormat.ENCODING_PCM_16BIT - JNIEnv * env; - jobject mtrack = NULL; - jmethodID mPlay = NULL; - jmethodID mGetMinBufferSize = NULL; - jmethodID mAudioTrack = NULL; - - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return -1; - - cAudioTrack = (*env)->FindClass(env, "android/media/AudioTrack"); - - mAudioTrack = (*env)->GetMethodID(env, cAudioTrack, "", "(IIIIII)V"); - - mWrite = (*env)->GetMethodID(env, cAudioTrack, "write", "([BII)I"); - - mPlay = (*env)->GetMethodID(env, cAudioTrack, "play", "()V"); - - mGetMinBufferSize = (*env)->GetStaticMethodID(env, cAudioTrack, "getMinBufferSize", "(III)I"); - - mbufferSizeInBytes = (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, sampleRateInHz, channelConfig, audioFormat); - - mtrack = (*env)->NewObject(env, cAudioTrack, mAudioTrack, 3 /* STREAM_MUSIC */, sampleRateInHz, channelConfig, audioFormat, mbufferSizeInBytes, 1 /* MODE_STREAM */); - - gtrack = (*env)->NewGlobalRef(env, mtrack); - - (*env)->CallNonvirtualVoidMethod(env, gtrack, cAudioTrack, mPlay); - - if ((stereodata16 = (u16 *)malloc(2 * mbufferSizeInBytes)) == NULL) - return -1; - memset(stereodata16, 0, soundbufsize); - - soundvolume = 100; - soundmaxvolume = 100; - soundbufsize = 85; - soundoffset = 0; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackDeInit(void) -{ - JNIEnv * env; - - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return; - - free(stereodata16); - stereodata16 = NULL; - - (*env)->DeleteGlobalRef(env, gtrack); -} - -////////////////////////////////////////////////////////////////////////////// - -static int SNDAudioTrackReset(void) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int SNDAudioTrackChangeVideoFormat(int vertfreq) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void sdlConvert32uto16s(s32 *srcL, s32 *srcR, s16 *dst, u32 len) { - u32 i; - - for (i = 0; i < len; i++) - { - // Left Channel - *srcL = ( *srcL *soundvolume ) / soundmaxvolume; - if (*srcL > 0x7FFF) *dst = 0x7FFF; - else if (*srcL < -0x8000) *dst = -0x8000; - else *dst = *srcL; - srcL++; - dst++; - // Right Channel - *srcR = ( *srcR *soundvolume ) / soundmaxvolume; - if (*srcR > 0x7FFF) *dst = 0x7FFF; - else if (*srcR < -0x8000) *dst = -0x8000; - else *dst = *srcR; - srcR++; - dst++; - } -} - -static void SNDAudioTrackUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples) -{ - u32 copy1size=0; - - copy1size = (num_samples * sizeof(s16) * 2); - - sdlConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)(((u8 *)stereodata16)+soundoffset), copy1size / sizeof(s16) / 2); - - soundoffset += copy1size; - - if (soundoffset > mbufferSizeInBytes) { - JNIEnv * env; - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return; - - jshortArray array = (*env)->NewShortArray(env, soundoffset); - if(array) { - (*env)->SetShortArrayRegion(env, array, 0, soundoffset, stereodata16); - } - - (*env)->CallNonvirtualIntMethod(env, gtrack, cAudioTrack, mWrite, array, 0, soundoffset); - - soundoffset = 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 SNDAudioTrackGetAudioSpace(void) -{ - static int i = 0; - i++; - if (i == 55) { - i = 0; - return mbufferSizeInBytes; - } else { - return 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackMuteAudio(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackUnMuteAudio(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackSetVolume(int volume) -{ -} diff --git a/yabause/src/android/jni/sndaudiotrack.h b/yabause/src/android/jni/sndaudiotrack.h deleted file mode 100644 index b912d52749..0000000000 --- a/yabause/src/android/jni/sndaudiotrack.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SNDAUDIOTRACK_H -#define SNDAUDIOTRACK_H - -#define SNDCORE_AUDIOTRACK 4 - -#include "scsp.h" - -extern SoundInterface_struct SNDAudioTrack; -#endif diff --git a/yabause/src/android/jni/yui.c b/yabause/src/android/jni/yui.c deleted file mode 100644 index 2d7dfc806e..0000000000 --- a/yabause/src/android/jni/yui.c +++ /dev/null @@ -1,419 +0,0 @@ -/* Copyright 2011 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "../../config.h" -#include "yabause.h" -#include "scsp.h" -#include "vidsoft.h" -#include "peripheral.h" -#include "m68kcore.h" -#include "sh2core.h" -#include "sh2int.h" -#include "cdbase.h" -#include "cs2.h" -#include "debug.h" - -#include -#include - -#define _ANDROID_2_2_ -#ifdef _ANDROID_2_2_ -#include "miniegl.h" -#else -#include -#endif - -#include -#include -#include - -#include "sndaudiotrack.h" - -JavaVM * yvm; -static jobject yabause; -static jobject ybitmap; - -static char biospath[256] = "/mnt/sdcard/jap.rom"; -static char cdpath[256] = "\0"; -static char buppath[256] = "\0"; -static char mpegpath[256] = "\0"; -static char cartpath[256] = "\0"; - -EGLDisplay g_Display = EGL_NO_DISPLAY; -EGLSurface g_Surface = EGL_NO_SURFACE; -EGLContext g_Context = EGL_NO_CONTEXT; -GLuint g_FrameBuffer = 0; -GLuint g_VertexBuffer = 0; -int g_buf_width = -1; -int g_buf_height = -1; -pthread_mutex_t g_mtxGlLock = PTHREAD_MUTEX_INITIALIZER; -float vertices [] = { - 0, 0, 0, 0, - 320, 0, 0, 0, - 320, 224, 0, 0, - 0, 224, 0, 0 -}; - - -M68K_struct * M68KCoreList[] = { -&M68KDummy, -#ifdef HAVE_C68K -&M68KC68K, -#endif -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -#ifdef SH2_DYNAREC -&SH2Dynarec, -#endif -NULL -}; - -PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -NULL -}; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -&SNDAudioTrack, -NULL -}; - -VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDSoft, -NULL -}; - - -#define LOG_TAG "yabause" - -/* Override printf for debug*/ -int printf( const char * fmt, ... ) -{ - va_list ap; - va_start(ap, fmt); - int result = __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, ap); - va_end(ap); - return result; -} - -void YuiErrorMsg(const char *string) -{ - jclass yclass; - jmethodID errorMsg; - jstring message; - JNIEnv * env; - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return; - - yclass = (*env)->GetObjectClass(env, yabause); - errorMsg = (*env)->GetMethodID(env, yclass, "errorMsg", "(Ljava/lang/String;)V"); - message = (*env)->NewStringUTF(env, string); - (*env)->CallVoidMethod(env, yabause, errorMsg, message); -} - -void YuiSwapBuffers(void) -{ - int buf_width, buf_height; - int error; - - - pthread_mutex_lock(&g_mtxGlLock); - if( g_Display == EGL_NO_DISPLAY ) - { - pthread_mutex_unlock(&g_mtxGlLock); - return; - } - - if( eglMakeCurrent(g_Display,g_Surface,g_Surface,g_Context) == EGL_FALSE ) - { - printf( "eglMakeCurrent fail %04x",eglGetError()); - pthread_mutex_unlock(&g_mtxGlLock); - return; - } - - glClearColor( 0.0f,0.0f,0.0f,1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - - if( g_FrameBuffer == 0 ) - { - glEnable(GL_TEXTURE_2D); - glGenTextures(1,&g_FrameBuffer); - glBindTexture(GL_TEXTURE_2D, g_FrameBuffer); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - error = glGetError(); - if( error != GL_NO_ERROR ) - { - printf("gl error %d", error ); - return; - } - }else{ - glBindTexture(GL_TEXTURE_2D, g_FrameBuffer); - } - - - VIDCore->GetGlSize(&buf_width, &buf_height); - glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,buf_width,buf_height,GL_RGBA,GL_UNSIGNED_BYTE,dispbuffer); - - - if( g_VertexBuffer == 0 ) - { - glGenBuffers(1, &g_VertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW); - error = glGetError(); - if( error != GL_NO_ERROR ) - { - printf("gl error %d", error ); - return; - } - }else{ - glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer); - } - - if( buf_width != g_buf_width || buf_height != g_buf_height ) - { - vertices[6]=vertices[10]=(float)buf_width/1024.f; - vertices[11]=vertices[15]=(float)buf_height/1024.f; - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW); - glVertexPointer(2, GL_FLOAT, sizeof(float)*4, 0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float)*4, (void*)(sizeof(float)*2)); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - g_buf_width = buf_width; - g_buf_height = buf_height; - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - eglSwapBuffers(g_Display,g_Surface); - - pthread_mutex_unlock(&g_mtxGlLock); -} - -int Java_org_yabause_android_YabauseRunnable_initViewport( int width, int height) -{ - int swidth; - int sheight; - int error; - char * buf; - - g_Display = eglGetCurrentDisplay(); - g_Surface = eglGetCurrentSurface(EGL_READ); - g_Context = eglGetCurrentContext(); - - eglQuerySurface(g_Display,g_Surface,EGL_WIDTH,&swidth); - eglQuerySurface(g_Display,g_Surface,EGL_HEIGHT,&sheight); - - glViewport(0,0,swidth,sheight); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof(0, 320, 224, 0, 1, 0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - printf(glGetString(GL_VENDOR)); - printf(glGetString(GL_RENDERER)); - printf(glGetString(GL_VERSION)); - printf(glGetString(GL_EXTENSIONS)); - printf(eglQueryString(g_Display,EGL_EXTENSIONS)); - eglSwapInterval(g_Display,0); - eglMakeCurrent(g_Display,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); - return 0; -} - -#ifdef _ANDROID_2_2_ -int initEGLFunc() -{ - void * handle; - char *error; - - handle = dlopen("libEGL.so",RTLD_LAZY); - if( handle == NULL ) - { - printf(dlerror()); - return -1; - } - - eglGetCurrentDisplay = dlsym(handle, "eglGetCurrentDisplay"); - if( eglGetCurrentDisplay == NULL){ printf(dlerror()); return -1; } - - eglGetCurrentSurface = dlsym(handle, "eglGetCurrentSurface"); - if( eglGetCurrentSurface == NULL){ printf(dlerror()); return -1; } - - eglGetCurrentContext = dlsym(handle, "eglGetCurrentContext"); - if( eglGetCurrentContext == NULL){ printf(dlerror()); return -1; } - - eglQuerySurface = dlsym(handle, "eglQuerySurface"); - if( eglQuerySurface == NULL){ printf(dlerror()); return -1; } - - eglSwapInterval = dlsym(handle, "eglSwapInterval"); - if( eglSwapInterval == NULL){ printf(dlerror()); return -1; } - - eglMakeCurrent = dlsym(handle, "eglMakeCurrent"); - if( eglMakeCurrent == NULL){ printf(dlerror()); return -1; } - - eglSwapBuffers = dlsym(handle, "eglSwapBuffers"); - if( eglSwapBuffers == NULL){ printf(dlerror()); return -1; } - - eglQueryString = dlsym(handle, "eglQueryString"); - if( eglQueryString == NULL){ printf(dlerror()); return -1; } - - eglGetError = dlsym(handle, "eglGetError"); - if( eglGetError == NULL){ printf(dlerror()); return -1; } - - return 0; -} -#else -int initEGLFunc() -{ - return 0; -} -#endif - -int Java_org_yabause_android_YabauseRunnable_lockGL() -{ - pthread_mutex_lock(&g_mtxGlLock); -} - -int Java_org_yabause_android_YabauseRunnable_unlockGL() -{ - pthread_mutex_unlock(&g_mtxGlLock); -} - - -jint -Java_org_yabause_android_YabauseRunnable_init( JNIEnv* env, jobject obj, jobject yab, jobject bitmap ) -{ - yabauseinit_struct yinit; - int res; - void * padbits; - - if( initEGLFunc() == -1 ) return -1; - - yabause = (*env)->NewGlobalRef(env, yab); - ybitmap = (*env)->NewGlobalRef(env, bitmap); - - yinit.m68kcoretype = M68KCORE_C68K; - yinit.percoretype = PERCORE_DUMMY; -#ifdef SH2_DYNAREC - yinit.sh2coretype = 2; -#else - yinit.sh2coretype = SH2CORE_DEFAULT; -#endif - yinit.vidcoretype = VIDCORE_SOFT; - yinit.sndcoretype = SNDCORE_AUDIOTRACK; - yinit.cdcoretype = CDCORE_DEFAULT; - yinit.carttype = CART_NONE; - yinit.regionid = 0; - yinit.biospath = biospath; - yinit.cdpath = cdpath; - yinit.buppath = buppath; - yinit.mpegpath = mpegpath; - yinit.cartpath = cartpath; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - - res = YabauseInit(&yinit); - - PerPortReset(); - padbits = PerPadAdd(&PORTDATA1); - PerSetKey(1, PERPAD_LEFT, padbits); - PerSetKey(4, PERPAD_UP, padbits); - PerSetKey(6, PERPAD_DOWN, padbits); - PerSetKey(9, PERPAD_RIGHT, padbits); - - ScspSetFrameAccurate(1); - - return res; -} - -void -Java_org_yabause_android_YabauseRunnable_deinit( JNIEnv* env ) -{ - YabauseDeInit(); -} - -void -Java_org_yabause_android_YabauseRunnable_exec( JNIEnv* env ) -{ - YabauseExec(); -} - -void -Java_org_yabause_android_YabauseRunnable_press( JNIEnv* env, jobject obj, jint key ) -{ - PerKeyDown(key); -} - -void -Java_org_yabause_android_YabauseRunnable_release( JNIEnv* env, jobject obj, jint key ) -{ - PerKeyUp(key); -} - -void log_callback(char * message) -{ - __android_log_print(ANDROID_LOG_INFO, "yabause", "%s", message); -} - -jint JNI_OnLoad(JavaVM * vm, void * reserved) -{ - JNIEnv * env; - if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return -1; - - yvm = vm; - - LogStart(); - LogChangeOutput(DEBUG_CALLBACK, (char *) log_callback); - - return JNI_VERSION_1_6; -} - diff --git a/yabause/src/android/project.properties b/yabause/src/android/project.properties deleted file mode 100644 index ea89160e01..0000000000 --- a/yabause/src/android/project.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-8 diff --git a/yabause/src/android/res/drawable-hdpi/icon.png b/yabause/src/android/res/drawable-hdpi/icon.png deleted file mode 100644 index 8a878c20d7..0000000000 Binary files a/yabause/src/android/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/yabause/src/android/res/drawable-ldpi/icon.png b/yabause/src/android/res/drawable-ldpi/icon.png deleted file mode 100644 index f987e3f090..0000000000 Binary files a/yabause/src/android/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/yabause/src/android/res/drawable-mdpi/icon.png b/yabause/src/android/res/drawable-mdpi/icon.png deleted file mode 100644 index 697e446a93..0000000000 Binary files a/yabause/src/android/res/drawable-mdpi/icon.png and /dev/null differ diff --git a/yabause/src/android/res/drawable/pad.png b/yabause/src/android/res/drawable/pad.png deleted file mode 100644 index 229ee2dabe..0000000000 Binary files a/yabause/src/android/res/drawable/pad.png and /dev/null differ diff --git a/yabause/src/android/res/layout/main.xml b/yabause/src/android/res/layout/main.xml deleted file mode 100644 index ed24490ae9..0000000000 --- a/yabause/src/android/res/layout/main.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/yabause/src/android/res/menu/emulation.xml b/yabause/src/android/res/menu/emulation.xml deleted file mode 100644 index 4bc79a0e2c..0000000000 --- a/yabause/src/android/res/menu/emulation.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/yabause/src/android/res/values/strings.xml b/yabause/src/android/res/values/strings.xml deleted file mode 100644 index a9a427a080..0000000000 --- a/yabause/src/android/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Yabause - diff --git a/yabause/src/android/src/org/yabause/android/Yabause.java b/yabause/src/android/src/org/yabause/android/Yabause.java deleted file mode 100644 index ec9f5eb6ba..0000000000 --- a/yabause/src/android/src/org/yabause/android/Yabause.java +++ /dev/null @@ -1,265 +0,0 @@ -/* Copyright 2011 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -package org.yabause.android; - -import java.lang.Runnable; - -import android.app.Activity; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.graphics.Bitmap; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MenuInflater; -import android.app.Dialog; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.content.DialogInterface; -import org.yabause.android.YabauseView; -import android.widget.ImageView; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; - -class InputHandler extends Handler { - private YabauseRunnable yr; - - public InputHandler(YabauseRunnable yr) { - this.yr = yr; - } - - public void handleMessage(Message msg) { - if (msg.arg1 == 1) { - yr.press(msg.arg2); - } else if (msg.arg1 == 2) { - yr.release(msg.arg2); - } - } -} - -class YabauseRunnable implements Runnable -{ - public static native int init(Yabause yabause, Bitmap bitmap); - public static native void deinit(); - public static native void exec(); - public static native void press(int key); - public static native void release(int key); - public static native int initViewport( int width, int hieght); - public static native int drawScreen(); - public static native int lockGL(); - public static native int unlockGL(); - - private boolean inited; - private boolean paused; - public InputHandler handler; - - public YabauseRunnable(Yabause yabause, Bitmap bitmap) - { - handler = new InputHandler(this); - int ok = init(yabause, bitmap); - inited = (ok == 0); - } - - public void pause() - { - Log.v("Yabause", "pause... should really pause emulation now..."); - paused = true; - } - - public void resume() - { - Log.v("Yabause", "resuming emulation..."); - paused = false; - handler.post(this); - } - - public void destroy() - { - Log.v("Yabause", "destroying yabause..."); - inited = false; - deinit(); - } - - public void run() - { - if (inited && (! paused)) - { - exec(); - - handler.post(this); - } - } - - public boolean paused() - { - return paused; - } -} - -class YabauseHandler extends Handler { - private Yabause yabause; - - public YabauseHandler(Yabause yabause) { - this.yabause = yabause; - } - - public void handleMessage(Message msg) { - yabause.showDialog(msg.what, msg.getData()); - } -} - -public class Yabause extends Activity implements OnTouchListener -{ - private static final String TAG = "Yabause"; - private YabauseRunnable yabauseThread; - private YabauseHandler handler; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - setContentView(R.layout.main); - - YabauseView view = (YabauseView) findViewById(R.id.yabause_view); - handler = new YabauseHandler(this); - yabauseThread = new YabauseRunnable(this,null); - view.setYabauseRunnable(yabauseThread); - - ImageView pad = (ImageView) findViewById(R.id.yabause_pad); - pad.setOnTouchListener(this); - } - - @Override - public void onPause() - { - super.onPause(); - Log.v(TAG, "pause... should pause emulation..."); - yabauseThread.pause(); - } - - @Override - public void onResume() - { - super.onResume(); - Log.v(TAG, "resume... should resume emulation..."); - yabauseThread.resume(); - } - - @Override - public void onDestroy() - { - super.onDestroy(); - Log.v(TAG, "this is the end..."); - yabauseThread.destroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.emulation, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.pause: - yabauseThread.pause(); - return true; - case R.id.quit: - this.finish(); - return true; - case R.id.resume: - yabauseThread.resume(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - if (yabauseThread.paused()) { - menu.setGroupVisible(R.id.paused, true); - menu.setGroupVisible(R.id.running, false); - } else { - menu.setGroupVisible(R.id.paused, false); - menu.setGroupVisible(R.id.running, true); - } - return true; - } - - @Override - public Dialog onCreateDialog(int id, Bundle args) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(args.getString("message")) - .setCancelable(false) - .setNegativeButton("Exit", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - Yabause.this.finish(); - } - }) - .setPositiveButton("Ignore", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - return alert; - } - - public boolean onTouch(View v, MotionEvent event) { - int action = event.getActionMasked(); - float x = event.getX(); - float y = event.getY(); - int keyx = (int) ((x - 10) / 30); - int keyy = (int) ((y - 10) / 30); - int key = (keyx << 2) | keyy; - int keya = 0; - if (action == event.ACTION_DOWN) { - keya = 1; - } else if (action == event.ACTION_UP) { - keya = 2; - } - - Message message = handler.obtainMessage(); - message.arg1 = keya; - message.arg2 = key; - yabauseThread.handler.sendMessage(message); - - return true; - } - - private void errorMsg(String msg) { - Message message = handler.obtainMessage(); - Bundle bundle = new Bundle(); - bundle.putString("message", msg); - message.setData(bundle); - handler.sendMessage(message); - } - - static { - System.loadLibrary("yabause"); - } -} diff --git a/yabause/src/android/src/org/yabause/android/YabauseView.java b/yabause/src/android/src/org/yabause/android/YabauseView.java deleted file mode 100644 index 0b114e7e41..0000000000 --- a/yabause/src/android/src/org/yabause/android/YabauseView.java +++ /dev/null @@ -1,196 +0,0 @@ -/* Copyright 2011 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -package org.yabause.android; - -import java.lang.Runnable; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.SurfaceHolder; -import android.view.SurfaceHolder.Callback; -import android.view.SurfaceView; -import android.view.View; - -class YabauseView extends SurfaceView implements Callback, View.OnKeyListener, View.OnTouchListener{ - private static String TAG = "YabauseView"; - private static final boolean DEBUG = false; - - private int axisX = 0; - private int axisY = 0; - - public boolean[] pointers = new boolean[256]; - public int[] pointerX = new int[256]; - public int[] pointerY = new int[256]; - - private YabauseRunnable _Runnable = null; - - private EGLContext mEglContext; - private EGLDisplay mEglDisplay; - private EGLSurface mEglSurface; - private EGLConfig mEglConfig; - - - public YabauseView(Context context, AttributeSet attrs) { - super(context,attrs); - init(false, 0, 0); - } - - public YabauseView(Context context) { - super(context); - init(false, 0, 0); - } - - public YabauseView(Context context, boolean translucent, int depth, int stencil) { - super(context); - init(translucent, depth, stencil); - } - - public void setYabauseRunnable( YabauseRunnable runnable ) - { - _Runnable = runnable; - } - - private void init(boolean translucent, int depth, int stencil) { - - setFocusable( true ); - setFocusableInTouchMode( true ); - requestFocus(); - setOnKeyListener( this ); - setOnTouchListener( this ); - - getHolder().addCallback(this); - getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); - initGLES(); - - } - - private boolean initGLES(){ - - EGL10 egl = (EGL10)EGLContext.getEGL(); - - mEglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if( mEglDisplay == EGL10.EGL_NO_DISPLAY ){ - Log.e(TAG, "Fail to get Display"); - return false; - } - - int[] version = new int[2]; - if( !egl.eglInitialize(mEglDisplay, version) ){ - Log.e(TAG, "Fail to eglInitialize"); - return false; - } - - int[] configSpec = { - EGL10.EGL_NONE - }; - EGLConfig[] configs = new EGLConfig[1]; - - int[] numConfigs = new int[1]; - if( !egl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, numConfigs) ){ - Log.e(TAG, "Fail to Choose Config"); - return false; - } - mEglConfig = configs[0]; - - mEglContext = egl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, null); - if( mEglContext == EGL10.EGL_NO_CONTEXT ){ - Log.e(TAG, "Fail to Create OpenGL Context"); - return false; - } - return true; - } - - - private boolean createSurface(){ - EGL10 egl = (EGL10)EGLContext.getEGL(); - mEglSurface = egl.eglCreateWindowSurface(mEglDisplay, mEglConfig, getHolder(), null); - if( mEglSurface == EGL10.EGL_NO_SURFACE ){ - return false; - } - return true; - } - - private void endGLES(){ - EGL10 egl = (EGL10)EGLContext.getEGL(); - if( mEglSurface != null){ - //レンダリングコンテキストとの結びつけは解除 - egl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); - - egl.eglDestroySurface(mEglDisplay, mEglSurface); - mEglSurface = null; - } - - if( mEglContext != null ){ - egl.eglDestroyContext(mEglDisplay, mEglContext); - mEglContext = null; - } - - if( mEglDisplay != null){ - egl.eglTerminate(mEglDisplay); - mEglDisplay = null; - } - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - - EGL10 egl = (EGL10)EGLContext.getEGL(); - - YabauseRunnable.lockGL(); - egl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - YabauseRunnable.initViewport(width, height); - YabauseRunnable.unlockGL(); - - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - if( !createSurface() ){ - Log.e(TAG, "Fail to Creat4e Surface"); - return ; - } - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - - } - - // Key events - public boolean onKey( View v, int keyCode, KeyEvent event ) - { - return false; - } - - public boolean onTouch( View v, MotionEvent event ) - { - return true; - } - -} diff --git a/yabause/src/bios.c b/yabause/src/bios.c deleted file mode 100644 index 1d7032ab54..0000000000 --- a/yabause/src/bios.c +++ /dev/null @@ -1,1869 +0,0 @@ -/* Copyright 2006-2007 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "memory.h" -#include "cs0.h" -#include "debug.h" -#include "sh2core.h" -#include "bios.h" -#include "smpc.h" - -static u8 sh2masklist[0x20] = { -0xF0, 0xE0, 0xD0, 0xC0, 0xB0, 0xA0, 0x90, 0x80, -0x80, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, -0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, -0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70 -}; - -static u32 scumasklist[0x20] = { -0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8, -0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80, -0xFFFFFF80, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00 -}; - -u32 interruptlist[2][0x80]; - -////////////////////////////////////////////////////////////////////////////// - -void BiosInit(void) -{ - int i; - - // Setup vectors - MappedMemoryWriteLong(0x06000600, 0x002B0009); // rte, nop - MappedMemoryWriteLong(0x06000604, 0xE0F0600C); // mov #0xF0, r0; extu.b r0, r0 - MappedMemoryWriteLong(0x06000608, 0x400E8BFE); // ldc r0, sr; bf - MappedMemoryWriteLong(0x0600060C, 0x00090009); // nop - MappedMemoryWriteLong(0x06000610, 0x000B0009); // rts, nop - - for (i = 0; i < 0x200; i+=4) - { - MappedMemoryWriteLong(0x06000000+i, 0x06000600); - MappedMemoryWriteLong(0x06000400+i, 0x06000600); - interruptlist[0][i >> 2] = 0x06000600; - interruptlist[1][i >> 2] = 0x06000600; - } - - MappedMemoryWriteLong(0x06000010, 0x06000604); - MappedMemoryWriteLong(0x06000018, 0x06000604); - MappedMemoryWriteLong(0x06000024, 0x06000604); - MappedMemoryWriteLong(0x06000028, 0x06000604); - interruptlist[0][4] = 0x06000604; - interruptlist[0][6] = 0x06000604; - interruptlist[0][9] = 0x06000604; - interruptlist[0][10] = 0x06000604; - - MappedMemoryWriteLong(0x06000410, 0x06000604); - MappedMemoryWriteLong(0x06000418, 0x06000604); - MappedMemoryWriteLong(0x06000424, 0x06000604); - MappedMemoryWriteLong(0x06000428, 0x06000604); - interruptlist[1][4] = 0x06000604; - interruptlist[1][6] = 0x06000604; - interruptlist[1][9] = 0x06000604; - interruptlist[1][10] = 0x06000604; - - // Scu Interrupts - for (i = 0; i < 0x38; i+=4) - { - MappedMemoryWriteLong(0x06000100+i, 0x00000400+i); - interruptlist[0][0x40+(i >> 2)] = 0x00000400+i; - } - - for (i = 0; i < 0x40; i+=4) - { - MappedMemoryWriteLong(0x06000140+i, 0x00000440+i); - interruptlist[0][0x50+(i >> 2)] = 0x00000440+i; - } - - for (i = 0; i < 0x100; i+=4) - MappedMemoryWriteLong(0x06000A00+i, 0x06000610); - - // Setup Bios Functions - MappedMemoryWriteLong(0x06000210, 0x00000210); - MappedMemoryWriteLong(0x0600026C, 0x0000026C); - MappedMemoryWriteLong(0x06000274, 0x00000274); - MappedMemoryWriteLong(0x06000280, 0x00000280); - MappedMemoryWriteLong(0x0600029C, 0x0000029C); - MappedMemoryWriteLong(0x060002DC, 0x000002DC); - MappedMemoryWriteLong(0x06000300, 0x00000300); - MappedMemoryWriteLong(0x06000304, 0x00000304); - MappedMemoryWriteLong(0x06000310, 0x00000310); - MappedMemoryWriteLong(0x06000314, 0x00000314); - MappedMemoryWriteLong(0x06000320, 0x00000320); - MappedMemoryWriteLong(0x06000324, 0x00000000); - MappedMemoryWriteLong(0x06000330, 0x00000330); - MappedMemoryWriteLong(0x06000334, 0x00000334); - MappedMemoryWriteLong(0x06000340, 0x00000340); - MappedMemoryWriteLong(0x06000344, 0x00000344); - MappedMemoryWriteLong(0x06000348, 0xFFFFFFFF); - MappedMemoryWriteLong(0x06000354, 0x00000000); - MappedMemoryWriteLong(0x06000358, 0x00000358); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosSetScuInterrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosSetScuInterrupt. vector = %02X, func = %08X\n", sh->regs.R[4], sh->regs.R[5]); - - if (sh->regs.R[5] == 0) - { - MappedMemoryWriteLong(0x06000900+(sh->regs.R[4] << 2), 0x06000610); - sh->cycles += 8; - } - else - { - MappedMemoryWriteLong(0x06000900+(sh->regs.R[4] << 2), sh->regs.R[5]); - sh->cycles += 9; - } - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosGetScuInterrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me -// LOG("BiosGetScuInterrupt\n"); - - sh->regs.R[0] = MappedMemoryReadLong(0x06000900+(sh->regs.R[4] << 2)); - sh->cycles += 5; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosSetSh2Interrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosSetSh2Interrupt\n"); - - if (sh->regs.R[5] == 0) - { - MappedMemoryWriteLong(sh->regs.VBR+(sh->regs.R[4] << 2), interruptlist[sh->isslave][sh->regs.R[4]]); - sh->cycles += 8; - } - else - { - MappedMemoryWriteLong(sh->regs.VBR+(sh->regs.R[4] << 2), sh->regs.R[5]); - sh->cycles += 9; - } - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosGetSh2Interrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me -// LOG("BiosGetSh2Interrupt\n"); - - sh->regs.R[0] = MappedMemoryReadLong(sh->regs.VBR+(sh->regs.R[4] << 2)); - sh->cycles += 5; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosSetScuInterruptMask(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me - LOG("BiosSetScuInterruptMask\n"); - - MappedMemoryWriteLong(0x06000348, sh->regs.R[4]); - MappedMemoryWriteLong(0x25FE00A0, sh->regs.R[4]); // Interrupt Mask Register - - if (!(sh->regs.R[4] & 0x8000)) // double check this - MappedMemoryWriteLong(0x25FE00A8, 1); // A-bus Interrupt Acknowledge - - sh->cycles += 17; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosChangeScuInterruptMask(SH2_struct * sh) -{ - u32 newmask; - - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosChangeScuInterruptMask\n"); - - // Read Stored Scu Interrupt Mask, AND it by R4, OR it by R5, then put it back - newmask = (MappedMemoryReadLong(0x06000348) & sh->regs.R[4]) | sh->regs.R[5]; - MappedMemoryWriteLong(0x06000348, newmask); - MappedMemoryWriteLong(0x25FE00A0, newmask); // Interrupt Mask Register - MappedMemoryWriteLong(0x25FE00A4, (u32)(s16)sh->regs.R[4]); // Interrupt Status Register - - if (!(sh->regs.R[4] & 0x8000)) // double check this - MappedMemoryWriteLong(0x25FE00A8, 1); // A-bus Interrupt Acknowledge - - sh->cycles += 20; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosCDINIT2(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosCDINIT1(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosGetSemaphore(SH2_struct * sh) -{ - u8 temp; - - SH2GetRegisters(sh, &sh->regs); - - // check me - LOG("BiosGetSemaphore\n"); - - if ((temp = MappedMemoryReadByte(0x06000B00 + sh->regs.R[4])) == 0) - sh->regs.R[0] = 1; - else - sh->regs.R[0] = 0; - - temp |= 0x80; - MappedMemoryWriteByte(0x06000B00 + sh->regs.R[4], temp); - - sh->cycles += 11; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosClearSemaphore(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me - LOG("BiosClearSemaphore\n"); - - MappedMemoryWriteByte(0x06000B00 + sh->regs.R[4], 0); - - sh->cycles += 5; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosChangeSystemClock(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosChangeSystemClock\n"); - - MappedMemoryWriteLong(0x06000324, sh->regs.R[4]); - - if (sh->regs.R[4] == 0) - SmpcCKCHG320(); - else - SmpcCKCHG352(); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosChangeScuInterruptPriority(SH2_struct * sh) -{ - int i; - - SH2GetRegisters(sh, &sh->regs); - - // check me -// LOG("BiosChangeScuInterruptPriority\n"); - - for (i = 0; i < 0x20; i++) - { - scumasklist[i] = MappedMemoryReadLong(sh->regs.R[4]+(i << 2)); - sh2masklist[i] = (scumasklist[i] >> 16); - if (scumasklist[i] & 0x8000) - scumasklist[i] |= 0xFFFF0000; - else - scumasklist[i] &= 0x0000FFFF; - } - - sh->cycles += 186; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosExecuteCDPlayer(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosExecuteCDPlayer\n"); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosPowerOnMemoryClear(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosPowerOnMemoryClear\n"); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosCheckMPEGCard(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosCheckMPEGCard\n"); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 GetDeviceStats(u32 device, u32 *size, u32 *addr, u32 *blocksize) -{ - switch(device) - { - case 0: - *addr = 0x00180000; - *size = 0x8000; - *blocksize = 0x40; - return 0; - case 1: - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - *addr = 0x04000000; - *size = 0x40000 << (CartridgeArea->cartid & 0x0F); - if (CartridgeArea->cartid == 0x24) - *blocksize = 0x400; - else - *blocksize = 0x200; - - return 0; - } - else - return 1; - default: - *addr = 0; - *size = 0; - *blocksize = 0; - return 1; - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static int CheckHeader(UNUSED u32 device) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int CalcSaveSize(u32 tableaddr, int blocksize) -{ - int numblocks=0; - - // Now figure out how many blocks this save is - for(;;) - { - u16 block; - block = (MappedMemoryReadByte(tableaddr) << 8) | MappedMemoryReadByte(tableaddr + 2); - if (block == 0) - break; - tableaddr += 4; - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - tableaddr += 8; - numblocks++; - } - - return numblocks; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 GetFreeSpace(UNUSED u32 device, u32 size, u32 addr, u32 blocksize) -{ - u32 i; - u32 usedblocks=0; - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - // Now figure out how many blocks this save is - usedblocks += (CalcSaveSize(addr+i+0x45, blocksize) + 1); - } - } - - return ((size / blocksize) - 2 - usedblocks); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FindSave(UNUSED u32 device, u32 stringaddr, u32 blockoffset, u32 size, u32 addr, u32 blocksize) -{ - u32 i; - - for (i = ((blockoffset * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - int i3; - - // See if string matches, or if there's no string to check, just copy - // the data over - for (i3 = 0; i3 < 11; i3++) - { - u8 data = MappedMemoryReadByte(stringaddr+i3); - - if (MappedMemoryReadByte(addr+i+0x9+(i3*2)) != data) - { - if (data == 0) - // There's no string to match - return ((i / blocksize) >> 1); - else - // No Match, move onto the next block - i3 = 12; - } - else - { - // Match - if (i3 == 10 || data == 0) - return ((i / blocksize) >> 1); - } - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FindSave2(UNUSED u32 device, const char *string, u32 blockoffset, u32 size, u32 addr, u32 blocksize) -{ - u32 i; - - for (i = ((blockoffset * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - int i3; - - // See if string matches, or if there's no string to check, just copy - // the data over - for (i3 = 0; i3 < 11; i3++) - { - if (MappedMemoryReadByte(addr+i+0x9+(i3*2)) != string[i3]) - { - if (string[i3] == 0) - // There's no string to match - return ((i / blocksize) >> 1); - else - // No Match, move onto the next block - i3 = 12; - } - else - { - // Match - if (i3 == 10 || string[i3] == 0) - return ((i / blocksize) >> 1); - } - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void DeleteSave(u32 addr, u32 blockoffset, u32 blocksize) -{ - MappedMemoryWriteByte(addr + (blockoffset * blocksize * 2) + 0x1, 0x00); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 *GetFreeBlocks(u32 addr, u32 blocksize, u32 numblocks, u32 size) -{ - u8 *blocktbl; - u16 *freetbl; - u32 tableaddr; - u32 i; - u32 blockcount=0; - - // Create a table that tells us which blocks are free and used - if ((blocktbl = (u8 *)malloc(sizeof(u8) * (size / blocksize))) == NULL) - return NULL; - - memset(blocktbl, 0, (size / blocksize)); - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - tableaddr = addr+i+0x45; - blocktbl[i / (blocksize << 1)] = 1; - - // Now let's figure out which blocks are used - for(;;) - { - u16 block; - block = (MappedMemoryReadByte(tableaddr) << 8) | MappedMemoryReadByte(tableaddr + 2); - if (block == 0) - break; - tableaddr += 4; - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - tableaddr += 8; - // block is used - blocktbl[block] = 1; - } - } - } - - if ((freetbl = (u16 *)malloc(sizeof(u16) * numblocks)) == NULL) - { - free(blocktbl); - return NULL; - } - - // Find some free blocks for us to use - for (i = 2; i < (size / blocksize); i++) - { - if (blocktbl[i] == 0) - { - freetbl[blockcount] = (u16)i; - blockcount++; - - if (blockcount >= numblocks) - break; - } - } - - // Ok, we're all done - free(blocktbl); - - return freetbl; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 *ReadBlockTable(u32 addr, u32 *tableaddr, int block, int blocksize, int *numblocks, int *blocksread) -{ - u16 *blocktbl; - int i=0; - - tableaddr[0] = addr + (block * blocksize * 2) + 0x45; - blocksread[0]=0; - - // First of all figure out how large of buffer we need - numblocks[0] = CalcSaveSize(tableaddr[0], blocksize); - - // Allocate buffer - if ((blocktbl = (u16 *)malloc(sizeof(u16) * numblocks[0])) == NULL) - return NULL; - - // Now read in the table - for(i = 0; i < numblocks[0]; i++) - { - u16 block; - block = (MappedMemoryReadByte(tableaddr[0]) << 8) | MappedMemoryReadByte(tableaddr[0] + 2); - tableaddr[0] += 4; - - if (((tableaddr[0]-1) & ((blocksize << 1) - 1)) == 0) - { - tableaddr[0] = addr + (blocktbl[blocksread[0]] * blocksize * 2) + 9; - blocksread[0]++; - } - blocktbl[i] = block; - } - - tableaddr[0] += 4; - - return blocktbl; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPInit(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosBUPInit. arg1 = %08X, arg2 = %08X, arg3 = %08X\n", sh->regs.R[4], sh->regs.R[5], sh->regs.R[6]); - - // Setup Function table - MappedMemoryWriteLong(0x06000354, sh->regs.R[5]); - MappedMemoryWriteLong(sh->regs.R[5]+0x00, 0x00000380); - MappedMemoryWriteLong(sh->regs.R[5]+0x04, 0x00000384); - MappedMemoryWriteLong(sh->regs.R[5]+0x08, 0x00000388); - MappedMemoryWriteLong(sh->regs.R[5]+0x0C, 0x0000038C); - MappedMemoryWriteLong(sh->regs.R[5]+0x10, 0x00000390); - MappedMemoryWriteLong(sh->regs.R[5]+0x14, 0x00000394); - MappedMemoryWriteLong(sh->regs.R[5]+0x18, 0x00000398); - MappedMemoryWriteLong(sh->regs.R[5]+0x1C, 0x0000039C); - MappedMemoryWriteLong(sh->regs.R[5]+0x20, 0x000003A0); - MappedMemoryWriteLong(sh->regs.R[5]+0x24, 0x000003A4); - MappedMemoryWriteLong(sh->regs.R[5]+0x28, 0x000003A8); - MappedMemoryWriteLong(sh->regs.R[5]+0x2C, 0x000003AC); - - // Setup Device list - - // First Device - MappedMemoryWriteWord(sh->regs.R[6], 1); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x2, 1); // Number of partitions - - // Second Device - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - MappedMemoryWriteWord(sh->regs.R[6]+0x4, 2); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x6, 1); // Number of partitions - } - else - { - MappedMemoryWriteWord(sh->regs.R[6]+0x4, 0); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x6, 0); // Number of partitions - } - - // Third Device - MappedMemoryWriteWord(sh->regs.R[6]+0x08, 0); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x0A, 0); // Number of partitions - - // cycles need to be incremented - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPSelectPartition(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPSelectPartition. PR = %08X\n", sh->regs.PR); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPFormat(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosBUPFormat. PR = %08X\n", sh->regs.PR); - - BupFormat(sh->regs.R[4]); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPStatus(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 ret; - u32 freeblocks=0; - - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosBUPStatus. arg1 = %d, arg2 = %d, arg3 = %08X, PR = %08X\n", sh->regs.R[4], sh->regs.R[5], sh->regs.R[6], sh->regs.PR); - - // Fill in status variables - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(sh->regs.R[4]) != 0) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - freeblocks = GetFreeSpace(sh->regs.R[4], size, addr, blocksize); - - MappedMemoryWriteLong(sh->regs.R[6], size); // Size of Backup Ram (in bytes) - MappedMemoryWriteLong(sh->regs.R[6]+0x4, size / blocksize); // Size of Backup Ram (in blocks) - MappedMemoryWriteLong(sh->regs.R[6]+0x8, blocksize); // Size of block - MappedMemoryWriteLong(sh->regs.R[6]+0xC, ((blocksize - 6) * freeblocks) - 30); // Free space(in bytes) - MappedMemoryWriteLong(sh->regs.R[6]+0x10, freeblocks); // Free space(in blocks) - MappedMemoryWriteLong(sh->regs.R[6]+0x14, freeblocks); // Not sure, but seems to be the same as Free Space(in blocks) - - // cycles need to be incremented - - sh->regs.R[0] = ret; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPWrite(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - u32 savesize; - u16 *blocktbl; - u32 workaddr; - u32 blockswritten=0; - u32 datasize; - u32 i; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPWrite. arg1 = %d, arg2 = %08X, arg3 = %08X, arg4 = %d, PR = %08X\n", sh->regs.R[4], sh->regs.R[5], sh->regs.R[6], sh->regs.R[7], sh->regs.PR); - - // Fill in status variables - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists already - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) != 0) - { - // save exists - - // Should we be overwriting it? - if (sh->regs.R[7] != 0) - { - // Nope, let's bail instead - sh->regs.R[0] = 6; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Delete old save - DeleteSave(addr, block, blocksize); - } - - // Let's figure out how many blocks will be needed for the save - datasize = MappedMemoryReadLong(sh->regs.R[5]+0x1C); - savesize = (datasize + 0x1D) / (blocksize - 6); - if ((datasize + 0x1D) % (blocksize - 6)) - savesize++; - - // Will it blend? Err... fit - if (savesize > GetFreeSpace(sh->regs.R[4], size, addr, blocksize)) - { - // Nope, time to bail - sh->regs.R[0] = 4; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Find free blocks for the save - if ((blocktbl = GetFreeBlocks(addr, blocksize, savesize, size)) == NULL) - { - // Just return an error that might make sense - sh->regs.R[0] = 8; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Create save - workaddr = addr + (blocktbl[0] * blocksize * 2); - - MappedMemoryWriteByte(workaddr+0x1, 0x80); - - // Copy over filename - for (i = workaddr+0x9; i < ((workaddr+0x9) + (11 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - sh->regs.R[5]++; - - // Copy over comment - for (i = workaddr+0x21; i < ((workaddr+0x21) + (10 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - // Copy over language - MappedMemoryWriteByte(workaddr+0x1F, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - - sh->regs.R[5]++; - - // Copy over date - for (i = workaddr+0x35; i < ((workaddr+0x35) + (4 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - // Copy over data size - for (i = workaddr+0x3D; i < ((workaddr+0x3D) + (4 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - // write the block table - workaddr += 0x45; - - for (i = 1; i < savesize; i++) - { - MappedMemoryWriteByte(workaddr, (u8)(blocktbl[i] >> 8)); - workaddr+=2; - MappedMemoryWriteByte(workaddr, (u8)blocktbl[i]); - workaddr+=2; - - if (((workaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Next block - blockswritten++; - workaddr = addr + (blocktbl[blockswritten] * blocksize * 2) + 9; - } - } - - // Write 2 blank bytes so we now how large the table size is next time - MappedMemoryWriteByte(workaddr, 0); - workaddr+=2; - MappedMemoryWriteByte(workaddr, 0); - workaddr+=2; - - // Lastly, write the actual save data - while (datasize > 0) - { - MappedMemoryWriteByte(workaddr, MappedMemoryReadByte(sh->regs.R[6])); - datasize--; - sh->regs.R[6]++; - workaddr+=2; - - if (((workaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Next block - blockswritten++; - workaddr = addr + (blocktbl[blockswritten] * blocksize * 2) + 9; - } - } - - free(blocktbl); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPRead(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - u32 tableaddr; - u16 *blocktbl; - int numblocks; - int blocksread; - u32 datasize; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPRead\n", sh->regs.PR); - - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) == 0) - { - // save doesn't exist - sh->regs.R[0] = 5; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - tableaddr = addr + (block * blocksize * 2) + 0x3D; - datasize = (MappedMemoryReadByte(tableaddr) << 24) | (MappedMemoryReadByte(tableaddr + 2) << 16) | - (MappedMemoryReadByte(tableaddr+4) << 8) | MappedMemoryReadByte(tableaddr + 6); - - // Read in Block Table - if ((blocktbl = ReadBlockTable(addr, &tableaddr, block, blocksize, &numblocks, &blocksread)) == NULL) - { - // Just return an error that might make sense - sh->regs.R[0] = 8; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Now let's read in the data - while (datasize > 0) - { - MappedMemoryWriteByte(sh->regs.R[6], MappedMemoryReadByte(tableaddr)); - datasize--; - sh->regs.R[6]++; - tableaddr+=2; - - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Load up the next block - tableaddr = addr + (blocktbl[blocksread] * blocksize * 2) + 9; - blocksread++; - } - } - - free(blocktbl); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPDelete(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPDelete. PR = %08X\n", sh->regs.PR); - - // Fill in status variables - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) == 0) - { - // Since the save doesn't exist, let's bail with an error - - sh->regs.R[0] = 5; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - DeleteSave(addr, block, blocksize); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPDirectory(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 ret; - u32 i; - char filename[12]; - u32 blockoffset=2; - - SH2GetRegisters(sh, &sh->regs); - -// int findmatch = MappedMemoryReadByte(sh->regs.R[5]); - - for (i = 0; i < 12; i++) - filename[i] = MappedMemoryReadByte(sh->regs.R[5]+i); - - LOG("BiosBUPDirectory. arg1 = %d, arg2 = %s, arg3 = %08X, arg4 = %08X, PR = %08X\n", sh->regs.R[4], filename, sh->regs.R[6], sh->regs.R[7], sh->regs.PR); - - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - for (i = 0; i < sh->regs.R[6]; i++) - { - u32 i4; - u32 datasize=0; - u32 block = FindSave(sh->regs.R[4], sh->regs.R[5], blockoffset, size, addr, blocksize); - - if (block == 0) - break; - - blockoffset = block+1; - - // Alright, we found a match :) Time to copy over some data - block = addr + (blocksize * block * 2); - - // Copy over filename - for (i4 = block+0x9; i4 < ((block+0x9) + (11 * 2)); i4+=2) - { - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(i4)); - sh->regs.R[7]++; - } - MappedMemoryWriteByte(sh->regs.R[7], 0); - sh->regs.R[7]++; - - // Copy over comment - for (i4 = block+0x21; i4 < ((block+0x21) + (10 * 2)); i4+=2) - { - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(i4)); - sh->regs.R[7]++; - } - - // Copy over language - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(block+0x1F)); - sh->regs.R[7]++; - - MappedMemoryWriteByte(sh->regs.R[7], 0); - sh->regs.R[7]++; - - // Copy over date - for (i4 = block+0x35; i4 < ((block+0x35) + (4 * 2)); i4+=2) - { - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(i4)); - sh->regs.R[7]++; - } - - // Copy over data size - for (i4 = block+0x3D; i4 < ((block+0x3D) + (4 * 2)); i4+=2) - { - u8 data; - datasize <<= 8; - data = MappedMemoryReadByte(i4); - MappedMemoryWriteByte(sh->regs.R[7], data); - datasize |= data; - sh->regs.R[7]++; - } - - // Calculate block size from the data size, and then copy it over - MappedMemoryWriteWord(sh->regs.R[7], (u16)(((datasize + 0x1D) / (blocksize - 6)) + 1)); - sh->regs.R[7] += 4; - } - - sh->regs.R[0] = i; // returns the number of successfully read dir entries - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPVerify(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - u32 tableaddr; - u32 datasize; - u16 *blocktbl; - int numblocks; - int blocksread; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPVerify. PR = %08X\n", sh->regs.PR); - - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) == 0) - { - // Since the save doesn't exist, let's bail with an error - sh->regs.R[0] = 5; // Not found - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - tableaddr = addr + (block * blocksize * 2) + 0x3D; - datasize = (MappedMemoryReadByte(tableaddr) << 24) | (MappedMemoryReadByte(tableaddr + 2) << 16) | - (MappedMemoryReadByte(tableaddr+4) << 8) | MappedMemoryReadByte(tableaddr + 6); - - // Read in Block Table - if ((blocktbl = ReadBlockTable(addr, &tableaddr, block, blocksize, &numblocks, &blocksread)) == NULL) - { - // Just return an error that might make sense - sh->regs.R[0] = 8; // Broken - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Now let's read in the data, and check to see if it matches - while (datasize > 0) - { - if (MappedMemoryReadByte(sh->regs.R[6]) != MappedMemoryReadByte(tableaddr)) - { - free(blocktbl); - // Ok, the data doesn't match - sh->regs.R[0] = 7; // No match - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - datasize--; - sh->regs.R[6]++; - tableaddr+=2; - - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Load up the next block - tableaddr = addr + (blocktbl[blocksread] * blocksize * 2) + 9; - blocksread++; - } - } - - free(blocktbl); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void ConvertMonthAndDay(u32 data, u32 monthaddr, u32 dayaddr, int type) -{ - int i; - u16 monthtbl[11] = { 31, 31+28, 31+28+31, 31+28+31+30, 31+28+31+30+31, - 31+28+31+30+31+30, 31+28+31+30+31+30+31, - 31+28+31+30+31+30+31+31, 31+28+31+30+31+30+31+31+30, - 31+28+31+30+31+30+31+31+30+31, - 31+28+31+30+31+30+31+31+30+31+30 }; - - if (data < monthtbl[0]) - { - // Month - MappedMemoryWriteByte(monthaddr, 1); - - // Day - MappedMemoryWriteByte(dayaddr, (u8)(data + 1)); - return; - } - - for (i = 1; i < 11; i++) - { - if (data <= monthtbl[i]) - break; - } - - if (type == 1) - { - // Month - MappedMemoryWriteByte(monthaddr, (u8)(i + 1)); - - // Day - if ((i + 1) == 2) - MappedMemoryWriteByte(dayaddr, (u8)(data - monthtbl[(i - 1)] + 1)); - else - MappedMemoryWriteByte(dayaddr, (u8)(data - monthtbl[(i - 1)])); - } - else - { - // Month - MappedMemoryWriteByte(monthaddr, (u8)(i + 1)); - - // Day - MappedMemoryWriteByte(dayaddr, (u8)(data - monthtbl[(i - 1)] + 1)); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPGetDate(SH2_struct * sh) -{ - u32 date; - u32 div; - u32 yearoffset; - u32 yearremainder; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPGetDate. PR = %08X\n", sh->regs.PR); - - date = sh->regs.R[4]; - - // Time - MappedMemoryWriteByte(sh->regs.R[5]+3, (u8)((date % 0x5A0) / 0x3C)); - - // Minute - MappedMemoryWriteByte(sh->regs.R[5]+4, (u8)(date % 0x3C)); - - div = date / 0x5A0; - - // Week - if (div > 0xAB71) - MappedMemoryWriteByte(sh->regs.R[5]+5, (u8)((div + 1) % 7)); - else - MappedMemoryWriteByte(sh->regs.R[5]+5, (u8)((div + 2) % 7)); - - yearremainder = div % 0x5B5; - - if (yearremainder > 0x16E) - { - yearoffset = (yearremainder - 1) / 0x16D; - ConvertMonthAndDay((yearremainder - 1) % 0x16D, sh->regs.R[5]+1, sh->regs.R[5]+2, 0); - } - else - { - yearoffset = 0; - ConvertMonthAndDay(0, sh->regs.R[5]+1, sh->regs.R[5]+2, 1); - } - - // Year - MappedMemoryWriteByte(sh->regs.R[5], (u8)(((div / 0x5B5) * 4) + yearoffset)); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPSetDate(SH2_struct * sh) -{ - u32 date; - u8 data; - u32 remainder; - u16 monthtbl[11] = { 31, 31+28, 31+28+31, 31+28+31+30, 31+28+31+30+31, - 31+28+31+30+31+30, 31+28+31+30+31+30+31, - 31+28+31+30+31+30+31+31, 31+28+31+30+31+30+31+31+30, - 31+28+31+30+31+30+31+31+30+31, - 31+28+31+30+31+30+31+31+30+31+30 }; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPSetDate. PR = %08X\n", sh->regs.PR); - - // Year - data = MappedMemoryReadByte(sh->regs.R[4]); - date = (data / 4) * 0x5B5; - remainder = data % 4; - if (remainder) - date += (remainder * 0x16D) + 1; - - // Month - data = MappedMemoryReadByte(sh->regs.R[4]+1); - if (data != 1 && data < 13) - { - date += monthtbl[data - 2]; - if (date > 2 && remainder == 0) - date++; - } - - // Day - date += MappedMemoryReadByte(sh->regs.R[4]+2) - 1; - date *= 0x5A0; - - // Hour - date += (MappedMemoryReadByte(sh->regs.R[4]+3) * 0x3C); - - // Minute - date += MappedMemoryReadByte(sh->regs.R[4]+4); - - sh->regs.R[0] = date; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosHandleScuInterrupt(SH2_struct * sh, int vector) -{ - SH2GetRegisters(sh, &sh->regs); - - // Save R0-R7, PR, GBR, and old Interrupt mask to stack - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[0]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[1]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[2]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[3]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], MappedMemoryReadLong(0x06000348)); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[4]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[5]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[6]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[7]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.PR); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.GBR); - - // Set SR according to vector - sh->regs.SR.all = (u32)sh2masklist[vector - 0x40]; - - // Write new Interrupt mask value - MappedMemoryWriteLong(0x06000348, MappedMemoryReadLong(0x06000348) | scumasklist[vector - 0x40]); - MappedMemoryWriteLong(0x25FE00A0, MappedMemoryReadLong(0x06000348) | scumasklist[vector - 0x40]); - - // Set PR to our Interrupt Return handler - sh->regs.PR = 0x00000480; - - // Now execute the interrupt - sh->regs.PC = MappedMemoryReadLong(0x06000900+(vector << 2)); -// LOG("Interrupt PC = %08X. Read from %08X\n", sh->regs.PC, 0x06000900+(vector << 2)); - - sh->cycles += 33; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosHandleScuInterruptReturn(SH2_struct * sh) -{ - u32 oldmask; - - SH2GetRegisters(sh, &sh->regs); - - // Restore R0-R7, PR, GBR, and old Interrupt mask from stack - sh->regs.GBR = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.PR = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[7] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[6] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[5] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[4] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - // Return SR back to normal - sh->regs.SR.all = 0xF0; - oldmask = MappedMemoryReadLong(sh->regs.R[15]); - MappedMemoryWriteLong(0x06000348, oldmask); - MappedMemoryWriteLong(0x25FE00A0, oldmask); - sh->regs.R[15] += 4; - sh->regs.R[3] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[2] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[1] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[0] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - - sh->regs.PC = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.SR.all = MappedMemoryReadLong(sh->regs.R[15]) & 0x000003F3; - sh->regs.R[15] += 4; - - sh->cycles += 24; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -int FASTCALL BiosHandleFunc(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // Let's see if it's a bios function - switch((sh->regs.PC - 0x200) >> 2) - { - case 0x04: // 0x06000210 - BiosPowerOnMemoryClear(sh); - break; - case 0x1B: // 0x0600026C - BiosExecuteCDPlayer(sh); - break; - case 0x1D: // 0x06000274 - BiosCheckMPEGCard(sh); - break; - case 0x20: // 0x06000280 - BiosChangeScuInterruptPriority(sh); - break; - case 0x27: // 0x0600029C - BiosCDINIT2(sh); - break; - case 0x37: // 0x060002DC - BiosCDINIT1(sh); - break; - case 0x40: // 0x06000300 - BiosSetScuInterrupt(sh); - break; - case 0x41: // 0x06000304 - BiosGetScuInterrupt(sh); - break; - case 0x44: // 0x06000310 - BiosSetSh2Interrupt(sh); - break; - case 0x45: // 0x06000314 - BiosGetSh2Interrupt(sh); - break; - case 0x48: // 0x06000320 - BiosChangeSystemClock(sh); - break; - case 0x4C: // 0x06000330 - BiosGetSemaphore(sh); - break; - case 0x4D: // 0x06000334 - BiosClearSemaphore(sh); - break; - case 0x50: // 0x06000340 - BiosSetScuInterruptMask(sh); - break; - case 0x51: // 0x06000344 - BiosChangeScuInterruptMask(sh); - break; - case 0x56: // 0x06000358 - BiosBUPInit(sh); - break; - case 0x60: // 0x06000380 - break; - case 0x61: // 0x06000384 - BiosBUPSelectPartition(sh); - break; - case 0x62: // 0x06000388 - BiosBUPFormat(sh); - break; - case 0x63: // 0x0600038C - BiosBUPStatus(sh); - break; - case 0x64: // 0x06000390 - BiosBUPWrite(sh); - break; - case 0x65: // 0x06000394 - BiosBUPRead(sh); - break; - case 0x66: // 0x06000398 - BiosBUPDelete(sh); - break; - case 0x67: // 0x0600039C - BiosBUPDirectory(sh); - break; - case 0x68: // 0x060003A0 - BiosBUPVerify(sh); - break; - case 0x69: // 0x060003A4 - BiosBUPGetDate(sh); - break; - case 0x6A: // 0x060003A8 - BiosBUPSetDate(sh); - break; - case 0x6B: // 0x060003AC - break; - case 0x80: // Interrupt Handler - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9A: - case 0x9B: - case 0x9C: - case 0x9D: - case 0x9E: - case 0x9F: - BiosHandleScuInterrupt(sh, (sh->regs.PC - 0x300) >> 2); - break; - case 0xA0: // Interrupt Handler Return - BiosHandleScuInterruptReturn(sh); - break; - default: - return 0; - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -deviceinfo_struct *BupGetDeviceList(int *numdevices) -{ - deviceinfo_struct *device; - int devicecount=1; - - if ((CartridgeArea->cartid & 0xF0) == 0x20) - devicecount++; - - if ((device = (deviceinfo_struct *)malloc(devicecount * sizeof(deviceinfo_struct))) == NULL) - { - *numdevices = 0; - return NULL; - } - - *numdevices = devicecount; - - device[0].id = 0; - sprintf(device[0].name, "Internal Backup RAM"); - - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - device[1].id = 1; - sprintf(device[1].name, "%d Mbit Backup RAM Cartridge", 1 << ((CartridgeArea->cartid & 0xF)+1)); - } - - // For now it's only internal backup ram and cartridge, no floppy :( -// device[2].id = 2; -// sprintf(device[1].name, "Floppy Disk Drive"); - - return device; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupGetStats(u32 device, u32 *freespace, u32 *maxspace) -{ - u32 ret; - u32 size; - u32 addr; - u32 blocksize; - - ret = GetDeviceStats(device, &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(device) != 0) - return 0; - - *maxspace = size / blocksize; - *freespace = GetFreeSpace(device, size, addr, blocksize); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -saveinfo_struct *BupGetSaveList(u32 device, int *numsaves) -{ - u32 ret; - u32 size; - u32 addr; - u32 blocksize; - saveinfo_struct *save; - int savecount=0; - u32 i, j; - u32 workaddr; - - ret = GetDeviceStats(device, &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(device) != 0) - { - *numsaves = 0; - return NULL; - } - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - savecount++; - } - - if ((save = (saveinfo_struct *)malloc(savecount * sizeof(saveinfo_struct))) == NULL) - { - *numsaves = 0; - return NULL; - } - - *numsaves = savecount; - - savecount = 0; - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - workaddr = addr + i; - - // Copy over filename - for (j = 0; j < 11; j++) - save[savecount].filename[j] = MappedMemoryReadByte(workaddr+0x9+(j * 2)); - save[savecount].filename[11] = '\0'; - - // Copy over comment - for (j = 0; j < 10; j++) - save[savecount].comment[j] = MappedMemoryReadByte(workaddr+0x21+(j * 2)); - save[savecount].comment[10] = '\0'; - - // Copy over language - save[savecount].language = MappedMemoryReadByte(workaddr+0x1F); - - // Copy over Date(fix me) - save[savecount].year = 0; - save[savecount].month = 0; - save[savecount].day = 0; - save[savecount].hour = 0; - save[savecount].minute = 0; - save[savecount].week = 0; - - // Copy over data size - save[savecount].datasize = (MappedMemoryReadByte(workaddr+0x3D) << 24) | - (MappedMemoryReadByte(workaddr+0x3F) << 16) | - (MappedMemoryReadByte(workaddr+0x41) << 8) | - MappedMemoryReadByte(workaddr+0x43); - - // Calculate size in blocks - save[savecount].blocksize = CalcSaveSize(workaddr+0x45, blocksize) + 1; - savecount++; - } - } - - return save; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupDeleteSave(u32 device, const char *savename) -{ - u32 ret; - u32 size; - u32 addr; - u32 blocksize; - u32 block; - - ret = GetDeviceStats(device, &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(device) != 0) - return -1; - - // Let's find and delete the save game - if ((block = FindSave2(device, savename, 2, size, addr, blocksize)) != 0) - { - // Delete old save - DeleteSave(addr, block, blocksize); - return 0; - } - - return -2; -} - -////////////////////////////////////////////////////////////////////////////// - -void BupFormat(u32 device) -{ - switch (device) - { - case 0: - FormatBackupRam(BupRam, 0x10000); - break; - case 1: - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - switch (CartridgeArea->cartid & 0xF) - { - case 1: - FormatBackupRam(CartridgeArea->bupram, 0x100000); - break; - case 2: - FormatBackupRam(CartridgeArea->bupram, 0x200000); - break; - case 3: - FormatBackupRam(CartridgeArea->bupram, 0x400000); - break; - case 4: - FormatBackupRam(CartridgeArea->bupram, 0x800000); - break; - default: break; - } - } - break; - case 2: - LOG("Formatting FDD not supported\n"); - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -int BupCopySave(UNUSED u32 srcdevice, UNUSED u32 dstdevice, UNUSED const char *savename) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupImportSave(UNUSED u32 device, const char *filename) -{ - FILE *fp; - u32 filesize; - u8 *buffer; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - // Calculate file size - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - if ((buffer = (u8 *)malloc(filesize)) == NULL) - { - fclose(fp); - return -2; - } - - fread((void *)buffer, 1, filesize, fp); - fclose(fp); - - // Write save here - - free(buffer); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupExportSave(UNUSED u32 device, UNUSED const char *savename, UNUSED const char *filename) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/bios.h b/yabause/src/bios.h deleted file mode 100644 index fbf21dca61..0000000000 --- a/yabause/src/bios.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef BIOS_H -#define BIOS_H - -#include "sh2core.h" - -typedef struct -{ - char filename[12]; - char comment[11]; - u8 language; - u8 year; - u8 month; - u8 day; - u8 hour; - u8 minute; - u8 week; - u32 datasize; - u16 blocksize; -} saveinfo_struct; - -typedef struct -{ - u8 id; - char name[32]; -} deviceinfo_struct; - -void BiosInit(void); -int FASTCALL BiosHandleFunc(SH2_struct * sh); - -deviceinfo_struct *BupGetDeviceList(int *numdevices); -int BupGetStats(u32 device, u32 *freespace, u32 *maxspace); -saveinfo_struct *BupGetSaveList(u32 device, int *numsaves); -int BupDeleteSave(u32 device, const char *savename); -void BupFormat(u32 device); -int BupCopySave(u32 srcdevice, u32 dstdevice, const char *savename); -int BupImportSave(u32 device, const char *filename); -int BupExportSave(u32 device, const char *savename, const char *filename); -#endif - diff --git a/yabause/src/c68k/CMakeLists.txt b/yabause/src/c68k/CMakeLists.txt deleted file mode 100644 index 6267fd8de1..0000000000 --- a/yabause/src/c68k/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -project(gen68k) - -cmake_minimum_required(VERSION 2.6) - -include(CheckCSourceCompiles) - -# variadic macros -check_c_source_compiles("#define MACRO(...) puts(__VA_ARGS__) - int main(int argc, char ** argv) { MACRO(\"foo\"); }" - VARIADIC_MACROS_OK) -if (VARIADIC_MACROS_OK) - add_definitions(-DHAVE_C99_VARIADIC_MACROS=1) -endif (VARIADIC_MACROS_OK) - -set(gen68k_SOURCES c68kexec.c c68k.c gen68k.c) - -add_definitions(-DC68K_GEN) -if (MSVC) - add_definitions(-DC68K_NO_JUMP_TABLE) -endif (MSVC) - -add_executable(gen68k ${gen68k_SOURCES}) - -execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gen68k) - -set(GEN68K_INC c68k_ini.inc c68k_op0.inc c68k_op1.inc c68k_op2.inc c68k_op3.inc c68k_op4.inc c68k_op5.inc c68k_op6.inc c68k_op7.inc c68k_op8.inc c68k_op9.inc c68k_opA.inc c68k_opB.inc c68k_opC.inc c68k_opD.inc c68k_opE.inc c68k_opF.inc) - -add_custom_command(OUTPUT ${GEN68K_INC} COMMAND gen68k DEPENDS gen68k) - -add_custom_target(c68kinc ALL DEPENDS ${GEN68K_INC}) diff --git a/yabause/src/c68k/Makefile.am b/yabause/src/c68k/Makefile.am deleted file mode 100644 index f4519b2048..0000000000 --- a/yabause/src/c68k/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -EXTRA_DIST = c68k.h c68kmac.inc gen68k.h gen68k.inc -noinst_PROGRAMS = gen68k -gen68k_SOURCES = c68kexec.c c68k.c gen68k.c -gen68k_CFLAGS = -DC68K_GEN -gen68k_LDFLAGS = -DC68K_GEN - -all-local: gen68k$(EXEEXT) - ./gen68k$(EXEEXT) - -clean-local: - -rm *_*.inc diff --git a/yabause/src/c68k/c68k.c b/yabause/src/c68k/c68k.c deleted file mode 100644 index eb77fb4605..0000000000 --- a/yabause/src/c68k/c68k.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * - * C68K (68000 CPU emulator) version 0.80 - * Compiled with Dev-C++ - * Copyright 2003-2004 Stephane Dallongeville - * - ********************************************************************************/ - -#include -#include - -#include "c68k.h" - -// shared global variable -////////////////////////// - -c68k_struc C68K; - -// include macro file -////////////////////// - -#include "c68kmac.inc" - -// prototype -///////////// - -u32 FASTCALL C68k_Read_Dummy(const u32 adr); -void FASTCALL C68k_Write_Dummy(const u32 adr, u32 data); - -u32 C68k_Read_Byte(c68k_struc *cpu, u32 adr); -u32 C68k_Read_Word(c68k_struc *cpu, u32 adr); -u32 C68k_Read_Long(c68k_struc *cpu, u32 adr); -void C68k_Write_Byte(c68k_struc *cpu, u32 adr, u32 data); -void C68k_Write_Word(c68k_struc *cpu, u32 adr, u32 data); -void C68k_Write_Long(c68k_struc *cpu, u32 adr, u32 data); - -s32 FASTCALL C68k_Interrupt_Ack_Dummy(s32 level); -void FASTCALL C68k_Reset_Dummy(void); - -// core main functions -/////////////////////// - -void C68k_Init(c68k_struc *cpu, C68K_INT_CALLBACK *int_cb) -{ - memset(cpu, 0, sizeof(c68k_struc)); - - C68k_Set_ReadB(cpu, C68k_Read_Dummy); - C68k_Set_ReadW(cpu, C68k_Read_Dummy); - - C68k_Set_WriteB(cpu, C68k_Write_Dummy); - C68k_Set_WriteW(cpu, C68k_Write_Dummy); - - if (int_cb) cpu->Interrupt_CallBack = int_cb; - else cpu->Interrupt_CallBack = C68k_Interrupt_Ack_Dummy; - cpu->Reset_CallBack = C68k_Reset_Dummy; - - // used to init JumpTable - cpu->Status |= C68K_DISABLE; - C68k_Exec(cpu, 0); - - cpu->Status &= ~C68K_DISABLE; -} - -s32 FASTCALL C68k_Reset(c68k_struc *cpu) -{ - memset(cpu, 0, ((u8 *)&(cpu->dirty1)) - ((u8 *)&(cpu->D[0]))); - - cpu->flag_notZ = 1; - cpu->flag_I = 7; - cpu->flag_S = C68K_SR_S; - - cpu->A[7] = C68k_Read_Long(cpu, 0); - C68k_Set_PC(cpu, C68k_Read_Long(cpu, 4)); - - return cpu->Status; -} - -///////////////////////////////// - -void FASTCALL C68k_Set_IRQ(c68k_struc *cpu, s32 level) -{ - cpu->IRQLine = level; - if (cpu->Status & C68K_RUNNING) - { - cpu->CycleSup = cpu->CycleIO; - cpu->CycleIO = 0; - } - cpu->Status &= ~(C68K_HALTED | C68K_WAITING); -} - -///////////////////////////////// - -s32 FASTCALL C68k_Get_CycleToDo(c68k_struc *cpu) -{ - if (!(cpu->Status & C68K_RUNNING)) return -1; - - return cpu->CycleToDo; -} - -s32 FASTCALL C68k_Get_CycleRemaining(c68k_struc *cpu) -{ - if (!(cpu->Status & C68K_RUNNING)) return -1; - - return (cpu->CycleIO + cpu->CycleSup); -} - -s32 FASTCALL C68k_Get_CycleDone(c68k_struc *cpu) -{ - if (!(cpu->Status & C68K_RUNNING)) return -1; - - return (cpu->CycleToDo - (cpu->CycleIO + cpu->CycleSup)); -} - -void FASTCALL C68k_Release_Cycle(c68k_struc *cpu) -{ - if (cpu->Status & C68K_RUNNING) cpu->CycleIO = cpu->CycleSup = 0; -} - -void FASTCALL C68k_Add_Cycle(c68k_struc *cpu, s32 cycle) -{ - if (cpu->Status & C68K_RUNNING) cpu->CycleIO -= cycle; -} - -// Read / Write dummy functions -//////////////////////////////// - -u32 FASTCALL C68k_Read_Dummy(UNUSED const u32 adr) -{ - return 0; -} - -void FASTCALL C68k_Write_Dummy(UNUSED const u32 adr, UNUSED u32 data) -{ - -} - -s32 FASTCALL C68k_Interrupt_Ack_Dummy(s32 level) -{ - // return vector - return (C68K_INTERRUPT_AUTOVECTOR_EX + level); -} - -void FASTCALL C68k_Reset_Dummy(void) -{ - -} - -// Read / Write core functions -/////////////////////////////// - -u32 C68k_Read_Byte(c68k_struc *cpu, u32 adr) -{ - return cpu->Read_Byte(adr); -} - -u32 C68k_Read_Word(c68k_struc *cpu, u32 adr) -{ - return cpu->Read_Word(adr); -} - -u32 C68k_Read_Long(c68k_struc *cpu, u32 adr) -{ -#ifdef C68K_BIG_ENDIAN - return (cpu->Read_Word(adr) << 16) | (cpu->Read_Word(adr + 2) & 0xFFFF); -#else - return (cpu->Read_Word(adr) << 16) | (cpu->Read_Word(adr + 2) & 0xFFFF); -#endif -} - -void C68k_Write_Byte(c68k_struc *cpu, u32 adr, u32 data) -{ - cpu->Write_Byte(adr, data); -} - -void C68k_Write_Word(c68k_struc *cpu, u32 adr, u32 data) -{ - cpu->Write_Word(adr, data); -} - -void C68k_Write_Long(c68k_struc *cpu, u32 adr, u32 data) -{ -#ifdef C68K_BIG_ENDIAN - cpu->Write_Word(adr, data >> 16); - cpu->Write_Word(adr + 2, data & 0xFFFF); -#else - cpu->Write_Word(adr, data >> 16); - cpu->Write_Word(adr + 2, data & 0xFFFF); -#endif -} - -// setting core functions -////////////////////////// - -void C68k_Set_Fetch(c68k_struc *cpu, u32 low_adr, u32 high_adr, pointer fetch_adr) -{ - u32 i, j; - - i = (low_adr >> C68K_FETCH_SFT) & C68K_FETCH_MASK; - j = (high_adr >> C68K_FETCH_SFT) & C68K_FETCH_MASK; - fetch_adr -= i << C68K_FETCH_SFT; - while (i <= j) cpu->Fetch[i++] = fetch_adr; -} - -void C68k_Set_ReadB(c68k_struc *cpu, C68K_READ *Func) -{ - cpu->Read_Byte = Func; -} - -void C68k_Set_ReadW(c68k_struc *cpu, C68K_READ *Func) -{ - cpu->Read_Word = Func; -} - -void C68k_Set_WriteB(c68k_struc *cpu, C68K_WRITE *Func) -{ - cpu->Write_Byte = Func; -} - -void C68k_Set_WriteW(c68k_struc *cpu, C68K_WRITE *Func) -{ - cpu->Write_Word = Func; -} - -// externals main functions -//////////////////////////// - -u32 C68k_Get_DReg(c68k_struc *cpu, u32 num) -{ - return cpu->D[num]; -} - -u32 C68k_Get_AReg(c68k_struc *cpu, u32 num) -{ - return cpu->A[num]; -} - -u32 C68k_Get_PC(c68k_struc *cpu) -{ - return (cpu->PC - cpu->BasePC); -} - -u32 C68k_Get_SR(c68k_struc *cpu) -{ - c68k_struc *CPU = cpu; - return GET_SR; -} - -u32 C68k_Get_USP(c68k_struc *cpu) -{ - if (cpu->flag_S) return cpu->USP; - else return cpu->A[7]; -} - -u32 C68k_Get_MSP(c68k_struc *cpu) -{ - if (cpu->flag_S) return cpu->A[7]; - else return cpu->USP; -} - -void C68k_Set_DReg(c68k_struc *cpu, u32 num, u32 val) -{ - cpu->D[num] = val; -} - -void C68k_Set_AReg(c68k_struc *cpu, u32 num, u32 val) -{ - cpu->A[num] = val; -} - -void C68k_Set_PC(c68k_struc *cpu, u32 val) -{ - cpu->BasePC = cpu->Fetch[(val >> C68K_FETCH_SFT) & C68K_FETCH_MASK]; - cpu->PC = val + cpu->BasePC; -} - -void C68k_Set_SR(c68k_struc *cpu, u32 val) -{ - c68k_struc *CPU = cpu; - SET_SR(val); -} - -void C68k_Set_USP(c68k_struc *cpu, u32 val) -{ - if (cpu->flag_S) cpu->USP = val; - else cpu->A[7] = val; -} - -void C68k_Set_MSP(c68k_struc *cpu, u32 val) -{ - if (cpu->flag_S) cpu->A[7] = val; - else cpu->USP = val; -} diff --git a/yabause/src/c68k/c68k.h b/yabause/src/c68k/c68k.h deleted file mode 100644 index a8297f4494..0000000000 --- a/yabause/src/c68k/c68k.h +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - Copyright 2004 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * C68K.H : - * - * C68K include file - * - ********************************************************************************/ - -#ifndef _C68K_H_ -#define _C68K_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../core.h" - -// setting -/////////// - -//#define NEOCD_HLE - -//#define C68K_GEN -#define C68K_BYTE_SWAP_OPT - -#ifdef WORDS_BIGENDIAN -#define C68K_BIG_ENDIAN -#endif - -#ifdef C68K_BIG_ENDIAN - #define BYTE_OFF 3 - #define WORD_OFF 1 -#else - #define BYTE_OFF 0 - #define WORD_OFF 0 -#endif - -//#define C68K_NO_JUMP_TABLE -//#define C68K_DEBUG -#define C68K_TAS_CAN_SET_MEMORY -//#define C68K_CONST_JUMP_TABLE -//#define C68K_AUTOVECTOR_CALLBACK - -// 68K core types definitions -////////////////////////////// - -#define C68K_FETCH_BITS 8 // [4-12] default = 8 -#define C68K_ADR_BITS 24 - -#define C68K_FETCH_SFT (C68K_ADR_BITS - C68K_FETCH_BITS) -#define C68K_FETCH_BANK (1 << C68K_FETCH_BITS) -#define C68K_FETCH_MASK (C68K_FETCH_BANK - 1) - -#define C68K_SR_C_SFT 8 -#define C68K_SR_V_SFT 7 -#define C68K_SR_Z_SFT 0 -#define C68K_SR_N_SFT 7 -#define C68K_SR_X_SFT 8 - -#define C68K_SR_S_SFT 13 - -#define C68K_SR_C (1 << C68K_SR_C_SFT) -#define C68K_SR_V (1 << C68K_SR_V_SFT) -#define C68K_SR_Z 0 -#define C68K_SR_N (1 << C68K_SR_N_SFT) -#define C68K_SR_X (1 << C68K_SR_X_SFT) - -#define C68K_SR_S (1 << C68K_SR_S_SFT) - -#define C68K_CCR_MASK 0x1F -#define C68K_SR_MASK (0x2700 | C68K_CCR_MASK) - -// exception defines taken from musashi core -#define C68K_RESET_EX 1 -#define C68K_BUS_ERROR_EX 2 -#define C68K_ADDRESS_ERROR_EX 3 -#define C68K_ILLEGAL_INSTRUCTION_EX 4 -#define C68K_ZERO_DIVIDE_EX 5 -#define C68K_CHK_EX 6 -#define C68K_TRAPV_EX 7 -#define C68K_PRIVILEGE_VIOLATION_EX 8 -#define C68K_TRACE_EX 9 -#define C68K_1010_EX 10 -#define C68K_1111_EX 11 -#define C68K_FORMAT_ERROR_EX 14 -#define C68K_UNINITIALIZED_INTERRUPT_EX 15 -#define C68K_SPURIOUS_INTERRUPT_EX 24 -#define C68K_INTERRUPT_AUTOVECTOR_EX 24 -#define C68K_TRAP_BASE_EX 32 - -#define C68K_INT_ACK_AUTOVECTOR -1 - -#define C68K_RUNNING 0x01 -#define C68K_HALTED 0x02 -#define C68K_WAITING 0x04 -#define C68K_DISABLE 0x10 -#define C68K_FAULTED 0x40 - -typedef u32 FASTCALL C68K_READ(const u32 adr); -typedef void FASTCALL C68K_WRITE(const u32 adr, u32 data); - -typedef s32 FASTCALL C68K_INT_CALLBACK(s32 level); -typedef void FASTCALL C68K_RESET_CALLBACK(void); - -typedef struct { - u32 D[8]; // 32 bytes aligned - u32 A[8]; // 16 bytes aligned - - u32 flag_C; // 32 bytes aligned - u32 flag_V; - u32 flag_notZ; - u32 flag_N; - - u32 flag_X; // 16 bytes aligned - u32 flag_I; - u32 flag_S; - - u32 USP; - - pointer PC; // 32 bytes aligned - pointer BasePC; - u32 Status; - s32 IRQLine; - - s32 CycleToDo; // 16 bytes aligned - s32 CycleIO; - s32 CycleSup; - u32 dirty1; - - C68K_READ *Read_Byte; // 32 bytes aligned - C68K_READ *Read_Word; - - C68K_WRITE *Write_Byte; - C68K_WRITE *Write_Word; - - C68K_INT_CALLBACK *Interrupt_CallBack; // 16 bytes aligned - C68K_RESET_CALLBACK *Reset_CallBack; - - pointer Fetch[C68K_FETCH_BANK]; // 32 bytes aligned -} c68k_struc; - - -// 68K core var declaration -//////////////////////////// - -extern c68k_struc C68K; - - -// 68K core function declaration -///////////////////////////////// - -void C68k_Init(c68k_struc *cpu, C68K_INT_CALLBACK *int_cb); - -s32 FASTCALL C68k_Reset(c68k_struc *cpu); - -// if < 0 --> error (cpu state returned) -// if >= 0 --> number of extras cycles done -s32 FASTCALL C68k_Exec(c68k_struc *cpu, s32 cycle); - -void FASTCALL C68k_Set_IRQ(c68k_struc *cpu, s32 level); - -s32 FASTCALL C68k_Get_CycleToDo(c68k_struc *cpu); -s32 FASTCALL C68k_Get_CycleRemaining(c68k_struc *cpu); -s32 FASTCALL C68k_Get_CycleDone(c68k_struc *cpu); -void FASTCALL C68k_Release_Cycle(c68k_struc *cpu); -void FASTCALL C68k_Add_Cycle(c68k_struc *cpu, s32 cycle); - -void C68k_Set_Fetch(c68k_struc *cpu, u32 low_adr, u32 high_adr, pointer fetch_adr); - -void C68k_Set_ReadB(c68k_struc *cpu, C68K_READ *Func); -void C68k_Set_ReadW(c68k_struc *cpu, C68K_READ *Func); -void C68k_Set_WriteB(c68k_struc *cpu, C68K_WRITE *Func); -void C68k_Set_WriteW(c68k_struc *cpu, C68K_WRITE *Func); - -u32 C68k_Get_DReg(c68k_struc *cpu, u32 num); -u32 C68k_Get_AReg(c68k_struc *cpu, u32 num); -u32 C68k_Get_PC(c68k_struc *cpu); -u32 C68k_Get_SR(c68k_struc *cpu); -u32 C68k_Get_USP(c68k_struc *cpu); -u32 C68k_Get_MSP(c68k_struc *cpu); - -void C68k_Set_DReg(c68k_struc *cpu, u32 num, u32 val); -void C68k_Set_AReg(c68k_struc *cpu, u32 num, u32 val); -void C68k_Set_PC(c68k_struc *cpu, u32 val); -void C68k_Set_SR(c68k_struc *cpu, u32 val); -void C68k_Set_USP(c68k_struc *cpu, u32 val); -void C68k_Set_MSP(c68k_struc *cpu, u32 val); - -#ifdef __cplusplus -} -#endif - -#endif // _C68K_H_ - diff --git a/yabause/src/c68k/c68k_ini.inc b/yabause/src/c68k/c68k_ini.inc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/yabause/src/c68k/c68k_op0.inc b/yabause/src/c68k/c68k_op0.inc deleted file mode 100644 index 59e79c2169..0000000000 --- a/yabause/src/c68k/c68k_op0.inc +++ /dev/null @@ -1,8330 +0,0 @@ -case 0x0001: -case 0x0002: -case 0x0003: -case 0x0004: -case 0x0005: -case 0x0006: -case 0x0007: - -// ORI -case 0x0000: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0011: -case 0x0012: -case 0x0013: -case 0x0014: -case 0x0015: -case 0x0016: -case 0x0017: - -// ORI -case 0x0010: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0019: -case 0x001A: -case 0x001B: -case 0x001C: -case 0x001D: -case 0x001E: - -// ORI -case 0x0018: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0021: -case 0x0022: -case 0x0023: -case 0x0024: -case 0x0025: -case 0x0026: - -// ORI -case 0x0020: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0029: -case 0x002A: -case 0x002B: -case 0x002C: -case 0x002D: -case 0x002E: -case 0x002F: - -// ORI -case 0x0028: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0031: -case 0x0032: -case 0x0033: -case 0x0034: -case 0x0035: -case 0x0036: -case 0x0037: - -// ORI -case 0x0030: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// ORI -case 0x0038: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// ORI -case 0x0039: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// ORI -case 0x001F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// ORI -case 0x0027: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0041: -case 0x0042: -case 0x0043: -case 0x0044: -case 0x0045: -case 0x0046: -case 0x0047: - -// ORI -case 0x0040: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0051: -case 0x0052: -case 0x0053: -case 0x0054: -case 0x0055: -case 0x0056: -case 0x0057: - -// ORI -case 0x0050: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0059: -case 0x005A: -case 0x005B: -case 0x005C: -case 0x005D: -case 0x005E: - -// ORI -case 0x0058: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0061: -case 0x0062: -case 0x0063: -case 0x0064: -case 0x0065: -case 0x0066: - -// ORI -case 0x0060: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0069: -case 0x006A: -case 0x006B: -case 0x006C: -case 0x006D: -case 0x006E: -case 0x006F: - -// ORI -case 0x0068: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0071: -case 0x0072: -case 0x0073: -case 0x0074: -case 0x0075: -case 0x0076: -case 0x0077: - -// ORI -case 0x0070: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// ORI -case 0x0078: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ORI -case 0x0079: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// ORI -case 0x005F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ORI -case 0x0067: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0081: -case 0x0082: -case 0x0083: -case 0x0084: -case 0x0085: -case 0x0086: -case 0x0087: - -// ORI -case 0x0080: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0091: -case 0x0092: -case 0x0093: -case 0x0094: -case 0x0095: -case 0x0096: -case 0x0097: - -// ORI -case 0x0090: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0099: -case 0x009A: -case 0x009B: -case 0x009C: -case 0x009D: -case 0x009E: - -// ORI -case 0x0098: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x00A1: -case 0x00A2: -case 0x00A3: -case 0x00A4: -case 0x00A5: -case 0x00A6: - -// ORI -case 0x00A0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x00A9: -case 0x00AA: -case 0x00AB: -case 0x00AC: -case 0x00AD: -case 0x00AE: -case 0x00AF: - -// ORI -case 0x00A8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x00B1: -case 0x00B2: -case 0x00B3: -case 0x00B4: -case 0x00B5: -case 0x00B6: -case 0x00B7: - -// ORI -case 0x00B0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// ORI -case 0x00B8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// ORI -case 0x00B9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// ORI -case 0x009F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// ORI -case 0x00A7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// ORICCR -case 0x003C: -{ - u32 res; - res = FETCH_BYTE & C68K_CCR_MASK; - PC += 2; - res |= GET_CCR; - SET_CCR(res) -} -RET(20) - -// ORISR -case 0x007C: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - res |= GET_SR; - SET_SR(res) - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x0201: -case 0x0202: -case 0x0203: -case 0x0204: -case 0x0205: -case 0x0206: -case 0x0207: - -// ANDI -case 0x0200: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0211: -case 0x0212: -case 0x0213: -case 0x0214: -case 0x0215: -case 0x0216: -case 0x0217: - -// ANDI -case 0x0210: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0219: -case 0x021A: -case 0x021B: -case 0x021C: -case 0x021D: -case 0x021E: - -// ANDI -case 0x0218: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0221: -case 0x0222: -case 0x0223: -case 0x0224: -case 0x0225: -case 0x0226: - -// ANDI -case 0x0220: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0229: -case 0x022A: -case 0x022B: -case 0x022C: -case 0x022D: -case 0x022E: -case 0x022F: - -// ANDI -case 0x0228: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0231: -case 0x0232: -case 0x0233: -case 0x0234: -case 0x0235: -case 0x0236: -case 0x0237: - -// ANDI -case 0x0230: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// ANDI -case 0x0238: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// ANDI -case 0x0239: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// ANDI -case 0x021F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// ANDI -case 0x0227: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0241: -case 0x0242: -case 0x0243: -case 0x0244: -case 0x0245: -case 0x0246: -case 0x0247: - -// ANDI -case 0x0240: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0251: -case 0x0252: -case 0x0253: -case 0x0254: -case 0x0255: -case 0x0256: -case 0x0257: - -// ANDI -case 0x0250: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0259: -case 0x025A: -case 0x025B: -case 0x025C: -case 0x025D: -case 0x025E: - -// ANDI -case 0x0258: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0261: -case 0x0262: -case 0x0263: -case 0x0264: -case 0x0265: -case 0x0266: - -// ANDI -case 0x0260: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0269: -case 0x026A: -case 0x026B: -case 0x026C: -case 0x026D: -case 0x026E: -case 0x026F: - -// ANDI -case 0x0268: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0271: -case 0x0272: -case 0x0273: -case 0x0274: -case 0x0275: -case 0x0276: -case 0x0277: - -// ANDI -case 0x0270: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// ANDI -case 0x0278: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ANDI -case 0x0279: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// ANDI -case 0x025F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ANDI -case 0x0267: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0281: -case 0x0282: -case 0x0283: -case 0x0284: -case 0x0285: -case 0x0286: -case 0x0287: - -// ANDI -case 0x0280: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0291: -case 0x0292: -case 0x0293: -case 0x0294: -case 0x0295: -case 0x0296: -case 0x0297: - -// ANDI -case 0x0290: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0299: -case 0x029A: -case 0x029B: -case 0x029C: -case 0x029D: -case 0x029E: - -// ANDI -case 0x0298: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x02A1: -case 0x02A2: -case 0x02A3: -case 0x02A4: -case 0x02A5: -case 0x02A6: - -// ANDI -case 0x02A0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x02A9: -case 0x02AA: -case 0x02AB: -case 0x02AC: -case 0x02AD: -case 0x02AE: -case 0x02AF: - -// ANDI -case 0x02A8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x02B1: -case 0x02B2: -case 0x02B3: -case 0x02B4: -case 0x02B5: -case 0x02B6: -case 0x02B7: - -// ANDI -case 0x02B0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// ANDI -case 0x02B8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// ANDI -case 0x02B9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// ANDI -case 0x029F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// ANDI -case 0x02A7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// ANDICCR -case 0x023C: -{ - u32 res; - res = FETCH_BYTE & C68K_CCR_MASK; - PC += 2; - res &= GET_CCR; - SET_CCR(res) -} -RET(20) - -// ANDISR -case 0x027C: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - res &= GET_SR; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x0A01: -case 0x0A02: -case 0x0A03: -case 0x0A04: -case 0x0A05: -case 0x0A06: -case 0x0A07: - -// EORI -case 0x0A00: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0A11: -case 0x0A12: -case 0x0A13: -case 0x0A14: -case 0x0A15: -case 0x0A16: -case 0x0A17: - -// EORI -case 0x0A10: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0A19: -case 0x0A1A: -case 0x0A1B: -case 0x0A1C: -case 0x0A1D: -case 0x0A1E: - -// EORI -case 0x0A18: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0A21: -case 0x0A22: -case 0x0A23: -case 0x0A24: -case 0x0A25: -case 0x0A26: - -// EORI -case 0x0A20: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0A29: -case 0x0A2A: -case 0x0A2B: -case 0x0A2C: -case 0x0A2D: -case 0x0A2E: -case 0x0A2F: - -// EORI -case 0x0A28: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0A31: -case 0x0A32: -case 0x0A33: -case 0x0A34: -case 0x0A35: -case 0x0A36: -case 0x0A37: - -// EORI -case 0x0A30: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// EORI -case 0x0A38: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// EORI -case 0x0A39: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// EORI -case 0x0A1F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// EORI -case 0x0A27: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0A41: -case 0x0A42: -case 0x0A43: -case 0x0A44: -case 0x0A45: -case 0x0A46: -case 0x0A47: - -// EORI -case 0x0A40: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0A51: -case 0x0A52: -case 0x0A53: -case 0x0A54: -case 0x0A55: -case 0x0A56: -case 0x0A57: - -// EORI -case 0x0A50: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0A59: -case 0x0A5A: -case 0x0A5B: -case 0x0A5C: -case 0x0A5D: -case 0x0A5E: - -// EORI -case 0x0A58: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0A61: -case 0x0A62: -case 0x0A63: -case 0x0A64: -case 0x0A65: -case 0x0A66: - -// EORI -case 0x0A60: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0A69: -case 0x0A6A: -case 0x0A6B: -case 0x0A6C: -case 0x0A6D: -case 0x0A6E: -case 0x0A6F: - -// EORI -case 0x0A68: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0A71: -case 0x0A72: -case 0x0A73: -case 0x0A74: -case 0x0A75: -case 0x0A76: -case 0x0A77: - -// EORI -case 0x0A70: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// EORI -case 0x0A78: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// EORI -case 0x0A79: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// EORI -case 0x0A5F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// EORI -case 0x0A67: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0A81: -case 0x0A82: -case 0x0A83: -case 0x0A84: -case 0x0A85: -case 0x0A86: -case 0x0A87: - -// EORI -case 0x0A80: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0A91: -case 0x0A92: -case 0x0A93: -case 0x0A94: -case 0x0A95: -case 0x0A96: -case 0x0A97: - -// EORI -case 0x0A90: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0A99: -case 0x0A9A: -case 0x0A9B: -case 0x0A9C: -case 0x0A9D: -case 0x0A9E: - -// EORI -case 0x0A98: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0AA1: -case 0x0AA2: -case 0x0AA3: -case 0x0AA4: -case 0x0AA5: -case 0x0AA6: - -// EORI -case 0x0AA0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x0AA9: -case 0x0AAA: -case 0x0AAB: -case 0x0AAC: -case 0x0AAD: -case 0x0AAE: -case 0x0AAF: - -// EORI -case 0x0AA8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x0AB1: -case 0x0AB2: -case 0x0AB3: -case 0x0AB4: -case 0x0AB5: -case 0x0AB6: -case 0x0AB7: - -// EORI -case 0x0AB0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// EORI -case 0x0AB8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// EORI -case 0x0AB9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// EORI -case 0x0A9F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// EORI -case 0x0AA7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// EORICCR -case 0x0A3C: -{ - u32 res; - res = FETCH_BYTE & C68K_CCR_MASK; - PC += 2; - res ^= GET_CCR; - SET_CCR(res) -} -RET(20) - -// EORISR -case 0x0A7C: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - res ^= GET_SR; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x0401: -case 0x0402: -case 0x0403: -case 0x0404: -case 0x0405: -case 0x0406: -case 0x0407: - -// SUBI -case 0x0400: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0411: -case 0x0412: -case 0x0413: -case 0x0414: -case 0x0415: -case 0x0416: -case 0x0417: - -// SUBI -case 0x0410: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0419: -case 0x041A: -case 0x041B: -case 0x041C: -case 0x041D: -case 0x041E: - -// SUBI -case 0x0418: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0421: -case 0x0422: -case 0x0423: -case 0x0424: -case 0x0425: -case 0x0426: - -// SUBI -case 0x0420: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0429: -case 0x042A: -case 0x042B: -case 0x042C: -case 0x042D: -case 0x042E: -case 0x042F: - -// SUBI -case 0x0428: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0431: -case 0x0432: -case 0x0433: -case 0x0434: -case 0x0435: -case 0x0436: -case 0x0437: - -// SUBI -case 0x0430: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// SUBI -case 0x0438: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// SUBI -case 0x0439: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// SUBI -case 0x041F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// SUBI -case 0x0427: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0441: -case 0x0442: -case 0x0443: -case 0x0444: -case 0x0445: -case 0x0446: -case 0x0447: - -// SUBI -case 0x0440: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0451: -case 0x0452: -case 0x0453: -case 0x0454: -case 0x0455: -case 0x0456: -case 0x0457: - -// SUBI -case 0x0450: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0459: -case 0x045A: -case 0x045B: -case 0x045C: -case 0x045D: -case 0x045E: - -// SUBI -case 0x0458: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0461: -case 0x0462: -case 0x0463: -case 0x0464: -case 0x0465: -case 0x0466: - -// SUBI -case 0x0460: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0469: -case 0x046A: -case 0x046B: -case 0x046C: -case 0x046D: -case 0x046E: -case 0x046F: - -// SUBI -case 0x0468: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0471: -case 0x0472: -case 0x0473: -case 0x0474: -case 0x0475: -case 0x0476: -case 0x0477: - -// SUBI -case 0x0470: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// SUBI -case 0x0478: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// SUBI -case 0x0479: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// SUBI -case 0x045F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// SUBI -case 0x0467: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0481: -case 0x0482: -case 0x0483: -case 0x0484: -case 0x0485: -case 0x0486: -case 0x0487: - -// SUBI -case 0x0480: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0491: -case 0x0492: -case 0x0493: -case 0x0494: -case 0x0495: -case 0x0496: -case 0x0497: - -// SUBI -case 0x0490: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0499: -case 0x049A: -case 0x049B: -case 0x049C: -case 0x049D: -case 0x049E: - -// SUBI -case 0x0498: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x04A1: -case 0x04A2: -case 0x04A3: -case 0x04A4: -case 0x04A5: -case 0x04A6: - -// SUBI -case 0x04A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x04A9: -case 0x04AA: -case 0x04AB: -case 0x04AC: -case 0x04AD: -case 0x04AE: -case 0x04AF: - -// SUBI -case 0x04A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x04B1: -case 0x04B2: -case 0x04B3: -case 0x04B4: -case 0x04B5: -case 0x04B6: -case 0x04B7: - -// SUBI -case 0x04B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// SUBI -case 0x04B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// SUBI -case 0x04B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// SUBI -case 0x049F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// SUBI -case 0x04A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x0601: -case 0x0602: -case 0x0603: -case 0x0604: -case 0x0605: -case 0x0606: -case 0x0607: - -// ADDI -case 0x0600: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0611: -case 0x0612: -case 0x0613: -case 0x0614: -case 0x0615: -case 0x0616: -case 0x0617: - -// ADDI -case 0x0610: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0619: -case 0x061A: -case 0x061B: -case 0x061C: -case 0x061D: -case 0x061E: - -// ADDI -case 0x0618: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0621: -case 0x0622: -case 0x0623: -case 0x0624: -case 0x0625: -case 0x0626: - -// ADDI -case 0x0620: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0629: -case 0x062A: -case 0x062B: -case 0x062C: -case 0x062D: -case 0x062E: -case 0x062F: - -// ADDI -case 0x0628: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0631: -case 0x0632: -case 0x0633: -case 0x0634: -case 0x0635: -case 0x0636: -case 0x0637: - -// ADDI -case 0x0630: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// ADDI -case 0x0638: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// ADDI -case 0x0639: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// ADDI -case 0x061F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// ADDI -case 0x0627: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0641: -case 0x0642: -case 0x0643: -case 0x0644: -case 0x0645: -case 0x0646: -case 0x0647: - -// ADDI -case 0x0640: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0651: -case 0x0652: -case 0x0653: -case 0x0654: -case 0x0655: -case 0x0656: -case 0x0657: - -// ADDI -case 0x0650: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0659: -case 0x065A: -case 0x065B: -case 0x065C: -case 0x065D: -case 0x065E: - -// ADDI -case 0x0658: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0661: -case 0x0662: -case 0x0663: -case 0x0664: -case 0x0665: -case 0x0666: - -// ADDI -case 0x0660: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0669: -case 0x066A: -case 0x066B: -case 0x066C: -case 0x066D: -case 0x066E: -case 0x066F: - -// ADDI -case 0x0668: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0671: -case 0x0672: -case 0x0673: -case 0x0674: -case 0x0675: -case 0x0676: -case 0x0677: - -// ADDI -case 0x0670: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// ADDI -case 0x0678: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ADDI -case 0x0679: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// ADDI -case 0x065F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ADDI -case 0x0667: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0681: -case 0x0682: -case 0x0683: -case 0x0684: -case 0x0685: -case 0x0686: -case 0x0687: - -// ADDI -case 0x0680: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0691: -case 0x0692: -case 0x0693: -case 0x0694: -case 0x0695: -case 0x0696: -case 0x0697: - -// ADDI -case 0x0690: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0699: -case 0x069A: -case 0x069B: -case 0x069C: -case 0x069D: -case 0x069E: - -// ADDI -case 0x0698: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x06A1: -case 0x06A2: -case 0x06A3: -case 0x06A4: -case 0x06A5: -case 0x06A6: - -// ADDI -case 0x06A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x06A9: -case 0x06AA: -case 0x06AB: -case 0x06AC: -case 0x06AD: -case 0x06AE: -case 0x06AF: - -// ADDI -case 0x06A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x06B1: -case 0x06B2: -case 0x06B3: -case 0x06B4: -case 0x06B5: -case 0x06B6: -case 0x06B7: - -// ADDI -case 0x06B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// ADDI -case 0x06B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// ADDI -case 0x06B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// ADDI -case 0x069F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// ADDI -case 0x06A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x0C01: -case 0x0C02: -case 0x0C03: -case 0x0C04: -case 0x0C05: -case 0x0C06: -case 0x0C07: - -// CMPI -case 0x0C00: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(8) -case 0x0C11: -case 0x0C12: -case 0x0C13: -case 0x0C14: -case 0x0C15: -case 0x0C16: -case 0x0C17: - -// CMPI -case 0x0C10: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0x0C19: -case 0x0C1A: -case 0x0C1B: -case 0x0C1C: -case 0x0C1D: -case 0x0C1E: - -// CMPI -case 0x0C18: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0x0C21: -case 0x0C22: -case 0x0C23: -case 0x0C24: -case 0x0C25: -case 0x0C26: - -// CMPI -case 0x0C20: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0x0C29: -case 0x0C2A: -case 0x0C2B: -case 0x0C2C: -case 0x0C2D: -case 0x0C2E: -case 0x0C2F: - -// CMPI -case 0x0C28: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(16) -case 0x0C31: -case 0x0C32: -case 0x0C33: -case 0x0C34: -case 0x0C35: -case 0x0C36: -case 0x0C37: - -// CMPI -case 0x0C30: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(18) - -// CMPI -case 0x0C38: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(16) - -// CMPI -case 0x0C39: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(20) - -// CMPI -case 0x0C1F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) - -// CMPI -case 0x0C27: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0x0C41: -case 0x0C42: -case 0x0C43: -case 0x0C44: -case 0x0C45: -case 0x0C46: -case 0x0C47: - -// CMPI -case 0x0C40: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(8) -case 0x0C51: -case 0x0C52: -case 0x0C53: -case 0x0C54: -case 0x0C55: -case 0x0C56: -case 0x0C57: - -// CMPI -case 0x0C50: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0x0C59: -case 0x0C5A: -case 0x0C5B: -case 0x0C5C: -case 0x0C5D: -case 0x0C5E: - -// CMPI -case 0x0C58: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0x0C61: -case 0x0C62: -case 0x0C63: -case 0x0C64: -case 0x0C65: -case 0x0C66: - -// CMPI -case 0x0C60: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0x0C69: -case 0x0C6A: -case 0x0C6B: -case 0x0C6C: -case 0x0C6D: -case 0x0C6E: -case 0x0C6F: - -// CMPI -case 0x0C68: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(16) -case 0x0C71: -case 0x0C72: -case 0x0C73: -case 0x0C74: -case 0x0C75: -case 0x0C76: -case 0x0C77: - -// CMPI -case 0x0C70: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(18) - -// CMPI -case 0x0C78: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(16) - -// CMPI -case 0x0C79: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(20) - -// CMPI -case 0x0C5F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) - -// CMPI -case 0x0C67: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0x0C81: -case 0x0C82: -case 0x0C83: -case 0x0C84: -case 0x0C85: -case 0x0C86: -case 0x0C87: - -// CMPI -case 0x0C80: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(14) -case 0x0C91: -case 0x0C92: -case 0x0C93: -case 0x0C94: -case 0x0C95: -case 0x0C96: -case 0x0C97: - -// CMPI -case 0x0C90: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0x0C99: -case 0x0C9A: -case 0x0C9B: -case 0x0C9C: -case 0x0C9D: -case 0x0C9E: - -// CMPI -case 0x0C98: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0x0CA1: -case 0x0CA2: -case 0x0CA3: -case 0x0CA4: -case 0x0CA5: -case 0x0CA6: - -// CMPI -case 0x0CA0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0x0CA9: -case 0x0CAA: -case 0x0CAB: -case 0x0CAC: -case 0x0CAD: -case 0x0CAE: -case 0x0CAF: - -// CMPI -case 0x0CA8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(24) -case 0x0CB1: -case 0x0CB2: -case 0x0CB3: -case 0x0CB4: -case 0x0CB5: -case 0x0CB6: -case 0x0CB7: - -// CMPI -case 0x0CB0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(26) - -// CMPI -case 0x0CB8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(24) - -// CMPI -case 0x0CB9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(28) - -// CMPI -case 0x0C9F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) - -// CMPI -case 0x0CA7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0x0801: -case 0x0802: -case 0x0803: -case 0x0804: -case 0x0805: -case 0x0806: -case 0x0807: - -// BTSTn -case 0x0800: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; -} -RET(10) -case 0x0811: -case 0x0812: -case 0x0813: -case 0x0814: -case 0x0815: -case 0x0816: -case 0x0817: - -// BTSTn -case 0x0810: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0819: -case 0x081A: -case 0x081B: -case 0x081C: -case 0x081D: -case 0x081E: - -// BTSTn -case 0x0818: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0821: -case 0x0822: -case 0x0823: -case 0x0824: -case 0x0825: -case 0x0826: - -// BTSTn -case 0x0820: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x0829: -case 0x082A: -case 0x082B: -case 0x082C: -case 0x082D: -case 0x082E: -case 0x082F: - -// BTSTn -case 0x0828: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) -case 0x0831: -case 0x0832: -case 0x0833: -case 0x0834: -case 0x0835: -case 0x0836: -case 0x0837: - -// BTSTn -case 0x0830: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(18) - -// BTSTn -case 0x0838: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) - -// BTSTn -case 0x0839: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(20) - -// BTSTn -case 0x083A: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) - -// BTSTn -case 0x083B: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(18) - -// BTSTn -case 0x081F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) - -// BTSTn -case 0x0827: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x0841: -case 0x0842: -case 0x0843: -case 0x0844: -case 0x0845: -case 0x0846: -case 0x0847: - -// BCHGn -case 0x0840: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res ^= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(12) -case 0x0851: -case 0x0852: -case 0x0853: -case 0x0854: -case 0x0855: -case 0x0856: -case 0x0857: - -// BCHGn -case 0x0850: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0859: -case 0x085A: -case 0x085B: -case 0x085C: -case 0x085D: -case 0x085E: - -// BCHGn -case 0x0858: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0861: -case 0x0862: -case 0x0863: -case 0x0864: -case 0x0865: -case 0x0866: - -// BCHGn -case 0x0860: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0869: -case 0x086A: -case 0x086B: -case 0x086C: -case 0x086D: -case 0x086E: -case 0x086F: - -// BCHGn -case 0x0868: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0871: -case 0x0872: -case 0x0873: -case 0x0874: -case 0x0875: -case 0x0876: -case 0x0877: - -// BCHGn -case 0x0870: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// BCHGn -case 0x0878: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// BCHGn -case 0x0879: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// BCHGn -case 0x085F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// BCHGn -case 0x0867: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0881: -case 0x0882: -case 0x0883: -case 0x0884: -case 0x0885: -case 0x0886: -case 0x0887: - -// BCLRn -case 0x0880: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res &= ~src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(14) -case 0x0891: -case 0x0892: -case 0x0893: -case 0x0894: -case 0x0895: -case 0x0896: -case 0x0897: - -// BCLRn -case 0x0890: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0899: -case 0x089A: -case 0x089B: -case 0x089C: -case 0x089D: -case 0x089E: - -// BCLRn -case 0x0898: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x08A1: -case 0x08A2: -case 0x08A3: -case 0x08A4: -case 0x08A5: -case 0x08A6: - -// BCLRn -case 0x08A0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x08A9: -case 0x08AA: -case 0x08AB: -case 0x08AC: -case 0x08AD: -case 0x08AE: -case 0x08AF: - -// BCLRn -case 0x08A8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x08B1: -case 0x08B2: -case 0x08B3: -case 0x08B4: -case 0x08B5: -case 0x08B6: -case 0x08B7: - -// BCLRn -case 0x08B0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// BCLRn -case 0x08B8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// BCLRn -case 0x08B9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// BCLRn -case 0x089F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// BCLRn -case 0x08A7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x08C1: -case 0x08C2: -case 0x08C3: -case 0x08C4: -case 0x08C5: -case 0x08C6: -case 0x08C7: - -// BSETn -case 0x08C0: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res |= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(12) -case 0x08D1: -case 0x08D2: -case 0x08D3: -case 0x08D4: -case 0x08D5: -case 0x08D6: -case 0x08D7: - -// BSETn -case 0x08D0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x08D9: -case 0x08DA: -case 0x08DB: -case 0x08DC: -case 0x08DD: -case 0x08DE: - -// BSETn -case 0x08D8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x08E1: -case 0x08E2: -case 0x08E3: -case 0x08E4: -case 0x08E5: -case 0x08E6: - -// BSETn -case 0x08E0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x08E9: -case 0x08EA: -case 0x08EB: -case 0x08EC: -case 0x08ED: -case 0x08EE: -case 0x08EF: - -// BSETn -case 0x08E8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x08F1: -case 0x08F2: -case 0x08F3: -case 0x08F4: -case 0x08F5: -case 0x08F6: -case 0x08F7: - -// BSETn -case 0x08F0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// BSETn -case 0x08F8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// BSETn -case 0x08F9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// BSETn -case 0x08DF: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// BSETn -case 0x08E7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0300: -case 0x0500: -case 0x0700: -case 0x0900: -case 0x0B00: -case 0x0D00: -case 0x0F00: -case 0x0101: -case 0x0301: -case 0x0501: -case 0x0701: -case 0x0901: -case 0x0B01: -case 0x0D01: -case 0x0F01: -case 0x0102: -case 0x0302: -case 0x0502: -case 0x0702: -case 0x0902: -case 0x0B02: -case 0x0D02: -case 0x0F02: -case 0x0103: -case 0x0303: -case 0x0503: -case 0x0703: -case 0x0903: -case 0x0B03: -case 0x0D03: -case 0x0F03: -case 0x0104: -case 0x0304: -case 0x0504: -case 0x0704: -case 0x0904: -case 0x0B04: -case 0x0D04: -case 0x0F04: -case 0x0105: -case 0x0305: -case 0x0505: -case 0x0705: -case 0x0905: -case 0x0B05: -case 0x0D05: -case 0x0F05: -case 0x0106: -case 0x0306: -case 0x0506: -case 0x0706: -case 0x0906: -case 0x0B06: -case 0x0D06: -case 0x0F06: -case 0x0107: -case 0x0307: -case 0x0507: -case 0x0707: -case 0x0907: -case 0x0B07: -case 0x0D07: -case 0x0F07: - -// BTST -case 0x0100: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; -} -RET(6) -case 0x0310: -case 0x0510: -case 0x0710: -case 0x0910: -case 0x0B10: -case 0x0D10: -case 0x0F10: -case 0x0111: -case 0x0311: -case 0x0511: -case 0x0711: -case 0x0911: -case 0x0B11: -case 0x0D11: -case 0x0F11: -case 0x0112: -case 0x0312: -case 0x0512: -case 0x0712: -case 0x0912: -case 0x0B12: -case 0x0D12: -case 0x0F12: -case 0x0113: -case 0x0313: -case 0x0513: -case 0x0713: -case 0x0913: -case 0x0B13: -case 0x0D13: -case 0x0F13: -case 0x0114: -case 0x0314: -case 0x0514: -case 0x0714: -case 0x0914: -case 0x0B14: -case 0x0D14: -case 0x0F14: -case 0x0115: -case 0x0315: -case 0x0515: -case 0x0715: -case 0x0915: -case 0x0B15: -case 0x0D15: -case 0x0F15: -case 0x0116: -case 0x0316: -case 0x0516: -case 0x0716: -case 0x0916: -case 0x0B16: -case 0x0D16: -case 0x0F16: -case 0x0117: -case 0x0317: -case 0x0517: -case 0x0717: -case 0x0917: -case 0x0B17: -case 0x0D17: -case 0x0F17: - -// BTST -case 0x0110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(8) -case 0x0318: -case 0x0518: -case 0x0718: -case 0x0918: -case 0x0B18: -case 0x0D18: -case 0x0F18: -case 0x0119: -case 0x0319: -case 0x0519: -case 0x0719: -case 0x0919: -case 0x0B19: -case 0x0D19: -case 0x0F19: -case 0x011A: -case 0x031A: -case 0x051A: -case 0x071A: -case 0x091A: -case 0x0B1A: -case 0x0D1A: -case 0x0F1A: -case 0x011B: -case 0x031B: -case 0x051B: -case 0x071B: -case 0x091B: -case 0x0B1B: -case 0x0D1B: -case 0x0F1B: -case 0x011C: -case 0x031C: -case 0x051C: -case 0x071C: -case 0x091C: -case 0x0B1C: -case 0x0D1C: -case 0x0F1C: -case 0x011D: -case 0x031D: -case 0x051D: -case 0x071D: -case 0x091D: -case 0x0B1D: -case 0x0D1D: -case 0x0F1D: -case 0x011E: -case 0x031E: -case 0x051E: -case 0x071E: -case 0x091E: -case 0x0B1E: -case 0x0D1E: -case 0x0F1E: - -// BTST -case 0x0118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(8) -case 0x0320: -case 0x0520: -case 0x0720: -case 0x0920: -case 0x0B20: -case 0x0D20: -case 0x0F20: -case 0x0121: -case 0x0321: -case 0x0521: -case 0x0721: -case 0x0921: -case 0x0B21: -case 0x0D21: -case 0x0F21: -case 0x0122: -case 0x0322: -case 0x0522: -case 0x0722: -case 0x0922: -case 0x0B22: -case 0x0D22: -case 0x0F22: -case 0x0123: -case 0x0323: -case 0x0523: -case 0x0723: -case 0x0923: -case 0x0B23: -case 0x0D23: -case 0x0F23: -case 0x0124: -case 0x0324: -case 0x0524: -case 0x0724: -case 0x0924: -case 0x0B24: -case 0x0D24: -case 0x0F24: -case 0x0125: -case 0x0325: -case 0x0525: -case 0x0725: -case 0x0925: -case 0x0B25: -case 0x0D25: -case 0x0F25: -case 0x0126: -case 0x0326: -case 0x0526: -case 0x0726: -case 0x0926: -case 0x0B26: -case 0x0D26: -case 0x0F26: - -// BTST -case 0x0120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(10) -case 0x0328: -case 0x0528: -case 0x0728: -case 0x0928: -case 0x0B28: -case 0x0D28: -case 0x0F28: -case 0x0129: -case 0x0329: -case 0x0529: -case 0x0729: -case 0x0929: -case 0x0B29: -case 0x0D29: -case 0x0F29: -case 0x012A: -case 0x032A: -case 0x052A: -case 0x072A: -case 0x092A: -case 0x0B2A: -case 0x0D2A: -case 0x0F2A: -case 0x012B: -case 0x032B: -case 0x052B: -case 0x072B: -case 0x092B: -case 0x0B2B: -case 0x0D2B: -case 0x0F2B: -case 0x012C: -case 0x032C: -case 0x052C: -case 0x072C: -case 0x092C: -case 0x0B2C: -case 0x0D2C: -case 0x0F2C: -case 0x012D: -case 0x032D: -case 0x052D: -case 0x072D: -case 0x092D: -case 0x0B2D: -case 0x0D2D: -case 0x0F2D: -case 0x012E: -case 0x032E: -case 0x052E: -case 0x072E: -case 0x092E: -case 0x0B2E: -case 0x0D2E: -case 0x0F2E: -case 0x012F: -case 0x032F: -case 0x052F: -case 0x072F: -case 0x092F: -case 0x0B2F: -case 0x0D2F: -case 0x0F2F: - -// BTST -case 0x0128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0330: -case 0x0530: -case 0x0730: -case 0x0930: -case 0x0B30: -case 0x0D30: -case 0x0F30: -case 0x0131: -case 0x0331: -case 0x0531: -case 0x0731: -case 0x0931: -case 0x0B31: -case 0x0D31: -case 0x0F31: -case 0x0132: -case 0x0332: -case 0x0532: -case 0x0732: -case 0x0932: -case 0x0B32: -case 0x0D32: -case 0x0F32: -case 0x0133: -case 0x0333: -case 0x0533: -case 0x0733: -case 0x0933: -case 0x0B33: -case 0x0D33: -case 0x0F33: -case 0x0134: -case 0x0334: -case 0x0534: -case 0x0734: -case 0x0934: -case 0x0B34: -case 0x0D34: -case 0x0F34: -case 0x0135: -case 0x0335: -case 0x0535: -case 0x0735: -case 0x0935: -case 0x0B35: -case 0x0D35: -case 0x0F35: -case 0x0136: -case 0x0336: -case 0x0536: -case 0x0736: -case 0x0936: -case 0x0B36: -case 0x0D36: -case 0x0F36: -case 0x0137: -case 0x0337: -case 0x0537: -case 0x0737: -case 0x0937: -case 0x0B37: -case 0x0D37: -case 0x0F37: - -// BTST -case 0x0130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x0338: -case 0x0538: -case 0x0738: -case 0x0938: -case 0x0B38: -case 0x0D38: -case 0x0F38: - -// BTST -case 0x0138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0339: -case 0x0539: -case 0x0739: -case 0x0939: -case 0x0B39: -case 0x0D39: -case 0x0F39: - -// BTST -case 0x0139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) -case 0x033A: -case 0x053A: -case 0x073A: -case 0x093A: -case 0x0B3A: -case 0x0D3A: -case 0x0F3A: - -// BTST -case 0x013A: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x033B: -case 0x053B: -case 0x073B: -case 0x093B: -case 0x0B3B: -case 0x0D3B: -case 0x0F3B: - -// BTST -case 0x013B: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x033C: -case 0x053C: -case 0x073C: -case 0x093C: -case 0x0B3C: -case 0x0D3C: -case 0x0F3C: - -// BTST -case 0x013C: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - res = FETCH_BYTE; - PC += 2; - CPU->flag_notZ = res & src; -} -RET(8) -case 0x031F: -case 0x051F: -case 0x071F: -case 0x091F: -case 0x0B1F: -case 0x0D1F: -case 0x0F1F: - -// BTST -case 0x011F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(8) -case 0x0327: -case 0x0527: -case 0x0727: -case 0x0927: -case 0x0B27: -case 0x0D27: -case 0x0F27: - -// BTST -case 0x0127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(10) -case 0x0340: -case 0x0540: -case 0x0740: -case 0x0940: -case 0x0B40: -case 0x0D40: -case 0x0F40: -case 0x0141: -case 0x0341: -case 0x0541: -case 0x0741: -case 0x0941: -case 0x0B41: -case 0x0D41: -case 0x0F41: -case 0x0142: -case 0x0342: -case 0x0542: -case 0x0742: -case 0x0942: -case 0x0B42: -case 0x0D42: -case 0x0F42: -case 0x0143: -case 0x0343: -case 0x0543: -case 0x0743: -case 0x0943: -case 0x0B43: -case 0x0D43: -case 0x0F43: -case 0x0144: -case 0x0344: -case 0x0544: -case 0x0744: -case 0x0944: -case 0x0B44: -case 0x0D44: -case 0x0F44: -case 0x0145: -case 0x0345: -case 0x0545: -case 0x0745: -case 0x0945: -case 0x0B45: -case 0x0D45: -case 0x0F45: -case 0x0146: -case 0x0346: -case 0x0546: -case 0x0746: -case 0x0946: -case 0x0B46: -case 0x0D46: -case 0x0F46: -case 0x0147: -case 0x0347: -case 0x0547: -case 0x0747: -case 0x0947: -case 0x0B47: -case 0x0D47: -case 0x0F47: - -// BCHG -case 0x0140: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res ^= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0350: -case 0x0550: -case 0x0750: -case 0x0950: -case 0x0B50: -case 0x0D50: -case 0x0F50: -case 0x0151: -case 0x0351: -case 0x0551: -case 0x0751: -case 0x0951: -case 0x0B51: -case 0x0D51: -case 0x0F51: -case 0x0152: -case 0x0352: -case 0x0552: -case 0x0752: -case 0x0952: -case 0x0B52: -case 0x0D52: -case 0x0F52: -case 0x0153: -case 0x0353: -case 0x0553: -case 0x0753: -case 0x0953: -case 0x0B53: -case 0x0D53: -case 0x0F53: -case 0x0154: -case 0x0354: -case 0x0554: -case 0x0754: -case 0x0954: -case 0x0B54: -case 0x0D54: -case 0x0F54: -case 0x0155: -case 0x0355: -case 0x0555: -case 0x0755: -case 0x0955: -case 0x0B55: -case 0x0D55: -case 0x0F55: -case 0x0156: -case 0x0356: -case 0x0556: -case 0x0756: -case 0x0956: -case 0x0B56: -case 0x0D56: -case 0x0F56: -case 0x0157: -case 0x0357: -case 0x0557: -case 0x0757: -case 0x0957: -case 0x0B57: -case 0x0D57: -case 0x0F57: - -// BCHG -case 0x0150: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0358: -case 0x0558: -case 0x0758: -case 0x0958: -case 0x0B58: -case 0x0D58: -case 0x0F58: -case 0x0159: -case 0x0359: -case 0x0559: -case 0x0759: -case 0x0959: -case 0x0B59: -case 0x0D59: -case 0x0F59: -case 0x015A: -case 0x035A: -case 0x055A: -case 0x075A: -case 0x095A: -case 0x0B5A: -case 0x0D5A: -case 0x0F5A: -case 0x015B: -case 0x035B: -case 0x055B: -case 0x075B: -case 0x095B: -case 0x0B5B: -case 0x0D5B: -case 0x0F5B: -case 0x015C: -case 0x035C: -case 0x055C: -case 0x075C: -case 0x095C: -case 0x0B5C: -case 0x0D5C: -case 0x0F5C: -case 0x015D: -case 0x035D: -case 0x055D: -case 0x075D: -case 0x095D: -case 0x0B5D: -case 0x0D5D: -case 0x0F5D: -case 0x015E: -case 0x035E: -case 0x055E: -case 0x075E: -case 0x095E: -case 0x0B5E: -case 0x0D5E: -case 0x0F5E: - -// BCHG -case 0x0158: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0360: -case 0x0560: -case 0x0760: -case 0x0960: -case 0x0B60: -case 0x0D60: -case 0x0F60: -case 0x0161: -case 0x0361: -case 0x0561: -case 0x0761: -case 0x0961: -case 0x0B61: -case 0x0D61: -case 0x0F61: -case 0x0162: -case 0x0362: -case 0x0562: -case 0x0762: -case 0x0962: -case 0x0B62: -case 0x0D62: -case 0x0F62: -case 0x0163: -case 0x0363: -case 0x0563: -case 0x0763: -case 0x0963: -case 0x0B63: -case 0x0D63: -case 0x0F63: -case 0x0164: -case 0x0364: -case 0x0564: -case 0x0764: -case 0x0964: -case 0x0B64: -case 0x0D64: -case 0x0F64: -case 0x0165: -case 0x0365: -case 0x0565: -case 0x0765: -case 0x0965: -case 0x0B65: -case 0x0D65: -case 0x0F65: -case 0x0166: -case 0x0366: -case 0x0566: -case 0x0766: -case 0x0966: -case 0x0B66: -case 0x0D66: -case 0x0F66: - -// BCHG -case 0x0160: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x0368: -case 0x0568: -case 0x0768: -case 0x0968: -case 0x0B68: -case 0x0D68: -case 0x0F68: -case 0x0169: -case 0x0369: -case 0x0569: -case 0x0769: -case 0x0969: -case 0x0B69: -case 0x0D69: -case 0x0F69: -case 0x016A: -case 0x036A: -case 0x056A: -case 0x076A: -case 0x096A: -case 0x0B6A: -case 0x0D6A: -case 0x0F6A: -case 0x016B: -case 0x036B: -case 0x056B: -case 0x076B: -case 0x096B: -case 0x0B6B: -case 0x0D6B: -case 0x0F6B: -case 0x016C: -case 0x036C: -case 0x056C: -case 0x076C: -case 0x096C: -case 0x0B6C: -case 0x0D6C: -case 0x0F6C: -case 0x016D: -case 0x036D: -case 0x056D: -case 0x076D: -case 0x096D: -case 0x0B6D: -case 0x0D6D: -case 0x0F6D: -case 0x016E: -case 0x036E: -case 0x056E: -case 0x076E: -case 0x096E: -case 0x0B6E: -case 0x0D6E: -case 0x0F6E: -case 0x016F: -case 0x036F: -case 0x056F: -case 0x076F: -case 0x096F: -case 0x0B6F: -case 0x0D6F: -case 0x0F6F: - -// BCHG -case 0x0168: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0370: -case 0x0570: -case 0x0770: -case 0x0970: -case 0x0B70: -case 0x0D70: -case 0x0F70: -case 0x0171: -case 0x0371: -case 0x0571: -case 0x0771: -case 0x0971: -case 0x0B71: -case 0x0D71: -case 0x0F71: -case 0x0172: -case 0x0372: -case 0x0572: -case 0x0772: -case 0x0972: -case 0x0B72: -case 0x0D72: -case 0x0F72: -case 0x0173: -case 0x0373: -case 0x0573: -case 0x0773: -case 0x0973: -case 0x0B73: -case 0x0D73: -case 0x0F73: -case 0x0174: -case 0x0374: -case 0x0574: -case 0x0774: -case 0x0974: -case 0x0B74: -case 0x0D74: -case 0x0F74: -case 0x0175: -case 0x0375: -case 0x0575: -case 0x0775: -case 0x0975: -case 0x0B75: -case 0x0D75: -case 0x0F75: -case 0x0176: -case 0x0376: -case 0x0576: -case 0x0776: -case 0x0976: -case 0x0B76: -case 0x0D76: -case 0x0F76: -case 0x0177: -case 0x0377: -case 0x0577: -case 0x0777: -case 0x0977: -case 0x0B77: -case 0x0D77: -case 0x0F77: - -// BCHG -case 0x0170: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0378: -case 0x0578: -case 0x0778: -case 0x0978: -case 0x0B78: -case 0x0D78: -case 0x0F78: - -// BCHG -case 0x0178: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0379: -case 0x0579: -case 0x0779: -case 0x0979: -case 0x0B79: -case 0x0D79: -case 0x0F79: - -// BCHG -case 0x0179: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x035F: -case 0x055F: -case 0x075F: -case 0x095F: -case 0x0B5F: -case 0x0D5F: -case 0x0F5F: - -// BCHG -case 0x015F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0367: -case 0x0567: -case 0x0767: -case 0x0967: -case 0x0B67: -case 0x0D67: -case 0x0F67: - -// BCHG -case 0x0167: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x0380: -case 0x0580: -case 0x0780: -case 0x0980: -case 0x0B80: -case 0x0D80: -case 0x0F80: -case 0x0181: -case 0x0381: -case 0x0581: -case 0x0781: -case 0x0981: -case 0x0B81: -case 0x0D81: -case 0x0F81: -case 0x0182: -case 0x0382: -case 0x0582: -case 0x0782: -case 0x0982: -case 0x0B82: -case 0x0D82: -case 0x0F82: -case 0x0183: -case 0x0383: -case 0x0583: -case 0x0783: -case 0x0983: -case 0x0B83: -case 0x0D83: -case 0x0F83: -case 0x0184: -case 0x0384: -case 0x0584: -case 0x0784: -case 0x0984: -case 0x0B84: -case 0x0D84: -case 0x0F84: -case 0x0185: -case 0x0385: -case 0x0585: -case 0x0785: -case 0x0985: -case 0x0B85: -case 0x0D85: -case 0x0F85: -case 0x0186: -case 0x0386: -case 0x0586: -case 0x0786: -case 0x0986: -case 0x0B86: -case 0x0D86: -case 0x0F86: -case 0x0187: -case 0x0387: -case 0x0587: -case 0x0787: -case 0x0987: -case 0x0B87: -case 0x0D87: -case 0x0F87: - -// BCLR -case 0x0180: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res &= ~src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(10) -case 0x0390: -case 0x0590: -case 0x0790: -case 0x0990: -case 0x0B90: -case 0x0D90: -case 0x0F90: -case 0x0191: -case 0x0391: -case 0x0591: -case 0x0791: -case 0x0991: -case 0x0B91: -case 0x0D91: -case 0x0F91: -case 0x0192: -case 0x0392: -case 0x0592: -case 0x0792: -case 0x0992: -case 0x0B92: -case 0x0D92: -case 0x0F92: -case 0x0193: -case 0x0393: -case 0x0593: -case 0x0793: -case 0x0993: -case 0x0B93: -case 0x0D93: -case 0x0F93: -case 0x0194: -case 0x0394: -case 0x0594: -case 0x0794: -case 0x0994: -case 0x0B94: -case 0x0D94: -case 0x0F94: -case 0x0195: -case 0x0395: -case 0x0595: -case 0x0795: -case 0x0995: -case 0x0B95: -case 0x0D95: -case 0x0F95: -case 0x0196: -case 0x0396: -case 0x0596: -case 0x0796: -case 0x0996: -case 0x0B96: -case 0x0D96: -case 0x0F96: -case 0x0197: -case 0x0397: -case 0x0597: -case 0x0797: -case 0x0997: -case 0x0B97: -case 0x0D97: -case 0x0F97: - -// BCLR -case 0x0190: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0398: -case 0x0598: -case 0x0798: -case 0x0998: -case 0x0B98: -case 0x0D98: -case 0x0F98: -case 0x0199: -case 0x0399: -case 0x0599: -case 0x0799: -case 0x0999: -case 0x0B99: -case 0x0D99: -case 0x0F99: -case 0x019A: -case 0x039A: -case 0x059A: -case 0x079A: -case 0x099A: -case 0x0B9A: -case 0x0D9A: -case 0x0F9A: -case 0x019B: -case 0x039B: -case 0x059B: -case 0x079B: -case 0x099B: -case 0x0B9B: -case 0x0D9B: -case 0x0F9B: -case 0x019C: -case 0x039C: -case 0x059C: -case 0x079C: -case 0x099C: -case 0x0B9C: -case 0x0D9C: -case 0x0F9C: -case 0x019D: -case 0x039D: -case 0x059D: -case 0x079D: -case 0x099D: -case 0x0B9D: -case 0x0D9D: -case 0x0F9D: -case 0x019E: -case 0x039E: -case 0x059E: -case 0x079E: -case 0x099E: -case 0x0B9E: -case 0x0D9E: -case 0x0F9E: - -// BCLR -case 0x0198: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03A0: -case 0x05A0: -case 0x07A0: -case 0x09A0: -case 0x0BA0: -case 0x0DA0: -case 0x0FA0: -case 0x01A1: -case 0x03A1: -case 0x05A1: -case 0x07A1: -case 0x09A1: -case 0x0BA1: -case 0x0DA1: -case 0x0FA1: -case 0x01A2: -case 0x03A2: -case 0x05A2: -case 0x07A2: -case 0x09A2: -case 0x0BA2: -case 0x0DA2: -case 0x0FA2: -case 0x01A3: -case 0x03A3: -case 0x05A3: -case 0x07A3: -case 0x09A3: -case 0x0BA3: -case 0x0DA3: -case 0x0FA3: -case 0x01A4: -case 0x03A4: -case 0x05A4: -case 0x07A4: -case 0x09A4: -case 0x0BA4: -case 0x0DA4: -case 0x0FA4: -case 0x01A5: -case 0x03A5: -case 0x05A5: -case 0x07A5: -case 0x09A5: -case 0x0BA5: -case 0x0DA5: -case 0x0FA5: -case 0x01A6: -case 0x03A6: -case 0x05A6: -case 0x07A6: -case 0x09A6: -case 0x0BA6: -case 0x0DA6: -case 0x0FA6: - -// BCLR -case 0x01A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x03A8: -case 0x05A8: -case 0x07A8: -case 0x09A8: -case 0x0BA8: -case 0x0DA8: -case 0x0FA8: -case 0x01A9: -case 0x03A9: -case 0x05A9: -case 0x07A9: -case 0x09A9: -case 0x0BA9: -case 0x0DA9: -case 0x0FA9: -case 0x01AA: -case 0x03AA: -case 0x05AA: -case 0x07AA: -case 0x09AA: -case 0x0BAA: -case 0x0DAA: -case 0x0FAA: -case 0x01AB: -case 0x03AB: -case 0x05AB: -case 0x07AB: -case 0x09AB: -case 0x0BAB: -case 0x0DAB: -case 0x0FAB: -case 0x01AC: -case 0x03AC: -case 0x05AC: -case 0x07AC: -case 0x09AC: -case 0x0BAC: -case 0x0DAC: -case 0x0FAC: -case 0x01AD: -case 0x03AD: -case 0x05AD: -case 0x07AD: -case 0x09AD: -case 0x0BAD: -case 0x0DAD: -case 0x0FAD: -case 0x01AE: -case 0x03AE: -case 0x05AE: -case 0x07AE: -case 0x09AE: -case 0x0BAE: -case 0x0DAE: -case 0x0FAE: -case 0x01AF: -case 0x03AF: -case 0x05AF: -case 0x07AF: -case 0x09AF: -case 0x0BAF: -case 0x0DAF: -case 0x0FAF: - -// BCLR -case 0x01A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03B0: -case 0x05B0: -case 0x07B0: -case 0x09B0: -case 0x0BB0: -case 0x0DB0: -case 0x0FB0: -case 0x01B1: -case 0x03B1: -case 0x05B1: -case 0x07B1: -case 0x09B1: -case 0x0BB1: -case 0x0DB1: -case 0x0FB1: -case 0x01B2: -case 0x03B2: -case 0x05B2: -case 0x07B2: -case 0x09B2: -case 0x0BB2: -case 0x0DB2: -case 0x0FB2: -case 0x01B3: -case 0x03B3: -case 0x05B3: -case 0x07B3: -case 0x09B3: -case 0x0BB3: -case 0x0DB3: -case 0x0FB3: -case 0x01B4: -case 0x03B4: -case 0x05B4: -case 0x07B4: -case 0x09B4: -case 0x0BB4: -case 0x0DB4: -case 0x0FB4: -case 0x01B5: -case 0x03B5: -case 0x05B5: -case 0x07B5: -case 0x09B5: -case 0x0BB5: -case 0x0DB5: -case 0x0FB5: -case 0x01B6: -case 0x03B6: -case 0x05B6: -case 0x07B6: -case 0x09B6: -case 0x0BB6: -case 0x0DB6: -case 0x0FB6: -case 0x01B7: -case 0x03B7: -case 0x05B7: -case 0x07B7: -case 0x09B7: -case 0x0BB7: -case 0x0DB7: -case 0x0FB7: - -// BCLR -case 0x01B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x03B8: -case 0x05B8: -case 0x07B8: -case 0x09B8: -case 0x0BB8: -case 0x0DB8: -case 0x0FB8: - -// BCLR -case 0x01B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03B9: -case 0x05B9: -case 0x07B9: -case 0x09B9: -case 0x0BB9: -case 0x0DB9: -case 0x0FB9: - -// BCLR -case 0x01B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x039F: -case 0x059F: -case 0x079F: -case 0x099F: -case 0x0B9F: -case 0x0D9F: -case 0x0F9F: - -// BCLR -case 0x019F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03A7: -case 0x05A7: -case 0x07A7: -case 0x09A7: -case 0x0BA7: -case 0x0DA7: -case 0x0FA7: - -// BCLR -case 0x01A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x03C0: -case 0x05C0: -case 0x07C0: -case 0x09C0: -case 0x0BC0: -case 0x0DC0: -case 0x0FC0: -case 0x01C1: -case 0x03C1: -case 0x05C1: -case 0x07C1: -case 0x09C1: -case 0x0BC1: -case 0x0DC1: -case 0x0FC1: -case 0x01C2: -case 0x03C2: -case 0x05C2: -case 0x07C2: -case 0x09C2: -case 0x0BC2: -case 0x0DC2: -case 0x0FC2: -case 0x01C3: -case 0x03C3: -case 0x05C3: -case 0x07C3: -case 0x09C3: -case 0x0BC3: -case 0x0DC3: -case 0x0FC3: -case 0x01C4: -case 0x03C4: -case 0x05C4: -case 0x07C4: -case 0x09C4: -case 0x0BC4: -case 0x0DC4: -case 0x0FC4: -case 0x01C5: -case 0x03C5: -case 0x05C5: -case 0x07C5: -case 0x09C5: -case 0x0BC5: -case 0x0DC5: -case 0x0FC5: -case 0x01C6: -case 0x03C6: -case 0x05C6: -case 0x07C6: -case 0x09C6: -case 0x0BC6: -case 0x0DC6: -case 0x0FC6: -case 0x01C7: -case 0x03C7: -case 0x05C7: -case 0x07C7: -case 0x09C7: -case 0x0BC7: -case 0x0DC7: -case 0x0FC7: - -// BSET -case 0x01C0: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res |= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x03D0: -case 0x05D0: -case 0x07D0: -case 0x09D0: -case 0x0BD0: -case 0x0DD0: -case 0x0FD0: -case 0x01D1: -case 0x03D1: -case 0x05D1: -case 0x07D1: -case 0x09D1: -case 0x0BD1: -case 0x0DD1: -case 0x0FD1: -case 0x01D2: -case 0x03D2: -case 0x05D2: -case 0x07D2: -case 0x09D2: -case 0x0BD2: -case 0x0DD2: -case 0x0FD2: -case 0x01D3: -case 0x03D3: -case 0x05D3: -case 0x07D3: -case 0x09D3: -case 0x0BD3: -case 0x0DD3: -case 0x0FD3: -case 0x01D4: -case 0x03D4: -case 0x05D4: -case 0x07D4: -case 0x09D4: -case 0x0BD4: -case 0x0DD4: -case 0x0FD4: -case 0x01D5: -case 0x03D5: -case 0x05D5: -case 0x07D5: -case 0x09D5: -case 0x0BD5: -case 0x0DD5: -case 0x0FD5: -case 0x01D6: -case 0x03D6: -case 0x05D6: -case 0x07D6: -case 0x09D6: -case 0x0BD6: -case 0x0DD6: -case 0x0FD6: -case 0x01D7: -case 0x03D7: -case 0x05D7: -case 0x07D7: -case 0x09D7: -case 0x0BD7: -case 0x0DD7: -case 0x0FD7: - -// BSET -case 0x01D0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03D8: -case 0x05D8: -case 0x07D8: -case 0x09D8: -case 0x0BD8: -case 0x0DD8: -case 0x0FD8: -case 0x01D9: -case 0x03D9: -case 0x05D9: -case 0x07D9: -case 0x09D9: -case 0x0BD9: -case 0x0DD9: -case 0x0FD9: -case 0x01DA: -case 0x03DA: -case 0x05DA: -case 0x07DA: -case 0x09DA: -case 0x0BDA: -case 0x0DDA: -case 0x0FDA: -case 0x01DB: -case 0x03DB: -case 0x05DB: -case 0x07DB: -case 0x09DB: -case 0x0BDB: -case 0x0DDB: -case 0x0FDB: -case 0x01DC: -case 0x03DC: -case 0x05DC: -case 0x07DC: -case 0x09DC: -case 0x0BDC: -case 0x0DDC: -case 0x0FDC: -case 0x01DD: -case 0x03DD: -case 0x05DD: -case 0x07DD: -case 0x09DD: -case 0x0BDD: -case 0x0DDD: -case 0x0FDD: -case 0x01DE: -case 0x03DE: -case 0x05DE: -case 0x07DE: -case 0x09DE: -case 0x0BDE: -case 0x0DDE: -case 0x0FDE: - -// BSET -case 0x01D8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03E0: -case 0x05E0: -case 0x07E0: -case 0x09E0: -case 0x0BE0: -case 0x0DE0: -case 0x0FE0: -case 0x01E1: -case 0x03E1: -case 0x05E1: -case 0x07E1: -case 0x09E1: -case 0x0BE1: -case 0x0DE1: -case 0x0FE1: -case 0x01E2: -case 0x03E2: -case 0x05E2: -case 0x07E2: -case 0x09E2: -case 0x0BE2: -case 0x0DE2: -case 0x0FE2: -case 0x01E3: -case 0x03E3: -case 0x05E3: -case 0x07E3: -case 0x09E3: -case 0x0BE3: -case 0x0DE3: -case 0x0FE3: -case 0x01E4: -case 0x03E4: -case 0x05E4: -case 0x07E4: -case 0x09E4: -case 0x0BE4: -case 0x0DE4: -case 0x0FE4: -case 0x01E5: -case 0x03E5: -case 0x05E5: -case 0x07E5: -case 0x09E5: -case 0x0BE5: -case 0x0DE5: -case 0x0FE5: -case 0x01E6: -case 0x03E6: -case 0x05E6: -case 0x07E6: -case 0x09E6: -case 0x0BE6: -case 0x0DE6: -case 0x0FE6: - -// BSET -case 0x01E0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x03E8: -case 0x05E8: -case 0x07E8: -case 0x09E8: -case 0x0BE8: -case 0x0DE8: -case 0x0FE8: -case 0x01E9: -case 0x03E9: -case 0x05E9: -case 0x07E9: -case 0x09E9: -case 0x0BE9: -case 0x0DE9: -case 0x0FE9: -case 0x01EA: -case 0x03EA: -case 0x05EA: -case 0x07EA: -case 0x09EA: -case 0x0BEA: -case 0x0DEA: -case 0x0FEA: -case 0x01EB: -case 0x03EB: -case 0x05EB: -case 0x07EB: -case 0x09EB: -case 0x0BEB: -case 0x0DEB: -case 0x0FEB: -case 0x01EC: -case 0x03EC: -case 0x05EC: -case 0x07EC: -case 0x09EC: -case 0x0BEC: -case 0x0DEC: -case 0x0FEC: -case 0x01ED: -case 0x03ED: -case 0x05ED: -case 0x07ED: -case 0x09ED: -case 0x0BED: -case 0x0DED: -case 0x0FED: -case 0x01EE: -case 0x03EE: -case 0x05EE: -case 0x07EE: -case 0x09EE: -case 0x0BEE: -case 0x0DEE: -case 0x0FEE: -case 0x01EF: -case 0x03EF: -case 0x05EF: -case 0x07EF: -case 0x09EF: -case 0x0BEF: -case 0x0DEF: -case 0x0FEF: - -// BSET -case 0x01E8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03F0: -case 0x05F0: -case 0x07F0: -case 0x09F0: -case 0x0BF0: -case 0x0DF0: -case 0x0FF0: -case 0x01F1: -case 0x03F1: -case 0x05F1: -case 0x07F1: -case 0x09F1: -case 0x0BF1: -case 0x0DF1: -case 0x0FF1: -case 0x01F2: -case 0x03F2: -case 0x05F2: -case 0x07F2: -case 0x09F2: -case 0x0BF2: -case 0x0DF2: -case 0x0FF2: -case 0x01F3: -case 0x03F3: -case 0x05F3: -case 0x07F3: -case 0x09F3: -case 0x0BF3: -case 0x0DF3: -case 0x0FF3: -case 0x01F4: -case 0x03F4: -case 0x05F4: -case 0x07F4: -case 0x09F4: -case 0x0BF4: -case 0x0DF4: -case 0x0FF4: -case 0x01F5: -case 0x03F5: -case 0x05F5: -case 0x07F5: -case 0x09F5: -case 0x0BF5: -case 0x0DF5: -case 0x0FF5: -case 0x01F6: -case 0x03F6: -case 0x05F6: -case 0x07F6: -case 0x09F6: -case 0x0BF6: -case 0x0DF6: -case 0x0FF6: -case 0x01F7: -case 0x03F7: -case 0x05F7: -case 0x07F7: -case 0x09F7: -case 0x0BF7: -case 0x0DF7: -case 0x0FF7: - -// BSET -case 0x01F0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x03F8: -case 0x05F8: -case 0x07F8: -case 0x09F8: -case 0x0BF8: -case 0x0DF8: -case 0x0FF8: - -// BSET -case 0x01F8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03F9: -case 0x05F9: -case 0x07F9: -case 0x09F9: -case 0x0BF9: -case 0x0DF9: -case 0x0FF9: - -// BSET -case 0x01F9: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x03DF: -case 0x05DF: -case 0x07DF: -case 0x09DF: -case 0x0BDF: -case 0x0DDF: -case 0x0FDF: - -// BSET -case 0x01DF: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03E7: -case 0x05E7: -case 0x07E7: -case 0x09E7: -case 0x0BE7: -case 0x0DE7: -case 0x0FE7: - -// BSET -case 0x01E7: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x0308: -case 0x0508: -case 0x0708: -case 0x0908: -case 0x0B08: -case 0x0D08: -case 0x0F08: -case 0x0109: -case 0x0309: -case 0x0509: -case 0x0709: -case 0x0909: -case 0x0B09: -case 0x0D09: -case 0x0F09: -case 0x010A: -case 0x030A: -case 0x050A: -case 0x070A: -case 0x090A: -case 0x0B0A: -case 0x0D0A: -case 0x0F0A: -case 0x010B: -case 0x030B: -case 0x050B: -case 0x070B: -case 0x090B: -case 0x0B0B: -case 0x0D0B: -case 0x0F0B: -case 0x010C: -case 0x030C: -case 0x050C: -case 0x070C: -case 0x090C: -case 0x0B0C: -case 0x0D0C: -case 0x0F0C: -case 0x010D: -case 0x030D: -case 0x050D: -case 0x070D: -case 0x090D: -case 0x0B0D: -case 0x0D0D: -case 0x0F0D: -case 0x010E: -case 0x030E: -case 0x050E: -case 0x070E: -case 0x090E: -case 0x0B0E: -case 0x0D0E: -case 0x0F0E: -case 0x010F: -case 0x030F: -case 0x050F: -case 0x070F: -case 0x090F: -case 0x0B0F: -case 0x0D0F: -case 0x0F0F: - -// MOVEPWaD -case 0x0108: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr + 0, res) - READ_BYTE_F(adr + 2, src) - *(u16*)(&CPU->D[(Opcode >> 9) & 7]) = (res << 8) | src; - POST_IO -} -RET(24) -case 0x0348: -case 0x0548: -case 0x0748: -case 0x0948: -case 0x0B48: -case 0x0D48: -case 0x0F48: -case 0x0149: -case 0x0349: -case 0x0549: -case 0x0749: -case 0x0949: -case 0x0B49: -case 0x0D49: -case 0x0F49: -case 0x014A: -case 0x034A: -case 0x054A: -case 0x074A: -case 0x094A: -case 0x0B4A: -case 0x0D4A: -case 0x0F4A: -case 0x014B: -case 0x034B: -case 0x054B: -case 0x074B: -case 0x094B: -case 0x0B4B: -case 0x0D4B: -case 0x0F4B: -case 0x014C: -case 0x034C: -case 0x054C: -case 0x074C: -case 0x094C: -case 0x0B4C: -case 0x0D4C: -case 0x0F4C: -case 0x014D: -case 0x034D: -case 0x054D: -case 0x074D: -case 0x094D: -case 0x0B4D: -case 0x0D4D: -case 0x0F4D: -case 0x014E: -case 0x034E: -case 0x054E: -case 0x074E: -case 0x094E: -case 0x0B4E: -case 0x0D4E: -case 0x0F4E: -case 0x014F: -case 0x034F: -case 0x054F: -case 0x074F: -case 0x094F: -case 0x0B4F: -case 0x0D4F: -case 0x0F4F: - -// MOVEPLaD -case 0x0148: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res <<= 24; - adr += 2; - READ_BYTE_F(adr, src) - res |= src << 16; - adr += 2; - READ_BYTE_F(adr, src) - res |= src << 8; - adr += 2; - READ_BYTE_F(adr, src) - CPU->D[(Opcode >> 9) & 7] = res | src; - POST_IO -} -RET(32) -case 0x0388: -case 0x0588: -case 0x0788: -case 0x0988: -case 0x0B88: -case 0x0D88: -case 0x0F88: -case 0x0189: -case 0x0389: -case 0x0589: -case 0x0789: -case 0x0989: -case 0x0B89: -case 0x0D89: -case 0x0F89: -case 0x018A: -case 0x038A: -case 0x058A: -case 0x078A: -case 0x098A: -case 0x0B8A: -case 0x0D8A: -case 0x0F8A: -case 0x018B: -case 0x038B: -case 0x058B: -case 0x078B: -case 0x098B: -case 0x0B8B: -case 0x0D8B: -case 0x0F8B: -case 0x018C: -case 0x038C: -case 0x058C: -case 0x078C: -case 0x098C: -case 0x0B8C: -case 0x0D8C: -case 0x0F8C: -case 0x018D: -case 0x038D: -case 0x058D: -case 0x078D: -case 0x098D: -case 0x0B8D: -case 0x0D8D: -case 0x0F8D: -case 0x018E: -case 0x038E: -case 0x058E: -case 0x078E: -case 0x098E: -case 0x0B8E: -case 0x0D8E: -case 0x0F8E: -case 0x018F: -case 0x038F: -case 0x058F: -case 0x078F: -case 0x098F: -case 0x0B8F: -case 0x0D8F: -case 0x0F8F: - -// MOVEPWDa -case 0x0188: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr + 0, res >> 8) - WRITE_BYTE_F(adr + 2, res >> 0) - POST_IO -} -RET(24) -case 0x03C8: -case 0x05C8: -case 0x07C8: -case 0x09C8: -case 0x0BC8: -case 0x0DC8: -case 0x0FC8: -case 0x01C9: -case 0x03C9: -case 0x05C9: -case 0x07C9: -case 0x09C9: -case 0x0BC9: -case 0x0DC9: -case 0x0FC9: -case 0x01CA: -case 0x03CA: -case 0x05CA: -case 0x07CA: -case 0x09CA: -case 0x0BCA: -case 0x0DCA: -case 0x0FCA: -case 0x01CB: -case 0x03CB: -case 0x05CB: -case 0x07CB: -case 0x09CB: -case 0x0BCB: -case 0x0DCB: -case 0x0FCB: -case 0x01CC: -case 0x03CC: -case 0x05CC: -case 0x07CC: -case 0x09CC: -case 0x0BCC: -case 0x0DCC: -case 0x0FCC: -case 0x01CD: -case 0x03CD: -case 0x05CD: -case 0x07CD: -case 0x09CD: -case 0x0BCD: -case 0x0DCD: -case 0x0FCD: -case 0x01CE: -case 0x03CE: -case 0x05CE: -case 0x07CE: -case 0x09CE: -case 0x0BCE: -case 0x0DCE: -case 0x0FCE: -case 0x01CF: -case 0x03CF: -case 0x05CF: -case 0x07CF: -case 0x09CF: -case 0x0BCF: -case 0x0DCF: -case 0x0FCF: - -// MOVEPLDa -case 0x01C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res >> 24) - adr += 2; - WRITE_BYTE_F(adr, res >> 16) - adr += 2; - WRITE_BYTE_F(adr, res >> 8) - adr += 2; - WRITE_BYTE_F(adr, res >> 0) - POST_IO -} -RET(32) diff --git a/yabause/src/c68k/c68k_op1.inc b/yabause/src/c68k/c68k_op1.inc deleted file mode 100644 index 93694ed9db..0000000000 --- a/yabause/src/c68k/c68k_op1.inc +++ /dev/null @@ -1,5629 +0,0 @@ -case 0x1200: -case 0x1400: -case 0x1600: -case 0x1800: -case 0x1A00: -case 0x1C00: -case 0x1E00: -case 0x1001: -case 0x1201: -case 0x1401: -case 0x1601: -case 0x1801: -case 0x1A01: -case 0x1C01: -case 0x1E01: -case 0x1002: -case 0x1202: -case 0x1402: -case 0x1602: -case 0x1802: -case 0x1A02: -case 0x1C02: -case 0x1E02: -case 0x1003: -case 0x1203: -case 0x1403: -case 0x1603: -case 0x1803: -case 0x1A03: -case 0x1C03: -case 0x1E03: -case 0x1004: -case 0x1204: -case 0x1404: -case 0x1604: -case 0x1804: -case 0x1A04: -case 0x1C04: -case 0x1E04: -case 0x1005: -case 0x1205: -case 0x1405: -case 0x1605: -case 0x1805: -case 0x1A05: -case 0x1C05: -case 0x1E05: -case 0x1006: -case 0x1206: -case 0x1406: -case 0x1606: -case 0x1806: -case 0x1A06: -case 0x1C06: -case 0x1E06: -case 0x1007: -case 0x1207: -case 0x1407: -case 0x1607: -case 0x1807: -case 0x1A07: -case 0x1C07: -case 0x1E07: - -// MOVEB -case 0x1000: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x1280: -case 0x1480: -case 0x1680: -case 0x1880: -case 0x1A80: -case 0x1C80: -case 0x1E80: -case 0x1081: -case 0x1281: -case 0x1481: -case 0x1681: -case 0x1881: -case 0x1A81: -case 0x1C81: -case 0x1E81: -case 0x1082: -case 0x1282: -case 0x1482: -case 0x1682: -case 0x1882: -case 0x1A82: -case 0x1C82: -case 0x1E82: -case 0x1083: -case 0x1283: -case 0x1483: -case 0x1683: -case 0x1883: -case 0x1A83: -case 0x1C83: -case 0x1E83: -case 0x1084: -case 0x1284: -case 0x1484: -case 0x1684: -case 0x1884: -case 0x1A84: -case 0x1C84: -case 0x1E84: -case 0x1085: -case 0x1285: -case 0x1485: -case 0x1685: -case 0x1885: -case 0x1A85: -case 0x1C85: -case 0x1E85: -case 0x1086: -case 0x1286: -case 0x1486: -case 0x1686: -case 0x1886: -case 0x1A86: -case 0x1C86: -case 0x1E86: -case 0x1087: -case 0x1287: -case 0x1487: -case 0x1687: -case 0x1887: -case 0x1A87: -case 0x1C87: -case 0x1E87: - -// MOVEB -case 0x1080: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x12C0: -case 0x14C0: -case 0x16C0: -case 0x18C0: -case 0x1AC0: -case 0x1CC0: -case 0x10C1: -case 0x12C1: -case 0x14C1: -case 0x16C1: -case 0x18C1: -case 0x1AC1: -case 0x1CC1: -case 0x10C2: -case 0x12C2: -case 0x14C2: -case 0x16C2: -case 0x18C2: -case 0x1AC2: -case 0x1CC2: -case 0x10C3: -case 0x12C3: -case 0x14C3: -case 0x16C3: -case 0x18C3: -case 0x1AC3: -case 0x1CC3: -case 0x10C4: -case 0x12C4: -case 0x14C4: -case 0x16C4: -case 0x18C4: -case 0x1AC4: -case 0x1CC4: -case 0x10C5: -case 0x12C5: -case 0x14C5: -case 0x16C5: -case 0x18C5: -case 0x1AC5: -case 0x1CC5: -case 0x10C6: -case 0x12C6: -case 0x14C6: -case 0x16C6: -case 0x18C6: -case 0x1AC6: -case 0x1CC6: -case 0x10C7: -case 0x12C7: -case 0x14C7: -case 0x16C7: -case 0x18C7: -case 0x1AC7: -case 0x1CC7: - -// MOVEB -case 0x10C0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1300: -case 0x1500: -case 0x1700: -case 0x1900: -case 0x1B00: -case 0x1D00: -case 0x1101: -case 0x1301: -case 0x1501: -case 0x1701: -case 0x1901: -case 0x1B01: -case 0x1D01: -case 0x1102: -case 0x1302: -case 0x1502: -case 0x1702: -case 0x1902: -case 0x1B02: -case 0x1D02: -case 0x1103: -case 0x1303: -case 0x1503: -case 0x1703: -case 0x1903: -case 0x1B03: -case 0x1D03: -case 0x1104: -case 0x1304: -case 0x1504: -case 0x1704: -case 0x1904: -case 0x1B04: -case 0x1D04: -case 0x1105: -case 0x1305: -case 0x1505: -case 0x1705: -case 0x1905: -case 0x1B05: -case 0x1D05: -case 0x1106: -case 0x1306: -case 0x1506: -case 0x1706: -case 0x1906: -case 0x1B06: -case 0x1D06: -case 0x1107: -case 0x1307: -case 0x1507: -case 0x1707: -case 0x1907: -case 0x1B07: -case 0x1D07: - -// MOVEB -case 0x1100: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1340: -case 0x1540: -case 0x1740: -case 0x1940: -case 0x1B40: -case 0x1D40: -case 0x1F40: -case 0x1141: -case 0x1341: -case 0x1541: -case 0x1741: -case 0x1941: -case 0x1B41: -case 0x1D41: -case 0x1F41: -case 0x1142: -case 0x1342: -case 0x1542: -case 0x1742: -case 0x1942: -case 0x1B42: -case 0x1D42: -case 0x1F42: -case 0x1143: -case 0x1343: -case 0x1543: -case 0x1743: -case 0x1943: -case 0x1B43: -case 0x1D43: -case 0x1F43: -case 0x1144: -case 0x1344: -case 0x1544: -case 0x1744: -case 0x1944: -case 0x1B44: -case 0x1D44: -case 0x1F44: -case 0x1145: -case 0x1345: -case 0x1545: -case 0x1745: -case 0x1945: -case 0x1B45: -case 0x1D45: -case 0x1F45: -case 0x1146: -case 0x1346: -case 0x1546: -case 0x1746: -case 0x1946: -case 0x1B46: -case 0x1D46: -case 0x1F46: -case 0x1147: -case 0x1347: -case 0x1547: -case 0x1747: -case 0x1947: -case 0x1B47: -case 0x1D47: -case 0x1F47: - -// MOVEB -case 0x1140: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1380: -case 0x1580: -case 0x1780: -case 0x1980: -case 0x1B80: -case 0x1D80: -case 0x1F80: -case 0x1181: -case 0x1381: -case 0x1581: -case 0x1781: -case 0x1981: -case 0x1B81: -case 0x1D81: -case 0x1F81: -case 0x1182: -case 0x1382: -case 0x1582: -case 0x1782: -case 0x1982: -case 0x1B82: -case 0x1D82: -case 0x1F82: -case 0x1183: -case 0x1383: -case 0x1583: -case 0x1783: -case 0x1983: -case 0x1B83: -case 0x1D83: -case 0x1F83: -case 0x1184: -case 0x1384: -case 0x1584: -case 0x1784: -case 0x1984: -case 0x1B84: -case 0x1D84: -case 0x1F84: -case 0x1185: -case 0x1385: -case 0x1585: -case 0x1785: -case 0x1985: -case 0x1B85: -case 0x1D85: -case 0x1F85: -case 0x1186: -case 0x1386: -case 0x1586: -case 0x1786: -case 0x1986: -case 0x1B86: -case 0x1D86: -case 0x1F86: -case 0x1187: -case 0x1387: -case 0x1587: -case 0x1787: -case 0x1987: -case 0x1B87: -case 0x1D87: -case 0x1F87: - -// MOVEB -case 0x1180: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x11C1: -case 0x11C2: -case 0x11C3: -case 0x11C4: -case 0x11C5: -case 0x11C6: -case 0x11C7: - -// MOVEB -case 0x11C0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x13C1: -case 0x13C2: -case 0x13C3: -case 0x13C4: -case 0x13C5: -case 0x13C6: -case 0x13C7: - -// MOVEB -case 0x13C0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1EC1: -case 0x1EC2: -case 0x1EC3: -case 0x1EC4: -case 0x1EC5: -case 0x1EC6: -case 0x1EC7: - -// MOVEB -case 0x1EC0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1F01: -case 0x1F02: -case 0x1F03: -case 0x1F04: -case 0x1F05: -case 0x1F06: -case 0x1F07: - -// MOVEB -case 0x1F00: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1208: -case 0x1408: -case 0x1608: -case 0x1808: -case 0x1A08: -case 0x1C08: -case 0x1E08: -case 0x1009: -case 0x1209: -case 0x1409: -case 0x1609: -case 0x1809: -case 0x1A09: -case 0x1C09: -case 0x1E09: -case 0x100A: -case 0x120A: -case 0x140A: -case 0x160A: -case 0x180A: -case 0x1A0A: -case 0x1C0A: -case 0x1E0A: -case 0x100B: -case 0x120B: -case 0x140B: -case 0x160B: -case 0x180B: -case 0x1A0B: -case 0x1C0B: -case 0x1E0B: -case 0x100C: -case 0x120C: -case 0x140C: -case 0x160C: -case 0x180C: -case 0x1A0C: -case 0x1C0C: -case 0x1E0C: -case 0x100D: -case 0x120D: -case 0x140D: -case 0x160D: -case 0x180D: -case 0x1A0D: -case 0x1C0D: -case 0x1E0D: -case 0x100E: -case 0x120E: -case 0x140E: -case 0x160E: -case 0x180E: -case 0x1A0E: -case 0x1C0E: -case 0x1E0E: -case 0x100F: -case 0x120F: -case 0x140F: -case 0x160F: -case 0x180F: -case 0x1A0F: -case 0x1C0F: -case 0x1E0F: - -// MOVEB -case 0x1008: -{ - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x1288: -case 0x1488: -case 0x1688: -case 0x1888: -case 0x1A88: -case 0x1C88: -case 0x1E88: -case 0x1089: -case 0x1289: -case 0x1489: -case 0x1689: -case 0x1889: -case 0x1A89: -case 0x1C89: -case 0x1E89: -case 0x108A: -case 0x128A: -case 0x148A: -case 0x168A: -case 0x188A: -case 0x1A8A: -case 0x1C8A: -case 0x1E8A: -case 0x108B: -case 0x128B: -case 0x148B: -case 0x168B: -case 0x188B: -case 0x1A8B: -case 0x1C8B: -case 0x1E8B: -case 0x108C: -case 0x128C: -case 0x148C: -case 0x168C: -case 0x188C: -case 0x1A8C: -case 0x1C8C: -case 0x1E8C: -case 0x108D: -case 0x128D: -case 0x148D: -case 0x168D: -case 0x188D: -case 0x1A8D: -case 0x1C8D: -case 0x1E8D: -case 0x108E: -case 0x128E: -case 0x148E: -case 0x168E: -case 0x188E: -case 0x1A8E: -case 0x1C8E: -case 0x1E8E: -case 0x108F: -case 0x128F: -case 0x148F: -case 0x168F: -case 0x188F: -case 0x1A8F: -case 0x1C8F: -case 0x1E8F: - -// MOVEB -case 0x1088: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x12C8: -case 0x14C8: -case 0x16C8: -case 0x18C8: -case 0x1AC8: -case 0x1CC8: -case 0x10C9: -case 0x12C9: -case 0x14C9: -case 0x16C9: -case 0x18C9: -case 0x1AC9: -case 0x1CC9: -case 0x10CA: -case 0x12CA: -case 0x14CA: -case 0x16CA: -case 0x18CA: -case 0x1ACA: -case 0x1CCA: -case 0x10CB: -case 0x12CB: -case 0x14CB: -case 0x16CB: -case 0x18CB: -case 0x1ACB: -case 0x1CCB: -case 0x10CC: -case 0x12CC: -case 0x14CC: -case 0x16CC: -case 0x18CC: -case 0x1ACC: -case 0x1CCC: -case 0x10CD: -case 0x12CD: -case 0x14CD: -case 0x16CD: -case 0x18CD: -case 0x1ACD: -case 0x1CCD: -case 0x10CE: -case 0x12CE: -case 0x14CE: -case 0x16CE: -case 0x18CE: -case 0x1ACE: -case 0x1CCE: -case 0x10CF: -case 0x12CF: -case 0x14CF: -case 0x16CF: -case 0x18CF: -case 0x1ACF: -case 0x1CCF: - -// MOVEB -case 0x10C8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1308: -case 0x1508: -case 0x1708: -case 0x1908: -case 0x1B08: -case 0x1D08: -case 0x1109: -case 0x1309: -case 0x1509: -case 0x1709: -case 0x1909: -case 0x1B09: -case 0x1D09: -case 0x110A: -case 0x130A: -case 0x150A: -case 0x170A: -case 0x190A: -case 0x1B0A: -case 0x1D0A: -case 0x110B: -case 0x130B: -case 0x150B: -case 0x170B: -case 0x190B: -case 0x1B0B: -case 0x1D0B: -case 0x110C: -case 0x130C: -case 0x150C: -case 0x170C: -case 0x190C: -case 0x1B0C: -case 0x1D0C: -case 0x110D: -case 0x130D: -case 0x150D: -case 0x170D: -case 0x190D: -case 0x1B0D: -case 0x1D0D: -case 0x110E: -case 0x130E: -case 0x150E: -case 0x170E: -case 0x190E: -case 0x1B0E: -case 0x1D0E: -case 0x110F: -case 0x130F: -case 0x150F: -case 0x170F: -case 0x190F: -case 0x1B0F: -case 0x1D0F: - -// MOVEB -case 0x1108: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1348: -case 0x1548: -case 0x1748: -case 0x1948: -case 0x1B48: -case 0x1D48: -case 0x1F48: -case 0x1149: -case 0x1349: -case 0x1549: -case 0x1749: -case 0x1949: -case 0x1B49: -case 0x1D49: -case 0x1F49: -case 0x114A: -case 0x134A: -case 0x154A: -case 0x174A: -case 0x194A: -case 0x1B4A: -case 0x1D4A: -case 0x1F4A: -case 0x114B: -case 0x134B: -case 0x154B: -case 0x174B: -case 0x194B: -case 0x1B4B: -case 0x1D4B: -case 0x1F4B: -case 0x114C: -case 0x134C: -case 0x154C: -case 0x174C: -case 0x194C: -case 0x1B4C: -case 0x1D4C: -case 0x1F4C: -case 0x114D: -case 0x134D: -case 0x154D: -case 0x174D: -case 0x194D: -case 0x1B4D: -case 0x1D4D: -case 0x1F4D: -case 0x114E: -case 0x134E: -case 0x154E: -case 0x174E: -case 0x194E: -case 0x1B4E: -case 0x1D4E: -case 0x1F4E: -case 0x114F: -case 0x134F: -case 0x154F: -case 0x174F: -case 0x194F: -case 0x1B4F: -case 0x1D4F: -case 0x1F4F: - -// MOVEB -case 0x1148: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1388: -case 0x1588: -case 0x1788: -case 0x1988: -case 0x1B88: -case 0x1D88: -case 0x1F88: -case 0x1189: -case 0x1389: -case 0x1589: -case 0x1789: -case 0x1989: -case 0x1B89: -case 0x1D89: -case 0x1F89: -case 0x118A: -case 0x138A: -case 0x158A: -case 0x178A: -case 0x198A: -case 0x1B8A: -case 0x1D8A: -case 0x1F8A: -case 0x118B: -case 0x138B: -case 0x158B: -case 0x178B: -case 0x198B: -case 0x1B8B: -case 0x1D8B: -case 0x1F8B: -case 0x118C: -case 0x138C: -case 0x158C: -case 0x178C: -case 0x198C: -case 0x1B8C: -case 0x1D8C: -case 0x1F8C: -case 0x118D: -case 0x138D: -case 0x158D: -case 0x178D: -case 0x198D: -case 0x1B8D: -case 0x1D8D: -case 0x1F8D: -case 0x118E: -case 0x138E: -case 0x158E: -case 0x178E: -case 0x198E: -case 0x1B8E: -case 0x1D8E: -case 0x1F8E: -case 0x118F: -case 0x138F: -case 0x158F: -case 0x178F: -case 0x198F: -case 0x1B8F: -case 0x1D8F: -case 0x1F8F: - -// MOVEB -case 0x1188: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x11C9: -case 0x11CA: -case 0x11CB: -case 0x11CC: -case 0x11CD: -case 0x11CE: -case 0x11CF: - -// MOVEB -case 0x11C8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x13C9: -case 0x13CA: -case 0x13CB: -case 0x13CC: -case 0x13CD: -case 0x13CE: -case 0x13CF: - -// MOVEB -case 0x13C8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1EC9: -case 0x1ECA: -case 0x1ECB: -case 0x1ECC: -case 0x1ECD: -case 0x1ECE: -case 0x1ECF: - -// MOVEB -case 0x1EC8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1F09: -case 0x1F0A: -case 0x1F0B: -case 0x1F0C: -case 0x1F0D: -case 0x1F0E: -case 0x1F0F: - -// MOVEB -case 0x1F08: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1210: -case 0x1410: -case 0x1610: -case 0x1810: -case 0x1A10: -case 0x1C10: -case 0x1E10: -case 0x1011: -case 0x1211: -case 0x1411: -case 0x1611: -case 0x1811: -case 0x1A11: -case 0x1C11: -case 0x1E11: -case 0x1012: -case 0x1212: -case 0x1412: -case 0x1612: -case 0x1812: -case 0x1A12: -case 0x1C12: -case 0x1E12: -case 0x1013: -case 0x1213: -case 0x1413: -case 0x1613: -case 0x1813: -case 0x1A13: -case 0x1C13: -case 0x1E13: -case 0x1014: -case 0x1214: -case 0x1414: -case 0x1614: -case 0x1814: -case 0x1A14: -case 0x1C14: -case 0x1E14: -case 0x1015: -case 0x1215: -case 0x1415: -case 0x1615: -case 0x1815: -case 0x1A15: -case 0x1C15: -case 0x1E15: -case 0x1016: -case 0x1216: -case 0x1416: -case 0x1616: -case 0x1816: -case 0x1A16: -case 0x1C16: -case 0x1E16: -case 0x1017: -case 0x1217: -case 0x1417: -case 0x1617: -case 0x1817: -case 0x1A17: -case 0x1C17: -case 0x1E17: - -// MOVEB -case 0x1010: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x1290: -case 0x1490: -case 0x1690: -case 0x1890: -case 0x1A90: -case 0x1C90: -case 0x1E90: -case 0x1091: -case 0x1291: -case 0x1491: -case 0x1691: -case 0x1891: -case 0x1A91: -case 0x1C91: -case 0x1E91: -case 0x1092: -case 0x1292: -case 0x1492: -case 0x1692: -case 0x1892: -case 0x1A92: -case 0x1C92: -case 0x1E92: -case 0x1093: -case 0x1293: -case 0x1493: -case 0x1693: -case 0x1893: -case 0x1A93: -case 0x1C93: -case 0x1E93: -case 0x1094: -case 0x1294: -case 0x1494: -case 0x1694: -case 0x1894: -case 0x1A94: -case 0x1C94: -case 0x1E94: -case 0x1095: -case 0x1295: -case 0x1495: -case 0x1695: -case 0x1895: -case 0x1A95: -case 0x1C95: -case 0x1E95: -case 0x1096: -case 0x1296: -case 0x1496: -case 0x1696: -case 0x1896: -case 0x1A96: -case 0x1C96: -case 0x1E96: -case 0x1097: -case 0x1297: -case 0x1497: -case 0x1697: -case 0x1897: -case 0x1A97: -case 0x1C97: -case 0x1E97: - -// MOVEB -case 0x1090: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12D0: -case 0x14D0: -case 0x16D0: -case 0x18D0: -case 0x1AD0: -case 0x1CD0: -case 0x10D1: -case 0x12D1: -case 0x14D1: -case 0x16D1: -case 0x18D1: -case 0x1AD1: -case 0x1CD1: -case 0x10D2: -case 0x12D2: -case 0x14D2: -case 0x16D2: -case 0x18D2: -case 0x1AD2: -case 0x1CD2: -case 0x10D3: -case 0x12D3: -case 0x14D3: -case 0x16D3: -case 0x18D3: -case 0x1AD3: -case 0x1CD3: -case 0x10D4: -case 0x12D4: -case 0x14D4: -case 0x16D4: -case 0x18D4: -case 0x1AD4: -case 0x1CD4: -case 0x10D5: -case 0x12D5: -case 0x14D5: -case 0x16D5: -case 0x18D5: -case 0x1AD5: -case 0x1CD5: -case 0x10D6: -case 0x12D6: -case 0x14D6: -case 0x16D6: -case 0x18D6: -case 0x1AD6: -case 0x1CD6: -case 0x10D7: -case 0x12D7: -case 0x14D7: -case 0x16D7: -case 0x18D7: -case 0x1AD7: -case 0x1CD7: - -// MOVEB -case 0x10D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1310: -case 0x1510: -case 0x1710: -case 0x1910: -case 0x1B10: -case 0x1D10: -case 0x1111: -case 0x1311: -case 0x1511: -case 0x1711: -case 0x1911: -case 0x1B11: -case 0x1D11: -case 0x1112: -case 0x1312: -case 0x1512: -case 0x1712: -case 0x1912: -case 0x1B12: -case 0x1D12: -case 0x1113: -case 0x1313: -case 0x1513: -case 0x1713: -case 0x1913: -case 0x1B13: -case 0x1D13: -case 0x1114: -case 0x1314: -case 0x1514: -case 0x1714: -case 0x1914: -case 0x1B14: -case 0x1D14: -case 0x1115: -case 0x1315: -case 0x1515: -case 0x1715: -case 0x1915: -case 0x1B15: -case 0x1D15: -case 0x1116: -case 0x1316: -case 0x1516: -case 0x1716: -case 0x1916: -case 0x1B16: -case 0x1D16: -case 0x1117: -case 0x1317: -case 0x1517: -case 0x1717: -case 0x1917: -case 0x1B17: -case 0x1D17: - -// MOVEB -case 0x1110: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1350: -case 0x1550: -case 0x1750: -case 0x1950: -case 0x1B50: -case 0x1D50: -case 0x1F50: -case 0x1151: -case 0x1351: -case 0x1551: -case 0x1751: -case 0x1951: -case 0x1B51: -case 0x1D51: -case 0x1F51: -case 0x1152: -case 0x1352: -case 0x1552: -case 0x1752: -case 0x1952: -case 0x1B52: -case 0x1D52: -case 0x1F52: -case 0x1153: -case 0x1353: -case 0x1553: -case 0x1753: -case 0x1953: -case 0x1B53: -case 0x1D53: -case 0x1F53: -case 0x1154: -case 0x1354: -case 0x1554: -case 0x1754: -case 0x1954: -case 0x1B54: -case 0x1D54: -case 0x1F54: -case 0x1155: -case 0x1355: -case 0x1555: -case 0x1755: -case 0x1955: -case 0x1B55: -case 0x1D55: -case 0x1F55: -case 0x1156: -case 0x1356: -case 0x1556: -case 0x1756: -case 0x1956: -case 0x1B56: -case 0x1D56: -case 0x1F56: -case 0x1157: -case 0x1357: -case 0x1557: -case 0x1757: -case 0x1957: -case 0x1B57: -case 0x1D57: -case 0x1F57: - -// MOVEB -case 0x1150: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1390: -case 0x1590: -case 0x1790: -case 0x1990: -case 0x1B90: -case 0x1D90: -case 0x1F90: -case 0x1191: -case 0x1391: -case 0x1591: -case 0x1791: -case 0x1991: -case 0x1B91: -case 0x1D91: -case 0x1F91: -case 0x1192: -case 0x1392: -case 0x1592: -case 0x1792: -case 0x1992: -case 0x1B92: -case 0x1D92: -case 0x1F92: -case 0x1193: -case 0x1393: -case 0x1593: -case 0x1793: -case 0x1993: -case 0x1B93: -case 0x1D93: -case 0x1F93: -case 0x1194: -case 0x1394: -case 0x1594: -case 0x1794: -case 0x1994: -case 0x1B94: -case 0x1D94: -case 0x1F94: -case 0x1195: -case 0x1395: -case 0x1595: -case 0x1795: -case 0x1995: -case 0x1B95: -case 0x1D95: -case 0x1F95: -case 0x1196: -case 0x1396: -case 0x1596: -case 0x1796: -case 0x1996: -case 0x1B96: -case 0x1D96: -case 0x1F96: -case 0x1197: -case 0x1397: -case 0x1597: -case 0x1797: -case 0x1997: -case 0x1B97: -case 0x1D97: -case 0x1F97: - -// MOVEB -case 0x1190: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x11D1: -case 0x11D2: -case 0x11D3: -case 0x11D4: -case 0x11D5: -case 0x11D6: -case 0x11D7: - -// MOVEB -case 0x11D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x13D1: -case 0x13D2: -case 0x13D3: -case 0x13D4: -case 0x13D5: -case 0x13D6: -case 0x13D7: - -// MOVEB -case 0x13D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1ED1: -case 0x1ED2: -case 0x1ED3: -case 0x1ED4: -case 0x1ED5: -case 0x1ED6: -case 0x1ED7: - -// MOVEB -case 0x1ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1F11: -case 0x1F12: -case 0x1F13: -case 0x1F14: -case 0x1F15: -case 0x1F16: -case 0x1F17: - -// MOVEB -case 0x1F10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1218: -case 0x1418: -case 0x1618: -case 0x1818: -case 0x1A18: -case 0x1C18: -case 0x1E18: -case 0x1019: -case 0x1219: -case 0x1419: -case 0x1619: -case 0x1819: -case 0x1A19: -case 0x1C19: -case 0x1E19: -case 0x101A: -case 0x121A: -case 0x141A: -case 0x161A: -case 0x181A: -case 0x1A1A: -case 0x1C1A: -case 0x1E1A: -case 0x101B: -case 0x121B: -case 0x141B: -case 0x161B: -case 0x181B: -case 0x1A1B: -case 0x1C1B: -case 0x1E1B: -case 0x101C: -case 0x121C: -case 0x141C: -case 0x161C: -case 0x181C: -case 0x1A1C: -case 0x1C1C: -case 0x1E1C: -case 0x101D: -case 0x121D: -case 0x141D: -case 0x161D: -case 0x181D: -case 0x1A1D: -case 0x1C1D: -case 0x1E1D: -case 0x101E: -case 0x121E: -case 0x141E: -case 0x161E: -case 0x181E: -case 0x1A1E: -case 0x1C1E: -case 0x1E1E: - -// MOVEB -case 0x1018: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x1298: -case 0x1498: -case 0x1698: -case 0x1898: -case 0x1A98: -case 0x1C98: -case 0x1E98: -case 0x1099: -case 0x1299: -case 0x1499: -case 0x1699: -case 0x1899: -case 0x1A99: -case 0x1C99: -case 0x1E99: -case 0x109A: -case 0x129A: -case 0x149A: -case 0x169A: -case 0x189A: -case 0x1A9A: -case 0x1C9A: -case 0x1E9A: -case 0x109B: -case 0x129B: -case 0x149B: -case 0x169B: -case 0x189B: -case 0x1A9B: -case 0x1C9B: -case 0x1E9B: -case 0x109C: -case 0x129C: -case 0x149C: -case 0x169C: -case 0x189C: -case 0x1A9C: -case 0x1C9C: -case 0x1E9C: -case 0x109D: -case 0x129D: -case 0x149D: -case 0x169D: -case 0x189D: -case 0x1A9D: -case 0x1C9D: -case 0x1E9D: -case 0x109E: -case 0x129E: -case 0x149E: -case 0x169E: -case 0x189E: -case 0x1A9E: -case 0x1C9E: -case 0x1E9E: - -// MOVEB -case 0x1098: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12D8: -case 0x14D8: -case 0x16D8: -case 0x18D8: -case 0x1AD8: -case 0x1CD8: -case 0x10D9: -case 0x12D9: -case 0x14D9: -case 0x16D9: -case 0x18D9: -case 0x1AD9: -case 0x1CD9: -case 0x10DA: -case 0x12DA: -case 0x14DA: -case 0x16DA: -case 0x18DA: -case 0x1ADA: -case 0x1CDA: -case 0x10DB: -case 0x12DB: -case 0x14DB: -case 0x16DB: -case 0x18DB: -case 0x1ADB: -case 0x1CDB: -case 0x10DC: -case 0x12DC: -case 0x14DC: -case 0x16DC: -case 0x18DC: -case 0x1ADC: -case 0x1CDC: -case 0x10DD: -case 0x12DD: -case 0x14DD: -case 0x16DD: -case 0x18DD: -case 0x1ADD: -case 0x1CDD: -case 0x10DE: -case 0x12DE: -case 0x14DE: -case 0x16DE: -case 0x18DE: -case 0x1ADE: -case 0x1CDE: - -// MOVEB -case 0x10D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1318: -case 0x1518: -case 0x1718: -case 0x1918: -case 0x1B18: -case 0x1D18: -case 0x1119: -case 0x1319: -case 0x1519: -case 0x1719: -case 0x1919: -case 0x1B19: -case 0x1D19: -case 0x111A: -case 0x131A: -case 0x151A: -case 0x171A: -case 0x191A: -case 0x1B1A: -case 0x1D1A: -case 0x111B: -case 0x131B: -case 0x151B: -case 0x171B: -case 0x191B: -case 0x1B1B: -case 0x1D1B: -case 0x111C: -case 0x131C: -case 0x151C: -case 0x171C: -case 0x191C: -case 0x1B1C: -case 0x1D1C: -case 0x111D: -case 0x131D: -case 0x151D: -case 0x171D: -case 0x191D: -case 0x1B1D: -case 0x1D1D: -case 0x111E: -case 0x131E: -case 0x151E: -case 0x171E: -case 0x191E: -case 0x1B1E: -case 0x1D1E: - -// MOVEB -case 0x1118: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1358: -case 0x1558: -case 0x1758: -case 0x1958: -case 0x1B58: -case 0x1D58: -case 0x1F58: -case 0x1159: -case 0x1359: -case 0x1559: -case 0x1759: -case 0x1959: -case 0x1B59: -case 0x1D59: -case 0x1F59: -case 0x115A: -case 0x135A: -case 0x155A: -case 0x175A: -case 0x195A: -case 0x1B5A: -case 0x1D5A: -case 0x1F5A: -case 0x115B: -case 0x135B: -case 0x155B: -case 0x175B: -case 0x195B: -case 0x1B5B: -case 0x1D5B: -case 0x1F5B: -case 0x115C: -case 0x135C: -case 0x155C: -case 0x175C: -case 0x195C: -case 0x1B5C: -case 0x1D5C: -case 0x1F5C: -case 0x115D: -case 0x135D: -case 0x155D: -case 0x175D: -case 0x195D: -case 0x1B5D: -case 0x1D5D: -case 0x1F5D: -case 0x115E: -case 0x135E: -case 0x155E: -case 0x175E: -case 0x195E: -case 0x1B5E: -case 0x1D5E: -case 0x1F5E: - -// MOVEB -case 0x1158: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1398: -case 0x1598: -case 0x1798: -case 0x1998: -case 0x1B98: -case 0x1D98: -case 0x1F98: -case 0x1199: -case 0x1399: -case 0x1599: -case 0x1799: -case 0x1999: -case 0x1B99: -case 0x1D99: -case 0x1F99: -case 0x119A: -case 0x139A: -case 0x159A: -case 0x179A: -case 0x199A: -case 0x1B9A: -case 0x1D9A: -case 0x1F9A: -case 0x119B: -case 0x139B: -case 0x159B: -case 0x179B: -case 0x199B: -case 0x1B9B: -case 0x1D9B: -case 0x1F9B: -case 0x119C: -case 0x139C: -case 0x159C: -case 0x179C: -case 0x199C: -case 0x1B9C: -case 0x1D9C: -case 0x1F9C: -case 0x119D: -case 0x139D: -case 0x159D: -case 0x179D: -case 0x199D: -case 0x1B9D: -case 0x1D9D: -case 0x1F9D: -case 0x119E: -case 0x139E: -case 0x159E: -case 0x179E: -case 0x199E: -case 0x1B9E: -case 0x1D9E: -case 0x1F9E: - -// MOVEB -case 0x1198: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x11D9: -case 0x11DA: -case 0x11DB: -case 0x11DC: -case 0x11DD: -case 0x11DE: - -// MOVEB -case 0x11D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x13D9: -case 0x13DA: -case 0x13DB: -case 0x13DC: -case 0x13DD: -case 0x13DE: - -// MOVEB -case 0x13D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1ED9: -case 0x1EDA: -case 0x1EDB: -case 0x1EDC: -case 0x1EDD: -case 0x1EDE: - -// MOVEB -case 0x1ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1F19: -case 0x1F1A: -case 0x1F1B: -case 0x1F1C: -case 0x1F1D: -case 0x1F1E: - -// MOVEB -case 0x1F18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1220: -case 0x1420: -case 0x1620: -case 0x1820: -case 0x1A20: -case 0x1C20: -case 0x1E20: -case 0x1021: -case 0x1221: -case 0x1421: -case 0x1621: -case 0x1821: -case 0x1A21: -case 0x1C21: -case 0x1E21: -case 0x1022: -case 0x1222: -case 0x1422: -case 0x1622: -case 0x1822: -case 0x1A22: -case 0x1C22: -case 0x1E22: -case 0x1023: -case 0x1223: -case 0x1423: -case 0x1623: -case 0x1823: -case 0x1A23: -case 0x1C23: -case 0x1E23: -case 0x1024: -case 0x1224: -case 0x1424: -case 0x1624: -case 0x1824: -case 0x1A24: -case 0x1C24: -case 0x1E24: -case 0x1025: -case 0x1225: -case 0x1425: -case 0x1625: -case 0x1825: -case 0x1A25: -case 0x1C25: -case 0x1E25: -case 0x1026: -case 0x1226: -case 0x1426: -case 0x1626: -case 0x1826: -case 0x1A26: -case 0x1C26: -case 0x1E26: - -// MOVEB -case 0x1020: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x12A0: -case 0x14A0: -case 0x16A0: -case 0x18A0: -case 0x1AA0: -case 0x1CA0: -case 0x1EA0: -case 0x10A1: -case 0x12A1: -case 0x14A1: -case 0x16A1: -case 0x18A1: -case 0x1AA1: -case 0x1CA1: -case 0x1EA1: -case 0x10A2: -case 0x12A2: -case 0x14A2: -case 0x16A2: -case 0x18A2: -case 0x1AA2: -case 0x1CA2: -case 0x1EA2: -case 0x10A3: -case 0x12A3: -case 0x14A3: -case 0x16A3: -case 0x18A3: -case 0x1AA3: -case 0x1CA3: -case 0x1EA3: -case 0x10A4: -case 0x12A4: -case 0x14A4: -case 0x16A4: -case 0x18A4: -case 0x1AA4: -case 0x1CA4: -case 0x1EA4: -case 0x10A5: -case 0x12A5: -case 0x14A5: -case 0x16A5: -case 0x18A5: -case 0x1AA5: -case 0x1CA5: -case 0x1EA5: -case 0x10A6: -case 0x12A6: -case 0x14A6: -case 0x16A6: -case 0x18A6: -case 0x1AA6: -case 0x1CA6: -case 0x1EA6: - -// MOVEB -case 0x10A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x12E0: -case 0x14E0: -case 0x16E0: -case 0x18E0: -case 0x1AE0: -case 0x1CE0: -case 0x10E1: -case 0x12E1: -case 0x14E1: -case 0x16E1: -case 0x18E1: -case 0x1AE1: -case 0x1CE1: -case 0x10E2: -case 0x12E2: -case 0x14E2: -case 0x16E2: -case 0x18E2: -case 0x1AE2: -case 0x1CE2: -case 0x10E3: -case 0x12E3: -case 0x14E3: -case 0x16E3: -case 0x18E3: -case 0x1AE3: -case 0x1CE3: -case 0x10E4: -case 0x12E4: -case 0x14E4: -case 0x16E4: -case 0x18E4: -case 0x1AE4: -case 0x1CE4: -case 0x10E5: -case 0x12E5: -case 0x14E5: -case 0x16E5: -case 0x18E5: -case 0x1AE5: -case 0x1CE5: -case 0x10E6: -case 0x12E6: -case 0x14E6: -case 0x16E6: -case 0x18E6: -case 0x1AE6: -case 0x1CE6: - -// MOVEB -case 0x10E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1320: -case 0x1520: -case 0x1720: -case 0x1920: -case 0x1B20: -case 0x1D20: -case 0x1121: -case 0x1321: -case 0x1521: -case 0x1721: -case 0x1921: -case 0x1B21: -case 0x1D21: -case 0x1122: -case 0x1322: -case 0x1522: -case 0x1722: -case 0x1922: -case 0x1B22: -case 0x1D22: -case 0x1123: -case 0x1323: -case 0x1523: -case 0x1723: -case 0x1923: -case 0x1B23: -case 0x1D23: -case 0x1124: -case 0x1324: -case 0x1524: -case 0x1724: -case 0x1924: -case 0x1B24: -case 0x1D24: -case 0x1125: -case 0x1325: -case 0x1525: -case 0x1725: -case 0x1925: -case 0x1B25: -case 0x1D25: -case 0x1126: -case 0x1326: -case 0x1526: -case 0x1726: -case 0x1926: -case 0x1B26: -case 0x1D26: - -// MOVEB -case 0x1120: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1360: -case 0x1560: -case 0x1760: -case 0x1960: -case 0x1B60: -case 0x1D60: -case 0x1F60: -case 0x1161: -case 0x1361: -case 0x1561: -case 0x1761: -case 0x1961: -case 0x1B61: -case 0x1D61: -case 0x1F61: -case 0x1162: -case 0x1362: -case 0x1562: -case 0x1762: -case 0x1962: -case 0x1B62: -case 0x1D62: -case 0x1F62: -case 0x1163: -case 0x1363: -case 0x1563: -case 0x1763: -case 0x1963: -case 0x1B63: -case 0x1D63: -case 0x1F63: -case 0x1164: -case 0x1364: -case 0x1564: -case 0x1764: -case 0x1964: -case 0x1B64: -case 0x1D64: -case 0x1F64: -case 0x1165: -case 0x1365: -case 0x1565: -case 0x1765: -case 0x1965: -case 0x1B65: -case 0x1D65: -case 0x1F65: -case 0x1166: -case 0x1366: -case 0x1566: -case 0x1766: -case 0x1966: -case 0x1B66: -case 0x1D66: -case 0x1F66: - -// MOVEB -case 0x1160: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x13A0: -case 0x15A0: -case 0x17A0: -case 0x19A0: -case 0x1BA0: -case 0x1DA0: -case 0x1FA0: -case 0x11A1: -case 0x13A1: -case 0x15A1: -case 0x17A1: -case 0x19A1: -case 0x1BA1: -case 0x1DA1: -case 0x1FA1: -case 0x11A2: -case 0x13A2: -case 0x15A2: -case 0x17A2: -case 0x19A2: -case 0x1BA2: -case 0x1DA2: -case 0x1FA2: -case 0x11A3: -case 0x13A3: -case 0x15A3: -case 0x17A3: -case 0x19A3: -case 0x1BA3: -case 0x1DA3: -case 0x1FA3: -case 0x11A4: -case 0x13A4: -case 0x15A4: -case 0x17A4: -case 0x19A4: -case 0x1BA4: -case 0x1DA4: -case 0x1FA4: -case 0x11A5: -case 0x13A5: -case 0x15A5: -case 0x17A5: -case 0x19A5: -case 0x1BA5: -case 0x1DA5: -case 0x1FA5: -case 0x11A6: -case 0x13A6: -case 0x15A6: -case 0x17A6: -case 0x19A6: -case 0x1BA6: -case 0x1DA6: -case 0x1FA6: - -// MOVEB -case 0x11A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x11E1: -case 0x11E2: -case 0x11E3: -case 0x11E4: -case 0x11E5: -case 0x11E6: - -// MOVEB -case 0x11E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x13E1: -case 0x13E2: -case 0x13E3: -case 0x13E4: -case 0x13E5: -case 0x13E6: - -// MOVEB -case 0x13E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x1EE1: -case 0x1EE2: -case 0x1EE3: -case 0x1EE4: -case 0x1EE5: -case 0x1EE6: - -// MOVEB -case 0x1EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1F21: -case 0x1F22: -case 0x1F23: -case 0x1F24: -case 0x1F25: -case 0x1F26: - -// MOVEB -case 0x1F20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1228: -case 0x1428: -case 0x1628: -case 0x1828: -case 0x1A28: -case 0x1C28: -case 0x1E28: -case 0x1029: -case 0x1229: -case 0x1429: -case 0x1629: -case 0x1829: -case 0x1A29: -case 0x1C29: -case 0x1E29: -case 0x102A: -case 0x122A: -case 0x142A: -case 0x162A: -case 0x182A: -case 0x1A2A: -case 0x1C2A: -case 0x1E2A: -case 0x102B: -case 0x122B: -case 0x142B: -case 0x162B: -case 0x182B: -case 0x1A2B: -case 0x1C2B: -case 0x1E2B: -case 0x102C: -case 0x122C: -case 0x142C: -case 0x162C: -case 0x182C: -case 0x1A2C: -case 0x1C2C: -case 0x1E2C: -case 0x102D: -case 0x122D: -case 0x142D: -case 0x162D: -case 0x182D: -case 0x1A2D: -case 0x1C2D: -case 0x1E2D: -case 0x102E: -case 0x122E: -case 0x142E: -case 0x162E: -case 0x182E: -case 0x1A2E: -case 0x1C2E: -case 0x1E2E: -case 0x102F: -case 0x122F: -case 0x142F: -case 0x162F: -case 0x182F: -case 0x1A2F: -case 0x1C2F: -case 0x1E2F: - -// MOVEB -case 0x1028: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x12A8: -case 0x14A8: -case 0x16A8: -case 0x18A8: -case 0x1AA8: -case 0x1CA8: -case 0x1EA8: -case 0x10A9: -case 0x12A9: -case 0x14A9: -case 0x16A9: -case 0x18A9: -case 0x1AA9: -case 0x1CA9: -case 0x1EA9: -case 0x10AA: -case 0x12AA: -case 0x14AA: -case 0x16AA: -case 0x18AA: -case 0x1AAA: -case 0x1CAA: -case 0x1EAA: -case 0x10AB: -case 0x12AB: -case 0x14AB: -case 0x16AB: -case 0x18AB: -case 0x1AAB: -case 0x1CAB: -case 0x1EAB: -case 0x10AC: -case 0x12AC: -case 0x14AC: -case 0x16AC: -case 0x18AC: -case 0x1AAC: -case 0x1CAC: -case 0x1EAC: -case 0x10AD: -case 0x12AD: -case 0x14AD: -case 0x16AD: -case 0x18AD: -case 0x1AAD: -case 0x1CAD: -case 0x1EAD: -case 0x10AE: -case 0x12AE: -case 0x14AE: -case 0x16AE: -case 0x18AE: -case 0x1AAE: -case 0x1CAE: -case 0x1EAE: -case 0x10AF: -case 0x12AF: -case 0x14AF: -case 0x16AF: -case 0x18AF: -case 0x1AAF: -case 0x1CAF: -case 0x1EAF: - -// MOVEB -case 0x10A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x12E8: -case 0x14E8: -case 0x16E8: -case 0x18E8: -case 0x1AE8: -case 0x1CE8: -case 0x10E9: -case 0x12E9: -case 0x14E9: -case 0x16E9: -case 0x18E9: -case 0x1AE9: -case 0x1CE9: -case 0x10EA: -case 0x12EA: -case 0x14EA: -case 0x16EA: -case 0x18EA: -case 0x1AEA: -case 0x1CEA: -case 0x10EB: -case 0x12EB: -case 0x14EB: -case 0x16EB: -case 0x18EB: -case 0x1AEB: -case 0x1CEB: -case 0x10EC: -case 0x12EC: -case 0x14EC: -case 0x16EC: -case 0x18EC: -case 0x1AEC: -case 0x1CEC: -case 0x10ED: -case 0x12ED: -case 0x14ED: -case 0x16ED: -case 0x18ED: -case 0x1AED: -case 0x1CED: -case 0x10EE: -case 0x12EE: -case 0x14EE: -case 0x16EE: -case 0x18EE: -case 0x1AEE: -case 0x1CEE: -case 0x10EF: -case 0x12EF: -case 0x14EF: -case 0x16EF: -case 0x18EF: -case 0x1AEF: -case 0x1CEF: - -// MOVEB -case 0x10E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1328: -case 0x1528: -case 0x1728: -case 0x1928: -case 0x1B28: -case 0x1D28: -case 0x1129: -case 0x1329: -case 0x1529: -case 0x1729: -case 0x1929: -case 0x1B29: -case 0x1D29: -case 0x112A: -case 0x132A: -case 0x152A: -case 0x172A: -case 0x192A: -case 0x1B2A: -case 0x1D2A: -case 0x112B: -case 0x132B: -case 0x152B: -case 0x172B: -case 0x192B: -case 0x1B2B: -case 0x1D2B: -case 0x112C: -case 0x132C: -case 0x152C: -case 0x172C: -case 0x192C: -case 0x1B2C: -case 0x1D2C: -case 0x112D: -case 0x132D: -case 0x152D: -case 0x172D: -case 0x192D: -case 0x1B2D: -case 0x1D2D: -case 0x112E: -case 0x132E: -case 0x152E: -case 0x172E: -case 0x192E: -case 0x1B2E: -case 0x1D2E: -case 0x112F: -case 0x132F: -case 0x152F: -case 0x172F: -case 0x192F: -case 0x1B2F: -case 0x1D2F: - -// MOVEB -case 0x1128: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1368: -case 0x1568: -case 0x1768: -case 0x1968: -case 0x1B68: -case 0x1D68: -case 0x1F68: -case 0x1169: -case 0x1369: -case 0x1569: -case 0x1769: -case 0x1969: -case 0x1B69: -case 0x1D69: -case 0x1F69: -case 0x116A: -case 0x136A: -case 0x156A: -case 0x176A: -case 0x196A: -case 0x1B6A: -case 0x1D6A: -case 0x1F6A: -case 0x116B: -case 0x136B: -case 0x156B: -case 0x176B: -case 0x196B: -case 0x1B6B: -case 0x1D6B: -case 0x1F6B: -case 0x116C: -case 0x136C: -case 0x156C: -case 0x176C: -case 0x196C: -case 0x1B6C: -case 0x1D6C: -case 0x1F6C: -case 0x116D: -case 0x136D: -case 0x156D: -case 0x176D: -case 0x196D: -case 0x1B6D: -case 0x1D6D: -case 0x1F6D: -case 0x116E: -case 0x136E: -case 0x156E: -case 0x176E: -case 0x196E: -case 0x1B6E: -case 0x1D6E: -case 0x1F6E: -case 0x116F: -case 0x136F: -case 0x156F: -case 0x176F: -case 0x196F: -case 0x1B6F: -case 0x1D6F: -case 0x1F6F: - -// MOVEB -case 0x1168: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13A8: -case 0x15A8: -case 0x17A8: -case 0x19A8: -case 0x1BA8: -case 0x1DA8: -case 0x1FA8: -case 0x11A9: -case 0x13A9: -case 0x15A9: -case 0x17A9: -case 0x19A9: -case 0x1BA9: -case 0x1DA9: -case 0x1FA9: -case 0x11AA: -case 0x13AA: -case 0x15AA: -case 0x17AA: -case 0x19AA: -case 0x1BAA: -case 0x1DAA: -case 0x1FAA: -case 0x11AB: -case 0x13AB: -case 0x15AB: -case 0x17AB: -case 0x19AB: -case 0x1BAB: -case 0x1DAB: -case 0x1FAB: -case 0x11AC: -case 0x13AC: -case 0x15AC: -case 0x17AC: -case 0x19AC: -case 0x1BAC: -case 0x1DAC: -case 0x1FAC: -case 0x11AD: -case 0x13AD: -case 0x15AD: -case 0x17AD: -case 0x19AD: -case 0x1BAD: -case 0x1DAD: -case 0x1FAD: -case 0x11AE: -case 0x13AE: -case 0x15AE: -case 0x17AE: -case 0x19AE: -case 0x1BAE: -case 0x1DAE: -case 0x1FAE: -case 0x11AF: -case 0x13AF: -case 0x15AF: -case 0x17AF: -case 0x19AF: -case 0x1BAF: -case 0x1DAF: -case 0x1FAF: - -// MOVEB -case 0x11A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x11E9: -case 0x11EA: -case 0x11EB: -case 0x11EC: -case 0x11ED: -case 0x11EE: -case 0x11EF: - -// MOVEB -case 0x11E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13E9: -case 0x13EA: -case 0x13EB: -case 0x13EC: -case 0x13ED: -case 0x13EE: -case 0x13EF: - -// MOVEB -case 0x13E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) -case 0x1EE9: -case 0x1EEA: -case 0x1EEB: -case 0x1EEC: -case 0x1EED: -case 0x1EEE: -case 0x1EEF: - -// MOVEB -case 0x1EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1F29: -case 0x1F2A: -case 0x1F2B: -case 0x1F2C: -case 0x1F2D: -case 0x1F2E: -case 0x1F2F: - -// MOVEB -case 0x1F28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1230: -case 0x1430: -case 0x1630: -case 0x1830: -case 0x1A30: -case 0x1C30: -case 0x1E30: -case 0x1031: -case 0x1231: -case 0x1431: -case 0x1631: -case 0x1831: -case 0x1A31: -case 0x1C31: -case 0x1E31: -case 0x1032: -case 0x1232: -case 0x1432: -case 0x1632: -case 0x1832: -case 0x1A32: -case 0x1C32: -case 0x1E32: -case 0x1033: -case 0x1233: -case 0x1433: -case 0x1633: -case 0x1833: -case 0x1A33: -case 0x1C33: -case 0x1E33: -case 0x1034: -case 0x1234: -case 0x1434: -case 0x1634: -case 0x1834: -case 0x1A34: -case 0x1C34: -case 0x1E34: -case 0x1035: -case 0x1235: -case 0x1435: -case 0x1635: -case 0x1835: -case 0x1A35: -case 0x1C35: -case 0x1E35: -case 0x1036: -case 0x1236: -case 0x1436: -case 0x1636: -case 0x1836: -case 0x1A36: -case 0x1C36: -case 0x1E36: -case 0x1037: -case 0x1237: -case 0x1437: -case 0x1637: -case 0x1837: -case 0x1A37: -case 0x1C37: -case 0x1E37: - -// MOVEB -case 0x1030: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x12B0: -case 0x14B0: -case 0x16B0: -case 0x18B0: -case 0x1AB0: -case 0x1CB0: -case 0x1EB0: -case 0x10B1: -case 0x12B1: -case 0x14B1: -case 0x16B1: -case 0x18B1: -case 0x1AB1: -case 0x1CB1: -case 0x1EB1: -case 0x10B2: -case 0x12B2: -case 0x14B2: -case 0x16B2: -case 0x18B2: -case 0x1AB2: -case 0x1CB2: -case 0x1EB2: -case 0x10B3: -case 0x12B3: -case 0x14B3: -case 0x16B3: -case 0x18B3: -case 0x1AB3: -case 0x1CB3: -case 0x1EB3: -case 0x10B4: -case 0x12B4: -case 0x14B4: -case 0x16B4: -case 0x18B4: -case 0x1AB4: -case 0x1CB4: -case 0x1EB4: -case 0x10B5: -case 0x12B5: -case 0x14B5: -case 0x16B5: -case 0x18B5: -case 0x1AB5: -case 0x1CB5: -case 0x1EB5: -case 0x10B6: -case 0x12B6: -case 0x14B6: -case 0x16B6: -case 0x18B6: -case 0x1AB6: -case 0x1CB6: -case 0x1EB6: -case 0x10B7: -case 0x12B7: -case 0x14B7: -case 0x16B7: -case 0x18B7: -case 0x1AB7: -case 0x1CB7: -case 0x1EB7: - -// MOVEB -case 0x10B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x12F0: -case 0x14F0: -case 0x16F0: -case 0x18F0: -case 0x1AF0: -case 0x1CF0: -case 0x10F1: -case 0x12F1: -case 0x14F1: -case 0x16F1: -case 0x18F1: -case 0x1AF1: -case 0x1CF1: -case 0x10F2: -case 0x12F2: -case 0x14F2: -case 0x16F2: -case 0x18F2: -case 0x1AF2: -case 0x1CF2: -case 0x10F3: -case 0x12F3: -case 0x14F3: -case 0x16F3: -case 0x18F3: -case 0x1AF3: -case 0x1CF3: -case 0x10F4: -case 0x12F4: -case 0x14F4: -case 0x16F4: -case 0x18F4: -case 0x1AF4: -case 0x1CF4: -case 0x10F5: -case 0x12F5: -case 0x14F5: -case 0x16F5: -case 0x18F5: -case 0x1AF5: -case 0x1CF5: -case 0x10F6: -case 0x12F6: -case 0x14F6: -case 0x16F6: -case 0x18F6: -case 0x1AF6: -case 0x1CF6: -case 0x10F7: -case 0x12F7: -case 0x14F7: -case 0x16F7: -case 0x18F7: -case 0x1AF7: -case 0x1CF7: - -// MOVEB -case 0x10F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1330: -case 0x1530: -case 0x1730: -case 0x1930: -case 0x1B30: -case 0x1D30: -case 0x1131: -case 0x1331: -case 0x1531: -case 0x1731: -case 0x1931: -case 0x1B31: -case 0x1D31: -case 0x1132: -case 0x1332: -case 0x1532: -case 0x1732: -case 0x1932: -case 0x1B32: -case 0x1D32: -case 0x1133: -case 0x1333: -case 0x1533: -case 0x1733: -case 0x1933: -case 0x1B33: -case 0x1D33: -case 0x1134: -case 0x1334: -case 0x1534: -case 0x1734: -case 0x1934: -case 0x1B34: -case 0x1D34: -case 0x1135: -case 0x1335: -case 0x1535: -case 0x1735: -case 0x1935: -case 0x1B35: -case 0x1D35: -case 0x1136: -case 0x1336: -case 0x1536: -case 0x1736: -case 0x1936: -case 0x1B36: -case 0x1D36: -case 0x1137: -case 0x1337: -case 0x1537: -case 0x1737: -case 0x1937: -case 0x1B37: -case 0x1D37: - -// MOVEB -case 0x1130: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1370: -case 0x1570: -case 0x1770: -case 0x1970: -case 0x1B70: -case 0x1D70: -case 0x1F70: -case 0x1171: -case 0x1371: -case 0x1571: -case 0x1771: -case 0x1971: -case 0x1B71: -case 0x1D71: -case 0x1F71: -case 0x1172: -case 0x1372: -case 0x1572: -case 0x1772: -case 0x1972: -case 0x1B72: -case 0x1D72: -case 0x1F72: -case 0x1173: -case 0x1373: -case 0x1573: -case 0x1773: -case 0x1973: -case 0x1B73: -case 0x1D73: -case 0x1F73: -case 0x1174: -case 0x1374: -case 0x1574: -case 0x1774: -case 0x1974: -case 0x1B74: -case 0x1D74: -case 0x1F74: -case 0x1175: -case 0x1375: -case 0x1575: -case 0x1775: -case 0x1975: -case 0x1B75: -case 0x1D75: -case 0x1F75: -case 0x1176: -case 0x1376: -case 0x1576: -case 0x1776: -case 0x1976: -case 0x1B76: -case 0x1D76: -case 0x1F76: -case 0x1177: -case 0x1377: -case 0x1577: -case 0x1777: -case 0x1977: -case 0x1B77: -case 0x1D77: -case 0x1F77: - -// MOVEB -case 0x1170: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x13B0: -case 0x15B0: -case 0x17B0: -case 0x19B0: -case 0x1BB0: -case 0x1DB0: -case 0x1FB0: -case 0x11B1: -case 0x13B1: -case 0x15B1: -case 0x17B1: -case 0x19B1: -case 0x1BB1: -case 0x1DB1: -case 0x1FB1: -case 0x11B2: -case 0x13B2: -case 0x15B2: -case 0x17B2: -case 0x19B2: -case 0x1BB2: -case 0x1DB2: -case 0x1FB2: -case 0x11B3: -case 0x13B3: -case 0x15B3: -case 0x17B3: -case 0x19B3: -case 0x1BB3: -case 0x1DB3: -case 0x1FB3: -case 0x11B4: -case 0x13B4: -case 0x15B4: -case 0x17B4: -case 0x19B4: -case 0x1BB4: -case 0x1DB4: -case 0x1FB4: -case 0x11B5: -case 0x13B5: -case 0x15B5: -case 0x17B5: -case 0x19B5: -case 0x1BB5: -case 0x1DB5: -case 0x1FB5: -case 0x11B6: -case 0x13B6: -case 0x15B6: -case 0x17B6: -case 0x19B6: -case 0x1BB6: -case 0x1DB6: -case 0x1FB6: -case 0x11B7: -case 0x13B7: -case 0x15B7: -case 0x17B7: -case 0x19B7: -case 0x1BB7: -case 0x1DB7: -case 0x1FB7: - -// MOVEB -case 0x11B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) -case 0x11F1: -case 0x11F2: -case 0x11F3: -case 0x11F4: -case 0x11F5: -case 0x11F6: -case 0x11F7: - -// MOVEB -case 0x11F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x13F1: -case 0x13F2: -case 0x13F3: -case 0x13F4: -case 0x13F5: -case 0x13F6: -case 0x13F7: - -// MOVEB -case 0x13F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(26) -case 0x1EF1: -case 0x1EF2: -case 0x1EF3: -case 0x1EF4: -case 0x1EF5: -case 0x1EF6: -case 0x1EF7: - -// MOVEB -case 0x1EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1F31: -case 0x1F32: -case 0x1F33: -case 0x1F34: -case 0x1F35: -case 0x1F36: -case 0x1F37: - -// MOVEB -case 0x1F30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1238: -case 0x1438: -case 0x1638: -case 0x1838: -case 0x1A38: -case 0x1C38: -case 0x1E38: - -// MOVEB -case 0x1038: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x12B8: -case 0x14B8: -case 0x16B8: -case 0x18B8: -case 0x1AB8: -case 0x1CB8: -case 0x1EB8: - -// MOVEB -case 0x10B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x12F8: -case 0x14F8: -case 0x16F8: -case 0x18F8: -case 0x1AF8: -case 0x1CF8: - -// MOVEB -case 0x10F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1338: -case 0x1538: -case 0x1738: -case 0x1938: -case 0x1B38: -case 0x1D38: - -// MOVEB -case 0x1138: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1378: -case 0x1578: -case 0x1778: -case 0x1978: -case 0x1B78: -case 0x1D78: -case 0x1F78: - -// MOVEB -case 0x1178: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13B8: -case 0x15B8: -case 0x17B8: -case 0x19B8: -case 0x1BB8: -case 0x1DB8: -case 0x1FB8: - -// MOVEB -case 0x11B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x11F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x13F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x1EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x1F38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1239: -case 0x1439: -case 0x1639: -case 0x1839: -case 0x1A39: -case 0x1C39: -case 0x1E39: - -// MOVEB -case 0x1039: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x12B9: -case 0x14B9: -case 0x16B9: -case 0x18B9: -case 0x1AB9: -case 0x1CB9: -case 0x1EB9: - -// MOVEB -case 0x10B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x12F9: -case 0x14F9: -case 0x16F9: -case 0x18F9: -case 0x1AF9: -case 0x1CF9: - -// MOVEB -case 0x10F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1339: -case 0x1539: -case 0x1739: -case 0x1939: -case 0x1B39: -case 0x1D39: - -// MOVEB -case 0x1139: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1379: -case 0x1579: -case 0x1779: -case 0x1979: -case 0x1B79: -case 0x1D79: -case 0x1F79: - -// MOVEB -case 0x1179: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) -case 0x13B9: -case 0x15B9: -case 0x17B9: -case 0x19B9: -case 0x1BB9: -case 0x1DB9: -case 0x1FB9: - -// MOVEB -case 0x11B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(26) - -// MOVEB -case 0x11F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x13F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(28) - -// MOVEB -case 0x1EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x1F39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x123A: -case 0x143A: -case 0x163A: -case 0x183A: -case 0x1A3A: -case 0x1C3A: -case 0x1E3A: - -// MOVEB -case 0x103A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x12BA: -case 0x14BA: -case 0x16BA: -case 0x18BA: -case 0x1ABA: -case 0x1CBA: -case 0x1EBA: - -// MOVEB -case 0x10BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x12FA: -case 0x14FA: -case 0x16FA: -case 0x18FA: -case 0x1AFA: -case 0x1CFA: - -// MOVEB -case 0x10FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x133A: -case 0x153A: -case 0x173A: -case 0x193A: -case 0x1B3A: -case 0x1D3A: - -// MOVEB -case 0x113A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x137A: -case 0x157A: -case 0x177A: -case 0x197A: -case 0x1B7A: -case 0x1D7A: -case 0x1F7A: - -// MOVEB -case 0x117A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13BA: -case 0x15BA: -case 0x17BA: -case 0x19BA: -case 0x1BBA: -case 0x1DBA: -case 0x1FBA: - -// MOVEB -case 0x11BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x11FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x13FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x1EFA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x1F3A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x123B: -case 0x143B: -case 0x163B: -case 0x183B: -case 0x1A3B: -case 0x1C3B: -case 0x1E3B: - -// MOVEB -case 0x103B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x12BB: -case 0x14BB: -case 0x16BB: -case 0x18BB: -case 0x1ABB: -case 0x1CBB: -case 0x1EBB: - -// MOVEB -case 0x10BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x12FB: -case 0x14FB: -case 0x16FB: -case 0x18FB: -case 0x1AFB: -case 0x1CFB: - -// MOVEB -case 0x10FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x133B: -case 0x153B: -case 0x173B: -case 0x193B: -case 0x1B3B: -case 0x1D3B: - -// MOVEB -case 0x113B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x137B: -case 0x157B: -case 0x177B: -case 0x197B: -case 0x1B7B: -case 0x1D7B: -case 0x1F7B: - -// MOVEB -case 0x117B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x13BB: -case 0x15BB: -case 0x17BB: -case 0x19BB: -case 0x1BBB: -case 0x1DBB: -case 0x1FBB: - -// MOVEB -case 0x11BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x11FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x13FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(26) - -// MOVEB -case 0x1EFB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x1F3B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x123C: -case 0x143C: -case 0x163C: -case 0x183C: -case 0x1A3C: -case 0x1C3C: -case 0x1E3C: - -// MOVEB -case 0x103C: -{ - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x12BC: -case 0x14BC: -case 0x16BC: -case 0x18BC: -case 0x1ABC: -case 0x1CBC: -case 0x1EBC: - -// MOVEB -case 0x10BC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12FC: -case 0x14FC: -case 0x16FC: -case 0x18FC: -case 0x1AFC: -case 0x1CFC: - -// MOVEB -case 0x10FC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x133C: -case 0x153C: -case 0x173C: -case 0x193C: -case 0x1B3C: -case 0x1D3C: - -// MOVEB -case 0x113C: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x137C: -case 0x157C: -case 0x177C: -case 0x197C: -case 0x1B7C: -case 0x1D7C: -case 0x1F7C: - -// MOVEB -case 0x117C: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x13BC: -case 0x15BC: -case 0x17BC: -case 0x19BC: -case 0x1BBC: -case 0x1DBC: -case 0x1FBC: - -// MOVEB -case 0x11BC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x11FC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x13FC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x1EFC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// MOVEB -case 0x1F3C: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x121F: -case 0x141F: -case 0x161F: -case 0x181F: -case 0x1A1F: -case 0x1C1F: -case 0x1E1F: - -// MOVEB -case 0x101F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x129F: -case 0x149F: -case 0x169F: -case 0x189F: -case 0x1A9F: -case 0x1C9F: -case 0x1E9F: - -// MOVEB -case 0x109F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12DF: -case 0x14DF: -case 0x16DF: -case 0x18DF: -case 0x1ADF: -case 0x1CDF: - -// MOVEB -case 0x10DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x131F: -case 0x151F: -case 0x171F: -case 0x191F: -case 0x1B1F: -case 0x1D1F: - -// MOVEB -case 0x111F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x135F: -case 0x155F: -case 0x175F: -case 0x195F: -case 0x1B5F: -case 0x1D5F: -case 0x1F5F: - -// MOVEB -case 0x115F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x139F: -case 0x159F: -case 0x179F: -case 0x199F: -case 0x1B9F: -case 0x1D9F: -case 0x1F9F: - -// MOVEB -case 0x119F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x11DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x13DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x1EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// MOVEB -case 0x1F1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1227: -case 0x1427: -case 0x1627: -case 0x1827: -case 0x1A27: -case 0x1C27: -case 0x1E27: - -// MOVEB -case 0x1027: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x12A7: -case 0x14A7: -case 0x16A7: -case 0x18A7: -case 0x1AA7: -case 0x1CA7: -case 0x1EA7: - -// MOVEB -case 0x10A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x12E7: -case 0x14E7: -case 0x16E7: -case 0x18E7: -case 0x1AE7: -case 0x1CE7: - -// MOVEB -case 0x10E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1327: -case 0x1527: -case 0x1727: -case 0x1927: -case 0x1B27: -case 0x1D27: - -// MOVEB -case 0x1127: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1367: -case 0x1567: -case 0x1767: -case 0x1967: -case 0x1B67: -case 0x1D67: -case 0x1F67: - -// MOVEB -case 0x1167: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x13A7: -case 0x15A7: -case 0x17A7: -case 0x19A7: -case 0x1BA7: -case 0x1DA7: -case 0x1FA7: - -// MOVEB -case 0x11A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x11E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x13E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x1EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) - -// MOVEB -case 0x1F27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) diff --git a/yabause/src/c68k/c68k_op2.inc b/yabause/src/c68k/c68k_op2.inc deleted file mode 100644 index 3228cd2dc4..0000000000 --- a/yabause/src/c68k/c68k_op2.inc +++ /dev/null @@ -1,6254 +0,0 @@ -case 0x2200: -case 0x2400: -case 0x2600: -case 0x2800: -case 0x2A00: -case 0x2C00: -case 0x2E00: -case 0x2001: -case 0x2201: -case 0x2401: -case 0x2601: -case 0x2801: -case 0x2A01: -case 0x2C01: -case 0x2E01: -case 0x2002: -case 0x2202: -case 0x2402: -case 0x2602: -case 0x2802: -case 0x2A02: -case 0x2C02: -case 0x2E02: -case 0x2003: -case 0x2203: -case 0x2403: -case 0x2603: -case 0x2803: -case 0x2A03: -case 0x2C03: -case 0x2E03: -case 0x2004: -case 0x2204: -case 0x2404: -case 0x2604: -case 0x2804: -case 0x2A04: -case 0x2C04: -case 0x2E04: -case 0x2005: -case 0x2205: -case 0x2405: -case 0x2605: -case 0x2805: -case 0x2A05: -case 0x2C05: -case 0x2E05: -case 0x2006: -case 0x2206: -case 0x2406: -case 0x2606: -case 0x2806: -case 0x2A06: -case 0x2C06: -case 0x2E06: -case 0x2007: -case 0x2207: -case 0x2407: -case 0x2607: -case 0x2807: -case 0x2A07: -case 0x2C07: -case 0x2E07: - -// MOVEL -case 0x2000: -{ - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x2280: -case 0x2480: -case 0x2680: -case 0x2880: -case 0x2A80: -case 0x2C80: -case 0x2E80: -case 0x2081: -case 0x2281: -case 0x2481: -case 0x2681: -case 0x2881: -case 0x2A81: -case 0x2C81: -case 0x2E81: -case 0x2082: -case 0x2282: -case 0x2482: -case 0x2682: -case 0x2882: -case 0x2A82: -case 0x2C82: -case 0x2E82: -case 0x2083: -case 0x2283: -case 0x2483: -case 0x2683: -case 0x2883: -case 0x2A83: -case 0x2C83: -case 0x2E83: -case 0x2084: -case 0x2284: -case 0x2484: -case 0x2684: -case 0x2884: -case 0x2A84: -case 0x2C84: -case 0x2E84: -case 0x2085: -case 0x2285: -case 0x2485: -case 0x2685: -case 0x2885: -case 0x2A85: -case 0x2C85: -case 0x2E85: -case 0x2086: -case 0x2286: -case 0x2486: -case 0x2686: -case 0x2886: -case 0x2A86: -case 0x2C86: -case 0x2E86: -case 0x2087: -case 0x2287: -case 0x2487: -case 0x2687: -case 0x2887: -case 0x2A87: -case 0x2C87: -case 0x2E87: - -// MOVEL -case 0x2080: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x22C0: -case 0x24C0: -case 0x26C0: -case 0x28C0: -case 0x2AC0: -case 0x2CC0: -case 0x20C1: -case 0x22C1: -case 0x24C1: -case 0x26C1: -case 0x28C1: -case 0x2AC1: -case 0x2CC1: -case 0x20C2: -case 0x22C2: -case 0x24C2: -case 0x26C2: -case 0x28C2: -case 0x2AC2: -case 0x2CC2: -case 0x20C3: -case 0x22C3: -case 0x24C3: -case 0x26C3: -case 0x28C3: -case 0x2AC3: -case 0x2CC3: -case 0x20C4: -case 0x22C4: -case 0x24C4: -case 0x26C4: -case 0x28C4: -case 0x2AC4: -case 0x2CC4: -case 0x20C5: -case 0x22C5: -case 0x24C5: -case 0x26C5: -case 0x28C5: -case 0x2AC5: -case 0x2CC5: -case 0x20C6: -case 0x22C6: -case 0x24C6: -case 0x26C6: -case 0x28C6: -case 0x2AC6: -case 0x2CC6: -case 0x20C7: -case 0x22C7: -case 0x24C7: -case 0x26C7: -case 0x28C7: -case 0x2AC7: -case 0x2CC7: - -// MOVEL -case 0x20C0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2300: -case 0x2500: -case 0x2700: -case 0x2900: -case 0x2B00: -case 0x2D00: -case 0x2101: -case 0x2301: -case 0x2501: -case 0x2701: -case 0x2901: -case 0x2B01: -case 0x2D01: -case 0x2102: -case 0x2302: -case 0x2502: -case 0x2702: -case 0x2902: -case 0x2B02: -case 0x2D02: -case 0x2103: -case 0x2303: -case 0x2503: -case 0x2703: -case 0x2903: -case 0x2B03: -case 0x2D03: -case 0x2104: -case 0x2304: -case 0x2504: -case 0x2704: -case 0x2904: -case 0x2B04: -case 0x2D04: -case 0x2105: -case 0x2305: -case 0x2505: -case 0x2705: -case 0x2905: -case 0x2B05: -case 0x2D05: -case 0x2106: -case 0x2306: -case 0x2506: -case 0x2706: -case 0x2906: -case 0x2B06: -case 0x2D06: -case 0x2107: -case 0x2307: -case 0x2507: -case 0x2707: -case 0x2907: -case 0x2B07: -case 0x2D07: - -// MOVEL -case 0x2100: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2340: -case 0x2540: -case 0x2740: -case 0x2940: -case 0x2B40: -case 0x2D40: -case 0x2F40: -case 0x2141: -case 0x2341: -case 0x2541: -case 0x2741: -case 0x2941: -case 0x2B41: -case 0x2D41: -case 0x2F41: -case 0x2142: -case 0x2342: -case 0x2542: -case 0x2742: -case 0x2942: -case 0x2B42: -case 0x2D42: -case 0x2F42: -case 0x2143: -case 0x2343: -case 0x2543: -case 0x2743: -case 0x2943: -case 0x2B43: -case 0x2D43: -case 0x2F43: -case 0x2144: -case 0x2344: -case 0x2544: -case 0x2744: -case 0x2944: -case 0x2B44: -case 0x2D44: -case 0x2F44: -case 0x2145: -case 0x2345: -case 0x2545: -case 0x2745: -case 0x2945: -case 0x2B45: -case 0x2D45: -case 0x2F45: -case 0x2146: -case 0x2346: -case 0x2546: -case 0x2746: -case 0x2946: -case 0x2B46: -case 0x2D46: -case 0x2F46: -case 0x2147: -case 0x2347: -case 0x2547: -case 0x2747: -case 0x2947: -case 0x2B47: -case 0x2D47: -case 0x2F47: - -// MOVEL -case 0x2140: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x2380: -case 0x2580: -case 0x2780: -case 0x2980: -case 0x2B80: -case 0x2D80: -case 0x2F80: -case 0x2181: -case 0x2381: -case 0x2581: -case 0x2781: -case 0x2981: -case 0x2B81: -case 0x2D81: -case 0x2F81: -case 0x2182: -case 0x2382: -case 0x2582: -case 0x2782: -case 0x2982: -case 0x2B82: -case 0x2D82: -case 0x2F82: -case 0x2183: -case 0x2383: -case 0x2583: -case 0x2783: -case 0x2983: -case 0x2B83: -case 0x2D83: -case 0x2F83: -case 0x2184: -case 0x2384: -case 0x2584: -case 0x2784: -case 0x2984: -case 0x2B84: -case 0x2D84: -case 0x2F84: -case 0x2185: -case 0x2385: -case 0x2585: -case 0x2785: -case 0x2985: -case 0x2B85: -case 0x2D85: -case 0x2F85: -case 0x2186: -case 0x2386: -case 0x2586: -case 0x2786: -case 0x2986: -case 0x2B86: -case 0x2D86: -case 0x2F86: -case 0x2187: -case 0x2387: -case 0x2587: -case 0x2787: -case 0x2987: -case 0x2B87: -case 0x2D87: -case 0x2F87: - -// MOVEL -case 0x2180: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(18) -case 0x21C1: -case 0x21C2: -case 0x21C3: -case 0x21C4: -case 0x21C5: -case 0x21C6: -case 0x21C7: - -// MOVEL -case 0x21C0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x23C1: -case 0x23C2: -case 0x23C3: -case 0x23C4: -case 0x23C5: -case 0x23C6: -case 0x23C7: - -// MOVEL -case 0x23C0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2EC1: -case 0x2EC2: -case 0x2EC3: -case 0x2EC4: -case 0x2EC5: -case 0x2EC6: -case 0x2EC7: - -// MOVEL -case 0x2EC0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2F01: -case 0x2F02: -case 0x2F03: -case 0x2F04: -case 0x2F05: -case 0x2F06: -case 0x2F07: - -// MOVEL -case 0x2F00: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2208: -case 0x2408: -case 0x2608: -case 0x2808: -case 0x2A08: -case 0x2C08: -case 0x2E08: -case 0x2009: -case 0x2209: -case 0x2409: -case 0x2609: -case 0x2809: -case 0x2A09: -case 0x2C09: -case 0x2E09: -case 0x200A: -case 0x220A: -case 0x240A: -case 0x260A: -case 0x280A: -case 0x2A0A: -case 0x2C0A: -case 0x2E0A: -case 0x200B: -case 0x220B: -case 0x240B: -case 0x260B: -case 0x280B: -case 0x2A0B: -case 0x2C0B: -case 0x2E0B: -case 0x200C: -case 0x220C: -case 0x240C: -case 0x260C: -case 0x280C: -case 0x2A0C: -case 0x2C0C: -case 0x2E0C: -case 0x200D: -case 0x220D: -case 0x240D: -case 0x260D: -case 0x280D: -case 0x2A0D: -case 0x2C0D: -case 0x2E0D: -case 0x200E: -case 0x220E: -case 0x240E: -case 0x260E: -case 0x280E: -case 0x2A0E: -case 0x2C0E: -case 0x2E0E: -case 0x200F: -case 0x220F: -case 0x240F: -case 0x260F: -case 0x280F: -case 0x2A0F: -case 0x2C0F: -case 0x2E0F: - -// MOVEL -case 0x2008: -{ - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x2288: -case 0x2488: -case 0x2688: -case 0x2888: -case 0x2A88: -case 0x2C88: -case 0x2E88: -case 0x2089: -case 0x2289: -case 0x2489: -case 0x2689: -case 0x2889: -case 0x2A89: -case 0x2C89: -case 0x2E89: -case 0x208A: -case 0x228A: -case 0x248A: -case 0x268A: -case 0x288A: -case 0x2A8A: -case 0x2C8A: -case 0x2E8A: -case 0x208B: -case 0x228B: -case 0x248B: -case 0x268B: -case 0x288B: -case 0x2A8B: -case 0x2C8B: -case 0x2E8B: -case 0x208C: -case 0x228C: -case 0x248C: -case 0x268C: -case 0x288C: -case 0x2A8C: -case 0x2C8C: -case 0x2E8C: -case 0x208D: -case 0x228D: -case 0x248D: -case 0x268D: -case 0x288D: -case 0x2A8D: -case 0x2C8D: -case 0x2E8D: -case 0x208E: -case 0x228E: -case 0x248E: -case 0x268E: -case 0x288E: -case 0x2A8E: -case 0x2C8E: -case 0x2E8E: -case 0x208F: -case 0x228F: -case 0x248F: -case 0x268F: -case 0x288F: -case 0x2A8F: -case 0x2C8F: -case 0x2E8F: - -// MOVEL -case 0x2088: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x22C8: -case 0x24C8: -case 0x26C8: -case 0x28C8: -case 0x2AC8: -case 0x2CC8: -case 0x20C9: -case 0x22C9: -case 0x24C9: -case 0x26C9: -case 0x28C9: -case 0x2AC9: -case 0x2CC9: -case 0x20CA: -case 0x22CA: -case 0x24CA: -case 0x26CA: -case 0x28CA: -case 0x2ACA: -case 0x2CCA: -case 0x20CB: -case 0x22CB: -case 0x24CB: -case 0x26CB: -case 0x28CB: -case 0x2ACB: -case 0x2CCB: -case 0x20CC: -case 0x22CC: -case 0x24CC: -case 0x26CC: -case 0x28CC: -case 0x2ACC: -case 0x2CCC: -case 0x20CD: -case 0x22CD: -case 0x24CD: -case 0x26CD: -case 0x28CD: -case 0x2ACD: -case 0x2CCD: -case 0x20CE: -case 0x22CE: -case 0x24CE: -case 0x26CE: -case 0x28CE: -case 0x2ACE: -case 0x2CCE: -case 0x20CF: -case 0x22CF: -case 0x24CF: -case 0x26CF: -case 0x28CF: -case 0x2ACF: -case 0x2CCF: - -// MOVEL -case 0x20C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2308: -case 0x2508: -case 0x2708: -case 0x2908: -case 0x2B08: -case 0x2D08: -case 0x2109: -case 0x2309: -case 0x2509: -case 0x2709: -case 0x2909: -case 0x2B09: -case 0x2D09: -case 0x210A: -case 0x230A: -case 0x250A: -case 0x270A: -case 0x290A: -case 0x2B0A: -case 0x2D0A: -case 0x210B: -case 0x230B: -case 0x250B: -case 0x270B: -case 0x290B: -case 0x2B0B: -case 0x2D0B: -case 0x210C: -case 0x230C: -case 0x250C: -case 0x270C: -case 0x290C: -case 0x2B0C: -case 0x2D0C: -case 0x210D: -case 0x230D: -case 0x250D: -case 0x270D: -case 0x290D: -case 0x2B0D: -case 0x2D0D: -case 0x210E: -case 0x230E: -case 0x250E: -case 0x270E: -case 0x290E: -case 0x2B0E: -case 0x2D0E: -case 0x210F: -case 0x230F: -case 0x250F: -case 0x270F: -case 0x290F: -case 0x2B0F: -case 0x2D0F: - -// MOVEL -case 0x2108: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2348: -case 0x2548: -case 0x2748: -case 0x2948: -case 0x2B48: -case 0x2D48: -case 0x2F48: -case 0x2149: -case 0x2349: -case 0x2549: -case 0x2749: -case 0x2949: -case 0x2B49: -case 0x2D49: -case 0x2F49: -case 0x214A: -case 0x234A: -case 0x254A: -case 0x274A: -case 0x294A: -case 0x2B4A: -case 0x2D4A: -case 0x2F4A: -case 0x214B: -case 0x234B: -case 0x254B: -case 0x274B: -case 0x294B: -case 0x2B4B: -case 0x2D4B: -case 0x2F4B: -case 0x214C: -case 0x234C: -case 0x254C: -case 0x274C: -case 0x294C: -case 0x2B4C: -case 0x2D4C: -case 0x2F4C: -case 0x214D: -case 0x234D: -case 0x254D: -case 0x274D: -case 0x294D: -case 0x2B4D: -case 0x2D4D: -case 0x2F4D: -case 0x214E: -case 0x234E: -case 0x254E: -case 0x274E: -case 0x294E: -case 0x2B4E: -case 0x2D4E: -case 0x2F4E: -case 0x214F: -case 0x234F: -case 0x254F: -case 0x274F: -case 0x294F: -case 0x2B4F: -case 0x2D4F: -case 0x2F4F: - -// MOVEL -case 0x2148: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x2388: -case 0x2588: -case 0x2788: -case 0x2988: -case 0x2B88: -case 0x2D88: -case 0x2F88: -case 0x2189: -case 0x2389: -case 0x2589: -case 0x2789: -case 0x2989: -case 0x2B89: -case 0x2D89: -case 0x2F89: -case 0x218A: -case 0x238A: -case 0x258A: -case 0x278A: -case 0x298A: -case 0x2B8A: -case 0x2D8A: -case 0x2F8A: -case 0x218B: -case 0x238B: -case 0x258B: -case 0x278B: -case 0x298B: -case 0x2B8B: -case 0x2D8B: -case 0x2F8B: -case 0x218C: -case 0x238C: -case 0x258C: -case 0x278C: -case 0x298C: -case 0x2B8C: -case 0x2D8C: -case 0x2F8C: -case 0x218D: -case 0x238D: -case 0x258D: -case 0x278D: -case 0x298D: -case 0x2B8D: -case 0x2D8D: -case 0x2F8D: -case 0x218E: -case 0x238E: -case 0x258E: -case 0x278E: -case 0x298E: -case 0x2B8E: -case 0x2D8E: -case 0x2F8E: -case 0x218F: -case 0x238F: -case 0x258F: -case 0x278F: -case 0x298F: -case 0x2B8F: -case 0x2D8F: -case 0x2F8F: - -// MOVEL -case 0x2188: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(18) -case 0x21C9: -case 0x21CA: -case 0x21CB: -case 0x21CC: -case 0x21CD: -case 0x21CE: -case 0x21CF: - -// MOVEL -case 0x21C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x23C9: -case 0x23CA: -case 0x23CB: -case 0x23CC: -case 0x23CD: -case 0x23CE: -case 0x23CF: - -// MOVEL -case 0x23C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2EC9: -case 0x2ECA: -case 0x2ECB: -case 0x2ECC: -case 0x2ECD: -case 0x2ECE: -case 0x2ECF: - -// MOVEL -case 0x2EC8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2F09: -case 0x2F0A: -case 0x2F0B: -case 0x2F0C: -case 0x2F0D: -case 0x2F0E: -case 0x2F0F: - -// MOVEL -case 0x2F08: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2210: -case 0x2410: -case 0x2610: -case 0x2810: -case 0x2A10: -case 0x2C10: -case 0x2E10: -case 0x2011: -case 0x2211: -case 0x2411: -case 0x2611: -case 0x2811: -case 0x2A11: -case 0x2C11: -case 0x2E11: -case 0x2012: -case 0x2212: -case 0x2412: -case 0x2612: -case 0x2812: -case 0x2A12: -case 0x2C12: -case 0x2E12: -case 0x2013: -case 0x2213: -case 0x2413: -case 0x2613: -case 0x2813: -case 0x2A13: -case 0x2C13: -case 0x2E13: -case 0x2014: -case 0x2214: -case 0x2414: -case 0x2614: -case 0x2814: -case 0x2A14: -case 0x2C14: -case 0x2E14: -case 0x2015: -case 0x2215: -case 0x2415: -case 0x2615: -case 0x2815: -case 0x2A15: -case 0x2C15: -case 0x2E15: -case 0x2016: -case 0x2216: -case 0x2416: -case 0x2616: -case 0x2816: -case 0x2A16: -case 0x2C16: -case 0x2E16: -case 0x2017: -case 0x2217: -case 0x2417: -case 0x2617: -case 0x2817: -case 0x2A17: -case 0x2C17: -case 0x2E17: - -// MOVEL -case 0x2010: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x2290: -case 0x2490: -case 0x2690: -case 0x2890: -case 0x2A90: -case 0x2C90: -case 0x2E90: -case 0x2091: -case 0x2291: -case 0x2491: -case 0x2691: -case 0x2891: -case 0x2A91: -case 0x2C91: -case 0x2E91: -case 0x2092: -case 0x2292: -case 0x2492: -case 0x2692: -case 0x2892: -case 0x2A92: -case 0x2C92: -case 0x2E92: -case 0x2093: -case 0x2293: -case 0x2493: -case 0x2693: -case 0x2893: -case 0x2A93: -case 0x2C93: -case 0x2E93: -case 0x2094: -case 0x2294: -case 0x2494: -case 0x2694: -case 0x2894: -case 0x2A94: -case 0x2C94: -case 0x2E94: -case 0x2095: -case 0x2295: -case 0x2495: -case 0x2695: -case 0x2895: -case 0x2A95: -case 0x2C95: -case 0x2E95: -case 0x2096: -case 0x2296: -case 0x2496: -case 0x2696: -case 0x2896: -case 0x2A96: -case 0x2C96: -case 0x2E96: -case 0x2097: -case 0x2297: -case 0x2497: -case 0x2697: -case 0x2897: -case 0x2A97: -case 0x2C97: -case 0x2E97: - -// MOVEL -case 0x2090: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22D0: -case 0x24D0: -case 0x26D0: -case 0x28D0: -case 0x2AD0: -case 0x2CD0: -case 0x20D1: -case 0x22D1: -case 0x24D1: -case 0x26D1: -case 0x28D1: -case 0x2AD1: -case 0x2CD1: -case 0x20D2: -case 0x22D2: -case 0x24D2: -case 0x26D2: -case 0x28D2: -case 0x2AD2: -case 0x2CD2: -case 0x20D3: -case 0x22D3: -case 0x24D3: -case 0x26D3: -case 0x28D3: -case 0x2AD3: -case 0x2CD3: -case 0x20D4: -case 0x22D4: -case 0x24D4: -case 0x26D4: -case 0x28D4: -case 0x2AD4: -case 0x2CD4: -case 0x20D5: -case 0x22D5: -case 0x24D5: -case 0x26D5: -case 0x28D5: -case 0x2AD5: -case 0x2CD5: -case 0x20D6: -case 0x22D6: -case 0x24D6: -case 0x26D6: -case 0x28D6: -case 0x2AD6: -case 0x2CD6: -case 0x20D7: -case 0x22D7: -case 0x24D7: -case 0x26D7: -case 0x28D7: -case 0x2AD7: -case 0x2CD7: - -// MOVEL -case 0x20D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2310: -case 0x2510: -case 0x2710: -case 0x2910: -case 0x2B10: -case 0x2D10: -case 0x2111: -case 0x2311: -case 0x2511: -case 0x2711: -case 0x2911: -case 0x2B11: -case 0x2D11: -case 0x2112: -case 0x2312: -case 0x2512: -case 0x2712: -case 0x2912: -case 0x2B12: -case 0x2D12: -case 0x2113: -case 0x2313: -case 0x2513: -case 0x2713: -case 0x2913: -case 0x2B13: -case 0x2D13: -case 0x2114: -case 0x2314: -case 0x2514: -case 0x2714: -case 0x2914: -case 0x2B14: -case 0x2D14: -case 0x2115: -case 0x2315: -case 0x2515: -case 0x2715: -case 0x2915: -case 0x2B15: -case 0x2D15: -case 0x2116: -case 0x2316: -case 0x2516: -case 0x2716: -case 0x2916: -case 0x2B16: -case 0x2D16: -case 0x2117: -case 0x2317: -case 0x2517: -case 0x2717: -case 0x2917: -case 0x2B17: -case 0x2D17: - -// MOVEL -case 0x2110: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2350: -case 0x2550: -case 0x2750: -case 0x2950: -case 0x2B50: -case 0x2D50: -case 0x2F50: -case 0x2151: -case 0x2351: -case 0x2551: -case 0x2751: -case 0x2951: -case 0x2B51: -case 0x2D51: -case 0x2F51: -case 0x2152: -case 0x2352: -case 0x2552: -case 0x2752: -case 0x2952: -case 0x2B52: -case 0x2D52: -case 0x2F52: -case 0x2153: -case 0x2353: -case 0x2553: -case 0x2753: -case 0x2953: -case 0x2B53: -case 0x2D53: -case 0x2F53: -case 0x2154: -case 0x2354: -case 0x2554: -case 0x2754: -case 0x2954: -case 0x2B54: -case 0x2D54: -case 0x2F54: -case 0x2155: -case 0x2355: -case 0x2555: -case 0x2755: -case 0x2955: -case 0x2B55: -case 0x2D55: -case 0x2F55: -case 0x2156: -case 0x2356: -case 0x2556: -case 0x2756: -case 0x2956: -case 0x2B56: -case 0x2D56: -case 0x2F56: -case 0x2157: -case 0x2357: -case 0x2557: -case 0x2757: -case 0x2957: -case 0x2B57: -case 0x2D57: -case 0x2F57: - -// MOVEL -case 0x2150: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2390: -case 0x2590: -case 0x2790: -case 0x2990: -case 0x2B90: -case 0x2D90: -case 0x2F90: -case 0x2191: -case 0x2391: -case 0x2591: -case 0x2791: -case 0x2991: -case 0x2B91: -case 0x2D91: -case 0x2F91: -case 0x2192: -case 0x2392: -case 0x2592: -case 0x2792: -case 0x2992: -case 0x2B92: -case 0x2D92: -case 0x2F92: -case 0x2193: -case 0x2393: -case 0x2593: -case 0x2793: -case 0x2993: -case 0x2B93: -case 0x2D93: -case 0x2F93: -case 0x2194: -case 0x2394: -case 0x2594: -case 0x2794: -case 0x2994: -case 0x2B94: -case 0x2D94: -case 0x2F94: -case 0x2195: -case 0x2395: -case 0x2595: -case 0x2795: -case 0x2995: -case 0x2B95: -case 0x2D95: -case 0x2F95: -case 0x2196: -case 0x2396: -case 0x2596: -case 0x2796: -case 0x2996: -case 0x2B96: -case 0x2D96: -case 0x2F96: -case 0x2197: -case 0x2397: -case 0x2597: -case 0x2797: -case 0x2997: -case 0x2B97: -case 0x2D97: -case 0x2F97: - -// MOVEL -case 0x2190: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x21D1: -case 0x21D2: -case 0x21D3: -case 0x21D4: -case 0x21D5: -case 0x21D6: -case 0x21D7: - -// MOVEL -case 0x21D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x23D1: -case 0x23D2: -case 0x23D3: -case 0x23D4: -case 0x23D5: -case 0x23D6: -case 0x23D7: - -// MOVEL -case 0x23D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2ED1: -case 0x2ED2: -case 0x2ED3: -case 0x2ED4: -case 0x2ED5: -case 0x2ED6: -case 0x2ED7: - -// MOVEL -case 0x2ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2F11: -case 0x2F12: -case 0x2F13: -case 0x2F14: -case 0x2F15: -case 0x2F16: -case 0x2F17: - -// MOVEL -case 0x2F10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2218: -case 0x2418: -case 0x2618: -case 0x2818: -case 0x2A18: -case 0x2C18: -case 0x2E18: -case 0x2019: -case 0x2219: -case 0x2419: -case 0x2619: -case 0x2819: -case 0x2A19: -case 0x2C19: -case 0x2E19: -case 0x201A: -case 0x221A: -case 0x241A: -case 0x261A: -case 0x281A: -case 0x2A1A: -case 0x2C1A: -case 0x2E1A: -case 0x201B: -case 0x221B: -case 0x241B: -case 0x261B: -case 0x281B: -case 0x2A1B: -case 0x2C1B: -case 0x2E1B: -case 0x201C: -case 0x221C: -case 0x241C: -case 0x261C: -case 0x281C: -case 0x2A1C: -case 0x2C1C: -case 0x2E1C: -case 0x201D: -case 0x221D: -case 0x241D: -case 0x261D: -case 0x281D: -case 0x2A1D: -case 0x2C1D: -case 0x2E1D: -case 0x201E: -case 0x221E: -case 0x241E: -case 0x261E: -case 0x281E: -case 0x2A1E: -case 0x2C1E: -case 0x2E1E: - -// MOVEL -case 0x2018: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x2298: -case 0x2498: -case 0x2698: -case 0x2898: -case 0x2A98: -case 0x2C98: -case 0x2E98: -case 0x2099: -case 0x2299: -case 0x2499: -case 0x2699: -case 0x2899: -case 0x2A99: -case 0x2C99: -case 0x2E99: -case 0x209A: -case 0x229A: -case 0x249A: -case 0x269A: -case 0x289A: -case 0x2A9A: -case 0x2C9A: -case 0x2E9A: -case 0x209B: -case 0x229B: -case 0x249B: -case 0x269B: -case 0x289B: -case 0x2A9B: -case 0x2C9B: -case 0x2E9B: -case 0x209C: -case 0x229C: -case 0x249C: -case 0x269C: -case 0x289C: -case 0x2A9C: -case 0x2C9C: -case 0x2E9C: -case 0x209D: -case 0x229D: -case 0x249D: -case 0x269D: -case 0x289D: -case 0x2A9D: -case 0x2C9D: -case 0x2E9D: -case 0x209E: -case 0x229E: -case 0x249E: -case 0x269E: -case 0x289E: -case 0x2A9E: -case 0x2C9E: -case 0x2E9E: - -// MOVEL -case 0x2098: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22D8: -case 0x24D8: -case 0x26D8: -case 0x28D8: -case 0x2AD8: -case 0x2CD8: -case 0x20D9: -case 0x22D9: -case 0x24D9: -case 0x26D9: -case 0x28D9: -case 0x2AD9: -case 0x2CD9: -case 0x20DA: -case 0x22DA: -case 0x24DA: -case 0x26DA: -case 0x28DA: -case 0x2ADA: -case 0x2CDA: -case 0x20DB: -case 0x22DB: -case 0x24DB: -case 0x26DB: -case 0x28DB: -case 0x2ADB: -case 0x2CDB: -case 0x20DC: -case 0x22DC: -case 0x24DC: -case 0x26DC: -case 0x28DC: -case 0x2ADC: -case 0x2CDC: -case 0x20DD: -case 0x22DD: -case 0x24DD: -case 0x26DD: -case 0x28DD: -case 0x2ADD: -case 0x2CDD: -case 0x20DE: -case 0x22DE: -case 0x24DE: -case 0x26DE: -case 0x28DE: -case 0x2ADE: -case 0x2CDE: - -// MOVEL -case 0x20D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2318: -case 0x2518: -case 0x2718: -case 0x2918: -case 0x2B18: -case 0x2D18: -case 0x2119: -case 0x2319: -case 0x2519: -case 0x2719: -case 0x2919: -case 0x2B19: -case 0x2D19: -case 0x211A: -case 0x231A: -case 0x251A: -case 0x271A: -case 0x291A: -case 0x2B1A: -case 0x2D1A: -case 0x211B: -case 0x231B: -case 0x251B: -case 0x271B: -case 0x291B: -case 0x2B1B: -case 0x2D1B: -case 0x211C: -case 0x231C: -case 0x251C: -case 0x271C: -case 0x291C: -case 0x2B1C: -case 0x2D1C: -case 0x211D: -case 0x231D: -case 0x251D: -case 0x271D: -case 0x291D: -case 0x2B1D: -case 0x2D1D: -case 0x211E: -case 0x231E: -case 0x251E: -case 0x271E: -case 0x291E: -case 0x2B1E: -case 0x2D1E: - -// MOVEL -case 0x2118: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2358: -case 0x2558: -case 0x2758: -case 0x2958: -case 0x2B58: -case 0x2D58: -case 0x2F58: -case 0x2159: -case 0x2359: -case 0x2559: -case 0x2759: -case 0x2959: -case 0x2B59: -case 0x2D59: -case 0x2F59: -case 0x215A: -case 0x235A: -case 0x255A: -case 0x275A: -case 0x295A: -case 0x2B5A: -case 0x2D5A: -case 0x2F5A: -case 0x215B: -case 0x235B: -case 0x255B: -case 0x275B: -case 0x295B: -case 0x2B5B: -case 0x2D5B: -case 0x2F5B: -case 0x215C: -case 0x235C: -case 0x255C: -case 0x275C: -case 0x295C: -case 0x2B5C: -case 0x2D5C: -case 0x2F5C: -case 0x215D: -case 0x235D: -case 0x255D: -case 0x275D: -case 0x295D: -case 0x2B5D: -case 0x2D5D: -case 0x2F5D: -case 0x215E: -case 0x235E: -case 0x255E: -case 0x275E: -case 0x295E: -case 0x2B5E: -case 0x2D5E: -case 0x2F5E: - -// MOVEL -case 0x2158: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2398: -case 0x2598: -case 0x2798: -case 0x2998: -case 0x2B98: -case 0x2D98: -case 0x2F98: -case 0x2199: -case 0x2399: -case 0x2599: -case 0x2799: -case 0x2999: -case 0x2B99: -case 0x2D99: -case 0x2F99: -case 0x219A: -case 0x239A: -case 0x259A: -case 0x279A: -case 0x299A: -case 0x2B9A: -case 0x2D9A: -case 0x2F9A: -case 0x219B: -case 0x239B: -case 0x259B: -case 0x279B: -case 0x299B: -case 0x2B9B: -case 0x2D9B: -case 0x2F9B: -case 0x219C: -case 0x239C: -case 0x259C: -case 0x279C: -case 0x299C: -case 0x2B9C: -case 0x2D9C: -case 0x2F9C: -case 0x219D: -case 0x239D: -case 0x259D: -case 0x279D: -case 0x299D: -case 0x2B9D: -case 0x2D9D: -case 0x2F9D: -case 0x219E: -case 0x239E: -case 0x259E: -case 0x279E: -case 0x299E: -case 0x2B9E: -case 0x2D9E: -case 0x2F9E: - -// MOVEL -case 0x2198: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x21D9: -case 0x21DA: -case 0x21DB: -case 0x21DC: -case 0x21DD: -case 0x21DE: - -// MOVEL -case 0x21D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x23D9: -case 0x23DA: -case 0x23DB: -case 0x23DC: -case 0x23DD: -case 0x23DE: - -// MOVEL -case 0x23D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2ED9: -case 0x2EDA: -case 0x2EDB: -case 0x2EDC: -case 0x2EDD: -case 0x2EDE: - -// MOVEL -case 0x2ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2F19: -case 0x2F1A: -case 0x2F1B: -case 0x2F1C: -case 0x2F1D: -case 0x2F1E: - -// MOVEL -case 0x2F18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2220: -case 0x2420: -case 0x2620: -case 0x2820: -case 0x2A20: -case 0x2C20: -case 0x2E20: -case 0x2021: -case 0x2221: -case 0x2421: -case 0x2621: -case 0x2821: -case 0x2A21: -case 0x2C21: -case 0x2E21: -case 0x2022: -case 0x2222: -case 0x2422: -case 0x2622: -case 0x2822: -case 0x2A22: -case 0x2C22: -case 0x2E22: -case 0x2023: -case 0x2223: -case 0x2423: -case 0x2623: -case 0x2823: -case 0x2A23: -case 0x2C23: -case 0x2E23: -case 0x2024: -case 0x2224: -case 0x2424: -case 0x2624: -case 0x2824: -case 0x2A24: -case 0x2C24: -case 0x2E24: -case 0x2025: -case 0x2225: -case 0x2425: -case 0x2625: -case 0x2825: -case 0x2A25: -case 0x2C25: -case 0x2E25: -case 0x2026: -case 0x2226: -case 0x2426: -case 0x2626: -case 0x2826: -case 0x2A26: -case 0x2C26: -case 0x2E26: - -// MOVEL -case 0x2020: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x22A0: -case 0x24A0: -case 0x26A0: -case 0x28A0: -case 0x2AA0: -case 0x2CA0: -case 0x2EA0: -case 0x20A1: -case 0x22A1: -case 0x24A1: -case 0x26A1: -case 0x28A1: -case 0x2AA1: -case 0x2CA1: -case 0x2EA1: -case 0x20A2: -case 0x22A2: -case 0x24A2: -case 0x26A2: -case 0x28A2: -case 0x2AA2: -case 0x2CA2: -case 0x2EA2: -case 0x20A3: -case 0x22A3: -case 0x24A3: -case 0x26A3: -case 0x28A3: -case 0x2AA3: -case 0x2CA3: -case 0x2EA3: -case 0x20A4: -case 0x22A4: -case 0x24A4: -case 0x26A4: -case 0x28A4: -case 0x2AA4: -case 0x2CA4: -case 0x2EA4: -case 0x20A5: -case 0x22A5: -case 0x24A5: -case 0x26A5: -case 0x28A5: -case 0x2AA5: -case 0x2CA5: -case 0x2EA5: -case 0x20A6: -case 0x22A6: -case 0x24A6: -case 0x26A6: -case 0x28A6: -case 0x2AA6: -case 0x2CA6: -case 0x2EA6: - -// MOVEL -case 0x20A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x22E0: -case 0x24E0: -case 0x26E0: -case 0x28E0: -case 0x2AE0: -case 0x2CE0: -case 0x20E1: -case 0x22E1: -case 0x24E1: -case 0x26E1: -case 0x28E1: -case 0x2AE1: -case 0x2CE1: -case 0x20E2: -case 0x22E2: -case 0x24E2: -case 0x26E2: -case 0x28E2: -case 0x2AE2: -case 0x2CE2: -case 0x20E3: -case 0x22E3: -case 0x24E3: -case 0x26E3: -case 0x28E3: -case 0x2AE3: -case 0x2CE3: -case 0x20E4: -case 0x22E4: -case 0x24E4: -case 0x26E4: -case 0x28E4: -case 0x2AE4: -case 0x2CE4: -case 0x20E5: -case 0x22E5: -case 0x24E5: -case 0x26E5: -case 0x28E5: -case 0x2AE5: -case 0x2CE5: -case 0x20E6: -case 0x22E6: -case 0x24E6: -case 0x26E6: -case 0x28E6: -case 0x2AE6: -case 0x2CE6: - -// MOVEL -case 0x20E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2320: -case 0x2520: -case 0x2720: -case 0x2920: -case 0x2B20: -case 0x2D20: -case 0x2121: -case 0x2321: -case 0x2521: -case 0x2721: -case 0x2921: -case 0x2B21: -case 0x2D21: -case 0x2122: -case 0x2322: -case 0x2522: -case 0x2722: -case 0x2922: -case 0x2B22: -case 0x2D22: -case 0x2123: -case 0x2323: -case 0x2523: -case 0x2723: -case 0x2923: -case 0x2B23: -case 0x2D23: -case 0x2124: -case 0x2324: -case 0x2524: -case 0x2724: -case 0x2924: -case 0x2B24: -case 0x2D24: -case 0x2125: -case 0x2325: -case 0x2525: -case 0x2725: -case 0x2925: -case 0x2B25: -case 0x2D25: -case 0x2126: -case 0x2326: -case 0x2526: -case 0x2726: -case 0x2926: -case 0x2B26: -case 0x2D26: - -// MOVEL -case 0x2120: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2360: -case 0x2560: -case 0x2760: -case 0x2960: -case 0x2B60: -case 0x2D60: -case 0x2F60: -case 0x2161: -case 0x2361: -case 0x2561: -case 0x2761: -case 0x2961: -case 0x2B61: -case 0x2D61: -case 0x2F61: -case 0x2162: -case 0x2362: -case 0x2562: -case 0x2762: -case 0x2962: -case 0x2B62: -case 0x2D62: -case 0x2F62: -case 0x2163: -case 0x2363: -case 0x2563: -case 0x2763: -case 0x2963: -case 0x2B63: -case 0x2D63: -case 0x2F63: -case 0x2164: -case 0x2364: -case 0x2564: -case 0x2764: -case 0x2964: -case 0x2B64: -case 0x2D64: -case 0x2F64: -case 0x2165: -case 0x2365: -case 0x2565: -case 0x2765: -case 0x2965: -case 0x2B65: -case 0x2D65: -case 0x2F65: -case 0x2166: -case 0x2366: -case 0x2566: -case 0x2766: -case 0x2966: -case 0x2B66: -case 0x2D66: -case 0x2F66: - -// MOVEL -case 0x2160: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x23A0: -case 0x25A0: -case 0x27A0: -case 0x29A0: -case 0x2BA0: -case 0x2DA0: -case 0x2FA0: -case 0x21A1: -case 0x23A1: -case 0x25A1: -case 0x27A1: -case 0x29A1: -case 0x2BA1: -case 0x2DA1: -case 0x2FA1: -case 0x21A2: -case 0x23A2: -case 0x25A2: -case 0x27A2: -case 0x29A2: -case 0x2BA2: -case 0x2DA2: -case 0x2FA2: -case 0x21A3: -case 0x23A3: -case 0x25A3: -case 0x27A3: -case 0x29A3: -case 0x2BA3: -case 0x2DA3: -case 0x2FA3: -case 0x21A4: -case 0x23A4: -case 0x25A4: -case 0x27A4: -case 0x29A4: -case 0x2BA4: -case 0x2DA4: -case 0x2FA4: -case 0x21A5: -case 0x23A5: -case 0x25A5: -case 0x27A5: -case 0x29A5: -case 0x2BA5: -case 0x2DA5: -case 0x2FA5: -case 0x21A6: -case 0x23A6: -case 0x25A6: -case 0x27A6: -case 0x29A6: -case 0x2BA6: -case 0x2DA6: -case 0x2FA6: - -// MOVEL -case 0x21A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x21E1: -case 0x21E2: -case 0x21E3: -case 0x21E4: -case 0x21E5: -case 0x21E6: - -// MOVEL -case 0x21E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x23E1: -case 0x23E2: -case 0x23E3: -case 0x23E4: -case 0x23E5: -case 0x23E6: - -// MOVEL -case 0x23E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x2EE1: -case 0x2EE2: -case 0x2EE3: -case 0x2EE4: -case 0x2EE5: -case 0x2EE6: - -// MOVEL -case 0x2EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2F21: -case 0x2F22: -case 0x2F23: -case 0x2F24: -case 0x2F25: -case 0x2F26: - -// MOVEL -case 0x2F20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2228: -case 0x2428: -case 0x2628: -case 0x2828: -case 0x2A28: -case 0x2C28: -case 0x2E28: -case 0x2029: -case 0x2229: -case 0x2429: -case 0x2629: -case 0x2829: -case 0x2A29: -case 0x2C29: -case 0x2E29: -case 0x202A: -case 0x222A: -case 0x242A: -case 0x262A: -case 0x282A: -case 0x2A2A: -case 0x2C2A: -case 0x2E2A: -case 0x202B: -case 0x222B: -case 0x242B: -case 0x262B: -case 0x282B: -case 0x2A2B: -case 0x2C2B: -case 0x2E2B: -case 0x202C: -case 0x222C: -case 0x242C: -case 0x262C: -case 0x282C: -case 0x2A2C: -case 0x2C2C: -case 0x2E2C: -case 0x202D: -case 0x222D: -case 0x242D: -case 0x262D: -case 0x282D: -case 0x2A2D: -case 0x2C2D: -case 0x2E2D: -case 0x202E: -case 0x222E: -case 0x242E: -case 0x262E: -case 0x282E: -case 0x2A2E: -case 0x2C2E: -case 0x2E2E: -case 0x202F: -case 0x222F: -case 0x242F: -case 0x262F: -case 0x282F: -case 0x2A2F: -case 0x2C2F: -case 0x2E2F: - -// MOVEL -case 0x2028: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x22A8: -case 0x24A8: -case 0x26A8: -case 0x28A8: -case 0x2AA8: -case 0x2CA8: -case 0x2EA8: -case 0x20A9: -case 0x22A9: -case 0x24A9: -case 0x26A9: -case 0x28A9: -case 0x2AA9: -case 0x2CA9: -case 0x2EA9: -case 0x20AA: -case 0x22AA: -case 0x24AA: -case 0x26AA: -case 0x28AA: -case 0x2AAA: -case 0x2CAA: -case 0x2EAA: -case 0x20AB: -case 0x22AB: -case 0x24AB: -case 0x26AB: -case 0x28AB: -case 0x2AAB: -case 0x2CAB: -case 0x2EAB: -case 0x20AC: -case 0x22AC: -case 0x24AC: -case 0x26AC: -case 0x28AC: -case 0x2AAC: -case 0x2CAC: -case 0x2EAC: -case 0x20AD: -case 0x22AD: -case 0x24AD: -case 0x26AD: -case 0x28AD: -case 0x2AAD: -case 0x2CAD: -case 0x2EAD: -case 0x20AE: -case 0x22AE: -case 0x24AE: -case 0x26AE: -case 0x28AE: -case 0x2AAE: -case 0x2CAE: -case 0x2EAE: -case 0x20AF: -case 0x22AF: -case 0x24AF: -case 0x26AF: -case 0x28AF: -case 0x2AAF: -case 0x2CAF: -case 0x2EAF: - -// MOVEL -case 0x20A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x22E8: -case 0x24E8: -case 0x26E8: -case 0x28E8: -case 0x2AE8: -case 0x2CE8: -case 0x20E9: -case 0x22E9: -case 0x24E9: -case 0x26E9: -case 0x28E9: -case 0x2AE9: -case 0x2CE9: -case 0x20EA: -case 0x22EA: -case 0x24EA: -case 0x26EA: -case 0x28EA: -case 0x2AEA: -case 0x2CEA: -case 0x20EB: -case 0x22EB: -case 0x24EB: -case 0x26EB: -case 0x28EB: -case 0x2AEB: -case 0x2CEB: -case 0x20EC: -case 0x22EC: -case 0x24EC: -case 0x26EC: -case 0x28EC: -case 0x2AEC: -case 0x2CEC: -case 0x20ED: -case 0x22ED: -case 0x24ED: -case 0x26ED: -case 0x28ED: -case 0x2AED: -case 0x2CED: -case 0x20EE: -case 0x22EE: -case 0x24EE: -case 0x26EE: -case 0x28EE: -case 0x2AEE: -case 0x2CEE: -case 0x20EF: -case 0x22EF: -case 0x24EF: -case 0x26EF: -case 0x28EF: -case 0x2AEF: -case 0x2CEF: - -// MOVEL -case 0x20E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2328: -case 0x2528: -case 0x2728: -case 0x2928: -case 0x2B28: -case 0x2D28: -case 0x2129: -case 0x2329: -case 0x2529: -case 0x2729: -case 0x2929: -case 0x2B29: -case 0x2D29: -case 0x212A: -case 0x232A: -case 0x252A: -case 0x272A: -case 0x292A: -case 0x2B2A: -case 0x2D2A: -case 0x212B: -case 0x232B: -case 0x252B: -case 0x272B: -case 0x292B: -case 0x2B2B: -case 0x2D2B: -case 0x212C: -case 0x232C: -case 0x252C: -case 0x272C: -case 0x292C: -case 0x2B2C: -case 0x2D2C: -case 0x212D: -case 0x232D: -case 0x252D: -case 0x272D: -case 0x292D: -case 0x2B2D: -case 0x2D2D: -case 0x212E: -case 0x232E: -case 0x252E: -case 0x272E: -case 0x292E: -case 0x2B2E: -case 0x2D2E: -case 0x212F: -case 0x232F: -case 0x252F: -case 0x272F: -case 0x292F: -case 0x2B2F: -case 0x2D2F: - -// MOVEL -case 0x2128: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2368: -case 0x2568: -case 0x2768: -case 0x2968: -case 0x2B68: -case 0x2D68: -case 0x2F68: -case 0x2169: -case 0x2369: -case 0x2569: -case 0x2769: -case 0x2969: -case 0x2B69: -case 0x2D69: -case 0x2F69: -case 0x216A: -case 0x236A: -case 0x256A: -case 0x276A: -case 0x296A: -case 0x2B6A: -case 0x2D6A: -case 0x2F6A: -case 0x216B: -case 0x236B: -case 0x256B: -case 0x276B: -case 0x296B: -case 0x2B6B: -case 0x2D6B: -case 0x2F6B: -case 0x216C: -case 0x236C: -case 0x256C: -case 0x276C: -case 0x296C: -case 0x2B6C: -case 0x2D6C: -case 0x2F6C: -case 0x216D: -case 0x236D: -case 0x256D: -case 0x276D: -case 0x296D: -case 0x2B6D: -case 0x2D6D: -case 0x2F6D: -case 0x216E: -case 0x236E: -case 0x256E: -case 0x276E: -case 0x296E: -case 0x2B6E: -case 0x2D6E: -case 0x2F6E: -case 0x216F: -case 0x236F: -case 0x256F: -case 0x276F: -case 0x296F: -case 0x2B6F: -case 0x2D6F: -case 0x2F6F: - -// MOVEL -case 0x2168: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23A8: -case 0x25A8: -case 0x27A8: -case 0x29A8: -case 0x2BA8: -case 0x2DA8: -case 0x2FA8: -case 0x21A9: -case 0x23A9: -case 0x25A9: -case 0x27A9: -case 0x29A9: -case 0x2BA9: -case 0x2DA9: -case 0x2FA9: -case 0x21AA: -case 0x23AA: -case 0x25AA: -case 0x27AA: -case 0x29AA: -case 0x2BAA: -case 0x2DAA: -case 0x2FAA: -case 0x21AB: -case 0x23AB: -case 0x25AB: -case 0x27AB: -case 0x29AB: -case 0x2BAB: -case 0x2DAB: -case 0x2FAB: -case 0x21AC: -case 0x23AC: -case 0x25AC: -case 0x27AC: -case 0x29AC: -case 0x2BAC: -case 0x2DAC: -case 0x2FAC: -case 0x21AD: -case 0x23AD: -case 0x25AD: -case 0x27AD: -case 0x29AD: -case 0x2BAD: -case 0x2DAD: -case 0x2FAD: -case 0x21AE: -case 0x23AE: -case 0x25AE: -case 0x27AE: -case 0x29AE: -case 0x2BAE: -case 0x2DAE: -case 0x2FAE: -case 0x21AF: -case 0x23AF: -case 0x25AF: -case 0x27AF: -case 0x29AF: -case 0x2BAF: -case 0x2DAF: -case 0x2FAF: - -// MOVEL -case 0x21A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x21E9: -case 0x21EA: -case 0x21EB: -case 0x21EC: -case 0x21ED: -case 0x21EE: -case 0x21EF: - -// MOVEL -case 0x21E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23E9: -case 0x23EA: -case 0x23EB: -case 0x23EC: -case 0x23ED: -case 0x23EE: -case 0x23EF: - -// MOVEL -case 0x23E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x2EE9: -case 0x2EEA: -case 0x2EEB: -case 0x2EEC: -case 0x2EED: -case 0x2EEE: -case 0x2EEF: - -// MOVEL -case 0x2EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2F29: -case 0x2F2A: -case 0x2F2B: -case 0x2F2C: -case 0x2F2D: -case 0x2F2E: -case 0x2F2F: - -// MOVEL -case 0x2F28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2230: -case 0x2430: -case 0x2630: -case 0x2830: -case 0x2A30: -case 0x2C30: -case 0x2E30: -case 0x2031: -case 0x2231: -case 0x2431: -case 0x2631: -case 0x2831: -case 0x2A31: -case 0x2C31: -case 0x2E31: -case 0x2032: -case 0x2232: -case 0x2432: -case 0x2632: -case 0x2832: -case 0x2A32: -case 0x2C32: -case 0x2E32: -case 0x2033: -case 0x2233: -case 0x2433: -case 0x2633: -case 0x2833: -case 0x2A33: -case 0x2C33: -case 0x2E33: -case 0x2034: -case 0x2234: -case 0x2434: -case 0x2634: -case 0x2834: -case 0x2A34: -case 0x2C34: -case 0x2E34: -case 0x2035: -case 0x2235: -case 0x2435: -case 0x2635: -case 0x2835: -case 0x2A35: -case 0x2C35: -case 0x2E35: -case 0x2036: -case 0x2236: -case 0x2436: -case 0x2636: -case 0x2836: -case 0x2A36: -case 0x2C36: -case 0x2E36: -case 0x2037: -case 0x2237: -case 0x2437: -case 0x2637: -case 0x2837: -case 0x2A37: -case 0x2C37: -case 0x2E37: - -// MOVEL -case 0x2030: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x22B0: -case 0x24B0: -case 0x26B0: -case 0x28B0: -case 0x2AB0: -case 0x2CB0: -case 0x2EB0: -case 0x20B1: -case 0x22B1: -case 0x24B1: -case 0x26B1: -case 0x28B1: -case 0x2AB1: -case 0x2CB1: -case 0x2EB1: -case 0x20B2: -case 0x22B2: -case 0x24B2: -case 0x26B2: -case 0x28B2: -case 0x2AB2: -case 0x2CB2: -case 0x2EB2: -case 0x20B3: -case 0x22B3: -case 0x24B3: -case 0x26B3: -case 0x28B3: -case 0x2AB3: -case 0x2CB3: -case 0x2EB3: -case 0x20B4: -case 0x22B4: -case 0x24B4: -case 0x26B4: -case 0x28B4: -case 0x2AB4: -case 0x2CB4: -case 0x2EB4: -case 0x20B5: -case 0x22B5: -case 0x24B5: -case 0x26B5: -case 0x28B5: -case 0x2AB5: -case 0x2CB5: -case 0x2EB5: -case 0x20B6: -case 0x22B6: -case 0x24B6: -case 0x26B6: -case 0x28B6: -case 0x2AB6: -case 0x2CB6: -case 0x2EB6: -case 0x20B7: -case 0x22B7: -case 0x24B7: -case 0x26B7: -case 0x28B7: -case 0x2AB7: -case 0x2CB7: -case 0x2EB7: - -// MOVEL -case 0x20B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x22F0: -case 0x24F0: -case 0x26F0: -case 0x28F0: -case 0x2AF0: -case 0x2CF0: -case 0x20F1: -case 0x22F1: -case 0x24F1: -case 0x26F1: -case 0x28F1: -case 0x2AF1: -case 0x2CF1: -case 0x20F2: -case 0x22F2: -case 0x24F2: -case 0x26F2: -case 0x28F2: -case 0x2AF2: -case 0x2CF2: -case 0x20F3: -case 0x22F3: -case 0x24F3: -case 0x26F3: -case 0x28F3: -case 0x2AF3: -case 0x2CF3: -case 0x20F4: -case 0x22F4: -case 0x24F4: -case 0x26F4: -case 0x28F4: -case 0x2AF4: -case 0x2CF4: -case 0x20F5: -case 0x22F5: -case 0x24F5: -case 0x26F5: -case 0x28F5: -case 0x2AF5: -case 0x2CF5: -case 0x20F6: -case 0x22F6: -case 0x24F6: -case 0x26F6: -case 0x28F6: -case 0x2AF6: -case 0x2CF6: -case 0x20F7: -case 0x22F7: -case 0x24F7: -case 0x26F7: -case 0x28F7: -case 0x2AF7: -case 0x2CF7: - -// MOVEL -case 0x20F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2330: -case 0x2530: -case 0x2730: -case 0x2930: -case 0x2B30: -case 0x2D30: -case 0x2131: -case 0x2331: -case 0x2531: -case 0x2731: -case 0x2931: -case 0x2B31: -case 0x2D31: -case 0x2132: -case 0x2332: -case 0x2532: -case 0x2732: -case 0x2932: -case 0x2B32: -case 0x2D32: -case 0x2133: -case 0x2333: -case 0x2533: -case 0x2733: -case 0x2933: -case 0x2B33: -case 0x2D33: -case 0x2134: -case 0x2334: -case 0x2534: -case 0x2734: -case 0x2934: -case 0x2B34: -case 0x2D34: -case 0x2135: -case 0x2335: -case 0x2535: -case 0x2735: -case 0x2935: -case 0x2B35: -case 0x2D35: -case 0x2136: -case 0x2336: -case 0x2536: -case 0x2736: -case 0x2936: -case 0x2B36: -case 0x2D36: -case 0x2137: -case 0x2337: -case 0x2537: -case 0x2737: -case 0x2937: -case 0x2B37: -case 0x2D37: - -// MOVEL -case 0x2130: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2370: -case 0x2570: -case 0x2770: -case 0x2970: -case 0x2B70: -case 0x2D70: -case 0x2F70: -case 0x2171: -case 0x2371: -case 0x2571: -case 0x2771: -case 0x2971: -case 0x2B71: -case 0x2D71: -case 0x2F71: -case 0x2172: -case 0x2372: -case 0x2572: -case 0x2772: -case 0x2972: -case 0x2B72: -case 0x2D72: -case 0x2F72: -case 0x2173: -case 0x2373: -case 0x2573: -case 0x2773: -case 0x2973: -case 0x2B73: -case 0x2D73: -case 0x2F73: -case 0x2174: -case 0x2374: -case 0x2574: -case 0x2774: -case 0x2974: -case 0x2B74: -case 0x2D74: -case 0x2F74: -case 0x2175: -case 0x2375: -case 0x2575: -case 0x2775: -case 0x2975: -case 0x2B75: -case 0x2D75: -case 0x2F75: -case 0x2176: -case 0x2376: -case 0x2576: -case 0x2776: -case 0x2976: -case 0x2B76: -case 0x2D76: -case 0x2F76: -case 0x2177: -case 0x2377: -case 0x2577: -case 0x2777: -case 0x2977: -case 0x2B77: -case 0x2D77: -case 0x2F77: - -// MOVEL -case 0x2170: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x23B0: -case 0x25B0: -case 0x27B0: -case 0x29B0: -case 0x2BB0: -case 0x2DB0: -case 0x2FB0: -case 0x21B1: -case 0x23B1: -case 0x25B1: -case 0x27B1: -case 0x29B1: -case 0x2BB1: -case 0x2DB1: -case 0x2FB1: -case 0x21B2: -case 0x23B2: -case 0x25B2: -case 0x27B2: -case 0x29B2: -case 0x2BB2: -case 0x2DB2: -case 0x2FB2: -case 0x21B3: -case 0x23B3: -case 0x25B3: -case 0x27B3: -case 0x29B3: -case 0x2BB3: -case 0x2DB3: -case 0x2FB3: -case 0x21B4: -case 0x23B4: -case 0x25B4: -case 0x27B4: -case 0x29B4: -case 0x2BB4: -case 0x2DB4: -case 0x2FB4: -case 0x21B5: -case 0x23B5: -case 0x25B5: -case 0x27B5: -case 0x29B5: -case 0x2BB5: -case 0x2DB5: -case 0x2FB5: -case 0x21B6: -case 0x23B6: -case 0x25B6: -case 0x27B6: -case 0x29B6: -case 0x2BB6: -case 0x2DB6: -case 0x2FB6: -case 0x21B7: -case 0x23B7: -case 0x25B7: -case 0x27B7: -case 0x29B7: -case 0x2BB7: -case 0x2DB7: -case 0x2FB7: - -// MOVEL -case 0x21B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x21F1: -case 0x21F2: -case 0x21F3: -case 0x21F4: -case 0x21F5: -case 0x21F6: -case 0x21F7: - -// MOVEL -case 0x21F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x23F1: -case 0x23F2: -case 0x23F3: -case 0x23F4: -case 0x23F5: -case 0x23F6: -case 0x23F7: - -// MOVEL -case 0x23F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) -case 0x2EF1: -case 0x2EF2: -case 0x2EF3: -case 0x2EF4: -case 0x2EF5: -case 0x2EF6: -case 0x2EF7: - -// MOVEL -case 0x2EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2F31: -case 0x2F32: -case 0x2F33: -case 0x2F34: -case 0x2F35: -case 0x2F36: -case 0x2F37: - -// MOVEL -case 0x2F30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2238: -case 0x2438: -case 0x2638: -case 0x2838: -case 0x2A38: -case 0x2C38: -case 0x2E38: - -// MOVEL -case 0x2038: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x22B8: -case 0x24B8: -case 0x26B8: -case 0x28B8: -case 0x2AB8: -case 0x2CB8: -case 0x2EB8: - -// MOVEL -case 0x20B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x22F8: -case 0x24F8: -case 0x26F8: -case 0x28F8: -case 0x2AF8: -case 0x2CF8: - -// MOVEL -case 0x20F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2338: -case 0x2538: -case 0x2738: -case 0x2938: -case 0x2B38: -case 0x2D38: - -// MOVEL -case 0x2138: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2378: -case 0x2578: -case 0x2778: -case 0x2978: -case 0x2B78: -case 0x2D78: -case 0x2F78: - -// MOVEL -case 0x2178: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23B8: -case 0x25B8: -case 0x27B8: -case 0x29B8: -case 0x2BB8: -case 0x2DB8: -case 0x2FB8: - -// MOVEL -case 0x21B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x21F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x23F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x2EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x2F38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2239: -case 0x2439: -case 0x2639: -case 0x2839: -case 0x2A39: -case 0x2C39: -case 0x2E39: - -// MOVEL -case 0x2039: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x22B9: -case 0x24B9: -case 0x26B9: -case 0x28B9: -case 0x2AB9: -case 0x2CB9: -case 0x2EB9: - -// MOVEL -case 0x20B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x22F9: -case 0x24F9: -case 0x26F9: -case 0x28F9: -case 0x2AF9: -case 0x2CF9: - -// MOVEL -case 0x20F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2339: -case 0x2539: -case 0x2739: -case 0x2939: -case 0x2B39: -case 0x2D39: - -// MOVEL -case 0x2139: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2379: -case 0x2579: -case 0x2779: -case 0x2979: -case 0x2B79: -case 0x2D79: -case 0x2F79: - -// MOVEL -case 0x2179: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x23B9: -case 0x25B9: -case 0x27B9: -case 0x29B9: -case 0x2BB9: -case 0x2DB9: -case 0x2FB9: - -// MOVEL -case 0x21B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// MOVEL -case 0x21F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x23F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// MOVEL -case 0x2EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x2F39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x223A: -case 0x243A: -case 0x263A: -case 0x283A: -case 0x2A3A: -case 0x2C3A: -case 0x2E3A: - -// MOVEL -case 0x203A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x22BA: -case 0x24BA: -case 0x26BA: -case 0x28BA: -case 0x2ABA: -case 0x2CBA: -case 0x2EBA: - -// MOVEL -case 0x20BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x22FA: -case 0x24FA: -case 0x26FA: -case 0x28FA: -case 0x2AFA: -case 0x2CFA: - -// MOVEL -case 0x20FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x233A: -case 0x253A: -case 0x273A: -case 0x293A: -case 0x2B3A: -case 0x2D3A: - -// MOVEL -case 0x213A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x237A: -case 0x257A: -case 0x277A: -case 0x297A: -case 0x2B7A: -case 0x2D7A: -case 0x2F7A: - -// MOVEL -case 0x217A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23BA: -case 0x25BA: -case 0x27BA: -case 0x29BA: -case 0x2BBA: -case 0x2DBA: -case 0x2FBA: - -// MOVEL -case 0x21BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x21FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x23FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x2EFA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x2F3A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x223B: -case 0x243B: -case 0x263B: -case 0x283B: -case 0x2A3B: -case 0x2C3B: -case 0x2E3B: - -// MOVEL -case 0x203B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x22BB: -case 0x24BB: -case 0x26BB: -case 0x28BB: -case 0x2ABB: -case 0x2CBB: -case 0x2EBB: - -// MOVEL -case 0x20BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x22FB: -case 0x24FB: -case 0x26FB: -case 0x28FB: -case 0x2AFB: -case 0x2CFB: - -// MOVEL -case 0x20FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x233B: -case 0x253B: -case 0x273B: -case 0x293B: -case 0x2B3B: -case 0x2D3B: - -// MOVEL -case 0x213B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x237B: -case 0x257B: -case 0x277B: -case 0x297B: -case 0x2B7B: -case 0x2D7B: -case 0x2F7B: - -// MOVEL -case 0x217B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x23BB: -case 0x25BB: -case 0x27BB: -case 0x29BB: -case 0x2BBB: -case 0x2DBB: -case 0x2FBB: - -// MOVEL -case 0x21BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x21FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x23FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// MOVEL -case 0x2EFB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x2F3B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x223C: -case 0x243C: -case 0x263C: -case 0x283C: -case 0x2A3C: -case 0x2C3C: -case 0x2E3C: - -// MOVEL -case 0x203C: -{ - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(12) -case 0x22BC: -case 0x24BC: -case 0x26BC: -case 0x28BC: -case 0x2ABC: -case 0x2CBC: -case 0x2EBC: - -// MOVEL -case 0x20BC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22FC: -case 0x24FC: -case 0x26FC: -case 0x28FC: -case 0x2AFC: -case 0x2CFC: - -// MOVEL -case 0x20FC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x233C: -case 0x253C: -case 0x273C: -case 0x293C: -case 0x2B3C: -case 0x2D3C: - -// MOVEL -case 0x213C: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x237C: -case 0x257C: -case 0x277C: -case 0x297C: -case 0x2B7C: -case 0x2D7C: -case 0x2F7C: - -// MOVEL -case 0x217C: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x23BC: -case 0x25BC: -case 0x27BC: -case 0x29BC: -case 0x2BBC: -case 0x2DBC: -case 0x2FBC: - -// MOVEL -case 0x21BC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x21FC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x23FC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x2EFC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// MOVEL -case 0x2F3C: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x221F: -case 0x241F: -case 0x261F: -case 0x281F: -case 0x2A1F: -case 0x2C1F: -case 0x2E1F: - -// MOVEL -case 0x201F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x229F: -case 0x249F: -case 0x269F: -case 0x289F: -case 0x2A9F: -case 0x2C9F: -case 0x2E9F: - -// MOVEL -case 0x209F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22DF: -case 0x24DF: -case 0x26DF: -case 0x28DF: -case 0x2ADF: -case 0x2CDF: - -// MOVEL -case 0x20DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x231F: -case 0x251F: -case 0x271F: -case 0x291F: -case 0x2B1F: -case 0x2D1F: - -// MOVEL -case 0x211F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x235F: -case 0x255F: -case 0x275F: -case 0x295F: -case 0x2B5F: -case 0x2D5F: -case 0x2F5F: - -// MOVEL -case 0x215F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x239F: -case 0x259F: -case 0x279F: -case 0x299F: -case 0x2B9F: -case 0x2D9F: -case 0x2F9F: - -// MOVEL -case 0x219F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x21DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x23DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x2EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// MOVEL -case 0x2F1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2227: -case 0x2427: -case 0x2627: -case 0x2827: -case 0x2A27: -case 0x2C27: -case 0x2E27: - -// MOVEL -case 0x2027: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x22A7: -case 0x24A7: -case 0x26A7: -case 0x28A7: -case 0x2AA7: -case 0x2CA7: -case 0x2EA7: - -// MOVEL -case 0x20A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x22E7: -case 0x24E7: -case 0x26E7: -case 0x28E7: -case 0x2AE7: -case 0x2CE7: - -// MOVEL -case 0x20E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2327: -case 0x2527: -case 0x2727: -case 0x2927: -case 0x2B27: -case 0x2D27: - -// MOVEL -case 0x2127: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2367: -case 0x2567: -case 0x2767: -case 0x2967: -case 0x2B67: -case 0x2D67: -case 0x2F67: - -// MOVEL -case 0x2167: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x23A7: -case 0x25A7: -case 0x27A7: -case 0x29A7: -case 0x2BA7: -case 0x2DA7: -case 0x2FA7: - -// MOVEL -case 0x21A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x21E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x23E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x2EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) - -// MOVEL -case 0x2F27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2240: -case 0x2440: -case 0x2640: -case 0x2840: -case 0x2A40: -case 0x2C40: -case 0x2E40: -case 0x2041: -case 0x2241: -case 0x2441: -case 0x2641: -case 0x2841: -case 0x2A41: -case 0x2C41: -case 0x2E41: -case 0x2042: -case 0x2242: -case 0x2442: -case 0x2642: -case 0x2842: -case 0x2A42: -case 0x2C42: -case 0x2E42: -case 0x2043: -case 0x2243: -case 0x2443: -case 0x2643: -case 0x2843: -case 0x2A43: -case 0x2C43: -case 0x2E43: -case 0x2044: -case 0x2244: -case 0x2444: -case 0x2644: -case 0x2844: -case 0x2A44: -case 0x2C44: -case 0x2E44: -case 0x2045: -case 0x2245: -case 0x2445: -case 0x2645: -case 0x2845: -case 0x2A45: -case 0x2C45: -case 0x2E45: -case 0x2046: -case 0x2246: -case 0x2446: -case 0x2646: -case 0x2846: -case 0x2A46: -case 0x2C46: -case 0x2E46: -case 0x2047: -case 0x2247: -case 0x2447: -case 0x2647: -case 0x2847: -case 0x2A47: -case 0x2C47: -case 0x2E47: - -// MOVEAL -case 0x2040: -{ - u32 res; - res = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x2248: -case 0x2448: -case 0x2648: -case 0x2848: -case 0x2A48: -case 0x2C48: -case 0x2E48: -case 0x2049: -case 0x2249: -case 0x2449: -case 0x2649: -case 0x2849: -case 0x2A49: -case 0x2C49: -case 0x2E49: -case 0x204A: -case 0x224A: -case 0x244A: -case 0x264A: -case 0x284A: -case 0x2A4A: -case 0x2C4A: -case 0x2E4A: -case 0x204B: -case 0x224B: -case 0x244B: -case 0x264B: -case 0x284B: -case 0x2A4B: -case 0x2C4B: -case 0x2E4B: -case 0x204C: -case 0x224C: -case 0x244C: -case 0x264C: -case 0x284C: -case 0x2A4C: -case 0x2C4C: -case 0x2E4C: -case 0x204D: -case 0x224D: -case 0x244D: -case 0x264D: -case 0x284D: -case 0x2A4D: -case 0x2C4D: -case 0x2E4D: -case 0x204E: -case 0x224E: -case 0x244E: -case 0x264E: -case 0x284E: -case 0x2A4E: -case 0x2C4E: -case 0x2E4E: -case 0x204F: -case 0x224F: -case 0x244F: -case 0x264F: -case 0x284F: -case 0x2A4F: -case 0x2C4F: -case 0x2E4F: - -// MOVEAL -case 0x2048: -{ - u32 res; - res = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x2250: -case 0x2450: -case 0x2650: -case 0x2850: -case 0x2A50: -case 0x2C50: -case 0x2E50: -case 0x2051: -case 0x2251: -case 0x2451: -case 0x2651: -case 0x2851: -case 0x2A51: -case 0x2C51: -case 0x2E51: -case 0x2052: -case 0x2252: -case 0x2452: -case 0x2652: -case 0x2852: -case 0x2A52: -case 0x2C52: -case 0x2E52: -case 0x2053: -case 0x2253: -case 0x2453: -case 0x2653: -case 0x2853: -case 0x2A53: -case 0x2C53: -case 0x2E53: -case 0x2054: -case 0x2254: -case 0x2454: -case 0x2654: -case 0x2854: -case 0x2A54: -case 0x2C54: -case 0x2E54: -case 0x2055: -case 0x2255: -case 0x2455: -case 0x2655: -case 0x2855: -case 0x2A55: -case 0x2C55: -case 0x2E55: -case 0x2056: -case 0x2256: -case 0x2456: -case 0x2656: -case 0x2856: -case 0x2A56: -case 0x2C56: -case 0x2E56: -case 0x2057: -case 0x2257: -case 0x2457: -case 0x2657: -case 0x2857: -case 0x2A57: -case 0x2C57: -case 0x2E57: - -// MOVEAL -case 0x2050: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x2258: -case 0x2458: -case 0x2658: -case 0x2858: -case 0x2A58: -case 0x2C58: -case 0x2E58: -case 0x2059: -case 0x2259: -case 0x2459: -case 0x2659: -case 0x2859: -case 0x2A59: -case 0x2C59: -case 0x2E59: -case 0x205A: -case 0x225A: -case 0x245A: -case 0x265A: -case 0x285A: -case 0x2A5A: -case 0x2C5A: -case 0x2E5A: -case 0x205B: -case 0x225B: -case 0x245B: -case 0x265B: -case 0x285B: -case 0x2A5B: -case 0x2C5B: -case 0x2E5B: -case 0x205C: -case 0x225C: -case 0x245C: -case 0x265C: -case 0x285C: -case 0x2A5C: -case 0x2C5C: -case 0x2E5C: -case 0x205D: -case 0x225D: -case 0x245D: -case 0x265D: -case 0x285D: -case 0x2A5D: -case 0x2C5D: -case 0x2E5D: -case 0x205E: -case 0x225E: -case 0x245E: -case 0x265E: -case 0x285E: -case 0x2A5E: -case 0x2C5E: -case 0x2E5E: - -// MOVEAL -case 0x2058: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x2260: -case 0x2460: -case 0x2660: -case 0x2860: -case 0x2A60: -case 0x2C60: -case 0x2E60: -case 0x2061: -case 0x2261: -case 0x2461: -case 0x2661: -case 0x2861: -case 0x2A61: -case 0x2C61: -case 0x2E61: -case 0x2062: -case 0x2262: -case 0x2462: -case 0x2662: -case 0x2862: -case 0x2A62: -case 0x2C62: -case 0x2E62: -case 0x2063: -case 0x2263: -case 0x2463: -case 0x2663: -case 0x2863: -case 0x2A63: -case 0x2C63: -case 0x2E63: -case 0x2064: -case 0x2264: -case 0x2464: -case 0x2664: -case 0x2864: -case 0x2A64: -case 0x2C64: -case 0x2E64: -case 0x2065: -case 0x2265: -case 0x2465: -case 0x2665: -case 0x2865: -case 0x2A65: -case 0x2C65: -case 0x2E65: -case 0x2066: -case 0x2266: -case 0x2466: -case 0x2666: -case 0x2866: -case 0x2A66: -case 0x2C66: -case 0x2E66: - -// MOVEAL -case 0x2060: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x2268: -case 0x2468: -case 0x2668: -case 0x2868: -case 0x2A68: -case 0x2C68: -case 0x2E68: -case 0x2069: -case 0x2269: -case 0x2469: -case 0x2669: -case 0x2869: -case 0x2A69: -case 0x2C69: -case 0x2E69: -case 0x206A: -case 0x226A: -case 0x246A: -case 0x266A: -case 0x286A: -case 0x2A6A: -case 0x2C6A: -case 0x2E6A: -case 0x206B: -case 0x226B: -case 0x246B: -case 0x266B: -case 0x286B: -case 0x2A6B: -case 0x2C6B: -case 0x2E6B: -case 0x206C: -case 0x226C: -case 0x246C: -case 0x266C: -case 0x286C: -case 0x2A6C: -case 0x2C6C: -case 0x2E6C: -case 0x206D: -case 0x226D: -case 0x246D: -case 0x266D: -case 0x286D: -case 0x2A6D: -case 0x2C6D: -case 0x2E6D: -case 0x206E: -case 0x226E: -case 0x246E: -case 0x266E: -case 0x286E: -case 0x2A6E: -case 0x2C6E: -case 0x2E6E: -case 0x206F: -case 0x226F: -case 0x246F: -case 0x266F: -case 0x286F: -case 0x2A6F: -case 0x2C6F: -case 0x2E6F: - -// MOVEAL -case 0x2068: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x2270: -case 0x2470: -case 0x2670: -case 0x2870: -case 0x2A70: -case 0x2C70: -case 0x2E70: -case 0x2071: -case 0x2271: -case 0x2471: -case 0x2671: -case 0x2871: -case 0x2A71: -case 0x2C71: -case 0x2E71: -case 0x2072: -case 0x2272: -case 0x2472: -case 0x2672: -case 0x2872: -case 0x2A72: -case 0x2C72: -case 0x2E72: -case 0x2073: -case 0x2273: -case 0x2473: -case 0x2673: -case 0x2873: -case 0x2A73: -case 0x2C73: -case 0x2E73: -case 0x2074: -case 0x2274: -case 0x2474: -case 0x2674: -case 0x2874: -case 0x2A74: -case 0x2C74: -case 0x2E74: -case 0x2075: -case 0x2275: -case 0x2475: -case 0x2675: -case 0x2875: -case 0x2A75: -case 0x2C75: -case 0x2E75: -case 0x2076: -case 0x2276: -case 0x2476: -case 0x2676: -case 0x2876: -case 0x2A76: -case 0x2C76: -case 0x2E76: -case 0x2077: -case 0x2277: -case 0x2477: -case 0x2677: -case 0x2877: -case 0x2A77: -case 0x2C77: -case 0x2E77: - -// MOVEAL -case 0x2070: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x2278: -case 0x2478: -case 0x2678: -case 0x2878: -case 0x2A78: -case 0x2C78: -case 0x2E78: - -// MOVEAL -case 0x2078: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x2279: -case 0x2479: -case 0x2679: -case 0x2879: -case 0x2A79: -case 0x2C79: -case 0x2E79: - -// MOVEAL -case 0x2079: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x227A: -case 0x247A: -case 0x267A: -case 0x287A: -case 0x2A7A: -case 0x2C7A: -case 0x2E7A: - -// MOVEAL -case 0x207A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x227B: -case 0x247B: -case 0x267B: -case 0x287B: -case 0x2A7B: -case 0x2C7B: -case 0x2E7B: - -// MOVEAL -case 0x207B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x227C: -case 0x247C: -case 0x267C: -case 0x287C: -case 0x2A7C: -case 0x2C7C: -case 0x2E7C: - -// MOVEAL -case 0x207C: -{ - u32 res; - res = (s32)(s32)FETCH_LONG; - PC += 4; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x225F: -case 0x245F: -case 0x265F: -case 0x285F: -case 0x2A5F: -case 0x2C5F: -case 0x2E5F: - -// MOVEAL -case 0x205F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x2267: -case 0x2467: -case 0x2667: -case 0x2867: -case 0x2A67: -case 0x2C67: -case 0x2E67: - -// MOVEAL -case 0x2067: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) diff --git a/yabause/src/c68k/c68k_op3.inc b/yabause/src/c68k/c68k_op3.inc deleted file mode 100644 index f1bbdc58ad..0000000000 --- a/yabause/src/c68k/c68k_op3.inc +++ /dev/null @@ -1,6254 +0,0 @@ -case 0x3200: -case 0x3400: -case 0x3600: -case 0x3800: -case 0x3A00: -case 0x3C00: -case 0x3E00: -case 0x3001: -case 0x3201: -case 0x3401: -case 0x3601: -case 0x3801: -case 0x3A01: -case 0x3C01: -case 0x3E01: -case 0x3002: -case 0x3202: -case 0x3402: -case 0x3602: -case 0x3802: -case 0x3A02: -case 0x3C02: -case 0x3E02: -case 0x3003: -case 0x3203: -case 0x3403: -case 0x3603: -case 0x3803: -case 0x3A03: -case 0x3C03: -case 0x3E03: -case 0x3004: -case 0x3204: -case 0x3404: -case 0x3604: -case 0x3804: -case 0x3A04: -case 0x3C04: -case 0x3E04: -case 0x3005: -case 0x3205: -case 0x3405: -case 0x3605: -case 0x3805: -case 0x3A05: -case 0x3C05: -case 0x3E05: -case 0x3006: -case 0x3206: -case 0x3406: -case 0x3606: -case 0x3806: -case 0x3A06: -case 0x3C06: -case 0x3E06: -case 0x3007: -case 0x3207: -case 0x3407: -case 0x3607: -case 0x3807: -case 0x3A07: -case 0x3C07: -case 0x3E07: - -// MOVEW -case 0x3000: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x3280: -case 0x3480: -case 0x3680: -case 0x3880: -case 0x3A80: -case 0x3C80: -case 0x3E80: -case 0x3081: -case 0x3281: -case 0x3481: -case 0x3681: -case 0x3881: -case 0x3A81: -case 0x3C81: -case 0x3E81: -case 0x3082: -case 0x3282: -case 0x3482: -case 0x3682: -case 0x3882: -case 0x3A82: -case 0x3C82: -case 0x3E82: -case 0x3083: -case 0x3283: -case 0x3483: -case 0x3683: -case 0x3883: -case 0x3A83: -case 0x3C83: -case 0x3E83: -case 0x3084: -case 0x3284: -case 0x3484: -case 0x3684: -case 0x3884: -case 0x3A84: -case 0x3C84: -case 0x3E84: -case 0x3085: -case 0x3285: -case 0x3485: -case 0x3685: -case 0x3885: -case 0x3A85: -case 0x3C85: -case 0x3E85: -case 0x3086: -case 0x3286: -case 0x3486: -case 0x3686: -case 0x3886: -case 0x3A86: -case 0x3C86: -case 0x3E86: -case 0x3087: -case 0x3287: -case 0x3487: -case 0x3687: -case 0x3887: -case 0x3A87: -case 0x3C87: -case 0x3E87: - -// MOVEW -case 0x3080: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x32C0: -case 0x34C0: -case 0x36C0: -case 0x38C0: -case 0x3AC0: -case 0x3CC0: -case 0x30C1: -case 0x32C1: -case 0x34C1: -case 0x36C1: -case 0x38C1: -case 0x3AC1: -case 0x3CC1: -case 0x30C2: -case 0x32C2: -case 0x34C2: -case 0x36C2: -case 0x38C2: -case 0x3AC2: -case 0x3CC2: -case 0x30C3: -case 0x32C3: -case 0x34C3: -case 0x36C3: -case 0x38C3: -case 0x3AC3: -case 0x3CC3: -case 0x30C4: -case 0x32C4: -case 0x34C4: -case 0x36C4: -case 0x38C4: -case 0x3AC4: -case 0x3CC4: -case 0x30C5: -case 0x32C5: -case 0x34C5: -case 0x36C5: -case 0x38C5: -case 0x3AC5: -case 0x3CC5: -case 0x30C6: -case 0x32C6: -case 0x34C6: -case 0x36C6: -case 0x38C6: -case 0x3AC6: -case 0x3CC6: -case 0x30C7: -case 0x32C7: -case 0x34C7: -case 0x36C7: -case 0x38C7: -case 0x3AC7: -case 0x3CC7: - -// MOVEW -case 0x30C0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3300: -case 0x3500: -case 0x3700: -case 0x3900: -case 0x3B00: -case 0x3D00: -case 0x3101: -case 0x3301: -case 0x3501: -case 0x3701: -case 0x3901: -case 0x3B01: -case 0x3D01: -case 0x3102: -case 0x3302: -case 0x3502: -case 0x3702: -case 0x3902: -case 0x3B02: -case 0x3D02: -case 0x3103: -case 0x3303: -case 0x3503: -case 0x3703: -case 0x3903: -case 0x3B03: -case 0x3D03: -case 0x3104: -case 0x3304: -case 0x3504: -case 0x3704: -case 0x3904: -case 0x3B04: -case 0x3D04: -case 0x3105: -case 0x3305: -case 0x3505: -case 0x3705: -case 0x3905: -case 0x3B05: -case 0x3D05: -case 0x3106: -case 0x3306: -case 0x3506: -case 0x3706: -case 0x3906: -case 0x3B06: -case 0x3D06: -case 0x3107: -case 0x3307: -case 0x3507: -case 0x3707: -case 0x3907: -case 0x3B07: -case 0x3D07: - -// MOVEW -case 0x3100: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3340: -case 0x3540: -case 0x3740: -case 0x3940: -case 0x3B40: -case 0x3D40: -case 0x3F40: -case 0x3141: -case 0x3341: -case 0x3541: -case 0x3741: -case 0x3941: -case 0x3B41: -case 0x3D41: -case 0x3F41: -case 0x3142: -case 0x3342: -case 0x3542: -case 0x3742: -case 0x3942: -case 0x3B42: -case 0x3D42: -case 0x3F42: -case 0x3143: -case 0x3343: -case 0x3543: -case 0x3743: -case 0x3943: -case 0x3B43: -case 0x3D43: -case 0x3F43: -case 0x3144: -case 0x3344: -case 0x3544: -case 0x3744: -case 0x3944: -case 0x3B44: -case 0x3D44: -case 0x3F44: -case 0x3145: -case 0x3345: -case 0x3545: -case 0x3745: -case 0x3945: -case 0x3B45: -case 0x3D45: -case 0x3F45: -case 0x3146: -case 0x3346: -case 0x3546: -case 0x3746: -case 0x3946: -case 0x3B46: -case 0x3D46: -case 0x3F46: -case 0x3147: -case 0x3347: -case 0x3547: -case 0x3747: -case 0x3947: -case 0x3B47: -case 0x3D47: -case 0x3F47: - -// MOVEW -case 0x3140: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3380: -case 0x3580: -case 0x3780: -case 0x3980: -case 0x3B80: -case 0x3D80: -case 0x3F80: -case 0x3181: -case 0x3381: -case 0x3581: -case 0x3781: -case 0x3981: -case 0x3B81: -case 0x3D81: -case 0x3F81: -case 0x3182: -case 0x3382: -case 0x3582: -case 0x3782: -case 0x3982: -case 0x3B82: -case 0x3D82: -case 0x3F82: -case 0x3183: -case 0x3383: -case 0x3583: -case 0x3783: -case 0x3983: -case 0x3B83: -case 0x3D83: -case 0x3F83: -case 0x3184: -case 0x3384: -case 0x3584: -case 0x3784: -case 0x3984: -case 0x3B84: -case 0x3D84: -case 0x3F84: -case 0x3185: -case 0x3385: -case 0x3585: -case 0x3785: -case 0x3985: -case 0x3B85: -case 0x3D85: -case 0x3F85: -case 0x3186: -case 0x3386: -case 0x3586: -case 0x3786: -case 0x3986: -case 0x3B86: -case 0x3D86: -case 0x3F86: -case 0x3187: -case 0x3387: -case 0x3587: -case 0x3787: -case 0x3987: -case 0x3B87: -case 0x3D87: -case 0x3F87: - -// MOVEW -case 0x3180: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x31C1: -case 0x31C2: -case 0x31C3: -case 0x31C4: -case 0x31C5: -case 0x31C6: -case 0x31C7: - -// MOVEW -case 0x31C0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x33C1: -case 0x33C2: -case 0x33C3: -case 0x33C4: -case 0x33C5: -case 0x33C6: -case 0x33C7: - -// MOVEW -case 0x33C0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3EC1: -case 0x3EC2: -case 0x3EC3: -case 0x3EC4: -case 0x3EC5: -case 0x3EC6: -case 0x3EC7: - -// MOVEW -case 0x3EC0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3F01: -case 0x3F02: -case 0x3F03: -case 0x3F04: -case 0x3F05: -case 0x3F06: -case 0x3F07: - -// MOVEW -case 0x3F00: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3208: -case 0x3408: -case 0x3608: -case 0x3808: -case 0x3A08: -case 0x3C08: -case 0x3E08: -case 0x3009: -case 0x3209: -case 0x3409: -case 0x3609: -case 0x3809: -case 0x3A09: -case 0x3C09: -case 0x3E09: -case 0x300A: -case 0x320A: -case 0x340A: -case 0x360A: -case 0x380A: -case 0x3A0A: -case 0x3C0A: -case 0x3E0A: -case 0x300B: -case 0x320B: -case 0x340B: -case 0x360B: -case 0x380B: -case 0x3A0B: -case 0x3C0B: -case 0x3E0B: -case 0x300C: -case 0x320C: -case 0x340C: -case 0x360C: -case 0x380C: -case 0x3A0C: -case 0x3C0C: -case 0x3E0C: -case 0x300D: -case 0x320D: -case 0x340D: -case 0x360D: -case 0x380D: -case 0x3A0D: -case 0x3C0D: -case 0x3E0D: -case 0x300E: -case 0x320E: -case 0x340E: -case 0x360E: -case 0x380E: -case 0x3A0E: -case 0x3C0E: -case 0x3E0E: -case 0x300F: -case 0x320F: -case 0x340F: -case 0x360F: -case 0x380F: -case 0x3A0F: -case 0x3C0F: -case 0x3E0F: - -// MOVEW -case 0x3008: -{ - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x3288: -case 0x3488: -case 0x3688: -case 0x3888: -case 0x3A88: -case 0x3C88: -case 0x3E88: -case 0x3089: -case 0x3289: -case 0x3489: -case 0x3689: -case 0x3889: -case 0x3A89: -case 0x3C89: -case 0x3E89: -case 0x308A: -case 0x328A: -case 0x348A: -case 0x368A: -case 0x388A: -case 0x3A8A: -case 0x3C8A: -case 0x3E8A: -case 0x308B: -case 0x328B: -case 0x348B: -case 0x368B: -case 0x388B: -case 0x3A8B: -case 0x3C8B: -case 0x3E8B: -case 0x308C: -case 0x328C: -case 0x348C: -case 0x368C: -case 0x388C: -case 0x3A8C: -case 0x3C8C: -case 0x3E8C: -case 0x308D: -case 0x328D: -case 0x348D: -case 0x368D: -case 0x388D: -case 0x3A8D: -case 0x3C8D: -case 0x3E8D: -case 0x308E: -case 0x328E: -case 0x348E: -case 0x368E: -case 0x388E: -case 0x3A8E: -case 0x3C8E: -case 0x3E8E: -case 0x308F: -case 0x328F: -case 0x348F: -case 0x368F: -case 0x388F: -case 0x3A8F: -case 0x3C8F: -case 0x3E8F: - -// MOVEW -case 0x3088: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x32C8: -case 0x34C8: -case 0x36C8: -case 0x38C8: -case 0x3AC8: -case 0x3CC8: -case 0x30C9: -case 0x32C9: -case 0x34C9: -case 0x36C9: -case 0x38C9: -case 0x3AC9: -case 0x3CC9: -case 0x30CA: -case 0x32CA: -case 0x34CA: -case 0x36CA: -case 0x38CA: -case 0x3ACA: -case 0x3CCA: -case 0x30CB: -case 0x32CB: -case 0x34CB: -case 0x36CB: -case 0x38CB: -case 0x3ACB: -case 0x3CCB: -case 0x30CC: -case 0x32CC: -case 0x34CC: -case 0x36CC: -case 0x38CC: -case 0x3ACC: -case 0x3CCC: -case 0x30CD: -case 0x32CD: -case 0x34CD: -case 0x36CD: -case 0x38CD: -case 0x3ACD: -case 0x3CCD: -case 0x30CE: -case 0x32CE: -case 0x34CE: -case 0x36CE: -case 0x38CE: -case 0x3ACE: -case 0x3CCE: -case 0x30CF: -case 0x32CF: -case 0x34CF: -case 0x36CF: -case 0x38CF: -case 0x3ACF: -case 0x3CCF: - -// MOVEW -case 0x30C8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3308: -case 0x3508: -case 0x3708: -case 0x3908: -case 0x3B08: -case 0x3D08: -case 0x3109: -case 0x3309: -case 0x3509: -case 0x3709: -case 0x3909: -case 0x3B09: -case 0x3D09: -case 0x310A: -case 0x330A: -case 0x350A: -case 0x370A: -case 0x390A: -case 0x3B0A: -case 0x3D0A: -case 0x310B: -case 0x330B: -case 0x350B: -case 0x370B: -case 0x390B: -case 0x3B0B: -case 0x3D0B: -case 0x310C: -case 0x330C: -case 0x350C: -case 0x370C: -case 0x390C: -case 0x3B0C: -case 0x3D0C: -case 0x310D: -case 0x330D: -case 0x350D: -case 0x370D: -case 0x390D: -case 0x3B0D: -case 0x3D0D: -case 0x310E: -case 0x330E: -case 0x350E: -case 0x370E: -case 0x390E: -case 0x3B0E: -case 0x3D0E: -case 0x310F: -case 0x330F: -case 0x350F: -case 0x370F: -case 0x390F: -case 0x3B0F: -case 0x3D0F: - -// MOVEW -case 0x3108: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3348: -case 0x3548: -case 0x3748: -case 0x3948: -case 0x3B48: -case 0x3D48: -case 0x3F48: -case 0x3149: -case 0x3349: -case 0x3549: -case 0x3749: -case 0x3949: -case 0x3B49: -case 0x3D49: -case 0x3F49: -case 0x314A: -case 0x334A: -case 0x354A: -case 0x374A: -case 0x394A: -case 0x3B4A: -case 0x3D4A: -case 0x3F4A: -case 0x314B: -case 0x334B: -case 0x354B: -case 0x374B: -case 0x394B: -case 0x3B4B: -case 0x3D4B: -case 0x3F4B: -case 0x314C: -case 0x334C: -case 0x354C: -case 0x374C: -case 0x394C: -case 0x3B4C: -case 0x3D4C: -case 0x3F4C: -case 0x314D: -case 0x334D: -case 0x354D: -case 0x374D: -case 0x394D: -case 0x3B4D: -case 0x3D4D: -case 0x3F4D: -case 0x314E: -case 0x334E: -case 0x354E: -case 0x374E: -case 0x394E: -case 0x3B4E: -case 0x3D4E: -case 0x3F4E: -case 0x314F: -case 0x334F: -case 0x354F: -case 0x374F: -case 0x394F: -case 0x3B4F: -case 0x3D4F: -case 0x3F4F: - -// MOVEW -case 0x3148: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3388: -case 0x3588: -case 0x3788: -case 0x3988: -case 0x3B88: -case 0x3D88: -case 0x3F88: -case 0x3189: -case 0x3389: -case 0x3589: -case 0x3789: -case 0x3989: -case 0x3B89: -case 0x3D89: -case 0x3F89: -case 0x318A: -case 0x338A: -case 0x358A: -case 0x378A: -case 0x398A: -case 0x3B8A: -case 0x3D8A: -case 0x3F8A: -case 0x318B: -case 0x338B: -case 0x358B: -case 0x378B: -case 0x398B: -case 0x3B8B: -case 0x3D8B: -case 0x3F8B: -case 0x318C: -case 0x338C: -case 0x358C: -case 0x378C: -case 0x398C: -case 0x3B8C: -case 0x3D8C: -case 0x3F8C: -case 0x318D: -case 0x338D: -case 0x358D: -case 0x378D: -case 0x398D: -case 0x3B8D: -case 0x3D8D: -case 0x3F8D: -case 0x318E: -case 0x338E: -case 0x358E: -case 0x378E: -case 0x398E: -case 0x3B8E: -case 0x3D8E: -case 0x3F8E: -case 0x318F: -case 0x338F: -case 0x358F: -case 0x378F: -case 0x398F: -case 0x3B8F: -case 0x3D8F: -case 0x3F8F: - -// MOVEW -case 0x3188: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x31C9: -case 0x31CA: -case 0x31CB: -case 0x31CC: -case 0x31CD: -case 0x31CE: -case 0x31CF: - -// MOVEW -case 0x31C8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x33C9: -case 0x33CA: -case 0x33CB: -case 0x33CC: -case 0x33CD: -case 0x33CE: -case 0x33CF: - -// MOVEW -case 0x33C8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3EC9: -case 0x3ECA: -case 0x3ECB: -case 0x3ECC: -case 0x3ECD: -case 0x3ECE: -case 0x3ECF: - -// MOVEW -case 0x3EC8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3F09: -case 0x3F0A: -case 0x3F0B: -case 0x3F0C: -case 0x3F0D: -case 0x3F0E: -case 0x3F0F: - -// MOVEW -case 0x3F08: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3210: -case 0x3410: -case 0x3610: -case 0x3810: -case 0x3A10: -case 0x3C10: -case 0x3E10: -case 0x3011: -case 0x3211: -case 0x3411: -case 0x3611: -case 0x3811: -case 0x3A11: -case 0x3C11: -case 0x3E11: -case 0x3012: -case 0x3212: -case 0x3412: -case 0x3612: -case 0x3812: -case 0x3A12: -case 0x3C12: -case 0x3E12: -case 0x3013: -case 0x3213: -case 0x3413: -case 0x3613: -case 0x3813: -case 0x3A13: -case 0x3C13: -case 0x3E13: -case 0x3014: -case 0x3214: -case 0x3414: -case 0x3614: -case 0x3814: -case 0x3A14: -case 0x3C14: -case 0x3E14: -case 0x3015: -case 0x3215: -case 0x3415: -case 0x3615: -case 0x3815: -case 0x3A15: -case 0x3C15: -case 0x3E15: -case 0x3016: -case 0x3216: -case 0x3416: -case 0x3616: -case 0x3816: -case 0x3A16: -case 0x3C16: -case 0x3E16: -case 0x3017: -case 0x3217: -case 0x3417: -case 0x3617: -case 0x3817: -case 0x3A17: -case 0x3C17: -case 0x3E17: - -// MOVEW -case 0x3010: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x3290: -case 0x3490: -case 0x3690: -case 0x3890: -case 0x3A90: -case 0x3C90: -case 0x3E90: -case 0x3091: -case 0x3291: -case 0x3491: -case 0x3691: -case 0x3891: -case 0x3A91: -case 0x3C91: -case 0x3E91: -case 0x3092: -case 0x3292: -case 0x3492: -case 0x3692: -case 0x3892: -case 0x3A92: -case 0x3C92: -case 0x3E92: -case 0x3093: -case 0x3293: -case 0x3493: -case 0x3693: -case 0x3893: -case 0x3A93: -case 0x3C93: -case 0x3E93: -case 0x3094: -case 0x3294: -case 0x3494: -case 0x3694: -case 0x3894: -case 0x3A94: -case 0x3C94: -case 0x3E94: -case 0x3095: -case 0x3295: -case 0x3495: -case 0x3695: -case 0x3895: -case 0x3A95: -case 0x3C95: -case 0x3E95: -case 0x3096: -case 0x3296: -case 0x3496: -case 0x3696: -case 0x3896: -case 0x3A96: -case 0x3C96: -case 0x3E96: -case 0x3097: -case 0x3297: -case 0x3497: -case 0x3697: -case 0x3897: -case 0x3A97: -case 0x3C97: -case 0x3E97: - -// MOVEW -case 0x3090: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32D0: -case 0x34D0: -case 0x36D0: -case 0x38D0: -case 0x3AD0: -case 0x3CD0: -case 0x30D1: -case 0x32D1: -case 0x34D1: -case 0x36D1: -case 0x38D1: -case 0x3AD1: -case 0x3CD1: -case 0x30D2: -case 0x32D2: -case 0x34D2: -case 0x36D2: -case 0x38D2: -case 0x3AD2: -case 0x3CD2: -case 0x30D3: -case 0x32D3: -case 0x34D3: -case 0x36D3: -case 0x38D3: -case 0x3AD3: -case 0x3CD3: -case 0x30D4: -case 0x32D4: -case 0x34D4: -case 0x36D4: -case 0x38D4: -case 0x3AD4: -case 0x3CD4: -case 0x30D5: -case 0x32D5: -case 0x34D5: -case 0x36D5: -case 0x38D5: -case 0x3AD5: -case 0x3CD5: -case 0x30D6: -case 0x32D6: -case 0x34D6: -case 0x36D6: -case 0x38D6: -case 0x3AD6: -case 0x3CD6: -case 0x30D7: -case 0x32D7: -case 0x34D7: -case 0x36D7: -case 0x38D7: -case 0x3AD7: -case 0x3CD7: - -// MOVEW -case 0x30D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3310: -case 0x3510: -case 0x3710: -case 0x3910: -case 0x3B10: -case 0x3D10: -case 0x3111: -case 0x3311: -case 0x3511: -case 0x3711: -case 0x3911: -case 0x3B11: -case 0x3D11: -case 0x3112: -case 0x3312: -case 0x3512: -case 0x3712: -case 0x3912: -case 0x3B12: -case 0x3D12: -case 0x3113: -case 0x3313: -case 0x3513: -case 0x3713: -case 0x3913: -case 0x3B13: -case 0x3D13: -case 0x3114: -case 0x3314: -case 0x3514: -case 0x3714: -case 0x3914: -case 0x3B14: -case 0x3D14: -case 0x3115: -case 0x3315: -case 0x3515: -case 0x3715: -case 0x3915: -case 0x3B15: -case 0x3D15: -case 0x3116: -case 0x3316: -case 0x3516: -case 0x3716: -case 0x3916: -case 0x3B16: -case 0x3D16: -case 0x3117: -case 0x3317: -case 0x3517: -case 0x3717: -case 0x3917: -case 0x3B17: -case 0x3D17: - -// MOVEW -case 0x3110: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3350: -case 0x3550: -case 0x3750: -case 0x3950: -case 0x3B50: -case 0x3D50: -case 0x3F50: -case 0x3151: -case 0x3351: -case 0x3551: -case 0x3751: -case 0x3951: -case 0x3B51: -case 0x3D51: -case 0x3F51: -case 0x3152: -case 0x3352: -case 0x3552: -case 0x3752: -case 0x3952: -case 0x3B52: -case 0x3D52: -case 0x3F52: -case 0x3153: -case 0x3353: -case 0x3553: -case 0x3753: -case 0x3953: -case 0x3B53: -case 0x3D53: -case 0x3F53: -case 0x3154: -case 0x3354: -case 0x3554: -case 0x3754: -case 0x3954: -case 0x3B54: -case 0x3D54: -case 0x3F54: -case 0x3155: -case 0x3355: -case 0x3555: -case 0x3755: -case 0x3955: -case 0x3B55: -case 0x3D55: -case 0x3F55: -case 0x3156: -case 0x3356: -case 0x3556: -case 0x3756: -case 0x3956: -case 0x3B56: -case 0x3D56: -case 0x3F56: -case 0x3157: -case 0x3357: -case 0x3557: -case 0x3757: -case 0x3957: -case 0x3B57: -case 0x3D57: -case 0x3F57: - -// MOVEW -case 0x3150: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3390: -case 0x3590: -case 0x3790: -case 0x3990: -case 0x3B90: -case 0x3D90: -case 0x3F90: -case 0x3191: -case 0x3391: -case 0x3591: -case 0x3791: -case 0x3991: -case 0x3B91: -case 0x3D91: -case 0x3F91: -case 0x3192: -case 0x3392: -case 0x3592: -case 0x3792: -case 0x3992: -case 0x3B92: -case 0x3D92: -case 0x3F92: -case 0x3193: -case 0x3393: -case 0x3593: -case 0x3793: -case 0x3993: -case 0x3B93: -case 0x3D93: -case 0x3F93: -case 0x3194: -case 0x3394: -case 0x3594: -case 0x3794: -case 0x3994: -case 0x3B94: -case 0x3D94: -case 0x3F94: -case 0x3195: -case 0x3395: -case 0x3595: -case 0x3795: -case 0x3995: -case 0x3B95: -case 0x3D95: -case 0x3F95: -case 0x3196: -case 0x3396: -case 0x3596: -case 0x3796: -case 0x3996: -case 0x3B96: -case 0x3D96: -case 0x3F96: -case 0x3197: -case 0x3397: -case 0x3597: -case 0x3797: -case 0x3997: -case 0x3B97: -case 0x3D97: -case 0x3F97: - -// MOVEW -case 0x3190: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x31D1: -case 0x31D2: -case 0x31D3: -case 0x31D4: -case 0x31D5: -case 0x31D6: -case 0x31D7: - -// MOVEW -case 0x31D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x33D1: -case 0x33D2: -case 0x33D3: -case 0x33D4: -case 0x33D5: -case 0x33D6: -case 0x33D7: - -// MOVEW -case 0x33D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3ED1: -case 0x3ED2: -case 0x3ED3: -case 0x3ED4: -case 0x3ED5: -case 0x3ED6: -case 0x3ED7: - -// MOVEW -case 0x3ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3F11: -case 0x3F12: -case 0x3F13: -case 0x3F14: -case 0x3F15: -case 0x3F16: -case 0x3F17: - -// MOVEW -case 0x3F10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3218: -case 0x3418: -case 0x3618: -case 0x3818: -case 0x3A18: -case 0x3C18: -case 0x3E18: -case 0x3019: -case 0x3219: -case 0x3419: -case 0x3619: -case 0x3819: -case 0x3A19: -case 0x3C19: -case 0x3E19: -case 0x301A: -case 0x321A: -case 0x341A: -case 0x361A: -case 0x381A: -case 0x3A1A: -case 0x3C1A: -case 0x3E1A: -case 0x301B: -case 0x321B: -case 0x341B: -case 0x361B: -case 0x381B: -case 0x3A1B: -case 0x3C1B: -case 0x3E1B: -case 0x301C: -case 0x321C: -case 0x341C: -case 0x361C: -case 0x381C: -case 0x3A1C: -case 0x3C1C: -case 0x3E1C: -case 0x301D: -case 0x321D: -case 0x341D: -case 0x361D: -case 0x381D: -case 0x3A1D: -case 0x3C1D: -case 0x3E1D: -case 0x301E: -case 0x321E: -case 0x341E: -case 0x361E: -case 0x381E: -case 0x3A1E: -case 0x3C1E: -case 0x3E1E: - -// MOVEW -case 0x3018: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x3298: -case 0x3498: -case 0x3698: -case 0x3898: -case 0x3A98: -case 0x3C98: -case 0x3E98: -case 0x3099: -case 0x3299: -case 0x3499: -case 0x3699: -case 0x3899: -case 0x3A99: -case 0x3C99: -case 0x3E99: -case 0x309A: -case 0x329A: -case 0x349A: -case 0x369A: -case 0x389A: -case 0x3A9A: -case 0x3C9A: -case 0x3E9A: -case 0x309B: -case 0x329B: -case 0x349B: -case 0x369B: -case 0x389B: -case 0x3A9B: -case 0x3C9B: -case 0x3E9B: -case 0x309C: -case 0x329C: -case 0x349C: -case 0x369C: -case 0x389C: -case 0x3A9C: -case 0x3C9C: -case 0x3E9C: -case 0x309D: -case 0x329D: -case 0x349D: -case 0x369D: -case 0x389D: -case 0x3A9D: -case 0x3C9D: -case 0x3E9D: -case 0x309E: -case 0x329E: -case 0x349E: -case 0x369E: -case 0x389E: -case 0x3A9E: -case 0x3C9E: -case 0x3E9E: - -// MOVEW -case 0x3098: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32D8: -case 0x34D8: -case 0x36D8: -case 0x38D8: -case 0x3AD8: -case 0x3CD8: -case 0x30D9: -case 0x32D9: -case 0x34D9: -case 0x36D9: -case 0x38D9: -case 0x3AD9: -case 0x3CD9: -case 0x30DA: -case 0x32DA: -case 0x34DA: -case 0x36DA: -case 0x38DA: -case 0x3ADA: -case 0x3CDA: -case 0x30DB: -case 0x32DB: -case 0x34DB: -case 0x36DB: -case 0x38DB: -case 0x3ADB: -case 0x3CDB: -case 0x30DC: -case 0x32DC: -case 0x34DC: -case 0x36DC: -case 0x38DC: -case 0x3ADC: -case 0x3CDC: -case 0x30DD: -case 0x32DD: -case 0x34DD: -case 0x36DD: -case 0x38DD: -case 0x3ADD: -case 0x3CDD: -case 0x30DE: -case 0x32DE: -case 0x34DE: -case 0x36DE: -case 0x38DE: -case 0x3ADE: -case 0x3CDE: - -// MOVEW -case 0x30D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3318: -case 0x3518: -case 0x3718: -case 0x3918: -case 0x3B18: -case 0x3D18: -case 0x3119: -case 0x3319: -case 0x3519: -case 0x3719: -case 0x3919: -case 0x3B19: -case 0x3D19: -case 0x311A: -case 0x331A: -case 0x351A: -case 0x371A: -case 0x391A: -case 0x3B1A: -case 0x3D1A: -case 0x311B: -case 0x331B: -case 0x351B: -case 0x371B: -case 0x391B: -case 0x3B1B: -case 0x3D1B: -case 0x311C: -case 0x331C: -case 0x351C: -case 0x371C: -case 0x391C: -case 0x3B1C: -case 0x3D1C: -case 0x311D: -case 0x331D: -case 0x351D: -case 0x371D: -case 0x391D: -case 0x3B1D: -case 0x3D1D: -case 0x311E: -case 0x331E: -case 0x351E: -case 0x371E: -case 0x391E: -case 0x3B1E: -case 0x3D1E: - -// MOVEW -case 0x3118: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3358: -case 0x3558: -case 0x3758: -case 0x3958: -case 0x3B58: -case 0x3D58: -case 0x3F58: -case 0x3159: -case 0x3359: -case 0x3559: -case 0x3759: -case 0x3959: -case 0x3B59: -case 0x3D59: -case 0x3F59: -case 0x315A: -case 0x335A: -case 0x355A: -case 0x375A: -case 0x395A: -case 0x3B5A: -case 0x3D5A: -case 0x3F5A: -case 0x315B: -case 0x335B: -case 0x355B: -case 0x375B: -case 0x395B: -case 0x3B5B: -case 0x3D5B: -case 0x3F5B: -case 0x315C: -case 0x335C: -case 0x355C: -case 0x375C: -case 0x395C: -case 0x3B5C: -case 0x3D5C: -case 0x3F5C: -case 0x315D: -case 0x335D: -case 0x355D: -case 0x375D: -case 0x395D: -case 0x3B5D: -case 0x3D5D: -case 0x3F5D: -case 0x315E: -case 0x335E: -case 0x355E: -case 0x375E: -case 0x395E: -case 0x3B5E: -case 0x3D5E: -case 0x3F5E: - -// MOVEW -case 0x3158: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3398: -case 0x3598: -case 0x3798: -case 0x3998: -case 0x3B98: -case 0x3D98: -case 0x3F98: -case 0x3199: -case 0x3399: -case 0x3599: -case 0x3799: -case 0x3999: -case 0x3B99: -case 0x3D99: -case 0x3F99: -case 0x319A: -case 0x339A: -case 0x359A: -case 0x379A: -case 0x399A: -case 0x3B9A: -case 0x3D9A: -case 0x3F9A: -case 0x319B: -case 0x339B: -case 0x359B: -case 0x379B: -case 0x399B: -case 0x3B9B: -case 0x3D9B: -case 0x3F9B: -case 0x319C: -case 0x339C: -case 0x359C: -case 0x379C: -case 0x399C: -case 0x3B9C: -case 0x3D9C: -case 0x3F9C: -case 0x319D: -case 0x339D: -case 0x359D: -case 0x379D: -case 0x399D: -case 0x3B9D: -case 0x3D9D: -case 0x3F9D: -case 0x319E: -case 0x339E: -case 0x359E: -case 0x379E: -case 0x399E: -case 0x3B9E: -case 0x3D9E: -case 0x3F9E: - -// MOVEW -case 0x3198: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x31D9: -case 0x31DA: -case 0x31DB: -case 0x31DC: -case 0x31DD: -case 0x31DE: - -// MOVEW -case 0x31D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x33D9: -case 0x33DA: -case 0x33DB: -case 0x33DC: -case 0x33DD: -case 0x33DE: - -// MOVEW -case 0x33D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3ED9: -case 0x3EDA: -case 0x3EDB: -case 0x3EDC: -case 0x3EDD: -case 0x3EDE: - -// MOVEW -case 0x3ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3F19: -case 0x3F1A: -case 0x3F1B: -case 0x3F1C: -case 0x3F1D: -case 0x3F1E: - -// MOVEW -case 0x3F18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3220: -case 0x3420: -case 0x3620: -case 0x3820: -case 0x3A20: -case 0x3C20: -case 0x3E20: -case 0x3021: -case 0x3221: -case 0x3421: -case 0x3621: -case 0x3821: -case 0x3A21: -case 0x3C21: -case 0x3E21: -case 0x3022: -case 0x3222: -case 0x3422: -case 0x3622: -case 0x3822: -case 0x3A22: -case 0x3C22: -case 0x3E22: -case 0x3023: -case 0x3223: -case 0x3423: -case 0x3623: -case 0x3823: -case 0x3A23: -case 0x3C23: -case 0x3E23: -case 0x3024: -case 0x3224: -case 0x3424: -case 0x3624: -case 0x3824: -case 0x3A24: -case 0x3C24: -case 0x3E24: -case 0x3025: -case 0x3225: -case 0x3425: -case 0x3625: -case 0x3825: -case 0x3A25: -case 0x3C25: -case 0x3E25: -case 0x3026: -case 0x3226: -case 0x3426: -case 0x3626: -case 0x3826: -case 0x3A26: -case 0x3C26: -case 0x3E26: - -// MOVEW -case 0x3020: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x32A0: -case 0x34A0: -case 0x36A0: -case 0x38A0: -case 0x3AA0: -case 0x3CA0: -case 0x3EA0: -case 0x30A1: -case 0x32A1: -case 0x34A1: -case 0x36A1: -case 0x38A1: -case 0x3AA1: -case 0x3CA1: -case 0x3EA1: -case 0x30A2: -case 0x32A2: -case 0x34A2: -case 0x36A2: -case 0x38A2: -case 0x3AA2: -case 0x3CA2: -case 0x3EA2: -case 0x30A3: -case 0x32A3: -case 0x34A3: -case 0x36A3: -case 0x38A3: -case 0x3AA3: -case 0x3CA3: -case 0x3EA3: -case 0x30A4: -case 0x32A4: -case 0x34A4: -case 0x36A4: -case 0x38A4: -case 0x3AA4: -case 0x3CA4: -case 0x3EA4: -case 0x30A5: -case 0x32A5: -case 0x34A5: -case 0x36A5: -case 0x38A5: -case 0x3AA5: -case 0x3CA5: -case 0x3EA5: -case 0x30A6: -case 0x32A6: -case 0x34A6: -case 0x36A6: -case 0x38A6: -case 0x3AA6: -case 0x3CA6: -case 0x3EA6: - -// MOVEW -case 0x30A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x32E0: -case 0x34E0: -case 0x36E0: -case 0x38E0: -case 0x3AE0: -case 0x3CE0: -case 0x30E1: -case 0x32E1: -case 0x34E1: -case 0x36E1: -case 0x38E1: -case 0x3AE1: -case 0x3CE1: -case 0x30E2: -case 0x32E2: -case 0x34E2: -case 0x36E2: -case 0x38E2: -case 0x3AE2: -case 0x3CE2: -case 0x30E3: -case 0x32E3: -case 0x34E3: -case 0x36E3: -case 0x38E3: -case 0x3AE3: -case 0x3CE3: -case 0x30E4: -case 0x32E4: -case 0x34E4: -case 0x36E4: -case 0x38E4: -case 0x3AE4: -case 0x3CE4: -case 0x30E5: -case 0x32E5: -case 0x34E5: -case 0x36E5: -case 0x38E5: -case 0x3AE5: -case 0x3CE5: -case 0x30E6: -case 0x32E6: -case 0x34E6: -case 0x36E6: -case 0x38E6: -case 0x3AE6: -case 0x3CE6: - -// MOVEW -case 0x30E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3320: -case 0x3520: -case 0x3720: -case 0x3920: -case 0x3B20: -case 0x3D20: -case 0x3121: -case 0x3321: -case 0x3521: -case 0x3721: -case 0x3921: -case 0x3B21: -case 0x3D21: -case 0x3122: -case 0x3322: -case 0x3522: -case 0x3722: -case 0x3922: -case 0x3B22: -case 0x3D22: -case 0x3123: -case 0x3323: -case 0x3523: -case 0x3723: -case 0x3923: -case 0x3B23: -case 0x3D23: -case 0x3124: -case 0x3324: -case 0x3524: -case 0x3724: -case 0x3924: -case 0x3B24: -case 0x3D24: -case 0x3125: -case 0x3325: -case 0x3525: -case 0x3725: -case 0x3925: -case 0x3B25: -case 0x3D25: -case 0x3126: -case 0x3326: -case 0x3526: -case 0x3726: -case 0x3926: -case 0x3B26: -case 0x3D26: - -// MOVEW -case 0x3120: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3360: -case 0x3560: -case 0x3760: -case 0x3960: -case 0x3B60: -case 0x3D60: -case 0x3F60: -case 0x3161: -case 0x3361: -case 0x3561: -case 0x3761: -case 0x3961: -case 0x3B61: -case 0x3D61: -case 0x3F61: -case 0x3162: -case 0x3362: -case 0x3562: -case 0x3762: -case 0x3962: -case 0x3B62: -case 0x3D62: -case 0x3F62: -case 0x3163: -case 0x3363: -case 0x3563: -case 0x3763: -case 0x3963: -case 0x3B63: -case 0x3D63: -case 0x3F63: -case 0x3164: -case 0x3364: -case 0x3564: -case 0x3764: -case 0x3964: -case 0x3B64: -case 0x3D64: -case 0x3F64: -case 0x3165: -case 0x3365: -case 0x3565: -case 0x3765: -case 0x3965: -case 0x3B65: -case 0x3D65: -case 0x3F65: -case 0x3166: -case 0x3366: -case 0x3566: -case 0x3766: -case 0x3966: -case 0x3B66: -case 0x3D66: -case 0x3F66: - -// MOVEW -case 0x3160: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x33A0: -case 0x35A0: -case 0x37A0: -case 0x39A0: -case 0x3BA0: -case 0x3DA0: -case 0x3FA0: -case 0x31A1: -case 0x33A1: -case 0x35A1: -case 0x37A1: -case 0x39A1: -case 0x3BA1: -case 0x3DA1: -case 0x3FA1: -case 0x31A2: -case 0x33A2: -case 0x35A2: -case 0x37A2: -case 0x39A2: -case 0x3BA2: -case 0x3DA2: -case 0x3FA2: -case 0x31A3: -case 0x33A3: -case 0x35A3: -case 0x37A3: -case 0x39A3: -case 0x3BA3: -case 0x3DA3: -case 0x3FA3: -case 0x31A4: -case 0x33A4: -case 0x35A4: -case 0x37A4: -case 0x39A4: -case 0x3BA4: -case 0x3DA4: -case 0x3FA4: -case 0x31A5: -case 0x33A5: -case 0x35A5: -case 0x37A5: -case 0x39A5: -case 0x3BA5: -case 0x3DA5: -case 0x3FA5: -case 0x31A6: -case 0x33A6: -case 0x35A6: -case 0x37A6: -case 0x39A6: -case 0x3BA6: -case 0x3DA6: -case 0x3FA6: - -// MOVEW -case 0x31A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x31E1: -case 0x31E2: -case 0x31E3: -case 0x31E4: -case 0x31E5: -case 0x31E6: - -// MOVEW -case 0x31E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x33E1: -case 0x33E2: -case 0x33E3: -case 0x33E4: -case 0x33E5: -case 0x33E6: - -// MOVEW -case 0x33E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x3EE1: -case 0x3EE2: -case 0x3EE3: -case 0x3EE4: -case 0x3EE5: -case 0x3EE6: - -// MOVEW -case 0x3EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3F21: -case 0x3F22: -case 0x3F23: -case 0x3F24: -case 0x3F25: -case 0x3F26: - -// MOVEW -case 0x3F20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3228: -case 0x3428: -case 0x3628: -case 0x3828: -case 0x3A28: -case 0x3C28: -case 0x3E28: -case 0x3029: -case 0x3229: -case 0x3429: -case 0x3629: -case 0x3829: -case 0x3A29: -case 0x3C29: -case 0x3E29: -case 0x302A: -case 0x322A: -case 0x342A: -case 0x362A: -case 0x382A: -case 0x3A2A: -case 0x3C2A: -case 0x3E2A: -case 0x302B: -case 0x322B: -case 0x342B: -case 0x362B: -case 0x382B: -case 0x3A2B: -case 0x3C2B: -case 0x3E2B: -case 0x302C: -case 0x322C: -case 0x342C: -case 0x362C: -case 0x382C: -case 0x3A2C: -case 0x3C2C: -case 0x3E2C: -case 0x302D: -case 0x322D: -case 0x342D: -case 0x362D: -case 0x382D: -case 0x3A2D: -case 0x3C2D: -case 0x3E2D: -case 0x302E: -case 0x322E: -case 0x342E: -case 0x362E: -case 0x382E: -case 0x3A2E: -case 0x3C2E: -case 0x3E2E: -case 0x302F: -case 0x322F: -case 0x342F: -case 0x362F: -case 0x382F: -case 0x3A2F: -case 0x3C2F: -case 0x3E2F: - -// MOVEW -case 0x3028: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x32A8: -case 0x34A8: -case 0x36A8: -case 0x38A8: -case 0x3AA8: -case 0x3CA8: -case 0x3EA8: -case 0x30A9: -case 0x32A9: -case 0x34A9: -case 0x36A9: -case 0x38A9: -case 0x3AA9: -case 0x3CA9: -case 0x3EA9: -case 0x30AA: -case 0x32AA: -case 0x34AA: -case 0x36AA: -case 0x38AA: -case 0x3AAA: -case 0x3CAA: -case 0x3EAA: -case 0x30AB: -case 0x32AB: -case 0x34AB: -case 0x36AB: -case 0x38AB: -case 0x3AAB: -case 0x3CAB: -case 0x3EAB: -case 0x30AC: -case 0x32AC: -case 0x34AC: -case 0x36AC: -case 0x38AC: -case 0x3AAC: -case 0x3CAC: -case 0x3EAC: -case 0x30AD: -case 0x32AD: -case 0x34AD: -case 0x36AD: -case 0x38AD: -case 0x3AAD: -case 0x3CAD: -case 0x3EAD: -case 0x30AE: -case 0x32AE: -case 0x34AE: -case 0x36AE: -case 0x38AE: -case 0x3AAE: -case 0x3CAE: -case 0x3EAE: -case 0x30AF: -case 0x32AF: -case 0x34AF: -case 0x36AF: -case 0x38AF: -case 0x3AAF: -case 0x3CAF: -case 0x3EAF: - -// MOVEW -case 0x30A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x32E8: -case 0x34E8: -case 0x36E8: -case 0x38E8: -case 0x3AE8: -case 0x3CE8: -case 0x30E9: -case 0x32E9: -case 0x34E9: -case 0x36E9: -case 0x38E9: -case 0x3AE9: -case 0x3CE9: -case 0x30EA: -case 0x32EA: -case 0x34EA: -case 0x36EA: -case 0x38EA: -case 0x3AEA: -case 0x3CEA: -case 0x30EB: -case 0x32EB: -case 0x34EB: -case 0x36EB: -case 0x38EB: -case 0x3AEB: -case 0x3CEB: -case 0x30EC: -case 0x32EC: -case 0x34EC: -case 0x36EC: -case 0x38EC: -case 0x3AEC: -case 0x3CEC: -case 0x30ED: -case 0x32ED: -case 0x34ED: -case 0x36ED: -case 0x38ED: -case 0x3AED: -case 0x3CED: -case 0x30EE: -case 0x32EE: -case 0x34EE: -case 0x36EE: -case 0x38EE: -case 0x3AEE: -case 0x3CEE: -case 0x30EF: -case 0x32EF: -case 0x34EF: -case 0x36EF: -case 0x38EF: -case 0x3AEF: -case 0x3CEF: - -// MOVEW -case 0x30E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3328: -case 0x3528: -case 0x3728: -case 0x3928: -case 0x3B28: -case 0x3D28: -case 0x3129: -case 0x3329: -case 0x3529: -case 0x3729: -case 0x3929: -case 0x3B29: -case 0x3D29: -case 0x312A: -case 0x332A: -case 0x352A: -case 0x372A: -case 0x392A: -case 0x3B2A: -case 0x3D2A: -case 0x312B: -case 0x332B: -case 0x352B: -case 0x372B: -case 0x392B: -case 0x3B2B: -case 0x3D2B: -case 0x312C: -case 0x332C: -case 0x352C: -case 0x372C: -case 0x392C: -case 0x3B2C: -case 0x3D2C: -case 0x312D: -case 0x332D: -case 0x352D: -case 0x372D: -case 0x392D: -case 0x3B2D: -case 0x3D2D: -case 0x312E: -case 0x332E: -case 0x352E: -case 0x372E: -case 0x392E: -case 0x3B2E: -case 0x3D2E: -case 0x312F: -case 0x332F: -case 0x352F: -case 0x372F: -case 0x392F: -case 0x3B2F: -case 0x3D2F: - -// MOVEW -case 0x3128: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3368: -case 0x3568: -case 0x3768: -case 0x3968: -case 0x3B68: -case 0x3D68: -case 0x3F68: -case 0x3169: -case 0x3369: -case 0x3569: -case 0x3769: -case 0x3969: -case 0x3B69: -case 0x3D69: -case 0x3F69: -case 0x316A: -case 0x336A: -case 0x356A: -case 0x376A: -case 0x396A: -case 0x3B6A: -case 0x3D6A: -case 0x3F6A: -case 0x316B: -case 0x336B: -case 0x356B: -case 0x376B: -case 0x396B: -case 0x3B6B: -case 0x3D6B: -case 0x3F6B: -case 0x316C: -case 0x336C: -case 0x356C: -case 0x376C: -case 0x396C: -case 0x3B6C: -case 0x3D6C: -case 0x3F6C: -case 0x316D: -case 0x336D: -case 0x356D: -case 0x376D: -case 0x396D: -case 0x3B6D: -case 0x3D6D: -case 0x3F6D: -case 0x316E: -case 0x336E: -case 0x356E: -case 0x376E: -case 0x396E: -case 0x3B6E: -case 0x3D6E: -case 0x3F6E: -case 0x316F: -case 0x336F: -case 0x356F: -case 0x376F: -case 0x396F: -case 0x3B6F: -case 0x3D6F: -case 0x3F6F: - -// MOVEW -case 0x3168: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33A8: -case 0x35A8: -case 0x37A8: -case 0x39A8: -case 0x3BA8: -case 0x3DA8: -case 0x3FA8: -case 0x31A9: -case 0x33A9: -case 0x35A9: -case 0x37A9: -case 0x39A9: -case 0x3BA9: -case 0x3DA9: -case 0x3FA9: -case 0x31AA: -case 0x33AA: -case 0x35AA: -case 0x37AA: -case 0x39AA: -case 0x3BAA: -case 0x3DAA: -case 0x3FAA: -case 0x31AB: -case 0x33AB: -case 0x35AB: -case 0x37AB: -case 0x39AB: -case 0x3BAB: -case 0x3DAB: -case 0x3FAB: -case 0x31AC: -case 0x33AC: -case 0x35AC: -case 0x37AC: -case 0x39AC: -case 0x3BAC: -case 0x3DAC: -case 0x3FAC: -case 0x31AD: -case 0x33AD: -case 0x35AD: -case 0x37AD: -case 0x39AD: -case 0x3BAD: -case 0x3DAD: -case 0x3FAD: -case 0x31AE: -case 0x33AE: -case 0x35AE: -case 0x37AE: -case 0x39AE: -case 0x3BAE: -case 0x3DAE: -case 0x3FAE: -case 0x31AF: -case 0x33AF: -case 0x35AF: -case 0x37AF: -case 0x39AF: -case 0x3BAF: -case 0x3DAF: -case 0x3FAF: - -// MOVEW -case 0x31A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x31E9: -case 0x31EA: -case 0x31EB: -case 0x31EC: -case 0x31ED: -case 0x31EE: -case 0x31EF: - -// MOVEW -case 0x31E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33E9: -case 0x33EA: -case 0x33EB: -case 0x33EC: -case 0x33ED: -case 0x33EE: -case 0x33EF: - -// MOVEW -case 0x33E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) -case 0x3EE9: -case 0x3EEA: -case 0x3EEB: -case 0x3EEC: -case 0x3EED: -case 0x3EEE: -case 0x3EEF: - -// MOVEW -case 0x3EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3F29: -case 0x3F2A: -case 0x3F2B: -case 0x3F2C: -case 0x3F2D: -case 0x3F2E: -case 0x3F2F: - -// MOVEW -case 0x3F28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3230: -case 0x3430: -case 0x3630: -case 0x3830: -case 0x3A30: -case 0x3C30: -case 0x3E30: -case 0x3031: -case 0x3231: -case 0x3431: -case 0x3631: -case 0x3831: -case 0x3A31: -case 0x3C31: -case 0x3E31: -case 0x3032: -case 0x3232: -case 0x3432: -case 0x3632: -case 0x3832: -case 0x3A32: -case 0x3C32: -case 0x3E32: -case 0x3033: -case 0x3233: -case 0x3433: -case 0x3633: -case 0x3833: -case 0x3A33: -case 0x3C33: -case 0x3E33: -case 0x3034: -case 0x3234: -case 0x3434: -case 0x3634: -case 0x3834: -case 0x3A34: -case 0x3C34: -case 0x3E34: -case 0x3035: -case 0x3235: -case 0x3435: -case 0x3635: -case 0x3835: -case 0x3A35: -case 0x3C35: -case 0x3E35: -case 0x3036: -case 0x3236: -case 0x3436: -case 0x3636: -case 0x3836: -case 0x3A36: -case 0x3C36: -case 0x3E36: -case 0x3037: -case 0x3237: -case 0x3437: -case 0x3637: -case 0x3837: -case 0x3A37: -case 0x3C37: -case 0x3E37: - -// MOVEW -case 0x3030: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x32B0: -case 0x34B0: -case 0x36B0: -case 0x38B0: -case 0x3AB0: -case 0x3CB0: -case 0x3EB0: -case 0x30B1: -case 0x32B1: -case 0x34B1: -case 0x36B1: -case 0x38B1: -case 0x3AB1: -case 0x3CB1: -case 0x3EB1: -case 0x30B2: -case 0x32B2: -case 0x34B2: -case 0x36B2: -case 0x38B2: -case 0x3AB2: -case 0x3CB2: -case 0x3EB2: -case 0x30B3: -case 0x32B3: -case 0x34B3: -case 0x36B3: -case 0x38B3: -case 0x3AB3: -case 0x3CB3: -case 0x3EB3: -case 0x30B4: -case 0x32B4: -case 0x34B4: -case 0x36B4: -case 0x38B4: -case 0x3AB4: -case 0x3CB4: -case 0x3EB4: -case 0x30B5: -case 0x32B5: -case 0x34B5: -case 0x36B5: -case 0x38B5: -case 0x3AB5: -case 0x3CB5: -case 0x3EB5: -case 0x30B6: -case 0x32B6: -case 0x34B6: -case 0x36B6: -case 0x38B6: -case 0x3AB6: -case 0x3CB6: -case 0x3EB6: -case 0x30B7: -case 0x32B7: -case 0x34B7: -case 0x36B7: -case 0x38B7: -case 0x3AB7: -case 0x3CB7: -case 0x3EB7: - -// MOVEW -case 0x30B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x32F0: -case 0x34F0: -case 0x36F0: -case 0x38F0: -case 0x3AF0: -case 0x3CF0: -case 0x30F1: -case 0x32F1: -case 0x34F1: -case 0x36F1: -case 0x38F1: -case 0x3AF1: -case 0x3CF1: -case 0x30F2: -case 0x32F2: -case 0x34F2: -case 0x36F2: -case 0x38F2: -case 0x3AF2: -case 0x3CF2: -case 0x30F3: -case 0x32F3: -case 0x34F3: -case 0x36F3: -case 0x38F3: -case 0x3AF3: -case 0x3CF3: -case 0x30F4: -case 0x32F4: -case 0x34F4: -case 0x36F4: -case 0x38F4: -case 0x3AF4: -case 0x3CF4: -case 0x30F5: -case 0x32F5: -case 0x34F5: -case 0x36F5: -case 0x38F5: -case 0x3AF5: -case 0x3CF5: -case 0x30F6: -case 0x32F6: -case 0x34F6: -case 0x36F6: -case 0x38F6: -case 0x3AF6: -case 0x3CF6: -case 0x30F7: -case 0x32F7: -case 0x34F7: -case 0x36F7: -case 0x38F7: -case 0x3AF7: -case 0x3CF7: - -// MOVEW -case 0x30F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3330: -case 0x3530: -case 0x3730: -case 0x3930: -case 0x3B30: -case 0x3D30: -case 0x3131: -case 0x3331: -case 0x3531: -case 0x3731: -case 0x3931: -case 0x3B31: -case 0x3D31: -case 0x3132: -case 0x3332: -case 0x3532: -case 0x3732: -case 0x3932: -case 0x3B32: -case 0x3D32: -case 0x3133: -case 0x3333: -case 0x3533: -case 0x3733: -case 0x3933: -case 0x3B33: -case 0x3D33: -case 0x3134: -case 0x3334: -case 0x3534: -case 0x3734: -case 0x3934: -case 0x3B34: -case 0x3D34: -case 0x3135: -case 0x3335: -case 0x3535: -case 0x3735: -case 0x3935: -case 0x3B35: -case 0x3D35: -case 0x3136: -case 0x3336: -case 0x3536: -case 0x3736: -case 0x3936: -case 0x3B36: -case 0x3D36: -case 0x3137: -case 0x3337: -case 0x3537: -case 0x3737: -case 0x3937: -case 0x3B37: -case 0x3D37: - -// MOVEW -case 0x3130: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3370: -case 0x3570: -case 0x3770: -case 0x3970: -case 0x3B70: -case 0x3D70: -case 0x3F70: -case 0x3171: -case 0x3371: -case 0x3571: -case 0x3771: -case 0x3971: -case 0x3B71: -case 0x3D71: -case 0x3F71: -case 0x3172: -case 0x3372: -case 0x3572: -case 0x3772: -case 0x3972: -case 0x3B72: -case 0x3D72: -case 0x3F72: -case 0x3173: -case 0x3373: -case 0x3573: -case 0x3773: -case 0x3973: -case 0x3B73: -case 0x3D73: -case 0x3F73: -case 0x3174: -case 0x3374: -case 0x3574: -case 0x3774: -case 0x3974: -case 0x3B74: -case 0x3D74: -case 0x3F74: -case 0x3175: -case 0x3375: -case 0x3575: -case 0x3775: -case 0x3975: -case 0x3B75: -case 0x3D75: -case 0x3F75: -case 0x3176: -case 0x3376: -case 0x3576: -case 0x3776: -case 0x3976: -case 0x3B76: -case 0x3D76: -case 0x3F76: -case 0x3177: -case 0x3377: -case 0x3577: -case 0x3777: -case 0x3977: -case 0x3B77: -case 0x3D77: -case 0x3F77: - -// MOVEW -case 0x3170: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x33B0: -case 0x35B0: -case 0x37B0: -case 0x39B0: -case 0x3BB0: -case 0x3DB0: -case 0x3FB0: -case 0x31B1: -case 0x33B1: -case 0x35B1: -case 0x37B1: -case 0x39B1: -case 0x3BB1: -case 0x3DB1: -case 0x3FB1: -case 0x31B2: -case 0x33B2: -case 0x35B2: -case 0x37B2: -case 0x39B2: -case 0x3BB2: -case 0x3DB2: -case 0x3FB2: -case 0x31B3: -case 0x33B3: -case 0x35B3: -case 0x37B3: -case 0x39B3: -case 0x3BB3: -case 0x3DB3: -case 0x3FB3: -case 0x31B4: -case 0x33B4: -case 0x35B4: -case 0x37B4: -case 0x39B4: -case 0x3BB4: -case 0x3DB4: -case 0x3FB4: -case 0x31B5: -case 0x33B5: -case 0x35B5: -case 0x37B5: -case 0x39B5: -case 0x3BB5: -case 0x3DB5: -case 0x3FB5: -case 0x31B6: -case 0x33B6: -case 0x35B6: -case 0x37B6: -case 0x39B6: -case 0x3BB6: -case 0x3DB6: -case 0x3FB6: -case 0x31B7: -case 0x33B7: -case 0x35B7: -case 0x37B7: -case 0x39B7: -case 0x3BB7: -case 0x3DB7: -case 0x3FB7: - -// MOVEW -case 0x31B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) -case 0x31F1: -case 0x31F2: -case 0x31F3: -case 0x31F4: -case 0x31F5: -case 0x31F6: -case 0x31F7: - -// MOVEW -case 0x31F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x33F1: -case 0x33F2: -case 0x33F3: -case 0x33F4: -case 0x33F5: -case 0x33F6: -case 0x33F7: - -// MOVEW -case 0x33F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(26) -case 0x3EF1: -case 0x3EF2: -case 0x3EF3: -case 0x3EF4: -case 0x3EF5: -case 0x3EF6: -case 0x3EF7: - -// MOVEW -case 0x3EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3F31: -case 0x3F32: -case 0x3F33: -case 0x3F34: -case 0x3F35: -case 0x3F36: -case 0x3F37: - -// MOVEW -case 0x3F30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3238: -case 0x3438: -case 0x3638: -case 0x3838: -case 0x3A38: -case 0x3C38: -case 0x3E38: - -// MOVEW -case 0x3038: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x32B8: -case 0x34B8: -case 0x36B8: -case 0x38B8: -case 0x3AB8: -case 0x3CB8: -case 0x3EB8: - -// MOVEW -case 0x30B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x32F8: -case 0x34F8: -case 0x36F8: -case 0x38F8: -case 0x3AF8: -case 0x3CF8: - -// MOVEW -case 0x30F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3338: -case 0x3538: -case 0x3738: -case 0x3938: -case 0x3B38: -case 0x3D38: - -// MOVEW -case 0x3138: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3378: -case 0x3578: -case 0x3778: -case 0x3978: -case 0x3B78: -case 0x3D78: -case 0x3F78: - -// MOVEW -case 0x3178: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33B8: -case 0x35B8: -case 0x37B8: -case 0x39B8: -case 0x3BB8: -case 0x3DB8: -case 0x3FB8: - -// MOVEW -case 0x31B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x31F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x33F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x3EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x3F38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3239: -case 0x3439: -case 0x3639: -case 0x3839: -case 0x3A39: -case 0x3C39: -case 0x3E39: - -// MOVEW -case 0x3039: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x32B9: -case 0x34B9: -case 0x36B9: -case 0x38B9: -case 0x3AB9: -case 0x3CB9: -case 0x3EB9: - -// MOVEW -case 0x30B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x32F9: -case 0x34F9: -case 0x36F9: -case 0x38F9: -case 0x3AF9: -case 0x3CF9: - -// MOVEW -case 0x30F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3339: -case 0x3539: -case 0x3739: -case 0x3939: -case 0x3B39: -case 0x3D39: - -// MOVEW -case 0x3139: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3379: -case 0x3579: -case 0x3779: -case 0x3979: -case 0x3B79: -case 0x3D79: -case 0x3F79: - -// MOVEW -case 0x3179: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) -case 0x33B9: -case 0x35B9: -case 0x37B9: -case 0x39B9: -case 0x3BB9: -case 0x3DB9: -case 0x3FB9: - -// MOVEW -case 0x31B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(26) - -// MOVEW -case 0x31F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x33F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(28) - -// MOVEW -case 0x3EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x3F39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x323A: -case 0x343A: -case 0x363A: -case 0x383A: -case 0x3A3A: -case 0x3C3A: -case 0x3E3A: - -// MOVEW -case 0x303A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x32BA: -case 0x34BA: -case 0x36BA: -case 0x38BA: -case 0x3ABA: -case 0x3CBA: -case 0x3EBA: - -// MOVEW -case 0x30BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x32FA: -case 0x34FA: -case 0x36FA: -case 0x38FA: -case 0x3AFA: -case 0x3CFA: - -// MOVEW -case 0x30FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x333A: -case 0x353A: -case 0x373A: -case 0x393A: -case 0x3B3A: -case 0x3D3A: - -// MOVEW -case 0x313A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x337A: -case 0x357A: -case 0x377A: -case 0x397A: -case 0x3B7A: -case 0x3D7A: -case 0x3F7A: - -// MOVEW -case 0x317A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33BA: -case 0x35BA: -case 0x37BA: -case 0x39BA: -case 0x3BBA: -case 0x3DBA: -case 0x3FBA: - -// MOVEW -case 0x31BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x31FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x33FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x3EFA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x3F3A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x323B: -case 0x343B: -case 0x363B: -case 0x383B: -case 0x3A3B: -case 0x3C3B: -case 0x3E3B: - -// MOVEW -case 0x303B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x32BB: -case 0x34BB: -case 0x36BB: -case 0x38BB: -case 0x3ABB: -case 0x3CBB: -case 0x3EBB: - -// MOVEW -case 0x30BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x32FB: -case 0x34FB: -case 0x36FB: -case 0x38FB: -case 0x3AFB: -case 0x3CFB: - -// MOVEW -case 0x30FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x333B: -case 0x353B: -case 0x373B: -case 0x393B: -case 0x3B3B: -case 0x3D3B: - -// MOVEW -case 0x313B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x337B: -case 0x357B: -case 0x377B: -case 0x397B: -case 0x3B7B: -case 0x3D7B: -case 0x3F7B: - -// MOVEW -case 0x317B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x33BB: -case 0x35BB: -case 0x37BB: -case 0x39BB: -case 0x3BBB: -case 0x3DBB: -case 0x3FBB: - -// MOVEW -case 0x31BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x31FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x33FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(26) - -// MOVEW -case 0x3EFB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x3F3B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x323C: -case 0x343C: -case 0x363C: -case 0x383C: -case 0x3A3C: -case 0x3C3C: -case 0x3E3C: - -// MOVEW -case 0x303C: -{ - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x32BC: -case 0x34BC: -case 0x36BC: -case 0x38BC: -case 0x3ABC: -case 0x3CBC: -case 0x3EBC: - -// MOVEW -case 0x30BC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32FC: -case 0x34FC: -case 0x36FC: -case 0x38FC: -case 0x3AFC: -case 0x3CFC: - -// MOVEW -case 0x30FC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x333C: -case 0x353C: -case 0x373C: -case 0x393C: -case 0x3B3C: -case 0x3D3C: - -// MOVEW -case 0x313C: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x337C: -case 0x357C: -case 0x377C: -case 0x397C: -case 0x3B7C: -case 0x3D7C: -case 0x3F7C: - -// MOVEW -case 0x317C: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x33BC: -case 0x35BC: -case 0x37BC: -case 0x39BC: -case 0x3BBC: -case 0x3DBC: -case 0x3FBC: - -// MOVEW -case 0x31BC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x31FC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x33FC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x3EFC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// MOVEW -case 0x3F3C: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x321F: -case 0x341F: -case 0x361F: -case 0x381F: -case 0x3A1F: -case 0x3C1F: -case 0x3E1F: - -// MOVEW -case 0x301F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x329F: -case 0x349F: -case 0x369F: -case 0x389F: -case 0x3A9F: -case 0x3C9F: -case 0x3E9F: - -// MOVEW -case 0x309F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32DF: -case 0x34DF: -case 0x36DF: -case 0x38DF: -case 0x3ADF: -case 0x3CDF: - -// MOVEW -case 0x30DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x331F: -case 0x351F: -case 0x371F: -case 0x391F: -case 0x3B1F: -case 0x3D1F: - -// MOVEW -case 0x311F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x335F: -case 0x355F: -case 0x375F: -case 0x395F: -case 0x3B5F: -case 0x3D5F: -case 0x3F5F: - -// MOVEW -case 0x315F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x339F: -case 0x359F: -case 0x379F: -case 0x399F: -case 0x3B9F: -case 0x3D9F: -case 0x3F9F: - -// MOVEW -case 0x319F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x31DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x33DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x3EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// MOVEW -case 0x3F1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3227: -case 0x3427: -case 0x3627: -case 0x3827: -case 0x3A27: -case 0x3C27: -case 0x3E27: - -// MOVEW -case 0x3027: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x32A7: -case 0x34A7: -case 0x36A7: -case 0x38A7: -case 0x3AA7: -case 0x3CA7: -case 0x3EA7: - -// MOVEW -case 0x30A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x32E7: -case 0x34E7: -case 0x36E7: -case 0x38E7: -case 0x3AE7: -case 0x3CE7: - -// MOVEW -case 0x30E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3327: -case 0x3527: -case 0x3727: -case 0x3927: -case 0x3B27: -case 0x3D27: - -// MOVEW -case 0x3127: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3367: -case 0x3567: -case 0x3767: -case 0x3967: -case 0x3B67: -case 0x3D67: -case 0x3F67: - -// MOVEW -case 0x3167: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x33A7: -case 0x35A7: -case 0x37A7: -case 0x39A7: -case 0x3BA7: -case 0x3DA7: -case 0x3FA7: - -// MOVEW -case 0x31A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x31E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x33E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x3EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) - -// MOVEW -case 0x3F27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3240: -case 0x3440: -case 0x3640: -case 0x3840: -case 0x3A40: -case 0x3C40: -case 0x3E40: -case 0x3041: -case 0x3241: -case 0x3441: -case 0x3641: -case 0x3841: -case 0x3A41: -case 0x3C41: -case 0x3E41: -case 0x3042: -case 0x3242: -case 0x3442: -case 0x3642: -case 0x3842: -case 0x3A42: -case 0x3C42: -case 0x3E42: -case 0x3043: -case 0x3243: -case 0x3443: -case 0x3643: -case 0x3843: -case 0x3A43: -case 0x3C43: -case 0x3E43: -case 0x3044: -case 0x3244: -case 0x3444: -case 0x3644: -case 0x3844: -case 0x3A44: -case 0x3C44: -case 0x3E44: -case 0x3045: -case 0x3245: -case 0x3445: -case 0x3645: -case 0x3845: -case 0x3A45: -case 0x3C45: -case 0x3E45: -case 0x3046: -case 0x3246: -case 0x3446: -case 0x3646: -case 0x3846: -case 0x3A46: -case 0x3C46: -case 0x3E46: -case 0x3047: -case 0x3247: -case 0x3447: -case 0x3647: -case 0x3847: -case 0x3A47: -case 0x3C47: -case 0x3E47: - -// MOVEAW -case 0x3040: -{ - u32 res; - res = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x3248: -case 0x3448: -case 0x3648: -case 0x3848: -case 0x3A48: -case 0x3C48: -case 0x3E48: -case 0x3049: -case 0x3249: -case 0x3449: -case 0x3649: -case 0x3849: -case 0x3A49: -case 0x3C49: -case 0x3E49: -case 0x304A: -case 0x324A: -case 0x344A: -case 0x364A: -case 0x384A: -case 0x3A4A: -case 0x3C4A: -case 0x3E4A: -case 0x304B: -case 0x324B: -case 0x344B: -case 0x364B: -case 0x384B: -case 0x3A4B: -case 0x3C4B: -case 0x3E4B: -case 0x304C: -case 0x324C: -case 0x344C: -case 0x364C: -case 0x384C: -case 0x3A4C: -case 0x3C4C: -case 0x3E4C: -case 0x304D: -case 0x324D: -case 0x344D: -case 0x364D: -case 0x384D: -case 0x3A4D: -case 0x3C4D: -case 0x3E4D: -case 0x304E: -case 0x324E: -case 0x344E: -case 0x364E: -case 0x384E: -case 0x3A4E: -case 0x3C4E: -case 0x3E4E: -case 0x304F: -case 0x324F: -case 0x344F: -case 0x364F: -case 0x384F: -case 0x3A4F: -case 0x3C4F: -case 0x3E4F: - -// MOVEAW -case 0x3048: -{ - u32 res; - res = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x3250: -case 0x3450: -case 0x3650: -case 0x3850: -case 0x3A50: -case 0x3C50: -case 0x3E50: -case 0x3051: -case 0x3251: -case 0x3451: -case 0x3651: -case 0x3851: -case 0x3A51: -case 0x3C51: -case 0x3E51: -case 0x3052: -case 0x3252: -case 0x3452: -case 0x3652: -case 0x3852: -case 0x3A52: -case 0x3C52: -case 0x3E52: -case 0x3053: -case 0x3253: -case 0x3453: -case 0x3653: -case 0x3853: -case 0x3A53: -case 0x3C53: -case 0x3E53: -case 0x3054: -case 0x3254: -case 0x3454: -case 0x3654: -case 0x3854: -case 0x3A54: -case 0x3C54: -case 0x3E54: -case 0x3055: -case 0x3255: -case 0x3455: -case 0x3655: -case 0x3855: -case 0x3A55: -case 0x3C55: -case 0x3E55: -case 0x3056: -case 0x3256: -case 0x3456: -case 0x3656: -case 0x3856: -case 0x3A56: -case 0x3C56: -case 0x3E56: -case 0x3057: -case 0x3257: -case 0x3457: -case 0x3657: -case 0x3857: -case 0x3A57: -case 0x3C57: -case 0x3E57: - -// MOVEAW -case 0x3050: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(8) -case 0x3258: -case 0x3458: -case 0x3658: -case 0x3858: -case 0x3A58: -case 0x3C58: -case 0x3E58: -case 0x3059: -case 0x3259: -case 0x3459: -case 0x3659: -case 0x3859: -case 0x3A59: -case 0x3C59: -case 0x3E59: -case 0x305A: -case 0x325A: -case 0x345A: -case 0x365A: -case 0x385A: -case 0x3A5A: -case 0x3C5A: -case 0x3E5A: -case 0x305B: -case 0x325B: -case 0x345B: -case 0x365B: -case 0x385B: -case 0x3A5B: -case 0x3C5B: -case 0x3E5B: -case 0x305C: -case 0x325C: -case 0x345C: -case 0x365C: -case 0x385C: -case 0x3A5C: -case 0x3C5C: -case 0x3E5C: -case 0x305D: -case 0x325D: -case 0x345D: -case 0x365D: -case 0x385D: -case 0x3A5D: -case 0x3C5D: -case 0x3E5D: -case 0x305E: -case 0x325E: -case 0x345E: -case 0x365E: -case 0x385E: -case 0x3A5E: -case 0x3C5E: -case 0x3E5E: - -// MOVEAW -case 0x3058: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(8) -case 0x3260: -case 0x3460: -case 0x3660: -case 0x3860: -case 0x3A60: -case 0x3C60: -case 0x3E60: -case 0x3061: -case 0x3261: -case 0x3461: -case 0x3661: -case 0x3861: -case 0x3A61: -case 0x3C61: -case 0x3E61: -case 0x3062: -case 0x3262: -case 0x3462: -case 0x3662: -case 0x3862: -case 0x3A62: -case 0x3C62: -case 0x3E62: -case 0x3063: -case 0x3263: -case 0x3463: -case 0x3663: -case 0x3863: -case 0x3A63: -case 0x3C63: -case 0x3E63: -case 0x3064: -case 0x3264: -case 0x3464: -case 0x3664: -case 0x3864: -case 0x3A64: -case 0x3C64: -case 0x3E64: -case 0x3065: -case 0x3265: -case 0x3465: -case 0x3665: -case 0x3865: -case 0x3A65: -case 0x3C65: -case 0x3E65: -case 0x3066: -case 0x3266: -case 0x3466: -case 0x3666: -case 0x3866: -case 0x3A66: -case 0x3C66: -case 0x3E66: - -// MOVEAW -case 0x3060: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(10) -case 0x3268: -case 0x3468: -case 0x3668: -case 0x3868: -case 0x3A68: -case 0x3C68: -case 0x3E68: -case 0x3069: -case 0x3269: -case 0x3469: -case 0x3669: -case 0x3869: -case 0x3A69: -case 0x3C69: -case 0x3E69: -case 0x306A: -case 0x326A: -case 0x346A: -case 0x366A: -case 0x386A: -case 0x3A6A: -case 0x3C6A: -case 0x3E6A: -case 0x306B: -case 0x326B: -case 0x346B: -case 0x366B: -case 0x386B: -case 0x3A6B: -case 0x3C6B: -case 0x3E6B: -case 0x306C: -case 0x326C: -case 0x346C: -case 0x366C: -case 0x386C: -case 0x3A6C: -case 0x3C6C: -case 0x3E6C: -case 0x306D: -case 0x326D: -case 0x346D: -case 0x366D: -case 0x386D: -case 0x3A6D: -case 0x3C6D: -case 0x3E6D: -case 0x306E: -case 0x326E: -case 0x346E: -case 0x366E: -case 0x386E: -case 0x3A6E: -case 0x3C6E: -case 0x3E6E: -case 0x306F: -case 0x326F: -case 0x346F: -case 0x366F: -case 0x386F: -case 0x3A6F: -case 0x3C6F: -case 0x3E6F: - -// MOVEAW -case 0x3068: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x3270: -case 0x3470: -case 0x3670: -case 0x3870: -case 0x3A70: -case 0x3C70: -case 0x3E70: -case 0x3071: -case 0x3271: -case 0x3471: -case 0x3671: -case 0x3871: -case 0x3A71: -case 0x3C71: -case 0x3E71: -case 0x3072: -case 0x3272: -case 0x3472: -case 0x3672: -case 0x3872: -case 0x3A72: -case 0x3C72: -case 0x3E72: -case 0x3073: -case 0x3273: -case 0x3473: -case 0x3673: -case 0x3873: -case 0x3A73: -case 0x3C73: -case 0x3E73: -case 0x3074: -case 0x3274: -case 0x3474: -case 0x3674: -case 0x3874: -case 0x3A74: -case 0x3C74: -case 0x3E74: -case 0x3075: -case 0x3275: -case 0x3475: -case 0x3675: -case 0x3875: -case 0x3A75: -case 0x3C75: -case 0x3E75: -case 0x3076: -case 0x3276: -case 0x3476: -case 0x3676: -case 0x3876: -case 0x3A76: -case 0x3C76: -case 0x3E76: -case 0x3077: -case 0x3277: -case 0x3477: -case 0x3677: -case 0x3877: -case 0x3A77: -case 0x3C77: -case 0x3E77: - -// MOVEAW -case 0x3070: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x3278: -case 0x3478: -case 0x3678: -case 0x3878: -case 0x3A78: -case 0x3C78: -case 0x3E78: - -// MOVEAW -case 0x3078: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x3279: -case 0x3479: -case 0x3679: -case 0x3879: -case 0x3A79: -case 0x3C79: -case 0x3E79: - -// MOVEAW -case 0x3079: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x327A: -case 0x347A: -case 0x367A: -case 0x387A: -case 0x3A7A: -case 0x3C7A: -case 0x3E7A: - -// MOVEAW -case 0x307A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x327B: -case 0x347B: -case 0x367B: -case 0x387B: -case 0x3A7B: -case 0x3C7B: -case 0x3E7B: - -// MOVEAW -case 0x307B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x327C: -case 0x347C: -case 0x367C: -case 0x387C: -case 0x3A7C: -case 0x3C7C: -case 0x3E7C: - -// MOVEAW -case 0x307C: -{ - u32 res; - res = (s32)(s16)FETCH_WORD; - PC += 2; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x325F: -case 0x345F: -case 0x365F: -case 0x385F: -case 0x3A5F: -case 0x3C5F: -case 0x3E5F: - -// MOVEAW -case 0x305F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(8) -case 0x3267: -case 0x3467: -case 0x3667: -case 0x3867: -case 0x3A67: -case 0x3C67: -case 0x3E67: - -// MOVEAW -case 0x3067: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(10) diff --git a/yabause/src/c68k/c68k_op4.inc b/yabause/src/c68k/c68k_op4.inc deleted file mode 100644 index 156122a392..0000000000 --- a/yabause/src/c68k/c68k_op4.inc +++ /dev/null @@ -1,7508 +0,0 @@ -case 0x4001: -case 0x4002: -case 0x4003: -case 0x4004: -case 0x4005: -case 0x4006: -case 0x4007: - -// NEGX -case 0x4000: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4011: -case 0x4012: -case 0x4013: -case 0x4014: -case 0x4015: -case 0x4016: -case 0x4017: - -// NEGX -case 0x4010: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4019: -case 0x401A: -case 0x401B: -case 0x401C: -case 0x401D: -case 0x401E: - -// NEGX -case 0x4018: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4021: -case 0x4022: -case 0x4023: -case 0x4024: -case 0x4025: -case 0x4026: - -// NEGX -case 0x4020: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4029: -case 0x402A: -case 0x402B: -case 0x402C: -case 0x402D: -case 0x402E: -case 0x402F: - -// NEGX -case 0x4028: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4031: -case 0x4032: -case 0x4033: -case 0x4034: -case 0x4035: -case 0x4036: -case 0x4037: - -// NEGX -case 0x4030: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// NEGX -case 0x4038: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// NEGX -case 0x4039: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// NEGX -case 0x401F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// NEGX -case 0x4027: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4041: -case 0x4042: -case 0x4043: -case 0x4044: -case 0x4045: -case 0x4046: -case 0x4047: - -// NEGX -case 0x4040: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4051: -case 0x4052: -case 0x4053: -case 0x4054: -case 0x4055: -case 0x4056: -case 0x4057: - -// NEGX -case 0x4050: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4059: -case 0x405A: -case 0x405B: -case 0x405C: -case 0x405D: -case 0x405E: - -// NEGX -case 0x4058: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4061: -case 0x4062: -case 0x4063: -case 0x4064: -case 0x4065: -case 0x4066: - -// NEGX -case 0x4060: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4069: -case 0x406A: -case 0x406B: -case 0x406C: -case 0x406D: -case 0x406E: -case 0x406F: - -// NEGX -case 0x4068: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4071: -case 0x4072: -case 0x4073: -case 0x4074: -case 0x4075: -case 0x4076: -case 0x4077: - -// NEGX -case 0x4070: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// NEGX -case 0x4078: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// NEGX -case 0x4079: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// NEGX -case 0x405F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// NEGX -case 0x4067: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4081: -case 0x4082: -case 0x4083: -case 0x4084: -case 0x4085: -case 0x4086: -case 0x4087: - -// NEGX -case 0x4080: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4091: -case 0x4092: -case 0x4093: -case 0x4094: -case 0x4095: -case 0x4096: -case 0x4097: - -// NEGX -case 0x4090: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4099: -case 0x409A: -case 0x409B: -case 0x409C: -case 0x409D: -case 0x409E: - -// NEGX -case 0x4098: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x40A1: -case 0x40A2: -case 0x40A3: -case 0x40A4: -case 0x40A5: -case 0x40A6: - -// NEGX -case 0x40A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x40A9: -case 0x40AA: -case 0x40AB: -case 0x40AC: -case 0x40AD: -case 0x40AE: -case 0x40AF: - -// NEGX -case 0x40A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x40B1: -case 0x40B2: -case 0x40B3: -case 0x40B4: -case 0x40B5: -case 0x40B6: -case 0x40B7: - -// NEGX -case 0x40B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// NEGX -case 0x40B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// NEGX -case 0x40B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// NEGX -case 0x409F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// NEGX -case 0x40A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x4201: -case 0x4202: -case 0x4203: -case 0x4204: -case 0x4205: -case 0x4206: -case 0x4207: - -// CLR -case 0x4200: -{ - u32 res; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4211: -case 0x4212: -case 0x4213: -case 0x4214: -case 0x4215: -case 0x4216: -case 0x4217: - -// CLR -case 0x4210: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4219: -case 0x421A: -case 0x421B: -case 0x421C: -case 0x421D: -case 0x421E: - -// CLR -case 0x4218: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4221: -case 0x4222: -case 0x4223: -case 0x4224: -case 0x4225: -case 0x4226: - -// CLR -case 0x4220: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4229: -case 0x422A: -case 0x422B: -case 0x422C: -case 0x422D: -case 0x422E: -case 0x422F: - -// CLR -case 0x4228: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4231: -case 0x4232: -case 0x4233: -case 0x4234: -case 0x4235: -case 0x4236: -case 0x4237: - -// CLR -case 0x4230: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// CLR -case 0x4238: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// CLR -case 0x4239: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// CLR -case 0x421F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// CLR -case 0x4227: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4241: -case 0x4242: -case 0x4243: -case 0x4244: -case 0x4245: -case 0x4246: -case 0x4247: - -// CLR -case 0x4240: -{ - u32 res; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4251: -case 0x4252: -case 0x4253: -case 0x4254: -case 0x4255: -case 0x4256: -case 0x4257: - -// CLR -case 0x4250: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4259: -case 0x425A: -case 0x425B: -case 0x425C: -case 0x425D: -case 0x425E: - -// CLR -case 0x4258: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4261: -case 0x4262: -case 0x4263: -case 0x4264: -case 0x4265: -case 0x4266: - -// CLR -case 0x4260: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4269: -case 0x426A: -case 0x426B: -case 0x426C: -case 0x426D: -case 0x426E: -case 0x426F: - -// CLR -case 0x4268: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4271: -case 0x4272: -case 0x4273: -case 0x4274: -case 0x4275: -case 0x4276: -case 0x4277: - -// CLR -case 0x4270: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// CLR -case 0x4278: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// CLR -case 0x4279: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// CLR -case 0x425F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// CLR -case 0x4267: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4281: -case 0x4282: -case 0x4283: -case 0x4284: -case 0x4285: -case 0x4286: -case 0x4287: - -// CLR -case 0x4280: -{ - u32 res; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4291: -case 0x4292: -case 0x4293: -case 0x4294: -case 0x4295: -case 0x4296: -case 0x4297: - -// CLR -case 0x4290: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4299: -case 0x429A: -case 0x429B: -case 0x429C: -case 0x429D: -case 0x429E: - -// CLR -case 0x4298: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x42A1: -case 0x42A2: -case 0x42A3: -case 0x42A4: -case 0x42A5: -case 0x42A6: - -// CLR -case 0x42A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x42A9: -case 0x42AA: -case 0x42AB: -case 0x42AC: -case 0x42AD: -case 0x42AE: -case 0x42AF: - -// CLR -case 0x42A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x42B1: -case 0x42B2: -case 0x42B3: -case 0x42B4: -case 0x42B5: -case 0x42B6: -case 0x42B7: - -// CLR -case 0x42B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// CLR -case 0x42B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// CLR -case 0x42B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// CLR -case 0x429F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// CLR -case 0x42A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x4401: -case 0x4402: -case 0x4403: -case 0x4404: -case 0x4405: -case 0x4406: -case 0x4407: - -// NEG -case 0x4400: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4411: -case 0x4412: -case 0x4413: -case 0x4414: -case 0x4415: -case 0x4416: -case 0x4417: - -// NEG -case 0x4410: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4419: -case 0x441A: -case 0x441B: -case 0x441C: -case 0x441D: -case 0x441E: - -// NEG -case 0x4418: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4421: -case 0x4422: -case 0x4423: -case 0x4424: -case 0x4425: -case 0x4426: - -// NEG -case 0x4420: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4429: -case 0x442A: -case 0x442B: -case 0x442C: -case 0x442D: -case 0x442E: -case 0x442F: - -// NEG -case 0x4428: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4431: -case 0x4432: -case 0x4433: -case 0x4434: -case 0x4435: -case 0x4436: -case 0x4437: - -// NEG -case 0x4430: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// NEG -case 0x4438: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// NEG -case 0x4439: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// NEG -case 0x441F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// NEG -case 0x4427: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4441: -case 0x4442: -case 0x4443: -case 0x4444: -case 0x4445: -case 0x4446: -case 0x4447: - -// NEG -case 0x4440: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4451: -case 0x4452: -case 0x4453: -case 0x4454: -case 0x4455: -case 0x4456: -case 0x4457: - -// NEG -case 0x4450: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4459: -case 0x445A: -case 0x445B: -case 0x445C: -case 0x445D: -case 0x445E: - -// NEG -case 0x4458: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4461: -case 0x4462: -case 0x4463: -case 0x4464: -case 0x4465: -case 0x4466: - -// NEG -case 0x4460: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4469: -case 0x446A: -case 0x446B: -case 0x446C: -case 0x446D: -case 0x446E: -case 0x446F: - -// NEG -case 0x4468: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4471: -case 0x4472: -case 0x4473: -case 0x4474: -case 0x4475: -case 0x4476: -case 0x4477: - -// NEG -case 0x4470: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// NEG -case 0x4478: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// NEG -case 0x4479: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// NEG -case 0x445F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// NEG -case 0x4467: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4481: -case 0x4482: -case 0x4483: -case 0x4484: -case 0x4485: -case 0x4486: -case 0x4487: - -// NEG -case 0x4480: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4491: -case 0x4492: -case 0x4493: -case 0x4494: -case 0x4495: -case 0x4496: -case 0x4497: - -// NEG -case 0x4490: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4499: -case 0x449A: -case 0x449B: -case 0x449C: -case 0x449D: -case 0x449E: - -// NEG -case 0x4498: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x44A1: -case 0x44A2: -case 0x44A3: -case 0x44A4: -case 0x44A5: -case 0x44A6: - -// NEG -case 0x44A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x44A9: -case 0x44AA: -case 0x44AB: -case 0x44AC: -case 0x44AD: -case 0x44AE: -case 0x44AF: - -// NEG -case 0x44A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x44B1: -case 0x44B2: -case 0x44B3: -case 0x44B4: -case 0x44B5: -case 0x44B6: -case 0x44B7: - -// NEG -case 0x44B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// NEG -case 0x44B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// NEG -case 0x44B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// NEG -case 0x449F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// NEG -case 0x44A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x4601: -case 0x4602: -case 0x4603: -case 0x4604: -case 0x4605: -case 0x4606: -case 0x4607: - -// NOT -case 0x4600: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4611: -case 0x4612: -case 0x4613: -case 0x4614: -case 0x4615: -case 0x4616: -case 0x4617: - -// NOT -case 0x4610: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4619: -case 0x461A: -case 0x461B: -case 0x461C: -case 0x461D: -case 0x461E: - -// NOT -case 0x4618: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4621: -case 0x4622: -case 0x4623: -case 0x4624: -case 0x4625: -case 0x4626: - -// NOT -case 0x4620: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4629: -case 0x462A: -case 0x462B: -case 0x462C: -case 0x462D: -case 0x462E: -case 0x462F: - -// NOT -case 0x4628: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4631: -case 0x4632: -case 0x4633: -case 0x4634: -case 0x4635: -case 0x4636: -case 0x4637: - -// NOT -case 0x4630: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// NOT -case 0x4638: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// NOT -case 0x4639: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// NOT -case 0x461F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// NOT -case 0x4627: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4641: -case 0x4642: -case 0x4643: -case 0x4644: -case 0x4645: -case 0x4646: -case 0x4647: - -// NOT -case 0x4640: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4651: -case 0x4652: -case 0x4653: -case 0x4654: -case 0x4655: -case 0x4656: -case 0x4657: - -// NOT -case 0x4650: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4659: -case 0x465A: -case 0x465B: -case 0x465C: -case 0x465D: -case 0x465E: - -// NOT -case 0x4658: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4661: -case 0x4662: -case 0x4663: -case 0x4664: -case 0x4665: -case 0x4666: - -// NOT -case 0x4660: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4669: -case 0x466A: -case 0x466B: -case 0x466C: -case 0x466D: -case 0x466E: -case 0x466F: - -// NOT -case 0x4668: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4671: -case 0x4672: -case 0x4673: -case 0x4674: -case 0x4675: -case 0x4676: -case 0x4677: - -// NOT -case 0x4670: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// NOT -case 0x4678: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// NOT -case 0x4679: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// NOT -case 0x465F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// NOT -case 0x4667: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4681: -case 0x4682: -case 0x4683: -case 0x4684: -case 0x4685: -case 0x4686: -case 0x4687: - -// NOT -case 0x4680: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4691: -case 0x4692: -case 0x4693: -case 0x4694: -case 0x4695: -case 0x4696: -case 0x4697: - -// NOT -case 0x4690: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4699: -case 0x469A: -case 0x469B: -case 0x469C: -case 0x469D: -case 0x469E: - -// NOT -case 0x4698: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x46A1: -case 0x46A2: -case 0x46A3: -case 0x46A4: -case 0x46A5: -case 0x46A6: - -// NOT -case 0x46A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x46A9: -case 0x46AA: -case 0x46AB: -case 0x46AC: -case 0x46AD: -case 0x46AE: -case 0x46AF: - -// NOT -case 0x46A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x46B1: -case 0x46B2: -case 0x46B3: -case 0x46B4: -case 0x46B5: -case 0x46B6: -case 0x46B7: - -// NOT -case 0x46B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// NOT -case 0x46B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// NOT -case 0x46B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// NOT -case 0x469F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// NOT -case 0x46A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x40C1: -case 0x40C2: -case 0x40C3: -case 0x40C4: -case 0x40C5: -case 0x40C6: -case 0x40C7: - -// MOVESRa -case 0x40C0: -{ - u32 res; - res = GET_SR; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x40D1: -case 0x40D2: -case 0x40D3: -case 0x40D4: -case 0x40D5: -case 0x40D6: -case 0x40D7: - -// MOVESRa -case 0x40D0: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x40D9: -case 0x40DA: -case 0x40DB: -case 0x40DC: -case 0x40DD: -case 0x40DE: - -// MOVESRa -case 0x40D8: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x40E1: -case 0x40E2: -case 0x40E3: -case 0x40E4: -case 0x40E5: -case 0x40E6: - -// MOVESRa -case 0x40E0: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x40E9: -case 0x40EA: -case 0x40EB: -case 0x40EC: -case 0x40ED: -case 0x40EE: -case 0x40EF: - -// MOVESRa -case 0x40E8: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x40F1: -case 0x40F2: -case 0x40F3: -case 0x40F4: -case 0x40F5: -case 0x40F6: -case 0x40F7: - -// MOVESRa -case 0x40F0: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVESRa -case 0x40F8: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVESRa -case 0x40F9: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVESRa -case 0x40DF: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// MOVESRa -case 0x40E7: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x44C1: -case 0x44C2: -case 0x44C3: -case 0x44C4: -case 0x44C5: -case 0x44C6: -case 0x44C7: - -// MOVEaCCR -case 0x44C0: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - SET_CCR(res) -} -RET(12) -case 0x44D1: -case 0x44D2: -case 0x44D3: -case 0x44D4: -case 0x44D5: -case 0x44D6: -case 0x44D7: - -// MOVEaCCR -case 0x44D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(16) -case 0x44D9: -case 0x44DA: -case 0x44DB: -case 0x44DC: -case 0x44DD: -case 0x44DE: - -// MOVEaCCR -case 0x44D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(16) -case 0x44E1: -case 0x44E2: -case 0x44E3: -case 0x44E4: -case 0x44E5: -case 0x44E6: - -// MOVEaCCR -case 0x44E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(18) -case 0x44E9: -case 0x44EA: -case 0x44EB: -case 0x44EC: -case 0x44ED: -case 0x44EE: -case 0x44EF: - -// MOVEaCCR -case 0x44E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(20) -case 0x44F1: -case 0x44F2: -case 0x44F3: -case 0x44F4: -case 0x44F5: -case 0x44F6: -case 0x44F7: - -// MOVEaCCR -case 0x44F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(22) - -// MOVEaCCR -case 0x44F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(20) - -// MOVEaCCR -case 0x44F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(24) - -// MOVEaCCR -case 0x44FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(20) - -// MOVEaCCR -case 0x44FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(22) - -// MOVEaCCR -case 0x44FC: -{ - u32 res; - res = FETCH_WORD; - PC += 2; - SET_CCR(res) -} -RET(16) - -// MOVEaCCR -case 0x44DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(16) - -// MOVEaCCR -case 0x44E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(18) -case 0x46C1: -case 0x46C2: -case 0x46C3: -case 0x46C4: -case 0x46C5: -case 0x46C6: -case 0x46C7: - -// MOVEaSR -case 0x46C0: -{ - u32 res; - if (CPU->flag_S) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 12; -goto C68k_Exec_End; -case 0x46D1: -case 0x46D2: -case 0x46D3: -case 0x46D4: -case 0x46D5: -case 0x46D6: -case 0x46D7: - -// MOVEaSR -case 0x46D0: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; -case 0x46D9: -case 0x46DA: -case 0x46DB: -case 0x46DC: -case 0x46DD: -case 0x46DE: - -// MOVEaSR -case 0x46D8: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; -case 0x46E1: -case 0x46E2: -case 0x46E3: -case 0x46E4: -case 0x46E5: -case 0x46E6: - -// MOVEaSR -case 0x46E0: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 18; -goto C68k_Exec_End; -case 0x46E9: -case 0x46EA: -case 0x46EB: -case 0x46EC: -case 0x46ED: -case 0x46EE: -case 0x46EF: - -// MOVEaSR -case 0x46E8: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x46F1: -case 0x46F2: -case 0x46F3: -case 0x46F4: -case 0x46F5: -case 0x46F6: -case 0x46F7: - -// MOVEaSR -case 0x46F0: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 22; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46F8: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46F9: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 24; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46FA: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46FB: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 22; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46FC: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD; - PC += 2; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46DF: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46E7: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 18; -goto C68k_Exec_End; -case 0x4801: -case 0x4802: -case 0x4803: -case 0x4804: -case 0x4805: -case 0x4806: -case 0x4807: - -// NBCD -case 0x4800: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; -} -RET(6) -case 0x4811: -case 0x4812: -case 0x4813: -case 0x4814: -case 0x4815: -case 0x4816: -case 0x4817: - -// NBCD -case 0x4810: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(12) -case 0x4819: -case 0x481A: -case 0x481B: -case 0x481C: -case 0x481D: -case 0x481E: - -// NBCD -case 0x4818: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(12) -case 0x4821: -case 0x4822: -case 0x4823: -case 0x4824: -case 0x4825: -case 0x4826: - -// NBCD -case 0x4820: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(14) -case 0x4829: -case 0x482A: -case 0x482B: -case 0x482C: -case 0x482D: -case 0x482E: -case 0x482F: - -// NBCD -case 0x4828: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(16) -case 0x4831: -case 0x4832: -case 0x4833: -case 0x4834: -case 0x4835: -case 0x4836: -case 0x4837: - -// NBCD -case 0x4830: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(18) - -// NBCD -case 0x4838: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(16) - -// NBCD -case 0x4839: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(20) - -// NBCD -case 0x481F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(12) - -// NBCD -case 0x4827: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(14) -case 0x4851: -case 0x4852: -case 0x4853: -case 0x4854: -case 0x4855: -case 0x4856: -case 0x4857: - -// PEA -case 0x4850: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(12) -case 0x4869: -case 0x486A: -case 0x486B: -case 0x486C: -case 0x486D: -case 0x486E: -case 0x486F: - -// PEA -case 0x4868: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(16) -case 0x4871: -case 0x4872: -case 0x4873: -case 0x4874: -case 0x4875: -case 0x4876: -case 0x4877: - -// PEA -case 0x4870: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(20) - -// PEA -case 0x4878: -{ - u32 adr; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(16) - -// PEA -case 0x4879: -{ - u32 adr; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(20) - -// PEA -case 0x487A: -{ - u32 adr; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(16) - -// PEA -case 0x487B: -{ - u32 adr; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(20) -case 0x4841: -case 0x4842: -case 0x4843: -case 0x4844: -case 0x4845: -case 0x4846: -case 0x4847: - -// SWAP -case 0x4840: -{ - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res = (res >> 16) | (res << 16); - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4891: -case 0x4892: -case 0x4893: -case 0x4894: -case 0x4895: -case 0x4896: -case 0x4897: - -// MOVEMRa -case 0x4890: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x48A1: -case 0x48A2: -case 0x48A3: -case 0x48A4: -case 0x48A5: -case 0x48A6: - -// MOVEMRa -case 0x48A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 2; - WRITE_WORD_F(adr, *(u16*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x48A9: -case 0x48AA: -case 0x48AB: -case 0x48AC: -case 0x48AD: -case 0x48AE: -case 0x48AF: - -// MOVEMRa -case 0x48A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(20) -case 0x48B1: -case 0x48B2: -case 0x48B3: -case 0x48B4: -case 0x48B5: -case 0x48B6: -case 0x48B7: - -// MOVEMRa -case 0x48B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMRa -case 0x48B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(20) - -// MOVEMRa -case 0x48B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMRa -case 0x48A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 2; - WRITE_WORD_F(adr, *(u16*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x48D1: -case 0x48D2: -case 0x48D3: -case 0x48D4: -case 0x48D5: -case 0x48D6: -case 0x48D7: - -// MOVEMRa -case 0x48D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(16) -case 0x48E1: -case 0x48E2: -case 0x48E3: -case 0x48E4: -case 0x48E5: -case 0x48E6: - -// MOVEMRa -case 0x48E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 4; - WRITE_LONG_DEC_F(adr, *(u32*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x48E9: -case 0x48EA: -case 0x48EB: -case 0x48EC: -case 0x48ED: -case 0x48EE: -case 0x48EF: - -// MOVEMRa -case 0x48E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) -case 0x48F1: -case 0x48F2: -case 0x48F3: -case 0x48F4: -case 0x48F5: -case 0x48F6: -case 0x48F7: - -// MOVEMRa -case 0x48F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMRa -case 0x48F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMRa -case 0x48F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMRa -case 0x48E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 4; - WRITE_LONG_DEC_F(adr, *(u32*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x4881: -case 0x4882: -case 0x4883: -case 0x4884: -case 0x4885: -case 0x4886: -case 0x4887: - -// EXT -case 0x4880: -{ - u32 res; - res = (s32)(s8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x48C1: -case 0x48C2: -case 0x48C3: -case 0x48C4: -case 0x48C5: -case 0x48C6: -case 0x48C7: - -// EXT -case 0x48C0: -{ - u32 res; - res = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4A01: -case 0x4A02: -case 0x4A03: -case 0x4A04: -case 0x4A05: -case 0x4A06: -case 0x4A07: - -// TST -case 0x4A00: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; -} -RET(4) -case 0x4A11: -case 0x4A12: -case 0x4A13: -case 0x4A14: -case 0x4A15: -case 0x4A16: -case 0x4A17: - -// TST -case 0x4A10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(8) -case 0x4A19: -case 0x4A1A: -case 0x4A1B: -case 0x4A1C: -case 0x4A1D: -case 0x4A1E: - -// TST -case 0x4A18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(8) -case 0x4A21: -case 0x4A22: -case 0x4A23: -case 0x4A24: -case 0x4A25: -case 0x4A26: - -// TST -case 0x4A20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(10) -case 0x4A29: -case 0x4A2A: -case 0x4A2B: -case 0x4A2C: -case 0x4A2D: -case 0x4A2E: -case 0x4A2F: - -// TST -case 0x4A28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(12) -case 0x4A31: -case 0x4A32: -case 0x4A33: -case 0x4A34: -case 0x4A35: -case 0x4A36: -case 0x4A37: - -// TST -case 0x4A30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(14) - -// TST -case 0x4A38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(12) - -// TST -case 0x4A39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(16) - -// TST -case 0x4A1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(8) - -// TST -case 0x4A27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(10) -case 0x4A41: -case 0x4A42: -case 0x4A43: -case 0x4A44: -case 0x4A45: -case 0x4A46: -case 0x4A47: - -// TST -case 0x4A40: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; -} -RET(4) -case 0x4A51: -case 0x4A52: -case 0x4A53: -case 0x4A54: -case 0x4A55: -case 0x4A56: -case 0x4A57: - -// TST -case 0x4A50: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(8) -case 0x4A59: -case 0x4A5A: -case 0x4A5B: -case 0x4A5C: -case 0x4A5D: -case 0x4A5E: - -// TST -case 0x4A58: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(8) -case 0x4A61: -case 0x4A62: -case 0x4A63: -case 0x4A64: -case 0x4A65: -case 0x4A66: - -// TST -case 0x4A60: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(10) -case 0x4A69: -case 0x4A6A: -case 0x4A6B: -case 0x4A6C: -case 0x4A6D: -case 0x4A6E: -case 0x4A6F: - -// TST -case 0x4A68: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(12) -case 0x4A71: -case 0x4A72: -case 0x4A73: -case 0x4A74: -case 0x4A75: -case 0x4A76: -case 0x4A77: - -// TST -case 0x4A70: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(14) - -// TST -case 0x4A78: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(12) - -// TST -case 0x4A79: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(16) - -// TST -case 0x4A5F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(8) - -// TST -case 0x4A67: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(10) -case 0x4A81: -case 0x4A82: -case 0x4A83: -case 0x4A84: -case 0x4A85: -case 0x4A86: -case 0x4A87: - -// TST -case 0x4A80: -{ - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; -} -RET(4) -case 0x4A91: -case 0x4A92: -case 0x4A93: -case 0x4A94: -case 0x4A95: -case 0x4A96: -case 0x4A97: - -// TST -case 0x4A90: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0x4A99: -case 0x4A9A: -case 0x4A9B: -case 0x4A9C: -case 0x4A9D: -case 0x4A9E: - -// TST -case 0x4A98: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0x4AA1: -case 0x4AA2: -case 0x4AA3: -case 0x4AA4: -case 0x4AA5: -case 0x4AA6: - -// TST -case 0x4AA0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0x4AA9: -case 0x4AAA: -case 0x4AAB: -case 0x4AAC: -case 0x4AAD: -case 0x4AAE: -case 0x4AAF: - -// TST -case 0x4AA8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0x4AB1: -case 0x4AB2: -case 0x4AB3: -case 0x4AB4: -case 0x4AB5: -case 0x4AB6: -case 0x4AB7: - -// TST -case 0x4AB0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) - -// TST -case 0x4AB8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) - -// TST -case 0x4AB9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) - -// TST -case 0x4A9F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) - -// TST -case 0x4AA7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0x4AC1: -case 0x4AC2: -case 0x4AC3: -case 0x4AC4: -case 0x4AC5: -case 0x4AC6: -case 0x4AC7: - -// TAS -case 0x4AC0: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4AD1: -case 0x4AD2: -case 0x4AD3: -case 0x4AD4: -case 0x4AD5: -case 0x4AD6: -case 0x4AD7: - -// TAS -case 0x4AD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x4AD9: -case 0x4ADA: -case 0x4ADB: -case 0x4ADC: -case 0x4ADD: -case 0x4ADE: - -// TAS -case 0x4AD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x4AE1: -case 0x4AE2: -case 0x4AE3: -case 0x4AE4: -case 0x4AE5: -case 0x4AE6: - -// TAS -case 0x4AE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(10) -case 0x4AE9: -case 0x4AEA: -case 0x4AEB: -case 0x4AEC: -case 0x4AED: -case 0x4AEE: -case 0x4AEF: - -// TAS -case 0x4AE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4AF1: -case 0x4AF2: -case 0x4AF3: -case 0x4AF4: -case 0x4AF5: -case 0x4AF6: -case 0x4AF7: - -// TAS -case 0x4AF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) - -// TAS -case 0x4AF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// TAS -case 0x4AF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// TAS -case 0x4ADF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) - -// TAS -case 0x4AE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(10) - -// ILLEGAL -case 0x4AFC: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ILLEGAL_INSTRUCTION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) -case 0x4C91: -case 0x4C92: -case 0x4C93: -case 0x4C94: -case 0x4C95: -case 0x4C96: -case 0x4C97: - -// MOVEMaR -case 0x4C90: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(16) -case 0x4C99: -case 0x4C9A: -case 0x4C9B: -case 0x4C9C: -case 0x4C9D: -case 0x4C9E: - -// MOVEMaR -case 0x4C98: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4CA9: -case 0x4CAA: -case 0x4CAB: -case 0x4CAC: -case 0x4CAD: -case 0x4CAE: -case 0x4CAF: - -// MOVEMaR -case 0x4CA8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) -case 0x4CB1: -case 0x4CB2: -case 0x4CB3: -case 0x4CB4: -case 0x4CB5: -case 0x4CB6: -case 0x4CB7: - -// MOVEMaR -case 0x4CB0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4CB8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMaR -case 0x4CB9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMaR -case 0x4CBA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMaR -case 0x4CBB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4C9F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4CD1: -case 0x4CD2: -case 0x4CD3: -case 0x4CD4: -case 0x4CD5: -case 0x4CD6: -case 0x4CD7: - -// MOVEMaR -case 0x4CD0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(20) -case 0x4CD9: -case 0x4CDA: -case 0x4CDB: -case 0x4CDC: -case 0x4CDD: -case 0x4CDE: - -// MOVEMaR -case 0x4CD8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4CE9: -case 0x4CEA: -case 0x4CEB: -case 0x4CEC: -case 0x4CED: -case 0x4CEE: -case 0x4CEF: - -// MOVEMaR -case 0x4CE8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) -case 0x4CF1: -case 0x4CF2: -case 0x4CF3: -case 0x4CF4: -case 0x4CF5: -case 0x4CF6: -case 0x4CF7: - -// MOVEMaR -case 0x4CF0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMaR -case 0x4CF8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4CF9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(36) - -// MOVEMaR -case 0x4CFA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4CFB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMaR -case 0x4CDF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4E41: -case 0x4E42: -case 0x4E43: -case 0x4E44: -case 0x4E45: -case 0x4E46: -case 0x4E47: -case 0x4E48: -case 0x4E49: -case 0x4E4A: -case 0x4E4B: -case 0x4E4C: -case 0x4E4D: -case 0x4E4E: -case 0x4E4F: - -// TRAP -case 0x4E40: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_TRAP_BASE_EX + (Opcode & 0xF); - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) -case 0x4E51: -case 0x4E52: -case 0x4E53: -case 0x4E54: -case 0x4E55: -case 0x4E56: - -// LINK -case 0x4E50: -{ - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - PRE_IO - PUSH_32_F(res) - res = CPU->A[7]; - CPU->A[(Opcode >> 0) & 7] = res; - CPU->A[7] += (s32)(s16)FETCH_WORD; - PC += 2; - POST_IO -} -RET(16) - -// LINKA7 -case 0x4E57: -{ - CPU->A[7] -= 4; - PRE_IO - WRITE_LONG_DEC_F(CPU->A[7], CPU->A[7]) - CPU->A[7] += (s32)(s16)FETCH_WORD; - PC += 2; - POST_IO -} -RET(16) -case 0x4E59: -case 0x4E5A: -case 0x4E5B: -case 0x4E5C: -case 0x4E5D: -case 0x4E5E: - -// ULNK -case 0x4E58: -{ - u32 res; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->A[7] = src + 4; - PRE_IO - READ_LONG_F(src, res) - CPU->A[(Opcode >> 0) & 7] = res; - POST_IO -} -RET(12) - -// ULNKA7 -case 0x4E5F: -{ - PRE_IO - READ_LONG_F(CPU->A[7], CPU->A[7]) - POST_IO -} -RET(12) -case 0x4E61: -case 0x4E62: -case 0x4E63: -case 0x4E64: -case 0x4E65: -case 0x4E66: -case 0x4E67: - -// MOVEAUSP -case 0x4E60: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->USP = res; -} -RET(4) -case 0x4E69: -case 0x4E6A: -case 0x4E6B: -case 0x4E6C: -case 0x4E6D: -case 0x4E6E: -case 0x4E6F: - -// MOVEUSPA -case 0x4E68: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - res = CPU->USP; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(4) - -// RESET -case 0x4E70: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - PRE_IO - CPU->Reset_CallBack(); - POST_IO -} -RET(132) - -// NOP -case 0x4E71: -{ -} -RET(4) - -// STOP -case 0x4E72: -{ - u32 res; - if (!CPU->flag_S) - { - PC += 2; - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - CPU->Status |= C68K_HALTED; - CCnt = 0; -} -CCnt -= 4; -goto C68k_Exec_End; - -// RTE -case 0x4E73: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - PRE_IO - POP_16_F(res) - SET_SR(res) - POP_32_F(res) - SET_PC(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; - -// RTS -case 0x4E75: -{ - u32 res; - PRE_IO - POP_32_F(res) - SET_PC(res) - POST_IO -} -RET(16) - -// TRAPV -case 0x4E76: -{ - u32 res; - if (CPU->flag_V & 0x80) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_TRAPV_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(4) - -// RTR -case 0x4E77: -{ - u32 res; - PRE_IO - POP_16_F(res) - SET_CCR(res) - POP_32_F(res) - SET_PC(res) - POST_IO -} -RET(20) -case 0x4E91: -case 0x4E92: -case 0x4E93: -case 0x4E94: -case 0x4E95: -case 0x4E96: -case 0x4E97: - -// JSR -case 0x4E90: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(16) -case 0x4EA9: -case 0x4EAA: -case 0x4EAB: -case 0x4EAC: -case 0x4EAD: -case 0x4EAE: -case 0x4EAF: - -// JSR -case 0x4EA8: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(18) -case 0x4EB1: -case 0x4EB2: -case 0x4EB3: -case 0x4EB4: -case 0x4EB5: -case 0x4EB6: -case 0x4EB7: - -// JSR -case 0x4EB0: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(22) - -// JSR -case 0x4EB8: -{ - u32 adr; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(18) - -// JSR -case 0x4EB9: -{ - u32 adr; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(20) - -// JSR -case 0x4EBA: -{ - u32 adr; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(18) - -// JSR -case 0x4EBB: -{ - u32 adr; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(22) -case 0x4ED1: -case 0x4ED2: -case 0x4ED3: -case 0x4ED4: -case 0x4ED5: -case 0x4ED6: -case 0x4ED7: - -// JMP -case 0x4ED0: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - SET_PC(adr) -} -RET(8) -case 0x4EE9: -case 0x4EEA: -case 0x4EEB: -case 0x4EEC: -case 0x4EED: -case 0x4EEE: -case 0x4EEF: - -// JMP -case 0x4EE8: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - SET_PC(adr) -} -RET(10) -case 0x4EF1: -case 0x4EF2: -case 0x4EF3: -case 0x4EF4: -case 0x4EF5: -case 0x4EF6: -case 0x4EF7: - -// JMP -case 0x4EF0: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - SET_PC(adr) -} -RET(14) - -// JMP -case 0x4EF8: -{ - u32 adr; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - SET_PC(adr) -} -RET(10) - -// JMP -case 0x4EF9: -{ - u32 adr; - adr = (s32)FETCH_LONG; - PC += 4; - SET_PC(adr) -} -RET(12) - -// JMP -case 0x4EFA: -{ - u32 adr; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - SET_PC(adr) -} -RET(10) - -// JMP -case 0x4EFB: -{ - u32 adr; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - SET_PC(adr) -} -RET(14) -case 0x4380: -case 0x4580: -case 0x4780: -case 0x4980: -case 0x4B80: -case 0x4D80: -case 0x4F80: -case 0x4181: -case 0x4381: -case 0x4581: -case 0x4781: -case 0x4981: -case 0x4B81: -case 0x4D81: -case 0x4F81: -case 0x4182: -case 0x4382: -case 0x4582: -case 0x4782: -case 0x4982: -case 0x4B82: -case 0x4D82: -case 0x4F82: -case 0x4183: -case 0x4383: -case 0x4583: -case 0x4783: -case 0x4983: -case 0x4B83: -case 0x4D83: -case 0x4F83: -case 0x4184: -case 0x4384: -case 0x4584: -case 0x4784: -case 0x4984: -case 0x4B84: -case 0x4D84: -case 0x4F84: -case 0x4185: -case 0x4385: -case 0x4585: -case 0x4785: -case 0x4985: -case 0x4B85: -case 0x4D85: -case 0x4F85: -case 0x4186: -case 0x4386: -case 0x4586: -case 0x4786: -case 0x4986: -case 0x4B86: -case 0x4D86: -case 0x4F86: -case 0x4187: -case 0x4387: -case 0x4587: -case 0x4787: -case 0x4987: -case 0x4B87: -case 0x4D87: -case 0x4F87: - -// CHK -case 0x4180: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(10) -case 0x4390: -case 0x4590: -case 0x4790: -case 0x4990: -case 0x4B90: -case 0x4D90: -case 0x4F90: -case 0x4191: -case 0x4391: -case 0x4591: -case 0x4791: -case 0x4991: -case 0x4B91: -case 0x4D91: -case 0x4F91: -case 0x4192: -case 0x4392: -case 0x4592: -case 0x4792: -case 0x4992: -case 0x4B92: -case 0x4D92: -case 0x4F92: -case 0x4193: -case 0x4393: -case 0x4593: -case 0x4793: -case 0x4993: -case 0x4B93: -case 0x4D93: -case 0x4F93: -case 0x4194: -case 0x4394: -case 0x4594: -case 0x4794: -case 0x4994: -case 0x4B94: -case 0x4D94: -case 0x4F94: -case 0x4195: -case 0x4395: -case 0x4595: -case 0x4795: -case 0x4995: -case 0x4B95: -case 0x4D95: -case 0x4F95: -case 0x4196: -case 0x4396: -case 0x4596: -case 0x4796: -case 0x4996: -case 0x4B96: -case 0x4D96: -case 0x4F96: -case 0x4197: -case 0x4397: -case 0x4597: -case 0x4797: -case 0x4997: -case 0x4B97: -case 0x4D97: -case 0x4F97: - -// CHK -case 0x4190: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x4398: -case 0x4598: -case 0x4798: -case 0x4998: -case 0x4B98: -case 0x4D98: -case 0x4F98: -case 0x4199: -case 0x4399: -case 0x4599: -case 0x4799: -case 0x4999: -case 0x4B99: -case 0x4D99: -case 0x4F99: -case 0x419A: -case 0x439A: -case 0x459A: -case 0x479A: -case 0x499A: -case 0x4B9A: -case 0x4D9A: -case 0x4F9A: -case 0x419B: -case 0x439B: -case 0x459B: -case 0x479B: -case 0x499B: -case 0x4B9B: -case 0x4D9B: -case 0x4F9B: -case 0x419C: -case 0x439C: -case 0x459C: -case 0x479C: -case 0x499C: -case 0x4B9C: -case 0x4D9C: -case 0x4F9C: -case 0x419D: -case 0x439D: -case 0x459D: -case 0x479D: -case 0x499D: -case 0x4B9D: -case 0x4D9D: -case 0x4F9D: -case 0x419E: -case 0x439E: -case 0x459E: -case 0x479E: -case 0x499E: -case 0x4B9E: -case 0x4D9E: -case 0x4F9E: - -// CHK -case 0x4198: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x43A0: -case 0x45A0: -case 0x47A0: -case 0x49A0: -case 0x4BA0: -case 0x4DA0: -case 0x4FA0: -case 0x41A1: -case 0x43A1: -case 0x45A1: -case 0x47A1: -case 0x49A1: -case 0x4BA1: -case 0x4DA1: -case 0x4FA1: -case 0x41A2: -case 0x43A2: -case 0x45A2: -case 0x47A2: -case 0x49A2: -case 0x4BA2: -case 0x4DA2: -case 0x4FA2: -case 0x41A3: -case 0x43A3: -case 0x45A3: -case 0x47A3: -case 0x49A3: -case 0x4BA3: -case 0x4DA3: -case 0x4FA3: -case 0x41A4: -case 0x43A4: -case 0x45A4: -case 0x47A4: -case 0x49A4: -case 0x4BA4: -case 0x4DA4: -case 0x4FA4: -case 0x41A5: -case 0x43A5: -case 0x45A5: -case 0x47A5: -case 0x49A5: -case 0x4BA5: -case 0x4DA5: -case 0x4FA5: -case 0x41A6: -case 0x43A6: -case 0x45A6: -case 0x47A6: -case 0x49A6: -case 0x4BA6: -case 0x4DA6: -case 0x4FA6: - -// CHK -case 0x41A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(16) -case 0x43A8: -case 0x45A8: -case 0x47A8: -case 0x49A8: -case 0x4BA8: -case 0x4DA8: -case 0x4FA8: -case 0x41A9: -case 0x43A9: -case 0x45A9: -case 0x47A9: -case 0x49A9: -case 0x4BA9: -case 0x4DA9: -case 0x4FA9: -case 0x41AA: -case 0x43AA: -case 0x45AA: -case 0x47AA: -case 0x49AA: -case 0x4BAA: -case 0x4DAA: -case 0x4FAA: -case 0x41AB: -case 0x43AB: -case 0x45AB: -case 0x47AB: -case 0x49AB: -case 0x4BAB: -case 0x4DAB: -case 0x4FAB: -case 0x41AC: -case 0x43AC: -case 0x45AC: -case 0x47AC: -case 0x49AC: -case 0x4BAC: -case 0x4DAC: -case 0x4FAC: -case 0x41AD: -case 0x43AD: -case 0x45AD: -case 0x47AD: -case 0x49AD: -case 0x4BAD: -case 0x4DAD: -case 0x4FAD: -case 0x41AE: -case 0x43AE: -case 0x45AE: -case 0x47AE: -case 0x49AE: -case 0x4BAE: -case 0x4DAE: -case 0x4FAE: -case 0x41AF: -case 0x43AF: -case 0x45AF: -case 0x47AF: -case 0x49AF: -case 0x4BAF: -case 0x4DAF: -case 0x4FAF: - -// CHK -case 0x41A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(18) -case 0x43B0: -case 0x45B0: -case 0x47B0: -case 0x49B0: -case 0x4BB0: -case 0x4DB0: -case 0x4FB0: -case 0x41B1: -case 0x43B1: -case 0x45B1: -case 0x47B1: -case 0x49B1: -case 0x4BB1: -case 0x4DB1: -case 0x4FB1: -case 0x41B2: -case 0x43B2: -case 0x45B2: -case 0x47B2: -case 0x49B2: -case 0x4BB2: -case 0x4DB2: -case 0x4FB2: -case 0x41B3: -case 0x43B3: -case 0x45B3: -case 0x47B3: -case 0x49B3: -case 0x4BB3: -case 0x4DB3: -case 0x4FB3: -case 0x41B4: -case 0x43B4: -case 0x45B4: -case 0x47B4: -case 0x49B4: -case 0x4BB4: -case 0x4DB4: -case 0x4FB4: -case 0x41B5: -case 0x43B5: -case 0x45B5: -case 0x47B5: -case 0x49B5: -case 0x4BB5: -case 0x4DB5: -case 0x4FB5: -case 0x41B6: -case 0x43B6: -case 0x45B6: -case 0x47B6: -case 0x49B6: -case 0x4BB6: -case 0x4DB6: -case 0x4FB6: -case 0x41B7: -case 0x43B7: -case 0x45B7: -case 0x47B7: -case 0x49B7: -case 0x4BB7: -case 0x4DB7: -case 0x4FB7: - -// CHK -case 0x41B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(20) -case 0x43B8: -case 0x45B8: -case 0x47B8: -case 0x49B8: -case 0x4BB8: -case 0x4DB8: -case 0x4FB8: - -// CHK -case 0x41B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(18) -case 0x43B9: -case 0x45B9: -case 0x47B9: -case 0x49B9: -case 0x4BB9: -case 0x4DB9: -case 0x4FB9: - -// CHK -case 0x41B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(22) -case 0x43BA: -case 0x45BA: -case 0x47BA: -case 0x49BA: -case 0x4BBA: -case 0x4DBA: -case 0x4FBA: - -// CHK -case 0x41BA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(18) -case 0x43BB: -case 0x45BB: -case 0x47BB: -case 0x49BB: -case 0x4BBB: -case 0x4DBB: -case 0x4FBB: - -// CHK -case 0x41BB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(20) -case 0x43BC: -case 0x45BC: -case 0x47BC: -case 0x49BC: -case 0x4BBC: -case 0x4DBC: -case 0x4FBC: - -// CHK -case 0x41BC: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x439F: -case 0x459F: -case 0x479F: -case 0x499F: -case 0x4B9F: -case 0x4D9F: -case 0x4F9F: - -// CHK -case 0x419F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x43A7: -case 0x45A7: -case 0x47A7: -case 0x49A7: -case 0x4BA7: -case 0x4DA7: -case 0x4FA7: - -// CHK -case 0x41A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(16) -case 0x43D0: -case 0x45D0: -case 0x47D0: -case 0x49D0: -case 0x4BD0: -case 0x4DD0: -case 0x4FD0: -case 0x41D1: -case 0x43D1: -case 0x45D1: -case 0x47D1: -case 0x49D1: -case 0x4BD1: -case 0x4DD1: -case 0x4FD1: -case 0x41D2: -case 0x43D2: -case 0x45D2: -case 0x47D2: -case 0x49D2: -case 0x4BD2: -case 0x4DD2: -case 0x4FD2: -case 0x41D3: -case 0x43D3: -case 0x45D3: -case 0x47D3: -case 0x49D3: -case 0x4BD3: -case 0x4DD3: -case 0x4FD3: -case 0x41D4: -case 0x43D4: -case 0x45D4: -case 0x47D4: -case 0x49D4: -case 0x4BD4: -case 0x4DD4: -case 0x4FD4: -case 0x41D5: -case 0x43D5: -case 0x45D5: -case 0x47D5: -case 0x49D5: -case 0x4BD5: -case 0x4DD5: -case 0x4FD5: -case 0x41D6: -case 0x43D6: -case 0x45D6: -case 0x47D6: -case 0x49D6: -case 0x4BD6: -case 0x4DD6: -case 0x4FD6: -case 0x41D7: -case 0x43D7: -case 0x45D7: -case 0x47D7: -case 0x49D7: -case 0x4BD7: -case 0x4DD7: -case 0x4FD7: - -// LEA -case 0x41D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x43E8: -case 0x45E8: -case 0x47E8: -case 0x49E8: -case 0x4BE8: -case 0x4DE8: -case 0x4FE8: -case 0x41E9: -case 0x43E9: -case 0x45E9: -case 0x47E9: -case 0x49E9: -case 0x4BE9: -case 0x4DE9: -case 0x4FE9: -case 0x41EA: -case 0x43EA: -case 0x45EA: -case 0x47EA: -case 0x49EA: -case 0x4BEA: -case 0x4DEA: -case 0x4FEA: -case 0x41EB: -case 0x43EB: -case 0x45EB: -case 0x47EB: -case 0x49EB: -case 0x4BEB: -case 0x4DEB: -case 0x4FEB: -case 0x41EC: -case 0x43EC: -case 0x45EC: -case 0x47EC: -case 0x49EC: -case 0x4BEC: -case 0x4DEC: -case 0x4FEC: -case 0x41ED: -case 0x43ED: -case 0x45ED: -case 0x47ED: -case 0x49ED: -case 0x4BED: -case 0x4DED: -case 0x4FED: -case 0x41EE: -case 0x43EE: -case 0x45EE: -case 0x47EE: -case 0x49EE: -case 0x4BEE: -case 0x4DEE: -case 0x4FEE: -case 0x41EF: -case 0x43EF: -case 0x45EF: -case 0x47EF: -case 0x49EF: -case 0x4BEF: -case 0x4DEF: -case 0x4FEF: - -// LEA -case 0x41E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x43F0: -case 0x45F0: -case 0x47F0: -case 0x49F0: -case 0x4BF0: -case 0x4DF0: -case 0x4FF0: -case 0x41F1: -case 0x43F1: -case 0x45F1: -case 0x47F1: -case 0x49F1: -case 0x4BF1: -case 0x4DF1: -case 0x4FF1: -case 0x41F2: -case 0x43F2: -case 0x45F2: -case 0x47F2: -case 0x49F2: -case 0x4BF2: -case 0x4DF2: -case 0x4FF2: -case 0x41F3: -case 0x43F3: -case 0x45F3: -case 0x47F3: -case 0x49F3: -case 0x4BF3: -case 0x4DF3: -case 0x4FF3: -case 0x41F4: -case 0x43F4: -case 0x45F4: -case 0x47F4: -case 0x49F4: -case 0x4BF4: -case 0x4DF4: -case 0x4FF4: -case 0x41F5: -case 0x43F5: -case 0x45F5: -case 0x47F5: -case 0x49F5: -case 0x4BF5: -case 0x4DF5: -case 0x4FF5: -case 0x41F6: -case 0x43F6: -case 0x45F6: -case 0x47F6: -case 0x49F6: -case 0x4BF6: -case 0x4DF6: -case 0x4FF6: -case 0x41F7: -case 0x43F7: -case 0x45F7: -case 0x47F7: -case 0x49F7: -case 0x4BF7: -case 0x4DF7: -case 0x4FF7: - -// LEA -case 0x41F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x43F8: -case 0x45F8: -case 0x47F8: -case 0x49F8: -case 0x4BF8: -case 0x4DF8: -case 0x4FF8: - -// LEA -case 0x41F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x43F9: -case 0x45F9: -case 0x47F9: -case 0x49F9: -case 0x4BF9: -case 0x4DF9: -case 0x4FF9: - -// LEA -case 0x41F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x43FA: -case 0x45FA: -case 0x47FA: -case 0x49FA: -case 0x4BFA: -case 0x4DFA: -case 0x4FFA: - -// LEA -case 0x41FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x43FB: -case 0x45FB: -case 0x47FB: -case 0x49FB: -case 0x4BFB: -case 0x4DFB: -case 0x4FFB: - -// LEA -case 0x41FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) diff --git a/yabause/src/c68k/c68k_op5.inc b/yabause/src/c68k/c68k_op5.inc deleted file mode 100644 index f11d085b15..0000000000 --- a/yabause/src/c68k/c68k_op5.inc +++ /dev/null @@ -1,8265 +0,0 @@ -case 0x50C1: -case 0x50C2: -case 0x50C3: -case 0x50C4: -case 0x50C5: -case 0x50C6: -case 0x50C7: - -// STCC -case 0x50C0: -{ - u32 res; - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) -} -case 0x51C1: -case 0x51C2: -case 0x51C3: -case 0x51C4: -case 0x51C5: -case 0x51C6: -case 0x51C7: - -// STCC -case 0x51C0: -{ - u32 res; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x52C1: -case 0x52C2: -case 0x52C3: -case 0x52C4: -case 0x52C5: -case 0x52C6: -case 0x52C7: - -// STCC -case 0x52C0: -{ - u32 res; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x53C1: -case 0x53C2: -case 0x53C3: -case 0x53C4: -case 0x53C5: -case 0x53C6: -case 0x53C7: - -// STCC -case 0x53C0: -{ - u32 res; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x54C1: -case 0x54C2: -case 0x54C3: -case 0x54C4: -case 0x54C5: -case 0x54C6: -case 0x54C7: - -// STCC -case 0x54C0: -{ - u32 res; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x55C1: -case 0x55C2: -case 0x55C3: -case 0x55C4: -case 0x55C5: -case 0x55C6: -case 0x55C7: - -// STCC -case 0x55C0: -{ - u32 res; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x56C1: -case 0x56C2: -case 0x56C3: -case 0x56C4: -case 0x56C5: -case 0x56C6: -case 0x56C7: - -// STCC -case 0x56C0: -{ - u32 res; - if (CPU->flag_notZ) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x57C1: -case 0x57C2: -case 0x57C3: -case 0x57C4: -case 0x57C5: -case 0x57C6: -case 0x57C7: - -// STCC -case 0x57C0: -{ - u32 res; - if (!CPU->flag_notZ) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x58C1: -case 0x58C2: -case 0x58C3: -case 0x58C4: -case 0x58C5: -case 0x58C6: -case 0x58C7: - -// STCC -case 0x58C0: -{ - u32 res; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x59C1: -case 0x59C2: -case 0x59C3: -case 0x59C4: -case 0x59C5: -case 0x59C6: -case 0x59C7: - -// STCC -case 0x59C0: -{ - u32 res; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5AC1: -case 0x5AC2: -case 0x5AC3: -case 0x5AC4: -case 0x5AC5: -case 0x5AC6: -case 0x5AC7: - -// STCC -case 0x5AC0: -{ - u32 res; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5BC1: -case 0x5BC2: -case 0x5BC3: -case 0x5BC4: -case 0x5BC5: -case 0x5BC6: -case 0x5BC7: - -// STCC -case 0x5BC0: -{ - u32 res; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5CC1: -case 0x5CC2: -case 0x5CC3: -case 0x5CC4: -case 0x5CC5: -case 0x5CC6: -case 0x5CC7: - -// STCC -case 0x5CC0: -{ - u32 res; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5DC1: -case 0x5DC2: -case 0x5DC3: -case 0x5DC4: -case 0x5DC5: -case 0x5DC6: -case 0x5DC7: - -// STCC -case 0x5DC0: -{ - u32 res; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5EC1: -case 0x5EC2: -case 0x5EC3: -case 0x5EC4: -case 0x5EC5: -case 0x5EC6: -case 0x5EC7: - -// STCC -case 0x5EC0: -{ - u32 res; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5FC1: -case 0x5FC2: -case 0x5FC3: -case 0x5FC4: -case 0x5FC5: -case 0x5FC6: -case 0x5FC7: - -// STCC -case 0x5FC0: -{ - u32 res; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x50D1: -case 0x50D2: -case 0x50D3: -case 0x50D4: -case 0x50D5: -case 0x50D6: -case 0x50D7: - -// STCC -case 0x50D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x51D1: -case 0x51D2: -case 0x51D3: -case 0x51D4: -case 0x51D5: -case 0x51D6: -case 0x51D7: - -// STCC -case 0x51D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x52D1: -case 0x52D2: -case 0x52D3: -case 0x52D4: -case 0x52D5: -case 0x52D6: -case 0x52D7: - -// STCC -case 0x52D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x53D1: -case 0x53D2: -case 0x53D3: -case 0x53D4: -case 0x53D5: -case 0x53D6: -case 0x53D7: - -// STCC -case 0x53D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x54D1: -case 0x54D2: -case 0x54D3: -case 0x54D4: -case 0x54D5: -case 0x54D6: -case 0x54D7: - -// STCC -case 0x54D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x55D1: -case 0x55D2: -case 0x55D3: -case 0x55D4: -case 0x55D5: -case 0x55D6: -case 0x55D7: - -// STCC -case 0x55D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x56D1: -case 0x56D2: -case 0x56D3: -case 0x56D4: -case 0x56D5: -case 0x56D6: -case 0x56D7: - -// STCC -case 0x56D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x57D1: -case 0x57D2: -case 0x57D3: -case 0x57D4: -case 0x57D5: -case 0x57D6: -case 0x57D7: - -// STCC -case 0x57D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x58D1: -case 0x58D2: -case 0x58D3: -case 0x58D4: -case 0x58D5: -case 0x58D6: -case 0x58D7: - -// STCC -case 0x58D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x59D1: -case 0x59D2: -case 0x59D3: -case 0x59D4: -case 0x59D5: -case 0x59D6: -case 0x59D7: - -// STCC -case 0x59D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5AD1: -case 0x5AD2: -case 0x5AD3: -case 0x5AD4: -case 0x5AD5: -case 0x5AD6: -case 0x5AD7: - -// STCC -case 0x5AD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5BD1: -case 0x5BD2: -case 0x5BD3: -case 0x5BD4: -case 0x5BD5: -case 0x5BD6: -case 0x5BD7: - -// STCC -case 0x5BD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5CD1: -case 0x5CD2: -case 0x5CD3: -case 0x5CD4: -case 0x5CD5: -case 0x5CD6: -case 0x5CD7: - -// STCC -case 0x5CD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5DD1: -case 0x5DD2: -case 0x5DD3: -case 0x5DD4: -case 0x5DD5: -case 0x5DD6: -case 0x5DD7: - -// STCC -case 0x5DD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5ED1: -case 0x5ED2: -case 0x5ED3: -case 0x5ED4: -case 0x5ED5: -case 0x5ED6: -case 0x5ED7: - -// STCC -case 0x5ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5FD1: -case 0x5FD2: -case 0x5FD3: -case 0x5FD4: -case 0x5FD5: -case 0x5FD6: -case 0x5FD7: - -// STCC -case 0x5FD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x50D9: -case 0x50DA: -case 0x50DB: -case 0x50DC: -case 0x50DD: -case 0x50DE: - -// STCC -case 0x50D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x51D9: -case 0x51DA: -case 0x51DB: -case 0x51DC: -case 0x51DD: -case 0x51DE: - -// STCC -case 0x51D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x52D9: -case 0x52DA: -case 0x52DB: -case 0x52DC: -case 0x52DD: -case 0x52DE: - -// STCC -case 0x52D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x53D9: -case 0x53DA: -case 0x53DB: -case 0x53DC: -case 0x53DD: -case 0x53DE: - -// STCC -case 0x53D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x54D9: -case 0x54DA: -case 0x54DB: -case 0x54DC: -case 0x54DD: -case 0x54DE: - -// STCC -case 0x54D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x55D9: -case 0x55DA: -case 0x55DB: -case 0x55DC: -case 0x55DD: -case 0x55DE: - -// STCC -case 0x55D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x56D9: -case 0x56DA: -case 0x56DB: -case 0x56DC: -case 0x56DD: -case 0x56DE: - -// STCC -case 0x56D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x57D9: -case 0x57DA: -case 0x57DB: -case 0x57DC: -case 0x57DD: -case 0x57DE: - -// STCC -case 0x57D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x58D9: -case 0x58DA: -case 0x58DB: -case 0x58DC: -case 0x58DD: -case 0x58DE: - -// STCC -case 0x58D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x59D9: -case 0x59DA: -case 0x59DB: -case 0x59DC: -case 0x59DD: -case 0x59DE: - -// STCC -case 0x59D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5AD9: -case 0x5ADA: -case 0x5ADB: -case 0x5ADC: -case 0x5ADD: -case 0x5ADE: - -// STCC -case 0x5AD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5BD9: -case 0x5BDA: -case 0x5BDB: -case 0x5BDC: -case 0x5BDD: -case 0x5BDE: - -// STCC -case 0x5BD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5CD9: -case 0x5CDA: -case 0x5CDB: -case 0x5CDC: -case 0x5CDD: -case 0x5CDE: - -// STCC -case 0x5CD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5DD9: -case 0x5DDA: -case 0x5DDB: -case 0x5DDC: -case 0x5DDD: -case 0x5DDE: - -// STCC -case 0x5DD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5ED9: -case 0x5EDA: -case 0x5EDB: -case 0x5EDC: -case 0x5EDD: -case 0x5EDE: - -// STCC -case 0x5ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5FD9: -case 0x5FDA: -case 0x5FDB: -case 0x5FDC: -case 0x5FDD: -case 0x5FDE: - -// STCC -case 0x5FD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x50E1: -case 0x50E2: -case 0x50E3: -case 0x50E4: -case 0x50E5: -case 0x50E6: - -// STCC -case 0x50E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x51E1: -case 0x51E2: -case 0x51E3: -case 0x51E4: -case 0x51E5: -case 0x51E6: - -// STCC -case 0x51E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x52E1: -case 0x52E2: -case 0x52E3: -case 0x52E4: -case 0x52E5: -case 0x52E6: - -// STCC -case 0x52E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x53E1: -case 0x53E2: -case 0x53E3: -case 0x53E4: -case 0x53E5: -case 0x53E6: - -// STCC -case 0x53E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x54E1: -case 0x54E2: -case 0x54E3: -case 0x54E4: -case 0x54E5: -case 0x54E6: - -// STCC -case 0x54E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x55E1: -case 0x55E2: -case 0x55E3: -case 0x55E4: -case 0x55E5: -case 0x55E6: - -// STCC -case 0x55E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x56E1: -case 0x56E2: -case 0x56E3: -case 0x56E4: -case 0x56E5: -case 0x56E6: - -// STCC -case 0x56E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x57E1: -case 0x57E2: -case 0x57E3: -case 0x57E4: -case 0x57E5: -case 0x57E6: - -// STCC -case 0x57E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x58E1: -case 0x58E2: -case 0x58E3: -case 0x58E4: -case 0x58E5: -case 0x58E6: - -// STCC -case 0x58E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x59E1: -case 0x59E2: -case 0x59E3: -case 0x59E4: -case 0x59E5: -case 0x59E6: - -// STCC -case 0x59E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5AE1: -case 0x5AE2: -case 0x5AE3: -case 0x5AE4: -case 0x5AE5: -case 0x5AE6: - -// STCC -case 0x5AE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5BE1: -case 0x5BE2: -case 0x5BE3: -case 0x5BE4: -case 0x5BE5: -case 0x5BE6: - -// STCC -case 0x5BE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5CE1: -case 0x5CE2: -case 0x5CE3: -case 0x5CE4: -case 0x5CE5: -case 0x5CE6: - -// STCC -case 0x5CE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5DE1: -case 0x5DE2: -case 0x5DE3: -case 0x5DE4: -case 0x5DE5: -case 0x5DE6: - -// STCC -case 0x5DE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5EE1: -case 0x5EE2: -case 0x5EE3: -case 0x5EE4: -case 0x5EE5: -case 0x5EE6: - -// STCC -case 0x5EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5FE1: -case 0x5FE2: -case 0x5FE3: -case 0x5FE4: -case 0x5FE5: -case 0x5FE6: - -// STCC -case 0x5FE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x50E9: -case 0x50EA: -case 0x50EB: -case 0x50EC: -case 0x50ED: -case 0x50EE: -case 0x50EF: - -// STCC -case 0x50E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x51E9: -case 0x51EA: -case 0x51EB: -case 0x51EC: -case 0x51ED: -case 0x51EE: -case 0x51EF: - -// STCC -case 0x51E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x52E9: -case 0x52EA: -case 0x52EB: -case 0x52EC: -case 0x52ED: -case 0x52EE: -case 0x52EF: - -// STCC -case 0x52E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x53E9: -case 0x53EA: -case 0x53EB: -case 0x53EC: -case 0x53ED: -case 0x53EE: -case 0x53EF: - -// STCC -case 0x53E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x54E9: -case 0x54EA: -case 0x54EB: -case 0x54EC: -case 0x54ED: -case 0x54EE: -case 0x54EF: - -// STCC -case 0x54E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x55E9: -case 0x55EA: -case 0x55EB: -case 0x55EC: -case 0x55ED: -case 0x55EE: -case 0x55EF: - -// STCC -case 0x55E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x56E9: -case 0x56EA: -case 0x56EB: -case 0x56EC: -case 0x56ED: -case 0x56EE: -case 0x56EF: - -// STCC -case 0x56E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x57E9: -case 0x57EA: -case 0x57EB: -case 0x57EC: -case 0x57ED: -case 0x57EE: -case 0x57EF: - -// STCC -case 0x57E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x58E9: -case 0x58EA: -case 0x58EB: -case 0x58EC: -case 0x58ED: -case 0x58EE: -case 0x58EF: - -// STCC -case 0x58E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x59E9: -case 0x59EA: -case 0x59EB: -case 0x59EC: -case 0x59ED: -case 0x59EE: -case 0x59EF: - -// STCC -case 0x59E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5AE9: -case 0x5AEA: -case 0x5AEB: -case 0x5AEC: -case 0x5AED: -case 0x5AEE: -case 0x5AEF: - -// STCC -case 0x5AE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5BE9: -case 0x5BEA: -case 0x5BEB: -case 0x5BEC: -case 0x5BED: -case 0x5BEE: -case 0x5BEF: - -// STCC -case 0x5BE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5CE9: -case 0x5CEA: -case 0x5CEB: -case 0x5CEC: -case 0x5CED: -case 0x5CEE: -case 0x5CEF: - -// STCC -case 0x5CE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5DE9: -case 0x5DEA: -case 0x5DEB: -case 0x5DEC: -case 0x5DED: -case 0x5DEE: -case 0x5DEF: - -// STCC -case 0x5DE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5EE9: -case 0x5EEA: -case 0x5EEB: -case 0x5EEC: -case 0x5EED: -case 0x5EEE: -case 0x5EEF: - -// STCC -case 0x5EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5FE9: -case 0x5FEA: -case 0x5FEB: -case 0x5FEC: -case 0x5FED: -case 0x5FEE: -case 0x5FEF: - -// STCC -case 0x5FE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x50F1: -case 0x50F2: -case 0x50F3: -case 0x50F4: -case 0x50F5: -case 0x50F6: -case 0x50F7: - -// STCC -case 0x50F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x51F1: -case 0x51F2: -case 0x51F3: -case 0x51F4: -case 0x51F5: -case 0x51F6: -case 0x51F7: - -// STCC -case 0x51F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x52F1: -case 0x52F2: -case 0x52F3: -case 0x52F4: -case 0x52F5: -case 0x52F6: -case 0x52F7: - -// STCC -case 0x52F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x53F1: -case 0x53F2: -case 0x53F3: -case 0x53F4: -case 0x53F5: -case 0x53F6: -case 0x53F7: - -// STCC -case 0x53F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x54F1: -case 0x54F2: -case 0x54F3: -case 0x54F4: -case 0x54F5: -case 0x54F6: -case 0x54F7: - -// STCC -case 0x54F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x55F1: -case 0x55F2: -case 0x55F3: -case 0x55F4: -case 0x55F5: -case 0x55F6: -case 0x55F7: - -// STCC -case 0x55F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x56F1: -case 0x56F2: -case 0x56F3: -case 0x56F4: -case 0x56F5: -case 0x56F6: -case 0x56F7: - -// STCC -case 0x56F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x57F1: -case 0x57F2: -case 0x57F3: -case 0x57F4: -case 0x57F5: -case 0x57F6: -case 0x57F7: - -// STCC -case 0x57F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x58F1: -case 0x58F2: -case 0x58F3: -case 0x58F4: -case 0x58F5: -case 0x58F6: -case 0x58F7: - -// STCC -case 0x58F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x59F1: -case 0x59F2: -case 0x59F3: -case 0x59F4: -case 0x59F5: -case 0x59F6: -case 0x59F7: - -// STCC -case 0x59F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5AF1: -case 0x5AF2: -case 0x5AF3: -case 0x5AF4: -case 0x5AF5: -case 0x5AF6: -case 0x5AF7: - -// STCC -case 0x5AF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5BF1: -case 0x5BF2: -case 0x5BF3: -case 0x5BF4: -case 0x5BF5: -case 0x5BF6: -case 0x5BF7: - -// STCC -case 0x5BF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5CF1: -case 0x5CF2: -case 0x5CF3: -case 0x5CF4: -case 0x5CF5: -case 0x5CF6: -case 0x5CF7: - -// STCC -case 0x5CF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5DF1: -case 0x5DF2: -case 0x5DF3: -case 0x5DF4: -case 0x5DF5: -case 0x5DF6: -case 0x5DF7: - -// STCC -case 0x5DF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5EF1: -case 0x5EF2: -case 0x5EF3: -case 0x5EF4: -case 0x5EF5: -case 0x5EF6: -case 0x5EF7: - -// STCC -case 0x5EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5FF1: -case 0x5FF2: -case 0x5FF3: -case 0x5FF4: -case 0x5FF5: -case 0x5FF6: -case 0x5FF7: - -// STCC -case 0x5FF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} - -// STCC -case 0x50F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x51F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x52F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x53F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x54F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x55F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x56F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x57F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x58F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x59F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5AF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5BF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5CF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5DF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5FF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x50F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x51F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x52F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x53F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x54F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x55F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x56F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x57F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x58F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x59F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5AF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5BF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5CF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5DF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5FF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x50DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x51DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x52DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x53DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x54DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x55DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x56DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x57DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x58DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x59DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5ADF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5BDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5CDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5DDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5FDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x50E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x51E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x52E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x53E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x54E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x55E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x56E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x57E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x58E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x59E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5AE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5BE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5CE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5DE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5FE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x50C9: -case 0x50CA: -case 0x50CB: -case 0x50CC: -case 0x50CD: -case 0x50CE: -case 0x50CF: - -// DBCC -case 0x50C8: -{ - PC += 2; -} -RET(12) -case 0x51C9: -case 0x51CA: -case 0x51CB: -case 0x51CC: -case 0x51CD: -case 0x51CE: -case 0x51CF: - -// DBCC -case 0x51C8: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(14) -case 0x52C9: -case 0x52CA: -case 0x52CB: -case 0x52CC: -case 0x52CD: -case 0x52CE: -case 0x52CF: - -// DBCC -case 0x52C8: -{ - u32 res; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x53C9: -case 0x53CA: -case 0x53CB: -case 0x53CC: -case 0x53CD: -case 0x53CE: -case 0x53CF: - -// DBCC -case 0x53C8: -{ - u32 res; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x54C9: -case 0x54CA: -case 0x54CB: -case 0x54CC: -case 0x54CD: -case 0x54CE: -case 0x54CF: - -// DBCC -case 0x54C8: -{ - u32 res; - if (CPU->flag_C & 0x100) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x55C9: -case 0x55CA: -case 0x55CB: -case 0x55CC: -case 0x55CD: -case 0x55CE: -case 0x55CF: - -// DBCC -case 0x55C8: -{ - u32 res; - if (!(CPU->flag_C & 0x100)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x56C9: -case 0x56CA: -case 0x56CB: -case 0x56CC: -case 0x56CD: -case 0x56CE: -case 0x56CF: - -// DBCC -case 0x56C8: -{ - u32 res; - if (!CPU->flag_notZ) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x57C9: -case 0x57CA: -case 0x57CB: -case 0x57CC: -case 0x57CD: -case 0x57CE: -case 0x57CF: - -// DBCC -case 0x57C8: -{ - u32 res; - if (CPU->flag_notZ) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x58C9: -case 0x58CA: -case 0x58CB: -case 0x58CC: -case 0x58CD: -case 0x58CE: -case 0x58CF: - -// DBCC -case 0x58C8: -{ - u32 res; - if (CPU->flag_V & 0x80) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x59C9: -case 0x59CA: -case 0x59CB: -case 0x59CC: -case 0x59CD: -case 0x59CE: -case 0x59CF: - -// DBCC -case 0x59C8: -{ - u32 res; - if (!(CPU->flag_V & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5AC9: -case 0x5ACA: -case 0x5ACB: -case 0x5ACC: -case 0x5ACD: -case 0x5ACE: -case 0x5ACF: - -// DBCC -case 0x5AC8: -{ - u32 res; - if (CPU->flag_N & 0x80) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5BC9: -case 0x5BCA: -case 0x5BCB: -case 0x5BCC: -case 0x5BCD: -case 0x5BCE: -case 0x5BCF: - -// DBCC -case 0x5BC8: -{ - u32 res; - if (!(CPU->flag_N & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5CC9: -case 0x5CCA: -case 0x5CCB: -case 0x5CCC: -case 0x5CCD: -case 0x5CCE: -case 0x5CCF: - -// DBCC -case 0x5CC8: -{ - u32 res; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5DC9: -case 0x5DCA: -case 0x5DCB: -case 0x5DCC: -case 0x5DCD: -case 0x5DCE: -case 0x5DCF: - -// DBCC -case 0x5DC8: -{ - u32 res; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5EC9: -case 0x5ECA: -case 0x5ECB: -case 0x5ECC: -case 0x5ECD: -case 0x5ECE: -case 0x5ECF: - -// DBCC -case 0x5EC8: -{ - u32 res; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5FC9: -case 0x5FCA: -case 0x5FCB: -case 0x5FCC: -case 0x5FCD: -case 0x5FCE: -case 0x5FCF: - -// DBCC -case 0x5FC8: -{ - u32 res; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5200: -case 0x5400: -case 0x5600: -case 0x5800: -case 0x5A00: -case 0x5C00: -case 0x5E00: -case 0x5001: -case 0x5201: -case 0x5401: -case 0x5601: -case 0x5801: -case 0x5A01: -case 0x5C01: -case 0x5E01: -case 0x5002: -case 0x5202: -case 0x5402: -case 0x5602: -case 0x5802: -case 0x5A02: -case 0x5C02: -case 0x5E02: -case 0x5003: -case 0x5203: -case 0x5403: -case 0x5603: -case 0x5803: -case 0x5A03: -case 0x5C03: -case 0x5E03: -case 0x5004: -case 0x5204: -case 0x5404: -case 0x5604: -case 0x5804: -case 0x5A04: -case 0x5C04: -case 0x5E04: -case 0x5005: -case 0x5205: -case 0x5405: -case 0x5605: -case 0x5805: -case 0x5A05: -case 0x5C05: -case 0x5E05: -case 0x5006: -case 0x5206: -case 0x5406: -case 0x5606: -case 0x5806: -case 0x5A06: -case 0x5C06: -case 0x5E06: -case 0x5007: -case 0x5207: -case 0x5407: -case 0x5607: -case 0x5807: -case 0x5A07: -case 0x5C07: -case 0x5E07: - -// ADDQ -case 0x5000: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5210: -case 0x5410: -case 0x5610: -case 0x5810: -case 0x5A10: -case 0x5C10: -case 0x5E10: -case 0x5011: -case 0x5211: -case 0x5411: -case 0x5611: -case 0x5811: -case 0x5A11: -case 0x5C11: -case 0x5E11: -case 0x5012: -case 0x5212: -case 0x5412: -case 0x5612: -case 0x5812: -case 0x5A12: -case 0x5C12: -case 0x5E12: -case 0x5013: -case 0x5213: -case 0x5413: -case 0x5613: -case 0x5813: -case 0x5A13: -case 0x5C13: -case 0x5E13: -case 0x5014: -case 0x5214: -case 0x5414: -case 0x5614: -case 0x5814: -case 0x5A14: -case 0x5C14: -case 0x5E14: -case 0x5015: -case 0x5215: -case 0x5415: -case 0x5615: -case 0x5815: -case 0x5A15: -case 0x5C15: -case 0x5E15: -case 0x5016: -case 0x5216: -case 0x5416: -case 0x5616: -case 0x5816: -case 0x5A16: -case 0x5C16: -case 0x5E16: -case 0x5017: -case 0x5217: -case 0x5417: -case 0x5617: -case 0x5817: -case 0x5A17: -case 0x5C17: -case 0x5E17: - -// ADDQ -case 0x5010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5218: -case 0x5418: -case 0x5618: -case 0x5818: -case 0x5A18: -case 0x5C18: -case 0x5E18: -case 0x5019: -case 0x5219: -case 0x5419: -case 0x5619: -case 0x5819: -case 0x5A19: -case 0x5C19: -case 0x5E19: -case 0x501A: -case 0x521A: -case 0x541A: -case 0x561A: -case 0x581A: -case 0x5A1A: -case 0x5C1A: -case 0x5E1A: -case 0x501B: -case 0x521B: -case 0x541B: -case 0x561B: -case 0x581B: -case 0x5A1B: -case 0x5C1B: -case 0x5E1B: -case 0x501C: -case 0x521C: -case 0x541C: -case 0x561C: -case 0x581C: -case 0x5A1C: -case 0x5C1C: -case 0x5E1C: -case 0x501D: -case 0x521D: -case 0x541D: -case 0x561D: -case 0x581D: -case 0x5A1D: -case 0x5C1D: -case 0x5E1D: -case 0x501E: -case 0x521E: -case 0x541E: -case 0x561E: -case 0x581E: -case 0x5A1E: -case 0x5C1E: -case 0x5E1E: - -// ADDQ -case 0x5018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5220: -case 0x5420: -case 0x5620: -case 0x5820: -case 0x5A20: -case 0x5C20: -case 0x5E20: -case 0x5021: -case 0x5221: -case 0x5421: -case 0x5621: -case 0x5821: -case 0x5A21: -case 0x5C21: -case 0x5E21: -case 0x5022: -case 0x5222: -case 0x5422: -case 0x5622: -case 0x5822: -case 0x5A22: -case 0x5C22: -case 0x5E22: -case 0x5023: -case 0x5223: -case 0x5423: -case 0x5623: -case 0x5823: -case 0x5A23: -case 0x5C23: -case 0x5E23: -case 0x5024: -case 0x5224: -case 0x5424: -case 0x5624: -case 0x5824: -case 0x5A24: -case 0x5C24: -case 0x5E24: -case 0x5025: -case 0x5225: -case 0x5425: -case 0x5625: -case 0x5825: -case 0x5A25: -case 0x5C25: -case 0x5E25: -case 0x5026: -case 0x5226: -case 0x5426: -case 0x5626: -case 0x5826: -case 0x5A26: -case 0x5C26: -case 0x5E26: - -// ADDQ -case 0x5020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5228: -case 0x5428: -case 0x5628: -case 0x5828: -case 0x5A28: -case 0x5C28: -case 0x5E28: -case 0x5029: -case 0x5229: -case 0x5429: -case 0x5629: -case 0x5829: -case 0x5A29: -case 0x5C29: -case 0x5E29: -case 0x502A: -case 0x522A: -case 0x542A: -case 0x562A: -case 0x582A: -case 0x5A2A: -case 0x5C2A: -case 0x5E2A: -case 0x502B: -case 0x522B: -case 0x542B: -case 0x562B: -case 0x582B: -case 0x5A2B: -case 0x5C2B: -case 0x5E2B: -case 0x502C: -case 0x522C: -case 0x542C: -case 0x562C: -case 0x582C: -case 0x5A2C: -case 0x5C2C: -case 0x5E2C: -case 0x502D: -case 0x522D: -case 0x542D: -case 0x562D: -case 0x582D: -case 0x5A2D: -case 0x5C2D: -case 0x5E2D: -case 0x502E: -case 0x522E: -case 0x542E: -case 0x562E: -case 0x582E: -case 0x5A2E: -case 0x5C2E: -case 0x5E2E: -case 0x502F: -case 0x522F: -case 0x542F: -case 0x562F: -case 0x582F: -case 0x5A2F: -case 0x5C2F: -case 0x5E2F: - -// ADDQ -case 0x5028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5230: -case 0x5430: -case 0x5630: -case 0x5830: -case 0x5A30: -case 0x5C30: -case 0x5E30: -case 0x5031: -case 0x5231: -case 0x5431: -case 0x5631: -case 0x5831: -case 0x5A31: -case 0x5C31: -case 0x5E31: -case 0x5032: -case 0x5232: -case 0x5432: -case 0x5632: -case 0x5832: -case 0x5A32: -case 0x5C32: -case 0x5E32: -case 0x5033: -case 0x5233: -case 0x5433: -case 0x5633: -case 0x5833: -case 0x5A33: -case 0x5C33: -case 0x5E33: -case 0x5034: -case 0x5234: -case 0x5434: -case 0x5634: -case 0x5834: -case 0x5A34: -case 0x5C34: -case 0x5E34: -case 0x5035: -case 0x5235: -case 0x5435: -case 0x5635: -case 0x5835: -case 0x5A35: -case 0x5C35: -case 0x5E35: -case 0x5036: -case 0x5236: -case 0x5436: -case 0x5636: -case 0x5836: -case 0x5A36: -case 0x5C36: -case 0x5E36: -case 0x5037: -case 0x5237: -case 0x5437: -case 0x5637: -case 0x5837: -case 0x5A37: -case 0x5C37: -case 0x5E37: - -// ADDQ -case 0x5030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x5238: -case 0x5438: -case 0x5638: -case 0x5838: -case 0x5A38: -case 0x5C38: -case 0x5E38: - -// ADDQ -case 0x5038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5239: -case 0x5439: -case 0x5639: -case 0x5839: -case 0x5A39: -case 0x5C39: -case 0x5E39: - -// ADDQ -case 0x5039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x521F: -case 0x541F: -case 0x561F: -case 0x581F: -case 0x5A1F: -case 0x5C1F: -case 0x5E1F: - -// ADDQ -case 0x501F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5227: -case 0x5427: -case 0x5627: -case 0x5827: -case 0x5A27: -case 0x5C27: -case 0x5E27: - -// ADDQ -case 0x5027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5240: -case 0x5440: -case 0x5640: -case 0x5840: -case 0x5A40: -case 0x5C40: -case 0x5E40: -case 0x5041: -case 0x5241: -case 0x5441: -case 0x5641: -case 0x5841: -case 0x5A41: -case 0x5C41: -case 0x5E41: -case 0x5042: -case 0x5242: -case 0x5442: -case 0x5642: -case 0x5842: -case 0x5A42: -case 0x5C42: -case 0x5E42: -case 0x5043: -case 0x5243: -case 0x5443: -case 0x5643: -case 0x5843: -case 0x5A43: -case 0x5C43: -case 0x5E43: -case 0x5044: -case 0x5244: -case 0x5444: -case 0x5644: -case 0x5844: -case 0x5A44: -case 0x5C44: -case 0x5E44: -case 0x5045: -case 0x5245: -case 0x5445: -case 0x5645: -case 0x5845: -case 0x5A45: -case 0x5C45: -case 0x5E45: -case 0x5046: -case 0x5246: -case 0x5446: -case 0x5646: -case 0x5846: -case 0x5A46: -case 0x5C46: -case 0x5E46: -case 0x5047: -case 0x5247: -case 0x5447: -case 0x5647: -case 0x5847: -case 0x5A47: -case 0x5C47: -case 0x5E47: - -// ADDQ -case 0x5040: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5248: -case 0x5448: -case 0x5648: -case 0x5848: -case 0x5A48: -case 0x5C48: -case 0x5E48: -case 0x5049: -case 0x5249: -case 0x5449: -case 0x5649: -case 0x5849: -case 0x5A49: -case 0x5C49: -case 0x5E49: -case 0x504A: -case 0x524A: -case 0x544A: -case 0x564A: -case 0x584A: -case 0x5A4A: -case 0x5C4A: -case 0x5E4A: -case 0x504B: -case 0x524B: -case 0x544B: -case 0x564B: -case 0x584B: -case 0x5A4B: -case 0x5C4B: -case 0x5E4B: -case 0x504C: -case 0x524C: -case 0x544C: -case 0x564C: -case 0x584C: -case 0x5A4C: -case 0x5C4C: -case 0x5E4C: -case 0x504D: -case 0x524D: -case 0x544D: -case 0x564D: -case 0x584D: -case 0x5A4D: -case 0x5C4D: -case 0x5E4D: -case 0x504E: -case 0x524E: -case 0x544E: -case 0x564E: -case 0x584E: -case 0x5A4E: -case 0x5C4E: -case 0x5E4E: -case 0x504F: -case 0x524F: -case 0x544F: -case 0x564F: -case 0x584F: -case 0x5A4F: -case 0x5C4F: -case 0x5E4F: - -// ADDQ -case 0x5048: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst + src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5250: -case 0x5450: -case 0x5650: -case 0x5850: -case 0x5A50: -case 0x5C50: -case 0x5E50: -case 0x5051: -case 0x5251: -case 0x5451: -case 0x5651: -case 0x5851: -case 0x5A51: -case 0x5C51: -case 0x5E51: -case 0x5052: -case 0x5252: -case 0x5452: -case 0x5652: -case 0x5852: -case 0x5A52: -case 0x5C52: -case 0x5E52: -case 0x5053: -case 0x5253: -case 0x5453: -case 0x5653: -case 0x5853: -case 0x5A53: -case 0x5C53: -case 0x5E53: -case 0x5054: -case 0x5254: -case 0x5454: -case 0x5654: -case 0x5854: -case 0x5A54: -case 0x5C54: -case 0x5E54: -case 0x5055: -case 0x5255: -case 0x5455: -case 0x5655: -case 0x5855: -case 0x5A55: -case 0x5C55: -case 0x5E55: -case 0x5056: -case 0x5256: -case 0x5456: -case 0x5656: -case 0x5856: -case 0x5A56: -case 0x5C56: -case 0x5E56: -case 0x5057: -case 0x5257: -case 0x5457: -case 0x5657: -case 0x5857: -case 0x5A57: -case 0x5C57: -case 0x5E57: - -// ADDQ -case 0x5050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5258: -case 0x5458: -case 0x5658: -case 0x5858: -case 0x5A58: -case 0x5C58: -case 0x5E58: -case 0x5059: -case 0x5259: -case 0x5459: -case 0x5659: -case 0x5859: -case 0x5A59: -case 0x5C59: -case 0x5E59: -case 0x505A: -case 0x525A: -case 0x545A: -case 0x565A: -case 0x585A: -case 0x5A5A: -case 0x5C5A: -case 0x5E5A: -case 0x505B: -case 0x525B: -case 0x545B: -case 0x565B: -case 0x585B: -case 0x5A5B: -case 0x5C5B: -case 0x5E5B: -case 0x505C: -case 0x525C: -case 0x545C: -case 0x565C: -case 0x585C: -case 0x5A5C: -case 0x5C5C: -case 0x5E5C: -case 0x505D: -case 0x525D: -case 0x545D: -case 0x565D: -case 0x585D: -case 0x5A5D: -case 0x5C5D: -case 0x5E5D: -case 0x505E: -case 0x525E: -case 0x545E: -case 0x565E: -case 0x585E: -case 0x5A5E: -case 0x5C5E: -case 0x5E5E: - -// ADDQ -case 0x5058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5260: -case 0x5460: -case 0x5660: -case 0x5860: -case 0x5A60: -case 0x5C60: -case 0x5E60: -case 0x5061: -case 0x5261: -case 0x5461: -case 0x5661: -case 0x5861: -case 0x5A61: -case 0x5C61: -case 0x5E61: -case 0x5062: -case 0x5262: -case 0x5462: -case 0x5662: -case 0x5862: -case 0x5A62: -case 0x5C62: -case 0x5E62: -case 0x5063: -case 0x5263: -case 0x5463: -case 0x5663: -case 0x5863: -case 0x5A63: -case 0x5C63: -case 0x5E63: -case 0x5064: -case 0x5264: -case 0x5464: -case 0x5664: -case 0x5864: -case 0x5A64: -case 0x5C64: -case 0x5E64: -case 0x5065: -case 0x5265: -case 0x5465: -case 0x5665: -case 0x5865: -case 0x5A65: -case 0x5C65: -case 0x5E65: -case 0x5066: -case 0x5266: -case 0x5466: -case 0x5666: -case 0x5866: -case 0x5A66: -case 0x5C66: -case 0x5E66: - -// ADDQ -case 0x5060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5268: -case 0x5468: -case 0x5668: -case 0x5868: -case 0x5A68: -case 0x5C68: -case 0x5E68: -case 0x5069: -case 0x5269: -case 0x5469: -case 0x5669: -case 0x5869: -case 0x5A69: -case 0x5C69: -case 0x5E69: -case 0x506A: -case 0x526A: -case 0x546A: -case 0x566A: -case 0x586A: -case 0x5A6A: -case 0x5C6A: -case 0x5E6A: -case 0x506B: -case 0x526B: -case 0x546B: -case 0x566B: -case 0x586B: -case 0x5A6B: -case 0x5C6B: -case 0x5E6B: -case 0x506C: -case 0x526C: -case 0x546C: -case 0x566C: -case 0x586C: -case 0x5A6C: -case 0x5C6C: -case 0x5E6C: -case 0x506D: -case 0x526D: -case 0x546D: -case 0x566D: -case 0x586D: -case 0x5A6D: -case 0x5C6D: -case 0x5E6D: -case 0x506E: -case 0x526E: -case 0x546E: -case 0x566E: -case 0x586E: -case 0x5A6E: -case 0x5C6E: -case 0x5E6E: -case 0x506F: -case 0x526F: -case 0x546F: -case 0x566F: -case 0x586F: -case 0x5A6F: -case 0x5C6F: -case 0x5E6F: - -// ADDQ -case 0x5068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5270: -case 0x5470: -case 0x5670: -case 0x5870: -case 0x5A70: -case 0x5C70: -case 0x5E70: -case 0x5071: -case 0x5271: -case 0x5471: -case 0x5671: -case 0x5871: -case 0x5A71: -case 0x5C71: -case 0x5E71: -case 0x5072: -case 0x5272: -case 0x5472: -case 0x5672: -case 0x5872: -case 0x5A72: -case 0x5C72: -case 0x5E72: -case 0x5073: -case 0x5273: -case 0x5473: -case 0x5673: -case 0x5873: -case 0x5A73: -case 0x5C73: -case 0x5E73: -case 0x5074: -case 0x5274: -case 0x5474: -case 0x5674: -case 0x5874: -case 0x5A74: -case 0x5C74: -case 0x5E74: -case 0x5075: -case 0x5275: -case 0x5475: -case 0x5675: -case 0x5875: -case 0x5A75: -case 0x5C75: -case 0x5E75: -case 0x5076: -case 0x5276: -case 0x5476: -case 0x5676: -case 0x5876: -case 0x5A76: -case 0x5C76: -case 0x5E76: -case 0x5077: -case 0x5277: -case 0x5477: -case 0x5677: -case 0x5877: -case 0x5A77: -case 0x5C77: -case 0x5E77: - -// ADDQ -case 0x5070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x5278: -case 0x5478: -case 0x5678: -case 0x5878: -case 0x5A78: -case 0x5C78: -case 0x5E78: - -// ADDQ -case 0x5078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5279: -case 0x5479: -case 0x5679: -case 0x5879: -case 0x5A79: -case 0x5C79: -case 0x5E79: - -// ADDQ -case 0x5079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x525F: -case 0x545F: -case 0x565F: -case 0x585F: -case 0x5A5F: -case 0x5C5F: -case 0x5E5F: - -// ADDQ -case 0x505F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5267: -case 0x5467: -case 0x5667: -case 0x5867: -case 0x5A67: -case 0x5C67: -case 0x5E67: - -// ADDQ -case 0x5067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5280: -case 0x5480: -case 0x5680: -case 0x5880: -case 0x5A80: -case 0x5C80: -case 0x5E80: -case 0x5081: -case 0x5281: -case 0x5481: -case 0x5681: -case 0x5881: -case 0x5A81: -case 0x5C81: -case 0x5E81: -case 0x5082: -case 0x5282: -case 0x5482: -case 0x5682: -case 0x5882: -case 0x5A82: -case 0x5C82: -case 0x5E82: -case 0x5083: -case 0x5283: -case 0x5483: -case 0x5683: -case 0x5883: -case 0x5A83: -case 0x5C83: -case 0x5E83: -case 0x5084: -case 0x5284: -case 0x5484: -case 0x5684: -case 0x5884: -case 0x5A84: -case 0x5C84: -case 0x5E84: -case 0x5085: -case 0x5285: -case 0x5485: -case 0x5685: -case 0x5885: -case 0x5A85: -case 0x5C85: -case 0x5E85: -case 0x5086: -case 0x5286: -case 0x5486: -case 0x5686: -case 0x5886: -case 0x5A86: -case 0x5C86: -case 0x5E86: -case 0x5087: -case 0x5287: -case 0x5487: -case 0x5687: -case 0x5887: -case 0x5A87: -case 0x5C87: -case 0x5E87: - -// ADDQ -case 0x5080: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x5288: -case 0x5488: -case 0x5688: -case 0x5888: -case 0x5A88: -case 0x5C88: -case 0x5E88: -case 0x5089: -case 0x5289: -case 0x5489: -case 0x5689: -case 0x5889: -case 0x5A89: -case 0x5C89: -case 0x5E89: -case 0x508A: -case 0x528A: -case 0x548A: -case 0x568A: -case 0x588A: -case 0x5A8A: -case 0x5C8A: -case 0x5E8A: -case 0x508B: -case 0x528B: -case 0x548B: -case 0x568B: -case 0x588B: -case 0x5A8B: -case 0x5C8B: -case 0x5E8B: -case 0x508C: -case 0x528C: -case 0x548C: -case 0x568C: -case 0x588C: -case 0x5A8C: -case 0x5C8C: -case 0x5E8C: -case 0x508D: -case 0x528D: -case 0x548D: -case 0x568D: -case 0x588D: -case 0x5A8D: -case 0x5C8D: -case 0x5E8D: -case 0x508E: -case 0x528E: -case 0x548E: -case 0x568E: -case 0x588E: -case 0x5A8E: -case 0x5C8E: -case 0x5E8E: -case 0x508F: -case 0x528F: -case 0x548F: -case 0x568F: -case 0x588F: -case 0x5A8F: -case 0x5C8F: -case 0x5E8F: - -// ADDQ -case 0x5088: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst + src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5290: -case 0x5490: -case 0x5690: -case 0x5890: -case 0x5A90: -case 0x5C90: -case 0x5E90: -case 0x5091: -case 0x5291: -case 0x5491: -case 0x5691: -case 0x5891: -case 0x5A91: -case 0x5C91: -case 0x5E91: -case 0x5092: -case 0x5292: -case 0x5492: -case 0x5692: -case 0x5892: -case 0x5A92: -case 0x5C92: -case 0x5E92: -case 0x5093: -case 0x5293: -case 0x5493: -case 0x5693: -case 0x5893: -case 0x5A93: -case 0x5C93: -case 0x5E93: -case 0x5094: -case 0x5294: -case 0x5494: -case 0x5694: -case 0x5894: -case 0x5A94: -case 0x5C94: -case 0x5E94: -case 0x5095: -case 0x5295: -case 0x5495: -case 0x5695: -case 0x5895: -case 0x5A95: -case 0x5C95: -case 0x5E95: -case 0x5096: -case 0x5296: -case 0x5496: -case 0x5696: -case 0x5896: -case 0x5A96: -case 0x5C96: -case 0x5E96: -case 0x5097: -case 0x5297: -case 0x5497: -case 0x5697: -case 0x5897: -case 0x5A97: -case 0x5C97: -case 0x5E97: - -// ADDQ -case 0x5090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x5298: -case 0x5498: -case 0x5698: -case 0x5898: -case 0x5A98: -case 0x5C98: -case 0x5E98: -case 0x5099: -case 0x5299: -case 0x5499: -case 0x5699: -case 0x5899: -case 0x5A99: -case 0x5C99: -case 0x5E99: -case 0x509A: -case 0x529A: -case 0x549A: -case 0x569A: -case 0x589A: -case 0x5A9A: -case 0x5C9A: -case 0x5E9A: -case 0x509B: -case 0x529B: -case 0x549B: -case 0x569B: -case 0x589B: -case 0x5A9B: -case 0x5C9B: -case 0x5E9B: -case 0x509C: -case 0x529C: -case 0x549C: -case 0x569C: -case 0x589C: -case 0x5A9C: -case 0x5C9C: -case 0x5E9C: -case 0x509D: -case 0x529D: -case 0x549D: -case 0x569D: -case 0x589D: -case 0x5A9D: -case 0x5C9D: -case 0x5E9D: -case 0x509E: -case 0x529E: -case 0x549E: -case 0x569E: -case 0x589E: -case 0x5A9E: -case 0x5C9E: -case 0x5E9E: - -// ADDQ -case 0x5098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x52A0: -case 0x54A0: -case 0x56A0: -case 0x58A0: -case 0x5AA0: -case 0x5CA0: -case 0x5EA0: -case 0x50A1: -case 0x52A1: -case 0x54A1: -case 0x56A1: -case 0x58A1: -case 0x5AA1: -case 0x5CA1: -case 0x5EA1: -case 0x50A2: -case 0x52A2: -case 0x54A2: -case 0x56A2: -case 0x58A2: -case 0x5AA2: -case 0x5CA2: -case 0x5EA2: -case 0x50A3: -case 0x52A3: -case 0x54A3: -case 0x56A3: -case 0x58A3: -case 0x5AA3: -case 0x5CA3: -case 0x5EA3: -case 0x50A4: -case 0x52A4: -case 0x54A4: -case 0x56A4: -case 0x58A4: -case 0x5AA4: -case 0x5CA4: -case 0x5EA4: -case 0x50A5: -case 0x52A5: -case 0x54A5: -case 0x56A5: -case 0x58A5: -case 0x5AA5: -case 0x5CA5: -case 0x5EA5: -case 0x50A6: -case 0x52A6: -case 0x54A6: -case 0x56A6: -case 0x58A6: -case 0x5AA6: -case 0x5CA6: -case 0x5EA6: - -// ADDQ -case 0x50A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x52A8: -case 0x54A8: -case 0x56A8: -case 0x58A8: -case 0x5AA8: -case 0x5CA8: -case 0x5EA8: -case 0x50A9: -case 0x52A9: -case 0x54A9: -case 0x56A9: -case 0x58A9: -case 0x5AA9: -case 0x5CA9: -case 0x5EA9: -case 0x50AA: -case 0x52AA: -case 0x54AA: -case 0x56AA: -case 0x58AA: -case 0x5AAA: -case 0x5CAA: -case 0x5EAA: -case 0x50AB: -case 0x52AB: -case 0x54AB: -case 0x56AB: -case 0x58AB: -case 0x5AAB: -case 0x5CAB: -case 0x5EAB: -case 0x50AC: -case 0x52AC: -case 0x54AC: -case 0x56AC: -case 0x58AC: -case 0x5AAC: -case 0x5CAC: -case 0x5EAC: -case 0x50AD: -case 0x52AD: -case 0x54AD: -case 0x56AD: -case 0x58AD: -case 0x5AAD: -case 0x5CAD: -case 0x5EAD: -case 0x50AE: -case 0x52AE: -case 0x54AE: -case 0x56AE: -case 0x58AE: -case 0x5AAE: -case 0x5CAE: -case 0x5EAE: -case 0x50AF: -case 0x52AF: -case 0x54AF: -case 0x56AF: -case 0x58AF: -case 0x5AAF: -case 0x5CAF: -case 0x5EAF: - -// ADDQ -case 0x50A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x52B0: -case 0x54B0: -case 0x56B0: -case 0x58B0: -case 0x5AB0: -case 0x5CB0: -case 0x5EB0: -case 0x50B1: -case 0x52B1: -case 0x54B1: -case 0x56B1: -case 0x58B1: -case 0x5AB1: -case 0x5CB1: -case 0x5EB1: -case 0x50B2: -case 0x52B2: -case 0x54B2: -case 0x56B2: -case 0x58B2: -case 0x5AB2: -case 0x5CB2: -case 0x5EB2: -case 0x50B3: -case 0x52B3: -case 0x54B3: -case 0x56B3: -case 0x58B3: -case 0x5AB3: -case 0x5CB3: -case 0x5EB3: -case 0x50B4: -case 0x52B4: -case 0x54B4: -case 0x56B4: -case 0x58B4: -case 0x5AB4: -case 0x5CB4: -case 0x5EB4: -case 0x50B5: -case 0x52B5: -case 0x54B5: -case 0x56B5: -case 0x58B5: -case 0x5AB5: -case 0x5CB5: -case 0x5EB5: -case 0x50B6: -case 0x52B6: -case 0x54B6: -case 0x56B6: -case 0x58B6: -case 0x5AB6: -case 0x5CB6: -case 0x5EB6: -case 0x50B7: -case 0x52B7: -case 0x54B7: -case 0x56B7: -case 0x58B7: -case 0x5AB7: -case 0x5CB7: -case 0x5EB7: - -// ADDQ -case 0x50B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x52B8: -case 0x54B8: -case 0x56B8: -case 0x58B8: -case 0x5AB8: -case 0x5CB8: -case 0x5EB8: - -// ADDQ -case 0x50B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x52B9: -case 0x54B9: -case 0x56B9: -case 0x58B9: -case 0x5AB9: -case 0x5CB9: -case 0x5EB9: - -// ADDQ -case 0x50B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x529F: -case 0x549F: -case 0x569F: -case 0x589F: -case 0x5A9F: -case 0x5C9F: -case 0x5E9F: - -// ADDQ -case 0x509F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x52A7: -case 0x54A7: -case 0x56A7: -case 0x58A7: -case 0x5AA7: -case 0x5CA7: -case 0x5EA7: - -// ADDQ -case 0x50A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x5300: -case 0x5500: -case 0x5700: -case 0x5900: -case 0x5B00: -case 0x5D00: -case 0x5F00: -case 0x5101: -case 0x5301: -case 0x5501: -case 0x5701: -case 0x5901: -case 0x5B01: -case 0x5D01: -case 0x5F01: -case 0x5102: -case 0x5302: -case 0x5502: -case 0x5702: -case 0x5902: -case 0x5B02: -case 0x5D02: -case 0x5F02: -case 0x5103: -case 0x5303: -case 0x5503: -case 0x5703: -case 0x5903: -case 0x5B03: -case 0x5D03: -case 0x5F03: -case 0x5104: -case 0x5304: -case 0x5504: -case 0x5704: -case 0x5904: -case 0x5B04: -case 0x5D04: -case 0x5F04: -case 0x5105: -case 0x5305: -case 0x5505: -case 0x5705: -case 0x5905: -case 0x5B05: -case 0x5D05: -case 0x5F05: -case 0x5106: -case 0x5306: -case 0x5506: -case 0x5706: -case 0x5906: -case 0x5B06: -case 0x5D06: -case 0x5F06: -case 0x5107: -case 0x5307: -case 0x5507: -case 0x5707: -case 0x5907: -case 0x5B07: -case 0x5D07: -case 0x5F07: - -// SUBQ -case 0x5100: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5310: -case 0x5510: -case 0x5710: -case 0x5910: -case 0x5B10: -case 0x5D10: -case 0x5F10: -case 0x5111: -case 0x5311: -case 0x5511: -case 0x5711: -case 0x5911: -case 0x5B11: -case 0x5D11: -case 0x5F11: -case 0x5112: -case 0x5312: -case 0x5512: -case 0x5712: -case 0x5912: -case 0x5B12: -case 0x5D12: -case 0x5F12: -case 0x5113: -case 0x5313: -case 0x5513: -case 0x5713: -case 0x5913: -case 0x5B13: -case 0x5D13: -case 0x5F13: -case 0x5114: -case 0x5314: -case 0x5514: -case 0x5714: -case 0x5914: -case 0x5B14: -case 0x5D14: -case 0x5F14: -case 0x5115: -case 0x5315: -case 0x5515: -case 0x5715: -case 0x5915: -case 0x5B15: -case 0x5D15: -case 0x5F15: -case 0x5116: -case 0x5316: -case 0x5516: -case 0x5716: -case 0x5916: -case 0x5B16: -case 0x5D16: -case 0x5F16: -case 0x5117: -case 0x5317: -case 0x5517: -case 0x5717: -case 0x5917: -case 0x5B17: -case 0x5D17: -case 0x5F17: - -// SUBQ -case 0x5110: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5318: -case 0x5518: -case 0x5718: -case 0x5918: -case 0x5B18: -case 0x5D18: -case 0x5F18: -case 0x5119: -case 0x5319: -case 0x5519: -case 0x5719: -case 0x5919: -case 0x5B19: -case 0x5D19: -case 0x5F19: -case 0x511A: -case 0x531A: -case 0x551A: -case 0x571A: -case 0x591A: -case 0x5B1A: -case 0x5D1A: -case 0x5F1A: -case 0x511B: -case 0x531B: -case 0x551B: -case 0x571B: -case 0x591B: -case 0x5B1B: -case 0x5D1B: -case 0x5F1B: -case 0x511C: -case 0x531C: -case 0x551C: -case 0x571C: -case 0x591C: -case 0x5B1C: -case 0x5D1C: -case 0x5F1C: -case 0x511D: -case 0x531D: -case 0x551D: -case 0x571D: -case 0x591D: -case 0x5B1D: -case 0x5D1D: -case 0x5F1D: -case 0x511E: -case 0x531E: -case 0x551E: -case 0x571E: -case 0x591E: -case 0x5B1E: -case 0x5D1E: -case 0x5F1E: - -// SUBQ -case 0x5118: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5320: -case 0x5520: -case 0x5720: -case 0x5920: -case 0x5B20: -case 0x5D20: -case 0x5F20: -case 0x5121: -case 0x5321: -case 0x5521: -case 0x5721: -case 0x5921: -case 0x5B21: -case 0x5D21: -case 0x5F21: -case 0x5122: -case 0x5322: -case 0x5522: -case 0x5722: -case 0x5922: -case 0x5B22: -case 0x5D22: -case 0x5F22: -case 0x5123: -case 0x5323: -case 0x5523: -case 0x5723: -case 0x5923: -case 0x5B23: -case 0x5D23: -case 0x5F23: -case 0x5124: -case 0x5324: -case 0x5524: -case 0x5724: -case 0x5924: -case 0x5B24: -case 0x5D24: -case 0x5F24: -case 0x5125: -case 0x5325: -case 0x5525: -case 0x5725: -case 0x5925: -case 0x5B25: -case 0x5D25: -case 0x5F25: -case 0x5126: -case 0x5326: -case 0x5526: -case 0x5726: -case 0x5926: -case 0x5B26: -case 0x5D26: -case 0x5F26: - -// SUBQ -case 0x5120: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5328: -case 0x5528: -case 0x5728: -case 0x5928: -case 0x5B28: -case 0x5D28: -case 0x5F28: -case 0x5129: -case 0x5329: -case 0x5529: -case 0x5729: -case 0x5929: -case 0x5B29: -case 0x5D29: -case 0x5F29: -case 0x512A: -case 0x532A: -case 0x552A: -case 0x572A: -case 0x592A: -case 0x5B2A: -case 0x5D2A: -case 0x5F2A: -case 0x512B: -case 0x532B: -case 0x552B: -case 0x572B: -case 0x592B: -case 0x5B2B: -case 0x5D2B: -case 0x5F2B: -case 0x512C: -case 0x532C: -case 0x552C: -case 0x572C: -case 0x592C: -case 0x5B2C: -case 0x5D2C: -case 0x5F2C: -case 0x512D: -case 0x532D: -case 0x552D: -case 0x572D: -case 0x592D: -case 0x5B2D: -case 0x5D2D: -case 0x5F2D: -case 0x512E: -case 0x532E: -case 0x552E: -case 0x572E: -case 0x592E: -case 0x5B2E: -case 0x5D2E: -case 0x5F2E: -case 0x512F: -case 0x532F: -case 0x552F: -case 0x572F: -case 0x592F: -case 0x5B2F: -case 0x5D2F: -case 0x5F2F: - -// SUBQ -case 0x5128: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5330: -case 0x5530: -case 0x5730: -case 0x5930: -case 0x5B30: -case 0x5D30: -case 0x5F30: -case 0x5131: -case 0x5331: -case 0x5531: -case 0x5731: -case 0x5931: -case 0x5B31: -case 0x5D31: -case 0x5F31: -case 0x5132: -case 0x5332: -case 0x5532: -case 0x5732: -case 0x5932: -case 0x5B32: -case 0x5D32: -case 0x5F32: -case 0x5133: -case 0x5333: -case 0x5533: -case 0x5733: -case 0x5933: -case 0x5B33: -case 0x5D33: -case 0x5F33: -case 0x5134: -case 0x5334: -case 0x5534: -case 0x5734: -case 0x5934: -case 0x5B34: -case 0x5D34: -case 0x5F34: -case 0x5135: -case 0x5335: -case 0x5535: -case 0x5735: -case 0x5935: -case 0x5B35: -case 0x5D35: -case 0x5F35: -case 0x5136: -case 0x5336: -case 0x5536: -case 0x5736: -case 0x5936: -case 0x5B36: -case 0x5D36: -case 0x5F36: -case 0x5137: -case 0x5337: -case 0x5537: -case 0x5737: -case 0x5937: -case 0x5B37: -case 0x5D37: -case 0x5F37: - -// SUBQ -case 0x5130: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x5338: -case 0x5538: -case 0x5738: -case 0x5938: -case 0x5B38: -case 0x5D38: -case 0x5F38: - -// SUBQ -case 0x5138: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5339: -case 0x5539: -case 0x5739: -case 0x5939: -case 0x5B39: -case 0x5D39: -case 0x5F39: - -// SUBQ -case 0x5139: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x531F: -case 0x551F: -case 0x571F: -case 0x591F: -case 0x5B1F: -case 0x5D1F: -case 0x5F1F: - -// SUBQ -case 0x511F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5327: -case 0x5527: -case 0x5727: -case 0x5927: -case 0x5B27: -case 0x5D27: -case 0x5F27: - -// SUBQ -case 0x5127: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5340: -case 0x5540: -case 0x5740: -case 0x5940: -case 0x5B40: -case 0x5D40: -case 0x5F40: -case 0x5141: -case 0x5341: -case 0x5541: -case 0x5741: -case 0x5941: -case 0x5B41: -case 0x5D41: -case 0x5F41: -case 0x5142: -case 0x5342: -case 0x5542: -case 0x5742: -case 0x5942: -case 0x5B42: -case 0x5D42: -case 0x5F42: -case 0x5143: -case 0x5343: -case 0x5543: -case 0x5743: -case 0x5943: -case 0x5B43: -case 0x5D43: -case 0x5F43: -case 0x5144: -case 0x5344: -case 0x5544: -case 0x5744: -case 0x5944: -case 0x5B44: -case 0x5D44: -case 0x5F44: -case 0x5145: -case 0x5345: -case 0x5545: -case 0x5745: -case 0x5945: -case 0x5B45: -case 0x5D45: -case 0x5F45: -case 0x5146: -case 0x5346: -case 0x5546: -case 0x5746: -case 0x5946: -case 0x5B46: -case 0x5D46: -case 0x5F46: -case 0x5147: -case 0x5347: -case 0x5547: -case 0x5747: -case 0x5947: -case 0x5B47: -case 0x5D47: -case 0x5F47: - -// SUBQ -case 0x5140: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5348: -case 0x5548: -case 0x5748: -case 0x5948: -case 0x5B48: -case 0x5D48: -case 0x5F48: -case 0x5149: -case 0x5349: -case 0x5549: -case 0x5749: -case 0x5949: -case 0x5B49: -case 0x5D49: -case 0x5F49: -case 0x514A: -case 0x534A: -case 0x554A: -case 0x574A: -case 0x594A: -case 0x5B4A: -case 0x5D4A: -case 0x5F4A: -case 0x514B: -case 0x534B: -case 0x554B: -case 0x574B: -case 0x594B: -case 0x5B4B: -case 0x5D4B: -case 0x5F4B: -case 0x514C: -case 0x534C: -case 0x554C: -case 0x574C: -case 0x594C: -case 0x5B4C: -case 0x5D4C: -case 0x5F4C: -case 0x514D: -case 0x534D: -case 0x554D: -case 0x574D: -case 0x594D: -case 0x5B4D: -case 0x5D4D: -case 0x5F4D: -case 0x514E: -case 0x534E: -case 0x554E: -case 0x574E: -case 0x594E: -case 0x5B4E: -case 0x5D4E: -case 0x5F4E: -case 0x514F: -case 0x534F: -case 0x554F: -case 0x574F: -case 0x594F: -case 0x5B4F: -case 0x5D4F: -case 0x5F4F: - -// SUBQ -case 0x5148: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst - src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5350: -case 0x5550: -case 0x5750: -case 0x5950: -case 0x5B50: -case 0x5D50: -case 0x5F50: -case 0x5151: -case 0x5351: -case 0x5551: -case 0x5751: -case 0x5951: -case 0x5B51: -case 0x5D51: -case 0x5F51: -case 0x5152: -case 0x5352: -case 0x5552: -case 0x5752: -case 0x5952: -case 0x5B52: -case 0x5D52: -case 0x5F52: -case 0x5153: -case 0x5353: -case 0x5553: -case 0x5753: -case 0x5953: -case 0x5B53: -case 0x5D53: -case 0x5F53: -case 0x5154: -case 0x5354: -case 0x5554: -case 0x5754: -case 0x5954: -case 0x5B54: -case 0x5D54: -case 0x5F54: -case 0x5155: -case 0x5355: -case 0x5555: -case 0x5755: -case 0x5955: -case 0x5B55: -case 0x5D55: -case 0x5F55: -case 0x5156: -case 0x5356: -case 0x5556: -case 0x5756: -case 0x5956: -case 0x5B56: -case 0x5D56: -case 0x5F56: -case 0x5157: -case 0x5357: -case 0x5557: -case 0x5757: -case 0x5957: -case 0x5B57: -case 0x5D57: -case 0x5F57: - -// SUBQ -case 0x5150: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5358: -case 0x5558: -case 0x5758: -case 0x5958: -case 0x5B58: -case 0x5D58: -case 0x5F58: -case 0x5159: -case 0x5359: -case 0x5559: -case 0x5759: -case 0x5959: -case 0x5B59: -case 0x5D59: -case 0x5F59: -case 0x515A: -case 0x535A: -case 0x555A: -case 0x575A: -case 0x595A: -case 0x5B5A: -case 0x5D5A: -case 0x5F5A: -case 0x515B: -case 0x535B: -case 0x555B: -case 0x575B: -case 0x595B: -case 0x5B5B: -case 0x5D5B: -case 0x5F5B: -case 0x515C: -case 0x535C: -case 0x555C: -case 0x575C: -case 0x595C: -case 0x5B5C: -case 0x5D5C: -case 0x5F5C: -case 0x515D: -case 0x535D: -case 0x555D: -case 0x575D: -case 0x595D: -case 0x5B5D: -case 0x5D5D: -case 0x5F5D: -case 0x515E: -case 0x535E: -case 0x555E: -case 0x575E: -case 0x595E: -case 0x5B5E: -case 0x5D5E: -case 0x5F5E: - -// SUBQ -case 0x5158: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5360: -case 0x5560: -case 0x5760: -case 0x5960: -case 0x5B60: -case 0x5D60: -case 0x5F60: -case 0x5161: -case 0x5361: -case 0x5561: -case 0x5761: -case 0x5961: -case 0x5B61: -case 0x5D61: -case 0x5F61: -case 0x5162: -case 0x5362: -case 0x5562: -case 0x5762: -case 0x5962: -case 0x5B62: -case 0x5D62: -case 0x5F62: -case 0x5163: -case 0x5363: -case 0x5563: -case 0x5763: -case 0x5963: -case 0x5B63: -case 0x5D63: -case 0x5F63: -case 0x5164: -case 0x5364: -case 0x5564: -case 0x5764: -case 0x5964: -case 0x5B64: -case 0x5D64: -case 0x5F64: -case 0x5165: -case 0x5365: -case 0x5565: -case 0x5765: -case 0x5965: -case 0x5B65: -case 0x5D65: -case 0x5F65: -case 0x5166: -case 0x5366: -case 0x5566: -case 0x5766: -case 0x5966: -case 0x5B66: -case 0x5D66: -case 0x5F66: - -// SUBQ -case 0x5160: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5368: -case 0x5568: -case 0x5768: -case 0x5968: -case 0x5B68: -case 0x5D68: -case 0x5F68: -case 0x5169: -case 0x5369: -case 0x5569: -case 0x5769: -case 0x5969: -case 0x5B69: -case 0x5D69: -case 0x5F69: -case 0x516A: -case 0x536A: -case 0x556A: -case 0x576A: -case 0x596A: -case 0x5B6A: -case 0x5D6A: -case 0x5F6A: -case 0x516B: -case 0x536B: -case 0x556B: -case 0x576B: -case 0x596B: -case 0x5B6B: -case 0x5D6B: -case 0x5F6B: -case 0x516C: -case 0x536C: -case 0x556C: -case 0x576C: -case 0x596C: -case 0x5B6C: -case 0x5D6C: -case 0x5F6C: -case 0x516D: -case 0x536D: -case 0x556D: -case 0x576D: -case 0x596D: -case 0x5B6D: -case 0x5D6D: -case 0x5F6D: -case 0x516E: -case 0x536E: -case 0x556E: -case 0x576E: -case 0x596E: -case 0x5B6E: -case 0x5D6E: -case 0x5F6E: -case 0x516F: -case 0x536F: -case 0x556F: -case 0x576F: -case 0x596F: -case 0x5B6F: -case 0x5D6F: -case 0x5F6F: - -// SUBQ -case 0x5168: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5370: -case 0x5570: -case 0x5770: -case 0x5970: -case 0x5B70: -case 0x5D70: -case 0x5F70: -case 0x5171: -case 0x5371: -case 0x5571: -case 0x5771: -case 0x5971: -case 0x5B71: -case 0x5D71: -case 0x5F71: -case 0x5172: -case 0x5372: -case 0x5572: -case 0x5772: -case 0x5972: -case 0x5B72: -case 0x5D72: -case 0x5F72: -case 0x5173: -case 0x5373: -case 0x5573: -case 0x5773: -case 0x5973: -case 0x5B73: -case 0x5D73: -case 0x5F73: -case 0x5174: -case 0x5374: -case 0x5574: -case 0x5774: -case 0x5974: -case 0x5B74: -case 0x5D74: -case 0x5F74: -case 0x5175: -case 0x5375: -case 0x5575: -case 0x5775: -case 0x5975: -case 0x5B75: -case 0x5D75: -case 0x5F75: -case 0x5176: -case 0x5376: -case 0x5576: -case 0x5776: -case 0x5976: -case 0x5B76: -case 0x5D76: -case 0x5F76: -case 0x5177: -case 0x5377: -case 0x5577: -case 0x5777: -case 0x5977: -case 0x5B77: -case 0x5D77: -case 0x5F77: - -// SUBQ -case 0x5170: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x5378: -case 0x5578: -case 0x5778: -case 0x5978: -case 0x5B78: -case 0x5D78: -case 0x5F78: - -// SUBQ -case 0x5178: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5379: -case 0x5579: -case 0x5779: -case 0x5979: -case 0x5B79: -case 0x5D79: -case 0x5F79: - -// SUBQ -case 0x5179: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x535F: -case 0x555F: -case 0x575F: -case 0x595F: -case 0x5B5F: -case 0x5D5F: -case 0x5F5F: - -// SUBQ -case 0x515F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5367: -case 0x5567: -case 0x5767: -case 0x5967: -case 0x5B67: -case 0x5D67: -case 0x5F67: - -// SUBQ -case 0x5167: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5380: -case 0x5580: -case 0x5780: -case 0x5980: -case 0x5B80: -case 0x5D80: -case 0x5F80: -case 0x5181: -case 0x5381: -case 0x5581: -case 0x5781: -case 0x5981: -case 0x5B81: -case 0x5D81: -case 0x5F81: -case 0x5182: -case 0x5382: -case 0x5582: -case 0x5782: -case 0x5982: -case 0x5B82: -case 0x5D82: -case 0x5F82: -case 0x5183: -case 0x5383: -case 0x5583: -case 0x5783: -case 0x5983: -case 0x5B83: -case 0x5D83: -case 0x5F83: -case 0x5184: -case 0x5384: -case 0x5584: -case 0x5784: -case 0x5984: -case 0x5B84: -case 0x5D84: -case 0x5F84: -case 0x5185: -case 0x5385: -case 0x5585: -case 0x5785: -case 0x5985: -case 0x5B85: -case 0x5D85: -case 0x5F85: -case 0x5186: -case 0x5386: -case 0x5586: -case 0x5786: -case 0x5986: -case 0x5B86: -case 0x5D86: -case 0x5F86: -case 0x5187: -case 0x5387: -case 0x5587: -case 0x5787: -case 0x5987: -case 0x5B87: -case 0x5D87: -case 0x5F87: - -// SUBQ -case 0x5180: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x5388: -case 0x5588: -case 0x5788: -case 0x5988: -case 0x5B88: -case 0x5D88: -case 0x5F88: -case 0x5189: -case 0x5389: -case 0x5589: -case 0x5789: -case 0x5989: -case 0x5B89: -case 0x5D89: -case 0x5F89: -case 0x518A: -case 0x538A: -case 0x558A: -case 0x578A: -case 0x598A: -case 0x5B8A: -case 0x5D8A: -case 0x5F8A: -case 0x518B: -case 0x538B: -case 0x558B: -case 0x578B: -case 0x598B: -case 0x5B8B: -case 0x5D8B: -case 0x5F8B: -case 0x518C: -case 0x538C: -case 0x558C: -case 0x578C: -case 0x598C: -case 0x5B8C: -case 0x5D8C: -case 0x5F8C: -case 0x518D: -case 0x538D: -case 0x558D: -case 0x578D: -case 0x598D: -case 0x5B8D: -case 0x5D8D: -case 0x5F8D: -case 0x518E: -case 0x538E: -case 0x558E: -case 0x578E: -case 0x598E: -case 0x5B8E: -case 0x5D8E: -case 0x5F8E: -case 0x518F: -case 0x538F: -case 0x558F: -case 0x578F: -case 0x598F: -case 0x5B8F: -case 0x5D8F: -case 0x5F8F: - -// SUBQ -case 0x5188: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst - src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5390: -case 0x5590: -case 0x5790: -case 0x5990: -case 0x5B90: -case 0x5D90: -case 0x5F90: -case 0x5191: -case 0x5391: -case 0x5591: -case 0x5791: -case 0x5991: -case 0x5B91: -case 0x5D91: -case 0x5F91: -case 0x5192: -case 0x5392: -case 0x5592: -case 0x5792: -case 0x5992: -case 0x5B92: -case 0x5D92: -case 0x5F92: -case 0x5193: -case 0x5393: -case 0x5593: -case 0x5793: -case 0x5993: -case 0x5B93: -case 0x5D93: -case 0x5F93: -case 0x5194: -case 0x5394: -case 0x5594: -case 0x5794: -case 0x5994: -case 0x5B94: -case 0x5D94: -case 0x5F94: -case 0x5195: -case 0x5395: -case 0x5595: -case 0x5795: -case 0x5995: -case 0x5B95: -case 0x5D95: -case 0x5F95: -case 0x5196: -case 0x5396: -case 0x5596: -case 0x5796: -case 0x5996: -case 0x5B96: -case 0x5D96: -case 0x5F96: -case 0x5197: -case 0x5397: -case 0x5597: -case 0x5797: -case 0x5997: -case 0x5B97: -case 0x5D97: -case 0x5F97: - -// SUBQ -case 0x5190: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x5398: -case 0x5598: -case 0x5798: -case 0x5998: -case 0x5B98: -case 0x5D98: -case 0x5F98: -case 0x5199: -case 0x5399: -case 0x5599: -case 0x5799: -case 0x5999: -case 0x5B99: -case 0x5D99: -case 0x5F99: -case 0x519A: -case 0x539A: -case 0x559A: -case 0x579A: -case 0x599A: -case 0x5B9A: -case 0x5D9A: -case 0x5F9A: -case 0x519B: -case 0x539B: -case 0x559B: -case 0x579B: -case 0x599B: -case 0x5B9B: -case 0x5D9B: -case 0x5F9B: -case 0x519C: -case 0x539C: -case 0x559C: -case 0x579C: -case 0x599C: -case 0x5B9C: -case 0x5D9C: -case 0x5F9C: -case 0x519D: -case 0x539D: -case 0x559D: -case 0x579D: -case 0x599D: -case 0x5B9D: -case 0x5D9D: -case 0x5F9D: -case 0x519E: -case 0x539E: -case 0x559E: -case 0x579E: -case 0x599E: -case 0x5B9E: -case 0x5D9E: -case 0x5F9E: - -// SUBQ -case 0x5198: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x53A0: -case 0x55A0: -case 0x57A0: -case 0x59A0: -case 0x5BA0: -case 0x5DA0: -case 0x5FA0: -case 0x51A1: -case 0x53A1: -case 0x55A1: -case 0x57A1: -case 0x59A1: -case 0x5BA1: -case 0x5DA1: -case 0x5FA1: -case 0x51A2: -case 0x53A2: -case 0x55A2: -case 0x57A2: -case 0x59A2: -case 0x5BA2: -case 0x5DA2: -case 0x5FA2: -case 0x51A3: -case 0x53A3: -case 0x55A3: -case 0x57A3: -case 0x59A3: -case 0x5BA3: -case 0x5DA3: -case 0x5FA3: -case 0x51A4: -case 0x53A4: -case 0x55A4: -case 0x57A4: -case 0x59A4: -case 0x5BA4: -case 0x5DA4: -case 0x5FA4: -case 0x51A5: -case 0x53A5: -case 0x55A5: -case 0x57A5: -case 0x59A5: -case 0x5BA5: -case 0x5DA5: -case 0x5FA5: -case 0x51A6: -case 0x53A6: -case 0x55A6: -case 0x57A6: -case 0x59A6: -case 0x5BA6: -case 0x5DA6: -case 0x5FA6: - -// SUBQ -case 0x51A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x53A8: -case 0x55A8: -case 0x57A8: -case 0x59A8: -case 0x5BA8: -case 0x5DA8: -case 0x5FA8: -case 0x51A9: -case 0x53A9: -case 0x55A9: -case 0x57A9: -case 0x59A9: -case 0x5BA9: -case 0x5DA9: -case 0x5FA9: -case 0x51AA: -case 0x53AA: -case 0x55AA: -case 0x57AA: -case 0x59AA: -case 0x5BAA: -case 0x5DAA: -case 0x5FAA: -case 0x51AB: -case 0x53AB: -case 0x55AB: -case 0x57AB: -case 0x59AB: -case 0x5BAB: -case 0x5DAB: -case 0x5FAB: -case 0x51AC: -case 0x53AC: -case 0x55AC: -case 0x57AC: -case 0x59AC: -case 0x5BAC: -case 0x5DAC: -case 0x5FAC: -case 0x51AD: -case 0x53AD: -case 0x55AD: -case 0x57AD: -case 0x59AD: -case 0x5BAD: -case 0x5DAD: -case 0x5FAD: -case 0x51AE: -case 0x53AE: -case 0x55AE: -case 0x57AE: -case 0x59AE: -case 0x5BAE: -case 0x5DAE: -case 0x5FAE: -case 0x51AF: -case 0x53AF: -case 0x55AF: -case 0x57AF: -case 0x59AF: -case 0x5BAF: -case 0x5DAF: -case 0x5FAF: - -// SUBQ -case 0x51A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x53B0: -case 0x55B0: -case 0x57B0: -case 0x59B0: -case 0x5BB0: -case 0x5DB0: -case 0x5FB0: -case 0x51B1: -case 0x53B1: -case 0x55B1: -case 0x57B1: -case 0x59B1: -case 0x5BB1: -case 0x5DB1: -case 0x5FB1: -case 0x51B2: -case 0x53B2: -case 0x55B2: -case 0x57B2: -case 0x59B2: -case 0x5BB2: -case 0x5DB2: -case 0x5FB2: -case 0x51B3: -case 0x53B3: -case 0x55B3: -case 0x57B3: -case 0x59B3: -case 0x5BB3: -case 0x5DB3: -case 0x5FB3: -case 0x51B4: -case 0x53B4: -case 0x55B4: -case 0x57B4: -case 0x59B4: -case 0x5BB4: -case 0x5DB4: -case 0x5FB4: -case 0x51B5: -case 0x53B5: -case 0x55B5: -case 0x57B5: -case 0x59B5: -case 0x5BB5: -case 0x5DB5: -case 0x5FB5: -case 0x51B6: -case 0x53B6: -case 0x55B6: -case 0x57B6: -case 0x59B6: -case 0x5BB6: -case 0x5DB6: -case 0x5FB6: -case 0x51B7: -case 0x53B7: -case 0x55B7: -case 0x57B7: -case 0x59B7: -case 0x5BB7: -case 0x5DB7: -case 0x5FB7: - -// SUBQ -case 0x51B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x53B8: -case 0x55B8: -case 0x57B8: -case 0x59B8: -case 0x5BB8: -case 0x5DB8: -case 0x5FB8: - -// SUBQ -case 0x51B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x53B9: -case 0x55B9: -case 0x57B9: -case 0x59B9: -case 0x5BB9: -case 0x5DB9: -case 0x5FB9: - -// SUBQ -case 0x51B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x539F: -case 0x559F: -case 0x579F: -case 0x599F: -case 0x5B9F: -case 0x5D9F: -case 0x5F9F: - -// SUBQ -case 0x519F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x53A7: -case 0x55A7: -case 0x57A7: -case 0x59A7: -case 0x5BA7: -case 0x5DA7: -case 0x5FA7: - -// SUBQ -case 0x51A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) diff --git a/yabause/src/c68k/c68k_op6.inc b/yabause/src/c68k/c68k_op6.inc deleted file mode 100644 index d5b94b5317..0000000000 --- a/yabause/src/c68k/c68k_op6.inc +++ /dev/null @@ -1,4454 +0,0 @@ -case 0x6202: -case 0x6203: -case 0x6204: -case 0x6205: -case 0x6206: -case 0x6207: -case 0x6208: -case 0x6209: -case 0x620A: -case 0x620B: -case 0x620C: -case 0x620D: -case 0x620E: -case 0x620F: -case 0x6210: -case 0x6211: -case 0x6212: -case 0x6213: -case 0x6214: -case 0x6215: -case 0x6216: -case 0x6217: -case 0x6218: -case 0x6219: -case 0x621A: -case 0x621B: -case 0x621C: -case 0x621D: -case 0x621E: -case 0x621F: -case 0x6220: -case 0x6221: -case 0x6222: -case 0x6223: -case 0x6224: -case 0x6225: -case 0x6226: -case 0x6227: -case 0x6228: -case 0x6229: -case 0x622A: -case 0x622B: -case 0x622C: -case 0x622D: -case 0x622E: -case 0x622F: -case 0x6230: -case 0x6231: -case 0x6232: -case 0x6233: -case 0x6234: -case 0x6235: -case 0x6236: -case 0x6237: -case 0x6238: -case 0x6239: -case 0x623A: -case 0x623B: -case 0x623C: -case 0x623D: -case 0x623E: -case 0x623F: -case 0x6240: -case 0x6241: -case 0x6242: -case 0x6243: -case 0x6244: -case 0x6245: -case 0x6246: -case 0x6247: -case 0x6248: -case 0x6249: -case 0x624A: -case 0x624B: -case 0x624C: -case 0x624D: -case 0x624E: -case 0x624F: -case 0x6250: -case 0x6251: -case 0x6252: -case 0x6253: -case 0x6254: -case 0x6255: -case 0x6256: -case 0x6257: -case 0x6258: -case 0x6259: -case 0x625A: -case 0x625B: -case 0x625C: -case 0x625D: -case 0x625E: -case 0x625F: -case 0x6260: -case 0x6261: -case 0x6262: -case 0x6263: -case 0x6264: -case 0x6265: -case 0x6266: -case 0x6267: -case 0x6268: -case 0x6269: -case 0x626A: -case 0x626B: -case 0x626C: -case 0x626D: -case 0x626E: -case 0x626F: -case 0x6270: -case 0x6271: -case 0x6272: -case 0x6273: -case 0x6274: -case 0x6275: -case 0x6276: -case 0x6277: -case 0x6278: -case 0x6279: -case 0x627A: -case 0x627B: -case 0x627C: -case 0x627D: -case 0x627E: -case 0x627F: -case 0x6280: -case 0x6281: -case 0x6282: -case 0x6283: -case 0x6284: -case 0x6285: -case 0x6286: -case 0x6287: -case 0x6288: -case 0x6289: -case 0x628A: -case 0x628B: -case 0x628C: -case 0x628D: -case 0x628E: -case 0x628F: -case 0x6290: -case 0x6291: -case 0x6292: -case 0x6293: -case 0x6294: -case 0x6295: -case 0x6296: -case 0x6297: -case 0x6298: -case 0x6299: -case 0x629A: -case 0x629B: -case 0x629C: -case 0x629D: -case 0x629E: -case 0x629F: -case 0x62A0: -case 0x62A1: -case 0x62A2: -case 0x62A3: -case 0x62A4: -case 0x62A5: -case 0x62A6: -case 0x62A7: -case 0x62A8: -case 0x62A9: -case 0x62AA: -case 0x62AB: -case 0x62AC: -case 0x62AD: -case 0x62AE: -case 0x62AF: -case 0x62B0: -case 0x62B1: -case 0x62B2: -case 0x62B3: -case 0x62B4: -case 0x62B5: -case 0x62B6: -case 0x62B7: -case 0x62B8: -case 0x62B9: -case 0x62BA: -case 0x62BB: -case 0x62BC: -case 0x62BD: -case 0x62BE: -case 0x62BF: -case 0x62C0: -case 0x62C1: -case 0x62C2: -case 0x62C3: -case 0x62C4: -case 0x62C5: -case 0x62C6: -case 0x62C7: -case 0x62C8: -case 0x62C9: -case 0x62CA: -case 0x62CB: -case 0x62CC: -case 0x62CD: -case 0x62CE: -case 0x62CF: -case 0x62D0: -case 0x62D1: -case 0x62D2: -case 0x62D3: -case 0x62D4: -case 0x62D5: -case 0x62D6: -case 0x62D7: -case 0x62D8: -case 0x62D9: -case 0x62DA: -case 0x62DB: -case 0x62DC: -case 0x62DD: -case 0x62DE: -case 0x62DF: -case 0x62E0: -case 0x62E1: -case 0x62E2: -case 0x62E3: -case 0x62E4: -case 0x62E5: -case 0x62E6: -case 0x62E7: -case 0x62E8: -case 0x62E9: -case 0x62EA: -case 0x62EB: -case 0x62EC: -case 0x62ED: -case 0x62EE: -case 0x62EF: -case 0x62F0: -case 0x62F1: -case 0x62F2: -case 0x62F3: -case 0x62F4: -case 0x62F5: -case 0x62F6: -case 0x62F7: -case 0x62F8: -case 0x62F9: -case 0x62FA: -case 0x62FB: -case 0x62FC: -case 0x62FD: -case 0x62FE: -case 0x62FF: - -// BCC -case 0x6201: -{ - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6302: -case 0x6303: -case 0x6304: -case 0x6305: -case 0x6306: -case 0x6307: -case 0x6308: -case 0x6309: -case 0x630A: -case 0x630B: -case 0x630C: -case 0x630D: -case 0x630E: -case 0x630F: -case 0x6310: -case 0x6311: -case 0x6312: -case 0x6313: -case 0x6314: -case 0x6315: -case 0x6316: -case 0x6317: -case 0x6318: -case 0x6319: -case 0x631A: -case 0x631B: -case 0x631C: -case 0x631D: -case 0x631E: -case 0x631F: -case 0x6320: -case 0x6321: -case 0x6322: -case 0x6323: -case 0x6324: -case 0x6325: -case 0x6326: -case 0x6327: -case 0x6328: -case 0x6329: -case 0x632A: -case 0x632B: -case 0x632C: -case 0x632D: -case 0x632E: -case 0x632F: -case 0x6330: -case 0x6331: -case 0x6332: -case 0x6333: -case 0x6334: -case 0x6335: -case 0x6336: -case 0x6337: -case 0x6338: -case 0x6339: -case 0x633A: -case 0x633B: -case 0x633C: -case 0x633D: -case 0x633E: -case 0x633F: -case 0x6340: -case 0x6341: -case 0x6342: -case 0x6343: -case 0x6344: -case 0x6345: -case 0x6346: -case 0x6347: -case 0x6348: -case 0x6349: -case 0x634A: -case 0x634B: -case 0x634C: -case 0x634D: -case 0x634E: -case 0x634F: -case 0x6350: -case 0x6351: -case 0x6352: -case 0x6353: -case 0x6354: -case 0x6355: -case 0x6356: -case 0x6357: -case 0x6358: -case 0x6359: -case 0x635A: -case 0x635B: -case 0x635C: -case 0x635D: -case 0x635E: -case 0x635F: -case 0x6360: -case 0x6361: -case 0x6362: -case 0x6363: -case 0x6364: -case 0x6365: -case 0x6366: -case 0x6367: -case 0x6368: -case 0x6369: -case 0x636A: -case 0x636B: -case 0x636C: -case 0x636D: -case 0x636E: -case 0x636F: -case 0x6370: -case 0x6371: -case 0x6372: -case 0x6373: -case 0x6374: -case 0x6375: -case 0x6376: -case 0x6377: -case 0x6378: -case 0x6379: -case 0x637A: -case 0x637B: -case 0x637C: -case 0x637D: -case 0x637E: -case 0x637F: -case 0x6380: -case 0x6381: -case 0x6382: -case 0x6383: -case 0x6384: -case 0x6385: -case 0x6386: -case 0x6387: -case 0x6388: -case 0x6389: -case 0x638A: -case 0x638B: -case 0x638C: -case 0x638D: -case 0x638E: -case 0x638F: -case 0x6390: -case 0x6391: -case 0x6392: -case 0x6393: -case 0x6394: -case 0x6395: -case 0x6396: -case 0x6397: -case 0x6398: -case 0x6399: -case 0x639A: -case 0x639B: -case 0x639C: -case 0x639D: -case 0x639E: -case 0x639F: -case 0x63A0: -case 0x63A1: -case 0x63A2: -case 0x63A3: -case 0x63A4: -case 0x63A5: -case 0x63A6: -case 0x63A7: -case 0x63A8: -case 0x63A9: -case 0x63AA: -case 0x63AB: -case 0x63AC: -case 0x63AD: -case 0x63AE: -case 0x63AF: -case 0x63B0: -case 0x63B1: -case 0x63B2: -case 0x63B3: -case 0x63B4: -case 0x63B5: -case 0x63B6: -case 0x63B7: -case 0x63B8: -case 0x63B9: -case 0x63BA: -case 0x63BB: -case 0x63BC: -case 0x63BD: -case 0x63BE: -case 0x63BF: -case 0x63C0: -case 0x63C1: -case 0x63C2: -case 0x63C3: -case 0x63C4: -case 0x63C5: -case 0x63C6: -case 0x63C7: -case 0x63C8: -case 0x63C9: -case 0x63CA: -case 0x63CB: -case 0x63CC: -case 0x63CD: -case 0x63CE: -case 0x63CF: -case 0x63D0: -case 0x63D1: -case 0x63D2: -case 0x63D3: -case 0x63D4: -case 0x63D5: -case 0x63D6: -case 0x63D7: -case 0x63D8: -case 0x63D9: -case 0x63DA: -case 0x63DB: -case 0x63DC: -case 0x63DD: -case 0x63DE: -case 0x63DF: -case 0x63E0: -case 0x63E1: -case 0x63E2: -case 0x63E3: -case 0x63E4: -case 0x63E5: -case 0x63E6: -case 0x63E7: -case 0x63E8: -case 0x63E9: -case 0x63EA: -case 0x63EB: -case 0x63EC: -case 0x63ED: -case 0x63EE: -case 0x63EF: -case 0x63F0: -case 0x63F1: -case 0x63F2: -case 0x63F3: -case 0x63F4: -case 0x63F5: -case 0x63F6: -case 0x63F7: -case 0x63F8: -case 0x63F9: -case 0x63FA: -case 0x63FB: -case 0x63FC: -case 0x63FD: -case 0x63FE: -case 0x63FF: - -// BCC -case 0x6301: -{ - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6402: -case 0x6403: -case 0x6404: -case 0x6405: -case 0x6406: -case 0x6407: -case 0x6408: -case 0x6409: -case 0x640A: -case 0x640B: -case 0x640C: -case 0x640D: -case 0x640E: -case 0x640F: -case 0x6410: -case 0x6411: -case 0x6412: -case 0x6413: -case 0x6414: -case 0x6415: -case 0x6416: -case 0x6417: -case 0x6418: -case 0x6419: -case 0x641A: -case 0x641B: -case 0x641C: -case 0x641D: -case 0x641E: -case 0x641F: -case 0x6420: -case 0x6421: -case 0x6422: -case 0x6423: -case 0x6424: -case 0x6425: -case 0x6426: -case 0x6427: -case 0x6428: -case 0x6429: -case 0x642A: -case 0x642B: -case 0x642C: -case 0x642D: -case 0x642E: -case 0x642F: -case 0x6430: -case 0x6431: -case 0x6432: -case 0x6433: -case 0x6434: -case 0x6435: -case 0x6436: -case 0x6437: -case 0x6438: -case 0x6439: -case 0x643A: -case 0x643B: -case 0x643C: -case 0x643D: -case 0x643E: -case 0x643F: -case 0x6440: -case 0x6441: -case 0x6442: -case 0x6443: -case 0x6444: -case 0x6445: -case 0x6446: -case 0x6447: -case 0x6448: -case 0x6449: -case 0x644A: -case 0x644B: -case 0x644C: -case 0x644D: -case 0x644E: -case 0x644F: -case 0x6450: -case 0x6451: -case 0x6452: -case 0x6453: -case 0x6454: -case 0x6455: -case 0x6456: -case 0x6457: -case 0x6458: -case 0x6459: -case 0x645A: -case 0x645B: -case 0x645C: -case 0x645D: -case 0x645E: -case 0x645F: -case 0x6460: -case 0x6461: -case 0x6462: -case 0x6463: -case 0x6464: -case 0x6465: -case 0x6466: -case 0x6467: -case 0x6468: -case 0x6469: -case 0x646A: -case 0x646B: -case 0x646C: -case 0x646D: -case 0x646E: -case 0x646F: -case 0x6470: -case 0x6471: -case 0x6472: -case 0x6473: -case 0x6474: -case 0x6475: -case 0x6476: -case 0x6477: -case 0x6478: -case 0x6479: -case 0x647A: -case 0x647B: -case 0x647C: -case 0x647D: -case 0x647E: -case 0x647F: -case 0x6480: -case 0x6481: -case 0x6482: -case 0x6483: -case 0x6484: -case 0x6485: -case 0x6486: -case 0x6487: -case 0x6488: -case 0x6489: -case 0x648A: -case 0x648B: -case 0x648C: -case 0x648D: -case 0x648E: -case 0x648F: -case 0x6490: -case 0x6491: -case 0x6492: -case 0x6493: -case 0x6494: -case 0x6495: -case 0x6496: -case 0x6497: -case 0x6498: -case 0x6499: -case 0x649A: -case 0x649B: -case 0x649C: -case 0x649D: -case 0x649E: -case 0x649F: -case 0x64A0: -case 0x64A1: -case 0x64A2: -case 0x64A3: -case 0x64A4: -case 0x64A5: -case 0x64A6: -case 0x64A7: -case 0x64A8: -case 0x64A9: -case 0x64AA: -case 0x64AB: -case 0x64AC: -case 0x64AD: -case 0x64AE: -case 0x64AF: -case 0x64B0: -case 0x64B1: -case 0x64B2: -case 0x64B3: -case 0x64B4: -case 0x64B5: -case 0x64B6: -case 0x64B7: -case 0x64B8: -case 0x64B9: -case 0x64BA: -case 0x64BB: -case 0x64BC: -case 0x64BD: -case 0x64BE: -case 0x64BF: -case 0x64C0: -case 0x64C1: -case 0x64C2: -case 0x64C3: -case 0x64C4: -case 0x64C5: -case 0x64C6: -case 0x64C7: -case 0x64C8: -case 0x64C9: -case 0x64CA: -case 0x64CB: -case 0x64CC: -case 0x64CD: -case 0x64CE: -case 0x64CF: -case 0x64D0: -case 0x64D1: -case 0x64D2: -case 0x64D3: -case 0x64D4: -case 0x64D5: -case 0x64D6: -case 0x64D7: -case 0x64D8: -case 0x64D9: -case 0x64DA: -case 0x64DB: -case 0x64DC: -case 0x64DD: -case 0x64DE: -case 0x64DF: -case 0x64E0: -case 0x64E1: -case 0x64E2: -case 0x64E3: -case 0x64E4: -case 0x64E5: -case 0x64E6: -case 0x64E7: -case 0x64E8: -case 0x64E9: -case 0x64EA: -case 0x64EB: -case 0x64EC: -case 0x64ED: -case 0x64EE: -case 0x64EF: -case 0x64F0: -case 0x64F1: -case 0x64F2: -case 0x64F3: -case 0x64F4: -case 0x64F5: -case 0x64F6: -case 0x64F7: -case 0x64F8: -case 0x64F9: -case 0x64FA: -case 0x64FB: -case 0x64FC: -case 0x64FD: -case 0x64FE: -case 0x64FF: - -// BCC -case 0x6401: -{ - if (!(CPU->flag_C & 0x100)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6502: -case 0x6503: -case 0x6504: -case 0x6505: -case 0x6506: -case 0x6507: -case 0x6508: -case 0x6509: -case 0x650A: -case 0x650B: -case 0x650C: -case 0x650D: -case 0x650E: -case 0x650F: -case 0x6510: -case 0x6511: -case 0x6512: -case 0x6513: -case 0x6514: -case 0x6515: -case 0x6516: -case 0x6517: -case 0x6518: -case 0x6519: -case 0x651A: -case 0x651B: -case 0x651C: -case 0x651D: -case 0x651E: -case 0x651F: -case 0x6520: -case 0x6521: -case 0x6522: -case 0x6523: -case 0x6524: -case 0x6525: -case 0x6526: -case 0x6527: -case 0x6528: -case 0x6529: -case 0x652A: -case 0x652B: -case 0x652C: -case 0x652D: -case 0x652E: -case 0x652F: -case 0x6530: -case 0x6531: -case 0x6532: -case 0x6533: -case 0x6534: -case 0x6535: -case 0x6536: -case 0x6537: -case 0x6538: -case 0x6539: -case 0x653A: -case 0x653B: -case 0x653C: -case 0x653D: -case 0x653E: -case 0x653F: -case 0x6540: -case 0x6541: -case 0x6542: -case 0x6543: -case 0x6544: -case 0x6545: -case 0x6546: -case 0x6547: -case 0x6548: -case 0x6549: -case 0x654A: -case 0x654B: -case 0x654C: -case 0x654D: -case 0x654E: -case 0x654F: -case 0x6550: -case 0x6551: -case 0x6552: -case 0x6553: -case 0x6554: -case 0x6555: -case 0x6556: -case 0x6557: -case 0x6558: -case 0x6559: -case 0x655A: -case 0x655B: -case 0x655C: -case 0x655D: -case 0x655E: -case 0x655F: -case 0x6560: -case 0x6561: -case 0x6562: -case 0x6563: -case 0x6564: -case 0x6565: -case 0x6566: -case 0x6567: -case 0x6568: -case 0x6569: -case 0x656A: -case 0x656B: -case 0x656C: -case 0x656D: -case 0x656E: -case 0x656F: -case 0x6570: -case 0x6571: -case 0x6572: -case 0x6573: -case 0x6574: -case 0x6575: -case 0x6576: -case 0x6577: -case 0x6578: -case 0x6579: -case 0x657A: -case 0x657B: -case 0x657C: -case 0x657D: -case 0x657E: -case 0x657F: -case 0x6580: -case 0x6581: -case 0x6582: -case 0x6583: -case 0x6584: -case 0x6585: -case 0x6586: -case 0x6587: -case 0x6588: -case 0x6589: -case 0x658A: -case 0x658B: -case 0x658C: -case 0x658D: -case 0x658E: -case 0x658F: -case 0x6590: -case 0x6591: -case 0x6592: -case 0x6593: -case 0x6594: -case 0x6595: -case 0x6596: -case 0x6597: -case 0x6598: -case 0x6599: -case 0x659A: -case 0x659B: -case 0x659C: -case 0x659D: -case 0x659E: -case 0x659F: -case 0x65A0: -case 0x65A1: -case 0x65A2: -case 0x65A3: -case 0x65A4: -case 0x65A5: -case 0x65A6: -case 0x65A7: -case 0x65A8: -case 0x65A9: -case 0x65AA: -case 0x65AB: -case 0x65AC: -case 0x65AD: -case 0x65AE: -case 0x65AF: -case 0x65B0: -case 0x65B1: -case 0x65B2: -case 0x65B3: -case 0x65B4: -case 0x65B5: -case 0x65B6: -case 0x65B7: -case 0x65B8: -case 0x65B9: -case 0x65BA: -case 0x65BB: -case 0x65BC: -case 0x65BD: -case 0x65BE: -case 0x65BF: -case 0x65C0: -case 0x65C1: -case 0x65C2: -case 0x65C3: -case 0x65C4: -case 0x65C5: -case 0x65C6: -case 0x65C7: -case 0x65C8: -case 0x65C9: -case 0x65CA: -case 0x65CB: -case 0x65CC: -case 0x65CD: -case 0x65CE: -case 0x65CF: -case 0x65D0: -case 0x65D1: -case 0x65D2: -case 0x65D3: -case 0x65D4: -case 0x65D5: -case 0x65D6: -case 0x65D7: -case 0x65D8: -case 0x65D9: -case 0x65DA: -case 0x65DB: -case 0x65DC: -case 0x65DD: -case 0x65DE: -case 0x65DF: -case 0x65E0: -case 0x65E1: -case 0x65E2: -case 0x65E3: -case 0x65E4: -case 0x65E5: -case 0x65E6: -case 0x65E7: -case 0x65E8: -case 0x65E9: -case 0x65EA: -case 0x65EB: -case 0x65EC: -case 0x65ED: -case 0x65EE: -case 0x65EF: -case 0x65F0: -case 0x65F1: -case 0x65F2: -case 0x65F3: -case 0x65F4: -case 0x65F5: -case 0x65F6: -case 0x65F7: -case 0x65F8: -case 0x65F9: -case 0x65FA: -case 0x65FB: -case 0x65FC: -case 0x65FD: -case 0x65FE: -case 0x65FF: - -// BCC -case 0x6501: -{ - if (CPU->flag_C & 0x100) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6602: -case 0x6603: -case 0x6604: -case 0x6605: -case 0x6606: -case 0x6607: -case 0x6608: -case 0x6609: -case 0x660A: -case 0x660B: -case 0x660C: -case 0x660D: -case 0x660E: -case 0x660F: -case 0x6610: -case 0x6611: -case 0x6612: -case 0x6613: -case 0x6614: -case 0x6615: -case 0x6616: -case 0x6617: -case 0x6618: -case 0x6619: -case 0x661A: -case 0x661B: -case 0x661C: -case 0x661D: -case 0x661E: -case 0x661F: -case 0x6620: -case 0x6621: -case 0x6622: -case 0x6623: -case 0x6624: -case 0x6625: -case 0x6626: -case 0x6627: -case 0x6628: -case 0x6629: -case 0x662A: -case 0x662B: -case 0x662C: -case 0x662D: -case 0x662E: -case 0x662F: -case 0x6630: -case 0x6631: -case 0x6632: -case 0x6633: -case 0x6634: -case 0x6635: -case 0x6636: -case 0x6637: -case 0x6638: -case 0x6639: -case 0x663A: -case 0x663B: -case 0x663C: -case 0x663D: -case 0x663E: -case 0x663F: -case 0x6640: -case 0x6641: -case 0x6642: -case 0x6643: -case 0x6644: -case 0x6645: -case 0x6646: -case 0x6647: -case 0x6648: -case 0x6649: -case 0x664A: -case 0x664B: -case 0x664C: -case 0x664D: -case 0x664E: -case 0x664F: -case 0x6650: -case 0x6651: -case 0x6652: -case 0x6653: -case 0x6654: -case 0x6655: -case 0x6656: -case 0x6657: -case 0x6658: -case 0x6659: -case 0x665A: -case 0x665B: -case 0x665C: -case 0x665D: -case 0x665E: -case 0x665F: -case 0x6660: -case 0x6661: -case 0x6662: -case 0x6663: -case 0x6664: -case 0x6665: -case 0x6666: -case 0x6667: -case 0x6668: -case 0x6669: -case 0x666A: -case 0x666B: -case 0x666C: -case 0x666D: -case 0x666E: -case 0x666F: -case 0x6670: -case 0x6671: -case 0x6672: -case 0x6673: -case 0x6674: -case 0x6675: -case 0x6676: -case 0x6677: -case 0x6678: -case 0x6679: -case 0x667A: -case 0x667B: -case 0x667C: -case 0x667D: -case 0x667E: -case 0x667F: -case 0x6680: -case 0x6681: -case 0x6682: -case 0x6683: -case 0x6684: -case 0x6685: -case 0x6686: -case 0x6687: -case 0x6688: -case 0x6689: -case 0x668A: -case 0x668B: -case 0x668C: -case 0x668D: -case 0x668E: -case 0x668F: -case 0x6690: -case 0x6691: -case 0x6692: -case 0x6693: -case 0x6694: -case 0x6695: -case 0x6696: -case 0x6697: -case 0x6698: -case 0x6699: -case 0x669A: -case 0x669B: -case 0x669C: -case 0x669D: -case 0x669E: -case 0x669F: -case 0x66A0: -case 0x66A1: -case 0x66A2: -case 0x66A3: -case 0x66A4: -case 0x66A5: -case 0x66A6: -case 0x66A7: -case 0x66A8: -case 0x66A9: -case 0x66AA: -case 0x66AB: -case 0x66AC: -case 0x66AD: -case 0x66AE: -case 0x66AF: -case 0x66B0: -case 0x66B1: -case 0x66B2: -case 0x66B3: -case 0x66B4: -case 0x66B5: -case 0x66B6: -case 0x66B7: -case 0x66B8: -case 0x66B9: -case 0x66BA: -case 0x66BB: -case 0x66BC: -case 0x66BD: -case 0x66BE: -case 0x66BF: -case 0x66C0: -case 0x66C1: -case 0x66C2: -case 0x66C3: -case 0x66C4: -case 0x66C5: -case 0x66C6: -case 0x66C7: -case 0x66C8: -case 0x66C9: -case 0x66CA: -case 0x66CB: -case 0x66CC: -case 0x66CD: -case 0x66CE: -case 0x66CF: -case 0x66D0: -case 0x66D1: -case 0x66D2: -case 0x66D3: -case 0x66D4: -case 0x66D5: -case 0x66D6: -case 0x66D7: -case 0x66D8: -case 0x66D9: -case 0x66DA: -case 0x66DB: -case 0x66DC: -case 0x66DD: -case 0x66DE: -case 0x66DF: -case 0x66E0: -case 0x66E1: -case 0x66E2: -case 0x66E3: -case 0x66E4: -case 0x66E5: -case 0x66E6: -case 0x66E7: -case 0x66E8: -case 0x66E9: -case 0x66EA: -case 0x66EB: -case 0x66EC: -case 0x66ED: -case 0x66EE: -case 0x66EF: -case 0x66F0: -case 0x66F1: -case 0x66F2: -case 0x66F3: -case 0x66F4: -case 0x66F5: -case 0x66F6: -case 0x66F7: -case 0x66F8: -case 0x66F9: -case 0x66FA: -case 0x66FB: -case 0x66FC: -case 0x66FD: -case 0x66FE: -case 0x66FF: - -// BCC -case 0x6601: -{ - if (CPU->flag_notZ) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6702: -case 0x6703: -case 0x6704: -case 0x6705: -case 0x6706: -case 0x6707: -case 0x6708: -case 0x6709: -case 0x670A: -case 0x670B: -case 0x670C: -case 0x670D: -case 0x670E: -case 0x670F: -case 0x6710: -case 0x6711: -case 0x6712: -case 0x6713: -case 0x6714: -case 0x6715: -case 0x6716: -case 0x6717: -case 0x6718: -case 0x6719: -case 0x671A: -case 0x671B: -case 0x671C: -case 0x671D: -case 0x671E: -case 0x671F: -case 0x6720: -case 0x6721: -case 0x6722: -case 0x6723: -case 0x6724: -case 0x6725: -case 0x6726: -case 0x6727: -case 0x6728: -case 0x6729: -case 0x672A: -case 0x672B: -case 0x672C: -case 0x672D: -case 0x672E: -case 0x672F: -case 0x6730: -case 0x6731: -case 0x6732: -case 0x6733: -case 0x6734: -case 0x6735: -case 0x6736: -case 0x6737: -case 0x6738: -case 0x6739: -case 0x673A: -case 0x673B: -case 0x673C: -case 0x673D: -case 0x673E: -case 0x673F: -case 0x6740: -case 0x6741: -case 0x6742: -case 0x6743: -case 0x6744: -case 0x6745: -case 0x6746: -case 0x6747: -case 0x6748: -case 0x6749: -case 0x674A: -case 0x674B: -case 0x674C: -case 0x674D: -case 0x674E: -case 0x674F: -case 0x6750: -case 0x6751: -case 0x6752: -case 0x6753: -case 0x6754: -case 0x6755: -case 0x6756: -case 0x6757: -case 0x6758: -case 0x6759: -case 0x675A: -case 0x675B: -case 0x675C: -case 0x675D: -case 0x675E: -case 0x675F: -case 0x6760: -case 0x6761: -case 0x6762: -case 0x6763: -case 0x6764: -case 0x6765: -case 0x6766: -case 0x6767: -case 0x6768: -case 0x6769: -case 0x676A: -case 0x676B: -case 0x676C: -case 0x676D: -case 0x676E: -case 0x676F: -case 0x6770: -case 0x6771: -case 0x6772: -case 0x6773: -case 0x6774: -case 0x6775: -case 0x6776: -case 0x6777: -case 0x6778: -case 0x6779: -case 0x677A: -case 0x677B: -case 0x677C: -case 0x677D: -case 0x677E: -case 0x677F: -case 0x6780: -case 0x6781: -case 0x6782: -case 0x6783: -case 0x6784: -case 0x6785: -case 0x6786: -case 0x6787: -case 0x6788: -case 0x6789: -case 0x678A: -case 0x678B: -case 0x678C: -case 0x678D: -case 0x678E: -case 0x678F: -case 0x6790: -case 0x6791: -case 0x6792: -case 0x6793: -case 0x6794: -case 0x6795: -case 0x6796: -case 0x6797: -case 0x6798: -case 0x6799: -case 0x679A: -case 0x679B: -case 0x679C: -case 0x679D: -case 0x679E: -case 0x679F: -case 0x67A0: -case 0x67A1: -case 0x67A2: -case 0x67A3: -case 0x67A4: -case 0x67A5: -case 0x67A6: -case 0x67A7: -case 0x67A8: -case 0x67A9: -case 0x67AA: -case 0x67AB: -case 0x67AC: -case 0x67AD: -case 0x67AE: -case 0x67AF: -case 0x67B0: -case 0x67B1: -case 0x67B2: -case 0x67B3: -case 0x67B4: -case 0x67B5: -case 0x67B6: -case 0x67B7: -case 0x67B8: -case 0x67B9: -case 0x67BA: -case 0x67BB: -case 0x67BC: -case 0x67BD: -case 0x67BE: -case 0x67BF: -case 0x67C0: -case 0x67C1: -case 0x67C2: -case 0x67C3: -case 0x67C4: -case 0x67C5: -case 0x67C6: -case 0x67C7: -case 0x67C8: -case 0x67C9: -case 0x67CA: -case 0x67CB: -case 0x67CC: -case 0x67CD: -case 0x67CE: -case 0x67CF: -case 0x67D0: -case 0x67D1: -case 0x67D2: -case 0x67D3: -case 0x67D4: -case 0x67D5: -case 0x67D6: -case 0x67D7: -case 0x67D8: -case 0x67D9: -case 0x67DA: -case 0x67DB: -case 0x67DC: -case 0x67DD: -case 0x67DE: -case 0x67DF: -case 0x67E0: -case 0x67E1: -case 0x67E2: -case 0x67E3: -case 0x67E4: -case 0x67E5: -case 0x67E6: -case 0x67E7: -case 0x67E8: -case 0x67E9: -case 0x67EA: -case 0x67EB: -case 0x67EC: -case 0x67ED: -case 0x67EE: -case 0x67EF: -case 0x67F0: -case 0x67F1: -case 0x67F2: -case 0x67F3: -case 0x67F4: -case 0x67F5: -case 0x67F6: -case 0x67F7: -case 0x67F8: -case 0x67F9: -case 0x67FA: -case 0x67FB: -case 0x67FC: -case 0x67FD: -case 0x67FE: -case 0x67FF: - -// BCC -case 0x6701: -{ - if (!CPU->flag_notZ) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6802: -case 0x6803: -case 0x6804: -case 0x6805: -case 0x6806: -case 0x6807: -case 0x6808: -case 0x6809: -case 0x680A: -case 0x680B: -case 0x680C: -case 0x680D: -case 0x680E: -case 0x680F: -case 0x6810: -case 0x6811: -case 0x6812: -case 0x6813: -case 0x6814: -case 0x6815: -case 0x6816: -case 0x6817: -case 0x6818: -case 0x6819: -case 0x681A: -case 0x681B: -case 0x681C: -case 0x681D: -case 0x681E: -case 0x681F: -case 0x6820: -case 0x6821: -case 0x6822: -case 0x6823: -case 0x6824: -case 0x6825: -case 0x6826: -case 0x6827: -case 0x6828: -case 0x6829: -case 0x682A: -case 0x682B: -case 0x682C: -case 0x682D: -case 0x682E: -case 0x682F: -case 0x6830: -case 0x6831: -case 0x6832: -case 0x6833: -case 0x6834: -case 0x6835: -case 0x6836: -case 0x6837: -case 0x6838: -case 0x6839: -case 0x683A: -case 0x683B: -case 0x683C: -case 0x683D: -case 0x683E: -case 0x683F: -case 0x6840: -case 0x6841: -case 0x6842: -case 0x6843: -case 0x6844: -case 0x6845: -case 0x6846: -case 0x6847: -case 0x6848: -case 0x6849: -case 0x684A: -case 0x684B: -case 0x684C: -case 0x684D: -case 0x684E: -case 0x684F: -case 0x6850: -case 0x6851: -case 0x6852: -case 0x6853: -case 0x6854: -case 0x6855: -case 0x6856: -case 0x6857: -case 0x6858: -case 0x6859: -case 0x685A: -case 0x685B: -case 0x685C: -case 0x685D: -case 0x685E: -case 0x685F: -case 0x6860: -case 0x6861: -case 0x6862: -case 0x6863: -case 0x6864: -case 0x6865: -case 0x6866: -case 0x6867: -case 0x6868: -case 0x6869: -case 0x686A: -case 0x686B: -case 0x686C: -case 0x686D: -case 0x686E: -case 0x686F: -case 0x6870: -case 0x6871: -case 0x6872: -case 0x6873: -case 0x6874: -case 0x6875: -case 0x6876: -case 0x6877: -case 0x6878: -case 0x6879: -case 0x687A: -case 0x687B: -case 0x687C: -case 0x687D: -case 0x687E: -case 0x687F: -case 0x6880: -case 0x6881: -case 0x6882: -case 0x6883: -case 0x6884: -case 0x6885: -case 0x6886: -case 0x6887: -case 0x6888: -case 0x6889: -case 0x688A: -case 0x688B: -case 0x688C: -case 0x688D: -case 0x688E: -case 0x688F: -case 0x6890: -case 0x6891: -case 0x6892: -case 0x6893: -case 0x6894: -case 0x6895: -case 0x6896: -case 0x6897: -case 0x6898: -case 0x6899: -case 0x689A: -case 0x689B: -case 0x689C: -case 0x689D: -case 0x689E: -case 0x689F: -case 0x68A0: -case 0x68A1: -case 0x68A2: -case 0x68A3: -case 0x68A4: -case 0x68A5: -case 0x68A6: -case 0x68A7: -case 0x68A8: -case 0x68A9: -case 0x68AA: -case 0x68AB: -case 0x68AC: -case 0x68AD: -case 0x68AE: -case 0x68AF: -case 0x68B0: -case 0x68B1: -case 0x68B2: -case 0x68B3: -case 0x68B4: -case 0x68B5: -case 0x68B6: -case 0x68B7: -case 0x68B8: -case 0x68B9: -case 0x68BA: -case 0x68BB: -case 0x68BC: -case 0x68BD: -case 0x68BE: -case 0x68BF: -case 0x68C0: -case 0x68C1: -case 0x68C2: -case 0x68C3: -case 0x68C4: -case 0x68C5: -case 0x68C6: -case 0x68C7: -case 0x68C8: -case 0x68C9: -case 0x68CA: -case 0x68CB: -case 0x68CC: -case 0x68CD: -case 0x68CE: -case 0x68CF: -case 0x68D0: -case 0x68D1: -case 0x68D2: -case 0x68D3: -case 0x68D4: -case 0x68D5: -case 0x68D6: -case 0x68D7: -case 0x68D8: -case 0x68D9: -case 0x68DA: -case 0x68DB: -case 0x68DC: -case 0x68DD: -case 0x68DE: -case 0x68DF: -case 0x68E0: -case 0x68E1: -case 0x68E2: -case 0x68E3: -case 0x68E4: -case 0x68E5: -case 0x68E6: -case 0x68E7: -case 0x68E8: -case 0x68E9: -case 0x68EA: -case 0x68EB: -case 0x68EC: -case 0x68ED: -case 0x68EE: -case 0x68EF: -case 0x68F0: -case 0x68F1: -case 0x68F2: -case 0x68F3: -case 0x68F4: -case 0x68F5: -case 0x68F6: -case 0x68F7: -case 0x68F8: -case 0x68F9: -case 0x68FA: -case 0x68FB: -case 0x68FC: -case 0x68FD: -case 0x68FE: -case 0x68FF: - -// BCC -case 0x6801: -{ - if (!(CPU->flag_V & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6902: -case 0x6903: -case 0x6904: -case 0x6905: -case 0x6906: -case 0x6907: -case 0x6908: -case 0x6909: -case 0x690A: -case 0x690B: -case 0x690C: -case 0x690D: -case 0x690E: -case 0x690F: -case 0x6910: -case 0x6911: -case 0x6912: -case 0x6913: -case 0x6914: -case 0x6915: -case 0x6916: -case 0x6917: -case 0x6918: -case 0x6919: -case 0x691A: -case 0x691B: -case 0x691C: -case 0x691D: -case 0x691E: -case 0x691F: -case 0x6920: -case 0x6921: -case 0x6922: -case 0x6923: -case 0x6924: -case 0x6925: -case 0x6926: -case 0x6927: -case 0x6928: -case 0x6929: -case 0x692A: -case 0x692B: -case 0x692C: -case 0x692D: -case 0x692E: -case 0x692F: -case 0x6930: -case 0x6931: -case 0x6932: -case 0x6933: -case 0x6934: -case 0x6935: -case 0x6936: -case 0x6937: -case 0x6938: -case 0x6939: -case 0x693A: -case 0x693B: -case 0x693C: -case 0x693D: -case 0x693E: -case 0x693F: -case 0x6940: -case 0x6941: -case 0x6942: -case 0x6943: -case 0x6944: -case 0x6945: -case 0x6946: -case 0x6947: -case 0x6948: -case 0x6949: -case 0x694A: -case 0x694B: -case 0x694C: -case 0x694D: -case 0x694E: -case 0x694F: -case 0x6950: -case 0x6951: -case 0x6952: -case 0x6953: -case 0x6954: -case 0x6955: -case 0x6956: -case 0x6957: -case 0x6958: -case 0x6959: -case 0x695A: -case 0x695B: -case 0x695C: -case 0x695D: -case 0x695E: -case 0x695F: -case 0x6960: -case 0x6961: -case 0x6962: -case 0x6963: -case 0x6964: -case 0x6965: -case 0x6966: -case 0x6967: -case 0x6968: -case 0x6969: -case 0x696A: -case 0x696B: -case 0x696C: -case 0x696D: -case 0x696E: -case 0x696F: -case 0x6970: -case 0x6971: -case 0x6972: -case 0x6973: -case 0x6974: -case 0x6975: -case 0x6976: -case 0x6977: -case 0x6978: -case 0x6979: -case 0x697A: -case 0x697B: -case 0x697C: -case 0x697D: -case 0x697E: -case 0x697F: -case 0x6980: -case 0x6981: -case 0x6982: -case 0x6983: -case 0x6984: -case 0x6985: -case 0x6986: -case 0x6987: -case 0x6988: -case 0x6989: -case 0x698A: -case 0x698B: -case 0x698C: -case 0x698D: -case 0x698E: -case 0x698F: -case 0x6990: -case 0x6991: -case 0x6992: -case 0x6993: -case 0x6994: -case 0x6995: -case 0x6996: -case 0x6997: -case 0x6998: -case 0x6999: -case 0x699A: -case 0x699B: -case 0x699C: -case 0x699D: -case 0x699E: -case 0x699F: -case 0x69A0: -case 0x69A1: -case 0x69A2: -case 0x69A3: -case 0x69A4: -case 0x69A5: -case 0x69A6: -case 0x69A7: -case 0x69A8: -case 0x69A9: -case 0x69AA: -case 0x69AB: -case 0x69AC: -case 0x69AD: -case 0x69AE: -case 0x69AF: -case 0x69B0: -case 0x69B1: -case 0x69B2: -case 0x69B3: -case 0x69B4: -case 0x69B5: -case 0x69B6: -case 0x69B7: -case 0x69B8: -case 0x69B9: -case 0x69BA: -case 0x69BB: -case 0x69BC: -case 0x69BD: -case 0x69BE: -case 0x69BF: -case 0x69C0: -case 0x69C1: -case 0x69C2: -case 0x69C3: -case 0x69C4: -case 0x69C5: -case 0x69C6: -case 0x69C7: -case 0x69C8: -case 0x69C9: -case 0x69CA: -case 0x69CB: -case 0x69CC: -case 0x69CD: -case 0x69CE: -case 0x69CF: -case 0x69D0: -case 0x69D1: -case 0x69D2: -case 0x69D3: -case 0x69D4: -case 0x69D5: -case 0x69D6: -case 0x69D7: -case 0x69D8: -case 0x69D9: -case 0x69DA: -case 0x69DB: -case 0x69DC: -case 0x69DD: -case 0x69DE: -case 0x69DF: -case 0x69E0: -case 0x69E1: -case 0x69E2: -case 0x69E3: -case 0x69E4: -case 0x69E5: -case 0x69E6: -case 0x69E7: -case 0x69E8: -case 0x69E9: -case 0x69EA: -case 0x69EB: -case 0x69EC: -case 0x69ED: -case 0x69EE: -case 0x69EF: -case 0x69F0: -case 0x69F1: -case 0x69F2: -case 0x69F3: -case 0x69F4: -case 0x69F5: -case 0x69F6: -case 0x69F7: -case 0x69F8: -case 0x69F9: -case 0x69FA: -case 0x69FB: -case 0x69FC: -case 0x69FD: -case 0x69FE: -case 0x69FF: - -// BCC -case 0x6901: -{ - if (CPU->flag_V & 0x80) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6A02: -case 0x6A03: -case 0x6A04: -case 0x6A05: -case 0x6A06: -case 0x6A07: -case 0x6A08: -case 0x6A09: -case 0x6A0A: -case 0x6A0B: -case 0x6A0C: -case 0x6A0D: -case 0x6A0E: -case 0x6A0F: -case 0x6A10: -case 0x6A11: -case 0x6A12: -case 0x6A13: -case 0x6A14: -case 0x6A15: -case 0x6A16: -case 0x6A17: -case 0x6A18: -case 0x6A19: -case 0x6A1A: -case 0x6A1B: -case 0x6A1C: -case 0x6A1D: -case 0x6A1E: -case 0x6A1F: -case 0x6A20: -case 0x6A21: -case 0x6A22: -case 0x6A23: -case 0x6A24: -case 0x6A25: -case 0x6A26: -case 0x6A27: -case 0x6A28: -case 0x6A29: -case 0x6A2A: -case 0x6A2B: -case 0x6A2C: -case 0x6A2D: -case 0x6A2E: -case 0x6A2F: -case 0x6A30: -case 0x6A31: -case 0x6A32: -case 0x6A33: -case 0x6A34: -case 0x6A35: -case 0x6A36: -case 0x6A37: -case 0x6A38: -case 0x6A39: -case 0x6A3A: -case 0x6A3B: -case 0x6A3C: -case 0x6A3D: -case 0x6A3E: -case 0x6A3F: -case 0x6A40: -case 0x6A41: -case 0x6A42: -case 0x6A43: -case 0x6A44: -case 0x6A45: -case 0x6A46: -case 0x6A47: -case 0x6A48: -case 0x6A49: -case 0x6A4A: -case 0x6A4B: -case 0x6A4C: -case 0x6A4D: -case 0x6A4E: -case 0x6A4F: -case 0x6A50: -case 0x6A51: -case 0x6A52: -case 0x6A53: -case 0x6A54: -case 0x6A55: -case 0x6A56: -case 0x6A57: -case 0x6A58: -case 0x6A59: -case 0x6A5A: -case 0x6A5B: -case 0x6A5C: -case 0x6A5D: -case 0x6A5E: -case 0x6A5F: -case 0x6A60: -case 0x6A61: -case 0x6A62: -case 0x6A63: -case 0x6A64: -case 0x6A65: -case 0x6A66: -case 0x6A67: -case 0x6A68: -case 0x6A69: -case 0x6A6A: -case 0x6A6B: -case 0x6A6C: -case 0x6A6D: -case 0x6A6E: -case 0x6A6F: -case 0x6A70: -case 0x6A71: -case 0x6A72: -case 0x6A73: -case 0x6A74: -case 0x6A75: -case 0x6A76: -case 0x6A77: -case 0x6A78: -case 0x6A79: -case 0x6A7A: -case 0x6A7B: -case 0x6A7C: -case 0x6A7D: -case 0x6A7E: -case 0x6A7F: -case 0x6A80: -case 0x6A81: -case 0x6A82: -case 0x6A83: -case 0x6A84: -case 0x6A85: -case 0x6A86: -case 0x6A87: -case 0x6A88: -case 0x6A89: -case 0x6A8A: -case 0x6A8B: -case 0x6A8C: -case 0x6A8D: -case 0x6A8E: -case 0x6A8F: -case 0x6A90: -case 0x6A91: -case 0x6A92: -case 0x6A93: -case 0x6A94: -case 0x6A95: -case 0x6A96: -case 0x6A97: -case 0x6A98: -case 0x6A99: -case 0x6A9A: -case 0x6A9B: -case 0x6A9C: -case 0x6A9D: -case 0x6A9E: -case 0x6A9F: -case 0x6AA0: -case 0x6AA1: -case 0x6AA2: -case 0x6AA3: -case 0x6AA4: -case 0x6AA5: -case 0x6AA6: -case 0x6AA7: -case 0x6AA8: -case 0x6AA9: -case 0x6AAA: -case 0x6AAB: -case 0x6AAC: -case 0x6AAD: -case 0x6AAE: -case 0x6AAF: -case 0x6AB0: -case 0x6AB1: -case 0x6AB2: -case 0x6AB3: -case 0x6AB4: -case 0x6AB5: -case 0x6AB6: -case 0x6AB7: -case 0x6AB8: -case 0x6AB9: -case 0x6ABA: -case 0x6ABB: -case 0x6ABC: -case 0x6ABD: -case 0x6ABE: -case 0x6ABF: -case 0x6AC0: -case 0x6AC1: -case 0x6AC2: -case 0x6AC3: -case 0x6AC4: -case 0x6AC5: -case 0x6AC6: -case 0x6AC7: -case 0x6AC8: -case 0x6AC9: -case 0x6ACA: -case 0x6ACB: -case 0x6ACC: -case 0x6ACD: -case 0x6ACE: -case 0x6ACF: -case 0x6AD0: -case 0x6AD1: -case 0x6AD2: -case 0x6AD3: -case 0x6AD4: -case 0x6AD5: -case 0x6AD6: -case 0x6AD7: -case 0x6AD8: -case 0x6AD9: -case 0x6ADA: -case 0x6ADB: -case 0x6ADC: -case 0x6ADD: -case 0x6ADE: -case 0x6ADF: -case 0x6AE0: -case 0x6AE1: -case 0x6AE2: -case 0x6AE3: -case 0x6AE4: -case 0x6AE5: -case 0x6AE6: -case 0x6AE7: -case 0x6AE8: -case 0x6AE9: -case 0x6AEA: -case 0x6AEB: -case 0x6AEC: -case 0x6AED: -case 0x6AEE: -case 0x6AEF: -case 0x6AF0: -case 0x6AF1: -case 0x6AF2: -case 0x6AF3: -case 0x6AF4: -case 0x6AF5: -case 0x6AF6: -case 0x6AF7: -case 0x6AF8: -case 0x6AF9: -case 0x6AFA: -case 0x6AFB: -case 0x6AFC: -case 0x6AFD: -case 0x6AFE: -case 0x6AFF: - -// BCC -case 0x6A01: -{ - if (!(CPU->flag_N & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6B02: -case 0x6B03: -case 0x6B04: -case 0x6B05: -case 0x6B06: -case 0x6B07: -case 0x6B08: -case 0x6B09: -case 0x6B0A: -case 0x6B0B: -case 0x6B0C: -case 0x6B0D: -case 0x6B0E: -case 0x6B0F: -case 0x6B10: -case 0x6B11: -case 0x6B12: -case 0x6B13: -case 0x6B14: -case 0x6B15: -case 0x6B16: -case 0x6B17: -case 0x6B18: -case 0x6B19: -case 0x6B1A: -case 0x6B1B: -case 0x6B1C: -case 0x6B1D: -case 0x6B1E: -case 0x6B1F: -case 0x6B20: -case 0x6B21: -case 0x6B22: -case 0x6B23: -case 0x6B24: -case 0x6B25: -case 0x6B26: -case 0x6B27: -case 0x6B28: -case 0x6B29: -case 0x6B2A: -case 0x6B2B: -case 0x6B2C: -case 0x6B2D: -case 0x6B2E: -case 0x6B2F: -case 0x6B30: -case 0x6B31: -case 0x6B32: -case 0x6B33: -case 0x6B34: -case 0x6B35: -case 0x6B36: -case 0x6B37: -case 0x6B38: -case 0x6B39: -case 0x6B3A: -case 0x6B3B: -case 0x6B3C: -case 0x6B3D: -case 0x6B3E: -case 0x6B3F: -case 0x6B40: -case 0x6B41: -case 0x6B42: -case 0x6B43: -case 0x6B44: -case 0x6B45: -case 0x6B46: -case 0x6B47: -case 0x6B48: -case 0x6B49: -case 0x6B4A: -case 0x6B4B: -case 0x6B4C: -case 0x6B4D: -case 0x6B4E: -case 0x6B4F: -case 0x6B50: -case 0x6B51: -case 0x6B52: -case 0x6B53: -case 0x6B54: -case 0x6B55: -case 0x6B56: -case 0x6B57: -case 0x6B58: -case 0x6B59: -case 0x6B5A: -case 0x6B5B: -case 0x6B5C: -case 0x6B5D: -case 0x6B5E: -case 0x6B5F: -case 0x6B60: -case 0x6B61: -case 0x6B62: -case 0x6B63: -case 0x6B64: -case 0x6B65: -case 0x6B66: -case 0x6B67: -case 0x6B68: -case 0x6B69: -case 0x6B6A: -case 0x6B6B: -case 0x6B6C: -case 0x6B6D: -case 0x6B6E: -case 0x6B6F: -case 0x6B70: -case 0x6B71: -case 0x6B72: -case 0x6B73: -case 0x6B74: -case 0x6B75: -case 0x6B76: -case 0x6B77: -case 0x6B78: -case 0x6B79: -case 0x6B7A: -case 0x6B7B: -case 0x6B7C: -case 0x6B7D: -case 0x6B7E: -case 0x6B7F: -case 0x6B80: -case 0x6B81: -case 0x6B82: -case 0x6B83: -case 0x6B84: -case 0x6B85: -case 0x6B86: -case 0x6B87: -case 0x6B88: -case 0x6B89: -case 0x6B8A: -case 0x6B8B: -case 0x6B8C: -case 0x6B8D: -case 0x6B8E: -case 0x6B8F: -case 0x6B90: -case 0x6B91: -case 0x6B92: -case 0x6B93: -case 0x6B94: -case 0x6B95: -case 0x6B96: -case 0x6B97: -case 0x6B98: -case 0x6B99: -case 0x6B9A: -case 0x6B9B: -case 0x6B9C: -case 0x6B9D: -case 0x6B9E: -case 0x6B9F: -case 0x6BA0: -case 0x6BA1: -case 0x6BA2: -case 0x6BA3: -case 0x6BA4: -case 0x6BA5: -case 0x6BA6: -case 0x6BA7: -case 0x6BA8: -case 0x6BA9: -case 0x6BAA: -case 0x6BAB: -case 0x6BAC: -case 0x6BAD: -case 0x6BAE: -case 0x6BAF: -case 0x6BB0: -case 0x6BB1: -case 0x6BB2: -case 0x6BB3: -case 0x6BB4: -case 0x6BB5: -case 0x6BB6: -case 0x6BB7: -case 0x6BB8: -case 0x6BB9: -case 0x6BBA: -case 0x6BBB: -case 0x6BBC: -case 0x6BBD: -case 0x6BBE: -case 0x6BBF: -case 0x6BC0: -case 0x6BC1: -case 0x6BC2: -case 0x6BC3: -case 0x6BC4: -case 0x6BC5: -case 0x6BC6: -case 0x6BC7: -case 0x6BC8: -case 0x6BC9: -case 0x6BCA: -case 0x6BCB: -case 0x6BCC: -case 0x6BCD: -case 0x6BCE: -case 0x6BCF: -case 0x6BD0: -case 0x6BD1: -case 0x6BD2: -case 0x6BD3: -case 0x6BD4: -case 0x6BD5: -case 0x6BD6: -case 0x6BD7: -case 0x6BD8: -case 0x6BD9: -case 0x6BDA: -case 0x6BDB: -case 0x6BDC: -case 0x6BDD: -case 0x6BDE: -case 0x6BDF: -case 0x6BE0: -case 0x6BE1: -case 0x6BE2: -case 0x6BE3: -case 0x6BE4: -case 0x6BE5: -case 0x6BE6: -case 0x6BE7: -case 0x6BE8: -case 0x6BE9: -case 0x6BEA: -case 0x6BEB: -case 0x6BEC: -case 0x6BED: -case 0x6BEE: -case 0x6BEF: -case 0x6BF0: -case 0x6BF1: -case 0x6BF2: -case 0x6BF3: -case 0x6BF4: -case 0x6BF5: -case 0x6BF6: -case 0x6BF7: -case 0x6BF8: -case 0x6BF9: -case 0x6BFA: -case 0x6BFB: -case 0x6BFC: -case 0x6BFD: -case 0x6BFE: -case 0x6BFF: - -// BCC -case 0x6B01: -{ - if (CPU->flag_N & 0x80) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6C02: -case 0x6C03: -case 0x6C04: -case 0x6C05: -case 0x6C06: -case 0x6C07: -case 0x6C08: -case 0x6C09: -case 0x6C0A: -case 0x6C0B: -case 0x6C0C: -case 0x6C0D: -case 0x6C0E: -case 0x6C0F: -case 0x6C10: -case 0x6C11: -case 0x6C12: -case 0x6C13: -case 0x6C14: -case 0x6C15: -case 0x6C16: -case 0x6C17: -case 0x6C18: -case 0x6C19: -case 0x6C1A: -case 0x6C1B: -case 0x6C1C: -case 0x6C1D: -case 0x6C1E: -case 0x6C1F: -case 0x6C20: -case 0x6C21: -case 0x6C22: -case 0x6C23: -case 0x6C24: -case 0x6C25: -case 0x6C26: -case 0x6C27: -case 0x6C28: -case 0x6C29: -case 0x6C2A: -case 0x6C2B: -case 0x6C2C: -case 0x6C2D: -case 0x6C2E: -case 0x6C2F: -case 0x6C30: -case 0x6C31: -case 0x6C32: -case 0x6C33: -case 0x6C34: -case 0x6C35: -case 0x6C36: -case 0x6C37: -case 0x6C38: -case 0x6C39: -case 0x6C3A: -case 0x6C3B: -case 0x6C3C: -case 0x6C3D: -case 0x6C3E: -case 0x6C3F: -case 0x6C40: -case 0x6C41: -case 0x6C42: -case 0x6C43: -case 0x6C44: -case 0x6C45: -case 0x6C46: -case 0x6C47: -case 0x6C48: -case 0x6C49: -case 0x6C4A: -case 0x6C4B: -case 0x6C4C: -case 0x6C4D: -case 0x6C4E: -case 0x6C4F: -case 0x6C50: -case 0x6C51: -case 0x6C52: -case 0x6C53: -case 0x6C54: -case 0x6C55: -case 0x6C56: -case 0x6C57: -case 0x6C58: -case 0x6C59: -case 0x6C5A: -case 0x6C5B: -case 0x6C5C: -case 0x6C5D: -case 0x6C5E: -case 0x6C5F: -case 0x6C60: -case 0x6C61: -case 0x6C62: -case 0x6C63: -case 0x6C64: -case 0x6C65: -case 0x6C66: -case 0x6C67: -case 0x6C68: -case 0x6C69: -case 0x6C6A: -case 0x6C6B: -case 0x6C6C: -case 0x6C6D: -case 0x6C6E: -case 0x6C6F: -case 0x6C70: -case 0x6C71: -case 0x6C72: -case 0x6C73: -case 0x6C74: -case 0x6C75: -case 0x6C76: -case 0x6C77: -case 0x6C78: -case 0x6C79: -case 0x6C7A: -case 0x6C7B: -case 0x6C7C: -case 0x6C7D: -case 0x6C7E: -case 0x6C7F: -case 0x6C80: -case 0x6C81: -case 0x6C82: -case 0x6C83: -case 0x6C84: -case 0x6C85: -case 0x6C86: -case 0x6C87: -case 0x6C88: -case 0x6C89: -case 0x6C8A: -case 0x6C8B: -case 0x6C8C: -case 0x6C8D: -case 0x6C8E: -case 0x6C8F: -case 0x6C90: -case 0x6C91: -case 0x6C92: -case 0x6C93: -case 0x6C94: -case 0x6C95: -case 0x6C96: -case 0x6C97: -case 0x6C98: -case 0x6C99: -case 0x6C9A: -case 0x6C9B: -case 0x6C9C: -case 0x6C9D: -case 0x6C9E: -case 0x6C9F: -case 0x6CA0: -case 0x6CA1: -case 0x6CA2: -case 0x6CA3: -case 0x6CA4: -case 0x6CA5: -case 0x6CA6: -case 0x6CA7: -case 0x6CA8: -case 0x6CA9: -case 0x6CAA: -case 0x6CAB: -case 0x6CAC: -case 0x6CAD: -case 0x6CAE: -case 0x6CAF: -case 0x6CB0: -case 0x6CB1: -case 0x6CB2: -case 0x6CB3: -case 0x6CB4: -case 0x6CB5: -case 0x6CB6: -case 0x6CB7: -case 0x6CB8: -case 0x6CB9: -case 0x6CBA: -case 0x6CBB: -case 0x6CBC: -case 0x6CBD: -case 0x6CBE: -case 0x6CBF: -case 0x6CC0: -case 0x6CC1: -case 0x6CC2: -case 0x6CC3: -case 0x6CC4: -case 0x6CC5: -case 0x6CC6: -case 0x6CC7: -case 0x6CC8: -case 0x6CC9: -case 0x6CCA: -case 0x6CCB: -case 0x6CCC: -case 0x6CCD: -case 0x6CCE: -case 0x6CCF: -case 0x6CD0: -case 0x6CD1: -case 0x6CD2: -case 0x6CD3: -case 0x6CD4: -case 0x6CD5: -case 0x6CD6: -case 0x6CD7: -case 0x6CD8: -case 0x6CD9: -case 0x6CDA: -case 0x6CDB: -case 0x6CDC: -case 0x6CDD: -case 0x6CDE: -case 0x6CDF: -case 0x6CE0: -case 0x6CE1: -case 0x6CE2: -case 0x6CE3: -case 0x6CE4: -case 0x6CE5: -case 0x6CE6: -case 0x6CE7: -case 0x6CE8: -case 0x6CE9: -case 0x6CEA: -case 0x6CEB: -case 0x6CEC: -case 0x6CED: -case 0x6CEE: -case 0x6CEF: -case 0x6CF0: -case 0x6CF1: -case 0x6CF2: -case 0x6CF3: -case 0x6CF4: -case 0x6CF5: -case 0x6CF6: -case 0x6CF7: -case 0x6CF8: -case 0x6CF9: -case 0x6CFA: -case 0x6CFB: -case 0x6CFC: -case 0x6CFD: -case 0x6CFE: -case 0x6CFF: - -// BCC -case 0x6C01: -{ - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6D02: -case 0x6D03: -case 0x6D04: -case 0x6D05: -case 0x6D06: -case 0x6D07: -case 0x6D08: -case 0x6D09: -case 0x6D0A: -case 0x6D0B: -case 0x6D0C: -case 0x6D0D: -case 0x6D0E: -case 0x6D0F: -case 0x6D10: -case 0x6D11: -case 0x6D12: -case 0x6D13: -case 0x6D14: -case 0x6D15: -case 0x6D16: -case 0x6D17: -case 0x6D18: -case 0x6D19: -case 0x6D1A: -case 0x6D1B: -case 0x6D1C: -case 0x6D1D: -case 0x6D1E: -case 0x6D1F: -case 0x6D20: -case 0x6D21: -case 0x6D22: -case 0x6D23: -case 0x6D24: -case 0x6D25: -case 0x6D26: -case 0x6D27: -case 0x6D28: -case 0x6D29: -case 0x6D2A: -case 0x6D2B: -case 0x6D2C: -case 0x6D2D: -case 0x6D2E: -case 0x6D2F: -case 0x6D30: -case 0x6D31: -case 0x6D32: -case 0x6D33: -case 0x6D34: -case 0x6D35: -case 0x6D36: -case 0x6D37: -case 0x6D38: -case 0x6D39: -case 0x6D3A: -case 0x6D3B: -case 0x6D3C: -case 0x6D3D: -case 0x6D3E: -case 0x6D3F: -case 0x6D40: -case 0x6D41: -case 0x6D42: -case 0x6D43: -case 0x6D44: -case 0x6D45: -case 0x6D46: -case 0x6D47: -case 0x6D48: -case 0x6D49: -case 0x6D4A: -case 0x6D4B: -case 0x6D4C: -case 0x6D4D: -case 0x6D4E: -case 0x6D4F: -case 0x6D50: -case 0x6D51: -case 0x6D52: -case 0x6D53: -case 0x6D54: -case 0x6D55: -case 0x6D56: -case 0x6D57: -case 0x6D58: -case 0x6D59: -case 0x6D5A: -case 0x6D5B: -case 0x6D5C: -case 0x6D5D: -case 0x6D5E: -case 0x6D5F: -case 0x6D60: -case 0x6D61: -case 0x6D62: -case 0x6D63: -case 0x6D64: -case 0x6D65: -case 0x6D66: -case 0x6D67: -case 0x6D68: -case 0x6D69: -case 0x6D6A: -case 0x6D6B: -case 0x6D6C: -case 0x6D6D: -case 0x6D6E: -case 0x6D6F: -case 0x6D70: -case 0x6D71: -case 0x6D72: -case 0x6D73: -case 0x6D74: -case 0x6D75: -case 0x6D76: -case 0x6D77: -case 0x6D78: -case 0x6D79: -case 0x6D7A: -case 0x6D7B: -case 0x6D7C: -case 0x6D7D: -case 0x6D7E: -case 0x6D7F: -case 0x6D80: -case 0x6D81: -case 0x6D82: -case 0x6D83: -case 0x6D84: -case 0x6D85: -case 0x6D86: -case 0x6D87: -case 0x6D88: -case 0x6D89: -case 0x6D8A: -case 0x6D8B: -case 0x6D8C: -case 0x6D8D: -case 0x6D8E: -case 0x6D8F: -case 0x6D90: -case 0x6D91: -case 0x6D92: -case 0x6D93: -case 0x6D94: -case 0x6D95: -case 0x6D96: -case 0x6D97: -case 0x6D98: -case 0x6D99: -case 0x6D9A: -case 0x6D9B: -case 0x6D9C: -case 0x6D9D: -case 0x6D9E: -case 0x6D9F: -case 0x6DA0: -case 0x6DA1: -case 0x6DA2: -case 0x6DA3: -case 0x6DA4: -case 0x6DA5: -case 0x6DA6: -case 0x6DA7: -case 0x6DA8: -case 0x6DA9: -case 0x6DAA: -case 0x6DAB: -case 0x6DAC: -case 0x6DAD: -case 0x6DAE: -case 0x6DAF: -case 0x6DB0: -case 0x6DB1: -case 0x6DB2: -case 0x6DB3: -case 0x6DB4: -case 0x6DB5: -case 0x6DB6: -case 0x6DB7: -case 0x6DB8: -case 0x6DB9: -case 0x6DBA: -case 0x6DBB: -case 0x6DBC: -case 0x6DBD: -case 0x6DBE: -case 0x6DBF: -case 0x6DC0: -case 0x6DC1: -case 0x6DC2: -case 0x6DC3: -case 0x6DC4: -case 0x6DC5: -case 0x6DC6: -case 0x6DC7: -case 0x6DC8: -case 0x6DC9: -case 0x6DCA: -case 0x6DCB: -case 0x6DCC: -case 0x6DCD: -case 0x6DCE: -case 0x6DCF: -case 0x6DD0: -case 0x6DD1: -case 0x6DD2: -case 0x6DD3: -case 0x6DD4: -case 0x6DD5: -case 0x6DD6: -case 0x6DD7: -case 0x6DD8: -case 0x6DD9: -case 0x6DDA: -case 0x6DDB: -case 0x6DDC: -case 0x6DDD: -case 0x6DDE: -case 0x6DDF: -case 0x6DE0: -case 0x6DE1: -case 0x6DE2: -case 0x6DE3: -case 0x6DE4: -case 0x6DE5: -case 0x6DE6: -case 0x6DE7: -case 0x6DE8: -case 0x6DE9: -case 0x6DEA: -case 0x6DEB: -case 0x6DEC: -case 0x6DED: -case 0x6DEE: -case 0x6DEF: -case 0x6DF0: -case 0x6DF1: -case 0x6DF2: -case 0x6DF3: -case 0x6DF4: -case 0x6DF5: -case 0x6DF6: -case 0x6DF7: -case 0x6DF8: -case 0x6DF9: -case 0x6DFA: -case 0x6DFB: -case 0x6DFC: -case 0x6DFD: -case 0x6DFE: -case 0x6DFF: - -// BCC -case 0x6D01: -{ - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6E02: -case 0x6E03: -case 0x6E04: -case 0x6E05: -case 0x6E06: -case 0x6E07: -case 0x6E08: -case 0x6E09: -case 0x6E0A: -case 0x6E0B: -case 0x6E0C: -case 0x6E0D: -case 0x6E0E: -case 0x6E0F: -case 0x6E10: -case 0x6E11: -case 0x6E12: -case 0x6E13: -case 0x6E14: -case 0x6E15: -case 0x6E16: -case 0x6E17: -case 0x6E18: -case 0x6E19: -case 0x6E1A: -case 0x6E1B: -case 0x6E1C: -case 0x6E1D: -case 0x6E1E: -case 0x6E1F: -case 0x6E20: -case 0x6E21: -case 0x6E22: -case 0x6E23: -case 0x6E24: -case 0x6E25: -case 0x6E26: -case 0x6E27: -case 0x6E28: -case 0x6E29: -case 0x6E2A: -case 0x6E2B: -case 0x6E2C: -case 0x6E2D: -case 0x6E2E: -case 0x6E2F: -case 0x6E30: -case 0x6E31: -case 0x6E32: -case 0x6E33: -case 0x6E34: -case 0x6E35: -case 0x6E36: -case 0x6E37: -case 0x6E38: -case 0x6E39: -case 0x6E3A: -case 0x6E3B: -case 0x6E3C: -case 0x6E3D: -case 0x6E3E: -case 0x6E3F: -case 0x6E40: -case 0x6E41: -case 0x6E42: -case 0x6E43: -case 0x6E44: -case 0x6E45: -case 0x6E46: -case 0x6E47: -case 0x6E48: -case 0x6E49: -case 0x6E4A: -case 0x6E4B: -case 0x6E4C: -case 0x6E4D: -case 0x6E4E: -case 0x6E4F: -case 0x6E50: -case 0x6E51: -case 0x6E52: -case 0x6E53: -case 0x6E54: -case 0x6E55: -case 0x6E56: -case 0x6E57: -case 0x6E58: -case 0x6E59: -case 0x6E5A: -case 0x6E5B: -case 0x6E5C: -case 0x6E5D: -case 0x6E5E: -case 0x6E5F: -case 0x6E60: -case 0x6E61: -case 0x6E62: -case 0x6E63: -case 0x6E64: -case 0x6E65: -case 0x6E66: -case 0x6E67: -case 0x6E68: -case 0x6E69: -case 0x6E6A: -case 0x6E6B: -case 0x6E6C: -case 0x6E6D: -case 0x6E6E: -case 0x6E6F: -case 0x6E70: -case 0x6E71: -case 0x6E72: -case 0x6E73: -case 0x6E74: -case 0x6E75: -case 0x6E76: -case 0x6E77: -case 0x6E78: -case 0x6E79: -case 0x6E7A: -case 0x6E7B: -case 0x6E7C: -case 0x6E7D: -case 0x6E7E: -case 0x6E7F: -case 0x6E80: -case 0x6E81: -case 0x6E82: -case 0x6E83: -case 0x6E84: -case 0x6E85: -case 0x6E86: -case 0x6E87: -case 0x6E88: -case 0x6E89: -case 0x6E8A: -case 0x6E8B: -case 0x6E8C: -case 0x6E8D: -case 0x6E8E: -case 0x6E8F: -case 0x6E90: -case 0x6E91: -case 0x6E92: -case 0x6E93: -case 0x6E94: -case 0x6E95: -case 0x6E96: -case 0x6E97: -case 0x6E98: -case 0x6E99: -case 0x6E9A: -case 0x6E9B: -case 0x6E9C: -case 0x6E9D: -case 0x6E9E: -case 0x6E9F: -case 0x6EA0: -case 0x6EA1: -case 0x6EA2: -case 0x6EA3: -case 0x6EA4: -case 0x6EA5: -case 0x6EA6: -case 0x6EA7: -case 0x6EA8: -case 0x6EA9: -case 0x6EAA: -case 0x6EAB: -case 0x6EAC: -case 0x6EAD: -case 0x6EAE: -case 0x6EAF: -case 0x6EB0: -case 0x6EB1: -case 0x6EB2: -case 0x6EB3: -case 0x6EB4: -case 0x6EB5: -case 0x6EB6: -case 0x6EB7: -case 0x6EB8: -case 0x6EB9: -case 0x6EBA: -case 0x6EBB: -case 0x6EBC: -case 0x6EBD: -case 0x6EBE: -case 0x6EBF: -case 0x6EC0: -case 0x6EC1: -case 0x6EC2: -case 0x6EC3: -case 0x6EC4: -case 0x6EC5: -case 0x6EC6: -case 0x6EC7: -case 0x6EC8: -case 0x6EC9: -case 0x6ECA: -case 0x6ECB: -case 0x6ECC: -case 0x6ECD: -case 0x6ECE: -case 0x6ECF: -case 0x6ED0: -case 0x6ED1: -case 0x6ED2: -case 0x6ED3: -case 0x6ED4: -case 0x6ED5: -case 0x6ED6: -case 0x6ED7: -case 0x6ED8: -case 0x6ED9: -case 0x6EDA: -case 0x6EDB: -case 0x6EDC: -case 0x6EDD: -case 0x6EDE: -case 0x6EDF: -case 0x6EE0: -case 0x6EE1: -case 0x6EE2: -case 0x6EE3: -case 0x6EE4: -case 0x6EE5: -case 0x6EE6: -case 0x6EE7: -case 0x6EE8: -case 0x6EE9: -case 0x6EEA: -case 0x6EEB: -case 0x6EEC: -case 0x6EED: -case 0x6EEE: -case 0x6EEF: -case 0x6EF0: -case 0x6EF1: -case 0x6EF2: -case 0x6EF3: -case 0x6EF4: -case 0x6EF5: -case 0x6EF6: -case 0x6EF7: -case 0x6EF8: -case 0x6EF9: -case 0x6EFA: -case 0x6EFB: -case 0x6EFC: -case 0x6EFD: -case 0x6EFE: -case 0x6EFF: - -// BCC -case 0x6E01: -{ - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6F02: -case 0x6F03: -case 0x6F04: -case 0x6F05: -case 0x6F06: -case 0x6F07: -case 0x6F08: -case 0x6F09: -case 0x6F0A: -case 0x6F0B: -case 0x6F0C: -case 0x6F0D: -case 0x6F0E: -case 0x6F0F: -case 0x6F10: -case 0x6F11: -case 0x6F12: -case 0x6F13: -case 0x6F14: -case 0x6F15: -case 0x6F16: -case 0x6F17: -case 0x6F18: -case 0x6F19: -case 0x6F1A: -case 0x6F1B: -case 0x6F1C: -case 0x6F1D: -case 0x6F1E: -case 0x6F1F: -case 0x6F20: -case 0x6F21: -case 0x6F22: -case 0x6F23: -case 0x6F24: -case 0x6F25: -case 0x6F26: -case 0x6F27: -case 0x6F28: -case 0x6F29: -case 0x6F2A: -case 0x6F2B: -case 0x6F2C: -case 0x6F2D: -case 0x6F2E: -case 0x6F2F: -case 0x6F30: -case 0x6F31: -case 0x6F32: -case 0x6F33: -case 0x6F34: -case 0x6F35: -case 0x6F36: -case 0x6F37: -case 0x6F38: -case 0x6F39: -case 0x6F3A: -case 0x6F3B: -case 0x6F3C: -case 0x6F3D: -case 0x6F3E: -case 0x6F3F: -case 0x6F40: -case 0x6F41: -case 0x6F42: -case 0x6F43: -case 0x6F44: -case 0x6F45: -case 0x6F46: -case 0x6F47: -case 0x6F48: -case 0x6F49: -case 0x6F4A: -case 0x6F4B: -case 0x6F4C: -case 0x6F4D: -case 0x6F4E: -case 0x6F4F: -case 0x6F50: -case 0x6F51: -case 0x6F52: -case 0x6F53: -case 0x6F54: -case 0x6F55: -case 0x6F56: -case 0x6F57: -case 0x6F58: -case 0x6F59: -case 0x6F5A: -case 0x6F5B: -case 0x6F5C: -case 0x6F5D: -case 0x6F5E: -case 0x6F5F: -case 0x6F60: -case 0x6F61: -case 0x6F62: -case 0x6F63: -case 0x6F64: -case 0x6F65: -case 0x6F66: -case 0x6F67: -case 0x6F68: -case 0x6F69: -case 0x6F6A: -case 0x6F6B: -case 0x6F6C: -case 0x6F6D: -case 0x6F6E: -case 0x6F6F: -case 0x6F70: -case 0x6F71: -case 0x6F72: -case 0x6F73: -case 0x6F74: -case 0x6F75: -case 0x6F76: -case 0x6F77: -case 0x6F78: -case 0x6F79: -case 0x6F7A: -case 0x6F7B: -case 0x6F7C: -case 0x6F7D: -case 0x6F7E: -case 0x6F7F: -case 0x6F80: -case 0x6F81: -case 0x6F82: -case 0x6F83: -case 0x6F84: -case 0x6F85: -case 0x6F86: -case 0x6F87: -case 0x6F88: -case 0x6F89: -case 0x6F8A: -case 0x6F8B: -case 0x6F8C: -case 0x6F8D: -case 0x6F8E: -case 0x6F8F: -case 0x6F90: -case 0x6F91: -case 0x6F92: -case 0x6F93: -case 0x6F94: -case 0x6F95: -case 0x6F96: -case 0x6F97: -case 0x6F98: -case 0x6F99: -case 0x6F9A: -case 0x6F9B: -case 0x6F9C: -case 0x6F9D: -case 0x6F9E: -case 0x6F9F: -case 0x6FA0: -case 0x6FA1: -case 0x6FA2: -case 0x6FA3: -case 0x6FA4: -case 0x6FA5: -case 0x6FA6: -case 0x6FA7: -case 0x6FA8: -case 0x6FA9: -case 0x6FAA: -case 0x6FAB: -case 0x6FAC: -case 0x6FAD: -case 0x6FAE: -case 0x6FAF: -case 0x6FB0: -case 0x6FB1: -case 0x6FB2: -case 0x6FB3: -case 0x6FB4: -case 0x6FB5: -case 0x6FB6: -case 0x6FB7: -case 0x6FB8: -case 0x6FB9: -case 0x6FBA: -case 0x6FBB: -case 0x6FBC: -case 0x6FBD: -case 0x6FBE: -case 0x6FBF: -case 0x6FC0: -case 0x6FC1: -case 0x6FC2: -case 0x6FC3: -case 0x6FC4: -case 0x6FC5: -case 0x6FC6: -case 0x6FC7: -case 0x6FC8: -case 0x6FC9: -case 0x6FCA: -case 0x6FCB: -case 0x6FCC: -case 0x6FCD: -case 0x6FCE: -case 0x6FCF: -case 0x6FD0: -case 0x6FD1: -case 0x6FD2: -case 0x6FD3: -case 0x6FD4: -case 0x6FD5: -case 0x6FD6: -case 0x6FD7: -case 0x6FD8: -case 0x6FD9: -case 0x6FDA: -case 0x6FDB: -case 0x6FDC: -case 0x6FDD: -case 0x6FDE: -case 0x6FDF: -case 0x6FE0: -case 0x6FE1: -case 0x6FE2: -case 0x6FE3: -case 0x6FE4: -case 0x6FE5: -case 0x6FE6: -case 0x6FE7: -case 0x6FE8: -case 0x6FE9: -case 0x6FEA: -case 0x6FEB: -case 0x6FEC: -case 0x6FED: -case 0x6FEE: -case 0x6FEF: -case 0x6FF0: -case 0x6FF1: -case 0x6FF2: -case 0x6FF3: -case 0x6FF4: -case 0x6FF5: -case 0x6FF6: -case 0x6FF7: -case 0x6FF8: -case 0x6FF9: -case 0x6FFA: -case 0x6FFB: -case 0x6FFC: -case 0x6FFD: -case 0x6FFE: -case 0x6FFF: - -// BCC -case 0x6F01: -{ - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) - -// BCC16 -case 0x6200: -{ - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6300: -{ - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6400: -{ - if (!(CPU->flag_C & 0x100)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6500: -{ - if (CPU->flag_C & 0x100) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6600: -{ - if (CPU->flag_notZ) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6700: -{ - if (!CPU->flag_notZ) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6800: -{ - if (!(CPU->flag_V & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6900: -{ - if (CPU->flag_V & 0x80) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6A00: -{ - if (!(CPU->flag_N & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6B00: -{ - if (CPU->flag_N & 0x80) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6C00: -{ - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6D00: -{ - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6E00: -{ - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6F00: -{ - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) -case 0x6002: -case 0x6003: -case 0x6004: -case 0x6005: -case 0x6006: -case 0x6007: -case 0x6008: -case 0x6009: -case 0x600A: -case 0x600B: -case 0x600C: -case 0x600D: -case 0x600E: -case 0x600F: -case 0x6010: -case 0x6011: -case 0x6012: -case 0x6013: -case 0x6014: -case 0x6015: -case 0x6016: -case 0x6017: -case 0x6018: -case 0x6019: -case 0x601A: -case 0x601B: -case 0x601C: -case 0x601D: -case 0x601E: -case 0x601F: -case 0x6020: -case 0x6021: -case 0x6022: -case 0x6023: -case 0x6024: -case 0x6025: -case 0x6026: -case 0x6027: -case 0x6028: -case 0x6029: -case 0x602A: -case 0x602B: -case 0x602C: -case 0x602D: -case 0x602E: -case 0x602F: -case 0x6030: -case 0x6031: -case 0x6032: -case 0x6033: -case 0x6034: -case 0x6035: -case 0x6036: -case 0x6037: -case 0x6038: -case 0x6039: -case 0x603A: -case 0x603B: -case 0x603C: -case 0x603D: -case 0x603E: -case 0x603F: -case 0x6040: -case 0x6041: -case 0x6042: -case 0x6043: -case 0x6044: -case 0x6045: -case 0x6046: -case 0x6047: -case 0x6048: -case 0x6049: -case 0x604A: -case 0x604B: -case 0x604C: -case 0x604D: -case 0x604E: -case 0x604F: -case 0x6050: -case 0x6051: -case 0x6052: -case 0x6053: -case 0x6054: -case 0x6055: -case 0x6056: -case 0x6057: -case 0x6058: -case 0x6059: -case 0x605A: -case 0x605B: -case 0x605C: -case 0x605D: -case 0x605E: -case 0x605F: -case 0x6060: -case 0x6061: -case 0x6062: -case 0x6063: -case 0x6064: -case 0x6065: -case 0x6066: -case 0x6067: -case 0x6068: -case 0x6069: -case 0x606A: -case 0x606B: -case 0x606C: -case 0x606D: -case 0x606E: -case 0x606F: -case 0x6070: -case 0x6071: -case 0x6072: -case 0x6073: -case 0x6074: -case 0x6075: -case 0x6076: -case 0x6077: -case 0x6078: -case 0x6079: -case 0x607A: -case 0x607B: -case 0x607C: -case 0x607D: -case 0x607E: -case 0x607F: -case 0x6080: -case 0x6081: -case 0x6082: -case 0x6083: -case 0x6084: -case 0x6085: -case 0x6086: -case 0x6087: -case 0x6088: -case 0x6089: -case 0x608A: -case 0x608B: -case 0x608C: -case 0x608D: -case 0x608E: -case 0x608F: -case 0x6090: -case 0x6091: -case 0x6092: -case 0x6093: -case 0x6094: -case 0x6095: -case 0x6096: -case 0x6097: -case 0x6098: -case 0x6099: -case 0x609A: -case 0x609B: -case 0x609C: -case 0x609D: -case 0x609E: -case 0x609F: -case 0x60A0: -case 0x60A1: -case 0x60A2: -case 0x60A3: -case 0x60A4: -case 0x60A5: -case 0x60A6: -case 0x60A7: -case 0x60A8: -case 0x60A9: -case 0x60AA: -case 0x60AB: -case 0x60AC: -case 0x60AD: -case 0x60AE: -case 0x60AF: -case 0x60B0: -case 0x60B1: -case 0x60B2: -case 0x60B3: -case 0x60B4: -case 0x60B5: -case 0x60B6: -case 0x60B7: -case 0x60B8: -case 0x60B9: -case 0x60BA: -case 0x60BB: -case 0x60BC: -case 0x60BD: -case 0x60BE: -case 0x60BF: -case 0x60C0: -case 0x60C1: -case 0x60C2: -case 0x60C3: -case 0x60C4: -case 0x60C5: -case 0x60C6: -case 0x60C7: -case 0x60C8: -case 0x60C9: -case 0x60CA: -case 0x60CB: -case 0x60CC: -case 0x60CD: -case 0x60CE: -case 0x60CF: -case 0x60D0: -case 0x60D1: -case 0x60D2: -case 0x60D3: -case 0x60D4: -case 0x60D5: -case 0x60D6: -case 0x60D7: -case 0x60D8: -case 0x60D9: -case 0x60DA: -case 0x60DB: -case 0x60DC: -case 0x60DD: -case 0x60DE: -case 0x60DF: -case 0x60E0: -case 0x60E1: -case 0x60E2: -case 0x60E3: -case 0x60E4: -case 0x60E5: -case 0x60E6: -case 0x60E7: -case 0x60E8: -case 0x60E9: -case 0x60EA: -case 0x60EB: -case 0x60EC: -case 0x60ED: -case 0x60EE: -case 0x60EF: -case 0x60F0: -case 0x60F1: -case 0x60F2: -case 0x60F3: -case 0x60F4: -case 0x60F5: -case 0x60F6: -case 0x60F7: -case 0x60F8: -case 0x60F9: -case 0x60FA: -case 0x60FB: -case 0x60FC: -case 0x60FD: -case 0x60FE: -case 0x60FF: - -// BRA -case 0x6001: -{ - PC += (s32)(s8)Opcode; -} -RET(10) - -// BRA16 -case 0x6000: -{ - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); -} -RET(10) -case 0x6102: -case 0x6103: -case 0x6104: -case 0x6105: -case 0x6106: -case 0x6107: -case 0x6108: -case 0x6109: -case 0x610A: -case 0x610B: -case 0x610C: -case 0x610D: -case 0x610E: -case 0x610F: -case 0x6110: -case 0x6111: -case 0x6112: -case 0x6113: -case 0x6114: -case 0x6115: -case 0x6116: -case 0x6117: -case 0x6118: -case 0x6119: -case 0x611A: -case 0x611B: -case 0x611C: -case 0x611D: -case 0x611E: -case 0x611F: -case 0x6120: -case 0x6121: -case 0x6122: -case 0x6123: -case 0x6124: -case 0x6125: -case 0x6126: -case 0x6127: -case 0x6128: -case 0x6129: -case 0x612A: -case 0x612B: -case 0x612C: -case 0x612D: -case 0x612E: -case 0x612F: -case 0x6130: -case 0x6131: -case 0x6132: -case 0x6133: -case 0x6134: -case 0x6135: -case 0x6136: -case 0x6137: -case 0x6138: -case 0x6139: -case 0x613A: -case 0x613B: -case 0x613C: -case 0x613D: -case 0x613E: -case 0x613F: -case 0x6140: -case 0x6141: -case 0x6142: -case 0x6143: -case 0x6144: -case 0x6145: -case 0x6146: -case 0x6147: -case 0x6148: -case 0x6149: -case 0x614A: -case 0x614B: -case 0x614C: -case 0x614D: -case 0x614E: -case 0x614F: -case 0x6150: -case 0x6151: -case 0x6152: -case 0x6153: -case 0x6154: -case 0x6155: -case 0x6156: -case 0x6157: -case 0x6158: -case 0x6159: -case 0x615A: -case 0x615B: -case 0x615C: -case 0x615D: -case 0x615E: -case 0x615F: -case 0x6160: -case 0x6161: -case 0x6162: -case 0x6163: -case 0x6164: -case 0x6165: -case 0x6166: -case 0x6167: -case 0x6168: -case 0x6169: -case 0x616A: -case 0x616B: -case 0x616C: -case 0x616D: -case 0x616E: -case 0x616F: -case 0x6170: -case 0x6171: -case 0x6172: -case 0x6173: -case 0x6174: -case 0x6175: -case 0x6176: -case 0x6177: -case 0x6178: -case 0x6179: -case 0x617A: -case 0x617B: -case 0x617C: -case 0x617D: -case 0x617E: -case 0x617F: -case 0x6180: -case 0x6181: -case 0x6182: -case 0x6183: -case 0x6184: -case 0x6185: -case 0x6186: -case 0x6187: -case 0x6188: -case 0x6189: -case 0x618A: -case 0x618B: -case 0x618C: -case 0x618D: -case 0x618E: -case 0x618F: -case 0x6190: -case 0x6191: -case 0x6192: -case 0x6193: -case 0x6194: -case 0x6195: -case 0x6196: -case 0x6197: -case 0x6198: -case 0x6199: -case 0x619A: -case 0x619B: -case 0x619C: -case 0x619D: -case 0x619E: -case 0x619F: -case 0x61A0: -case 0x61A1: -case 0x61A2: -case 0x61A3: -case 0x61A4: -case 0x61A5: -case 0x61A6: -case 0x61A7: -case 0x61A8: -case 0x61A9: -case 0x61AA: -case 0x61AB: -case 0x61AC: -case 0x61AD: -case 0x61AE: -case 0x61AF: -case 0x61B0: -case 0x61B1: -case 0x61B2: -case 0x61B3: -case 0x61B4: -case 0x61B5: -case 0x61B6: -case 0x61B7: -case 0x61B8: -case 0x61B9: -case 0x61BA: -case 0x61BB: -case 0x61BC: -case 0x61BD: -case 0x61BE: -case 0x61BF: -case 0x61C0: -case 0x61C1: -case 0x61C2: -case 0x61C3: -case 0x61C4: -case 0x61C5: -case 0x61C6: -case 0x61C7: -case 0x61C8: -case 0x61C9: -case 0x61CA: -case 0x61CB: -case 0x61CC: -case 0x61CD: -case 0x61CE: -case 0x61CF: -case 0x61D0: -case 0x61D1: -case 0x61D2: -case 0x61D3: -case 0x61D4: -case 0x61D5: -case 0x61D6: -case 0x61D7: -case 0x61D8: -case 0x61D9: -case 0x61DA: -case 0x61DB: -case 0x61DC: -case 0x61DD: -case 0x61DE: -case 0x61DF: -case 0x61E0: -case 0x61E1: -case 0x61E2: -case 0x61E3: -case 0x61E4: -case 0x61E5: -case 0x61E6: -case 0x61E7: -case 0x61E8: -case 0x61E9: -case 0x61EA: -case 0x61EB: -case 0x61EC: -case 0x61ED: -case 0x61EE: -case 0x61EF: -case 0x61F0: -case 0x61F1: -case 0x61F2: -case 0x61F3: -case 0x61F4: -case 0x61F5: -case 0x61F6: -case 0x61F7: -case 0x61F8: -case 0x61F9: -case 0x61FA: -case 0x61FB: -case 0x61FC: -case 0x61FD: -case 0x61FE: -case 0x61FF: - -// BSR -case 0x6101: -{ - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PC += (s32)(s8)Opcode; - POST_IO -} -RET(18) - -// BSR16 -case 0x6100: -{ - u32 res; - res = (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - PRE_IO - PUSH_32_F(PC + 2) - PC += (s32) res; - SET_PC(PC); - POST_IO -} -RET(18) diff --git a/yabause/src/c68k/c68k_op7.inc b/yabause/src/c68k/c68k_op7.inc deleted file mode 100644 index ba0b48ba31..0000000000 --- a/yabause/src/c68k/c68k_op7.inc +++ /dev/null @@ -1,2058 +0,0 @@ -case 0x7001: -case 0x7002: -case 0x7003: -case 0x7004: -case 0x7005: -case 0x7006: -case 0x7007: -case 0x7008: -case 0x7009: -case 0x700A: -case 0x700B: -case 0x700C: -case 0x700D: -case 0x700E: -case 0x700F: -case 0x7010: -case 0x7011: -case 0x7012: -case 0x7013: -case 0x7014: -case 0x7015: -case 0x7016: -case 0x7017: -case 0x7018: -case 0x7019: -case 0x701A: -case 0x701B: -case 0x701C: -case 0x701D: -case 0x701E: -case 0x701F: -case 0x7020: -case 0x7021: -case 0x7022: -case 0x7023: -case 0x7024: -case 0x7025: -case 0x7026: -case 0x7027: -case 0x7028: -case 0x7029: -case 0x702A: -case 0x702B: -case 0x702C: -case 0x702D: -case 0x702E: -case 0x702F: -case 0x7030: -case 0x7031: -case 0x7032: -case 0x7033: -case 0x7034: -case 0x7035: -case 0x7036: -case 0x7037: -case 0x7038: -case 0x7039: -case 0x703A: -case 0x703B: -case 0x703C: -case 0x703D: -case 0x703E: -case 0x703F: -case 0x7040: -case 0x7041: -case 0x7042: -case 0x7043: -case 0x7044: -case 0x7045: -case 0x7046: -case 0x7047: -case 0x7048: -case 0x7049: -case 0x704A: -case 0x704B: -case 0x704C: -case 0x704D: -case 0x704E: -case 0x704F: -case 0x7050: -case 0x7051: -case 0x7052: -case 0x7053: -case 0x7054: -case 0x7055: -case 0x7056: -case 0x7057: -case 0x7058: -case 0x7059: -case 0x705A: -case 0x705B: -case 0x705C: -case 0x705D: -case 0x705E: -case 0x705F: -case 0x7060: -case 0x7061: -case 0x7062: -case 0x7063: -case 0x7064: -case 0x7065: -case 0x7066: -case 0x7067: -case 0x7068: -case 0x7069: -case 0x706A: -case 0x706B: -case 0x706C: -case 0x706D: -case 0x706E: -case 0x706F: -case 0x7070: -case 0x7071: -case 0x7072: -case 0x7073: -case 0x7074: -case 0x7075: -case 0x7076: -case 0x7077: -case 0x7078: -case 0x7079: -case 0x707A: -case 0x707B: -case 0x707C: -case 0x707D: -case 0x707E: -case 0x707F: -case 0x7080: -case 0x7081: -case 0x7082: -case 0x7083: -case 0x7084: -case 0x7085: -case 0x7086: -case 0x7087: -case 0x7088: -case 0x7089: -case 0x708A: -case 0x708B: -case 0x708C: -case 0x708D: -case 0x708E: -case 0x708F: -case 0x7090: -case 0x7091: -case 0x7092: -case 0x7093: -case 0x7094: -case 0x7095: -case 0x7096: -case 0x7097: -case 0x7098: -case 0x7099: -case 0x709A: -case 0x709B: -case 0x709C: -case 0x709D: -case 0x709E: -case 0x709F: -case 0x70A0: -case 0x70A1: -case 0x70A2: -case 0x70A3: -case 0x70A4: -case 0x70A5: -case 0x70A6: -case 0x70A7: -case 0x70A8: -case 0x70A9: -case 0x70AA: -case 0x70AB: -case 0x70AC: -case 0x70AD: -case 0x70AE: -case 0x70AF: -case 0x70B0: -case 0x70B1: -case 0x70B2: -case 0x70B3: -case 0x70B4: -case 0x70B5: -case 0x70B6: -case 0x70B7: -case 0x70B8: -case 0x70B9: -case 0x70BA: -case 0x70BB: -case 0x70BC: -case 0x70BD: -case 0x70BE: -case 0x70BF: -case 0x70C0: -case 0x70C1: -case 0x70C2: -case 0x70C3: -case 0x70C4: -case 0x70C5: -case 0x70C6: -case 0x70C7: -case 0x70C8: -case 0x70C9: -case 0x70CA: -case 0x70CB: -case 0x70CC: -case 0x70CD: -case 0x70CE: -case 0x70CF: -case 0x70D0: -case 0x70D1: -case 0x70D2: -case 0x70D3: -case 0x70D4: -case 0x70D5: -case 0x70D6: -case 0x70D7: -case 0x70D8: -case 0x70D9: -case 0x70DA: -case 0x70DB: -case 0x70DC: -case 0x70DD: -case 0x70DE: -case 0x70DF: -case 0x70E0: -case 0x70E1: -case 0x70E2: -case 0x70E3: -case 0x70E4: -case 0x70E5: -case 0x70E6: -case 0x70E7: -case 0x70E8: -case 0x70E9: -case 0x70EA: -case 0x70EB: -case 0x70EC: -case 0x70ED: -case 0x70EE: -case 0x70EF: -case 0x70F0: -case 0x70F1: -case 0x70F2: -case 0x70F3: -case 0x70F4: -case 0x70F5: -case 0x70F6: -case 0x70F7: -case 0x70F8: -case 0x70F9: -case 0x70FA: -case 0x70FB: -case 0x70FC: -case 0x70FD: -case 0x70FE: -case 0x70FF: -case 0x7200: -case 0x7201: -case 0x7202: -case 0x7203: -case 0x7204: -case 0x7205: -case 0x7206: -case 0x7207: -case 0x7208: -case 0x7209: -case 0x720A: -case 0x720B: -case 0x720C: -case 0x720D: -case 0x720E: -case 0x720F: -case 0x7210: -case 0x7211: -case 0x7212: -case 0x7213: -case 0x7214: -case 0x7215: -case 0x7216: -case 0x7217: -case 0x7218: -case 0x7219: -case 0x721A: -case 0x721B: -case 0x721C: -case 0x721D: -case 0x721E: -case 0x721F: -case 0x7220: -case 0x7221: -case 0x7222: -case 0x7223: -case 0x7224: -case 0x7225: -case 0x7226: -case 0x7227: -case 0x7228: -case 0x7229: -case 0x722A: -case 0x722B: -case 0x722C: -case 0x722D: -case 0x722E: -case 0x722F: -case 0x7230: -case 0x7231: -case 0x7232: -case 0x7233: -case 0x7234: -case 0x7235: -case 0x7236: -case 0x7237: -case 0x7238: -case 0x7239: -case 0x723A: -case 0x723B: -case 0x723C: -case 0x723D: -case 0x723E: -case 0x723F: -case 0x7240: -case 0x7241: -case 0x7242: -case 0x7243: -case 0x7244: -case 0x7245: -case 0x7246: -case 0x7247: -case 0x7248: -case 0x7249: -case 0x724A: -case 0x724B: -case 0x724C: -case 0x724D: -case 0x724E: -case 0x724F: -case 0x7250: -case 0x7251: -case 0x7252: -case 0x7253: -case 0x7254: -case 0x7255: -case 0x7256: -case 0x7257: -case 0x7258: -case 0x7259: -case 0x725A: -case 0x725B: -case 0x725C: -case 0x725D: -case 0x725E: -case 0x725F: -case 0x7260: -case 0x7261: -case 0x7262: -case 0x7263: -case 0x7264: -case 0x7265: -case 0x7266: -case 0x7267: -case 0x7268: -case 0x7269: -case 0x726A: -case 0x726B: -case 0x726C: -case 0x726D: -case 0x726E: -case 0x726F: -case 0x7270: -case 0x7271: -case 0x7272: -case 0x7273: -case 0x7274: -case 0x7275: -case 0x7276: -case 0x7277: -case 0x7278: -case 0x7279: -case 0x727A: -case 0x727B: -case 0x727C: -case 0x727D: -case 0x727E: -case 0x727F: -case 0x7280: -case 0x7281: -case 0x7282: -case 0x7283: -case 0x7284: -case 0x7285: -case 0x7286: -case 0x7287: -case 0x7288: -case 0x7289: -case 0x728A: -case 0x728B: -case 0x728C: -case 0x728D: -case 0x728E: -case 0x728F: -case 0x7290: -case 0x7291: -case 0x7292: -case 0x7293: -case 0x7294: -case 0x7295: -case 0x7296: -case 0x7297: -case 0x7298: -case 0x7299: -case 0x729A: -case 0x729B: -case 0x729C: -case 0x729D: -case 0x729E: -case 0x729F: -case 0x72A0: -case 0x72A1: -case 0x72A2: -case 0x72A3: -case 0x72A4: -case 0x72A5: -case 0x72A6: -case 0x72A7: -case 0x72A8: -case 0x72A9: -case 0x72AA: -case 0x72AB: -case 0x72AC: -case 0x72AD: -case 0x72AE: -case 0x72AF: -case 0x72B0: -case 0x72B1: -case 0x72B2: -case 0x72B3: -case 0x72B4: -case 0x72B5: -case 0x72B6: -case 0x72B7: -case 0x72B8: -case 0x72B9: -case 0x72BA: -case 0x72BB: -case 0x72BC: -case 0x72BD: -case 0x72BE: -case 0x72BF: -case 0x72C0: -case 0x72C1: -case 0x72C2: -case 0x72C3: -case 0x72C4: -case 0x72C5: -case 0x72C6: -case 0x72C7: -case 0x72C8: -case 0x72C9: -case 0x72CA: -case 0x72CB: -case 0x72CC: -case 0x72CD: -case 0x72CE: -case 0x72CF: -case 0x72D0: -case 0x72D1: -case 0x72D2: -case 0x72D3: -case 0x72D4: -case 0x72D5: -case 0x72D6: -case 0x72D7: -case 0x72D8: -case 0x72D9: -case 0x72DA: -case 0x72DB: -case 0x72DC: -case 0x72DD: -case 0x72DE: -case 0x72DF: -case 0x72E0: -case 0x72E1: -case 0x72E2: -case 0x72E3: -case 0x72E4: -case 0x72E5: -case 0x72E6: -case 0x72E7: -case 0x72E8: -case 0x72E9: -case 0x72EA: -case 0x72EB: -case 0x72EC: -case 0x72ED: -case 0x72EE: -case 0x72EF: -case 0x72F0: -case 0x72F1: -case 0x72F2: -case 0x72F3: -case 0x72F4: -case 0x72F5: -case 0x72F6: -case 0x72F7: -case 0x72F8: -case 0x72F9: -case 0x72FA: -case 0x72FB: -case 0x72FC: -case 0x72FD: -case 0x72FE: -case 0x72FF: -case 0x7400: -case 0x7401: -case 0x7402: -case 0x7403: -case 0x7404: -case 0x7405: -case 0x7406: -case 0x7407: -case 0x7408: -case 0x7409: -case 0x740A: -case 0x740B: -case 0x740C: -case 0x740D: -case 0x740E: -case 0x740F: -case 0x7410: -case 0x7411: -case 0x7412: -case 0x7413: -case 0x7414: -case 0x7415: -case 0x7416: -case 0x7417: -case 0x7418: -case 0x7419: -case 0x741A: -case 0x741B: -case 0x741C: -case 0x741D: -case 0x741E: -case 0x741F: -case 0x7420: -case 0x7421: -case 0x7422: -case 0x7423: -case 0x7424: -case 0x7425: -case 0x7426: -case 0x7427: -case 0x7428: -case 0x7429: -case 0x742A: -case 0x742B: -case 0x742C: -case 0x742D: -case 0x742E: -case 0x742F: -case 0x7430: -case 0x7431: -case 0x7432: -case 0x7433: -case 0x7434: -case 0x7435: -case 0x7436: -case 0x7437: -case 0x7438: -case 0x7439: -case 0x743A: -case 0x743B: -case 0x743C: -case 0x743D: -case 0x743E: -case 0x743F: -case 0x7440: -case 0x7441: -case 0x7442: -case 0x7443: -case 0x7444: -case 0x7445: -case 0x7446: -case 0x7447: -case 0x7448: -case 0x7449: -case 0x744A: -case 0x744B: -case 0x744C: -case 0x744D: -case 0x744E: -case 0x744F: -case 0x7450: -case 0x7451: -case 0x7452: -case 0x7453: -case 0x7454: -case 0x7455: -case 0x7456: -case 0x7457: -case 0x7458: -case 0x7459: -case 0x745A: -case 0x745B: -case 0x745C: -case 0x745D: -case 0x745E: -case 0x745F: -case 0x7460: -case 0x7461: -case 0x7462: -case 0x7463: -case 0x7464: -case 0x7465: -case 0x7466: -case 0x7467: -case 0x7468: -case 0x7469: -case 0x746A: -case 0x746B: -case 0x746C: -case 0x746D: -case 0x746E: -case 0x746F: -case 0x7470: -case 0x7471: -case 0x7472: -case 0x7473: -case 0x7474: -case 0x7475: -case 0x7476: -case 0x7477: -case 0x7478: -case 0x7479: -case 0x747A: -case 0x747B: -case 0x747C: -case 0x747D: -case 0x747E: -case 0x747F: -case 0x7480: -case 0x7481: -case 0x7482: -case 0x7483: -case 0x7484: -case 0x7485: -case 0x7486: -case 0x7487: -case 0x7488: -case 0x7489: -case 0x748A: -case 0x748B: -case 0x748C: -case 0x748D: -case 0x748E: -case 0x748F: -case 0x7490: -case 0x7491: -case 0x7492: -case 0x7493: -case 0x7494: -case 0x7495: -case 0x7496: -case 0x7497: -case 0x7498: -case 0x7499: -case 0x749A: -case 0x749B: -case 0x749C: -case 0x749D: -case 0x749E: -case 0x749F: -case 0x74A0: -case 0x74A1: -case 0x74A2: -case 0x74A3: -case 0x74A4: -case 0x74A5: -case 0x74A6: -case 0x74A7: -case 0x74A8: -case 0x74A9: -case 0x74AA: -case 0x74AB: -case 0x74AC: -case 0x74AD: -case 0x74AE: -case 0x74AF: -case 0x74B0: -case 0x74B1: -case 0x74B2: -case 0x74B3: -case 0x74B4: -case 0x74B5: -case 0x74B6: -case 0x74B7: -case 0x74B8: -case 0x74B9: -case 0x74BA: -case 0x74BB: -case 0x74BC: -case 0x74BD: -case 0x74BE: -case 0x74BF: -case 0x74C0: -case 0x74C1: -case 0x74C2: -case 0x74C3: -case 0x74C4: -case 0x74C5: -case 0x74C6: -case 0x74C7: -case 0x74C8: -case 0x74C9: -case 0x74CA: -case 0x74CB: -case 0x74CC: -case 0x74CD: -case 0x74CE: -case 0x74CF: -case 0x74D0: -case 0x74D1: -case 0x74D2: -case 0x74D3: -case 0x74D4: -case 0x74D5: -case 0x74D6: -case 0x74D7: -case 0x74D8: -case 0x74D9: -case 0x74DA: -case 0x74DB: -case 0x74DC: -case 0x74DD: -case 0x74DE: -case 0x74DF: -case 0x74E0: -case 0x74E1: -case 0x74E2: -case 0x74E3: -case 0x74E4: -case 0x74E5: -case 0x74E6: -case 0x74E7: -case 0x74E8: -case 0x74E9: -case 0x74EA: -case 0x74EB: -case 0x74EC: -case 0x74ED: -case 0x74EE: -case 0x74EF: -case 0x74F0: -case 0x74F1: -case 0x74F2: -case 0x74F3: -case 0x74F4: -case 0x74F5: -case 0x74F6: -case 0x74F7: -case 0x74F8: -case 0x74F9: -case 0x74FA: -case 0x74FB: -case 0x74FC: -case 0x74FD: -case 0x74FE: -case 0x74FF: -case 0x7600: -case 0x7601: -case 0x7602: -case 0x7603: -case 0x7604: -case 0x7605: -case 0x7606: -case 0x7607: -case 0x7608: -case 0x7609: -case 0x760A: -case 0x760B: -case 0x760C: -case 0x760D: -case 0x760E: -case 0x760F: -case 0x7610: -case 0x7611: -case 0x7612: -case 0x7613: -case 0x7614: -case 0x7615: -case 0x7616: -case 0x7617: -case 0x7618: -case 0x7619: -case 0x761A: -case 0x761B: -case 0x761C: -case 0x761D: -case 0x761E: -case 0x761F: -case 0x7620: -case 0x7621: -case 0x7622: -case 0x7623: -case 0x7624: -case 0x7625: -case 0x7626: -case 0x7627: -case 0x7628: -case 0x7629: -case 0x762A: -case 0x762B: -case 0x762C: -case 0x762D: -case 0x762E: -case 0x762F: -case 0x7630: -case 0x7631: -case 0x7632: -case 0x7633: -case 0x7634: -case 0x7635: -case 0x7636: -case 0x7637: -case 0x7638: -case 0x7639: -case 0x763A: -case 0x763B: -case 0x763C: -case 0x763D: -case 0x763E: -case 0x763F: -case 0x7640: -case 0x7641: -case 0x7642: -case 0x7643: -case 0x7644: -case 0x7645: -case 0x7646: -case 0x7647: -case 0x7648: -case 0x7649: -case 0x764A: -case 0x764B: -case 0x764C: -case 0x764D: -case 0x764E: -case 0x764F: -case 0x7650: -case 0x7651: -case 0x7652: -case 0x7653: -case 0x7654: -case 0x7655: -case 0x7656: -case 0x7657: -case 0x7658: -case 0x7659: -case 0x765A: -case 0x765B: -case 0x765C: -case 0x765D: -case 0x765E: -case 0x765F: -case 0x7660: -case 0x7661: -case 0x7662: -case 0x7663: -case 0x7664: -case 0x7665: -case 0x7666: -case 0x7667: -case 0x7668: -case 0x7669: -case 0x766A: -case 0x766B: -case 0x766C: -case 0x766D: -case 0x766E: -case 0x766F: -case 0x7670: -case 0x7671: -case 0x7672: -case 0x7673: -case 0x7674: -case 0x7675: -case 0x7676: -case 0x7677: -case 0x7678: -case 0x7679: -case 0x767A: -case 0x767B: -case 0x767C: -case 0x767D: -case 0x767E: -case 0x767F: -case 0x7680: -case 0x7681: -case 0x7682: -case 0x7683: -case 0x7684: -case 0x7685: -case 0x7686: -case 0x7687: -case 0x7688: -case 0x7689: -case 0x768A: -case 0x768B: -case 0x768C: -case 0x768D: -case 0x768E: -case 0x768F: -case 0x7690: -case 0x7691: -case 0x7692: -case 0x7693: -case 0x7694: -case 0x7695: -case 0x7696: -case 0x7697: -case 0x7698: -case 0x7699: -case 0x769A: -case 0x769B: -case 0x769C: -case 0x769D: -case 0x769E: -case 0x769F: -case 0x76A0: -case 0x76A1: -case 0x76A2: -case 0x76A3: -case 0x76A4: -case 0x76A5: -case 0x76A6: -case 0x76A7: -case 0x76A8: -case 0x76A9: -case 0x76AA: -case 0x76AB: -case 0x76AC: -case 0x76AD: -case 0x76AE: -case 0x76AF: -case 0x76B0: -case 0x76B1: -case 0x76B2: -case 0x76B3: -case 0x76B4: -case 0x76B5: -case 0x76B6: -case 0x76B7: -case 0x76B8: -case 0x76B9: -case 0x76BA: -case 0x76BB: -case 0x76BC: -case 0x76BD: -case 0x76BE: -case 0x76BF: -case 0x76C0: -case 0x76C1: -case 0x76C2: -case 0x76C3: -case 0x76C4: -case 0x76C5: -case 0x76C6: -case 0x76C7: -case 0x76C8: -case 0x76C9: -case 0x76CA: -case 0x76CB: -case 0x76CC: -case 0x76CD: -case 0x76CE: -case 0x76CF: -case 0x76D0: -case 0x76D1: -case 0x76D2: -case 0x76D3: -case 0x76D4: -case 0x76D5: -case 0x76D6: -case 0x76D7: -case 0x76D8: -case 0x76D9: -case 0x76DA: -case 0x76DB: -case 0x76DC: -case 0x76DD: -case 0x76DE: -case 0x76DF: -case 0x76E0: -case 0x76E1: -case 0x76E2: -case 0x76E3: -case 0x76E4: -case 0x76E5: -case 0x76E6: -case 0x76E7: -case 0x76E8: -case 0x76E9: -case 0x76EA: -case 0x76EB: -case 0x76EC: -case 0x76ED: -case 0x76EE: -case 0x76EF: -case 0x76F0: -case 0x76F1: -case 0x76F2: -case 0x76F3: -case 0x76F4: -case 0x76F5: -case 0x76F6: -case 0x76F7: -case 0x76F8: -case 0x76F9: -case 0x76FA: -case 0x76FB: -case 0x76FC: -case 0x76FD: -case 0x76FE: -case 0x76FF: -case 0x7800: -case 0x7801: -case 0x7802: -case 0x7803: -case 0x7804: -case 0x7805: -case 0x7806: -case 0x7807: -case 0x7808: -case 0x7809: -case 0x780A: -case 0x780B: -case 0x780C: -case 0x780D: -case 0x780E: -case 0x780F: -case 0x7810: -case 0x7811: -case 0x7812: -case 0x7813: -case 0x7814: -case 0x7815: -case 0x7816: -case 0x7817: -case 0x7818: -case 0x7819: -case 0x781A: -case 0x781B: -case 0x781C: -case 0x781D: -case 0x781E: -case 0x781F: -case 0x7820: -case 0x7821: -case 0x7822: -case 0x7823: -case 0x7824: -case 0x7825: -case 0x7826: -case 0x7827: -case 0x7828: -case 0x7829: -case 0x782A: -case 0x782B: -case 0x782C: -case 0x782D: -case 0x782E: -case 0x782F: -case 0x7830: -case 0x7831: -case 0x7832: -case 0x7833: -case 0x7834: -case 0x7835: -case 0x7836: -case 0x7837: -case 0x7838: -case 0x7839: -case 0x783A: -case 0x783B: -case 0x783C: -case 0x783D: -case 0x783E: -case 0x783F: -case 0x7840: -case 0x7841: -case 0x7842: -case 0x7843: -case 0x7844: -case 0x7845: -case 0x7846: -case 0x7847: -case 0x7848: -case 0x7849: -case 0x784A: -case 0x784B: -case 0x784C: -case 0x784D: -case 0x784E: -case 0x784F: -case 0x7850: -case 0x7851: -case 0x7852: -case 0x7853: -case 0x7854: -case 0x7855: -case 0x7856: -case 0x7857: -case 0x7858: -case 0x7859: -case 0x785A: -case 0x785B: -case 0x785C: -case 0x785D: -case 0x785E: -case 0x785F: -case 0x7860: -case 0x7861: -case 0x7862: -case 0x7863: -case 0x7864: -case 0x7865: -case 0x7866: -case 0x7867: -case 0x7868: -case 0x7869: -case 0x786A: -case 0x786B: -case 0x786C: -case 0x786D: -case 0x786E: -case 0x786F: -case 0x7870: -case 0x7871: -case 0x7872: -case 0x7873: -case 0x7874: -case 0x7875: -case 0x7876: -case 0x7877: -case 0x7878: -case 0x7879: -case 0x787A: -case 0x787B: -case 0x787C: -case 0x787D: -case 0x787E: -case 0x787F: -case 0x7880: -case 0x7881: -case 0x7882: -case 0x7883: -case 0x7884: -case 0x7885: -case 0x7886: -case 0x7887: -case 0x7888: -case 0x7889: -case 0x788A: -case 0x788B: -case 0x788C: -case 0x788D: -case 0x788E: -case 0x788F: -case 0x7890: -case 0x7891: -case 0x7892: -case 0x7893: -case 0x7894: -case 0x7895: -case 0x7896: -case 0x7897: -case 0x7898: -case 0x7899: -case 0x789A: -case 0x789B: -case 0x789C: -case 0x789D: -case 0x789E: -case 0x789F: -case 0x78A0: -case 0x78A1: -case 0x78A2: -case 0x78A3: -case 0x78A4: -case 0x78A5: -case 0x78A6: -case 0x78A7: -case 0x78A8: -case 0x78A9: -case 0x78AA: -case 0x78AB: -case 0x78AC: -case 0x78AD: -case 0x78AE: -case 0x78AF: -case 0x78B0: -case 0x78B1: -case 0x78B2: -case 0x78B3: -case 0x78B4: -case 0x78B5: -case 0x78B6: -case 0x78B7: -case 0x78B8: -case 0x78B9: -case 0x78BA: -case 0x78BB: -case 0x78BC: -case 0x78BD: -case 0x78BE: -case 0x78BF: -case 0x78C0: -case 0x78C1: -case 0x78C2: -case 0x78C3: -case 0x78C4: -case 0x78C5: -case 0x78C6: -case 0x78C7: -case 0x78C8: -case 0x78C9: -case 0x78CA: -case 0x78CB: -case 0x78CC: -case 0x78CD: -case 0x78CE: -case 0x78CF: -case 0x78D0: -case 0x78D1: -case 0x78D2: -case 0x78D3: -case 0x78D4: -case 0x78D5: -case 0x78D6: -case 0x78D7: -case 0x78D8: -case 0x78D9: -case 0x78DA: -case 0x78DB: -case 0x78DC: -case 0x78DD: -case 0x78DE: -case 0x78DF: -case 0x78E0: -case 0x78E1: -case 0x78E2: -case 0x78E3: -case 0x78E4: -case 0x78E5: -case 0x78E6: -case 0x78E7: -case 0x78E8: -case 0x78E9: -case 0x78EA: -case 0x78EB: -case 0x78EC: -case 0x78ED: -case 0x78EE: -case 0x78EF: -case 0x78F0: -case 0x78F1: -case 0x78F2: -case 0x78F3: -case 0x78F4: -case 0x78F5: -case 0x78F6: -case 0x78F7: -case 0x78F8: -case 0x78F9: -case 0x78FA: -case 0x78FB: -case 0x78FC: -case 0x78FD: -case 0x78FE: -case 0x78FF: -case 0x7A00: -case 0x7A01: -case 0x7A02: -case 0x7A03: -case 0x7A04: -case 0x7A05: -case 0x7A06: -case 0x7A07: -case 0x7A08: -case 0x7A09: -case 0x7A0A: -case 0x7A0B: -case 0x7A0C: -case 0x7A0D: -case 0x7A0E: -case 0x7A0F: -case 0x7A10: -case 0x7A11: -case 0x7A12: -case 0x7A13: -case 0x7A14: -case 0x7A15: -case 0x7A16: -case 0x7A17: -case 0x7A18: -case 0x7A19: -case 0x7A1A: -case 0x7A1B: -case 0x7A1C: -case 0x7A1D: -case 0x7A1E: -case 0x7A1F: -case 0x7A20: -case 0x7A21: -case 0x7A22: -case 0x7A23: -case 0x7A24: -case 0x7A25: -case 0x7A26: -case 0x7A27: -case 0x7A28: -case 0x7A29: -case 0x7A2A: -case 0x7A2B: -case 0x7A2C: -case 0x7A2D: -case 0x7A2E: -case 0x7A2F: -case 0x7A30: -case 0x7A31: -case 0x7A32: -case 0x7A33: -case 0x7A34: -case 0x7A35: -case 0x7A36: -case 0x7A37: -case 0x7A38: -case 0x7A39: -case 0x7A3A: -case 0x7A3B: -case 0x7A3C: -case 0x7A3D: -case 0x7A3E: -case 0x7A3F: -case 0x7A40: -case 0x7A41: -case 0x7A42: -case 0x7A43: -case 0x7A44: -case 0x7A45: -case 0x7A46: -case 0x7A47: -case 0x7A48: -case 0x7A49: -case 0x7A4A: -case 0x7A4B: -case 0x7A4C: -case 0x7A4D: -case 0x7A4E: -case 0x7A4F: -case 0x7A50: -case 0x7A51: -case 0x7A52: -case 0x7A53: -case 0x7A54: -case 0x7A55: -case 0x7A56: -case 0x7A57: -case 0x7A58: -case 0x7A59: -case 0x7A5A: -case 0x7A5B: -case 0x7A5C: -case 0x7A5D: -case 0x7A5E: -case 0x7A5F: -case 0x7A60: -case 0x7A61: -case 0x7A62: -case 0x7A63: -case 0x7A64: -case 0x7A65: -case 0x7A66: -case 0x7A67: -case 0x7A68: -case 0x7A69: -case 0x7A6A: -case 0x7A6B: -case 0x7A6C: -case 0x7A6D: -case 0x7A6E: -case 0x7A6F: -case 0x7A70: -case 0x7A71: -case 0x7A72: -case 0x7A73: -case 0x7A74: -case 0x7A75: -case 0x7A76: -case 0x7A77: -case 0x7A78: -case 0x7A79: -case 0x7A7A: -case 0x7A7B: -case 0x7A7C: -case 0x7A7D: -case 0x7A7E: -case 0x7A7F: -case 0x7A80: -case 0x7A81: -case 0x7A82: -case 0x7A83: -case 0x7A84: -case 0x7A85: -case 0x7A86: -case 0x7A87: -case 0x7A88: -case 0x7A89: -case 0x7A8A: -case 0x7A8B: -case 0x7A8C: -case 0x7A8D: -case 0x7A8E: -case 0x7A8F: -case 0x7A90: -case 0x7A91: -case 0x7A92: -case 0x7A93: -case 0x7A94: -case 0x7A95: -case 0x7A96: -case 0x7A97: -case 0x7A98: -case 0x7A99: -case 0x7A9A: -case 0x7A9B: -case 0x7A9C: -case 0x7A9D: -case 0x7A9E: -case 0x7A9F: -case 0x7AA0: -case 0x7AA1: -case 0x7AA2: -case 0x7AA3: -case 0x7AA4: -case 0x7AA5: -case 0x7AA6: -case 0x7AA7: -case 0x7AA8: -case 0x7AA9: -case 0x7AAA: -case 0x7AAB: -case 0x7AAC: -case 0x7AAD: -case 0x7AAE: -case 0x7AAF: -case 0x7AB0: -case 0x7AB1: -case 0x7AB2: -case 0x7AB3: -case 0x7AB4: -case 0x7AB5: -case 0x7AB6: -case 0x7AB7: -case 0x7AB8: -case 0x7AB9: -case 0x7ABA: -case 0x7ABB: -case 0x7ABC: -case 0x7ABD: -case 0x7ABE: -case 0x7ABF: -case 0x7AC0: -case 0x7AC1: -case 0x7AC2: -case 0x7AC3: -case 0x7AC4: -case 0x7AC5: -case 0x7AC6: -case 0x7AC7: -case 0x7AC8: -case 0x7AC9: -case 0x7ACA: -case 0x7ACB: -case 0x7ACC: -case 0x7ACD: -case 0x7ACE: -case 0x7ACF: -case 0x7AD0: -case 0x7AD1: -case 0x7AD2: -case 0x7AD3: -case 0x7AD4: -case 0x7AD5: -case 0x7AD6: -case 0x7AD7: -case 0x7AD8: -case 0x7AD9: -case 0x7ADA: -case 0x7ADB: -case 0x7ADC: -case 0x7ADD: -case 0x7ADE: -case 0x7ADF: -case 0x7AE0: -case 0x7AE1: -case 0x7AE2: -case 0x7AE3: -case 0x7AE4: -case 0x7AE5: -case 0x7AE6: -case 0x7AE7: -case 0x7AE8: -case 0x7AE9: -case 0x7AEA: -case 0x7AEB: -case 0x7AEC: -case 0x7AED: -case 0x7AEE: -case 0x7AEF: -case 0x7AF0: -case 0x7AF1: -case 0x7AF2: -case 0x7AF3: -case 0x7AF4: -case 0x7AF5: -case 0x7AF6: -case 0x7AF7: -case 0x7AF8: -case 0x7AF9: -case 0x7AFA: -case 0x7AFB: -case 0x7AFC: -case 0x7AFD: -case 0x7AFE: -case 0x7AFF: -case 0x7C00: -case 0x7C01: -case 0x7C02: -case 0x7C03: -case 0x7C04: -case 0x7C05: -case 0x7C06: -case 0x7C07: -case 0x7C08: -case 0x7C09: -case 0x7C0A: -case 0x7C0B: -case 0x7C0C: -case 0x7C0D: -case 0x7C0E: -case 0x7C0F: -case 0x7C10: -case 0x7C11: -case 0x7C12: -case 0x7C13: -case 0x7C14: -case 0x7C15: -case 0x7C16: -case 0x7C17: -case 0x7C18: -case 0x7C19: -case 0x7C1A: -case 0x7C1B: -case 0x7C1C: -case 0x7C1D: -case 0x7C1E: -case 0x7C1F: -case 0x7C20: -case 0x7C21: -case 0x7C22: -case 0x7C23: -case 0x7C24: -case 0x7C25: -case 0x7C26: -case 0x7C27: -case 0x7C28: -case 0x7C29: -case 0x7C2A: -case 0x7C2B: -case 0x7C2C: -case 0x7C2D: -case 0x7C2E: -case 0x7C2F: -case 0x7C30: -case 0x7C31: -case 0x7C32: -case 0x7C33: -case 0x7C34: -case 0x7C35: -case 0x7C36: -case 0x7C37: -case 0x7C38: -case 0x7C39: -case 0x7C3A: -case 0x7C3B: -case 0x7C3C: -case 0x7C3D: -case 0x7C3E: -case 0x7C3F: -case 0x7C40: -case 0x7C41: -case 0x7C42: -case 0x7C43: -case 0x7C44: -case 0x7C45: -case 0x7C46: -case 0x7C47: -case 0x7C48: -case 0x7C49: -case 0x7C4A: -case 0x7C4B: -case 0x7C4C: -case 0x7C4D: -case 0x7C4E: -case 0x7C4F: -case 0x7C50: -case 0x7C51: -case 0x7C52: -case 0x7C53: -case 0x7C54: -case 0x7C55: -case 0x7C56: -case 0x7C57: -case 0x7C58: -case 0x7C59: -case 0x7C5A: -case 0x7C5B: -case 0x7C5C: -case 0x7C5D: -case 0x7C5E: -case 0x7C5F: -case 0x7C60: -case 0x7C61: -case 0x7C62: -case 0x7C63: -case 0x7C64: -case 0x7C65: -case 0x7C66: -case 0x7C67: -case 0x7C68: -case 0x7C69: -case 0x7C6A: -case 0x7C6B: -case 0x7C6C: -case 0x7C6D: -case 0x7C6E: -case 0x7C6F: -case 0x7C70: -case 0x7C71: -case 0x7C72: -case 0x7C73: -case 0x7C74: -case 0x7C75: -case 0x7C76: -case 0x7C77: -case 0x7C78: -case 0x7C79: -case 0x7C7A: -case 0x7C7B: -case 0x7C7C: -case 0x7C7D: -case 0x7C7E: -case 0x7C7F: -case 0x7C80: -case 0x7C81: -case 0x7C82: -case 0x7C83: -case 0x7C84: -case 0x7C85: -case 0x7C86: -case 0x7C87: -case 0x7C88: -case 0x7C89: -case 0x7C8A: -case 0x7C8B: -case 0x7C8C: -case 0x7C8D: -case 0x7C8E: -case 0x7C8F: -case 0x7C90: -case 0x7C91: -case 0x7C92: -case 0x7C93: -case 0x7C94: -case 0x7C95: -case 0x7C96: -case 0x7C97: -case 0x7C98: -case 0x7C99: -case 0x7C9A: -case 0x7C9B: -case 0x7C9C: -case 0x7C9D: -case 0x7C9E: -case 0x7C9F: -case 0x7CA0: -case 0x7CA1: -case 0x7CA2: -case 0x7CA3: -case 0x7CA4: -case 0x7CA5: -case 0x7CA6: -case 0x7CA7: -case 0x7CA8: -case 0x7CA9: -case 0x7CAA: -case 0x7CAB: -case 0x7CAC: -case 0x7CAD: -case 0x7CAE: -case 0x7CAF: -case 0x7CB0: -case 0x7CB1: -case 0x7CB2: -case 0x7CB3: -case 0x7CB4: -case 0x7CB5: -case 0x7CB6: -case 0x7CB7: -case 0x7CB8: -case 0x7CB9: -case 0x7CBA: -case 0x7CBB: -case 0x7CBC: -case 0x7CBD: -case 0x7CBE: -case 0x7CBF: -case 0x7CC0: -case 0x7CC1: -case 0x7CC2: -case 0x7CC3: -case 0x7CC4: -case 0x7CC5: -case 0x7CC6: -case 0x7CC7: -case 0x7CC8: -case 0x7CC9: -case 0x7CCA: -case 0x7CCB: -case 0x7CCC: -case 0x7CCD: -case 0x7CCE: -case 0x7CCF: -case 0x7CD0: -case 0x7CD1: -case 0x7CD2: -case 0x7CD3: -case 0x7CD4: -case 0x7CD5: -case 0x7CD6: -case 0x7CD7: -case 0x7CD8: -case 0x7CD9: -case 0x7CDA: -case 0x7CDB: -case 0x7CDC: -case 0x7CDD: -case 0x7CDE: -case 0x7CDF: -case 0x7CE0: -case 0x7CE1: -case 0x7CE2: -case 0x7CE3: -case 0x7CE4: -case 0x7CE5: -case 0x7CE6: -case 0x7CE7: -case 0x7CE8: -case 0x7CE9: -case 0x7CEA: -case 0x7CEB: -case 0x7CEC: -case 0x7CED: -case 0x7CEE: -case 0x7CEF: -case 0x7CF0: -case 0x7CF1: -case 0x7CF2: -case 0x7CF3: -case 0x7CF4: -case 0x7CF5: -case 0x7CF6: -case 0x7CF7: -case 0x7CF8: -case 0x7CF9: -case 0x7CFA: -case 0x7CFB: -case 0x7CFC: -case 0x7CFD: -case 0x7CFE: -case 0x7CFF: -case 0x7E00: -case 0x7E01: -case 0x7E02: -case 0x7E03: -case 0x7E04: -case 0x7E05: -case 0x7E06: -case 0x7E07: -case 0x7E08: -case 0x7E09: -case 0x7E0A: -case 0x7E0B: -case 0x7E0C: -case 0x7E0D: -case 0x7E0E: -case 0x7E0F: -case 0x7E10: -case 0x7E11: -case 0x7E12: -case 0x7E13: -case 0x7E14: -case 0x7E15: -case 0x7E16: -case 0x7E17: -case 0x7E18: -case 0x7E19: -case 0x7E1A: -case 0x7E1B: -case 0x7E1C: -case 0x7E1D: -case 0x7E1E: -case 0x7E1F: -case 0x7E20: -case 0x7E21: -case 0x7E22: -case 0x7E23: -case 0x7E24: -case 0x7E25: -case 0x7E26: -case 0x7E27: -case 0x7E28: -case 0x7E29: -case 0x7E2A: -case 0x7E2B: -case 0x7E2C: -case 0x7E2D: -case 0x7E2E: -case 0x7E2F: -case 0x7E30: -case 0x7E31: -case 0x7E32: -case 0x7E33: -case 0x7E34: -case 0x7E35: -case 0x7E36: -case 0x7E37: -case 0x7E38: -case 0x7E39: -case 0x7E3A: -case 0x7E3B: -case 0x7E3C: -case 0x7E3D: -case 0x7E3E: -case 0x7E3F: -case 0x7E40: -case 0x7E41: -case 0x7E42: -case 0x7E43: -case 0x7E44: -case 0x7E45: -case 0x7E46: -case 0x7E47: -case 0x7E48: -case 0x7E49: -case 0x7E4A: -case 0x7E4B: -case 0x7E4C: -case 0x7E4D: -case 0x7E4E: -case 0x7E4F: -case 0x7E50: -case 0x7E51: -case 0x7E52: -case 0x7E53: -case 0x7E54: -case 0x7E55: -case 0x7E56: -case 0x7E57: -case 0x7E58: -case 0x7E59: -case 0x7E5A: -case 0x7E5B: -case 0x7E5C: -case 0x7E5D: -case 0x7E5E: -case 0x7E5F: -case 0x7E60: -case 0x7E61: -case 0x7E62: -case 0x7E63: -case 0x7E64: -case 0x7E65: -case 0x7E66: -case 0x7E67: -case 0x7E68: -case 0x7E69: -case 0x7E6A: -case 0x7E6B: -case 0x7E6C: -case 0x7E6D: -case 0x7E6E: -case 0x7E6F: -case 0x7E70: -case 0x7E71: -case 0x7E72: -case 0x7E73: -case 0x7E74: -case 0x7E75: -case 0x7E76: -case 0x7E77: -case 0x7E78: -case 0x7E79: -case 0x7E7A: -case 0x7E7B: -case 0x7E7C: -case 0x7E7D: -case 0x7E7E: -case 0x7E7F: -case 0x7E80: -case 0x7E81: -case 0x7E82: -case 0x7E83: -case 0x7E84: -case 0x7E85: -case 0x7E86: -case 0x7E87: -case 0x7E88: -case 0x7E89: -case 0x7E8A: -case 0x7E8B: -case 0x7E8C: -case 0x7E8D: -case 0x7E8E: -case 0x7E8F: -case 0x7E90: -case 0x7E91: -case 0x7E92: -case 0x7E93: -case 0x7E94: -case 0x7E95: -case 0x7E96: -case 0x7E97: -case 0x7E98: -case 0x7E99: -case 0x7E9A: -case 0x7E9B: -case 0x7E9C: -case 0x7E9D: -case 0x7E9E: -case 0x7E9F: -case 0x7EA0: -case 0x7EA1: -case 0x7EA2: -case 0x7EA3: -case 0x7EA4: -case 0x7EA5: -case 0x7EA6: -case 0x7EA7: -case 0x7EA8: -case 0x7EA9: -case 0x7EAA: -case 0x7EAB: -case 0x7EAC: -case 0x7EAD: -case 0x7EAE: -case 0x7EAF: -case 0x7EB0: -case 0x7EB1: -case 0x7EB2: -case 0x7EB3: -case 0x7EB4: -case 0x7EB5: -case 0x7EB6: -case 0x7EB7: -case 0x7EB8: -case 0x7EB9: -case 0x7EBA: -case 0x7EBB: -case 0x7EBC: -case 0x7EBD: -case 0x7EBE: -case 0x7EBF: -case 0x7EC0: -case 0x7EC1: -case 0x7EC2: -case 0x7EC3: -case 0x7EC4: -case 0x7EC5: -case 0x7EC6: -case 0x7EC7: -case 0x7EC8: -case 0x7EC9: -case 0x7ECA: -case 0x7ECB: -case 0x7ECC: -case 0x7ECD: -case 0x7ECE: -case 0x7ECF: -case 0x7ED0: -case 0x7ED1: -case 0x7ED2: -case 0x7ED3: -case 0x7ED4: -case 0x7ED5: -case 0x7ED6: -case 0x7ED7: -case 0x7ED8: -case 0x7ED9: -case 0x7EDA: -case 0x7EDB: -case 0x7EDC: -case 0x7EDD: -case 0x7EDE: -case 0x7EDF: -case 0x7EE0: -case 0x7EE1: -case 0x7EE2: -case 0x7EE3: -case 0x7EE4: -case 0x7EE5: -case 0x7EE6: -case 0x7EE7: -case 0x7EE8: -case 0x7EE9: -case 0x7EEA: -case 0x7EEB: -case 0x7EEC: -case 0x7EED: -case 0x7EEE: -case 0x7EEF: -case 0x7EF0: -case 0x7EF1: -case 0x7EF2: -case 0x7EF3: -case 0x7EF4: -case 0x7EF5: -case 0x7EF6: -case 0x7EF7: -case 0x7EF8: -case 0x7EF9: -case 0x7EFA: -case 0x7EFB: -case 0x7EFC: -case 0x7EFD: -case 0x7EFE: -case 0x7EFF: - -// MOVEQ -case 0x7000: -{ - u32 res; - res = (s32)(s8)Opcode; - CPU->flag_C = CPU->flag_V = 0; - CPU->flag_N = CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) diff --git a/yabause/src/c68k/c68k_op8.inc b/yabause/src/c68k/c68k_op8.inc deleted file mode 100644 index 6b0949d7ef..0000000000 --- a/yabause/src/c68k/c68k_op8.inc +++ /dev/null @@ -1,6117 +0,0 @@ -case 0x8200: -case 0x8400: -case 0x8600: -case 0x8800: -case 0x8A00: -case 0x8C00: -case 0x8E00: -case 0x8001: -case 0x8201: -case 0x8401: -case 0x8601: -case 0x8801: -case 0x8A01: -case 0x8C01: -case 0x8E01: -case 0x8002: -case 0x8202: -case 0x8402: -case 0x8602: -case 0x8802: -case 0x8A02: -case 0x8C02: -case 0x8E02: -case 0x8003: -case 0x8203: -case 0x8403: -case 0x8603: -case 0x8803: -case 0x8A03: -case 0x8C03: -case 0x8E03: -case 0x8004: -case 0x8204: -case 0x8404: -case 0x8604: -case 0x8804: -case 0x8A04: -case 0x8C04: -case 0x8E04: -case 0x8005: -case 0x8205: -case 0x8405: -case 0x8605: -case 0x8805: -case 0x8A05: -case 0x8C05: -case 0x8E05: -case 0x8006: -case 0x8206: -case 0x8406: -case 0x8606: -case 0x8806: -case 0x8A06: -case 0x8C06: -case 0x8E06: -case 0x8007: -case 0x8207: -case 0x8407: -case 0x8607: -case 0x8807: -case 0x8A07: -case 0x8C07: -case 0x8E07: - -// ORaD -case 0x8000: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x8210: -case 0x8410: -case 0x8610: -case 0x8810: -case 0x8A10: -case 0x8C10: -case 0x8E10: -case 0x8011: -case 0x8211: -case 0x8411: -case 0x8611: -case 0x8811: -case 0x8A11: -case 0x8C11: -case 0x8E11: -case 0x8012: -case 0x8212: -case 0x8412: -case 0x8612: -case 0x8812: -case 0x8A12: -case 0x8C12: -case 0x8E12: -case 0x8013: -case 0x8213: -case 0x8413: -case 0x8613: -case 0x8813: -case 0x8A13: -case 0x8C13: -case 0x8E13: -case 0x8014: -case 0x8214: -case 0x8414: -case 0x8614: -case 0x8814: -case 0x8A14: -case 0x8C14: -case 0x8E14: -case 0x8015: -case 0x8215: -case 0x8415: -case 0x8615: -case 0x8815: -case 0x8A15: -case 0x8C15: -case 0x8E15: -case 0x8016: -case 0x8216: -case 0x8416: -case 0x8616: -case 0x8816: -case 0x8A16: -case 0x8C16: -case 0x8E16: -case 0x8017: -case 0x8217: -case 0x8417: -case 0x8617: -case 0x8817: -case 0x8A17: -case 0x8C17: -case 0x8E17: - -// ORaD -case 0x8010: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8218: -case 0x8418: -case 0x8618: -case 0x8818: -case 0x8A18: -case 0x8C18: -case 0x8E18: -case 0x8019: -case 0x8219: -case 0x8419: -case 0x8619: -case 0x8819: -case 0x8A19: -case 0x8C19: -case 0x8E19: -case 0x801A: -case 0x821A: -case 0x841A: -case 0x861A: -case 0x881A: -case 0x8A1A: -case 0x8C1A: -case 0x8E1A: -case 0x801B: -case 0x821B: -case 0x841B: -case 0x861B: -case 0x881B: -case 0x8A1B: -case 0x8C1B: -case 0x8E1B: -case 0x801C: -case 0x821C: -case 0x841C: -case 0x861C: -case 0x881C: -case 0x8A1C: -case 0x8C1C: -case 0x8E1C: -case 0x801D: -case 0x821D: -case 0x841D: -case 0x861D: -case 0x881D: -case 0x8A1D: -case 0x8C1D: -case 0x8E1D: -case 0x801E: -case 0x821E: -case 0x841E: -case 0x861E: -case 0x881E: -case 0x8A1E: -case 0x8C1E: -case 0x8E1E: - -// ORaD -case 0x8018: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8220: -case 0x8420: -case 0x8620: -case 0x8820: -case 0x8A20: -case 0x8C20: -case 0x8E20: -case 0x8021: -case 0x8221: -case 0x8421: -case 0x8621: -case 0x8821: -case 0x8A21: -case 0x8C21: -case 0x8E21: -case 0x8022: -case 0x8222: -case 0x8422: -case 0x8622: -case 0x8822: -case 0x8A22: -case 0x8C22: -case 0x8E22: -case 0x8023: -case 0x8223: -case 0x8423: -case 0x8623: -case 0x8823: -case 0x8A23: -case 0x8C23: -case 0x8E23: -case 0x8024: -case 0x8224: -case 0x8424: -case 0x8624: -case 0x8824: -case 0x8A24: -case 0x8C24: -case 0x8E24: -case 0x8025: -case 0x8225: -case 0x8425: -case 0x8625: -case 0x8825: -case 0x8A25: -case 0x8C25: -case 0x8E25: -case 0x8026: -case 0x8226: -case 0x8426: -case 0x8626: -case 0x8826: -case 0x8A26: -case 0x8C26: -case 0x8E26: - -// ORaD -case 0x8020: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8228: -case 0x8428: -case 0x8628: -case 0x8828: -case 0x8A28: -case 0x8C28: -case 0x8E28: -case 0x8029: -case 0x8229: -case 0x8429: -case 0x8629: -case 0x8829: -case 0x8A29: -case 0x8C29: -case 0x8E29: -case 0x802A: -case 0x822A: -case 0x842A: -case 0x862A: -case 0x882A: -case 0x8A2A: -case 0x8C2A: -case 0x8E2A: -case 0x802B: -case 0x822B: -case 0x842B: -case 0x862B: -case 0x882B: -case 0x8A2B: -case 0x8C2B: -case 0x8E2B: -case 0x802C: -case 0x822C: -case 0x842C: -case 0x862C: -case 0x882C: -case 0x8A2C: -case 0x8C2C: -case 0x8E2C: -case 0x802D: -case 0x822D: -case 0x842D: -case 0x862D: -case 0x882D: -case 0x8A2D: -case 0x8C2D: -case 0x8E2D: -case 0x802E: -case 0x822E: -case 0x842E: -case 0x862E: -case 0x882E: -case 0x8A2E: -case 0x8C2E: -case 0x8E2E: -case 0x802F: -case 0x822F: -case 0x842F: -case 0x862F: -case 0x882F: -case 0x8A2F: -case 0x8C2F: -case 0x8E2F: - -// ORaD -case 0x8028: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8230: -case 0x8430: -case 0x8630: -case 0x8830: -case 0x8A30: -case 0x8C30: -case 0x8E30: -case 0x8031: -case 0x8231: -case 0x8431: -case 0x8631: -case 0x8831: -case 0x8A31: -case 0x8C31: -case 0x8E31: -case 0x8032: -case 0x8232: -case 0x8432: -case 0x8632: -case 0x8832: -case 0x8A32: -case 0x8C32: -case 0x8E32: -case 0x8033: -case 0x8233: -case 0x8433: -case 0x8633: -case 0x8833: -case 0x8A33: -case 0x8C33: -case 0x8E33: -case 0x8034: -case 0x8234: -case 0x8434: -case 0x8634: -case 0x8834: -case 0x8A34: -case 0x8C34: -case 0x8E34: -case 0x8035: -case 0x8235: -case 0x8435: -case 0x8635: -case 0x8835: -case 0x8A35: -case 0x8C35: -case 0x8E35: -case 0x8036: -case 0x8236: -case 0x8436: -case 0x8636: -case 0x8836: -case 0x8A36: -case 0x8C36: -case 0x8E36: -case 0x8037: -case 0x8237: -case 0x8437: -case 0x8637: -case 0x8837: -case 0x8A37: -case 0x8C37: -case 0x8E37: - -// ORaD -case 0x8030: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x8238: -case 0x8438: -case 0x8638: -case 0x8838: -case 0x8A38: -case 0x8C38: -case 0x8E38: - -// ORaD -case 0x8038: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8239: -case 0x8439: -case 0x8639: -case 0x8839: -case 0x8A39: -case 0x8C39: -case 0x8E39: - -// ORaD -case 0x8039: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x823A: -case 0x843A: -case 0x863A: -case 0x883A: -case 0x8A3A: -case 0x8C3A: -case 0x8E3A: - -// ORaD -case 0x803A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x823B: -case 0x843B: -case 0x863B: -case 0x883B: -case 0x8A3B: -case 0x8C3B: -case 0x8E3B: - -// ORaD -case 0x803B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x823C: -case 0x843C: -case 0x863C: -case 0x883C: -case 0x8A3C: -case 0x8C3C: -case 0x8E3C: - -// ORaD -case 0x803C: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x821F: -case 0x841F: -case 0x861F: -case 0x881F: -case 0x8A1F: -case 0x8C1F: -case 0x8E1F: - -// ORaD -case 0x801F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8227: -case 0x8427: -case 0x8627: -case 0x8827: -case 0x8A27: -case 0x8C27: -case 0x8E27: - -// ORaD -case 0x8027: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8240: -case 0x8440: -case 0x8640: -case 0x8840: -case 0x8A40: -case 0x8C40: -case 0x8E40: -case 0x8041: -case 0x8241: -case 0x8441: -case 0x8641: -case 0x8841: -case 0x8A41: -case 0x8C41: -case 0x8E41: -case 0x8042: -case 0x8242: -case 0x8442: -case 0x8642: -case 0x8842: -case 0x8A42: -case 0x8C42: -case 0x8E42: -case 0x8043: -case 0x8243: -case 0x8443: -case 0x8643: -case 0x8843: -case 0x8A43: -case 0x8C43: -case 0x8E43: -case 0x8044: -case 0x8244: -case 0x8444: -case 0x8644: -case 0x8844: -case 0x8A44: -case 0x8C44: -case 0x8E44: -case 0x8045: -case 0x8245: -case 0x8445: -case 0x8645: -case 0x8845: -case 0x8A45: -case 0x8C45: -case 0x8E45: -case 0x8046: -case 0x8246: -case 0x8446: -case 0x8646: -case 0x8846: -case 0x8A46: -case 0x8C46: -case 0x8E46: -case 0x8047: -case 0x8247: -case 0x8447: -case 0x8647: -case 0x8847: -case 0x8A47: -case 0x8C47: -case 0x8E47: - -// ORaD -case 0x8040: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x8250: -case 0x8450: -case 0x8650: -case 0x8850: -case 0x8A50: -case 0x8C50: -case 0x8E50: -case 0x8051: -case 0x8251: -case 0x8451: -case 0x8651: -case 0x8851: -case 0x8A51: -case 0x8C51: -case 0x8E51: -case 0x8052: -case 0x8252: -case 0x8452: -case 0x8652: -case 0x8852: -case 0x8A52: -case 0x8C52: -case 0x8E52: -case 0x8053: -case 0x8253: -case 0x8453: -case 0x8653: -case 0x8853: -case 0x8A53: -case 0x8C53: -case 0x8E53: -case 0x8054: -case 0x8254: -case 0x8454: -case 0x8654: -case 0x8854: -case 0x8A54: -case 0x8C54: -case 0x8E54: -case 0x8055: -case 0x8255: -case 0x8455: -case 0x8655: -case 0x8855: -case 0x8A55: -case 0x8C55: -case 0x8E55: -case 0x8056: -case 0x8256: -case 0x8456: -case 0x8656: -case 0x8856: -case 0x8A56: -case 0x8C56: -case 0x8E56: -case 0x8057: -case 0x8257: -case 0x8457: -case 0x8657: -case 0x8857: -case 0x8A57: -case 0x8C57: -case 0x8E57: - -// ORaD -case 0x8050: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8258: -case 0x8458: -case 0x8658: -case 0x8858: -case 0x8A58: -case 0x8C58: -case 0x8E58: -case 0x8059: -case 0x8259: -case 0x8459: -case 0x8659: -case 0x8859: -case 0x8A59: -case 0x8C59: -case 0x8E59: -case 0x805A: -case 0x825A: -case 0x845A: -case 0x865A: -case 0x885A: -case 0x8A5A: -case 0x8C5A: -case 0x8E5A: -case 0x805B: -case 0x825B: -case 0x845B: -case 0x865B: -case 0x885B: -case 0x8A5B: -case 0x8C5B: -case 0x8E5B: -case 0x805C: -case 0x825C: -case 0x845C: -case 0x865C: -case 0x885C: -case 0x8A5C: -case 0x8C5C: -case 0x8E5C: -case 0x805D: -case 0x825D: -case 0x845D: -case 0x865D: -case 0x885D: -case 0x8A5D: -case 0x8C5D: -case 0x8E5D: -case 0x805E: -case 0x825E: -case 0x845E: -case 0x865E: -case 0x885E: -case 0x8A5E: -case 0x8C5E: -case 0x8E5E: - -// ORaD -case 0x8058: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8260: -case 0x8460: -case 0x8660: -case 0x8860: -case 0x8A60: -case 0x8C60: -case 0x8E60: -case 0x8061: -case 0x8261: -case 0x8461: -case 0x8661: -case 0x8861: -case 0x8A61: -case 0x8C61: -case 0x8E61: -case 0x8062: -case 0x8262: -case 0x8462: -case 0x8662: -case 0x8862: -case 0x8A62: -case 0x8C62: -case 0x8E62: -case 0x8063: -case 0x8263: -case 0x8463: -case 0x8663: -case 0x8863: -case 0x8A63: -case 0x8C63: -case 0x8E63: -case 0x8064: -case 0x8264: -case 0x8464: -case 0x8664: -case 0x8864: -case 0x8A64: -case 0x8C64: -case 0x8E64: -case 0x8065: -case 0x8265: -case 0x8465: -case 0x8665: -case 0x8865: -case 0x8A65: -case 0x8C65: -case 0x8E65: -case 0x8066: -case 0x8266: -case 0x8466: -case 0x8666: -case 0x8866: -case 0x8A66: -case 0x8C66: -case 0x8E66: - -// ORaD -case 0x8060: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8268: -case 0x8468: -case 0x8668: -case 0x8868: -case 0x8A68: -case 0x8C68: -case 0x8E68: -case 0x8069: -case 0x8269: -case 0x8469: -case 0x8669: -case 0x8869: -case 0x8A69: -case 0x8C69: -case 0x8E69: -case 0x806A: -case 0x826A: -case 0x846A: -case 0x866A: -case 0x886A: -case 0x8A6A: -case 0x8C6A: -case 0x8E6A: -case 0x806B: -case 0x826B: -case 0x846B: -case 0x866B: -case 0x886B: -case 0x8A6B: -case 0x8C6B: -case 0x8E6B: -case 0x806C: -case 0x826C: -case 0x846C: -case 0x866C: -case 0x886C: -case 0x8A6C: -case 0x8C6C: -case 0x8E6C: -case 0x806D: -case 0x826D: -case 0x846D: -case 0x866D: -case 0x886D: -case 0x8A6D: -case 0x8C6D: -case 0x8E6D: -case 0x806E: -case 0x826E: -case 0x846E: -case 0x866E: -case 0x886E: -case 0x8A6E: -case 0x8C6E: -case 0x8E6E: -case 0x806F: -case 0x826F: -case 0x846F: -case 0x866F: -case 0x886F: -case 0x8A6F: -case 0x8C6F: -case 0x8E6F: - -// ORaD -case 0x8068: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8270: -case 0x8470: -case 0x8670: -case 0x8870: -case 0x8A70: -case 0x8C70: -case 0x8E70: -case 0x8071: -case 0x8271: -case 0x8471: -case 0x8671: -case 0x8871: -case 0x8A71: -case 0x8C71: -case 0x8E71: -case 0x8072: -case 0x8272: -case 0x8472: -case 0x8672: -case 0x8872: -case 0x8A72: -case 0x8C72: -case 0x8E72: -case 0x8073: -case 0x8273: -case 0x8473: -case 0x8673: -case 0x8873: -case 0x8A73: -case 0x8C73: -case 0x8E73: -case 0x8074: -case 0x8274: -case 0x8474: -case 0x8674: -case 0x8874: -case 0x8A74: -case 0x8C74: -case 0x8E74: -case 0x8075: -case 0x8275: -case 0x8475: -case 0x8675: -case 0x8875: -case 0x8A75: -case 0x8C75: -case 0x8E75: -case 0x8076: -case 0x8276: -case 0x8476: -case 0x8676: -case 0x8876: -case 0x8A76: -case 0x8C76: -case 0x8E76: -case 0x8077: -case 0x8277: -case 0x8477: -case 0x8677: -case 0x8877: -case 0x8A77: -case 0x8C77: -case 0x8E77: - -// ORaD -case 0x8070: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x8278: -case 0x8478: -case 0x8678: -case 0x8878: -case 0x8A78: -case 0x8C78: -case 0x8E78: - -// ORaD -case 0x8078: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8279: -case 0x8479: -case 0x8679: -case 0x8879: -case 0x8A79: -case 0x8C79: -case 0x8E79: - -// ORaD -case 0x8079: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x827A: -case 0x847A: -case 0x867A: -case 0x887A: -case 0x8A7A: -case 0x8C7A: -case 0x8E7A: - -// ORaD -case 0x807A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x827B: -case 0x847B: -case 0x867B: -case 0x887B: -case 0x8A7B: -case 0x8C7B: -case 0x8E7B: - -// ORaD -case 0x807B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x827C: -case 0x847C: -case 0x867C: -case 0x887C: -case 0x8A7C: -case 0x8C7C: -case 0x8E7C: - -// ORaD -case 0x807C: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x825F: -case 0x845F: -case 0x865F: -case 0x885F: -case 0x8A5F: -case 0x8C5F: -case 0x8E5F: - -// ORaD -case 0x805F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8267: -case 0x8467: -case 0x8667: -case 0x8867: -case 0x8A67: -case 0x8C67: -case 0x8E67: - -// ORaD -case 0x8067: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8280: -case 0x8480: -case 0x8680: -case 0x8880: -case 0x8A80: -case 0x8C80: -case 0x8E80: -case 0x8081: -case 0x8281: -case 0x8481: -case 0x8681: -case 0x8881: -case 0x8A81: -case 0x8C81: -case 0x8E81: -case 0x8082: -case 0x8282: -case 0x8482: -case 0x8682: -case 0x8882: -case 0x8A82: -case 0x8C82: -case 0x8E82: -case 0x8083: -case 0x8283: -case 0x8483: -case 0x8683: -case 0x8883: -case 0x8A83: -case 0x8C83: -case 0x8E83: -case 0x8084: -case 0x8284: -case 0x8484: -case 0x8684: -case 0x8884: -case 0x8A84: -case 0x8C84: -case 0x8E84: -case 0x8085: -case 0x8285: -case 0x8485: -case 0x8685: -case 0x8885: -case 0x8A85: -case 0x8C85: -case 0x8E85: -case 0x8086: -case 0x8286: -case 0x8486: -case 0x8686: -case 0x8886: -case 0x8A86: -case 0x8C86: -case 0x8E86: -case 0x8087: -case 0x8287: -case 0x8487: -case 0x8687: -case 0x8887: -case 0x8A87: -case 0x8C87: -case 0x8E87: - -// ORaD -case 0x8080: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x8290: -case 0x8490: -case 0x8690: -case 0x8890: -case 0x8A90: -case 0x8C90: -case 0x8E90: -case 0x8091: -case 0x8291: -case 0x8491: -case 0x8691: -case 0x8891: -case 0x8A91: -case 0x8C91: -case 0x8E91: -case 0x8092: -case 0x8292: -case 0x8492: -case 0x8692: -case 0x8892: -case 0x8A92: -case 0x8C92: -case 0x8E92: -case 0x8093: -case 0x8293: -case 0x8493: -case 0x8693: -case 0x8893: -case 0x8A93: -case 0x8C93: -case 0x8E93: -case 0x8094: -case 0x8294: -case 0x8494: -case 0x8694: -case 0x8894: -case 0x8A94: -case 0x8C94: -case 0x8E94: -case 0x8095: -case 0x8295: -case 0x8495: -case 0x8695: -case 0x8895: -case 0x8A95: -case 0x8C95: -case 0x8E95: -case 0x8096: -case 0x8296: -case 0x8496: -case 0x8696: -case 0x8896: -case 0x8A96: -case 0x8C96: -case 0x8E96: -case 0x8097: -case 0x8297: -case 0x8497: -case 0x8697: -case 0x8897: -case 0x8A97: -case 0x8C97: -case 0x8E97: - -// ORaD -case 0x8090: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x8298: -case 0x8498: -case 0x8698: -case 0x8898: -case 0x8A98: -case 0x8C98: -case 0x8E98: -case 0x8099: -case 0x8299: -case 0x8499: -case 0x8699: -case 0x8899: -case 0x8A99: -case 0x8C99: -case 0x8E99: -case 0x809A: -case 0x829A: -case 0x849A: -case 0x869A: -case 0x889A: -case 0x8A9A: -case 0x8C9A: -case 0x8E9A: -case 0x809B: -case 0x829B: -case 0x849B: -case 0x869B: -case 0x889B: -case 0x8A9B: -case 0x8C9B: -case 0x8E9B: -case 0x809C: -case 0x829C: -case 0x849C: -case 0x869C: -case 0x889C: -case 0x8A9C: -case 0x8C9C: -case 0x8E9C: -case 0x809D: -case 0x829D: -case 0x849D: -case 0x869D: -case 0x889D: -case 0x8A9D: -case 0x8C9D: -case 0x8E9D: -case 0x809E: -case 0x829E: -case 0x849E: -case 0x869E: -case 0x889E: -case 0x8A9E: -case 0x8C9E: -case 0x8E9E: - -// ORaD -case 0x8098: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x82A0: -case 0x84A0: -case 0x86A0: -case 0x88A0: -case 0x8AA0: -case 0x8CA0: -case 0x8EA0: -case 0x80A1: -case 0x82A1: -case 0x84A1: -case 0x86A1: -case 0x88A1: -case 0x8AA1: -case 0x8CA1: -case 0x8EA1: -case 0x80A2: -case 0x82A2: -case 0x84A2: -case 0x86A2: -case 0x88A2: -case 0x8AA2: -case 0x8CA2: -case 0x8EA2: -case 0x80A3: -case 0x82A3: -case 0x84A3: -case 0x86A3: -case 0x88A3: -case 0x8AA3: -case 0x8CA3: -case 0x8EA3: -case 0x80A4: -case 0x82A4: -case 0x84A4: -case 0x86A4: -case 0x88A4: -case 0x8AA4: -case 0x8CA4: -case 0x8EA4: -case 0x80A5: -case 0x82A5: -case 0x84A5: -case 0x86A5: -case 0x88A5: -case 0x8AA5: -case 0x8CA5: -case 0x8EA5: -case 0x80A6: -case 0x82A6: -case 0x84A6: -case 0x86A6: -case 0x88A6: -case 0x8AA6: -case 0x8CA6: -case 0x8EA6: - -// ORaD -case 0x80A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x82A8: -case 0x84A8: -case 0x86A8: -case 0x88A8: -case 0x8AA8: -case 0x8CA8: -case 0x8EA8: -case 0x80A9: -case 0x82A9: -case 0x84A9: -case 0x86A9: -case 0x88A9: -case 0x8AA9: -case 0x8CA9: -case 0x8EA9: -case 0x80AA: -case 0x82AA: -case 0x84AA: -case 0x86AA: -case 0x88AA: -case 0x8AAA: -case 0x8CAA: -case 0x8EAA: -case 0x80AB: -case 0x82AB: -case 0x84AB: -case 0x86AB: -case 0x88AB: -case 0x8AAB: -case 0x8CAB: -case 0x8EAB: -case 0x80AC: -case 0x82AC: -case 0x84AC: -case 0x86AC: -case 0x88AC: -case 0x8AAC: -case 0x8CAC: -case 0x8EAC: -case 0x80AD: -case 0x82AD: -case 0x84AD: -case 0x86AD: -case 0x88AD: -case 0x8AAD: -case 0x8CAD: -case 0x8EAD: -case 0x80AE: -case 0x82AE: -case 0x84AE: -case 0x86AE: -case 0x88AE: -case 0x8AAE: -case 0x8CAE: -case 0x8EAE: -case 0x80AF: -case 0x82AF: -case 0x84AF: -case 0x86AF: -case 0x88AF: -case 0x8AAF: -case 0x8CAF: -case 0x8EAF: - -// ORaD -case 0x80A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x82B0: -case 0x84B0: -case 0x86B0: -case 0x88B0: -case 0x8AB0: -case 0x8CB0: -case 0x8EB0: -case 0x80B1: -case 0x82B1: -case 0x84B1: -case 0x86B1: -case 0x88B1: -case 0x8AB1: -case 0x8CB1: -case 0x8EB1: -case 0x80B2: -case 0x82B2: -case 0x84B2: -case 0x86B2: -case 0x88B2: -case 0x8AB2: -case 0x8CB2: -case 0x8EB2: -case 0x80B3: -case 0x82B3: -case 0x84B3: -case 0x86B3: -case 0x88B3: -case 0x8AB3: -case 0x8CB3: -case 0x8EB3: -case 0x80B4: -case 0x82B4: -case 0x84B4: -case 0x86B4: -case 0x88B4: -case 0x8AB4: -case 0x8CB4: -case 0x8EB4: -case 0x80B5: -case 0x82B5: -case 0x84B5: -case 0x86B5: -case 0x88B5: -case 0x8AB5: -case 0x8CB5: -case 0x8EB5: -case 0x80B6: -case 0x82B6: -case 0x84B6: -case 0x86B6: -case 0x88B6: -case 0x8AB6: -case 0x8CB6: -case 0x8EB6: -case 0x80B7: -case 0x82B7: -case 0x84B7: -case 0x86B7: -case 0x88B7: -case 0x8AB7: -case 0x8CB7: -case 0x8EB7: - -// ORaD -case 0x80B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x82B8: -case 0x84B8: -case 0x86B8: -case 0x88B8: -case 0x8AB8: -case 0x8CB8: -case 0x8EB8: - -// ORaD -case 0x80B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x82B9: -case 0x84B9: -case 0x86B9: -case 0x88B9: -case 0x8AB9: -case 0x8CB9: -case 0x8EB9: - -// ORaD -case 0x80B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0x82BA: -case 0x84BA: -case 0x86BA: -case 0x88BA: -case 0x8ABA: -case 0x8CBA: -case 0x8EBA: - -// ORaD -case 0x80BA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x82BB: -case 0x84BB: -case 0x86BB: -case 0x88BB: -case 0x8ABB: -case 0x8CBB: -case 0x8EBB: - -// ORaD -case 0x80BB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x82BC: -case 0x84BC: -case 0x86BC: -case 0x88BC: -case 0x8ABC: -case 0x8CBC: -case 0x8EBC: - -// ORaD -case 0x80BC: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0x829F: -case 0x849F: -case 0x869F: -case 0x889F: -case 0x8A9F: -case 0x8C9F: -case 0x8E9F: - -// ORaD -case 0x809F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x82A7: -case 0x84A7: -case 0x86A7: -case 0x88A7: -case 0x8AA7: -case 0x8CA7: -case 0x8EA7: - -// ORaD -case 0x80A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x8310: -case 0x8510: -case 0x8710: -case 0x8910: -case 0x8B10: -case 0x8D10: -case 0x8F10: -case 0x8111: -case 0x8311: -case 0x8511: -case 0x8711: -case 0x8911: -case 0x8B11: -case 0x8D11: -case 0x8F11: -case 0x8112: -case 0x8312: -case 0x8512: -case 0x8712: -case 0x8912: -case 0x8B12: -case 0x8D12: -case 0x8F12: -case 0x8113: -case 0x8313: -case 0x8513: -case 0x8713: -case 0x8913: -case 0x8B13: -case 0x8D13: -case 0x8F13: -case 0x8114: -case 0x8314: -case 0x8514: -case 0x8714: -case 0x8914: -case 0x8B14: -case 0x8D14: -case 0x8F14: -case 0x8115: -case 0x8315: -case 0x8515: -case 0x8715: -case 0x8915: -case 0x8B15: -case 0x8D15: -case 0x8F15: -case 0x8116: -case 0x8316: -case 0x8516: -case 0x8716: -case 0x8916: -case 0x8B16: -case 0x8D16: -case 0x8F16: -case 0x8117: -case 0x8317: -case 0x8517: -case 0x8717: -case 0x8917: -case 0x8B17: -case 0x8D17: -case 0x8F17: - -// ORDa -case 0x8110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x8318: -case 0x8518: -case 0x8718: -case 0x8918: -case 0x8B18: -case 0x8D18: -case 0x8F18: -case 0x8119: -case 0x8319: -case 0x8519: -case 0x8719: -case 0x8919: -case 0x8B19: -case 0x8D19: -case 0x8F19: -case 0x811A: -case 0x831A: -case 0x851A: -case 0x871A: -case 0x891A: -case 0x8B1A: -case 0x8D1A: -case 0x8F1A: -case 0x811B: -case 0x831B: -case 0x851B: -case 0x871B: -case 0x891B: -case 0x8B1B: -case 0x8D1B: -case 0x8F1B: -case 0x811C: -case 0x831C: -case 0x851C: -case 0x871C: -case 0x891C: -case 0x8B1C: -case 0x8D1C: -case 0x8F1C: -case 0x811D: -case 0x831D: -case 0x851D: -case 0x871D: -case 0x891D: -case 0x8B1D: -case 0x8D1D: -case 0x8F1D: -case 0x811E: -case 0x831E: -case 0x851E: -case 0x871E: -case 0x891E: -case 0x8B1E: -case 0x8D1E: -case 0x8F1E: - -// ORDa -case 0x8118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x8320: -case 0x8520: -case 0x8720: -case 0x8920: -case 0x8B20: -case 0x8D20: -case 0x8F20: -case 0x8121: -case 0x8321: -case 0x8521: -case 0x8721: -case 0x8921: -case 0x8B21: -case 0x8D21: -case 0x8F21: -case 0x8122: -case 0x8322: -case 0x8522: -case 0x8722: -case 0x8922: -case 0x8B22: -case 0x8D22: -case 0x8F22: -case 0x8123: -case 0x8323: -case 0x8523: -case 0x8723: -case 0x8923: -case 0x8B23: -case 0x8D23: -case 0x8F23: -case 0x8124: -case 0x8324: -case 0x8524: -case 0x8724: -case 0x8924: -case 0x8B24: -case 0x8D24: -case 0x8F24: -case 0x8125: -case 0x8325: -case 0x8525: -case 0x8725: -case 0x8925: -case 0x8B25: -case 0x8D25: -case 0x8F25: -case 0x8126: -case 0x8326: -case 0x8526: -case 0x8726: -case 0x8926: -case 0x8B26: -case 0x8D26: -case 0x8F26: - -// ORDa -case 0x8120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x8328: -case 0x8528: -case 0x8728: -case 0x8928: -case 0x8B28: -case 0x8D28: -case 0x8F28: -case 0x8129: -case 0x8329: -case 0x8529: -case 0x8729: -case 0x8929: -case 0x8B29: -case 0x8D29: -case 0x8F29: -case 0x812A: -case 0x832A: -case 0x852A: -case 0x872A: -case 0x892A: -case 0x8B2A: -case 0x8D2A: -case 0x8F2A: -case 0x812B: -case 0x832B: -case 0x852B: -case 0x872B: -case 0x892B: -case 0x8B2B: -case 0x8D2B: -case 0x8F2B: -case 0x812C: -case 0x832C: -case 0x852C: -case 0x872C: -case 0x892C: -case 0x8B2C: -case 0x8D2C: -case 0x8F2C: -case 0x812D: -case 0x832D: -case 0x852D: -case 0x872D: -case 0x892D: -case 0x8B2D: -case 0x8D2D: -case 0x8F2D: -case 0x812E: -case 0x832E: -case 0x852E: -case 0x872E: -case 0x892E: -case 0x8B2E: -case 0x8D2E: -case 0x8F2E: -case 0x812F: -case 0x832F: -case 0x852F: -case 0x872F: -case 0x892F: -case 0x8B2F: -case 0x8D2F: -case 0x8F2F: - -// ORDa -case 0x8128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x8330: -case 0x8530: -case 0x8730: -case 0x8930: -case 0x8B30: -case 0x8D30: -case 0x8F30: -case 0x8131: -case 0x8331: -case 0x8531: -case 0x8731: -case 0x8931: -case 0x8B31: -case 0x8D31: -case 0x8F31: -case 0x8132: -case 0x8332: -case 0x8532: -case 0x8732: -case 0x8932: -case 0x8B32: -case 0x8D32: -case 0x8F32: -case 0x8133: -case 0x8333: -case 0x8533: -case 0x8733: -case 0x8933: -case 0x8B33: -case 0x8D33: -case 0x8F33: -case 0x8134: -case 0x8334: -case 0x8534: -case 0x8734: -case 0x8934: -case 0x8B34: -case 0x8D34: -case 0x8F34: -case 0x8135: -case 0x8335: -case 0x8535: -case 0x8735: -case 0x8935: -case 0x8B35: -case 0x8D35: -case 0x8F35: -case 0x8136: -case 0x8336: -case 0x8536: -case 0x8736: -case 0x8936: -case 0x8B36: -case 0x8D36: -case 0x8F36: -case 0x8137: -case 0x8337: -case 0x8537: -case 0x8737: -case 0x8937: -case 0x8B37: -case 0x8D37: -case 0x8F37: - -// ORDa -case 0x8130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x8338: -case 0x8538: -case 0x8738: -case 0x8938: -case 0x8B38: -case 0x8D38: -case 0x8F38: - -// ORDa -case 0x8138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x8339: -case 0x8539: -case 0x8739: -case 0x8939: -case 0x8B39: -case 0x8D39: -case 0x8F39: - -// ORDa -case 0x8139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x831F: -case 0x851F: -case 0x871F: -case 0x891F: -case 0x8B1F: -case 0x8D1F: -case 0x8F1F: - -// ORDa -case 0x811F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x8327: -case 0x8527: -case 0x8727: -case 0x8927: -case 0x8B27: -case 0x8D27: -case 0x8F27: - -// ORDa -case 0x8127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x8350: -case 0x8550: -case 0x8750: -case 0x8950: -case 0x8B50: -case 0x8D50: -case 0x8F50: -case 0x8151: -case 0x8351: -case 0x8551: -case 0x8751: -case 0x8951: -case 0x8B51: -case 0x8D51: -case 0x8F51: -case 0x8152: -case 0x8352: -case 0x8552: -case 0x8752: -case 0x8952: -case 0x8B52: -case 0x8D52: -case 0x8F52: -case 0x8153: -case 0x8353: -case 0x8553: -case 0x8753: -case 0x8953: -case 0x8B53: -case 0x8D53: -case 0x8F53: -case 0x8154: -case 0x8354: -case 0x8554: -case 0x8754: -case 0x8954: -case 0x8B54: -case 0x8D54: -case 0x8F54: -case 0x8155: -case 0x8355: -case 0x8555: -case 0x8755: -case 0x8955: -case 0x8B55: -case 0x8D55: -case 0x8F55: -case 0x8156: -case 0x8356: -case 0x8556: -case 0x8756: -case 0x8956: -case 0x8B56: -case 0x8D56: -case 0x8F56: -case 0x8157: -case 0x8357: -case 0x8557: -case 0x8757: -case 0x8957: -case 0x8B57: -case 0x8D57: -case 0x8F57: - -// ORDa -case 0x8150: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x8358: -case 0x8558: -case 0x8758: -case 0x8958: -case 0x8B58: -case 0x8D58: -case 0x8F58: -case 0x8159: -case 0x8359: -case 0x8559: -case 0x8759: -case 0x8959: -case 0x8B59: -case 0x8D59: -case 0x8F59: -case 0x815A: -case 0x835A: -case 0x855A: -case 0x875A: -case 0x895A: -case 0x8B5A: -case 0x8D5A: -case 0x8F5A: -case 0x815B: -case 0x835B: -case 0x855B: -case 0x875B: -case 0x895B: -case 0x8B5B: -case 0x8D5B: -case 0x8F5B: -case 0x815C: -case 0x835C: -case 0x855C: -case 0x875C: -case 0x895C: -case 0x8B5C: -case 0x8D5C: -case 0x8F5C: -case 0x815D: -case 0x835D: -case 0x855D: -case 0x875D: -case 0x895D: -case 0x8B5D: -case 0x8D5D: -case 0x8F5D: -case 0x815E: -case 0x835E: -case 0x855E: -case 0x875E: -case 0x895E: -case 0x8B5E: -case 0x8D5E: -case 0x8F5E: - -// ORDa -case 0x8158: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x8360: -case 0x8560: -case 0x8760: -case 0x8960: -case 0x8B60: -case 0x8D60: -case 0x8F60: -case 0x8161: -case 0x8361: -case 0x8561: -case 0x8761: -case 0x8961: -case 0x8B61: -case 0x8D61: -case 0x8F61: -case 0x8162: -case 0x8362: -case 0x8562: -case 0x8762: -case 0x8962: -case 0x8B62: -case 0x8D62: -case 0x8F62: -case 0x8163: -case 0x8363: -case 0x8563: -case 0x8763: -case 0x8963: -case 0x8B63: -case 0x8D63: -case 0x8F63: -case 0x8164: -case 0x8364: -case 0x8564: -case 0x8764: -case 0x8964: -case 0x8B64: -case 0x8D64: -case 0x8F64: -case 0x8165: -case 0x8365: -case 0x8565: -case 0x8765: -case 0x8965: -case 0x8B65: -case 0x8D65: -case 0x8F65: -case 0x8166: -case 0x8366: -case 0x8566: -case 0x8766: -case 0x8966: -case 0x8B66: -case 0x8D66: -case 0x8F66: - -// ORDa -case 0x8160: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x8368: -case 0x8568: -case 0x8768: -case 0x8968: -case 0x8B68: -case 0x8D68: -case 0x8F68: -case 0x8169: -case 0x8369: -case 0x8569: -case 0x8769: -case 0x8969: -case 0x8B69: -case 0x8D69: -case 0x8F69: -case 0x816A: -case 0x836A: -case 0x856A: -case 0x876A: -case 0x896A: -case 0x8B6A: -case 0x8D6A: -case 0x8F6A: -case 0x816B: -case 0x836B: -case 0x856B: -case 0x876B: -case 0x896B: -case 0x8B6B: -case 0x8D6B: -case 0x8F6B: -case 0x816C: -case 0x836C: -case 0x856C: -case 0x876C: -case 0x896C: -case 0x8B6C: -case 0x8D6C: -case 0x8F6C: -case 0x816D: -case 0x836D: -case 0x856D: -case 0x876D: -case 0x896D: -case 0x8B6D: -case 0x8D6D: -case 0x8F6D: -case 0x816E: -case 0x836E: -case 0x856E: -case 0x876E: -case 0x896E: -case 0x8B6E: -case 0x8D6E: -case 0x8F6E: -case 0x816F: -case 0x836F: -case 0x856F: -case 0x876F: -case 0x896F: -case 0x8B6F: -case 0x8D6F: -case 0x8F6F: - -// ORDa -case 0x8168: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x8370: -case 0x8570: -case 0x8770: -case 0x8970: -case 0x8B70: -case 0x8D70: -case 0x8F70: -case 0x8171: -case 0x8371: -case 0x8571: -case 0x8771: -case 0x8971: -case 0x8B71: -case 0x8D71: -case 0x8F71: -case 0x8172: -case 0x8372: -case 0x8572: -case 0x8772: -case 0x8972: -case 0x8B72: -case 0x8D72: -case 0x8F72: -case 0x8173: -case 0x8373: -case 0x8573: -case 0x8773: -case 0x8973: -case 0x8B73: -case 0x8D73: -case 0x8F73: -case 0x8174: -case 0x8374: -case 0x8574: -case 0x8774: -case 0x8974: -case 0x8B74: -case 0x8D74: -case 0x8F74: -case 0x8175: -case 0x8375: -case 0x8575: -case 0x8775: -case 0x8975: -case 0x8B75: -case 0x8D75: -case 0x8F75: -case 0x8176: -case 0x8376: -case 0x8576: -case 0x8776: -case 0x8976: -case 0x8B76: -case 0x8D76: -case 0x8F76: -case 0x8177: -case 0x8377: -case 0x8577: -case 0x8777: -case 0x8977: -case 0x8B77: -case 0x8D77: -case 0x8F77: - -// ORDa -case 0x8170: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x8378: -case 0x8578: -case 0x8778: -case 0x8978: -case 0x8B78: -case 0x8D78: -case 0x8F78: - -// ORDa -case 0x8178: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x8379: -case 0x8579: -case 0x8779: -case 0x8979: -case 0x8B79: -case 0x8D79: -case 0x8F79: - -// ORDa -case 0x8179: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x835F: -case 0x855F: -case 0x875F: -case 0x895F: -case 0x8B5F: -case 0x8D5F: -case 0x8F5F: - -// ORDa -case 0x815F: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x8367: -case 0x8567: -case 0x8767: -case 0x8967: -case 0x8B67: -case 0x8D67: -case 0x8F67: - -// ORDa -case 0x8167: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x8390: -case 0x8590: -case 0x8790: -case 0x8990: -case 0x8B90: -case 0x8D90: -case 0x8F90: -case 0x8191: -case 0x8391: -case 0x8591: -case 0x8791: -case 0x8991: -case 0x8B91: -case 0x8D91: -case 0x8F91: -case 0x8192: -case 0x8392: -case 0x8592: -case 0x8792: -case 0x8992: -case 0x8B92: -case 0x8D92: -case 0x8F92: -case 0x8193: -case 0x8393: -case 0x8593: -case 0x8793: -case 0x8993: -case 0x8B93: -case 0x8D93: -case 0x8F93: -case 0x8194: -case 0x8394: -case 0x8594: -case 0x8794: -case 0x8994: -case 0x8B94: -case 0x8D94: -case 0x8F94: -case 0x8195: -case 0x8395: -case 0x8595: -case 0x8795: -case 0x8995: -case 0x8B95: -case 0x8D95: -case 0x8F95: -case 0x8196: -case 0x8396: -case 0x8596: -case 0x8796: -case 0x8996: -case 0x8B96: -case 0x8D96: -case 0x8F96: -case 0x8197: -case 0x8397: -case 0x8597: -case 0x8797: -case 0x8997: -case 0x8B97: -case 0x8D97: -case 0x8F97: - -// ORDa -case 0x8190: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x8398: -case 0x8598: -case 0x8798: -case 0x8998: -case 0x8B98: -case 0x8D98: -case 0x8F98: -case 0x8199: -case 0x8399: -case 0x8599: -case 0x8799: -case 0x8999: -case 0x8B99: -case 0x8D99: -case 0x8F99: -case 0x819A: -case 0x839A: -case 0x859A: -case 0x879A: -case 0x899A: -case 0x8B9A: -case 0x8D9A: -case 0x8F9A: -case 0x819B: -case 0x839B: -case 0x859B: -case 0x879B: -case 0x899B: -case 0x8B9B: -case 0x8D9B: -case 0x8F9B: -case 0x819C: -case 0x839C: -case 0x859C: -case 0x879C: -case 0x899C: -case 0x8B9C: -case 0x8D9C: -case 0x8F9C: -case 0x819D: -case 0x839D: -case 0x859D: -case 0x879D: -case 0x899D: -case 0x8B9D: -case 0x8D9D: -case 0x8F9D: -case 0x819E: -case 0x839E: -case 0x859E: -case 0x879E: -case 0x899E: -case 0x8B9E: -case 0x8D9E: -case 0x8F9E: - -// ORDa -case 0x8198: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x83A0: -case 0x85A0: -case 0x87A0: -case 0x89A0: -case 0x8BA0: -case 0x8DA0: -case 0x8FA0: -case 0x81A1: -case 0x83A1: -case 0x85A1: -case 0x87A1: -case 0x89A1: -case 0x8BA1: -case 0x8DA1: -case 0x8FA1: -case 0x81A2: -case 0x83A2: -case 0x85A2: -case 0x87A2: -case 0x89A2: -case 0x8BA2: -case 0x8DA2: -case 0x8FA2: -case 0x81A3: -case 0x83A3: -case 0x85A3: -case 0x87A3: -case 0x89A3: -case 0x8BA3: -case 0x8DA3: -case 0x8FA3: -case 0x81A4: -case 0x83A4: -case 0x85A4: -case 0x87A4: -case 0x89A4: -case 0x8BA4: -case 0x8DA4: -case 0x8FA4: -case 0x81A5: -case 0x83A5: -case 0x85A5: -case 0x87A5: -case 0x89A5: -case 0x8BA5: -case 0x8DA5: -case 0x8FA5: -case 0x81A6: -case 0x83A6: -case 0x85A6: -case 0x87A6: -case 0x89A6: -case 0x8BA6: -case 0x8DA6: -case 0x8FA6: - -// ORDa -case 0x81A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x83A8: -case 0x85A8: -case 0x87A8: -case 0x89A8: -case 0x8BA8: -case 0x8DA8: -case 0x8FA8: -case 0x81A9: -case 0x83A9: -case 0x85A9: -case 0x87A9: -case 0x89A9: -case 0x8BA9: -case 0x8DA9: -case 0x8FA9: -case 0x81AA: -case 0x83AA: -case 0x85AA: -case 0x87AA: -case 0x89AA: -case 0x8BAA: -case 0x8DAA: -case 0x8FAA: -case 0x81AB: -case 0x83AB: -case 0x85AB: -case 0x87AB: -case 0x89AB: -case 0x8BAB: -case 0x8DAB: -case 0x8FAB: -case 0x81AC: -case 0x83AC: -case 0x85AC: -case 0x87AC: -case 0x89AC: -case 0x8BAC: -case 0x8DAC: -case 0x8FAC: -case 0x81AD: -case 0x83AD: -case 0x85AD: -case 0x87AD: -case 0x89AD: -case 0x8BAD: -case 0x8DAD: -case 0x8FAD: -case 0x81AE: -case 0x83AE: -case 0x85AE: -case 0x87AE: -case 0x89AE: -case 0x8BAE: -case 0x8DAE: -case 0x8FAE: -case 0x81AF: -case 0x83AF: -case 0x85AF: -case 0x87AF: -case 0x89AF: -case 0x8BAF: -case 0x8DAF: -case 0x8FAF: - -// ORDa -case 0x81A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x83B0: -case 0x85B0: -case 0x87B0: -case 0x89B0: -case 0x8BB0: -case 0x8DB0: -case 0x8FB0: -case 0x81B1: -case 0x83B1: -case 0x85B1: -case 0x87B1: -case 0x89B1: -case 0x8BB1: -case 0x8DB1: -case 0x8FB1: -case 0x81B2: -case 0x83B2: -case 0x85B2: -case 0x87B2: -case 0x89B2: -case 0x8BB2: -case 0x8DB2: -case 0x8FB2: -case 0x81B3: -case 0x83B3: -case 0x85B3: -case 0x87B3: -case 0x89B3: -case 0x8BB3: -case 0x8DB3: -case 0x8FB3: -case 0x81B4: -case 0x83B4: -case 0x85B4: -case 0x87B4: -case 0x89B4: -case 0x8BB4: -case 0x8DB4: -case 0x8FB4: -case 0x81B5: -case 0x83B5: -case 0x85B5: -case 0x87B5: -case 0x89B5: -case 0x8BB5: -case 0x8DB5: -case 0x8FB5: -case 0x81B6: -case 0x83B6: -case 0x85B6: -case 0x87B6: -case 0x89B6: -case 0x8BB6: -case 0x8DB6: -case 0x8FB6: -case 0x81B7: -case 0x83B7: -case 0x85B7: -case 0x87B7: -case 0x89B7: -case 0x8BB7: -case 0x8DB7: -case 0x8FB7: - -// ORDa -case 0x81B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x83B8: -case 0x85B8: -case 0x87B8: -case 0x89B8: -case 0x8BB8: -case 0x8DB8: -case 0x8FB8: - -// ORDa -case 0x81B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x83B9: -case 0x85B9: -case 0x87B9: -case 0x89B9: -case 0x8BB9: -case 0x8DB9: -case 0x8FB9: - -// ORDa -case 0x81B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x839F: -case 0x859F: -case 0x879F: -case 0x899F: -case 0x8B9F: -case 0x8D9F: -case 0x8F9F: - -// ORDa -case 0x819F: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x83A7: -case 0x85A7: -case 0x87A7: -case 0x89A7: -case 0x8BA7: -case 0x8DA7: -case 0x8FA7: - -// ORDa -case 0x81A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x8300: -case 0x8500: -case 0x8700: -case 0x8900: -case 0x8B00: -case 0x8D00: -case 0x8F00: -case 0x8101: -case 0x8301: -case 0x8501: -case 0x8701: -case 0x8901: -case 0x8B01: -case 0x8D01: -case 0x8F01: -case 0x8102: -case 0x8302: -case 0x8502: -case 0x8702: -case 0x8902: -case 0x8B02: -case 0x8D02: -case 0x8F02: -case 0x8103: -case 0x8303: -case 0x8503: -case 0x8703: -case 0x8903: -case 0x8B03: -case 0x8D03: -case 0x8F03: -case 0x8104: -case 0x8304: -case 0x8504: -case 0x8704: -case 0x8904: -case 0x8B04: -case 0x8D04: -case 0x8F04: -case 0x8105: -case 0x8305: -case 0x8505: -case 0x8705: -case 0x8905: -case 0x8B05: -case 0x8D05: -case 0x8F05: -case 0x8106: -case 0x8306: -case 0x8506: -case 0x8706: -case 0x8906: -case 0x8B06: -case 0x8D06: -case 0x8F06: -case 0x8107: -case 0x8307: -case 0x8507: -case 0x8707: -case 0x8907: -case 0x8B07: -case 0x8D07: -case 0x8F07: - -// SBCD -case 0x8100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x8308: -case 0x8508: -case 0x8708: -case 0x8908: -case 0x8B08: -case 0x8D08: -case 0x8109: -case 0x8309: -case 0x8509: -case 0x8709: -case 0x8909: -case 0x8B09: -case 0x8D09: -case 0x810A: -case 0x830A: -case 0x850A: -case 0x870A: -case 0x890A: -case 0x8B0A: -case 0x8D0A: -case 0x810B: -case 0x830B: -case 0x850B: -case 0x870B: -case 0x890B: -case 0x8B0B: -case 0x8D0B: -case 0x810C: -case 0x830C: -case 0x850C: -case 0x870C: -case 0x890C: -case 0x8B0C: -case 0x8D0C: -case 0x810D: -case 0x830D: -case 0x850D: -case 0x870D: -case 0x890D: -case 0x8B0D: -case 0x8D0D: -case 0x810E: -case 0x830E: -case 0x850E: -case 0x870E: -case 0x890E: -case 0x8B0E: -case 0x8D0E: - -// SBCDM -case 0x8108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x830F: -case 0x850F: -case 0x870F: -case 0x890F: -case 0x8B0F: -case 0x8D0F: - -// SBCD7M -case 0x810F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x8F09: -case 0x8F0A: -case 0x8F0B: -case 0x8F0C: -case 0x8F0D: -case 0x8F0E: - -// SBCDM7 -case 0x8F08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// SBCD7M7 -case 0x8F0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x82C0: -case 0x84C0: -case 0x86C0: -case 0x88C0: -case 0x8AC0: -case 0x8CC0: -case 0x8EC0: -case 0x80C1: -case 0x82C1: -case 0x84C1: -case 0x86C1: -case 0x88C1: -case 0x8AC1: -case 0x8CC1: -case 0x8EC1: -case 0x80C2: -case 0x82C2: -case 0x84C2: -case 0x86C2: -case 0x88C2: -case 0x8AC2: -case 0x8CC2: -case 0x8EC2: -case 0x80C3: -case 0x82C3: -case 0x84C3: -case 0x86C3: -case 0x88C3: -case 0x8AC3: -case 0x8CC3: -case 0x8EC3: -case 0x80C4: -case 0x82C4: -case 0x84C4: -case 0x86C4: -case 0x88C4: -case 0x8AC4: -case 0x8CC4: -case 0x8EC4: -case 0x80C5: -case 0x82C5: -case 0x84C5: -case 0x86C5: -case 0x88C5: -case 0x8AC5: -case 0x8CC5: -case 0x8EC5: -case 0x80C6: -case 0x82C6: -case 0x84C6: -case 0x86C6: -case 0x88C6: -case 0x8AC6: -case 0x8CC6: -case 0x8EC6: -case 0x80C7: -case 0x82C7: -case 0x84C7: -case 0x86C7: -case 0x88C7: -case 0x8AC7: -case 0x8CC7: -case 0x8EC7: - -// DIVU -case 0x80C0: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(10) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(70) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(90) -case 0x82D0: -case 0x84D0: -case 0x86D0: -case 0x88D0: -case 0x8AD0: -case 0x8CD0: -case 0x8ED0: -case 0x80D1: -case 0x82D1: -case 0x84D1: -case 0x86D1: -case 0x88D1: -case 0x8AD1: -case 0x8CD1: -case 0x8ED1: -case 0x80D2: -case 0x82D2: -case 0x84D2: -case 0x86D2: -case 0x88D2: -case 0x8AD2: -case 0x8CD2: -case 0x8ED2: -case 0x80D3: -case 0x82D3: -case 0x84D3: -case 0x86D3: -case 0x88D3: -case 0x8AD3: -case 0x8CD3: -case 0x8ED3: -case 0x80D4: -case 0x82D4: -case 0x84D4: -case 0x86D4: -case 0x88D4: -case 0x8AD4: -case 0x8CD4: -case 0x8ED4: -case 0x80D5: -case 0x82D5: -case 0x84D5: -case 0x86D5: -case 0x88D5: -case 0x8AD5: -case 0x8CD5: -case 0x8ED5: -case 0x80D6: -case 0x82D6: -case 0x84D6: -case 0x86D6: -case 0x88D6: -case 0x8AD6: -case 0x8CD6: -case 0x8ED6: -case 0x80D7: -case 0x82D7: -case 0x84D7: -case 0x86D7: -case 0x88D7: -case 0x8AD7: -case 0x8CD7: -case 0x8ED7: - -// DIVU -case 0x80D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82D8: -case 0x84D8: -case 0x86D8: -case 0x88D8: -case 0x8AD8: -case 0x8CD8: -case 0x8ED8: -case 0x80D9: -case 0x82D9: -case 0x84D9: -case 0x86D9: -case 0x88D9: -case 0x8AD9: -case 0x8CD9: -case 0x8ED9: -case 0x80DA: -case 0x82DA: -case 0x84DA: -case 0x86DA: -case 0x88DA: -case 0x8ADA: -case 0x8CDA: -case 0x8EDA: -case 0x80DB: -case 0x82DB: -case 0x84DB: -case 0x86DB: -case 0x88DB: -case 0x8ADB: -case 0x8CDB: -case 0x8EDB: -case 0x80DC: -case 0x82DC: -case 0x84DC: -case 0x86DC: -case 0x88DC: -case 0x8ADC: -case 0x8CDC: -case 0x8EDC: -case 0x80DD: -case 0x82DD: -case 0x84DD: -case 0x86DD: -case 0x88DD: -case 0x8ADD: -case 0x8CDD: -case 0x8EDD: -case 0x80DE: -case 0x82DE: -case 0x84DE: -case 0x86DE: -case 0x88DE: -case 0x8ADE: -case 0x8CDE: -case 0x8EDE: - -// DIVU -case 0x80D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82E0: -case 0x84E0: -case 0x86E0: -case 0x88E0: -case 0x8AE0: -case 0x8CE0: -case 0x8EE0: -case 0x80E1: -case 0x82E1: -case 0x84E1: -case 0x86E1: -case 0x88E1: -case 0x8AE1: -case 0x8CE1: -case 0x8EE1: -case 0x80E2: -case 0x82E2: -case 0x84E2: -case 0x86E2: -case 0x88E2: -case 0x8AE2: -case 0x8CE2: -case 0x8EE2: -case 0x80E3: -case 0x82E3: -case 0x84E3: -case 0x86E3: -case 0x88E3: -case 0x8AE3: -case 0x8CE3: -case 0x8EE3: -case 0x80E4: -case 0x82E4: -case 0x84E4: -case 0x86E4: -case 0x88E4: -case 0x8AE4: -case 0x8CE4: -case 0x8EE4: -case 0x80E5: -case 0x82E5: -case 0x84E5: -case 0x86E5: -case 0x88E5: -case 0x8AE5: -case 0x8CE5: -case 0x8EE5: -case 0x80E6: -case 0x82E6: -case 0x84E6: -case 0x86E6: -case 0x88E6: -case 0x8AE6: -case 0x8CE6: -case 0x8EE6: - -// DIVU -case 0x80E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(76) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(96) -case 0x82E8: -case 0x84E8: -case 0x86E8: -case 0x88E8: -case 0x8AE8: -case 0x8CE8: -case 0x8EE8: -case 0x80E9: -case 0x82E9: -case 0x84E9: -case 0x86E9: -case 0x88E9: -case 0x8AE9: -case 0x8CE9: -case 0x8EE9: -case 0x80EA: -case 0x82EA: -case 0x84EA: -case 0x86EA: -case 0x88EA: -case 0x8AEA: -case 0x8CEA: -case 0x8EEA: -case 0x80EB: -case 0x82EB: -case 0x84EB: -case 0x86EB: -case 0x88EB: -case 0x8AEB: -case 0x8CEB: -case 0x8EEB: -case 0x80EC: -case 0x82EC: -case 0x84EC: -case 0x86EC: -case 0x88EC: -case 0x8AEC: -case 0x8CEC: -case 0x8EEC: -case 0x80ED: -case 0x82ED: -case 0x84ED: -case 0x86ED: -case 0x88ED: -case 0x8AED: -case 0x8CED: -case 0x8EED: -case 0x80EE: -case 0x82EE: -case 0x84EE: -case 0x86EE: -case 0x88EE: -case 0x8AEE: -case 0x8CEE: -case 0x8EEE: -case 0x80EF: -case 0x82EF: -case 0x84EF: -case 0x86EF: -case 0x88EF: -case 0x8AEF: -case 0x8CEF: -case 0x8EEF: - -// DIVU -case 0x80E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(78) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(98) -case 0x82F0: -case 0x84F0: -case 0x86F0: -case 0x88F0: -case 0x8AF0: -case 0x8CF0: -case 0x8EF0: -case 0x80F1: -case 0x82F1: -case 0x84F1: -case 0x86F1: -case 0x88F1: -case 0x8AF1: -case 0x8CF1: -case 0x8EF1: -case 0x80F2: -case 0x82F2: -case 0x84F2: -case 0x86F2: -case 0x88F2: -case 0x8AF2: -case 0x8CF2: -case 0x8EF2: -case 0x80F3: -case 0x82F3: -case 0x84F3: -case 0x86F3: -case 0x88F3: -case 0x8AF3: -case 0x8CF3: -case 0x8EF3: -case 0x80F4: -case 0x82F4: -case 0x84F4: -case 0x86F4: -case 0x88F4: -case 0x8AF4: -case 0x8CF4: -case 0x8EF4: -case 0x80F5: -case 0x82F5: -case 0x84F5: -case 0x86F5: -case 0x88F5: -case 0x8AF5: -case 0x8CF5: -case 0x8EF5: -case 0x80F6: -case 0x82F6: -case 0x84F6: -case 0x86F6: -case 0x88F6: -case 0x8AF6: -case 0x8CF6: -case 0x8EF6: -case 0x80F7: -case 0x82F7: -case 0x84F7: -case 0x86F7: -case 0x88F7: -case 0x8AF7: -case 0x8CF7: -case 0x8EF7: - -// DIVU -case 0x80F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(80) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(100) -case 0x82F8: -case 0x84F8: -case 0x86F8: -case 0x88F8: -case 0x8AF8: -case 0x8CF8: -case 0x8EF8: - -// DIVU -case 0x80F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(78) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(98) -case 0x82F9: -case 0x84F9: -case 0x86F9: -case 0x88F9: -case 0x8AF9: -case 0x8CF9: -case 0x8EF9: - -// DIVU -case 0x80F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(22) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(82) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(102) -case 0x82FA: -case 0x84FA: -case 0x86FA: -case 0x88FA: -case 0x8AFA: -case 0x8CFA: -case 0x8EFA: - -// DIVU -case 0x80FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(78) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(98) -case 0x82FB: -case 0x84FB: -case 0x86FB: -case 0x88FB: -case 0x8AFB: -case 0x8CFB: -case 0x8EFB: - -// DIVU -case 0x80FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(80) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(100) -case 0x82FC: -case 0x84FC: -case 0x86FC: -case 0x88FC: -case 0x8AFC: -case 0x8CFC: -case 0x8EFC: - -// DIVU -case 0x80FC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82DF: -case 0x84DF: -case 0x86DF: -case 0x88DF: -case 0x8ADF: -case 0x8CDF: -case 0x8EDF: - -// DIVU -case 0x80DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82E7: -case 0x84E7: -case 0x86E7: -case 0x88E7: -case 0x8AE7: -case 0x8CE7: -case 0x8EE7: - -// DIVU -case 0x80E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(76) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(96) -case 0x83C0: -case 0x85C0: -case 0x87C0: -case 0x89C0: -case 0x8BC0: -case 0x8DC0: -case 0x8FC0: -case 0x81C1: -case 0x83C1: -case 0x85C1: -case 0x87C1: -case 0x89C1: -case 0x8BC1: -case 0x8DC1: -case 0x8FC1: -case 0x81C2: -case 0x83C2: -case 0x85C2: -case 0x87C2: -case 0x89C2: -case 0x8BC2: -case 0x8DC2: -case 0x8FC2: -case 0x81C3: -case 0x83C3: -case 0x85C3: -case 0x87C3: -case 0x89C3: -case 0x8BC3: -case 0x8DC3: -case 0x8FC3: -case 0x81C4: -case 0x83C4: -case 0x85C4: -case 0x87C4: -case 0x89C4: -case 0x8BC4: -case 0x8DC4: -case 0x8FC4: -case 0x81C5: -case 0x83C5: -case 0x85C5: -case 0x87C5: -case 0x89C5: -case 0x8BC5: -case 0x8DC5: -case 0x8FC5: -case 0x81C6: -case 0x83C6: -case 0x85C6: -case 0x87C6: -case 0x89C6: -case 0x8BC6: -case 0x8DC6: -case 0x8FC6: -case 0x81C7: -case 0x83C7: -case 0x85C7: -case 0x87C7: -case 0x89C7: -case 0x8BC7: -case 0x8DC7: -case 0x8FC7: - -// DIVS -case 0x81C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(10) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(50) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(80) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(108) -case 0x83D0: -case 0x85D0: -case 0x87D0: -case 0x89D0: -case 0x8BD0: -case 0x8DD0: -case 0x8FD0: -case 0x81D1: -case 0x83D1: -case 0x85D1: -case 0x87D1: -case 0x89D1: -case 0x8BD1: -case 0x8DD1: -case 0x8FD1: -case 0x81D2: -case 0x83D2: -case 0x85D2: -case 0x87D2: -case 0x89D2: -case 0x8BD2: -case 0x8DD2: -case 0x8FD2: -case 0x81D3: -case 0x83D3: -case 0x85D3: -case 0x87D3: -case 0x89D3: -case 0x8BD3: -case 0x8DD3: -case 0x8FD3: -case 0x81D4: -case 0x83D4: -case 0x85D4: -case 0x87D4: -case 0x89D4: -case 0x8BD4: -case 0x8DD4: -case 0x8FD4: -case 0x81D5: -case 0x83D5: -case 0x85D5: -case 0x87D5: -case 0x89D5: -case 0x8BD5: -case 0x8DD5: -case 0x8FD5: -case 0x81D6: -case 0x83D6: -case 0x85D6: -case 0x87D6: -case 0x89D6: -case 0x8BD6: -case 0x8DD6: -case 0x8FD6: -case 0x81D7: -case 0x83D7: -case 0x85D7: -case 0x87D7: -case 0x89D7: -case 0x8BD7: -case 0x8DD7: -case 0x8FD7: - -// DIVS -case 0x81D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83D8: -case 0x85D8: -case 0x87D8: -case 0x89D8: -case 0x8BD8: -case 0x8DD8: -case 0x8FD8: -case 0x81D9: -case 0x83D9: -case 0x85D9: -case 0x87D9: -case 0x89D9: -case 0x8BD9: -case 0x8DD9: -case 0x8FD9: -case 0x81DA: -case 0x83DA: -case 0x85DA: -case 0x87DA: -case 0x89DA: -case 0x8BDA: -case 0x8DDA: -case 0x8FDA: -case 0x81DB: -case 0x83DB: -case 0x85DB: -case 0x87DB: -case 0x89DB: -case 0x8BDB: -case 0x8DDB: -case 0x8FDB: -case 0x81DC: -case 0x83DC: -case 0x85DC: -case 0x87DC: -case 0x89DC: -case 0x8BDC: -case 0x8DDC: -case 0x8FDC: -case 0x81DD: -case 0x83DD: -case 0x85DD: -case 0x87DD: -case 0x89DD: -case 0x8BDD: -case 0x8DDD: -case 0x8FDD: -case 0x81DE: -case 0x83DE: -case 0x85DE: -case 0x87DE: -case 0x89DE: -case 0x8BDE: -case 0x8DDE: -case 0x8FDE: - -// DIVS -case 0x81D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83E0: -case 0x85E0: -case 0x87E0: -case 0x89E0: -case 0x8BE0: -case 0x8DE0: -case 0x8FE0: -case 0x81E1: -case 0x83E1: -case 0x85E1: -case 0x87E1: -case 0x89E1: -case 0x8BE1: -case 0x8DE1: -case 0x8FE1: -case 0x81E2: -case 0x83E2: -case 0x85E2: -case 0x87E2: -case 0x89E2: -case 0x8BE2: -case 0x8DE2: -case 0x8FE2: -case 0x81E3: -case 0x83E3: -case 0x85E3: -case 0x87E3: -case 0x89E3: -case 0x8BE3: -case 0x8DE3: -case 0x8FE3: -case 0x81E4: -case 0x83E4: -case 0x85E4: -case 0x87E4: -case 0x89E4: -case 0x8BE4: -case 0x8DE4: -case 0x8FE4: -case 0x81E5: -case 0x83E5: -case 0x85E5: -case 0x87E5: -case 0x89E5: -case 0x8BE5: -case 0x8DE5: -case 0x8FE5: -case 0x81E6: -case 0x83E6: -case 0x85E6: -case 0x87E6: -case 0x89E6: -case 0x8BE6: -case 0x8DE6: -case 0x8FE6: - -// DIVS -case 0x81E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(56) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(86) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(114) -case 0x83E8: -case 0x85E8: -case 0x87E8: -case 0x89E8: -case 0x8BE8: -case 0x8DE8: -case 0x8FE8: -case 0x81E9: -case 0x83E9: -case 0x85E9: -case 0x87E9: -case 0x89E9: -case 0x8BE9: -case 0x8DE9: -case 0x8FE9: -case 0x81EA: -case 0x83EA: -case 0x85EA: -case 0x87EA: -case 0x89EA: -case 0x8BEA: -case 0x8DEA: -case 0x8FEA: -case 0x81EB: -case 0x83EB: -case 0x85EB: -case 0x87EB: -case 0x89EB: -case 0x8BEB: -case 0x8DEB: -case 0x8FEB: -case 0x81EC: -case 0x83EC: -case 0x85EC: -case 0x87EC: -case 0x89EC: -case 0x8BEC: -case 0x8DEC: -case 0x8FEC: -case 0x81ED: -case 0x83ED: -case 0x85ED: -case 0x87ED: -case 0x89ED: -case 0x8BED: -case 0x8DED: -case 0x8FED: -case 0x81EE: -case 0x83EE: -case 0x85EE: -case 0x87EE: -case 0x89EE: -case 0x8BEE: -case 0x8DEE: -case 0x8FEE: -case 0x81EF: -case 0x83EF: -case 0x85EF: -case 0x87EF: -case 0x89EF: -case 0x8BEF: -case 0x8DEF: -case 0x8FEF: - -// DIVS -case 0x81E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(58) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(88) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(116) -case 0x83F0: -case 0x85F0: -case 0x87F0: -case 0x89F0: -case 0x8BF0: -case 0x8DF0: -case 0x8FF0: -case 0x81F1: -case 0x83F1: -case 0x85F1: -case 0x87F1: -case 0x89F1: -case 0x8BF1: -case 0x8DF1: -case 0x8FF1: -case 0x81F2: -case 0x83F2: -case 0x85F2: -case 0x87F2: -case 0x89F2: -case 0x8BF2: -case 0x8DF2: -case 0x8FF2: -case 0x81F3: -case 0x83F3: -case 0x85F3: -case 0x87F3: -case 0x89F3: -case 0x8BF3: -case 0x8DF3: -case 0x8FF3: -case 0x81F4: -case 0x83F4: -case 0x85F4: -case 0x87F4: -case 0x89F4: -case 0x8BF4: -case 0x8DF4: -case 0x8FF4: -case 0x81F5: -case 0x83F5: -case 0x85F5: -case 0x87F5: -case 0x89F5: -case 0x8BF5: -case 0x8DF5: -case 0x8FF5: -case 0x81F6: -case 0x83F6: -case 0x85F6: -case 0x87F6: -case 0x89F6: -case 0x8BF6: -case 0x8DF6: -case 0x8FF6: -case 0x81F7: -case 0x83F7: -case 0x85F7: -case 0x87F7: -case 0x89F7: -case 0x8BF7: -case 0x8DF7: -case 0x8FF7: - -// DIVS -case 0x81F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(60) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(90) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(118) -case 0x83F8: -case 0x85F8: -case 0x87F8: -case 0x89F8: -case 0x8BF8: -case 0x8DF8: -case 0x8FF8: - -// DIVS -case 0x81F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(58) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(88) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(116) -case 0x83F9: -case 0x85F9: -case 0x87F9: -case 0x89F9: -case 0x8BF9: -case 0x8DF9: -case 0x8FF9: - -// DIVS -case 0x81F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(22) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(62) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(92) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(120) -case 0x83FA: -case 0x85FA: -case 0x87FA: -case 0x89FA: -case 0x8BFA: -case 0x8DFA: -case 0x8FFA: - -// DIVS -case 0x81FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(58) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(88) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(116) -case 0x83FB: -case 0x85FB: -case 0x87FB: -case 0x89FB: -case 0x8BFB: -case 0x8DFB: -case 0x8FFB: - -// DIVS -case 0x81FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(60) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(90) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(118) -case 0x83FC: -case 0x85FC: -case 0x87FC: -case 0x89FC: -case 0x8BFC: -case 0x8DFC: -case 0x8FFC: - -// DIVS -case 0x81FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83DF: -case 0x85DF: -case 0x87DF: -case 0x89DF: -case 0x8BDF: -case 0x8DDF: -case 0x8FDF: - -// DIVS -case 0x81DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83E7: -case 0x85E7: -case 0x87E7: -case 0x89E7: -case 0x8BE7: -case 0x8DE7: -case 0x8FE7: - -// DIVS -case 0x81E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(56) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(86) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(114) diff --git a/yabause/src/c68k/c68k_op9.inc b/yabause/src/c68k/c68k_op9.inc deleted file mode 100644 index ef0bdc95c1..0000000000 --- a/yabause/src/c68k/c68k_op9.inc +++ /dev/null @@ -1,5950 +0,0 @@ -case 0x9200: -case 0x9400: -case 0x9600: -case 0x9800: -case 0x9A00: -case 0x9C00: -case 0x9E00: -case 0x9001: -case 0x9201: -case 0x9401: -case 0x9601: -case 0x9801: -case 0x9A01: -case 0x9C01: -case 0x9E01: -case 0x9002: -case 0x9202: -case 0x9402: -case 0x9602: -case 0x9802: -case 0x9A02: -case 0x9C02: -case 0x9E02: -case 0x9003: -case 0x9203: -case 0x9403: -case 0x9603: -case 0x9803: -case 0x9A03: -case 0x9C03: -case 0x9E03: -case 0x9004: -case 0x9204: -case 0x9404: -case 0x9604: -case 0x9804: -case 0x9A04: -case 0x9C04: -case 0x9E04: -case 0x9005: -case 0x9205: -case 0x9405: -case 0x9605: -case 0x9805: -case 0x9A05: -case 0x9C05: -case 0x9E05: -case 0x9006: -case 0x9206: -case 0x9406: -case 0x9606: -case 0x9806: -case 0x9A06: -case 0x9C06: -case 0x9E06: -case 0x9007: -case 0x9207: -case 0x9407: -case 0x9607: -case 0x9807: -case 0x9A07: -case 0x9C07: -case 0x9E07: - -// SUBaD -case 0x9000: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9208: -case 0x9408: -case 0x9608: -case 0x9808: -case 0x9A08: -case 0x9C08: -case 0x9E08: -case 0x9009: -case 0x9209: -case 0x9409: -case 0x9609: -case 0x9809: -case 0x9A09: -case 0x9C09: -case 0x9E09: -case 0x900A: -case 0x920A: -case 0x940A: -case 0x960A: -case 0x980A: -case 0x9A0A: -case 0x9C0A: -case 0x9E0A: -case 0x900B: -case 0x920B: -case 0x940B: -case 0x960B: -case 0x980B: -case 0x9A0B: -case 0x9C0B: -case 0x9E0B: -case 0x900C: -case 0x920C: -case 0x940C: -case 0x960C: -case 0x980C: -case 0x9A0C: -case 0x9C0C: -case 0x9E0C: -case 0x900D: -case 0x920D: -case 0x940D: -case 0x960D: -case 0x980D: -case 0x9A0D: -case 0x9C0D: -case 0x9E0D: -case 0x900E: -case 0x920E: -case 0x940E: -case 0x960E: -case 0x980E: -case 0x9A0E: -case 0x9C0E: -case 0x9E0E: -case 0x900F: -case 0x920F: -case 0x940F: -case 0x960F: -case 0x980F: -case 0x9A0F: -case 0x9C0F: -case 0x9E0F: - -// SUBaD -case 0x9008: -{ - u32 res; - pointer dst; - pointer src; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9210: -case 0x9410: -case 0x9610: -case 0x9810: -case 0x9A10: -case 0x9C10: -case 0x9E10: -case 0x9011: -case 0x9211: -case 0x9411: -case 0x9611: -case 0x9811: -case 0x9A11: -case 0x9C11: -case 0x9E11: -case 0x9012: -case 0x9212: -case 0x9412: -case 0x9612: -case 0x9812: -case 0x9A12: -case 0x9C12: -case 0x9E12: -case 0x9013: -case 0x9213: -case 0x9413: -case 0x9613: -case 0x9813: -case 0x9A13: -case 0x9C13: -case 0x9E13: -case 0x9014: -case 0x9214: -case 0x9414: -case 0x9614: -case 0x9814: -case 0x9A14: -case 0x9C14: -case 0x9E14: -case 0x9015: -case 0x9215: -case 0x9415: -case 0x9615: -case 0x9815: -case 0x9A15: -case 0x9C15: -case 0x9E15: -case 0x9016: -case 0x9216: -case 0x9416: -case 0x9616: -case 0x9816: -case 0x9A16: -case 0x9C16: -case 0x9E16: -case 0x9017: -case 0x9217: -case 0x9417: -case 0x9617: -case 0x9817: -case 0x9A17: -case 0x9C17: -case 0x9E17: - -// SUBaD -case 0x9010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9218: -case 0x9418: -case 0x9618: -case 0x9818: -case 0x9A18: -case 0x9C18: -case 0x9E18: -case 0x9019: -case 0x9219: -case 0x9419: -case 0x9619: -case 0x9819: -case 0x9A19: -case 0x9C19: -case 0x9E19: -case 0x901A: -case 0x921A: -case 0x941A: -case 0x961A: -case 0x981A: -case 0x9A1A: -case 0x9C1A: -case 0x9E1A: -case 0x901B: -case 0x921B: -case 0x941B: -case 0x961B: -case 0x981B: -case 0x9A1B: -case 0x9C1B: -case 0x9E1B: -case 0x901C: -case 0x921C: -case 0x941C: -case 0x961C: -case 0x981C: -case 0x9A1C: -case 0x9C1C: -case 0x9E1C: -case 0x901D: -case 0x921D: -case 0x941D: -case 0x961D: -case 0x981D: -case 0x9A1D: -case 0x9C1D: -case 0x9E1D: -case 0x901E: -case 0x921E: -case 0x941E: -case 0x961E: -case 0x981E: -case 0x9A1E: -case 0x9C1E: -case 0x9E1E: - -// SUBaD -case 0x9018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9220: -case 0x9420: -case 0x9620: -case 0x9820: -case 0x9A20: -case 0x9C20: -case 0x9E20: -case 0x9021: -case 0x9221: -case 0x9421: -case 0x9621: -case 0x9821: -case 0x9A21: -case 0x9C21: -case 0x9E21: -case 0x9022: -case 0x9222: -case 0x9422: -case 0x9622: -case 0x9822: -case 0x9A22: -case 0x9C22: -case 0x9E22: -case 0x9023: -case 0x9223: -case 0x9423: -case 0x9623: -case 0x9823: -case 0x9A23: -case 0x9C23: -case 0x9E23: -case 0x9024: -case 0x9224: -case 0x9424: -case 0x9624: -case 0x9824: -case 0x9A24: -case 0x9C24: -case 0x9E24: -case 0x9025: -case 0x9225: -case 0x9425: -case 0x9625: -case 0x9825: -case 0x9A25: -case 0x9C25: -case 0x9E25: -case 0x9026: -case 0x9226: -case 0x9426: -case 0x9626: -case 0x9826: -case 0x9A26: -case 0x9C26: -case 0x9E26: - -// SUBaD -case 0x9020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9228: -case 0x9428: -case 0x9628: -case 0x9828: -case 0x9A28: -case 0x9C28: -case 0x9E28: -case 0x9029: -case 0x9229: -case 0x9429: -case 0x9629: -case 0x9829: -case 0x9A29: -case 0x9C29: -case 0x9E29: -case 0x902A: -case 0x922A: -case 0x942A: -case 0x962A: -case 0x982A: -case 0x9A2A: -case 0x9C2A: -case 0x9E2A: -case 0x902B: -case 0x922B: -case 0x942B: -case 0x962B: -case 0x982B: -case 0x9A2B: -case 0x9C2B: -case 0x9E2B: -case 0x902C: -case 0x922C: -case 0x942C: -case 0x962C: -case 0x982C: -case 0x9A2C: -case 0x9C2C: -case 0x9E2C: -case 0x902D: -case 0x922D: -case 0x942D: -case 0x962D: -case 0x982D: -case 0x9A2D: -case 0x9C2D: -case 0x9E2D: -case 0x902E: -case 0x922E: -case 0x942E: -case 0x962E: -case 0x982E: -case 0x9A2E: -case 0x9C2E: -case 0x9E2E: -case 0x902F: -case 0x922F: -case 0x942F: -case 0x962F: -case 0x982F: -case 0x9A2F: -case 0x9C2F: -case 0x9E2F: - -// SUBaD -case 0x9028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9230: -case 0x9430: -case 0x9630: -case 0x9830: -case 0x9A30: -case 0x9C30: -case 0x9E30: -case 0x9031: -case 0x9231: -case 0x9431: -case 0x9631: -case 0x9831: -case 0x9A31: -case 0x9C31: -case 0x9E31: -case 0x9032: -case 0x9232: -case 0x9432: -case 0x9632: -case 0x9832: -case 0x9A32: -case 0x9C32: -case 0x9E32: -case 0x9033: -case 0x9233: -case 0x9433: -case 0x9633: -case 0x9833: -case 0x9A33: -case 0x9C33: -case 0x9E33: -case 0x9034: -case 0x9234: -case 0x9434: -case 0x9634: -case 0x9834: -case 0x9A34: -case 0x9C34: -case 0x9E34: -case 0x9035: -case 0x9235: -case 0x9435: -case 0x9635: -case 0x9835: -case 0x9A35: -case 0x9C35: -case 0x9E35: -case 0x9036: -case 0x9236: -case 0x9436: -case 0x9636: -case 0x9836: -case 0x9A36: -case 0x9C36: -case 0x9E36: -case 0x9037: -case 0x9237: -case 0x9437: -case 0x9637: -case 0x9837: -case 0x9A37: -case 0x9C37: -case 0x9E37: - -// SUBaD -case 0x9030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x9238: -case 0x9438: -case 0x9638: -case 0x9838: -case 0x9A38: -case 0x9C38: -case 0x9E38: - -// SUBaD -case 0x9038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9239: -case 0x9439: -case 0x9639: -case 0x9839: -case 0x9A39: -case 0x9C39: -case 0x9E39: - -// SUBaD -case 0x9039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x923A: -case 0x943A: -case 0x963A: -case 0x983A: -case 0x9A3A: -case 0x9C3A: -case 0x9E3A: - -// SUBaD -case 0x903A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x923B: -case 0x943B: -case 0x963B: -case 0x983B: -case 0x9A3B: -case 0x9C3B: -case 0x9E3B: - -// SUBaD -case 0x903B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x923C: -case 0x943C: -case 0x963C: -case 0x983C: -case 0x9A3C: -case 0x9C3C: -case 0x9E3C: - -// SUBaD -case 0x903C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x921F: -case 0x941F: -case 0x961F: -case 0x981F: -case 0x9A1F: -case 0x9C1F: -case 0x9E1F: - -// SUBaD -case 0x901F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9227: -case 0x9427: -case 0x9627: -case 0x9827: -case 0x9A27: -case 0x9C27: -case 0x9E27: - -// SUBaD -case 0x9027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9240: -case 0x9440: -case 0x9640: -case 0x9840: -case 0x9A40: -case 0x9C40: -case 0x9E40: -case 0x9041: -case 0x9241: -case 0x9441: -case 0x9641: -case 0x9841: -case 0x9A41: -case 0x9C41: -case 0x9E41: -case 0x9042: -case 0x9242: -case 0x9442: -case 0x9642: -case 0x9842: -case 0x9A42: -case 0x9C42: -case 0x9E42: -case 0x9043: -case 0x9243: -case 0x9443: -case 0x9643: -case 0x9843: -case 0x9A43: -case 0x9C43: -case 0x9E43: -case 0x9044: -case 0x9244: -case 0x9444: -case 0x9644: -case 0x9844: -case 0x9A44: -case 0x9C44: -case 0x9E44: -case 0x9045: -case 0x9245: -case 0x9445: -case 0x9645: -case 0x9845: -case 0x9A45: -case 0x9C45: -case 0x9E45: -case 0x9046: -case 0x9246: -case 0x9446: -case 0x9646: -case 0x9846: -case 0x9A46: -case 0x9C46: -case 0x9E46: -case 0x9047: -case 0x9247: -case 0x9447: -case 0x9647: -case 0x9847: -case 0x9A47: -case 0x9C47: -case 0x9E47: - -// SUBaD -case 0x9040: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9248: -case 0x9448: -case 0x9648: -case 0x9848: -case 0x9A48: -case 0x9C48: -case 0x9E48: -case 0x9049: -case 0x9249: -case 0x9449: -case 0x9649: -case 0x9849: -case 0x9A49: -case 0x9C49: -case 0x9E49: -case 0x904A: -case 0x924A: -case 0x944A: -case 0x964A: -case 0x984A: -case 0x9A4A: -case 0x9C4A: -case 0x9E4A: -case 0x904B: -case 0x924B: -case 0x944B: -case 0x964B: -case 0x984B: -case 0x9A4B: -case 0x9C4B: -case 0x9E4B: -case 0x904C: -case 0x924C: -case 0x944C: -case 0x964C: -case 0x984C: -case 0x9A4C: -case 0x9C4C: -case 0x9E4C: -case 0x904D: -case 0x924D: -case 0x944D: -case 0x964D: -case 0x984D: -case 0x9A4D: -case 0x9C4D: -case 0x9E4D: -case 0x904E: -case 0x924E: -case 0x944E: -case 0x964E: -case 0x984E: -case 0x9A4E: -case 0x9C4E: -case 0x9E4E: -case 0x904F: -case 0x924F: -case 0x944F: -case 0x964F: -case 0x984F: -case 0x9A4F: -case 0x9C4F: -case 0x9E4F: - -// SUBaD -case 0x9048: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->A[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9250: -case 0x9450: -case 0x9650: -case 0x9850: -case 0x9A50: -case 0x9C50: -case 0x9E50: -case 0x9051: -case 0x9251: -case 0x9451: -case 0x9651: -case 0x9851: -case 0x9A51: -case 0x9C51: -case 0x9E51: -case 0x9052: -case 0x9252: -case 0x9452: -case 0x9652: -case 0x9852: -case 0x9A52: -case 0x9C52: -case 0x9E52: -case 0x9053: -case 0x9253: -case 0x9453: -case 0x9653: -case 0x9853: -case 0x9A53: -case 0x9C53: -case 0x9E53: -case 0x9054: -case 0x9254: -case 0x9454: -case 0x9654: -case 0x9854: -case 0x9A54: -case 0x9C54: -case 0x9E54: -case 0x9055: -case 0x9255: -case 0x9455: -case 0x9655: -case 0x9855: -case 0x9A55: -case 0x9C55: -case 0x9E55: -case 0x9056: -case 0x9256: -case 0x9456: -case 0x9656: -case 0x9856: -case 0x9A56: -case 0x9C56: -case 0x9E56: -case 0x9057: -case 0x9257: -case 0x9457: -case 0x9657: -case 0x9857: -case 0x9A57: -case 0x9C57: -case 0x9E57: - -// SUBaD -case 0x9050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9258: -case 0x9458: -case 0x9658: -case 0x9858: -case 0x9A58: -case 0x9C58: -case 0x9E58: -case 0x9059: -case 0x9259: -case 0x9459: -case 0x9659: -case 0x9859: -case 0x9A59: -case 0x9C59: -case 0x9E59: -case 0x905A: -case 0x925A: -case 0x945A: -case 0x965A: -case 0x985A: -case 0x9A5A: -case 0x9C5A: -case 0x9E5A: -case 0x905B: -case 0x925B: -case 0x945B: -case 0x965B: -case 0x985B: -case 0x9A5B: -case 0x9C5B: -case 0x9E5B: -case 0x905C: -case 0x925C: -case 0x945C: -case 0x965C: -case 0x985C: -case 0x9A5C: -case 0x9C5C: -case 0x9E5C: -case 0x905D: -case 0x925D: -case 0x945D: -case 0x965D: -case 0x985D: -case 0x9A5D: -case 0x9C5D: -case 0x9E5D: -case 0x905E: -case 0x925E: -case 0x945E: -case 0x965E: -case 0x985E: -case 0x9A5E: -case 0x9C5E: -case 0x9E5E: - -// SUBaD -case 0x9058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9260: -case 0x9460: -case 0x9660: -case 0x9860: -case 0x9A60: -case 0x9C60: -case 0x9E60: -case 0x9061: -case 0x9261: -case 0x9461: -case 0x9661: -case 0x9861: -case 0x9A61: -case 0x9C61: -case 0x9E61: -case 0x9062: -case 0x9262: -case 0x9462: -case 0x9662: -case 0x9862: -case 0x9A62: -case 0x9C62: -case 0x9E62: -case 0x9063: -case 0x9263: -case 0x9463: -case 0x9663: -case 0x9863: -case 0x9A63: -case 0x9C63: -case 0x9E63: -case 0x9064: -case 0x9264: -case 0x9464: -case 0x9664: -case 0x9864: -case 0x9A64: -case 0x9C64: -case 0x9E64: -case 0x9065: -case 0x9265: -case 0x9465: -case 0x9665: -case 0x9865: -case 0x9A65: -case 0x9C65: -case 0x9E65: -case 0x9066: -case 0x9266: -case 0x9466: -case 0x9666: -case 0x9866: -case 0x9A66: -case 0x9C66: -case 0x9E66: - -// SUBaD -case 0x9060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9268: -case 0x9468: -case 0x9668: -case 0x9868: -case 0x9A68: -case 0x9C68: -case 0x9E68: -case 0x9069: -case 0x9269: -case 0x9469: -case 0x9669: -case 0x9869: -case 0x9A69: -case 0x9C69: -case 0x9E69: -case 0x906A: -case 0x926A: -case 0x946A: -case 0x966A: -case 0x986A: -case 0x9A6A: -case 0x9C6A: -case 0x9E6A: -case 0x906B: -case 0x926B: -case 0x946B: -case 0x966B: -case 0x986B: -case 0x9A6B: -case 0x9C6B: -case 0x9E6B: -case 0x906C: -case 0x926C: -case 0x946C: -case 0x966C: -case 0x986C: -case 0x9A6C: -case 0x9C6C: -case 0x9E6C: -case 0x906D: -case 0x926D: -case 0x946D: -case 0x966D: -case 0x986D: -case 0x9A6D: -case 0x9C6D: -case 0x9E6D: -case 0x906E: -case 0x926E: -case 0x946E: -case 0x966E: -case 0x986E: -case 0x9A6E: -case 0x9C6E: -case 0x9E6E: -case 0x906F: -case 0x926F: -case 0x946F: -case 0x966F: -case 0x986F: -case 0x9A6F: -case 0x9C6F: -case 0x9E6F: - -// SUBaD -case 0x9068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9270: -case 0x9470: -case 0x9670: -case 0x9870: -case 0x9A70: -case 0x9C70: -case 0x9E70: -case 0x9071: -case 0x9271: -case 0x9471: -case 0x9671: -case 0x9871: -case 0x9A71: -case 0x9C71: -case 0x9E71: -case 0x9072: -case 0x9272: -case 0x9472: -case 0x9672: -case 0x9872: -case 0x9A72: -case 0x9C72: -case 0x9E72: -case 0x9073: -case 0x9273: -case 0x9473: -case 0x9673: -case 0x9873: -case 0x9A73: -case 0x9C73: -case 0x9E73: -case 0x9074: -case 0x9274: -case 0x9474: -case 0x9674: -case 0x9874: -case 0x9A74: -case 0x9C74: -case 0x9E74: -case 0x9075: -case 0x9275: -case 0x9475: -case 0x9675: -case 0x9875: -case 0x9A75: -case 0x9C75: -case 0x9E75: -case 0x9076: -case 0x9276: -case 0x9476: -case 0x9676: -case 0x9876: -case 0x9A76: -case 0x9C76: -case 0x9E76: -case 0x9077: -case 0x9277: -case 0x9477: -case 0x9677: -case 0x9877: -case 0x9A77: -case 0x9C77: -case 0x9E77: - -// SUBaD -case 0x9070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x9278: -case 0x9478: -case 0x9678: -case 0x9878: -case 0x9A78: -case 0x9C78: -case 0x9E78: - -// SUBaD -case 0x9078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9279: -case 0x9479: -case 0x9679: -case 0x9879: -case 0x9A79: -case 0x9C79: -case 0x9E79: - -// SUBaD -case 0x9079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x927A: -case 0x947A: -case 0x967A: -case 0x987A: -case 0x9A7A: -case 0x9C7A: -case 0x9E7A: - -// SUBaD -case 0x907A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x927B: -case 0x947B: -case 0x967B: -case 0x987B: -case 0x9A7B: -case 0x9C7B: -case 0x9E7B: - -// SUBaD -case 0x907B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x927C: -case 0x947C: -case 0x967C: -case 0x987C: -case 0x9A7C: -case 0x9C7C: -case 0x9E7C: - -// SUBaD -case 0x907C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x925F: -case 0x945F: -case 0x965F: -case 0x985F: -case 0x9A5F: -case 0x9C5F: -case 0x9E5F: - -// SUBaD -case 0x905F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9267: -case 0x9467: -case 0x9667: -case 0x9867: -case 0x9A67: -case 0x9C67: -case 0x9E67: - -// SUBaD -case 0x9067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9280: -case 0x9480: -case 0x9680: -case 0x9880: -case 0x9A80: -case 0x9C80: -case 0x9E80: -case 0x9081: -case 0x9281: -case 0x9481: -case 0x9681: -case 0x9881: -case 0x9A81: -case 0x9C81: -case 0x9E81: -case 0x9082: -case 0x9282: -case 0x9482: -case 0x9682: -case 0x9882: -case 0x9A82: -case 0x9C82: -case 0x9E82: -case 0x9083: -case 0x9283: -case 0x9483: -case 0x9683: -case 0x9883: -case 0x9A83: -case 0x9C83: -case 0x9E83: -case 0x9084: -case 0x9284: -case 0x9484: -case 0x9684: -case 0x9884: -case 0x9A84: -case 0x9C84: -case 0x9E84: -case 0x9085: -case 0x9285: -case 0x9485: -case 0x9685: -case 0x9885: -case 0x9A85: -case 0x9C85: -case 0x9E85: -case 0x9086: -case 0x9286: -case 0x9486: -case 0x9686: -case 0x9886: -case 0x9A86: -case 0x9C86: -case 0x9E86: -case 0x9087: -case 0x9287: -case 0x9487: -case 0x9687: -case 0x9887: -case 0x9A87: -case 0x9C87: -case 0x9E87: - -// SUBaD -case 0x9080: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x9288: -case 0x9488: -case 0x9688: -case 0x9888: -case 0x9A88: -case 0x9C88: -case 0x9E88: -case 0x9089: -case 0x9289: -case 0x9489: -case 0x9689: -case 0x9889: -case 0x9A89: -case 0x9C89: -case 0x9E89: -case 0x908A: -case 0x928A: -case 0x948A: -case 0x968A: -case 0x988A: -case 0x9A8A: -case 0x9C8A: -case 0x9E8A: -case 0x908B: -case 0x928B: -case 0x948B: -case 0x968B: -case 0x988B: -case 0x9A8B: -case 0x9C8B: -case 0x9E8B: -case 0x908C: -case 0x928C: -case 0x948C: -case 0x968C: -case 0x988C: -case 0x9A8C: -case 0x9C8C: -case 0x9E8C: -case 0x908D: -case 0x928D: -case 0x948D: -case 0x968D: -case 0x988D: -case 0x9A8D: -case 0x9C8D: -case 0x9E8D: -case 0x908E: -case 0x928E: -case 0x948E: -case 0x968E: -case 0x988E: -case 0x9A8E: -case 0x9C8E: -case 0x9E8E: -case 0x908F: -case 0x928F: -case 0x948F: -case 0x968F: -case 0x988F: -case 0x9A8F: -case 0x9C8F: -case 0x9E8F: - -// SUBaD -case 0x9088: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x9290: -case 0x9490: -case 0x9690: -case 0x9890: -case 0x9A90: -case 0x9C90: -case 0x9E90: -case 0x9091: -case 0x9291: -case 0x9491: -case 0x9691: -case 0x9891: -case 0x9A91: -case 0x9C91: -case 0x9E91: -case 0x9092: -case 0x9292: -case 0x9492: -case 0x9692: -case 0x9892: -case 0x9A92: -case 0x9C92: -case 0x9E92: -case 0x9093: -case 0x9293: -case 0x9493: -case 0x9693: -case 0x9893: -case 0x9A93: -case 0x9C93: -case 0x9E93: -case 0x9094: -case 0x9294: -case 0x9494: -case 0x9694: -case 0x9894: -case 0x9A94: -case 0x9C94: -case 0x9E94: -case 0x9095: -case 0x9295: -case 0x9495: -case 0x9695: -case 0x9895: -case 0x9A95: -case 0x9C95: -case 0x9E95: -case 0x9096: -case 0x9296: -case 0x9496: -case 0x9696: -case 0x9896: -case 0x9A96: -case 0x9C96: -case 0x9E96: -case 0x9097: -case 0x9297: -case 0x9497: -case 0x9697: -case 0x9897: -case 0x9A97: -case 0x9C97: -case 0x9E97: - -// SUBaD -case 0x9090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x9298: -case 0x9498: -case 0x9698: -case 0x9898: -case 0x9A98: -case 0x9C98: -case 0x9E98: -case 0x9099: -case 0x9299: -case 0x9499: -case 0x9699: -case 0x9899: -case 0x9A99: -case 0x9C99: -case 0x9E99: -case 0x909A: -case 0x929A: -case 0x949A: -case 0x969A: -case 0x989A: -case 0x9A9A: -case 0x9C9A: -case 0x9E9A: -case 0x909B: -case 0x929B: -case 0x949B: -case 0x969B: -case 0x989B: -case 0x9A9B: -case 0x9C9B: -case 0x9E9B: -case 0x909C: -case 0x929C: -case 0x949C: -case 0x969C: -case 0x989C: -case 0x9A9C: -case 0x9C9C: -case 0x9E9C: -case 0x909D: -case 0x929D: -case 0x949D: -case 0x969D: -case 0x989D: -case 0x9A9D: -case 0x9C9D: -case 0x9E9D: -case 0x909E: -case 0x929E: -case 0x949E: -case 0x969E: -case 0x989E: -case 0x9A9E: -case 0x9C9E: -case 0x9E9E: - -// SUBaD -case 0x9098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x92A0: -case 0x94A0: -case 0x96A0: -case 0x98A0: -case 0x9AA0: -case 0x9CA0: -case 0x9EA0: -case 0x90A1: -case 0x92A1: -case 0x94A1: -case 0x96A1: -case 0x98A1: -case 0x9AA1: -case 0x9CA1: -case 0x9EA1: -case 0x90A2: -case 0x92A2: -case 0x94A2: -case 0x96A2: -case 0x98A2: -case 0x9AA2: -case 0x9CA2: -case 0x9EA2: -case 0x90A3: -case 0x92A3: -case 0x94A3: -case 0x96A3: -case 0x98A3: -case 0x9AA3: -case 0x9CA3: -case 0x9EA3: -case 0x90A4: -case 0x92A4: -case 0x94A4: -case 0x96A4: -case 0x98A4: -case 0x9AA4: -case 0x9CA4: -case 0x9EA4: -case 0x90A5: -case 0x92A5: -case 0x94A5: -case 0x96A5: -case 0x98A5: -case 0x9AA5: -case 0x9CA5: -case 0x9EA5: -case 0x90A6: -case 0x92A6: -case 0x94A6: -case 0x96A6: -case 0x98A6: -case 0x9AA6: -case 0x9CA6: -case 0x9EA6: - -// SUBaD -case 0x90A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x92A8: -case 0x94A8: -case 0x96A8: -case 0x98A8: -case 0x9AA8: -case 0x9CA8: -case 0x9EA8: -case 0x90A9: -case 0x92A9: -case 0x94A9: -case 0x96A9: -case 0x98A9: -case 0x9AA9: -case 0x9CA9: -case 0x9EA9: -case 0x90AA: -case 0x92AA: -case 0x94AA: -case 0x96AA: -case 0x98AA: -case 0x9AAA: -case 0x9CAA: -case 0x9EAA: -case 0x90AB: -case 0x92AB: -case 0x94AB: -case 0x96AB: -case 0x98AB: -case 0x9AAB: -case 0x9CAB: -case 0x9EAB: -case 0x90AC: -case 0x92AC: -case 0x94AC: -case 0x96AC: -case 0x98AC: -case 0x9AAC: -case 0x9CAC: -case 0x9EAC: -case 0x90AD: -case 0x92AD: -case 0x94AD: -case 0x96AD: -case 0x98AD: -case 0x9AAD: -case 0x9CAD: -case 0x9EAD: -case 0x90AE: -case 0x92AE: -case 0x94AE: -case 0x96AE: -case 0x98AE: -case 0x9AAE: -case 0x9CAE: -case 0x9EAE: -case 0x90AF: -case 0x92AF: -case 0x94AF: -case 0x96AF: -case 0x98AF: -case 0x9AAF: -case 0x9CAF: -case 0x9EAF: - -// SUBaD -case 0x90A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x92B0: -case 0x94B0: -case 0x96B0: -case 0x98B0: -case 0x9AB0: -case 0x9CB0: -case 0x9EB0: -case 0x90B1: -case 0x92B1: -case 0x94B1: -case 0x96B1: -case 0x98B1: -case 0x9AB1: -case 0x9CB1: -case 0x9EB1: -case 0x90B2: -case 0x92B2: -case 0x94B2: -case 0x96B2: -case 0x98B2: -case 0x9AB2: -case 0x9CB2: -case 0x9EB2: -case 0x90B3: -case 0x92B3: -case 0x94B3: -case 0x96B3: -case 0x98B3: -case 0x9AB3: -case 0x9CB3: -case 0x9EB3: -case 0x90B4: -case 0x92B4: -case 0x94B4: -case 0x96B4: -case 0x98B4: -case 0x9AB4: -case 0x9CB4: -case 0x9EB4: -case 0x90B5: -case 0x92B5: -case 0x94B5: -case 0x96B5: -case 0x98B5: -case 0x9AB5: -case 0x9CB5: -case 0x9EB5: -case 0x90B6: -case 0x92B6: -case 0x94B6: -case 0x96B6: -case 0x98B6: -case 0x9AB6: -case 0x9CB6: -case 0x9EB6: -case 0x90B7: -case 0x92B7: -case 0x94B7: -case 0x96B7: -case 0x98B7: -case 0x9AB7: -case 0x9CB7: -case 0x9EB7: - -// SUBaD -case 0x90B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x92B8: -case 0x94B8: -case 0x96B8: -case 0x98B8: -case 0x9AB8: -case 0x9CB8: -case 0x9EB8: - -// SUBaD -case 0x90B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x92B9: -case 0x94B9: -case 0x96B9: -case 0x98B9: -case 0x9AB9: -case 0x9CB9: -case 0x9EB9: - -// SUBaD -case 0x90B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0x92BA: -case 0x94BA: -case 0x96BA: -case 0x98BA: -case 0x9ABA: -case 0x9CBA: -case 0x9EBA: - -// SUBaD -case 0x90BA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x92BB: -case 0x94BB: -case 0x96BB: -case 0x98BB: -case 0x9ABB: -case 0x9CBB: -case 0x9EBB: - -// SUBaD -case 0x90BB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x92BC: -case 0x94BC: -case 0x96BC: -case 0x98BC: -case 0x9ABC: -case 0x9CBC: -case 0x9EBC: - -// SUBaD -case 0x90BC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0x929F: -case 0x949F: -case 0x969F: -case 0x989F: -case 0x9A9F: -case 0x9C9F: -case 0x9E9F: - -// SUBaD -case 0x909F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x92A7: -case 0x94A7: -case 0x96A7: -case 0x98A7: -case 0x9AA7: -case 0x9CA7: -case 0x9EA7: - -// SUBaD -case 0x90A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x9310: -case 0x9510: -case 0x9710: -case 0x9910: -case 0x9B10: -case 0x9D10: -case 0x9F10: -case 0x9111: -case 0x9311: -case 0x9511: -case 0x9711: -case 0x9911: -case 0x9B11: -case 0x9D11: -case 0x9F11: -case 0x9112: -case 0x9312: -case 0x9512: -case 0x9712: -case 0x9912: -case 0x9B12: -case 0x9D12: -case 0x9F12: -case 0x9113: -case 0x9313: -case 0x9513: -case 0x9713: -case 0x9913: -case 0x9B13: -case 0x9D13: -case 0x9F13: -case 0x9114: -case 0x9314: -case 0x9514: -case 0x9714: -case 0x9914: -case 0x9B14: -case 0x9D14: -case 0x9F14: -case 0x9115: -case 0x9315: -case 0x9515: -case 0x9715: -case 0x9915: -case 0x9B15: -case 0x9D15: -case 0x9F15: -case 0x9116: -case 0x9316: -case 0x9516: -case 0x9716: -case 0x9916: -case 0x9B16: -case 0x9D16: -case 0x9F16: -case 0x9117: -case 0x9317: -case 0x9517: -case 0x9717: -case 0x9917: -case 0x9B17: -case 0x9D17: -case 0x9F17: - -// SUBDa -case 0x9110: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x9318: -case 0x9518: -case 0x9718: -case 0x9918: -case 0x9B18: -case 0x9D18: -case 0x9F18: -case 0x9119: -case 0x9319: -case 0x9519: -case 0x9719: -case 0x9919: -case 0x9B19: -case 0x9D19: -case 0x9F19: -case 0x911A: -case 0x931A: -case 0x951A: -case 0x971A: -case 0x991A: -case 0x9B1A: -case 0x9D1A: -case 0x9F1A: -case 0x911B: -case 0x931B: -case 0x951B: -case 0x971B: -case 0x991B: -case 0x9B1B: -case 0x9D1B: -case 0x9F1B: -case 0x911C: -case 0x931C: -case 0x951C: -case 0x971C: -case 0x991C: -case 0x9B1C: -case 0x9D1C: -case 0x9F1C: -case 0x911D: -case 0x931D: -case 0x951D: -case 0x971D: -case 0x991D: -case 0x9B1D: -case 0x9D1D: -case 0x9F1D: -case 0x911E: -case 0x931E: -case 0x951E: -case 0x971E: -case 0x991E: -case 0x9B1E: -case 0x9D1E: -case 0x9F1E: - -// SUBDa -case 0x9118: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x9320: -case 0x9520: -case 0x9720: -case 0x9920: -case 0x9B20: -case 0x9D20: -case 0x9F20: -case 0x9121: -case 0x9321: -case 0x9521: -case 0x9721: -case 0x9921: -case 0x9B21: -case 0x9D21: -case 0x9F21: -case 0x9122: -case 0x9322: -case 0x9522: -case 0x9722: -case 0x9922: -case 0x9B22: -case 0x9D22: -case 0x9F22: -case 0x9123: -case 0x9323: -case 0x9523: -case 0x9723: -case 0x9923: -case 0x9B23: -case 0x9D23: -case 0x9F23: -case 0x9124: -case 0x9324: -case 0x9524: -case 0x9724: -case 0x9924: -case 0x9B24: -case 0x9D24: -case 0x9F24: -case 0x9125: -case 0x9325: -case 0x9525: -case 0x9725: -case 0x9925: -case 0x9B25: -case 0x9D25: -case 0x9F25: -case 0x9126: -case 0x9326: -case 0x9526: -case 0x9726: -case 0x9926: -case 0x9B26: -case 0x9D26: -case 0x9F26: - -// SUBDa -case 0x9120: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x9328: -case 0x9528: -case 0x9728: -case 0x9928: -case 0x9B28: -case 0x9D28: -case 0x9F28: -case 0x9129: -case 0x9329: -case 0x9529: -case 0x9729: -case 0x9929: -case 0x9B29: -case 0x9D29: -case 0x9F29: -case 0x912A: -case 0x932A: -case 0x952A: -case 0x972A: -case 0x992A: -case 0x9B2A: -case 0x9D2A: -case 0x9F2A: -case 0x912B: -case 0x932B: -case 0x952B: -case 0x972B: -case 0x992B: -case 0x9B2B: -case 0x9D2B: -case 0x9F2B: -case 0x912C: -case 0x932C: -case 0x952C: -case 0x972C: -case 0x992C: -case 0x9B2C: -case 0x9D2C: -case 0x9F2C: -case 0x912D: -case 0x932D: -case 0x952D: -case 0x972D: -case 0x992D: -case 0x9B2D: -case 0x9D2D: -case 0x9F2D: -case 0x912E: -case 0x932E: -case 0x952E: -case 0x972E: -case 0x992E: -case 0x9B2E: -case 0x9D2E: -case 0x9F2E: -case 0x912F: -case 0x932F: -case 0x952F: -case 0x972F: -case 0x992F: -case 0x9B2F: -case 0x9D2F: -case 0x9F2F: - -// SUBDa -case 0x9128: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x9330: -case 0x9530: -case 0x9730: -case 0x9930: -case 0x9B30: -case 0x9D30: -case 0x9F30: -case 0x9131: -case 0x9331: -case 0x9531: -case 0x9731: -case 0x9931: -case 0x9B31: -case 0x9D31: -case 0x9F31: -case 0x9132: -case 0x9332: -case 0x9532: -case 0x9732: -case 0x9932: -case 0x9B32: -case 0x9D32: -case 0x9F32: -case 0x9133: -case 0x9333: -case 0x9533: -case 0x9733: -case 0x9933: -case 0x9B33: -case 0x9D33: -case 0x9F33: -case 0x9134: -case 0x9334: -case 0x9534: -case 0x9734: -case 0x9934: -case 0x9B34: -case 0x9D34: -case 0x9F34: -case 0x9135: -case 0x9335: -case 0x9535: -case 0x9735: -case 0x9935: -case 0x9B35: -case 0x9D35: -case 0x9F35: -case 0x9136: -case 0x9336: -case 0x9536: -case 0x9736: -case 0x9936: -case 0x9B36: -case 0x9D36: -case 0x9F36: -case 0x9137: -case 0x9337: -case 0x9537: -case 0x9737: -case 0x9937: -case 0x9B37: -case 0x9D37: -case 0x9F37: - -// SUBDa -case 0x9130: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x9338: -case 0x9538: -case 0x9738: -case 0x9938: -case 0x9B38: -case 0x9D38: -case 0x9F38: - -// SUBDa -case 0x9138: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x9339: -case 0x9539: -case 0x9739: -case 0x9939: -case 0x9B39: -case 0x9D39: -case 0x9F39: - -// SUBDa -case 0x9139: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x931F: -case 0x951F: -case 0x971F: -case 0x991F: -case 0x9B1F: -case 0x9D1F: -case 0x9F1F: - -// SUBDa -case 0x911F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x9327: -case 0x9527: -case 0x9727: -case 0x9927: -case 0x9B27: -case 0x9D27: -case 0x9F27: - -// SUBDa -case 0x9127: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x9350: -case 0x9550: -case 0x9750: -case 0x9950: -case 0x9B50: -case 0x9D50: -case 0x9F50: -case 0x9151: -case 0x9351: -case 0x9551: -case 0x9751: -case 0x9951: -case 0x9B51: -case 0x9D51: -case 0x9F51: -case 0x9152: -case 0x9352: -case 0x9552: -case 0x9752: -case 0x9952: -case 0x9B52: -case 0x9D52: -case 0x9F52: -case 0x9153: -case 0x9353: -case 0x9553: -case 0x9753: -case 0x9953: -case 0x9B53: -case 0x9D53: -case 0x9F53: -case 0x9154: -case 0x9354: -case 0x9554: -case 0x9754: -case 0x9954: -case 0x9B54: -case 0x9D54: -case 0x9F54: -case 0x9155: -case 0x9355: -case 0x9555: -case 0x9755: -case 0x9955: -case 0x9B55: -case 0x9D55: -case 0x9F55: -case 0x9156: -case 0x9356: -case 0x9556: -case 0x9756: -case 0x9956: -case 0x9B56: -case 0x9D56: -case 0x9F56: -case 0x9157: -case 0x9357: -case 0x9557: -case 0x9757: -case 0x9957: -case 0x9B57: -case 0x9D57: -case 0x9F57: - -// SUBDa -case 0x9150: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x9358: -case 0x9558: -case 0x9758: -case 0x9958: -case 0x9B58: -case 0x9D58: -case 0x9F58: -case 0x9159: -case 0x9359: -case 0x9559: -case 0x9759: -case 0x9959: -case 0x9B59: -case 0x9D59: -case 0x9F59: -case 0x915A: -case 0x935A: -case 0x955A: -case 0x975A: -case 0x995A: -case 0x9B5A: -case 0x9D5A: -case 0x9F5A: -case 0x915B: -case 0x935B: -case 0x955B: -case 0x975B: -case 0x995B: -case 0x9B5B: -case 0x9D5B: -case 0x9F5B: -case 0x915C: -case 0x935C: -case 0x955C: -case 0x975C: -case 0x995C: -case 0x9B5C: -case 0x9D5C: -case 0x9F5C: -case 0x915D: -case 0x935D: -case 0x955D: -case 0x975D: -case 0x995D: -case 0x9B5D: -case 0x9D5D: -case 0x9F5D: -case 0x915E: -case 0x935E: -case 0x955E: -case 0x975E: -case 0x995E: -case 0x9B5E: -case 0x9D5E: -case 0x9F5E: - -// SUBDa -case 0x9158: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x9360: -case 0x9560: -case 0x9760: -case 0x9960: -case 0x9B60: -case 0x9D60: -case 0x9F60: -case 0x9161: -case 0x9361: -case 0x9561: -case 0x9761: -case 0x9961: -case 0x9B61: -case 0x9D61: -case 0x9F61: -case 0x9162: -case 0x9362: -case 0x9562: -case 0x9762: -case 0x9962: -case 0x9B62: -case 0x9D62: -case 0x9F62: -case 0x9163: -case 0x9363: -case 0x9563: -case 0x9763: -case 0x9963: -case 0x9B63: -case 0x9D63: -case 0x9F63: -case 0x9164: -case 0x9364: -case 0x9564: -case 0x9764: -case 0x9964: -case 0x9B64: -case 0x9D64: -case 0x9F64: -case 0x9165: -case 0x9365: -case 0x9565: -case 0x9765: -case 0x9965: -case 0x9B65: -case 0x9D65: -case 0x9F65: -case 0x9166: -case 0x9366: -case 0x9566: -case 0x9766: -case 0x9966: -case 0x9B66: -case 0x9D66: -case 0x9F66: - -// SUBDa -case 0x9160: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x9368: -case 0x9568: -case 0x9768: -case 0x9968: -case 0x9B68: -case 0x9D68: -case 0x9F68: -case 0x9169: -case 0x9369: -case 0x9569: -case 0x9769: -case 0x9969: -case 0x9B69: -case 0x9D69: -case 0x9F69: -case 0x916A: -case 0x936A: -case 0x956A: -case 0x976A: -case 0x996A: -case 0x9B6A: -case 0x9D6A: -case 0x9F6A: -case 0x916B: -case 0x936B: -case 0x956B: -case 0x976B: -case 0x996B: -case 0x9B6B: -case 0x9D6B: -case 0x9F6B: -case 0x916C: -case 0x936C: -case 0x956C: -case 0x976C: -case 0x996C: -case 0x9B6C: -case 0x9D6C: -case 0x9F6C: -case 0x916D: -case 0x936D: -case 0x956D: -case 0x976D: -case 0x996D: -case 0x9B6D: -case 0x9D6D: -case 0x9F6D: -case 0x916E: -case 0x936E: -case 0x956E: -case 0x976E: -case 0x996E: -case 0x9B6E: -case 0x9D6E: -case 0x9F6E: -case 0x916F: -case 0x936F: -case 0x956F: -case 0x976F: -case 0x996F: -case 0x9B6F: -case 0x9D6F: -case 0x9F6F: - -// SUBDa -case 0x9168: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x9370: -case 0x9570: -case 0x9770: -case 0x9970: -case 0x9B70: -case 0x9D70: -case 0x9F70: -case 0x9171: -case 0x9371: -case 0x9571: -case 0x9771: -case 0x9971: -case 0x9B71: -case 0x9D71: -case 0x9F71: -case 0x9172: -case 0x9372: -case 0x9572: -case 0x9772: -case 0x9972: -case 0x9B72: -case 0x9D72: -case 0x9F72: -case 0x9173: -case 0x9373: -case 0x9573: -case 0x9773: -case 0x9973: -case 0x9B73: -case 0x9D73: -case 0x9F73: -case 0x9174: -case 0x9374: -case 0x9574: -case 0x9774: -case 0x9974: -case 0x9B74: -case 0x9D74: -case 0x9F74: -case 0x9175: -case 0x9375: -case 0x9575: -case 0x9775: -case 0x9975: -case 0x9B75: -case 0x9D75: -case 0x9F75: -case 0x9176: -case 0x9376: -case 0x9576: -case 0x9776: -case 0x9976: -case 0x9B76: -case 0x9D76: -case 0x9F76: -case 0x9177: -case 0x9377: -case 0x9577: -case 0x9777: -case 0x9977: -case 0x9B77: -case 0x9D77: -case 0x9F77: - -// SUBDa -case 0x9170: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x9378: -case 0x9578: -case 0x9778: -case 0x9978: -case 0x9B78: -case 0x9D78: -case 0x9F78: - -// SUBDa -case 0x9178: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x9379: -case 0x9579: -case 0x9779: -case 0x9979: -case 0x9B79: -case 0x9D79: -case 0x9F79: - -// SUBDa -case 0x9179: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x935F: -case 0x955F: -case 0x975F: -case 0x995F: -case 0x9B5F: -case 0x9D5F: -case 0x9F5F: - -// SUBDa -case 0x915F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x9367: -case 0x9567: -case 0x9767: -case 0x9967: -case 0x9B67: -case 0x9D67: -case 0x9F67: - -// SUBDa -case 0x9167: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x9390: -case 0x9590: -case 0x9790: -case 0x9990: -case 0x9B90: -case 0x9D90: -case 0x9F90: -case 0x9191: -case 0x9391: -case 0x9591: -case 0x9791: -case 0x9991: -case 0x9B91: -case 0x9D91: -case 0x9F91: -case 0x9192: -case 0x9392: -case 0x9592: -case 0x9792: -case 0x9992: -case 0x9B92: -case 0x9D92: -case 0x9F92: -case 0x9193: -case 0x9393: -case 0x9593: -case 0x9793: -case 0x9993: -case 0x9B93: -case 0x9D93: -case 0x9F93: -case 0x9194: -case 0x9394: -case 0x9594: -case 0x9794: -case 0x9994: -case 0x9B94: -case 0x9D94: -case 0x9F94: -case 0x9195: -case 0x9395: -case 0x9595: -case 0x9795: -case 0x9995: -case 0x9B95: -case 0x9D95: -case 0x9F95: -case 0x9196: -case 0x9396: -case 0x9596: -case 0x9796: -case 0x9996: -case 0x9B96: -case 0x9D96: -case 0x9F96: -case 0x9197: -case 0x9397: -case 0x9597: -case 0x9797: -case 0x9997: -case 0x9B97: -case 0x9D97: -case 0x9F97: - -// SUBDa -case 0x9190: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x9398: -case 0x9598: -case 0x9798: -case 0x9998: -case 0x9B98: -case 0x9D98: -case 0x9F98: -case 0x9199: -case 0x9399: -case 0x9599: -case 0x9799: -case 0x9999: -case 0x9B99: -case 0x9D99: -case 0x9F99: -case 0x919A: -case 0x939A: -case 0x959A: -case 0x979A: -case 0x999A: -case 0x9B9A: -case 0x9D9A: -case 0x9F9A: -case 0x919B: -case 0x939B: -case 0x959B: -case 0x979B: -case 0x999B: -case 0x9B9B: -case 0x9D9B: -case 0x9F9B: -case 0x919C: -case 0x939C: -case 0x959C: -case 0x979C: -case 0x999C: -case 0x9B9C: -case 0x9D9C: -case 0x9F9C: -case 0x919D: -case 0x939D: -case 0x959D: -case 0x979D: -case 0x999D: -case 0x9B9D: -case 0x9D9D: -case 0x9F9D: -case 0x919E: -case 0x939E: -case 0x959E: -case 0x979E: -case 0x999E: -case 0x9B9E: -case 0x9D9E: -case 0x9F9E: - -// SUBDa -case 0x9198: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x93A0: -case 0x95A0: -case 0x97A0: -case 0x99A0: -case 0x9BA0: -case 0x9DA0: -case 0x9FA0: -case 0x91A1: -case 0x93A1: -case 0x95A1: -case 0x97A1: -case 0x99A1: -case 0x9BA1: -case 0x9DA1: -case 0x9FA1: -case 0x91A2: -case 0x93A2: -case 0x95A2: -case 0x97A2: -case 0x99A2: -case 0x9BA2: -case 0x9DA2: -case 0x9FA2: -case 0x91A3: -case 0x93A3: -case 0x95A3: -case 0x97A3: -case 0x99A3: -case 0x9BA3: -case 0x9DA3: -case 0x9FA3: -case 0x91A4: -case 0x93A4: -case 0x95A4: -case 0x97A4: -case 0x99A4: -case 0x9BA4: -case 0x9DA4: -case 0x9FA4: -case 0x91A5: -case 0x93A5: -case 0x95A5: -case 0x97A5: -case 0x99A5: -case 0x9BA5: -case 0x9DA5: -case 0x9FA5: -case 0x91A6: -case 0x93A6: -case 0x95A6: -case 0x97A6: -case 0x99A6: -case 0x9BA6: -case 0x9DA6: -case 0x9FA6: - -// SUBDa -case 0x91A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x93A8: -case 0x95A8: -case 0x97A8: -case 0x99A8: -case 0x9BA8: -case 0x9DA8: -case 0x9FA8: -case 0x91A9: -case 0x93A9: -case 0x95A9: -case 0x97A9: -case 0x99A9: -case 0x9BA9: -case 0x9DA9: -case 0x9FA9: -case 0x91AA: -case 0x93AA: -case 0x95AA: -case 0x97AA: -case 0x99AA: -case 0x9BAA: -case 0x9DAA: -case 0x9FAA: -case 0x91AB: -case 0x93AB: -case 0x95AB: -case 0x97AB: -case 0x99AB: -case 0x9BAB: -case 0x9DAB: -case 0x9FAB: -case 0x91AC: -case 0x93AC: -case 0x95AC: -case 0x97AC: -case 0x99AC: -case 0x9BAC: -case 0x9DAC: -case 0x9FAC: -case 0x91AD: -case 0x93AD: -case 0x95AD: -case 0x97AD: -case 0x99AD: -case 0x9BAD: -case 0x9DAD: -case 0x9FAD: -case 0x91AE: -case 0x93AE: -case 0x95AE: -case 0x97AE: -case 0x99AE: -case 0x9BAE: -case 0x9DAE: -case 0x9FAE: -case 0x91AF: -case 0x93AF: -case 0x95AF: -case 0x97AF: -case 0x99AF: -case 0x9BAF: -case 0x9DAF: -case 0x9FAF: - -// SUBDa -case 0x91A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x93B0: -case 0x95B0: -case 0x97B0: -case 0x99B0: -case 0x9BB0: -case 0x9DB0: -case 0x9FB0: -case 0x91B1: -case 0x93B1: -case 0x95B1: -case 0x97B1: -case 0x99B1: -case 0x9BB1: -case 0x9DB1: -case 0x9FB1: -case 0x91B2: -case 0x93B2: -case 0x95B2: -case 0x97B2: -case 0x99B2: -case 0x9BB2: -case 0x9DB2: -case 0x9FB2: -case 0x91B3: -case 0x93B3: -case 0x95B3: -case 0x97B3: -case 0x99B3: -case 0x9BB3: -case 0x9DB3: -case 0x9FB3: -case 0x91B4: -case 0x93B4: -case 0x95B4: -case 0x97B4: -case 0x99B4: -case 0x9BB4: -case 0x9DB4: -case 0x9FB4: -case 0x91B5: -case 0x93B5: -case 0x95B5: -case 0x97B5: -case 0x99B5: -case 0x9BB5: -case 0x9DB5: -case 0x9FB5: -case 0x91B6: -case 0x93B6: -case 0x95B6: -case 0x97B6: -case 0x99B6: -case 0x9BB6: -case 0x9DB6: -case 0x9FB6: -case 0x91B7: -case 0x93B7: -case 0x95B7: -case 0x97B7: -case 0x99B7: -case 0x9BB7: -case 0x9DB7: -case 0x9FB7: - -// SUBDa -case 0x91B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x93B8: -case 0x95B8: -case 0x97B8: -case 0x99B8: -case 0x9BB8: -case 0x9DB8: -case 0x9FB8: - -// SUBDa -case 0x91B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x93B9: -case 0x95B9: -case 0x97B9: -case 0x99B9: -case 0x9BB9: -case 0x9DB9: -case 0x9FB9: - -// SUBDa -case 0x91B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x939F: -case 0x959F: -case 0x979F: -case 0x999F: -case 0x9B9F: -case 0x9D9F: -case 0x9F9F: - -// SUBDa -case 0x919F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x93A7: -case 0x95A7: -case 0x97A7: -case 0x99A7: -case 0x9BA7: -case 0x9DA7: -case 0x9FA7: - -// SUBDa -case 0x91A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x9300: -case 0x9500: -case 0x9700: -case 0x9900: -case 0x9B00: -case 0x9D00: -case 0x9F00: -case 0x9101: -case 0x9301: -case 0x9501: -case 0x9701: -case 0x9901: -case 0x9B01: -case 0x9D01: -case 0x9F01: -case 0x9102: -case 0x9302: -case 0x9502: -case 0x9702: -case 0x9902: -case 0x9B02: -case 0x9D02: -case 0x9F02: -case 0x9103: -case 0x9303: -case 0x9503: -case 0x9703: -case 0x9903: -case 0x9B03: -case 0x9D03: -case 0x9F03: -case 0x9104: -case 0x9304: -case 0x9504: -case 0x9704: -case 0x9904: -case 0x9B04: -case 0x9D04: -case 0x9F04: -case 0x9105: -case 0x9305: -case 0x9505: -case 0x9705: -case 0x9905: -case 0x9B05: -case 0x9D05: -case 0x9F05: -case 0x9106: -case 0x9306: -case 0x9506: -case 0x9706: -case 0x9906: -case 0x9B06: -case 0x9D06: -case 0x9F06: -case 0x9107: -case 0x9307: -case 0x9507: -case 0x9707: -case 0x9907: -case 0x9B07: -case 0x9D07: -case 0x9F07: - -// SUBX -case 0x9100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9340: -case 0x9540: -case 0x9740: -case 0x9940: -case 0x9B40: -case 0x9D40: -case 0x9F40: -case 0x9141: -case 0x9341: -case 0x9541: -case 0x9741: -case 0x9941: -case 0x9B41: -case 0x9D41: -case 0x9F41: -case 0x9142: -case 0x9342: -case 0x9542: -case 0x9742: -case 0x9942: -case 0x9B42: -case 0x9D42: -case 0x9F42: -case 0x9143: -case 0x9343: -case 0x9543: -case 0x9743: -case 0x9943: -case 0x9B43: -case 0x9D43: -case 0x9F43: -case 0x9144: -case 0x9344: -case 0x9544: -case 0x9744: -case 0x9944: -case 0x9B44: -case 0x9D44: -case 0x9F44: -case 0x9145: -case 0x9345: -case 0x9545: -case 0x9745: -case 0x9945: -case 0x9B45: -case 0x9D45: -case 0x9F45: -case 0x9146: -case 0x9346: -case 0x9546: -case 0x9746: -case 0x9946: -case 0x9B46: -case 0x9D46: -case 0x9F46: -case 0x9147: -case 0x9347: -case 0x9547: -case 0x9747: -case 0x9947: -case 0x9B47: -case 0x9D47: -case 0x9F47: - -// SUBX -case 0x9140: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9380: -case 0x9580: -case 0x9780: -case 0x9980: -case 0x9B80: -case 0x9D80: -case 0x9F80: -case 0x9181: -case 0x9381: -case 0x9581: -case 0x9781: -case 0x9981: -case 0x9B81: -case 0x9D81: -case 0x9F81: -case 0x9182: -case 0x9382: -case 0x9582: -case 0x9782: -case 0x9982: -case 0x9B82: -case 0x9D82: -case 0x9F82: -case 0x9183: -case 0x9383: -case 0x9583: -case 0x9783: -case 0x9983: -case 0x9B83: -case 0x9D83: -case 0x9F83: -case 0x9184: -case 0x9384: -case 0x9584: -case 0x9784: -case 0x9984: -case 0x9B84: -case 0x9D84: -case 0x9F84: -case 0x9185: -case 0x9385: -case 0x9585: -case 0x9785: -case 0x9985: -case 0x9B85: -case 0x9D85: -case 0x9F85: -case 0x9186: -case 0x9386: -case 0x9586: -case 0x9786: -case 0x9986: -case 0x9B86: -case 0x9D86: -case 0x9F86: -case 0x9187: -case 0x9387: -case 0x9587: -case 0x9787: -case 0x9987: -case 0x9B87: -case 0x9D87: -case 0x9F87: - -// SUBX -case 0x9180: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x9308: -case 0x9508: -case 0x9708: -case 0x9908: -case 0x9B08: -case 0x9D08: -case 0x9109: -case 0x9309: -case 0x9509: -case 0x9709: -case 0x9909: -case 0x9B09: -case 0x9D09: -case 0x910A: -case 0x930A: -case 0x950A: -case 0x970A: -case 0x990A: -case 0x9B0A: -case 0x9D0A: -case 0x910B: -case 0x930B: -case 0x950B: -case 0x970B: -case 0x990B: -case 0x9B0B: -case 0x9D0B: -case 0x910C: -case 0x930C: -case 0x950C: -case 0x970C: -case 0x990C: -case 0x9B0C: -case 0x9D0C: -case 0x910D: -case 0x930D: -case 0x950D: -case 0x970D: -case 0x990D: -case 0x9B0D: -case 0x9D0D: -case 0x910E: -case 0x930E: -case 0x950E: -case 0x970E: -case 0x990E: -case 0x9B0E: -case 0x9D0E: - -// SUBXM -case 0x9108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x9348: -case 0x9548: -case 0x9748: -case 0x9948: -case 0x9B48: -case 0x9D48: -case 0x9149: -case 0x9349: -case 0x9549: -case 0x9749: -case 0x9949: -case 0x9B49: -case 0x9D49: -case 0x914A: -case 0x934A: -case 0x954A: -case 0x974A: -case 0x994A: -case 0x9B4A: -case 0x9D4A: -case 0x914B: -case 0x934B: -case 0x954B: -case 0x974B: -case 0x994B: -case 0x9B4B: -case 0x9D4B: -case 0x914C: -case 0x934C: -case 0x954C: -case 0x974C: -case 0x994C: -case 0x9B4C: -case 0x9D4C: -case 0x914D: -case 0x934D: -case 0x954D: -case 0x974D: -case 0x994D: -case 0x9B4D: -case 0x9D4D: -case 0x914E: -case 0x934E: -case 0x954E: -case 0x974E: -case 0x994E: -case 0x9B4E: -case 0x9D4E: - -// SUBXM -case 0x9148: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x9388: -case 0x9588: -case 0x9788: -case 0x9988: -case 0x9B88: -case 0x9D88: -case 0x9189: -case 0x9389: -case 0x9589: -case 0x9789: -case 0x9989: -case 0x9B89: -case 0x9D89: -case 0x918A: -case 0x938A: -case 0x958A: -case 0x978A: -case 0x998A: -case 0x9B8A: -case 0x9D8A: -case 0x918B: -case 0x938B: -case 0x958B: -case 0x978B: -case 0x998B: -case 0x9B8B: -case 0x9D8B: -case 0x918C: -case 0x938C: -case 0x958C: -case 0x978C: -case 0x998C: -case 0x9B8C: -case 0x9D8C: -case 0x918D: -case 0x938D: -case 0x958D: -case 0x978D: -case 0x998D: -case 0x9B8D: -case 0x9D8D: -case 0x918E: -case 0x938E: -case 0x958E: -case 0x978E: -case 0x998E: -case 0x9B8E: -case 0x9D8E: - -// SUBXM -case 0x9188: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x930F: -case 0x950F: -case 0x970F: -case 0x990F: -case 0x9B0F: -case 0x9D0F: - -// SUBX7M -case 0x910F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x934F: -case 0x954F: -case 0x974F: -case 0x994F: -case 0x9B4F: -case 0x9D4F: - -// SUBX7M -case 0x914F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x938F: -case 0x958F: -case 0x978F: -case 0x998F: -case 0x9B8F: -case 0x9D8F: - -// SUBX7M -case 0x918F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x9F09: -case 0x9F0A: -case 0x9F0B: -case 0x9F0C: -case 0x9F0D: -case 0x9F0E: - -// SUBXM7 -case 0x9F08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x9F49: -case 0x9F4A: -case 0x9F4B: -case 0x9F4C: -case 0x9F4D: -case 0x9F4E: - -// SUBXM7 -case 0x9F48: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x9F89: -case 0x9F8A: -case 0x9F8B: -case 0x9F8C: -case 0x9F8D: -case 0x9F8E: - -// SUBXM7 -case 0x9F88: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// SUBX7M7 -case 0x9F0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// SUBX7M7 -case 0x9F4F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// SUBX7M7 -case 0x9F8F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x92C0: -case 0x94C0: -case 0x96C0: -case 0x98C0: -case 0x9AC0: -case 0x9CC0: -case 0x9EC0: -case 0x90C1: -case 0x92C1: -case 0x94C1: -case 0x96C1: -case 0x98C1: -case 0x9AC1: -case 0x9CC1: -case 0x9EC1: -case 0x90C2: -case 0x92C2: -case 0x94C2: -case 0x96C2: -case 0x98C2: -case 0x9AC2: -case 0x9CC2: -case 0x9EC2: -case 0x90C3: -case 0x92C3: -case 0x94C3: -case 0x96C3: -case 0x98C3: -case 0x9AC3: -case 0x9CC3: -case 0x9EC3: -case 0x90C4: -case 0x92C4: -case 0x94C4: -case 0x96C4: -case 0x98C4: -case 0x9AC4: -case 0x9CC4: -case 0x9EC4: -case 0x90C5: -case 0x92C5: -case 0x94C5: -case 0x96C5: -case 0x98C5: -case 0x9AC5: -case 0x9CC5: -case 0x9EC5: -case 0x90C6: -case 0x92C6: -case 0x94C6: -case 0x96C6: -case 0x98C6: -case 0x9AC6: -case 0x9CC6: -case 0x9EC6: -case 0x90C7: -case 0x92C7: -case 0x94C7: -case 0x96C7: -case 0x98C7: -case 0x9AC7: -case 0x9CC7: -case 0x9EC7: - -// SUBA -case 0x90C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x92C8: -case 0x94C8: -case 0x96C8: -case 0x98C8: -case 0x9AC8: -case 0x9CC8: -case 0x9EC8: -case 0x90C9: -case 0x92C9: -case 0x94C9: -case 0x96C9: -case 0x98C9: -case 0x9AC9: -case 0x9CC9: -case 0x9EC9: -case 0x90CA: -case 0x92CA: -case 0x94CA: -case 0x96CA: -case 0x98CA: -case 0x9ACA: -case 0x9CCA: -case 0x9ECA: -case 0x90CB: -case 0x92CB: -case 0x94CB: -case 0x96CB: -case 0x98CB: -case 0x9ACB: -case 0x9CCB: -case 0x9ECB: -case 0x90CC: -case 0x92CC: -case 0x94CC: -case 0x96CC: -case 0x98CC: -case 0x9ACC: -case 0x9CCC: -case 0x9ECC: -case 0x90CD: -case 0x92CD: -case 0x94CD: -case 0x96CD: -case 0x98CD: -case 0x9ACD: -case 0x9CCD: -case 0x9ECD: -case 0x90CE: -case 0x92CE: -case 0x94CE: -case 0x96CE: -case 0x98CE: -case 0x9ACE: -case 0x9CCE: -case 0x9ECE: -case 0x90CF: -case 0x92CF: -case 0x94CF: -case 0x96CF: -case 0x98CF: -case 0x9ACF: -case 0x9CCF: -case 0x9ECF: - -// SUBA -case 0x90C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x92D0: -case 0x94D0: -case 0x96D0: -case 0x98D0: -case 0x9AD0: -case 0x9CD0: -case 0x9ED0: -case 0x90D1: -case 0x92D1: -case 0x94D1: -case 0x96D1: -case 0x98D1: -case 0x9AD1: -case 0x9CD1: -case 0x9ED1: -case 0x90D2: -case 0x92D2: -case 0x94D2: -case 0x96D2: -case 0x98D2: -case 0x9AD2: -case 0x9CD2: -case 0x9ED2: -case 0x90D3: -case 0x92D3: -case 0x94D3: -case 0x96D3: -case 0x98D3: -case 0x9AD3: -case 0x9CD3: -case 0x9ED3: -case 0x90D4: -case 0x92D4: -case 0x94D4: -case 0x96D4: -case 0x98D4: -case 0x9AD4: -case 0x9CD4: -case 0x9ED4: -case 0x90D5: -case 0x92D5: -case 0x94D5: -case 0x96D5: -case 0x98D5: -case 0x9AD5: -case 0x9CD5: -case 0x9ED5: -case 0x90D6: -case 0x92D6: -case 0x94D6: -case 0x96D6: -case 0x98D6: -case 0x9AD6: -case 0x9CD6: -case 0x9ED6: -case 0x90D7: -case 0x92D7: -case 0x94D7: -case 0x96D7: -case 0x98D7: -case 0x9AD7: -case 0x9CD7: -case 0x9ED7: - -// SUBA -case 0x90D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x92D8: -case 0x94D8: -case 0x96D8: -case 0x98D8: -case 0x9AD8: -case 0x9CD8: -case 0x9ED8: -case 0x90D9: -case 0x92D9: -case 0x94D9: -case 0x96D9: -case 0x98D9: -case 0x9AD9: -case 0x9CD9: -case 0x9ED9: -case 0x90DA: -case 0x92DA: -case 0x94DA: -case 0x96DA: -case 0x98DA: -case 0x9ADA: -case 0x9CDA: -case 0x9EDA: -case 0x90DB: -case 0x92DB: -case 0x94DB: -case 0x96DB: -case 0x98DB: -case 0x9ADB: -case 0x9CDB: -case 0x9EDB: -case 0x90DC: -case 0x92DC: -case 0x94DC: -case 0x96DC: -case 0x98DC: -case 0x9ADC: -case 0x9CDC: -case 0x9EDC: -case 0x90DD: -case 0x92DD: -case 0x94DD: -case 0x96DD: -case 0x98DD: -case 0x9ADD: -case 0x9CDD: -case 0x9EDD: -case 0x90DE: -case 0x92DE: -case 0x94DE: -case 0x96DE: -case 0x98DE: -case 0x9ADE: -case 0x9CDE: -case 0x9EDE: - -// SUBA -case 0x90D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x92E0: -case 0x94E0: -case 0x96E0: -case 0x98E0: -case 0x9AE0: -case 0x9CE0: -case 0x9EE0: -case 0x90E1: -case 0x92E1: -case 0x94E1: -case 0x96E1: -case 0x98E1: -case 0x9AE1: -case 0x9CE1: -case 0x9EE1: -case 0x90E2: -case 0x92E2: -case 0x94E2: -case 0x96E2: -case 0x98E2: -case 0x9AE2: -case 0x9CE2: -case 0x9EE2: -case 0x90E3: -case 0x92E3: -case 0x94E3: -case 0x96E3: -case 0x98E3: -case 0x9AE3: -case 0x9CE3: -case 0x9EE3: -case 0x90E4: -case 0x92E4: -case 0x94E4: -case 0x96E4: -case 0x98E4: -case 0x9AE4: -case 0x9CE4: -case 0x9EE4: -case 0x90E5: -case 0x92E5: -case 0x94E5: -case 0x96E5: -case 0x98E5: -case 0x9AE5: -case 0x9CE5: -case 0x9EE5: -case 0x90E6: -case 0x92E6: -case 0x94E6: -case 0x96E6: -case 0x98E6: -case 0x9AE6: -case 0x9CE6: -case 0x9EE6: - -// SUBA -case 0x90E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x92E8: -case 0x94E8: -case 0x96E8: -case 0x98E8: -case 0x9AE8: -case 0x9CE8: -case 0x9EE8: -case 0x90E9: -case 0x92E9: -case 0x94E9: -case 0x96E9: -case 0x98E9: -case 0x9AE9: -case 0x9CE9: -case 0x9EE9: -case 0x90EA: -case 0x92EA: -case 0x94EA: -case 0x96EA: -case 0x98EA: -case 0x9AEA: -case 0x9CEA: -case 0x9EEA: -case 0x90EB: -case 0x92EB: -case 0x94EB: -case 0x96EB: -case 0x98EB: -case 0x9AEB: -case 0x9CEB: -case 0x9EEB: -case 0x90EC: -case 0x92EC: -case 0x94EC: -case 0x96EC: -case 0x98EC: -case 0x9AEC: -case 0x9CEC: -case 0x9EEC: -case 0x90ED: -case 0x92ED: -case 0x94ED: -case 0x96ED: -case 0x98ED: -case 0x9AED: -case 0x9CED: -case 0x9EED: -case 0x90EE: -case 0x92EE: -case 0x94EE: -case 0x96EE: -case 0x98EE: -case 0x9AEE: -case 0x9CEE: -case 0x9EEE: -case 0x90EF: -case 0x92EF: -case 0x94EF: -case 0x96EF: -case 0x98EF: -case 0x9AEF: -case 0x9CEF: -case 0x9EEF: - -// SUBA -case 0x90E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x92F0: -case 0x94F0: -case 0x96F0: -case 0x98F0: -case 0x9AF0: -case 0x9CF0: -case 0x9EF0: -case 0x90F1: -case 0x92F1: -case 0x94F1: -case 0x96F1: -case 0x98F1: -case 0x9AF1: -case 0x9CF1: -case 0x9EF1: -case 0x90F2: -case 0x92F2: -case 0x94F2: -case 0x96F2: -case 0x98F2: -case 0x9AF2: -case 0x9CF2: -case 0x9EF2: -case 0x90F3: -case 0x92F3: -case 0x94F3: -case 0x96F3: -case 0x98F3: -case 0x9AF3: -case 0x9CF3: -case 0x9EF3: -case 0x90F4: -case 0x92F4: -case 0x94F4: -case 0x96F4: -case 0x98F4: -case 0x9AF4: -case 0x9CF4: -case 0x9EF4: -case 0x90F5: -case 0x92F5: -case 0x94F5: -case 0x96F5: -case 0x98F5: -case 0x9AF5: -case 0x9CF5: -case 0x9EF5: -case 0x90F6: -case 0x92F6: -case 0x94F6: -case 0x96F6: -case 0x98F6: -case 0x9AF6: -case 0x9CF6: -case 0x9EF6: -case 0x90F7: -case 0x92F7: -case 0x94F7: -case 0x96F7: -case 0x98F7: -case 0x9AF7: -case 0x9CF7: -case 0x9EF7: - -// SUBA -case 0x90F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x92F8: -case 0x94F8: -case 0x96F8: -case 0x98F8: -case 0x9AF8: -case 0x9CF8: -case 0x9EF8: - -// SUBA -case 0x90F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x92F9: -case 0x94F9: -case 0x96F9: -case 0x98F9: -case 0x9AF9: -case 0x9CF9: -case 0x9EF9: - -// SUBA -case 0x90F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x92FA: -case 0x94FA: -case 0x96FA: -case 0x98FA: -case 0x9AFA: -case 0x9CFA: -case 0x9EFA: - -// SUBA -case 0x90FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x92FB: -case 0x94FB: -case 0x96FB: -case 0x98FB: -case 0x9AFB: -case 0x9CFB: -case 0x9EFB: - -// SUBA -case 0x90FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x92FC: -case 0x94FC: -case 0x96FC: -case 0x98FC: -case 0x9AFC: -case 0x9CFC: -case 0x9EFC: - -// SUBA -case 0x90FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x92DF: -case 0x94DF: -case 0x96DF: -case 0x98DF: -case 0x9ADF: -case 0x9CDF: -case 0x9EDF: - -// SUBA -case 0x90DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x92E7: -case 0x94E7: -case 0x96E7: -case 0x98E7: -case 0x9AE7: -case 0x9CE7: -case 0x9EE7: - -// SUBA -case 0x90E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x93C0: -case 0x95C0: -case 0x97C0: -case 0x99C0: -case 0x9BC0: -case 0x9DC0: -case 0x9FC0: -case 0x91C1: -case 0x93C1: -case 0x95C1: -case 0x97C1: -case 0x99C1: -case 0x9BC1: -case 0x9DC1: -case 0x9FC1: -case 0x91C2: -case 0x93C2: -case 0x95C2: -case 0x97C2: -case 0x99C2: -case 0x9BC2: -case 0x9DC2: -case 0x9FC2: -case 0x91C3: -case 0x93C3: -case 0x95C3: -case 0x97C3: -case 0x99C3: -case 0x9BC3: -case 0x9DC3: -case 0x9FC3: -case 0x91C4: -case 0x93C4: -case 0x95C4: -case 0x97C4: -case 0x99C4: -case 0x9BC4: -case 0x9DC4: -case 0x9FC4: -case 0x91C5: -case 0x93C5: -case 0x95C5: -case 0x97C5: -case 0x99C5: -case 0x9BC5: -case 0x9DC5: -case 0x9FC5: -case 0x91C6: -case 0x93C6: -case 0x95C6: -case 0x97C6: -case 0x99C6: -case 0x9BC6: -case 0x9DC6: -case 0x9FC6: -case 0x91C7: -case 0x93C7: -case 0x95C7: -case 0x97C7: -case 0x99C7: -case 0x9BC7: -case 0x9DC7: -case 0x9FC7: - -// SUBA -case 0x91C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0x93C8: -case 0x95C8: -case 0x97C8: -case 0x99C8: -case 0x9BC8: -case 0x9DC8: -case 0x9FC8: -case 0x91C9: -case 0x93C9: -case 0x95C9: -case 0x97C9: -case 0x99C9: -case 0x9BC9: -case 0x9DC9: -case 0x9FC9: -case 0x91CA: -case 0x93CA: -case 0x95CA: -case 0x97CA: -case 0x99CA: -case 0x9BCA: -case 0x9DCA: -case 0x9FCA: -case 0x91CB: -case 0x93CB: -case 0x95CB: -case 0x97CB: -case 0x99CB: -case 0x9BCB: -case 0x9DCB: -case 0x9FCB: -case 0x91CC: -case 0x93CC: -case 0x95CC: -case 0x97CC: -case 0x99CC: -case 0x9BCC: -case 0x9DCC: -case 0x9FCC: -case 0x91CD: -case 0x93CD: -case 0x95CD: -case 0x97CD: -case 0x99CD: -case 0x9BCD: -case 0x9DCD: -case 0x9FCD: -case 0x91CE: -case 0x93CE: -case 0x95CE: -case 0x97CE: -case 0x99CE: -case 0x9BCE: -case 0x9DCE: -case 0x9FCE: -case 0x91CF: -case 0x93CF: -case 0x95CF: -case 0x97CF: -case 0x99CF: -case 0x9BCF: -case 0x9DCF: -case 0x9FCF: - -// SUBA -case 0x91C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0x93D0: -case 0x95D0: -case 0x97D0: -case 0x99D0: -case 0x9BD0: -case 0x9DD0: -case 0x9FD0: -case 0x91D1: -case 0x93D1: -case 0x95D1: -case 0x97D1: -case 0x99D1: -case 0x9BD1: -case 0x9DD1: -case 0x9FD1: -case 0x91D2: -case 0x93D2: -case 0x95D2: -case 0x97D2: -case 0x99D2: -case 0x9BD2: -case 0x9DD2: -case 0x9FD2: -case 0x91D3: -case 0x93D3: -case 0x95D3: -case 0x97D3: -case 0x99D3: -case 0x9BD3: -case 0x9DD3: -case 0x9FD3: -case 0x91D4: -case 0x93D4: -case 0x95D4: -case 0x97D4: -case 0x99D4: -case 0x9BD4: -case 0x9DD4: -case 0x9FD4: -case 0x91D5: -case 0x93D5: -case 0x95D5: -case 0x97D5: -case 0x99D5: -case 0x9BD5: -case 0x9DD5: -case 0x9FD5: -case 0x91D6: -case 0x93D6: -case 0x95D6: -case 0x97D6: -case 0x99D6: -case 0x9BD6: -case 0x9DD6: -case 0x9FD6: -case 0x91D7: -case 0x93D7: -case 0x95D7: -case 0x97D7: -case 0x99D7: -case 0x9BD7: -case 0x9DD7: -case 0x9FD7: - -// SUBA -case 0x91D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x93D8: -case 0x95D8: -case 0x97D8: -case 0x99D8: -case 0x9BD8: -case 0x9DD8: -case 0x9FD8: -case 0x91D9: -case 0x93D9: -case 0x95D9: -case 0x97D9: -case 0x99D9: -case 0x9BD9: -case 0x9DD9: -case 0x9FD9: -case 0x91DA: -case 0x93DA: -case 0x95DA: -case 0x97DA: -case 0x99DA: -case 0x9BDA: -case 0x9DDA: -case 0x9FDA: -case 0x91DB: -case 0x93DB: -case 0x95DB: -case 0x97DB: -case 0x99DB: -case 0x9BDB: -case 0x9DDB: -case 0x9FDB: -case 0x91DC: -case 0x93DC: -case 0x95DC: -case 0x97DC: -case 0x99DC: -case 0x9BDC: -case 0x9DDC: -case 0x9FDC: -case 0x91DD: -case 0x93DD: -case 0x95DD: -case 0x97DD: -case 0x99DD: -case 0x9BDD: -case 0x9DDD: -case 0x9FDD: -case 0x91DE: -case 0x93DE: -case 0x95DE: -case 0x97DE: -case 0x99DE: -case 0x9BDE: -case 0x9DDE: -case 0x9FDE: - -// SUBA -case 0x91D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x93E0: -case 0x95E0: -case 0x97E0: -case 0x99E0: -case 0x9BE0: -case 0x9DE0: -case 0x9FE0: -case 0x91E1: -case 0x93E1: -case 0x95E1: -case 0x97E1: -case 0x99E1: -case 0x9BE1: -case 0x9DE1: -case 0x9FE1: -case 0x91E2: -case 0x93E2: -case 0x95E2: -case 0x97E2: -case 0x99E2: -case 0x9BE2: -case 0x9DE2: -case 0x9FE2: -case 0x91E3: -case 0x93E3: -case 0x95E3: -case 0x97E3: -case 0x99E3: -case 0x9BE3: -case 0x9DE3: -case 0x9FE3: -case 0x91E4: -case 0x93E4: -case 0x95E4: -case 0x97E4: -case 0x99E4: -case 0x9BE4: -case 0x9DE4: -case 0x9FE4: -case 0x91E5: -case 0x93E5: -case 0x95E5: -case 0x97E5: -case 0x99E5: -case 0x9BE5: -case 0x9DE5: -case 0x9FE5: -case 0x91E6: -case 0x93E6: -case 0x95E6: -case 0x97E6: -case 0x99E6: -case 0x9BE6: -case 0x9DE6: -case 0x9FE6: - -// SUBA -case 0x91E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x93E8: -case 0x95E8: -case 0x97E8: -case 0x99E8: -case 0x9BE8: -case 0x9DE8: -case 0x9FE8: -case 0x91E9: -case 0x93E9: -case 0x95E9: -case 0x97E9: -case 0x99E9: -case 0x9BE9: -case 0x9DE9: -case 0x9FE9: -case 0x91EA: -case 0x93EA: -case 0x95EA: -case 0x97EA: -case 0x99EA: -case 0x9BEA: -case 0x9DEA: -case 0x9FEA: -case 0x91EB: -case 0x93EB: -case 0x95EB: -case 0x97EB: -case 0x99EB: -case 0x9BEB: -case 0x9DEB: -case 0x9FEB: -case 0x91EC: -case 0x93EC: -case 0x95EC: -case 0x97EC: -case 0x99EC: -case 0x9BEC: -case 0x9DEC: -case 0x9FEC: -case 0x91ED: -case 0x93ED: -case 0x95ED: -case 0x97ED: -case 0x99ED: -case 0x9BED: -case 0x9DED: -case 0x9FED: -case 0x91EE: -case 0x93EE: -case 0x95EE: -case 0x97EE: -case 0x99EE: -case 0x9BEE: -case 0x9DEE: -case 0x9FEE: -case 0x91EF: -case 0x93EF: -case 0x95EF: -case 0x97EF: -case 0x99EF: -case 0x9BEF: -case 0x9DEF: -case 0x9FEF: - -// SUBA -case 0x91E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x93F0: -case 0x95F0: -case 0x97F0: -case 0x99F0: -case 0x9BF0: -case 0x9DF0: -case 0x9FF0: -case 0x91F1: -case 0x93F1: -case 0x95F1: -case 0x97F1: -case 0x99F1: -case 0x9BF1: -case 0x9DF1: -case 0x9FF1: -case 0x91F2: -case 0x93F2: -case 0x95F2: -case 0x97F2: -case 0x99F2: -case 0x9BF2: -case 0x9DF2: -case 0x9FF2: -case 0x91F3: -case 0x93F3: -case 0x95F3: -case 0x97F3: -case 0x99F3: -case 0x9BF3: -case 0x9DF3: -case 0x9FF3: -case 0x91F4: -case 0x93F4: -case 0x95F4: -case 0x97F4: -case 0x99F4: -case 0x9BF4: -case 0x9DF4: -case 0x9FF4: -case 0x91F5: -case 0x93F5: -case 0x95F5: -case 0x97F5: -case 0x99F5: -case 0x9BF5: -case 0x9DF5: -case 0x9FF5: -case 0x91F6: -case 0x93F6: -case 0x95F6: -case 0x97F6: -case 0x99F6: -case 0x9BF6: -case 0x9DF6: -case 0x9FF6: -case 0x91F7: -case 0x93F7: -case 0x95F7: -case 0x97F7: -case 0x99F7: -case 0x9BF7: -case 0x9DF7: -case 0x9FF7: - -// SUBA -case 0x91F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0x93F8: -case 0x95F8: -case 0x97F8: -case 0x99F8: -case 0x9BF8: -case 0x9DF8: -case 0x9FF8: - -// SUBA -case 0x91F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x93F9: -case 0x95F9: -case 0x97F9: -case 0x99F9: -case 0x9BF9: -case 0x9DF9: -case 0x9FF9: - -// SUBA -case 0x91F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(24) -case 0x93FA: -case 0x95FA: -case 0x97FA: -case 0x99FA: -case 0x9BFA: -case 0x9DFA: -case 0x9FFA: - -// SUBA -case 0x91FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x93FB: -case 0x95FB: -case 0x97FB: -case 0x99FB: -case 0x9BFB: -case 0x9DFB: -case 0x9FFB: - -// SUBA -case 0x91FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0x93FC: -case 0x95FC: -case 0x97FC: -case 0x99FC: -case 0x9BFC: -case 0x9DFC: -case 0x9FFC: - -// SUBA -case 0x91FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)FETCH_LONG; - PC += 4; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(14) -case 0x93DF: -case 0x95DF: -case 0x97DF: -case 0x99DF: -case 0x9BDF: -case 0x9DDF: -case 0x9FDF: - -// SUBA -case 0x91DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x93E7: -case 0x95E7: -case 0x97E7: -case 0x99E7: -case 0x9BE7: -case 0x9DE7: -case 0x9FE7: - -// SUBA -case 0x91E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) diff --git a/yabause/src/c68k/c68k_opA.inc b/yabause/src/c68k/c68k_opA.inc deleted file mode 100644 index 0bf57ce785..0000000000 --- a/yabause/src/c68k/c68k_opA.inc +++ /dev/null @@ -1,4118 +0,0 @@ -case 0xA001: -case 0xA002: -case 0xA003: -case 0xA004: -case 0xA005: -case 0xA006: -case 0xA007: -case 0xA008: -case 0xA009: -case 0xA00A: -case 0xA00B: -case 0xA00C: -case 0xA00D: -case 0xA00E: -case 0xA00F: -case 0xA010: -case 0xA011: -case 0xA012: -case 0xA013: -case 0xA014: -case 0xA015: -case 0xA016: -case 0xA017: -case 0xA018: -case 0xA019: -case 0xA01A: -case 0xA01B: -case 0xA01C: -case 0xA01D: -case 0xA01E: -case 0xA01F: -case 0xA020: -case 0xA021: -case 0xA022: -case 0xA023: -case 0xA024: -case 0xA025: -case 0xA026: -case 0xA027: -case 0xA028: -case 0xA029: -case 0xA02A: -case 0xA02B: -case 0xA02C: -case 0xA02D: -case 0xA02E: -case 0xA02F: -case 0xA030: -case 0xA031: -case 0xA032: -case 0xA033: -case 0xA034: -case 0xA035: -case 0xA036: -case 0xA037: -case 0xA038: -case 0xA039: -case 0xA03A: -case 0xA03B: -case 0xA03C: -case 0xA03D: -case 0xA03E: -case 0xA03F: -case 0xA040: -case 0xA041: -case 0xA042: -case 0xA043: -case 0xA044: -case 0xA045: -case 0xA046: -case 0xA047: -case 0xA048: -case 0xA049: -case 0xA04A: -case 0xA04B: -case 0xA04C: -case 0xA04D: -case 0xA04E: -case 0xA04F: -case 0xA050: -case 0xA051: -case 0xA052: -case 0xA053: -case 0xA054: -case 0xA055: -case 0xA056: -case 0xA057: -case 0xA058: -case 0xA059: -case 0xA05A: -case 0xA05B: -case 0xA05C: -case 0xA05D: -case 0xA05E: -case 0xA05F: -case 0xA060: -case 0xA061: -case 0xA062: -case 0xA063: -case 0xA064: -case 0xA065: -case 0xA066: -case 0xA067: -case 0xA068: -case 0xA069: -case 0xA06A: -case 0xA06B: -case 0xA06C: -case 0xA06D: -case 0xA06E: -case 0xA06F: -case 0xA070: -case 0xA071: -case 0xA072: -case 0xA073: -case 0xA074: -case 0xA075: -case 0xA076: -case 0xA077: -case 0xA078: -case 0xA079: -case 0xA07A: -case 0xA07B: -case 0xA07C: -case 0xA07D: -case 0xA07E: -case 0xA07F: -case 0xA080: -case 0xA081: -case 0xA082: -case 0xA083: -case 0xA084: -case 0xA085: -case 0xA086: -case 0xA087: -case 0xA088: -case 0xA089: -case 0xA08A: -case 0xA08B: -case 0xA08C: -case 0xA08D: -case 0xA08E: -case 0xA08F: -case 0xA090: -case 0xA091: -case 0xA092: -case 0xA093: -case 0xA094: -case 0xA095: -case 0xA096: -case 0xA097: -case 0xA098: -case 0xA099: -case 0xA09A: -case 0xA09B: -case 0xA09C: -case 0xA09D: -case 0xA09E: -case 0xA09F: -case 0xA0A0: -case 0xA0A1: -case 0xA0A2: -case 0xA0A3: -case 0xA0A4: -case 0xA0A5: -case 0xA0A6: -case 0xA0A7: -case 0xA0A8: -case 0xA0A9: -case 0xA0AA: -case 0xA0AB: -case 0xA0AC: -case 0xA0AD: -case 0xA0AE: -case 0xA0AF: -case 0xA0B0: -case 0xA0B1: -case 0xA0B2: -case 0xA0B3: -case 0xA0B4: -case 0xA0B5: -case 0xA0B6: -case 0xA0B7: -case 0xA0B8: -case 0xA0B9: -case 0xA0BA: -case 0xA0BB: -case 0xA0BC: -case 0xA0BD: -case 0xA0BE: -case 0xA0BF: -case 0xA0C0: -case 0xA0C1: -case 0xA0C2: -case 0xA0C3: -case 0xA0C4: -case 0xA0C5: -case 0xA0C6: -case 0xA0C7: -case 0xA0C8: -case 0xA0C9: -case 0xA0CA: -case 0xA0CB: -case 0xA0CC: -case 0xA0CD: -case 0xA0CE: -case 0xA0CF: -case 0xA0D0: -case 0xA0D1: -case 0xA0D2: -case 0xA0D3: -case 0xA0D4: -case 0xA0D5: -case 0xA0D6: -case 0xA0D7: -case 0xA0D8: -case 0xA0D9: -case 0xA0DA: -case 0xA0DB: -case 0xA0DC: -case 0xA0DD: -case 0xA0DE: -case 0xA0DF: -case 0xA0E0: -case 0xA0E1: -case 0xA0E2: -case 0xA0E3: -case 0xA0E4: -case 0xA0E5: -case 0xA0E6: -case 0xA0E7: -case 0xA0E8: -case 0xA0E9: -case 0xA0EA: -case 0xA0EB: -case 0xA0EC: -case 0xA0ED: -case 0xA0EE: -case 0xA0EF: -case 0xA0F0: -case 0xA0F1: -case 0xA0F2: -case 0xA0F3: -case 0xA0F4: -case 0xA0F5: -case 0xA0F6: -case 0xA0F7: -case 0xA0F8: -case 0xA0F9: -case 0xA0FA: -case 0xA0FB: -case 0xA0FC: -case 0xA0FD: -case 0xA0FE: -case 0xA0FF: -case 0xA100: -case 0xA101: -case 0xA102: -case 0xA103: -case 0xA104: -case 0xA105: -case 0xA106: -case 0xA107: -case 0xA108: -case 0xA109: -case 0xA10A: -case 0xA10B: -case 0xA10C: -case 0xA10D: -case 0xA10E: -case 0xA10F: -case 0xA110: -case 0xA111: -case 0xA112: -case 0xA113: -case 0xA114: -case 0xA115: -case 0xA116: -case 0xA117: -case 0xA118: -case 0xA119: -case 0xA11A: -case 0xA11B: -case 0xA11C: -case 0xA11D: -case 0xA11E: -case 0xA11F: -case 0xA120: -case 0xA121: -case 0xA122: -case 0xA123: -case 0xA124: -case 0xA125: -case 0xA126: -case 0xA127: -case 0xA128: -case 0xA129: -case 0xA12A: -case 0xA12B: -case 0xA12C: -case 0xA12D: -case 0xA12E: -case 0xA12F: -case 0xA130: -case 0xA131: -case 0xA132: -case 0xA133: -case 0xA134: -case 0xA135: -case 0xA136: -case 0xA137: -case 0xA138: -case 0xA139: -case 0xA13A: -case 0xA13B: -case 0xA13C: -case 0xA13D: -case 0xA13E: -case 0xA13F: -case 0xA140: -case 0xA141: -case 0xA142: -case 0xA143: -case 0xA144: -case 0xA145: -case 0xA146: -case 0xA147: -case 0xA148: -case 0xA149: -case 0xA14A: -case 0xA14B: -case 0xA14C: -case 0xA14D: -case 0xA14E: -case 0xA14F: -case 0xA150: -case 0xA151: -case 0xA152: -case 0xA153: -case 0xA154: -case 0xA155: -case 0xA156: -case 0xA157: -case 0xA158: -case 0xA159: -case 0xA15A: -case 0xA15B: -case 0xA15C: -case 0xA15D: -case 0xA15E: -case 0xA15F: -case 0xA160: -case 0xA161: -case 0xA162: -case 0xA163: -case 0xA164: -case 0xA165: -case 0xA166: -case 0xA167: -case 0xA168: -case 0xA169: -case 0xA16A: -case 0xA16B: -case 0xA16C: -case 0xA16D: -case 0xA16E: -case 0xA16F: -case 0xA170: -case 0xA171: -case 0xA172: -case 0xA173: -case 0xA174: -case 0xA175: -case 0xA176: -case 0xA177: -case 0xA178: -case 0xA179: -case 0xA17A: -case 0xA17B: -case 0xA17C: -case 0xA17D: -case 0xA17E: -case 0xA17F: -case 0xA180: -case 0xA181: -case 0xA182: -case 0xA183: -case 0xA184: -case 0xA185: -case 0xA186: -case 0xA187: -case 0xA188: -case 0xA189: -case 0xA18A: -case 0xA18B: -case 0xA18C: -case 0xA18D: -case 0xA18E: -case 0xA18F: -case 0xA190: -case 0xA191: -case 0xA192: -case 0xA193: -case 0xA194: -case 0xA195: -case 0xA196: -case 0xA197: -case 0xA198: -case 0xA199: -case 0xA19A: -case 0xA19B: -case 0xA19C: -case 0xA19D: -case 0xA19E: -case 0xA19F: -case 0xA1A0: -case 0xA1A1: -case 0xA1A2: -case 0xA1A3: -case 0xA1A4: -case 0xA1A5: -case 0xA1A6: -case 0xA1A7: -case 0xA1A8: -case 0xA1A9: -case 0xA1AA: -case 0xA1AB: -case 0xA1AC: -case 0xA1AD: -case 0xA1AE: -case 0xA1AF: -case 0xA1B0: -case 0xA1B1: -case 0xA1B2: -case 0xA1B3: -case 0xA1B4: -case 0xA1B5: -case 0xA1B6: -case 0xA1B7: -case 0xA1B8: -case 0xA1B9: -case 0xA1BA: -case 0xA1BB: -case 0xA1BC: -case 0xA1BD: -case 0xA1BE: -case 0xA1BF: -case 0xA1C0: -case 0xA1C1: -case 0xA1C2: -case 0xA1C3: -case 0xA1C4: -case 0xA1C5: -case 0xA1C6: -case 0xA1C7: -case 0xA1C8: -case 0xA1C9: -case 0xA1CA: -case 0xA1CB: -case 0xA1CC: -case 0xA1CD: -case 0xA1CE: -case 0xA1CF: -case 0xA1D0: -case 0xA1D1: -case 0xA1D2: -case 0xA1D3: -case 0xA1D4: -case 0xA1D5: -case 0xA1D6: -case 0xA1D7: -case 0xA1D8: -case 0xA1D9: -case 0xA1DA: -case 0xA1DB: -case 0xA1DC: -case 0xA1DD: -case 0xA1DE: -case 0xA1DF: -case 0xA1E0: -case 0xA1E1: -case 0xA1E2: -case 0xA1E3: -case 0xA1E4: -case 0xA1E5: -case 0xA1E6: -case 0xA1E7: -case 0xA1E8: -case 0xA1E9: -case 0xA1EA: -case 0xA1EB: -case 0xA1EC: -case 0xA1ED: -case 0xA1EE: -case 0xA1EF: -case 0xA1F0: -case 0xA1F1: -case 0xA1F2: -case 0xA1F3: -case 0xA1F4: -case 0xA1F5: -case 0xA1F6: -case 0xA1F7: -case 0xA1F8: -case 0xA1F9: -case 0xA1FA: -case 0xA1FB: -case 0xA1FC: -case 0xA1FD: -case 0xA1FE: -case 0xA1FF: -case 0xA200: -case 0xA201: -case 0xA202: -case 0xA203: -case 0xA204: -case 0xA205: -case 0xA206: -case 0xA207: -case 0xA208: -case 0xA209: -case 0xA20A: -case 0xA20B: -case 0xA20C: -case 0xA20D: -case 0xA20E: -case 0xA20F: -case 0xA210: -case 0xA211: -case 0xA212: -case 0xA213: -case 0xA214: -case 0xA215: -case 0xA216: -case 0xA217: -case 0xA218: -case 0xA219: -case 0xA21A: -case 0xA21B: -case 0xA21C: -case 0xA21D: -case 0xA21E: -case 0xA21F: -case 0xA220: -case 0xA221: -case 0xA222: -case 0xA223: -case 0xA224: -case 0xA225: -case 0xA226: -case 0xA227: -case 0xA228: -case 0xA229: -case 0xA22A: -case 0xA22B: -case 0xA22C: -case 0xA22D: -case 0xA22E: -case 0xA22F: -case 0xA230: -case 0xA231: -case 0xA232: -case 0xA233: -case 0xA234: -case 0xA235: -case 0xA236: -case 0xA237: -case 0xA238: -case 0xA239: -case 0xA23A: -case 0xA23B: -case 0xA23C: -case 0xA23D: -case 0xA23E: -case 0xA23F: -case 0xA240: -case 0xA241: -case 0xA242: -case 0xA243: -case 0xA244: -case 0xA245: -case 0xA246: -case 0xA247: -case 0xA248: -case 0xA249: -case 0xA24A: -case 0xA24B: -case 0xA24C: -case 0xA24D: -case 0xA24E: -case 0xA24F: -case 0xA250: -case 0xA251: -case 0xA252: -case 0xA253: -case 0xA254: -case 0xA255: -case 0xA256: -case 0xA257: -case 0xA258: -case 0xA259: -case 0xA25A: -case 0xA25B: -case 0xA25C: -case 0xA25D: -case 0xA25E: -case 0xA25F: -case 0xA260: -case 0xA261: -case 0xA262: -case 0xA263: -case 0xA264: -case 0xA265: -case 0xA266: -case 0xA267: -case 0xA268: -case 0xA269: -case 0xA26A: -case 0xA26B: -case 0xA26C: -case 0xA26D: -case 0xA26E: -case 0xA26F: -case 0xA270: -case 0xA271: -case 0xA272: -case 0xA273: -case 0xA274: -case 0xA275: -case 0xA276: -case 0xA277: -case 0xA278: -case 0xA279: -case 0xA27A: -case 0xA27B: -case 0xA27C: -case 0xA27D: -case 0xA27E: -case 0xA27F: -case 0xA280: -case 0xA281: -case 0xA282: -case 0xA283: -case 0xA284: -case 0xA285: -case 0xA286: -case 0xA287: -case 0xA288: -case 0xA289: -case 0xA28A: -case 0xA28B: -case 0xA28C: -case 0xA28D: -case 0xA28E: -case 0xA28F: -case 0xA290: -case 0xA291: -case 0xA292: -case 0xA293: -case 0xA294: -case 0xA295: -case 0xA296: -case 0xA297: -case 0xA298: -case 0xA299: -case 0xA29A: -case 0xA29B: -case 0xA29C: -case 0xA29D: -case 0xA29E: -case 0xA29F: -case 0xA2A0: -case 0xA2A1: -case 0xA2A2: -case 0xA2A3: -case 0xA2A4: -case 0xA2A5: -case 0xA2A6: -case 0xA2A7: -case 0xA2A8: -case 0xA2A9: -case 0xA2AA: -case 0xA2AB: -case 0xA2AC: -case 0xA2AD: -case 0xA2AE: -case 0xA2AF: -case 0xA2B0: -case 0xA2B1: -case 0xA2B2: -case 0xA2B3: -case 0xA2B4: -case 0xA2B5: -case 0xA2B6: -case 0xA2B7: -case 0xA2B8: -case 0xA2B9: -case 0xA2BA: -case 0xA2BB: -case 0xA2BC: -case 0xA2BD: -case 0xA2BE: -case 0xA2BF: -case 0xA2C0: -case 0xA2C1: -case 0xA2C2: -case 0xA2C3: -case 0xA2C4: -case 0xA2C5: -case 0xA2C6: -case 0xA2C7: -case 0xA2C8: -case 0xA2C9: -case 0xA2CA: -case 0xA2CB: -case 0xA2CC: -case 0xA2CD: -case 0xA2CE: -case 0xA2CF: -case 0xA2D0: -case 0xA2D1: -case 0xA2D2: -case 0xA2D3: -case 0xA2D4: -case 0xA2D5: -case 0xA2D6: -case 0xA2D7: -case 0xA2D8: -case 0xA2D9: -case 0xA2DA: -case 0xA2DB: -case 0xA2DC: -case 0xA2DD: -case 0xA2DE: -case 0xA2DF: -case 0xA2E0: -case 0xA2E1: -case 0xA2E2: -case 0xA2E3: -case 0xA2E4: -case 0xA2E5: -case 0xA2E6: -case 0xA2E7: -case 0xA2E8: -case 0xA2E9: -case 0xA2EA: -case 0xA2EB: -case 0xA2EC: -case 0xA2ED: -case 0xA2EE: -case 0xA2EF: -case 0xA2F0: -case 0xA2F1: -case 0xA2F2: -case 0xA2F3: -case 0xA2F4: -case 0xA2F5: -case 0xA2F6: -case 0xA2F7: -case 0xA2F8: -case 0xA2F9: -case 0xA2FA: -case 0xA2FB: -case 0xA2FC: -case 0xA2FD: -case 0xA2FE: -case 0xA2FF: -case 0xA300: -case 0xA301: -case 0xA302: -case 0xA303: -case 0xA304: -case 0xA305: -case 0xA306: -case 0xA307: -case 0xA308: -case 0xA309: -case 0xA30A: -case 0xA30B: -case 0xA30C: -case 0xA30D: -case 0xA30E: -case 0xA30F: -case 0xA310: -case 0xA311: -case 0xA312: -case 0xA313: -case 0xA314: -case 0xA315: -case 0xA316: -case 0xA317: -case 0xA318: -case 0xA319: -case 0xA31A: -case 0xA31B: -case 0xA31C: -case 0xA31D: -case 0xA31E: -case 0xA31F: -case 0xA320: -case 0xA321: -case 0xA322: -case 0xA323: -case 0xA324: -case 0xA325: -case 0xA326: -case 0xA327: -case 0xA328: -case 0xA329: -case 0xA32A: -case 0xA32B: -case 0xA32C: -case 0xA32D: -case 0xA32E: -case 0xA32F: -case 0xA330: -case 0xA331: -case 0xA332: -case 0xA333: -case 0xA334: -case 0xA335: -case 0xA336: -case 0xA337: -case 0xA338: -case 0xA339: -case 0xA33A: -case 0xA33B: -case 0xA33C: -case 0xA33D: -case 0xA33E: -case 0xA33F: -case 0xA340: -case 0xA341: -case 0xA342: -case 0xA343: -case 0xA344: -case 0xA345: -case 0xA346: -case 0xA347: -case 0xA348: -case 0xA349: -case 0xA34A: -case 0xA34B: -case 0xA34C: -case 0xA34D: -case 0xA34E: -case 0xA34F: -case 0xA350: -case 0xA351: -case 0xA352: -case 0xA353: -case 0xA354: -case 0xA355: -case 0xA356: -case 0xA357: -case 0xA358: -case 0xA359: -case 0xA35A: -case 0xA35B: -case 0xA35C: -case 0xA35D: -case 0xA35E: -case 0xA35F: -case 0xA360: -case 0xA361: -case 0xA362: -case 0xA363: -case 0xA364: -case 0xA365: -case 0xA366: -case 0xA367: -case 0xA368: -case 0xA369: -case 0xA36A: -case 0xA36B: -case 0xA36C: -case 0xA36D: -case 0xA36E: -case 0xA36F: -case 0xA370: -case 0xA371: -case 0xA372: -case 0xA373: -case 0xA374: -case 0xA375: -case 0xA376: -case 0xA377: -case 0xA378: -case 0xA379: -case 0xA37A: -case 0xA37B: -case 0xA37C: -case 0xA37D: -case 0xA37E: -case 0xA37F: -case 0xA380: -case 0xA381: -case 0xA382: -case 0xA383: -case 0xA384: -case 0xA385: -case 0xA386: -case 0xA387: -case 0xA388: -case 0xA389: -case 0xA38A: -case 0xA38B: -case 0xA38C: -case 0xA38D: -case 0xA38E: -case 0xA38F: -case 0xA390: -case 0xA391: -case 0xA392: -case 0xA393: -case 0xA394: -case 0xA395: -case 0xA396: -case 0xA397: -case 0xA398: -case 0xA399: -case 0xA39A: -case 0xA39B: -case 0xA39C: -case 0xA39D: -case 0xA39E: -case 0xA39F: -case 0xA3A0: -case 0xA3A1: -case 0xA3A2: -case 0xA3A3: -case 0xA3A4: -case 0xA3A5: -case 0xA3A6: -case 0xA3A7: -case 0xA3A8: -case 0xA3A9: -case 0xA3AA: -case 0xA3AB: -case 0xA3AC: -case 0xA3AD: -case 0xA3AE: -case 0xA3AF: -case 0xA3B0: -case 0xA3B1: -case 0xA3B2: -case 0xA3B3: -case 0xA3B4: -case 0xA3B5: -case 0xA3B6: -case 0xA3B7: -case 0xA3B8: -case 0xA3B9: -case 0xA3BA: -case 0xA3BB: -case 0xA3BC: -case 0xA3BD: -case 0xA3BE: -case 0xA3BF: -case 0xA3C0: -case 0xA3C1: -case 0xA3C2: -case 0xA3C3: -case 0xA3C4: -case 0xA3C5: -case 0xA3C6: -case 0xA3C7: -case 0xA3C8: -case 0xA3C9: -case 0xA3CA: -case 0xA3CB: -case 0xA3CC: -case 0xA3CD: -case 0xA3CE: -case 0xA3CF: -case 0xA3D0: -case 0xA3D1: -case 0xA3D2: -case 0xA3D3: -case 0xA3D4: -case 0xA3D5: -case 0xA3D6: -case 0xA3D7: -case 0xA3D8: -case 0xA3D9: -case 0xA3DA: -case 0xA3DB: -case 0xA3DC: -case 0xA3DD: -case 0xA3DE: -case 0xA3DF: -case 0xA3E0: -case 0xA3E1: -case 0xA3E2: -case 0xA3E3: -case 0xA3E4: -case 0xA3E5: -case 0xA3E6: -case 0xA3E7: -case 0xA3E8: -case 0xA3E9: -case 0xA3EA: -case 0xA3EB: -case 0xA3EC: -case 0xA3ED: -case 0xA3EE: -case 0xA3EF: -case 0xA3F0: -case 0xA3F1: -case 0xA3F2: -case 0xA3F3: -case 0xA3F4: -case 0xA3F5: -case 0xA3F6: -case 0xA3F7: -case 0xA3F8: -case 0xA3F9: -case 0xA3FA: -case 0xA3FB: -case 0xA3FC: -case 0xA3FD: -case 0xA3FE: -case 0xA3FF: -case 0xA400: -case 0xA401: -case 0xA402: -case 0xA403: -case 0xA404: -case 0xA405: -case 0xA406: -case 0xA407: -case 0xA408: -case 0xA409: -case 0xA40A: -case 0xA40B: -case 0xA40C: -case 0xA40D: -case 0xA40E: -case 0xA40F: -case 0xA410: -case 0xA411: -case 0xA412: -case 0xA413: -case 0xA414: -case 0xA415: -case 0xA416: -case 0xA417: -case 0xA418: -case 0xA419: -case 0xA41A: -case 0xA41B: -case 0xA41C: -case 0xA41D: -case 0xA41E: -case 0xA41F: -case 0xA420: -case 0xA421: -case 0xA422: -case 0xA423: -case 0xA424: -case 0xA425: -case 0xA426: -case 0xA427: -case 0xA428: -case 0xA429: -case 0xA42A: -case 0xA42B: -case 0xA42C: -case 0xA42D: -case 0xA42E: -case 0xA42F: -case 0xA430: -case 0xA431: -case 0xA432: -case 0xA433: -case 0xA434: -case 0xA435: -case 0xA436: -case 0xA437: -case 0xA438: -case 0xA439: -case 0xA43A: -case 0xA43B: -case 0xA43C: -case 0xA43D: -case 0xA43E: -case 0xA43F: -case 0xA440: -case 0xA441: -case 0xA442: -case 0xA443: -case 0xA444: -case 0xA445: -case 0xA446: -case 0xA447: -case 0xA448: -case 0xA449: -case 0xA44A: -case 0xA44B: -case 0xA44C: -case 0xA44D: -case 0xA44E: -case 0xA44F: -case 0xA450: -case 0xA451: -case 0xA452: -case 0xA453: -case 0xA454: -case 0xA455: -case 0xA456: -case 0xA457: -case 0xA458: -case 0xA459: -case 0xA45A: -case 0xA45B: -case 0xA45C: -case 0xA45D: -case 0xA45E: -case 0xA45F: -case 0xA460: -case 0xA461: -case 0xA462: -case 0xA463: -case 0xA464: -case 0xA465: -case 0xA466: -case 0xA467: -case 0xA468: -case 0xA469: -case 0xA46A: -case 0xA46B: -case 0xA46C: -case 0xA46D: -case 0xA46E: -case 0xA46F: -case 0xA470: -case 0xA471: -case 0xA472: -case 0xA473: -case 0xA474: -case 0xA475: -case 0xA476: -case 0xA477: -case 0xA478: -case 0xA479: -case 0xA47A: -case 0xA47B: -case 0xA47C: -case 0xA47D: -case 0xA47E: -case 0xA47F: -case 0xA480: -case 0xA481: -case 0xA482: -case 0xA483: -case 0xA484: -case 0xA485: -case 0xA486: -case 0xA487: -case 0xA488: -case 0xA489: -case 0xA48A: -case 0xA48B: -case 0xA48C: -case 0xA48D: -case 0xA48E: -case 0xA48F: -case 0xA490: -case 0xA491: -case 0xA492: -case 0xA493: -case 0xA494: -case 0xA495: -case 0xA496: -case 0xA497: -case 0xA498: -case 0xA499: -case 0xA49A: -case 0xA49B: -case 0xA49C: -case 0xA49D: -case 0xA49E: -case 0xA49F: -case 0xA4A0: -case 0xA4A1: -case 0xA4A2: -case 0xA4A3: -case 0xA4A4: -case 0xA4A5: -case 0xA4A6: -case 0xA4A7: -case 0xA4A8: -case 0xA4A9: -case 0xA4AA: -case 0xA4AB: -case 0xA4AC: -case 0xA4AD: -case 0xA4AE: -case 0xA4AF: -case 0xA4B0: -case 0xA4B1: -case 0xA4B2: -case 0xA4B3: -case 0xA4B4: -case 0xA4B5: -case 0xA4B6: -case 0xA4B7: -case 0xA4B8: -case 0xA4B9: -case 0xA4BA: -case 0xA4BB: -case 0xA4BC: -case 0xA4BD: -case 0xA4BE: -case 0xA4BF: -case 0xA4C0: -case 0xA4C1: -case 0xA4C2: -case 0xA4C3: -case 0xA4C4: -case 0xA4C5: -case 0xA4C6: -case 0xA4C7: -case 0xA4C8: -case 0xA4C9: -case 0xA4CA: -case 0xA4CB: -case 0xA4CC: -case 0xA4CD: -case 0xA4CE: -case 0xA4CF: -case 0xA4D0: -case 0xA4D1: -case 0xA4D2: -case 0xA4D3: -case 0xA4D4: -case 0xA4D5: -case 0xA4D6: -case 0xA4D7: -case 0xA4D8: -case 0xA4D9: -case 0xA4DA: -case 0xA4DB: -case 0xA4DC: -case 0xA4DD: -case 0xA4DE: -case 0xA4DF: -case 0xA4E0: -case 0xA4E1: -case 0xA4E2: -case 0xA4E3: -case 0xA4E4: -case 0xA4E5: -case 0xA4E6: -case 0xA4E7: -case 0xA4E8: -case 0xA4E9: -case 0xA4EA: -case 0xA4EB: -case 0xA4EC: -case 0xA4ED: -case 0xA4EE: -case 0xA4EF: -case 0xA4F0: -case 0xA4F1: -case 0xA4F2: -case 0xA4F3: -case 0xA4F4: -case 0xA4F5: -case 0xA4F6: -case 0xA4F7: -case 0xA4F8: -case 0xA4F9: -case 0xA4FA: -case 0xA4FB: -case 0xA4FC: -case 0xA4FD: -case 0xA4FE: -case 0xA4FF: -case 0xA500: -case 0xA501: -case 0xA502: -case 0xA503: -case 0xA504: -case 0xA505: -case 0xA506: -case 0xA507: -case 0xA508: -case 0xA509: -case 0xA50A: -case 0xA50B: -case 0xA50C: -case 0xA50D: -case 0xA50E: -case 0xA50F: -case 0xA510: -case 0xA511: -case 0xA512: -case 0xA513: -case 0xA514: -case 0xA515: -case 0xA516: -case 0xA517: -case 0xA518: -case 0xA519: -case 0xA51A: -case 0xA51B: -case 0xA51C: -case 0xA51D: -case 0xA51E: -case 0xA51F: -case 0xA520: -case 0xA521: -case 0xA522: -case 0xA523: -case 0xA524: -case 0xA525: -case 0xA526: -case 0xA527: -case 0xA528: -case 0xA529: -case 0xA52A: -case 0xA52B: -case 0xA52C: -case 0xA52D: -case 0xA52E: -case 0xA52F: -case 0xA530: -case 0xA531: -case 0xA532: -case 0xA533: -case 0xA534: -case 0xA535: -case 0xA536: -case 0xA537: -case 0xA538: -case 0xA539: -case 0xA53A: -case 0xA53B: -case 0xA53C: -case 0xA53D: -case 0xA53E: -case 0xA53F: -case 0xA540: -case 0xA541: -case 0xA542: -case 0xA543: -case 0xA544: -case 0xA545: -case 0xA546: -case 0xA547: -case 0xA548: -case 0xA549: -case 0xA54A: -case 0xA54B: -case 0xA54C: -case 0xA54D: -case 0xA54E: -case 0xA54F: -case 0xA550: -case 0xA551: -case 0xA552: -case 0xA553: -case 0xA554: -case 0xA555: -case 0xA556: -case 0xA557: -case 0xA558: -case 0xA559: -case 0xA55A: -case 0xA55B: -case 0xA55C: -case 0xA55D: -case 0xA55E: -case 0xA55F: -case 0xA560: -case 0xA561: -case 0xA562: -case 0xA563: -case 0xA564: -case 0xA565: -case 0xA566: -case 0xA567: -case 0xA568: -case 0xA569: -case 0xA56A: -case 0xA56B: -case 0xA56C: -case 0xA56D: -case 0xA56E: -case 0xA56F: -case 0xA570: -case 0xA571: -case 0xA572: -case 0xA573: -case 0xA574: -case 0xA575: -case 0xA576: -case 0xA577: -case 0xA578: -case 0xA579: -case 0xA57A: -case 0xA57B: -case 0xA57C: -case 0xA57D: -case 0xA57E: -case 0xA57F: -case 0xA580: -case 0xA581: -case 0xA582: -case 0xA583: -case 0xA584: -case 0xA585: -case 0xA586: -case 0xA587: -case 0xA588: -case 0xA589: -case 0xA58A: -case 0xA58B: -case 0xA58C: -case 0xA58D: -case 0xA58E: -case 0xA58F: -case 0xA590: -case 0xA591: -case 0xA592: -case 0xA593: -case 0xA594: -case 0xA595: -case 0xA596: -case 0xA597: -case 0xA598: -case 0xA599: -case 0xA59A: -case 0xA59B: -case 0xA59C: -case 0xA59D: -case 0xA59E: -case 0xA59F: -case 0xA5A0: -case 0xA5A1: -case 0xA5A2: -case 0xA5A3: -case 0xA5A4: -case 0xA5A5: -case 0xA5A6: -case 0xA5A7: -case 0xA5A8: -case 0xA5A9: -case 0xA5AA: -case 0xA5AB: -case 0xA5AC: -case 0xA5AD: -case 0xA5AE: -case 0xA5AF: -case 0xA5B0: -case 0xA5B1: -case 0xA5B2: -case 0xA5B3: -case 0xA5B4: -case 0xA5B5: -case 0xA5B6: -case 0xA5B7: -case 0xA5B8: -case 0xA5B9: -case 0xA5BA: -case 0xA5BB: -case 0xA5BC: -case 0xA5BD: -case 0xA5BE: -case 0xA5BF: -case 0xA5C0: -case 0xA5C1: -case 0xA5C2: -case 0xA5C3: -case 0xA5C4: -case 0xA5C5: -case 0xA5C6: -case 0xA5C7: -case 0xA5C8: -case 0xA5C9: -case 0xA5CA: -case 0xA5CB: -case 0xA5CC: -case 0xA5CD: -case 0xA5CE: -case 0xA5CF: -case 0xA5D0: -case 0xA5D1: -case 0xA5D2: -case 0xA5D3: -case 0xA5D4: -case 0xA5D5: -case 0xA5D6: -case 0xA5D7: -case 0xA5D8: -case 0xA5D9: -case 0xA5DA: -case 0xA5DB: -case 0xA5DC: -case 0xA5DD: -case 0xA5DE: -case 0xA5DF: -case 0xA5E0: -case 0xA5E1: -case 0xA5E2: -case 0xA5E3: -case 0xA5E4: -case 0xA5E5: -case 0xA5E6: -case 0xA5E7: -case 0xA5E8: -case 0xA5E9: -case 0xA5EA: -case 0xA5EB: -case 0xA5EC: -case 0xA5ED: -case 0xA5EE: -case 0xA5EF: -case 0xA5F0: -case 0xA5F1: -case 0xA5F2: -case 0xA5F3: -case 0xA5F4: -case 0xA5F5: -case 0xA5F6: -case 0xA5F7: -case 0xA5F8: -case 0xA5F9: -case 0xA5FA: -case 0xA5FB: -case 0xA5FC: -case 0xA5FD: -case 0xA5FE: -case 0xA5FF: -case 0xA600: -case 0xA601: -case 0xA602: -case 0xA603: -case 0xA604: -case 0xA605: -case 0xA606: -case 0xA607: -case 0xA608: -case 0xA609: -case 0xA60A: -case 0xA60B: -case 0xA60C: -case 0xA60D: -case 0xA60E: -case 0xA60F: -case 0xA610: -case 0xA611: -case 0xA612: -case 0xA613: -case 0xA614: -case 0xA615: -case 0xA616: -case 0xA617: -case 0xA618: -case 0xA619: -case 0xA61A: -case 0xA61B: -case 0xA61C: -case 0xA61D: -case 0xA61E: -case 0xA61F: -case 0xA620: -case 0xA621: -case 0xA622: -case 0xA623: -case 0xA624: -case 0xA625: -case 0xA626: -case 0xA627: -case 0xA628: -case 0xA629: -case 0xA62A: -case 0xA62B: -case 0xA62C: -case 0xA62D: -case 0xA62E: -case 0xA62F: -case 0xA630: -case 0xA631: -case 0xA632: -case 0xA633: -case 0xA634: -case 0xA635: -case 0xA636: -case 0xA637: -case 0xA638: -case 0xA639: -case 0xA63A: -case 0xA63B: -case 0xA63C: -case 0xA63D: -case 0xA63E: -case 0xA63F: -case 0xA640: -case 0xA641: -case 0xA642: -case 0xA643: -case 0xA644: -case 0xA645: -case 0xA646: -case 0xA647: -case 0xA648: -case 0xA649: -case 0xA64A: -case 0xA64B: -case 0xA64C: -case 0xA64D: -case 0xA64E: -case 0xA64F: -case 0xA650: -case 0xA651: -case 0xA652: -case 0xA653: -case 0xA654: -case 0xA655: -case 0xA656: -case 0xA657: -case 0xA658: -case 0xA659: -case 0xA65A: -case 0xA65B: -case 0xA65C: -case 0xA65D: -case 0xA65E: -case 0xA65F: -case 0xA660: -case 0xA661: -case 0xA662: -case 0xA663: -case 0xA664: -case 0xA665: -case 0xA666: -case 0xA667: -case 0xA668: -case 0xA669: -case 0xA66A: -case 0xA66B: -case 0xA66C: -case 0xA66D: -case 0xA66E: -case 0xA66F: -case 0xA670: -case 0xA671: -case 0xA672: -case 0xA673: -case 0xA674: -case 0xA675: -case 0xA676: -case 0xA677: -case 0xA678: -case 0xA679: -case 0xA67A: -case 0xA67B: -case 0xA67C: -case 0xA67D: -case 0xA67E: -case 0xA67F: -case 0xA680: -case 0xA681: -case 0xA682: -case 0xA683: -case 0xA684: -case 0xA685: -case 0xA686: -case 0xA687: -case 0xA688: -case 0xA689: -case 0xA68A: -case 0xA68B: -case 0xA68C: -case 0xA68D: -case 0xA68E: -case 0xA68F: -case 0xA690: -case 0xA691: -case 0xA692: -case 0xA693: -case 0xA694: -case 0xA695: -case 0xA696: -case 0xA697: -case 0xA698: -case 0xA699: -case 0xA69A: -case 0xA69B: -case 0xA69C: -case 0xA69D: -case 0xA69E: -case 0xA69F: -case 0xA6A0: -case 0xA6A1: -case 0xA6A2: -case 0xA6A3: -case 0xA6A4: -case 0xA6A5: -case 0xA6A6: -case 0xA6A7: -case 0xA6A8: -case 0xA6A9: -case 0xA6AA: -case 0xA6AB: -case 0xA6AC: -case 0xA6AD: -case 0xA6AE: -case 0xA6AF: -case 0xA6B0: -case 0xA6B1: -case 0xA6B2: -case 0xA6B3: -case 0xA6B4: -case 0xA6B5: -case 0xA6B6: -case 0xA6B7: -case 0xA6B8: -case 0xA6B9: -case 0xA6BA: -case 0xA6BB: -case 0xA6BC: -case 0xA6BD: -case 0xA6BE: -case 0xA6BF: -case 0xA6C0: -case 0xA6C1: -case 0xA6C2: -case 0xA6C3: -case 0xA6C4: -case 0xA6C5: -case 0xA6C6: -case 0xA6C7: -case 0xA6C8: -case 0xA6C9: -case 0xA6CA: -case 0xA6CB: -case 0xA6CC: -case 0xA6CD: -case 0xA6CE: -case 0xA6CF: -case 0xA6D0: -case 0xA6D1: -case 0xA6D2: -case 0xA6D3: -case 0xA6D4: -case 0xA6D5: -case 0xA6D6: -case 0xA6D7: -case 0xA6D8: -case 0xA6D9: -case 0xA6DA: -case 0xA6DB: -case 0xA6DC: -case 0xA6DD: -case 0xA6DE: -case 0xA6DF: -case 0xA6E0: -case 0xA6E1: -case 0xA6E2: -case 0xA6E3: -case 0xA6E4: -case 0xA6E5: -case 0xA6E6: -case 0xA6E7: -case 0xA6E8: -case 0xA6E9: -case 0xA6EA: -case 0xA6EB: -case 0xA6EC: -case 0xA6ED: -case 0xA6EE: -case 0xA6EF: -case 0xA6F0: -case 0xA6F1: -case 0xA6F2: -case 0xA6F3: -case 0xA6F4: -case 0xA6F5: -case 0xA6F6: -case 0xA6F7: -case 0xA6F8: -case 0xA6F9: -case 0xA6FA: -case 0xA6FB: -case 0xA6FC: -case 0xA6FD: -case 0xA6FE: -case 0xA6FF: -case 0xA700: -case 0xA701: -case 0xA702: -case 0xA703: -case 0xA704: -case 0xA705: -case 0xA706: -case 0xA707: -case 0xA708: -case 0xA709: -case 0xA70A: -case 0xA70B: -case 0xA70C: -case 0xA70D: -case 0xA70E: -case 0xA70F: -case 0xA710: -case 0xA711: -case 0xA712: -case 0xA713: -case 0xA714: -case 0xA715: -case 0xA716: -case 0xA717: -case 0xA718: -case 0xA719: -case 0xA71A: -case 0xA71B: -case 0xA71C: -case 0xA71D: -case 0xA71E: -case 0xA71F: -case 0xA720: -case 0xA721: -case 0xA722: -case 0xA723: -case 0xA724: -case 0xA725: -case 0xA726: -case 0xA727: -case 0xA728: -case 0xA729: -case 0xA72A: -case 0xA72B: -case 0xA72C: -case 0xA72D: -case 0xA72E: -case 0xA72F: -case 0xA730: -case 0xA731: -case 0xA732: -case 0xA733: -case 0xA734: -case 0xA735: -case 0xA736: -case 0xA737: -case 0xA738: -case 0xA739: -case 0xA73A: -case 0xA73B: -case 0xA73C: -case 0xA73D: -case 0xA73E: -case 0xA73F: -case 0xA740: -case 0xA741: -case 0xA742: -case 0xA743: -case 0xA744: -case 0xA745: -case 0xA746: -case 0xA747: -case 0xA748: -case 0xA749: -case 0xA74A: -case 0xA74B: -case 0xA74C: -case 0xA74D: -case 0xA74E: -case 0xA74F: -case 0xA750: -case 0xA751: -case 0xA752: -case 0xA753: -case 0xA754: -case 0xA755: -case 0xA756: -case 0xA757: -case 0xA758: -case 0xA759: -case 0xA75A: -case 0xA75B: -case 0xA75C: -case 0xA75D: -case 0xA75E: -case 0xA75F: -case 0xA760: -case 0xA761: -case 0xA762: -case 0xA763: -case 0xA764: -case 0xA765: -case 0xA766: -case 0xA767: -case 0xA768: -case 0xA769: -case 0xA76A: -case 0xA76B: -case 0xA76C: -case 0xA76D: -case 0xA76E: -case 0xA76F: -case 0xA770: -case 0xA771: -case 0xA772: -case 0xA773: -case 0xA774: -case 0xA775: -case 0xA776: -case 0xA777: -case 0xA778: -case 0xA779: -case 0xA77A: -case 0xA77B: -case 0xA77C: -case 0xA77D: -case 0xA77E: -case 0xA77F: -case 0xA780: -case 0xA781: -case 0xA782: -case 0xA783: -case 0xA784: -case 0xA785: -case 0xA786: -case 0xA787: -case 0xA788: -case 0xA789: -case 0xA78A: -case 0xA78B: -case 0xA78C: -case 0xA78D: -case 0xA78E: -case 0xA78F: -case 0xA790: -case 0xA791: -case 0xA792: -case 0xA793: -case 0xA794: -case 0xA795: -case 0xA796: -case 0xA797: -case 0xA798: -case 0xA799: -case 0xA79A: -case 0xA79B: -case 0xA79C: -case 0xA79D: -case 0xA79E: -case 0xA79F: -case 0xA7A0: -case 0xA7A1: -case 0xA7A2: -case 0xA7A3: -case 0xA7A4: -case 0xA7A5: -case 0xA7A6: -case 0xA7A7: -case 0xA7A8: -case 0xA7A9: -case 0xA7AA: -case 0xA7AB: -case 0xA7AC: -case 0xA7AD: -case 0xA7AE: -case 0xA7AF: -case 0xA7B0: -case 0xA7B1: -case 0xA7B2: -case 0xA7B3: -case 0xA7B4: -case 0xA7B5: -case 0xA7B6: -case 0xA7B7: -case 0xA7B8: -case 0xA7B9: -case 0xA7BA: -case 0xA7BB: -case 0xA7BC: -case 0xA7BD: -case 0xA7BE: -case 0xA7BF: -case 0xA7C0: -case 0xA7C1: -case 0xA7C2: -case 0xA7C3: -case 0xA7C4: -case 0xA7C5: -case 0xA7C6: -case 0xA7C7: -case 0xA7C8: -case 0xA7C9: -case 0xA7CA: -case 0xA7CB: -case 0xA7CC: -case 0xA7CD: -case 0xA7CE: -case 0xA7CF: -case 0xA7D0: -case 0xA7D1: -case 0xA7D2: -case 0xA7D3: -case 0xA7D4: -case 0xA7D5: -case 0xA7D6: -case 0xA7D7: -case 0xA7D8: -case 0xA7D9: -case 0xA7DA: -case 0xA7DB: -case 0xA7DC: -case 0xA7DD: -case 0xA7DE: -case 0xA7DF: -case 0xA7E0: -case 0xA7E1: -case 0xA7E2: -case 0xA7E3: -case 0xA7E4: -case 0xA7E5: -case 0xA7E6: -case 0xA7E7: -case 0xA7E8: -case 0xA7E9: -case 0xA7EA: -case 0xA7EB: -case 0xA7EC: -case 0xA7ED: -case 0xA7EE: -case 0xA7EF: -case 0xA7F0: -case 0xA7F1: -case 0xA7F2: -case 0xA7F3: -case 0xA7F4: -case 0xA7F5: -case 0xA7F6: -case 0xA7F7: -case 0xA7F8: -case 0xA7F9: -case 0xA7FA: -case 0xA7FB: -case 0xA7FC: -case 0xA7FD: -case 0xA7FE: -case 0xA7FF: -case 0xA800: -case 0xA801: -case 0xA802: -case 0xA803: -case 0xA804: -case 0xA805: -case 0xA806: -case 0xA807: -case 0xA808: -case 0xA809: -case 0xA80A: -case 0xA80B: -case 0xA80C: -case 0xA80D: -case 0xA80E: -case 0xA80F: -case 0xA810: -case 0xA811: -case 0xA812: -case 0xA813: -case 0xA814: -case 0xA815: -case 0xA816: -case 0xA817: -case 0xA818: -case 0xA819: -case 0xA81A: -case 0xA81B: -case 0xA81C: -case 0xA81D: -case 0xA81E: -case 0xA81F: -case 0xA820: -case 0xA821: -case 0xA822: -case 0xA823: -case 0xA824: -case 0xA825: -case 0xA826: -case 0xA827: -case 0xA828: -case 0xA829: -case 0xA82A: -case 0xA82B: -case 0xA82C: -case 0xA82D: -case 0xA82E: -case 0xA82F: -case 0xA830: -case 0xA831: -case 0xA832: -case 0xA833: -case 0xA834: -case 0xA835: -case 0xA836: -case 0xA837: -case 0xA838: -case 0xA839: -case 0xA83A: -case 0xA83B: -case 0xA83C: -case 0xA83D: -case 0xA83E: -case 0xA83F: -case 0xA840: -case 0xA841: -case 0xA842: -case 0xA843: -case 0xA844: -case 0xA845: -case 0xA846: -case 0xA847: -case 0xA848: -case 0xA849: -case 0xA84A: -case 0xA84B: -case 0xA84C: -case 0xA84D: -case 0xA84E: -case 0xA84F: -case 0xA850: -case 0xA851: -case 0xA852: -case 0xA853: -case 0xA854: -case 0xA855: -case 0xA856: -case 0xA857: -case 0xA858: -case 0xA859: -case 0xA85A: -case 0xA85B: -case 0xA85C: -case 0xA85D: -case 0xA85E: -case 0xA85F: -case 0xA860: -case 0xA861: -case 0xA862: -case 0xA863: -case 0xA864: -case 0xA865: -case 0xA866: -case 0xA867: -case 0xA868: -case 0xA869: -case 0xA86A: -case 0xA86B: -case 0xA86C: -case 0xA86D: -case 0xA86E: -case 0xA86F: -case 0xA870: -case 0xA871: -case 0xA872: -case 0xA873: -case 0xA874: -case 0xA875: -case 0xA876: -case 0xA877: -case 0xA878: -case 0xA879: -case 0xA87A: -case 0xA87B: -case 0xA87C: -case 0xA87D: -case 0xA87E: -case 0xA87F: -case 0xA880: -case 0xA881: -case 0xA882: -case 0xA883: -case 0xA884: -case 0xA885: -case 0xA886: -case 0xA887: -case 0xA888: -case 0xA889: -case 0xA88A: -case 0xA88B: -case 0xA88C: -case 0xA88D: -case 0xA88E: -case 0xA88F: -case 0xA890: -case 0xA891: -case 0xA892: -case 0xA893: -case 0xA894: -case 0xA895: -case 0xA896: -case 0xA897: -case 0xA898: -case 0xA899: -case 0xA89A: -case 0xA89B: -case 0xA89C: -case 0xA89D: -case 0xA89E: -case 0xA89F: -case 0xA8A0: -case 0xA8A1: -case 0xA8A2: -case 0xA8A3: -case 0xA8A4: -case 0xA8A5: -case 0xA8A6: -case 0xA8A7: -case 0xA8A8: -case 0xA8A9: -case 0xA8AA: -case 0xA8AB: -case 0xA8AC: -case 0xA8AD: -case 0xA8AE: -case 0xA8AF: -case 0xA8B0: -case 0xA8B1: -case 0xA8B2: -case 0xA8B3: -case 0xA8B4: -case 0xA8B5: -case 0xA8B6: -case 0xA8B7: -case 0xA8B8: -case 0xA8B9: -case 0xA8BA: -case 0xA8BB: -case 0xA8BC: -case 0xA8BD: -case 0xA8BE: -case 0xA8BF: -case 0xA8C0: -case 0xA8C1: -case 0xA8C2: -case 0xA8C3: -case 0xA8C4: -case 0xA8C5: -case 0xA8C6: -case 0xA8C7: -case 0xA8C8: -case 0xA8C9: -case 0xA8CA: -case 0xA8CB: -case 0xA8CC: -case 0xA8CD: -case 0xA8CE: -case 0xA8CF: -case 0xA8D0: -case 0xA8D1: -case 0xA8D2: -case 0xA8D3: -case 0xA8D4: -case 0xA8D5: -case 0xA8D6: -case 0xA8D7: -case 0xA8D8: -case 0xA8D9: -case 0xA8DA: -case 0xA8DB: -case 0xA8DC: -case 0xA8DD: -case 0xA8DE: -case 0xA8DF: -case 0xA8E0: -case 0xA8E1: -case 0xA8E2: -case 0xA8E3: -case 0xA8E4: -case 0xA8E5: -case 0xA8E6: -case 0xA8E7: -case 0xA8E8: -case 0xA8E9: -case 0xA8EA: -case 0xA8EB: -case 0xA8EC: -case 0xA8ED: -case 0xA8EE: -case 0xA8EF: -case 0xA8F0: -case 0xA8F1: -case 0xA8F2: -case 0xA8F3: -case 0xA8F4: -case 0xA8F5: -case 0xA8F6: -case 0xA8F7: -case 0xA8F8: -case 0xA8F9: -case 0xA8FA: -case 0xA8FB: -case 0xA8FC: -case 0xA8FD: -case 0xA8FE: -case 0xA8FF: -case 0xA900: -case 0xA901: -case 0xA902: -case 0xA903: -case 0xA904: -case 0xA905: -case 0xA906: -case 0xA907: -case 0xA908: -case 0xA909: -case 0xA90A: -case 0xA90B: -case 0xA90C: -case 0xA90D: -case 0xA90E: -case 0xA90F: -case 0xA910: -case 0xA911: -case 0xA912: -case 0xA913: -case 0xA914: -case 0xA915: -case 0xA916: -case 0xA917: -case 0xA918: -case 0xA919: -case 0xA91A: -case 0xA91B: -case 0xA91C: -case 0xA91D: -case 0xA91E: -case 0xA91F: -case 0xA920: -case 0xA921: -case 0xA922: -case 0xA923: -case 0xA924: -case 0xA925: -case 0xA926: -case 0xA927: -case 0xA928: -case 0xA929: -case 0xA92A: -case 0xA92B: -case 0xA92C: -case 0xA92D: -case 0xA92E: -case 0xA92F: -case 0xA930: -case 0xA931: -case 0xA932: -case 0xA933: -case 0xA934: -case 0xA935: -case 0xA936: -case 0xA937: -case 0xA938: -case 0xA939: -case 0xA93A: -case 0xA93B: -case 0xA93C: -case 0xA93D: -case 0xA93E: -case 0xA93F: -case 0xA940: -case 0xA941: -case 0xA942: -case 0xA943: -case 0xA944: -case 0xA945: -case 0xA946: -case 0xA947: -case 0xA948: -case 0xA949: -case 0xA94A: -case 0xA94B: -case 0xA94C: -case 0xA94D: -case 0xA94E: -case 0xA94F: -case 0xA950: -case 0xA951: -case 0xA952: -case 0xA953: -case 0xA954: -case 0xA955: -case 0xA956: -case 0xA957: -case 0xA958: -case 0xA959: -case 0xA95A: -case 0xA95B: -case 0xA95C: -case 0xA95D: -case 0xA95E: -case 0xA95F: -case 0xA960: -case 0xA961: -case 0xA962: -case 0xA963: -case 0xA964: -case 0xA965: -case 0xA966: -case 0xA967: -case 0xA968: -case 0xA969: -case 0xA96A: -case 0xA96B: -case 0xA96C: -case 0xA96D: -case 0xA96E: -case 0xA96F: -case 0xA970: -case 0xA971: -case 0xA972: -case 0xA973: -case 0xA974: -case 0xA975: -case 0xA976: -case 0xA977: -case 0xA978: -case 0xA979: -case 0xA97A: -case 0xA97B: -case 0xA97C: -case 0xA97D: -case 0xA97E: -case 0xA97F: -case 0xA980: -case 0xA981: -case 0xA982: -case 0xA983: -case 0xA984: -case 0xA985: -case 0xA986: -case 0xA987: -case 0xA988: -case 0xA989: -case 0xA98A: -case 0xA98B: -case 0xA98C: -case 0xA98D: -case 0xA98E: -case 0xA98F: -case 0xA990: -case 0xA991: -case 0xA992: -case 0xA993: -case 0xA994: -case 0xA995: -case 0xA996: -case 0xA997: -case 0xA998: -case 0xA999: -case 0xA99A: -case 0xA99B: -case 0xA99C: -case 0xA99D: -case 0xA99E: -case 0xA99F: -case 0xA9A0: -case 0xA9A1: -case 0xA9A2: -case 0xA9A3: -case 0xA9A4: -case 0xA9A5: -case 0xA9A6: -case 0xA9A7: -case 0xA9A8: -case 0xA9A9: -case 0xA9AA: -case 0xA9AB: -case 0xA9AC: -case 0xA9AD: -case 0xA9AE: -case 0xA9AF: -case 0xA9B0: -case 0xA9B1: -case 0xA9B2: -case 0xA9B3: -case 0xA9B4: -case 0xA9B5: -case 0xA9B6: -case 0xA9B7: -case 0xA9B8: -case 0xA9B9: -case 0xA9BA: -case 0xA9BB: -case 0xA9BC: -case 0xA9BD: -case 0xA9BE: -case 0xA9BF: -case 0xA9C0: -case 0xA9C1: -case 0xA9C2: -case 0xA9C3: -case 0xA9C4: -case 0xA9C5: -case 0xA9C6: -case 0xA9C7: -case 0xA9C8: -case 0xA9C9: -case 0xA9CA: -case 0xA9CB: -case 0xA9CC: -case 0xA9CD: -case 0xA9CE: -case 0xA9CF: -case 0xA9D0: -case 0xA9D1: -case 0xA9D2: -case 0xA9D3: -case 0xA9D4: -case 0xA9D5: -case 0xA9D6: -case 0xA9D7: -case 0xA9D8: -case 0xA9D9: -case 0xA9DA: -case 0xA9DB: -case 0xA9DC: -case 0xA9DD: -case 0xA9DE: -case 0xA9DF: -case 0xA9E0: -case 0xA9E1: -case 0xA9E2: -case 0xA9E3: -case 0xA9E4: -case 0xA9E5: -case 0xA9E6: -case 0xA9E7: -case 0xA9E8: -case 0xA9E9: -case 0xA9EA: -case 0xA9EB: -case 0xA9EC: -case 0xA9ED: -case 0xA9EE: -case 0xA9EF: -case 0xA9F0: -case 0xA9F1: -case 0xA9F2: -case 0xA9F3: -case 0xA9F4: -case 0xA9F5: -case 0xA9F6: -case 0xA9F7: -case 0xA9F8: -case 0xA9F9: -case 0xA9FA: -case 0xA9FB: -case 0xA9FC: -case 0xA9FD: -case 0xA9FE: -case 0xA9FF: -case 0xAA00: -case 0xAA01: -case 0xAA02: -case 0xAA03: -case 0xAA04: -case 0xAA05: -case 0xAA06: -case 0xAA07: -case 0xAA08: -case 0xAA09: -case 0xAA0A: -case 0xAA0B: -case 0xAA0C: -case 0xAA0D: -case 0xAA0E: -case 0xAA0F: -case 0xAA10: -case 0xAA11: -case 0xAA12: -case 0xAA13: -case 0xAA14: -case 0xAA15: -case 0xAA16: -case 0xAA17: -case 0xAA18: -case 0xAA19: -case 0xAA1A: -case 0xAA1B: -case 0xAA1C: -case 0xAA1D: -case 0xAA1E: -case 0xAA1F: -case 0xAA20: -case 0xAA21: -case 0xAA22: -case 0xAA23: -case 0xAA24: -case 0xAA25: -case 0xAA26: -case 0xAA27: -case 0xAA28: -case 0xAA29: -case 0xAA2A: -case 0xAA2B: -case 0xAA2C: -case 0xAA2D: -case 0xAA2E: -case 0xAA2F: -case 0xAA30: -case 0xAA31: -case 0xAA32: -case 0xAA33: -case 0xAA34: -case 0xAA35: -case 0xAA36: -case 0xAA37: -case 0xAA38: -case 0xAA39: -case 0xAA3A: -case 0xAA3B: -case 0xAA3C: -case 0xAA3D: -case 0xAA3E: -case 0xAA3F: -case 0xAA40: -case 0xAA41: -case 0xAA42: -case 0xAA43: -case 0xAA44: -case 0xAA45: -case 0xAA46: -case 0xAA47: -case 0xAA48: -case 0xAA49: -case 0xAA4A: -case 0xAA4B: -case 0xAA4C: -case 0xAA4D: -case 0xAA4E: -case 0xAA4F: -case 0xAA50: -case 0xAA51: -case 0xAA52: -case 0xAA53: -case 0xAA54: -case 0xAA55: -case 0xAA56: -case 0xAA57: -case 0xAA58: -case 0xAA59: -case 0xAA5A: -case 0xAA5B: -case 0xAA5C: -case 0xAA5D: -case 0xAA5E: -case 0xAA5F: -case 0xAA60: -case 0xAA61: -case 0xAA62: -case 0xAA63: -case 0xAA64: -case 0xAA65: -case 0xAA66: -case 0xAA67: -case 0xAA68: -case 0xAA69: -case 0xAA6A: -case 0xAA6B: -case 0xAA6C: -case 0xAA6D: -case 0xAA6E: -case 0xAA6F: -case 0xAA70: -case 0xAA71: -case 0xAA72: -case 0xAA73: -case 0xAA74: -case 0xAA75: -case 0xAA76: -case 0xAA77: -case 0xAA78: -case 0xAA79: -case 0xAA7A: -case 0xAA7B: -case 0xAA7C: -case 0xAA7D: -case 0xAA7E: -case 0xAA7F: -case 0xAA80: -case 0xAA81: -case 0xAA82: -case 0xAA83: -case 0xAA84: -case 0xAA85: -case 0xAA86: -case 0xAA87: -case 0xAA88: -case 0xAA89: -case 0xAA8A: -case 0xAA8B: -case 0xAA8C: -case 0xAA8D: -case 0xAA8E: -case 0xAA8F: -case 0xAA90: -case 0xAA91: -case 0xAA92: -case 0xAA93: -case 0xAA94: -case 0xAA95: -case 0xAA96: -case 0xAA97: -case 0xAA98: -case 0xAA99: -case 0xAA9A: -case 0xAA9B: -case 0xAA9C: -case 0xAA9D: -case 0xAA9E: -case 0xAA9F: -case 0xAAA0: -case 0xAAA1: -case 0xAAA2: -case 0xAAA3: -case 0xAAA4: -case 0xAAA5: -case 0xAAA6: -case 0xAAA7: -case 0xAAA8: -case 0xAAA9: -case 0xAAAA: -case 0xAAAB: -case 0xAAAC: -case 0xAAAD: -case 0xAAAE: -case 0xAAAF: -case 0xAAB0: -case 0xAAB1: -case 0xAAB2: -case 0xAAB3: -case 0xAAB4: -case 0xAAB5: -case 0xAAB6: -case 0xAAB7: -case 0xAAB8: -case 0xAAB9: -case 0xAABA: -case 0xAABB: -case 0xAABC: -case 0xAABD: -case 0xAABE: -case 0xAABF: -case 0xAAC0: -case 0xAAC1: -case 0xAAC2: -case 0xAAC3: -case 0xAAC4: -case 0xAAC5: -case 0xAAC6: -case 0xAAC7: -case 0xAAC8: -case 0xAAC9: -case 0xAACA: -case 0xAACB: -case 0xAACC: -case 0xAACD: -case 0xAACE: -case 0xAACF: -case 0xAAD0: -case 0xAAD1: -case 0xAAD2: -case 0xAAD3: -case 0xAAD4: -case 0xAAD5: -case 0xAAD6: -case 0xAAD7: -case 0xAAD8: -case 0xAAD9: -case 0xAADA: -case 0xAADB: -case 0xAADC: -case 0xAADD: -case 0xAADE: -case 0xAADF: -case 0xAAE0: -case 0xAAE1: -case 0xAAE2: -case 0xAAE3: -case 0xAAE4: -case 0xAAE5: -case 0xAAE6: -case 0xAAE7: -case 0xAAE8: -case 0xAAE9: -case 0xAAEA: -case 0xAAEB: -case 0xAAEC: -case 0xAAED: -case 0xAAEE: -case 0xAAEF: -case 0xAAF0: -case 0xAAF1: -case 0xAAF2: -case 0xAAF3: -case 0xAAF4: -case 0xAAF5: -case 0xAAF6: -case 0xAAF7: -case 0xAAF8: -case 0xAAF9: -case 0xAAFA: -case 0xAAFB: -case 0xAAFC: -case 0xAAFD: -case 0xAAFE: -case 0xAAFF: -case 0xAB00: -case 0xAB01: -case 0xAB02: -case 0xAB03: -case 0xAB04: -case 0xAB05: -case 0xAB06: -case 0xAB07: -case 0xAB08: -case 0xAB09: -case 0xAB0A: -case 0xAB0B: -case 0xAB0C: -case 0xAB0D: -case 0xAB0E: -case 0xAB0F: -case 0xAB10: -case 0xAB11: -case 0xAB12: -case 0xAB13: -case 0xAB14: -case 0xAB15: -case 0xAB16: -case 0xAB17: -case 0xAB18: -case 0xAB19: -case 0xAB1A: -case 0xAB1B: -case 0xAB1C: -case 0xAB1D: -case 0xAB1E: -case 0xAB1F: -case 0xAB20: -case 0xAB21: -case 0xAB22: -case 0xAB23: -case 0xAB24: -case 0xAB25: -case 0xAB26: -case 0xAB27: -case 0xAB28: -case 0xAB29: -case 0xAB2A: -case 0xAB2B: -case 0xAB2C: -case 0xAB2D: -case 0xAB2E: -case 0xAB2F: -case 0xAB30: -case 0xAB31: -case 0xAB32: -case 0xAB33: -case 0xAB34: -case 0xAB35: -case 0xAB36: -case 0xAB37: -case 0xAB38: -case 0xAB39: -case 0xAB3A: -case 0xAB3B: -case 0xAB3C: -case 0xAB3D: -case 0xAB3E: -case 0xAB3F: -case 0xAB40: -case 0xAB41: -case 0xAB42: -case 0xAB43: -case 0xAB44: -case 0xAB45: -case 0xAB46: -case 0xAB47: -case 0xAB48: -case 0xAB49: -case 0xAB4A: -case 0xAB4B: -case 0xAB4C: -case 0xAB4D: -case 0xAB4E: -case 0xAB4F: -case 0xAB50: -case 0xAB51: -case 0xAB52: -case 0xAB53: -case 0xAB54: -case 0xAB55: -case 0xAB56: -case 0xAB57: -case 0xAB58: -case 0xAB59: -case 0xAB5A: -case 0xAB5B: -case 0xAB5C: -case 0xAB5D: -case 0xAB5E: -case 0xAB5F: -case 0xAB60: -case 0xAB61: -case 0xAB62: -case 0xAB63: -case 0xAB64: -case 0xAB65: -case 0xAB66: -case 0xAB67: -case 0xAB68: -case 0xAB69: -case 0xAB6A: -case 0xAB6B: -case 0xAB6C: -case 0xAB6D: -case 0xAB6E: -case 0xAB6F: -case 0xAB70: -case 0xAB71: -case 0xAB72: -case 0xAB73: -case 0xAB74: -case 0xAB75: -case 0xAB76: -case 0xAB77: -case 0xAB78: -case 0xAB79: -case 0xAB7A: -case 0xAB7B: -case 0xAB7C: -case 0xAB7D: -case 0xAB7E: -case 0xAB7F: -case 0xAB80: -case 0xAB81: -case 0xAB82: -case 0xAB83: -case 0xAB84: -case 0xAB85: -case 0xAB86: -case 0xAB87: -case 0xAB88: -case 0xAB89: -case 0xAB8A: -case 0xAB8B: -case 0xAB8C: -case 0xAB8D: -case 0xAB8E: -case 0xAB8F: -case 0xAB90: -case 0xAB91: -case 0xAB92: -case 0xAB93: -case 0xAB94: -case 0xAB95: -case 0xAB96: -case 0xAB97: -case 0xAB98: -case 0xAB99: -case 0xAB9A: -case 0xAB9B: -case 0xAB9C: -case 0xAB9D: -case 0xAB9E: -case 0xAB9F: -case 0xABA0: -case 0xABA1: -case 0xABA2: -case 0xABA3: -case 0xABA4: -case 0xABA5: -case 0xABA6: -case 0xABA7: -case 0xABA8: -case 0xABA9: -case 0xABAA: -case 0xABAB: -case 0xABAC: -case 0xABAD: -case 0xABAE: -case 0xABAF: -case 0xABB0: -case 0xABB1: -case 0xABB2: -case 0xABB3: -case 0xABB4: -case 0xABB5: -case 0xABB6: -case 0xABB7: -case 0xABB8: -case 0xABB9: -case 0xABBA: -case 0xABBB: -case 0xABBC: -case 0xABBD: -case 0xABBE: -case 0xABBF: -case 0xABC0: -case 0xABC1: -case 0xABC2: -case 0xABC3: -case 0xABC4: -case 0xABC5: -case 0xABC6: -case 0xABC7: -case 0xABC8: -case 0xABC9: -case 0xABCA: -case 0xABCB: -case 0xABCC: -case 0xABCD: -case 0xABCE: -case 0xABCF: -case 0xABD0: -case 0xABD1: -case 0xABD2: -case 0xABD3: -case 0xABD4: -case 0xABD5: -case 0xABD6: -case 0xABD7: -case 0xABD8: -case 0xABD9: -case 0xABDA: -case 0xABDB: -case 0xABDC: -case 0xABDD: -case 0xABDE: -case 0xABDF: -case 0xABE0: -case 0xABE1: -case 0xABE2: -case 0xABE3: -case 0xABE4: -case 0xABE5: -case 0xABE6: -case 0xABE7: -case 0xABE8: -case 0xABE9: -case 0xABEA: -case 0xABEB: -case 0xABEC: -case 0xABED: -case 0xABEE: -case 0xABEF: -case 0xABF0: -case 0xABF1: -case 0xABF2: -case 0xABF3: -case 0xABF4: -case 0xABF5: -case 0xABF6: -case 0xABF7: -case 0xABF8: -case 0xABF9: -case 0xABFA: -case 0xABFB: -case 0xABFC: -case 0xABFD: -case 0xABFE: -case 0xABFF: -case 0xAC00: -case 0xAC01: -case 0xAC02: -case 0xAC03: -case 0xAC04: -case 0xAC05: -case 0xAC06: -case 0xAC07: -case 0xAC08: -case 0xAC09: -case 0xAC0A: -case 0xAC0B: -case 0xAC0C: -case 0xAC0D: -case 0xAC0E: -case 0xAC0F: -case 0xAC10: -case 0xAC11: -case 0xAC12: -case 0xAC13: -case 0xAC14: -case 0xAC15: -case 0xAC16: -case 0xAC17: -case 0xAC18: -case 0xAC19: -case 0xAC1A: -case 0xAC1B: -case 0xAC1C: -case 0xAC1D: -case 0xAC1E: -case 0xAC1F: -case 0xAC20: -case 0xAC21: -case 0xAC22: -case 0xAC23: -case 0xAC24: -case 0xAC25: -case 0xAC26: -case 0xAC27: -case 0xAC28: -case 0xAC29: -case 0xAC2A: -case 0xAC2B: -case 0xAC2C: -case 0xAC2D: -case 0xAC2E: -case 0xAC2F: -case 0xAC30: -case 0xAC31: -case 0xAC32: -case 0xAC33: -case 0xAC34: -case 0xAC35: -case 0xAC36: -case 0xAC37: -case 0xAC38: -case 0xAC39: -case 0xAC3A: -case 0xAC3B: -case 0xAC3C: -case 0xAC3D: -case 0xAC3E: -case 0xAC3F: -case 0xAC40: -case 0xAC41: -case 0xAC42: -case 0xAC43: -case 0xAC44: -case 0xAC45: -case 0xAC46: -case 0xAC47: -case 0xAC48: -case 0xAC49: -case 0xAC4A: -case 0xAC4B: -case 0xAC4C: -case 0xAC4D: -case 0xAC4E: -case 0xAC4F: -case 0xAC50: -case 0xAC51: -case 0xAC52: -case 0xAC53: -case 0xAC54: -case 0xAC55: -case 0xAC56: -case 0xAC57: -case 0xAC58: -case 0xAC59: -case 0xAC5A: -case 0xAC5B: -case 0xAC5C: -case 0xAC5D: -case 0xAC5E: -case 0xAC5F: -case 0xAC60: -case 0xAC61: -case 0xAC62: -case 0xAC63: -case 0xAC64: -case 0xAC65: -case 0xAC66: -case 0xAC67: -case 0xAC68: -case 0xAC69: -case 0xAC6A: -case 0xAC6B: -case 0xAC6C: -case 0xAC6D: -case 0xAC6E: -case 0xAC6F: -case 0xAC70: -case 0xAC71: -case 0xAC72: -case 0xAC73: -case 0xAC74: -case 0xAC75: -case 0xAC76: -case 0xAC77: -case 0xAC78: -case 0xAC79: -case 0xAC7A: -case 0xAC7B: -case 0xAC7C: -case 0xAC7D: -case 0xAC7E: -case 0xAC7F: -case 0xAC80: -case 0xAC81: -case 0xAC82: -case 0xAC83: -case 0xAC84: -case 0xAC85: -case 0xAC86: -case 0xAC87: -case 0xAC88: -case 0xAC89: -case 0xAC8A: -case 0xAC8B: -case 0xAC8C: -case 0xAC8D: -case 0xAC8E: -case 0xAC8F: -case 0xAC90: -case 0xAC91: -case 0xAC92: -case 0xAC93: -case 0xAC94: -case 0xAC95: -case 0xAC96: -case 0xAC97: -case 0xAC98: -case 0xAC99: -case 0xAC9A: -case 0xAC9B: -case 0xAC9C: -case 0xAC9D: -case 0xAC9E: -case 0xAC9F: -case 0xACA0: -case 0xACA1: -case 0xACA2: -case 0xACA3: -case 0xACA4: -case 0xACA5: -case 0xACA6: -case 0xACA7: -case 0xACA8: -case 0xACA9: -case 0xACAA: -case 0xACAB: -case 0xACAC: -case 0xACAD: -case 0xACAE: -case 0xACAF: -case 0xACB0: -case 0xACB1: -case 0xACB2: -case 0xACB3: -case 0xACB4: -case 0xACB5: -case 0xACB6: -case 0xACB7: -case 0xACB8: -case 0xACB9: -case 0xACBA: -case 0xACBB: -case 0xACBC: -case 0xACBD: -case 0xACBE: -case 0xACBF: -case 0xACC0: -case 0xACC1: -case 0xACC2: -case 0xACC3: -case 0xACC4: -case 0xACC5: -case 0xACC6: -case 0xACC7: -case 0xACC8: -case 0xACC9: -case 0xACCA: -case 0xACCB: -case 0xACCC: -case 0xACCD: -case 0xACCE: -case 0xACCF: -case 0xACD0: -case 0xACD1: -case 0xACD2: -case 0xACD3: -case 0xACD4: -case 0xACD5: -case 0xACD6: -case 0xACD7: -case 0xACD8: -case 0xACD9: -case 0xACDA: -case 0xACDB: -case 0xACDC: -case 0xACDD: -case 0xACDE: -case 0xACDF: -case 0xACE0: -case 0xACE1: -case 0xACE2: -case 0xACE3: -case 0xACE4: -case 0xACE5: -case 0xACE6: -case 0xACE7: -case 0xACE8: -case 0xACE9: -case 0xACEA: -case 0xACEB: -case 0xACEC: -case 0xACED: -case 0xACEE: -case 0xACEF: -case 0xACF0: -case 0xACF1: -case 0xACF2: -case 0xACF3: -case 0xACF4: -case 0xACF5: -case 0xACF6: -case 0xACF7: -case 0xACF8: -case 0xACF9: -case 0xACFA: -case 0xACFB: -case 0xACFC: -case 0xACFD: -case 0xACFE: -case 0xACFF: -case 0xAD00: -case 0xAD01: -case 0xAD02: -case 0xAD03: -case 0xAD04: -case 0xAD05: -case 0xAD06: -case 0xAD07: -case 0xAD08: -case 0xAD09: -case 0xAD0A: -case 0xAD0B: -case 0xAD0C: -case 0xAD0D: -case 0xAD0E: -case 0xAD0F: -case 0xAD10: -case 0xAD11: -case 0xAD12: -case 0xAD13: -case 0xAD14: -case 0xAD15: -case 0xAD16: -case 0xAD17: -case 0xAD18: -case 0xAD19: -case 0xAD1A: -case 0xAD1B: -case 0xAD1C: -case 0xAD1D: -case 0xAD1E: -case 0xAD1F: -case 0xAD20: -case 0xAD21: -case 0xAD22: -case 0xAD23: -case 0xAD24: -case 0xAD25: -case 0xAD26: -case 0xAD27: -case 0xAD28: -case 0xAD29: -case 0xAD2A: -case 0xAD2B: -case 0xAD2C: -case 0xAD2D: -case 0xAD2E: -case 0xAD2F: -case 0xAD30: -case 0xAD31: -case 0xAD32: -case 0xAD33: -case 0xAD34: -case 0xAD35: -case 0xAD36: -case 0xAD37: -case 0xAD38: -case 0xAD39: -case 0xAD3A: -case 0xAD3B: -case 0xAD3C: -case 0xAD3D: -case 0xAD3E: -case 0xAD3F: -case 0xAD40: -case 0xAD41: -case 0xAD42: -case 0xAD43: -case 0xAD44: -case 0xAD45: -case 0xAD46: -case 0xAD47: -case 0xAD48: -case 0xAD49: -case 0xAD4A: -case 0xAD4B: -case 0xAD4C: -case 0xAD4D: -case 0xAD4E: -case 0xAD4F: -case 0xAD50: -case 0xAD51: -case 0xAD52: -case 0xAD53: -case 0xAD54: -case 0xAD55: -case 0xAD56: -case 0xAD57: -case 0xAD58: -case 0xAD59: -case 0xAD5A: -case 0xAD5B: -case 0xAD5C: -case 0xAD5D: -case 0xAD5E: -case 0xAD5F: -case 0xAD60: -case 0xAD61: -case 0xAD62: -case 0xAD63: -case 0xAD64: -case 0xAD65: -case 0xAD66: -case 0xAD67: -case 0xAD68: -case 0xAD69: -case 0xAD6A: -case 0xAD6B: -case 0xAD6C: -case 0xAD6D: -case 0xAD6E: -case 0xAD6F: -case 0xAD70: -case 0xAD71: -case 0xAD72: -case 0xAD73: -case 0xAD74: -case 0xAD75: -case 0xAD76: -case 0xAD77: -case 0xAD78: -case 0xAD79: -case 0xAD7A: -case 0xAD7B: -case 0xAD7C: -case 0xAD7D: -case 0xAD7E: -case 0xAD7F: -case 0xAD80: -case 0xAD81: -case 0xAD82: -case 0xAD83: -case 0xAD84: -case 0xAD85: -case 0xAD86: -case 0xAD87: -case 0xAD88: -case 0xAD89: -case 0xAD8A: -case 0xAD8B: -case 0xAD8C: -case 0xAD8D: -case 0xAD8E: -case 0xAD8F: -case 0xAD90: -case 0xAD91: -case 0xAD92: -case 0xAD93: -case 0xAD94: -case 0xAD95: -case 0xAD96: -case 0xAD97: -case 0xAD98: -case 0xAD99: -case 0xAD9A: -case 0xAD9B: -case 0xAD9C: -case 0xAD9D: -case 0xAD9E: -case 0xAD9F: -case 0xADA0: -case 0xADA1: -case 0xADA2: -case 0xADA3: -case 0xADA4: -case 0xADA5: -case 0xADA6: -case 0xADA7: -case 0xADA8: -case 0xADA9: -case 0xADAA: -case 0xADAB: -case 0xADAC: -case 0xADAD: -case 0xADAE: -case 0xADAF: -case 0xADB0: -case 0xADB1: -case 0xADB2: -case 0xADB3: -case 0xADB4: -case 0xADB5: -case 0xADB6: -case 0xADB7: -case 0xADB8: -case 0xADB9: -case 0xADBA: -case 0xADBB: -case 0xADBC: -case 0xADBD: -case 0xADBE: -case 0xADBF: -case 0xADC0: -case 0xADC1: -case 0xADC2: -case 0xADC3: -case 0xADC4: -case 0xADC5: -case 0xADC6: -case 0xADC7: -case 0xADC8: -case 0xADC9: -case 0xADCA: -case 0xADCB: -case 0xADCC: -case 0xADCD: -case 0xADCE: -case 0xADCF: -case 0xADD0: -case 0xADD1: -case 0xADD2: -case 0xADD3: -case 0xADD4: -case 0xADD5: -case 0xADD6: -case 0xADD7: -case 0xADD8: -case 0xADD9: -case 0xADDA: -case 0xADDB: -case 0xADDC: -case 0xADDD: -case 0xADDE: -case 0xADDF: -case 0xADE0: -case 0xADE1: -case 0xADE2: -case 0xADE3: -case 0xADE4: -case 0xADE5: -case 0xADE6: -case 0xADE7: -case 0xADE8: -case 0xADE9: -case 0xADEA: -case 0xADEB: -case 0xADEC: -case 0xADED: -case 0xADEE: -case 0xADEF: -case 0xADF0: -case 0xADF1: -case 0xADF2: -case 0xADF3: -case 0xADF4: -case 0xADF5: -case 0xADF6: -case 0xADF7: -case 0xADF8: -case 0xADF9: -case 0xADFA: -case 0xADFB: -case 0xADFC: -case 0xADFD: -case 0xADFE: -case 0xADFF: -case 0xAE00: -case 0xAE01: -case 0xAE02: -case 0xAE03: -case 0xAE04: -case 0xAE05: -case 0xAE06: -case 0xAE07: -case 0xAE08: -case 0xAE09: -case 0xAE0A: -case 0xAE0B: -case 0xAE0C: -case 0xAE0D: -case 0xAE0E: -case 0xAE0F: -case 0xAE10: -case 0xAE11: -case 0xAE12: -case 0xAE13: -case 0xAE14: -case 0xAE15: -case 0xAE16: -case 0xAE17: -case 0xAE18: -case 0xAE19: -case 0xAE1A: -case 0xAE1B: -case 0xAE1C: -case 0xAE1D: -case 0xAE1E: -case 0xAE1F: -case 0xAE20: -case 0xAE21: -case 0xAE22: -case 0xAE23: -case 0xAE24: -case 0xAE25: -case 0xAE26: -case 0xAE27: -case 0xAE28: -case 0xAE29: -case 0xAE2A: -case 0xAE2B: -case 0xAE2C: -case 0xAE2D: -case 0xAE2E: -case 0xAE2F: -case 0xAE30: -case 0xAE31: -case 0xAE32: -case 0xAE33: -case 0xAE34: -case 0xAE35: -case 0xAE36: -case 0xAE37: -case 0xAE38: -case 0xAE39: -case 0xAE3A: -case 0xAE3B: -case 0xAE3C: -case 0xAE3D: -case 0xAE3E: -case 0xAE3F: -case 0xAE40: -case 0xAE41: -case 0xAE42: -case 0xAE43: -case 0xAE44: -case 0xAE45: -case 0xAE46: -case 0xAE47: -case 0xAE48: -case 0xAE49: -case 0xAE4A: -case 0xAE4B: -case 0xAE4C: -case 0xAE4D: -case 0xAE4E: -case 0xAE4F: -case 0xAE50: -case 0xAE51: -case 0xAE52: -case 0xAE53: -case 0xAE54: -case 0xAE55: -case 0xAE56: -case 0xAE57: -case 0xAE58: -case 0xAE59: -case 0xAE5A: -case 0xAE5B: -case 0xAE5C: -case 0xAE5D: -case 0xAE5E: -case 0xAE5F: -case 0xAE60: -case 0xAE61: -case 0xAE62: -case 0xAE63: -case 0xAE64: -case 0xAE65: -case 0xAE66: -case 0xAE67: -case 0xAE68: -case 0xAE69: -case 0xAE6A: -case 0xAE6B: -case 0xAE6C: -case 0xAE6D: -case 0xAE6E: -case 0xAE6F: -case 0xAE70: -case 0xAE71: -case 0xAE72: -case 0xAE73: -case 0xAE74: -case 0xAE75: -case 0xAE76: -case 0xAE77: -case 0xAE78: -case 0xAE79: -case 0xAE7A: -case 0xAE7B: -case 0xAE7C: -case 0xAE7D: -case 0xAE7E: -case 0xAE7F: -case 0xAE80: -case 0xAE81: -case 0xAE82: -case 0xAE83: -case 0xAE84: -case 0xAE85: -case 0xAE86: -case 0xAE87: -case 0xAE88: -case 0xAE89: -case 0xAE8A: -case 0xAE8B: -case 0xAE8C: -case 0xAE8D: -case 0xAE8E: -case 0xAE8F: -case 0xAE90: -case 0xAE91: -case 0xAE92: -case 0xAE93: -case 0xAE94: -case 0xAE95: -case 0xAE96: -case 0xAE97: -case 0xAE98: -case 0xAE99: -case 0xAE9A: -case 0xAE9B: -case 0xAE9C: -case 0xAE9D: -case 0xAE9E: -case 0xAE9F: -case 0xAEA0: -case 0xAEA1: -case 0xAEA2: -case 0xAEA3: -case 0xAEA4: -case 0xAEA5: -case 0xAEA6: -case 0xAEA7: -case 0xAEA8: -case 0xAEA9: -case 0xAEAA: -case 0xAEAB: -case 0xAEAC: -case 0xAEAD: -case 0xAEAE: -case 0xAEAF: -case 0xAEB0: -case 0xAEB1: -case 0xAEB2: -case 0xAEB3: -case 0xAEB4: -case 0xAEB5: -case 0xAEB6: -case 0xAEB7: -case 0xAEB8: -case 0xAEB9: -case 0xAEBA: -case 0xAEBB: -case 0xAEBC: -case 0xAEBD: -case 0xAEBE: -case 0xAEBF: -case 0xAEC0: -case 0xAEC1: -case 0xAEC2: -case 0xAEC3: -case 0xAEC4: -case 0xAEC5: -case 0xAEC6: -case 0xAEC7: -case 0xAEC8: -case 0xAEC9: -case 0xAECA: -case 0xAECB: -case 0xAECC: -case 0xAECD: -case 0xAECE: -case 0xAECF: -case 0xAED0: -case 0xAED1: -case 0xAED2: -case 0xAED3: -case 0xAED4: -case 0xAED5: -case 0xAED6: -case 0xAED7: -case 0xAED8: -case 0xAED9: -case 0xAEDA: -case 0xAEDB: -case 0xAEDC: -case 0xAEDD: -case 0xAEDE: -case 0xAEDF: -case 0xAEE0: -case 0xAEE1: -case 0xAEE2: -case 0xAEE3: -case 0xAEE4: -case 0xAEE5: -case 0xAEE6: -case 0xAEE7: -case 0xAEE8: -case 0xAEE9: -case 0xAEEA: -case 0xAEEB: -case 0xAEEC: -case 0xAEED: -case 0xAEEE: -case 0xAEEF: -case 0xAEF0: -case 0xAEF1: -case 0xAEF2: -case 0xAEF3: -case 0xAEF4: -case 0xAEF5: -case 0xAEF6: -case 0xAEF7: -case 0xAEF8: -case 0xAEF9: -case 0xAEFA: -case 0xAEFB: -case 0xAEFC: -case 0xAEFD: -case 0xAEFE: -case 0xAEFF: -case 0xAF00: -case 0xAF01: -case 0xAF02: -case 0xAF03: -case 0xAF04: -case 0xAF05: -case 0xAF06: -case 0xAF07: -case 0xAF08: -case 0xAF09: -case 0xAF0A: -case 0xAF0B: -case 0xAF0C: -case 0xAF0D: -case 0xAF0E: -case 0xAF0F: -case 0xAF10: -case 0xAF11: -case 0xAF12: -case 0xAF13: -case 0xAF14: -case 0xAF15: -case 0xAF16: -case 0xAF17: -case 0xAF18: -case 0xAF19: -case 0xAF1A: -case 0xAF1B: -case 0xAF1C: -case 0xAF1D: -case 0xAF1E: -case 0xAF1F: -case 0xAF20: -case 0xAF21: -case 0xAF22: -case 0xAF23: -case 0xAF24: -case 0xAF25: -case 0xAF26: -case 0xAF27: -case 0xAF28: -case 0xAF29: -case 0xAF2A: -case 0xAF2B: -case 0xAF2C: -case 0xAF2D: -case 0xAF2E: -case 0xAF2F: -case 0xAF30: -case 0xAF31: -case 0xAF32: -case 0xAF33: -case 0xAF34: -case 0xAF35: -case 0xAF36: -case 0xAF37: -case 0xAF38: -case 0xAF39: -case 0xAF3A: -case 0xAF3B: -case 0xAF3C: -case 0xAF3D: -case 0xAF3E: -case 0xAF3F: -case 0xAF40: -case 0xAF41: -case 0xAF42: -case 0xAF43: -case 0xAF44: -case 0xAF45: -case 0xAF46: -case 0xAF47: -case 0xAF48: -case 0xAF49: -case 0xAF4A: -case 0xAF4B: -case 0xAF4C: -case 0xAF4D: -case 0xAF4E: -case 0xAF4F: -case 0xAF50: -case 0xAF51: -case 0xAF52: -case 0xAF53: -case 0xAF54: -case 0xAF55: -case 0xAF56: -case 0xAF57: -case 0xAF58: -case 0xAF59: -case 0xAF5A: -case 0xAF5B: -case 0xAF5C: -case 0xAF5D: -case 0xAF5E: -case 0xAF5F: -case 0xAF60: -case 0xAF61: -case 0xAF62: -case 0xAF63: -case 0xAF64: -case 0xAF65: -case 0xAF66: -case 0xAF67: -case 0xAF68: -case 0xAF69: -case 0xAF6A: -case 0xAF6B: -case 0xAF6C: -case 0xAF6D: -case 0xAF6E: -case 0xAF6F: -case 0xAF70: -case 0xAF71: -case 0xAF72: -case 0xAF73: -case 0xAF74: -case 0xAF75: -case 0xAF76: -case 0xAF77: -case 0xAF78: -case 0xAF79: -case 0xAF7A: -case 0xAF7B: -case 0xAF7C: -case 0xAF7D: -case 0xAF7E: -case 0xAF7F: -case 0xAF80: -case 0xAF81: -case 0xAF82: -case 0xAF83: -case 0xAF84: -case 0xAF85: -case 0xAF86: -case 0xAF87: -case 0xAF88: -case 0xAF89: -case 0xAF8A: -case 0xAF8B: -case 0xAF8C: -case 0xAF8D: -case 0xAF8E: -case 0xAF8F: -case 0xAF90: -case 0xAF91: -case 0xAF92: -case 0xAF93: -case 0xAF94: -case 0xAF95: -case 0xAF96: -case 0xAF97: -case 0xAF98: -case 0xAF99: -case 0xAF9A: -case 0xAF9B: -case 0xAF9C: -case 0xAF9D: -case 0xAF9E: -case 0xAF9F: -case 0xAFA0: -case 0xAFA1: -case 0xAFA2: -case 0xAFA3: -case 0xAFA4: -case 0xAFA5: -case 0xAFA6: -case 0xAFA7: -case 0xAFA8: -case 0xAFA9: -case 0xAFAA: -case 0xAFAB: -case 0xAFAC: -case 0xAFAD: -case 0xAFAE: -case 0xAFAF: -case 0xAFB0: -case 0xAFB1: -case 0xAFB2: -case 0xAFB3: -case 0xAFB4: -case 0xAFB5: -case 0xAFB6: -case 0xAFB7: -case 0xAFB8: -case 0xAFB9: -case 0xAFBA: -case 0xAFBB: -case 0xAFBC: -case 0xAFBD: -case 0xAFBE: -case 0xAFBF: -case 0xAFC0: -case 0xAFC1: -case 0xAFC2: -case 0xAFC3: -case 0xAFC4: -case 0xAFC5: -case 0xAFC6: -case 0xAFC7: -case 0xAFC8: -case 0xAFC9: -case 0xAFCA: -case 0xAFCB: -case 0xAFCC: -case 0xAFCD: -case 0xAFCE: -case 0xAFCF: -case 0xAFD0: -case 0xAFD1: -case 0xAFD2: -case 0xAFD3: -case 0xAFD4: -case 0xAFD5: -case 0xAFD6: -case 0xAFD7: -case 0xAFD8: -case 0xAFD9: -case 0xAFDA: -case 0xAFDB: -case 0xAFDC: -case 0xAFDD: -case 0xAFDE: -case 0xAFDF: -case 0xAFE0: -case 0xAFE1: -case 0xAFE2: -case 0xAFE3: -case 0xAFE4: -case 0xAFE5: -case 0xAFE6: -case 0xAFE7: -case 0xAFE8: -case 0xAFE9: -case 0xAFEA: -case 0xAFEB: -case 0xAFEC: -case 0xAFED: -case 0xAFEE: -case 0xAFEF: -case 0xAFF0: -case 0xAFF1: -case 0xAFF2: -case 0xAFF3: -case 0xAFF4: -case 0xAFF5: -case 0xAFF6: -case 0xAFF7: -case 0xAFF8: -case 0xAFF9: -case 0xAFFA: -case 0xAFFB: -case 0xAFFC: -case 0xAFFD: -case 0xAFFE: -case 0xAFFF: - -// 1010 -case 0xA000: -{ - u32 res; - PC -= 2; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_1010_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) diff --git a/yabause/src/c68k/c68k_opB.inc b/yabause/src/c68k/c68k_opB.inc deleted file mode 100644 index 84175c98a9..0000000000 --- a/yabause/src/c68k/c68k_opB.inc +++ /dev/null @@ -1,5970 +0,0 @@ -case 0xB200: -case 0xB400: -case 0xB600: -case 0xB800: -case 0xBA00: -case 0xBC00: -case 0xBE00: -case 0xB001: -case 0xB201: -case 0xB401: -case 0xB601: -case 0xB801: -case 0xBA01: -case 0xBC01: -case 0xBE01: -case 0xB002: -case 0xB202: -case 0xB402: -case 0xB602: -case 0xB802: -case 0xBA02: -case 0xBC02: -case 0xBE02: -case 0xB003: -case 0xB203: -case 0xB403: -case 0xB603: -case 0xB803: -case 0xBA03: -case 0xBC03: -case 0xBE03: -case 0xB004: -case 0xB204: -case 0xB404: -case 0xB604: -case 0xB804: -case 0xBA04: -case 0xBC04: -case 0xBE04: -case 0xB005: -case 0xB205: -case 0xB405: -case 0xB605: -case 0xB805: -case 0xBA05: -case 0xBC05: -case 0xBE05: -case 0xB006: -case 0xB206: -case 0xB406: -case 0xB606: -case 0xB806: -case 0xBA06: -case 0xBC06: -case 0xBE06: -case 0xB007: -case 0xB207: -case 0xB407: -case 0xB607: -case 0xB807: -case 0xBA07: -case 0xBC07: -case 0xBE07: - -// CMP -case 0xB000: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(4) -case 0xB208: -case 0xB408: -case 0xB608: -case 0xB808: -case 0xBA08: -case 0xBC08: -case 0xBE08: -case 0xB009: -case 0xB209: -case 0xB409: -case 0xB609: -case 0xB809: -case 0xBA09: -case 0xBC09: -case 0xBE09: -case 0xB00A: -case 0xB20A: -case 0xB40A: -case 0xB60A: -case 0xB80A: -case 0xBA0A: -case 0xBC0A: -case 0xBE0A: -case 0xB00B: -case 0xB20B: -case 0xB40B: -case 0xB60B: -case 0xB80B: -case 0xBA0B: -case 0xBC0B: -case 0xBE0B: -case 0xB00C: -case 0xB20C: -case 0xB40C: -case 0xB60C: -case 0xB80C: -case 0xBA0C: -case 0xBC0C: -case 0xBE0C: -case 0xB00D: -case 0xB20D: -case 0xB40D: -case 0xB60D: -case 0xB80D: -case 0xBA0D: -case 0xBC0D: -case 0xBE0D: -case 0xB00E: -case 0xB20E: -case 0xB40E: -case 0xB60E: -case 0xB80E: -case 0xBA0E: -case 0xBC0E: -case 0xBE0E: -case 0xB00F: -case 0xB20F: -case 0xB40F: -case 0xB60F: -case 0xB80F: -case 0xBA0F: -case 0xBC0F: -case 0xBE0F: - -// CMP -case 0xB008: -{ - u32 res; - pointer dst; - pointer src; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(4) -case 0xB210: -case 0xB410: -case 0xB610: -case 0xB810: -case 0xBA10: -case 0xBC10: -case 0xBE10: -case 0xB011: -case 0xB211: -case 0xB411: -case 0xB611: -case 0xB811: -case 0xBA11: -case 0xBC11: -case 0xBE11: -case 0xB012: -case 0xB212: -case 0xB412: -case 0xB612: -case 0xB812: -case 0xBA12: -case 0xBC12: -case 0xBE12: -case 0xB013: -case 0xB213: -case 0xB413: -case 0xB613: -case 0xB813: -case 0xBA13: -case 0xBC13: -case 0xBE13: -case 0xB014: -case 0xB214: -case 0xB414: -case 0xB614: -case 0xB814: -case 0xBA14: -case 0xBC14: -case 0xBE14: -case 0xB015: -case 0xB215: -case 0xB415: -case 0xB615: -case 0xB815: -case 0xBA15: -case 0xBC15: -case 0xBE15: -case 0xB016: -case 0xB216: -case 0xB416: -case 0xB616: -case 0xB816: -case 0xBA16: -case 0xBC16: -case 0xBE16: -case 0xB017: -case 0xB217: -case 0xB417: -case 0xB617: -case 0xB817: -case 0xBA17: -case 0xBC17: -case 0xBE17: - -// CMP -case 0xB010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(8) -case 0xB218: -case 0xB418: -case 0xB618: -case 0xB818: -case 0xBA18: -case 0xBC18: -case 0xBE18: -case 0xB019: -case 0xB219: -case 0xB419: -case 0xB619: -case 0xB819: -case 0xBA19: -case 0xBC19: -case 0xBE19: -case 0xB01A: -case 0xB21A: -case 0xB41A: -case 0xB61A: -case 0xB81A: -case 0xBA1A: -case 0xBC1A: -case 0xBE1A: -case 0xB01B: -case 0xB21B: -case 0xB41B: -case 0xB61B: -case 0xB81B: -case 0xBA1B: -case 0xBC1B: -case 0xBE1B: -case 0xB01C: -case 0xB21C: -case 0xB41C: -case 0xB61C: -case 0xB81C: -case 0xBA1C: -case 0xBC1C: -case 0xBE1C: -case 0xB01D: -case 0xB21D: -case 0xB41D: -case 0xB61D: -case 0xB81D: -case 0xBA1D: -case 0xBC1D: -case 0xBE1D: -case 0xB01E: -case 0xB21E: -case 0xB41E: -case 0xB61E: -case 0xB81E: -case 0xBA1E: -case 0xBC1E: -case 0xBE1E: - -// CMP -case 0xB018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(8) -case 0xB220: -case 0xB420: -case 0xB620: -case 0xB820: -case 0xBA20: -case 0xBC20: -case 0xBE20: -case 0xB021: -case 0xB221: -case 0xB421: -case 0xB621: -case 0xB821: -case 0xBA21: -case 0xBC21: -case 0xBE21: -case 0xB022: -case 0xB222: -case 0xB422: -case 0xB622: -case 0xB822: -case 0xBA22: -case 0xBC22: -case 0xBE22: -case 0xB023: -case 0xB223: -case 0xB423: -case 0xB623: -case 0xB823: -case 0xBA23: -case 0xBC23: -case 0xBE23: -case 0xB024: -case 0xB224: -case 0xB424: -case 0xB624: -case 0xB824: -case 0xBA24: -case 0xBC24: -case 0xBE24: -case 0xB025: -case 0xB225: -case 0xB425: -case 0xB625: -case 0xB825: -case 0xBA25: -case 0xBC25: -case 0xBE25: -case 0xB026: -case 0xB226: -case 0xB426: -case 0xB626: -case 0xB826: -case 0xBA26: -case 0xBC26: -case 0xBE26: - -// CMP -case 0xB020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(10) -case 0xB228: -case 0xB428: -case 0xB628: -case 0xB828: -case 0xBA28: -case 0xBC28: -case 0xBE28: -case 0xB029: -case 0xB229: -case 0xB429: -case 0xB629: -case 0xB829: -case 0xBA29: -case 0xBC29: -case 0xBE29: -case 0xB02A: -case 0xB22A: -case 0xB42A: -case 0xB62A: -case 0xB82A: -case 0xBA2A: -case 0xBC2A: -case 0xBE2A: -case 0xB02B: -case 0xB22B: -case 0xB42B: -case 0xB62B: -case 0xB82B: -case 0xBA2B: -case 0xBC2B: -case 0xBE2B: -case 0xB02C: -case 0xB22C: -case 0xB42C: -case 0xB62C: -case 0xB82C: -case 0xBA2C: -case 0xBC2C: -case 0xBE2C: -case 0xB02D: -case 0xB22D: -case 0xB42D: -case 0xB62D: -case 0xB82D: -case 0xBA2D: -case 0xBC2D: -case 0xBE2D: -case 0xB02E: -case 0xB22E: -case 0xB42E: -case 0xB62E: -case 0xB82E: -case 0xBA2E: -case 0xBC2E: -case 0xBE2E: -case 0xB02F: -case 0xB22F: -case 0xB42F: -case 0xB62F: -case 0xB82F: -case 0xBA2F: -case 0xBC2F: -case 0xBE2F: - -// CMP -case 0xB028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB230: -case 0xB430: -case 0xB630: -case 0xB830: -case 0xBA30: -case 0xBC30: -case 0xBE30: -case 0xB031: -case 0xB231: -case 0xB431: -case 0xB631: -case 0xB831: -case 0xBA31: -case 0xBC31: -case 0xBE31: -case 0xB032: -case 0xB232: -case 0xB432: -case 0xB632: -case 0xB832: -case 0xBA32: -case 0xBC32: -case 0xBE32: -case 0xB033: -case 0xB233: -case 0xB433: -case 0xB633: -case 0xB833: -case 0xBA33: -case 0xBC33: -case 0xBE33: -case 0xB034: -case 0xB234: -case 0xB434: -case 0xB634: -case 0xB834: -case 0xBA34: -case 0xBC34: -case 0xBE34: -case 0xB035: -case 0xB235: -case 0xB435: -case 0xB635: -case 0xB835: -case 0xBA35: -case 0xBC35: -case 0xBE35: -case 0xB036: -case 0xB236: -case 0xB436: -case 0xB636: -case 0xB836: -case 0xBA36: -case 0xBC36: -case 0xBE36: -case 0xB037: -case 0xB237: -case 0xB437: -case 0xB637: -case 0xB837: -case 0xBA37: -case 0xBC37: -case 0xBE37: - -// CMP -case 0xB030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0xB238: -case 0xB438: -case 0xB638: -case 0xB838: -case 0xBA38: -case 0xBC38: -case 0xBE38: - -// CMP -case 0xB038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB239: -case 0xB439: -case 0xB639: -case 0xB839: -case 0xBA39: -case 0xBC39: -case 0xBE39: - -// CMP -case 0xB039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(16) -case 0xB23A: -case 0xB43A: -case 0xB63A: -case 0xB83A: -case 0xBA3A: -case 0xBC3A: -case 0xBE3A: - -// CMP -case 0xB03A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB23B: -case 0xB43B: -case 0xB63B: -case 0xB83B: -case 0xBA3B: -case 0xBC3B: -case 0xBE3B: - -// CMP -case 0xB03B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0xB23C: -case 0xB43C: -case 0xB63C: -case 0xB83C: -case 0xBA3C: -case 0xBC3C: -case 0xBE3C: - -// CMP -case 0xB03C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(8) -case 0xB21F: -case 0xB41F: -case 0xB61F: -case 0xB81F: -case 0xBA1F: -case 0xBC1F: -case 0xBE1F: - -// CMP -case 0xB01F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(8) -case 0xB227: -case 0xB427: -case 0xB627: -case 0xB827: -case 0xBA27: -case 0xBC27: -case 0xBE27: - -// CMP -case 0xB027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(10) -case 0xB240: -case 0xB440: -case 0xB640: -case 0xB840: -case 0xBA40: -case 0xBC40: -case 0xBE40: -case 0xB041: -case 0xB241: -case 0xB441: -case 0xB641: -case 0xB841: -case 0xBA41: -case 0xBC41: -case 0xBE41: -case 0xB042: -case 0xB242: -case 0xB442: -case 0xB642: -case 0xB842: -case 0xBA42: -case 0xBC42: -case 0xBE42: -case 0xB043: -case 0xB243: -case 0xB443: -case 0xB643: -case 0xB843: -case 0xBA43: -case 0xBC43: -case 0xBE43: -case 0xB044: -case 0xB244: -case 0xB444: -case 0xB644: -case 0xB844: -case 0xBA44: -case 0xBC44: -case 0xBE44: -case 0xB045: -case 0xB245: -case 0xB445: -case 0xB645: -case 0xB845: -case 0xBA45: -case 0xBC45: -case 0xBE45: -case 0xB046: -case 0xB246: -case 0xB446: -case 0xB646: -case 0xB846: -case 0xBA46: -case 0xBC46: -case 0xBE46: -case 0xB047: -case 0xB247: -case 0xB447: -case 0xB647: -case 0xB847: -case 0xBA47: -case 0xBC47: -case 0xBE47: - -// CMP -case 0xB040: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(4) -case 0xB248: -case 0xB448: -case 0xB648: -case 0xB848: -case 0xBA48: -case 0xBC48: -case 0xBE48: -case 0xB049: -case 0xB249: -case 0xB449: -case 0xB649: -case 0xB849: -case 0xBA49: -case 0xBC49: -case 0xBE49: -case 0xB04A: -case 0xB24A: -case 0xB44A: -case 0xB64A: -case 0xB84A: -case 0xBA4A: -case 0xBC4A: -case 0xBE4A: -case 0xB04B: -case 0xB24B: -case 0xB44B: -case 0xB64B: -case 0xB84B: -case 0xBA4B: -case 0xBC4B: -case 0xBE4B: -case 0xB04C: -case 0xB24C: -case 0xB44C: -case 0xB64C: -case 0xB84C: -case 0xBA4C: -case 0xBC4C: -case 0xBE4C: -case 0xB04D: -case 0xB24D: -case 0xB44D: -case 0xB64D: -case 0xB84D: -case 0xBA4D: -case 0xBC4D: -case 0xBE4D: -case 0xB04E: -case 0xB24E: -case 0xB44E: -case 0xB64E: -case 0xB84E: -case 0xBA4E: -case 0xBC4E: -case 0xBE4E: -case 0xB04F: -case 0xB24F: -case 0xB44F: -case 0xB64F: -case 0xB84F: -case 0xBA4F: -case 0xBC4F: -case 0xBE4F: - -// CMP -case 0xB048: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->A[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(4) -case 0xB250: -case 0xB450: -case 0xB650: -case 0xB850: -case 0xBA50: -case 0xBC50: -case 0xBE50: -case 0xB051: -case 0xB251: -case 0xB451: -case 0xB651: -case 0xB851: -case 0xBA51: -case 0xBC51: -case 0xBE51: -case 0xB052: -case 0xB252: -case 0xB452: -case 0xB652: -case 0xB852: -case 0xBA52: -case 0xBC52: -case 0xBE52: -case 0xB053: -case 0xB253: -case 0xB453: -case 0xB653: -case 0xB853: -case 0xBA53: -case 0xBC53: -case 0xBE53: -case 0xB054: -case 0xB254: -case 0xB454: -case 0xB654: -case 0xB854: -case 0xBA54: -case 0xBC54: -case 0xBE54: -case 0xB055: -case 0xB255: -case 0xB455: -case 0xB655: -case 0xB855: -case 0xBA55: -case 0xBC55: -case 0xBE55: -case 0xB056: -case 0xB256: -case 0xB456: -case 0xB656: -case 0xB856: -case 0xBA56: -case 0xBC56: -case 0xBE56: -case 0xB057: -case 0xB257: -case 0xB457: -case 0xB657: -case 0xB857: -case 0xBA57: -case 0xBC57: -case 0xBE57: - -// CMP -case 0xB050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(8) -case 0xB258: -case 0xB458: -case 0xB658: -case 0xB858: -case 0xBA58: -case 0xBC58: -case 0xBE58: -case 0xB059: -case 0xB259: -case 0xB459: -case 0xB659: -case 0xB859: -case 0xBA59: -case 0xBC59: -case 0xBE59: -case 0xB05A: -case 0xB25A: -case 0xB45A: -case 0xB65A: -case 0xB85A: -case 0xBA5A: -case 0xBC5A: -case 0xBE5A: -case 0xB05B: -case 0xB25B: -case 0xB45B: -case 0xB65B: -case 0xB85B: -case 0xBA5B: -case 0xBC5B: -case 0xBE5B: -case 0xB05C: -case 0xB25C: -case 0xB45C: -case 0xB65C: -case 0xB85C: -case 0xBA5C: -case 0xBC5C: -case 0xBE5C: -case 0xB05D: -case 0xB25D: -case 0xB45D: -case 0xB65D: -case 0xB85D: -case 0xBA5D: -case 0xBC5D: -case 0xBE5D: -case 0xB05E: -case 0xB25E: -case 0xB45E: -case 0xB65E: -case 0xB85E: -case 0xBA5E: -case 0xBC5E: -case 0xBE5E: - -// CMP -case 0xB058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(8) -case 0xB260: -case 0xB460: -case 0xB660: -case 0xB860: -case 0xBA60: -case 0xBC60: -case 0xBE60: -case 0xB061: -case 0xB261: -case 0xB461: -case 0xB661: -case 0xB861: -case 0xBA61: -case 0xBC61: -case 0xBE61: -case 0xB062: -case 0xB262: -case 0xB462: -case 0xB662: -case 0xB862: -case 0xBA62: -case 0xBC62: -case 0xBE62: -case 0xB063: -case 0xB263: -case 0xB463: -case 0xB663: -case 0xB863: -case 0xBA63: -case 0xBC63: -case 0xBE63: -case 0xB064: -case 0xB264: -case 0xB464: -case 0xB664: -case 0xB864: -case 0xBA64: -case 0xBC64: -case 0xBE64: -case 0xB065: -case 0xB265: -case 0xB465: -case 0xB665: -case 0xB865: -case 0xBA65: -case 0xBC65: -case 0xBE65: -case 0xB066: -case 0xB266: -case 0xB466: -case 0xB666: -case 0xB866: -case 0xBA66: -case 0xBC66: -case 0xBE66: - -// CMP -case 0xB060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(10) -case 0xB268: -case 0xB468: -case 0xB668: -case 0xB868: -case 0xBA68: -case 0xBC68: -case 0xBE68: -case 0xB069: -case 0xB269: -case 0xB469: -case 0xB669: -case 0xB869: -case 0xBA69: -case 0xBC69: -case 0xBE69: -case 0xB06A: -case 0xB26A: -case 0xB46A: -case 0xB66A: -case 0xB86A: -case 0xBA6A: -case 0xBC6A: -case 0xBE6A: -case 0xB06B: -case 0xB26B: -case 0xB46B: -case 0xB66B: -case 0xB86B: -case 0xBA6B: -case 0xBC6B: -case 0xBE6B: -case 0xB06C: -case 0xB26C: -case 0xB46C: -case 0xB66C: -case 0xB86C: -case 0xBA6C: -case 0xBC6C: -case 0xBE6C: -case 0xB06D: -case 0xB26D: -case 0xB46D: -case 0xB66D: -case 0xB86D: -case 0xBA6D: -case 0xBC6D: -case 0xBE6D: -case 0xB06E: -case 0xB26E: -case 0xB46E: -case 0xB66E: -case 0xB86E: -case 0xBA6E: -case 0xBC6E: -case 0xBE6E: -case 0xB06F: -case 0xB26F: -case 0xB46F: -case 0xB66F: -case 0xB86F: -case 0xBA6F: -case 0xBC6F: -case 0xBE6F: - -// CMP -case 0xB068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB270: -case 0xB470: -case 0xB670: -case 0xB870: -case 0xBA70: -case 0xBC70: -case 0xBE70: -case 0xB071: -case 0xB271: -case 0xB471: -case 0xB671: -case 0xB871: -case 0xBA71: -case 0xBC71: -case 0xBE71: -case 0xB072: -case 0xB272: -case 0xB472: -case 0xB672: -case 0xB872: -case 0xBA72: -case 0xBC72: -case 0xBE72: -case 0xB073: -case 0xB273: -case 0xB473: -case 0xB673: -case 0xB873: -case 0xBA73: -case 0xBC73: -case 0xBE73: -case 0xB074: -case 0xB274: -case 0xB474: -case 0xB674: -case 0xB874: -case 0xBA74: -case 0xBC74: -case 0xBE74: -case 0xB075: -case 0xB275: -case 0xB475: -case 0xB675: -case 0xB875: -case 0xBA75: -case 0xBC75: -case 0xBE75: -case 0xB076: -case 0xB276: -case 0xB476: -case 0xB676: -case 0xB876: -case 0xBA76: -case 0xBC76: -case 0xBE76: -case 0xB077: -case 0xB277: -case 0xB477: -case 0xB677: -case 0xB877: -case 0xBA77: -case 0xBC77: -case 0xBE77: - -// CMP -case 0xB070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0xB278: -case 0xB478: -case 0xB678: -case 0xB878: -case 0xBA78: -case 0xBC78: -case 0xBE78: - -// CMP -case 0xB078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB279: -case 0xB479: -case 0xB679: -case 0xB879: -case 0xBA79: -case 0xBC79: -case 0xBE79: - -// CMP -case 0xB079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(16) -case 0xB27A: -case 0xB47A: -case 0xB67A: -case 0xB87A: -case 0xBA7A: -case 0xBC7A: -case 0xBE7A: - -// CMP -case 0xB07A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB27B: -case 0xB47B: -case 0xB67B: -case 0xB87B: -case 0xBA7B: -case 0xBC7B: -case 0xBE7B: - -// CMP -case 0xB07B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0xB27C: -case 0xB47C: -case 0xB67C: -case 0xB87C: -case 0xBA7C: -case 0xBC7C: -case 0xBE7C: - -// CMP -case 0xB07C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(8) -case 0xB25F: -case 0xB45F: -case 0xB65F: -case 0xB85F: -case 0xBA5F: -case 0xBC5F: -case 0xBE5F: - -// CMP -case 0xB05F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(8) -case 0xB267: -case 0xB467: -case 0xB667: -case 0xB867: -case 0xBA67: -case 0xBC67: -case 0xBE67: - -// CMP -case 0xB067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(10) -case 0xB280: -case 0xB480: -case 0xB680: -case 0xB880: -case 0xBA80: -case 0xBC80: -case 0xBE80: -case 0xB081: -case 0xB281: -case 0xB481: -case 0xB681: -case 0xB881: -case 0xBA81: -case 0xBC81: -case 0xBE81: -case 0xB082: -case 0xB282: -case 0xB482: -case 0xB682: -case 0xB882: -case 0xBA82: -case 0xBC82: -case 0xBE82: -case 0xB083: -case 0xB283: -case 0xB483: -case 0xB683: -case 0xB883: -case 0xBA83: -case 0xBC83: -case 0xBE83: -case 0xB084: -case 0xB284: -case 0xB484: -case 0xB684: -case 0xB884: -case 0xBA84: -case 0xBC84: -case 0xBE84: -case 0xB085: -case 0xB285: -case 0xB485: -case 0xB685: -case 0xB885: -case 0xBA85: -case 0xBC85: -case 0xBE85: -case 0xB086: -case 0xB286: -case 0xB486: -case 0xB686: -case 0xB886: -case 0xBA86: -case 0xBC86: -case 0xBE86: -case 0xB087: -case 0xB287: -case 0xB487: -case 0xB687: -case 0xB887: -case 0xBA87: -case 0xBC87: -case 0xBE87: - -// CMP -case 0xB080: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB288: -case 0xB488: -case 0xB688: -case 0xB888: -case 0xBA88: -case 0xBC88: -case 0xBE88: -case 0xB089: -case 0xB289: -case 0xB489: -case 0xB689: -case 0xB889: -case 0xBA89: -case 0xBC89: -case 0xBE89: -case 0xB08A: -case 0xB28A: -case 0xB48A: -case 0xB68A: -case 0xB88A: -case 0xBA8A: -case 0xBC8A: -case 0xBE8A: -case 0xB08B: -case 0xB28B: -case 0xB48B: -case 0xB68B: -case 0xB88B: -case 0xBA8B: -case 0xBC8B: -case 0xBE8B: -case 0xB08C: -case 0xB28C: -case 0xB48C: -case 0xB68C: -case 0xB88C: -case 0xBA8C: -case 0xBC8C: -case 0xBE8C: -case 0xB08D: -case 0xB28D: -case 0xB48D: -case 0xB68D: -case 0xB88D: -case 0xBA8D: -case 0xBC8D: -case 0xBE8D: -case 0xB08E: -case 0xB28E: -case 0xB48E: -case 0xB68E: -case 0xB88E: -case 0xBA8E: -case 0xBC8E: -case 0xBE8E: -case 0xB08F: -case 0xB28F: -case 0xB48F: -case 0xB68F: -case 0xB88F: -case 0xBA8F: -case 0xBC8F: -case 0xBE8F: - -// CMP -case 0xB088: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB290: -case 0xB490: -case 0xB690: -case 0xB890: -case 0xBA90: -case 0xBC90: -case 0xBE90: -case 0xB091: -case 0xB291: -case 0xB491: -case 0xB691: -case 0xB891: -case 0xBA91: -case 0xBC91: -case 0xBE91: -case 0xB092: -case 0xB292: -case 0xB492: -case 0xB692: -case 0xB892: -case 0xBA92: -case 0xBC92: -case 0xBE92: -case 0xB093: -case 0xB293: -case 0xB493: -case 0xB693: -case 0xB893: -case 0xBA93: -case 0xBC93: -case 0xBE93: -case 0xB094: -case 0xB294: -case 0xB494: -case 0xB694: -case 0xB894: -case 0xBA94: -case 0xBC94: -case 0xBE94: -case 0xB095: -case 0xB295: -case 0xB495: -case 0xB695: -case 0xB895: -case 0xBA95: -case 0xBC95: -case 0xBE95: -case 0xB096: -case 0xB296: -case 0xB496: -case 0xB696: -case 0xB896: -case 0xBA96: -case 0xBC96: -case 0xBE96: -case 0xB097: -case 0xB297: -case 0xB497: -case 0xB697: -case 0xB897: -case 0xBA97: -case 0xBC97: -case 0xBE97: - -// CMP -case 0xB090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB298: -case 0xB498: -case 0xB698: -case 0xB898: -case 0xBA98: -case 0xBC98: -case 0xBE98: -case 0xB099: -case 0xB299: -case 0xB499: -case 0xB699: -case 0xB899: -case 0xBA99: -case 0xBC99: -case 0xBE99: -case 0xB09A: -case 0xB29A: -case 0xB49A: -case 0xB69A: -case 0xB89A: -case 0xBA9A: -case 0xBC9A: -case 0xBE9A: -case 0xB09B: -case 0xB29B: -case 0xB49B: -case 0xB69B: -case 0xB89B: -case 0xBA9B: -case 0xBC9B: -case 0xBE9B: -case 0xB09C: -case 0xB29C: -case 0xB49C: -case 0xB69C: -case 0xB89C: -case 0xBA9C: -case 0xBC9C: -case 0xBE9C: -case 0xB09D: -case 0xB29D: -case 0xB49D: -case 0xB69D: -case 0xB89D: -case 0xBA9D: -case 0xBC9D: -case 0xBE9D: -case 0xB09E: -case 0xB29E: -case 0xB49E: -case 0xB69E: -case 0xB89E: -case 0xBA9E: -case 0xBC9E: -case 0xBE9E: - -// CMP -case 0xB098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2A0: -case 0xB4A0: -case 0xB6A0: -case 0xB8A0: -case 0xBAA0: -case 0xBCA0: -case 0xBEA0: -case 0xB0A1: -case 0xB2A1: -case 0xB4A1: -case 0xB6A1: -case 0xB8A1: -case 0xBAA1: -case 0xBCA1: -case 0xBEA1: -case 0xB0A2: -case 0xB2A2: -case 0xB4A2: -case 0xB6A2: -case 0xB8A2: -case 0xBAA2: -case 0xBCA2: -case 0xBEA2: -case 0xB0A3: -case 0xB2A3: -case 0xB4A3: -case 0xB6A3: -case 0xB8A3: -case 0xBAA3: -case 0xBCA3: -case 0xBEA3: -case 0xB0A4: -case 0xB2A4: -case 0xB4A4: -case 0xB6A4: -case 0xB8A4: -case 0xBAA4: -case 0xBCA4: -case 0xBEA4: -case 0xB0A5: -case 0xB2A5: -case 0xB4A5: -case 0xB6A5: -case 0xB8A5: -case 0xBAA5: -case 0xBCA5: -case 0xBEA5: -case 0xB0A6: -case 0xB2A6: -case 0xB4A6: -case 0xB6A6: -case 0xB8A6: -case 0xBAA6: -case 0xBCA6: -case 0xBEA6: - -// CMP -case 0xB0A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB2A8: -case 0xB4A8: -case 0xB6A8: -case 0xB8A8: -case 0xBAA8: -case 0xBCA8: -case 0xBEA8: -case 0xB0A9: -case 0xB2A9: -case 0xB4A9: -case 0xB6A9: -case 0xB8A9: -case 0xBAA9: -case 0xBCA9: -case 0xBEA9: -case 0xB0AA: -case 0xB2AA: -case 0xB4AA: -case 0xB6AA: -case 0xB8AA: -case 0xBAAA: -case 0xBCAA: -case 0xBEAA: -case 0xB0AB: -case 0xB2AB: -case 0xB4AB: -case 0xB6AB: -case 0xB8AB: -case 0xBAAB: -case 0xBCAB: -case 0xBEAB: -case 0xB0AC: -case 0xB2AC: -case 0xB4AC: -case 0xB6AC: -case 0xB8AC: -case 0xBAAC: -case 0xBCAC: -case 0xBEAC: -case 0xB0AD: -case 0xB2AD: -case 0xB4AD: -case 0xB6AD: -case 0xB8AD: -case 0xBAAD: -case 0xBCAD: -case 0xBEAD: -case 0xB0AE: -case 0xB2AE: -case 0xB4AE: -case 0xB6AE: -case 0xB8AE: -case 0xBAAE: -case 0xBCAE: -case 0xBEAE: -case 0xB0AF: -case 0xB2AF: -case 0xB4AF: -case 0xB6AF: -case 0xB8AF: -case 0xBAAF: -case 0xBCAF: -case 0xBEAF: - -// CMP -case 0xB0A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB2B0: -case 0xB4B0: -case 0xB6B0: -case 0xB8B0: -case 0xBAB0: -case 0xBCB0: -case 0xBEB0: -case 0xB0B1: -case 0xB2B1: -case 0xB4B1: -case 0xB6B1: -case 0xB8B1: -case 0xBAB1: -case 0xBCB1: -case 0xBEB1: -case 0xB0B2: -case 0xB2B2: -case 0xB4B2: -case 0xB6B2: -case 0xB8B2: -case 0xBAB2: -case 0xBCB2: -case 0xBEB2: -case 0xB0B3: -case 0xB2B3: -case 0xB4B3: -case 0xB6B3: -case 0xB8B3: -case 0xBAB3: -case 0xBCB3: -case 0xBEB3: -case 0xB0B4: -case 0xB2B4: -case 0xB4B4: -case 0xB6B4: -case 0xB8B4: -case 0xBAB4: -case 0xBCB4: -case 0xBEB4: -case 0xB0B5: -case 0xB2B5: -case 0xB4B5: -case 0xB6B5: -case 0xB8B5: -case 0xBAB5: -case 0xBCB5: -case 0xBEB5: -case 0xB0B6: -case 0xB2B6: -case 0xB4B6: -case 0xB6B6: -case 0xB8B6: -case 0xBAB6: -case 0xBCB6: -case 0xBEB6: -case 0xB0B7: -case 0xB2B7: -case 0xB4B7: -case 0xB6B7: -case 0xB8B7: -case 0xBAB7: -case 0xBCB7: -case 0xBEB7: - -// CMP -case 0xB0B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0xB2B8: -case 0xB4B8: -case 0xB6B8: -case 0xB8B8: -case 0xBAB8: -case 0xBCB8: -case 0xBEB8: - -// CMP -case 0xB0B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB2B9: -case 0xB4B9: -case 0xB6B9: -case 0xB8B9: -case 0xBAB9: -case 0xBCB9: -case 0xBEB9: - -// CMP -case 0xB0B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(24) -case 0xB2BA: -case 0xB4BA: -case 0xB6BA: -case 0xB8BA: -case 0xBABA: -case 0xBCBA: -case 0xBEBA: - -// CMP -case 0xB0BA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB2BB: -case 0xB4BB: -case 0xB6BB: -case 0xB8BB: -case 0xBABB: -case 0xBCBB: -case 0xBEBB: - -// CMP -case 0xB0BB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0xB2BC: -case 0xB4BC: -case 0xB6BC: -case 0xB8BC: -case 0xBABC: -case 0xBCBC: -case 0xBEBC: - -// CMP -case 0xB0BC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(14) -case 0xB29F: -case 0xB49F: -case 0xB69F: -case 0xB89F: -case 0xBA9F: -case 0xBC9F: -case 0xBE9F: - -// CMP -case 0xB09F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2A7: -case 0xB4A7: -case 0xB6A7: -case 0xB8A7: -case 0xBAA7: -case 0xBCA7: -case 0xBEA7: - -// CMP -case 0xB0A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB308: -case 0xB508: -case 0xB708: -case 0xB908: -case 0xBB08: -case 0xBD08: -case 0xB109: -case 0xB309: -case 0xB509: -case 0xB709: -case 0xB909: -case 0xBB09: -case 0xBD09: -case 0xB10A: -case 0xB30A: -case 0xB50A: -case 0xB70A: -case 0xB90A: -case 0xBB0A: -case 0xBD0A: -case 0xB10B: -case 0xB30B: -case 0xB50B: -case 0xB70B: -case 0xB90B: -case 0xBB0B: -case 0xBD0B: -case 0xB10C: -case 0xB30C: -case 0xB50C: -case 0xB70C: -case 0xB90C: -case 0xBB0C: -case 0xBD0C: -case 0xB10D: -case 0xB30D: -case 0xB50D: -case 0xB70D: -case 0xB90D: -case 0xBB0D: -case 0xBD0D: -case 0xB10E: -case 0xB30E: -case 0xB50E: -case 0xB70E: -case 0xB90E: -case 0xBB0E: -case 0xBD0E: - -// CMPM -case 0xB108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB348: -case 0xB548: -case 0xB748: -case 0xB948: -case 0xBB48: -case 0xBD48: -case 0xB149: -case 0xB349: -case 0xB549: -case 0xB749: -case 0xB949: -case 0xBB49: -case 0xBD49: -case 0xB14A: -case 0xB34A: -case 0xB54A: -case 0xB74A: -case 0xB94A: -case 0xBB4A: -case 0xBD4A: -case 0xB14B: -case 0xB34B: -case 0xB54B: -case 0xB74B: -case 0xB94B: -case 0xBB4B: -case 0xBD4B: -case 0xB14C: -case 0xB34C: -case 0xB54C: -case 0xB74C: -case 0xB94C: -case 0xBB4C: -case 0xBD4C: -case 0xB14D: -case 0xB34D: -case 0xB54D: -case 0xB74D: -case 0xB94D: -case 0xBB4D: -case 0xBD4D: -case 0xB14E: -case 0xB34E: -case 0xB54E: -case 0xB74E: -case 0xB94E: -case 0xBB4E: -case 0xBD4E: - -// CMPM -case 0xB148: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB388: -case 0xB588: -case 0xB788: -case 0xB988: -case 0xBB88: -case 0xBD88: -case 0xB189: -case 0xB389: -case 0xB589: -case 0xB789: -case 0xB989: -case 0xBB89: -case 0xBD89: -case 0xB18A: -case 0xB38A: -case 0xB58A: -case 0xB78A: -case 0xB98A: -case 0xBB8A: -case 0xBD8A: -case 0xB18B: -case 0xB38B: -case 0xB58B: -case 0xB78B: -case 0xB98B: -case 0xBB8B: -case 0xBD8B: -case 0xB18C: -case 0xB38C: -case 0xB58C: -case 0xB78C: -case 0xB98C: -case 0xBB8C: -case 0xBD8C: -case 0xB18D: -case 0xB38D: -case 0xB58D: -case 0xB78D: -case 0xB98D: -case 0xBB8D: -case 0xBD8D: -case 0xB18E: -case 0xB38E: -case 0xB58E: -case 0xB78E: -case 0xB98E: -case 0xBB8E: -case 0xBD8E: - -// CMPM -case 0xB188: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB30F: -case 0xB50F: -case 0xB70F: -case 0xB90F: -case 0xBB0F: -case 0xBD0F: - -// CMP7M -case 0xB10F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB34F: -case 0xB54F: -case 0xB74F: -case 0xB94F: -case 0xBB4F: -case 0xBD4F: - -// CMP7M -case 0xB14F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB38F: -case 0xB58F: -case 0xB78F: -case 0xB98F: -case 0xBB8F: -case 0xBD8F: - -// CMP7M -case 0xB18F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xBF09: -case 0xBF0A: -case 0xBF0B: -case 0xBF0C: -case 0xBF0D: -case 0xBF0E: - -// CMPM7 -case 0xBF08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xBF49: -case 0xBF4A: -case 0xBF4B: -case 0xBF4C: -case 0xBF4D: -case 0xBF4E: - -// CMPM7 -case 0xBF48: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xBF89: -case 0xBF8A: -case 0xBF8B: -case 0xBF8C: -case 0xBF8D: -case 0xBF8E: - -// CMPM7 -case 0xBF88: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) - -// CMP7M7 -case 0xBF0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) - -// CMP7M7 -case 0xBF4F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) - -// CMP7M7 -case 0xBF8F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB300: -case 0xB500: -case 0xB700: -case 0xB900: -case 0xBB00: -case 0xBD00: -case 0xBF00: -case 0xB101: -case 0xB301: -case 0xB501: -case 0xB701: -case 0xB901: -case 0xBB01: -case 0xBD01: -case 0xBF01: -case 0xB102: -case 0xB302: -case 0xB502: -case 0xB702: -case 0xB902: -case 0xBB02: -case 0xBD02: -case 0xBF02: -case 0xB103: -case 0xB303: -case 0xB503: -case 0xB703: -case 0xB903: -case 0xBB03: -case 0xBD03: -case 0xBF03: -case 0xB104: -case 0xB304: -case 0xB504: -case 0xB704: -case 0xB904: -case 0xBB04: -case 0xBD04: -case 0xBF04: -case 0xB105: -case 0xB305: -case 0xB505: -case 0xB705: -case 0xB905: -case 0xBB05: -case 0xBD05: -case 0xBF05: -case 0xB106: -case 0xB306: -case 0xB506: -case 0xB706: -case 0xB906: -case 0xBB06: -case 0xBD06: -case 0xBF06: -case 0xB107: -case 0xB307: -case 0xB507: -case 0xB707: -case 0xB907: -case 0xBB07: -case 0xBD07: -case 0xBF07: - -// EORDa -case 0xB100: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0xB310: -case 0xB510: -case 0xB710: -case 0xB910: -case 0xBB10: -case 0xBD10: -case 0xBF10: -case 0xB111: -case 0xB311: -case 0xB511: -case 0xB711: -case 0xB911: -case 0xBB11: -case 0xBD11: -case 0xBF11: -case 0xB112: -case 0xB312: -case 0xB512: -case 0xB712: -case 0xB912: -case 0xBB12: -case 0xBD12: -case 0xBF12: -case 0xB113: -case 0xB313: -case 0xB513: -case 0xB713: -case 0xB913: -case 0xBB13: -case 0xBD13: -case 0xBF13: -case 0xB114: -case 0xB314: -case 0xB514: -case 0xB714: -case 0xB914: -case 0xBB14: -case 0xBD14: -case 0xBF14: -case 0xB115: -case 0xB315: -case 0xB515: -case 0xB715: -case 0xB915: -case 0xBB15: -case 0xBD15: -case 0xBF15: -case 0xB116: -case 0xB316: -case 0xB516: -case 0xB716: -case 0xB916: -case 0xBB16: -case 0xBD16: -case 0xBF16: -case 0xB117: -case 0xB317: -case 0xB517: -case 0xB717: -case 0xB917: -case 0xBB17: -case 0xBD17: -case 0xBF17: - -// EORDa -case 0xB110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xB318: -case 0xB518: -case 0xB718: -case 0xB918: -case 0xBB18: -case 0xBD18: -case 0xBF18: -case 0xB119: -case 0xB319: -case 0xB519: -case 0xB719: -case 0xB919: -case 0xBB19: -case 0xBD19: -case 0xBF19: -case 0xB11A: -case 0xB31A: -case 0xB51A: -case 0xB71A: -case 0xB91A: -case 0xBB1A: -case 0xBD1A: -case 0xBF1A: -case 0xB11B: -case 0xB31B: -case 0xB51B: -case 0xB71B: -case 0xB91B: -case 0xBB1B: -case 0xBD1B: -case 0xBF1B: -case 0xB11C: -case 0xB31C: -case 0xB51C: -case 0xB71C: -case 0xB91C: -case 0xBB1C: -case 0xBD1C: -case 0xBF1C: -case 0xB11D: -case 0xB31D: -case 0xB51D: -case 0xB71D: -case 0xB91D: -case 0xBB1D: -case 0xBD1D: -case 0xBF1D: -case 0xB11E: -case 0xB31E: -case 0xB51E: -case 0xB71E: -case 0xB91E: -case 0xBB1E: -case 0xBD1E: -case 0xBF1E: - -// EORDa -case 0xB118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xB320: -case 0xB520: -case 0xB720: -case 0xB920: -case 0xBB20: -case 0xBD20: -case 0xBF20: -case 0xB121: -case 0xB321: -case 0xB521: -case 0xB721: -case 0xB921: -case 0xBB21: -case 0xBD21: -case 0xBF21: -case 0xB122: -case 0xB322: -case 0xB522: -case 0xB722: -case 0xB922: -case 0xBB22: -case 0xBD22: -case 0xBF22: -case 0xB123: -case 0xB323: -case 0xB523: -case 0xB723: -case 0xB923: -case 0xBB23: -case 0xBD23: -case 0xBF23: -case 0xB124: -case 0xB324: -case 0xB524: -case 0xB724: -case 0xB924: -case 0xBB24: -case 0xBD24: -case 0xBF24: -case 0xB125: -case 0xB325: -case 0xB525: -case 0xB725: -case 0xB925: -case 0xBB25: -case 0xBD25: -case 0xBF25: -case 0xB126: -case 0xB326: -case 0xB526: -case 0xB726: -case 0xB926: -case 0xBB26: -case 0xBD26: -case 0xBF26: - -// EORDa -case 0xB120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xB328: -case 0xB528: -case 0xB728: -case 0xB928: -case 0xBB28: -case 0xBD28: -case 0xBF28: -case 0xB129: -case 0xB329: -case 0xB529: -case 0xB729: -case 0xB929: -case 0xBB29: -case 0xBD29: -case 0xBF29: -case 0xB12A: -case 0xB32A: -case 0xB52A: -case 0xB72A: -case 0xB92A: -case 0xBB2A: -case 0xBD2A: -case 0xBF2A: -case 0xB12B: -case 0xB32B: -case 0xB52B: -case 0xB72B: -case 0xB92B: -case 0xBB2B: -case 0xBD2B: -case 0xBF2B: -case 0xB12C: -case 0xB32C: -case 0xB52C: -case 0xB72C: -case 0xB92C: -case 0xBB2C: -case 0xBD2C: -case 0xBF2C: -case 0xB12D: -case 0xB32D: -case 0xB52D: -case 0xB72D: -case 0xB92D: -case 0xBB2D: -case 0xBD2D: -case 0xBF2D: -case 0xB12E: -case 0xB32E: -case 0xB52E: -case 0xB72E: -case 0xB92E: -case 0xBB2E: -case 0xBD2E: -case 0xBF2E: -case 0xB12F: -case 0xB32F: -case 0xB52F: -case 0xB72F: -case 0xB92F: -case 0xBB2F: -case 0xBD2F: -case 0xBF2F: - -// EORDa -case 0xB128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xB330: -case 0xB530: -case 0xB730: -case 0xB930: -case 0xBB30: -case 0xBD30: -case 0xBF30: -case 0xB131: -case 0xB331: -case 0xB531: -case 0xB731: -case 0xB931: -case 0xBB31: -case 0xBD31: -case 0xBF31: -case 0xB132: -case 0xB332: -case 0xB532: -case 0xB732: -case 0xB932: -case 0xBB32: -case 0xBD32: -case 0xBF32: -case 0xB133: -case 0xB333: -case 0xB533: -case 0xB733: -case 0xB933: -case 0xBB33: -case 0xBD33: -case 0xBF33: -case 0xB134: -case 0xB334: -case 0xB534: -case 0xB734: -case 0xB934: -case 0xBB34: -case 0xBD34: -case 0xBF34: -case 0xB135: -case 0xB335: -case 0xB535: -case 0xB735: -case 0xB935: -case 0xBB35: -case 0xBD35: -case 0xBF35: -case 0xB136: -case 0xB336: -case 0xB536: -case 0xB736: -case 0xB936: -case 0xBB36: -case 0xBD36: -case 0xBF36: -case 0xB137: -case 0xB337: -case 0xB537: -case 0xB737: -case 0xB937: -case 0xBB37: -case 0xBD37: -case 0xBF37: - -// EORDa -case 0xB130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xB338: -case 0xB538: -case 0xB738: -case 0xB938: -case 0xBB38: -case 0xBD38: -case 0xBF38: - -// EORDa -case 0xB138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xB339: -case 0xB539: -case 0xB739: -case 0xB939: -case 0xBB39: -case 0xBD39: -case 0xBF39: - -// EORDa -case 0xB139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0xB31F: -case 0xB51F: -case 0xB71F: -case 0xB91F: -case 0xBB1F: -case 0xBD1F: -case 0xBF1F: - -// EORDa -case 0xB11F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xB327: -case 0xB527: -case 0xB727: -case 0xB927: -case 0xBB27: -case 0xBD27: -case 0xBF27: - -// EORDa -case 0xB127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xB340: -case 0xB540: -case 0xB740: -case 0xB940: -case 0xBB40: -case 0xBD40: -case 0xBF40: -case 0xB141: -case 0xB341: -case 0xB541: -case 0xB741: -case 0xB941: -case 0xBB41: -case 0xBD41: -case 0xBF41: -case 0xB142: -case 0xB342: -case 0xB542: -case 0xB742: -case 0xB942: -case 0xBB42: -case 0xBD42: -case 0xBF42: -case 0xB143: -case 0xB343: -case 0xB543: -case 0xB743: -case 0xB943: -case 0xBB43: -case 0xBD43: -case 0xBF43: -case 0xB144: -case 0xB344: -case 0xB544: -case 0xB744: -case 0xB944: -case 0xBB44: -case 0xBD44: -case 0xBF44: -case 0xB145: -case 0xB345: -case 0xB545: -case 0xB745: -case 0xB945: -case 0xBB45: -case 0xBD45: -case 0xBF45: -case 0xB146: -case 0xB346: -case 0xB546: -case 0xB746: -case 0xB946: -case 0xBB46: -case 0xBD46: -case 0xBF46: -case 0xB147: -case 0xB347: -case 0xB547: -case 0xB747: -case 0xB947: -case 0xBB47: -case 0xBD47: -case 0xBF47: - -// EORDa -case 0xB140: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0xB350: -case 0xB550: -case 0xB750: -case 0xB950: -case 0xBB50: -case 0xBD50: -case 0xBF50: -case 0xB151: -case 0xB351: -case 0xB551: -case 0xB751: -case 0xB951: -case 0xBB51: -case 0xBD51: -case 0xBF51: -case 0xB152: -case 0xB352: -case 0xB552: -case 0xB752: -case 0xB952: -case 0xBB52: -case 0xBD52: -case 0xBF52: -case 0xB153: -case 0xB353: -case 0xB553: -case 0xB753: -case 0xB953: -case 0xBB53: -case 0xBD53: -case 0xBF53: -case 0xB154: -case 0xB354: -case 0xB554: -case 0xB754: -case 0xB954: -case 0xBB54: -case 0xBD54: -case 0xBF54: -case 0xB155: -case 0xB355: -case 0xB555: -case 0xB755: -case 0xB955: -case 0xBB55: -case 0xBD55: -case 0xBF55: -case 0xB156: -case 0xB356: -case 0xB556: -case 0xB756: -case 0xB956: -case 0xBB56: -case 0xBD56: -case 0xBF56: -case 0xB157: -case 0xB357: -case 0xB557: -case 0xB757: -case 0xB957: -case 0xBB57: -case 0xBD57: -case 0xBF57: - -// EORDa -case 0xB150: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xB358: -case 0xB558: -case 0xB758: -case 0xB958: -case 0xBB58: -case 0xBD58: -case 0xBF58: -case 0xB159: -case 0xB359: -case 0xB559: -case 0xB759: -case 0xB959: -case 0xBB59: -case 0xBD59: -case 0xBF59: -case 0xB15A: -case 0xB35A: -case 0xB55A: -case 0xB75A: -case 0xB95A: -case 0xBB5A: -case 0xBD5A: -case 0xBF5A: -case 0xB15B: -case 0xB35B: -case 0xB55B: -case 0xB75B: -case 0xB95B: -case 0xBB5B: -case 0xBD5B: -case 0xBF5B: -case 0xB15C: -case 0xB35C: -case 0xB55C: -case 0xB75C: -case 0xB95C: -case 0xBB5C: -case 0xBD5C: -case 0xBF5C: -case 0xB15D: -case 0xB35D: -case 0xB55D: -case 0xB75D: -case 0xB95D: -case 0xBB5D: -case 0xBD5D: -case 0xBF5D: -case 0xB15E: -case 0xB35E: -case 0xB55E: -case 0xB75E: -case 0xB95E: -case 0xBB5E: -case 0xBD5E: -case 0xBF5E: - -// EORDa -case 0xB158: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xB360: -case 0xB560: -case 0xB760: -case 0xB960: -case 0xBB60: -case 0xBD60: -case 0xBF60: -case 0xB161: -case 0xB361: -case 0xB561: -case 0xB761: -case 0xB961: -case 0xBB61: -case 0xBD61: -case 0xBF61: -case 0xB162: -case 0xB362: -case 0xB562: -case 0xB762: -case 0xB962: -case 0xBB62: -case 0xBD62: -case 0xBF62: -case 0xB163: -case 0xB363: -case 0xB563: -case 0xB763: -case 0xB963: -case 0xBB63: -case 0xBD63: -case 0xBF63: -case 0xB164: -case 0xB364: -case 0xB564: -case 0xB764: -case 0xB964: -case 0xBB64: -case 0xBD64: -case 0xBF64: -case 0xB165: -case 0xB365: -case 0xB565: -case 0xB765: -case 0xB965: -case 0xBB65: -case 0xBD65: -case 0xBF65: -case 0xB166: -case 0xB366: -case 0xB566: -case 0xB766: -case 0xB966: -case 0xBB66: -case 0xBD66: -case 0xBF66: - -// EORDa -case 0xB160: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xB368: -case 0xB568: -case 0xB768: -case 0xB968: -case 0xBB68: -case 0xBD68: -case 0xBF68: -case 0xB169: -case 0xB369: -case 0xB569: -case 0xB769: -case 0xB969: -case 0xBB69: -case 0xBD69: -case 0xBF69: -case 0xB16A: -case 0xB36A: -case 0xB56A: -case 0xB76A: -case 0xB96A: -case 0xBB6A: -case 0xBD6A: -case 0xBF6A: -case 0xB16B: -case 0xB36B: -case 0xB56B: -case 0xB76B: -case 0xB96B: -case 0xBB6B: -case 0xBD6B: -case 0xBF6B: -case 0xB16C: -case 0xB36C: -case 0xB56C: -case 0xB76C: -case 0xB96C: -case 0xBB6C: -case 0xBD6C: -case 0xBF6C: -case 0xB16D: -case 0xB36D: -case 0xB56D: -case 0xB76D: -case 0xB96D: -case 0xBB6D: -case 0xBD6D: -case 0xBF6D: -case 0xB16E: -case 0xB36E: -case 0xB56E: -case 0xB76E: -case 0xB96E: -case 0xBB6E: -case 0xBD6E: -case 0xBF6E: -case 0xB16F: -case 0xB36F: -case 0xB56F: -case 0xB76F: -case 0xB96F: -case 0xBB6F: -case 0xBD6F: -case 0xBF6F: - -// EORDa -case 0xB168: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xB370: -case 0xB570: -case 0xB770: -case 0xB970: -case 0xBB70: -case 0xBD70: -case 0xBF70: -case 0xB171: -case 0xB371: -case 0xB571: -case 0xB771: -case 0xB971: -case 0xBB71: -case 0xBD71: -case 0xBF71: -case 0xB172: -case 0xB372: -case 0xB572: -case 0xB772: -case 0xB972: -case 0xBB72: -case 0xBD72: -case 0xBF72: -case 0xB173: -case 0xB373: -case 0xB573: -case 0xB773: -case 0xB973: -case 0xBB73: -case 0xBD73: -case 0xBF73: -case 0xB174: -case 0xB374: -case 0xB574: -case 0xB774: -case 0xB974: -case 0xBB74: -case 0xBD74: -case 0xBF74: -case 0xB175: -case 0xB375: -case 0xB575: -case 0xB775: -case 0xB975: -case 0xBB75: -case 0xBD75: -case 0xBF75: -case 0xB176: -case 0xB376: -case 0xB576: -case 0xB776: -case 0xB976: -case 0xBB76: -case 0xBD76: -case 0xBF76: -case 0xB177: -case 0xB377: -case 0xB577: -case 0xB777: -case 0xB977: -case 0xBB77: -case 0xBD77: -case 0xBF77: - -// EORDa -case 0xB170: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xB378: -case 0xB578: -case 0xB778: -case 0xB978: -case 0xBB78: -case 0xBD78: -case 0xBF78: - -// EORDa -case 0xB178: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xB379: -case 0xB579: -case 0xB779: -case 0xB979: -case 0xBB79: -case 0xBD79: -case 0xBF79: - -// EORDa -case 0xB179: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0xB35F: -case 0xB55F: -case 0xB75F: -case 0xB95F: -case 0xBB5F: -case 0xBD5F: -case 0xBF5F: - -// EORDa -case 0xB15F: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xB367: -case 0xB567: -case 0xB767: -case 0xB967: -case 0xBB67: -case 0xBD67: -case 0xBF67: - -// EORDa -case 0xB167: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xB380: -case 0xB580: -case 0xB780: -case 0xB980: -case 0xBB80: -case 0xBD80: -case 0xBF80: -case 0xB181: -case 0xB381: -case 0xB581: -case 0xB781: -case 0xB981: -case 0xBB81: -case 0xBD81: -case 0xBF81: -case 0xB182: -case 0xB382: -case 0xB582: -case 0xB782: -case 0xB982: -case 0xBB82: -case 0xBD82: -case 0xBF82: -case 0xB183: -case 0xB383: -case 0xB583: -case 0xB783: -case 0xB983: -case 0xBB83: -case 0xBD83: -case 0xBF83: -case 0xB184: -case 0xB384: -case 0xB584: -case 0xB784: -case 0xB984: -case 0xBB84: -case 0xBD84: -case 0xBF84: -case 0xB185: -case 0xB385: -case 0xB585: -case 0xB785: -case 0xB985: -case 0xBB85: -case 0xBD85: -case 0xBF85: -case 0xB186: -case 0xB386: -case 0xB586: -case 0xB786: -case 0xB986: -case 0xBB86: -case 0xBD86: -case 0xBF86: -case 0xB187: -case 0xB387: -case 0xB587: -case 0xB787: -case 0xB987: -case 0xBB87: -case 0xBD87: -case 0xBF87: - -// EORDa -case 0xB180: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xB390: -case 0xB590: -case 0xB790: -case 0xB990: -case 0xBB90: -case 0xBD90: -case 0xBF90: -case 0xB191: -case 0xB391: -case 0xB591: -case 0xB791: -case 0xB991: -case 0xBB91: -case 0xBD91: -case 0xBF91: -case 0xB192: -case 0xB392: -case 0xB592: -case 0xB792: -case 0xB992: -case 0xBB92: -case 0xBD92: -case 0xBF92: -case 0xB193: -case 0xB393: -case 0xB593: -case 0xB793: -case 0xB993: -case 0xBB93: -case 0xBD93: -case 0xBF93: -case 0xB194: -case 0xB394: -case 0xB594: -case 0xB794: -case 0xB994: -case 0xBB94: -case 0xBD94: -case 0xBF94: -case 0xB195: -case 0xB395: -case 0xB595: -case 0xB795: -case 0xB995: -case 0xBB95: -case 0xBD95: -case 0xBF95: -case 0xB196: -case 0xB396: -case 0xB596: -case 0xB796: -case 0xB996: -case 0xBB96: -case 0xBD96: -case 0xBF96: -case 0xB197: -case 0xB397: -case 0xB597: -case 0xB797: -case 0xB997: -case 0xBB97: -case 0xBD97: -case 0xBF97: - -// EORDa -case 0xB190: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xB398: -case 0xB598: -case 0xB798: -case 0xB998: -case 0xBB98: -case 0xBD98: -case 0xBF98: -case 0xB199: -case 0xB399: -case 0xB599: -case 0xB799: -case 0xB999: -case 0xBB99: -case 0xBD99: -case 0xBF99: -case 0xB19A: -case 0xB39A: -case 0xB59A: -case 0xB79A: -case 0xB99A: -case 0xBB9A: -case 0xBD9A: -case 0xBF9A: -case 0xB19B: -case 0xB39B: -case 0xB59B: -case 0xB79B: -case 0xB99B: -case 0xBB9B: -case 0xBD9B: -case 0xBF9B: -case 0xB19C: -case 0xB39C: -case 0xB59C: -case 0xB79C: -case 0xB99C: -case 0xBB9C: -case 0xBD9C: -case 0xBF9C: -case 0xB19D: -case 0xB39D: -case 0xB59D: -case 0xB79D: -case 0xB99D: -case 0xBB9D: -case 0xBD9D: -case 0xBF9D: -case 0xB19E: -case 0xB39E: -case 0xB59E: -case 0xB79E: -case 0xB99E: -case 0xBB9E: -case 0xBD9E: -case 0xBF9E: - -// EORDa -case 0xB198: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xB3A0: -case 0xB5A0: -case 0xB7A0: -case 0xB9A0: -case 0xBBA0: -case 0xBDA0: -case 0xBFA0: -case 0xB1A1: -case 0xB3A1: -case 0xB5A1: -case 0xB7A1: -case 0xB9A1: -case 0xBBA1: -case 0xBDA1: -case 0xBFA1: -case 0xB1A2: -case 0xB3A2: -case 0xB5A2: -case 0xB7A2: -case 0xB9A2: -case 0xBBA2: -case 0xBDA2: -case 0xBFA2: -case 0xB1A3: -case 0xB3A3: -case 0xB5A3: -case 0xB7A3: -case 0xB9A3: -case 0xBBA3: -case 0xBDA3: -case 0xBFA3: -case 0xB1A4: -case 0xB3A4: -case 0xB5A4: -case 0xB7A4: -case 0xB9A4: -case 0xBBA4: -case 0xBDA4: -case 0xBFA4: -case 0xB1A5: -case 0xB3A5: -case 0xB5A5: -case 0xB7A5: -case 0xB9A5: -case 0xBBA5: -case 0xBDA5: -case 0xBFA5: -case 0xB1A6: -case 0xB3A6: -case 0xB5A6: -case 0xB7A6: -case 0xB9A6: -case 0xBBA6: -case 0xBDA6: -case 0xBFA6: - -// EORDa -case 0xB1A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xB3A8: -case 0xB5A8: -case 0xB7A8: -case 0xB9A8: -case 0xBBA8: -case 0xBDA8: -case 0xBFA8: -case 0xB1A9: -case 0xB3A9: -case 0xB5A9: -case 0xB7A9: -case 0xB9A9: -case 0xBBA9: -case 0xBDA9: -case 0xBFA9: -case 0xB1AA: -case 0xB3AA: -case 0xB5AA: -case 0xB7AA: -case 0xB9AA: -case 0xBBAA: -case 0xBDAA: -case 0xBFAA: -case 0xB1AB: -case 0xB3AB: -case 0xB5AB: -case 0xB7AB: -case 0xB9AB: -case 0xBBAB: -case 0xBDAB: -case 0xBFAB: -case 0xB1AC: -case 0xB3AC: -case 0xB5AC: -case 0xB7AC: -case 0xB9AC: -case 0xBBAC: -case 0xBDAC: -case 0xBFAC: -case 0xB1AD: -case 0xB3AD: -case 0xB5AD: -case 0xB7AD: -case 0xB9AD: -case 0xBBAD: -case 0xBDAD: -case 0xBFAD: -case 0xB1AE: -case 0xB3AE: -case 0xB5AE: -case 0xB7AE: -case 0xB9AE: -case 0xBBAE: -case 0xBDAE: -case 0xBFAE: -case 0xB1AF: -case 0xB3AF: -case 0xB5AF: -case 0xB7AF: -case 0xB9AF: -case 0xBBAF: -case 0xBDAF: -case 0xBFAF: - -// EORDa -case 0xB1A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xB3B0: -case 0xB5B0: -case 0xB7B0: -case 0xB9B0: -case 0xBBB0: -case 0xBDB0: -case 0xBFB0: -case 0xB1B1: -case 0xB3B1: -case 0xB5B1: -case 0xB7B1: -case 0xB9B1: -case 0xBBB1: -case 0xBDB1: -case 0xBFB1: -case 0xB1B2: -case 0xB3B2: -case 0xB5B2: -case 0xB7B2: -case 0xB9B2: -case 0xBBB2: -case 0xBDB2: -case 0xBFB2: -case 0xB1B3: -case 0xB3B3: -case 0xB5B3: -case 0xB7B3: -case 0xB9B3: -case 0xBBB3: -case 0xBDB3: -case 0xBFB3: -case 0xB1B4: -case 0xB3B4: -case 0xB5B4: -case 0xB7B4: -case 0xB9B4: -case 0xBBB4: -case 0xBDB4: -case 0xBFB4: -case 0xB1B5: -case 0xB3B5: -case 0xB5B5: -case 0xB7B5: -case 0xB9B5: -case 0xBBB5: -case 0xBDB5: -case 0xBFB5: -case 0xB1B6: -case 0xB3B6: -case 0xB5B6: -case 0xB7B6: -case 0xB9B6: -case 0xBBB6: -case 0xBDB6: -case 0xBFB6: -case 0xB1B7: -case 0xB3B7: -case 0xB5B7: -case 0xB7B7: -case 0xB9B7: -case 0xBBB7: -case 0xBDB7: -case 0xBFB7: - -// EORDa -case 0xB1B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0xB3B8: -case 0xB5B8: -case 0xB7B8: -case 0xB9B8: -case 0xBBB8: -case 0xBDB8: -case 0xBFB8: - -// EORDa -case 0xB1B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xB3B9: -case 0xB5B9: -case 0xB7B9: -case 0xB9B9: -case 0xBBB9: -case 0xBDB9: -case 0xBFB9: - -// EORDa -case 0xB1B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0xB39F: -case 0xB59F: -case 0xB79F: -case 0xB99F: -case 0xBB9F: -case 0xBD9F: -case 0xBF9F: - -// EORDa -case 0xB19F: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xB3A7: -case 0xB5A7: -case 0xB7A7: -case 0xB9A7: -case 0xBBA7: -case 0xBDA7: -case 0xBFA7: - -// EORDa -case 0xB1A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xB2C0: -case 0xB4C0: -case 0xB6C0: -case 0xB8C0: -case 0xBAC0: -case 0xBCC0: -case 0xBEC0: -case 0xB0C1: -case 0xB2C1: -case 0xB4C1: -case 0xB6C1: -case 0xB8C1: -case 0xBAC1: -case 0xBCC1: -case 0xBEC1: -case 0xB0C2: -case 0xB2C2: -case 0xB4C2: -case 0xB6C2: -case 0xB8C2: -case 0xBAC2: -case 0xBCC2: -case 0xBEC2: -case 0xB0C3: -case 0xB2C3: -case 0xB4C3: -case 0xB6C3: -case 0xB8C3: -case 0xBAC3: -case 0xBCC3: -case 0xBEC3: -case 0xB0C4: -case 0xB2C4: -case 0xB4C4: -case 0xB6C4: -case 0xB8C4: -case 0xBAC4: -case 0xBCC4: -case 0xBEC4: -case 0xB0C5: -case 0xB2C5: -case 0xB4C5: -case 0xB6C5: -case 0xB8C5: -case 0xBAC5: -case 0xBCC5: -case 0xBEC5: -case 0xB0C6: -case 0xB2C6: -case 0xB4C6: -case 0xB6C6: -case 0xB8C6: -case 0xBAC6: -case 0xBCC6: -case 0xBEC6: -case 0xB0C7: -case 0xB2C7: -case 0xB4C7: -case 0xB6C7: -case 0xB8C7: -case 0xBAC7: -case 0xBCC7: -case 0xBEC7: - -// CMPA -case 0xB0C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB2C8: -case 0xB4C8: -case 0xB6C8: -case 0xB8C8: -case 0xBAC8: -case 0xBCC8: -case 0xBEC8: -case 0xB0C9: -case 0xB2C9: -case 0xB4C9: -case 0xB6C9: -case 0xB8C9: -case 0xBAC9: -case 0xBCC9: -case 0xBEC9: -case 0xB0CA: -case 0xB2CA: -case 0xB4CA: -case 0xB6CA: -case 0xB8CA: -case 0xBACA: -case 0xBCCA: -case 0xBECA: -case 0xB0CB: -case 0xB2CB: -case 0xB4CB: -case 0xB6CB: -case 0xB8CB: -case 0xBACB: -case 0xBCCB: -case 0xBECB: -case 0xB0CC: -case 0xB2CC: -case 0xB4CC: -case 0xB6CC: -case 0xB8CC: -case 0xBACC: -case 0xBCCC: -case 0xBECC: -case 0xB0CD: -case 0xB2CD: -case 0xB4CD: -case 0xB6CD: -case 0xB8CD: -case 0xBACD: -case 0xBCCD: -case 0xBECD: -case 0xB0CE: -case 0xB2CE: -case 0xB4CE: -case 0xB6CE: -case 0xB8CE: -case 0xBACE: -case 0xBCCE: -case 0xBECE: -case 0xB0CF: -case 0xB2CF: -case 0xB4CF: -case 0xB6CF: -case 0xB8CF: -case 0xBACF: -case 0xBCCF: -case 0xBECF: - -// CMPA -case 0xB0C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB2D0: -case 0xB4D0: -case 0xB6D0: -case 0xB8D0: -case 0xBAD0: -case 0xBCD0: -case 0xBED0: -case 0xB0D1: -case 0xB2D1: -case 0xB4D1: -case 0xB6D1: -case 0xB8D1: -case 0xBAD1: -case 0xBCD1: -case 0xBED1: -case 0xB0D2: -case 0xB2D2: -case 0xB4D2: -case 0xB6D2: -case 0xB8D2: -case 0xBAD2: -case 0xBCD2: -case 0xBED2: -case 0xB0D3: -case 0xB2D3: -case 0xB4D3: -case 0xB6D3: -case 0xB8D3: -case 0xBAD3: -case 0xBCD3: -case 0xBED3: -case 0xB0D4: -case 0xB2D4: -case 0xB4D4: -case 0xB6D4: -case 0xB8D4: -case 0xBAD4: -case 0xBCD4: -case 0xBED4: -case 0xB0D5: -case 0xB2D5: -case 0xB4D5: -case 0xB6D5: -case 0xB8D5: -case 0xBAD5: -case 0xBCD5: -case 0xBED5: -case 0xB0D6: -case 0xB2D6: -case 0xB4D6: -case 0xB6D6: -case 0xB8D6: -case 0xBAD6: -case 0xBCD6: -case 0xBED6: -case 0xB0D7: -case 0xB2D7: -case 0xB4D7: -case 0xB6D7: -case 0xB8D7: -case 0xBAD7: -case 0xBCD7: -case 0xBED7: - -// CMPA -case 0xB0D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(10) -case 0xB2D8: -case 0xB4D8: -case 0xB6D8: -case 0xB8D8: -case 0xBAD8: -case 0xBCD8: -case 0xBED8: -case 0xB0D9: -case 0xB2D9: -case 0xB4D9: -case 0xB6D9: -case 0xB8D9: -case 0xBAD9: -case 0xBCD9: -case 0xBED9: -case 0xB0DA: -case 0xB2DA: -case 0xB4DA: -case 0xB6DA: -case 0xB8DA: -case 0xBADA: -case 0xBCDA: -case 0xBEDA: -case 0xB0DB: -case 0xB2DB: -case 0xB4DB: -case 0xB6DB: -case 0xB8DB: -case 0xBADB: -case 0xBCDB: -case 0xBEDB: -case 0xB0DC: -case 0xB2DC: -case 0xB4DC: -case 0xB6DC: -case 0xB8DC: -case 0xBADC: -case 0xBCDC: -case 0xBEDC: -case 0xB0DD: -case 0xB2DD: -case 0xB4DD: -case 0xB6DD: -case 0xB8DD: -case 0xBADD: -case 0xBCDD: -case 0xBEDD: -case 0xB0DE: -case 0xB2DE: -case 0xB4DE: -case 0xB6DE: -case 0xB8DE: -case 0xBADE: -case 0xBCDE: -case 0xBEDE: - -// CMPA -case 0xB0D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(10) -case 0xB2E0: -case 0xB4E0: -case 0xB6E0: -case 0xB8E0: -case 0xBAE0: -case 0xBCE0: -case 0xBEE0: -case 0xB0E1: -case 0xB2E1: -case 0xB4E1: -case 0xB6E1: -case 0xB8E1: -case 0xBAE1: -case 0xBCE1: -case 0xBEE1: -case 0xB0E2: -case 0xB2E2: -case 0xB4E2: -case 0xB6E2: -case 0xB8E2: -case 0xBAE2: -case 0xBCE2: -case 0xBEE2: -case 0xB0E3: -case 0xB2E3: -case 0xB4E3: -case 0xB6E3: -case 0xB8E3: -case 0xBAE3: -case 0xBCE3: -case 0xBEE3: -case 0xB0E4: -case 0xB2E4: -case 0xB4E4: -case 0xB6E4: -case 0xB8E4: -case 0xBAE4: -case 0xBCE4: -case 0xBEE4: -case 0xB0E5: -case 0xB2E5: -case 0xB4E5: -case 0xB6E5: -case 0xB8E5: -case 0xBAE5: -case 0xBCE5: -case 0xBEE5: -case 0xB0E6: -case 0xB2E6: -case 0xB4E6: -case 0xB6E6: -case 0xB8E6: -case 0xBAE6: -case 0xBCE6: -case 0xBEE6: - -// CMPA -case 0xB0E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0xB2E8: -case 0xB4E8: -case 0xB6E8: -case 0xB8E8: -case 0xBAE8: -case 0xBCE8: -case 0xBEE8: -case 0xB0E9: -case 0xB2E9: -case 0xB4E9: -case 0xB6E9: -case 0xB8E9: -case 0xBAE9: -case 0xBCE9: -case 0xBEE9: -case 0xB0EA: -case 0xB2EA: -case 0xB4EA: -case 0xB6EA: -case 0xB8EA: -case 0xBAEA: -case 0xBCEA: -case 0xBEEA: -case 0xB0EB: -case 0xB2EB: -case 0xB4EB: -case 0xB6EB: -case 0xB8EB: -case 0xBAEB: -case 0xBCEB: -case 0xBEEB: -case 0xB0EC: -case 0xB2EC: -case 0xB4EC: -case 0xB6EC: -case 0xB8EC: -case 0xBAEC: -case 0xBCEC: -case 0xBEEC: -case 0xB0ED: -case 0xB2ED: -case 0xB4ED: -case 0xB6ED: -case 0xB8ED: -case 0xBAED: -case 0xBCED: -case 0xBEED: -case 0xB0EE: -case 0xB2EE: -case 0xB4EE: -case 0xB6EE: -case 0xB8EE: -case 0xBAEE: -case 0xBCEE: -case 0xBEEE: -case 0xB0EF: -case 0xB2EF: -case 0xB4EF: -case 0xB6EF: -case 0xB8EF: -case 0xBAEF: -case 0xBCEF: -case 0xBEEF: - -// CMPA -case 0xB0E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB2F0: -case 0xB4F0: -case 0xB6F0: -case 0xB8F0: -case 0xBAF0: -case 0xBCF0: -case 0xBEF0: -case 0xB0F1: -case 0xB2F1: -case 0xB4F1: -case 0xB6F1: -case 0xB8F1: -case 0xBAF1: -case 0xBCF1: -case 0xBEF1: -case 0xB0F2: -case 0xB2F2: -case 0xB4F2: -case 0xB6F2: -case 0xB8F2: -case 0xBAF2: -case 0xBCF2: -case 0xBEF2: -case 0xB0F3: -case 0xB2F3: -case 0xB4F3: -case 0xB6F3: -case 0xB8F3: -case 0xBAF3: -case 0xBCF3: -case 0xBEF3: -case 0xB0F4: -case 0xB2F4: -case 0xB4F4: -case 0xB6F4: -case 0xB8F4: -case 0xBAF4: -case 0xBCF4: -case 0xBEF4: -case 0xB0F5: -case 0xB2F5: -case 0xB4F5: -case 0xB6F5: -case 0xB8F5: -case 0xBAF5: -case 0xBCF5: -case 0xBEF5: -case 0xB0F6: -case 0xB2F6: -case 0xB4F6: -case 0xB6F6: -case 0xB8F6: -case 0xBAF6: -case 0xBCF6: -case 0xBEF6: -case 0xB0F7: -case 0xB2F7: -case 0xB4F7: -case 0xB6F7: -case 0xB8F7: -case 0xBAF7: -case 0xBCF7: -case 0xBEF7: - -// CMPA -case 0xB0F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2F8: -case 0xB4F8: -case 0xB6F8: -case 0xB8F8: -case 0xBAF8: -case 0xBCF8: -case 0xBEF8: - -// CMPA -case 0xB0F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB2F9: -case 0xB4F9: -case 0xB6F9: -case 0xB8F9: -case 0xBAF9: -case 0xBCF9: -case 0xBEF9: - -// CMPA -case 0xB0F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB2FA: -case 0xB4FA: -case 0xB6FA: -case 0xB8FA: -case 0xBAFA: -case 0xBCFA: -case 0xBEFA: - -// CMPA -case 0xB0FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB2FB: -case 0xB4FB: -case 0xB6FB: -case 0xB8FB: -case 0xBAFB: -case 0xBCFB: -case 0xBEFB: - -// CMPA -case 0xB0FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2FC: -case 0xB4FC: -case 0xB6FC: -case 0xB8FC: -case 0xBAFC: -case 0xBCFC: -case 0xBEFC: - -// CMPA -case 0xB0FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(10) -case 0xB2DF: -case 0xB4DF: -case 0xB6DF: -case 0xB8DF: -case 0xBADF: -case 0xBCDF: -case 0xBEDF: - -// CMPA -case 0xB0DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(10) -case 0xB2E7: -case 0xB4E7: -case 0xB6E7: -case 0xB8E7: -case 0xBAE7: -case 0xBCE7: -case 0xBEE7: - -// CMPA -case 0xB0E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0xB3C0: -case 0xB5C0: -case 0xB7C0: -case 0xB9C0: -case 0xBBC0: -case 0xBDC0: -case 0xBFC0: -case 0xB1C1: -case 0xB3C1: -case 0xB5C1: -case 0xB7C1: -case 0xB9C1: -case 0xBBC1: -case 0xBDC1: -case 0xBFC1: -case 0xB1C2: -case 0xB3C2: -case 0xB5C2: -case 0xB7C2: -case 0xB9C2: -case 0xBBC2: -case 0xBDC2: -case 0xBFC2: -case 0xB1C3: -case 0xB3C3: -case 0xB5C3: -case 0xB7C3: -case 0xB9C3: -case 0xBBC3: -case 0xBDC3: -case 0xBFC3: -case 0xB1C4: -case 0xB3C4: -case 0xB5C4: -case 0xB7C4: -case 0xB9C4: -case 0xBBC4: -case 0xBDC4: -case 0xBFC4: -case 0xB1C5: -case 0xB3C5: -case 0xB5C5: -case 0xB7C5: -case 0xB9C5: -case 0xBBC5: -case 0xBDC5: -case 0xBFC5: -case 0xB1C6: -case 0xB3C6: -case 0xB5C6: -case 0xB7C6: -case 0xB9C6: -case 0xBBC6: -case 0xBDC6: -case 0xBFC6: -case 0xB1C7: -case 0xB3C7: -case 0xB5C7: -case 0xB7C7: -case 0xB9C7: -case 0xBBC7: -case 0xBDC7: -case 0xBFC7: - -// CMPA -case 0xB1C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB3C8: -case 0xB5C8: -case 0xB7C8: -case 0xB9C8: -case 0xBBC8: -case 0xBDC8: -case 0xBFC8: -case 0xB1C9: -case 0xB3C9: -case 0xB5C9: -case 0xB7C9: -case 0xB9C9: -case 0xBBC9: -case 0xBDC9: -case 0xBFC9: -case 0xB1CA: -case 0xB3CA: -case 0xB5CA: -case 0xB7CA: -case 0xB9CA: -case 0xBBCA: -case 0xBDCA: -case 0xBFCA: -case 0xB1CB: -case 0xB3CB: -case 0xB5CB: -case 0xB7CB: -case 0xB9CB: -case 0xBBCB: -case 0xBDCB: -case 0xBFCB: -case 0xB1CC: -case 0xB3CC: -case 0xB5CC: -case 0xB7CC: -case 0xB9CC: -case 0xBBCC: -case 0xBDCC: -case 0xBFCC: -case 0xB1CD: -case 0xB3CD: -case 0xB5CD: -case 0xB7CD: -case 0xB9CD: -case 0xBBCD: -case 0xBDCD: -case 0xBFCD: -case 0xB1CE: -case 0xB3CE: -case 0xB5CE: -case 0xB7CE: -case 0xB9CE: -case 0xBBCE: -case 0xBDCE: -case 0xBFCE: -case 0xB1CF: -case 0xB3CF: -case 0xB5CF: -case 0xB7CF: -case 0xB9CF: -case 0xBBCF: -case 0xBDCF: -case 0xBFCF: - -// CMPA -case 0xB1C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB3D0: -case 0xB5D0: -case 0xB7D0: -case 0xB9D0: -case 0xBBD0: -case 0xBDD0: -case 0xBFD0: -case 0xB1D1: -case 0xB3D1: -case 0xB5D1: -case 0xB7D1: -case 0xB9D1: -case 0xBBD1: -case 0xBDD1: -case 0xBFD1: -case 0xB1D2: -case 0xB3D2: -case 0xB5D2: -case 0xB7D2: -case 0xB9D2: -case 0xBBD2: -case 0xBDD2: -case 0xBFD2: -case 0xB1D3: -case 0xB3D3: -case 0xB5D3: -case 0xB7D3: -case 0xB9D3: -case 0xBBD3: -case 0xBDD3: -case 0xBFD3: -case 0xB1D4: -case 0xB3D4: -case 0xB5D4: -case 0xB7D4: -case 0xB9D4: -case 0xBBD4: -case 0xBDD4: -case 0xBFD4: -case 0xB1D5: -case 0xB3D5: -case 0xB5D5: -case 0xB7D5: -case 0xB9D5: -case 0xBBD5: -case 0xBDD5: -case 0xBFD5: -case 0xB1D6: -case 0xB3D6: -case 0xB5D6: -case 0xB7D6: -case 0xB9D6: -case 0xBBD6: -case 0xBDD6: -case 0xBFD6: -case 0xB1D7: -case 0xB3D7: -case 0xB5D7: -case 0xB7D7: -case 0xB9D7: -case 0xBBD7: -case 0xBDD7: -case 0xBFD7: - -// CMPA -case 0xB1D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB3D8: -case 0xB5D8: -case 0xB7D8: -case 0xB9D8: -case 0xBBD8: -case 0xBDD8: -case 0xBFD8: -case 0xB1D9: -case 0xB3D9: -case 0xB5D9: -case 0xB7D9: -case 0xB9D9: -case 0xBBD9: -case 0xBDD9: -case 0xBFD9: -case 0xB1DA: -case 0xB3DA: -case 0xB5DA: -case 0xB7DA: -case 0xB9DA: -case 0xBBDA: -case 0xBDDA: -case 0xBFDA: -case 0xB1DB: -case 0xB3DB: -case 0xB5DB: -case 0xB7DB: -case 0xB9DB: -case 0xBBDB: -case 0xBDDB: -case 0xBFDB: -case 0xB1DC: -case 0xB3DC: -case 0xB5DC: -case 0xB7DC: -case 0xB9DC: -case 0xBBDC: -case 0xBDDC: -case 0xBFDC: -case 0xB1DD: -case 0xB3DD: -case 0xB5DD: -case 0xB7DD: -case 0xB9DD: -case 0xBBDD: -case 0xBDDD: -case 0xBFDD: -case 0xB1DE: -case 0xB3DE: -case 0xB5DE: -case 0xB7DE: -case 0xB9DE: -case 0xBBDE: -case 0xBDDE: -case 0xBFDE: - -// CMPA -case 0xB1D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB3E0: -case 0xB5E0: -case 0xB7E0: -case 0xB9E0: -case 0xBBE0: -case 0xBDE0: -case 0xBFE0: -case 0xB1E1: -case 0xB3E1: -case 0xB5E1: -case 0xB7E1: -case 0xB9E1: -case 0xBBE1: -case 0xBDE1: -case 0xBFE1: -case 0xB1E2: -case 0xB3E2: -case 0xB5E2: -case 0xB7E2: -case 0xB9E2: -case 0xBBE2: -case 0xBDE2: -case 0xBFE2: -case 0xB1E3: -case 0xB3E3: -case 0xB5E3: -case 0xB7E3: -case 0xB9E3: -case 0xBBE3: -case 0xBDE3: -case 0xBFE3: -case 0xB1E4: -case 0xB3E4: -case 0xB5E4: -case 0xB7E4: -case 0xB9E4: -case 0xBBE4: -case 0xBDE4: -case 0xBFE4: -case 0xB1E5: -case 0xB3E5: -case 0xB5E5: -case 0xB7E5: -case 0xB9E5: -case 0xBBE5: -case 0xBDE5: -case 0xBFE5: -case 0xB1E6: -case 0xB3E6: -case 0xB5E6: -case 0xB7E6: -case 0xB9E6: -case 0xBBE6: -case 0xBDE6: -case 0xBFE6: - -// CMPA -case 0xB1E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB3E8: -case 0xB5E8: -case 0xB7E8: -case 0xB9E8: -case 0xBBE8: -case 0xBDE8: -case 0xBFE8: -case 0xB1E9: -case 0xB3E9: -case 0xB5E9: -case 0xB7E9: -case 0xB9E9: -case 0xBBE9: -case 0xBDE9: -case 0xBFE9: -case 0xB1EA: -case 0xB3EA: -case 0xB5EA: -case 0xB7EA: -case 0xB9EA: -case 0xBBEA: -case 0xBDEA: -case 0xBFEA: -case 0xB1EB: -case 0xB3EB: -case 0xB5EB: -case 0xB7EB: -case 0xB9EB: -case 0xBBEB: -case 0xBDEB: -case 0xBFEB: -case 0xB1EC: -case 0xB3EC: -case 0xB5EC: -case 0xB7EC: -case 0xB9EC: -case 0xBBEC: -case 0xBDEC: -case 0xBFEC: -case 0xB1ED: -case 0xB3ED: -case 0xB5ED: -case 0xB7ED: -case 0xB9ED: -case 0xBBED: -case 0xBDED: -case 0xBFED: -case 0xB1EE: -case 0xB3EE: -case 0xB5EE: -case 0xB7EE: -case 0xB9EE: -case 0xBBEE: -case 0xBDEE: -case 0xBFEE: -case 0xB1EF: -case 0xB3EF: -case 0xB5EF: -case 0xB7EF: -case 0xB9EF: -case 0xBBEF: -case 0xBDEF: -case 0xBFEF: - -// CMPA -case 0xB1E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB3F0: -case 0xB5F0: -case 0xB7F0: -case 0xB9F0: -case 0xBBF0: -case 0xBDF0: -case 0xBFF0: -case 0xB1F1: -case 0xB3F1: -case 0xB5F1: -case 0xB7F1: -case 0xB9F1: -case 0xBBF1: -case 0xBDF1: -case 0xBFF1: -case 0xB1F2: -case 0xB3F2: -case 0xB5F2: -case 0xB7F2: -case 0xB9F2: -case 0xBBF2: -case 0xBDF2: -case 0xBFF2: -case 0xB1F3: -case 0xB3F3: -case 0xB5F3: -case 0xB7F3: -case 0xB9F3: -case 0xBBF3: -case 0xBDF3: -case 0xBFF3: -case 0xB1F4: -case 0xB3F4: -case 0xB5F4: -case 0xB7F4: -case 0xB9F4: -case 0xBBF4: -case 0xBDF4: -case 0xBFF4: -case 0xB1F5: -case 0xB3F5: -case 0xB5F5: -case 0xB7F5: -case 0xB9F5: -case 0xBBF5: -case 0xBDF5: -case 0xBFF5: -case 0xB1F6: -case 0xB3F6: -case 0xB5F6: -case 0xB7F6: -case 0xB9F6: -case 0xBBF6: -case 0xBDF6: -case 0xBFF6: -case 0xB1F7: -case 0xB3F7: -case 0xB5F7: -case 0xB7F7: -case 0xB9F7: -case 0xBBF7: -case 0xBDF7: -case 0xBFF7: - -// CMPA -case 0xB1F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB3F8: -case 0xB5F8: -case 0xB7F8: -case 0xB9F8: -case 0xBBF8: -case 0xBDF8: -case 0xBFF8: - -// CMPA -case 0xB1F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB3F9: -case 0xB5F9: -case 0xB7F9: -case 0xB9F9: -case 0xBBF9: -case 0xBDF9: -case 0xBFF9: - -// CMPA -case 0xB1F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0xB3FA: -case 0xB5FA: -case 0xB7FA: -case 0xB9FA: -case 0xBBFA: -case 0xBDFA: -case 0xBFFA: - -// CMPA -case 0xB1FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB3FB: -case 0xB5FB: -case 0xB7FB: -case 0xB9FB: -case 0xBBFB: -case 0xBDFB: -case 0xBFFB: - -// CMPA -case 0xB1FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB3FC: -case 0xB5FC: -case 0xB7FC: -case 0xB9FC: -case 0xBBFC: -case 0xBDFC: -case 0xBFFC: - -// CMPA -case 0xB1FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)FETCH_LONG; - PC += 4; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(14) -case 0xB3DF: -case 0xB5DF: -case 0xB7DF: -case 0xB9DF: -case 0xBBDF: -case 0xBDDF: -case 0xBFDF: - -// CMPA -case 0xB1DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB3E7: -case 0xB5E7: -case 0xB7E7: -case 0xB9E7: -case 0xBBE7: -case 0xBDE7: -case 0xBFE7: - -// CMPA -case 0xB1E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) diff --git a/yabause/src/c68k/c68k_opC.inc b/yabause/src/c68k/c68k_opC.inc deleted file mode 100644 index df59c4338d..0000000000 --- a/yabause/src/c68k/c68k_opC.inc +++ /dev/null @@ -1,5383 +0,0 @@ -case 0xC200: -case 0xC400: -case 0xC600: -case 0xC800: -case 0xCA00: -case 0xCC00: -case 0xCE00: -case 0xC001: -case 0xC201: -case 0xC401: -case 0xC601: -case 0xC801: -case 0xCA01: -case 0xCC01: -case 0xCE01: -case 0xC002: -case 0xC202: -case 0xC402: -case 0xC602: -case 0xC802: -case 0xCA02: -case 0xCC02: -case 0xCE02: -case 0xC003: -case 0xC203: -case 0xC403: -case 0xC603: -case 0xC803: -case 0xCA03: -case 0xCC03: -case 0xCE03: -case 0xC004: -case 0xC204: -case 0xC404: -case 0xC604: -case 0xC804: -case 0xCA04: -case 0xCC04: -case 0xCE04: -case 0xC005: -case 0xC205: -case 0xC405: -case 0xC605: -case 0xC805: -case 0xCA05: -case 0xCC05: -case 0xCE05: -case 0xC006: -case 0xC206: -case 0xC406: -case 0xC606: -case 0xC806: -case 0xCA06: -case 0xCC06: -case 0xCE06: -case 0xC007: -case 0xC207: -case 0xC407: -case 0xC607: -case 0xC807: -case 0xCA07: -case 0xCC07: -case 0xCE07: - -// ANDaD -case 0xC000: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xC210: -case 0xC410: -case 0xC610: -case 0xC810: -case 0xCA10: -case 0xCC10: -case 0xCE10: -case 0xC011: -case 0xC211: -case 0xC411: -case 0xC611: -case 0xC811: -case 0xCA11: -case 0xCC11: -case 0xCE11: -case 0xC012: -case 0xC212: -case 0xC412: -case 0xC612: -case 0xC812: -case 0xCA12: -case 0xCC12: -case 0xCE12: -case 0xC013: -case 0xC213: -case 0xC413: -case 0xC613: -case 0xC813: -case 0xCA13: -case 0xCC13: -case 0xCE13: -case 0xC014: -case 0xC214: -case 0xC414: -case 0xC614: -case 0xC814: -case 0xCA14: -case 0xCC14: -case 0xCE14: -case 0xC015: -case 0xC215: -case 0xC415: -case 0xC615: -case 0xC815: -case 0xCA15: -case 0xCC15: -case 0xCE15: -case 0xC016: -case 0xC216: -case 0xC416: -case 0xC616: -case 0xC816: -case 0xCA16: -case 0xCC16: -case 0xCE16: -case 0xC017: -case 0xC217: -case 0xC417: -case 0xC617: -case 0xC817: -case 0xCA17: -case 0xCC17: -case 0xCE17: - -// ANDaD -case 0xC010: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC218: -case 0xC418: -case 0xC618: -case 0xC818: -case 0xCA18: -case 0xCC18: -case 0xCE18: -case 0xC019: -case 0xC219: -case 0xC419: -case 0xC619: -case 0xC819: -case 0xCA19: -case 0xCC19: -case 0xCE19: -case 0xC01A: -case 0xC21A: -case 0xC41A: -case 0xC61A: -case 0xC81A: -case 0xCA1A: -case 0xCC1A: -case 0xCE1A: -case 0xC01B: -case 0xC21B: -case 0xC41B: -case 0xC61B: -case 0xC81B: -case 0xCA1B: -case 0xCC1B: -case 0xCE1B: -case 0xC01C: -case 0xC21C: -case 0xC41C: -case 0xC61C: -case 0xC81C: -case 0xCA1C: -case 0xCC1C: -case 0xCE1C: -case 0xC01D: -case 0xC21D: -case 0xC41D: -case 0xC61D: -case 0xC81D: -case 0xCA1D: -case 0xCC1D: -case 0xCE1D: -case 0xC01E: -case 0xC21E: -case 0xC41E: -case 0xC61E: -case 0xC81E: -case 0xCA1E: -case 0xCC1E: -case 0xCE1E: - -// ANDaD -case 0xC018: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC220: -case 0xC420: -case 0xC620: -case 0xC820: -case 0xCA20: -case 0xCC20: -case 0xCE20: -case 0xC021: -case 0xC221: -case 0xC421: -case 0xC621: -case 0xC821: -case 0xCA21: -case 0xCC21: -case 0xCE21: -case 0xC022: -case 0xC222: -case 0xC422: -case 0xC622: -case 0xC822: -case 0xCA22: -case 0xCC22: -case 0xCE22: -case 0xC023: -case 0xC223: -case 0xC423: -case 0xC623: -case 0xC823: -case 0xCA23: -case 0xCC23: -case 0xCE23: -case 0xC024: -case 0xC224: -case 0xC424: -case 0xC624: -case 0xC824: -case 0xCA24: -case 0xCC24: -case 0xCE24: -case 0xC025: -case 0xC225: -case 0xC425: -case 0xC625: -case 0xC825: -case 0xCA25: -case 0xCC25: -case 0xCE25: -case 0xC026: -case 0xC226: -case 0xC426: -case 0xC626: -case 0xC826: -case 0xCA26: -case 0xCC26: -case 0xCE26: - -// ANDaD -case 0xC020: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC228: -case 0xC428: -case 0xC628: -case 0xC828: -case 0xCA28: -case 0xCC28: -case 0xCE28: -case 0xC029: -case 0xC229: -case 0xC429: -case 0xC629: -case 0xC829: -case 0xCA29: -case 0xCC29: -case 0xCE29: -case 0xC02A: -case 0xC22A: -case 0xC42A: -case 0xC62A: -case 0xC82A: -case 0xCA2A: -case 0xCC2A: -case 0xCE2A: -case 0xC02B: -case 0xC22B: -case 0xC42B: -case 0xC62B: -case 0xC82B: -case 0xCA2B: -case 0xCC2B: -case 0xCE2B: -case 0xC02C: -case 0xC22C: -case 0xC42C: -case 0xC62C: -case 0xC82C: -case 0xCA2C: -case 0xCC2C: -case 0xCE2C: -case 0xC02D: -case 0xC22D: -case 0xC42D: -case 0xC62D: -case 0xC82D: -case 0xCA2D: -case 0xCC2D: -case 0xCE2D: -case 0xC02E: -case 0xC22E: -case 0xC42E: -case 0xC62E: -case 0xC82E: -case 0xCA2E: -case 0xCC2E: -case 0xCE2E: -case 0xC02F: -case 0xC22F: -case 0xC42F: -case 0xC62F: -case 0xC82F: -case 0xCA2F: -case 0xCC2F: -case 0xCE2F: - -// ANDaD -case 0xC028: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC230: -case 0xC430: -case 0xC630: -case 0xC830: -case 0xCA30: -case 0xCC30: -case 0xCE30: -case 0xC031: -case 0xC231: -case 0xC431: -case 0xC631: -case 0xC831: -case 0xCA31: -case 0xCC31: -case 0xCE31: -case 0xC032: -case 0xC232: -case 0xC432: -case 0xC632: -case 0xC832: -case 0xCA32: -case 0xCC32: -case 0xCE32: -case 0xC033: -case 0xC233: -case 0xC433: -case 0xC633: -case 0xC833: -case 0xCA33: -case 0xCC33: -case 0xCE33: -case 0xC034: -case 0xC234: -case 0xC434: -case 0xC634: -case 0xC834: -case 0xCA34: -case 0xCC34: -case 0xCE34: -case 0xC035: -case 0xC235: -case 0xC435: -case 0xC635: -case 0xC835: -case 0xCA35: -case 0xCC35: -case 0xCE35: -case 0xC036: -case 0xC236: -case 0xC436: -case 0xC636: -case 0xC836: -case 0xCA36: -case 0xCC36: -case 0xCE36: -case 0xC037: -case 0xC237: -case 0xC437: -case 0xC637: -case 0xC837: -case 0xCA37: -case 0xCC37: -case 0xCE37: - -// ANDaD -case 0xC030: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC238: -case 0xC438: -case 0xC638: -case 0xC838: -case 0xCA38: -case 0xCC38: -case 0xCE38: - -// ANDaD -case 0xC038: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC239: -case 0xC439: -case 0xC639: -case 0xC839: -case 0xCA39: -case 0xCC39: -case 0xCE39: - -// ANDaD -case 0xC039: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC23A: -case 0xC43A: -case 0xC63A: -case 0xC83A: -case 0xCA3A: -case 0xCC3A: -case 0xCE3A: - -// ANDaD -case 0xC03A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC23B: -case 0xC43B: -case 0xC63B: -case 0xC83B: -case 0xCA3B: -case 0xCC3B: -case 0xCE3B: - -// ANDaD -case 0xC03B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC23C: -case 0xC43C: -case 0xC63C: -case 0xC83C: -case 0xCA3C: -case 0xCC3C: -case 0xCE3C: - -// ANDaD -case 0xC03C: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xC21F: -case 0xC41F: -case 0xC61F: -case 0xC81F: -case 0xCA1F: -case 0xCC1F: -case 0xCE1F: - -// ANDaD -case 0xC01F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC227: -case 0xC427: -case 0xC627: -case 0xC827: -case 0xCA27: -case 0xCC27: -case 0xCE27: - -// ANDaD -case 0xC027: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC240: -case 0xC440: -case 0xC640: -case 0xC840: -case 0xCA40: -case 0xCC40: -case 0xCE40: -case 0xC041: -case 0xC241: -case 0xC441: -case 0xC641: -case 0xC841: -case 0xCA41: -case 0xCC41: -case 0xCE41: -case 0xC042: -case 0xC242: -case 0xC442: -case 0xC642: -case 0xC842: -case 0xCA42: -case 0xCC42: -case 0xCE42: -case 0xC043: -case 0xC243: -case 0xC443: -case 0xC643: -case 0xC843: -case 0xCA43: -case 0xCC43: -case 0xCE43: -case 0xC044: -case 0xC244: -case 0xC444: -case 0xC644: -case 0xC844: -case 0xCA44: -case 0xCC44: -case 0xCE44: -case 0xC045: -case 0xC245: -case 0xC445: -case 0xC645: -case 0xC845: -case 0xCA45: -case 0xCC45: -case 0xCE45: -case 0xC046: -case 0xC246: -case 0xC446: -case 0xC646: -case 0xC846: -case 0xCA46: -case 0xCC46: -case 0xCE46: -case 0xC047: -case 0xC247: -case 0xC447: -case 0xC647: -case 0xC847: -case 0xCA47: -case 0xCC47: -case 0xCE47: - -// ANDaD -case 0xC040: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xC250: -case 0xC450: -case 0xC650: -case 0xC850: -case 0xCA50: -case 0xCC50: -case 0xCE50: -case 0xC051: -case 0xC251: -case 0xC451: -case 0xC651: -case 0xC851: -case 0xCA51: -case 0xCC51: -case 0xCE51: -case 0xC052: -case 0xC252: -case 0xC452: -case 0xC652: -case 0xC852: -case 0xCA52: -case 0xCC52: -case 0xCE52: -case 0xC053: -case 0xC253: -case 0xC453: -case 0xC653: -case 0xC853: -case 0xCA53: -case 0xCC53: -case 0xCE53: -case 0xC054: -case 0xC254: -case 0xC454: -case 0xC654: -case 0xC854: -case 0xCA54: -case 0xCC54: -case 0xCE54: -case 0xC055: -case 0xC255: -case 0xC455: -case 0xC655: -case 0xC855: -case 0xCA55: -case 0xCC55: -case 0xCE55: -case 0xC056: -case 0xC256: -case 0xC456: -case 0xC656: -case 0xC856: -case 0xCA56: -case 0xCC56: -case 0xCE56: -case 0xC057: -case 0xC257: -case 0xC457: -case 0xC657: -case 0xC857: -case 0xCA57: -case 0xCC57: -case 0xCE57: - -// ANDaD -case 0xC050: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC258: -case 0xC458: -case 0xC658: -case 0xC858: -case 0xCA58: -case 0xCC58: -case 0xCE58: -case 0xC059: -case 0xC259: -case 0xC459: -case 0xC659: -case 0xC859: -case 0xCA59: -case 0xCC59: -case 0xCE59: -case 0xC05A: -case 0xC25A: -case 0xC45A: -case 0xC65A: -case 0xC85A: -case 0xCA5A: -case 0xCC5A: -case 0xCE5A: -case 0xC05B: -case 0xC25B: -case 0xC45B: -case 0xC65B: -case 0xC85B: -case 0xCA5B: -case 0xCC5B: -case 0xCE5B: -case 0xC05C: -case 0xC25C: -case 0xC45C: -case 0xC65C: -case 0xC85C: -case 0xCA5C: -case 0xCC5C: -case 0xCE5C: -case 0xC05D: -case 0xC25D: -case 0xC45D: -case 0xC65D: -case 0xC85D: -case 0xCA5D: -case 0xCC5D: -case 0xCE5D: -case 0xC05E: -case 0xC25E: -case 0xC45E: -case 0xC65E: -case 0xC85E: -case 0xCA5E: -case 0xCC5E: -case 0xCE5E: - -// ANDaD -case 0xC058: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC260: -case 0xC460: -case 0xC660: -case 0xC860: -case 0xCA60: -case 0xCC60: -case 0xCE60: -case 0xC061: -case 0xC261: -case 0xC461: -case 0xC661: -case 0xC861: -case 0xCA61: -case 0xCC61: -case 0xCE61: -case 0xC062: -case 0xC262: -case 0xC462: -case 0xC662: -case 0xC862: -case 0xCA62: -case 0xCC62: -case 0xCE62: -case 0xC063: -case 0xC263: -case 0xC463: -case 0xC663: -case 0xC863: -case 0xCA63: -case 0xCC63: -case 0xCE63: -case 0xC064: -case 0xC264: -case 0xC464: -case 0xC664: -case 0xC864: -case 0xCA64: -case 0xCC64: -case 0xCE64: -case 0xC065: -case 0xC265: -case 0xC465: -case 0xC665: -case 0xC865: -case 0xCA65: -case 0xCC65: -case 0xCE65: -case 0xC066: -case 0xC266: -case 0xC466: -case 0xC666: -case 0xC866: -case 0xCA66: -case 0xCC66: -case 0xCE66: - -// ANDaD -case 0xC060: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC268: -case 0xC468: -case 0xC668: -case 0xC868: -case 0xCA68: -case 0xCC68: -case 0xCE68: -case 0xC069: -case 0xC269: -case 0xC469: -case 0xC669: -case 0xC869: -case 0xCA69: -case 0xCC69: -case 0xCE69: -case 0xC06A: -case 0xC26A: -case 0xC46A: -case 0xC66A: -case 0xC86A: -case 0xCA6A: -case 0xCC6A: -case 0xCE6A: -case 0xC06B: -case 0xC26B: -case 0xC46B: -case 0xC66B: -case 0xC86B: -case 0xCA6B: -case 0xCC6B: -case 0xCE6B: -case 0xC06C: -case 0xC26C: -case 0xC46C: -case 0xC66C: -case 0xC86C: -case 0xCA6C: -case 0xCC6C: -case 0xCE6C: -case 0xC06D: -case 0xC26D: -case 0xC46D: -case 0xC66D: -case 0xC86D: -case 0xCA6D: -case 0xCC6D: -case 0xCE6D: -case 0xC06E: -case 0xC26E: -case 0xC46E: -case 0xC66E: -case 0xC86E: -case 0xCA6E: -case 0xCC6E: -case 0xCE6E: -case 0xC06F: -case 0xC26F: -case 0xC46F: -case 0xC66F: -case 0xC86F: -case 0xCA6F: -case 0xCC6F: -case 0xCE6F: - -// ANDaD -case 0xC068: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC270: -case 0xC470: -case 0xC670: -case 0xC870: -case 0xCA70: -case 0xCC70: -case 0xCE70: -case 0xC071: -case 0xC271: -case 0xC471: -case 0xC671: -case 0xC871: -case 0xCA71: -case 0xCC71: -case 0xCE71: -case 0xC072: -case 0xC272: -case 0xC472: -case 0xC672: -case 0xC872: -case 0xCA72: -case 0xCC72: -case 0xCE72: -case 0xC073: -case 0xC273: -case 0xC473: -case 0xC673: -case 0xC873: -case 0xCA73: -case 0xCC73: -case 0xCE73: -case 0xC074: -case 0xC274: -case 0xC474: -case 0xC674: -case 0xC874: -case 0xCA74: -case 0xCC74: -case 0xCE74: -case 0xC075: -case 0xC275: -case 0xC475: -case 0xC675: -case 0xC875: -case 0xCA75: -case 0xCC75: -case 0xCE75: -case 0xC076: -case 0xC276: -case 0xC476: -case 0xC676: -case 0xC876: -case 0xCA76: -case 0xCC76: -case 0xCE76: -case 0xC077: -case 0xC277: -case 0xC477: -case 0xC677: -case 0xC877: -case 0xCA77: -case 0xCC77: -case 0xCE77: - -// ANDaD -case 0xC070: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC278: -case 0xC478: -case 0xC678: -case 0xC878: -case 0xCA78: -case 0xCC78: -case 0xCE78: - -// ANDaD -case 0xC078: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC279: -case 0xC479: -case 0xC679: -case 0xC879: -case 0xCA79: -case 0xCC79: -case 0xCE79: - -// ANDaD -case 0xC079: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC27A: -case 0xC47A: -case 0xC67A: -case 0xC87A: -case 0xCA7A: -case 0xCC7A: -case 0xCE7A: - -// ANDaD -case 0xC07A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC27B: -case 0xC47B: -case 0xC67B: -case 0xC87B: -case 0xCA7B: -case 0xCC7B: -case 0xCE7B: - -// ANDaD -case 0xC07B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC27C: -case 0xC47C: -case 0xC67C: -case 0xC87C: -case 0xCA7C: -case 0xCC7C: -case 0xCE7C: - -// ANDaD -case 0xC07C: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xC25F: -case 0xC45F: -case 0xC65F: -case 0xC85F: -case 0xCA5F: -case 0xCC5F: -case 0xCE5F: - -// ANDaD -case 0xC05F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC267: -case 0xC467: -case 0xC667: -case 0xC867: -case 0xCA67: -case 0xCC67: -case 0xCE67: - -// ANDaD -case 0xC067: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC280: -case 0xC480: -case 0xC680: -case 0xC880: -case 0xCA80: -case 0xCC80: -case 0xCE80: -case 0xC081: -case 0xC281: -case 0xC481: -case 0xC681: -case 0xC881: -case 0xCA81: -case 0xCC81: -case 0xCE81: -case 0xC082: -case 0xC282: -case 0xC482: -case 0xC682: -case 0xC882: -case 0xCA82: -case 0xCC82: -case 0xCE82: -case 0xC083: -case 0xC283: -case 0xC483: -case 0xC683: -case 0xC883: -case 0xCA83: -case 0xCC83: -case 0xCE83: -case 0xC084: -case 0xC284: -case 0xC484: -case 0xC684: -case 0xC884: -case 0xCA84: -case 0xCC84: -case 0xCE84: -case 0xC085: -case 0xC285: -case 0xC485: -case 0xC685: -case 0xC885: -case 0xCA85: -case 0xCC85: -case 0xCE85: -case 0xC086: -case 0xC286: -case 0xC486: -case 0xC686: -case 0xC886: -case 0xCA86: -case 0xCC86: -case 0xCE86: -case 0xC087: -case 0xC287: -case 0xC487: -case 0xC687: -case 0xC887: -case 0xCA87: -case 0xCC87: -case 0xCE87: - -// ANDaD -case 0xC080: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xC290: -case 0xC490: -case 0xC690: -case 0xC890: -case 0xCA90: -case 0xCC90: -case 0xCE90: -case 0xC091: -case 0xC291: -case 0xC491: -case 0xC691: -case 0xC891: -case 0xCA91: -case 0xCC91: -case 0xCE91: -case 0xC092: -case 0xC292: -case 0xC492: -case 0xC692: -case 0xC892: -case 0xCA92: -case 0xCC92: -case 0xCE92: -case 0xC093: -case 0xC293: -case 0xC493: -case 0xC693: -case 0xC893: -case 0xCA93: -case 0xCC93: -case 0xCE93: -case 0xC094: -case 0xC294: -case 0xC494: -case 0xC694: -case 0xC894: -case 0xCA94: -case 0xCC94: -case 0xCE94: -case 0xC095: -case 0xC295: -case 0xC495: -case 0xC695: -case 0xC895: -case 0xCA95: -case 0xCC95: -case 0xCE95: -case 0xC096: -case 0xC296: -case 0xC496: -case 0xC696: -case 0xC896: -case 0xCA96: -case 0xCC96: -case 0xCE96: -case 0xC097: -case 0xC297: -case 0xC497: -case 0xC697: -case 0xC897: -case 0xCA97: -case 0xCC97: -case 0xCE97: - -// ANDaD -case 0xC090: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC298: -case 0xC498: -case 0xC698: -case 0xC898: -case 0xCA98: -case 0xCC98: -case 0xCE98: -case 0xC099: -case 0xC299: -case 0xC499: -case 0xC699: -case 0xC899: -case 0xCA99: -case 0xCC99: -case 0xCE99: -case 0xC09A: -case 0xC29A: -case 0xC49A: -case 0xC69A: -case 0xC89A: -case 0xCA9A: -case 0xCC9A: -case 0xCE9A: -case 0xC09B: -case 0xC29B: -case 0xC49B: -case 0xC69B: -case 0xC89B: -case 0xCA9B: -case 0xCC9B: -case 0xCE9B: -case 0xC09C: -case 0xC29C: -case 0xC49C: -case 0xC69C: -case 0xC89C: -case 0xCA9C: -case 0xCC9C: -case 0xCE9C: -case 0xC09D: -case 0xC29D: -case 0xC49D: -case 0xC69D: -case 0xC89D: -case 0xCA9D: -case 0xCC9D: -case 0xCE9D: -case 0xC09E: -case 0xC29E: -case 0xC49E: -case 0xC69E: -case 0xC89E: -case 0xCA9E: -case 0xCC9E: -case 0xCE9E: - -// ANDaD -case 0xC098: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC2A0: -case 0xC4A0: -case 0xC6A0: -case 0xC8A0: -case 0xCAA0: -case 0xCCA0: -case 0xCEA0: -case 0xC0A1: -case 0xC2A1: -case 0xC4A1: -case 0xC6A1: -case 0xC8A1: -case 0xCAA1: -case 0xCCA1: -case 0xCEA1: -case 0xC0A2: -case 0xC2A2: -case 0xC4A2: -case 0xC6A2: -case 0xC8A2: -case 0xCAA2: -case 0xCCA2: -case 0xCEA2: -case 0xC0A3: -case 0xC2A3: -case 0xC4A3: -case 0xC6A3: -case 0xC8A3: -case 0xCAA3: -case 0xCCA3: -case 0xCEA3: -case 0xC0A4: -case 0xC2A4: -case 0xC4A4: -case 0xC6A4: -case 0xC8A4: -case 0xCAA4: -case 0xCCA4: -case 0xCEA4: -case 0xC0A5: -case 0xC2A5: -case 0xC4A5: -case 0xC6A5: -case 0xC8A5: -case 0xCAA5: -case 0xCCA5: -case 0xCEA5: -case 0xC0A6: -case 0xC2A6: -case 0xC4A6: -case 0xC6A6: -case 0xC8A6: -case 0xCAA6: -case 0xCCA6: -case 0xCEA6: - -// ANDaD -case 0xC0A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xC2A8: -case 0xC4A8: -case 0xC6A8: -case 0xC8A8: -case 0xCAA8: -case 0xCCA8: -case 0xCEA8: -case 0xC0A9: -case 0xC2A9: -case 0xC4A9: -case 0xC6A9: -case 0xC8A9: -case 0xCAA9: -case 0xCCA9: -case 0xCEA9: -case 0xC0AA: -case 0xC2AA: -case 0xC4AA: -case 0xC6AA: -case 0xC8AA: -case 0xCAAA: -case 0xCCAA: -case 0xCEAA: -case 0xC0AB: -case 0xC2AB: -case 0xC4AB: -case 0xC6AB: -case 0xC8AB: -case 0xCAAB: -case 0xCCAB: -case 0xCEAB: -case 0xC0AC: -case 0xC2AC: -case 0xC4AC: -case 0xC6AC: -case 0xC8AC: -case 0xCAAC: -case 0xCCAC: -case 0xCEAC: -case 0xC0AD: -case 0xC2AD: -case 0xC4AD: -case 0xC6AD: -case 0xC8AD: -case 0xCAAD: -case 0xCCAD: -case 0xCEAD: -case 0xC0AE: -case 0xC2AE: -case 0xC4AE: -case 0xC6AE: -case 0xC8AE: -case 0xCAAE: -case 0xCCAE: -case 0xCEAE: -case 0xC0AF: -case 0xC2AF: -case 0xC4AF: -case 0xC6AF: -case 0xC8AF: -case 0xCAAF: -case 0xCCAF: -case 0xCEAF: - -// ANDaD -case 0xC0A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xC2B0: -case 0xC4B0: -case 0xC6B0: -case 0xC8B0: -case 0xCAB0: -case 0xCCB0: -case 0xCEB0: -case 0xC0B1: -case 0xC2B1: -case 0xC4B1: -case 0xC6B1: -case 0xC8B1: -case 0xCAB1: -case 0xCCB1: -case 0xCEB1: -case 0xC0B2: -case 0xC2B2: -case 0xC4B2: -case 0xC6B2: -case 0xC8B2: -case 0xCAB2: -case 0xCCB2: -case 0xCEB2: -case 0xC0B3: -case 0xC2B3: -case 0xC4B3: -case 0xC6B3: -case 0xC8B3: -case 0xCAB3: -case 0xCCB3: -case 0xCEB3: -case 0xC0B4: -case 0xC2B4: -case 0xC4B4: -case 0xC6B4: -case 0xC8B4: -case 0xCAB4: -case 0xCCB4: -case 0xCEB4: -case 0xC0B5: -case 0xC2B5: -case 0xC4B5: -case 0xC6B5: -case 0xC8B5: -case 0xCAB5: -case 0xCCB5: -case 0xCEB5: -case 0xC0B6: -case 0xC2B6: -case 0xC4B6: -case 0xC6B6: -case 0xC8B6: -case 0xCAB6: -case 0xCCB6: -case 0xCEB6: -case 0xC0B7: -case 0xC2B7: -case 0xC4B7: -case 0xC6B7: -case 0xC8B7: -case 0xCAB7: -case 0xCCB7: -case 0xCEB7: - -// ANDaD -case 0xC0B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xC2B8: -case 0xC4B8: -case 0xC6B8: -case 0xC8B8: -case 0xCAB8: -case 0xCCB8: -case 0xCEB8: - -// ANDaD -case 0xC0B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xC2B9: -case 0xC4B9: -case 0xC6B9: -case 0xC8B9: -case 0xCAB9: -case 0xCCB9: -case 0xCEB9: - -// ANDaD -case 0xC0B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0xC2BA: -case 0xC4BA: -case 0xC6BA: -case 0xC8BA: -case 0xCABA: -case 0xCCBA: -case 0xCEBA: - -// ANDaD -case 0xC0BA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xC2BB: -case 0xC4BB: -case 0xC6BB: -case 0xC8BB: -case 0xCABB: -case 0xCCBB: -case 0xCEBB: - -// ANDaD -case 0xC0BB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xC2BC: -case 0xC4BC: -case 0xC6BC: -case 0xC8BC: -case 0xCABC: -case 0xCCBC: -case 0xCEBC: - -// ANDaD -case 0xC0BC: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0xC29F: -case 0xC49F: -case 0xC69F: -case 0xC89F: -case 0xCA9F: -case 0xCC9F: -case 0xCE9F: - -// ANDaD -case 0xC09F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC2A7: -case 0xC4A7: -case 0xC6A7: -case 0xC8A7: -case 0xCAA7: -case 0xCCA7: -case 0xCEA7: - -// ANDaD -case 0xC0A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xC310: -case 0xC510: -case 0xC710: -case 0xC910: -case 0xCB10: -case 0xCD10: -case 0xCF10: -case 0xC111: -case 0xC311: -case 0xC511: -case 0xC711: -case 0xC911: -case 0xCB11: -case 0xCD11: -case 0xCF11: -case 0xC112: -case 0xC312: -case 0xC512: -case 0xC712: -case 0xC912: -case 0xCB12: -case 0xCD12: -case 0xCF12: -case 0xC113: -case 0xC313: -case 0xC513: -case 0xC713: -case 0xC913: -case 0xCB13: -case 0xCD13: -case 0xCF13: -case 0xC114: -case 0xC314: -case 0xC514: -case 0xC714: -case 0xC914: -case 0xCB14: -case 0xCD14: -case 0xCF14: -case 0xC115: -case 0xC315: -case 0xC515: -case 0xC715: -case 0xC915: -case 0xCB15: -case 0xCD15: -case 0xCF15: -case 0xC116: -case 0xC316: -case 0xC516: -case 0xC716: -case 0xC916: -case 0xCB16: -case 0xCD16: -case 0xCF16: -case 0xC117: -case 0xC317: -case 0xC517: -case 0xC717: -case 0xC917: -case 0xCB17: -case 0xCD17: -case 0xCF17: - -// ANDDa -case 0xC110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xC318: -case 0xC518: -case 0xC718: -case 0xC918: -case 0xCB18: -case 0xCD18: -case 0xCF18: -case 0xC119: -case 0xC319: -case 0xC519: -case 0xC719: -case 0xC919: -case 0xCB19: -case 0xCD19: -case 0xCF19: -case 0xC11A: -case 0xC31A: -case 0xC51A: -case 0xC71A: -case 0xC91A: -case 0xCB1A: -case 0xCD1A: -case 0xCF1A: -case 0xC11B: -case 0xC31B: -case 0xC51B: -case 0xC71B: -case 0xC91B: -case 0xCB1B: -case 0xCD1B: -case 0xCF1B: -case 0xC11C: -case 0xC31C: -case 0xC51C: -case 0xC71C: -case 0xC91C: -case 0xCB1C: -case 0xCD1C: -case 0xCF1C: -case 0xC11D: -case 0xC31D: -case 0xC51D: -case 0xC71D: -case 0xC91D: -case 0xCB1D: -case 0xCD1D: -case 0xCF1D: -case 0xC11E: -case 0xC31E: -case 0xC51E: -case 0xC71E: -case 0xC91E: -case 0xCB1E: -case 0xCD1E: -case 0xCF1E: - -// ANDDa -case 0xC118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xC320: -case 0xC520: -case 0xC720: -case 0xC920: -case 0xCB20: -case 0xCD20: -case 0xCF20: -case 0xC121: -case 0xC321: -case 0xC521: -case 0xC721: -case 0xC921: -case 0xCB21: -case 0xCD21: -case 0xCF21: -case 0xC122: -case 0xC322: -case 0xC522: -case 0xC722: -case 0xC922: -case 0xCB22: -case 0xCD22: -case 0xCF22: -case 0xC123: -case 0xC323: -case 0xC523: -case 0xC723: -case 0xC923: -case 0xCB23: -case 0xCD23: -case 0xCF23: -case 0xC124: -case 0xC324: -case 0xC524: -case 0xC724: -case 0xC924: -case 0xCB24: -case 0xCD24: -case 0xCF24: -case 0xC125: -case 0xC325: -case 0xC525: -case 0xC725: -case 0xC925: -case 0xCB25: -case 0xCD25: -case 0xCF25: -case 0xC126: -case 0xC326: -case 0xC526: -case 0xC726: -case 0xC926: -case 0xCB26: -case 0xCD26: -case 0xCF26: - -// ANDDa -case 0xC120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xC328: -case 0xC528: -case 0xC728: -case 0xC928: -case 0xCB28: -case 0xCD28: -case 0xCF28: -case 0xC129: -case 0xC329: -case 0xC529: -case 0xC729: -case 0xC929: -case 0xCB29: -case 0xCD29: -case 0xCF29: -case 0xC12A: -case 0xC32A: -case 0xC52A: -case 0xC72A: -case 0xC92A: -case 0xCB2A: -case 0xCD2A: -case 0xCF2A: -case 0xC12B: -case 0xC32B: -case 0xC52B: -case 0xC72B: -case 0xC92B: -case 0xCB2B: -case 0xCD2B: -case 0xCF2B: -case 0xC12C: -case 0xC32C: -case 0xC52C: -case 0xC72C: -case 0xC92C: -case 0xCB2C: -case 0xCD2C: -case 0xCF2C: -case 0xC12D: -case 0xC32D: -case 0xC52D: -case 0xC72D: -case 0xC92D: -case 0xCB2D: -case 0xCD2D: -case 0xCF2D: -case 0xC12E: -case 0xC32E: -case 0xC52E: -case 0xC72E: -case 0xC92E: -case 0xCB2E: -case 0xCD2E: -case 0xCF2E: -case 0xC12F: -case 0xC32F: -case 0xC52F: -case 0xC72F: -case 0xC92F: -case 0xCB2F: -case 0xCD2F: -case 0xCF2F: - -// ANDDa -case 0xC128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xC330: -case 0xC530: -case 0xC730: -case 0xC930: -case 0xCB30: -case 0xCD30: -case 0xCF30: -case 0xC131: -case 0xC331: -case 0xC531: -case 0xC731: -case 0xC931: -case 0xCB31: -case 0xCD31: -case 0xCF31: -case 0xC132: -case 0xC332: -case 0xC532: -case 0xC732: -case 0xC932: -case 0xCB32: -case 0xCD32: -case 0xCF32: -case 0xC133: -case 0xC333: -case 0xC533: -case 0xC733: -case 0xC933: -case 0xCB33: -case 0xCD33: -case 0xCF33: -case 0xC134: -case 0xC334: -case 0xC534: -case 0xC734: -case 0xC934: -case 0xCB34: -case 0xCD34: -case 0xCF34: -case 0xC135: -case 0xC335: -case 0xC535: -case 0xC735: -case 0xC935: -case 0xCB35: -case 0xCD35: -case 0xCF35: -case 0xC136: -case 0xC336: -case 0xC536: -case 0xC736: -case 0xC936: -case 0xCB36: -case 0xCD36: -case 0xCF36: -case 0xC137: -case 0xC337: -case 0xC537: -case 0xC737: -case 0xC937: -case 0xCB37: -case 0xCD37: -case 0xCF37: - -// ANDDa -case 0xC130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xC338: -case 0xC538: -case 0xC738: -case 0xC938: -case 0xCB38: -case 0xCD38: -case 0xCF38: - -// ANDDa -case 0xC138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xC339: -case 0xC539: -case 0xC739: -case 0xC939: -case 0xCB39: -case 0xCD39: -case 0xCF39: - -// ANDDa -case 0xC139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0xC31F: -case 0xC51F: -case 0xC71F: -case 0xC91F: -case 0xCB1F: -case 0xCD1F: -case 0xCF1F: - -// ANDDa -case 0xC11F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xC327: -case 0xC527: -case 0xC727: -case 0xC927: -case 0xCB27: -case 0xCD27: -case 0xCF27: - -// ANDDa -case 0xC127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xC350: -case 0xC550: -case 0xC750: -case 0xC950: -case 0xCB50: -case 0xCD50: -case 0xCF50: -case 0xC151: -case 0xC351: -case 0xC551: -case 0xC751: -case 0xC951: -case 0xCB51: -case 0xCD51: -case 0xCF51: -case 0xC152: -case 0xC352: -case 0xC552: -case 0xC752: -case 0xC952: -case 0xCB52: -case 0xCD52: -case 0xCF52: -case 0xC153: -case 0xC353: -case 0xC553: -case 0xC753: -case 0xC953: -case 0xCB53: -case 0xCD53: -case 0xCF53: -case 0xC154: -case 0xC354: -case 0xC554: -case 0xC754: -case 0xC954: -case 0xCB54: -case 0xCD54: -case 0xCF54: -case 0xC155: -case 0xC355: -case 0xC555: -case 0xC755: -case 0xC955: -case 0xCB55: -case 0xCD55: -case 0xCF55: -case 0xC156: -case 0xC356: -case 0xC556: -case 0xC756: -case 0xC956: -case 0xCB56: -case 0xCD56: -case 0xCF56: -case 0xC157: -case 0xC357: -case 0xC557: -case 0xC757: -case 0xC957: -case 0xCB57: -case 0xCD57: -case 0xCF57: - -// ANDDa -case 0xC150: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xC358: -case 0xC558: -case 0xC758: -case 0xC958: -case 0xCB58: -case 0xCD58: -case 0xCF58: -case 0xC159: -case 0xC359: -case 0xC559: -case 0xC759: -case 0xC959: -case 0xCB59: -case 0xCD59: -case 0xCF59: -case 0xC15A: -case 0xC35A: -case 0xC55A: -case 0xC75A: -case 0xC95A: -case 0xCB5A: -case 0xCD5A: -case 0xCF5A: -case 0xC15B: -case 0xC35B: -case 0xC55B: -case 0xC75B: -case 0xC95B: -case 0xCB5B: -case 0xCD5B: -case 0xCF5B: -case 0xC15C: -case 0xC35C: -case 0xC55C: -case 0xC75C: -case 0xC95C: -case 0xCB5C: -case 0xCD5C: -case 0xCF5C: -case 0xC15D: -case 0xC35D: -case 0xC55D: -case 0xC75D: -case 0xC95D: -case 0xCB5D: -case 0xCD5D: -case 0xCF5D: -case 0xC15E: -case 0xC35E: -case 0xC55E: -case 0xC75E: -case 0xC95E: -case 0xCB5E: -case 0xCD5E: -case 0xCF5E: - -// ANDDa -case 0xC158: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xC360: -case 0xC560: -case 0xC760: -case 0xC960: -case 0xCB60: -case 0xCD60: -case 0xCF60: -case 0xC161: -case 0xC361: -case 0xC561: -case 0xC761: -case 0xC961: -case 0xCB61: -case 0xCD61: -case 0xCF61: -case 0xC162: -case 0xC362: -case 0xC562: -case 0xC762: -case 0xC962: -case 0xCB62: -case 0xCD62: -case 0xCF62: -case 0xC163: -case 0xC363: -case 0xC563: -case 0xC763: -case 0xC963: -case 0xCB63: -case 0xCD63: -case 0xCF63: -case 0xC164: -case 0xC364: -case 0xC564: -case 0xC764: -case 0xC964: -case 0xCB64: -case 0xCD64: -case 0xCF64: -case 0xC165: -case 0xC365: -case 0xC565: -case 0xC765: -case 0xC965: -case 0xCB65: -case 0xCD65: -case 0xCF65: -case 0xC166: -case 0xC366: -case 0xC566: -case 0xC766: -case 0xC966: -case 0xCB66: -case 0xCD66: -case 0xCF66: - -// ANDDa -case 0xC160: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xC368: -case 0xC568: -case 0xC768: -case 0xC968: -case 0xCB68: -case 0xCD68: -case 0xCF68: -case 0xC169: -case 0xC369: -case 0xC569: -case 0xC769: -case 0xC969: -case 0xCB69: -case 0xCD69: -case 0xCF69: -case 0xC16A: -case 0xC36A: -case 0xC56A: -case 0xC76A: -case 0xC96A: -case 0xCB6A: -case 0xCD6A: -case 0xCF6A: -case 0xC16B: -case 0xC36B: -case 0xC56B: -case 0xC76B: -case 0xC96B: -case 0xCB6B: -case 0xCD6B: -case 0xCF6B: -case 0xC16C: -case 0xC36C: -case 0xC56C: -case 0xC76C: -case 0xC96C: -case 0xCB6C: -case 0xCD6C: -case 0xCF6C: -case 0xC16D: -case 0xC36D: -case 0xC56D: -case 0xC76D: -case 0xC96D: -case 0xCB6D: -case 0xCD6D: -case 0xCF6D: -case 0xC16E: -case 0xC36E: -case 0xC56E: -case 0xC76E: -case 0xC96E: -case 0xCB6E: -case 0xCD6E: -case 0xCF6E: -case 0xC16F: -case 0xC36F: -case 0xC56F: -case 0xC76F: -case 0xC96F: -case 0xCB6F: -case 0xCD6F: -case 0xCF6F: - -// ANDDa -case 0xC168: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xC370: -case 0xC570: -case 0xC770: -case 0xC970: -case 0xCB70: -case 0xCD70: -case 0xCF70: -case 0xC171: -case 0xC371: -case 0xC571: -case 0xC771: -case 0xC971: -case 0xCB71: -case 0xCD71: -case 0xCF71: -case 0xC172: -case 0xC372: -case 0xC572: -case 0xC772: -case 0xC972: -case 0xCB72: -case 0xCD72: -case 0xCF72: -case 0xC173: -case 0xC373: -case 0xC573: -case 0xC773: -case 0xC973: -case 0xCB73: -case 0xCD73: -case 0xCF73: -case 0xC174: -case 0xC374: -case 0xC574: -case 0xC774: -case 0xC974: -case 0xCB74: -case 0xCD74: -case 0xCF74: -case 0xC175: -case 0xC375: -case 0xC575: -case 0xC775: -case 0xC975: -case 0xCB75: -case 0xCD75: -case 0xCF75: -case 0xC176: -case 0xC376: -case 0xC576: -case 0xC776: -case 0xC976: -case 0xCB76: -case 0xCD76: -case 0xCF76: -case 0xC177: -case 0xC377: -case 0xC577: -case 0xC777: -case 0xC977: -case 0xCB77: -case 0xCD77: -case 0xCF77: - -// ANDDa -case 0xC170: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xC378: -case 0xC578: -case 0xC778: -case 0xC978: -case 0xCB78: -case 0xCD78: -case 0xCF78: - -// ANDDa -case 0xC178: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xC379: -case 0xC579: -case 0xC779: -case 0xC979: -case 0xCB79: -case 0xCD79: -case 0xCF79: - -// ANDDa -case 0xC179: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0xC35F: -case 0xC55F: -case 0xC75F: -case 0xC95F: -case 0xCB5F: -case 0xCD5F: -case 0xCF5F: - -// ANDDa -case 0xC15F: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xC367: -case 0xC567: -case 0xC767: -case 0xC967: -case 0xCB67: -case 0xCD67: -case 0xCF67: - -// ANDDa -case 0xC167: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xC390: -case 0xC590: -case 0xC790: -case 0xC990: -case 0xCB90: -case 0xCD90: -case 0xCF90: -case 0xC191: -case 0xC391: -case 0xC591: -case 0xC791: -case 0xC991: -case 0xCB91: -case 0xCD91: -case 0xCF91: -case 0xC192: -case 0xC392: -case 0xC592: -case 0xC792: -case 0xC992: -case 0xCB92: -case 0xCD92: -case 0xCF92: -case 0xC193: -case 0xC393: -case 0xC593: -case 0xC793: -case 0xC993: -case 0xCB93: -case 0xCD93: -case 0xCF93: -case 0xC194: -case 0xC394: -case 0xC594: -case 0xC794: -case 0xC994: -case 0xCB94: -case 0xCD94: -case 0xCF94: -case 0xC195: -case 0xC395: -case 0xC595: -case 0xC795: -case 0xC995: -case 0xCB95: -case 0xCD95: -case 0xCF95: -case 0xC196: -case 0xC396: -case 0xC596: -case 0xC796: -case 0xC996: -case 0xCB96: -case 0xCD96: -case 0xCF96: -case 0xC197: -case 0xC397: -case 0xC597: -case 0xC797: -case 0xC997: -case 0xCB97: -case 0xCD97: -case 0xCF97: - -// ANDDa -case 0xC190: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xC398: -case 0xC598: -case 0xC798: -case 0xC998: -case 0xCB98: -case 0xCD98: -case 0xCF98: -case 0xC199: -case 0xC399: -case 0xC599: -case 0xC799: -case 0xC999: -case 0xCB99: -case 0xCD99: -case 0xCF99: -case 0xC19A: -case 0xC39A: -case 0xC59A: -case 0xC79A: -case 0xC99A: -case 0xCB9A: -case 0xCD9A: -case 0xCF9A: -case 0xC19B: -case 0xC39B: -case 0xC59B: -case 0xC79B: -case 0xC99B: -case 0xCB9B: -case 0xCD9B: -case 0xCF9B: -case 0xC19C: -case 0xC39C: -case 0xC59C: -case 0xC79C: -case 0xC99C: -case 0xCB9C: -case 0xCD9C: -case 0xCF9C: -case 0xC19D: -case 0xC39D: -case 0xC59D: -case 0xC79D: -case 0xC99D: -case 0xCB9D: -case 0xCD9D: -case 0xCF9D: -case 0xC19E: -case 0xC39E: -case 0xC59E: -case 0xC79E: -case 0xC99E: -case 0xCB9E: -case 0xCD9E: -case 0xCF9E: - -// ANDDa -case 0xC198: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xC3A0: -case 0xC5A0: -case 0xC7A0: -case 0xC9A0: -case 0xCBA0: -case 0xCDA0: -case 0xCFA0: -case 0xC1A1: -case 0xC3A1: -case 0xC5A1: -case 0xC7A1: -case 0xC9A1: -case 0xCBA1: -case 0xCDA1: -case 0xCFA1: -case 0xC1A2: -case 0xC3A2: -case 0xC5A2: -case 0xC7A2: -case 0xC9A2: -case 0xCBA2: -case 0xCDA2: -case 0xCFA2: -case 0xC1A3: -case 0xC3A3: -case 0xC5A3: -case 0xC7A3: -case 0xC9A3: -case 0xCBA3: -case 0xCDA3: -case 0xCFA3: -case 0xC1A4: -case 0xC3A4: -case 0xC5A4: -case 0xC7A4: -case 0xC9A4: -case 0xCBA4: -case 0xCDA4: -case 0xCFA4: -case 0xC1A5: -case 0xC3A5: -case 0xC5A5: -case 0xC7A5: -case 0xC9A5: -case 0xCBA5: -case 0xCDA5: -case 0xCFA5: -case 0xC1A6: -case 0xC3A6: -case 0xC5A6: -case 0xC7A6: -case 0xC9A6: -case 0xCBA6: -case 0xCDA6: -case 0xCFA6: - -// ANDDa -case 0xC1A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xC3A8: -case 0xC5A8: -case 0xC7A8: -case 0xC9A8: -case 0xCBA8: -case 0xCDA8: -case 0xCFA8: -case 0xC1A9: -case 0xC3A9: -case 0xC5A9: -case 0xC7A9: -case 0xC9A9: -case 0xCBA9: -case 0xCDA9: -case 0xCFA9: -case 0xC1AA: -case 0xC3AA: -case 0xC5AA: -case 0xC7AA: -case 0xC9AA: -case 0xCBAA: -case 0xCDAA: -case 0xCFAA: -case 0xC1AB: -case 0xC3AB: -case 0xC5AB: -case 0xC7AB: -case 0xC9AB: -case 0xCBAB: -case 0xCDAB: -case 0xCFAB: -case 0xC1AC: -case 0xC3AC: -case 0xC5AC: -case 0xC7AC: -case 0xC9AC: -case 0xCBAC: -case 0xCDAC: -case 0xCFAC: -case 0xC1AD: -case 0xC3AD: -case 0xC5AD: -case 0xC7AD: -case 0xC9AD: -case 0xCBAD: -case 0xCDAD: -case 0xCFAD: -case 0xC1AE: -case 0xC3AE: -case 0xC5AE: -case 0xC7AE: -case 0xC9AE: -case 0xCBAE: -case 0xCDAE: -case 0xCFAE: -case 0xC1AF: -case 0xC3AF: -case 0xC5AF: -case 0xC7AF: -case 0xC9AF: -case 0xCBAF: -case 0xCDAF: -case 0xCFAF: - -// ANDDa -case 0xC1A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xC3B0: -case 0xC5B0: -case 0xC7B0: -case 0xC9B0: -case 0xCBB0: -case 0xCDB0: -case 0xCFB0: -case 0xC1B1: -case 0xC3B1: -case 0xC5B1: -case 0xC7B1: -case 0xC9B1: -case 0xCBB1: -case 0xCDB1: -case 0xCFB1: -case 0xC1B2: -case 0xC3B2: -case 0xC5B2: -case 0xC7B2: -case 0xC9B2: -case 0xCBB2: -case 0xCDB2: -case 0xCFB2: -case 0xC1B3: -case 0xC3B3: -case 0xC5B3: -case 0xC7B3: -case 0xC9B3: -case 0xCBB3: -case 0xCDB3: -case 0xCFB3: -case 0xC1B4: -case 0xC3B4: -case 0xC5B4: -case 0xC7B4: -case 0xC9B4: -case 0xCBB4: -case 0xCDB4: -case 0xCFB4: -case 0xC1B5: -case 0xC3B5: -case 0xC5B5: -case 0xC7B5: -case 0xC9B5: -case 0xCBB5: -case 0xCDB5: -case 0xCFB5: -case 0xC1B6: -case 0xC3B6: -case 0xC5B6: -case 0xC7B6: -case 0xC9B6: -case 0xCBB6: -case 0xCDB6: -case 0xCFB6: -case 0xC1B7: -case 0xC3B7: -case 0xC5B7: -case 0xC7B7: -case 0xC9B7: -case 0xCBB7: -case 0xCDB7: -case 0xCFB7: - -// ANDDa -case 0xC1B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0xC3B8: -case 0xC5B8: -case 0xC7B8: -case 0xC9B8: -case 0xCBB8: -case 0xCDB8: -case 0xCFB8: - -// ANDDa -case 0xC1B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xC3B9: -case 0xC5B9: -case 0xC7B9: -case 0xC9B9: -case 0xCBB9: -case 0xCDB9: -case 0xCFB9: - -// ANDDa -case 0xC1B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0xC39F: -case 0xC59F: -case 0xC79F: -case 0xC99F: -case 0xCB9F: -case 0xCD9F: -case 0xCF9F: - -// ANDDa -case 0xC19F: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xC3A7: -case 0xC5A7: -case 0xC7A7: -case 0xC9A7: -case 0xCBA7: -case 0xCDA7: -case 0xCFA7: - -// ANDDa -case 0xC1A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xC300: -case 0xC500: -case 0xC700: -case 0xC900: -case 0xCB00: -case 0xCD00: -case 0xCF00: -case 0xC101: -case 0xC301: -case 0xC501: -case 0xC701: -case 0xC901: -case 0xCB01: -case 0xCD01: -case 0xCF01: -case 0xC102: -case 0xC302: -case 0xC502: -case 0xC702: -case 0xC902: -case 0xCB02: -case 0xCD02: -case 0xCF02: -case 0xC103: -case 0xC303: -case 0xC503: -case 0xC703: -case 0xC903: -case 0xCB03: -case 0xCD03: -case 0xCF03: -case 0xC104: -case 0xC304: -case 0xC504: -case 0xC704: -case 0xC904: -case 0xCB04: -case 0xCD04: -case 0xCF04: -case 0xC105: -case 0xC305: -case 0xC505: -case 0xC705: -case 0xC905: -case 0xCB05: -case 0xCD05: -case 0xCF05: -case 0xC106: -case 0xC306: -case 0xC506: -case 0xC706: -case 0xC906: -case 0xCB06: -case 0xCD06: -case 0xCF06: -case 0xC107: -case 0xC307: -case 0xC507: -case 0xC707: -case 0xC907: -case 0xCB07: -case 0xCD07: -case 0xCF07: - -// ABCD -case 0xC100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xC308: -case 0xC508: -case 0xC708: -case 0xC908: -case 0xCB08: -case 0xCD08: -case 0xC109: -case 0xC309: -case 0xC509: -case 0xC709: -case 0xC909: -case 0xCB09: -case 0xCD09: -case 0xC10A: -case 0xC30A: -case 0xC50A: -case 0xC70A: -case 0xC90A: -case 0xCB0A: -case 0xCD0A: -case 0xC10B: -case 0xC30B: -case 0xC50B: -case 0xC70B: -case 0xC90B: -case 0xCB0B: -case 0xCD0B: -case 0xC10C: -case 0xC30C: -case 0xC50C: -case 0xC70C: -case 0xC90C: -case 0xCB0C: -case 0xCD0C: -case 0xC10D: -case 0xC30D: -case 0xC50D: -case 0xC70D: -case 0xC90D: -case 0xCB0D: -case 0xCD0D: -case 0xC10E: -case 0xC30E: -case 0xC50E: -case 0xC70E: -case 0xC90E: -case 0xCB0E: -case 0xCD0E: - -// ABCDM -case 0xC108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xC30F: -case 0xC50F: -case 0xC70F: -case 0xC90F: -case 0xCB0F: -case 0xCD0F: - -// ABCD7M -case 0xC10F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xCF09: -case 0xCF0A: -case 0xCF0B: -case 0xCF0C: -case 0xCF0D: -case 0xCF0E: - -// ABCDM7 -case 0xCF08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// ABCD7M7 -case 0xCF0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xC2C0: -case 0xC4C0: -case 0xC6C0: -case 0xC8C0: -case 0xCAC0: -case 0xCCC0: -case 0xCEC0: -case 0xC0C1: -case 0xC2C1: -case 0xC4C1: -case 0xC6C1: -case 0xC8C1: -case 0xCAC1: -case 0xCCC1: -case 0xCEC1: -case 0xC0C2: -case 0xC2C2: -case 0xC4C2: -case 0xC6C2: -case 0xC8C2: -case 0xCAC2: -case 0xCCC2: -case 0xCEC2: -case 0xC0C3: -case 0xC2C3: -case 0xC4C3: -case 0xC6C3: -case 0xC8C3: -case 0xCAC3: -case 0xCCC3: -case 0xCEC3: -case 0xC0C4: -case 0xC2C4: -case 0xC4C4: -case 0xC6C4: -case 0xC8C4: -case 0xCAC4: -case 0xCCC4: -case 0xCEC4: -case 0xC0C5: -case 0xC2C5: -case 0xC4C5: -case 0xC6C5: -case 0xC8C5: -case 0xCAC5: -case 0xCCC5: -case 0xCEC5: -case 0xC0C6: -case 0xC2C6: -case 0xC4C6: -case 0xC6C6: -case 0xC8C6: -case 0xCAC6: -case 0xCCC6: -case 0xCEC6: -case 0xC0C7: -case 0xC2C7: -case 0xC4C7: -case 0xC6C7: -case 0xC8C7: -case 0xCAC7: -case 0xCCC7: -case 0xCEC7: - -// MULU -case 0xC0C0: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(50) -case 0xC2D0: -case 0xC4D0: -case 0xC6D0: -case 0xC8D0: -case 0xCAD0: -case 0xCCD0: -case 0xCED0: -case 0xC0D1: -case 0xC2D1: -case 0xC4D1: -case 0xC6D1: -case 0xC8D1: -case 0xCAD1: -case 0xCCD1: -case 0xCED1: -case 0xC0D2: -case 0xC2D2: -case 0xC4D2: -case 0xC6D2: -case 0xC8D2: -case 0xCAD2: -case 0xCCD2: -case 0xCED2: -case 0xC0D3: -case 0xC2D3: -case 0xC4D3: -case 0xC6D3: -case 0xC8D3: -case 0xCAD3: -case 0xCCD3: -case 0xCED3: -case 0xC0D4: -case 0xC2D4: -case 0xC4D4: -case 0xC6D4: -case 0xC8D4: -case 0xCAD4: -case 0xCCD4: -case 0xCED4: -case 0xC0D5: -case 0xC2D5: -case 0xC4D5: -case 0xC6D5: -case 0xC8D5: -case 0xCAD5: -case 0xCCD5: -case 0xCED5: -case 0xC0D6: -case 0xC2D6: -case 0xC4D6: -case 0xC6D6: -case 0xC8D6: -case 0xCAD6: -case 0xCCD6: -case 0xCED6: -case 0xC0D7: -case 0xC2D7: -case 0xC4D7: -case 0xC6D7: -case 0xC8D7: -case 0xCAD7: -case 0xCCD7: -case 0xCED7: - -// MULU -case 0xC0D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC2D8: -case 0xC4D8: -case 0xC6D8: -case 0xC8D8: -case 0xCAD8: -case 0xCCD8: -case 0xCED8: -case 0xC0D9: -case 0xC2D9: -case 0xC4D9: -case 0xC6D9: -case 0xC8D9: -case 0xCAD9: -case 0xCCD9: -case 0xCED9: -case 0xC0DA: -case 0xC2DA: -case 0xC4DA: -case 0xC6DA: -case 0xC8DA: -case 0xCADA: -case 0xCCDA: -case 0xCEDA: -case 0xC0DB: -case 0xC2DB: -case 0xC4DB: -case 0xC6DB: -case 0xC8DB: -case 0xCADB: -case 0xCCDB: -case 0xCEDB: -case 0xC0DC: -case 0xC2DC: -case 0xC4DC: -case 0xC6DC: -case 0xC8DC: -case 0xCADC: -case 0xCCDC: -case 0xCEDC: -case 0xC0DD: -case 0xC2DD: -case 0xC4DD: -case 0xC6DD: -case 0xC8DD: -case 0xCADD: -case 0xCCDD: -case 0xCEDD: -case 0xC0DE: -case 0xC2DE: -case 0xC4DE: -case 0xC6DE: -case 0xC8DE: -case 0xCADE: -case 0xCCDE: -case 0xCEDE: - -// MULU -case 0xC0D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC2E0: -case 0xC4E0: -case 0xC6E0: -case 0xC8E0: -case 0xCAE0: -case 0xCCE0: -case 0xCEE0: -case 0xC0E1: -case 0xC2E1: -case 0xC4E1: -case 0xC6E1: -case 0xC8E1: -case 0xCAE1: -case 0xCCE1: -case 0xCEE1: -case 0xC0E2: -case 0xC2E2: -case 0xC4E2: -case 0xC6E2: -case 0xC8E2: -case 0xCAE2: -case 0xCCE2: -case 0xCEE2: -case 0xC0E3: -case 0xC2E3: -case 0xC4E3: -case 0xC6E3: -case 0xC8E3: -case 0xCAE3: -case 0xCCE3: -case 0xCEE3: -case 0xC0E4: -case 0xC2E4: -case 0xC4E4: -case 0xC6E4: -case 0xC8E4: -case 0xCAE4: -case 0xCCE4: -case 0xCEE4: -case 0xC0E5: -case 0xC2E5: -case 0xC4E5: -case 0xC6E5: -case 0xC8E5: -case 0xCAE5: -case 0xCCE5: -case 0xCEE5: -case 0xC0E6: -case 0xC2E6: -case 0xC4E6: -case 0xC6E6: -case 0xC8E6: -case 0xCAE6: -case 0xCCE6: -case 0xCEE6: - -// MULU -case 0xC0E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC2E8: -case 0xC4E8: -case 0xC6E8: -case 0xC8E8: -case 0xCAE8: -case 0xCCE8: -case 0xCEE8: -case 0xC0E9: -case 0xC2E9: -case 0xC4E9: -case 0xC6E9: -case 0xC8E9: -case 0xCAE9: -case 0xCCE9: -case 0xCEE9: -case 0xC0EA: -case 0xC2EA: -case 0xC4EA: -case 0xC6EA: -case 0xC8EA: -case 0xCAEA: -case 0xCCEA: -case 0xCEEA: -case 0xC0EB: -case 0xC2EB: -case 0xC4EB: -case 0xC6EB: -case 0xC8EB: -case 0xCAEB: -case 0xCCEB: -case 0xCEEB: -case 0xC0EC: -case 0xC2EC: -case 0xC4EC: -case 0xC6EC: -case 0xC8EC: -case 0xCAEC: -case 0xCCEC: -case 0xCEEC: -case 0xC0ED: -case 0xC2ED: -case 0xC4ED: -case 0xC6ED: -case 0xC8ED: -case 0xCAED: -case 0xCCED: -case 0xCEED: -case 0xC0EE: -case 0xC2EE: -case 0xC4EE: -case 0xC6EE: -case 0xC8EE: -case 0xCAEE: -case 0xCCEE: -case 0xCEEE: -case 0xC0EF: -case 0xC2EF: -case 0xC4EF: -case 0xC6EF: -case 0xC8EF: -case 0xCAEF: -case 0xCCEF: -case 0xCEEF: - -// MULU -case 0xC0E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC2F0: -case 0xC4F0: -case 0xC6F0: -case 0xC8F0: -case 0xCAF0: -case 0xCCF0: -case 0xCEF0: -case 0xC0F1: -case 0xC2F1: -case 0xC4F1: -case 0xC6F1: -case 0xC8F1: -case 0xCAF1: -case 0xCCF1: -case 0xCEF1: -case 0xC0F2: -case 0xC2F2: -case 0xC4F2: -case 0xC6F2: -case 0xC8F2: -case 0xCAF2: -case 0xCCF2: -case 0xCEF2: -case 0xC0F3: -case 0xC2F3: -case 0xC4F3: -case 0xC6F3: -case 0xC8F3: -case 0xCAF3: -case 0xCCF3: -case 0xCEF3: -case 0xC0F4: -case 0xC2F4: -case 0xC4F4: -case 0xC6F4: -case 0xC8F4: -case 0xCAF4: -case 0xCCF4: -case 0xCEF4: -case 0xC0F5: -case 0xC2F5: -case 0xC4F5: -case 0xC6F5: -case 0xC8F5: -case 0xCAF5: -case 0xCCF5: -case 0xCEF5: -case 0xC0F6: -case 0xC2F6: -case 0xC4F6: -case 0xC6F6: -case 0xC8F6: -case 0xCAF6: -case 0xCCF6: -case 0xCEF6: -case 0xC0F7: -case 0xC2F7: -case 0xC4F7: -case 0xC6F7: -case 0xC8F7: -case 0xCAF7: -case 0xCCF7: -case 0xCEF7: - -// MULU -case 0xC0F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC2F8: -case 0xC4F8: -case 0xC6F8: -case 0xC8F8: -case 0xCAF8: -case 0xCCF8: -case 0xCEF8: - -// MULU -case 0xC0F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC2F9: -case 0xC4F9: -case 0xC6F9: -case 0xC8F9: -case 0xCAF9: -case 0xCCF9: -case 0xCEF9: - -// MULU -case 0xC0F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(62) -case 0xC2FA: -case 0xC4FA: -case 0xC6FA: -case 0xC8FA: -case 0xCAFA: -case 0xCCFA: -case 0xCEFA: - -// MULU -case 0xC0FA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC2FB: -case 0xC4FB: -case 0xC6FB: -case 0xC8FB: -case 0xCAFB: -case 0xCCFB: -case 0xCEFB: - -// MULU -case 0xC0FB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC2FC: -case 0xC4FC: -case 0xC6FC: -case 0xC8FC: -case 0xCAFC: -case 0xCCFC: -case 0xCEFC: - -// MULU -case 0xC0FC: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(54) -case 0xC2DF: -case 0xC4DF: -case 0xC6DF: -case 0xC8DF: -case 0xCADF: -case 0xCCDF: -case 0xCEDF: - -// MULU -case 0xC0DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC2E7: -case 0xC4E7: -case 0xC6E7: -case 0xC8E7: -case 0xCAE7: -case 0xCCE7: -case 0xCEE7: - -// MULU -case 0xC0E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC3C0: -case 0xC5C0: -case 0xC7C0: -case 0xC9C0: -case 0xCBC0: -case 0xCDC0: -case 0xCFC0: -case 0xC1C1: -case 0xC3C1: -case 0xC5C1: -case 0xC7C1: -case 0xC9C1: -case 0xCBC1: -case 0xCDC1: -case 0xCFC1: -case 0xC1C2: -case 0xC3C2: -case 0xC5C2: -case 0xC7C2: -case 0xC9C2: -case 0xCBC2: -case 0xCDC2: -case 0xCFC2: -case 0xC1C3: -case 0xC3C3: -case 0xC5C3: -case 0xC7C3: -case 0xC9C3: -case 0xCBC3: -case 0xCDC3: -case 0xCFC3: -case 0xC1C4: -case 0xC3C4: -case 0xC5C4: -case 0xC7C4: -case 0xC9C4: -case 0xCBC4: -case 0xCDC4: -case 0xCFC4: -case 0xC1C5: -case 0xC3C5: -case 0xC5C5: -case 0xC7C5: -case 0xC9C5: -case 0xCBC5: -case 0xCDC5: -case 0xCFC5: -case 0xC1C6: -case 0xC3C6: -case 0xC5C6: -case 0xC7C6: -case 0xC9C6: -case 0xCBC6: -case 0xCDC6: -case 0xCFC6: -case 0xC1C7: -case 0xC3C7: -case 0xC5C7: -case 0xC7C7: -case 0xC9C7: -case 0xCBC7: -case 0xCDC7: -case 0xCFC7: - -// MULS -case 0xC1C0: -{ - u32 res; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(50) -case 0xC3D0: -case 0xC5D0: -case 0xC7D0: -case 0xC9D0: -case 0xCBD0: -case 0xCDD0: -case 0xCFD0: -case 0xC1D1: -case 0xC3D1: -case 0xC5D1: -case 0xC7D1: -case 0xC9D1: -case 0xCBD1: -case 0xCDD1: -case 0xCFD1: -case 0xC1D2: -case 0xC3D2: -case 0xC5D2: -case 0xC7D2: -case 0xC9D2: -case 0xCBD2: -case 0xCDD2: -case 0xCFD2: -case 0xC1D3: -case 0xC3D3: -case 0xC5D3: -case 0xC7D3: -case 0xC9D3: -case 0xCBD3: -case 0xCDD3: -case 0xCFD3: -case 0xC1D4: -case 0xC3D4: -case 0xC5D4: -case 0xC7D4: -case 0xC9D4: -case 0xCBD4: -case 0xCDD4: -case 0xCFD4: -case 0xC1D5: -case 0xC3D5: -case 0xC5D5: -case 0xC7D5: -case 0xC9D5: -case 0xCBD5: -case 0xCDD5: -case 0xCFD5: -case 0xC1D6: -case 0xC3D6: -case 0xC5D6: -case 0xC7D6: -case 0xC9D6: -case 0xCBD6: -case 0xCDD6: -case 0xCFD6: -case 0xC1D7: -case 0xC3D7: -case 0xC5D7: -case 0xC7D7: -case 0xC9D7: -case 0xCBD7: -case 0xCDD7: -case 0xCFD7: - -// MULS -case 0xC1D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC3D8: -case 0xC5D8: -case 0xC7D8: -case 0xC9D8: -case 0xCBD8: -case 0xCDD8: -case 0xCFD8: -case 0xC1D9: -case 0xC3D9: -case 0xC5D9: -case 0xC7D9: -case 0xC9D9: -case 0xCBD9: -case 0xCDD9: -case 0xCFD9: -case 0xC1DA: -case 0xC3DA: -case 0xC5DA: -case 0xC7DA: -case 0xC9DA: -case 0xCBDA: -case 0xCDDA: -case 0xCFDA: -case 0xC1DB: -case 0xC3DB: -case 0xC5DB: -case 0xC7DB: -case 0xC9DB: -case 0xCBDB: -case 0xCDDB: -case 0xCFDB: -case 0xC1DC: -case 0xC3DC: -case 0xC5DC: -case 0xC7DC: -case 0xC9DC: -case 0xCBDC: -case 0xCDDC: -case 0xCFDC: -case 0xC1DD: -case 0xC3DD: -case 0xC5DD: -case 0xC7DD: -case 0xC9DD: -case 0xCBDD: -case 0xCDDD: -case 0xCFDD: -case 0xC1DE: -case 0xC3DE: -case 0xC5DE: -case 0xC7DE: -case 0xC9DE: -case 0xCBDE: -case 0xCDDE: -case 0xCFDE: - -// MULS -case 0xC1D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC3E0: -case 0xC5E0: -case 0xC7E0: -case 0xC9E0: -case 0xCBE0: -case 0xCDE0: -case 0xCFE0: -case 0xC1E1: -case 0xC3E1: -case 0xC5E1: -case 0xC7E1: -case 0xC9E1: -case 0xCBE1: -case 0xCDE1: -case 0xCFE1: -case 0xC1E2: -case 0xC3E2: -case 0xC5E2: -case 0xC7E2: -case 0xC9E2: -case 0xCBE2: -case 0xCDE2: -case 0xCFE2: -case 0xC1E3: -case 0xC3E3: -case 0xC5E3: -case 0xC7E3: -case 0xC9E3: -case 0xCBE3: -case 0xCDE3: -case 0xCFE3: -case 0xC1E4: -case 0xC3E4: -case 0xC5E4: -case 0xC7E4: -case 0xC9E4: -case 0xCBE4: -case 0xCDE4: -case 0xCFE4: -case 0xC1E5: -case 0xC3E5: -case 0xC5E5: -case 0xC7E5: -case 0xC9E5: -case 0xCBE5: -case 0xCDE5: -case 0xCFE5: -case 0xC1E6: -case 0xC3E6: -case 0xC5E6: -case 0xC7E6: -case 0xC9E6: -case 0xCBE6: -case 0xCDE6: -case 0xCFE6: - -// MULS -case 0xC1E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC3E8: -case 0xC5E8: -case 0xC7E8: -case 0xC9E8: -case 0xCBE8: -case 0xCDE8: -case 0xCFE8: -case 0xC1E9: -case 0xC3E9: -case 0xC5E9: -case 0xC7E9: -case 0xC9E9: -case 0xCBE9: -case 0xCDE9: -case 0xCFE9: -case 0xC1EA: -case 0xC3EA: -case 0xC5EA: -case 0xC7EA: -case 0xC9EA: -case 0xCBEA: -case 0xCDEA: -case 0xCFEA: -case 0xC1EB: -case 0xC3EB: -case 0xC5EB: -case 0xC7EB: -case 0xC9EB: -case 0xCBEB: -case 0xCDEB: -case 0xCFEB: -case 0xC1EC: -case 0xC3EC: -case 0xC5EC: -case 0xC7EC: -case 0xC9EC: -case 0xCBEC: -case 0xCDEC: -case 0xCFEC: -case 0xC1ED: -case 0xC3ED: -case 0xC5ED: -case 0xC7ED: -case 0xC9ED: -case 0xCBED: -case 0xCDED: -case 0xCFED: -case 0xC1EE: -case 0xC3EE: -case 0xC5EE: -case 0xC7EE: -case 0xC9EE: -case 0xCBEE: -case 0xCDEE: -case 0xCFEE: -case 0xC1EF: -case 0xC3EF: -case 0xC5EF: -case 0xC7EF: -case 0xC9EF: -case 0xCBEF: -case 0xCDEF: -case 0xCFEF: - -// MULS -case 0xC1E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC3F0: -case 0xC5F0: -case 0xC7F0: -case 0xC9F0: -case 0xCBF0: -case 0xCDF0: -case 0xCFF0: -case 0xC1F1: -case 0xC3F1: -case 0xC5F1: -case 0xC7F1: -case 0xC9F1: -case 0xCBF1: -case 0xCDF1: -case 0xCFF1: -case 0xC1F2: -case 0xC3F2: -case 0xC5F2: -case 0xC7F2: -case 0xC9F2: -case 0xCBF2: -case 0xCDF2: -case 0xCFF2: -case 0xC1F3: -case 0xC3F3: -case 0xC5F3: -case 0xC7F3: -case 0xC9F3: -case 0xCBF3: -case 0xCDF3: -case 0xCFF3: -case 0xC1F4: -case 0xC3F4: -case 0xC5F4: -case 0xC7F4: -case 0xC9F4: -case 0xCBF4: -case 0xCDF4: -case 0xCFF4: -case 0xC1F5: -case 0xC3F5: -case 0xC5F5: -case 0xC7F5: -case 0xC9F5: -case 0xCBF5: -case 0xCDF5: -case 0xCFF5: -case 0xC1F6: -case 0xC3F6: -case 0xC5F6: -case 0xC7F6: -case 0xC9F6: -case 0xCBF6: -case 0xCDF6: -case 0xCFF6: -case 0xC1F7: -case 0xC3F7: -case 0xC5F7: -case 0xC7F7: -case 0xC9F7: -case 0xCBF7: -case 0xCDF7: -case 0xCFF7: - -// MULS -case 0xC1F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC3F8: -case 0xC5F8: -case 0xC7F8: -case 0xC9F8: -case 0xCBF8: -case 0xCDF8: -case 0xCFF8: - -// MULS -case 0xC1F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC3F9: -case 0xC5F9: -case 0xC7F9: -case 0xC9F9: -case 0xCBF9: -case 0xCDF9: -case 0xCFF9: - -// MULS -case 0xC1F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(62) -case 0xC3FA: -case 0xC5FA: -case 0xC7FA: -case 0xC9FA: -case 0xCBFA: -case 0xCDFA: -case 0xCFFA: - -// MULS -case 0xC1FA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC3FB: -case 0xC5FB: -case 0xC7FB: -case 0xC9FB: -case 0xCBFB: -case 0xCDFB: -case 0xCFFB: - -// MULS -case 0xC1FB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC3FC: -case 0xC5FC: -case 0xC7FC: -case 0xC9FC: -case 0xCBFC: -case 0xCDFC: -case 0xCFFC: - -// MULS -case 0xC1FC: -{ - u32 res; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(54) -case 0xC3DF: -case 0xC5DF: -case 0xC7DF: -case 0xC9DF: -case 0xCBDF: -case 0xCDDF: -case 0xCFDF: - -// MULS -case 0xC1DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC3E7: -case 0xC5E7: -case 0xC7E7: -case 0xC9E7: -case 0xCBE7: -case 0xCDE7: -case 0xCFE7: - -// MULS -case 0xC1E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC340: -case 0xC540: -case 0xC740: -case 0xC940: -case 0xCB40: -case 0xCD40: -case 0xCF40: -case 0xC141: -case 0xC341: -case 0xC541: -case 0xC741: -case 0xC941: -case 0xCB41: -case 0xCD41: -case 0xCF41: -case 0xC142: -case 0xC342: -case 0xC542: -case 0xC742: -case 0xC942: -case 0xCB42: -case 0xCD42: -case 0xCF42: -case 0xC143: -case 0xC343: -case 0xC543: -case 0xC743: -case 0xC943: -case 0xCB43: -case 0xCD43: -case 0xCF43: -case 0xC144: -case 0xC344: -case 0xC544: -case 0xC744: -case 0xC944: -case 0xCB44: -case 0xCD44: -case 0xCF44: -case 0xC145: -case 0xC345: -case 0xC545: -case 0xC745: -case 0xC945: -case 0xCB45: -case 0xCD45: -case 0xCF45: -case 0xC146: -case 0xC346: -case 0xC546: -case 0xC746: -case 0xC946: -case 0xCB46: -case 0xCD46: -case 0xCF46: -case 0xC147: -case 0xC347: -case 0xC547: -case 0xC747: -case 0xC947: -case 0xCB47: -case 0xCD47: -case 0xCF47: - -// EXGDD -case 0xC140: -{ - u32 res; - pointer src; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - res = src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xC348: -case 0xC548: -case 0xC748: -case 0xC948: -case 0xCB48: -case 0xCD48: -case 0xCF48: -case 0xC149: -case 0xC349: -case 0xC549: -case 0xC749: -case 0xC949: -case 0xCB49: -case 0xCD49: -case 0xCF49: -case 0xC14A: -case 0xC34A: -case 0xC54A: -case 0xC74A: -case 0xC94A: -case 0xCB4A: -case 0xCD4A: -case 0xCF4A: -case 0xC14B: -case 0xC34B: -case 0xC54B: -case 0xC74B: -case 0xC94B: -case 0xCB4B: -case 0xCD4B: -case 0xCF4B: -case 0xC14C: -case 0xC34C: -case 0xC54C: -case 0xC74C: -case 0xC94C: -case 0xCB4C: -case 0xCD4C: -case 0xCF4C: -case 0xC14D: -case 0xC34D: -case 0xC54D: -case 0xC74D: -case 0xC94D: -case 0xCB4D: -case 0xCD4D: -case 0xCF4D: -case 0xC14E: -case 0xC34E: -case 0xC54E: -case 0xC74E: -case 0xC94E: -case 0xCB4E: -case 0xCD4E: -case 0xCF4E: -case 0xC14F: -case 0xC34F: -case 0xC54F: -case 0xC74F: -case 0xC94F: -case 0xCB4F: -case 0xCD4F: -case 0xCF4F: - -// EXGAA -case 0xC148: -{ - u32 res; - pointer src; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - src = (u32)CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; - res = src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(6) -case 0xC388: -case 0xC588: -case 0xC788: -case 0xC988: -case 0xCB88: -case 0xCD88: -case 0xCF88: -case 0xC189: -case 0xC389: -case 0xC589: -case 0xC789: -case 0xC989: -case 0xCB89: -case 0xCD89: -case 0xCF89: -case 0xC18A: -case 0xC38A: -case 0xC58A: -case 0xC78A: -case 0xC98A: -case 0xCB8A: -case 0xCD8A: -case 0xCF8A: -case 0xC18B: -case 0xC38B: -case 0xC58B: -case 0xC78B: -case 0xC98B: -case 0xCB8B: -case 0xCD8B: -case 0xCF8B: -case 0xC18C: -case 0xC38C: -case 0xC58C: -case 0xC78C: -case 0xC98C: -case 0xCB8C: -case 0xCD8C: -case 0xCF8C: -case 0xC18D: -case 0xC38D: -case 0xC58D: -case 0xC78D: -case 0xC98D: -case 0xCB8D: -case 0xCD8D: -case 0xCF8D: -case 0xC18E: -case 0xC38E: -case 0xC58E: -case 0xC78E: -case 0xC98E: -case 0xCB8E: -case 0xCD8E: -case 0xCF8E: -case 0xC18F: -case 0xC38F: -case 0xC58F: -case 0xC78F: -case 0xC98F: -case 0xCB8F: -case 0xCD8F: -case 0xCF8F: - -// EXGAD -case 0xC188: -{ - u32 res; - pointer src; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - res = src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(6) diff --git a/yabause/src/c68k/c68k_opD.inc b/yabause/src/c68k/c68k_opD.inc deleted file mode 100644 index af269730e8..0000000000 --- a/yabause/src/c68k/c68k_opD.inc +++ /dev/null @@ -1,5950 +0,0 @@ -case 0xD200: -case 0xD400: -case 0xD600: -case 0xD800: -case 0xDA00: -case 0xDC00: -case 0xDE00: -case 0xD001: -case 0xD201: -case 0xD401: -case 0xD601: -case 0xD801: -case 0xDA01: -case 0xDC01: -case 0xDE01: -case 0xD002: -case 0xD202: -case 0xD402: -case 0xD602: -case 0xD802: -case 0xDA02: -case 0xDC02: -case 0xDE02: -case 0xD003: -case 0xD203: -case 0xD403: -case 0xD603: -case 0xD803: -case 0xDA03: -case 0xDC03: -case 0xDE03: -case 0xD004: -case 0xD204: -case 0xD404: -case 0xD604: -case 0xD804: -case 0xDA04: -case 0xDC04: -case 0xDE04: -case 0xD005: -case 0xD205: -case 0xD405: -case 0xD605: -case 0xD805: -case 0xDA05: -case 0xDC05: -case 0xDE05: -case 0xD006: -case 0xD206: -case 0xD406: -case 0xD606: -case 0xD806: -case 0xDA06: -case 0xDC06: -case 0xDE06: -case 0xD007: -case 0xD207: -case 0xD407: -case 0xD607: -case 0xD807: -case 0xDA07: -case 0xDC07: -case 0xDE07: - -// ADDaD -case 0xD000: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD208: -case 0xD408: -case 0xD608: -case 0xD808: -case 0xDA08: -case 0xDC08: -case 0xDE08: -case 0xD009: -case 0xD209: -case 0xD409: -case 0xD609: -case 0xD809: -case 0xDA09: -case 0xDC09: -case 0xDE09: -case 0xD00A: -case 0xD20A: -case 0xD40A: -case 0xD60A: -case 0xD80A: -case 0xDA0A: -case 0xDC0A: -case 0xDE0A: -case 0xD00B: -case 0xD20B: -case 0xD40B: -case 0xD60B: -case 0xD80B: -case 0xDA0B: -case 0xDC0B: -case 0xDE0B: -case 0xD00C: -case 0xD20C: -case 0xD40C: -case 0xD60C: -case 0xD80C: -case 0xDA0C: -case 0xDC0C: -case 0xDE0C: -case 0xD00D: -case 0xD20D: -case 0xD40D: -case 0xD60D: -case 0xD80D: -case 0xDA0D: -case 0xDC0D: -case 0xDE0D: -case 0xD00E: -case 0xD20E: -case 0xD40E: -case 0xD60E: -case 0xD80E: -case 0xDA0E: -case 0xDC0E: -case 0xDE0E: -case 0xD00F: -case 0xD20F: -case 0xD40F: -case 0xD60F: -case 0xD80F: -case 0xDA0F: -case 0xDC0F: -case 0xDE0F: - -// ADDaD -case 0xD008: -{ - u32 res; - pointer dst; - pointer src; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD210: -case 0xD410: -case 0xD610: -case 0xD810: -case 0xDA10: -case 0xDC10: -case 0xDE10: -case 0xD011: -case 0xD211: -case 0xD411: -case 0xD611: -case 0xD811: -case 0xDA11: -case 0xDC11: -case 0xDE11: -case 0xD012: -case 0xD212: -case 0xD412: -case 0xD612: -case 0xD812: -case 0xDA12: -case 0xDC12: -case 0xDE12: -case 0xD013: -case 0xD213: -case 0xD413: -case 0xD613: -case 0xD813: -case 0xDA13: -case 0xDC13: -case 0xDE13: -case 0xD014: -case 0xD214: -case 0xD414: -case 0xD614: -case 0xD814: -case 0xDA14: -case 0xDC14: -case 0xDE14: -case 0xD015: -case 0xD215: -case 0xD415: -case 0xD615: -case 0xD815: -case 0xDA15: -case 0xDC15: -case 0xDE15: -case 0xD016: -case 0xD216: -case 0xD416: -case 0xD616: -case 0xD816: -case 0xDA16: -case 0xDC16: -case 0xDE16: -case 0xD017: -case 0xD217: -case 0xD417: -case 0xD617: -case 0xD817: -case 0xDA17: -case 0xDC17: -case 0xDE17: - -// ADDaD -case 0xD010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD218: -case 0xD418: -case 0xD618: -case 0xD818: -case 0xDA18: -case 0xDC18: -case 0xDE18: -case 0xD019: -case 0xD219: -case 0xD419: -case 0xD619: -case 0xD819: -case 0xDA19: -case 0xDC19: -case 0xDE19: -case 0xD01A: -case 0xD21A: -case 0xD41A: -case 0xD61A: -case 0xD81A: -case 0xDA1A: -case 0xDC1A: -case 0xDE1A: -case 0xD01B: -case 0xD21B: -case 0xD41B: -case 0xD61B: -case 0xD81B: -case 0xDA1B: -case 0xDC1B: -case 0xDE1B: -case 0xD01C: -case 0xD21C: -case 0xD41C: -case 0xD61C: -case 0xD81C: -case 0xDA1C: -case 0xDC1C: -case 0xDE1C: -case 0xD01D: -case 0xD21D: -case 0xD41D: -case 0xD61D: -case 0xD81D: -case 0xDA1D: -case 0xDC1D: -case 0xDE1D: -case 0xD01E: -case 0xD21E: -case 0xD41E: -case 0xD61E: -case 0xD81E: -case 0xDA1E: -case 0xDC1E: -case 0xDE1E: - -// ADDaD -case 0xD018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD220: -case 0xD420: -case 0xD620: -case 0xD820: -case 0xDA20: -case 0xDC20: -case 0xDE20: -case 0xD021: -case 0xD221: -case 0xD421: -case 0xD621: -case 0xD821: -case 0xDA21: -case 0xDC21: -case 0xDE21: -case 0xD022: -case 0xD222: -case 0xD422: -case 0xD622: -case 0xD822: -case 0xDA22: -case 0xDC22: -case 0xDE22: -case 0xD023: -case 0xD223: -case 0xD423: -case 0xD623: -case 0xD823: -case 0xDA23: -case 0xDC23: -case 0xDE23: -case 0xD024: -case 0xD224: -case 0xD424: -case 0xD624: -case 0xD824: -case 0xDA24: -case 0xDC24: -case 0xDE24: -case 0xD025: -case 0xD225: -case 0xD425: -case 0xD625: -case 0xD825: -case 0xDA25: -case 0xDC25: -case 0xDE25: -case 0xD026: -case 0xD226: -case 0xD426: -case 0xD626: -case 0xD826: -case 0xDA26: -case 0xDC26: -case 0xDE26: - -// ADDaD -case 0xD020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD228: -case 0xD428: -case 0xD628: -case 0xD828: -case 0xDA28: -case 0xDC28: -case 0xDE28: -case 0xD029: -case 0xD229: -case 0xD429: -case 0xD629: -case 0xD829: -case 0xDA29: -case 0xDC29: -case 0xDE29: -case 0xD02A: -case 0xD22A: -case 0xD42A: -case 0xD62A: -case 0xD82A: -case 0xDA2A: -case 0xDC2A: -case 0xDE2A: -case 0xD02B: -case 0xD22B: -case 0xD42B: -case 0xD62B: -case 0xD82B: -case 0xDA2B: -case 0xDC2B: -case 0xDE2B: -case 0xD02C: -case 0xD22C: -case 0xD42C: -case 0xD62C: -case 0xD82C: -case 0xDA2C: -case 0xDC2C: -case 0xDE2C: -case 0xD02D: -case 0xD22D: -case 0xD42D: -case 0xD62D: -case 0xD82D: -case 0xDA2D: -case 0xDC2D: -case 0xDE2D: -case 0xD02E: -case 0xD22E: -case 0xD42E: -case 0xD62E: -case 0xD82E: -case 0xDA2E: -case 0xDC2E: -case 0xDE2E: -case 0xD02F: -case 0xD22F: -case 0xD42F: -case 0xD62F: -case 0xD82F: -case 0xDA2F: -case 0xDC2F: -case 0xDE2F: - -// ADDaD -case 0xD028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD230: -case 0xD430: -case 0xD630: -case 0xD830: -case 0xDA30: -case 0xDC30: -case 0xDE30: -case 0xD031: -case 0xD231: -case 0xD431: -case 0xD631: -case 0xD831: -case 0xDA31: -case 0xDC31: -case 0xDE31: -case 0xD032: -case 0xD232: -case 0xD432: -case 0xD632: -case 0xD832: -case 0xDA32: -case 0xDC32: -case 0xDE32: -case 0xD033: -case 0xD233: -case 0xD433: -case 0xD633: -case 0xD833: -case 0xDA33: -case 0xDC33: -case 0xDE33: -case 0xD034: -case 0xD234: -case 0xD434: -case 0xD634: -case 0xD834: -case 0xDA34: -case 0xDC34: -case 0xDE34: -case 0xD035: -case 0xD235: -case 0xD435: -case 0xD635: -case 0xD835: -case 0xDA35: -case 0xDC35: -case 0xDE35: -case 0xD036: -case 0xD236: -case 0xD436: -case 0xD636: -case 0xD836: -case 0xDA36: -case 0xDC36: -case 0xDE36: -case 0xD037: -case 0xD237: -case 0xD437: -case 0xD637: -case 0xD837: -case 0xDA37: -case 0xDC37: -case 0xDE37: - -// ADDaD -case 0xD030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD238: -case 0xD438: -case 0xD638: -case 0xD838: -case 0xDA38: -case 0xDC38: -case 0xDE38: - -// ADDaD -case 0xD038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD239: -case 0xD439: -case 0xD639: -case 0xD839: -case 0xDA39: -case 0xDC39: -case 0xDE39: - -// ADDaD -case 0xD039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD23A: -case 0xD43A: -case 0xD63A: -case 0xD83A: -case 0xDA3A: -case 0xDC3A: -case 0xDE3A: - -// ADDaD -case 0xD03A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD23B: -case 0xD43B: -case 0xD63B: -case 0xD83B: -case 0xDA3B: -case 0xDC3B: -case 0xDE3B: - -// ADDaD -case 0xD03B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD23C: -case 0xD43C: -case 0xD63C: -case 0xD83C: -case 0xDA3C: -case 0xDC3C: -case 0xDE3C: - -// ADDaD -case 0xD03C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xD21F: -case 0xD41F: -case 0xD61F: -case 0xD81F: -case 0xDA1F: -case 0xDC1F: -case 0xDE1F: - -// ADDaD -case 0xD01F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD227: -case 0xD427: -case 0xD627: -case 0xD827: -case 0xDA27: -case 0xDC27: -case 0xDE27: - -// ADDaD -case 0xD027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD240: -case 0xD440: -case 0xD640: -case 0xD840: -case 0xDA40: -case 0xDC40: -case 0xDE40: -case 0xD041: -case 0xD241: -case 0xD441: -case 0xD641: -case 0xD841: -case 0xDA41: -case 0xDC41: -case 0xDE41: -case 0xD042: -case 0xD242: -case 0xD442: -case 0xD642: -case 0xD842: -case 0xDA42: -case 0xDC42: -case 0xDE42: -case 0xD043: -case 0xD243: -case 0xD443: -case 0xD643: -case 0xD843: -case 0xDA43: -case 0xDC43: -case 0xDE43: -case 0xD044: -case 0xD244: -case 0xD444: -case 0xD644: -case 0xD844: -case 0xDA44: -case 0xDC44: -case 0xDE44: -case 0xD045: -case 0xD245: -case 0xD445: -case 0xD645: -case 0xD845: -case 0xDA45: -case 0xDC45: -case 0xDE45: -case 0xD046: -case 0xD246: -case 0xD446: -case 0xD646: -case 0xD846: -case 0xDA46: -case 0xDC46: -case 0xDE46: -case 0xD047: -case 0xD247: -case 0xD447: -case 0xD647: -case 0xD847: -case 0xDA47: -case 0xDC47: -case 0xDE47: - -// ADDaD -case 0xD040: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD248: -case 0xD448: -case 0xD648: -case 0xD848: -case 0xDA48: -case 0xDC48: -case 0xDE48: -case 0xD049: -case 0xD249: -case 0xD449: -case 0xD649: -case 0xD849: -case 0xDA49: -case 0xDC49: -case 0xDE49: -case 0xD04A: -case 0xD24A: -case 0xD44A: -case 0xD64A: -case 0xD84A: -case 0xDA4A: -case 0xDC4A: -case 0xDE4A: -case 0xD04B: -case 0xD24B: -case 0xD44B: -case 0xD64B: -case 0xD84B: -case 0xDA4B: -case 0xDC4B: -case 0xDE4B: -case 0xD04C: -case 0xD24C: -case 0xD44C: -case 0xD64C: -case 0xD84C: -case 0xDA4C: -case 0xDC4C: -case 0xDE4C: -case 0xD04D: -case 0xD24D: -case 0xD44D: -case 0xD64D: -case 0xD84D: -case 0xDA4D: -case 0xDC4D: -case 0xDE4D: -case 0xD04E: -case 0xD24E: -case 0xD44E: -case 0xD64E: -case 0xD84E: -case 0xDA4E: -case 0xDC4E: -case 0xDE4E: -case 0xD04F: -case 0xD24F: -case 0xD44F: -case 0xD64F: -case 0xD84F: -case 0xDA4F: -case 0xDC4F: -case 0xDE4F: - -// ADDaD -case 0xD048: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->A[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD250: -case 0xD450: -case 0xD650: -case 0xD850: -case 0xDA50: -case 0xDC50: -case 0xDE50: -case 0xD051: -case 0xD251: -case 0xD451: -case 0xD651: -case 0xD851: -case 0xDA51: -case 0xDC51: -case 0xDE51: -case 0xD052: -case 0xD252: -case 0xD452: -case 0xD652: -case 0xD852: -case 0xDA52: -case 0xDC52: -case 0xDE52: -case 0xD053: -case 0xD253: -case 0xD453: -case 0xD653: -case 0xD853: -case 0xDA53: -case 0xDC53: -case 0xDE53: -case 0xD054: -case 0xD254: -case 0xD454: -case 0xD654: -case 0xD854: -case 0xDA54: -case 0xDC54: -case 0xDE54: -case 0xD055: -case 0xD255: -case 0xD455: -case 0xD655: -case 0xD855: -case 0xDA55: -case 0xDC55: -case 0xDE55: -case 0xD056: -case 0xD256: -case 0xD456: -case 0xD656: -case 0xD856: -case 0xDA56: -case 0xDC56: -case 0xDE56: -case 0xD057: -case 0xD257: -case 0xD457: -case 0xD657: -case 0xD857: -case 0xDA57: -case 0xDC57: -case 0xDE57: - -// ADDaD -case 0xD050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD258: -case 0xD458: -case 0xD658: -case 0xD858: -case 0xDA58: -case 0xDC58: -case 0xDE58: -case 0xD059: -case 0xD259: -case 0xD459: -case 0xD659: -case 0xD859: -case 0xDA59: -case 0xDC59: -case 0xDE59: -case 0xD05A: -case 0xD25A: -case 0xD45A: -case 0xD65A: -case 0xD85A: -case 0xDA5A: -case 0xDC5A: -case 0xDE5A: -case 0xD05B: -case 0xD25B: -case 0xD45B: -case 0xD65B: -case 0xD85B: -case 0xDA5B: -case 0xDC5B: -case 0xDE5B: -case 0xD05C: -case 0xD25C: -case 0xD45C: -case 0xD65C: -case 0xD85C: -case 0xDA5C: -case 0xDC5C: -case 0xDE5C: -case 0xD05D: -case 0xD25D: -case 0xD45D: -case 0xD65D: -case 0xD85D: -case 0xDA5D: -case 0xDC5D: -case 0xDE5D: -case 0xD05E: -case 0xD25E: -case 0xD45E: -case 0xD65E: -case 0xD85E: -case 0xDA5E: -case 0xDC5E: -case 0xDE5E: - -// ADDaD -case 0xD058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD260: -case 0xD460: -case 0xD660: -case 0xD860: -case 0xDA60: -case 0xDC60: -case 0xDE60: -case 0xD061: -case 0xD261: -case 0xD461: -case 0xD661: -case 0xD861: -case 0xDA61: -case 0xDC61: -case 0xDE61: -case 0xD062: -case 0xD262: -case 0xD462: -case 0xD662: -case 0xD862: -case 0xDA62: -case 0xDC62: -case 0xDE62: -case 0xD063: -case 0xD263: -case 0xD463: -case 0xD663: -case 0xD863: -case 0xDA63: -case 0xDC63: -case 0xDE63: -case 0xD064: -case 0xD264: -case 0xD464: -case 0xD664: -case 0xD864: -case 0xDA64: -case 0xDC64: -case 0xDE64: -case 0xD065: -case 0xD265: -case 0xD465: -case 0xD665: -case 0xD865: -case 0xDA65: -case 0xDC65: -case 0xDE65: -case 0xD066: -case 0xD266: -case 0xD466: -case 0xD666: -case 0xD866: -case 0xDA66: -case 0xDC66: -case 0xDE66: - -// ADDaD -case 0xD060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD268: -case 0xD468: -case 0xD668: -case 0xD868: -case 0xDA68: -case 0xDC68: -case 0xDE68: -case 0xD069: -case 0xD269: -case 0xD469: -case 0xD669: -case 0xD869: -case 0xDA69: -case 0xDC69: -case 0xDE69: -case 0xD06A: -case 0xD26A: -case 0xD46A: -case 0xD66A: -case 0xD86A: -case 0xDA6A: -case 0xDC6A: -case 0xDE6A: -case 0xD06B: -case 0xD26B: -case 0xD46B: -case 0xD66B: -case 0xD86B: -case 0xDA6B: -case 0xDC6B: -case 0xDE6B: -case 0xD06C: -case 0xD26C: -case 0xD46C: -case 0xD66C: -case 0xD86C: -case 0xDA6C: -case 0xDC6C: -case 0xDE6C: -case 0xD06D: -case 0xD26D: -case 0xD46D: -case 0xD66D: -case 0xD86D: -case 0xDA6D: -case 0xDC6D: -case 0xDE6D: -case 0xD06E: -case 0xD26E: -case 0xD46E: -case 0xD66E: -case 0xD86E: -case 0xDA6E: -case 0xDC6E: -case 0xDE6E: -case 0xD06F: -case 0xD26F: -case 0xD46F: -case 0xD66F: -case 0xD86F: -case 0xDA6F: -case 0xDC6F: -case 0xDE6F: - -// ADDaD -case 0xD068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD270: -case 0xD470: -case 0xD670: -case 0xD870: -case 0xDA70: -case 0xDC70: -case 0xDE70: -case 0xD071: -case 0xD271: -case 0xD471: -case 0xD671: -case 0xD871: -case 0xDA71: -case 0xDC71: -case 0xDE71: -case 0xD072: -case 0xD272: -case 0xD472: -case 0xD672: -case 0xD872: -case 0xDA72: -case 0xDC72: -case 0xDE72: -case 0xD073: -case 0xD273: -case 0xD473: -case 0xD673: -case 0xD873: -case 0xDA73: -case 0xDC73: -case 0xDE73: -case 0xD074: -case 0xD274: -case 0xD474: -case 0xD674: -case 0xD874: -case 0xDA74: -case 0xDC74: -case 0xDE74: -case 0xD075: -case 0xD275: -case 0xD475: -case 0xD675: -case 0xD875: -case 0xDA75: -case 0xDC75: -case 0xDE75: -case 0xD076: -case 0xD276: -case 0xD476: -case 0xD676: -case 0xD876: -case 0xDA76: -case 0xDC76: -case 0xDE76: -case 0xD077: -case 0xD277: -case 0xD477: -case 0xD677: -case 0xD877: -case 0xDA77: -case 0xDC77: -case 0xDE77: - -// ADDaD -case 0xD070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD278: -case 0xD478: -case 0xD678: -case 0xD878: -case 0xDA78: -case 0xDC78: -case 0xDE78: - -// ADDaD -case 0xD078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD279: -case 0xD479: -case 0xD679: -case 0xD879: -case 0xDA79: -case 0xDC79: -case 0xDE79: - -// ADDaD -case 0xD079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD27A: -case 0xD47A: -case 0xD67A: -case 0xD87A: -case 0xDA7A: -case 0xDC7A: -case 0xDE7A: - -// ADDaD -case 0xD07A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD27B: -case 0xD47B: -case 0xD67B: -case 0xD87B: -case 0xDA7B: -case 0xDC7B: -case 0xDE7B: - -// ADDaD -case 0xD07B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD27C: -case 0xD47C: -case 0xD67C: -case 0xD87C: -case 0xDA7C: -case 0xDC7C: -case 0xDE7C: - -// ADDaD -case 0xD07C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xD25F: -case 0xD45F: -case 0xD65F: -case 0xD85F: -case 0xDA5F: -case 0xDC5F: -case 0xDE5F: - -// ADDaD -case 0xD05F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD267: -case 0xD467: -case 0xD667: -case 0xD867: -case 0xDA67: -case 0xDC67: -case 0xDE67: - -// ADDaD -case 0xD067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD280: -case 0xD480: -case 0xD680: -case 0xD880: -case 0xDA80: -case 0xDC80: -case 0xDE80: -case 0xD081: -case 0xD281: -case 0xD481: -case 0xD681: -case 0xD881: -case 0xDA81: -case 0xDC81: -case 0xDE81: -case 0xD082: -case 0xD282: -case 0xD482: -case 0xD682: -case 0xD882: -case 0xDA82: -case 0xDC82: -case 0xDE82: -case 0xD083: -case 0xD283: -case 0xD483: -case 0xD683: -case 0xD883: -case 0xDA83: -case 0xDC83: -case 0xDE83: -case 0xD084: -case 0xD284: -case 0xD484: -case 0xD684: -case 0xD884: -case 0xDA84: -case 0xDC84: -case 0xDE84: -case 0xD085: -case 0xD285: -case 0xD485: -case 0xD685: -case 0xD885: -case 0xDA85: -case 0xDC85: -case 0xDE85: -case 0xD086: -case 0xD286: -case 0xD486: -case 0xD686: -case 0xD886: -case 0xDA86: -case 0xDC86: -case 0xDE86: -case 0xD087: -case 0xD287: -case 0xD487: -case 0xD687: -case 0xD887: -case 0xDA87: -case 0xDC87: -case 0xDE87: - -// ADDaD -case 0xD080: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xD288: -case 0xD488: -case 0xD688: -case 0xD888: -case 0xDA88: -case 0xDC88: -case 0xDE88: -case 0xD089: -case 0xD289: -case 0xD489: -case 0xD689: -case 0xD889: -case 0xDA89: -case 0xDC89: -case 0xDE89: -case 0xD08A: -case 0xD28A: -case 0xD48A: -case 0xD68A: -case 0xD88A: -case 0xDA8A: -case 0xDC8A: -case 0xDE8A: -case 0xD08B: -case 0xD28B: -case 0xD48B: -case 0xD68B: -case 0xD88B: -case 0xDA8B: -case 0xDC8B: -case 0xDE8B: -case 0xD08C: -case 0xD28C: -case 0xD48C: -case 0xD68C: -case 0xD88C: -case 0xDA8C: -case 0xDC8C: -case 0xDE8C: -case 0xD08D: -case 0xD28D: -case 0xD48D: -case 0xD68D: -case 0xD88D: -case 0xDA8D: -case 0xDC8D: -case 0xDE8D: -case 0xD08E: -case 0xD28E: -case 0xD48E: -case 0xD68E: -case 0xD88E: -case 0xDA8E: -case 0xDC8E: -case 0xDE8E: -case 0xD08F: -case 0xD28F: -case 0xD48F: -case 0xD68F: -case 0xD88F: -case 0xDA8F: -case 0xDC8F: -case 0xDE8F: - -// ADDaD -case 0xD088: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xD290: -case 0xD490: -case 0xD690: -case 0xD890: -case 0xDA90: -case 0xDC90: -case 0xDE90: -case 0xD091: -case 0xD291: -case 0xD491: -case 0xD691: -case 0xD891: -case 0xDA91: -case 0xDC91: -case 0xDE91: -case 0xD092: -case 0xD292: -case 0xD492: -case 0xD692: -case 0xD892: -case 0xDA92: -case 0xDC92: -case 0xDE92: -case 0xD093: -case 0xD293: -case 0xD493: -case 0xD693: -case 0xD893: -case 0xDA93: -case 0xDC93: -case 0xDE93: -case 0xD094: -case 0xD294: -case 0xD494: -case 0xD694: -case 0xD894: -case 0xDA94: -case 0xDC94: -case 0xDE94: -case 0xD095: -case 0xD295: -case 0xD495: -case 0xD695: -case 0xD895: -case 0xDA95: -case 0xDC95: -case 0xDE95: -case 0xD096: -case 0xD296: -case 0xD496: -case 0xD696: -case 0xD896: -case 0xDA96: -case 0xDC96: -case 0xDE96: -case 0xD097: -case 0xD297: -case 0xD497: -case 0xD697: -case 0xD897: -case 0xDA97: -case 0xDC97: -case 0xDE97: - -// ADDaD -case 0xD090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD298: -case 0xD498: -case 0xD698: -case 0xD898: -case 0xDA98: -case 0xDC98: -case 0xDE98: -case 0xD099: -case 0xD299: -case 0xD499: -case 0xD699: -case 0xD899: -case 0xDA99: -case 0xDC99: -case 0xDE99: -case 0xD09A: -case 0xD29A: -case 0xD49A: -case 0xD69A: -case 0xD89A: -case 0xDA9A: -case 0xDC9A: -case 0xDE9A: -case 0xD09B: -case 0xD29B: -case 0xD49B: -case 0xD69B: -case 0xD89B: -case 0xDA9B: -case 0xDC9B: -case 0xDE9B: -case 0xD09C: -case 0xD29C: -case 0xD49C: -case 0xD69C: -case 0xD89C: -case 0xDA9C: -case 0xDC9C: -case 0xDE9C: -case 0xD09D: -case 0xD29D: -case 0xD49D: -case 0xD69D: -case 0xD89D: -case 0xDA9D: -case 0xDC9D: -case 0xDE9D: -case 0xD09E: -case 0xD29E: -case 0xD49E: -case 0xD69E: -case 0xD89E: -case 0xDA9E: -case 0xDC9E: -case 0xDE9E: - -// ADDaD -case 0xD098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD2A0: -case 0xD4A0: -case 0xD6A0: -case 0xD8A0: -case 0xDAA0: -case 0xDCA0: -case 0xDEA0: -case 0xD0A1: -case 0xD2A1: -case 0xD4A1: -case 0xD6A1: -case 0xD8A1: -case 0xDAA1: -case 0xDCA1: -case 0xDEA1: -case 0xD0A2: -case 0xD2A2: -case 0xD4A2: -case 0xD6A2: -case 0xD8A2: -case 0xDAA2: -case 0xDCA2: -case 0xDEA2: -case 0xD0A3: -case 0xD2A3: -case 0xD4A3: -case 0xD6A3: -case 0xD8A3: -case 0xDAA3: -case 0xDCA3: -case 0xDEA3: -case 0xD0A4: -case 0xD2A4: -case 0xD4A4: -case 0xD6A4: -case 0xD8A4: -case 0xDAA4: -case 0xDCA4: -case 0xDEA4: -case 0xD0A5: -case 0xD2A5: -case 0xD4A5: -case 0xD6A5: -case 0xD8A5: -case 0xDAA5: -case 0xDCA5: -case 0xDEA5: -case 0xD0A6: -case 0xD2A6: -case 0xD4A6: -case 0xD6A6: -case 0xD8A6: -case 0xDAA6: -case 0xDCA6: -case 0xDEA6: - -// ADDaD -case 0xD0A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xD2A8: -case 0xD4A8: -case 0xD6A8: -case 0xD8A8: -case 0xDAA8: -case 0xDCA8: -case 0xDEA8: -case 0xD0A9: -case 0xD2A9: -case 0xD4A9: -case 0xD6A9: -case 0xD8A9: -case 0xDAA9: -case 0xDCA9: -case 0xDEA9: -case 0xD0AA: -case 0xD2AA: -case 0xD4AA: -case 0xD6AA: -case 0xD8AA: -case 0xDAAA: -case 0xDCAA: -case 0xDEAA: -case 0xD0AB: -case 0xD2AB: -case 0xD4AB: -case 0xD6AB: -case 0xD8AB: -case 0xDAAB: -case 0xDCAB: -case 0xDEAB: -case 0xD0AC: -case 0xD2AC: -case 0xD4AC: -case 0xD6AC: -case 0xD8AC: -case 0xDAAC: -case 0xDCAC: -case 0xDEAC: -case 0xD0AD: -case 0xD2AD: -case 0xD4AD: -case 0xD6AD: -case 0xD8AD: -case 0xDAAD: -case 0xDCAD: -case 0xDEAD: -case 0xD0AE: -case 0xD2AE: -case 0xD4AE: -case 0xD6AE: -case 0xD8AE: -case 0xDAAE: -case 0xDCAE: -case 0xDEAE: -case 0xD0AF: -case 0xD2AF: -case 0xD4AF: -case 0xD6AF: -case 0xD8AF: -case 0xDAAF: -case 0xDCAF: -case 0xDEAF: - -// ADDaD -case 0xD0A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xD2B0: -case 0xD4B0: -case 0xD6B0: -case 0xD8B0: -case 0xDAB0: -case 0xDCB0: -case 0xDEB0: -case 0xD0B1: -case 0xD2B1: -case 0xD4B1: -case 0xD6B1: -case 0xD8B1: -case 0xDAB1: -case 0xDCB1: -case 0xDEB1: -case 0xD0B2: -case 0xD2B2: -case 0xD4B2: -case 0xD6B2: -case 0xD8B2: -case 0xDAB2: -case 0xDCB2: -case 0xDEB2: -case 0xD0B3: -case 0xD2B3: -case 0xD4B3: -case 0xD6B3: -case 0xD8B3: -case 0xDAB3: -case 0xDCB3: -case 0xDEB3: -case 0xD0B4: -case 0xD2B4: -case 0xD4B4: -case 0xD6B4: -case 0xD8B4: -case 0xDAB4: -case 0xDCB4: -case 0xDEB4: -case 0xD0B5: -case 0xD2B5: -case 0xD4B5: -case 0xD6B5: -case 0xD8B5: -case 0xDAB5: -case 0xDCB5: -case 0xDEB5: -case 0xD0B6: -case 0xD2B6: -case 0xD4B6: -case 0xD6B6: -case 0xD8B6: -case 0xDAB6: -case 0xDCB6: -case 0xDEB6: -case 0xD0B7: -case 0xD2B7: -case 0xD4B7: -case 0xD6B7: -case 0xD8B7: -case 0xDAB7: -case 0xDCB7: -case 0xDEB7: - -// ADDaD -case 0xD0B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xD2B8: -case 0xD4B8: -case 0xD6B8: -case 0xD8B8: -case 0xDAB8: -case 0xDCB8: -case 0xDEB8: - -// ADDaD -case 0xD0B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xD2B9: -case 0xD4B9: -case 0xD6B9: -case 0xD8B9: -case 0xDAB9: -case 0xDCB9: -case 0xDEB9: - -// ADDaD -case 0xD0B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0xD2BA: -case 0xD4BA: -case 0xD6BA: -case 0xD8BA: -case 0xDABA: -case 0xDCBA: -case 0xDEBA: - -// ADDaD -case 0xD0BA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xD2BB: -case 0xD4BB: -case 0xD6BB: -case 0xD8BB: -case 0xDABB: -case 0xDCBB: -case 0xDEBB: - -// ADDaD -case 0xD0BB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xD2BC: -case 0xD4BC: -case 0xD6BC: -case 0xD8BC: -case 0xDABC: -case 0xDCBC: -case 0xDEBC: - -// ADDaD -case 0xD0BC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0xD29F: -case 0xD49F: -case 0xD69F: -case 0xD89F: -case 0xDA9F: -case 0xDC9F: -case 0xDE9F: - -// ADDaD -case 0xD09F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD2A7: -case 0xD4A7: -case 0xD6A7: -case 0xD8A7: -case 0xDAA7: -case 0xDCA7: -case 0xDEA7: - -// ADDaD -case 0xD0A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xD310: -case 0xD510: -case 0xD710: -case 0xD910: -case 0xDB10: -case 0xDD10: -case 0xDF10: -case 0xD111: -case 0xD311: -case 0xD511: -case 0xD711: -case 0xD911: -case 0xDB11: -case 0xDD11: -case 0xDF11: -case 0xD112: -case 0xD312: -case 0xD512: -case 0xD712: -case 0xD912: -case 0xDB12: -case 0xDD12: -case 0xDF12: -case 0xD113: -case 0xD313: -case 0xD513: -case 0xD713: -case 0xD913: -case 0xDB13: -case 0xDD13: -case 0xDF13: -case 0xD114: -case 0xD314: -case 0xD514: -case 0xD714: -case 0xD914: -case 0xDB14: -case 0xDD14: -case 0xDF14: -case 0xD115: -case 0xD315: -case 0xD515: -case 0xD715: -case 0xD915: -case 0xDB15: -case 0xDD15: -case 0xDF15: -case 0xD116: -case 0xD316: -case 0xD516: -case 0xD716: -case 0xD916: -case 0xDB16: -case 0xDD16: -case 0xDF16: -case 0xD117: -case 0xD317: -case 0xD517: -case 0xD717: -case 0xD917: -case 0xDB17: -case 0xDD17: -case 0xDF17: - -// ADDDa -case 0xD110: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xD318: -case 0xD518: -case 0xD718: -case 0xD918: -case 0xDB18: -case 0xDD18: -case 0xDF18: -case 0xD119: -case 0xD319: -case 0xD519: -case 0xD719: -case 0xD919: -case 0xDB19: -case 0xDD19: -case 0xDF19: -case 0xD11A: -case 0xD31A: -case 0xD51A: -case 0xD71A: -case 0xD91A: -case 0xDB1A: -case 0xDD1A: -case 0xDF1A: -case 0xD11B: -case 0xD31B: -case 0xD51B: -case 0xD71B: -case 0xD91B: -case 0xDB1B: -case 0xDD1B: -case 0xDF1B: -case 0xD11C: -case 0xD31C: -case 0xD51C: -case 0xD71C: -case 0xD91C: -case 0xDB1C: -case 0xDD1C: -case 0xDF1C: -case 0xD11D: -case 0xD31D: -case 0xD51D: -case 0xD71D: -case 0xD91D: -case 0xDB1D: -case 0xDD1D: -case 0xDF1D: -case 0xD11E: -case 0xD31E: -case 0xD51E: -case 0xD71E: -case 0xD91E: -case 0xDB1E: -case 0xDD1E: -case 0xDF1E: - -// ADDDa -case 0xD118: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xD320: -case 0xD520: -case 0xD720: -case 0xD920: -case 0xDB20: -case 0xDD20: -case 0xDF20: -case 0xD121: -case 0xD321: -case 0xD521: -case 0xD721: -case 0xD921: -case 0xDB21: -case 0xDD21: -case 0xDF21: -case 0xD122: -case 0xD322: -case 0xD522: -case 0xD722: -case 0xD922: -case 0xDB22: -case 0xDD22: -case 0xDF22: -case 0xD123: -case 0xD323: -case 0xD523: -case 0xD723: -case 0xD923: -case 0xDB23: -case 0xDD23: -case 0xDF23: -case 0xD124: -case 0xD324: -case 0xD524: -case 0xD724: -case 0xD924: -case 0xDB24: -case 0xDD24: -case 0xDF24: -case 0xD125: -case 0xD325: -case 0xD525: -case 0xD725: -case 0xD925: -case 0xDB25: -case 0xDD25: -case 0xDF25: -case 0xD126: -case 0xD326: -case 0xD526: -case 0xD726: -case 0xD926: -case 0xDB26: -case 0xDD26: -case 0xDF26: - -// ADDDa -case 0xD120: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xD328: -case 0xD528: -case 0xD728: -case 0xD928: -case 0xDB28: -case 0xDD28: -case 0xDF28: -case 0xD129: -case 0xD329: -case 0xD529: -case 0xD729: -case 0xD929: -case 0xDB29: -case 0xDD29: -case 0xDF29: -case 0xD12A: -case 0xD32A: -case 0xD52A: -case 0xD72A: -case 0xD92A: -case 0xDB2A: -case 0xDD2A: -case 0xDF2A: -case 0xD12B: -case 0xD32B: -case 0xD52B: -case 0xD72B: -case 0xD92B: -case 0xDB2B: -case 0xDD2B: -case 0xDF2B: -case 0xD12C: -case 0xD32C: -case 0xD52C: -case 0xD72C: -case 0xD92C: -case 0xDB2C: -case 0xDD2C: -case 0xDF2C: -case 0xD12D: -case 0xD32D: -case 0xD52D: -case 0xD72D: -case 0xD92D: -case 0xDB2D: -case 0xDD2D: -case 0xDF2D: -case 0xD12E: -case 0xD32E: -case 0xD52E: -case 0xD72E: -case 0xD92E: -case 0xDB2E: -case 0xDD2E: -case 0xDF2E: -case 0xD12F: -case 0xD32F: -case 0xD52F: -case 0xD72F: -case 0xD92F: -case 0xDB2F: -case 0xDD2F: -case 0xDF2F: - -// ADDDa -case 0xD128: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xD330: -case 0xD530: -case 0xD730: -case 0xD930: -case 0xDB30: -case 0xDD30: -case 0xDF30: -case 0xD131: -case 0xD331: -case 0xD531: -case 0xD731: -case 0xD931: -case 0xDB31: -case 0xDD31: -case 0xDF31: -case 0xD132: -case 0xD332: -case 0xD532: -case 0xD732: -case 0xD932: -case 0xDB32: -case 0xDD32: -case 0xDF32: -case 0xD133: -case 0xD333: -case 0xD533: -case 0xD733: -case 0xD933: -case 0xDB33: -case 0xDD33: -case 0xDF33: -case 0xD134: -case 0xD334: -case 0xD534: -case 0xD734: -case 0xD934: -case 0xDB34: -case 0xDD34: -case 0xDF34: -case 0xD135: -case 0xD335: -case 0xD535: -case 0xD735: -case 0xD935: -case 0xDB35: -case 0xDD35: -case 0xDF35: -case 0xD136: -case 0xD336: -case 0xD536: -case 0xD736: -case 0xD936: -case 0xDB36: -case 0xDD36: -case 0xDF36: -case 0xD137: -case 0xD337: -case 0xD537: -case 0xD737: -case 0xD937: -case 0xDB37: -case 0xDD37: -case 0xDF37: - -// ADDDa -case 0xD130: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xD338: -case 0xD538: -case 0xD738: -case 0xD938: -case 0xDB38: -case 0xDD38: -case 0xDF38: - -// ADDDa -case 0xD138: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xD339: -case 0xD539: -case 0xD739: -case 0xD939: -case 0xDB39: -case 0xDD39: -case 0xDF39: - -// ADDDa -case 0xD139: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0xD31F: -case 0xD51F: -case 0xD71F: -case 0xD91F: -case 0xDB1F: -case 0xDD1F: -case 0xDF1F: - -// ADDDa -case 0xD11F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xD327: -case 0xD527: -case 0xD727: -case 0xD927: -case 0xDB27: -case 0xDD27: -case 0xDF27: - -// ADDDa -case 0xD127: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xD350: -case 0xD550: -case 0xD750: -case 0xD950: -case 0xDB50: -case 0xDD50: -case 0xDF50: -case 0xD151: -case 0xD351: -case 0xD551: -case 0xD751: -case 0xD951: -case 0xDB51: -case 0xDD51: -case 0xDF51: -case 0xD152: -case 0xD352: -case 0xD552: -case 0xD752: -case 0xD952: -case 0xDB52: -case 0xDD52: -case 0xDF52: -case 0xD153: -case 0xD353: -case 0xD553: -case 0xD753: -case 0xD953: -case 0xDB53: -case 0xDD53: -case 0xDF53: -case 0xD154: -case 0xD354: -case 0xD554: -case 0xD754: -case 0xD954: -case 0xDB54: -case 0xDD54: -case 0xDF54: -case 0xD155: -case 0xD355: -case 0xD555: -case 0xD755: -case 0xD955: -case 0xDB55: -case 0xDD55: -case 0xDF55: -case 0xD156: -case 0xD356: -case 0xD556: -case 0xD756: -case 0xD956: -case 0xDB56: -case 0xDD56: -case 0xDF56: -case 0xD157: -case 0xD357: -case 0xD557: -case 0xD757: -case 0xD957: -case 0xDB57: -case 0xDD57: -case 0xDF57: - -// ADDDa -case 0xD150: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xD358: -case 0xD558: -case 0xD758: -case 0xD958: -case 0xDB58: -case 0xDD58: -case 0xDF58: -case 0xD159: -case 0xD359: -case 0xD559: -case 0xD759: -case 0xD959: -case 0xDB59: -case 0xDD59: -case 0xDF59: -case 0xD15A: -case 0xD35A: -case 0xD55A: -case 0xD75A: -case 0xD95A: -case 0xDB5A: -case 0xDD5A: -case 0xDF5A: -case 0xD15B: -case 0xD35B: -case 0xD55B: -case 0xD75B: -case 0xD95B: -case 0xDB5B: -case 0xDD5B: -case 0xDF5B: -case 0xD15C: -case 0xD35C: -case 0xD55C: -case 0xD75C: -case 0xD95C: -case 0xDB5C: -case 0xDD5C: -case 0xDF5C: -case 0xD15D: -case 0xD35D: -case 0xD55D: -case 0xD75D: -case 0xD95D: -case 0xDB5D: -case 0xDD5D: -case 0xDF5D: -case 0xD15E: -case 0xD35E: -case 0xD55E: -case 0xD75E: -case 0xD95E: -case 0xDB5E: -case 0xDD5E: -case 0xDF5E: - -// ADDDa -case 0xD158: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xD360: -case 0xD560: -case 0xD760: -case 0xD960: -case 0xDB60: -case 0xDD60: -case 0xDF60: -case 0xD161: -case 0xD361: -case 0xD561: -case 0xD761: -case 0xD961: -case 0xDB61: -case 0xDD61: -case 0xDF61: -case 0xD162: -case 0xD362: -case 0xD562: -case 0xD762: -case 0xD962: -case 0xDB62: -case 0xDD62: -case 0xDF62: -case 0xD163: -case 0xD363: -case 0xD563: -case 0xD763: -case 0xD963: -case 0xDB63: -case 0xDD63: -case 0xDF63: -case 0xD164: -case 0xD364: -case 0xD564: -case 0xD764: -case 0xD964: -case 0xDB64: -case 0xDD64: -case 0xDF64: -case 0xD165: -case 0xD365: -case 0xD565: -case 0xD765: -case 0xD965: -case 0xDB65: -case 0xDD65: -case 0xDF65: -case 0xD166: -case 0xD366: -case 0xD566: -case 0xD766: -case 0xD966: -case 0xDB66: -case 0xDD66: -case 0xDF66: - -// ADDDa -case 0xD160: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xD368: -case 0xD568: -case 0xD768: -case 0xD968: -case 0xDB68: -case 0xDD68: -case 0xDF68: -case 0xD169: -case 0xD369: -case 0xD569: -case 0xD769: -case 0xD969: -case 0xDB69: -case 0xDD69: -case 0xDF69: -case 0xD16A: -case 0xD36A: -case 0xD56A: -case 0xD76A: -case 0xD96A: -case 0xDB6A: -case 0xDD6A: -case 0xDF6A: -case 0xD16B: -case 0xD36B: -case 0xD56B: -case 0xD76B: -case 0xD96B: -case 0xDB6B: -case 0xDD6B: -case 0xDF6B: -case 0xD16C: -case 0xD36C: -case 0xD56C: -case 0xD76C: -case 0xD96C: -case 0xDB6C: -case 0xDD6C: -case 0xDF6C: -case 0xD16D: -case 0xD36D: -case 0xD56D: -case 0xD76D: -case 0xD96D: -case 0xDB6D: -case 0xDD6D: -case 0xDF6D: -case 0xD16E: -case 0xD36E: -case 0xD56E: -case 0xD76E: -case 0xD96E: -case 0xDB6E: -case 0xDD6E: -case 0xDF6E: -case 0xD16F: -case 0xD36F: -case 0xD56F: -case 0xD76F: -case 0xD96F: -case 0xDB6F: -case 0xDD6F: -case 0xDF6F: - -// ADDDa -case 0xD168: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xD370: -case 0xD570: -case 0xD770: -case 0xD970: -case 0xDB70: -case 0xDD70: -case 0xDF70: -case 0xD171: -case 0xD371: -case 0xD571: -case 0xD771: -case 0xD971: -case 0xDB71: -case 0xDD71: -case 0xDF71: -case 0xD172: -case 0xD372: -case 0xD572: -case 0xD772: -case 0xD972: -case 0xDB72: -case 0xDD72: -case 0xDF72: -case 0xD173: -case 0xD373: -case 0xD573: -case 0xD773: -case 0xD973: -case 0xDB73: -case 0xDD73: -case 0xDF73: -case 0xD174: -case 0xD374: -case 0xD574: -case 0xD774: -case 0xD974: -case 0xDB74: -case 0xDD74: -case 0xDF74: -case 0xD175: -case 0xD375: -case 0xD575: -case 0xD775: -case 0xD975: -case 0xDB75: -case 0xDD75: -case 0xDF75: -case 0xD176: -case 0xD376: -case 0xD576: -case 0xD776: -case 0xD976: -case 0xDB76: -case 0xDD76: -case 0xDF76: -case 0xD177: -case 0xD377: -case 0xD577: -case 0xD777: -case 0xD977: -case 0xDB77: -case 0xDD77: -case 0xDF77: - -// ADDDa -case 0xD170: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xD378: -case 0xD578: -case 0xD778: -case 0xD978: -case 0xDB78: -case 0xDD78: -case 0xDF78: - -// ADDDa -case 0xD178: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xD379: -case 0xD579: -case 0xD779: -case 0xD979: -case 0xDB79: -case 0xDD79: -case 0xDF79: - -// ADDDa -case 0xD179: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0xD35F: -case 0xD55F: -case 0xD75F: -case 0xD95F: -case 0xDB5F: -case 0xDD5F: -case 0xDF5F: - -// ADDDa -case 0xD15F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xD367: -case 0xD567: -case 0xD767: -case 0xD967: -case 0xDB67: -case 0xDD67: -case 0xDF67: - -// ADDDa -case 0xD167: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xD390: -case 0xD590: -case 0xD790: -case 0xD990: -case 0xDB90: -case 0xDD90: -case 0xDF90: -case 0xD191: -case 0xD391: -case 0xD591: -case 0xD791: -case 0xD991: -case 0xDB91: -case 0xDD91: -case 0xDF91: -case 0xD192: -case 0xD392: -case 0xD592: -case 0xD792: -case 0xD992: -case 0xDB92: -case 0xDD92: -case 0xDF92: -case 0xD193: -case 0xD393: -case 0xD593: -case 0xD793: -case 0xD993: -case 0xDB93: -case 0xDD93: -case 0xDF93: -case 0xD194: -case 0xD394: -case 0xD594: -case 0xD794: -case 0xD994: -case 0xDB94: -case 0xDD94: -case 0xDF94: -case 0xD195: -case 0xD395: -case 0xD595: -case 0xD795: -case 0xD995: -case 0xDB95: -case 0xDD95: -case 0xDF95: -case 0xD196: -case 0xD396: -case 0xD596: -case 0xD796: -case 0xD996: -case 0xDB96: -case 0xDD96: -case 0xDF96: -case 0xD197: -case 0xD397: -case 0xD597: -case 0xD797: -case 0xD997: -case 0xDB97: -case 0xDD97: -case 0xDF97: - -// ADDDa -case 0xD190: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xD398: -case 0xD598: -case 0xD798: -case 0xD998: -case 0xDB98: -case 0xDD98: -case 0xDF98: -case 0xD199: -case 0xD399: -case 0xD599: -case 0xD799: -case 0xD999: -case 0xDB99: -case 0xDD99: -case 0xDF99: -case 0xD19A: -case 0xD39A: -case 0xD59A: -case 0xD79A: -case 0xD99A: -case 0xDB9A: -case 0xDD9A: -case 0xDF9A: -case 0xD19B: -case 0xD39B: -case 0xD59B: -case 0xD79B: -case 0xD99B: -case 0xDB9B: -case 0xDD9B: -case 0xDF9B: -case 0xD19C: -case 0xD39C: -case 0xD59C: -case 0xD79C: -case 0xD99C: -case 0xDB9C: -case 0xDD9C: -case 0xDF9C: -case 0xD19D: -case 0xD39D: -case 0xD59D: -case 0xD79D: -case 0xD99D: -case 0xDB9D: -case 0xDD9D: -case 0xDF9D: -case 0xD19E: -case 0xD39E: -case 0xD59E: -case 0xD79E: -case 0xD99E: -case 0xDB9E: -case 0xDD9E: -case 0xDF9E: - -// ADDDa -case 0xD198: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xD3A0: -case 0xD5A0: -case 0xD7A0: -case 0xD9A0: -case 0xDBA0: -case 0xDDA0: -case 0xDFA0: -case 0xD1A1: -case 0xD3A1: -case 0xD5A1: -case 0xD7A1: -case 0xD9A1: -case 0xDBA1: -case 0xDDA1: -case 0xDFA1: -case 0xD1A2: -case 0xD3A2: -case 0xD5A2: -case 0xD7A2: -case 0xD9A2: -case 0xDBA2: -case 0xDDA2: -case 0xDFA2: -case 0xD1A3: -case 0xD3A3: -case 0xD5A3: -case 0xD7A3: -case 0xD9A3: -case 0xDBA3: -case 0xDDA3: -case 0xDFA3: -case 0xD1A4: -case 0xD3A4: -case 0xD5A4: -case 0xD7A4: -case 0xD9A4: -case 0xDBA4: -case 0xDDA4: -case 0xDFA4: -case 0xD1A5: -case 0xD3A5: -case 0xD5A5: -case 0xD7A5: -case 0xD9A5: -case 0xDBA5: -case 0xDDA5: -case 0xDFA5: -case 0xD1A6: -case 0xD3A6: -case 0xD5A6: -case 0xD7A6: -case 0xD9A6: -case 0xDBA6: -case 0xDDA6: -case 0xDFA6: - -// ADDDa -case 0xD1A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xD3A8: -case 0xD5A8: -case 0xD7A8: -case 0xD9A8: -case 0xDBA8: -case 0xDDA8: -case 0xDFA8: -case 0xD1A9: -case 0xD3A9: -case 0xD5A9: -case 0xD7A9: -case 0xD9A9: -case 0xDBA9: -case 0xDDA9: -case 0xDFA9: -case 0xD1AA: -case 0xD3AA: -case 0xD5AA: -case 0xD7AA: -case 0xD9AA: -case 0xDBAA: -case 0xDDAA: -case 0xDFAA: -case 0xD1AB: -case 0xD3AB: -case 0xD5AB: -case 0xD7AB: -case 0xD9AB: -case 0xDBAB: -case 0xDDAB: -case 0xDFAB: -case 0xD1AC: -case 0xD3AC: -case 0xD5AC: -case 0xD7AC: -case 0xD9AC: -case 0xDBAC: -case 0xDDAC: -case 0xDFAC: -case 0xD1AD: -case 0xD3AD: -case 0xD5AD: -case 0xD7AD: -case 0xD9AD: -case 0xDBAD: -case 0xDDAD: -case 0xDFAD: -case 0xD1AE: -case 0xD3AE: -case 0xD5AE: -case 0xD7AE: -case 0xD9AE: -case 0xDBAE: -case 0xDDAE: -case 0xDFAE: -case 0xD1AF: -case 0xD3AF: -case 0xD5AF: -case 0xD7AF: -case 0xD9AF: -case 0xDBAF: -case 0xDDAF: -case 0xDFAF: - -// ADDDa -case 0xD1A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xD3B0: -case 0xD5B0: -case 0xD7B0: -case 0xD9B0: -case 0xDBB0: -case 0xDDB0: -case 0xDFB0: -case 0xD1B1: -case 0xD3B1: -case 0xD5B1: -case 0xD7B1: -case 0xD9B1: -case 0xDBB1: -case 0xDDB1: -case 0xDFB1: -case 0xD1B2: -case 0xD3B2: -case 0xD5B2: -case 0xD7B2: -case 0xD9B2: -case 0xDBB2: -case 0xDDB2: -case 0xDFB2: -case 0xD1B3: -case 0xD3B3: -case 0xD5B3: -case 0xD7B3: -case 0xD9B3: -case 0xDBB3: -case 0xDDB3: -case 0xDFB3: -case 0xD1B4: -case 0xD3B4: -case 0xD5B4: -case 0xD7B4: -case 0xD9B4: -case 0xDBB4: -case 0xDDB4: -case 0xDFB4: -case 0xD1B5: -case 0xD3B5: -case 0xD5B5: -case 0xD7B5: -case 0xD9B5: -case 0xDBB5: -case 0xDDB5: -case 0xDFB5: -case 0xD1B6: -case 0xD3B6: -case 0xD5B6: -case 0xD7B6: -case 0xD9B6: -case 0xDBB6: -case 0xDDB6: -case 0xDFB6: -case 0xD1B7: -case 0xD3B7: -case 0xD5B7: -case 0xD7B7: -case 0xD9B7: -case 0xDBB7: -case 0xDDB7: -case 0xDFB7: - -// ADDDa -case 0xD1B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0xD3B8: -case 0xD5B8: -case 0xD7B8: -case 0xD9B8: -case 0xDBB8: -case 0xDDB8: -case 0xDFB8: - -// ADDDa -case 0xD1B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xD3B9: -case 0xD5B9: -case 0xD7B9: -case 0xD9B9: -case 0xDBB9: -case 0xDDB9: -case 0xDFB9: - -// ADDDa -case 0xD1B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0xD39F: -case 0xD59F: -case 0xD79F: -case 0xD99F: -case 0xDB9F: -case 0xDD9F: -case 0xDF9F: - -// ADDDa -case 0xD19F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xD3A7: -case 0xD5A7: -case 0xD7A7: -case 0xD9A7: -case 0xDBA7: -case 0xDDA7: -case 0xDFA7: - -// ADDDa -case 0xD1A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xD300: -case 0xD500: -case 0xD700: -case 0xD900: -case 0xDB00: -case 0xDD00: -case 0xDF00: -case 0xD101: -case 0xD301: -case 0xD501: -case 0xD701: -case 0xD901: -case 0xDB01: -case 0xDD01: -case 0xDF01: -case 0xD102: -case 0xD302: -case 0xD502: -case 0xD702: -case 0xD902: -case 0xDB02: -case 0xDD02: -case 0xDF02: -case 0xD103: -case 0xD303: -case 0xD503: -case 0xD703: -case 0xD903: -case 0xDB03: -case 0xDD03: -case 0xDF03: -case 0xD104: -case 0xD304: -case 0xD504: -case 0xD704: -case 0xD904: -case 0xDB04: -case 0xDD04: -case 0xDF04: -case 0xD105: -case 0xD305: -case 0xD505: -case 0xD705: -case 0xD905: -case 0xDB05: -case 0xDD05: -case 0xDF05: -case 0xD106: -case 0xD306: -case 0xD506: -case 0xD706: -case 0xD906: -case 0xDB06: -case 0xDD06: -case 0xDF06: -case 0xD107: -case 0xD307: -case 0xD507: -case 0xD707: -case 0xD907: -case 0xDB07: -case 0xDD07: -case 0xDF07: - -// ADDX -case 0xD100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD340: -case 0xD540: -case 0xD740: -case 0xD940: -case 0xDB40: -case 0xDD40: -case 0xDF40: -case 0xD141: -case 0xD341: -case 0xD541: -case 0xD741: -case 0xD941: -case 0xDB41: -case 0xDD41: -case 0xDF41: -case 0xD142: -case 0xD342: -case 0xD542: -case 0xD742: -case 0xD942: -case 0xDB42: -case 0xDD42: -case 0xDF42: -case 0xD143: -case 0xD343: -case 0xD543: -case 0xD743: -case 0xD943: -case 0xDB43: -case 0xDD43: -case 0xDF43: -case 0xD144: -case 0xD344: -case 0xD544: -case 0xD744: -case 0xD944: -case 0xDB44: -case 0xDD44: -case 0xDF44: -case 0xD145: -case 0xD345: -case 0xD545: -case 0xD745: -case 0xD945: -case 0xDB45: -case 0xDD45: -case 0xDF45: -case 0xD146: -case 0xD346: -case 0xD546: -case 0xD746: -case 0xD946: -case 0xDB46: -case 0xDD46: -case 0xDF46: -case 0xD147: -case 0xD347: -case 0xD547: -case 0xD747: -case 0xD947: -case 0xDB47: -case 0xDD47: -case 0xDF47: - -// ADDX -case 0xD140: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD380: -case 0xD580: -case 0xD780: -case 0xD980: -case 0xDB80: -case 0xDD80: -case 0xDF80: -case 0xD181: -case 0xD381: -case 0xD581: -case 0xD781: -case 0xD981: -case 0xDB81: -case 0xDD81: -case 0xDF81: -case 0xD182: -case 0xD382: -case 0xD582: -case 0xD782: -case 0xD982: -case 0xDB82: -case 0xDD82: -case 0xDF82: -case 0xD183: -case 0xD383: -case 0xD583: -case 0xD783: -case 0xD983: -case 0xDB83: -case 0xDD83: -case 0xDF83: -case 0xD184: -case 0xD384: -case 0xD584: -case 0xD784: -case 0xD984: -case 0xDB84: -case 0xDD84: -case 0xDF84: -case 0xD185: -case 0xD385: -case 0xD585: -case 0xD785: -case 0xD985: -case 0xDB85: -case 0xDD85: -case 0xDF85: -case 0xD186: -case 0xD386: -case 0xD586: -case 0xD786: -case 0xD986: -case 0xDB86: -case 0xDD86: -case 0xDF86: -case 0xD187: -case 0xD387: -case 0xD587: -case 0xD787: -case 0xD987: -case 0xDB87: -case 0xDD87: -case 0xDF87: - -// ADDX -case 0xD180: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xD308: -case 0xD508: -case 0xD708: -case 0xD908: -case 0xDB08: -case 0xDD08: -case 0xD109: -case 0xD309: -case 0xD509: -case 0xD709: -case 0xD909: -case 0xDB09: -case 0xDD09: -case 0xD10A: -case 0xD30A: -case 0xD50A: -case 0xD70A: -case 0xD90A: -case 0xDB0A: -case 0xDD0A: -case 0xD10B: -case 0xD30B: -case 0xD50B: -case 0xD70B: -case 0xD90B: -case 0xDB0B: -case 0xDD0B: -case 0xD10C: -case 0xD30C: -case 0xD50C: -case 0xD70C: -case 0xD90C: -case 0xDB0C: -case 0xDD0C: -case 0xD10D: -case 0xD30D: -case 0xD50D: -case 0xD70D: -case 0xD90D: -case 0xDB0D: -case 0xDD0D: -case 0xD10E: -case 0xD30E: -case 0xD50E: -case 0xD70E: -case 0xD90E: -case 0xDB0E: -case 0xDD0E: - -// ADDXM -case 0xD108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xD348: -case 0xD548: -case 0xD748: -case 0xD948: -case 0xDB48: -case 0xDD48: -case 0xD149: -case 0xD349: -case 0xD549: -case 0xD749: -case 0xD949: -case 0xDB49: -case 0xDD49: -case 0xD14A: -case 0xD34A: -case 0xD54A: -case 0xD74A: -case 0xD94A: -case 0xDB4A: -case 0xDD4A: -case 0xD14B: -case 0xD34B: -case 0xD54B: -case 0xD74B: -case 0xD94B: -case 0xDB4B: -case 0xDD4B: -case 0xD14C: -case 0xD34C: -case 0xD54C: -case 0xD74C: -case 0xD94C: -case 0xDB4C: -case 0xDD4C: -case 0xD14D: -case 0xD34D: -case 0xD54D: -case 0xD74D: -case 0xD94D: -case 0xDB4D: -case 0xDD4D: -case 0xD14E: -case 0xD34E: -case 0xD54E: -case 0xD74E: -case 0xD94E: -case 0xDB4E: -case 0xDD4E: - -// ADDXM -case 0xD148: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xD388: -case 0xD588: -case 0xD788: -case 0xD988: -case 0xDB88: -case 0xDD88: -case 0xD189: -case 0xD389: -case 0xD589: -case 0xD789: -case 0xD989: -case 0xDB89: -case 0xDD89: -case 0xD18A: -case 0xD38A: -case 0xD58A: -case 0xD78A: -case 0xD98A: -case 0xDB8A: -case 0xDD8A: -case 0xD18B: -case 0xD38B: -case 0xD58B: -case 0xD78B: -case 0xD98B: -case 0xDB8B: -case 0xDD8B: -case 0xD18C: -case 0xD38C: -case 0xD58C: -case 0xD78C: -case 0xD98C: -case 0xDB8C: -case 0xDD8C: -case 0xD18D: -case 0xD38D: -case 0xD58D: -case 0xD78D: -case 0xD98D: -case 0xDB8D: -case 0xDD8D: -case 0xD18E: -case 0xD38E: -case 0xD58E: -case 0xD78E: -case 0xD98E: -case 0xDB8E: -case 0xDD8E: - -// ADDXM -case 0xD188: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0xD30F: -case 0xD50F: -case 0xD70F: -case 0xD90F: -case 0xDB0F: -case 0xDD0F: - -// ADDX7M -case 0xD10F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xD34F: -case 0xD54F: -case 0xD74F: -case 0xD94F: -case 0xDB4F: -case 0xDD4F: - -// ADDX7M -case 0xD14F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xD38F: -case 0xD58F: -case 0xD78F: -case 0xD98F: -case 0xDB8F: -case 0xDD8F: - -// ADDX7M -case 0xD18F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0xDF09: -case 0xDF0A: -case 0xDF0B: -case 0xDF0C: -case 0xDF0D: -case 0xDF0E: - -// ADDXM7 -case 0xDF08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xDF49: -case 0xDF4A: -case 0xDF4B: -case 0xDF4C: -case 0xDF4D: -case 0xDF4E: - -// ADDXM7 -case 0xDF48: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xDF89: -case 0xDF8A: -case 0xDF8B: -case 0xDF8C: -case 0xDF8D: -case 0xDF8E: - -// ADDXM7 -case 0xDF88: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// ADDX7M7 -case 0xDF0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// ADDX7M7 -case 0xDF4F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ADDX7M7 -case 0xDF8F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0xD2C0: -case 0xD4C0: -case 0xD6C0: -case 0xD8C0: -case 0xDAC0: -case 0xDCC0: -case 0xDEC0: -case 0xD0C1: -case 0xD2C1: -case 0xD4C1: -case 0xD6C1: -case 0xD8C1: -case 0xDAC1: -case 0xDCC1: -case 0xDEC1: -case 0xD0C2: -case 0xD2C2: -case 0xD4C2: -case 0xD6C2: -case 0xD8C2: -case 0xDAC2: -case 0xDCC2: -case 0xDEC2: -case 0xD0C3: -case 0xD2C3: -case 0xD4C3: -case 0xD6C3: -case 0xD8C3: -case 0xDAC3: -case 0xDCC3: -case 0xDEC3: -case 0xD0C4: -case 0xD2C4: -case 0xD4C4: -case 0xD6C4: -case 0xD8C4: -case 0xDAC4: -case 0xDCC4: -case 0xDEC4: -case 0xD0C5: -case 0xD2C5: -case 0xD4C5: -case 0xD6C5: -case 0xD8C5: -case 0xDAC5: -case 0xDCC5: -case 0xDEC5: -case 0xD0C6: -case 0xD2C6: -case 0xD4C6: -case 0xD6C6: -case 0xD8C6: -case 0xDAC6: -case 0xDCC6: -case 0xDEC6: -case 0xD0C7: -case 0xD2C7: -case 0xD4C7: -case 0xD6C7: -case 0xD8C7: -case 0xDAC7: -case 0xDCC7: -case 0xDEC7: - -// ADDA -case 0xD0C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0xD2C8: -case 0xD4C8: -case 0xD6C8: -case 0xD8C8: -case 0xDAC8: -case 0xDCC8: -case 0xDEC8: -case 0xD0C9: -case 0xD2C9: -case 0xD4C9: -case 0xD6C9: -case 0xD8C9: -case 0xDAC9: -case 0xDCC9: -case 0xDEC9: -case 0xD0CA: -case 0xD2CA: -case 0xD4CA: -case 0xD6CA: -case 0xD8CA: -case 0xDACA: -case 0xDCCA: -case 0xDECA: -case 0xD0CB: -case 0xD2CB: -case 0xD4CB: -case 0xD6CB: -case 0xD8CB: -case 0xDACB: -case 0xDCCB: -case 0xDECB: -case 0xD0CC: -case 0xD2CC: -case 0xD4CC: -case 0xD6CC: -case 0xD8CC: -case 0xDACC: -case 0xDCCC: -case 0xDECC: -case 0xD0CD: -case 0xD2CD: -case 0xD4CD: -case 0xD6CD: -case 0xD8CD: -case 0xDACD: -case 0xDCCD: -case 0xDECD: -case 0xD0CE: -case 0xD2CE: -case 0xD4CE: -case 0xD6CE: -case 0xD8CE: -case 0xDACE: -case 0xDCCE: -case 0xDECE: -case 0xD0CF: -case 0xD2CF: -case 0xD4CF: -case 0xD6CF: -case 0xD8CF: -case 0xDACF: -case 0xDCCF: -case 0xDECF: - -// ADDA -case 0xD0C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0xD2D0: -case 0xD4D0: -case 0xD6D0: -case 0xD8D0: -case 0xDAD0: -case 0xDCD0: -case 0xDED0: -case 0xD0D1: -case 0xD2D1: -case 0xD4D1: -case 0xD6D1: -case 0xD8D1: -case 0xDAD1: -case 0xDCD1: -case 0xDED1: -case 0xD0D2: -case 0xD2D2: -case 0xD4D2: -case 0xD6D2: -case 0xD8D2: -case 0xDAD2: -case 0xDCD2: -case 0xDED2: -case 0xD0D3: -case 0xD2D3: -case 0xD4D3: -case 0xD6D3: -case 0xD8D3: -case 0xDAD3: -case 0xDCD3: -case 0xDED3: -case 0xD0D4: -case 0xD2D4: -case 0xD4D4: -case 0xD6D4: -case 0xD8D4: -case 0xDAD4: -case 0xDCD4: -case 0xDED4: -case 0xD0D5: -case 0xD2D5: -case 0xD4D5: -case 0xD6D5: -case 0xD8D5: -case 0xDAD5: -case 0xDCD5: -case 0xDED5: -case 0xD0D6: -case 0xD2D6: -case 0xD4D6: -case 0xD6D6: -case 0xD8D6: -case 0xDAD6: -case 0xDCD6: -case 0xDED6: -case 0xD0D7: -case 0xD2D7: -case 0xD4D7: -case 0xD6D7: -case 0xD8D7: -case 0xDAD7: -case 0xDCD7: -case 0xDED7: - -// ADDA -case 0xD0D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0xD2D8: -case 0xD4D8: -case 0xD6D8: -case 0xD8D8: -case 0xDAD8: -case 0xDCD8: -case 0xDED8: -case 0xD0D9: -case 0xD2D9: -case 0xD4D9: -case 0xD6D9: -case 0xD8D9: -case 0xDAD9: -case 0xDCD9: -case 0xDED9: -case 0xD0DA: -case 0xD2DA: -case 0xD4DA: -case 0xD6DA: -case 0xD8DA: -case 0xDADA: -case 0xDCDA: -case 0xDEDA: -case 0xD0DB: -case 0xD2DB: -case 0xD4DB: -case 0xD6DB: -case 0xD8DB: -case 0xDADB: -case 0xDCDB: -case 0xDEDB: -case 0xD0DC: -case 0xD2DC: -case 0xD4DC: -case 0xD6DC: -case 0xD8DC: -case 0xDADC: -case 0xDCDC: -case 0xDEDC: -case 0xD0DD: -case 0xD2DD: -case 0xD4DD: -case 0xD6DD: -case 0xD8DD: -case 0xDADD: -case 0xDCDD: -case 0xDEDD: -case 0xD0DE: -case 0xD2DE: -case 0xD4DE: -case 0xD6DE: -case 0xD8DE: -case 0xDADE: -case 0xDCDE: -case 0xDEDE: - -// ADDA -case 0xD0D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0xD2E0: -case 0xD4E0: -case 0xD6E0: -case 0xD8E0: -case 0xDAE0: -case 0xDCE0: -case 0xDEE0: -case 0xD0E1: -case 0xD2E1: -case 0xD4E1: -case 0xD6E1: -case 0xD8E1: -case 0xDAE1: -case 0xDCE1: -case 0xDEE1: -case 0xD0E2: -case 0xD2E2: -case 0xD4E2: -case 0xD6E2: -case 0xD8E2: -case 0xDAE2: -case 0xDCE2: -case 0xDEE2: -case 0xD0E3: -case 0xD2E3: -case 0xD4E3: -case 0xD6E3: -case 0xD8E3: -case 0xDAE3: -case 0xDCE3: -case 0xDEE3: -case 0xD0E4: -case 0xD2E4: -case 0xD4E4: -case 0xD6E4: -case 0xD8E4: -case 0xDAE4: -case 0xDCE4: -case 0xDEE4: -case 0xD0E5: -case 0xD2E5: -case 0xD4E5: -case 0xD6E5: -case 0xD8E5: -case 0xDAE5: -case 0xDCE5: -case 0xDEE5: -case 0xD0E6: -case 0xD2E6: -case 0xD4E6: -case 0xD6E6: -case 0xD8E6: -case 0xDAE6: -case 0xDCE6: -case 0xDEE6: - -// ADDA -case 0xD0E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0xD2E8: -case 0xD4E8: -case 0xD6E8: -case 0xD8E8: -case 0xDAE8: -case 0xDCE8: -case 0xDEE8: -case 0xD0E9: -case 0xD2E9: -case 0xD4E9: -case 0xD6E9: -case 0xD8E9: -case 0xDAE9: -case 0xDCE9: -case 0xDEE9: -case 0xD0EA: -case 0xD2EA: -case 0xD4EA: -case 0xD6EA: -case 0xD8EA: -case 0xDAEA: -case 0xDCEA: -case 0xDEEA: -case 0xD0EB: -case 0xD2EB: -case 0xD4EB: -case 0xD6EB: -case 0xD8EB: -case 0xDAEB: -case 0xDCEB: -case 0xDEEB: -case 0xD0EC: -case 0xD2EC: -case 0xD4EC: -case 0xD6EC: -case 0xD8EC: -case 0xDAEC: -case 0xDCEC: -case 0xDEEC: -case 0xD0ED: -case 0xD2ED: -case 0xD4ED: -case 0xD6ED: -case 0xD8ED: -case 0xDAED: -case 0xDCED: -case 0xDEED: -case 0xD0EE: -case 0xD2EE: -case 0xD4EE: -case 0xD6EE: -case 0xD8EE: -case 0xDAEE: -case 0xDCEE: -case 0xDEEE: -case 0xD0EF: -case 0xD2EF: -case 0xD4EF: -case 0xD6EF: -case 0xD8EF: -case 0xDAEF: -case 0xDCEF: -case 0xDEEF: - -// ADDA -case 0xD0E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD2F0: -case 0xD4F0: -case 0xD6F0: -case 0xD8F0: -case 0xDAF0: -case 0xDCF0: -case 0xDEF0: -case 0xD0F1: -case 0xD2F1: -case 0xD4F1: -case 0xD6F1: -case 0xD8F1: -case 0xDAF1: -case 0xDCF1: -case 0xDEF1: -case 0xD0F2: -case 0xD2F2: -case 0xD4F2: -case 0xD6F2: -case 0xD8F2: -case 0xDAF2: -case 0xDCF2: -case 0xDEF2: -case 0xD0F3: -case 0xD2F3: -case 0xD4F3: -case 0xD6F3: -case 0xD8F3: -case 0xDAF3: -case 0xDCF3: -case 0xDEF3: -case 0xD0F4: -case 0xD2F4: -case 0xD4F4: -case 0xD6F4: -case 0xD8F4: -case 0xDAF4: -case 0xDCF4: -case 0xDEF4: -case 0xD0F5: -case 0xD2F5: -case 0xD4F5: -case 0xD6F5: -case 0xD8F5: -case 0xDAF5: -case 0xDCF5: -case 0xDEF5: -case 0xD0F6: -case 0xD2F6: -case 0xD4F6: -case 0xD6F6: -case 0xD8F6: -case 0xDAF6: -case 0xDCF6: -case 0xDEF6: -case 0xD0F7: -case 0xD2F7: -case 0xD4F7: -case 0xD6F7: -case 0xD8F7: -case 0xDAF7: -case 0xDCF7: -case 0xDEF7: - -// ADDA -case 0xD0F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0xD2F8: -case 0xD4F8: -case 0xD6F8: -case 0xD8F8: -case 0xDAF8: -case 0xDCF8: -case 0xDEF8: - -// ADDA -case 0xD0F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD2F9: -case 0xD4F9: -case 0xD6F9: -case 0xD8F9: -case 0xDAF9: -case 0xDCF9: -case 0xDEF9: - -// ADDA -case 0xD0F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD2FA: -case 0xD4FA: -case 0xD6FA: -case 0xD8FA: -case 0xDAFA: -case 0xDCFA: -case 0xDEFA: - -// ADDA -case 0xD0FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD2FB: -case 0xD4FB: -case 0xD6FB: -case 0xD8FB: -case 0xDAFB: -case 0xDCFB: -case 0xDEFB: - -// ADDA -case 0xD0FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0xD2FC: -case 0xD4FC: -case 0xD6FC: -case 0xD8FC: -case 0xDAFC: -case 0xDCFC: -case 0xDEFC: - -// ADDA -case 0xD0FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0xD2DF: -case 0xD4DF: -case 0xD6DF: -case 0xD8DF: -case 0xDADF: -case 0xDCDF: -case 0xDEDF: - -// ADDA -case 0xD0DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0xD2E7: -case 0xD4E7: -case 0xD6E7: -case 0xD8E7: -case 0xDAE7: -case 0xDCE7: -case 0xDEE7: - -// ADDA -case 0xD0E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0xD3C0: -case 0xD5C0: -case 0xD7C0: -case 0xD9C0: -case 0xDBC0: -case 0xDDC0: -case 0xDFC0: -case 0xD1C1: -case 0xD3C1: -case 0xD5C1: -case 0xD7C1: -case 0xD9C1: -case 0xDBC1: -case 0xDDC1: -case 0xDFC1: -case 0xD1C2: -case 0xD3C2: -case 0xD5C2: -case 0xD7C2: -case 0xD9C2: -case 0xDBC2: -case 0xDDC2: -case 0xDFC2: -case 0xD1C3: -case 0xD3C3: -case 0xD5C3: -case 0xD7C3: -case 0xD9C3: -case 0xDBC3: -case 0xDDC3: -case 0xDFC3: -case 0xD1C4: -case 0xD3C4: -case 0xD5C4: -case 0xD7C4: -case 0xD9C4: -case 0xDBC4: -case 0xDDC4: -case 0xDFC4: -case 0xD1C5: -case 0xD3C5: -case 0xD5C5: -case 0xD7C5: -case 0xD9C5: -case 0xDBC5: -case 0xDDC5: -case 0xDFC5: -case 0xD1C6: -case 0xD3C6: -case 0xD5C6: -case 0xD7C6: -case 0xD9C6: -case 0xDBC6: -case 0xDDC6: -case 0xDFC6: -case 0xD1C7: -case 0xD3C7: -case 0xD5C7: -case 0xD7C7: -case 0xD9C7: -case 0xDBC7: -case 0xDDC7: -case 0xDFC7: - -// ADDA -case 0xD1C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0xD3C8: -case 0xD5C8: -case 0xD7C8: -case 0xD9C8: -case 0xDBC8: -case 0xDDC8: -case 0xDFC8: -case 0xD1C9: -case 0xD3C9: -case 0xD5C9: -case 0xD7C9: -case 0xD9C9: -case 0xDBC9: -case 0xDDC9: -case 0xDFC9: -case 0xD1CA: -case 0xD3CA: -case 0xD5CA: -case 0xD7CA: -case 0xD9CA: -case 0xDBCA: -case 0xDDCA: -case 0xDFCA: -case 0xD1CB: -case 0xD3CB: -case 0xD5CB: -case 0xD7CB: -case 0xD9CB: -case 0xDBCB: -case 0xDDCB: -case 0xDFCB: -case 0xD1CC: -case 0xD3CC: -case 0xD5CC: -case 0xD7CC: -case 0xD9CC: -case 0xDBCC: -case 0xDDCC: -case 0xDFCC: -case 0xD1CD: -case 0xD3CD: -case 0xD5CD: -case 0xD7CD: -case 0xD9CD: -case 0xDBCD: -case 0xDDCD: -case 0xDFCD: -case 0xD1CE: -case 0xD3CE: -case 0xD5CE: -case 0xD7CE: -case 0xD9CE: -case 0xDBCE: -case 0xDDCE: -case 0xDFCE: -case 0xD1CF: -case 0xD3CF: -case 0xD5CF: -case 0xD7CF: -case 0xD9CF: -case 0xDBCF: -case 0xDDCF: -case 0xDFCF: - -// ADDA -case 0xD1C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0xD3D0: -case 0xD5D0: -case 0xD7D0: -case 0xD9D0: -case 0xDBD0: -case 0xDDD0: -case 0xDFD0: -case 0xD1D1: -case 0xD3D1: -case 0xD5D1: -case 0xD7D1: -case 0xD9D1: -case 0xDBD1: -case 0xDDD1: -case 0xDFD1: -case 0xD1D2: -case 0xD3D2: -case 0xD5D2: -case 0xD7D2: -case 0xD9D2: -case 0xDBD2: -case 0xDDD2: -case 0xDFD2: -case 0xD1D3: -case 0xD3D3: -case 0xD5D3: -case 0xD7D3: -case 0xD9D3: -case 0xDBD3: -case 0xDDD3: -case 0xDFD3: -case 0xD1D4: -case 0xD3D4: -case 0xD5D4: -case 0xD7D4: -case 0xD9D4: -case 0xDBD4: -case 0xDDD4: -case 0xDFD4: -case 0xD1D5: -case 0xD3D5: -case 0xD5D5: -case 0xD7D5: -case 0xD9D5: -case 0xDBD5: -case 0xDDD5: -case 0xDFD5: -case 0xD1D6: -case 0xD3D6: -case 0xD5D6: -case 0xD7D6: -case 0xD9D6: -case 0xDBD6: -case 0xDDD6: -case 0xDFD6: -case 0xD1D7: -case 0xD3D7: -case 0xD5D7: -case 0xD7D7: -case 0xD9D7: -case 0xDBD7: -case 0xDDD7: -case 0xDFD7: - -// ADDA -case 0xD1D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD3D8: -case 0xD5D8: -case 0xD7D8: -case 0xD9D8: -case 0xDBD8: -case 0xDDD8: -case 0xDFD8: -case 0xD1D9: -case 0xD3D9: -case 0xD5D9: -case 0xD7D9: -case 0xD9D9: -case 0xDBD9: -case 0xDDD9: -case 0xDFD9: -case 0xD1DA: -case 0xD3DA: -case 0xD5DA: -case 0xD7DA: -case 0xD9DA: -case 0xDBDA: -case 0xDDDA: -case 0xDFDA: -case 0xD1DB: -case 0xD3DB: -case 0xD5DB: -case 0xD7DB: -case 0xD9DB: -case 0xDBDB: -case 0xDDDB: -case 0xDFDB: -case 0xD1DC: -case 0xD3DC: -case 0xD5DC: -case 0xD7DC: -case 0xD9DC: -case 0xDBDC: -case 0xDDDC: -case 0xDFDC: -case 0xD1DD: -case 0xD3DD: -case 0xD5DD: -case 0xD7DD: -case 0xD9DD: -case 0xDBDD: -case 0xDDDD: -case 0xDFDD: -case 0xD1DE: -case 0xD3DE: -case 0xD5DE: -case 0xD7DE: -case 0xD9DE: -case 0xDBDE: -case 0xDDDE: -case 0xDFDE: - -// ADDA -case 0xD1D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD3E0: -case 0xD5E0: -case 0xD7E0: -case 0xD9E0: -case 0xDBE0: -case 0xDDE0: -case 0xDFE0: -case 0xD1E1: -case 0xD3E1: -case 0xD5E1: -case 0xD7E1: -case 0xD9E1: -case 0xDBE1: -case 0xDDE1: -case 0xDFE1: -case 0xD1E2: -case 0xD3E2: -case 0xD5E2: -case 0xD7E2: -case 0xD9E2: -case 0xDBE2: -case 0xDDE2: -case 0xDFE2: -case 0xD1E3: -case 0xD3E3: -case 0xD5E3: -case 0xD7E3: -case 0xD9E3: -case 0xDBE3: -case 0xDDE3: -case 0xDFE3: -case 0xD1E4: -case 0xD3E4: -case 0xD5E4: -case 0xD7E4: -case 0xD9E4: -case 0xDBE4: -case 0xDDE4: -case 0xDFE4: -case 0xD1E5: -case 0xD3E5: -case 0xD5E5: -case 0xD7E5: -case 0xD9E5: -case 0xDBE5: -case 0xDDE5: -case 0xDFE5: -case 0xD1E6: -case 0xD3E6: -case 0xD5E6: -case 0xD7E6: -case 0xD9E6: -case 0xDBE6: -case 0xDDE6: -case 0xDFE6: - -// ADDA -case 0xD1E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0xD3E8: -case 0xD5E8: -case 0xD7E8: -case 0xD9E8: -case 0xDBE8: -case 0xDDE8: -case 0xDFE8: -case 0xD1E9: -case 0xD3E9: -case 0xD5E9: -case 0xD7E9: -case 0xD9E9: -case 0xDBE9: -case 0xDDE9: -case 0xDFE9: -case 0xD1EA: -case 0xD3EA: -case 0xD5EA: -case 0xD7EA: -case 0xD9EA: -case 0xDBEA: -case 0xDDEA: -case 0xDFEA: -case 0xD1EB: -case 0xD3EB: -case 0xD5EB: -case 0xD7EB: -case 0xD9EB: -case 0xDBEB: -case 0xDDEB: -case 0xDFEB: -case 0xD1EC: -case 0xD3EC: -case 0xD5EC: -case 0xD7EC: -case 0xD9EC: -case 0xDBEC: -case 0xDDEC: -case 0xDFEC: -case 0xD1ED: -case 0xD3ED: -case 0xD5ED: -case 0xD7ED: -case 0xD9ED: -case 0xDBED: -case 0xDDED: -case 0xDFED: -case 0xD1EE: -case 0xD3EE: -case 0xD5EE: -case 0xD7EE: -case 0xD9EE: -case 0xDBEE: -case 0xDDEE: -case 0xDFEE: -case 0xD1EF: -case 0xD3EF: -case 0xD5EF: -case 0xD7EF: -case 0xD9EF: -case 0xDBEF: -case 0xDDEF: -case 0xDFEF: - -// ADDA -case 0xD1E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD3F0: -case 0xD5F0: -case 0xD7F0: -case 0xD9F0: -case 0xDBF0: -case 0xDDF0: -case 0xDFF0: -case 0xD1F1: -case 0xD3F1: -case 0xD5F1: -case 0xD7F1: -case 0xD9F1: -case 0xDBF1: -case 0xDDF1: -case 0xDFF1: -case 0xD1F2: -case 0xD3F2: -case 0xD5F2: -case 0xD7F2: -case 0xD9F2: -case 0xDBF2: -case 0xDDF2: -case 0xDFF2: -case 0xD1F3: -case 0xD3F3: -case 0xD5F3: -case 0xD7F3: -case 0xD9F3: -case 0xDBF3: -case 0xDDF3: -case 0xDFF3: -case 0xD1F4: -case 0xD3F4: -case 0xD5F4: -case 0xD7F4: -case 0xD9F4: -case 0xDBF4: -case 0xDDF4: -case 0xDFF4: -case 0xD1F5: -case 0xD3F5: -case 0xD5F5: -case 0xD7F5: -case 0xD9F5: -case 0xDBF5: -case 0xDDF5: -case 0xDFF5: -case 0xD1F6: -case 0xD3F6: -case 0xD5F6: -case 0xD7F6: -case 0xD9F6: -case 0xDBF6: -case 0xDDF6: -case 0xDFF6: -case 0xD1F7: -case 0xD3F7: -case 0xD5F7: -case 0xD7F7: -case 0xD9F7: -case 0xDBF7: -case 0xDDF7: -case 0xDFF7: - -// ADDA -case 0xD1F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0xD3F8: -case 0xD5F8: -case 0xD7F8: -case 0xD9F8: -case 0xDBF8: -case 0xDDF8: -case 0xDFF8: - -// ADDA -case 0xD1F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD3F9: -case 0xD5F9: -case 0xD7F9: -case 0xD9F9: -case 0xDBF9: -case 0xDDF9: -case 0xDFF9: - -// ADDA -case 0xD1F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(24) -case 0xD3FA: -case 0xD5FA: -case 0xD7FA: -case 0xD9FA: -case 0xDBFA: -case 0xDDFA: -case 0xDFFA: - -// ADDA -case 0xD1FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD3FB: -case 0xD5FB: -case 0xD7FB: -case 0xD9FB: -case 0xDBFB: -case 0xDDFB: -case 0xDFFB: - -// ADDA -case 0xD1FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0xD3FC: -case 0xD5FC: -case 0xD7FC: -case 0xD9FC: -case 0xDBFC: -case 0xDDFC: -case 0xDFFC: - -// ADDA -case 0xD1FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)FETCH_LONG; - PC += 4; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(14) -case 0xD3DF: -case 0xD5DF: -case 0xD7DF: -case 0xD9DF: -case 0xDBDF: -case 0xDDDF: -case 0xDFDF: - -// ADDA -case 0xD1DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD3E7: -case 0xD5E7: -case 0xD7E7: -case 0xD9E7: -case 0xDBE7: -case 0xDDE7: -case 0xDFE7: - -// ADDA -case 0xD1E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) diff --git a/yabause/src/c68k/c68k_opE.inc b/yabause/src/c68k/c68k_opE.inc deleted file mode 100644 index 29c55772fd..0000000000 --- a/yabause/src/c68k/c68k_opE.inc +++ /dev/null @@ -1,6130 +0,0 @@ -case 0xE200: -case 0xE400: -case 0xE600: -case 0xE800: -case 0xEA00: -case 0xEC00: -case 0xEE00: -case 0xE001: -case 0xE201: -case 0xE401: -case 0xE601: -case 0xE801: -case 0xEA01: -case 0xEC01: -case 0xEE01: -case 0xE002: -case 0xE202: -case 0xE402: -case 0xE602: -case 0xE802: -case 0xEA02: -case 0xEC02: -case 0xEE02: -case 0xE003: -case 0xE203: -case 0xE403: -case 0xE603: -case 0xE803: -case 0xEA03: -case 0xEC03: -case 0xEE03: -case 0xE004: -case 0xE204: -case 0xE404: -case 0xE604: -case 0xE804: -case 0xEA04: -case 0xEC04: -case 0xEE04: -case 0xE005: -case 0xE205: -case 0xE405: -case 0xE605: -case 0xE805: -case 0xEA05: -case 0xEC05: -case 0xEE05: -case 0xE006: -case 0xE206: -case 0xE406: -case 0xE606: -case 0xE806: -case 0xEA06: -case 0xEC06: -case 0xEE06: -case 0xE007: -case 0xE207: -case 0xE407: -case 0xE607: -case 0xE807: -case 0xEA07: -case 0xEC07: -case 0xEE07: - -// ASRk -case 0xE000: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (s32)(s8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE240: -case 0xE440: -case 0xE640: -case 0xE840: -case 0xEA40: -case 0xEC40: -case 0xEE40: -case 0xE041: -case 0xE241: -case 0xE441: -case 0xE641: -case 0xE841: -case 0xEA41: -case 0xEC41: -case 0xEE41: -case 0xE042: -case 0xE242: -case 0xE442: -case 0xE642: -case 0xE842: -case 0xEA42: -case 0xEC42: -case 0xEE42: -case 0xE043: -case 0xE243: -case 0xE443: -case 0xE643: -case 0xE843: -case 0xEA43: -case 0xEC43: -case 0xEE43: -case 0xE044: -case 0xE244: -case 0xE444: -case 0xE644: -case 0xE844: -case 0xEA44: -case 0xEC44: -case 0xEE44: -case 0xE045: -case 0xE245: -case 0xE445: -case 0xE645: -case 0xE845: -case 0xEA45: -case 0xEC45: -case 0xEE45: -case 0xE046: -case 0xE246: -case 0xE446: -case 0xE646: -case 0xE846: -case 0xEA46: -case 0xEC46: -case 0xEE46: -case 0xE047: -case 0xE247: -case 0xE447: -case 0xE647: -case 0xE847: -case 0xEA47: -case 0xEC47: -case 0xEE47: - -// ASRk -case 0xE040: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE280: -case 0xE480: -case 0xE680: -case 0xE880: -case 0xEA80: -case 0xEC80: -case 0xEE80: -case 0xE081: -case 0xE281: -case 0xE481: -case 0xE681: -case 0xE881: -case 0xEA81: -case 0xEC81: -case 0xEE81: -case 0xE082: -case 0xE282: -case 0xE482: -case 0xE682: -case 0xE882: -case 0xEA82: -case 0xEC82: -case 0xEE82: -case 0xE083: -case 0xE283: -case 0xE483: -case 0xE683: -case 0xE883: -case 0xEA83: -case 0xEC83: -case 0xEE83: -case 0xE084: -case 0xE284: -case 0xE484: -case 0xE684: -case 0xE884: -case 0xEA84: -case 0xEC84: -case 0xEE84: -case 0xE085: -case 0xE285: -case 0xE485: -case 0xE685: -case 0xE885: -case 0xEA85: -case 0xEC85: -case 0xEE85: -case 0xE086: -case 0xE286: -case 0xE486: -case 0xE686: -case 0xE886: -case 0xEA86: -case 0xEC86: -case 0xEE86: -case 0xE087: -case 0xE287: -case 0xE487: -case 0xE687: -case 0xE887: -case 0xEA87: -case 0xEC87: -case 0xEE87: - -// ASRk -case 0xE080: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE208: -case 0xE408: -case 0xE608: -case 0xE808: -case 0xEA08: -case 0xEC08: -case 0xEE08: -case 0xE009: -case 0xE209: -case 0xE409: -case 0xE609: -case 0xE809: -case 0xEA09: -case 0xEC09: -case 0xEE09: -case 0xE00A: -case 0xE20A: -case 0xE40A: -case 0xE60A: -case 0xE80A: -case 0xEA0A: -case 0xEC0A: -case 0xEE0A: -case 0xE00B: -case 0xE20B: -case 0xE40B: -case 0xE60B: -case 0xE80B: -case 0xEA0B: -case 0xEC0B: -case 0xEE0B: -case 0xE00C: -case 0xE20C: -case 0xE40C: -case 0xE60C: -case 0xE80C: -case 0xEA0C: -case 0xEC0C: -case 0xEE0C: -case 0xE00D: -case 0xE20D: -case 0xE40D: -case 0xE60D: -case 0xE80D: -case 0xEA0D: -case 0xEC0D: -case 0xEE0D: -case 0xE00E: -case 0xE20E: -case 0xE40E: -case 0xE60E: -case 0xE80E: -case 0xEA0E: -case 0xEC0E: -case 0xEE0E: -case 0xE00F: -case 0xE20F: -case 0xE40F: -case 0xE60F: -case 0xE80F: -case 0xEA0F: -case 0xEC0F: -case 0xEE0F: - -// LSRk -case 0xE008: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE248: -case 0xE448: -case 0xE648: -case 0xE848: -case 0xEA48: -case 0xEC48: -case 0xEE48: -case 0xE049: -case 0xE249: -case 0xE449: -case 0xE649: -case 0xE849: -case 0xEA49: -case 0xEC49: -case 0xEE49: -case 0xE04A: -case 0xE24A: -case 0xE44A: -case 0xE64A: -case 0xE84A: -case 0xEA4A: -case 0xEC4A: -case 0xEE4A: -case 0xE04B: -case 0xE24B: -case 0xE44B: -case 0xE64B: -case 0xE84B: -case 0xEA4B: -case 0xEC4B: -case 0xEE4B: -case 0xE04C: -case 0xE24C: -case 0xE44C: -case 0xE64C: -case 0xE84C: -case 0xEA4C: -case 0xEC4C: -case 0xEE4C: -case 0xE04D: -case 0xE24D: -case 0xE44D: -case 0xE64D: -case 0xE84D: -case 0xEA4D: -case 0xEC4D: -case 0xEE4D: -case 0xE04E: -case 0xE24E: -case 0xE44E: -case 0xE64E: -case 0xE84E: -case 0xEA4E: -case 0xEC4E: -case 0xEE4E: -case 0xE04F: -case 0xE24F: -case 0xE44F: -case 0xE64F: -case 0xE84F: -case 0xEA4F: -case 0xEC4F: -case 0xEE4F: - -// LSRk -case 0xE048: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE288: -case 0xE488: -case 0xE688: -case 0xE888: -case 0xEA88: -case 0xEC88: -case 0xEE88: -case 0xE089: -case 0xE289: -case 0xE489: -case 0xE689: -case 0xE889: -case 0xEA89: -case 0xEC89: -case 0xEE89: -case 0xE08A: -case 0xE28A: -case 0xE48A: -case 0xE68A: -case 0xE88A: -case 0xEA8A: -case 0xEC8A: -case 0xEE8A: -case 0xE08B: -case 0xE28B: -case 0xE48B: -case 0xE68B: -case 0xE88B: -case 0xEA8B: -case 0xEC8B: -case 0xEE8B: -case 0xE08C: -case 0xE28C: -case 0xE48C: -case 0xE68C: -case 0xE88C: -case 0xEA8C: -case 0xEC8C: -case 0xEE8C: -case 0xE08D: -case 0xE28D: -case 0xE48D: -case 0xE68D: -case 0xE88D: -case 0xEA8D: -case 0xEC8D: -case 0xEE8D: -case 0xE08E: -case 0xE28E: -case 0xE48E: -case 0xE68E: -case 0xE88E: -case 0xEA8E: -case 0xEC8E: -case 0xEE8E: -case 0xE08F: -case 0xE28F: -case 0xE48F: -case 0xE68F: -case 0xE88F: -case 0xEA8F: -case 0xEC8F: -case 0xEE8F: - -// LSRk -case 0xE088: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE210: -case 0xE410: -case 0xE610: -case 0xE810: -case 0xEA10: -case 0xEC10: -case 0xEE10: -case 0xE011: -case 0xE211: -case 0xE411: -case 0xE611: -case 0xE811: -case 0xEA11: -case 0xEC11: -case 0xEE11: -case 0xE012: -case 0xE212: -case 0xE412: -case 0xE612: -case 0xE812: -case 0xEA12: -case 0xEC12: -case 0xEE12: -case 0xE013: -case 0xE213: -case 0xE413: -case 0xE613: -case 0xE813: -case 0xEA13: -case 0xEC13: -case 0xEE13: -case 0xE014: -case 0xE214: -case 0xE414: -case 0xE614: -case 0xE814: -case 0xEA14: -case 0xEC14: -case 0xEE14: -case 0xE015: -case 0xE215: -case 0xE415: -case 0xE615: -case 0xE815: -case 0xEA15: -case 0xEC15: -case 0xEE15: -case 0xE016: -case 0xE216: -case 0xE416: -case 0xE616: -case 0xE816: -case 0xEA16: -case 0xEC16: -case 0xEE16: -case 0xE017: -case 0xE217: -case 0xE417: -case 0xE617: -case 0xE817: -case 0xEA17: -case 0xEC17: -case 0xEE17: - -// ROXRk -case 0xE010: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src >> sft) | (src << (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE250: -case 0xE450: -case 0xE650: -case 0xE850: -case 0xEA50: -case 0xEC50: -case 0xEE50: -case 0xE051: -case 0xE251: -case 0xE451: -case 0xE651: -case 0xE851: -case 0xEA51: -case 0xEC51: -case 0xEE51: -case 0xE052: -case 0xE252: -case 0xE452: -case 0xE652: -case 0xE852: -case 0xEA52: -case 0xEC52: -case 0xEE52: -case 0xE053: -case 0xE253: -case 0xE453: -case 0xE653: -case 0xE853: -case 0xEA53: -case 0xEC53: -case 0xEE53: -case 0xE054: -case 0xE254: -case 0xE454: -case 0xE654: -case 0xE854: -case 0xEA54: -case 0xEC54: -case 0xEE54: -case 0xE055: -case 0xE255: -case 0xE455: -case 0xE655: -case 0xE855: -case 0xEA55: -case 0xEC55: -case 0xEE55: -case 0xE056: -case 0xE256: -case 0xE456: -case 0xE656: -case 0xE856: -case 0xEA56: -case 0xEC56: -case 0xEE56: -case 0xE057: -case 0xE257: -case 0xE457: -case 0xE657: -case 0xE857: -case 0xEA57: -case 0xEC57: -case 0xEE57: - -// ROXRk -case 0xE050: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src >> sft) | (src << (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE290: -case 0xE490: -case 0xE690: -case 0xE890: -case 0xEA90: -case 0xEC90: -case 0xEE90: -case 0xE091: -case 0xE291: -case 0xE491: -case 0xE691: -case 0xE891: -case 0xEA91: -case 0xEC91: -case 0xEE91: -case 0xE092: -case 0xE292: -case 0xE492: -case 0xE692: -case 0xE892: -case 0xEA92: -case 0xEC92: -case 0xEE92: -case 0xE093: -case 0xE293: -case 0xE493: -case 0xE693: -case 0xE893: -case 0xEA93: -case 0xEC93: -case 0xEE93: -case 0xE094: -case 0xE294: -case 0xE494: -case 0xE694: -case 0xE894: -case 0xEA94: -case 0xEC94: -case 0xEE94: -case 0xE095: -case 0xE295: -case 0xE495: -case 0xE695: -case 0xE895: -case 0xEA95: -case 0xEC95: -case 0xEE95: -case 0xE096: -case 0xE296: -case 0xE496: -case 0xE696: -case 0xE896: -case 0xEA96: -case 0xEC96: -case 0xEE96: -case 0xE097: -case 0xE297: -case 0xE497: -case 0xE697: -case 0xE897: -case 0xEA97: -case 0xEC97: -case 0xEE97: - -// ROXRk -case 0xE090: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - if (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))); - else res = (src >> sft) | (src << (33 - sft)) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + sft))); - CPU->flag_X = CPU->flag_C; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE218: -case 0xE418: -case 0xE618: -case 0xE818: -case 0xEA18: -case 0xEC18: -case 0xEE18: -case 0xE019: -case 0xE219: -case 0xE419: -case 0xE619: -case 0xE819: -case 0xEA19: -case 0xEC19: -case 0xEE19: -case 0xE01A: -case 0xE21A: -case 0xE41A: -case 0xE61A: -case 0xE81A: -case 0xEA1A: -case 0xEC1A: -case 0xEE1A: -case 0xE01B: -case 0xE21B: -case 0xE41B: -case 0xE61B: -case 0xE81B: -case 0xEA1B: -case 0xEC1B: -case 0xEE1B: -case 0xE01C: -case 0xE21C: -case 0xE41C: -case 0xE61C: -case 0xE81C: -case 0xEA1C: -case 0xEC1C: -case 0xEE1C: -case 0xE01D: -case 0xE21D: -case 0xE41D: -case 0xE61D: -case 0xE81D: -case 0xEA1D: -case 0xEC1D: -case 0xEE1D: -case 0xE01E: -case 0xE21E: -case 0xE41E: -case 0xE61E: -case 0xE81E: -case 0xEA1E: -case 0xEC1E: -case 0xEE1E: -case 0xE01F: -case 0xE21F: -case 0xE41F: -case 0xE61F: -case 0xE81F: -case 0xEA1F: -case 0xEC1F: -case 0xEE1F: - -// RORk -case 0xE018: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = (src >> sft) | (src << (8 - sft)); - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE258: -case 0xE458: -case 0xE658: -case 0xE858: -case 0xEA58: -case 0xEC58: -case 0xEE58: -case 0xE059: -case 0xE259: -case 0xE459: -case 0xE659: -case 0xE859: -case 0xEA59: -case 0xEC59: -case 0xEE59: -case 0xE05A: -case 0xE25A: -case 0xE45A: -case 0xE65A: -case 0xE85A: -case 0xEA5A: -case 0xEC5A: -case 0xEE5A: -case 0xE05B: -case 0xE25B: -case 0xE45B: -case 0xE65B: -case 0xE85B: -case 0xEA5B: -case 0xEC5B: -case 0xEE5B: -case 0xE05C: -case 0xE25C: -case 0xE45C: -case 0xE65C: -case 0xE85C: -case 0xEA5C: -case 0xEC5C: -case 0xEE5C: -case 0xE05D: -case 0xE25D: -case 0xE45D: -case 0xE65D: -case 0xE85D: -case 0xEA5D: -case 0xEC5D: -case 0xEE5D: -case 0xE05E: -case 0xE25E: -case 0xE45E: -case 0xE65E: -case 0xE85E: -case 0xEA5E: -case 0xEC5E: -case 0xEE5E: -case 0xE05F: -case 0xE25F: -case 0xE45F: -case 0xE65F: -case 0xE85F: -case 0xEA5F: -case 0xEC5F: -case 0xEE5F: - -// RORk -case 0xE058: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = (src >> sft) | (src << (16 - sft)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE298: -case 0xE498: -case 0xE698: -case 0xE898: -case 0xEA98: -case 0xEC98: -case 0xEE98: -case 0xE099: -case 0xE299: -case 0xE499: -case 0xE699: -case 0xE899: -case 0xEA99: -case 0xEC99: -case 0xEE99: -case 0xE09A: -case 0xE29A: -case 0xE49A: -case 0xE69A: -case 0xE89A: -case 0xEA9A: -case 0xEC9A: -case 0xEE9A: -case 0xE09B: -case 0xE29B: -case 0xE49B: -case 0xE69B: -case 0xE89B: -case 0xEA9B: -case 0xEC9B: -case 0xEE9B: -case 0xE09C: -case 0xE29C: -case 0xE49C: -case 0xE69C: -case 0xE89C: -case 0xEA9C: -case 0xEC9C: -case 0xEE9C: -case 0xE09D: -case 0xE29D: -case 0xE49D: -case 0xE69D: -case 0xE89D: -case 0xEA9D: -case 0xEC9D: -case 0xEE9D: -case 0xE09E: -case 0xE29E: -case 0xE49E: -case 0xE69E: -case 0xE89E: -case 0xEA9E: -case 0xEC9E: -case 0xEE9E: -case 0xE09F: -case 0xE29F: -case 0xE49F: -case 0xE69F: -case 0xE89F: -case 0xEA9F: -case 0xEC9F: -case 0xEE9F: - -// RORk -case 0xE098: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = (src >> sft) | (src << (32 - sft)); - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE300: -case 0xE500: -case 0xE700: -case 0xE900: -case 0xEB00: -case 0xED00: -case 0xEF00: -case 0xE101: -case 0xE301: -case 0xE501: -case 0xE701: -case 0xE901: -case 0xEB01: -case 0xED01: -case 0xEF01: -case 0xE102: -case 0xE302: -case 0xE502: -case 0xE702: -case 0xE902: -case 0xEB02: -case 0xED02: -case 0xEF02: -case 0xE103: -case 0xE303: -case 0xE503: -case 0xE703: -case 0xE903: -case 0xEB03: -case 0xED03: -case 0xEF03: -case 0xE104: -case 0xE304: -case 0xE504: -case 0xE704: -case 0xE904: -case 0xEB04: -case 0xED04: -case 0xEF04: -case 0xE105: -case 0xE305: -case 0xE505: -case 0xE705: -case 0xE905: -case 0xEB05: -case 0xED05: -case 0xEF05: -case 0xE106: -case 0xE306: -case 0xE506: -case 0xE706: -case 0xE906: -case 0xEB06: -case 0xED06: -case 0xEF06: -case 0xE107: -case 0xE307: -case 0xE507: -case 0xE707: -case 0xE907: -case 0xEB07: -case 0xED07: -case 0xEF07: - -// ASLk -case 0xE100: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft < 8) - { - CPU->flag_X = CPU->flag_C = src << (0 + sft); - res = src << sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - if ((sft > 7) && (src)) CPU->flag_V = C68K_SR_V; - else - { - u32 msk = (((s32)0x80000000) >> (sft + 24)) & 0x000000FF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(6) - } - - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; -} -RET(6) -case 0xE340: -case 0xE540: -case 0xE740: -case 0xE940: -case 0xEB40: -case 0xED40: -case 0xEF40: -case 0xE141: -case 0xE341: -case 0xE541: -case 0xE741: -case 0xE941: -case 0xEB41: -case 0xED41: -case 0xEF41: -case 0xE142: -case 0xE342: -case 0xE542: -case 0xE742: -case 0xE942: -case 0xEB42: -case 0xED42: -case 0xEF42: -case 0xE143: -case 0xE343: -case 0xE543: -case 0xE743: -case 0xE943: -case 0xEB43: -case 0xED43: -case 0xEF43: -case 0xE144: -case 0xE344: -case 0xE544: -case 0xE744: -case 0xE944: -case 0xEB44: -case 0xED44: -case 0xEF44: -case 0xE145: -case 0xE345: -case 0xE545: -case 0xE745: -case 0xE945: -case 0xEB45: -case 0xED45: -case 0xEF45: -case 0xE146: -case 0xE346: -case 0xE546: -case 0xE746: -case 0xE946: -case 0xEB46: -case 0xED46: -case 0xEF46: -case 0xE147: -case 0xE347: -case 0xE547: -case 0xE747: -case 0xE947: -case 0xEB47: -case 0xED47: -case 0xEF47: - -// ASLk -case 0xE140: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_X = CPU->flag_C = src >> (8 - sft); - res = src << sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 16)) & 0x0000FFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } -} -RET(6) -case 0xE380: -case 0xE580: -case 0xE780: -case 0xE980: -case 0xEB80: -case 0xED80: -case 0xEF80: -case 0xE181: -case 0xE381: -case 0xE581: -case 0xE781: -case 0xE981: -case 0xEB81: -case 0xED81: -case 0xEF81: -case 0xE182: -case 0xE382: -case 0xE582: -case 0xE782: -case 0xE982: -case 0xEB82: -case 0xED82: -case 0xEF82: -case 0xE183: -case 0xE383: -case 0xE583: -case 0xE783: -case 0xE983: -case 0xEB83: -case 0xED83: -case 0xEF83: -case 0xE184: -case 0xE384: -case 0xE584: -case 0xE784: -case 0xE984: -case 0xEB84: -case 0xED84: -case 0xEF84: -case 0xE185: -case 0xE385: -case 0xE585: -case 0xE785: -case 0xE985: -case 0xEB85: -case 0xED85: -case 0xEF85: -case 0xE186: -case 0xE386: -case 0xE586: -case 0xE786: -case 0xE986: -case 0xEB86: -case 0xED86: -case 0xEF86: -case 0xE187: -case 0xE387: -case 0xE587: -case 0xE787: -case 0xE987: -case 0xEB87: -case 0xED87: -case 0xEF87: - -// ASLk -case 0xE180: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_X = CPU->flag_C = src >> (24 - sft); - res = src << sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res & 0xFFFFFFFF; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 0)) & 0xFFFFFFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } -} -RET(8) -case 0xE308: -case 0xE508: -case 0xE708: -case 0xE908: -case 0xEB08: -case 0xED08: -case 0xEF08: -case 0xE109: -case 0xE309: -case 0xE509: -case 0xE709: -case 0xE909: -case 0xEB09: -case 0xED09: -case 0xEF09: -case 0xE10A: -case 0xE30A: -case 0xE50A: -case 0xE70A: -case 0xE90A: -case 0xEB0A: -case 0xED0A: -case 0xEF0A: -case 0xE10B: -case 0xE30B: -case 0xE50B: -case 0xE70B: -case 0xE90B: -case 0xEB0B: -case 0xED0B: -case 0xEF0B: -case 0xE10C: -case 0xE30C: -case 0xE50C: -case 0xE70C: -case 0xE90C: -case 0xEB0C: -case 0xED0C: -case 0xEF0C: -case 0xE10D: -case 0xE30D: -case 0xE50D: -case 0xE70D: -case 0xE90D: -case 0xEB0D: -case 0xED0D: -case 0xEF0D: -case 0xE10E: -case 0xE30E: -case 0xE50E: -case 0xE70E: -case 0xE90E: -case 0xEB0E: -case 0xED0E: -case 0xEF0E: -case 0xE10F: -case 0xE30F: -case 0xE50F: -case 0xE70F: -case 0xE90F: -case 0xEB0F: -case 0xED0F: -case 0xEF0F: - -// LSLk -case 0xE108: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << (0 + sft); - res = src << sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE348: -case 0xE548: -case 0xE748: -case 0xE948: -case 0xEB48: -case 0xED48: -case 0xEF48: -case 0xE149: -case 0xE349: -case 0xE549: -case 0xE749: -case 0xE949: -case 0xEB49: -case 0xED49: -case 0xEF49: -case 0xE14A: -case 0xE34A: -case 0xE54A: -case 0xE74A: -case 0xE94A: -case 0xEB4A: -case 0xED4A: -case 0xEF4A: -case 0xE14B: -case 0xE34B: -case 0xE54B: -case 0xE74B: -case 0xE94B: -case 0xEB4B: -case 0xED4B: -case 0xEF4B: -case 0xE14C: -case 0xE34C: -case 0xE54C: -case 0xE74C: -case 0xE94C: -case 0xEB4C: -case 0xED4C: -case 0xEF4C: -case 0xE14D: -case 0xE34D: -case 0xE54D: -case 0xE74D: -case 0xE94D: -case 0xEB4D: -case 0xED4D: -case 0xEF4D: -case 0xE14E: -case 0xE34E: -case 0xE54E: -case 0xE74E: -case 0xE94E: -case 0xEB4E: -case 0xED4E: -case 0xEF4E: -case 0xE14F: -case 0xE34F: -case 0xE54F: -case 0xE74F: -case 0xE94F: -case 0xEB4F: -case 0xED4F: -case 0xEF4F: - -// LSLk -case 0xE148: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> (8 - sft); - res = src << sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE388: -case 0xE588: -case 0xE788: -case 0xE988: -case 0xEB88: -case 0xED88: -case 0xEF88: -case 0xE189: -case 0xE389: -case 0xE589: -case 0xE789: -case 0xE989: -case 0xEB89: -case 0xED89: -case 0xEF89: -case 0xE18A: -case 0xE38A: -case 0xE58A: -case 0xE78A: -case 0xE98A: -case 0xEB8A: -case 0xED8A: -case 0xEF8A: -case 0xE18B: -case 0xE38B: -case 0xE58B: -case 0xE78B: -case 0xE98B: -case 0xEB8B: -case 0xED8B: -case 0xEF8B: -case 0xE18C: -case 0xE38C: -case 0xE58C: -case 0xE78C: -case 0xE98C: -case 0xEB8C: -case 0xED8C: -case 0xEF8C: -case 0xE18D: -case 0xE38D: -case 0xE58D: -case 0xE78D: -case 0xE98D: -case 0xEB8D: -case 0xED8D: -case 0xEF8D: -case 0xE18E: -case 0xE38E: -case 0xE58E: -case 0xE78E: -case 0xE98E: -case 0xEB8E: -case 0xED8E: -case 0xEF8E: -case 0xE18F: -case 0xE38F: -case 0xE58F: -case 0xE78F: -case 0xE98F: -case 0xEB8F: -case 0xED8F: -case 0xEF8F: - -// LSLk -case 0xE188: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> (24 - sft); - res = src << sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res & 0xFFFFFFFF; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE310: -case 0xE510: -case 0xE710: -case 0xE910: -case 0xEB10: -case 0xED10: -case 0xEF10: -case 0xE111: -case 0xE311: -case 0xE511: -case 0xE711: -case 0xE911: -case 0xEB11: -case 0xED11: -case 0xEF11: -case 0xE112: -case 0xE312: -case 0xE512: -case 0xE712: -case 0xE912: -case 0xEB12: -case 0xED12: -case 0xEF12: -case 0xE113: -case 0xE313: -case 0xE513: -case 0xE713: -case 0xE913: -case 0xEB13: -case 0xED13: -case 0xEF13: -case 0xE114: -case 0xE314: -case 0xE514: -case 0xE714: -case 0xE914: -case 0xEB14: -case 0xED14: -case 0xEF14: -case 0xE115: -case 0xE315: -case 0xE515: -case 0xE715: -case 0xE915: -case 0xEB15: -case 0xED15: -case 0xEF15: -case 0xE116: -case 0xE316: -case 0xE516: -case 0xE716: -case 0xE916: -case 0xEB16: -case 0xED16: -case 0xEF16: -case 0xE117: -case 0xE317: -case 0xE517: -case 0xE717: -case 0xE917: -case 0xEB17: -case 0xED17: -case 0xEF17: - -// ROXLk -case 0xE110: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src << sft) | (src >> (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE350: -case 0xE550: -case 0xE750: -case 0xE950: -case 0xEB50: -case 0xED50: -case 0xEF50: -case 0xE151: -case 0xE351: -case 0xE551: -case 0xE751: -case 0xE951: -case 0xEB51: -case 0xED51: -case 0xEF51: -case 0xE152: -case 0xE352: -case 0xE552: -case 0xE752: -case 0xE952: -case 0xEB52: -case 0xED52: -case 0xEF52: -case 0xE153: -case 0xE353: -case 0xE553: -case 0xE753: -case 0xE953: -case 0xEB53: -case 0xED53: -case 0xEF53: -case 0xE154: -case 0xE354: -case 0xE554: -case 0xE754: -case 0xE954: -case 0xEB54: -case 0xED54: -case 0xEF54: -case 0xE155: -case 0xE355: -case 0xE555: -case 0xE755: -case 0xE955: -case 0xEB55: -case 0xED55: -case 0xEF55: -case 0xE156: -case 0xE356: -case 0xE556: -case 0xE756: -case 0xE956: -case 0xEB56: -case 0xED56: -case 0xEF56: -case 0xE157: -case 0xE357: -case 0xE557: -case 0xE757: -case 0xE957: -case 0xEB57: -case 0xED57: -case 0xEF57: - -// ROXLk -case 0xE150: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src << sft) | (src >> (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE390: -case 0xE590: -case 0xE790: -case 0xE990: -case 0xEB90: -case 0xED90: -case 0xEF90: -case 0xE191: -case 0xE391: -case 0xE591: -case 0xE791: -case 0xE991: -case 0xEB91: -case 0xED91: -case 0xEF91: -case 0xE192: -case 0xE392: -case 0xE592: -case 0xE792: -case 0xE992: -case 0xEB92: -case 0xED92: -case 0xEF92: -case 0xE193: -case 0xE393: -case 0xE593: -case 0xE793: -case 0xE993: -case 0xEB93: -case 0xED93: -case 0xEF93: -case 0xE194: -case 0xE394: -case 0xE594: -case 0xE794: -case 0xE994: -case 0xEB94: -case 0xED94: -case 0xEF94: -case 0xE195: -case 0xE395: -case 0xE595: -case 0xE795: -case 0xE995: -case 0xEB95: -case 0xED95: -case 0xEF95: -case 0xE196: -case 0xE396: -case 0xE596: -case 0xE796: -case 0xE996: -case 0xEB96: -case 0xED96: -case 0xEF96: -case 0xE197: -case 0xE397: -case 0xE597: -case 0xE797: -case 0xE997: -case 0xEB97: -case 0xED97: -case 0xEF97: - -// ROXLk -case 0xE190: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = src >> ((32 - C68K_SR_C_SFT) - sft); - if (sft == 1) res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - 1)); - else res = (src << sft) | (src >> (33 - sft)) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - sft)); - CPU->flag_X = CPU->flag_C; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE318: -case 0xE518: -case 0xE718: -case 0xE918: -case 0xEB18: -case 0xED18: -case 0xEF18: -case 0xE119: -case 0xE319: -case 0xE519: -case 0xE719: -case 0xE919: -case 0xEB19: -case 0xED19: -case 0xEF19: -case 0xE11A: -case 0xE31A: -case 0xE51A: -case 0xE71A: -case 0xE91A: -case 0xEB1A: -case 0xED1A: -case 0xEF1A: -case 0xE11B: -case 0xE31B: -case 0xE51B: -case 0xE71B: -case 0xE91B: -case 0xEB1B: -case 0xED1B: -case 0xEF1B: -case 0xE11C: -case 0xE31C: -case 0xE51C: -case 0xE71C: -case 0xE91C: -case 0xEB1C: -case 0xED1C: -case 0xEF1C: -case 0xE11D: -case 0xE31D: -case 0xE51D: -case 0xE71D: -case 0xE91D: -case 0xEB1D: -case 0xED1D: -case 0xEF1D: -case 0xE11E: -case 0xE31E: -case 0xE51E: -case 0xE71E: -case 0xE91E: -case 0xEB1E: -case 0xED1E: -case 0xEF1E: -case 0xE11F: -case 0xE31F: -case 0xE51F: -case 0xE71F: -case 0xE91F: -case 0xEB1F: -case 0xED1F: -case 0xEF1F: - -// ROLk -case 0xE118: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << (0 + sft); - res = (src << sft) | (src >> (8 - sft)); - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE358: -case 0xE558: -case 0xE758: -case 0xE958: -case 0xEB58: -case 0xED58: -case 0xEF58: -case 0xE159: -case 0xE359: -case 0xE559: -case 0xE759: -case 0xE959: -case 0xEB59: -case 0xED59: -case 0xEF59: -case 0xE15A: -case 0xE35A: -case 0xE55A: -case 0xE75A: -case 0xE95A: -case 0xEB5A: -case 0xED5A: -case 0xEF5A: -case 0xE15B: -case 0xE35B: -case 0xE55B: -case 0xE75B: -case 0xE95B: -case 0xEB5B: -case 0xED5B: -case 0xEF5B: -case 0xE15C: -case 0xE35C: -case 0xE55C: -case 0xE75C: -case 0xE95C: -case 0xEB5C: -case 0xED5C: -case 0xEF5C: -case 0xE15D: -case 0xE35D: -case 0xE55D: -case 0xE75D: -case 0xE95D: -case 0xEB5D: -case 0xED5D: -case 0xEF5D: -case 0xE15E: -case 0xE35E: -case 0xE55E: -case 0xE75E: -case 0xE95E: -case 0xEB5E: -case 0xED5E: -case 0xEF5E: -case 0xE15F: -case 0xE35F: -case 0xE55F: -case 0xE75F: -case 0xE95F: -case 0xEB5F: -case 0xED5F: -case 0xEF5F: - -// ROLk -case 0xE158: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src >> (8 - sft); - res = (src << sft) | (src >> (16 - sft)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE398: -case 0xE598: -case 0xE798: -case 0xE998: -case 0xEB98: -case 0xED98: -case 0xEF98: -case 0xE199: -case 0xE399: -case 0xE599: -case 0xE799: -case 0xE999: -case 0xEB99: -case 0xED99: -case 0xEF99: -case 0xE19A: -case 0xE39A: -case 0xE59A: -case 0xE79A: -case 0xE99A: -case 0xEB9A: -case 0xED9A: -case 0xEF9A: -case 0xE19B: -case 0xE39B: -case 0xE59B: -case 0xE79B: -case 0xE99B: -case 0xEB9B: -case 0xED9B: -case 0xEF9B: -case 0xE19C: -case 0xE39C: -case 0xE59C: -case 0xE79C: -case 0xE99C: -case 0xEB9C: -case 0xED9C: -case 0xEF9C: -case 0xE19D: -case 0xE39D: -case 0xE59D: -case 0xE79D: -case 0xE99D: -case 0xEB9D: -case 0xED9D: -case 0xEF9D: -case 0xE19E: -case 0xE39E: -case 0xE59E: -case 0xE79E: -case 0xE99E: -case 0xEB9E: -case 0xED9E: -case 0xEF9E: -case 0xE19F: -case 0xE39F: -case 0xE59F: -case 0xE79F: -case 0xE99F: -case 0xEB9F: -case 0xED9F: -case 0xEF9F: - -// ROLk -case 0xE198: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src >> (24 - sft); - res = (src << sft) | (src >> (32 - sft)); - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE220: -case 0xE420: -case 0xE620: -case 0xE820: -case 0xEA20: -case 0xEC20: -case 0xEE20: -case 0xE021: -case 0xE221: -case 0xE421: -case 0xE621: -case 0xE821: -case 0xEA21: -case 0xEC21: -case 0xEE21: -case 0xE022: -case 0xE222: -case 0xE422: -case 0xE622: -case 0xE822: -case 0xEA22: -case 0xEC22: -case 0xEE22: -case 0xE023: -case 0xE223: -case 0xE423: -case 0xE623: -case 0xE823: -case 0xEA23: -case 0xEC23: -case 0xEE23: -case 0xE024: -case 0xE224: -case 0xE424: -case 0xE624: -case 0xE824: -case 0xEA24: -case 0xEC24: -case 0xEE24: -case 0xE025: -case 0xE225: -case 0xE425: -case 0xE625: -case 0xE825: -case 0xEA25: -case 0xEC25: -case 0xEE25: -case 0xE026: -case 0xE226: -case 0xE426: -case 0xE626: -case 0xE826: -case 0xEA26: -case 0xEC26: -case 0xEE26: -case 0xE027: -case 0xE227: -case 0xE427: -case 0xE627: -case 0xE827: -case 0xEA27: -case 0xEC27: -case 0xEE27: - -// ASRD -case 0xE020: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (s32)(s8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 8) - { - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - if (src & (1 << 7)) - { - CPU->flag_N = C68K_SR_N; - CPU->flag_notZ = 1; - CPU->flag_V = 0; - CPU->flag_C = C68K_SR_C; - CPU->flag_X = C68K_SR_X; - res = 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_X = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE260: -case 0xE460: -case 0xE660: -case 0xE860: -case 0xEA60: -case 0xEC60: -case 0xEE60: -case 0xE061: -case 0xE261: -case 0xE461: -case 0xE661: -case 0xE861: -case 0xEA61: -case 0xEC61: -case 0xEE61: -case 0xE062: -case 0xE262: -case 0xE462: -case 0xE662: -case 0xE862: -case 0xEA62: -case 0xEC62: -case 0xEE62: -case 0xE063: -case 0xE263: -case 0xE463: -case 0xE663: -case 0xE863: -case 0xEA63: -case 0xEC63: -case 0xEE63: -case 0xE064: -case 0xE264: -case 0xE464: -case 0xE664: -case 0xE864: -case 0xEA64: -case 0xEC64: -case 0xEE64: -case 0xE065: -case 0xE265: -case 0xE465: -case 0xE665: -case 0xE865: -case 0xEA65: -case 0xEC65: -case 0xEE65: -case 0xE066: -case 0xE266: -case 0xE466: -case 0xE666: -case 0xE866: -case 0xEA66: -case 0xEC66: -case 0xEE66: -case 0xE067: -case 0xE267: -case 0xE467: -case 0xE667: -case 0xE867: -case 0xEA67: -case 0xEC67: -case 0xEE67: - -// ASRD -case 0xE060: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 16) - { - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = ((s32)src) >> sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - if (src & (1 << 15)) - { - CPU->flag_N = C68K_SR_N; - CPU->flag_notZ = 1; - CPU->flag_V = 0; - CPU->flag_C = C68K_SR_C; - CPU->flag_X = C68K_SR_X; - res = 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_X = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2A0: -case 0xE4A0: -case 0xE6A0: -case 0xE8A0: -case 0xEAA0: -case 0xECA0: -case 0xEEA0: -case 0xE0A1: -case 0xE2A1: -case 0xE4A1: -case 0xE6A1: -case 0xE8A1: -case 0xEAA1: -case 0xECA1: -case 0xEEA1: -case 0xE0A2: -case 0xE2A2: -case 0xE4A2: -case 0xE6A2: -case 0xE8A2: -case 0xEAA2: -case 0xECA2: -case 0xEEA2: -case 0xE0A3: -case 0xE2A3: -case 0xE4A3: -case 0xE6A3: -case 0xE8A3: -case 0xEAA3: -case 0xECA3: -case 0xEEA3: -case 0xE0A4: -case 0xE2A4: -case 0xE4A4: -case 0xE6A4: -case 0xE8A4: -case 0xEAA4: -case 0xECA4: -case 0xEEA4: -case 0xE0A5: -case 0xE2A5: -case 0xE4A5: -case 0xE6A5: -case 0xE8A5: -case 0xEAA5: -case 0xECA5: -case 0xEEA5: -case 0xE0A6: -case 0xE2A6: -case 0xE4A6: -case 0xE6A6: -case 0xE8A6: -case 0xEAA6: -case 0xECA6: -case 0xEEA6: -case 0xE0A7: -case 0xE2A7: -case 0xE4A7: -case 0xE6A7: -case 0xE8A7: -case 0xEAA7: -case 0xECA7: -case 0xEEA7: - -// ASRD -case 0xE0A0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = ((s32)src) >> sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - if (src & (1 << 31)) - { - CPU->flag_N = C68K_SR_N; - CPU->flag_notZ = 1; - CPU->flag_V = 0; - CPU->flag_C = C68K_SR_C; - CPU->flag_X = C68K_SR_X; - res = 0xFFFFFFFF; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_X = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE228: -case 0xE428: -case 0xE628: -case 0xE828: -case 0xEA28: -case 0xEC28: -case 0xEE28: -case 0xE029: -case 0xE229: -case 0xE429: -case 0xE629: -case 0xE829: -case 0xEA29: -case 0xEC29: -case 0xEE29: -case 0xE02A: -case 0xE22A: -case 0xE42A: -case 0xE62A: -case 0xE82A: -case 0xEA2A: -case 0xEC2A: -case 0xEE2A: -case 0xE02B: -case 0xE22B: -case 0xE42B: -case 0xE62B: -case 0xE82B: -case 0xEA2B: -case 0xEC2B: -case 0xEE2B: -case 0xE02C: -case 0xE22C: -case 0xE42C: -case 0xE62C: -case 0xE82C: -case 0xEA2C: -case 0xEC2C: -case 0xEE2C: -case 0xE02D: -case 0xE22D: -case 0xE42D: -case 0xE62D: -case 0xE82D: -case 0xEA2D: -case 0xEC2D: -case 0xEE2D: -case 0xE02E: -case 0xE22E: -case 0xE42E: -case 0xE62E: -case 0xE82E: -case 0xEA2E: -case 0xEC2E: -case 0xEE2E: -case 0xE02F: -case 0xE22F: -case 0xE42F: -case 0xE62F: -case 0xE82F: -case 0xEA2F: -case 0xEC2F: -case 0xEE2F: - -// LSRD -case 0xE028: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 8) - { - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE268: -case 0xE468: -case 0xE668: -case 0xE868: -case 0xEA68: -case 0xEC68: -case 0xEE68: -case 0xE069: -case 0xE269: -case 0xE469: -case 0xE669: -case 0xE869: -case 0xEA69: -case 0xEC69: -case 0xEE69: -case 0xE06A: -case 0xE26A: -case 0xE46A: -case 0xE66A: -case 0xE86A: -case 0xEA6A: -case 0xEC6A: -case 0xEE6A: -case 0xE06B: -case 0xE26B: -case 0xE46B: -case 0xE66B: -case 0xE86B: -case 0xEA6B: -case 0xEC6B: -case 0xEE6B: -case 0xE06C: -case 0xE26C: -case 0xE46C: -case 0xE66C: -case 0xE86C: -case 0xEA6C: -case 0xEC6C: -case 0xEE6C: -case 0xE06D: -case 0xE26D: -case 0xE46D: -case 0xE66D: -case 0xE86D: -case 0xEA6D: -case 0xEC6D: -case 0xEE6D: -case 0xE06E: -case 0xE26E: -case 0xE46E: -case 0xE66E: -case 0xE86E: -case 0xEA6E: -case 0xEC6E: -case 0xEE6E: -case 0xE06F: -case 0xE26F: -case 0xE46F: -case 0xE66F: -case 0xE86F: -case 0xEA6F: -case 0xEC6F: -case 0xEE6F: - -// LSRD -case 0xE068: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 16) - { - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = src >> sft; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2A8: -case 0xE4A8: -case 0xE6A8: -case 0xE8A8: -case 0xEAA8: -case 0xECA8: -case 0xEEA8: -case 0xE0A9: -case 0xE2A9: -case 0xE4A9: -case 0xE6A9: -case 0xE8A9: -case 0xEAA9: -case 0xECA9: -case 0xEEA9: -case 0xE0AA: -case 0xE2AA: -case 0xE4AA: -case 0xE6AA: -case 0xE8AA: -case 0xEAAA: -case 0xECAA: -case 0xEEAA: -case 0xE0AB: -case 0xE2AB: -case 0xE4AB: -case 0xE6AB: -case 0xE8AB: -case 0xEAAB: -case 0xECAB: -case 0xEEAB: -case 0xE0AC: -case 0xE2AC: -case 0xE4AC: -case 0xE6AC: -case 0xE8AC: -case 0xEAAC: -case 0xECAC: -case 0xEEAC: -case 0xE0AD: -case 0xE2AD: -case 0xE4AD: -case 0xE6AD: -case 0xE8AD: -case 0xEAAD: -case 0xECAD: -case 0xEEAD: -case 0xE0AE: -case 0xE2AE: -case 0xE4AE: -case 0xE6AE: -case 0xE8AE: -case 0xEAAE: -case 0xECAE: -case 0xEEAE: -case 0xE0AF: -case 0xE2AF: -case 0xE4AF: -case 0xE6AF: -case 0xE8AF: -case 0xEAAF: -case 0xECAF: -case 0xEEAF: - -// LSRD -case 0xE0A8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = src >> sft; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - if (sft == 32) CPU->flag_C = src >> (31 - C68K_SR_C_SFT); - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE230: -case 0xE430: -case 0xE630: -case 0xE830: -case 0xEA30: -case 0xEC30: -case 0xEE30: -case 0xE031: -case 0xE231: -case 0xE431: -case 0xE631: -case 0xE831: -case 0xEA31: -case 0xEC31: -case 0xEE31: -case 0xE032: -case 0xE232: -case 0xE432: -case 0xE632: -case 0xE832: -case 0xEA32: -case 0xEC32: -case 0xEE32: -case 0xE033: -case 0xE233: -case 0xE433: -case 0xE633: -case 0xE833: -case 0xEA33: -case 0xEC33: -case 0xEE33: -case 0xE034: -case 0xE234: -case 0xE434: -case 0xE634: -case 0xE834: -case 0xEA34: -case 0xEC34: -case 0xEE34: -case 0xE035: -case 0xE235: -case 0xE435: -case 0xE635: -case 0xE835: -case 0xEA35: -case 0xEC35: -case 0xEE35: -case 0xE036: -case 0xE236: -case 0xE436: -case 0xE636: -case 0xE836: -case 0xEA36: -case 0xEC36: -case 0xEE36: -case 0xE037: -case 0xE237: -case 0xE437: -case 0xE637: -case 0xE837: -case 0xEA37: -case 0xEC37: -case 0xEE37: - -// ROXRD -case 0xE030: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 9; - - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src >> sft) | (src << (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE270: -case 0xE470: -case 0xE670: -case 0xE870: -case 0xEA70: -case 0xEC70: -case 0xEE70: -case 0xE071: -case 0xE271: -case 0xE471: -case 0xE671: -case 0xE871: -case 0xEA71: -case 0xEC71: -case 0xEE71: -case 0xE072: -case 0xE272: -case 0xE472: -case 0xE672: -case 0xE872: -case 0xEA72: -case 0xEC72: -case 0xEE72: -case 0xE073: -case 0xE273: -case 0xE473: -case 0xE673: -case 0xE873: -case 0xEA73: -case 0xEC73: -case 0xEE73: -case 0xE074: -case 0xE274: -case 0xE474: -case 0xE674: -case 0xE874: -case 0xEA74: -case 0xEC74: -case 0xEE74: -case 0xE075: -case 0xE275: -case 0xE475: -case 0xE675: -case 0xE875: -case 0xEA75: -case 0xEC75: -case 0xEE75: -case 0xE076: -case 0xE276: -case 0xE476: -case 0xE676: -case 0xE876: -case 0xEA76: -case 0xEC76: -case 0xEE76: -case 0xE077: -case 0xE277: -case 0xE477: -case 0xE677: -case 0xE877: -case 0xEA77: -case 0xEC77: -case 0xEE77: - -// ROXRD -case 0xE070: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 17; - - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src >> sft) | (src << (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2B0: -case 0xE4B0: -case 0xE6B0: -case 0xE8B0: -case 0xEAB0: -case 0xECB0: -case 0xEEB0: -case 0xE0B1: -case 0xE2B1: -case 0xE4B1: -case 0xE6B1: -case 0xE8B1: -case 0xEAB1: -case 0xECB1: -case 0xEEB1: -case 0xE0B2: -case 0xE2B2: -case 0xE4B2: -case 0xE6B2: -case 0xE8B2: -case 0xEAB2: -case 0xECB2: -case 0xEEB2: -case 0xE0B3: -case 0xE2B3: -case 0xE4B3: -case 0xE6B3: -case 0xE8B3: -case 0xEAB3: -case 0xECB3: -case 0xEEB3: -case 0xE0B4: -case 0xE2B4: -case 0xE4B4: -case 0xE6B4: -case 0xE8B4: -case 0xEAB4: -case 0xECB4: -case 0xEEB4: -case 0xE0B5: -case 0xE2B5: -case 0xE4B5: -case 0xE6B5: -case 0xE8B5: -case 0xEAB5: -case 0xECB5: -case 0xEEB5: -case 0xE0B6: -case 0xE2B6: -case 0xE4B6: -case 0xE6B6: -case 0xE8B6: -case 0xEAB6: -case 0xECB6: -case 0xEEB6: -case 0xE0B7: -case 0xE2B7: -case 0xE4B7: -case 0xE6B7: -case 0xE8B7: -case 0xEAB7: -case 0xECB7: -case 0xEEB7: - -// ROXRD -case 0xE0B0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 33; - - if (sft != 0) - { - if (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))); - else res = (src >> sft) | (src << (33 - sft)) | (((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))) >> (sft - 1)); - CPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT; - } - else res = src; - CPU->flag_C = CPU->flag_X; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE238: -case 0xE438: -case 0xE638: -case 0xE838: -case 0xEA38: -case 0xEC38: -case 0xEE38: -case 0xE039: -case 0xE239: -case 0xE439: -case 0xE639: -case 0xE839: -case 0xEA39: -case 0xEC39: -case 0xEE39: -case 0xE03A: -case 0xE23A: -case 0xE43A: -case 0xE63A: -case 0xE83A: -case 0xEA3A: -case 0xEC3A: -case 0xEE3A: -case 0xE03B: -case 0xE23B: -case 0xE43B: -case 0xE63B: -case 0xE83B: -case 0xEA3B: -case 0xEC3B: -case 0xEE3B: -case 0xE03C: -case 0xE23C: -case 0xE43C: -case 0xE63C: -case 0xE83C: -case 0xEA3C: -case 0xEC3C: -case 0xEE3C: -case 0xE03D: -case 0xE23D: -case 0xE43D: -case 0xE63D: -case 0xE83D: -case 0xEA3D: -case 0xEC3D: -case 0xEE3D: -case 0xE03E: -case 0xE23E: -case 0xE43E: -case 0xE63E: -case 0xE83E: -case 0xEA3E: -case 0xEC3E: -case 0xEE3E: -case 0xE03F: -case 0xE23F: -case 0xE43F: -case 0xE63F: -case 0xE83F: -case 0xEA3F: -case 0xEC3F: -case 0xEE3F: - -// RORD -case 0xE038: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft &= 0x07; - - CPU->flag_C = src << (C68K_SR_C_SFT - ((sft - 1) & 7)); - res = (src >> sft) | (src << (8 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE278: -case 0xE478: -case 0xE678: -case 0xE878: -case 0xEA78: -case 0xEC78: -case 0xEE78: -case 0xE079: -case 0xE279: -case 0xE479: -case 0xE679: -case 0xE879: -case 0xEA79: -case 0xEC79: -case 0xEE79: -case 0xE07A: -case 0xE27A: -case 0xE47A: -case 0xE67A: -case 0xE87A: -case 0xEA7A: -case 0xEC7A: -case 0xEE7A: -case 0xE07B: -case 0xE27B: -case 0xE47B: -case 0xE67B: -case 0xE87B: -case 0xEA7B: -case 0xEC7B: -case 0xEE7B: -case 0xE07C: -case 0xE27C: -case 0xE47C: -case 0xE67C: -case 0xE87C: -case 0xEA7C: -case 0xEC7C: -case 0xEE7C: -case 0xE07D: -case 0xE27D: -case 0xE47D: -case 0xE67D: -case 0xE87D: -case 0xEA7D: -case 0xEC7D: -case 0xEE7D: -case 0xE07E: -case 0xE27E: -case 0xE47E: -case 0xE67E: -case 0xE87E: -case 0xEA7E: -case 0xEC7E: -case 0xEE7E: -case 0xE07F: -case 0xE27F: -case 0xE47F: -case 0xE67F: -case 0xE87F: -case 0xEA7F: -case 0xEC7F: -case 0xEE7F: - -// RORD -case 0xE078: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft &= 0x0F; - - CPU->flag_C = (src >> ((sft - 1) & 15)) << C68K_SR_C_SFT; - res = (src >> sft) | (src << (16 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2B8: -case 0xE4B8: -case 0xE6B8: -case 0xE8B8: -case 0xEAB8: -case 0xECB8: -case 0xEEB8: -case 0xE0B9: -case 0xE2B9: -case 0xE4B9: -case 0xE6B9: -case 0xE8B9: -case 0xEAB9: -case 0xECB9: -case 0xEEB9: -case 0xE0BA: -case 0xE2BA: -case 0xE4BA: -case 0xE6BA: -case 0xE8BA: -case 0xEABA: -case 0xECBA: -case 0xEEBA: -case 0xE0BB: -case 0xE2BB: -case 0xE4BB: -case 0xE6BB: -case 0xE8BB: -case 0xEABB: -case 0xECBB: -case 0xEEBB: -case 0xE0BC: -case 0xE2BC: -case 0xE4BC: -case 0xE6BC: -case 0xE8BC: -case 0xEABC: -case 0xECBC: -case 0xEEBC: -case 0xE0BD: -case 0xE2BD: -case 0xE4BD: -case 0xE6BD: -case 0xE8BD: -case 0xEABD: -case 0xECBD: -case 0xEEBD: -case 0xE0BE: -case 0xE2BE: -case 0xE4BE: -case 0xE6BE: -case 0xE8BE: -case 0xEABE: -case 0xECBE: -case 0xEEBE: -case 0xE0BF: -case 0xE2BF: -case 0xE4BF: -case 0xE6BF: -case 0xE8BF: -case 0xEABF: -case 0xECBF: -case 0xEEBF: - -// RORD -case 0xE0B8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft &= 0x1F; - - CPU->flag_C = (src >> ((sft - 1) & 31)) << C68K_SR_C_SFT; - res = (src >> sft) | (src << (32 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE320: -case 0xE520: -case 0xE720: -case 0xE920: -case 0xEB20: -case 0xED20: -case 0xEF20: -case 0xE121: -case 0xE321: -case 0xE521: -case 0xE721: -case 0xE921: -case 0xEB21: -case 0xED21: -case 0xEF21: -case 0xE122: -case 0xE322: -case 0xE522: -case 0xE722: -case 0xE922: -case 0xEB22: -case 0xED22: -case 0xEF22: -case 0xE123: -case 0xE323: -case 0xE523: -case 0xE723: -case 0xE923: -case 0xEB23: -case 0xED23: -case 0xEF23: -case 0xE124: -case 0xE324: -case 0xE524: -case 0xE724: -case 0xE924: -case 0xEB24: -case 0xED24: -case 0xEF24: -case 0xE125: -case 0xE325: -case 0xE525: -case 0xE725: -case 0xE925: -case 0xEB25: -case 0xED25: -case 0xEF25: -case 0xE126: -case 0xE326: -case 0xE526: -case 0xE726: -case 0xE926: -case 0xEB26: -case 0xED26: -case 0xEF26: -case 0xE127: -case 0xE327: -case 0xE527: -case 0xE727: -case 0xE927: -case 0xEB27: -case 0xED27: -case 0xEF27: - -// ASLD -case 0xE120: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 8) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 0; - res = (src << sft) & 0x000000FF; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 24)) & 0x000000FF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(6) - } - - if (sft == 256) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE360: -case 0xE560: -case 0xE760: -case 0xE960: -case 0xEB60: -case 0xED60: -case 0xEF60: -case 0xE161: -case 0xE361: -case 0xE561: -case 0xE761: -case 0xE961: -case 0xEB61: -case 0xED61: -case 0xEF61: -case 0xE162: -case 0xE362: -case 0xE562: -case 0xE762: -case 0xE962: -case 0xEB62: -case 0xED62: -case 0xEF62: -case 0xE163: -case 0xE363: -case 0xE563: -case 0xE763: -case 0xE963: -case 0xEB63: -case 0xED63: -case 0xEF63: -case 0xE164: -case 0xE364: -case 0xE564: -case 0xE764: -case 0xE964: -case 0xEB64: -case 0xED64: -case 0xEF64: -case 0xE165: -case 0xE365: -case 0xE565: -case 0xE765: -case 0xE965: -case 0xEB65: -case 0xED65: -case 0xEF65: -case 0xE166: -case 0xE366: -case 0xE566: -case 0xE766: -case 0xE966: -case 0xEB66: -case 0xED66: -case 0xEF66: -case 0xE167: -case 0xE367: -case 0xE567: -case 0xE767: -case 0xE967: -case 0xEB67: -case 0xED67: -case 0xEF67: - -// ASLD -case 0xE160: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 16) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 8; - res = (src << sft) & 0x0000FFFF; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 16)) & 0x0000FFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(6) - } - - if (sft == 65536) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3A0: -case 0xE5A0: -case 0xE7A0: -case 0xE9A0: -case 0xEBA0: -case 0xEDA0: -case 0xEFA0: -case 0xE1A1: -case 0xE3A1: -case 0xE5A1: -case 0xE7A1: -case 0xE9A1: -case 0xEBA1: -case 0xEDA1: -case 0xEFA1: -case 0xE1A2: -case 0xE3A2: -case 0xE5A2: -case 0xE7A2: -case 0xE9A2: -case 0xEBA2: -case 0xEDA2: -case 0xEFA2: -case 0xE1A3: -case 0xE3A3: -case 0xE5A3: -case 0xE7A3: -case 0xE9A3: -case 0xEBA3: -case 0xEDA3: -case 0xEFA3: -case 0xE1A4: -case 0xE3A4: -case 0xE5A4: -case 0xE7A4: -case 0xE9A4: -case 0xEBA4: -case 0xEDA4: -case 0xEFA4: -case 0xE1A5: -case 0xE3A5: -case 0xE5A5: -case 0xE7A5: -case 0xE9A5: -case 0xEBA5: -case 0xEDA5: -case 0xEFA5: -case 0xE1A6: -case 0xE3A6: -case 0xE5A6: -case 0xE7A6: -case 0xE9A6: -case 0xEBA6: -case 0xEDA6: -case 0xEFA6: -case 0xE1A7: -case 0xE3A7: -case 0xE5A7: -case 0xE7A7: -case 0xE9A7: -case 0xEBA7: -case 0xEDA7: -case 0xEFA7: - -// ASLD -case 0xE1A0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT; - res = src << sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 0)) & 0xFFFFFFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(8) - } - - if (sft == 0) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE328: -case 0xE528: -case 0xE728: -case 0xE928: -case 0xEB28: -case 0xED28: -case 0xEF28: -case 0xE129: -case 0xE329: -case 0xE529: -case 0xE729: -case 0xE929: -case 0xEB29: -case 0xED29: -case 0xEF29: -case 0xE12A: -case 0xE32A: -case 0xE52A: -case 0xE72A: -case 0xE92A: -case 0xEB2A: -case 0xED2A: -case 0xEF2A: -case 0xE12B: -case 0xE32B: -case 0xE52B: -case 0xE72B: -case 0xE92B: -case 0xEB2B: -case 0xED2B: -case 0xEF2B: -case 0xE12C: -case 0xE32C: -case 0xE52C: -case 0xE72C: -case 0xE92C: -case 0xEB2C: -case 0xED2C: -case 0xEF2C: -case 0xE12D: -case 0xE32D: -case 0xE52D: -case 0xE72D: -case 0xE92D: -case 0xEB2D: -case 0xED2D: -case 0xEF2D: -case 0xE12E: -case 0xE32E: -case 0xE52E: -case 0xE72E: -case 0xE92E: -case 0xEB2E: -case 0xED2E: -case 0xEF2E: -case 0xE12F: -case 0xE32F: -case 0xE52F: -case 0xE72F: -case 0xE92F: -case 0xEB2F: -case 0xED2F: -case 0xEF2F: - -// LSLD -case 0xE128: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 8) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 0; - res = (src << sft) & 0x000000FF; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE368: -case 0xE568: -case 0xE768: -case 0xE968: -case 0xEB68: -case 0xED68: -case 0xEF68: -case 0xE169: -case 0xE369: -case 0xE569: -case 0xE769: -case 0xE969: -case 0xEB69: -case 0xED69: -case 0xEF69: -case 0xE16A: -case 0xE36A: -case 0xE56A: -case 0xE76A: -case 0xE96A: -case 0xEB6A: -case 0xED6A: -case 0xEF6A: -case 0xE16B: -case 0xE36B: -case 0xE56B: -case 0xE76B: -case 0xE96B: -case 0xEB6B: -case 0xED6B: -case 0xEF6B: -case 0xE16C: -case 0xE36C: -case 0xE56C: -case 0xE76C: -case 0xE96C: -case 0xEB6C: -case 0xED6C: -case 0xEF6C: -case 0xE16D: -case 0xE36D: -case 0xE56D: -case 0xE76D: -case 0xE96D: -case 0xEB6D: -case 0xED6D: -case 0xEF6D: -case 0xE16E: -case 0xE36E: -case 0xE56E: -case 0xE76E: -case 0xE96E: -case 0xEB6E: -case 0xED6E: -case 0xEF6E: -case 0xE16F: -case 0xE36F: -case 0xE56F: -case 0xE76F: -case 0xE96F: -case 0xEB6F: -case 0xED6F: -case 0xEF6F: - -// LSLD -case 0xE168: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 16) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 8; - res = (src << sft) & 0x0000FFFF; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3A8: -case 0xE5A8: -case 0xE7A8: -case 0xE9A8: -case 0xEBA8: -case 0xEDA8: -case 0xEFA8: -case 0xE1A9: -case 0xE3A9: -case 0xE5A9: -case 0xE7A9: -case 0xE9A9: -case 0xEBA9: -case 0xEDA9: -case 0xEFA9: -case 0xE1AA: -case 0xE3AA: -case 0xE5AA: -case 0xE7AA: -case 0xE9AA: -case 0xEBAA: -case 0xEDAA: -case 0xEFAA: -case 0xE1AB: -case 0xE3AB: -case 0xE5AB: -case 0xE7AB: -case 0xE9AB: -case 0xEBAB: -case 0xEDAB: -case 0xEFAB: -case 0xE1AC: -case 0xE3AC: -case 0xE5AC: -case 0xE7AC: -case 0xE9AC: -case 0xEBAC: -case 0xEDAC: -case 0xEFAC: -case 0xE1AD: -case 0xE3AD: -case 0xE5AD: -case 0xE7AD: -case 0xE9AD: -case 0xEBAD: -case 0xEDAD: -case 0xEFAD: -case 0xE1AE: -case 0xE3AE: -case 0xE5AE: -case 0xE7AE: -case 0xE9AE: -case 0xEBAE: -case 0xEDAE: -case 0xEFAE: -case 0xE1AF: -case 0xE3AF: -case 0xE5AF: -case 0xE7AF: -case 0xE9AF: -case 0xEBAF: -case 0xEDAF: -case 0xEFAF: - -// LSLD -case 0xE1A8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT; - res = src << sft; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - if (sft == 32) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE330: -case 0xE530: -case 0xE730: -case 0xE930: -case 0xEB30: -case 0xED30: -case 0xEF30: -case 0xE131: -case 0xE331: -case 0xE531: -case 0xE731: -case 0xE931: -case 0xEB31: -case 0xED31: -case 0xEF31: -case 0xE132: -case 0xE332: -case 0xE532: -case 0xE732: -case 0xE932: -case 0xEB32: -case 0xED32: -case 0xEF32: -case 0xE133: -case 0xE333: -case 0xE533: -case 0xE733: -case 0xE933: -case 0xEB33: -case 0xED33: -case 0xEF33: -case 0xE134: -case 0xE334: -case 0xE534: -case 0xE734: -case 0xE934: -case 0xEB34: -case 0xED34: -case 0xEF34: -case 0xE135: -case 0xE335: -case 0xE535: -case 0xE735: -case 0xE935: -case 0xEB35: -case 0xED35: -case 0xEF35: -case 0xE136: -case 0xE336: -case 0xE536: -case 0xE736: -case 0xE936: -case 0xEB36: -case 0xED36: -case 0xEF36: -case 0xE137: -case 0xE337: -case 0xE537: -case 0xE737: -case 0xE937: -case 0xEB37: -case 0xED37: -case 0xEF37: - -// ROXLD -case 0xE130: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 9; - - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src << sft) | (src >> (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE370: -case 0xE570: -case 0xE770: -case 0xE970: -case 0xEB70: -case 0xED70: -case 0xEF70: -case 0xE171: -case 0xE371: -case 0xE571: -case 0xE771: -case 0xE971: -case 0xEB71: -case 0xED71: -case 0xEF71: -case 0xE172: -case 0xE372: -case 0xE572: -case 0xE772: -case 0xE972: -case 0xEB72: -case 0xED72: -case 0xEF72: -case 0xE173: -case 0xE373: -case 0xE573: -case 0xE773: -case 0xE973: -case 0xEB73: -case 0xED73: -case 0xEF73: -case 0xE174: -case 0xE374: -case 0xE574: -case 0xE774: -case 0xE974: -case 0xEB74: -case 0xED74: -case 0xEF74: -case 0xE175: -case 0xE375: -case 0xE575: -case 0xE775: -case 0xE975: -case 0xEB75: -case 0xED75: -case 0xEF75: -case 0xE176: -case 0xE376: -case 0xE576: -case 0xE776: -case 0xE976: -case 0xEB76: -case 0xED76: -case 0xEF76: -case 0xE177: -case 0xE377: -case 0xE577: -case 0xE777: -case 0xE977: -case 0xEB77: -case 0xED77: -case 0xEF77: - -// ROXLD -case 0xE170: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 17; - - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src << sft) | (src >> (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3B0: -case 0xE5B0: -case 0xE7B0: -case 0xE9B0: -case 0xEBB0: -case 0xEDB0: -case 0xEFB0: -case 0xE1B1: -case 0xE3B1: -case 0xE5B1: -case 0xE7B1: -case 0xE9B1: -case 0xEBB1: -case 0xEDB1: -case 0xEFB1: -case 0xE1B2: -case 0xE3B2: -case 0xE5B2: -case 0xE7B2: -case 0xE9B2: -case 0xEBB2: -case 0xEDB2: -case 0xEFB2: -case 0xE1B3: -case 0xE3B3: -case 0xE5B3: -case 0xE7B3: -case 0xE9B3: -case 0xEBB3: -case 0xEDB3: -case 0xEFB3: -case 0xE1B4: -case 0xE3B4: -case 0xE5B4: -case 0xE7B4: -case 0xE9B4: -case 0xEBB4: -case 0xEDB4: -case 0xEFB4: -case 0xE1B5: -case 0xE3B5: -case 0xE5B5: -case 0xE7B5: -case 0xE9B5: -case 0xEBB5: -case 0xEDB5: -case 0xEFB5: -case 0xE1B6: -case 0xE3B6: -case 0xE5B6: -case 0xE7B6: -case 0xE9B6: -case 0xEBB6: -case 0xEDB6: -case 0xEFB6: -case 0xE1B7: -case 0xE3B7: -case 0xE5B7: -case 0xE7B7: -case 0xE9B7: -case 0xEBB7: -case 0xEDB7: -case 0xEFB7: - -// ROXLD -case 0xE1B0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 33; - - if (sft != 0) - { - if (sft == 1) res = (src << 1) | ((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1); - else res = (src << sft) | (src >> (33 - sft)) | (((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1) << (sft - 1)); - CPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT; - } - else res = src; - CPU->flag_C = CPU->flag_X; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE338: -case 0xE538: -case 0xE738: -case 0xE938: -case 0xEB38: -case 0xED38: -case 0xEF38: -case 0xE139: -case 0xE339: -case 0xE539: -case 0xE739: -case 0xE939: -case 0xEB39: -case 0xED39: -case 0xEF39: -case 0xE13A: -case 0xE33A: -case 0xE53A: -case 0xE73A: -case 0xE93A: -case 0xEB3A: -case 0xED3A: -case 0xEF3A: -case 0xE13B: -case 0xE33B: -case 0xE53B: -case 0xE73B: -case 0xE93B: -case 0xEB3B: -case 0xED3B: -case 0xEF3B: -case 0xE13C: -case 0xE33C: -case 0xE53C: -case 0xE73C: -case 0xE93C: -case 0xEB3C: -case 0xED3C: -case 0xEF3C: -case 0xE13D: -case 0xE33D: -case 0xE53D: -case 0xE73D: -case 0xE93D: -case 0xEB3D: -case 0xED3D: -case 0xEF3D: -case 0xE13E: -case 0xE33E: -case 0xE53E: -case 0xE73E: -case 0xE93E: -case 0xEB3E: -case 0xED3E: -case 0xEF3E: -case 0xE13F: -case 0xE33F: -case 0xE53F: -case 0xE73F: -case 0xE93F: -case 0xEB3F: -case 0xED3F: -case 0xEF3F: - -// ROLD -case 0xE138: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft &= 0x07) - { - CPU->flag_C = (src << sft) >> 0; - res = ((src << sft) | (src >> (8 - sft))) & 0x000000FF; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE378: -case 0xE578: -case 0xE778: -case 0xE978: -case 0xEB78: -case 0xED78: -case 0xEF78: -case 0xE179: -case 0xE379: -case 0xE579: -case 0xE779: -case 0xE979: -case 0xEB79: -case 0xED79: -case 0xEF79: -case 0xE17A: -case 0xE37A: -case 0xE57A: -case 0xE77A: -case 0xE97A: -case 0xEB7A: -case 0xED7A: -case 0xEF7A: -case 0xE17B: -case 0xE37B: -case 0xE57B: -case 0xE77B: -case 0xE97B: -case 0xEB7B: -case 0xED7B: -case 0xEF7B: -case 0xE17C: -case 0xE37C: -case 0xE57C: -case 0xE77C: -case 0xE97C: -case 0xEB7C: -case 0xED7C: -case 0xEF7C: -case 0xE17D: -case 0xE37D: -case 0xE57D: -case 0xE77D: -case 0xE97D: -case 0xEB7D: -case 0xED7D: -case 0xEF7D: -case 0xE17E: -case 0xE37E: -case 0xE57E: -case 0xE77E: -case 0xE97E: -case 0xEB7E: -case 0xED7E: -case 0xEF7E: -case 0xE17F: -case 0xE37F: -case 0xE57F: -case 0xE77F: -case 0xE97F: -case 0xEB7F: -case 0xED7F: -case 0xEF7F: - -// ROLD -case 0xE178: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft &= 0x0F) - { - CPU->flag_C = (src << sft) >> 8; - res = ((src << sft) | (src >> (16 - sft))) & 0x0000FFFF; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3B8: -case 0xE5B8: -case 0xE7B8: -case 0xE9B8: -case 0xEBB8: -case 0xEDB8: -case 0xEFB8: -case 0xE1B9: -case 0xE3B9: -case 0xE5B9: -case 0xE7B9: -case 0xE9B9: -case 0xEBB9: -case 0xEDB9: -case 0xEFB9: -case 0xE1BA: -case 0xE3BA: -case 0xE5BA: -case 0xE7BA: -case 0xE9BA: -case 0xEBBA: -case 0xEDBA: -case 0xEFBA: -case 0xE1BB: -case 0xE3BB: -case 0xE5BB: -case 0xE7BB: -case 0xE9BB: -case 0xEBBB: -case 0xEDBB: -case 0xEFBB: -case 0xE1BC: -case 0xE3BC: -case 0xE5BC: -case 0xE7BC: -case 0xE9BC: -case 0xEBBC: -case 0xEDBC: -case 0xEFBC: -case 0xE1BD: -case 0xE3BD: -case 0xE5BD: -case 0xE7BD: -case 0xE9BD: -case 0xEBBD: -case 0xEDBD: -case 0xEFBD: -case 0xE1BE: -case 0xE3BE: -case 0xE5BE: -case 0xE7BE: -case 0xE9BE: -case 0xEBBE: -case 0xEDBE: -case 0xEFBE: -case 0xE1BF: -case 0xE3BF: -case 0xE5BF: -case 0xE7BF: -case 0xE9BF: -case 0xEBBF: -case 0xEDBF: -case 0xEFBF: - -// ROLD -case 0xE1B8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft &= 0x1F) - { - CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT; - res = (src << sft) | (src >> (32 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE0D1: -case 0xE0D2: -case 0xE0D3: -case 0xE0D4: -case 0xE0D5: -case 0xE0D6: -case 0xE0D7: - -// ASR -case 0xE0D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE0D9: -case 0xE0DA: -case 0xE0DB: -case 0xE0DC: -case 0xE0DD: -case 0xE0DE: - -// ASR -case 0xE0D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE0E1: -case 0xE0E2: -case 0xE0E3: -case 0xE0E4: -case 0xE0E5: -case 0xE0E6: - -// ASR -case 0xE0E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE0E9: -case 0xE0EA: -case 0xE0EB: -case 0xE0EC: -case 0xE0ED: -case 0xE0EE: -case 0xE0EF: - -// ASR -case 0xE0E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE0F1: -case 0xE0F2: -case 0xE0F3: -case 0xE0F4: -case 0xE0F5: -case 0xE0F6: -case 0xE0F7: - -// ASR -case 0xE0F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ASR -case 0xE0F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ASR -case 0xE0F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ASR -case 0xE0DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ASR -case 0xE0E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE2D1: -case 0xE2D2: -case 0xE2D3: -case 0xE2D4: -case 0xE2D5: -case 0xE2D6: -case 0xE2D7: - -// LSR -case 0xE2D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE2D9: -case 0xE2DA: -case 0xE2DB: -case 0xE2DC: -case 0xE2DD: -case 0xE2DE: - -// LSR -case 0xE2D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE2E1: -case 0xE2E2: -case 0xE2E3: -case 0xE2E4: -case 0xE2E5: -case 0xE2E6: - -// LSR -case 0xE2E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE2E9: -case 0xE2EA: -case 0xE2EB: -case 0xE2EC: -case 0xE2ED: -case 0xE2EE: -case 0xE2EF: - -// LSR -case 0xE2E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE2F1: -case 0xE2F2: -case 0xE2F3: -case 0xE2F4: -case 0xE2F5: -case 0xE2F6: -case 0xE2F7: - -// LSR -case 0xE2F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// LSR -case 0xE2F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// LSR -case 0xE2F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// LSR -case 0xE2DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// LSR -case 0xE2E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE4D1: -case 0xE4D2: -case 0xE4D3: -case 0xE4D4: -case 0xE4D5: -case 0xE4D6: -case 0xE4D7: - -// ROXR -case 0xE4D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE4D9: -case 0xE4DA: -case 0xE4DB: -case 0xE4DC: -case 0xE4DD: -case 0xE4DE: - -// ROXR -case 0xE4D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE4E1: -case 0xE4E2: -case 0xE4E3: -case 0xE4E4: -case 0xE4E5: -case 0xE4E6: - -// ROXR -case 0xE4E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE4E9: -case 0xE4EA: -case 0xE4EB: -case 0xE4EC: -case 0xE4ED: -case 0xE4EE: -case 0xE4EF: - -// ROXR -case 0xE4E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE4F1: -case 0xE4F2: -case 0xE4F3: -case 0xE4F4: -case 0xE4F5: -case 0xE4F6: -case 0xE4F7: - -// ROXR -case 0xE4F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROXR -case 0xE4F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROXR -case 0xE4F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROXR -case 0xE4DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROXR -case 0xE4E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE6D1: -case 0xE6D2: -case 0xE6D3: -case 0xE6D4: -case 0xE6D5: -case 0xE6D6: -case 0xE6D7: - -// ROR -case 0xE6D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE6D9: -case 0xE6DA: -case 0xE6DB: -case 0xE6DC: -case 0xE6DD: -case 0xE6DE: - -// ROR -case 0xE6D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE6E1: -case 0xE6E2: -case 0xE6E3: -case 0xE6E4: -case 0xE6E5: -case 0xE6E6: - -// ROR -case 0xE6E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE6E9: -case 0xE6EA: -case 0xE6EB: -case 0xE6EC: -case 0xE6ED: -case 0xE6EE: -case 0xE6EF: - -// ROR -case 0xE6E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE6F1: -case 0xE6F2: -case 0xE6F3: -case 0xE6F4: -case 0xE6F5: -case 0xE6F6: -case 0xE6F7: - -// ROR -case 0xE6F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROR -case 0xE6F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROR -case 0xE6F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROR -case 0xE6DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROR -case 0xE6E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE1D1: -case 0xE1D2: -case 0xE1D3: -case 0xE1D4: -case 0xE1D5: -case 0xE1D6: -case 0xE1D7: - -// ASL -case 0xE1D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE1D9: -case 0xE1DA: -case 0xE1DB: -case 0xE1DC: -case 0xE1DD: -case 0xE1DE: - -// ASL -case 0xE1D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE1E1: -case 0xE1E2: -case 0xE1E3: -case 0xE1E4: -case 0xE1E5: -case 0xE1E6: - -// ASL -case 0xE1E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE1E9: -case 0xE1EA: -case 0xE1EB: -case 0xE1EC: -case 0xE1ED: -case 0xE1EE: -case 0xE1EF: - -// ASL -case 0xE1E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE1F1: -case 0xE1F2: -case 0xE1F3: -case 0xE1F4: -case 0xE1F5: -case 0xE1F6: -case 0xE1F7: - -// ASL -case 0xE1F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ASL -case 0xE1F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ASL -case 0xE1F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ASL -case 0xE1DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ASL -case 0xE1E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE3D1: -case 0xE3D2: -case 0xE3D3: -case 0xE3D4: -case 0xE3D5: -case 0xE3D6: -case 0xE3D7: - -// LSL -case 0xE3D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE3D9: -case 0xE3DA: -case 0xE3DB: -case 0xE3DC: -case 0xE3DD: -case 0xE3DE: - -// LSL -case 0xE3D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE3E1: -case 0xE3E2: -case 0xE3E3: -case 0xE3E4: -case 0xE3E5: -case 0xE3E6: - -// LSL -case 0xE3E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE3E9: -case 0xE3EA: -case 0xE3EB: -case 0xE3EC: -case 0xE3ED: -case 0xE3EE: -case 0xE3EF: - -// LSL -case 0xE3E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE3F1: -case 0xE3F2: -case 0xE3F3: -case 0xE3F4: -case 0xE3F5: -case 0xE3F6: -case 0xE3F7: - -// LSL -case 0xE3F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// LSL -case 0xE3F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// LSL -case 0xE3F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// LSL -case 0xE3DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// LSL -case 0xE3E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE5D1: -case 0xE5D2: -case 0xE5D3: -case 0xE5D4: -case 0xE5D5: -case 0xE5D6: -case 0xE5D7: - -// ROXL -case 0xE5D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE5D9: -case 0xE5DA: -case 0xE5DB: -case 0xE5DC: -case 0xE5DD: -case 0xE5DE: - -// ROXL -case 0xE5D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE5E1: -case 0xE5E2: -case 0xE5E3: -case 0xE5E4: -case 0xE5E5: -case 0xE5E6: - -// ROXL -case 0xE5E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE5E9: -case 0xE5EA: -case 0xE5EB: -case 0xE5EC: -case 0xE5ED: -case 0xE5EE: -case 0xE5EF: - -// ROXL -case 0xE5E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE5F1: -case 0xE5F2: -case 0xE5F3: -case 0xE5F4: -case 0xE5F5: -case 0xE5F6: -case 0xE5F7: - -// ROXL -case 0xE5F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROXL -case 0xE5F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROXL -case 0xE5F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROXL -case 0xE5DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROXL -case 0xE5E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE7D1: -case 0xE7D2: -case 0xE7D3: -case 0xE7D4: -case 0xE7D5: -case 0xE7D6: -case 0xE7D7: - -// ROL -case 0xE7D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE7D9: -case 0xE7DA: -case 0xE7DB: -case 0xE7DC: -case 0xE7DD: -case 0xE7DE: - -// ROL -case 0xE7D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE7E1: -case 0xE7E2: -case 0xE7E3: -case 0xE7E4: -case 0xE7E5: -case 0xE7E6: - -// ROL -case 0xE7E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE7E9: -case 0xE7EA: -case 0xE7EB: -case 0xE7EC: -case 0xE7ED: -case 0xE7EE: -case 0xE7EF: - -// ROL -case 0xE7E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE7F1: -case 0xE7F2: -case 0xE7F3: -case 0xE7F4: -case 0xE7F5: -case 0xE7F6: -case 0xE7F7: - -// ROL -case 0xE7F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROL -case 0xE7F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROL -case 0xE7F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROL -case 0xE7DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROL -case 0xE7E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) diff --git a/yabause/src/c68k/c68k_opF.inc b/yabause/src/c68k/c68k_opF.inc deleted file mode 100644 index 802c9b31b8..0000000000 --- a/yabause/src/c68k/c68k_opF.inc +++ /dev/null @@ -1,4118 +0,0 @@ -case 0xF001: -case 0xF002: -case 0xF003: -case 0xF004: -case 0xF005: -case 0xF006: -case 0xF007: -case 0xF008: -case 0xF009: -case 0xF00A: -case 0xF00B: -case 0xF00C: -case 0xF00D: -case 0xF00E: -case 0xF00F: -case 0xF010: -case 0xF011: -case 0xF012: -case 0xF013: -case 0xF014: -case 0xF015: -case 0xF016: -case 0xF017: -case 0xF018: -case 0xF019: -case 0xF01A: -case 0xF01B: -case 0xF01C: -case 0xF01D: -case 0xF01E: -case 0xF01F: -case 0xF020: -case 0xF021: -case 0xF022: -case 0xF023: -case 0xF024: -case 0xF025: -case 0xF026: -case 0xF027: -case 0xF028: -case 0xF029: -case 0xF02A: -case 0xF02B: -case 0xF02C: -case 0xF02D: -case 0xF02E: -case 0xF02F: -case 0xF030: -case 0xF031: -case 0xF032: -case 0xF033: -case 0xF034: -case 0xF035: -case 0xF036: -case 0xF037: -case 0xF038: -case 0xF039: -case 0xF03A: -case 0xF03B: -case 0xF03C: -case 0xF03D: -case 0xF03E: -case 0xF03F: -case 0xF040: -case 0xF041: -case 0xF042: -case 0xF043: -case 0xF044: -case 0xF045: -case 0xF046: -case 0xF047: -case 0xF048: -case 0xF049: -case 0xF04A: -case 0xF04B: -case 0xF04C: -case 0xF04D: -case 0xF04E: -case 0xF04F: -case 0xF050: -case 0xF051: -case 0xF052: -case 0xF053: -case 0xF054: -case 0xF055: -case 0xF056: -case 0xF057: -case 0xF058: -case 0xF059: -case 0xF05A: -case 0xF05B: -case 0xF05C: -case 0xF05D: -case 0xF05E: -case 0xF05F: -case 0xF060: -case 0xF061: -case 0xF062: -case 0xF063: -case 0xF064: -case 0xF065: -case 0xF066: -case 0xF067: -case 0xF068: -case 0xF069: -case 0xF06A: -case 0xF06B: -case 0xF06C: -case 0xF06D: -case 0xF06E: -case 0xF06F: -case 0xF070: -case 0xF071: -case 0xF072: -case 0xF073: -case 0xF074: -case 0xF075: -case 0xF076: -case 0xF077: -case 0xF078: -case 0xF079: -case 0xF07A: -case 0xF07B: -case 0xF07C: -case 0xF07D: -case 0xF07E: -case 0xF07F: -case 0xF080: -case 0xF081: -case 0xF082: -case 0xF083: -case 0xF084: -case 0xF085: -case 0xF086: -case 0xF087: -case 0xF088: -case 0xF089: -case 0xF08A: -case 0xF08B: -case 0xF08C: -case 0xF08D: -case 0xF08E: -case 0xF08F: -case 0xF090: -case 0xF091: -case 0xF092: -case 0xF093: -case 0xF094: -case 0xF095: -case 0xF096: -case 0xF097: -case 0xF098: -case 0xF099: -case 0xF09A: -case 0xF09B: -case 0xF09C: -case 0xF09D: -case 0xF09E: -case 0xF09F: -case 0xF0A0: -case 0xF0A1: -case 0xF0A2: -case 0xF0A3: -case 0xF0A4: -case 0xF0A5: -case 0xF0A6: -case 0xF0A7: -case 0xF0A8: -case 0xF0A9: -case 0xF0AA: -case 0xF0AB: -case 0xF0AC: -case 0xF0AD: -case 0xF0AE: -case 0xF0AF: -case 0xF0B0: -case 0xF0B1: -case 0xF0B2: -case 0xF0B3: -case 0xF0B4: -case 0xF0B5: -case 0xF0B6: -case 0xF0B7: -case 0xF0B8: -case 0xF0B9: -case 0xF0BA: -case 0xF0BB: -case 0xF0BC: -case 0xF0BD: -case 0xF0BE: -case 0xF0BF: -case 0xF0C0: -case 0xF0C1: -case 0xF0C2: -case 0xF0C3: -case 0xF0C4: -case 0xF0C5: -case 0xF0C6: -case 0xF0C7: -case 0xF0C8: -case 0xF0C9: -case 0xF0CA: -case 0xF0CB: -case 0xF0CC: -case 0xF0CD: -case 0xF0CE: -case 0xF0CF: -case 0xF0D0: -case 0xF0D1: -case 0xF0D2: -case 0xF0D3: -case 0xF0D4: -case 0xF0D5: -case 0xF0D6: -case 0xF0D7: -case 0xF0D8: -case 0xF0D9: -case 0xF0DA: -case 0xF0DB: -case 0xF0DC: -case 0xF0DD: -case 0xF0DE: -case 0xF0DF: -case 0xF0E0: -case 0xF0E1: -case 0xF0E2: -case 0xF0E3: -case 0xF0E4: -case 0xF0E5: -case 0xF0E6: -case 0xF0E7: -case 0xF0E8: -case 0xF0E9: -case 0xF0EA: -case 0xF0EB: -case 0xF0EC: -case 0xF0ED: -case 0xF0EE: -case 0xF0EF: -case 0xF0F0: -case 0xF0F1: -case 0xF0F2: -case 0xF0F3: -case 0xF0F4: -case 0xF0F5: -case 0xF0F6: -case 0xF0F7: -case 0xF0F8: -case 0xF0F9: -case 0xF0FA: -case 0xF0FB: -case 0xF0FC: -case 0xF0FD: -case 0xF0FE: -case 0xF0FF: -case 0xF100: -case 0xF101: -case 0xF102: -case 0xF103: -case 0xF104: -case 0xF105: -case 0xF106: -case 0xF107: -case 0xF108: -case 0xF109: -case 0xF10A: -case 0xF10B: -case 0xF10C: -case 0xF10D: -case 0xF10E: -case 0xF10F: -case 0xF110: -case 0xF111: -case 0xF112: -case 0xF113: -case 0xF114: -case 0xF115: -case 0xF116: -case 0xF117: -case 0xF118: -case 0xF119: -case 0xF11A: -case 0xF11B: -case 0xF11C: -case 0xF11D: -case 0xF11E: -case 0xF11F: -case 0xF120: -case 0xF121: -case 0xF122: -case 0xF123: -case 0xF124: -case 0xF125: -case 0xF126: -case 0xF127: -case 0xF128: -case 0xF129: -case 0xF12A: -case 0xF12B: -case 0xF12C: -case 0xF12D: -case 0xF12E: -case 0xF12F: -case 0xF130: -case 0xF131: -case 0xF132: -case 0xF133: -case 0xF134: -case 0xF135: -case 0xF136: -case 0xF137: -case 0xF138: -case 0xF139: -case 0xF13A: -case 0xF13B: -case 0xF13C: -case 0xF13D: -case 0xF13E: -case 0xF13F: -case 0xF140: -case 0xF141: -case 0xF142: -case 0xF143: -case 0xF144: -case 0xF145: -case 0xF146: -case 0xF147: -case 0xF148: -case 0xF149: -case 0xF14A: -case 0xF14B: -case 0xF14C: -case 0xF14D: -case 0xF14E: -case 0xF14F: -case 0xF150: -case 0xF151: -case 0xF152: -case 0xF153: -case 0xF154: -case 0xF155: -case 0xF156: -case 0xF157: -case 0xF158: -case 0xF159: -case 0xF15A: -case 0xF15B: -case 0xF15C: -case 0xF15D: -case 0xF15E: -case 0xF15F: -case 0xF160: -case 0xF161: -case 0xF162: -case 0xF163: -case 0xF164: -case 0xF165: -case 0xF166: -case 0xF167: -case 0xF168: -case 0xF169: -case 0xF16A: -case 0xF16B: -case 0xF16C: -case 0xF16D: -case 0xF16E: -case 0xF16F: -case 0xF170: -case 0xF171: -case 0xF172: -case 0xF173: -case 0xF174: -case 0xF175: -case 0xF176: -case 0xF177: -case 0xF178: -case 0xF179: -case 0xF17A: -case 0xF17B: -case 0xF17C: -case 0xF17D: -case 0xF17E: -case 0xF17F: -case 0xF180: -case 0xF181: -case 0xF182: -case 0xF183: -case 0xF184: -case 0xF185: -case 0xF186: -case 0xF187: -case 0xF188: -case 0xF189: -case 0xF18A: -case 0xF18B: -case 0xF18C: -case 0xF18D: -case 0xF18E: -case 0xF18F: -case 0xF190: -case 0xF191: -case 0xF192: -case 0xF193: -case 0xF194: -case 0xF195: -case 0xF196: -case 0xF197: -case 0xF198: -case 0xF199: -case 0xF19A: -case 0xF19B: -case 0xF19C: -case 0xF19D: -case 0xF19E: -case 0xF19F: -case 0xF1A0: -case 0xF1A1: -case 0xF1A2: -case 0xF1A3: -case 0xF1A4: -case 0xF1A5: -case 0xF1A6: -case 0xF1A7: -case 0xF1A8: -case 0xF1A9: -case 0xF1AA: -case 0xF1AB: -case 0xF1AC: -case 0xF1AD: -case 0xF1AE: -case 0xF1AF: -case 0xF1B0: -case 0xF1B1: -case 0xF1B2: -case 0xF1B3: -case 0xF1B4: -case 0xF1B5: -case 0xF1B6: -case 0xF1B7: -case 0xF1B8: -case 0xF1B9: -case 0xF1BA: -case 0xF1BB: -case 0xF1BC: -case 0xF1BD: -case 0xF1BE: -case 0xF1BF: -case 0xF1C0: -case 0xF1C1: -case 0xF1C2: -case 0xF1C3: -case 0xF1C4: -case 0xF1C5: -case 0xF1C6: -case 0xF1C7: -case 0xF1C8: -case 0xF1C9: -case 0xF1CA: -case 0xF1CB: -case 0xF1CC: -case 0xF1CD: -case 0xF1CE: -case 0xF1CF: -case 0xF1D0: -case 0xF1D1: -case 0xF1D2: -case 0xF1D3: -case 0xF1D4: -case 0xF1D5: -case 0xF1D6: -case 0xF1D7: -case 0xF1D8: -case 0xF1D9: -case 0xF1DA: -case 0xF1DB: -case 0xF1DC: -case 0xF1DD: -case 0xF1DE: -case 0xF1DF: -case 0xF1E0: -case 0xF1E1: -case 0xF1E2: -case 0xF1E3: -case 0xF1E4: -case 0xF1E5: -case 0xF1E6: -case 0xF1E7: -case 0xF1E8: -case 0xF1E9: -case 0xF1EA: -case 0xF1EB: -case 0xF1EC: -case 0xF1ED: -case 0xF1EE: -case 0xF1EF: -case 0xF1F0: -case 0xF1F1: -case 0xF1F2: -case 0xF1F3: -case 0xF1F4: -case 0xF1F5: -case 0xF1F6: -case 0xF1F7: -case 0xF1F8: -case 0xF1F9: -case 0xF1FA: -case 0xF1FB: -case 0xF1FC: -case 0xF1FD: -case 0xF1FE: -case 0xF1FF: -case 0xF200: -case 0xF201: -case 0xF202: -case 0xF203: -case 0xF204: -case 0xF205: -case 0xF206: -case 0xF207: -case 0xF208: -case 0xF209: -case 0xF20A: -case 0xF20B: -case 0xF20C: -case 0xF20D: -case 0xF20E: -case 0xF20F: -case 0xF210: -case 0xF211: -case 0xF212: -case 0xF213: -case 0xF214: -case 0xF215: -case 0xF216: -case 0xF217: -case 0xF218: -case 0xF219: -case 0xF21A: -case 0xF21B: -case 0xF21C: -case 0xF21D: -case 0xF21E: -case 0xF21F: -case 0xF220: -case 0xF221: -case 0xF222: -case 0xF223: -case 0xF224: -case 0xF225: -case 0xF226: -case 0xF227: -case 0xF228: -case 0xF229: -case 0xF22A: -case 0xF22B: -case 0xF22C: -case 0xF22D: -case 0xF22E: -case 0xF22F: -case 0xF230: -case 0xF231: -case 0xF232: -case 0xF233: -case 0xF234: -case 0xF235: -case 0xF236: -case 0xF237: -case 0xF238: -case 0xF239: -case 0xF23A: -case 0xF23B: -case 0xF23C: -case 0xF23D: -case 0xF23E: -case 0xF23F: -case 0xF240: -case 0xF241: -case 0xF242: -case 0xF243: -case 0xF244: -case 0xF245: -case 0xF246: -case 0xF247: -case 0xF248: -case 0xF249: -case 0xF24A: -case 0xF24B: -case 0xF24C: -case 0xF24D: -case 0xF24E: -case 0xF24F: -case 0xF250: -case 0xF251: -case 0xF252: -case 0xF253: -case 0xF254: -case 0xF255: -case 0xF256: -case 0xF257: -case 0xF258: -case 0xF259: -case 0xF25A: -case 0xF25B: -case 0xF25C: -case 0xF25D: -case 0xF25E: -case 0xF25F: -case 0xF260: -case 0xF261: -case 0xF262: -case 0xF263: -case 0xF264: -case 0xF265: -case 0xF266: -case 0xF267: -case 0xF268: -case 0xF269: -case 0xF26A: -case 0xF26B: -case 0xF26C: -case 0xF26D: -case 0xF26E: -case 0xF26F: -case 0xF270: -case 0xF271: -case 0xF272: -case 0xF273: -case 0xF274: -case 0xF275: -case 0xF276: -case 0xF277: -case 0xF278: -case 0xF279: -case 0xF27A: -case 0xF27B: -case 0xF27C: -case 0xF27D: -case 0xF27E: -case 0xF27F: -case 0xF280: -case 0xF281: -case 0xF282: -case 0xF283: -case 0xF284: -case 0xF285: -case 0xF286: -case 0xF287: -case 0xF288: -case 0xF289: -case 0xF28A: -case 0xF28B: -case 0xF28C: -case 0xF28D: -case 0xF28E: -case 0xF28F: -case 0xF290: -case 0xF291: -case 0xF292: -case 0xF293: -case 0xF294: -case 0xF295: -case 0xF296: -case 0xF297: -case 0xF298: -case 0xF299: -case 0xF29A: -case 0xF29B: -case 0xF29C: -case 0xF29D: -case 0xF29E: -case 0xF29F: -case 0xF2A0: -case 0xF2A1: -case 0xF2A2: -case 0xF2A3: -case 0xF2A4: -case 0xF2A5: -case 0xF2A6: -case 0xF2A7: -case 0xF2A8: -case 0xF2A9: -case 0xF2AA: -case 0xF2AB: -case 0xF2AC: -case 0xF2AD: -case 0xF2AE: -case 0xF2AF: -case 0xF2B0: -case 0xF2B1: -case 0xF2B2: -case 0xF2B3: -case 0xF2B4: -case 0xF2B5: -case 0xF2B6: -case 0xF2B7: -case 0xF2B8: -case 0xF2B9: -case 0xF2BA: -case 0xF2BB: -case 0xF2BC: -case 0xF2BD: -case 0xF2BE: -case 0xF2BF: -case 0xF2C0: -case 0xF2C1: -case 0xF2C2: -case 0xF2C3: -case 0xF2C4: -case 0xF2C5: -case 0xF2C6: -case 0xF2C7: -case 0xF2C8: -case 0xF2C9: -case 0xF2CA: -case 0xF2CB: -case 0xF2CC: -case 0xF2CD: -case 0xF2CE: -case 0xF2CF: -case 0xF2D0: -case 0xF2D1: -case 0xF2D2: -case 0xF2D3: -case 0xF2D4: -case 0xF2D5: -case 0xF2D6: -case 0xF2D7: -case 0xF2D8: -case 0xF2D9: -case 0xF2DA: -case 0xF2DB: -case 0xF2DC: -case 0xF2DD: -case 0xF2DE: -case 0xF2DF: -case 0xF2E0: -case 0xF2E1: -case 0xF2E2: -case 0xF2E3: -case 0xF2E4: -case 0xF2E5: -case 0xF2E6: -case 0xF2E7: -case 0xF2E8: -case 0xF2E9: -case 0xF2EA: -case 0xF2EB: -case 0xF2EC: -case 0xF2ED: -case 0xF2EE: -case 0xF2EF: -case 0xF2F0: -case 0xF2F1: -case 0xF2F2: -case 0xF2F3: -case 0xF2F4: -case 0xF2F5: -case 0xF2F6: -case 0xF2F7: -case 0xF2F8: -case 0xF2F9: -case 0xF2FA: -case 0xF2FB: -case 0xF2FC: -case 0xF2FD: -case 0xF2FE: -case 0xF2FF: -case 0xF300: -case 0xF301: -case 0xF302: -case 0xF303: -case 0xF304: -case 0xF305: -case 0xF306: -case 0xF307: -case 0xF308: -case 0xF309: -case 0xF30A: -case 0xF30B: -case 0xF30C: -case 0xF30D: -case 0xF30E: -case 0xF30F: -case 0xF310: -case 0xF311: -case 0xF312: -case 0xF313: -case 0xF314: -case 0xF315: -case 0xF316: -case 0xF317: -case 0xF318: -case 0xF319: -case 0xF31A: -case 0xF31B: -case 0xF31C: -case 0xF31D: -case 0xF31E: -case 0xF31F: -case 0xF320: -case 0xF321: -case 0xF322: -case 0xF323: -case 0xF324: -case 0xF325: -case 0xF326: -case 0xF327: -case 0xF328: -case 0xF329: -case 0xF32A: -case 0xF32B: -case 0xF32C: -case 0xF32D: -case 0xF32E: -case 0xF32F: -case 0xF330: -case 0xF331: -case 0xF332: -case 0xF333: -case 0xF334: -case 0xF335: -case 0xF336: -case 0xF337: -case 0xF338: -case 0xF339: -case 0xF33A: -case 0xF33B: -case 0xF33C: -case 0xF33D: -case 0xF33E: -case 0xF33F: -case 0xF340: -case 0xF341: -case 0xF342: -case 0xF343: -case 0xF344: -case 0xF345: -case 0xF346: -case 0xF347: -case 0xF348: -case 0xF349: -case 0xF34A: -case 0xF34B: -case 0xF34C: -case 0xF34D: -case 0xF34E: -case 0xF34F: -case 0xF350: -case 0xF351: -case 0xF352: -case 0xF353: -case 0xF354: -case 0xF355: -case 0xF356: -case 0xF357: -case 0xF358: -case 0xF359: -case 0xF35A: -case 0xF35B: -case 0xF35C: -case 0xF35D: -case 0xF35E: -case 0xF35F: -case 0xF360: -case 0xF361: -case 0xF362: -case 0xF363: -case 0xF364: -case 0xF365: -case 0xF366: -case 0xF367: -case 0xF368: -case 0xF369: -case 0xF36A: -case 0xF36B: -case 0xF36C: -case 0xF36D: -case 0xF36E: -case 0xF36F: -case 0xF370: -case 0xF371: -case 0xF372: -case 0xF373: -case 0xF374: -case 0xF375: -case 0xF376: -case 0xF377: -case 0xF378: -case 0xF379: -case 0xF37A: -case 0xF37B: -case 0xF37C: -case 0xF37D: -case 0xF37E: -case 0xF37F: -case 0xF380: -case 0xF381: -case 0xF382: -case 0xF383: -case 0xF384: -case 0xF385: -case 0xF386: -case 0xF387: -case 0xF388: -case 0xF389: -case 0xF38A: -case 0xF38B: -case 0xF38C: -case 0xF38D: -case 0xF38E: -case 0xF38F: -case 0xF390: -case 0xF391: -case 0xF392: -case 0xF393: -case 0xF394: -case 0xF395: -case 0xF396: -case 0xF397: -case 0xF398: -case 0xF399: -case 0xF39A: -case 0xF39B: -case 0xF39C: -case 0xF39D: -case 0xF39E: -case 0xF39F: -case 0xF3A0: -case 0xF3A1: -case 0xF3A2: -case 0xF3A3: -case 0xF3A4: -case 0xF3A5: -case 0xF3A6: -case 0xF3A7: -case 0xF3A8: -case 0xF3A9: -case 0xF3AA: -case 0xF3AB: -case 0xF3AC: -case 0xF3AD: -case 0xF3AE: -case 0xF3AF: -case 0xF3B0: -case 0xF3B1: -case 0xF3B2: -case 0xF3B3: -case 0xF3B4: -case 0xF3B5: -case 0xF3B6: -case 0xF3B7: -case 0xF3B8: -case 0xF3B9: -case 0xF3BA: -case 0xF3BB: -case 0xF3BC: -case 0xF3BD: -case 0xF3BE: -case 0xF3BF: -case 0xF3C0: -case 0xF3C1: -case 0xF3C2: -case 0xF3C3: -case 0xF3C4: -case 0xF3C5: -case 0xF3C6: -case 0xF3C7: -case 0xF3C8: -case 0xF3C9: -case 0xF3CA: -case 0xF3CB: -case 0xF3CC: -case 0xF3CD: -case 0xF3CE: -case 0xF3CF: -case 0xF3D0: -case 0xF3D1: -case 0xF3D2: -case 0xF3D3: -case 0xF3D4: -case 0xF3D5: -case 0xF3D6: -case 0xF3D7: -case 0xF3D8: -case 0xF3D9: -case 0xF3DA: -case 0xF3DB: -case 0xF3DC: -case 0xF3DD: -case 0xF3DE: -case 0xF3DF: -case 0xF3E0: -case 0xF3E1: -case 0xF3E2: -case 0xF3E3: -case 0xF3E4: -case 0xF3E5: -case 0xF3E6: -case 0xF3E7: -case 0xF3E8: -case 0xF3E9: -case 0xF3EA: -case 0xF3EB: -case 0xF3EC: -case 0xF3ED: -case 0xF3EE: -case 0xF3EF: -case 0xF3F0: -case 0xF3F1: -case 0xF3F2: -case 0xF3F3: -case 0xF3F4: -case 0xF3F5: -case 0xF3F6: -case 0xF3F7: -case 0xF3F8: -case 0xF3F9: -case 0xF3FA: -case 0xF3FB: -case 0xF3FC: -case 0xF3FD: -case 0xF3FE: -case 0xF3FF: -case 0xF400: -case 0xF401: -case 0xF402: -case 0xF403: -case 0xF404: -case 0xF405: -case 0xF406: -case 0xF407: -case 0xF408: -case 0xF409: -case 0xF40A: -case 0xF40B: -case 0xF40C: -case 0xF40D: -case 0xF40E: -case 0xF40F: -case 0xF410: -case 0xF411: -case 0xF412: -case 0xF413: -case 0xF414: -case 0xF415: -case 0xF416: -case 0xF417: -case 0xF418: -case 0xF419: -case 0xF41A: -case 0xF41B: -case 0xF41C: -case 0xF41D: -case 0xF41E: -case 0xF41F: -case 0xF420: -case 0xF421: -case 0xF422: -case 0xF423: -case 0xF424: -case 0xF425: -case 0xF426: -case 0xF427: -case 0xF428: -case 0xF429: -case 0xF42A: -case 0xF42B: -case 0xF42C: -case 0xF42D: -case 0xF42E: -case 0xF42F: -case 0xF430: -case 0xF431: -case 0xF432: -case 0xF433: -case 0xF434: -case 0xF435: -case 0xF436: -case 0xF437: -case 0xF438: -case 0xF439: -case 0xF43A: -case 0xF43B: -case 0xF43C: -case 0xF43D: -case 0xF43E: -case 0xF43F: -case 0xF440: -case 0xF441: -case 0xF442: -case 0xF443: -case 0xF444: -case 0xF445: -case 0xF446: -case 0xF447: -case 0xF448: -case 0xF449: -case 0xF44A: -case 0xF44B: -case 0xF44C: -case 0xF44D: -case 0xF44E: -case 0xF44F: -case 0xF450: -case 0xF451: -case 0xF452: -case 0xF453: -case 0xF454: -case 0xF455: -case 0xF456: -case 0xF457: -case 0xF458: -case 0xF459: -case 0xF45A: -case 0xF45B: -case 0xF45C: -case 0xF45D: -case 0xF45E: -case 0xF45F: -case 0xF460: -case 0xF461: -case 0xF462: -case 0xF463: -case 0xF464: -case 0xF465: -case 0xF466: -case 0xF467: -case 0xF468: -case 0xF469: -case 0xF46A: -case 0xF46B: -case 0xF46C: -case 0xF46D: -case 0xF46E: -case 0xF46F: -case 0xF470: -case 0xF471: -case 0xF472: -case 0xF473: -case 0xF474: -case 0xF475: -case 0xF476: -case 0xF477: -case 0xF478: -case 0xF479: -case 0xF47A: -case 0xF47B: -case 0xF47C: -case 0xF47D: -case 0xF47E: -case 0xF47F: -case 0xF480: -case 0xF481: -case 0xF482: -case 0xF483: -case 0xF484: -case 0xF485: -case 0xF486: -case 0xF487: -case 0xF488: -case 0xF489: -case 0xF48A: -case 0xF48B: -case 0xF48C: -case 0xF48D: -case 0xF48E: -case 0xF48F: -case 0xF490: -case 0xF491: -case 0xF492: -case 0xF493: -case 0xF494: -case 0xF495: -case 0xF496: -case 0xF497: -case 0xF498: -case 0xF499: -case 0xF49A: -case 0xF49B: -case 0xF49C: -case 0xF49D: -case 0xF49E: -case 0xF49F: -case 0xF4A0: -case 0xF4A1: -case 0xF4A2: -case 0xF4A3: -case 0xF4A4: -case 0xF4A5: -case 0xF4A6: -case 0xF4A7: -case 0xF4A8: -case 0xF4A9: -case 0xF4AA: -case 0xF4AB: -case 0xF4AC: -case 0xF4AD: -case 0xF4AE: -case 0xF4AF: -case 0xF4B0: -case 0xF4B1: -case 0xF4B2: -case 0xF4B3: -case 0xF4B4: -case 0xF4B5: -case 0xF4B6: -case 0xF4B7: -case 0xF4B8: -case 0xF4B9: -case 0xF4BA: -case 0xF4BB: -case 0xF4BC: -case 0xF4BD: -case 0xF4BE: -case 0xF4BF: -case 0xF4C0: -case 0xF4C1: -case 0xF4C2: -case 0xF4C3: -case 0xF4C4: -case 0xF4C5: -case 0xF4C6: -case 0xF4C7: -case 0xF4C8: -case 0xF4C9: -case 0xF4CA: -case 0xF4CB: -case 0xF4CC: -case 0xF4CD: -case 0xF4CE: -case 0xF4CF: -case 0xF4D0: -case 0xF4D1: -case 0xF4D2: -case 0xF4D3: -case 0xF4D4: -case 0xF4D5: -case 0xF4D6: -case 0xF4D7: -case 0xF4D8: -case 0xF4D9: -case 0xF4DA: -case 0xF4DB: -case 0xF4DC: -case 0xF4DD: -case 0xF4DE: -case 0xF4DF: -case 0xF4E0: -case 0xF4E1: -case 0xF4E2: -case 0xF4E3: -case 0xF4E4: -case 0xF4E5: -case 0xF4E6: -case 0xF4E7: -case 0xF4E8: -case 0xF4E9: -case 0xF4EA: -case 0xF4EB: -case 0xF4EC: -case 0xF4ED: -case 0xF4EE: -case 0xF4EF: -case 0xF4F0: -case 0xF4F1: -case 0xF4F2: -case 0xF4F3: -case 0xF4F4: -case 0xF4F5: -case 0xF4F6: -case 0xF4F7: -case 0xF4F8: -case 0xF4F9: -case 0xF4FA: -case 0xF4FB: -case 0xF4FC: -case 0xF4FD: -case 0xF4FE: -case 0xF4FF: -case 0xF500: -case 0xF501: -case 0xF502: -case 0xF503: -case 0xF504: -case 0xF505: -case 0xF506: -case 0xF507: -case 0xF508: -case 0xF509: -case 0xF50A: -case 0xF50B: -case 0xF50C: -case 0xF50D: -case 0xF50E: -case 0xF50F: -case 0xF510: -case 0xF511: -case 0xF512: -case 0xF513: -case 0xF514: -case 0xF515: -case 0xF516: -case 0xF517: -case 0xF518: -case 0xF519: -case 0xF51A: -case 0xF51B: -case 0xF51C: -case 0xF51D: -case 0xF51E: -case 0xF51F: -case 0xF520: -case 0xF521: -case 0xF522: -case 0xF523: -case 0xF524: -case 0xF525: -case 0xF526: -case 0xF527: -case 0xF528: -case 0xF529: -case 0xF52A: -case 0xF52B: -case 0xF52C: -case 0xF52D: -case 0xF52E: -case 0xF52F: -case 0xF530: -case 0xF531: -case 0xF532: -case 0xF533: -case 0xF534: -case 0xF535: -case 0xF536: -case 0xF537: -case 0xF538: -case 0xF539: -case 0xF53A: -case 0xF53B: -case 0xF53C: -case 0xF53D: -case 0xF53E: -case 0xF53F: -case 0xF540: -case 0xF541: -case 0xF542: -case 0xF543: -case 0xF544: -case 0xF545: -case 0xF546: -case 0xF547: -case 0xF548: -case 0xF549: -case 0xF54A: -case 0xF54B: -case 0xF54C: -case 0xF54D: -case 0xF54E: -case 0xF54F: -case 0xF550: -case 0xF551: -case 0xF552: -case 0xF553: -case 0xF554: -case 0xF555: -case 0xF556: -case 0xF557: -case 0xF558: -case 0xF559: -case 0xF55A: -case 0xF55B: -case 0xF55C: -case 0xF55D: -case 0xF55E: -case 0xF55F: -case 0xF560: -case 0xF561: -case 0xF562: -case 0xF563: -case 0xF564: -case 0xF565: -case 0xF566: -case 0xF567: -case 0xF568: -case 0xF569: -case 0xF56A: -case 0xF56B: -case 0xF56C: -case 0xF56D: -case 0xF56E: -case 0xF56F: -case 0xF570: -case 0xF571: -case 0xF572: -case 0xF573: -case 0xF574: -case 0xF575: -case 0xF576: -case 0xF577: -case 0xF578: -case 0xF579: -case 0xF57A: -case 0xF57B: -case 0xF57C: -case 0xF57D: -case 0xF57E: -case 0xF57F: -case 0xF580: -case 0xF581: -case 0xF582: -case 0xF583: -case 0xF584: -case 0xF585: -case 0xF586: -case 0xF587: -case 0xF588: -case 0xF589: -case 0xF58A: -case 0xF58B: -case 0xF58C: -case 0xF58D: -case 0xF58E: -case 0xF58F: -case 0xF590: -case 0xF591: -case 0xF592: -case 0xF593: -case 0xF594: -case 0xF595: -case 0xF596: -case 0xF597: -case 0xF598: -case 0xF599: -case 0xF59A: -case 0xF59B: -case 0xF59C: -case 0xF59D: -case 0xF59E: -case 0xF59F: -case 0xF5A0: -case 0xF5A1: -case 0xF5A2: -case 0xF5A3: -case 0xF5A4: -case 0xF5A5: -case 0xF5A6: -case 0xF5A7: -case 0xF5A8: -case 0xF5A9: -case 0xF5AA: -case 0xF5AB: -case 0xF5AC: -case 0xF5AD: -case 0xF5AE: -case 0xF5AF: -case 0xF5B0: -case 0xF5B1: -case 0xF5B2: -case 0xF5B3: -case 0xF5B4: -case 0xF5B5: -case 0xF5B6: -case 0xF5B7: -case 0xF5B8: -case 0xF5B9: -case 0xF5BA: -case 0xF5BB: -case 0xF5BC: -case 0xF5BD: -case 0xF5BE: -case 0xF5BF: -case 0xF5C0: -case 0xF5C1: -case 0xF5C2: -case 0xF5C3: -case 0xF5C4: -case 0xF5C5: -case 0xF5C6: -case 0xF5C7: -case 0xF5C8: -case 0xF5C9: -case 0xF5CA: -case 0xF5CB: -case 0xF5CC: -case 0xF5CD: -case 0xF5CE: -case 0xF5CF: -case 0xF5D0: -case 0xF5D1: -case 0xF5D2: -case 0xF5D3: -case 0xF5D4: -case 0xF5D5: -case 0xF5D6: -case 0xF5D7: -case 0xF5D8: -case 0xF5D9: -case 0xF5DA: -case 0xF5DB: -case 0xF5DC: -case 0xF5DD: -case 0xF5DE: -case 0xF5DF: -case 0xF5E0: -case 0xF5E1: -case 0xF5E2: -case 0xF5E3: -case 0xF5E4: -case 0xF5E5: -case 0xF5E6: -case 0xF5E7: -case 0xF5E8: -case 0xF5E9: -case 0xF5EA: -case 0xF5EB: -case 0xF5EC: -case 0xF5ED: -case 0xF5EE: -case 0xF5EF: -case 0xF5F0: -case 0xF5F1: -case 0xF5F2: -case 0xF5F3: -case 0xF5F4: -case 0xF5F5: -case 0xF5F6: -case 0xF5F7: -case 0xF5F8: -case 0xF5F9: -case 0xF5FA: -case 0xF5FB: -case 0xF5FC: -case 0xF5FD: -case 0xF5FE: -case 0xF5FF: -case 0xF600: -case 0xF601: -case 0xF602: -case 0xF603: -case 0xF604: -case 0xF605: -case 0xF606: -case 0xF607: -case 0xF608: -case 0xF609: -case 0xF60A: -case 0xF60B: -case 0xF60C: -case 0xF60D: -case 0xF60E: -case 0xF60F: -case 0xF610: -case 0xF611: -case 0xF612: -case 0xF613: -case 0xF614: -case 0xF615: -case 0xF616: -case 0xF617: -case 0xF618: -case 0xF619: -case 0xF61A: -case 0xF61B: -case 0xF61C: -case 0xF61D: -case 0xF61E: -case 0xF61F: -case 0xF620: -case 0xF621: -case 0xF622: -case 0xF623: -case 0xF624: -case 0xF625: -case 0xF626: -case 0xF627: -case 0xF628: -case 0xF629: -case 0xF62A: -case 0xF62B: -case 0xF62C: -case 0xF62D: -case 0xF62E: -case 0xF62F: -case 0xF630: -case 0xF631: -case 0xF632: -case 0xF633: -case 0xF634: -case 0xF635: -case 0xF636: -case 0xF637: -case 0xF638: -case 0xF639: -case 0xF63A: -case 0xF63B: -case 0xF63C: -case 0xF63D: -case 0xF63E: -case 0xF63F: -case 0xF640: -case 0xF641: -case 0xF642: -case 0xF643: -case 0xF644: -case 0xF645: -case 0xF646: -case 0xF647: -case 0xF648: -case 0xF649: -case 0xF64A: -case 0xF64B: -case 0xF64C: -case 0xF64D: -case 0xF64E: -case 0xF64F: -case 0xF650: -case 0xF651: -case 0xF652: -case 0xF653: -case 0xF654: -case 0xF655: -case 0xF656: -case 0xF657: -case 0xF658: -case 0xF659: -case 0xF65A: -case 0xF65B: -case 0xF65C: -case 0xF65D: -case 0xF65E: -case 0xF65F: -case 0xF660: -case 0xF661: -case 0xF662: -case 0xF663: -case 0xF664: -case 0xF665: -case 0xF666: -case 0xF667: -case 0xF668: -case 0xF669: -case 0xF66A: -case 0xF66B: -case 0xF66C: -case 0xF66D: -case 0xF66E: -case 0xF66F: -case 0xF670: -case 0xF671: -case 0xF672: -case 0xF673: -case 0xF674: -case 0xF675: -case 0xF676: -case 0xF677: -case 0xF678: -case 0xF679: -case 0xF67A: -case 0xF67B: -case 0xF67C: -case 0xF67D: -case 0xF67E: -case 0xF67F: -case 0xF680: -case 0xF681: -case 0xF682: -case 0xF683: -case 0xF684: -case 0xF685: -case 0xF686: -case 0xF687: -case 0xF688: -case 0xF689: -case 0xF68A: -case 0xF68B: -case 0xF68C: -case 0xF68D: -case 0xF68E: -case 0xF68F: -case 0xF690: -case 0xF691: -case 0xF692: -case 0xF693: -case 0xF694: -case 0xF695: -case 0xF696: -case 0xF697: -case 0xF698: -case 0xF699: -case 0xF69A: -case 0xF69B: -case 0xF69C: -case 0xF69D: -case 0xF69E: -case 0xF69F: -case 0xF6A0: -case 0xF6A1: -case 0xF6A2: -case 0xF6A3: -case 0xF6A4: -case 0xF6A5: -case 0xF6A6: -case 0xF6A7: -case 0xF6A8: -case 0xF6A9: -case 0xF6AA: -case 0xF6AB: -case 0xF6AC: -case 0xF6AD: -case 0xF6AE: -case 0xF6AF: -case 0xF6B0: -case 0xF6B1: -case 0xF6B2: -case 0xF6B3: -case 0xF6B4: -case 0xF6B5: -case 0xF6B6: -case 0xF6B7: -case 0xF6B8: -case 0xF6B9: -case 0xF6BA: -case 0xF6BB: -case 0xF6BC: -case 0xF6BD: -case 0xF6BE: -case 0xF6BF: -case 0xF6C0: -case 0xF6C1: -case 0xF6C2: -case 0xF6C3: -case 0xF6C4: -case 0xF6C5: -case 0xF6C6: -case 0xF6C7: -case 0xF6C8: -case 0xF6C9: -case 0xF6CA: -case 0xF6CB: -case 0xF6CC: -case 0xF6CD: -case 0xF6CE: -case 0xF6CF: -case 0xF6D0: -case 0xF6D1: -case 0xF6D2: -case 0xF6D3: -case 0xF6D4: -case 0xF6D5: -case 0xF6D6: -case 0xF6D7: -case 0xF6D8: -case 0xF6D9: -case 0xF6DA: -case 0xF6DB: -case 0xF6DC: -case 0xF6DD: -case 0xF6DE: -case 0xF6DF: -case 0xF6E0: -case 0xF6E1: -case 0xF6E2: -case 0xF6E3: -case 0xF6E4: -case 0xF6E5: -case 0xF6E6: -case 0xF6E7: -case 0xF6E8: -case 0xF6E9: -case 0xF6EA: -case 0xF6EB: -case 0xF6EC: -case 0xF6ED: -case 0xF6EE: -case 0xF6EF: -case 0xF6F0: -case 0xF6F1: -case 0xF6F2: -case 0xF6F3: -case 0xF6F4: -case 0xF6F5: -case 0xF6F6: -case 0xF6F7: -case 0xF6F8: -case 0xF6F9: -case 0xF6FA: -case 0xF6FB: -case 0xF6FC: -case 0xF6FD: -case 0xF6FE: -case 0xF6FF: -case 0xF700: -case 0xF701: -case 0xF702: -case 0xF703: -case 0xF704: -case 0xF705: -case 0xF706: -case 0xF707: -case 0xF708: -case 0xF709: -case 0xF70A: -case 0xF70B: -case 0xF70C: -case 0xF70D: -case 0xF70E: -case 0xF70F: -case 0xF710: -case 0xF711: -case 0xF712: -case 0xF713: -case 0xF714: -case 0xF715: -case 0xF716: -case 0xF717: -case 0xF718: -case 0xF719: -case 0xF71A: -case 0xF71B: -case 0xF71C: -case 0xF71D: -case 0xF71E: -case 0xF71F: -case 0xF720: -case 0xF721: -case 0xF722: -case 0xF723: -case 0xF724: -case 0xF725: -case 0xF726: -case 0xF727: -case 0xF728: -case 0xF729: -case 0xF72A: -case 0xF72B: -case 0xF72C: -case 0xF72D: -case 0xF72E: -case 0xF72F: -case 0xF730: -case 0xF731: -case 0xF732: -case 0xF733: -case 0xF734: -case 0xF735: -case 0xF736: -case 0xF737: -case 0xF738: -case 0xF739: -case 0xF73A: -case 0xF73B: -case 0xF73C: -case 0xF73D: -case 0xF73E: -case 0xF73F: -case 0xF740: -case 0xF741: -case 0xF742: -case 0xF743: -case 0xF744: -case 0xF745: -case 0xF746: -case 0xF747: -case 0xF748: -case 0xF749: -case 0xF74A: -case 0xF74B: -case 0xF74C: -case 0xF74D: -case 0xF74E: -case 0xF74F: -case 0xF750: -case 0xF751: -case 0xF752: -case 0xF753: -case 0xF754: -case 0xF755: -case 0xF756: -case 0xF757: -case 0xF758: -case 0xF759: -case 0xF75A: -case 0xF75B: -case 0xF75C: -case 0xF75D: -case 0xF75E: -case 0xF75F: -case 0xF760: -case 0xF761: -case 0xF762: -case 0xF763: -case 0xF764: -case 0xF765: -case 0xF766: -case 0xF767: -case 0xF768: -case 0xF769: -case 0xF76A: -case 0xF76B: -case 0xF76C: -case 0xF76D: -case 0xF76E: -case 0xF76F: -case 0xF770: -case 0xF771: -case 0xF772: -case 0xF773: -case 0xF774: -case 0xF775: -case 0xF776: -case 0xF777: -case 0xF778: -case 0xF779: -case 0xF77A: -case 0xF77B: -case 0xF77C: -case 0xF77D: -case 0xF77E: -case 0xF77F: -case 0xF780: -case 0xF781: -case 0xF782: -case 0xF783: -case 0xF784: -case 0xF785: -case 0xF786: -case 0xF787: -case 0xF788: -case 0xF789: -case 0xF78A: -case 0xF78B: -case 0xF78C: -case 0xF78D: -case 0xF78E: -case 0xF78F: -case 0xF790: -case 0xF791: -case 0xF792: -case 0xF793: -case 0xF794: -case 0xF795: -case 0xF796: -case 0xF797: -case 0xF798: -case 0xF799: -case 0xF79A: -case 0xF79B: -case 0xF79C: -case 0xF79D: -case 0xF79E: -case 0xF79F: -case 0xF7A0: -case 0xF7A1: -case 0xF7A2: -case 0xF7A3: -case 0xF7A4: -case 0xF7A5: -case 0xF7A6: -case 0xF7A7: -case 0xF7A8: -case 0xF7A9: -case 0xF7AA: -case 0xF7AB: -case 0xF7AC: -case 0xF7AD: -case 0xF7AE: -case 0xF7AF: -case 0xF7B0: -case 0xF7B1: -case 0xF7B2: -case 0xF7B3: -case 0xF7B4: -case 0xF7B5: -case 0xF7B6: -case 0xF7B7: -case 0xF7B8: -case 0xF7B9: -case 0xF7BA: -case 0xF7BB: -case 0xF7BC: -case 0xF7BD: -case 0xF7BE: -case 0xF7BF: -case 0xF7C0: -case 0xF7C1: -case 0xF7C2: -case 0xF7C3: -case 0xF7C4: -case 0xF7C5: -case 0xF7C6: -case 0xF7C7: -case 0xF7C8: -case 0xF7C9: -case 0xF7CA: -case 0xF7CB: -case 0xF7CC: -case 0xF7CD: -case 0xF7CE: -case 0xF7CF: -case 0xF7D0: -case 0xF7D1: -case 0xF7D2: -case 0xF7D3: -case 0xF7D4: -case 0xF7D5: -case 0xF7D6: -case 0xF7D7: -case 0xF7D8: -case 0xF7D9: -case 0xF7DA: -case 0xF7DB: -case 0xF7DC: -case 0xF7DD: -case 0xF7DE: -case 0xF7DF: -case 0xF7E0: -case 0xF7E1: -case 0xF7E2: -case 0xF7E3: -case 0xF7E4: -case 0xF7E5: -case 0xF7E6: -case 0xF7E7: -case 0xF7E8: -case 0xF7E9: -case 0xF7EA: -case 0xF7EB: -case 0xF7EC: -case 0xF7ED: -case 0xF7EE: -case 0xF7EF: -case 0xF7F0: -case 0xF7F1: -case 0xF7F2: -case 0xF7F3: -case 0xF7F4: -case 0xF7F5: -case 0xF7F6: -case 0xF7F7: -case 0xF7F8: -case 0xF7F9: -case 0xF7FA: -case 0xF7FB: -case 0xF7FC: -case 0xF7FD: -case 0xF7FE: -case 0xF7FF: -case 0xF800: -case 0xF801: -case 0xF802: -case 0xF803: -case 0xF804: -case 0xF805: -case 0xF806: -case 0xF807: -case 0xF808: -case 0xF809: -case 0xF80A: -case 0xF80B: -case 0xF80C: -case 0xF80D: -case 0xF80E: -case 0xF80F: -case 0xF810: -case 0xF811: -case 0xF812: -case 0xF813: -case 0xF814: -case 0xF815: -case 0xF816: -case 0xF817: -case 0xF818: -case 0xF819: -case 0xF81A: -case 0xF81B: -case 0xF81C: -case 0xF81D: -case 0xF81E: -case 0xF81F: -case 0xF820: -case 0xF821: -case 0xF822: -case 0xF823: -case 0xF824: -case 0xF825: -case 0xF826: -case 0xF827: -case 0xF828: -case 0xF829: -case 0xF82A: -case 0xF82B: -case 0xF82C: -case 0xF82D: -case 0xF82E: -case 0xF82F: -case 0xF830: -case 0xF831: -case 0xF832: -case 0xF833: -case 0xF834: -case 0xF835: -case 0xF836: -case 0xF837: -case 0xF838: -case 0xF839: -case 0xF83A: -case 0xF83B: -case 0xF83C: -case 0xF83D: -case 0xF83E: -case 0xF83F: -case 0xF840: -case 0xF841: -case 0xF842: -case 0xF843: -case 0xF844: -case 0xF845: -case 0xF846: -case 0xF847: -case 0xF848: -case 0xF849: -case 0xF84A: -case 0xF84B: -case 0xF84C: -case 0xF84D: -case 0xF84E: -case 0xF84F: -case 0xF850: -case 0xF851: -case 0xF852: -case 0xF853: -case 0xF854: -case 0xF855: -case 0xF856: -case 0xF857: -case 0xF858: -case 0xF859: -case 0xF85A: -case 0xF85B: -case 0xF85C: -case 0xF85D: -case 0xF85E: -case 0xF85F: -case 0xF860: -case 0xF861: -case 0xF862: -case 0xF863: -case 0xF864: -case 0xF865: -case 0xF866: -case 0xF867: -case 0xF868: -case 0xF869: -case 0xF86A: -case 0xF86B: -case 0xF86C: -case 0xF86D: -case 0xF86E: -case 0xF86F: -case 0xF870: -case 0xF871: -case 0xF872: -case 0xF873: -case 0xF874: -case 0xF875: -case 0xF876: -case 0xF877: -case 0xF878: -case 0xF879: -case 0xF87A: -case 0xF87B: -case 0xF87C: -case 0xF87D: -case 0xF87E: -case 0xF87F: -case 0xF880: -case 0xF881: -case 0xF882: -case 0xF883: -case 0xF884: -case 0xF885: -case 0xF886: -case 0xF887: -case 0xF888: -case 0xF889: -case 0xF88A: -case 0xF88B: -case 0xF88C: -case 0xF88D: -case 0xF88E: -case 0xF88F: -case 0xF890: -case 0xF891: -case 0xF892: -case 0xF893: -case 0xF894: -case 0xF895: -case 0xF896: -case 0xF897: -case 0xF898: -case 0xF899: -case 0xF89A: -case 0xF89B: -case 0xF89C: -case 0xF89D: -case 0xF89E: -case 0xF89F: -case 0xF8A0: -case 0xF8A1: -case 0xF8A2: -case 0xF8A3: -case 0xF8A4: -case 0xF8A5: -case 0xF8A6: -case 0xF8A7: -case 0xF8A8: -case 0xF8A9: -case 0xF8AA: -case 0xF8AB: -case 0xF8AC: -case 0xF8AD: -case 0xF8AE: -case 0xF8AF: -case 0xF8B0: -case 0xF8B1: -case 0xF8B2: -case 0xF8B3: -case 0xF8B4: -case 0xF8B5: -case 0xF8B6: -case 0xF8B7: -case 0xF8B8: -case 0xF8B9: -case 0xF8BA: -case 0xF8BB: -case 0xF8BC: -case 0xF8BD: -case 0xF8BE: -case 0xF8BF: -case 0xF8C0: -case 0xF8C1: -case 0xF8C2: -case 0xF8C3: -case 0xF8C4: -case 0xF8C5: -case 0xF8C6: -case 0xF8C7: -case 0xF8C8: -case 0xF8C9: -case 0xF8CA: -case 0xF8CB: -case 0xF8CC: -case 0xF8CD: -case 0xF8CE: -case 0xF8CF: -case 0xF8D0: -case 0xF8D1: -case 0xF8D2: -case 0xF8D3: -case 0xF8D4: -case 0xF8D5: -case 0xF8D6: -case 0xF8D7: -case 0xF8D8: -case 0xF8D9: -case 0xF8DA: -case 0xF8DB: -case 0xF8DC: -case 0xF8DD: -case 0xF8DE: -case 0xF8DF: -case 0xF8E0: -case 0xF8E1: -case 0xF8E2: -case 0xF8E3: -case 0xF8E4: -case 0xF8E5: -case 0xF8E6: -case 0xF8E7: -case 0xF8E8: -case 0xF8E9: -case 0xF8EA: -case 0xF8EB: -case 0xF8EC: -case 0xF8ED: -case 0xF8EE: -case 0xF8EF: -case 0xF8F0: -case 0xF8F1: -case 0xF8F2: -case 0xF8F3: -case 0xF8F4: -case 0xF8F5: -case 0xF8F6: -case 0xF8F7: -case 0xF8F8: -case 0xF8F9: -case 0xF8FA: -case 0xF8FB: -case 0xF8FC: -case 0xF8FD: -case 0xF8FE: -case 0xF8FF: -case 0xF900: -case 0xF901: -case 0xF902: -case 0xF903: -case 0xF904: -case 0xF905: -case 0xF906: -case 0xF907: -case 0xF908: -case 0xF909: -case 0xF90A: -case 0xF90B: -case 0xF90C: -case 0xF90D: -case 0xF90E: -case 0xF90F: -case 0xF910: -case 0xF911: -case 0xF912: -case 0xF913: -case 0xF914: -case 0xF915: -case 0xF916: -case 0xF917: -case 0xF918: -case 0xF919: -case 0xF91A: -case 0xF91B: -case 0xF91C: -case 0xF91D: -case 0xF91E: -case 0xF91F: -case 0xF920: -case 0xF921: -case 0xF922: -case 0xF923: -case 0xF924: -case 0xF925: -case 0xF926: -case 0xF927: -case 0xF928: -case 0xF929: -case 0xF92A: -case 0xF92B: -case 0xF92C: -case 0xF92D: -case 0xF92E: -case 0xF92F: -case 0xF930: -case 0xF931: -case 0xF932: -case 0xF933: -case 0xF934: -case 0xF935: -case 0xF936: -case 0xF937: -case 0xF938: -case 0xF939: -case 0xF93A: -case 0xF93B: -case 0xF93C: -case 0xF93D: -case 0xF93E: -case 0xF93F: -case 0xF940: -case 0xF941: -case 0xF942: -case 0xF943: -case 0xF944: -case 0xF945: -case 0xF946: -case 0xF947: -case 0xF948: -case 0xF949: -case 0xF94A: -case 0xF94B: -case 0xF94C: -case 0xF94D: -case 0xF94E: -case 0xF94F: -case 0xF950: -case 0xF951: -case 0xF952: -case 0xF953: -case 0xF954: -case 0xF955: -case 0xF956: -case 0xF957: -case 0xF958: -case 0xF959: -case 0xF95A: -case 0xF95B: -case 0xF95C: -case 0xF95D: -case 0xF95E: -case 0xF95F: -case 0xF960: -case 0xF961: -case 0xF962: -case 0xF963: -case 0xF964: -case 0xF965: -case 0xF966: -case 0xF967: -case 0xF968: -case 0xF969: -case 0xF96A: -case 0xF96B: -case 0xF96C: -case 0xF96D: -case 0xF96E: -case 0xF96F: -case 0xF970: -case 0xF971: -case 0xF972: -case 0xF973: -case 0xF974: -case 0xF975: -case 0xF976: -case 0xF977: -case 0xF978: -case 0xF979: -case 0xF97A: -case 0xF97B: -case 0xF97C: -case 0xF97D: -case 0xF97E: -case 0xF97F: -case 0xF980: -case 0xF981: -case 0xF982: -case 0xF983: -case 0xF984: -case 0xF985: -case 0xF986: -case 0xF987: -case 0xF988: -case 0xF989: -case 0xF98A: -case 0xF98B: -case 0xF98C: -case 0xF98D: -case 0xF98E: -case 0xF98F: -case 0xF990: -case 0xF991: -case 0xF992: -case 0xF993: -case 0xF994: -case 0xF995: -case 0xF996: -case 0xF997: -case 0xF998: -case 0xF999: -case 0xF99A: -case 0xF99B: -case 0xF99C: -case 0xF99D: -case 0xF99E: -case 0xF99F: -case 0xF9A0: -case 0xF9A1: -case 0xF9A2: -case 0xF9A3: -case 0xF9A4: -case 0xF9A5: -case 0xF9A6: -case 0xF9A7: -case 0xF9A8: -case 0xF9A9: -case 0xF9AA: -case 0xF9AB: -case 0xF9AC: -case 0xF9AD: -case 0xF9AE: -case 0xF9AF: -case 0xF9B0: -case 0xF9B1: -case 0xF9B2: -case 0xF9B3: -case 0xF9B4: -case 0xF9B5: -case 0xF9B6: -case 0xF9B7: -case 0xF9B8: -case 0xF9B9: -case 0xF9BA: -case 0xF9BB: -case 0xF9BC: -case 0xF9BD: -case 0xF9BE: -case 0xF9BF: -case 0xF9C0: -case 0xF9C1: -case 0xF9C2: -case 0xF9C3: -case 0xF9C4: -case 0xF9C5: -case 0xF9C6: -case 0xF9C7: -case 0xF9C8: -case 0xF9C9: -case 0xF9CA: -case 0xF9CB: -case 0xF9CC: -case 0xF9CD: -case 0xF9CE: -case 0xF9CF: -case 0xF9D0: -case 0xF9D1: -case 0xF9D2: -case 0xF9D3: -case 0xF9D4: -case 0xF9D5: -case 0xF9D6: -case 0xF9D7: -case 0xF9D8: -case 0xF9D9: -case 0xF9DA: -case 0xF9DB: -case 0xF9DC: -case 0xF9DD: -case 0xF9DE: -case 0xF9DF: -case 0xF9E0: -case 0xF9E1: -case 0xF9E2: -case 0xF9E3: -case 0xF9E4: -case 0xF9E5: -case 0xF9E6: -case 0xF9E7: -case 0xF9E8: -case 0xF9E9: -case 0xF9EA: -case 0xF9EB: -case 0xF9EC: -case 0xF9ED: -case 0xF9EE: -case 0xF9EF: -case 0xF9F0: -case 0xF9F1: -case 0xF9F2: -case 0xF9F3: -case 0xF9F4: -case 0xF9F5: -case 0xF9F6: -case 0xF9F7: -case 0xF9F8: -case 0xF9F9: -case 0xF9FA: -case 0xF9FB: -case 0xF9FC: -case 0xF9FD: -case 0xF9FE: -case 0xF9FF: -case 0xFA00: -case 0xFA01: -case 0xFA02: -case 0xFA03: -case 0xFA04: -case 0xFA05: -case 0xFA06: -case 0xFA07: -case 0xFA08: -case 0xFA09: -case 0xFA0A: -case 0xFA0B: -case 0xFA0C: -case 0xFA0D: -case 0xFA0E: -case 0xFA0F: -case 0xFA10: -case 0xFA11: -case 0xFA12: -case 0xFA13: -case 0xFA14: -case 0xFA15: -case 0xFA16: -case 0xFA17: -case 0xFA18: -case 0xFA19: -case 0xFA1A: -case 0xFA1B: -case 0xFA1C: -case 0xFA1D: -case 0xFA1E: -case 0xFA1F: -case 0xFA20: -case 0xFA21: -case 0xFA22: -case 0xFA23: -case 0xFA24: -case 0xFA25: -case 0xFA26: -case 0xFA27: -case 0xFA28: -case 0xFA29: -case 0xFA2A: -case 0xFA2B: -case 0xFA2C: -case 0xFA2D: -case 0xFA2E: -case 0xFA2F: -case 0xFA30: -case 0xFA31: -case 0xFA32: -case 0xFA33: -case 0xFA34: -case 0xFA35: -case 0xFA36: -case 0xFA37: -case 0xFA38: -case 0xFA39: -case 0xFA3A: -case 0xFA3B: -case 0xFA3C: -case 0xFA3D: -case 0xFA3E: -case 0xFA3F: -case 0xFA40: -case 0xFA41: -case 0xFA42: -case 0xFA43: -case 0xFA44: -case 0xFA45: -case 0xFA46: -case 0xFA47: -case 0xFA48: -case 0xFA49: -case 0xFA4A: -case 0xFA4B: -case 0xFA4C: -case 0xFA4D: -case 0xFA4E: -case 0xFA4F: -case 0xFA50: -case 0xFA51: -case 0xFA52: -case 0xFA53: -case 0xFA54: -case 0xFA55: -case 0xFA56: -case 0xFA57: -case 0xFA58: -case 0xFA59: -case 0xFA5A: -case 0xFA5B: -case 0xFA5C: -case 0xFA5D: -case 0xFA5E: -case 0xFA5F: -case 0xFA60: -case 0xFA61: -case 0xFA62: -case 0xFA63: -case 0xFA64: -case 0xFA65: -case 0xFA66: -case 0xFA67: -case 0xFA68: -case 0xFA69: -case 0xFA6A: -case 0xFA6B: -case 0xFA6C: -case 0xFA6D: -case 0xFA6E: -case 0xFA6F: -case 0xFA70: -case 0xFA71: -case 0xFA72: -case 0xFA73: -case 0xFA74: -case 0xFA75: -case 0xFA76: -case 0xFA77: -case 0xFA78: -case 0xFA79: -case 0xFA7A: -case 0xFA7B: -case 0xFA7C: -case 0xFA7D: -case 0xFA7E: -case 0xFA7F: -case 0xFA80: -case 0xFA81: -case 0xFA82: -case 0xFA83: -case 0xFA84: -case 0xFA85: -case 0xFA86: -case 0xFA87: -case 0xFA88: -case 0xFA89: -case 0xFA8A: -case 0xFA8B: -case 0xFA8C: -case 0xFA8D: -case 0xFA8E: -case 0xFA8F: -case 0xFA90: -case 0xFA91: -case 0xFA92: -case 0xFA93: -case 0xFA94: -case 0xFA95: -case 0xFA96: -case 0xFA97: -case 0xFA98: -case 0xFA99: -case 0xFA9A: -case 0xFA9B: -case 0xFA9C: -case 0xFA9D: -case 0xFA9E: -case 0xFA9F: -case 0xFAA0: -case 0xFAA1: -case 0xFAA2: -case 0xFAA3: -case 0xFAA4: -case 0xFAA5: -case 0xFAA6: -case 0xFAA7: -case 0xFAA8: -case 0xFAA9: -case 0xFAAA: -case 0xFAAB: -case 0xFAAC: -case 0xFAAD: -case 0xFAAE: -case 0xFAAF: -case 0xFAB0: -case 0xFAB1: -case 0xFAB2: -case 0xFAB3: -case 0xFAB4: -case 0xFAB5: -case 0xFAB6: -case 0xFAB7: -case 0xFAB8: -case 0xFAB9: -case 0xFABA: -case 0xFABB: -case 0xFABC: -case 0xFABD: -case 0xFABE: -case 0xFABF: -case 0xFAC0: -case 0xFAC1: -case 0xFAC2: -case 0xFAC3: -case 0xFAC4: -case 0xFAC5: -case 0xFAC6: -case 0xFAC7: -case 0xFAC8: -case 0xFAC9: -case 0xFACA: -case 0xFACB: -case 0xFACC: -case 0xFACD: -case 0xFACE: -case 0xFACF: -case 0xFAD0: -case 0xFAD1: -case 0xFAD2: -case 0xFAD3: -case 0xFAD4: -case 0xFAD5: -case 0xFAD6: -case 0xFAD7: -case 0xFAD8: -case 0xFAD9: -case 0xFADA: -case 0xFADB: -case 0xFADC: -case 0xFADD: -case 0xFADE: -case 0xFADF: -case 0xFAE0: -case 0xFAE1: -case 0xFAE2: -case 0xFAE3: -case 0xFAE4: -case 0xFAE5: -case 0xFAE6: -case 0xFAE7: -case 0xFAE8: -case 0xFAE9: -case 0xFAEA: -case 0xFAEB: -case 0xFAEC: -case 0xFAED: -case 0xFAEE: -case 0xFAEF: -case 0xFAF0: -case 0xFAF1: -case 0xFAF2: -case 0xFAF3: -case 0xFAF4: -case 0xFAF5: -case 0xFAF6: -case 0xFAF7: -case 0xFAF8: -case 0xFAF9: -case 0xFAFA: -case 0xFAFB: -case 0xFAFC: -case 0xFAFD: -case 0xFAFE: -case 0xFAFF: -case 0xFB00: -case 0xFB01: -case 0xFB02: -case 0xFB03: -case 0xFB04: -case 0xFB05: -case 0xFB06: -case 0xFB07: -case 0xFB08: -case 0xFB09: -case 0xFB0A: -case 0xFB0B: -case 0xFB0C: -case 0xFB0D: -case 0xFB0E: -case 0xFB0F: -case 0xFB10: -case 0xFB11: -case 0xFB12: -case 0xFB13: -case 0xFB14: -case 0xFB15: -case 0xFB16: -case 0xFB17: -case 0xFB18: -case 0xFB19: -case 0xFB1A: -case 0xFB1B: -case 0xFB1C: -case 0xFB1D: -case 0xFB1E: -case 0xFB1F: -case 0xFB20: -case 0xFB21: -case 0xFB22: -case 0xFB23: -case 0xFB24: -case 0xFB25: -case 0xFB26: -case 0xFB27: -case 0xFB28: -case 0xFB29: -case 0xFB2A: -case 0xFB2B: -case 0xFB2C: -case 0xFB2D: -case 0xFB2E: -case 0xFB2F: -case 0xFB30: -case 0xFB31: -case 0xFB32: -case 0xFB33: -case 0xFB34: -case 0xFB35: -case 0xFB36: -case 0xFB37: -case 0xFB38: -case 0xFB39: -case 0xFB3A: -case 0xFB3B: -case 0xFB3C: -case 0xFB3D: -case 0xFB3E: -case 0xFB3F: -case 0xFB40: -case 0xFB41: -case 0xFB42: -case 0xFB43: -case 0xFB44: -case 0xFB45: -case 0xFB46: -case 0xFB47: -case 0xFB48: -case 0xFB49: -case 0xFB4A: -case 0xFB4B: -case 0xFB4C: -case 0xFB4D: -case 0xFB4E: -case 0xFB4F: -case 0xFB50: -case 0xFB51: -case 0xFB52: -case 0xFB53: -case 0xFB54: -case 0xFB55: -case 0xFB56: -case 0xFB57: -case 0xFB58: -case 0xFB59: -case 0xFB5A: -case 0xFB5B: -case 0xFB5C: -case 0xFB5D: -case 0xFB5E: -case 0xFB5F: -case 0xFB60: -case 0xFB61: -case 0xFB62: -case 0xFB63: -case 0xFB64: -case 0xFB65: -case 0xFB66: -case 0xFB67: -case 0xFB68: -case 0xFB69: -case 0xFB6A: -case 0xFB6B: -case 0xFB6C: -case 0xFB6D: -case 0xFB6E: -case 0xFB6F: -case 0xFB70: -case 0xFB71: -case 0xFB72: -case 0xFB73: -case 0xFB74: -case 0xFB75: -case 0xFB76: -case 0xFB77: -case 0xFB78: -case 0xFB79: -case 0xFB7A: -case 0xFB7B: -case 0xFB7C: -case 0xFB7D: -case 0xFB7E: -case 0xFB7F: -case 0xFB80: -case 0xFB81: -case 0xFB82: -case 0xFB83: -case 0xFB84: -case 0xFB85: -case 0xFB86: -case 0xFB87: -case 0xFB88: -case 0xFB89: -case 0xFB8A: -case 0xFB8B: -case 0xFB8C: -case 0xFB8D: -case 0xFB8E: -case 0xFB8F: -case 0xFB90: -case 0xFB91: -case 0xFB92: -case 0xFB93: -case 0xFB94: -case 0xFB95: -case 0xFB96: -case 0xFB97: -case 0xFB98: -case 0xFB99: -case 0xFB9A: -case 0xFB9B: -case 0xFB9C: -case 0xFB9D: -case 0xFB9E: -case 0xFB9F: -case 0xFBA0: -case 0xFBA1: -case 0xFBA2: -case 0xFBA3: -case 0xFBA4: -case 0xFBA5: -case 0xFBA6: -case 0xFBA7: -case 0xFBA8: -case 0xFBA9: -case 0xFBAA: -case 0xFBAB: -case 0xFBAC: -case 0xFBAD: -case 0xFBAE: -case 0xFBAF: -case 0xFBB0: -case 0xFBB1: -case 0xFBB2: -case 0xFBB3: -case 0xFBB4: -case 0xFBB5: -case 0xFBB6: -case 0xFBB7: -case 0xFBB8: -case 0xFBB9: -case 0xFBBA: -case 0xFBBB: -case 0xFBBC: -case 0xFBBD: -case 0xFBBE: -case 0xFBBF: -case 0xFBC0: -case 0xFBC1: -case 0xFBC2: -case 0xFBC3: -case 0xFBC4: -case 0xFBC5: -case 0xFBC6: -case 0xFBC7: -case 0xFBC8: -case 0xFBC9: -case 0xFBCA: -case 0xFBCB: -case 0xFBCC: -case 0xFBCD: -case 0xFBCE: -case 0xFBCF: -case 0xFBD0: -case 0xFBD1: -case 0xFBD2: -case 0xFBD3: -case 0xFBD4: -case 0xFBD5: -case 0xFBD6: -case 0xFBD7: -case 0xFBD8: -case 0xFBD9: -case 0xFBDA: -case 0xFBDB: -case 0xFBDC: -case 0xFBDD: -case 0xFBDE: -case 0xFBDF: -case 0xFBE0: -case 0xFBE1: -case 0xFBE2: -case 0xFBE3: -case 0xFBE4: -case 0xFBE5: -case 0xFBE6: -case 0xFBE7: -case 0xFBE8: -case 0xFBE9: -case 0xFBEA: -case 0xFBEB: -case 0xFBEC: -case 0xFBED: -case 0xFBEE: -case 0xFBEF: -case 0xFBF0: -case 0xFBF1: -case 0xFBF2: -case 0xFBF3: -case 0xFBF4: -case 0xFBF5: -case 0xFBF6: -case 0xFBF7: -case 0xFBF8: -case 0xFBF9: -case 0xFBFA: -case 0xFBFB: -case 0xFBFC: -case 0xFBFD: -case 0xFBFE: -case 0xFBFF: -case 0xFC00: -case 0xFC01: -case 0xFC02: -case 0xFC03: -case 0xFC04: -case 0xFC05: -case 0xFC06: -case 0xFC07: -case 0xFC08: -case 0xFC09: -case 0xFC0A: -case 0xFC0B: -case 0xFC0C: -case 0xFC0D: -case 0xFC0E: -case 0xFC0F: -case 0xFC10: -case 0xFC11: -case 0xFC12: -case 0xFC13: -case 0xFC14: -case 0xFC15: -case 0xFC16: -case 0xFC17: -case 0xFC18: -case 0xFC19: -case 0xFC1A: -case 0xFC1B: -case 0xFC1C: -case 0xFC1D: -case 0xFC1E: -case 0xFC1F: -case 0xFC20: -case 0xFC21: -case 0xFC22: -case 0xFC23: -case 0xFC24: -case 0xFC25: -case 0xFC26: -case 0xFC27: -case 0xFC28: -case 0xFC29: -case 0xFC2A: -case 0xFC2B: -case 0xFC2C: -case 0xFC2D: -case 0xFC2E: -case 0xFC2F: -case 0xFC30: -case 0xFC31: -case 0xFC32: -case 0xFC33: -case 0xFC34: -case 0xFC35: -case 0xFC36: -case 0xFC37: -case 0xFC38: -case 0xFC39: -case 0xFC3A: -case 0xFC3B: -case 0xFC3C: -case 0xFC3D: -case 0xFC3E: -case 0xFC3F: -case 0xFC40: -case 0xFC41: -case 0xFC42: -case 0xFC43: -case 0xFC44: -case 0xFC45: -case 0xFC46: -case 0xFC47: -case 0xFC48: -case 0xFC49: -case 0xFC4A: -case 0xFC4B: -case 0xFC4C: -case 0xFC4D: -case 0xFC4E: -case 0xFC4F: -case 0xFC50: -case 0xFC51: -case 0xFC52: -case 0xFC53: -case 0xFC54: -case 0xFC55: -case 0xFC56: -case 0xFC57: -case 0xFC58: -case 0xFC59: -case 0xFC5A: -case 0xFC5B: -case 0xFC5C: -case 0xFC5D: -case 0xFC5E: -case 0xFC5F: -case 0xFC60: -case 0xFC61: -case 0xFC62: -case 0xFC63: -case 0xFC64: -case 0xFC65: -case 0xFC66: -case 0xFC67: -case 0xFC68: -case 0xFC69: -case 0xFC6A: -case 0xFC6B: -case 0xFC6C: -case 0xFC6D: -case 0xFC6E: -case 0xFC6F: -case 0xFC70: -case 0xFC71: -case 0xFC72: -case 0xFC73: -case 0xFC74: -case 0xFC75: -case 0xFC76: -case 0xFC77: -case 0xFC78: -case 0xFC79: -case 0xFC7A: -case 0xFC7B: -case 0xFC7C: -case 0xFC7D: -case 0xFC7E: -case 0xFC7F: -case 0xFC80: -case 0xFC81: -case 0xFC82: -case 0xFC83: -case 0xFC84: -case 0xFC85: -case 0xFC86: -case 0xFC87: -case 0xFC88: -case 0xFC89: -case 0xFC8A: -case 0xFC8B: -case 0xFC8C: -case 0xFC8D: -case 0xFC8E: -case 0xFC8F: -case 0xFC90: -case 0xFC91: -case 0xFC92: -case 0xFC93: -case 0xFC94: -case 0xFC95: -case 0xFC96: -case 0xFC97: -case 0xFC98: -case 0xFC99: -case 0xFC9A: -case 0xFC9B: -case 0xFC9C: -case 0xFC9D: -case 0xFC9E: -case 0xFC9F: -case 0xFCA0: -case 0xFCA1: -case 0xFCA2: -case 0xFCA3: -case 0xFCA4: -case 0xFCA5: -case 0xFCA6: -case 0xFCA7: -case 0xFCA8: -case 0xFCA9: -case 0xFCAA: -case 0xFCAB: -case 0xFCAC: -case 0xFCAD: -case 0xFCAE: -case 0xFCAF: -case 0xFCB0: -case 0xFCB1: -case 0xFCB2: -case 0xFCB3: -case 0xFCB4: -case 0xFCB5: -case 0xFCB6: -case 0xFCB7: -case 0xFCB8: -case 0xFCB9: -case 0xFCBA: -case 0xFCBB: -case 0xFCBC: -case 0xFCBD: -case 0xFCBE: -case 0xFCBF: -case 0xFCC0: -case 0xFCC1: -case 0xFCC2: -case 0xFCC3: -case 0xFCC4: -case 0xFCC5: -case 0xFCC6: -case 0xFCC7: -case 0xFCC8: -case 0xFCC9: -case 0xFCCA: -case 0xFCCB: -case 0xFCCC: -case 0xFCCD: -case 0xFCCE: -case 0xFCCF: -case 0xFCD0: -case 0xFCD1: -case 0xFCD2: -case 0xFCD3: -case 0xFCD4: -case 0xFCD5: -case 0xFCD6: -case 0xFCD7: -case 0xFCD8: -case 0xFCD9: -case 0xFCDA: -case 0xFCDB: -case 0xFCDC: -case 0xFCDD: -case 0xFCDE: -case 0xFCDF: -case 0xFCE0: -case 0xFCE1: -case 0xFCE2: -case 0xFCE3: -case 0xFCE4: -case 0xFCE5: -case 0xFCE6: -case 0xFCE7: -case 0xFCE8: -case 0xFCE9: -case 0xFCEA: -case 0xFCEB: -case 0xFCEC: -case 0xFCED: -case 0xFCEE: -case 0xFCEF: -case 0xFCF0: -case 0xFCF1: -case 0xFCF2: -case 0xFCF3: -case 0xFCF4: -case 0xFCF5: -case 0xFCF6: -case 0xFCF7: -case 0xFCF8: -case 0xFCF9: -case 0xFCFA: -case 0xFCFB: -case 0xFCFC: -case 0xFCFD: -case 0xFCFE: -case 0xFCFF: -case 0xFD00: -case 0xFD01: -case 0xFD02: -case 0xFD03: -case 0xFD04: -case 0xFD05: -case 0xFD06: -case 0xFD07: -case 0xFD08: -case 0xFD09: -case 0xFD0A: -case 0xFD0B: -case 0xFD0C: -case 0xFD0D: -case 0xFD0E: -case 0xFD0F: -case 0xFD10: -case 0xFD11: -case 0xFD12: -case 0xFD13: -case 0xFD14: -case 0xFD15: -case 0xFD16: -case 0xFD17: -case 0xFD18: -case 0xFD19: -case 0xFD1A: -case 0xFD1B: -case 0xFD1C: -case 0xFD1D: -case 0xFD1E: -case 0xFD1F: -case 0xFD20: -case 0xFD21: -case 0xFD22: -case 0xFD23: -case 0xFD24: -case 0xFD25: -case 0xFD26: -case 0xFD27: -case 0xFD28: -case 0xFD29: -case 0xFD2A: -case 0xFD2B: -case 0xFD2C: -case 0xFD2D: -case 0xFD2E: -case 0xFD2F: -case 0xFD30: -case 0xFD31: -case 0xFD32: -case 0xFD33: -case 0xFD34: -case 0xFD35: -case 0xFD36: -case 0xFD37: -case 0xFD38: -case 0xFD39: -case 0xFD3A: -case 0xFD3B: -case 0xFD3C: -case 0xFD3D: -case 0xFD3E: -case 0xFD3F: -case 0xFD40: -case 0xFD41: -case 0xFD42: -case 0xFD43: -case 0xFD44: -case 0xFD45: -case 0xFD46: -case 0xFD47: -case 0xFD48: -case 0xFD49: -case 0xFD4A: -case 0xFD4B: -case 0xFD4C: -case 0xFD4D: -case 0xFD4E: -case 0xFD4F: -case 0xFD50: -case 0xFD51: -case 0xFD52: -case 0xFD53: -case 0xFD54: -case 0xFD55: -case 0xFD56: -case 0xFD57: -case 0xFD58: -case 0xFD59: -case 0xFD5A: -case 0xFD5B: -case 0xFD5C: -case 0xFD5D: -case 0xFD5E: -case 0xFD5F: -case 0xFD60: -case 0xFD61: -case 0xFD62: -case 0xFD63: -case 0xFD64: -case 0xFD65: -case 0xFD66: -case 0xFD67: -case 0xFD68: -case 0xFD69: -case 0xFD6A: -case 0xFD6B: -case 0xFD6C: -case 0xFD6D: -case 0xFD6E: -case 0xFD6F: -case 0xFD70: -case 0xFD71: -case 0xFD72: -case 0xFD73: -case 0xFD74: -case 0xFD75: -case 0xFD76: -case 0xFD77: -case 0xFD78: -case 0xFD79: -case 0xFD7A: -case 0xFD7B: -case 0xFD7C: -case 0xFD7D: -case 0xFD7E: -case 0xFD7F: -case 0xFD80: -case 0xFD81: -case 0xFD82: -case 0xFD83: -case 0xFD84: -case 0xFD85: -case 0xFD86: -case 0xFD87: -case 0xFD88: -case 0xFD89: -case 0xFD8A: -case 0xFD8B: -case 0xFD8C: -case 0xFD8D: -case 0xFD8E: -case 0xFD8F: -case 0xFD90: -case 0xFD91: -case 0xFD92: -case 0xFD93: -case 0xFD94: -case 0xFD95: -case 0xFD96: -case 0xFD97: -case 0xFD98: -case 0xFD99: -case 0xFD9A: -case 0xFD9B: -case 0xFD9C: -case 0xFD9D: -case 0xFD9E: -case 0xFD9F: -case 0xFDA0: -case 0xFDA1: -case 0xFDA2: -case 0xFDA3: -case 0xFDA4: -case 0xFDA5: -case 0xFDA6: -case 0xFDA7: -case 0xFDA8: -case 0xFDA9: -case 0xFDAA: -case 0xFDAB: -case 0xFDAC: -case 0xFDAD: -case 0xFDAE: -case 0xFDAF: -case 0xFDB0: -case 0xFDB1: -case 0xFDB2: -case 0xFDB3: -case 0xFDB4: -case 0xFDB5: -case 0xFDB6: -case 0xFDB7: -case 0xFDB8: -case 0xFDB9: -case 0xFDBA: -case 0xFDBB: -case 0xFDBC: -case 0xFDBD: -case 0xFDBE: -case 0xFDBF: -case 0xFDC0: -case 0xFDC1: -case 0xFDC2: -case 0xFDC3: -case 0xFDC4: -case 0xFDC5: -case 0xFDC6: -case 0xFDC7: -case 0xFDC8: -case 0xFDC9: -case 0xFDCA: -case 0xFDCB: -case 0xFDCC: -case 0xFDCD: -case 0xFDCE: -case 0xFDCF: -case 0xFDD0: -case 0xFDD1: -case 0xFDD2: -case 0xFDD3: -case 0xFDD4: -case 0xFDD5: -case 0xFDD6: -case 0xFDD7: -case 0xFDD8: -case 0xFDD9: -case 0xFDDA: -case 0xFDDB: -case 0xFDDC: -case 0xFDDD: -case 0xFDDE: -case 0xFDDF: -case 0xFDE0: -case 0xFDE1: -case 0xFDE2: -case 0xFDE3: -case 0xFDE4: -case 0xFDE5: -case 0xFDE6: -case 0xFDE7: -case 0xFDE8: -case 0xFDE9: -case 0xFDEA: -case 0xFDEB: -case 0xFDEC: -case 0xFDED: -case 0xFDEE: -case 0xFDEF: -case 0xFDF0: -case 0xFDF1: -case 0xFDF2: -case 0xFDF3: -case 0xFDF4: -case 0xFDF5: -case 0xFDF6: -case 0xFDF7: -case 0xFDF8: -case 0xFDF9: -case 0xFDFA: -case 0xFDFB: -case 0xFDFC: -case 0xFDFD: -case 0xFDFE: -case 0xFDFF: -case 0xFE00: -case 0xFE01: -case 0xFE02: -case 0xFE03: -case 0xFE04: -case 0xFE05: -case 0xFE06: -case 0xFE07: -case 0xFE08: -case 0xFE09: -case 0xFE0A: -case 0xFE0B: -case 0xFE0C: -case 0xFE0D: -case 0xFE0E: -case 0xFE0F: -case 0xFE10: -case 0xFE11: -case 0xFE12: -case 0xFE13: -case 0xFE14: -case 0xFE15: -case 0xFE16: -case 0xFE17: -case 0xFE18: -case 0xFE19: -case 0xFE1A: -case 0xFE1B: -case 0xFE1C: -case 0xFE1D: -case 0xFE1E: -case 0xFE1F: -case 0xFE20: -case 0xFE21: -case 0xFE22: -case 0xFE23: -case 0xFE24: -case 0xFE25: -case 0xFE26: -case 0xFE27: -case 0xFE28: -case 0xFE29: -case 0xFE2A: -case 0xFE2B: -case 0xFE2C: -case 0xFE2D: -case 0xFE2E: -case 0xFE2F: -case 0xFE30: -case 0xFE31: -case 0xFE32: -case 0xFE33: -case 0xFE34: -case 0xFE35: -case 0xFE36: -case 0xFE37: -case 0xFE38: -case 0xFE39: -case 0xFE3A: -case 0xFE3B: -case 0xFE3C: -case 0xFE3D: -case 0xFE3E: -case 0xFE3F: -case 0xFE40: -case 0xFE41: -case 0xFE42: -case 0xFE43: -case 0xFE44: -case 0xFE45: -case 0xFE46: -case 0xFE47: -case 0xFE48: -case 0xFE49: -case 0xFE4A: -case 0xFE4B: -case 0xFE4C: -case 0xFE4D: -case 0xFE4E: -case 0xFE4F: -case 0xFE50: -case 0xFE51: -case 0xFE52: -case 0xFE53: -case 0xFE54: -case 0xFE55: -case 0xFE56: -case 0xFE57: -case 0xFE58: -case 0xFE59: -case 0xFE5A: -case 0xFE5B: -case 0xFE5C: -case 0xFE5D: -case 0xFE5E: -case 0xFE5F: -case 0xFE60: -case 0xFE61: -case 0xFE62: -case 0xFE63: -case 0xFE64: -case 0xFE65: -case 0xFE66: -case 0xFE67: -case 0xFE68: -case 0xFE69: -case 0xFE6A: -case 0xFE6B: -case 0xFE6C: -case 0xFE6D: -case 0xFE6E: -case 0xFE6F: -case 0xFE70: -case 0xFE71: -case 0xFE72: -case 0xFE73: -case 0xFE74: -case 0xFE75: -case 0xFE76: -case 0xFE77: -case 0xFE78: -case 0xFE79: -case 0xFE7A: -case 0xFE7B: -case 0xFE7C: -case 0xFE7D: -case 0xFE7E: -case 0xFE7F: -case 0xFE80: -case 0xFE81: -case 0xFE82: -case 0xFE83: -case 0xFE84: -case 0xFE85: -case 0xFE86: -case 0xFE87: -case 0xFE88: -case 0xFE89: -case 0xFE8A: -case 0xFE8B: -case 0xFE8C: -case 0xFE8D: -case 0xFE8E: -case 0xFE8F: -case 0xFE90: -case 0xFE91: -case 0xFE92: -case 0xFE93: -case 0xFE94: -case 0xFE95: -case 0xFE96: -case 0xFE97: -case 0xFE98: -case 0xFE99: -case 0xFE9A: -case 0xFE9B: -case 0xFE9C: -case 0xFE9D: -case 0xFE9E: -case 0xFE9F: -case 0xFEA0: -case 0xFEA1: -case 0xFEA2: -case 0xFEA3: -case 0xFEA4: -case 0xFEA5: -case 0xFEA6: -case 0xFEA7: -case 0xFEA8: -case 0xFEA9: -case 0xFEAA: -case 0xFEAB: -case 0xFEAC: -case 0xFEAD: -case 0xFEAE: -case 0xFEAF: -case 0xFEB0: -case 0xFEB1: -case 0xFEB2: -case 0xFEB3: -case 0xFEB4: -case 0xFEB5: -case 0xFEB6: -case 0xFEB7: -case 0xFEB8: -case 0xFEB9: -case 0xFEBA: -case 0xFEBB: -case 0xFEBC: -case 0xFEBD: -case 0xFEBE: -case 0xFEBF: -case 0xFEC0: -case 0xFEC1: -case 0xFEC2: -case 0xFEC3: -case 0xFEC4: -case 0xFEC5: -case 0xFEC6: -case 0xFEC7: -case 0xFEC8: -case 0xFEC9: -case 0xFECA: -case 0xFECB: -case 0xFECC: -case 0xFECD: -case 0xFECE: -case 0xFECF: -case 0xFED0: -case 0xFED1: -case 0xFED2: -case 0xFED3: -case 0xFED4: -case 0xFED5: -case 0xFED6: -case 0xFED7: -case 0xFED8: -case 0xFED9: -case 0xFEDA: -case 0xFEDB: -case 0xFEDC: -case 0xFEDD: -case 0xFEDE: -case 0xFEDF: -case 0xFEE0: -case 0xFEE1: -case 0xFEE2: -case 0xFEE3: -case 0xFEE4: -case 0xFEE5: -case 0xFEE6: -case 0xFEE7: -case 0xFEE8: -case 0xFEE9: -case 0xFEEA: -case 0xFEEB: -case 0xFEEC: -case 0xFEED: -case 0xFEEE: -case 0xFEEF: -case 0xFEF0: -case 0xFEF1: -case 0xFEF2: -case 0xFEF3: -case 0xFEF4: -case 0xFEF5: -case 0xFEF6: -case 0xFEF7: -case 0xFEF8: -case 0xFEF9: -case 0xFEFA: -case 0xFEFB: -case 0xFEFC: -case 0xFEFD: -case 0xFEFE: -case 0xFEFF: -case 0xFF00: -case 0xFF01: -case 0xFF02: -case 0xFF03: -case 0xFF04: -case 0xFF05: -case 0xFF06: -case 0xFF07: -case 0xFF08: -case 0xFF09: -case 0xFF0A: -case 0xFF0B: -case 0xFF0C: -case 0xFF0D: -case 0xFF0E: -case 0xFF0F: -case 0xFF10: -case 0xFF11: -case 0xFF12: -case 0xFF13: -case 0xFF14: -case 0xFF15: -case 0xFF16: -case 0xFF17: -case 0xFF18: -case 0xFF19: -case 0xFF1A: -case 0xFF1B: -case 0xFF1C: -case 0xFF1D: -case 0xFF1E: -case 0xFF1F: -case 0xFF20: -case 0xFF21: -case 0xFF22: -case 0xFF23: -case 0xFF24: -case 0xFF25: -case 0xFF26: -case 0xFF27: -case 0xFF28: -case 0xFF29: -case 0xFF2A: -case 0xFF2B: -case 0xFF2C: -case 0xFF2D: -case 0xFF2E: -case 0xFF2F: -case 0xFF30: -case 0xFF31: -case 0xFF32: -case 0xFF33: -case 0xFF34: -case 0xFF35: -case 0xFF36: -case 0xFF37: -case 0xFF38: -case 0xFF39: -case 0xFF3A: -case 0xFF3B: -case 0xFF3C: -case 0xFF3D: -case 0xFF3E: -case 0xFF3F: -case 0xFF40: -case 0xFF41: -case 0xFF42: -case 0xFF43: -case 0xFF44: -case 0xFF45: -case 0xFF46: -case 0xFF47: -case 0xFF48: -case 0xFF49: -case 0xFF4A: -case 0xFF4B: -case 0xFF4C: -case 0xFF4D: -case 0xFF4E: -case 0xFF4F: -case 0xFF50: -case 0xFF51: -case 0xFF52: -case 0xFF53: -case 0xFF54: -case 0xFF55: -case 0xFF56: -case 0xFF57: -case 0xFF58: -case 0xFF59: -case 0xFF5A: -case 0xFF5B: -case 0xFF5C: -case 0xFF5D: -case 0xFF5E: -case 0xFF5F: -case 0xFF60: -case 0xFF61: -case 0xFF62: -case 0xFF63: -case 0xFF64: -case 0xFF65: -case 0xFF66: -case 0xFF67: -case 0xFF68: -case 0xFF69: -case 0xFF6A: -case 0xFF6B: -case 0xFF6C: -case 0xFF6D: -case 0xFF6E: -case 0xFF6F: -case 0xFF70: -case 0xFF71: -case 0xFF72: -case 0xFF73: -case 0xFF74: -case 0xFF75: -case 0xFF76: -case 0xFF77: -case 0xFF78: -case 0xFF79: -case 0xFF7A: -case 0xFF7B: -case 0xFF7C: -case 0xFF7D: -case 0xFF7E: -case 0xFF7F: -case 0xFF80: -case 0xFF81: -case 0xFF82: -case 0xFF83: -case 0xFF84: -case 0xFF85: -case 0xFF86: -case 0xFF87: -case 0xFF88: -case 0xFF89: -case 0xFF8A: -case 0xFF8B: -case 0xFF8C: -case 0xFF8D: -case 0xFF8E: -case 0xFF8F: -case 0xFF90: -case 0xFF91: -case 0xFF92: -case 0xFF93: -case 0xFF94: -case 0xFF95: -case 0xFF96: -case 0xFF97: -case 0xFF98: -case 0xFF99: -case 0xFF9A: -case 0xFF9B: -case 0xFF9C: -case 0xFF9D: -case 0xFF9E: -case 0xFF9F: -case 0xFFA0: -case 0xFFA1: -case 0xFFA2: -case 0xFFA3: -case 0xFFA4: -case 0xFFA5: -case 0xFFA6: -case 0xFFA7: -case 0xFFA8: -case 0xFFA9: -case 0xFFAA: -case 0xFFAB: -case 0xFFAC: -case 0xFFAD: -case 0xFFAE: -case 0xFFAF: -case 0xFFB0: -case 0xFFB1: -case 0xFFB2: -case 0xFFB3: -case 0xFFB4: -case 0xFFB5: -case 0xFFB6: -case 0xFFB7: -case 0xFFB8: -case 0xFFB9: -case 0xFFBA: -case 0xFFBB: -case 0xFFBC: -case 0xFFBD: -case 0xFFBE: -case 0xFFBF: -case 0xFFC0: -case 0xFFC1: -case 0xFFC2: -case 0xFFC3: -case 0xFFC4: -case 0xFFC5: -case 0xFFC6: -case 0xFFC7: -case 0xFFC8: -case 0xFFC9: -case 0xFFCA: -case 0xFFCB: -case 0xFFCC: -case 0xFFCD: -case 0xFFCE: -case 0xFFCF: -case 0xFFD0: -case 0xFFD1: -case 0xFFD2: -case 0xFFD3: -case 0xFFD4: -case 0xFFD5: -case 0xFFD6: -case 0xFFD7: -case 0xFFD8: -case 0xFFD9: -case 0xFFDA: -case 0xFFDB: -case 0xFFDC: -case 0xFFDD: -case 0xFFDE: -case 0xFFDF: -case 0xFFE0: -case 0xFFE1: -case 0xFFE2: -case 0xFFE3: -case 0xFFE4: -case 0xFFE5: -case 0xFFE6: -case 0xFFE7: -case 0xFFE8: -case 0xFFE9: -case 0xFFEA: -case 0xFFEB: -case 0xFFEC: -case 0xFFED: -case 0xFFEE: -case 0xFFEF: -case 0xFFF0: -case 0xFFF1: -case 0xFFF2: -case 0xFFF3: -case 0xFFF4: -case 0xFFF5: -case 0xFFF6: -case 0xFFF7: -case 0xFFF8: -case 0xFFF9: -case 0xFFFA: -case 0xFFFB: -case 0xFFFC: -case 0xFFFD: -case 0xFFFE: -case 0xFFFF: - -// 1111 -case 0xF000: -{ - u32 res; - PC -= 2; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_1111_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) diff --git a/yabause/src/c68k/c68kexec.c b/yabause/src/c68k/c68kexec.c deleted file mode 100644 index c9ad703871..0000000000 --- a/yabause/src/c68k/c68kexec.c +++ /dev/null @@ -1,335 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "../core.h" -#include "c68k.h" - -// #define TRACE_WITH_Q68 // Define to use Q68 tracing code to trace insns - // (requires Q68 built in, of course) - -#ifdef NEOCD_HLE -void cdrom_load_files(void); -void neogeo_cdda_control(void); -void neogeo_prio_switch(void); -void neogeo_upload(void); -#endif - -// exception cycle table (taken from musashi core) -static const s32 c68k_exception_cycle_table[256] = -{ - 4, // 0: Reset - Initial Stack Pointer - 4, // 1: Reset - Initial Program Counter - 50, // 2: Bus Error - 50, // 3: Address Error - 34, // 4: Illegal Instruction - 38, // 5: Divide by Zero - 40, // 6: CHK - 34, // 7: TRAPV - 34, // 8: Privilege Violation - 34, // 9: Trace - 4, // 10: - 4, // 11: - 4, // 12: RESERVED - 4, // 13: Coprocessor Protocol Violation - 4, // 14: Format Error - 44, // 15: Uninitialized Interrupt - 4, // 16: RESERVED - 4, // 17: RESERVED - 4, // 18: RESERVED - 4, // 19: RESERVED - 4, // 20: RESERVED - 4, // 21: RESERVED - 4, // 22: RESERVED - 4, // 23: RESERVED - 44, // 24: Spurious Interrupt - 44, // 25: Level 1 Interrupt Autovector - 44, // 26: Level 2 Interrupt Autovector - 44, // 27: Level 3 Interrupt Autovector - 44, // 28: Level 4 Interrupt Autovector - 44, // 29: Level 5 Interrupt Autovector - 44, // 30: Level 6 Interrupt Autovector - 44, // 31: Level 7 Interrupt Autovector - 34, // 32: TRAP #0 - 34, // 33: TRAP #1 - 34, // 34: TRAP #2 - 34, // 35: TRAP #3 - 34, // 36: TRAP #4 - 34, // 37: TRAP #5 - 34, // 38: TRAP #6 - 34, // 39: TRAP #7 - 34, // 40: TRAP #8 - 34, // 41: TRAP #9 - 34, // 42: TRAP #10 - 34, // 43: TRAP #11 - 34, // 44: TRAP #12 - 34, // 45: TRAP #13 - 34, // 46: TRAP #14 - 34, // 47: TRAP #15 - 4, // 48: FP Branch or Set on Unknown Condition - 4, // 49: FP Inexact Result - 4, // 50: FP Divide by Zero - 4, // 51: FP Underflow - 4, // 52: FP Operand Error - 4, // 53: FP Overflow - 4, // 54: FP Signaling NAN - 4, // 55: FP Unimplemented Data Type - 4, // 56: MMU Configuration Error - 4, // 57: MMU Illegal Operation Error - 4, // 58: MMU Access Level Violation Error - 4, // 59: RESERVED - 4, // 60: RESERVED - 4, // 61: RESERVED - 4, // 62: RESERVED - 4, // 63: RESERVED - // 64-255: User Defined - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 -}; - -// global variable -/////////////////// - -#ifndef C68K_GEN - -#ifndef C68K_NO_JUMP_TABLE -#ifndef C68K_CONST_JUMP_TABLE -static void *JumpTable[0x10000]; -#endif -#endif - -static u32 C68k_Initialised = 0; - -#endif // C68K_GEN - -#ifdef NEOCD_HLE -extern int img_display; -#endif - -// include macro file -////////////////////// - -#include "c68kmac.inc" - -#ifndef C68K_GEN -# ifdef TRACE_WITH_Q68 -#include "../q68/q68.h" -static c68k_struc *TRACE_CPU; -static uint32_t readw(uint32_t address) { - return TRACE_CPU->Read_Word(address); -} -/* Make our own version of the structure to avoid the overhead of dozens of - * function calls every instruction */ -static struct { - u32 D[8], A[8], PC, SR, USP, SSP, dummy[7]; - void *readb, *readw, *writeb, *writew; -} state = {.readw = readw}; -void TRACE(int PC,c68k_struc *CPU,int Opcode,int CCnt) { - static FILE *f; - if (!f) f = fopen("c68k.log", "w"); - TRACE_CPU = CPU; - memcpy(state.D, CPU->D, 16*4); - state.PC = PC - 2 - CPU->BasePC; - state.SR = GET_SR; - if (f) q68_trace((Q68State *)&state, f, - CPU->CycleToDo - CCnt, CPU->CycleToDo); -} -# endif // TRACE_WITH_Q68 -#endif // !C68K_GEN - -// main exec function -////////////////////// - -s32 FASTCALL C68k_Exec(c68k_struc *cpu, s32 cycle) -{ -#ifndef C68K_GEN -#if 0 - register c68k_struc *CPU asm ("ebx"); - register pointer PC asm ("esi"); - register s32 CCnt asm ("edi"); -// register u32 Opcode asm ("edi"); -// c68k_struc *CPU; -// u32 PC; -// s32 CCnt; - u32 Opcode; -#else -// register c68k_struc *CPU asm ("r10"); -// register u32 PC asm ("r11"); -// register s32 CCnt asm ("r12"); -// register u32 Opcode asm ("r13"); - c68k_struc *CPU; - pointer PC; - s32 CCnt; - u32 Opcode; -#endif -#endif - -#ifndef C68K_GEN - -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE - #include "c68k_ini.inc" -#endif -#else - C68k_Initialised = 1; -#endif - - CPU = cpu; - PC = CPU->PC; - - if (CPU->Status & (C68K_RUNNING | C68K_DISABLE | C68K_FAULTED)) - { -#ifndef C68K_NO_JUMP_TABLE -#ifndef C68K_CONST_JUMP_TABLE - if (!C68k_Initialised) goto C68k_Init; -#endif -#endif - return (CPU->Status | 0x80000000); - } - - if (cycle <= 0) return -cycle; - - CPU->CycleToDo = CCnt = cycle; - -#ifndef C68K_DEBUG - CHECK_INT -#else - { - s32 line, vect; - - line = CPU->IRQLine; - - if ((line == 7) || (line > CPU->flag_I)) - { - PRE_IO - - /* get vector */ - CPU->IRQLine = 0; - vect = CPU->Interrupt_CallBack(line); - if (vect == C68K_INT_ACK_AUTOVECTOR) - vect = C68K_INTERRUPT_AUTOVECTOR_EX + (line & 7); - - /* adjust CCnt */ - CCnt -= c68k_exception_cycle_table[vect]; - - /* swap A7 and USP */ - if (!CPU->flag_S) - { - u32 tmpSP; - - tmpSP = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = tmpSP; - } - - /* push PC and SR */ - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - - /* adjust SR */ - CPU->flag_S = C68K_SR_S; - CPU->flag_I = line; - - /* fetch new PC */ - READ_LONG_F(vect * 4, PC) - SET_PC(PC) - - POST_IO - } - } -#endif - - if (CPU->Status & (C68K_HALTED | C68K_WAITING)) return CPU->CycleToDo; - - CPU->CycleSup = 0; - CPU->Status |= C68K_RUNNING; - -#ifndef C68K_DEBUG - NEXT -#else -#ifdef C68K_NO_JUMP_TABLE - NEXT -#else - Opcode = FETCH_WORD; - PC += 2; - goto *JumpTable[Opcode]; -#endif -#endif - -#ifdef C68K_NO_JUMP_TABLE -SwitchTable: - switch(Opcode) - { -#endif - #include "c68k_op0.inc" - #include "c68k_op1.inc" - #include "c68k_op2.inc" - #include "c68k_op3.inc" - #include "c68k_op4.inc" - #include "c68k_op5.inc" - #include "c68k_op6.inc" - #include "c68k_op7.inc" - #include "c68k_op8.inc" - #include "c68k_op9.inc" - #include "c68k_opA.inc" - #include "c68k_opB.inc" - #include "c68k_opC.inc" - #include "c68k_opD.inc" - #include "c68k_opE.inc" - #include "c68k_opF.inc" -#ifdef C68K_NO_JUMP_TABLE - } -#endif - -C68k_Exec_End: - CHECK_INT - if ((CCnt += CPU->CycleSup) > 0) - { - CPU->CycleSup = 0; - NEXT; - } - -C68k_Exec_Really_End: - CPU->Status &= ~C68K_RUNNING; - CPU->PC = PC; - - return (CPU->CycleToDo - CCnt); - -#ifndef C68K_CONST_JUMP_TABLE -#ifndef C68K_NO_JUMP_TABLE -C68k_Init: - { - u32 i, j; - - #include "c68k_ini.inc" - - C68k_Initialised = 1; - } - - return 0; -#endif -#endif -#else - return 0; -#endif -} - diff --git a/yabause/src/c68k/c68kmac.inc b/yabause/src/c68k/c68kmac.inc deleted file mode 100644 index 25767be99b..0000000000 --- a/yabause/src/c68k/c68kmac.inc +++ /dev/null @@ -1,307 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// internals core macros -///////////////////////// - -#define LSL(A, C) ((A) << (C)) -#define LSR(A, C) ((A) >> (C)) - -#define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) -#define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) - -#define ROL_8(A, C) (LSL(A, C) | LSR(A, 8-(C))) -#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) -#define ROL_16(A, C) (LSL(A, C) | LSR(A, 16-(C))) -#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) -#define ROL_32(A, C) (LSL_32(A, C) | LSR_32(A, 32-(C))) -#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) - -#define ROR_8(A, C) (LSR(A, C) | LSL(A, 8-(C))) -#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) -#define ROR_16(A, C) (LSR(A, C) | LSL(A, 16-(C))) -#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) -#define ROR_32(A, C) (LSR_32(A, C) | LSL_32(A, 32-(C))) -#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) - - -#ifdef TRACE_WITH_Q68 -extern void TRACE(int,c68k_struc*,int,int); -#else -# define TRACE(a,b,c,d) /*nothing*/ -#endif -#ifndef C68K_NO_JUMP_TABLE -#define NEXT \ - PRE_IO \ - Opcode = FETCH_WORD; \ - PC += 2; \ - TRACE(PC, CPU, Opcode, CCnt); \ - goto *JumpTable[Opcode]; -#else -#define NEXT \ - PRE_IO \ - Opcode = FETCH_WORD; \ - PC += 2; \ - TRACE(PC, CPU, Opcode, CCnt); \ - goto SwitchTable; -#endif - -#define RET(A) \ - CCnt -= (A); \ - if (CCnt <= 0) goto C68k_Exec_End; \ - NEXT - -#define SET_PC(A) \ - CPU->BasePC = CPU->Fetch[((A) >> C68K_FETCH_SFT) & C68K_FETCH_MASK]; \ - CPU->BasePC -= (A) & 0xFF000000; \ - PC = (A) + CPU->BasePC; - -#define PRE_IO \ - CPU->CycleIO = CCnt; - -#define POST_IO \ - CCnt = CPU->CycleIO; - -#define READ_BYTE_F(A, D) \ - D = CPU->Read_Byte(A) & 0xFF; - -#define READ_WORD_F(A, D) \ - D = CPU->Read_Word(A) & 0xFFFF; - -#ifdef C68K_BIG_ENDIAN - #define READ_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READ_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#else - #define READ_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READ_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#endif - -#define READSX_BYTE_F(A, D) \ - D = (s32)(s8)CPU->Read_Byte(A); - -#define READSX_WORD_F(A, D) \ - D = (s32)(s16)CPU->Read_Word(A); - -#ifdef C68K_BIG_ENDIAN - #define READSX_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READSX_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#else - #define READSX_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READSX_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#endif - -#define WRITE_BYTE_F(A, D) \ - CPU->Write_Byte(A, D); - -#define WRITE_WORD_F(A, D) \ - CPU->Write_Word(A, D); - -#ifdef C68K_BIG_ENDIAN - #define WRITE_LONG_F(A, D) \ - CPU->Write_Word((A), (D) >> 16); \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); - - #define WRITE_LONG_DEC_F(A, D) \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); \ - CPU->Write_Word((A), (D) >> 16); -#else - #define WRITE_LONG_F(A, D) \ - CPU->Write_Word((A), (D) >> 16); \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); - - #define WRITE_LONG_DEC_F(A, D) \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); \ - CPU->Write_Word((A), (D) >> 16); -#endif - -#define PUSH_16_F(D) \ - CPU->Write_Word(CPU->A[7] -= 2, D); \ - -#define POP_16_F(D) \ - D = (u16)CPU->Read_Word(CPU->A[7]); \ - CPU->A[7] += 2; - -#ifdef C68K_BIG_ENDIAN - #define PUSH_32_F(D) \ - CPU->A[7] -= 4; \ - CPU->Write_Word(CPU->A[7] + 2, (D) & 0xFFFF); \ - CPU->Write_Word(CPU->A[7], (D) >> 16); - - #define POP_32_F(D) \ - D = CPU->Read_Word(CPU->A[7]) << 16; \ - D |= CPU->Read_Word(CPU->A[7] + 2) & 0xFFFF; \ - CPU->A[7] += 4; -#else - #define PUSH_32_F(D) \ - CPU->A[7] -= 4; \ - CPU->Write_Word(CPU->A[7] + 2, (D) & 0xFFFF); \ - CPU->Write_Word(CPU->A[7], (D) >> 16); - - #define POP_32_F(D) \ - D = CPU->Read_Word(CPU->A[7]) << 16; \ - D |= CPU->Read_Word(CPU->A[7] + 2) & 0xFFFF; \ - CPU->A[7] += 4; -#endif - -#define FETCH_BYTE \ -((*(u16*)PC) & 0xFF) - -#define FETCH_WORD \ -(*(u16*)PC) - - -#define FETCH_LONG \ -(*(u32*)PC) - -#define DECODE_EXT_WORD \ -{ \ - u32 ext; \ - \ - ext = (*(u16*)PC); \ - PC += 2; \ - \ - adr += (s32)((s8)(ext)); \ - if (ext & 0x0800) adr += (s32) CPU->D[ext >> 12]; \ - else adr += (s32)((s16)(CPU->D[ext >> 12])); \ -} - -#ifndef C68K_BIG_ENDIAN -#ifdef C68K_BYTE_SWAP_OPT - #undef FETCH_LONG - #define FETCH_LONG \ - ((((u32)(*(u16*)PC)) << 16) | ((u32)(*(u16*)(PC + 2)))) -// ((((u32)(*(u8*)(PC + 2))) | (((u32)(*(u8*)(PC + 3))) << 8) | (((u32)(*(u8*)PC)) << 16) | (((u32)(*(u8*)(PC + 1))) << 24))) -#else - #undef FETCH_BYTE - #define FETCH_BYTE \ - (*(u16*)PC) >> 8) - - #undef FETCH_WORD - #define FETCH_WORD \ - ((((u16)(*(u8*)PC)) << 8) | ((u16)(*(u8*)(PC + 1)))) -// ((((u16)(*(u8*)(PC + 1))) | (((u16)(*(u8*)PC)) << 8))) - - #undef FETCH_LONG - #define FETCH_LONG \ - ((((u32)(*(u8*)PC)) << 24) | (((u32)(*(u8*)(PC + 1))) << 16) | (((u32)(*(u8*)(PC + 2))) << 8) | ((u32)(*(u8*)(PC + 3)))) -// ((((u32)(*(u8*)(PC + 3))) | (((u32)(*(u8*)(PC + 2))) << 8) | (((u32)(*(u8*)(PC + 1))) << 16) | (((u32)(*(u8*)PC)) << 24))) - - #undef DECODE_EXT_WORD - #define DECODE_EXT_WORD \ - { \ - u32 ext; \ - \ - ext = (*(u16*)PC); \ - PC += 2; \ - \ - adr += (s32)((s8)(ext >> 8)); \ - if (ext & 0x0008) adr += (s32) CPU->D[(ext >> 4) & 0x000F]; \ - else adr += (s32)((s16)(CPU->D[(ext >> 4) & 0x000F])); \ - } -#endif -#endif - -#define GET_CCR \ - (((CPU->flag_C >> (C68K_SR_C_SFT - 0)) & 1) | \ - ((CPU->flag_V >> (C68K_SR_V_SFT - 1)) & 2) | \ - (((!CPU->flag_notZ) & 1) << 2) | \ - ((CPU->flag_N >> (C68K_SR_N_SFT - 3)) & 8) | \ - ((CPU->flag_X >> (C68K_SR_X_SFT - 4)) & 0x10)) - -#define GET_SR \ - ((CPU->flag_S << 0) | \ - (CPU->flag_I << 8) | \ - GET_CCR) - -#define SET_CCR(A) \ - CPU->flag_C = (A) << (C68K_SR_C_SFT - 0); \ - CPU->flag_V = (A) << (C68K_SR_V_SFT - 1); \ - CPU->flag_notZ = ~(A) & 4; \ - CPU->flag_N = (A) << (C68K_SR_N_SFT - 3); \ - CPU->flag_X = (A) << (C68K_SR_X_SFT - 4); - -#define SET_SR(A) \ - SET_CCR(A) \ - CPU->flag_I = ((A) >> 8) & 7; \ - CPU->flag_S = (A) & C68K_SR_S; - -#define CHECK_INT \ - { \ - s32 line, vect; \ - \ - line = CPU->IRQLine; \ - \ - if ((line == 7) || (line > CPU->flag_I)) \ - { \ - /* get vector */ \ - CPU->IRQLine = 0; \ - vect = CPU->Interrupt_CallBack(line); \ - if (vect == C68K_INT_ACK_AUTOVECTOR) \ - vect = C68K_INTERRUPT_AUTOVECTOR_EX + (line & 7); \ - \ - /* adjust CCnt */ \ - CCnt -= c68k_exception_cycle_table[vect]; \ - \ - /* swap A7 and USP */ \ - if (!CPU->flag_S) \ - { \ - u32 tmpSP; \ - \ - tmpSP = CPU->USP; \ - CPU->USP = CPU->A[7]; \ - CPU->A[7] = tmpSP; \ - } \ - \ - PRE_IO \ - \ - /* push PC and SR */ \ - PUSH_32_F(PC - CPU->BasePC) \ - PUSH_16_F(GET_SR) \ - \ - /* adjust SR */ \ - CPU->flag_S = C68K_SR_S; \ - CPU->flag_I = line; \ - \ - /* fetch new PC */ \ - READ_LONG_F(vect * 4, PC) \ - SET_PC(PC) \ - \ - POST_IO \ - } \ - } diff --git a/yabause/src/c68k/configure.in b/yabause/src/c68k/configure.in deleted file mode 100644 index ed03d740a2..0000000000 --- a/yabause/src/c68k/configure.in +++ /dev/null @@ -1,18 +0,0 @@ -AC_INIT(gen68k, 0.9.10) - -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -AM_INIT_AUTOMAKE([1.8.0 foreign]) - -AC_PROG_CC - -AC_LANG(C) - -AC_C_BIGENDIAN - -AM_PROG_CC_C_O - -AC_CONFIG_FILES([Makefile]) - -AC_OUTPUT diff --git a/yabause/src/c68k/gen68k.c b/yabause/src/c68k/gen68k.c deleted file mode 100644 index 1a540598b4..0000000000 --- a/yabause/src/c68k/gen68k.c +++ /dev/null @@ -1,3820 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * GEN68K.C : - * - * C68K generator source file - * - ********************************************************************************/ - -#include -#ifdef __WIN32__ -#include -#endif - -#include "../core.h" -#include "c68k.h" -#include "gen68k.h" - -#ifdef C68K_GEN - -#include "gen68k.inc" - -// to do : -// need accurate cycles calculations in MUL and DIV instruction -// some bugs to fix - -// opcode generation function -////////////////////////////// - -static void GenLogicI(char op) -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_ea != EA_DREG) current_cycle += 4; - switch (current_size) - { - case SIZE_BYTE: - wf_op("\tsrc = FETCH_BYTE;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\tsrc = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\tsrc = FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - current_cycle += 8; - break; - } - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // op - wf_op("\tres %c= src;\n", op); - // flag calculation - set_logic_flag(); - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenLogicICCR(char op) -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tres = FETCH_BYTE & C68K_CCR_MASK;\n"); - wf_op("\tPC += 2;\n"); - wf_op("\tres %c= GET_CCR;\n", op); - wf_op("\tSET_CCR(res)\n"); - - terminate_op(20); -} - -static void GenLogicISR(char op) -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tres = FETCH_WORD & C68K_SR_MASK;\n"); - wf_op("\t\tPC += 2;\n"); - wf_op("\t\tres %c= GET_SR;\n", op); - wf_op("\t\tSET_SR(res)\n"); - if (op != '|') - { - wf_op("\t\tif (!CPU->flag_S)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tres = CPU->A[7];\n"); - wf_op("\t\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\t\tCPU->USP = res;\n"); - wf_op("\t\t}\n"); - } - wf_op("\t}\n"); - wf_op("\telse\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - wf_op("\t}\n"); - - // check for interrupt - fterminate_op(20); -} - -static void GenORI() -{ - GenLogicI('|'); -} - -static void GenORICCR() -{ - GenLogicICCR('|'); -} - -static void GenORISR() -{ - GenLogicISR('|'); -} - -static void GenANDI() -{ - GenLogicI('&'); -} - -static void GenANDICCR() -{ - GenLogicICCR('&'); -} - -static void GenANDISR() -{ - GenLogicISR('&'); -} - -static void GenEORI() -{ - GenLogicI('^'); -} - -static void GenEORICCR() -{ - GenLogicICCR('^'); -} - -static void GenEORISR() -{ - GenLogicISR('^'); -} - -static void GenArithI(char op) -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC | GEN_DST); - else - start_all(GEN_ALL); - - if ((op != ' ') && (current_ea != EA_DREG)) current_cycle += 4; - switch (current_size) - { - case SIZE_BYTE: - wf_op("\tsrc = FETCH_BYTE;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\tsrc = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\tsrc = FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - if (op == ' ') - { - if (current_ea == EA_DREG) current_cycle += 6; - else current_cycle += 4; - } else current_cycle += 8; - break; - } - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_dst(current_ea, current_op->reg_sft); - if (op == ' ') - { - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - } - else - { - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (op == '+') set_add_flag(); - else set_sub_flag(); - // write - _ea_write(current_ea, current_op->reg_sft); - } - - terminate_op(8); -} - -static void GenSUBI() -{ - GenArithI('-'); -} - -static void GenADDI() -{ - GenArithI('+'); -} - -static void GenCMPI() -{ - GenArithI(' '); -} - -static void GenBitsOp(char op, u32 dyn) -{ - // generate jump table & opcode declaration - if (dyn) current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_ea == EA_DREG) - { - set_current_size(SIZE_LONG); - if ((op == 'c') || (op == ' ')) current_cycle += 2; - } - else set_current_size(SIZE_BYTE); - - // get shift value in src - if (dyn) - { - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - } - else - { - wf_op("\tsrc = FETCH_BYTE;\n"); - wf_op("\tPC += 2;\n"); - current_cycle += 4; - } - wf_op("\tsrc = 1 << (src & %d);\n", current_sft_mask); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - wf_op("\tCPU->flag_notZ = res & src;\n"); - // op - switch(op) - { - case 'c': - wf_op("\tres &= ~src;\n"); - break; - - case 'g': - wf_op("\tres ^= src;\n"); - break; - - case 's': - wf_op("\tres |= src;\n"); - break; - } - // write - if (op != ' ') - { - _ea_write(current_ea, current_op->reg_sft); - current_cycle += 4; - } - - terminate_op(4); -} - -static void GenBTSTn() -{ - GenBitsOp(' ', 0); -} - -static void GenBCHGn() -{ - GenBitsOp('g', 0); -} - -static void GenBCLRn() -{ - GenBitsOp('c', 0); -} - -static void GenBSETn() -{ - GenBitsOp('s', 0); -} - -static void GenBTST() -{ - GenBitsOp(' ', 1); -} - -static void GenBCHG() -{ - GenBitsOp('g', 1); -} - -static void GenBCLR() -{ - GenBitsOp('c', 1); -} - -static void GenBSET() -{ - GenBitsOp('s', 1); -} - -static void GenMOVEPWaD() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - set_current_size(SIZE_BYTE); - _ea_calc(current_ea, current_op->reg_sft); - mem_op("\tREAD_BYTE_F(adr + 0, res)\n"); - mem_op("\tREAD_BYTE_F(adr + 2, src)\n"); - // write - wf_op("\t*(u16*)(&CPU->D[(Opcode >> %d) & 7]) = (res << 8) | src;\n", current_op->reg2_sft); - - terminate_op(16); -} - -static void GenMOVEPLaD() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - set_current_size(SIZE_BYTE); - _ea_calc(EA_D16A, current_op->reg_sft); - mem_op("\tREAD_BYTE_F(adr, res)\n"); - wf_op("\tres <<= 24;\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tREAD_BYTE_F(adr, src)\n"); - wf_op("\tres |= src << 16;\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tREAD_BYTE_F(adr, src)\n"); - wf_op("\tres |= src << 8;\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tREAD_BYTE_F(adr, src)\n"); - // write - wf_op("\tCPU->D[(Opcode >> %d) & 7] = res | src;\n", current_op->reg2_sft); - - terminate_op(24); -} - -static void GenMOVEPWDa() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES); - - // read - set_current_size(SIZE_LONG); - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - // write - set_current_size(SIZE_BYTE); - _ea_calc(current_ea, current_op->reg_sft); - mem_op("\tWRITE_BYTE_F(adr + 0, res >> 8)\n"); - mem_op("\tWRITE_BYTE_F(adr + 2, res >> 0)\n"); - - terminate_op(16); -} - -static void GenMOVEPLDa() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES); - - // read - set_current_size(SIZE_LONG); - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - // write - set_current_size(SIZE_BYTE); - _ea_calc(current_ea, current_op->reg_sft); - mem_op("\tWRITE_BYTE_F(adr, res >> 24)\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tWRITE_BYTE_F(adr, res >> 16)\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tWRITE_BYTE_F(adr, res >> 8)\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tWRITE_BYTE_F(adr, res >> 0)\n"); - - terminate_op(24); -} - -static void GenMOVE(u32 size) -{ - set_current_size(size); - - // generate jump table & opcode declaration - if (((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) && - ((current_ea2 == EA_AREG) || (current_ea2 == EA_DREG) || (current_ea2 == EA_IMM))) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); - if ((current_ea2 == EA_ADEC) || (current_ea2 == EA_ADEC7)) current_cycle -= 2; - // write - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenMOVEB() -{ - GenMOVE(SIZE_BYTE); -} - -static void GenMOVEW() -{ - GenMOVE(SIZE_WORD); -} - -static void GenMOVEL() -{ - GenMOVE(SIZE_LONG); -} - -static void GenMOVEA(u32 size) -{ - set_current_size(size); - - // generate jump table & opcode declaration - current_ea2 = EA_AREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_sx(current_ea, current_op->reg_sft); - // write (dst = Ax) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenMOVEAW() -{ - GenMOVEA(SIZE_WORD); -} - -static void GenMOVEAL() -{ - GenMOVEA(SIZE_LONG); -} - -static void GenMOVEQ() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - current_ea = EA_DREG; - gen_opjumptable_ext(base, 0x00, 0xFF, 1, base); - - // generate label & declarations - start_op(base, GEN_RES); - - // read - set_current_size(SIZE_BYTE); - wf_op("\tres = (s32)(s8)Opcode;\n"); - // fast flag calculation for moveQ - wf_op("\tCPU->flag_C = CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_N = CPU->flag_notZ = res;\n"); - // write - set_current_size(SIZE_LONG); - _ea_calc(current_ea, current_op->reg_sft); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenSingle(char op) -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) { - if (op == 'c') - start_all(GEN_RES); - else - start_all(GEN_RES | GEN_SRC); - } else { - if (op == 'c') - start_all(GEN_ADR | GEN_RES); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - } - - if (current_size == SIZE_LONG) current_cycle = 6; - else current_cycle= 4; - if (is_ea_memory(current_ea)) current_cycle *= 2; - - // read - _ea_calc(current_ea, current_op->reg_sft); - if (op != 'c') _ea_read_src(current_ea, current_op->reg_sft); - // op - switch (op) - { - case 'x': // negx - wf_op("\tres = -src - ((CPU->flag_X >> 8) & 1);\n"); - break; - - case 'g': // neg - wf_op("\tres = -src;\n"); - break; - - case 'n': // not - wf_op("\tres = ~src;\n"); - break; - - case 'c': // clr - wf_op("\tres = 0;\n"); - break; - } - // flag calculation - switch (op) - { - case 'x': // negx - set_negx_flag(); - break; - - case 'g': // neg - set_neg_flag(); - break; - - case 'n': // not - set_logicl_flag(); - break; - - case 'c': // clr - wf_op("\tCPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0;\n"); - break; - } - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(0); -} - -static void GenCLR() -{ - GenSingle('c'); -} - -static void GenNEGX() -{ - GenSingle('x'); -} - -static void GenNEG() -{ - GenSingle('g'); -} - -static void GenNOT() -{ - GenSingle('n'); -} - -static void GenMOVESRa() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - wf_op("\tres = GET_SR;\n"); - // write - set_current_size(SIZE_WORD); - if (is_ea_memory(current_ea)) current_cycle += 2; - _ea_calc(current_ea, current_op->reg_sft); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenMOVEaSR() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - wf_op("\tif (CPU->flag_S)\n"); - wf_op("\t{\n"); - // read - set_current_size(SIZE_WORD); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - wf_op("\t\tSET_SR(res)\n"); - wf_op("\t\tif (!CPU->flag_S)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tres = CPU->A[7];\n"); - wf_op("\t\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\t\tCPU->USP = res;\n"); - wf_op("\t\t}\n"); - wf_op("\t}\n"); - wf_op("\telse\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - wf_op("\t}\n"); - - // force terminaison to check for interrupt - fterminate_op(12); -} - -static void GenMOVEaCCR() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - set_current_size(SIZE_WORD); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // write - wf_op("\tSET_CCR(res)\n"); - - terminate_op(12); -} - -static void GenMOVEAUSP() -{ - current_ea = EA_AREG; - - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // read - set_current_size(SIZE_LONG); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // write - wf_op("\tCPU->USP = res;\n"); - - terminate_op(4); -} - -static void GenMOVEUSPA() -{ - current_ea = EA_AREG; - - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // read - wf_op("\tres = CPU->USP;\n"); - // write - set_current_size(SIZE_LONG); - _ea_calc(current_ea, current_op->reg_sft); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenPEA() -{ - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(0); - else - start_all(GEN_ADR); - - _ea_calc_free(current_ea, current_op->reg_sft); - mem_op("\tPUSH_32_F(adr)\n"); - - terminate_op(lea_pea_cycle_table[current_ea] + 12); -} - -static void GenSWAP() -{ - current_ea = EA_DREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // op - wf_op("\tres = (res >> 16) | (res << 16);\n"); - // flag calculation - set_logic_flag(); - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenMOVEMaR() -{ - // generate jump table & opcode declaration - start_all(GEN_ALL); - - // get register mask - wf_op("\tres = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - // get adr - if (current_ea == EA_AINC) wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", current_op->reg_sft); - else if (current_ea == EA_AINC7) wf_op("\tadr = CPU->A[7];\n"); - else _ea_calc(current_ea, current_op->reg_sft); - wf_op("\tsrc = (pointer)(&CPU->D[0]);\n"); - - wf_op("\tdst = adr;\n"); - do_pre_io(); - - wf_op("\tdo\n"); - wf_op("\t{\n"); - wf_op("\t\tif (res & 1)\n"); - wf_op("\t\t{\n"); - - if (current_size == SIZE_WORD) - { - wf_op("\t\t\tREADSX_WORD_F(adr, *(s32*)src)\n"); - wf_op("\t\t\tadr += 2;\n"); - } - else - { - wf_op("\t\t\tREAD_LONG_F(adr, *(u32*)src)\n"); - wf_op("\t\t\tadr += 4;\n"); - } - wf_op("\t\t}\n"); - wf_op("\t\tsrc += 4;\n"); - wf_op("\t} while (res >>= 1);\n"); - - if (current_ea == EA_AINC) wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", current_op->reg_sft); - else if (current_ea == EA_AINC7) wf_op("\tCPU->A[7] = adr;\n"); - adds_CCnt("(adr - dst) * 2"); - - terminate_op(movem_cycle_table[current_ea] + 12); -} - -static void GenMOVEMRa() -{ - // generate jump table & opcode declaration - start_all(GEN_ALL); - - // get register mask - wf_op("\tres = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - // get adr - if (current_ea == EA_ADEC) wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", current_op->reg_sft); - else if (current_ea == EA_ADEC7) wf_op("\tadr = CPU->A[7];\n"); - else _ea_calc(current_ea, current_op->reg_sft); - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) wf_op("\tsrc = (pointer)(&CPU->A[7]);\n"); - else wf_op("\tsrc = (pointer)(&CPU->D[0]);\n"); - - wf_op("\tdst = adr;\n"); - do_pre_io(); - - wf_op("\tdo\n"); - wf_op("\t{\n"); - wf_op("\t\tif (res & 1)\n"); - wf_op("\t\t{\n"); - - if (current_size == SIZE_WORD) - { - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) wf_op("\t\t\tadr -= 2;\n"); - wf_op("\t\t\tWRITE_WORD_F(adr, *(u16*)src)\n"); - if (!((current_ea == EA_ADEC) || (current_ea == EA_ADEC7))) wf_op("\t\t\tadr += 2;\n"); - } - else - { - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) - { - wf_op("\t\t\tadr -= 4;\n"); - wf_op("\t\t\tWRITE_LONG_DEC_F(adr, *(u32*)src)\n"); - } - else - { - wf_op("\t\t\tWRITE_LONG_F(adr, *(u32*)src)\n"); - wf_op("\t\t\tadr += 4;\n"); - } - } - wf_op("\t\t}\n"); - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) wf_op("\t\tsrc -= 4;\n"); - else wf_op("\t\tsrc += 4;\n"); - wf_op("\t} while (res >>= 1);\n"); - - if (current_ea == EA_ADEC) wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", current_op->reg_sft); - else if (current_ea == EA_ADEC7) wf_op("\tCPU->A[7] = adr;\n"); - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) adds_CCnt("(dst - adr) * 2"); - else adds_CCnt("(adr - dst) * 2"); - - terminate_op(movem_cycle_table[current_ea] + 8); -} - -static void GenEXT() -{ - current_ea = EA_DREG; - // generate jump table & opcode declaration - start_all(GEN_RES); - - // read - set_current_size(current_size - 1); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_sx(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); - // write - set_current_size(current_size + 1); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenTST() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); - - terminate_op(4); -} - -static void GenTAS() -{ - set_current_size(SIZE_BYTE); - - if (is_ea_memory(current_ea)) current_cycle += 6; - - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); -#ifndef C68K_TAS_CAN_SET_MEMORY - if (current_ea < EA_AIND) - { -#endif - // flag calculation - wf_op("\tres |= 0x80;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); -#ifndef C68K_TAS_CAN_SET_MEMORY - } -#endif - - terminate_op(4); -} - -static void GenTRAP() -{ - u32 base; - - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, (0 << 0), (15 << 0), (1 << 0), base); - - // generate label & declarations - start_op(base, GEN_RES); - - gen_exception("\t", "C68K_TRAP_BASE_EX + (Opcode & 0xF)"); - - terminate_op(4); -} - -static void GenTRAPV() -{ - // generate label & declarations - start_all(GEN_RES); - - wf_op("\tif %s\n", get_cond_as_cond(COND_VS, 0)); - wf_op("\t{\n"); - gen_exception("\t\t", "C68K_TRAPV_EX"); - wf_op("\t}\n"); - - terminate_op(4); -} - -static void GenLINK() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // push - mem_op("\tPUSH_32_F(res)\n"); - wf_op("\tres = CPU->A[7];\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - // update SP - wf_op("\tCPU->A[7] += (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - - terminate_op(16); -} - -static void GenLINKA7() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(0); - - // push A7 - wf_op("\tCPU->A[7] -= 4;\n"); - mem_op("\tWRITE_LONG_DEC_F(CPU->A[7], CPU->A[7])\n"); - // update A7 - wf_op("\tCPU->A[7] += (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - - terminate_op(16); -} - -static void GenULNK() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // pop - wf_op("\tCPU->A[7] = src + 4;\n"); - mem_op("\tREAD_LONG_F(src, res)\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(12); -} - -static void GenULNKA7() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(0); - - mem_op("\tREAD_LONG_F(CPU->A[7], CPU->A[7])\n"); - - terminate_op(12); -} - -static void GenRESET() -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // Reset callback function - mem_op("\tCPU->Reset_CallBack();\n"); - - terminate_op(132); -} - -static void GenLEA() -{ - current_ea2 = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_ADR | GEN_RES); - - _ea_calc_free(current_ea, current_op->reg_sft); - wf_op("\tres = adr;\n"); - current_cycle = lea_pea_cycle_table[current_ea]; - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenNOP() -{ - start_all(0); - terminate_op(4); -} - -static void GenILLEGAL() -{ - start_all(GEN_RES); - - gen_exception("\t\t", "C68K_ILLEGAL_INSTRUCTION_EX"); - - terminate_op(4); -} - -static void GenCHK() -{ - current_ea2 = EA_DREG; - set_current_size(SIZE_WORD); - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read Src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read Dx - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - - wf_op("\tif (((s32)res < 0) || (res > src))\n"); - wf_op("\t{\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - gen_exception("\t\t", "C68K_CHK_EX"); - wf_op("\t}\n"); - - terminate_op(10); -} - -static void GenSTOP() -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tPC += 2;\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // read & set SR - wf_op("\tres = FETCH_WORD & C68K_SR_MASK;\n"); - wf_op("\tPC += 2;\n"); - wf_op("\tSET_SR(res)\n"); - - // if S flag not set --> we swap stack pointer - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tres = CPU->A[7];\n"); - wf_op("\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\tCPU->USP = res;\n"); - wf_op("\t}\n"); - - wf_op("\tCPU->Status |= C68K_HALTED;\n"); - wf_op("\tCCnt = 0;\n"); - - // force end execution - fterminate_op(4); -} - -static void GenRTE() -{ - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // restore SR and PC - mem_op("\tPOP_16_F(res)\n"); - wf_op("\tSET_SR(res)\n"); - mem_op("\tPOP_32_F(res)\n"); - wf_op("\tSET_PC(res)\n"); - - // if S flag not set --> we swap stack pointer - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tres = CPU->A[7];\n"); - wf_op("\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\tCPU->USP = res;\n"); - wf_op("\t}\n"); - - // check for interrupt - fterminate_op(20); -} - -static void GenRTS() -{ - start_all(GEN_RES); - - mem_op("\tPOP_32_F(res)\n"); - wf_op("\tSET_PC(res)\n"); - - terminate_op(16); -} - -static void GenRTR() -{ - start_all(GEN_RES); - - mem_op("\tPOP_16_F(res)\n"); - wf_op("\tSET_CCR(res)\n"); - mem_op("\tPOP_32_F(res)\n"); - wf_op("\tSET_PC(res)\n"); - - terminate_op(20); -} - -static void GenJSR() -{ - start_all(GEN_ADR); - - // get adr - _ea_calc_free(current_ea, current_op->reg_sft); - mem_op("\tPUSH_32_F(PC - CPU->BasePC)\n"); - wf_op("\tSET_PC(adr)\n"); - - terminate_op(jmp_jsr_cycle_table[current_ea] + 12); -} - -static void GenJMP() -{ - start_all(GEN_ADR); - - // get adr - _ea_calc_free(current_ea, current_op->reg_sft); - wf_op("\tSET_PC(adr)\n"); - - terminate_op(jmp_jsr_cycle_table[current_ea] + 4); -} - -static void GenSTCC() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - for(cond = 0; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable(base + (cond << 8)); - // generate label & declarations - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_op(base + (cond << 8), GEN_RES); - else - start_op(base + (cond << 8), GEN_ADR | GEN_RES); - - set_current_size(SIZE_BYTE); - - if (is_ea_memory(current_ea)) current_cycle += 4; - - // op - _ea_calc(current_ea, current_op->reg_sft); - if ((cond != COND_TR) && (cond != COND_FA)) - { - wf_op("\tif %s\n", get_cond_as_cond(cond, 0)); - wf_op("\t{\n"); - } - if (cond != COND_FA) - { - wf_op("\tres = 0xFF;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - if (!is_ea_memory(current_ea)) quick_terminate_op(6); - else quick_terminate_op(4); - } - if ((cond != COND_TR) && (cond != COND_FA)) - { - wf_op("\t}\n"); - } - if (cond != COND_TR) - { - wf_op("\tres = 0;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - quick_terminate_op(4); - } - - wf_op("}\n"); - } -} - -static void GenDBCC() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - current_ea = EA_DREG; - set_current_size(SIZE_WORD); - - for(cond = 0; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable(base + (cond << 8)); - // generate label & declarations - start_op(base + (cond << 8), cond==COND_TR ? 0 : GEN_RES); - - if (cond != COND_TR) - { - if (cond != COND_FA) - { - wf_op("\tif %s\n", get_cond_as_cond(cond, 1)); - wf_op("\t{\n"); - } - - // read Dx - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // dec Dx - wf_op("\tres--;\n"); - // write Dx - _ea_write(current_ea, current_op->reg_sft); - wf_op("\tif ((s32)res != -1)\n"); - wf_op("\t{\n"); - wf_op("\t\tPC += (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\t\tPC -= CPU->BasePC;\n"); - // rebase PC - wf_op("\t\tSET_PC(PC);\n"); - quick_terminate_op(10); - wf_op("\t}\n"); - - if (cond != COND_FA) - { - wf_op("\t}\n"); - wf_op("\telse\n"); - wf_op("\t{\n"); - wf_op("\t\tPC += 2;\n"); - quick_terminate_op(12); - wf_op("\t}\n"); - } - } - - wf_op("\tPC += 2;\n"); - - if (cond == COND_TR) terminate_op(12); - else terminate_op(14); - } -} - -static void GenBCC() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - for(cond = 2; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable_ext(base + (cond << 8), 0x01, 0xFF, 1, base + (cond << 8) + 0x01); - // generate label & declarations - start_op(base + (cond << 8) + 0x01, 0); - - // op - wf_op("\tif %s\n", get_cond_as_cond(cond, 0)); - wf_op("\t{\n"); - wf_op("\t\tPC += (s32)(s8)Opcode;\n"); // no rebase needed for 8 bits deplacement - add_CCnt(2); - wf_op("\t}\n"); - - terminate_op(8); - } -} - -static void GenBCC16() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - for(cond = 2; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable(base + (cond << 8)); - // generate label & declarations - start_op(base + (cond << 8), 0); - - // op - wf_op("\tif %s\n", get_cond_as_cond(cond, 0)); - wf_op("\t{\n"); - wf_op("\t\tPC += (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\t\tPC -= CPU->BasePC;\n"); - // rebase PC - wf_op("\t\tSET_PC(PC);\n"); - quick_terminate_op(10); - wf_op("\t}\n"); - - wf_op("\tPC += 2;\n"); - - terminate_op(12); - } -} - -static void GenBRA() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x01, 0xFF, 1, base + 0x01); - // generate label & declarations - start_op(base + 0x01, 0); - - wf_op("\tPC += (s32)(s8)Opcode;\n"); // no rebase needed for 8 bits deplacement - - terminate_op(10); -} - -static void GenBRA16() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable(base + 0x00); - // generate label & declarations - start_op(base + 0x00, 0); - - wf_op("\tPC += (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\tPC -= CPU->BasePC;\n"); - // rebase PC - wf_op("\tSET_PC(PC);\n"); - - terminate_op(10); -} - -static void GenBSR() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x01, 0xFF, 1, base + 0x01); - // generate label & declarations - start_op(base + 0x01, 0); - - mem_op("\tPUSH_32_F(PC - CPU->BasePC)\n"); - wf_op("\tPC += (s32)(s8)Opcode;\n"); // no rebase needed for 8 bits deplacement - - terminate_op(18); -} - -static void GenBSR16() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable(base + 0x00); - // generate label & declarations - start_op(base + 0x00, GEN_RES); - - wf_op("\tres = (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\tPC -= CPU->BasePC;\n"); - mem_op("\tPUSH_32_F(PC + 2)\n"); - wf_op("\tPC += (s32) res;\n"); - // rebase PC for 16 bits deplacement - wf_op("\tSET_PC(PC);\n"); - - terminate_op(18); -} - -static void GenArithQ(char op) -{ - u32 base; - - if ((current_ea == EA_AREG) && (current_size == SIZE_BYTE)) return; - - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, (0 << 9), (7 << 9), (1 << 9), base); - - // generate label & declarations - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_op(base, GEN_DST | GEN_RES | GEN_SRC); - else - start_op(base, GEN_ALL); - - if (current_ea == EA_AREG) set_current_size(SIZE_LONG); - - if (is_ea_memory(current_ea)) current_cycle += 4; - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src - wf_op("\tsrc = (((Opcode >> 9) - 1) & 7) + 1;\n"); - // read dst - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_dst(current_ea, current_op->reg_sft); - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (current_ea != EA_AREG) - { - if (op == '+') set_add_flag(); - else set_sub_flag(); - } - // write dst - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenADDQ() -{ - GenArithQ('+'); -} - -static void GenSUBQ() -{ - GenArithQ('-'); -} - -static void GenLogicaD(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) - { - if (!is_ea_memory(current_ea)) current_cycle += 2; - else current_cycle += 4; - } - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres %c= src;\n", op); - // flag calculation - set_logic_flag(); - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenLogicDa(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // read dst - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // op - wf_op("\tres %c= src;\n", op); - // flag calculation - set_logic_flag(); - // write dst - _ea_write(current_ea, current_op->reg_sft); - - if (current_ea == EA_DREG) terminate_op(4); - else terminate_op(8); -} - -static void GenANDaD() -{ - GenLogicaD('&'); -} - -static void GenANDDa() -{ - GenLogicDa('&'); -} - -static void GenORaD() -{ - GenLogicaD('|'); -} - -static void GenORDa() -{ - GenLogicDa('|'); -} - -static void GenEORDa() -{ - GenLogicDa('^'); -} - -static void GenNBCD() -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - if (is_ea_memory(current_ea)) current_cycle += 2; - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - - // op - wf_op("\tres = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1);\n"); - wf_op("\n"); - wf_op("\tif (res != 0x9a)\n"); - wf_op("\t{\n"); - wf_op("\t\tif ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;\n"); - wf_op("\t\tres &= 0xFF;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - // flag calculation - wf_op("\t\tCPU->flag_notZ |= res;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C = C68K_SR_C;\n"); - - wf_op("\t}\n"); - wf_op("\telse CPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = res;\n"); - - terminate_op(6); -} - -static void GenBCD(char op) -{ - // op - wf_op("\tres = (dst & 0xF) %c (src & 0xF) %c ((CPU->flag_X >> C68K_SR_X_SFT) & 1);\n", op, op); - wf_op("\tif (res > 9) res %c= 6;\n", op); - wf_op("\tres += (dst & 0xF0) %c (src & 0xF0);\n", op, op); - - // flag calculation - wf_op("\tif (res > 0x99)\n"); - wf_op("\t{\n"); - switch (op) - { - case '+': - wf_op("\t\tres -= 0xA0;\n"); - break; - - case '-': - wf_op("\t\tres += 0xA0;\n"); - break; - } - wf_op("\t\tCPU->flag_X = CPU->flag_C = C68K_SR_C;\n"); - wf_op("\t}\n"); - wf_op("\telse CPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - wf_op("\tCPU->flag_N = res;\n"); -} - -static void GenxBCD(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_DREG; - current_ea2 = EA_DREG; - start_all(GEN_DST | GEN_RES | GEN_SRC); - - // read src (Dx) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // op & flag calculation - GenBCD(op); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenxBCDM(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenxBCD7M(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenxBCDM7(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenxBCD7M7(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenABCD() -{ - GenxBCD('+'); -} - -static void GenABCDM() -{ - GenxBCDM('+'); -} - -static void GenABCD7M() -{ - GenxBCD7M('+'); -} - -static void GenABCDM7() -{ - GenxBCDM7('+'); -} - -static void GenABCD7M7() -{ - GenxBCD7M7('+'); -} - -static void GenSBCD() -{ - GenxBCD('-'); -} - -static void GenSBCDM() -{ - GenxBCDM('-'); -} - -static void GenSBCD7M() -{ - GenxBCD7M('-'); -} - -static void GenSBCDM7() -{ - GenxBCDM7('-'); -} - -static void GenSBCD7M7() -{ - GenxBCD7M7('-'); -} - -static void GenDIVU() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - set_current_size(SIZE_WORD); - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // division by zero - wf_op("\tif (src == 0)\n"); - wf_op("\t{\n"); - gen_exception("\t\t", "C68K_ZERO_DIVIDE_EX"); - quick_terminate_op(10); - wf_op("\t}\n"); - - set_current_size(SIZE_LONG); - - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - wf_op("\t{\n"); - wf_op("\t\tu32 q, r;\n"); - wf_op("\n"); - wf_op("\t\tq = dst / src;\n"); - wf_op("\t\tr = dst %% src;\n"); - wf_op("\n"); - - wf_op("\t\tif (q & 0xFFFF0000)\n"); - wf_op("\t\t{\n"); - // overflow occured - wf_op("\t\t\tCPU->flag_V = C68K_SR_V;\n"); - quick_terminate_op(70); - wf_op("\t\t}\n"); - - // quotient size = word - set_current_size(SIZE_WORD); - - wf_op("\t\tq &= 0x%.8X;\n", current_bits_mask); - wf_op("\t\tCPU->flag_notZ = q;\n"); - wf_op("\t\tCPU->flag_N = q >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_V = CPU->flag_C = 0;\n"); - - wf_op("\t\tres = q | (r << 16);\n"); - - set_current_size(SIZE_LONG); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\t}\n"); - - // max cycle = 140 - terminate_op(140 - 50); -} - -static void GenDIVS() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - set_current_size(SIZE_WORD); - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - - // division by zero - wf_op("\tif (src == 0)\n"); - wf_op("\t{\n"); - gen_exception("\t\t", "C68K_ZERO_DIVIDE_EX"); - quick_terminate_op(10); - wf_op("\t}\n"); - - set_current_size(SIZE_LONG); - - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // division by zero - wf_op("\tif ((dst == 0x80000000) && (src == -1))\n"); - wf_op("\t{\n"); - wf_op("\t\tCPU->flag_notZ = CPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_V = CPU->flag_C = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - quick_terminate_op(50); - wf_op("\t}\n"); - - wf_op("\t{\n"); - wf_op("\t\ts32 q, r;\n"); - wf_op("\n"); - wf_op("\t\tq = (s32)dst / (s32)src;\n"); - wf_op("\t\tr = (s32)dst %% (s32)src;\n"); - wf_op("\n"); - - wf_op("\t\tif ((q > 0x7FFF) || (q < -0x8000))\n"); - wf_op("\t\t{\n"); - // overflow occured - wf_op("\t\t\tCPU->flag_V = C68K_SR_V;\n"); - quick_terminate_op(80); - wf_op("\t\t}\n"); - - // quotient size = word - set_current_size(SIZE_WORD); - - wf_op("\t\tq &= 0x%.8X;\n", current_bits_mask); - wf_op("\t\tCPU->flag_notZ = q;\n"); - wf_op("\t\tCPU->flag_N = q >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_V = CPU->flag_C = 0;\n"); - - wf_op("\t\tres = q | (r << 16);\n"); - - set_current_size(SIZE_LONG); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\t}\n"); - - // max cycle = 158 - terminate_op(158 - 50); -} - -static void GenMULU() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - set_current_size(SIZE_WORD); - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - - set_current_size(SIZE_LONG); - // op - wf_op("\tres *= src;\n"); - - // flag calculation - wf_op("\tCPU->flag_N = res >> 24;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_V = CPU->flag_C = 0;\n"); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - // min cycle = 38; max cycle = 70 - terminate_op(38 + (2 * 6)); -} - -static void GenMULS() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - set_current_size(SIZE_WORD); - // read src signed - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - // read dst signed (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_sx(current_ea2, current_op->reg2_sft); - - set_current_size(SIZE_LONG); - // op - //wf_op("\t(s32)res *= (s32)src;\n"); - wf_op("\tres *= (s32)src;\n"); // antime fix - - // flag calculation - wf_op("\tCPU->flag_N = res >> 24;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_V = CPU->flag_C = 0;\n"); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - // min cycle = 38; max cycle = 70 - terminate_op(38 + (2 * 6)); -} - -static void GenArithaD(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) - { - if (!is_ea_memory(current_ea)) current_cycle += 2; - else current_cycle += 4; - } - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - if (op == ' ') - { - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - } - else - { - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (op == '+') set_add_flag(); - else set_sub_flag(); - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - } - - terminate_op(4); -} - -static void GenArithDa(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // read dst - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_dst(current_ea, current_op->reg_sft); - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (op == '+') set_add_flag(); - else set_sub_flag(); - // write dst - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenArithA(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_AREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - if ((op != ' ') && ((current_size == SIZE_WORD) || (is_ea_memory(current_ea)))) current_cycle += 2; - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - // read dst (Ax) - set_current_size(SIZE_LONG); - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - if (op == ' ') - { - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - } - else - { - // op - wf_op("\tres = dst %c src;\n", op); - // write dst (Ax) - _ea_write(current_ea2, current_op->reg2_sft); - } - - terminate_op(6); -} - -static void GenArithX(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_DREG; - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (Dx) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenArithXM(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenArithX7M(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenArithXM7(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenArithX7M7(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenADDaD() -{ - GenArithaD('+'); -} - -static void GenADDDa() -{ - GenArithDa('+'); -} - -static void GenADDA() -{ - GenArithA('+'); -} - -static void GenADDX() -{ - GenArithX('+'); -} - -static void GenADDXM() -{ - GenArithXM('+'); -} - -static void GenADDX7M() -{ - GenArithX7M('+'); -} - -static void GenADDXM7() -{ - GenArithXM7('+'); -} - -static void GenADDX7M7() -{ - GenArithX7M7('+'); -} - -static void GenSUBaD() -{ - GenArithaD('-'); -} - -static void GenSUBDa() -{ - GenArithDa('-'); -} - -static void GenSUBA() -{ - GenArithA('-'); -} - -static void GenSUBX() -{ - GenArithX('-'); -} - -static void GenSUBXM() -{ - GenArithXM('-'); -} - -static void GenSUBX7M() -{ - GenArithX7M('-'); -} - -static void GenSUBXM7() -{ - GenArithXM7('-'); -} - -static void GenSUBX7M7() -{ - GenArithX7M7('-'); -} - -static void GenCMP() -{ - GenArithaD(' '); -} - -static void GenCMPA() -{ - GenArithA(' '); -} - -static void GenCMPM() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC; - current_ea2 = EA_AINC; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenCMP7M() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC7; - current_ea2 = EA_AINC; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenCMPM7() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC; - current_ea2 = EA_AINC7; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenCMP7M7() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC7; - current_ea2 = EA_AINC7; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenEXGDD() -{ - // generate jump table & opcode declaration - set_current_size(SIZE_LONG); - current_ea = EA_DREG; - current_ea2 = EA_DREG; - start_all(GEN_RES | GEN_SRC); - - // read R1 - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // read R2 - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // write R1 - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\tres = src;\n"); - // write R2 - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenEXGAA() -{ - // generate jump table & opcode declaration - set_current_size(SIZE_LONG); - current_ea = EA_AREG; - current_ea2 = EA_AREG; - start_all(GEN_RES | GEN_SRC); - - // read R1 - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // read R2 - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // write R1 - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\tres = src;\n"); - // write R2 - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenEXGAD() -{ - // generate jump table & opcode declaration - set_current_size(SIZE_LONG); - current_ea = EA_AREG; - current_ea2 = EA_DREG; - start_all(GEN_RES | GEN_SRC); - - // read R1 - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // read R2 - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // write R1 - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\tres = src;\n"); - // write R2 - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenASRk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read (sign extend) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tres = ((s32)src) >> sft;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenLSRk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_N = CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tres = src >> sft;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenROXRk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & C / X flags calculation - if (current_size != SIZE_LONG) - { - wf_op("\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 2); - wf_op("\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\tCPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tif (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1)));\n"); - wf_op("\telse res = (src >> sft) | (src << (33 - sft)) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + sft)));\n"); - wf_op("\tCPU->flag_X = CPU->flag_C;\n"); - } - - // V / N / Z flags calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenRORk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 1); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenASLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift < size op) ... only for BYTE here - if (current_size == SIZE_BYTE) - { - wf_op("\tif (sft < %d)\n", current_sft_mask + 1); - wf_op("\t{\n"); - } - - // op & flag X, C, N, Z calculation - if (((current_sft_mask + 1) - C68K_SR_C_SFT) < 8) - wf_op("\t\tCPU->flag_X = CPU->flag_C = src << (%d + sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - else wf_op("\t\tCPU->flag_X = CPU->flag_C = src >> (%d - sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - wf_op("\t\tres = src << sft;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - // we do V flag calculation at end for a better register usage - wf_op("\t\tCPU->flag_V = 0;\n"); - if (current_size == SIZE_BYTE) - { - wf_op("\t\tif ((sft > %d) && (src)) CPU->flag_V = C68K_SR_V;\n", current_sft_mask); - wf_op("\t\telse\n"); - } - wf_op("\t\t{\n"); - wf_op("\t\t\tu32 msk = (((s32)0x80000000) >> (sft + %d)) & 0x%.8X;\n", 31 - current_sft_mask, current_bits_mask); - wf_op("\t\t\tsrc &= msk;\n"); - wf_op("\t\t\tif ((src) && (src != msk)) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\t\t}\n"); - - if (current_size == SIZE_BYTE) - { - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of shift == size op (sft = 8 for byte operation) - wf_op("\tif (src) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\telse CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT;\n"); - - // write - wf_op("\tres = 0;\n"); - _ea_write(current_ea, current_op->reg_sft); - - // others flags - wf_op("\tCPU->flag_N = 0;\n"); - wf_op("\tCPU->flag_notZ = 0;\n"); - } - - terminate_op(6); -} - -static void GenLSLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - if (((current_sft_mask + 1) - C68K_SR_C_SFT) < 8) - wf_op("\tCPU->flag_X = CPU->flag_C = src << (%d + sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - else wf_op("\tCPU->flag_X = CPU->flag_C = src >> (%d - sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - wf_op("\tres = src << sft;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenROXLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & C / X flags calculation - if (current_size != SIZE_LONG) - { - wf_op("\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 2); - wf_op("\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\tCPU->flag_C = src >> ((32 - C68K_SR_C_SFT) - sft);\n"); - wf_op("\tif (sft == 1) res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - 1));\n"); - wf_op("\telse res = (src << sft) | (src >> (33 - sft)) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - sft));\n"); - wf_op("\tCPU->flag_X = CPU->flag_C;\n"); - } - - // V / N / Z flags calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenROLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - if (((current_sft_mask + 1) - C68K_SR_C_SFT) < 8) - wf_op("\tCPU->flag_C = src << (%d + sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - else wf_op("\tCPU->flag_C = src >> (%d - sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - wf_op("\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 1); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenASRD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read (sign extend) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift < size op) - wf_op("\t\tif (sft < %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - wf_op("\t\t\tCPU->flag_V = 0;\n"); - if (current_size == SIZE_BYTE) wf_op("\t\t\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - else wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = ((s32)src) >> sft;\n", szcs); - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift >= size op - - // if signed - wf_op("\t\tif (src & (1 << %d))\n", current_sft_mask); - wf_op("\t\t{\n"); - - // op & flag calculation - wf_op("\t\t\tCPU->flag_N = C68K_SR_N;\n"); - wf_op("\t\t\tCPU->flag_notZ = 1;\n"); - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\tCPU->flag_C = C68K_SR_C;\n"); - wf_op("\t\t\tCPU->flag_X = C68K_SR_X;\n"); - wf_op("\t\t\tres = 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // if not signed - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenLSRD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift <= size op) - if (current_size == SIZE_LONG) wf_op("\t\tif (sft < 32)\n"); - else wf_op("\t\tif (sft <= %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - wf_op("\t\t\tCPU->flag_N = CPU->flag_V = 0;\n"); - if (current_size == SIZE_BYTE) wf_op("\t\t\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - else wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = src >> sft;\n", szcs); - wf_op("\t\t\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift > size op - if (current_size == SIZE_LONG) - { - wf_op("\t\tif (sft == 32) CPU->flag_C = src >> (31 - C68K_SR_C_SFT);\n"); - wf_op("\t\telse CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C;\n"); - } - else wf_op("\t\tCPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenROXRD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - wf_op("\t\tsft %%= %d;\n", current_sft_mask + 2); - wf_op("\n"); - - // op & C / X flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\t\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 2); - wf_op("\t\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\t\tif (sft != 0)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tif (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1)));\n"); - wf_op("\t\t\telse res = (src >> sft) | (src << (33 - sft)) | (((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))) >> (sft - 1));\n"); - wf_op("\t\t\tCPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT;\n"); - wf_op("\t\t}\n"); - wf_op("\t\telse res = src;\n"); - wf_op("\t\tCPU->flag_C = CPU->flag_X;\n"); - } - - // V / N / Z flag calculation - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\t\tCPU->flag_notZ = res;\n"); - else wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = CPU->flag_X;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenRORD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - wf_op("\t\tsft &= 0x%.2X;\n", current_sft_mask); - wf_op("\t\t\n"); - - // op & flag calculation - if (current_size == SIZE_BYTE) - wf_op("\t\tCPU->flag_C = src << (C68K_SR_C_SFT - ((sft - 1) & 7));\n"); - else - wf_op("\t\tCPU->flag_C = (src >> ((sft - 1) & %d)) << C68K_SR_C_SFT;\n", current_sft_mask); - wf_op("\t\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 1); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\t\tCPU->flag_notZ = res;\n"); - else wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenASLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift < size op) - wf_op("\t\tif (sft < %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src << sft) >> %d;\n", (current_sft_mask + 1) - C68K_SR_C_SFT); - wf_op("\t\t\tres = (src << sft) & 0x%.8X;\n", current_bits_mask); - } - else - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = src << sft;\n"); - } - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - // we do V flag calculation at end for a better register usage - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\t{\n"); - wf_op("\t\t\t\tu32 msk = (((s32)0x80000000) >> (sft + %d)) & 0x%.8X;\n", 31 - current_sft_mask, current_bits_mask); - wf_op("\t\t\t\tsrc &= msk;\n"); - wf_op("\t\t\t\tif ((src) && (src != msk)) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\t\t\t}\n"); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift >= size op - wf_op("\t\tif (sft == %d) CPU->flag_C = src << C68K_SR_C_SFT;\n", current_bits_mask + 1); - wf_op("\t\telse CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C;\n"); - wf_op("\t\tif (src) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\t\telse CPU->flag_V = 0;\n"); - - wf_op("\t\tres = 0;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - - // others flags - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenLSLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift <= size op) - if (current_size == SIZE_LONG) wf_op("\t\tif (sft < 32)\n"); - else wf_op("\t\tif (sft <= %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src << sft) >> %d;\n", (current_sft_mask + 1) - C68K_SR_C_SFT); - wf_op("\t\t\tres = (src << sft) & 0x%.8X;\n", current_bits_mask); - } - else - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = src << sft;\n"); - } - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift > size op - if (current_size == SIZE_LONG) - { - wf_op("\t\tif (sft == 32) CPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\t\telse CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C;\n"); - } - else wf_op("\t\tCPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenROXLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - wf_op("\t\tsft %%= %d;\n", current_sft_mask + 2); - wf_op("\n"); - - // op & C/X flags calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\t\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 2); - wf_op("\t\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\t\tif (sft != 0)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tif (sft == 1) res = (src << 1) | ((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1);\n"); - wf_op("\t\t\telse res = (src << sft) | (src >> (33 - sft)) | (((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1) << (sft - 1));\n"); - wf_op("\t\t\tCPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT;\n"); - wf_op("\t\t}\n"); - wf_op("\t\telse res = src;\n"); - wf_op("\t\tCPU->flag_C = CPU->flag_X;\n"); - } - - // V / N / Z flags calculation - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\t\tCPU->flag_notZ = res;\n"); - else wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = CPU->flag_X;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenROLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if ((shift & size op) != 0) - wf_op("\t\tif (sft &= 0x%.2X)\n", current_sft_mask); - wf_op("\t\t{\n"); - - // op & flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\t\tCPU->flag_C = (src << sft) >> %d;\n", (current_sft_mask + 1) - C68K_SR_C_SFT); - wf_op("\t\t\tres = ((src << sft) | (src >> (%d - sft))) & 0x%.8X;\n", current_sft_mask + 1, current_bits_mask); - } - else - { - wf_op("\t\t\tCPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 1); - } - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of ((shift & size op) == 0) - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\t\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_notZ = src;\n"); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenASR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\tres = (src >> 1) | (src & (1 << %d));\n", current_sft_mask); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenLSR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_N = CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\tres = src >> 1;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROXR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tres = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << %d);\n", current_sft_mask - C68K_SR_X_SFT); - wf_op("\tCPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\tres = (src >> 1) | (src << %d);\n", current_sft_mask); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenASL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_X = CPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tres = src << 1;\n"); - wf_op("\tCPU->flag_V = (src ^ res) >> %d;\n", current_sft_mask - C68K_SR_V_SFT); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenLSL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tres = src << 1;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROXL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tres = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> %d);\n", C68K_SR_X_SFT); - wf_op("\tCPU->flag_X = CPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tres = (src << 1) | (src >> %d);\n", current_sft_mask); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void Gen1010() -{ - u32 base; - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0FFF, 0x1, base); - - // generate label & declarations - start_op(base, GEN_RES); - wf_op("\tPC -= 2;\n"); - gen_exception("\t", "C68K_1010_EX"); - terminate_op(4); -} - -static void Gen1111() -{ - u32 base; - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0FFF, 0x1, base); - - // generate label & declarations - start_op(base, GEN_RES); - wf_op("\tPC -= 2;\n"); - gen_exception("\t", "C68K_1111_EX"); - terminate_op(4); -} - -#ifdef NEOCD_HLE -static void Gen0xFABE() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_exit();\n"); - - terminate_op(0); -} - -static void Gen0xFABF() -{ - start_all(GEN_ALL); - - wf_op("\timg_display = 1;\n"); - wf_op("\tcdrom_load_files();\n"); - - terminate_op(0); -} - -static void Gen0xFAC0() -{ - start_all(GEN_ALL); - - wf_op("\timg_display = 0;\n"); - wf_op("\tcdrom_load_files();\n"); - - terminate_op(0); -} - -static void Gen0xFAC1() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_upload();\n"); - - terminate_op(0); -} - -static void Gen0xFAC2() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_prio_switch();\n"); - - terminate_op(0); -} - -static void Gen0xFAC3() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_cdda_control();\n"); - - terminate_op(0); -} -#endif - - -// main function -///////////////// -int main(void) -{ - u32 i; - u32 s; - u32 smax; - - // clear opcode files - for(i = 0; i < 0x10; i++) - { - char fn[16]; - - sprintf(fn, "c68k_op%.1X.inc", (int)i); - opcode_file = fopen(fn, "wt"); - if (opcode_file != NULL) - { - fclose(opcode_file); - opcode_file = NULL; - } - } - - // init opcode jump table - ini_file = fopen("c68k_ini.inc", "wt"); -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE - for(i = 0; i < 0x10000; i++) op_jump_table[i] = OP_ILLEGAL; -#else - // defaut ILLEGAL instruction - gen_jumptable(0x0000, 0x0000, 0xFFFF, 1, 0, 0, 0, 0, 0, 0, 0x4AFC); -#endif -#endif - // generate opcode files - for(i = 0; i < OP_INFO_TABLE_LEN; i++) - { - current_op = &(op_info_table[i]); - if (prepare_generate()) return 1; - - // s = size to start - current_size = 0; - smax = SIZE_LONG; - if (current_op->size_type == 0) smax = 0; - else if (current_op->size_type == 1) current_size = 1; - - for(s = current_size; s <= smax; s++) - { - if (current_op->eam_sft != -1) - { - for(current_ea = 0; current_ea <= EA_ADEC7; current_ea++) - { - if (!has_ea(current_ea)) continue; - current_eam = _ea_to_eamreg(current_ea) >> 3; - current_reg = _ea_to_eamreg(current_ea) & 7; - - if (op_info_table[i].eam2_sft != -1) - { - for(current_ea2 = 0; current_ea2 <= EA_ADEC7; current_ea2++) - { - if (!has_ea2(current_ea2)) continue; - current_eam2 = _ea_to_eamreg(current_ea2) >> 3; - current_reg2 = _ea_to_eamreg(current_ea2) & 7; - - set_current_size(s); - current_op->genfunc(); - } - } - else - { - current_reg2 = 0; - set_current_size(s); - current_op->genfunc(); - } - } - } - else - { - current_reg = 0; - set_current_size(s); - current_op->genfunc(); - } - } - } - - // generate jumptable file -#ifdef C68K_CONST_JUMP_TABLE - if (ini_file != NULL) - { - fprintf(ini_file, "\tstatic const void *JumpTable[0x10000] =\n"); - fprintf(ini_file, "\t{\n"); - - for(i = 0; i < (0x10000 - 4); i += 4) - fprintf(ini_file, "\t\t&&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X,\n", op_jump_table[i + 0], op_jump_table[i + 1], op_jump_table[i + 2], op_jump_table[i + 3]); - fprintf(ini_file, "\t\t&&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X\n", op_jump_table[0xFFFC], op_jump_table[0xFFFD], op_jump_table[0xFFFE], op_jump_table[0xFFFF]); - - fprintf(ini_file, "\t};\n\n"); - } -#endif - - // close handle - if (ini_file != NULL) fclose(ini_file); - if (opcode_file != NULL) fclose(opcode_file); - - return 0; -} -#endif diff --git a/yabause/src/c68k/gen68k.h b/yabause/src/c68k/gen68k.h deleted file mode 100644 index e8b71d83db..0000000000 --- a/yabause/src/c68k/gen68k.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - Copyright 2004 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * GEN68K.H : - * - * C68K generator include file - * - ********************************************************************************/ - -#ifndef _GEN68K_H_ -#define _GEN68K_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// setting -/////////// - -// structure definition -//////////////////////// - -typedef struct { - u32 name; - u32 mask; - u32 match; -} c68k_ea_info_struc; - -typedef struct __c68k_op_info_struc { - s8 op_name[8 + 1]; - u16 op_base; - u16 op_mask; - s8 size_type; - s8 size_sft; - s8 eam_sft; - s8 reg_sft; - s8 eam2_sft; - s8 reg2_sft; - s8 ea_supported[12 + 1]; - s8 ea2_supported[12 + 1]; - void (*genfunc)(void); -} c68k_op_info_struc; - - -#ifdef __cplusplus -} -#endif - -#endif // _GEN68K_H_ - diff --git a/yabause/src/c68k/gen68k.inc b/yabause/src/c68k/gen68k.inc deleted file mode 100644 index 483a4f7b07..0000000000 --- a/yabause/src/c68k/gen68k.inc +++ /dev/null @@ -1,1649 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#define EA_DREG 0 -#define EA_AREG 1 -#define EA_AIND 2 -#define EA_AINC 3 -#define EA_ADEC 4 -#define EA_D16A 5 -#define EA_D8AX 6 -#define EA_A16 7 -#define EA_A32 8 -#define EA_D16P 9 -#define EA_D8PX 10 -#define EA_IMM 11 -#define EA_AINC7 12 -#define EA_ADEC7 13 -#define EA_ILLEGAL 15 - -#define SIZE_BYTE 0 -#define SIZE_WORD 1 -#define SIZE_LONG 2 - -#define COND_TR 0 -#define COND_FA 1 -#define COND_HI 2 -#define COND_LS 3 -#define COND_CC 4 -#define COND_CS 5 -#define COND_NE 6 -#define COND_EQ 7 -#define COND_VC 8 -#define COND_VS 9 -#define COND_PL 10 -#define COND_MI 11 -#define COND_GE 12 -#define COND_LT 13 -#define COND_GT 14 -#define COND_LE 15 - -#define COND_NOT_TR COND_FA -#define COND_NOT_FA COND_TR -#define COND_NOT_HI COND_LS -#define COND_NOT_LS COND_HI -#define COND_NOT_CC COND_CS -#define COND_NOT_CS COND_CC -#define COND_NOT_NE COND_EQ -#define COND_NOT_EQ COND_NE -#define COND_NOT_VC COND_VS -#define COND_NOT_VS COND_VC -#define COND_NOT_PL COND_MI -#define COND_NOT_MI COND_PL -#define COND_NOT_GE COND_LT -#define COND_NOT_LT COND_GE -#define COND_NOT_GT COND_LE -#define COND_NOT_LE COND_GT - -#define OP_ILLEGAL 0x4AFC - -static void GenORI(void); -static void GenORICCR(void); -static void GenORISR(void); -static void GenANDI(void); -static void GenANDICCR(void); -static void GenANDISR(void); -static void GenEORI(void); -static void GenEORICCR(void); -static void GenEORISR(void); -static void GenSUBI(void); -static void GenADDI(void); -static void GenCMPI(void); -static void GenBTSTn(void); -static void GenBCHGn(void); -static void GenBCLRn(void); -static void GenBSETn(void); -static void GenBTST(void); -static void GenBCHG(void); -static void GenBCLR(void); -static void GenBSET(void); -static void GenMOVEPWaD(void); -static void GenMOVEPLaD(void); -static void GenMOVEPWDa(void); -static void GenMOVEPLDa(void); -static void GenMOVEB(void); -static void GenMOVEL(void); -static void GenMOVEW(void); -static void GenMOVEAL(void); -static void GenMOVEAW(void); -static void GenNEGX(void); -static void GenCLR(void); -static void GenNEG(void); -static void GenNOT(void); -static void GenMOVESRa(void); -static void GenMOVEaSR(void); -static void GenMOVEaCCR(void); -static void GenNBCD(void); -static void GenPEA(void); -static void GenSWAP(void); -static void GenMOVEMaR(void); -static void GenEXT(void); -static void GenTST(void); -static void GenTAS(void); -static void GenILLEGAL(void); -static void GenMOVEMRa(void); -static void GenTRAP(void); -static void GenLINK(void); -static void GenLINKA7(void); -static void GenULNK(void); -static void GenULNKA7(void); -static void GenMOVEAUSP(void); -static void GenMOVEUSPA(void); -static void GenRESET(void); -static void GenNOP(void); -static void GenSTOP(void); -static void GenRTE(void); -static void GenRTS(void); -static void GenTRAPV(void); -static void GenRTR(void); -static void GenJSR(void); -static void GenJMP(void); -static void GenCHK(void); -static void GenLEA(void); -static void GenSTCC(void); -static void GenDBCC(void); -static void GenADDQ(void); -static void GenSUBQ(void); -static void GenBCC(void); -static void GenBCC16(void); -static void GenBRA(void); -static void GenBRA16(void); -static void GenBSR(void); -static void GenBSR16(void); -static void GenMOVEQ(void); -static void GenORaD(void); -static void GenORDa(void); -static void GenSBCD(void); -static void GenSBCDM(void); -static void GenSBCD7M(void); -static void GenSBCDM7(void); -static void GenSBCD7M7(void); -static void GenDIVU(void); -static void GenDIVS(void); -static void GenSUBaD(void); -static void GenSUBDa(void); -static void GenSUBX(void); -static void GenSUBXM(void); -static void GenSUBX7M(void); -static void GenSUBXM7(void); -static void GenSUBX7M7(void); -static void GenSUBA(void); -static void GenCMP(void); -static void GenCMPM(void); -static void GenCMP7M(void); -static void GenCMPM7(void); -static void GenCMP7M7(void); -static void GenEORDa(void); -static void GenCMPA(void); -static void GenANDaD(void); -static void GenANDDa(void); -static void GenABCD(void); -static void GenABCDM(void); -static void GenABCD7M(void); -static void GenABCDM7(void); -static void GenABCD7M7(void); -static void GenMULU(void); -static void GenMULS(void); -static void GenEXGDD(void); -static void GenEXGAA(void); -static void GenEXGAD(void); -static void GenADDaD(void); -static void GenADDDa(void); -static void GenADDX(void); -static void GenADDXM(void); -static void GenADDX7M(void); -static void GenADDXM7(void); -static void GenADDX7M7(void); -static void GenADDA(void); -static void GenASRk(void); -static void GenLSRk(void); -static void GenROXRk(void); -static void GenRORk(void); -static void GenASLk(void); -static void GenLSLk(void); -static void GenROXLk(void); -static void GenROLk(void); -static void GenASRD(void); -static void GenLSRD(void); -static void GenROXRD(void); -static void GenRORD(void); -static void GenASLD(void); -static void GenLSLD(void); -static void GenROXLD(void); -static void GenROLD(void); -static void GenASR(void); -static void GenLSR(void); -static void GenROXR(void); -static void GenROR(void); -static void GenASL(void); -static void GenLSL(void); -static void GenROXL(void); -static void GenROL(void); -static void Gen1010(void); -static void Gen1111(void); -#ifdef NEOCD_HLE -static void Gen0xFABE(void); -static void Gen0xFABF(void); -static void Gen0xFAC0(void); -static void Gen0xFAC1(void); -static void Gen0xFAC2(void); -static void Gen0xFAC3(void); -#endif - -#ifdef NEOCD_HLE -#define OP_INFO_TABLE_LEN (142 + 6) -#else -#define OP_INFO_TABLE_LEN 144 -#endif - -static c68k_op_info_struc op_info_table[OP_INFO_TABLE_LEN] = -{ // DAAAAddaaddi DAAAAddaaddi - // iid181318m iid181318m - // siz siz eam ear eam ear nne6A626Pm nne6A626Pm - // opname opbase opmask typ sft 1 1 2 2 dccAX PX dccAX PX GenFunc - { "1010", 0xA000, 0xF000, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen1010 }, - { "1111", 0xF000, 0xF000, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen1111 }, - { "ORI", 0x0000, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenORI }, - { "ORICCR", 0x003C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenORICCR }, - { "ORISR", 0x007C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenORISR }, - { "ANDI", 0x0200, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenANDI }, - { "ANDICCR", 0x023C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenANDICCR }, - { "ANDISR", 0x027C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenANDISR }, - { "EORI", 0x0A00, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenEORI }, - { "EORICCR", 0x0A3C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenEORICCR }, - { "EORISR", 0x0A7C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenEORISR }, - - { "SUBI", 0x0400, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenSUBI }, - { "ADDI", 0x0600, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenADDI }, - { "CMPI", 0x0C00, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenCMPI }, - - { "BTSTn", 0x0800, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooooo-", "------------", GenBTSTn }, - { "BCHGn", 0x0840, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenBCHGn }, - { "BCLRn", 0x0880, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenBCLRn }, - { "BSETn", 0x08C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenBSETn }, - - { "BTST", 0x0100, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenBTST }, - { "BCHG", 0x0140, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-ooooooo---", "------------", GenBCHG }, - { "BCLR", 0x0180, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-ooooooo---", "------------", GenBCLR }, - { "BSET", 0x01C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-ooooooo---", "------------", GenBSET }, - - { "MOVEPWaD", 0x0108, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPWaD }, - { "MOVEPLaD", 0x0148, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPLaD }, - { "MOVEPWDa", 0x0188, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPWDa }, - { "MOVEPLDa", 0x01C8, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPLDa }, - - { "MOVEB", 0x1000, 0xF000, 0, 0, 3, 0, 6, 9, "oooooooooooo", "o-ooooooo---", GenMOVEB }, - { "MOVEL", 0x2000, 0xF000, 0, 0, 3, 0, 6, 9, "oooooooooooo", "o-ooooooo---", GenMOVEL }, - { "MOVEW", 0x3000, 0xF000, 0, 0, 3, 0, 6, 9, "oooooooooooo", "o-ooooooo---", GenMOVEW }, - { "MOVEAL", 0x2040, 0xF1C0, 0, 0, 3, 0, -1, 9, "oooooooooooo", "------------", GenMOVEAL }, - { "MOVEAW", 0x3040, 0xF1C0, 0, 0, 3, 0, -1, 9, "oooooooooooo", "------------", GenMOVEAW }, - - { "NEGX", 0x4000, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNEGX }, - { "CLR", 0x4200, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenCLR }, - { "NEG", 0x4400, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNEG }, - { "NOT", 0x4600, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNOT }, - - { "MOVESRa", 0x40C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenMOVESRa }, - { "MOVEaCCR", 0x44C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-oooooooooo", "------------", GenMOVEaCCR }, - { "MOVEaSR", 0x46C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-oooooooooo", "------------", GenMOVEaSR }, - - { "NBCD", 0x4800, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNBCD }, - { "PEA", 0x4840, 0xFFC0, 0, 0, 3, 0, -1, -1, "--o--oooooo-", "------------", GenPEA }, - { "SWAP", 0x4840, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenSWAP }, - - { "MOVEMRa", 0x4880, 0xFF80, 1, 6, 3, 0, -1, -1, "--o-ooooo---", "------------", GenMOVEMRa }, - { "EXT", 0x4880, 0xFFB8, 1, 6, -1, 0, -1, -1, "------------", "------------", GenEXT }, - { "TST", 0x4A00, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenTST }, - { "TAS", 0x4AC0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenTAS }, - { "ILLEGAL", 0x4AFC, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenILLEGAL }, - { "MOVEMaR", 0x4C80, 0xFF80, 1, 6, 3, 0, -1, -1, "--oo-oooooo-", "------------", GenMOVEMaR }, - - { "TRAP", 0x4E40, 0xFFF0, 0, 0, -1, -1, -1, -1, "------------", "------------", GenTRAP }, - { "LINK", 0x4E50, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenLINK }, - { "LINKA7", 0x4E57, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenLINKA7 }, - { "ULNK", 0x4E58, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenULNK }, - { "ULNKA7", 0x4E5F, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenULNKA7 }, - { "MOVEAUSP", 0x4E60, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenMOVEAUSP }, - { "MOVEUSPA", 0x4E68, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenMOVEUSPA }, - - { "RESET", 0x4E70, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRESET }, - { "NOP", 0x4E71, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenNOP }, - { "STOP", 0x4E72, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenSTOP }, - { "RTE", 0x4E73, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRTE }, - { "RTS", 0x4E75, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRTS }, - { "TRAPV", 0x4E76, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenTRAPV }, - { "RTR", 0x4E77, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRTR }, - - { "JSR", 0x4E80, 0xFFC0, 0, 0, 3, 0, -1, -1, "--o--oooooo-", "------------", GenJSR }, - { "JMP", 0x4EC0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--o--oooooo-", "------------", GenJMP }, - - { "CHK", 0x4180, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenCHK }, - { "LEA", 0x41C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "--o--oooooo-", "------------", GenLEA }, - - { "STCC", 0x50C0, 0xF0C0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenSTCC }, - { "DBCC", 0x50C8, 0xF0F8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenDBCC }, - - { "ADDQ", 0x5000, 0xF100, 2, 6, 3, 0, -1, -1, "ooooooooo---", "------------", GenADDQ }, - { "SUBQ", 0x5100, 0xF100, 2, 6, 3, 0, -1, -1, "ooooooooo---", "------------", GenSUBQ }, - - { "BCC", 0x6000, 0xF000, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBCC }, - { "BCC16", 0x6000, 0xF0FF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBCC16 }, - { "BRA", 0x6000, 0xFF00, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBRA }, - { "BRA16", 0x6000, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBRA16 }, - { "BSR", 0x6100, 0xFF00, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBSR }, - { "BSR16", 0x6100, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBSR16 }, - - { "MOVEQ", 0x7000, 0xF100, 0, 0, -1, 9, -1, -1, "------------", "------------", GenMOVEQ }, - - { "ORaD", 0x8000, 0xF100, 2, 6, 3, 0, -1, 9, "o-oooooooooo", "------------", GenORaD }, - { "ORDa", 0x8100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenORDa }, - { "SBCD", 0x8100, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCD }, - { "SBCDM", 0x8108, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCDM }, - { "SBCD7M", 0x810F, 0xF1FF, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCD7M }, - { "SBCDM7", 0x8F08, 0xFFF8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCDM7 }, - { "SBCD7M7", 0x8F0F, 0xFFFF, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCD7M7 }, - { "DIVU", 0x80C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenDIVU }, - { "DIVS", 0x81C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenDIVS }, - - { "SUBaD", 0x9000, 0xF100, 2, 6, 3, 0, -1, 9, "oooooooooooo", "------------", GenSUBaD }, - { "SUBDa", 0x9100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenSUBDa }, - { "SUBX", 0x9100, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenSUBX }, - { "SUBXM", 0x9108, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenSUBXM }, - { "SUBX7M", 0x910F, 0xF13F, 2, 6, -1, -1, -1, 9, "------------", "------------", GenSUBX7M }, - { "SUBXM7", 0x9F08, 0xFF38, 2, 6, -1, 0, -1, -1, "------------", "------------", GenSUBXM7 }, - { "SUBX7M7", 0x9F0F, 0xFF3F, 2, 6, -1, -1, -1, -1, "------------", "------------", GenSUBX7M7 }, - { "SUBA", 0x90C0, 0xF0C0, 1, 8, 3, 0, -1, 9, "oooooooooooo", "------------", GenSUBA }, - - { "CMP", 0xB000, 0xF100, 2, 6, 3, 0, -1, 9, "oooooooooooo", "------------", GenCMP }, - { "CMPM", 0xB108, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenCMPM }, - { "CMP7M", 0xB10F, 0xF13F, 2, 6, -1, -1, -1, 9, "------------", "------------", GenCMP7M }, - { "CMPM7", 0xBF08, 0xFF38, 2, 6, -1, 0, -1, -1, "------------", "------------", GenCMPM7 }, - { "CMP7M7", 0xBF0F, 0xFF3F, 2, 6, -1, -1, -1, -1, "------------", "------------", GenCMP7M7 }, - { "EORDa", 0xB100, 0xF100, 2, 6, 3, 0, -1, 9, "o-ooooooo---", "------------", GenEORDa }, - { "CMPA", 0xB0C0, 0xF0C0, 1, 8, 3, 0, -1, 9, "oooooooooooo", "------------", GenCMPA }, - - { "ANDaD", 0xC000, 0xF100, 2, 6, 3, 0, -1, 9, "o-oooooooooo", "------------", GenANDaD }, - { "ANDDa", 0xC100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenANDDa }, - { "ABCD", 0xC100, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenABCD }, - { "ABCDM", 0xC108, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenABCDM }, - { "ABCD7M", 0xC10F, 0xF1FF, 0, 0, -1, -1, -1, 9, "------------", "------------", GenABCD7M }, - { "ABCDM7", 0xCF08, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenABCDM7 }, - { "ABCD7M7", 0xCF0F, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenABCD7M7 }, - { "MULU", 0xC0C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenMULU }, - { "MULS", 0xC1C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenMULS }, - { "EXGDD", 0xC140, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenEXGDD }, - { "EXGAA", 0xC148, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenEXGAA }, - { "EXGAD", 0xC188, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenEXGAD }, - - { "ADDaD", 0xD000, 0xF100, 2, 6, 3, 0, -1, 9, "oooooooooooo", "------------", GenADDaD }, - { "ADDDa", 0xD100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenADDDa }, - { "ADDX", 0xD100, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenADDX }, - { "ADDXM", 0xD108, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenADDXM }, - { "ADDX7M", 0xD10F, 0xF13F, 2, 6, -1, -1, -1, 9, "------------", "------------", GenADDX7M }, - { "ADDXM7", 0xDF08, 0xFF38, 2, 6, -1, 0, -1, -1, "------------", "------------", GenADDXM7 }, - { "ADDX7M7", 0xDF0F, 0xFF3F, 2, 6, -1, -1, -1, -1, "------------", "------------", GenADDX7M7 }, - { "ADDA", 0xD0C0, 0xF0C0, 1, 8, 3, 0, -1, 9, "oooooooooooo", "------------", GenADDA }, - - { "ASRk", 0xE000, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenASRk }, - { "LSRk", 0xE008, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenLSRk }, - { "ROXRk", 0xE010, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenROXRk }, - { "RORk", 0xE018, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenRORk }, - { "ASLk", 0xE100, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenASLk }, - { "LSLk", 0xE108, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenLSLk }, - { "ROXLk", 0xE110, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenROXLk }, - { "ROLk", 0xE118, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenROLk }, - - { "ASRD", 0xE020, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenASRD }, - { "LSRD", 0xE028, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenLSRD }, - { "ROXRD", 0xE030, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenROXRD }, - { "RORD", 0xE038, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenRORD }, - { "ASLD", 0xE120, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenASLD }, - { "LSLD", 0xE128, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenLSLD }, - { "ROXLD", 0xE130, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenROXLD }, - { "ROLD", 0xE138, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenROLD }, - - { "ASR", 0xE0C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenASR }, - { "LSR", 0xE2C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenLSR }, - { "ROXR", 0xE4C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROXR }, - { "ROR", 0xE6C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROR }, - { "ASL", 0xE1C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenASL }, - { "LSL", 0xE3C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenLSL }, - { "ROXL", 0xE5C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROXL }, - { "ROL", 0xE7C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROL } - -#ifdef NEOCD_HLE - , - { "0xFABE", 0xFABE, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFABE }, - { "0xFABF", 0xFABF, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFABF }, - { "0xFAC0", 0xFAC0, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC0 }, - { "0xFAC1", 0xFAC1, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC1 }, - { "0xFAC2", 0xFAC2, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC2 }, - { "0xFAC3", 0xFAC3, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC3 } -#endif -}; - -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE -static u16 op_jump_table[0x10000]; -#endif -#endif - -// files where code is generated -static FILE* ini_file = NULL; -static FILE* opcode_file = NULL; - -// current generated instruction infos -static c68k_op_info_struc *current_op; -static u32 current_ea; -static u32 current_eam; -static u32 current_reg; -static u32 current_ea2; -static u32 current_eam2; -static u32 current_reg2; -static u32 current_size; -static u32 current_cycle; -static u32 current_io_sav; - -static char current_cond_char[128]; - -static char szc[20]; -static char szcs[20]; -static char szcf[20]; -static char szcsf[20]; - -static u32 current_bits_mask; -static u8 current_sft_mask; - -#define EA_DREG 0 -#define EA_AREG 1 -#define EA_AIND 2 -#define EA_AINC 3 -#define EA_ADEC 4 -#define EA_D16A 5 -#define EA_D8AX 6 -#define EA_A16 7 -#define EA_A32 8 -#define EA_D16P 9 -#define EA_D8PX 10 -#define EA_IMM 11 -#define EA_AINC7 12 -#define EA_ADEC7 13 -#define EA_ILLEGAL 15 - -static const u32 jmp_jsr_cycle_table[16] = -{ - 0, 0, - 4, - 0, - 0, - 6, - 10, - 6, - 8, - 6, - 10, - 0, 0, 0, 0 -}; - -static const u32 lea_pea_cycle_table[16] = -{ - 0, 0, - 0, - 0, - 0, - 4, - 8, - 4, - 8, - 4, - 8, - 0, 0, 0, 0 -}; - -static const u32 movem_cycle_table[16] = -{ - 0, 0, - 0, - 0, - 0, - 4, - 6, - 4, - 8, - 4, - 6, - 0, 0, 0, 0 -}; - -// general emitter function -//////////////////////////// - -static u32 prepare_generate(void) -{ - char filename[32]; - - sprintf(filename, "c68k_op%.1X.inc", (current_op->op_base >> 12) & 0xF); - if (opcode_file != NULL) - { - fclose(opcode_file); - opcode_file = NULL; - } - opcode_file = fopen(filename, "at"); - if (opcode_file == NULL) - { - printf("Can't open %s\n", filename); - return 1; - } - return 0; -} - -static void wf_op(char* fmt, ...) -{ - va_list args; - - if (opcode_file == NULL) return; - - va_start(args, fmt); - vfprintf(opcode_file, fmt, args); - va_end(args); -} - -static void gen_jumptable(u32 base, u32 start1, u32 end1, u32 step1, u32 start2, u32 end2, u32 step2, u32 start3, u32 end3, u32 step3, u32 op) -{ -#ifdef C68K_CONST_JUMP_TABLE - u32 i, j, k; -#endif -#ifdef C68K_NO_JUMP_TABLE - u32 i, j, k; -#endif - - - base &= 0xFFFF; - start1 &= 0xFFFF; - end1 &= 0xFFFF; - step1 &= 0xFFFF; - if (end1 < start1) end1 = start1; - start2 &= 0xFFFF; - end2 &= 0xFFFF; - step2 &= 0xFFFF; - if (end2 < start2) end2 = start2; - op &= 0xFFFF; - -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE - if (step1 == 0) step1 = 1; - if (step2 == 0) step2 = 1; - if (step3 == 0) step3 = 1; - - for(i = start1; i <= end1; i += step1) - for(j = start2; j <= end2; j += step2) - for(k = start3; k <= end3; k += step3) - op_jump_table[base + i + j + k] = op; - -#else - if (ini_file == NULL) return; - - if (start1 != end1) - { - fprintf(ini_file, "\t\tfor(i = 0x%.4X; i <= 0x%.4X; i += 0x%.4X)\n", (int)start1, (int)end1, (int)step1); - if (start2 != end2) - { - fprintf(ini_file, "\t\t\tfor(j = 0x%.4X; j <= 0x%.4X; j += 0x%.4X)\n\t", (int)start2, (int)end2, (int)step2); - if (start3 != end3) - { - fprintf(ini_file, "\t\t\t\tfor(k = 0x%.4X; k <= 0x%.4X; k += 0x%.4X)\n\t", (int)start3, (int)end3, (int)step3); - fprintf(ini_file, "\t\t\t\t\tJumpTable[0x%.4X + i + j + k] = &&OP_0x%.4X;\n", (int)base, (int)op); - } - else fprintf(ini_file, "\t\t\t\tJumpTable[0x%.4X + i + j] = &&OP_0x%.4X;\n", (int)base, (int)op); - } - else fprintf(ini_file, "\t\t\tJumpTable[0x%.4X + i] = &&OP_0x%.4X;\n", (int)base, (int)op); - } - else fprintf(ini_file, "\t\tJumpTable[0x%.4X] = &&OP_0x%.4X;\n", (int)base, (int)op); -#endif -#else - if (step1 == 0) step1 = 1; - if (step2 == 0) step2 = 1; - if (step3 == 0) step3 = 1; - - for(i = start1; i <= end1; i += step1) - for(j = start2; j <= end2; j += step2) - for(k = start3; k <= end3; k += step3) - { - u32 temp=(base + i + j + k); - if (temp != op && temp != 0x4E57 && temp != 0x4E5F) - wf_op("case 0x%.4X:\n", base + i + j + k); - } -#endif -} - -static void gen_opjumptable_ext(u32 base, u32 start3, u32 end3, u32 step3, u32 op) -{ - u32 start1, end1, step1, start2, end2, step2; - - start1 = end1 = step1 = 0; - start2 = end2 = step2 = 0; - - if ((current_op->reg_sft != -1) && (current_ea < 7)) - { - if ((current_ea == EA_AINC) || (current_ea == EA_ADEC)) end1 = 6 << current_op->reg_sft; - else end1 = 7 << current_op->reg_sft; - step1 = 1 << current_op->reg_sft; - } - if ((current_op->reg2_sft != -1) && (current_ea2 < 7)) - { - if ((current_ea2 == EA_AINC) || (current_ea2 == EA_ADEC)) end2 = 6 << current_op->reg2_sft; - else end2 = 7 << current_op->reg2_sft; - step2 = 1 << current_op->reg2_sft; - } - - if (start1 != end1) - { - if (start2 != end2) gen_jumptable(base, start1, end1, step1, start2, end2, step2, start3, end3, step3, op); - else gen_jumptable(base, start1, end1, step1, start3, end3, step3, start2, end2, step2, op); - } - else if (start2 != end2) gen_jumptable(base, start2, end2, step2, start3, end3, step3, start1, end1, step1, op); - else gen_jumptable(base, start3, end3, step3, start2, end2, step2, start1, end1, step1, op); -} - -static void gen_opjumptable(u32 op) -{ - gen_opjumptable_ext(op, 0, 0, 0, op); -} - -#define GEN_ADR 1 -#define GEN_RES 2 -#define GEN_SRC 4 -#define GEN_DST 8 -#define GEN_ALL 15 - -static void start_op(u32 op, int v) -{ - current_io_sav = 0; - current_cycle = 0; - - wf_op("\n// %s\n", current_op->op_name); -#ifndef C68K_NO_JUMP_TABLE - wf_op("OP_0x%.4X:\n", op & 0xFFFF); -#else - wf_op("case 0x%.4X:\n", op & 0xFFFF); -#endif - wf_op("{\n"); - if (v & GEN_ADR) wf_op("\tu32 adr;\n"); - if (v & GEN_RES) wf_op("\tu32 res;\n"); - if (v & GEN_DST) wf_op("\tpointer dst;\n"); - if (v & GEN_SRC) wf_op("\tpointer src;\n"); -} - -static void add_CCnt(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt -= %d;\n", cycle); -} - -static void adds_CCnt(char *str) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt -= %s;\n", str); -} - -#if 0 // FIXME: warning removal -static void sub_CCnt(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt += %d;\n", cycle); -} - -static void subs_CCnt(char *str) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt += %s;\n", str); -} - -static void quick_fterminate_op(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt -= %d;\n", current_cycle + cycle); - wf_op("\tgoto C68k_Exec_End;\n"); -} -#endif - -static void fterminate_op(u32 cycle) -{ - wf_op("}\n"); - if (current_io_sav) wf_op("POST_IO\n"); - current_io_sav = 0; - wf_op("CCnt -= %d;\n", current_cycle + cycle); - wf_op("goto C68k_Exec_End;\n"); -} - -static void quick_terminate_op(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tRET(%d)\n", current_cycle + cycle); -} - -static void terminate_op(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - wf_op("}\n"); - current_io_sav = 0; - wf_op("RET(%d)\n", current_cycle + cycle); -} - -static void do_pre_io(void) -{ - if (!current_io_sav) fprintf(opcode_file, "\tPRE_IO\n"); - current_io_sav = 1; -} - -static void mem_op(char* fmt, ...) -{ - va_list args; - - if (opcode_file == NULL) return; - - do_pre_io(); - - va_start(args, fmt); - vfprintf(opcode_file, fmt, args); - va_end(args); -} - -// flag emitter function -///////////////////////// - -static void set_logic_flag(void) -{ - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = res;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_N = res >> 8;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_logicl_flag(void) -{ - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_V = 0;\n"); - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = res;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - wf_op("\tCPU->flag_N = res >> 8;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_add_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ res) & (dst ^ res);\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst) | (~res & (src | dst))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_addx_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ res) & (dst ^ res);\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ |= res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst) | (~res & (src | dst))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_sub_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ dst) & (res ^ dst);\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_subx_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ dst) & (res ^ dst);\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ |= res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_cmp_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ dst) & (res ^ dst);\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_negx_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_V = res & src;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = (res & src) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ |= res;\n"); - wf_op("\tCPU->flag_V = (res & src) >> 24;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_neg_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_V = res & src;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = (res & src) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_V = (res & src) >> 24;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static char* get_cond_as_cond(u32 cond, u32 notvar) -{ - if (notvar) cond ^= 1; - - switch(cond) - { - case COND_TR: - sprintf(current_cond_char, "(1)"); - break; - - case COND_FA: - sprintf(current_cond_char, "(0)"); - break; - - case COND_HI: - sprintf(current_cond_char, "(CPU->flag_notZ && (!(CPU->flag_C & 0x100)))"); - break; - - case COND_LS: - sprintf(current_cond_char, "((!CPU->flag_notZ) || (CPU->flag_C & 0x100))"); - break; - - case COND_CC: - sprintf(current_cond_char, "(!(CPU->flag_C & 0x100))"); - break; - - case COND_CS: - sprintf(current_cond_char, "(CPU->flag_C & 0x100)"); - break; - - case COND_NE: - sprintf(current_cond_char, "(CPU->flag_notZ)"); - break; - - case COND_EQ: - sprintf(current_cond_char, "(!CPU->flag_notZ)"); - break; - - case COND_VC: - sprintf(current_cond_char, "(!(CPU->flag_V & 0x80))"); - break; - - case COND_VS: - sprintf(current_cond_char, "(CPU->flag_V & 0x80)"); - break; - - case COND_PL: - sprintf(current_cond_char, "(!(CPU->flag_N & 0x80))"); - break; - - case COND_MI: - sprintf(current_cond_char, "(CPU->flag_N & 0x80)"); - break; - - case COND_GE: - sprintf(current_cond_char, "(!((CPU->flag_N ^ CPU->flag_V) & 0x80))"); - break; - - case COND_LT: - sprintf(current_cond_char, "((CPU->flag_N ^ CPU->flag_V) & 0x80)"); - break; - - case COND_GT: - sprintf(current_cond_char, "(CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80)))"); - break; - - case COND_LE: - sprintf(current_cond_char, "((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80))"); - break; - } - - return current_cond_char; -} - -// effective address related function -////////////////////////////////////// - -static u32 has_ea(u32 ea) -{ - if (ea == EA_AINC7) return (current_op->ea_supported[EA_AINC] == 'o'); - if (ea == EA_ADEC7) return (current_op->ea_supported[EA_ADEC] == 'o'); - if (ea <= EA_IMM) return (current_op->ea_supported[ea] == 'o'); - return 0; -} - -static u32 has_ea2(u32 ea) -{ - if (ea == EA_AINC7) return (current_op->ea2_supported[EA_AINC] == 'o'); - if (ea == EA_ADEC7) return (current_op->ea2_supported[EA_ADEC] == 'o'); - if (ea <= EA_IMM) return (current_op->ea2_supported[ea] == 'o'); - return 0; -} - -#if 0 // FIXME: warning removal -static u32 _eamreg_to_ea(u32 eam, u32 reg) -{ - if ((eam > 7) || (reg > 7)) return EA_ILLEGAL; - if ((eam == 3) && (reg == 7)) return EA_AINC7; - if ((eam == 4) && (reg == 7)) return EA_ADEC7; - if (eam != 7) return eam; - if (reg < 5) return (eam + reg); - return EA_ILLEGAL; -} -#endif - -static u32 _ea_to_eamreg(u32 ea) -{ - if (ea < 7) return (ea << 3) | 0; - if (ea == EA_AINC7) return (EA_AINC << 3) | 7; - if (ea == EA_ADEC7) return (EA_ADEC << 3) | 7; - if (ea <= EA_IMM) return (7 << 3) | (ea - 7); - return (7 << 3) | 7; -} - -static u32 is_ea_memory(u32 ea) -{ - if ((ea > EA_AREG) && (ea != EA_IMM)) return 1; - else return 0; -} - -static void _ea_calc_free(u32 ea, u32 rsft) -{ - u32 step; - - step = 0; - switch (current_size) - { - case SIZE_BYTE: - if ((ea == EA_AINC7) || (ea == EA_ADEC7)) step = 2; - else step = 1; - break; - - case SIZE_WORD: - step = 2; - break; - - case SIZE_LONG: - step = 4; - break; - } - - switch (ea) - { - case EA_DREG: -// wf_op("\tadr = (u32)(&CPU->D[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_AREG: -// wf_op("\tadr = (u32)(&CPU->A[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_AIND: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - break; - - case EA_AINC: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tCPU->A[(Opcode >> %d) & 7] += %d;\n", rsft, step); - break; - - case EA_AINC7: - wf_op("\tadr = CPU->A[7];\n"); - wf_op("\tCPU->A[7] += %d;\n", step); - break; - - case EA_ADEC: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] - %d;\n", rsft, step); - wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", rsft); - break; - - case EA_ADEC7: - wf_op("\tadr = CPU->A[7] - %d;\n", step); - wf_op("\tCPU->A[7] = adr;\n"); - break; - - case EA_D16A: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] + (s32)(s16)FETCH_WORD;\n", rsft); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8AX: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tDECODE_EXT_WORD\n"); - break; - - case EA_A16: - wf_op("\tadr = (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_A32: - wf_op("\tadr = (s32)FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - break; - - case EA_D16P: - wf_op("\tadr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8PX: - wf_op("\tadr = PC - CPU->BasePC;\n"); - wf_op("\tDECODE_EXT_WORD\n"); - break; - } -} - -static void _ea_calc(u32 ea, u32 rsft) -{ - u32 step; - u32 cycle_sft; - - step = 0; - cycle_sft = 0; - switch (current_size) - { - case SIZE_BYTE: - if ((ea == EA_AINC7) || (ea == EA_ADEC7)) step = 2; - else step = 1; - break; - - case SIZE_WORD: - step = 2; - break; - - case SIZE_LONG: - cycle_sft = 1; - step = 4; - break; - } - - switch (ea) - { - case EA_DREG: -// wf_op("\tadr = (u32)(&CPU->D[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_AREG: -// wf_op("\tadr = (u32)(&CPU->A[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_IMM: - current_cycle += (4 << cycle_sft) + 0; - break; - - case EA_AIND: - current_cycle += (4 << cycle_sft) + 0; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - break; - - case EA_AINC: - current_cycle += (4 << cycle_sft) + 0; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tCPU->A[(Opcode >> %d) & 7] += %d;\n", rsft, step); - break; - - case EA_AINC7: - current_cycle += (4 << cycle_sft) + 0; - wf_op("\tadr = CPU->A[7];\n"); - wf_op("\tCPU->A[7] += %d;\n", step); - break; - - case EA_ADEC: - current_cycle += (4 << cycle_sft) + 2; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] - %d;\n", rsft, step); - wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", rsft); - break; - - case EA_ADEC7: - current_cycle += (4 << cycle_sft) + 2; - wf_op("\tadr = CPU->A[7] - %d;\n", step); - wf_op("\tCPU->A[7] = adr;\n"); - break; - - case EA_D16A: - current_cycle += (4 << cycle_sft) + 4; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] + (s32)(s16)FETCH_WORD;\n", rsft); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8AX: - current_cycle += (4 << cycle_sft) + 6; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tDECODE_EXT_WORD\n"); - break; - - case EA_A16: - current_cycle += (4 << cycle_sft) + 4; - wf_op("\tadr = (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_A32: - current_cycle += (4 << cycle_sft) + 8; - wf_op("\tadr = (s32)FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - break; - - case EA_D16P: - current_cycle += (4 << cycle_sft) + 4; - wf_op("\tadr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8PX: - current_cycle += (4 << cycle_sft) + 6; - wf_op("\tadr = PC - CPU->BasePC;\n"); - wf_op("\tDECODE_EXT_WORD\n"); - break; - } -} - -static void _ea_read_(u32 ea, u32 rsft, char dest[4]) -{ - char sz[8]; - - switch (current_size) - { - case SIZE_BYTE: - strcpy(sz, "BYTE"); - break; - - case SIZE_WORD: - strcpy(sz, "WORD"); - break; - - case SIZE_LONG: - strcpy(sz, "LONG"); - break; - } - - switch (ea) - { - case EA_DREG: - wf_op("\t%s = (%s)CPU->D[(Opcode >> %d) & 7];\n", dest, szc, rsft); - break; - - case EA_AREG: - if (current_size == SIZE_BYTE) - { - wf_op("\t// can't read byte from Ax registers !\n"); - wf_op("\tCPU->Status |= C68K_FAULTED;\n"); - wf_op("\tCCnt = 0;\n"); - wf_op("\tgoto C68k_Exec_Really_End;\n"); - } - else wf_op("\t%s = (%s)CPU->A[(Opcode >> %d) & 7];\n", dest, szc, rsft); - break; -/* - case EA_DREG: - case EA_AREG: - wf_op("\t%s = %s(adr);\n", dest, szcf); - break; -*/ - case EA_A32: - case EA_D8AX: - case EA_D8PX: - case EA_D16A: - case EA_D16P: - case EA_A16: - case EA_ADEC: - case EA_ADEC7: - case EA_AIND: - case EA_AINC: - case EA_AINC7: - mem_op("\tREAD_%s_F(adr, %s)\n", sz, dest); - break; - - case EA_IMM: - switch (current_size) - { - case SIZE_BYTE: - wf_op("\t%s = FETCH_BYTE;\n", dest); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\t%s = FETCH_WORD;\n", dest); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\t%s = FETCH_LONG;\n", dest); - wf_op("\tPC += 4;\n"); - break; - } - break; - } -} - -static void _ea_read(u32 ea, u32 rsft) -{ - _ea_read_(ea, rsft, "res"); -} - -static void _ea_read_src(u32 ea, u32 rsft) -{ - _ea_read_(ea, rsft, "src"); -} - -static void _ea_read_dst(u32 ea, u32 rsft) -{ - _ea_read_(ea, rsft, "dst"); -} - -static void _ea_read_sx_(u32 ea, u32 rsft, char dest[4]) -{ - char sz[8]; - - switch (current_size) - { - case SIZE_BYTE: - strcpy(sz, "BYTE"); - break; - - case SIZE_WORD: - strcpy(sz, "WORD"); - break; - - case SIZE_LONG: - strcpy(sz, "LONG"); - break; - } - - switch (ea) - { - case EA_DREG: - wf_op("\t%s = (s32)(%s)CPU->D[(Opcode >> %d) & 7];\n", dest, szcs, rsft); - break; - - case EA_AREG: - if (current_size == SIZE_BYTE) - { - wf_op("\t// can't read byte from Ax registers !\n"); - wf_op("\tCPU->Status |= C68K_FAULTED;\n"); - wf_op("\tCCnt = 0;\n"); - wf_op("\tgoto C68k_Exec_Really_End;\n"); - } - else wf_op("\t%s = (s32)(%s)CPU->A[(Opcode >> %d) & 7];\n", dest, szcs, rsft); - break; -/* - case EA_DREG: - case EA_AREG: - wf_op("\t%s = (s32)(%s(adr));\n", dest, szcsf); - break; -*/ - case EA_A32: - case EA_D8AX: - case EA_D8PX: - case EA_D16A: - case EA_D16P: - case EA_A16: - case EA_ADEC: - case EA_ADEC7: - case EA_AIND: - case EA_AINC: - case EA_AINC7: - mem_op("\tREADSX_%s_F(adr, %s)\n", sz, dest); - break; - - case EA_IMM: - switch (current_size) - { - case SIZE_BYTE: - wf_op("\t%s = (s32)(%s(PC)));\n", dest, szcsf); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\t%s = (s32)(%s)FETCH_WORD;\n", dest, szcs); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\t%s = (s32)(%s)FETCH_LONG;\n", dest, szcs); - wf_op("\tPC += 4;\n"); - break; - } - break; - } -} - -static void _ea_read_sx(u32 ea, u32 rsft) -{ - _ea_read_sx_(ea, rsft, "res"); -} - -static void _ea_read_src_sx(u32 ea, u32 rsft) -{ - _ea_read_sx_(ea, rsft, "src"); -} - -static void _ea_write(u32 ea, u32 rsft) -{ - char sz[8]; - - switch (current_size) - { - case SIZE_BYTE: - strcpy(sz, "BYTE"); - break; - - case SIZE_WORD: - strcpy(sz, "WORD"); - break; - - case SIZE_LONG: - strcpy(sz, "LONG"); - break; - } - - switch (ea) - { - case EA_DREG: - wf_op("\t%s(&CPU->D[(Opcode >> %d) & 7])) = res;\n", szcf, -rsft); - break; - - case EA_AREG: - // writes in Ax registers are always 32 bits sized - wf_op("\tCPU->A[(Opcode >> %d) & 7] = res;\n", rsft); - break; -/* - case EA_DREG: - case EA_AREG: - wf_op("\t%s(adr) = res;\n", szcf); - break; -*/ - case EA_A32: - case EA_D8AX: - case EA_D8PX: - case EA_D16A: - case EA_D16P: - case EA_A16: - case EA_ADEC: - case EA_ADEC7: - case EA_AIND: - case EA_AINC: - case EA_AINC7: - mem_op("\tWRITE_%s_F(adr, res)\n", sz); - break; - } -} - -// misc function -///////////////// - -static u32 get_current_opcode_base(void) -{ - u32 base; - - base = current_op->op_base; - if (current_op->eam_sft != -1) base += (current_eam & 7) << current_op->eam_sft; - if (current_op->reg_sft != -1) base += (current_reg & 7) << current_op->reg_sft; - if (current_op->eam2_sft != -1) base += (current_eam2 & 7) << current_op->eam2_sft; - if (current_op->reg2_sft != -1) base += (current_reg2 & 7) << current_op->reg2_sft; - if (current_op->size_type == 1) base += (current_size - 1) << current_op->size_sft; - else if (current_op->size_type == 2) base += (current_size & 3) << current_op->size_sft; - - return base; -} - -static void start_all(int v) -{ - u32 base; - - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable(base); - - // generate label & declarations - start_op(base, v); -} - -static void set_current_size(u32 sz) -{ - current_size = sz; - switch(current_size) - { - case SIZE_BYTE: - current_bits_mask = 0xFF; - current_sft_mask = 7; - strcpy(szc, "u8"); - strcpy(szcf, "*(BYTE_OFF + (u8*)"); - strcpy(szcs, "s8"); - strcpy(szcsf, "*(BYTE_OFF + (s8*)"); - break; - - case SIZE_WORD: - current_bits_mask = 0xFFFF; - current_sft_mask = 15; - strcpy(szc, "u16"); - strcpy(szcf, "*(WORD_OFF + (u16*)"); - strcpy(szcs, "s16"); - strcpy(szcsf, "*(WORD_OFF + (s16*)"); - break; - - case SIZE_LONG: - current_bits_mask = 0xFFFFFFFF; - current_sft_mask = 31; - strcpy(szc, "u32"); - strcpy(szcf, "*((u32*)"); - strcpy(szcs, "s32"); - strcpy(szcsf, "*((s32*)"); - break; - } -} - -// gen privilege exception (happen when S flag is not set) -static void gen_privilege_exception(char *pre) -{ - // swap A7 and USP (because S not set) - wf_op("%sres = CPU->USP;\n", pre); - wf_op("%sCPU->USP = CPU->A[7];\n", pre); - wf_op("%sCPU->A[7] = res;\n", pre); - - // get vector & add cycle - wf_op("%sres = C68K_PRIVILEGE_VIOLATION_EX;\n", pre); - adds_CCnt("c68k_exception_cycle_table[res]"); - - // we will do some mem/io access - do_pre_io(); - - // push PC and SR - mem_op("%sPUSH_32_F(PC - CPU->BasePC)\n", pre); - mem_op("%sPUSH_16_F(GET_SR)\n", pre); - - // adjust SR - wf_op("%sCPU->flag_S = C68K_SR_S;\n", pre); - - // fetch new PC - mem_op("%sREAD_LONG_F(res * 4, PC)\n", pre); - wf_op("%sSET_PC(PC)\n", pre); -} - -static void gen_exception(char *pre, char* exception) -{ - // swap A7 and USP if needed - wf_op("%sif (!CPU->flag_S)\n", pre); - wf_op("%s{\n", pre); - wf_op("%s\tres = CPU->USP;\n", pre); - wf_op("%s\tCPU->USP = CPU->A[7];\n", pre); - wf_op("%s\tCPU->A[7] = res;\n", pre); - wf_op("%s}\n", pre); - - // get vector & add cycle - wf_op("%sres = %s;\n", pre, exception); - adds_CCnt("c68k_exception_cycle_table[res]"); - - // we will do some mem/io access - do_pre_io(); - - // push PC and SR - mem_op("%sPUSH_32_F(PC - CPU->BasePC)\n", pre); - mem_op("%sPUSH_16_F(GET_SR)\n", pre); - - // adjust SR - wf_op("%sCPU->flag_S = C68K_SR_S;\n", pre); - - // fetch new PC - mem_op("%sREAD_LONG_F(res * 4, PC)\n", pre); - wf_op("%sSET_PC(PC)\n", pre); -} - diff --git a/yabause/src/carbon/CMakeLists.txt b/yabause/src/carbon/CMakeLists.txt deleted file mode 100644 index 219de3e075..0000000000 --- a/yabause/src/carbon/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -project(yabause-carbon) - -find_library(CARBON_LIBRARY carbon) - -if (NOT CARBON_LIBRARY) - return() -endif() - -set(yabause_carbon_SOURCES main.c settings.c settings.h cpustatus.c cpustatus.h) - -add_executable(yabause-carbon ${yabause_carbon_SOURCES}) -target_link_libraries(yabause-carbon yabause ${YABAUSE_LIBRARIES} ${CARBON_LIBRARY}) - -if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app" - COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/Yabause.app" "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Yabause.app" - ) -endif() - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS" - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS/yabause" - COMMAND ${CMAKE_COMMAND} -E copy $ "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS/yabause" - DEPENDS yabause-carbon - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS" -) - -add_custom_target(yabause-carbon-app ALL - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS/yabause") diff --git a/yabause/src/carbon/Makefile.am b/yabause/src/carbon/Makefile.am deleted file mode 100644 index b2822d2096..0000000000 --- a/yabause/src/carbon/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -EXTRA_DIST = build_dmg.sh Yabause.app/Contents/Info.plist Yabause.app/Contents/Resources/yabause.icns \ - Yabause.app/Contents/Resources/cpustatus.nib/classes.nib Yabause.app/Contents/Resources/cpustatus.nib/info.nib \ - Yabause.app/Contents/Resources/cpustatus.nib/objects.xib \ - Yabause.app/Contents/Resources/menu.nib/classes.nib Yabause.app/Contents/Resources/menu.nib/info.nib \ - Yabause.app/Contents/Resources/menu.nib/objects.xib \ - Yabause.app/Contents/Resources/preferences.nib/classes.nib Yabause.app/Contents/Resources/preferences.nib/info.nib \ - Yabause.app/Contents/Resources/preferences.nib/objects.xib -bin_PROGRAMS = yabause -yabause_SOURCES = main.c settings.c settings.h cpustatus.c cpustatus.h -yabause_CFLAGS = $(YAB_CFLAGS) -yabause_LDADD = $(YAB_LIBS) ../libyabause.a - -all-local: - if [ ! -e Yabause.app/Contents/MacOS ]; then mkdir Yabause.app/Contents/MacOS; fi - cp yabause Yabause.app/Contents/MacOS - if [ ! -e Yabause.app/Contents/Frameworks ]; then mkdir Yabause.app/Contents/Frameworks; fi - if [ ! -e Yabause.app/Contents/Frameworks/SDL.framework ]; then \ - if [ -e /Library/Frameworks/SDL.framework ]; then \ - cp -R /Library/Frameworks/SDL.framework Yabause.app/Contents/Frameworks; \ - elif [ -e ~/Library/Frameworks/SDL.framework ]; then \ - cp -R ~/Library/Frameworks/SDL.framework Yabause.app/Contents/Frameworks; \ - fi; \ - fi diff --git a/yabause/src/carbon/Yabause.app/Contents/Info.plist b/yabause/src/carbon/Yabause.app/Contents/Info.plist deleted file mode 100644 index 9e3e0c781f..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleExecutable - yabause - CFBundleIconFile - yabause.icns - CFBundleIdentifier - org.yabause.Yabause - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Yabause - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.9.10 - CFBundleVersion - 0.9.10 - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/classes.nib deleted file mode 100644 index ea58db1189..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/info.nib deleted file mode 100644 index 79be5a82ec..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/info.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBDocumentLocation - 76 101 356 240 0 0 1280 1002 - IBFramework Version - 446.1 - IBLockedObjects - - 223 - 239 - 240 - 241 - 242 - 243 - 244 - 245 - 232 - 235 - 246 - 247 - 248 - 249 - 250 - 251 - 252 - 253 - 254 - 258 - 259 - 261 - 277 - 296 - 286 - 271 - 267 - 299 - 300 - 306 - 304 - 270 - 308 - 303 - 266 - 298 - 273 - 302 - 274 - 301 - 269 - 311 - 310 - 295 - - IBOldestOS - 1 - IBOpenObjects - - 166 - - IBSystem Version - 8L2127 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/objects.xib deleted file mode 100644 index 025d5f41b5..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/objects.xib +++ /dev/null @@ -1,1229 +0,0 @@ - - - IBCarbonFramework - - NSApplication - - - - 404 468 747 1080 - Processor Status - - 0 0 343 612 - 0 0 612 343 - - - 6 20 323 296 - 20 6 276 317 - - - 36 36 49 73 - 16 30 37 13 - TRUE - 1 - R0 - -2 - - - 57 36 70 73 - 16 51 37 13 - TRUE - 1 - R1 - -2 - - - 78 36 91 73 - 16 72 37 13 - TRUE - 1 - R2 - -2 - - - 99 36 112 73 - 16 93 37 13 - TRUE - 1 - R3 - -2 - - - 120 36 133 73 - 16 114 37 13 - TRUE - 1 - R4 - -2 - - - 141 36 154 73 - 16 135 37 13 - TRUE - 1 - R5 - -2 - - - 162 36 175 73 - 16 156 37 13 - TRUE - 1 - R6 - -2 - - - 183 36 196 73 - 16 177 37 13 - TRUE - 1 - R7 - -2 - - - 36 162 49 199 - 142 30 37 13 - TRUE - 1 - R8 - -2 - - - 57 162 70 199 - 142 51 37 13 - TRUE - 1 - R9 - -2 - - - 78 162 91 199 - 142 72 37 13 - TRUE - 1 - R10 - -2 - - - 99 162 112 199 - 142 93 37 13 - TRUE - 1 - R11 - -2 - - - 120 162 133 199 - 142 114 37 13 - TRUE - 1 - R12 - -2 - - - 141 162 154 199 - 142 135 37 13 - TRUE - 1 - R13 - -2 - - - 162 162 175 199 - 142 156 37 13 - TRUE - 1 - R14 - -2 - - - 183 162 196 199 - 142 177 37 13 - TRUE - 1 - R15 - -2 - - - 38 84 48 151 - 64 32 67 10 - cpus - 1 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 36 219 73 - 16 200 37 13 - TRUE - 1 - MACH - -2 - - - 208 84 218 151 - 64 202 67 10 - cpus - 17 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 162 219 199 - 142 200 37 13 - TRUE - 1 - MACL - -2 - - - 229 36 242 73 - 16 223 37 13 - TRUE - 1 - GBR - -2 - - - 231 84 241 151 - 64 225 67 10 - cpus - 19 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 229 162 242 199 - 142 223 37 13 - TRUE - 1 - VBR - -2 - - - 252 36 265 73 - 16 246 37 13 - TRUE - 1 - PC - -2 - - - 252 162 265 199 - 142 246 37 13 - TRUE - 1 - PR - -2 - - - 59 84 69 151 - 64 53 67 10 - cpus - 2 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 84 90 151 - 64 74 67 10 - cpus - 3 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 84 111 151 - 64 95 67 10 - cpus - 4 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 84 132 151 - 64 116 67 10 - cpus - 5 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 84 153 151 - 64 137 67 10 - cpus - 6 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 84 174 151 - 64 158 67 10 - cpus - 7 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 84 195 151 - 64 179 67 10 - cpus - 8 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 84 262 151 - 64 246 67 10 - cpus - 21 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 38 210 48 277 - 190 32 67 10 - cpus - 9 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 59 210 69 277 - 190 53 67 10 - cpus - 10 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 210 90 277 - 190 74 67 10 - cpus - 11 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 210 111 277 - 190 95 67 10 - cpus - 12 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 210 132 277 - 190 116 67 10 - cpus - 13 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 210 153 277 - 190 137 67 10 - cpus - 14 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 210 174 277 - 190 158 67 10 - cpus - 15 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 210 195 277 - 190 179 67 10 - cpus - 16 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 208 210 218 277 - 190 202 67 10 - cpus - 18 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 231 210 241 277 - 190 225 67 10 - cpus - 20 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 210 262 277 - 190 246 67 10 - cpus - 22 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 273 81 286 280 - 61 267 199 13 - TRUE - 1 - Status bits go here - -1 - - - 294 36 307 73 - 16 288 37 13 - TRUE - 1 - SR - -2 - - - 296 84 306 277 - 64 290 193 10 - cpus - 23 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - Master - - - 6 316 323 592 - 316 6 276 317 - - - 36 332 49 369 - 16 30 37 13 - TRUE - 1 - R0 - -2 - - - 57 332 70 369 - 16 51 37 13 - TRUE - 1 - R1 - -2 - - - 78 332 91 369 - 16 72 37 13 - TRUE - 1 - R2 - -2 - - - 99 332 112 369 - 16 93 37 13 - TRUE - 1 - R3 - -2 - - - 120 332 133 369 - 16 114 37 13 - TRUE - 1 - R4 - -2 - - - 141 332 154 369 - 16 135 37 13 - TRUE - 1 - R5 - -2 - - - 162 332 175 369 - 16 156 37 13 - TRUE - 1 - R6 - -2 - - - 183 332 196 369 - 16 177 37 13 - TRUE - 1 - R7 - -2 - - - 36 458 49 495 - 142 30 37 13 - TRUE - 1 - R8 - -2 - - - 57 458 70 495 - 142 51 37 13 - TRUE - 1 - R9 - -2 - - - 78 458 91 495 - 142 72 37 13 - TRUE - 1 - R10 - -2 - - - 99 458 112 495 - 142 93 37 13 - TRUE - 1 - R11 - -2 - - - 120 458 133 495 - 142 114 37 13 - TRUE - 1 - R12 - -2 - - - 141 458 154 495 - 142 135 37 13 - TRUE - 1 - R13 - -2 - - - 162 458 175 495 - 142 156 37 13 - TRUE - 1 - R14 - -2 - - - 183 458 196 495 - 142 177 37 13 - TRUE - 1 - R15 - -2 - - - 38 380 48 447 - 64 32 67 10 - cpus - 31 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 332 219 369 - 16 200 37 13 - TRUE - 1 - MACH - -2 - - - 208 380 218 447 - 64 202 67 10 - cpus - 47 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 458 219 495 - 142 200 37 13 - TRUE - 1 - MACL - -2 - - - 229 332 242 369 - 16 223 37 13 - TRUE - 1 - GBR - -2 - - - 231 380 241 447 - 64 225 67 10 - cpus - 49 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 229 458 242 495 - 142 223 37 13 - TRUE - 1 - VBR - -2 - - - 252 332 265 369 - 16 246 37 13 - TRUE - 1 - PC - -2 - - - 252 458 265 495 - 142 246 37 13 - TRUE - 1 - PR - -2 - - - 59 380 69 447 - 64 53 67 10 - cpus - 32 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 380 90 447 - 64 74 67 10 - cpus - 33 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 380 111 447 - 64 95 67 10 - cpus - 34 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 380 132 447 - 64 116 67 10 - cpus - 35 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 380 153 447 - 64 137 67 10 - cpus - 36 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 380 174 447 - 64 158 67 10 - cpus - 37 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 380 195 447 - 64 179 67 10 - cpus - 38 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 380 262 447 - 64 246 67 10 - cpus - 51 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 38 506 48 573 - 190 32 67 10 - cpus - 39 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 59 506 69 573 - 190 53 67 10 - cpus - 40 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 506 90 573 - 190 74 67 10 - cpus - 41 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 506 111 573 - 190 95 67 10 - cpus - 42 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 506 132 573 - 190 116 67 10 - cpus - 43 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 506 153 573 - 190 137 67 10 - cpus - 44 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 506 174 573 - 190 158 67 10 - cpus - 45 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 506 195 573 - 190 179 67 10 - cpus - 46 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 208 506 218 573 - 190 202 67 10 - cpus - 48 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 231 506 241 573 - 190 225 67 10 - cpus - 50 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 506 262 573 - 190 246 67 10 - cpus - 52 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 273 377 286 576 - 61 267 199 13 - TRUE - 1 - Status bits go here - -1 - - - 294 332 307 369 - 16 288 37 13 - TRUE - 1 - SR - -2 - - - 296 380 306 573 - 64 290 193 10 - cpus - 53 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - Slave - - - - FALSE - FALSE - FALSE - FALSE - FALSE - TRUE - 5 - 5 - FALSE - TRUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - File's Owner - - Window - - - 313 - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/classes.nib deleted file mode 100644 index c4b887e72b..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/classes.nib +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IBVersion - 1 - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/info.nib deleted file mode 100644 index 44cc4f505c..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 740 - IBOldestOS - 6 - IBOpenObjects - - 167 - - IBSystem Version - 10C540 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/objects.xib deleted file mode 100644 index c8fc38239d..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/objects.xib +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - Address - 55 20 71 72 - - - conf - 50 - Browse - 20 239 40 309 - - - conf - 1 - 23 23 39 228 - - - FALSE - FALSE - FALSE - FALSE - 5 - Load - - - - - - conf - 2 - 55 83 71 306 - - - - 0 0 94 329 - - 72 111 166 440 - 60 0 778 1280 - - - - - - - - - - - - - - Dialog - - File's Owner - - - IBCarbonFramework - 320 - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/classes.nib deleted file mode 100644 index c4b887e72b..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/classes.nib +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IBVersion - 1 - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/info.nib deleted file mode 100644 index f17a327dc0..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 740 - IBOldestOS - 6 - IBOpenObjects - - 195 - - IBSystem Version - 10C540 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/objects.xib deleted file mode 100644 index 6c19b8b5ad..0000000000 Binary files a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/objects.xib and /dev/null differ diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/classes.nib deleted file mode 100644 index ea58db1189..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/info.nib deleted file mode 100644 index 8bec016c9c..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBDocumentLocation - 267 126 356 240 0 0 1280 1002 - IBFramework Version - 446.1 - IBOpenObjects - - 166 - - IBSystem Version - 8P2137 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/objects.xib deleted file mode 100644 index 607de62a48..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/objects.xib +++ /dev/null @@ -1,775 +0,0 @@ - - - IBCarbonFramework - - NSApplication - - - - 81 82 409 437 - Yabause preferences - - 0 0 328 355 - - - 12 -1 328 360 - - - 49 -1 328 360 - - - 50 19 116 340 - - - 81 38 97 243 - conf - 1 - - - 79 254 99 324 - conf - 50 - Browse - - - Bios - - - 124 19 218 340 - - - 155 38 171 243 - conf - 2 - - - 153 254 173 324 - conf - 51 - Browse - - - 182 35 202 324 - conf - 3 - - Popup: - - - Dummy CD - - - ISO or CUE file - - - Cdrom device - - - - - - Cdrom - - - 226 19 290 340 - - - 254 35 274 324 - conf - 4 - - Popup: - - - Auto-detect - - - Japan (NTSC) - - - Asia (NTSC) - - - North America (NTSC) - - - Central/South America (NTSC) - - - Korea (NTSC) - - - Asia (PAL) - - - Europe + others (PAL) - - - Central/South America (PAL) - - - - - - Region - - - tabs - 129 - 2 - - - 49 -1 328 360 - - - 50 19 146 340 - - - 78 35 98 324 - conf - 5 - - Popup: - - - TRUE - Dummy Video Interface - - - OpenGL Video Interface - - - Software Video Interface - - - - - - 112 35 130 196 - conf - 11 - Enable auto frameskip - - - Video core - - - 148 19 242 340 - - - 207 98 223 226 - FALSE - 224 - - - 176 35 192 87 - Width - - - 200 35 216 87 - Height - - - 178 237 192 324 - FALSE - Keep ratio - - - 177 98 193 226 - FALSE - 320 - - - Resolution - - - 244 19 308 340 - - - 272 35 292 324 - conf - 6 - - Popup: - - - Dummy Sound Interface - - - SDL Sound Interface - - - - - - Sound core - - - tabs - 130 - 2 - - - 49 -1 328 360 - - - 50 19 144 340 - - - 81 38 97 243 - conf - 7 - - - 79 254 99 324 - conf - 52 - Browse - - - 108 35 128 324 - conf - 8 - - Popup: - - - None - - - Pro Action Replay - - - 4 Mbit Backup Ram - - - 8 Mbit Backup Ram - - - 16 Mbit Backup Ram - - - 32 Mbit Backup Ram - - - 8 Mbit Dram - - - 32 Mbit Dram - - - Netlink - - - 16 Mbit ROM - - - - - - Cartridge - - - 152 19 218 340 - - - 183 38 199 243 - conf - 9 - - - 181 254 201 324 - conf - 53 - Browse - - - Memory - - - 226 19 292 340 - - - 257 38 273 243 - conf - 10 - - - 255 254 275 324 - conf - 54 - Browse - - - Mpeg ROM - - - tabs - 131 - 2 - - - 49 -1 328 360 - - - 64 19 80 115 - Up - - - 65 126 81 167 - conf - 31 - - - 90 19 106 115 - Right - - - 91 126 107 167 - conf - 32 - - - 116 19 132 115 - Down - - - 117 126 133 167 - conf - 33 - - - 142 19 158 115 - Left - - - 143 126 159 167 - conf - 34 - - - 168 19 184 115 - Right trigger - - - 169 126 185 167 - conf - 35 - - - 194 19 210 115 - Left trigger - - - 195 126 211 167 - conf - 36 - - - 220 19 236 115 - Start - - - 221 126 237 167 - conf - 37 - - - 65 296 81 337 - conf - 38 - - - 64 189 80 285 - A - - - 117 296 133 337 - conf - 40 - - - 142 189 158 285 - X - - - 194 189 210 285 - Z - - - 169 296 185 337 - conf - 42 - - - 195 296 211 337 - conf - 43 - - - 90 189 106 285 - B - - - 116 189 132 285 - C - - - 91 296 107 337 - conf - 39 - - - 143 296 159 337 - conf - 41 - - - 168 189 184 285 - Y - - - 54 178 296 179 - - - tabs - 132 - Input - 2 - - - tabs - 128 - - - contentResID - 0 - tabEnabled - 1 - tabName - General - userPane - - - - contentResID - 0 - tabEnabled - 1 - tabName - Video/Sound - userPane - - - - contentResID - 0 - tabEnabled - 1 - tabName - Memory - userPane - - - - contentResID - 0 - tabEnabled - 1 - tabName - Input - userPane - - - - - - - FALSE - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23642 -6178 23658 -6082 - Up - - - 23653 -6048 23649 -6053 - - - 23647 -6173 23663 -6077 - Up - - - 23658 -6043 23654 -6048 - - - - - - - - - 23648 -6053 23644 -6058 - - - 23585 -6183 23601 -6087 - Right - - - 23700 -6053 23696 -6058 - - - 23611 -6183 23627 -6087 - Down - - - 23726 -6053 23722 -6058 - - - 23715 -6183 23731 -6087 - Start - - - 23622 -6053 23618 -6058 - - - 23689 -6183 23705 -6087 - Left trigger - - - 23596 -6053 23592 -6058 - - - 23674 -6053 23670 -6058 - - - 23663 -6183 23679 -6087 - Right trigger - - - 23570 -6053 23566 -6058 - - - 23559 -6183 23575 -6087 - Up - - - 23637 -6183 23653 -6087 - Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dialog - - File's Owner - - NSCustomView2 - - - 313 - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/yabause.icns b/yabause/src/carbon/Yabause.app/Contents/Resources/yabause.icns deleted file mode 100644 index a039119928..0000000000 Binary files a/yabause/src/carbon/Yabause.app/Contents/Resources/yabause.icns and /dev/null differ diff --git a/yabause/src/carbon/build_dmg.sh b/yabause/src/carbon/build_dmg.sh deleted file mode 100644 index 3f3e2573bb..0000000000 --- a/yabause/src/carbon/build_dmg.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2006 Guillaume Duhamel -# Copyright 2006 Lawrence Sebald -# Copyright 2007 Anders Montonen -# -# This file is part of Yabause. -# -# Yabause 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. -# -# Yabause 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 Yabause; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - -hdiutil create -megabytes 20 tmp.dmg -layout NONE -fs HFS+ -volname Yabause -ov -tmp=`hdid tmp.dmg` -disk=`echo $tmp | cut -f 1 -d\ ` -cp -R Yabause.app /Volumes/Yabause/ -cp ../../ChangeLog /Volumes/Yabause/ -cp ../../README /Volumes/Yabause/ -cp ../../README.MAC /Volumes/Yabause/ -cp ../../AUTHORS /Volumes/Yabause/ -cp ../../COPYING /Volumes/Yabause/ -hdiutil eject $disk -hdiutil convert -format UDZO tmp.dmg -o Yabause.dmg -rm tmp.dmg diff --git a/yabause/src/carbon/cpustatus.c b/yabause/src/carbon/cpustatus.c deleted file mode 100644 index e672abea11..0000000000 --- a/yabause/src/carbon/cpustatus.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright 2006 Anders Montonen - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "cpustatus.h" -#include "../sh2core.h" - -/* Dialog field IDs */ - -#define SLAVE_ID_OFFSET 30 - -#define R0_ID 1 -#define R1_ID 2 -#define R2_ID 3 -#define R3_ID 4 -#define R4_ID 5 -#define R5_ID 6 -#define R6_ID 7 -#define R7_ID 8 -#define R8_ID 9 -#define R9_ID 10 -#define R10_ID 11 -#define R11_ID 12 -#define R12_ID 13 -#define R13_ID 14 -#define R14_ID 15 -#define R15_ID 16 -#define MACH_ID 17 -#define MACL_ID 18 -#define GBR_ID 19 -#define VBR_ID 20 -#define PC_ID 21 -#define PR_ID 22 -#define SR_ID 23 - -static WindowRef CPUStatusWindow; - -static OSStatus CPUStatusWindowEventHandler(EventHandlerCallRef myHandler, - EventRef theEvent, - void *userData) -{ - OSStatus result = eventNotHandledErr; - WindowRef window; - MenuRef menu; - - switch(GetEventKind(theEvent)) - { - case kEventWindowClose: - GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, - 0, sizeof(typeWindowRef), 0, &window); - DisposeWindow(window); - menu = GetMenuRef(1); - ChangeMenuItemAttributes(menu, 4, 0, kMenuItemAttrHidden); - ChangeMenuItemAttributes(menu, 5, kMenuItemAttrHidden, 0); - - result = noErr; - break; - } - - return result; -} - -void ShowCPUStatusWindow(void) -{ - IBNibRef nib; - - EventTypeSpec eventList[] = { {kEventClassWindow, kEventWindowClose} }; - - CreateNibReference(CFSTR("cpustatus"), &nib); - CreateWindowFromNib(nib, CFSTR("Window"), &CPUStatusWindow); - ShowWindow(CPUStatusWindow); - - InstallWindowEventHandler(CPUStatusWindow, - NewEventHandlerUPP(CPUStatusWindowEventHandler), - GetEventTypeCount(eventList), - eventList, CPUStatusWindow, NULL); - - UpdateCPUStatusWindow(); -} - -void HideCPUStatusWindow(void) -{ - DisposeWindow(CPUStatusWindow); -} - -static void SetSRString(u32 SR, CFMutableStringRef s) -{ - int ii; - - for(ii = 0; ii < 32; ii++) - { - if(SR & 0x80000000) - CFStringAppendCString(s, "1", kCFStringEncodingASCII); - else - CFStringAppendCString(s, "0", kCFStringEncodingASCII); - - SR <<= 1; - } -} - -static void SetRegisterValue(const int controlId, CFStringRef s) -{ - ControlID id; - ControlRef control; - - id.signature = 'cpus'; - id.id = controlId; - GetControlByID(CPUStatusWindow, &id, &control); - SetControlData(control, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - -} - -void UpdateCPUStatusWindow(void) -{ - CFStringRef s; - CFMutableStringRef ms; - sh2regs_struct master = {0}; - sh2regs_struct slave = {0}; - int ii = 0; - int srNumber = 0; - - if(MSH2) - SH2GetRegisters(MSH2, &master); - - if(SSH2) - SH2GetRegisters(SSH2, &slave); - - /* Master registers */ - for(ii = 0; ii < 16; ii++) - { - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.R[ii]); - SetRegisterValue(ii+1, s); - } - - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.MACH); - SetRegisterValue(MACH_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.MACL); - SetRegisterValue(MACL_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.GBR); - SetRegisterValue(GBR_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.VBR); - SetRegisterValue(VBR_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.PC); - SetRegisterValue(PC_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.PR); - SetRegisterValue(PR_ID, s); - - ms = CFStringCreateMutable(kCFAllocatorDefault, 32); - SetSRString(master.SR.all, ms); - SetRegisterValue(SR_ID, ms); - - /* Slave registers */ - for(ii = 0; ii < 16; ii++) - { - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.R[ii]); - SetRegisterValue(ii+1+SLAVE_ID_OFFSET, s); - } - - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.MACH); - SetRegisterValue(MACH_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.MACL); - SetRegisterValue(MACL_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.GBR); - SetRegisterValue(GBR_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.VBR); - SetRegisterValue(VBR_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.PC); - SetRegisterValue(PC_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.PR); - SetRegisterValue(PR_ID+SLAVE_ID_OFFSET, s); - ms = CFStringCreateMutable(kCFAllocatorDefault, 32); - SetSRString(slave.SR.all, ms); - SetRegisterValue(SR_ID+SLAVE_ID_OFFSET, ms); -} diff --git a/yabause/src/carbon/cpustatus.h b/yabause/src/carbon/cpustatus.h deleted file mode 100644 index 58cb7df205..0000000000 --- a/yabause/src/carbon/cpustatus.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2006 Anders Montonen - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CPUSTATUS_H_ -#define CPUSTATUS_H_ - -void ShowCPUStatusWindow(void); -void HideCPUStatusWindow(void); -void UpdateCPUStatusWindow(void); - -#endif /* CPUSTATUS_H_ */ diff --git a/yabause/src/carbon/main.c b/yabause/src/carbon/main.c deleted file mode 100644 index e89acccf91..0000000000 --- a/yabause/src/carbon/main.c +++ /dev/null @@ -1,609 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Anders Montonen - Copyright 2010 Alex Marshall - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "../core.h" -#include "../memory.h" -#include "settings.h" -#include "cpustatus.h" -#include "../yabause.h" - -#define YUI_MENU_EMULATION 1 -#define YUI_MENU_DEBUG 2 - -#define YUI_COMMAND_RESET 1 -#define YUI_COMMAND_PAUSE 2 -#define YUI_COMMAND_RESUME 3 -#define YUI_COMMAND_SHOW_CPU 4 -#define YUI_COMMAND_HIDE_CPU 5 -#define YUI_COMMAND_TOGGLE_NBG0 6 -#define YUI_COMMAND_TOGGLE_NBG1 7 -#define YUI_COMMAND_TOGGLE_NBG2 8 -#define YUI_COMMAND_TOGGLE_NBG3 9 -#define YUI_COMMAND_TOGGLE_RBG0 10 -#define YUI_COMMAND_TOGGLE_VDP1 11 -#define YUI_COMMAND_TOGGLE_FULLSCREEN 12 -#define YUI_COMMAND_LOAD_BINARY 13 -#define YUI_COMMAND_LOAD_AND_EXECUTE 14 -#define YUI_COMMAND_SAVE_BINARY 15 - -AGLContext myAGLContext = NULL; -WindowRef myWindow = NULL; -yabauseinit_struct yinit; - -M68K_struct * M68KCoreList[] = { -&M68KDummy, -#ifdef HAVE_C68K -&M68KC68K, -#endif -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -NULL -}; - -PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -&ArchCD, -NULL -}; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -#ifdef HAVE_LIBSDL -&SNDSDL, -#endif -NULL -}; - -VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDOGL, -&VIDSoft, -NULL -}; - -static EventLoopTimerRef EventTimer; -int load_file_core(char* file, char* addr, int type); - -void YuiIdle(EventLoopTimerRef a, void * b) -{ - PERCore->HandleEvents(); -} - -void read_settings(void) { - PerPad_struct * pad; - int i; - CFStringRef s; - yinit.percoretype = PERCORE_DUMMY; - yinit.sh2coretype = SH2CORE_INTERPRETER; - yinit.vidcoretype = VIDCORE_OGL; - yinit.m68kcoretype = M68KCORE_C68K; - s = CFPreferencesCopyAppValue(CFSTR("VideoCore"), - kCFPreferencesCurrentApplication); - if (s) - yinit.vidcoretype = CFStringGetIntValue(s) - 1; - yinit.sndcoretype = SNDCORE_DUMMY; - s = CFPreferencesCopyAppValue(CFSTR("SoundCore"), - kCFPreferencesCurrentApplication); - if (s) - yinit.sndcoretype = CFStringGetIntValue(s) - 1; - yinit.cdcoretype = CDCORE_ARCH; - s = CFPreferencesCopyAppValue(CFSTR("CDROMCore"), - kCFPreferencesCurrentApplication); - if (s) - yinit.cdcoretype = CFStringGetIntValue(s) - 1; - yinit.carttype = CART_NONE; - s = CFPreferencesCopyAppValue(CFSTR("CartType"), - kCFPreferencesCurrentApplication); - if (s) - yinit.carttype = CFStringGetIntValue(s) - 1; - yinit.regionid = 0; - s = CFPreferencesCopyAppValue(CFSTR("Region"), - kCFPreferencesCurrentApplication); - if (s) - yinit.regionid = CFStringGetIntValue(s) - 1; - - yinit.biospath = 0; - s = CFPreferencesCopyAppValue(CFSTR("BiosPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.biospath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.cdpath = 0; - s = CFPreferencesCopyAppValue(CFSTR("CDROMDrive"), - kCFPreferencesCurrentApplication); - if (s) - yinit.cdpath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.buppath = 0; - s = CFPreferencesCopyAppValue(CFSTR("BackupRamPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.buppath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.mpegpath = 0; - s = CFPreferencesCopyAppValue(CFSTR("MpegRomPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.mpegpath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.cartpath = 0; - s = CFPreferencesCopyAppValue(CFSTR("CartPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.cartpath = strdup(CFStringGetCStringPtr(s, 0)); - - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - - s = CFPreferencesCopyAppValue(CFSTR("AutoFrameSkip"), - kCFPreferencesCurrentApplication); - if (s) - yinit.frameskip = CFStringGetIntValue(s); - - PerPortReset(); - pad = PerPadAdd(&PORTDATA1); - - i = 0; - while(PerPadNames[i]) { - s = CFPreferencesCopyAppValue( - CFStringCreateWithCString(0, PerPadNames[i], 0), - kCFPreferencesCurrentApplication); - if (s) - PerSetKey(CFStringGetIntValue(s), i, pad); - i++; - } -} - -static void YuiPause(const int Pause) -{ - EventTimerInterval Interval; - - if(Pause) - { - Interval = kEventDurationForever; - ScspMuteAudio(SCSP_MUTE_SYSTEM); - } - else - { - Interval = 16*kEventDurationMillisecond; - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - } - - SetEventLoopTimerNextFireTime(EventTimer, Interval); -} - -void YuiRun(void) { - static int FirstRun = 1; - EventLoopTimerUPP myFrameUPP; - - if(FirstRun) - { - myFrameUPP = NewEventLoopTimerUPP(YuiIdle); - InstallEventLoopTimer(GetCurrentEventLoop(), kEventDurationNoWait, - 16*kEventDurationMillisecond, myFrameUPP, NULL, &EventTimer); - FirstRun = 0; - } - else - { - YuiPause(0); - YabauseDeInit(); - } - - read_settings(); - YabauseInit(&yinit); -} - -static void TogglePairedMenuItems(MenuRef menu, MenuItemIndex BaseItemIndex) -{ - MenuItemAttributes ItemAttributes; - - GetMenuItemAttributes(menu, BaseItemIndex, &ItemAttributes); - - if(ItemAttributes & kMenuItemAttrHidden) - { - ChangeMenuItemAttributes(menu, BaseItemIndex, 0, kMenuItemAttrHidden); - ChangeMenuItemAttributes(menu, BaseItemIndex+1, kMenuItemAttrHidden, 0); - } - else - { - ChangeMenuItemAttributes(menu, BaseItemIndex, kMenuItemAttrHidden, 0); - ChangeMenuItemAttributes(menu, BaseItemIndex+1, 0, kMenuItemAttrHidden); - } -} - -OSStatus MyWindowEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData) -{ - OSStatus ret = noErr; - MenuRef menu; - - switch(GetEventClass(theEvent)) { - case kEventClassWindow: - switch (GetEventKind (theEvent)) { - case kEventWindowClose: - - YabauseDeInit(); - QuitApplicationEventLoop(); - break; - - case kEventWindowBoundsChanged: - aglUpdateContext(myAGLContext); - { - Rect bounds; - GetEventParameter(theEvent, kEventParamCurrentBounds, - typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds); - glViewport(0, 0, bounds.right - bounds.left, - bounds.bottom - bounds.top); - } - break; - } - break; - case kEventClassCommand: - { - HICommand command; - GetEventParameter(theEvent, kEventParamDirectObject, - typeHICommand, NULL, sizeof(HICommand), NULL, &command); - switch(command.commandID) { - case kHICommandPreferences: - CreateSettingsWindow(); - break; - case kHICommandQuit: - YabauseDeInit(); - QuitApplicationEventLoop(); - break; - case YUI_COMMAND_RESET: - YabauseReset(); - break; - case YUI_COMMAND_PAUSE: - YuiPause(1); - menu = GetMenuRef(YUI_MENU_EMULATION); - TogglePairedMenuItems(menu, 2); - UpdateCPUStatusWindow(); - break; - case YUI_COMMAND_RESUME: - YuiPause(0); - menu = GetMenuRef(YUI_MENU_EMULATION); - TogglePairedMenuItems(menu, 2); - break; - case YUI_COMMAND_SHOW_CPU: - ShowCPUStatusWindow(); - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 1); - break; - case YUI_COMMAND_HIDE_CPU: - HideCPUStatusWindow(); - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 1); - break; - case YUI_COMMAND_TOGGLE_NBG0: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 4); - ToggleNBG0(); - } - break; - case YUI_COMMAND_TOGGLE_NBG1: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 6); - ToggleNBG1(); - } - break; - case YUI_COMMAND_TOGGLE_NBG2: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 8); - ToggleNBG2(); - } - break; - case YUI_COMMAND_TOGGLE_NBG3: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 10); - ToggleNBG3(); - } - break; - case YUI_COMMAND_TOGGLE_RBG0: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 12); - ToggleRBG0(); - } - break; - case YUI_COMMAND_TOGGLE_VDP1: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 14); - ToggleVDP1(); - } - break; - case YUI_COMMAND_TOGGLE_FULLSCREEN: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_EMULATION); - TogglePairedMenuItems(menu, 5); - ToggleFullScreen(); - } - break; - case YUI_COMMAND_LOAD_BINARY: - CreateLoadWindow(0); - break; - case YUI_COMMAND_LOAD_AND_EXECUTE: - CreateLoadWindow(1); - break; - case YUI_COMMAND_SAVE_BINARY: -// MappedMemorySave(file, address, size); - break; - default: - ret = eventNotHandledErr; - printf("unhandled command\n"); - break; - } - } - break; - - case kEventClassKeyboard: - switch(GetEventKind(theEvent)) { - int i; - UInt32 key; - case kEventRawKeyDown: - GetEventParameter(theEvent, kEventParamKeyCode, - typeUInt32, NULL, sizeof(UInt32), NULL, &key); - PerKeyDown(key); - break; - case kEventRawKeyUp: - GetEventParameter(theEvent, kEventParamKeyCode, - typeUInt32, NULL, sizeof(UInt32), NULL, &key); - PerKeyUp(key); - break; - } - break; - } - - return ret; -} - -static WindowRef CreateMyWindow() { - - WindowRef myWindow; - Rect contentBounds; - - CFStringRef windowTitle = CFSTR("Yabause"); - WindowClass windowClass = kDocumentWindowClass; - WindowAttributes attributes = - kWindowStandardDocumentAttributes | - kWindowStandardHandlerAttribute | - kWindowLiveResizeAttribute; - - EventTypeSpec eventList[] = { - { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowBoundsChanged }, - { kEventClassCommand, kEventCommandProcess }, - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyUp } - }; - - SetRect(&contentBounds, 200, 200, 520, 424); - - CreateNewWindow (windowClass, - attributes, - &contentBounds, - &myWindow); - - SetWindowTitleWithCFString (myWindow, windowTitle); - CFRelease(windowTitle); - ShowWindow(myWindow); - - InstallWindowEventHandler(myWindow, - NewEventHandlerUPP (MyWindowEventHandler), - GetEventTypeCount(eventList), - eventList, myWindow, NULL); - return myWindow; -} - -static OSStatus MyAGLReportError (void) { - GLenum err = aglGetError(); - - if (err == AGL_NO_ERROR) - return noErr; - else - return (OSStatus) err; -} - -static OSStatus MySetWindowAsDrawableObject (WindowRef window) -{ - OSStatus err = noErr; - - GLint attributes[] = { AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_DEPTH_SIZE, 24, - AGL_NONE }; - - AGLPixelFormat myAGLPixelFormat; - - myAGLPixelFormat = aglChoosePixelFormat (NULL, 0, attributes); - - err = MyAGLReportError (); - - if (myAGLPixelFormat) { - myAGLContext = aglCreateContext (myAGLPixelFormat, NULL); - - err = MyAGLReportError (); - aglDestroyPixelFormat(myAGLPixelFormat); - } - - if (! aglSetDrawable (myAGLContext, GetWindowPort (window))) - err = MyAGLReportError (); - - if (!aglSetCurrentContext (myAGLContext)) - err = MyAGLReportError (); - - return err; - -} - -int main(int argc, char* argv[]) { - MenuRef menu; - EventLoopTimerRef nextFrameTimer; - IBNibRef menuNib; - - myWindow = CreateMyWindow(); - MySetWindowAsDrawableObject(myWindow); - - CreateNibReference(CFSTR("menu"), &menuNib); - SetMenuBarFromNib(menuNib, CFSTR("MenuBar")); - - EnableMenuCommand(NULL, kHICommandPreferences); - - read_settings(); - - YuiRun(); - if(argc >= 2) - load_file_core(argv[1], (argc >= 3) ? argv[2] : NULL, 1); - - RunApplicationEventLoop(); - - return 0; -} - -void YuiErrorMsg(const char * string) { - printf("%s\n", string); -} - -void YuiSetVideoAttribute(int type, int val) { -} - -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) -{ - static CFDictionaryRef oldDisplayMode = 0; - static int oldDisplayModeValid = 0; - - AGLPixelFormat myAGLPixelFormat; - AGLDrawable myDrawable = aglGetDrawable(myAGLContext); - OSStatus err = noErr; - GLint attributesFullscreen[] = { AGL_RGBA, - AGL_FULLSCREEN, - AGL_DOUBLEBUFFER, - AGL_DEPTH_SIZE, 24, - AGL_NONE }; - CGDirectDisplayID displayId = kCGDirectMainDisplay; - - if(myDrawable) - { - if(fullscreen) - { - Rect bounds; - CGPoint point; - CGDisplayCount displayCount; - - GetWindowBounds(myWindow, kWindowGlobalPortRgn, &bounds); - point.x = (float)bounds.left; - point.y = (float)bounds.top; - - CGGetDisplaysWithPoint(point, 1, &displayId, &displayCount); - - CFDictionaryRef refDisplayMode = CGDisplayBestModeForParameters(displayId, - bpp, width, height, NULL); - if(refDisplayMode) - { - GDHandle gdhDisplay; - oldDisplayMode = CGDisplayCurrentMode(displayId); - oldDisplayModeValid = 1; - - aglSetDrawable(myAGLContext, NULL); - aglSetCurrentContext(NULL); - aglDestroyContext(myAGLContext); - myAGLContext = NULL; - - CGCaptureAllDisplays(); - CGDisplaySwitchToMode(displayId, refDisplayMode); - CGDisplayHideCursor(displayId); - - DMGetGDeviceByDisplayID((DisplayIDType)displayId, &gdhDisplay, 0); - - myAGLPixelFormat = aglChoosePixelFormat(&gdhDisplay, 1, attributesFullscreen); - if(myAGLPixelFormat) - { - myAGLContext = aglCreateContext(myAGLPixelFormat, NULL); - if(myAGLContext) - { - aglSetCurrentContext(myAGLContext); - aglSetFullScreen(myAGLContext, width, height, 0, 0); - } - - err = MyAGLReportError(); - aglDestroyPixelFormat(myAGLPixelFormat); - } - else - { - err = MyAGLReportError(); - CGReleaseAllDisplays(); - CGDisplayShowCursor(displayId); - } - } - else - { - err = MyAGLReportError(); - } - } - else - { - if(oldDisplayModeValid) - { - oldDisplayModeValid = 0; - - aglSetDrawable(myAGLContext, NULL); - aglSetCurrentContext(NULL); - aglDestroyContext(myAGLContext); - myAGLContext = NULL; - - CGDisplayShowCursor(displayId); - CGDisplaySwitchToMode(displayId, oldDisplayMode); - CGReleaseAllDisplays(); - - MySetWindowAsDrawableObject(myWindow); - } - } - } - - return !(err == noErr); -} - -void YuiSwapBuffers(void) { - aglSwapBuffers(myAGLContext); -} diff --git a/yabause/src/carbon/settings.c b/yabause/src/carbon/settings.c deleted file mode 100644 index 091dfa05ff..0000000000 --- a/yabause/src/carbon/settings.c +++ /dev/null @@ -1,491 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Anders Montonen - Copyright 2010 Alex Marshall - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "settings.h" - -#define TAB_ID 128 -#define TAB_SIGNATURE 'tabs' -int tabList[] = {129, 130, 131, 132}; - -int loadtype = 0; -ControlRef oldTab; - -int mystrnlen(char* in, int maxlen) -{ - int len; - for(len = 0; (*in != 0) && (len < maxlen); len++, in++); - return len; -} - -unsigned int mytoi(char* in) -{ - unsigned int out = 0; - int length = 0; - int i; - int format = 0; /* Decimal */ - if((in[0] == '0') && (in[1] == 'x')) { - in += 2; - format = 1; /* Hexadecimal */ - }else if(in[0] == '$') { - in += 1; - format = 1; /* Hexadecimal */ - }else if((in[0] == 'H') && (in[1] == '\'')) { - in += 2; - format = 1; /* Hexadecimal */ - } - length = mystrnlen(in, 11); - for(i = 0; i < length; i++) { - switch(format) { - case 0: /* Decimal */ - out *= 10; - if((in[i] >= '0') && (in[i] <= '9')) - out += in[i] - '0'; - break; - case 1: /* Hexadecimal */ - out <<= 4; - if((in[i] >= '0') && (in[i] <= '9')) - out += in[i] - '0'; - if((in[i] >= 'A') && (in[i] <= 'F')) - out += (in[i] - 'A') + 0xA; - if((in[i] >= 'a') && (in[i] <= 'f')) - out += (in[i] - 'a') + 0xA; - break; - } - } - return out; -} - -void SelectItemOfTabControl(ControlRef tabControl) -{ - ControlRef userPane; - ControlID controlID; - - GetControlID(tabControl, &controlID); - if (controlID.id != TAB_ID) return; - - controlID.signature = TAB_SIGNATURE; - - controlID.id = tabList[GetControlValue(tabControl) - 1]; - GetControlByID(GetControlOwner(tabControl), &controlID, &userPane); - - DisableControl(oldTab); - SetControlVisibility(oldTab, false, false); - EnableControl(userPane); - SetControlVisibility(userPane, true, true); - oldTab = userPane; - - Draw1Control(tabControl); -} - -pascal OSStatus TabEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) -{ - ControlRef control; - - GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, - NULL, sizeof(ControlRef), NULL, &control ); - - SelectItemOfTabControl(control); - - return eventNotHandledErr; -} - -void InstallTabHandler(WindowRef window) -{ - EventTypeSpec controlSpec = { kEventClassControl, kEventControlHit }; - ControlRef tabControl; - ControlID controlID; - int i; - - controlID.signature = TAB_SIGNATURE; - - for(i = 0;i < 4;i++) { - controlID.id = tabList[i]; - GetControlByID(window, &controlID, &tabControl); - DisableControl(tabControl); - SetControlVisibility(tabControl, false, false); - } - - controlID.id = TAB_ID; - GetControlByID(window, &controlID, &tabControl); - - InstallControlEventHandler(tabControl, - NewEventHandlerUPP( TabEventHandler ), - 1, &controlSpec, 0, NULL); - - SetControl32BitValue(tabControl, 1); - - SelectItemOfTabControl(tabControl); -} - -CFStringRef get_settings(WindowRef window, int i) { - ControlID id; - ControlRef control; - CFStringRef s; - - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - GetControlData(control, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s, NULL); - - return s; -} - -CFStringRef get_settings_c(WindowRef window, int i) { - ControlID id; - ControlRef control; - CFStringRef s; - - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%d"), GetControl32BitValue(control)); - - return s; -} - -void set_settings(WindowRef window, int i, CFStringRef s) { - ControlID id; - ControlRef control; - - if (s) { - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - SetControlData(control, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - } -} - -void set_settings_c(WindowRef window, int i, CFStringRef s) { - ControlID id; - ControlRef control; - - if (s) { - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - SetControl32BitValue(control, CFStringGetIntValue(s)); - } -} - -void save_settings(WindowRef window) { - PerPad_struct * pad; - int i; - CFStringRef s; - - CFPreferencesSetAppValue(CFSTR("BiosPath"), get_settings(window, 1), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CDROMDrive"), get_settings(window, 2), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CDROMCore"), get_settings_c(window, 3), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("Region"), get_settings_c(window, 4), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("VideoCore"), get_settings_c(window, 5), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("SoundCore"), get_settings_c(window, 6), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CartPath"), get_settings(window, 7), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CartType"), get_settings_c(window, 8), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("BackupRamPath"), - get_settings(window, 9), kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("MpegRomPath"), - get_settings(window, 10), kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("AutoFrameSkip"), - get_settings_c(window, 11), kCFPreferencesCurrentApplication); - - PerPortReset(); - pad = PerPadAdd(&PORTDATA1); - - i = 0; - while(PerPadNames[i]) { - s = get_settings(window, 31 + i); - CFPreferencesSetAppValue( - CFStringCreateWithCString(0, PerPadNames[i], 0), - s, kCFPreferencesCurrentApplication); - PerSetKey(CFStringGetIntValue(s), i, pad); - i++; - } - - CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); -} - -void load_settings(WindowRef window) { - int i; - - set_settings(window, 1, CFPreferencesCopyAppValue(CFSTR("BiosPath"), - kCFPreferencesCurrentApplication)); - set_settings(window, 2, CFPreferencesCopyAppValue(CFSTR("CDROMDrive"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 3, CFPreferencesCopyAppValue(CFSTR("CDROMCore"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 4, CFPreferencesCopyAppValue(CFSTR("Region"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 5, CFPreferencesCopyAppValue(CFSTR("VideoCore"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 6, CFPreferencesCopyAppValue(CFSTR("SoundCore"), - kCFPreferencesCurrentApplication)); - set_settings(window, 7, CFPreferencesCopyAppValue(CFSTR("CartPath"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 8, CFPreferencesCopyAppValue(CFSTR("CartType"), - kCFPreferencesCurrentApplication)); - set_settings(window, 9, - CFPreferencesCopyAppValue(CFSTR("BackupRamPath"), - kCFPreferencesCurrentApplication)); - set_settings(window, 10, CFPreferencesCopyAppValue(CFSTR("MpegRomPath"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 11, CFPreferencesCopyAppValue(CFSTR("AutoFrameSkip"), - kCFPreferencesCurrentApplication)); - - i = 0; - while(PerPadNames[i]) { - set_settings(window, 31 + i, CFPreferencesCopyAppValue( - CFStringCreateWithCString(0, PerPadNames[i], 0), - kCFPreferencesCurrentApplication)); - i++; - } -} - -int load_file_core(char* file, char* addr, int type) -{ - unsigned int adr; - int ret = -1; - if(addr == NULL) - adr = 0; - else - adr = mytoi(addr); - switch(type) { - case 0: - ret = MappedMemoryLoad(file, adr); - break; - case 1: - MappedMemoryLoadExec(file, adr); - ret = 0; - break; - } - return ret; -} - -void load_file(WindowRef window, int type) { - char addrbuf[12]; - char filebuf[256]; - int ret = -1; - CFStringGetCString(get_settings(window, 1), filebuf, 256, kCFStringEncodingUTF8); - CFStringGetCString(get_settings(window, 2), addrbuf, 12, kCFStringEncodingUTF8); - ret = load_file_core(filebuf, addrbuf, type); - (void)(ret); /* We need to do something about bad return values... */ -} - -OSStatus SettingsWindowEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData) -{ - OSStatus result = eventNotHandledErr; - - switch (GetEventKind (theEvent)) - { - case kEventWindowClose: - { - WindowRef window; - GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, - 0, sizeof(typeWindowRef), 0, &window); - - save_settings(window); - - DisposeWindow(window); - } - result = noErr; - break; - - } - - return (result); -} - -OSStatus BrowseHandler(EventHandlerCallRef h, EventRef event, void* data) { - NavDialogRef dialog; - NavDialogCreationOptions options; - - NavGetDefaultDialogCreationOptions(&options); - NavCreateChooseFileDialog(&options, NULL, NULL, NULL, NULL, - NULL, &dialog); - NavDialogRun(dialog); - - if (NavDialogGetUserAction(dialog) == kNavUserActionChoose) { - NavReplyRecord reply; - FSRef fileAsFSRef; - CFURLRef fileAsCFURLRef = NULL; - CFStringRef s; - - NavDialogGetReply(dialog, &reply); - - AEGetNthPtr(&(reply.selection), 1, typeFSRef, - NULL, NULL, &fileAsFSRef, sizeof(FSRef), NULL); - - NavDisposeReply(&reply); - NavDialogDispose(dialog); - - fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef); - s = CFURLCopyFileSystemPath(fileAsCFURLRef, kCFURLPOSIXPathStyle); - - CFShow(s); - - SetControlData(data, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - Draw1Control(data); - } - - return noErr; -} - -OSStatus KeyConfigHandler(EventHandlerCallRef h, EventRef event, void* data) { - UInt32 key; - CFStringRef s; - GetEventParameter(event, kEventParamKeyCode, - typeUInt32, NULL, sizeof(UInt32), NULL, &key); - s = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), key); - SetControlData(data, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - Draw1Control(data); - - return noErr; -} - -void InstallBrowseHandler(WindowRef myWindow, const SInt32 ControllerId, - const SInt32 ControlledId) -{ - EventTypeSpec flist[] = { - { kEventClassControl, kEventControlHit } - }; - ControlID Id; - ControlRef Controller, Controlled; - - Id.signature = 'conf'; - Id.id = ControllerId; - GetControlByID(myWindow, &Id, &Controller); - Id.id = ControlledId; - GetControlByID(myWindow, &Id, &Controlled); - InstallControlEventHandler(Controller, NewEventHandlerUPP(BrowseHandler), - GetEventTypeCount(flist), flist, Controlled, NULL); -} - -WindowRef CreateSettingsWindow() { - - WindowRef myWindow; - IBNibRef nib; - - EventTypeSpec eventList[] = { - { kEventClassWindow, kEventWindowClose } - }; - - CreateNibReference(CFSTR("preferences"), &nib); - CreateWindowFromNib(nib, CFSTR("Dialog"), &myWindow); - - load_settings(myWindow); - - InstallTabHandler(myWindow); - - { - int i; - ControlRef control, controlled; - ControlID id; - EventTypeSpec elist[] = { - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyUp } - }; - - id.signature = 'conf'; - i = 0; - while(PerPadNames[i]) { - id.id = 31 + i; - GetControlByID(myWindow, &id, &control); - - InstallControlEventHandler(control, NewEventHandlerUPP(KeyConfigHandler), - GetEventTypeCount(elist), elist, control, NULL); - i++; - } - - InstallBrowseHandler(myWindow, 50, 1); /* BIOS */ - InstallBrowseHandler(myWindow, 51, 2); /* CDROM */ - InstallBrowseHandler(myWindow, 52, 7); /* Cartridge ROM */ - InstallBrowseHandler(myWindow, 53, 9); /* Memory */ - InstallBrowseHandler(myWindow, 54, 10); /* MPEG ROM */ - } - - ShowWindow(myWindow); - - InstallWindowEventHandler(myWindow, - NewEventHandlerUPP (SettingsWindowEventHandler), - GetEventTypeCount(eventList), - eventList, myWindow, NULL); - - return myWindow; -} - -OSStatus LoadWindowEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData) -{ - OSStatus result = eventNotHandledErr; - switch (GetEventKind (theEvent)) - { - case kEventWindowClose: - { - WindowRef window; - GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, - 0, sizeof(typeWindowRef), 0, &window); - - load_file(window, loadtype); - - DisposeWindow(window); - } - result = noErr; - break; - } - return (result); -} - -WindowRef CreateLoadWindow(int type) { - WindowRef myWindow; - IBNibRef nib; - int* hack; - EventTypeSpec eventList[] = { - { kEventClassWindow, kEventWindowClose } - }; - - CreateNibReference(CFSTR("load_dialog"), &nib); - CreateWindowFromNib(nib, CFSTR("Dialog"), &myWindow); - - InstallTabHandler(myWindow); - hack = malloc(sizeof(int)); - loadtype = type; - InstallBrowseHandler(myWindow, 50, 1); /* File */ - ShowWindow(myWindow); - - InstallWindowEventHandler(myWindow, - NewEventHandlerUPP (LoadWindowEventHandler), - GetEventTypeCount(eventList), - eventList, myWindow, NULL); - return myWindow; -} diff --git a/yabause/src/carbon/settings.h b/yabause/src/carbon/settings.h deleted file mode 100644 index 37f6522522..0000000000 --- a/yabause/src/carbon/settings.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "../yabause.h" -#include "../peripheral.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vidogl.h" -#include "../vidsoft.h" -#include "../scsp.h" -#include "../sndsdl.h" -#include "../cdbase.h" -#include "../cs0.h" -#include "../m68kcore.h" - -extern yabauseinit_struct yinit; - -WindowRef CreateSettingsWindow(); - -typedef struct _YuiAction YuiAction; - -/* -struct _YuiAction { - UInt32 key; - const char * name; - void (*press)(void); - void (*release)(void); -}; - -extern YuiAction key_config[]; -*/ diff --git a/yabause/src/cd-freebsd.c b/yabause/src/cd-freebsd.c deleted file mode 100644 index 9e451b20a0..0000000000 --- a/yabause/src/cd-freebsd.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2004-2006 Guillaume Duhamel - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cdbase.h" -#include "debug.h" - -static int FreeBSDCDInit(const char *); -static void FreeBSDCDDeInit(void); -static s32 FreeBSDCDReadTOC(u32 *); -static int FreeBSDCDGetStatus(void); -static int FreeBSDCDReadSectorFAD(u32, void *); -static void FreeBSDCDReadAheadFAD(u32); - -CDInterface ArchCD = { - CDCORE_ARCH, - "FreeBSD CD Drive", - FreeBSDCDInit, - FreeBSDCDDeInit, - FreeBSDCDGetStatus, - FreeBSDCDReadTOC, - FreeBSDCDReadSectorFAD, - FreeBSDCDReadAheadFAD, -}; - -static int hCDROM; - -static int FreeBSDCDInit(const char * cdrom_name) { - int bsize = 2352; - - if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) { - LOG("CDInit (%s) failed\n", cdrom_name); - return -1; - } - - if (ioctl (hCDROM, CDRIOCSETBLOCKSIZE, &bsize) == -1) { - return -1; - } - - LOG("CDInit (%s) OK\n", cdrom_name); - return 0; -} - -static void FreeBSDCDDeInit(void) { - if (hCDROM != -1) { - close(hCDROM); - } - - LOG("CDDeInit OK\n"); -} - - -static s32 FreeBSDCDReadTOC(u32 * TOC) -{ - int success; - struct ioc_toc_header ctTOC; - struct ioc_read_toc_single_entry ctTOCent; - int i, j; - int add150 = 0; - - ctTOCent.address_format = CD_LBA_FORMAT; - - if (hCDROM != -1) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(struct ioc_toc_header)); - - if (ioctl(hCDROM, CDIOREADTOCHEADER, &ctTOC) == -1) { - return 0; - } - - ctTOCent.track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - if (ctTOCent.entry.addr.lba == 0) add150 = 150; - TOC[0] = ((ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - ctTOCent.entry.addr.lba + add150); - - // convert TOC to saturn format - for (i = ctTOC.starting_track + 1; i <= ctTOC.ending_track; i++) - { - ctTOCent.track = i; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[i - 1] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOCent.entry.addr.lba + add150); - } - - // Do First, Last, and Lead out sections here - - ctTOCent.track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[99] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.track = ctTOC.ending_track; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[100] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.track = 0xAA; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[101] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOCent.entry.addr.lba + add150); - - return (0xCC * 2); - } - - return 0; -} - -static int FreeBSDCDGetStatus(void) { - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - return 0; -} - -static int FreeBSDCDReadSectorFAD(u32 FAD, void *buffer) { - if (hCDROM != -1) - { - lseek(hCDROM, (FAD - 150) * 2352, SEEK_SET); - read(hCDROM, buffer, 2352); - - return 1; - } - - return 0; -} - -static void FreeBSDCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-linux.c b/yabause/src/cd-linux.c deleted file mode 100644 index e488c64ce8..0000000000 --- a/yabause/src/cd-linux.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2004-2006 Guillaume Duhamel - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#ifdef LINUX_CDROM_H_IS_BROKEN -#include -#endif - -#include "cdbase.h" -#include "debug.h" - -static int LinuxCDInit(const char *); -static void LinuxCDDeInit(void); -static s32 LinuxCDReadTOC(u32 *); -static int LinuxCDGetStatus(void); -static int LinuxCDReadSectorFAD(u32, void *); -static void LinuxCDReadAheadFAD(u32); - -CDInterface ArchCD = { - CDCORE_ARCH, - "Linux CD Drive", - LinuxCDInit, - LinuxCDDeInit, - LinuxCDGetStatus, - LinuxCDReadTOC, - LinuxCDReadSectorFAD, - LinuxCDReadAheadFAD, -}; - -static int hCDROM; - -static int LinuxCDInit(const char * cdrom_name) { - if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) { - return -1; - } - LOG("CDInit (%s) OK\n", cdrom_name); - return 0; -} - -static void LinuxCDDeInit(void) { - if (hCDROM != -1) { - close(hCDROM); - } - - LOG("CDDeInit OK\n"); -} - - -static s32 LinuxCDReadTOC(u32 * TOC) -{ - struct cdrom_tochdr ctTOC; - struct cdrom_tocentry ctTOCent; - int i; - int add150 = 0; - - ctTOCent.cdte_format = CDROM_LBA; - - if (hCDROM != -1) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(struct cdrom_tochdr)); - - if (ioctl(hCDROM, CDROMREADTOCHDR, &ctTOC) == -1) { - return 0; - } - - ctTOCent.cdte_track = ctTOC.cdth_trk0; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - if (ctTOCent.cdte_addr.lba == 0) add150 = 150; - TOC[0] = ((ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOCent.cdte_addr.lba + add150)); - - // convert TOC to saturn format - for (i = ctTOC.cdth_trk0 + 1; i <= ctTOC.cdth_trk1; i++) - { - ctTOCent.cdte_track = i; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[i - 1] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOCent.cdte_addr.lba + add150); - } - - // Do First, Last, and Lead out sections here - - ctTOCent.cdte_track = ctTOC.cdth_trk0; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[99] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOC.cdth_trk0 << 16); - - ctTOCent.cdte_track = ctTOC.cdth_trk1; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[100] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOC.cdth_trk1 << 16); - - ctTOCent.cdte_track = CDROM_LEADOUT; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[101] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOCent.cdte_addr.lba + add150); - - return (0xCC * 2); - } - - return 0; -} - -static int LinuxCDGetStatus(void) { - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - int ret = ioctl(hCDROM, CDROM_DRIVE_STATUS, CDSL_CURRENT); - switch(ret) { - case CDS_DISC_OK: - return 0; - case CDS_NO_DISC: - return 2; - case CDS_TRAY_OPEN: - return 3; - } - - // guess it's ok to say there's no disc here... - return 2; -} - -static int LinuxCDReadSectorFAD(u32 FAD, void *buffer) { - union { - struct cdrom_msf msf; - char bigbuf[2352]; - } position; - - if (hCDROM != -1) - { - position.msf.cdmsf_min0 = FAD / 4500; - position.msf.cdmsf_sec0 = (FAD % 4500) / 75; - position.msf.cdmsf_frame0 = FAD % 75; - - if (ioctl(hCDROM, CDROMREADRAW, &position) == -1) { - return 0; - } - - memcpy(buffer, position.bigbuf, 2352); - - return 1; - } - - return 0; -} - -static void LinuxCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-macosx.c b/yabause/src/cd-macosx.c deleted file mode 100644 index 67916553b4..0000000000 --- a/yabause/src/cd-macosx.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright 2004-2005 Lucas Newman - Copyright 2004-2005 Theo Berkau - Copyright 2005 Weston Yager - Copyright 2006-2008 Guillaume Duhamel - Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cdbase.h" - -static int MacOSXCDInit(const char *); -static void MacOSXCDDeInit(void); -static int MacOSXCDGetStatus(void); -static s32 MacOSXCDReadTOC(u32 *); -static int MacOSXCDReadSectorFAD(u32, void *); -static void MacOSXCDReadAheadFAD(u32); - -CDInterface ArchCD = { -CDCORE_ARCH, -"MacOSX CD Drive", -MacOSXCDInit, -MacOSXCDDeInit, -MacOSXCDGetStatus, -MacOSXCDReadTOC, -MacOSXCDReadSectorFAD, -MacOSXCDReadAheadFAD, -}; - -static int hCDROM; - -static int MacOSXCDInit(const char * useless_for_now) -{ - CFMutableDictionaryRef classesToMatch; - io_iterator_t mediaIterator; - io_object_t media; - char cdrom_name[ MAXPATHLEN ]; - - classesToMatch = IOServiceMatching(kIOCDMediaClass); - CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey), - kCFBooleanTrue); - IOServiceGetMatchingServices(kIOMasterPortDefault, - classesToMatch, &mediaIterator); - - media = IOIteratorNext(mediaIterator); - - if(media) - { - CFTypeRef path; - - path = IORegistryEntryCreateCFProperty(media, - CFSTR(kIOBSDNameKey), - kCFAllocatorDefault, 0); - - if (path) - { - size_t length; - - strcpy(cdrom_name, _PATH_DEV); - strcat(cdrom_name, "r"); - length = strlen(cdrom_name); - - CFStringGetCString(path, cdrom_name + length, - MAXPATHLEN - length, kCFStringEncodingUTF8); - - CFRelease(path); - } - IOObjectRelease(media); - } - - if ((hCDROM = open(cdrom_name, O_RDONLY)) == -1) - { - return -1; - } - - return 0; -} - -static void MacOSXCDDeInit(void) -{ - if (hCDROM != -1) - { - close(hCDROM); - } -} - -static CDTOC * GetTOCFromCDPath(void) -{ - CFMutableDictionaryRef classesToMatch; - io_iterator_t mediaIterator; - io_object_t media; - CDTOC * TOC; - - classesToMatch = IOServiceMatching(kIOCDMediaClass); - CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey), - kCFBooleanTrue); - IOServiceGetMatchingServices(kIOMasterPortDefault, - classesToMatch, &mediaIterator); - - media = IOIteratorNext(mediaIterator); - - if(media) - { - CFDataRef TOCData = IORegistryEntryCreateCFProperty(media, CFSTR(kIOCDMediaTOCKey), kCFAllocatorDefault, 0); - TOC = malloc(CFDataGetLength(TOCData)); - CFDataGetBytes(TOCData,CFRangeMake(0,CFDataGetLength(TOCData)),(UInt8 *)TOC); - CFRelease(TOCData); - IOObjectRelease(media); - } - - return TOC; -} - -static s32 MacOSXCDReadTOC(u32 *TOC) -{ - int add150 = 150, tracks = 0; - u_char track; - int i, fad = 0; - CDTOC *cdTOC = GetTOCFromCDPath(); - CDTOCDescriptor *pTrackDescriptors; - pTrackDescriptors = cdTOC->descriptors; - - memset(TOC, 0xFF, 0xCC * 2); - - /* Convert TOC to Saturn format */ - for( i = 3; i < CDTOCGetDescriptorCount(cdTOC); i++ ) { - track = pTrackDescriptors[i].point; - fad = CDConvertMSFToLBA(pTrackDescriptors[i].p) + add150; - if ((track > 99) || (track < 1)) - continue; - TOC[i-3] = (pTrackDescriptors[i].control << 28 | pTrackDescriptors[i].adr << 24 | fad); - tracks++; - } - - /* First */ - TOC[99] = pTrackDescriptors[0].control << 28 | pTrackDescriptors[0].adr << 24 | 1 << 16; - /* Last */ - TOC[100] = pTrackDescriptors[1].control << 28 | pTrackDescriptors[1].adr << 24 | tracks << 16; - /* Leadout */ - TOC[101] = pTrackDescriptors[2].control << 28 | pTrackDescriptors[2].adr << 24 | CDConvertMSFToLBA(pTrackDescriptors[2].p) + add150; - - //free(cdTOC); Looks like this is not need, will look into that. - return (0xCC * 2); -} - -static int MacOSXCDGetStatus(void) -{ - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - //Return that disc is present and spinning. 2 and 3 can't happen in the mac port, i don't understand what "not spinning" is supposed to say - return 0; -} - -static int MacOSXCDReadSectorFAD(u32 FAD, void *buffer) -{ - const int blockSize = 2352; -#ifdef CRAB_REWRITE - const int cacheBlocks = 32; - static u8 cache[blockSize * cacheBlocks]; - static u32 cacheFAD = 0xFFFFFF00; -#endif - - if (hCDROM != -1) - { -#ifdef CRAB_REWRITE - /* See if the block we are looking for is in the cache already... */ - if(FAD < cacheFAD || FAD >= cacheFAD + cacheBlocks) { - /* Cache miss, read some blocks from the cd, then we'll hit the - cache below. */ - if(!pread(hCDROM, cache, blockSize * cacheBlocks, - (FAD - 150) * blockSize)) { - return 0; - } - - cacheFAD = FAD; - } - - /* Cache hit, copy the block out. */ - memcpy(buffer, cache + (blockSize * (FAD - cacheFAD)), blockSize); - return 1; -#else - if (pread(hCDROM, buffer, blockSize, (FAD - 150) * blockSize)) - return true; -#endif - } - - return false; -} - -static void MacOSXCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-netbsd.c b/yabause/src/cd-netbsd.c deleted file mode 100644 index 98a871eb9f..0000000000 --- a/yabause/src/cd-netbsd.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2004-2005 Guillaume Duhamel - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "cdbase.h" -#include "debug.h" - -static int NetBSDCDInit(const char *); -static void NetBSDCDDeInit(void); -static s32 NetBSDCDReadTOC(u32 *); -static int NetBSDCDGetStatus(void); -static int NetBSDCDReadSectorFAD(u32, void *); -static void NetBSDCDReadAheadFAD(u32); - -CDInterface ArchCD = { - CDCORE_ARCH, - "NetBSD CD Drive", - NetBSDCDInit, - NetBSDCDDeInit, - NetBSDCDGetStatus, - NetBSDCDReadTOC, - NetBSDCDReadSectorFAD, - NetBSDCDReadAheadFAD, -}; - -static int hCDROM; - -static int NetBSDCDInit(const char * cdrom_name) { - if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) { - LOG("CDInit (%s) failed\n", cdrom_name); - return -1; - } - - LOG("CDInit (%s) OK\n", cdrom_name); - return 0; -} - -static void NetBSDCDDeInit(void) { - if (hCDROM != -1) { - close(hCDROM); - } - - LOG("CDDeInit OK\n"); -} - - -static s32 NetBSDCDReadTOC(u32 * TOC) -{ - int success; - struct ioc_toc_header ctTOC; - struct ioc_read_toc_entry ctTOCent; - struct cd_toc_entry data; - int i, j; - int add150 = 0; - - ctTOCent.address_format = CD_LBA_FORMAT; - ctTOCent.data_len = sizeof (struct cd_toc_entry); - ctTOCent.data = &data; - - if (hCDROM != -1) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(struct ioc_toc_header)); - - if (ioctl(hCDROM, CDIOREADTOCHEADER, &ctTOC) == -1) { - return 0; - } - - ctTOCent.starting_track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - if (ctTOCent.data->addr.lba == 0) add150 = 150; - TOC[0] = ((ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - ctTOCent.data->addr.lba + add150); - - // convert TOC to saturn format - for (i = ctTOC.starting_track + 1; i <= ctTOC.ending_track; i++) - { - ctTOCent.starting_track = i; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[i - 1] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOCent.data->addr.lba + add150); - } - - // Do First, Last, and Lead out sections here - - ctTOCent.starting_track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[99] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.starting_track = ctTOC.ending_track; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[100] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.starting_track = 0xAA; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[101] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOCent.data->addr.lba + add150); - - return (0xCC * 2); - } - - return 0; -} - -static int NetBSDCDGetStatus(void) { - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - return 0; -} - -static int NetBSDCDReadSectorFAD(u32 FAD, void *buffer) { - static const s8 syncHdr[] = { - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - if (hCDROM != -1) - { - memcpy(buffer, syncHdr, sizeof (syncHdr)); - lseek(hCDROM, (FAD - 150) * 2048, SEEK_SET); - read(hCDROM, (char *)buffer + 0x10, 2048); - - return 1; - } - - return 0; -} - -static void NetBSDCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-windows.c b/yabause/src/cd-windows.c deleted file mode 100644 index e80ab7b326..0000000000 --- a/yabause/src/cd-windows.c +++ /dev/null @@ -1,364 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include "windows/cd.h" - -////////////////////////////////////////////////////////////////////////////// - -static HANDLE hCDROM; -static SCSI_PASS_THROUGH_DIRECT sptd; -static int KillCDThread=0; -static HANDLE thread_handle=INVALID_HANDLE_VALUE; -static int drivestatus=0; -static DWORD thread_id; - -CDInterface ArchCD = { -CDCORE_SPTI, -"Windows SPTI Driver", -SPTICDInit, -SPTICDDeInit, -SPTICDGetStatus, -SPTICDReadTOC, -SPTICDReadSectorFAD, -SPTICDReadAheadFAD, -}; - -////////////////////////////////////////////////////////////////////////////// -// SPTI Interface -////////////////////////////////////////////////////////////////////////////// - -DWORD WINAPI __stdcall SPTICDThread(void *b); - -int SPTICDInit(const char *cdrom_name) { - char pipe_name[7]; - - sprintf(pipe_name, "\\\\.\\?:"); - pipe_name[4] = cdrom_name[0]; - - if ((hCDROM = CreateFileA(pipe_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) - { - return -1; - } - - // Setup a separate thread for handling SPTI commands(that way the emulation - // code doesn't have to wait for a response) - KillCDThread=0; - thread_handle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) SPTICDThread,(void *) &KillCDThread,0,&thread_id); - - // Set it to highest priority to avoid breaks -// SetThreadPriority(thread_handle,THREAD_PRIORITY_HIGHEST); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void SPTICDDeInit() { - if (thread_handle != INVALID_HANDLE_VALUE) - { - // Set the flag telling it to stop - KillCDThread=1; - if (WaitForSingleObject(thread_handle,INFINITE) == WAIT_TIMEOUT) - { - // Couldn't close thread cleanly - TerminateThread(thread_handle,0); - } - CloseHandle(thread_handle); - thread_handle = INVALID_HANDLE_VALUE; - } - - CloseHandle(hCDROM); -} - -////////////////////////////////////////////////////////////////////////////// - -DWORD WINAPI __stdcall SPTICDThread(void *b) -{ - while (KillCDThread != 1) - { - DWORD dwBytesReturned; - unsigned char statusbuf[8]; - BOOL success; - - // Check to see if we have any work to do(for now, let's just do a drive - // status check once a second) - - sptd.Length=sizeof(sptd); - sptd.PathId=0; // - sptd.TargetId=0; // Don't need these, they're automatically generated - sptd.Lun=0; // - sptd.CdbLength=12; - sptd.SenseInfoLength=0; // No sense data - sptd.DataIn=SCSI_IOCTL_DATA_IN; - sptd.TimeOutValue=60; // may need to be changed - sptd.DataBuffer=(PVOID)&(statusbuf); - sptd.SenseInfoOffset=0; - sptd.DataTransferLength=8; // may need to change this - - sptd.Cdb[0]=0xBD; // CDB12 code - sptd.Cdb[1]=0; // Reserved - sptd.Cdb[2]=0; // Reserved - sptd.Cdb[3]=0; // Reserved - sptd.Cdb[4]=0; // Reserved - sptd.Cdb[5]=0; // Reserved - sptd.Cdb[6]=0; // Reserved - sptd.Cdb[7]=0; // Reserved - sptd.Cdb[8]=0; // Allocation Length(byte 1) - sptd.Cdb[9]=8; // Allocation Length(byte 2) (may have to change this) - sptd.Cdb[10]=0; // Reserved - sptd.Cdb[11]=0; // Control - sptd.Cdb[12]=0; - sptd.Cdb[13]=0; - sptd.Cdb[14]=0; - sptd.Cdb[15]=0; - - success=DeviceIoControl(hCDROM, IOCTL_SCSI_PASS_THROUGH_DIRECT, - (PVOID)&sptd, (DWORD)sizeof(SCSI_PASS_THROUGH_DIRECT), - NULL, 0, &dwBytesReturned, NULL); - - if (success) - { - // Figure out drive status - - // Is door open? - if (statusbuf[1] & 0x10) - drivestatus = 3; - else - { - // Ok, so the door is closed, now is there a disc there? - success = DeviceIoControl(hCDROM, IOCTL_STORAGE_CHECK_VERIFY, - NULL, 0, NULL, 0, &dwBytesReturned, NULL); - if (!success) - drivestatus = 2; - else - drivestatus = 0; - } - } - else - drivestatus = 2; - - Sleep(1000); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int SPTICDGetStatus() { - // This function is called periodically to see what the status of the - // drive is. - // - // Should return one of the following values: - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // - // If you really don't want to bother too much with this function, just - // return status 0. Though it is kind of nice when the bios's cd player, - // etc. recognizes when you've ejected the tray and popped in another disc. -/* - DWORD dwBytesReturned; - unsigned char statusbuf[8]; - BOOL success; - - sptd.Length=sizeof(sptd); - sptd.PathId=0; // - sptd.TargetId=0; // Don't need these, they're automatically generated - sptd.Lun=0; // - sptd.CdbLength=12; - sptd.SenseInfoLength=0; // No sense data - sptd.DataIn=SCSI_IOCTL_DATA_IN; - sptd.TimeOutValue=60; // may need to be changed - sptd.DataBuffer=(PVOID)&(statusbuf); - sptd.SenseInfoOffset=0; - sptd.DataTransferLength=8; // may need to change this - - sptd.Cdb[0]=0xBD; // CDB12 code - sptd.Cdb[1]=0; // Reserved - sptd.Cdb[2]=0; // Reserved - sptd.Cdb[3]=0; // Reserved - sptd.Cdb[4]=0; // Reserved - sptd.Cdb[5]=0; // Reserved - sptd.Cdb[6]=0; // Reserved - sptd.Cdb[7]=0; // Reserved - sptd.Cdb[8]=0; // Allocation Length(byte 1) - sptd.Cdb[9]=8; // Allocation Length(byte 2) (may have to change this) - sptd.Cdb[10]=0; // Reserved - sptd.Cdb[11]=0; // Control - sptd.Cdb[12]=0; - sptd.Cdb[13]=0; - sptd.Cdb[14]=0; - sptd.Cdb[15]=0; - - success=DeviceIoControl(hCDROM, IOCTL_SCSI_PASS_THROUGH_DIRECT, - (PVOID)&sptd, (DWORD)sizeof(SCSI_PASS_THROUGH_DIRECT), - NULL, 0, &dwBytesReturned, NULL); - - if (success) - { - // Figure out drive status - - // Is door open? - if (statusbuf[1] & 0x10) return 3; - - // Ok, so the door is closed, now is there a disc there? - success = DeviceIoControl(hCDROM, IOCTL_STORAGE_CHECK_VERIFY, - NULL, 0, NULL, 0, &dwBytesReturned, NULL); - if (!success) - return 2; - - return 0; - } - - return 2; -*/ - return drivestatus; -} - -////////////////////////////////////////////////////////////////////////////// - -#define MSF_TO_FAD(m,s,f) ((m * 4500) + (s * 75) + f) - -s32 SPTICDReadTOC(u32 *TOC) { -// FILE *debugfp; - CDROM_TOC ctTOC; - DWORD dwNotUsed; - int i; - - if (hCDROM != INVALID_HANDLE_VALUE) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(CDROM_TOC)); - - if (DeviceIoControl (hCDROM, IOCTL_CDROM_READ_TOC, - NULL, 0, &ctTOC, sizeof(ctTOC), - &dwNotUsed, NULL) == 0) - { - return 0; - } - - // convert TOC to saturn format - for (i = 0; i < ctTOC.LastTrack; i++) - { - TOC[i] = (ctTOC.TrackData[i].Control << 28) | - (ctTOC.TrackData[i].Adr << 24) | - MSF_TO_FAD(ctTOC.TrackData[i].Address[1], ctTOC.TrackData[i].Address[2], ctTOC.TrackData[i].Address[3]); - } - - // Do First, Last, and Lead out sections here - - TOC[99] = (ctTOC.TrackData[0].Control << 28) | - (ctTOC.TrackData[0].Adr << 24) | - (ctTOC.FirstTrack << 16); - - TOC[100] = (ctTOC.TrackData[ctTOC.LastTrack - 1].Control << 28) | - (ctTOC.TrackData[ctTOC.LastTrack - 1].Adr << 24) | - (ctTOC.LastTrack << 16); - - TOC[101] = (ctTOC.TrackData[ctTOC.LastTrack].Control << 28) | - (ctTOC.TrackData[ctTOC.LastTrack].Adr << 24) | - MSF_TO_FAD(ctTOC.TrackData[ctTOC.LastTrack].Address[1], ctTOC.TrackData[ctTOC.LastTrack].Address[2], ctTOC.TrackData[ctTOC.LastTrack].Address[3]); - -// debugfp = fopen("cot2toc.bin", "wb"); -// fwrite((void *)TOC, 1, 0xCC * 2, debugfp); -// fclose(debugfp); - - return (0xCC * 2); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int SPTICDReadSectorFAD(u32 FAD, void *buffer) { - // This function is supposed to read exactly 1 -RAW- 2352-byte sector at - // the specified FAD address to buffer. Should return true if successful, - // false if there was an error. - // - // Special Note: To convert from FAD to LBA/LSN, minus 150. - // - // The whole process needed to be changed since I need more control over - // sector detection, etc. Not to mention it means less work for the porter - // since they only have to implement raw sector reading as opposed to - // implementing mode 1, mode 2 form1/form2, -and- raw sector reading. - - DWORD dwBytesReturned; - BOOL success; - - sptd.Length=sizeof(sptd); - sptd.PathId=0; // - sptd.TargetId=0; // Don't need these, they're automatically generated - sptd.Lun=0; // - sptd.CdbLength=12; - sptd.SenseInfoLength=0; // No sense data - sptd.DataIn=SCSI_IOCTL_DATA_IN; - sptd.TimeOutValue=60; // may need to be changed - sptd.DataBuffer=(PVOID)buffer; - sptd.SenseInfoOffset=0; - sptd.DataTransferLength=2352; - - sptd.Cdb[0]=0xBE; // CDB12 code - sptd.Cdb[1]=0; // Sector Type, RELADR - FAD -= 150; - sptd.Cdb[2]=(unsigned char)((FAD & 0xFF000000) >> 24); // lba(byte 1) - sptd.Cdb[3]=(unsigned char)((FAD & 0x00FF0000) >> 16); // lba(byte 2) - sptd.Cdb[4]=(unsigned char)((FAD & 0x0000FF00) >> 8); // lba(byte 3) - sptd.Cdb[5]=(unsigned char)(FAD & 0x000000FF); // lba(byte 4) - sptd.Cdb[6]=0; // number of sectors(byte 1) - sptd.Cdb[7]=0; // number of sectors(byte 2) - sptd.Cdb[8]=1; // number of sectors(byte 3) - sptd.Cdb[9]=0xF8; // Sync + All Headers + User data + EDC/ECC - sptd.Cdb[10]=0; - sptd.Cdb[11]=0; - sptd.Cdb[12]=0; - sptd.Cdb[13]=0; - sptd.Cdb[14]=0; - sptd.Cdb[15]=0; - - success=DeviceIoControl(hCDROM, - IOCTL_SCSI_PASS_THROUGH_DIRECT, - (PVOID)&sptd, (DWORD)sizeof(SCSI_PASS_THROUGH_DIRECT), - NULL, 0, - &dwBytesReturned, - NULL); - - if (!success) - { - return 0; - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void SPTICDReadAheadFAD(u32 FAD) { - // No-op -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/cdbase.c b/yabause/src/cdbase.c deleted file mode 100644 index 3e3d0dc8ac..0000000000 --- a/yabause/src/cdbase.c +++ /dev/null @@ -1,512 +0,0 @@ -/* Copyright 2004-2008 Theo Berkau - Copyright 2005 Joost Peters - Copyright 2005-2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "cdbase.h" -#include "error.h" -#include "debug.h" - -////////////////////////////////////////////////////////////////////////////// - -// Contains the Dummy and ISO CD Interfaces - -static int DummyCDInit(const char *); -static void DummyCDDeInit(void); -static int DummyCDGetStatus(void); -static s32 DummyCDReadTOC(u32 *); -static int DummyCDReadSectorFAD(u32, void *); -static void DummyCDReadAheadFAD(u32); - -CDInterface DummyCD = { -CDCORE_DUMMY, -"Dummy CD Drive", -DummyCDInit, -DummyCDDeInit, -DummyCDGetStatus, -DummyCDReadTOC, -DummyCDReadSectorFAD, -DummyCDReadAheadFAD, -}; - -static int ISOCDInit(const char *); -static void ISOCDDeInit(void); -static int ISOCDGetStatus(void); -static s32 ISOCDReadTOC(u32 *); -static int ISOCDReadSectorFAD(u32, void *); -static void ISOCDReadAheadFAD(u32); - -CDInterface ISOCD = { -CDCORE_ISO, -"ISO-File Virtual Drive", -ISOCDInit, -ISOCDDeInit, -ISOCDGetStatus, -ISOCDReadTOC, -ISOCDReadSectorFAD, -ISOCDReadAheadFAD, -}; - -////////////////////////////////////////////////////////////////////////////// -// Dummy Interface -////////////////////////////////////////////////////////////////////////////// - -static int DummyCDInit(UNUSED const char *cdrom_name) -{ - // Initialization function. cdrom_name can be whatever you want it to - // be. Obviously with some ports(e.g. the dreamcast port) you probably - // won't even use it. - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void DummyCDDeInit(void) -{ - // Cleanup function. Enough said. -} - -////////////////////////////////////////////////////////////////////////////// - -static int DummyCDGetStatus(void) -{ - // This function is called periodically to see what the status of the - // drive is. - // - // Should return one of the following values: - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // - // If you really don't want to bother too much with this function, just - // return status 0. Though it is kind of nice when the bios's cd - // player, etc. recognizes when you've ejected the tray and popped in - // another disc. - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static s32 DummyCDReadTOC(UNUSED u32 *TOC) -{ - // The format of TOC is as follows: - // TOC[0] - TOC[98] are meant for tracks 1-99. Each entry has the - // following format: - // bits 0 - 23: track FAD address - // bits 24 - 27: track addr - // bits 28 - 31: track ctrl - // - // Any Unused tracks should be set to 0xFFFFFFFF - // - // TOC[99] - Point A0 information - // Uses the following format: - // bits 0 - 7: PFRAME(should always be 0) - // bits 7 - 15: PSEC(Program area format: 0x00 - CDDA or CDROM, - // 0x10 - CDI, 0x20 - CDROM-XA) - // bits 16 - 23: PMIN(first track's number) - // bits 24 - 27: first track's addr - // bits 28 - 31: first track's ctrl - // - // TOC[100] - Point A1 information - // Uses the following format: - // bits 0 - 7: PFRAME(should always be 0) - // bits 7 - 15: PSEC(should always be 0) - // bits 16 - 23: PMIN(last track's number) - // bits 24 - 27: last track's addr - // bits 28 - 31: last track's ctrl - // - // TOC[101] - Point A2 information - // Uses the following format: - // bits 0 - 23: leadout FAD address - // bits 24 - 27: leadout's addr - // bits 28 - 31: leadout's ctrl - // - // Special Note: To convert from LBA/LSN to FAD, add 150. - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int DummyCDReadSectorFAD(UNUSED u32 FAD, void * buffer) -{ - // This function is supposed to read exactly 1 -RAW- 2352-byte sector - // at the specified FAD address to buffer. Should return true if - // successful, false if there was an error. - // - // Special Note: To convert from FAD to LBA/LSN, minus 150. - // - // The whole process needed to be changed since I need more control - // over sector detection, etc. Not to mention it means less work for - // the porter since they only have to implement raw sector reading as - // opposed to implementing mode 1, mode 2 form1/form2, -and- raw - // sector reading. - - memset(buffer, 0, 2352); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void DummyCDReadAheadFAD(UNUSED u32 FAD) -{ - // This function is called to tell the driver which sector (FAD - // address) is expected to be read next. If the driver supports - // read-ahead, it should start reading the given sector in the - // background while the emulation continues, so that when the - // sector is actually read with ReadSectorFAD() it'll be available - // immediately. (Note that there's no guarantee this sector will - // actually be requested--the emulated CD might be stopped before - // the sector is read, for example.) - // - // This function should NOT block. If the driver can't perform - // asynchronous reads (or you just don't want to bother handling - // them), make this function a no-op and just read sectors - // normally. -} - -////////////////////////////////////////////////////////////////////////////// -// ISO Interface -////////////////////////////////////////////////////////////////////////////// - -static const s8 syncHdr[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }; -static FILE *isofile=NULL; -static int isofilesize=0; -static int bytesPerSector = 0; -static int isbincue = 0; -static u32 isoTOC[102]; -static struct -{ - u32 fadstart; - u32 fileoffset; -} isooffsettbl[100]; - -#define MSF_TO_FAD(m,s,f) ((m * 4500) + (s * 75) + f) - -////////////////////////////////////////////////////////////////////////////// - -static int InitBinCue(const char *cuefilename) -{ - u32 size; - char *tempbuffer, *tempbuffer2; - unsigned int tracknum; - unsigned int indexnum, min, sec, frame; - unsigned int pregap=0; - char *p, *p2; - - fseek(isofile, 0, SEEK_END); - size = ftell(isofile); - fseek(isofile, 0, SEEK_SET); - - // Allocate buffer with enough space for reading cue - if ((tempbuffer = (char *)calloc(size, 1)) == NULL) - return -1; - - // Skip image filename - if (fscanf(isofile, "FILE \"%*[^\"]\" %*s\r\n") == EOF) - { - free(tempbuffer); - return -1; - } - - // Time to generate TOC - for (;;) - { - // Retrieve a line in cue - if (fscanf(isofile, "%s", tempbuffer) == EOF) - break; - - // Figure out what it is - if (strncmp(tempbuffer, "TRACK", 5) == 0) - { - // Handle accordingly - if (fscanf(isofile, "%d %[^\r\n]\r\n", &tracknum, tempbuffer) == EOF) - break; - - if (strncmp(tempbuffer, "MODE1", 5) == 0 || - strncmp(tempbuffer, "MODE2", 5) == 0) - { - // Figure out the track sector size - bytesPerSector = atoi(tempbuffer + 6); - - // Update toc entry - isoTOC[tracknum-1] = 0x41000000; - } - else if (strncmp(tempbuffer, "AUDIO", 5) == 0) - { - // fix me - // Update toc entry - isoTOC[tracknum-1] = 0x01000000; - } - } - else if (strncmp(tempbuffer, "INDEX", 5) == 0) - { - // Handle accordingly - - if (fscanf(isofile, "%d %d:%d:%d\r\n", &indexnum, &min, &sec, &frame) == EOF) - break; - - if (indexnum == 1) - { - // Update toc entry - isoTOC[tracknum-1] = (isoTOC[tracknum-1] & 0xFF000000) | (MSF_TO_FAD(min, sec, frame) + pregap + 150); - - isooffsettbl[tracknum-1].fadstart = MSF_TO_FAD(min, sec, frame) + pregap + 150; - isooffsettbl[tracknum-1].fileoffset = pregap + 150; - } - } - else if (strncmp(tempbuffer, "PREGAP", 5) == 0) - { - if (fscanf(isofile, "%d:%d:%d\r\n", &min, &sec, &frame) == EOF) - break; - - pregap += MSF_TO_FAD(min, sec, frame); - } - else if (strncmp(tempbuffer, "POSTGAP", 5) == 0) - { - if (fscanf(isofile, "%d:%d:%d\r\n", &min, &sec, &frame) == EOF) - break; - } - } - - // Go back, retrieve image filename - fseek(isofile, 0, SEEK_SET); - fscanf(isofile, "FILE \"%[^\"]\" %*s\r\n", tempbuffer); - fclose(isofile); - - // Now go and open up the image file, figure out its size, etc. - if ((isofile = fopen(tempbuffer, "rb")) == NULL) - { - // Ok, exact path didn't work. Let's trim the path and try opening the - // file from the same directory as the cue. - - // find the start of filename - p = tempbuffer; - - for (;;) - { - if (strcspn(p, "/\\") == strlen(p)) - break; - - p += strcspn(p, "/\\") + 1; - } - - // append directory of cue file with bin filename - if ((tempbuffer2 = (char *)calloc(strlen(cuefilename) + strlen(p) + 1, 1)) == NULL) - { - free(tempbuffer); - return -1; - } - - // find end of path - p2 = (char *)cuefilename; - - for (;;) - { - if (strcspn(p2, "/\\") == strlen(p2)) - break; - p2 += strcspn(p2, "/\\") + 1; - } - - // Make sure there was at least some kind of path, otherwise our - // second check is pretty useless - if (cuefilename == p2 && tempbuffer == p) - { - free(tempbuffer); - free(tempbuffer2); - return -1; - } - - strncpy(tempbuffer2, cuefilename, p2 - cuefilename); - strcat(tempbuffer2, p); - - // Let's give it another try - isofile = fopen(tempbuffer2, "rb"); - free(tempbuffer2); - - if (isofile == NULL) - { - YabSetError(YAB_ERR_FILENOTFOUND, tempbuffer); - free(tempbuffer); - return -1; - } - } - - // buffer is no longer needed - free(tempbuffer); - - fseek(isofile, 0, SEEK_END); - isofilesize = ftell(isofile); - fseek(isofile, 0, SEEK_SET); - - // Now then, generate rest of TOC - isoTOC[99] = (isoTOC[0] & 0xFF000000) | 0x010000; - isoTOC[100] = (isoTOC[tracknum - 1] & 0xFF000000) | (tracknum << 16); - isoTOC[101] = (isoTOC[tracknum - 1] & 0xFF000000) | ((isofilesize / bytesPerSector) + pregap + 150); - - isooffsettbl[tracknum].fileoffset = 0; - isooffsettbl[tracknum].fadstart = 0xFFFFFFFF; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int ISOCDInit(const char * iso) { - char header[6]; - - memset(isoTOC, 0xFF, 0xCC * 2); - - if (!iso) - return -1; - - if (!(isofile = fopen(iso, "rb"))) - { - YabSetError(YAB_ERR_FILENOTFOUND, (char *)iso); - return -1; - } - - fread((void *)header, 1, 6, isofile); - - // Figure out what kind of image format we're dealing with - if (strncmp(header, "FILE \"", 6) == 0) - { - // It's a BIN/CUE - isbincue = 1; - - // Generate TOC for bin file - if (InitBinCue(iso) != 0) - { - if (isofile) - free(isofile); - return -1; - } - } - else - { - // Assume it's an ISO file - isbincue = 0; - - fseek(isofile, 0, SEEK_END); - isofilesize = ftell(isofile); - - if (0 == (isofilesize % 2048)) - bytesPerSector = 2048; - else if (0 == (isofilesize % 2352)) - bytesPerSector = 2352; - else - { - YabSetError(YAB_ERR_OTHER, "Unsupported CD image!\n"); - - return -1; - } - - // Generate TOC - isoTOC[0] = 0x41000096; - isoTOC[99] = 0x41010000; - isoTOC[100] = 0x41010000; - isoTOC[101] = (0x41 << 24) | (isofilesize / bytesPerSector); //this isn't fully correct, but it does the job for now. - - isooffsettbl[0].fileoffset = 150; - isooffsettbl[0].fadstart = 150; - isooffsettbl[1].fileoffset = 0; - isooffsettbl[1].fadstart = 0xFFFFFFFF; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void ISOCDDeInit(void) { - if (isofile) - { - fclose(isofile); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int ISOCDGetStatus(void) { - return isofile != NULL ? 0 : 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static s32 ISOCDReadTOC(u32 * TOC) { - memcpy(TOC, isoTOC, 0xCC * 2); - - return (0xCC * 2); -} - -////////////////////////////////////////////////////////////////////////////// - -static int ISOCDReadSectorFAD(u32 FAD, void *buffer) { - int sector; - int i; - - assert(isofile); - - memset(buffer, 0, 2352); - - for (i = 1; i < 100; i++) - { - if (FAD < isooffsettbl[i].fadstart) - { - sector = FAD - isooffsettbl[i-1].fileoffset; - break; - } - } - if (i == 100) { - CDLOG("Warning: Sector not found in track list"); - return 0; - } - - if ((sector * bytesPerSector) >= isofilesize) { - CDLOG("Warning: Trying to read beyond end of CD image! (sector: %d)\n", sector); - return 0; - } - - fseek(isofile, sector * bytesPerSector, SEEK_SET); - - if (2048 == bytesPerSector) { - memcpy(buffer, syncHdr, 12); - fread((char *)buffer + 0x10, bytesPerSector, 1, isofile); - } else { //2352 - fread(buffer, bytesPerSector, 1, isofile); - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void ISOCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/cdbase.h b/yabause/src/cdbase.h deleted file mode 100644 index 624716b4ba..0000000000 --- a/yabause/src/cdbase.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2005 Joost Peters - Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CDBASE_H -#define CDBASE_H - -#include -#include "core.h" - -#define CDCORE_DEFAULT -1 -#define CDCORE_DUMMY 0 -#define CDCORE_ISO 1 -#define CDCORE_ARCH 2 - -typedef struct -{ - int id; - const char *Name; - int (*Init)(const char *); - void (*DeInit)(void); - int (*GetStatus)(void); - s32 (*ReadTOC)(u32 *TOC); - int (*ReadSectorFAD)(u32 FAD, void *buffer); - void (*ReadAheadFAD)(u32 FAD); -} CDInterface; - -extern CDInterface DummyCD; - -extern CDInterface ISOCD; - -extern CDInterface ArchCD; - -#endif diff --git a/yabause/src/cheat.c b/yabause/src/cheat.c deleted file mode 100644 index b3e001a715..0000000000 --- a/yabause/src/cheat.c +++ /dev/null @@ -1,383 +0,0 @@ -/* Copyright 2007-2008 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "cheat.h" -#include "memory.h" -#include "sh2core.h" - -cheatlist_struct *cheatlist=NULL; -int numcheats=0; -int cheatsize; - -#define DoubleWordSwap(x) x = (((x & 0xFF000000) >> 24) + \ - ((x & 0x00FF0000) >> 8) + \ - ((x & 0x0000FF00) << 8) + \ - ((x & 0x000000FF) << 24)); - -////////////////////////////////////////////////////////////////////////////// - -int CheatInit(void) -{ - cheatsize = 10; - if ((cheatlist = (cheatlist_struct *)calloc(cheatsize, sizeof(cheatlist_struct))) == NULL) - return -1; - cheatlist[0].type = CHEATTYPE_NONE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatDeInit(void) -{ - if (cheatlist) - free(cheatlist); - cheatlist = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatAddCode(int type, u32 addr, u32 val) -{ - cheatlist[numcheats].type = type; - cheatlist[numcheats].addr = addr; - cheatlist[numcheats].val = val; - cheatlist[numcheats].desc = NULL; - cheatlist[numcheats].enable = 1; - numcheats++; - - // Make sure we still have room - if (numcheats >= cheatsize) - { - cheatlist = realloc(cheatlist, sizeof(cheatlist_struct) * (cheatsize * 2)); - cheatsize *= 2; - } - - cheatlist[numcheats].type = CHEATTYPE_NONE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatAddARCode(const char *code) -{ - unsigned long addr; - unsigned short val; - sscanf(code, "%08lX %04hX", &addr, &val); - switch (addr >> 28) - { - case 0x0: - // One time word write(fix me) - return -1; - case 0x1: - return CheatAddCode(CHEATTYPE_WORDWRITE, addr & 0x0FFFFFFF, val); - case 0x3: - return CheatAddCode(CHEATTYPE_BYTEWRITE, addr & 0x0FFFFFFF, val); - case 0xD: - return CheatAddCode(CHEATTYPE_ENABLE, addr & 0x0FFFFFFF, val); - default: return -1; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int FindCheat(int type, u32 addr, u32 val) -{ - int i; - - for (i = 0; i < numcheats; i++) - { - if (cheatlist[i].type == type && - cheatlist[i].addr == addr && - cheatlist[i].val == val) - return i; - } - - return -1; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatChangeDescription(int type, u32 addr, u32 val, char *desc) -{ - int i; - - if ((i = FindCheat(type, addr, val)) == -1) - // There is no matches, so let's bail - return -1; - - return CheatChangeDescriptionByIndex(i, desc); -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatChangeDescriptionByIndex(int i, char *desc) -{ - // Free old description(if existing) - if (cheatlist[i].desc) - free(cheatlist[i].desc); - - cheatlist[i].desc = strdup(desc); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatRemoveCode(int type, u32 addr, u32 val) -{ - int i; - - if ((i = FindCheat(type, addr, val)) == -1) - // There is no matches, so let's bail - return -1; - - return CheatRemoveCodeByIndex(i); -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatRemoveCodeByIndex(int i) -{ - // If there's a description, free the memory. - if (cheatlist[i].desc) - { - free(cheatlist[i].desc); - cheatlist[i].desc = NULL; - } - - // Move all entries one forward - for (; i < numcheats-1; i++) - memcpy(&cheatlist[i], &cheatlist[i+1], sizeof(cheatlist_struct)); - - numcheats--; - - // Set the last one to type none - cheatlist[numcheats].type = CHEATTYPE_NONE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatRemoveARCode(const char *code) -{ - unsigned long addr; - unsigned short val; - sscanf(code, "%08lX %04hX", &addr, &val); - - switch (addr >> 28) - { - case 0x1: - return CheatRemoveCode(CHEATTYPE_WORDWRITE, addr & 0x0FFFFFFF, val); - case 0x3: - return CheatRemoveCode(CHEATTYPE_BYTEWRITE, addr & 0x0FFFFFFF, val); - case 0xD: - return CheatRemoveCode(CHEATTYPE_ENABLE, addr & 0x0FFFFFFF, val); - default: return -1; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatClearCodes(void) -{ - while (numcheats > 0) - CheatRemoveCodeByIndex(numcheats-1); -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatEnableCode(int index) -{ - cheatlist[index].enable = 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatDisableCode(int index) -{ - cheatlist[index].enable = 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatDoPatches(void) -{ - int i; - - for (i = 0; ; i++) - { - switch (cheatlist[i].type) - { - case CHEATTYPE_NONE: - return; - case CHEATTYPE_ENABLE: - if (cheatlist[i].enable == 0) - continue; - if (MappedMemoryReadWord(cheatlist[i].addr) != cheatlist[i].val) - return; - break; - case CHEATTYPE_BYTEWRITE: - if (cheatlist[i].enable == 0) - continue; - MappedMemoryWriteByte(cheatlist[i].addr, (u8)cheatlist[i].val); - SH2WriteNotify(cheatlist[i].addr, 1); - break; - case CHEATTYPE_WORDWRITE: - if (cheatlist[i].enable == 0) - continue; - MappedMemoryWriteWord(cheatlist[i].addr, (u16)cheatlist[i].val); - SH2WriteNotify(cheatlist[i].addr, 2); - break; - case CHEATTYPE_LONGWRITE: - if (cheatlist[i].enable == 0) - continue; - MappedMemoryWriteLong(cheatlist[i].addr, cheatlist[i].val); - SH2WriteNotify(cheatlist[i].addr, 4); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -cheatlist_struct *CheatGetList(int *cheatnum) -{ - if (cheatnum == NULL) - return NULL; - - *cheatnum = numcheats; - return cheatlist; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatSave(const char *filename) -{ - FILE *fp; - int i; - int num; - IOCheck_struct check; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "wb")) == NULL) - return -1; - - fprintf(fp, "YCHT"); - num = numcheats; -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(num); -#endif - ywrite(&check, (void *)&num, sizeof(int), 1, fp); - - for(i = 0; i < numcheats; i++) - { - u8 descsize; - cheatlist_struct cheat; - - memcpy(&cheat, &cheatlist[i], sizeof(cheatlist_struct)); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(cheat.type); - DoubleWordSwap(cheat.addr); - DoubleWordSwap(cheat.val); - DoubleWordSwap(cheat.enable); -#endif - ywrite(&check, (void *)&cheat.type, sizeof(int), 1, fp); - ywrite(&check, (void *)&cheat.addr, sizeof(u32), 1, fp); - ywrite(&check, (void *)&cheat.val, sizeof(u32), 1, fp); - descsize = (u8)strlen(cheatlist[i].desc)+1; - ywrite(&check, (void *)&descsize, sizeof(u8), 1, fp); - ywrite(&check, (void *)cheatlist[i].desc, sizeof(char), descsize, fp); - ywrite(&check, (void *)&cheat.enable, sizeof(int), 1, fp); - } - - fclose (fp); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatLoad(const char *filename) -{ - FILE *fp; - int i; - char id[4]; - char desc[256]; - IOCheck_struct check; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - yread(&check, (void *)id, 1, 4, fp); - if (strncmp(id, "YCHT", 4) != 0) - { - fclose(fp); - return -2; - } - - CheatClearCodes(); - - yread(&check, (void *)&numcheats, sizeof(int), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(numcheats); -#endif - - if (numcheats >= cheatsize) - { - cheatlist = realloc(cheatlist, sizeof(cheatlist_struct) * (cheatsize * 2)); - memset((void *)cheatlist, 0, sizeof(cheatlist_struct) * (cheatsize * 2)); - cheatsize *= 2; - } - - for(i = 0; i < numcheats; i++) - { - u8 descsize; - - yread(&check, (void *)&cheatlist[i].type, sizeof(int), 1, fp); - yread(&check, (void *)&cheatlist[i].addr, sizeof(u32), 1, fp); - yread(&check, (void *)&cheatlist[i].val, sizeof(u32), 1, fp); - yread(&check, (void *)&descsize, sizeof(u8), 1, fp); - yread(&check, (void *)desc, sizeof(char), descsize, fp); - CheatChangeDescriptionByIndex(i, desc); - yread(&check, (void *)&cheatlist[i].enable, sizeof(int), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(cheatlist[i].type); - DoubleWordSwap(cheatlist[i].addr); - DoubleWordSwap(cheatlist[i].val); - DoubleWordSwap(cheatlist[i].enable); -#endif - } - - fclose (fp); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/cheat.h b/yabause/src/cheat.h deleted file mode 100644 index 009b2b4449..0000000000 --- a/yabause/src/cheat.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright 2007 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CHEAT_H -#define CHEAT_H - -#include "core.h" - -enum -{ - CHEATTYPE_NONE=0, - CHEATTYPE_ENABLE, - CHEATTYPE_BYTEWRITE, - CHEATTYPE_WORDWRITE, - CHEATTYPE_LONGWRITE -}; - -typedef struct -{ - int type; - u32 addr; - u32 val; - char *desc; - int enable; -} cheatlist_struct; - -int CheatInit(void); -void CheatDeInit(void); -int CheatAddCode(int type, u32 addr, u32 val); -int CheatAddARCode(const char *code); -int CheatChangeDescription(int type, u32 addr, u32 val, char *desc); -int CheatChangeDescriptionByIndex(int i, char *desc); -int CheatRemoveCode(int type, u32 addr, u32 val); -int CheatRemoveCodeByIndex(int i); -int CheatRemoveARCode(const char *code); -void CheatClearCodes(void); -void CheatEnableCode(int index); -void CheatDisableCode(int index); -void CheatDoPatches(void); -cheatlist_struct *CheatGetList(int *cheatnum); -int CheatSave(const char *filename); -int CheatLoad(const char *filename); - -#endif diff --git a/yabause/src/cocoa/CMake-Info.plist b/yabause/src/cocoa/CMake-Info.plist deleted file mode 100644 index c045bd04b9..0000000000 --- a/yabause/src/cocoa/CMake-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Yabause - CFBundleIconFile - Yabause.icns - CFBundleIdentifier - org.yabause.yabause.cocoa - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Yabause - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleShortVersionString - ${YAB_VERSION} - CFBundleVersion - - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSHumanReadableCopyright - Copyright © Yabause Team - - diff --git a/yabause/src/cocoa/CMakeLists.txt b/yabause/src/cocoa/CMakeLists.txt deleted file mode 100644 index 4bfab44374..0000000000 --- a/yabause/src/cocoa/CMakeLists.txt +++ /dev/null @@ -1,73 +0,0 @@ -project(yabause-cocoa) - -yab_port_start() - -find_library(AUDIO_LIBRARY AudioUnit) - -if (NOT AUDIO_LIBRARY) - return() -endif() - -set(yabause_cocoa_SOURCES - main.m - PerCocoa.m - YabauseButtonFormatter.m - YabauseController.m - YabauseGLView.m - YabausePrefsController.m - vidgcd.c - vidgcd.h -) - -set(yabause_cocoa_XIBS English.lproj/MainMenu) - -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/..") - -add_executable(yabause-cocoa MACOSX_BUNDLE ${yabause_cocoa_SOURCES}) -target_link_libraries(yabause-cocoa yabause ${YABAUSE_LIBRARIES} - ${AUDIO_LIBRARY}) - -yab_port_stop() -set_target_properties(yabause-cocoa PROPERTIES OUTPUT_NAME Yabause) - -set_target_properties(yabause-cocoa PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/CMake-Info.plist) - -find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin") -if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND") - message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with - the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin") -endif() - -add_custom_command( - TARGET yabause-cocoa PRE_BUILD - COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS) - -add_custom_command( - TARGET yabause-cocoa PRE_BUILD - COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources/English.lproj) - -foreach(xib ${yabause_cocoa_XIBS}) - add_custom_command( - TARGET yabause-cocoa POST_BUILD - COMMAND ${IBTOOL} --errors --warnings --notices - --output-format human-readable-text - --compile ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources/${xib}.nib - ${CMAKE_CURRENT_SOURCE_DIR}/${xib}.xib - COMMENT "Compiling ${CMAKE_CURRENT_SOURCE_DIR}/${xib}.xib") - -endforeach() - -add_custom_command( - TARGET yabause-cocoa POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Yabause.icns ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources) - -add_custom_command( - TARGET yabause-cocoa POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/controller.png ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources) - -install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/" DESTINATION "Yabause.app" USE_SOURCE_PERMISSIONS) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../AUTHORS DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../ChangeLog DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../COPYING DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../README DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../README.MAC DESTINATION ".") diff --git a/yabause/src/cocoa/English.lproj/InfoPlist.strings b/yabause/src/cocoa/English.lproj/InfoPlist.strings deleted file mode 100644 index b92732c79e..0000000000 --- a/yabause/src/cocoa/English.lproj/InfoPlist.strings +++ /dev/null @@ -1 +0,0 @@ -/* Localized versions of Info.plist keys */ diff --git a/yabause/src/cocoa/English.lproj/MainMenu.xib b/yabause/src/cocoa/English.lproj/MainMenu.xib deleted file mode 100644 index ac87a6f20e..0000000000 --- a/yabause/src/cocoa/English.lproj/MainMenu.xib +++ /dev/null @@ -1,6148 +0,0 @@ - - - - 1060 - 12C54 - 851 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 851 - - - YES - - - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - NSApplication - - - FirstResponder - - - NSApplication - - - NSFontManager - - - Main Menu - - YES - - - Yabause - - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - Yabause - - YES - - - About Yabause - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Services - - 2147483647 - - - submenuAction: - - Services - - YES - - _NSServicesMenu - - - - - YES - YES - - - 2147483647 - - - - - - Hide Yabause - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Quit Yabause - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 2147483647 - - - submenuAction: - - File - - YES - - - Run CD-ROM - o - 1048576 - 2147483647 - - - - - - Run Image - O - 1048576 - 2147483647 - - - - - - Run BIOS - o - 1572864 - 2147483647 - - - - - - - - - Emulation - - 2147483647 - - - submenuAction: - - Emulation - - YES - - - Pause - p - 1048576 - 2147483647 - - - - - - Reset - r - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Enable Frameskip - - 2147483647 - 1 - - - - - - - - - View - - 2147483647 - - - submenuAction: - - View - - YES - - - Show Framerate - - 2147483647 - - - 7 - - - - Fullscreen - f - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Layers - - 2147483647 - - - submenuAction: - - Layers - - YES - - - VDP1 - - 2147483647 - 1 - - - 1 - - - - NBG0 - - 2147483647 - 1 - - - 2 - - - - NBG1 - - 2147483647 - 1 - - - 3 - - - - NBG2 - - 2147483647 - 1 - - - 4 - - - - NBG3 - - 2147483647 - 1 - - - 5 - - - - RBG0 - - 2147483647 - 1 - - - 6 - - - - - - - - - - Window - - 2147483647 - - - submenuAction: - - Window - - YES - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bring All to Front - - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - YES - - - Yabause Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - 271 - 2 - {{168, 237}, {320, 224}} - 1685585920 - Yabause - NSWindow - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {320, 224} - - - 274 - - YES - - - 274 - {320, 224} - - YabauseGLView - - - {320, 224} - - {{0, 0}, {1440, 878}} - {320, 246} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - YabauseController - - - 7 - 2 - {{162, 79}, {484, 400}} - -193462272 - Preferences - NSPanel - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - - - 256 - - YES - - - 12 - {{13, 10}, {458, 384}} - - - YES - - 1 - - - 256 - - YES - - - 12 - - YES - - - 274 - - YES - - - 268 - {{18, 36}, {296, 22}} - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1040 - - Not Set - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - NO - - - - 268 - {{316, 30}, {96, 32}} - - YES - - 67108864 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - - 268 - {{16, 12}, {163, 18}} - - YES - - -2080374784 - 0 - Enable BIOS Emulation - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {{1, 1}, {424, 68}} - - - - {{6, 254}, {426, 84}} - - {0, 0} - - 67108864 - 0 - BIOS - - LucidaGrande - 11 - 3088 - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 274 - - YES - - - 268 - {{10, 10}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - Auto-detect - - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - Japan (NTSC) - - 2147483647 - - - _popUpItemAction: - 1 - - - - - Asia (NTSC) - - 2147483647 - - - _popUpItemAction: - 2 - - - - - North America (NTSC) - - 2147483647 - - - _popUpItemAction: - 4 - - - - - Central/South America (NTSC) - - 2147483647 - - - _popUpItemAction: - 5 - - - - - Korea (NTSC) - - 2147483647 - - - _popUpItemAction: - 6 - - - - - Asia (PAL) - - 2147483647 - - - _popUpItemAction: - 10 - - - - - Europe/Australia (PAL) - - 2147483647 - - - _popUpItemAction: - 12 - - - - - Central/South America (PAL) - - 2147483647 - - - _popUpItemAction: - 13 - - - - - - 1 - YES - YES - 2 - - NO - - - {{1, 1}, {424, 44}} - - - - {{6, 124}, {426, 60}} - - {0, 0} - - 67108864 - 0 - Region - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 274 - - YES - - - 268 - {{18, 14}, {296, 22}} - - YES - - -1804599231 - 272630784 - - - Not Set - - YES - - - - NO - - - - 268 - {{316, 8}, {96, 32}} - - YES - - 67108864 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {{1, 1}, {424, 46}} - - - - {{6, 188}, {426, 62}} - - {0, 0} - - 67108864 - 0 - MPEG ROM - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {{10, 33}, {438, 338}} - - - General - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - - - 2 - - - 256 - - YES - - - 12 - - YES - - - 256 - - YES - - - 268 - {{15, 10}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - Software Video Core - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - 2 - - - YES - - OtherViews - - YES - - - OpenGL Hardware Video Core - - 1048576 - 2147483647 - - - _popUpItemAction: - 1 - - - - - - Grand Central Dispatch Software Core - - 2147483647 - - - _popUpItemAction: - 10 - - - - - Disable Video - - 2147483647 - - - _popUpItemAction: - - - - - - 1 - 1 - YES - YES - 2 - - NO - - - {{1, 1}, {424, 44}} - - - - {{6, 278}, {426, 60}} - - {0, 0} - - 67108864 - 0 - Video Core - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 256 - - YES - - - 268 - {{15, 10}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - Core Audio Sound Core - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - 3 - - - YES - - OtherViews - - YES - - - - Disable Sound - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - - 1 - YES - YES - 2 - - NO - - - {{1, 1}, {424, 44}} - - - - {{6, 214}, {426, 60}} - - {0, 0} - - 67108864 - 0 - Sound Core - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {{10, 33}, {438, 338}} - - Video/Sound - - - - - Item 2 - - - 256 - - YES - - - 12 - - YES - - - 256 - - YES - - - 268 - {{18, 14}, {296, 22}} - - YES - - -1804599231 - 272630784 - - - Not Set - - YES - - - - NO - - - - 268 - {{316, 8}, {96, 32}} - - YES - - 67108864 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {{1, 1}, {424, 46}} - - - - {{6, 276}, {426, 62}} - - {0, 0} - - 67108864 - 0 - Internal Memory (BRAM) - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 256 - - YES - - - 268 - {{15, 52}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - None - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - Pro Action Replay - - 1048576 - 2147483647 - - - _popUpItemAction: - 1 - - - - - Backup RAM (4 Mbit) - - 1048576 - 2147483647 - - - _popUpItemAction: - 2 - - - - - Backup RAM (8 Mbit) - - 2147483647 - - - _popUpItemAction: - 3 - - - - - Backup RAM (16 Mbit) - - 2147483647 - - - _popUpItemAction: - 4 - - - - - Backup RAM (32 Mbit) - - 2147483647 - - - _popUpItemAction: - 5 - - - - - DRAM (8 Mbit) - - 2147483647 - - - _popUpItemAction: - 6 - - - - - DRAM (32 Mbit) - - 2147483647 - - - _popUpItemAction: - 7 - - - - - Netlink - - 2147483647 - - - _popUpItemAction: - 8 - - - - - ROM (16 Mbit) - - 2147483647 - - - _popUpItemAction: - 9 - - - - - - 1 - YES - YES - 2 - - NO - - - - 268 - {{18, 14}, {296, 22}} - - YES - - -1267728319 - 272630784 - - - No file required for the selected cartridge - - YES - - - - NO - - - - 268 - {{316, 8}, {96, 32}} - - YES - - 603979776 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {{1, 1}, {424, 86}} - - - - {{6, 170}, {426, 102}} - - {0, 0} - - 67108864 - 0 - Cartridge - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {{10, 33}, {438, 338}} - - Memory - - - - - Item 3 - - - 256 - - YES - - - 12 - {{10, 7}, {418, 324}} - - - YES - - 1 - - - 256 - - YES - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{14, 14}, {370, 264}} - - YES - - 0 - 33554432 - - NSImage - controller - - 0 - 0 - 3 - NO - - NO - YES - - - - 268 - {{292, 177}, {17, 18}} - - 12 - YES - - -2080374784 - 134217728 - Z - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{263, 164}, {17, 18}} - - 11 - YES - - -2080374784 - 134217728 - Y - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{237, 145}, {17, 18}} - - 10 - YES - - -2080374784 - 134217728 - X - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{278, 130}, {17, 18}} - - 8 - YES - - -2080374784 - 134217728 - B - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{314, 145}, {17, 18}} - - 9 - YES - - -2080374784 - 134217728 - C - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 210}, {67, 18}} - - 4 - YES - - -2080374784 - 134217728 - R Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{102, 162}, {21, 18}} - - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{103, 117}, {21, 18}} - - 2 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{125, 139}, {21, 18}} - - 1 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 139}, {21, 18}} - - 3 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 210}, {65, 18}} - - 5 - YES - - -2080374784 - 134217728 - L Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{180, 111}, {38, 18}} - - 6 - YES - - -2080374784 - 134217728 - Start - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 111}, {17, 18}} - - 7 - YES - - -2080374784 - 134217728 - A - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - {{10, 33}, {398, 278}} - - - Controller 1 - - - - - 2 - - - 256 - - YES - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{14, 14}, {370, 264}} - - YES - - 0 - 33554432 - - 0 - 0 - 3 - NO - - NO - YES - - - - 268 - {{292, 177}, {17, 18}} - - 25 - YES - - -2080374784 - 134217728 - Z - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{263, 164}, {17, 18}} - - 24 - YES - - -2080374784 - 134217728 - Y - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{237, 145}, {17, 18}} - - 23 - YES - - -2080374784 - 134217728 - X - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{278, 130}, {17, 18}} - - 21 - YES - - -2080374784 - 134217728 - B - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{314, 145}, {17, 18}} - - 22 - YES - - -2080374784 - 134217728 - C - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 210}, {67, 18}} - - 17 - YES - - -2080374784 - 134217728 - R Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{102, 162}, {21, 18}} - - 13 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{103, 117}, {21, 18}} - - 15 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{125, 139}, {21, 18}} - - 14 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 139}, {21, 18}} - - 16 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 210}, {65, 18}} - - 18 - YES - - -2080374784 - 134217728 - L Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{180, 111}, {38, 18}} - - 19 - YES - - -2080374784 - 134217728 - Start - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 111}, {17, 18}} - - 20 - YES - - -2080374784 - 134217728 - A - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - {{10, 33}, {398, 278}} - - Controller 2 - - - - - - - 0 - YES - YES - - YES - - - - - {{10, 33}, {438, 338}} - - Input - - - - - - - 0 - YES - YES - - YES - - - - - {484, 400} - - - {{0, 0}, {1440, 878}} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - YabausePrefsController - - - 17 - 2 - {{162, 364}, {220, 115}} - -461897728 - Button Assignment - NSPanel - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - - - 256 - - YES - - - 268 - {{17, 78}, {186, 17}} - - YES - - 68157504 - 138413056 - Current Assignment: - - - - - 6 - System - controlTextColor - - - - NO - - - - 268 - {{110, 12}, {96, 32}} - - YES - - 67108864 - 134217728 - Cancel - - - -2038284288 - 129 - - Gw - 200 - 25 - - NO - - - - 268 - {{14, 12}, {96, 32}} - - YES - - 67108864 - 134217728 - OK - - - -2038284288 - 129 - - DQ - 200 - 25 - - NO - - - - 268 - {{62, 48}, {96, 22}} - - YES - - -1805647807 - 138414080 - - - - YES - - - - NO - - - {220, 115} - - - {{0, 0}, {1440, 878}} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - YabauseButtonFormatter - - - - - YES - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - performZoom: - - - - 240 - - - - showHelp: - - - - 360 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - terminate: - - - - 369 - - - - unhideAllApplications: - - - - 370 - - - - window - - - - 853 - - - - view - - - - 855 - - - - toggleFullscreen: - - - - 858 - - - - toggle: - - - - 875 - - - - toggle: - - - - 876 - - - - toggle: - - - - 877 - - - - toggle: - - - - 878 - - - - toggle: - - - - 879 - - - - toggle: - - - - 880 - - - - toggle: - - - - 881 - - - - toggleFrameskip: - - - - 883 - - - - runCD: - - - - 884 - - - - runBIOS: - - - - 885 - - - - pause: - - - - 893 - - - - reset: - - - - 894 - - - - delegate - - - - 897 - - - - prefsPane - - - - 1048 - - - - showPreferences: - - - - 1049 - - - - region - - - - 1051 - - - - mpegPath - - - - 1052 - - - - biosPath - - - - 1053 - - - - emulateBios - - - - 1054 - - - - videoCore - - - - 1055 - - - - soundCore - - - - 1056 - - - - cartType - - - - 1058 - - - - cartPath - - - - 1059 - - - - cartBrowse - - - - 1060 - - - - regionSelected: - - - - 1061 - - - - videoCoreSelected: - - - - 1062 - - - - soundCoreSelected: - - - - 1063 - - - - cartSelected: - - - - 1064 - - - - prefs - - - - 1065 - - - - bramBrowse: - - - - 1066 - - - - cartBrowse: - - - - 1067 - - - - biosBrowse: - - - - 1068 - - - - mpegBrowse: - - - - 1069 - - - - delegate - - - - 1070 - - - - bramPath - - - - 1072 - - - - frameskip - - - - 1073 - - - - biosToggle: - - - - 1074 - - - - delegate - - - - 1076 - - - - delegate - - - - 1077 - - - - delegate - - - - 1078 - - - - delegate - - - - 1079 - - - - buttonAssignment - - - - 1115 - - - - buttonSelect: - - - - 1120 - - - - prefsPane - - - - 1121 - - - - buttonSetOk: - - - - 1128 - - - - buttonSetCancel: - - - - 1129 - - - - buttonBox - - - - 1134 - - - - formatter - - - - 1136 - - - - delegate - - - - 1137 - - - - buttonSelect: - - - - 1227 - - - - buttonSelect: - - - - 1228 - - - - buttonSelect: - - - - 1229 - - - - buttonSelect: - - - - 1230 - - - - buttonSelect: - - - - 1231 - - - - buttonSelect: - - - - 1232 - - - - buttonSelect: - - - - 1233 - - - - buttonSelect: - - - - 1234 - - - - buttonSelect: - - - - 1235 - - - - buttonSelect: - - - - 1236 - - - - buttonSelect: - - - - 1237 - - - - buttonSelect: - - - - 1238 - - - - buttonSelect: - - - - 1239 - - - - buttonSelect: - - - - 1240 - - - - buttonSelect: - - - - 1241 - - - - buttonSelect: - - - - 1242 - - - - buttonSelect: - - - - 1244 - - - - buttonSelect: - - - - 1245 - - - - buttonSelect: - - - - 1246 - - - - buttonSelect: - - - - 1247 - - - - buttonSelect: - - - - 1248 - - - - buttonSelect: - - - - 1249 - - - - buttonSelect: - - - - 1250 - - - - buttonSelect: - - - - 1251 - - - - buttonSelect: - - - - 1252 - - - - runISO: - - - - 1254 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - YES - - - - - - - - - - - 19 - - - YES - - - - - - 56 - - - YES - - - - - - 103 - - - YES - - - - - - 83 - - - YES - - - - - - 81 - - - YES - - - - - - - - 72 - - - - - 106 - - - YES - - - - - - 111 - - - - - 57 - - - YES - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - YES - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - YES - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 371 - - - - - 843 - - - YES - - - - - - 844 - - - YES - - - - - - 846 - - - - - 847 - - - YES - - - - - - 848 - - - YES - - - - - - - - - 854 - - - - - 882 - - - - - 856 - - - - - 886 - - - YES - - - - - - 887 - - - YES - - - - - - - - - 864 - - - YES - - - - - - 865 - - - YES - - - - - - - - - - - 866 - - - - - 869 - - - - - 870 - - - - - 871 - - - - - 872 - - - - - 873 - - - - - 859 - - - - - 849 - - - - - 889 - - - - - 890 - - - - - 891 - - - - - 892 - - - - - 899 - - - YES - - - - - - 900 - - - YES - - - - - - 901 - - - YES - - - - - - - - - 902 - - - YES - - - - - - 903 - - - YES - - - - - - 904 - - - YES - - - - - - - 905 - - - YES - - - - - - - - 906 - - - YES - - - - - - - - 907 - - - YES - - - - - - 908 - - - - - 909 - - - YES - - - - - - 910 - - - - - 911 - - - YES - - - - - - 912 - - - YES - - - - - - 913 - - - YES - - - - - - 914 - - - YES - - - - - - - - - - - - - - 917 - - - - - 916 - - - - - 915 - - - - - 918 - - - - - 919 - - - - - 920 - - - - - 921 - - - - - 922 - - - - - 923 - - - - - 924 - - - YES - - - - - - 925 - - - - - 926 - - - YES - - - - - - 927 - - - YES - - - - - - 928 - - - YES - - - - - - 929 - - - YES - - - - - - - - - 930 - - - - - 931 - - - - - 933 - - - YES - - - - - - 934 - - - YES - - - - - - 935 - - - YES - - - - - - 936 - - - YES - - - - - - - 937 - - - - - 938 - - - - - 940 - - - - - 941 - - - YES - - - - - - - 942 - - - YES - - - - - - 945 - - - - - 943 - - - YES - - - - - - 944 - - - - - 946 - - - YES - - - - - - 947 - - - YES - - - - - - - 948 - - - YES - - - - - - - 949 - - - YES - - - - - - 952 - - - - - 950 - - - YES - - - - - - 951 - - - - - 953 - - - YES - - - - - - 954 - - - YES - - - - - - 965 - - - YES - - - - - - - 966 - - - YES - - - - - - 967 - - - YES - - - - - - 968 - - - YES - - - - - - - - - - - - - - - - - - - 969 - - - YES - - - - - - - - - - - - - - - - - - - 972 - - - YES - - - - - - 973 - - - - - 974 - - - YES - - - - - - 975 - - - - - 976 - - - YES - - - - - - 977 - - - - - 978 - - - YES - - - - - - 979 - - - - - 980 - - - YES - - - - - - 981 - - - - - 982 - - - YES - - - - - - 983 - - - - - 984 - - - YES - - - - - - 985 - - - - - 986 - - - YES - - - - - - 987 - - - - - 988 - - - YES - - - - - - 989 - - - - - 990 - - - YES - - - - - - 991 - - - - - 992 - - - YES - - - - - - 993 - - - - - 994 - - - YES - - - - - - 995 - - - - - 996 - - - YES - - - - - - 997 - - - - - 998 - - - YES - - - - - - 999 - - - - - 1000 - - - YES - - - - - - 1027 - - - - - 1028 - - - YES - - - - - - - - 1029 - - - YES - - - - - - 1030 - - - YES - - - - - - 1031 - - - YES - - - - - - - - - - - - - - - 1032 - - - - - 1033 - - - - - 1034 - - - - - 1035 - - - - - 1036 - - - - - 1037 - - - - - 1038 - - - - - 1039 - - - - - 1040 - - - - - 1041 - - - - - 1044 - - - YES - - - - - - 1045 - - - YES - - - - - - 1046 - - - - - 1047 - - - - - 1050 - - - - - 1097 - - - - - 1109 - - - YES - - - - - - 1110 - - - YES - - - - - - - - - 1111 - - - YES - - - - - - 1112 - - - - - 1124 - - - YES - - - - - - 1125 - - - - - 1126 - - - YES - - - - - - 1127 - - - - - 1132 - - - YES - - - - - - 1133 - - - - - 1135 - - - - - 1200 - - - YES - - - - - - 1201 - - - YES - - - - - - 1202 - - - YES - - - - - - 1203 - - - YES - - - - - - 1204 - - - YES - - - - - - 1205 - - - YES - - - - - - 1206 - - - YES - - - - - - 1207 - - - YES - - - - - - 1208 - - - YES - - - - - - 1209 - - - YES - - - - - - 1210 - - - YES - - - - - - 1211 - - - YES - - - - - - 1212 - - - YES - - - - - - 1213 - - - - - 1214 - - - - - 1215 - - - - - 1216 - - - - - 1217 - - - - - 1218 - - - - - 1219 - - - - - 1220 - - - - - 1221 - - - - - 1222 - - - - - 1223 - - - - - 1224 - - - - - 1225 - - - - - 1253 - - - - - - - YES - - YES - -3.IBPluginDependency - 1000.IBPluginDependency - 1027.IBPluginDependency - 1028.IBPluginDependency - 1029.IBPluginDependency - 103.IBPluginDependency - 103.ImportedFromIB2 - 1030.IBPluginDependency - 1031.IBEditorWindowLastContentRect - 1031.IBPluginDependency - 1032.IBPluginDependency - 1033.IBPluginDependency - 1034.IBPluginDependency - 1035.IBPluginDependency - 1036.IBPluginDependency - 1037.IBPluginDependency - 1038.IBPluginDependency - 1039.IBPluginDependency - 1040.IBPluginDependency - 1041.IBPluginDependency - 1044.IBPluginDependency - 1045.IBPluginDependency - 1046.IBPluginDependency - 1047.IBPluginDependency - 106.IBEditorWindowLastContentRect - 106.IBPluginDependency - 106.ImportedFromIB2 - 106.editorWindowContentRectSynchronizationRect - 1097.IBPluginDependency - 1109.IBEditorWindowLastContentRect - 1109.IBPluginDependency - 1109.IBWindowTemplateEditedContentRect - 1109.NSWindowTemplate.visibleAtLaunch - 111.IBPluginDependency - 111.ImportedFromIB2 - 1110.IBPluginDependency - 1111.IBPluginDependency - 1111.IBViewBoundsToFrameTransform - 1112.IBPluginDependency - 1124.IBPluginDependency - 1124.IBViewBoundsToFrameTransform - 1125.IBPluginDependency - 1126.IBPluginDependency - 1126.IBViewBoundsToFrameTransform - 1127.IBPluginDependency - 1132.IBPluginDependency - 1132.IBViewBoundsToFrameTransform - 1133.IBPluginDependency - 1135.IBPluginDependency - 1200.IBPluginDependency - 1200.IBViewBoundsToFrameTransform - 1201.IBPluginDependency - 1201.IBViewBoundsToFrameTransform - 1202.IBPluginDependency - 1202.IBViewBoundsToFrameTransform - 1203.IBPluginDependency - 1203.IBViewBoundsToFrameTransform - 1204.IBPluginDependency - 1204.IBViewBoundsToFrameTransform - 1205.IBPluginDependency - 1205.IBViewBoundsToFrameTransform - 1206.IBPluginDependency - 1206.IBViewBoundsToFrameTransform - 1207.IBPluginDependency - 1207.IBViewBoundsToFrameTransform - 1208.IBPluginDependency - 1208.IBViewBoundsToFrameTransform - 1209.IBPluginDependency - 1209.IBViewBoundsToFrameTransform - 1210.IBPluginDependency - 1210.IBViewBoundsToFrameTransform - 1211.IBPluginDependency - 1211.IBViewBoundsToFrameTransform - 1212.IBPluginDependency - 1212.IBViewBoundsToFrameTransform - 1213.IBPluginDependency - 1214.IBPluginDependency - 1215.IBPluginDependency - 1216.IBPluginDependency - 1217.IBPluginDependency - 1218.IBPluginDependency - 1219.IBPluginDependency - 1220.IBPluginDependency - 1221.IBPluginDependency - 1222.IBPluginDependency - 1223.IBPluginDependency - 1224.IBPluginDependency - 1225.IBPluginDependency - 1253.IBPluginDependency - 129.IBPluginDependency - 129.ImportedFromIB2 - 130.IBPluginDependency - 130.ImportedFromIB2 - 130.editorWindowContentRectSynchronizationRect - 131.IBPluginDependency - 131.ImportedFromIB2 - 134.IBPluginDependency - 134.ImportedFromIB2 - 136.IBPluginDependency - 136.ImportedFromIB2 - 143.IBPluginDependency - 143.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 19.IBPluginDependency - 19.ImportedFromIB2 - 23.IBPluginDependency - 23.ImportedFromIB2 - 236.IBPluginDependency - 236.ImportedFromIB2 - 239.IBPluginDependency - 239.ImportedFromIB2 - 24.IBEditorWindowLastContentRect - 24.IBPluginDependency - 24.ImportedFromIB2 - 24.editorWindowContentRectSynchronizationRect - 29.IBEditorWindowLastContentRect - 29.IBPluginDependency - 29.ImportedFromIB2 - 29.WindowOrigin - 29.editorWindowContentRectSynchronizationRect - 5.IBPluginDependency - 5.ImportedFromIB2 - 56.IBPluginDependency - 56.ImportedFromIB2 - 57.IBEditorWindowLastContentRect - 57.IBPluginDependency - 57.ImportedFromIB2 - 57.editorWindowContentRectSynchronizationRect - 58.IBPluginDependency - 58.ImportedFromIB2 - 72.IBPluginDependency - 72.ImportedFromIB2 - 81.IBEditorWindowLastContentRect - 81.IBPluginDependency - 81.ImportedFromIB2 - 81.editorWindowContentRectSynchronizationRect - 83.IBPluginDependency - 83.ImportedFromIB2 - 843.IBEditorWindowLastContentRect - 843.IBPluginDependency - 843.IBWindowTemplateEditedContentRect - 843.NSWindowTemplate.visibleAtLaunch - 843.windowTemplate.hasMinSize - 843.windowTemplate.minSize - 844.IBPluginDependency - 846.IBPluginDependency - 847.IBPluginDependency - 848.IBEditorWindowLastContentRect - 848.IBPluginDependency - 849.IBPluginDependency - 856.IBPluginDependency - 859.IBPluginDependency - 864.IBPluginDependency - 865.IBEditorWindowLastContentRect - 865.IBPluginDependency - 866.IBPluginDependency - 869.IBPluginDependency - 870.IBPluginDependency - 871.IBPluginDependency - 872.IBPluginDependency - 873.IBPluginDependency - 882.IBPluginDependency - 886.IBPluginDependency - 887.IBEditorWindowLastContentRect - 887.IBPluginDependency - 889.IBPluginDependency - 890.IBPluginDependency - 891.IBPluginDependency - 892.IBPluginDependency - 899.IBEditorWindowLastContentRect - 899.IBPluginDependency - 899.IBWindowTemplateEditedContentRect - 899.NSWindowTemplate.visibleAtLaunch - 900.IBPluginDependency - 901.IBAttributePlaceholdersKey - 901.IBPluginDependency - 902.IBPluginDependency - 903.IBPluginDependency - 904.IBPluginDependency - 905.IBPluginDependency - 906.IBPluginDependency - 907.IBPluginDependency - 908.IBPluginDependency - 909.IBPluginDependency - 910.IBPluginDependency - 911.IBPluginDependency - 912.IBPluginDependency - 913.IBPluginDependency - 914.IBEditorWindowLastContentRect - 914.IBPluginDependency - 915.IBPluginDependency - 916.IBPluginDependency - 917.IBPluginDependency - 918.IBPluginDependency - 919.IBPluginDependency - 92.IBPluginDependency - 92.ImportedFromIB2 - 920.IBPluginDependency - 921.IBPluginDependency - 922.IBPluginDependency - 923.IBPluginDependency - 924.IBPluginDependency - 925.IBPluginDependency - 926.IBPluginDependency - 927.IBPluginDependency - 928.IBPluginDependency - 929.IBEditorWindowLastContentRect - 929.IBPluginDependency - 930.IBPluginDependency - 931.IBPluginDependency - 933.IBPluginDependency - 934.IBPluginDependency - 935.IBPluginDependency - 936.IBEditorWindowLastContentRect - 936.IBPluginDependency - 937.IBPluginDependency - 938.IBPluginDependency - 940.IBPluginDependency - 941.IBPluginDependency - 942.IBPluginDependency - 943.IBPluginDependency - 944.IBPluginDependency - 945.IBPluginDependency - 946.IBPluginDependency - 947.IBPluginDependency - 948.IBPluginDependency - 949.IBPluginDependency - 950.IBPluginDependency - 951.IBPluginDependency - 952.IBPluginDependency - 953.IBPluginDependency - 954.IBPluginDependency - 965.IBAttributePlaceholdersKey - 965.IBPluginDependency - 965.IBViewBoundsToFrameTransform - 966.IBPluginDependency - 967.IBPluginDependency - 968.IBPluginDependency - 969.IBPluginDependency - 972.IBPluginDependency - 972.IBViewBoundsToFrameTransform - 973.IBPluginDependency - 974.IBPluginDependency - 974.IBViewBoundsToFrameTransform - 975.IBPluginDependency - 976.IBPluginDependency - 976.IBViewBoundsToFrameTransform - 977.IBPluginDependency - 978.IBPluginDependency - 978.IBViewBoundsToFrameTransform - 979.IBPluginDependency - 980.IBPluginDependency - 980.IBViewBoundsToFrameTransform - 981.IBPluginDependency - 982.IBPluginDependency - 982.IBViewBoundsToFrameTransform - 983.IBPluginDependency - 984.IBPluginDependency - 984.IBViewBoundsToFrameTransform - 985.IBPluginDependency - 986.IBPluginDependency - 986.IBViewBoundsToFrameTransform - 987.IBPluginDependency - 988.IBPluginDependency - 988.IBViewBoundsToFrameTransform - 989.IBPluginDependency - 990.IBPluginDependency - 990.IBViewBoundsToFrameTransform - 991.IBPluginDependency - 992.IBPluginDependency - 992.IBViewBoundsToFrameTransform - 993.IBPluginDependency - 994.IBPluginDependency - 994.IBViewBoundsToFrameTransform - 995.IBPluginDependency - 996.IBPluginDependency - 996.IBViewBoundsToFrameTransform - 997.IBPluginDependency - 998.IBPluginDependency - 998.IBViewBoundsToFrameTransform - 999.IBPluginDependency - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - {{572, 78}, {262, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{768, 368}, {163, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{596, 852}, {216, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - {{477, 639}, {220, 115}} - com.apple.InterfaceBuilder.CocoaPlugin - {{477, 639}, {220, 115}} - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwswAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDAwAAwigAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABB0AAAwigAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCkAAAwogAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkoAAw0EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDhAAAwzQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDbgAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDi4AAwxIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDnYAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeQAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCzgAAwzIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC0AAAwwUAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC/AAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCpAAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCpAAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDNQAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeQAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{436, 809}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{697, 318}, {194, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{525, 802}, {197, 73}} - {{428, 391}, {401, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - {74, 862} - {{11, 977}, {478, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{439, 208}, {192, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{23, 794}, {245, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{519, 328}, {181, 63}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{323, 672}, {199, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{257, 623}, {320, 224}} - com.apple.InterfaceBuilder.CocoaPlugin - {{257, 623}, {320, 224}} - - - {320, 224} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{561, 318}, {193, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{828, 218}, {90, 123}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{647, 318}, {182, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{329, 203}, {484, 400}} - com.apple.InterfaceBuilder.CocoaPlugin - {{329, 203}, {484, 400}} - - com.apple.InterfaceBuilder.CocoaPlugin - - InitialTabViewItem - - InitialTabViewItem - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{756, 355}, {262, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{398, 411}, {324, 83}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{608, 620}, {262, 43}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - InitialTabViewItem - - InitialTabViewItem - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBIAAAw6SAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - AUFgAABBYAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCzAAAwzIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCzgAAwwUAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC+gAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCogAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCogAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeAAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDNAAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeAAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiwAAwxIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDnQAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDbQAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDg4AAwzQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkgAAw0EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 1254 - - - - YES - - YabauseButtonFormatter - NSFormatter - - IBProjectSource - YabauseButtonFormatter.h - - - - YabauseController - NSObject - - YES - - YES - pause: - reset: - runBIOS: - runCD: - runISO: - showPreferences: - toggle: - toggleFrameskip: - toggleFullscreen: - - - YES - id - id - id - id - id - id - id - id - id - - - - YES - - YES - pause: - reset: - runBIOS: - runCD: - runISO: - showPreferences: - toggle: - toggleFrameskip: - toggleFullscreen: - - - YES - - pause: - id - - - reset: - id - - - runBIOS: - id - - - runCD: - id - - - runISO: - id - - - showPreferences: - id - - - toggle: - id - - - toggleFrameskip: - id - - - toggleFullscreen: - id - - - - - YES - - YES - frameskip - logView - logWindow - prefs - prefsPane - view - - - YES - NSMenuItem - NSTextView - NSWindow - YabausePrefsController - NSPanel - YabauseGLView - - - - YES - - YES - frameskip - logView - logWindow - prefs - prefsPane - view - - - YES - - frameskip - NSMenuItem - - - logView - NSTextView - - - logWindow - NSWindow - - - prefs - YabausePrefsController - - - prefsPane - NSPanel - - - view - YabauseGLView - - - - - IBProjectSource - YabauseController.h - - - - YabauseGLView - NSOpenGLView - - window - NSWindow - - - window - - window - NSWindow - - - - IBProjectSource - YabauseGLView.h - - - - YabauseGLView - NSOpenGLView - - IBUserSource - - - - - YabausePrefsController - NSObject - - YES - - YES - biosBrowse: - biosToggle: - bramBrowse: - buttonSelect: - buttonSetCancel: - buttonSetOk: - cartBrowse: - cartSelected: - mpegBrowse: - regionSelected: - soundCoreSelected: - videoCoreSelected: - - - YES - id - id - id - id - id - id - id - id - id - id - id - id - - - - YES - - YES - biosBrowse: - biosToggle: - bramBrowse: - buttonSelect: - buttonSetCancel: - buttonSetOk: - cartBrowse: - cartSelected: - mpegBrowse: - regionSelected: - soundCoreSelected: - videoCoreSelected: - - - YES - - biosBrowse: - id - - - biosToggle: - id - - - bramBrowse: - id - - - buttonSelect: - id - - - buttonSetCancel: - id - - - buttonSetOk: - id - - - cartBrowse: - id - - - cartSelected: - id - - - mpegBrowse: - id - - - regionSelected: - id - - - soundCoreSelected: - id - - - videoCoreSelected: - id - - - - - YES - - YES - biosPath - bramPath - buttonAssignment - buttonBox - cartBrowse - cartPath - cartType - emulateBios - mpegPath - prefsPane - region - soundCore - videoCore - - - YES - NSTextField - NSTextField - NSPanel - NSTextField - NSButton - NSTextField - NSPopUpButton - NSButton - NSTextField - NSPanel - NSPopUpButton - NSPopUpButton - NSPopUpButton - - - - YES - - YES - biosPath - bramPath - buttonAssignment - buttonBox - cartBrowse - cartPath - cartType - emulateBios - mpegPath - prefsPane - region - soundCore - videoCore - - - YES - - biosPath - NSTextField - - - bramPath - NSTextField - - - buttonAssignment - NSPanel - - - buttonBox - NSTextField - - - cartBrowse - NSButton - - - cartPath - NSTextField - - - cartType - NSPopUpButton - - - emulateBios - NSButton - - - mpegPath - NSTextField - - - prefsPane - NSPanel - - - region - NSPopUpButton - - - soundCore - NSPopUpButton - - - videoCore - NSPopUpButton - - - - - IBProjectSource - YabausePrefsController.h - - - - YabausePrefsController - NSObject - - IBUserSource - - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSWindowRestoration.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSLayoutConstraint.h - - - - NSFontManager - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSImageCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSImageCell.h - - - - NSImageView - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSImageView.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSOpenGLView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSOpenGLView.h - - - - NSPanel - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSPanel.h - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSResponder - - - - NSTabView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSTabView.h - - - - NSTabViewItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTabViewItem.h - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../Yabause.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - NSSwitch - controller - - - YES - {11, 11} - {10, 3} - {15, 15} - {621, 376} - - - - diff --git a/yabause/src/cocoa/PerCocoa.h b/yabause/src/cocoa/PerCocoa.h deleted file mode 100644 index 568f4442b2..0000000000 --- a/yabause/src/cocoa/PerCocoa.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2010, 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PerCocoa_h -#define PerCocoa_h - -#include "peripheral.h" - -#define PERCORE_COCOA 42 -extern PerInterface_struct PERCocoa; - -/* Update a key mapping */ -void PERCocoaSetKey(u32 key, u8 name, int port); -u32 PERCocoaGetKey(u8 n, int p); - -#endif /* !PerCocoa_h */ diff --git a/yabause/src/cocoa/PerCocoa.m b/yabause/src/cocoa/PerCocoa.m deleted file mode 100644 index dd6890a569..0000000000 --- a/yabause/src/cocoa/PerCocoa.m +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright 2010, 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "PerCocoa.h" -#include "yabause.h" - -#include -#include -#include - -/* Forward Declarations. */ -static int PERCocoaInit(void); -static void PERCocoaDeInit(void); -static int PERCocoaHandleEvents(void); -static void PERCocoaNothing(void); - -static u32 PERCocoaScan(void); -static void PERCocoaFlush(void); - -static PerPad_struct *c1 = NULL, *c2 = NULL; - -PerInterface_struct PERCocoa = { - PERCORE_COCOA, - "Cocoa Keyboard Input Interface", - &PERCocoaInit, - &PERCocoaDeInit, - &PERCocoaHandleEvents, - &PERCocoaNothing, - &PERCocoaScan, - 0, - &PERCocoaFlush -}; - -/* Utility function to check if everything's set up right for a port */ -static BOOL AllSetForPort(int p) { - int i; - NSString *str; - NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; - id val; - Class c = [NSNumber class]; - - for(i = 0; i < 13; ++i) { - str = [NSString stringWithFormat:@"Keyboard %d %s", p, PerPadNames[i]]; - val = [d objectForKey:str]; - - if(!val || ![val isKindOfClass:c]) { - return NO; - } - } - - return YES; -} - -void PERCocoaSetKey(u32 key, u8 n, int p) { - PerPad_struct *c; - NSString *str; - NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; - NSNumber *val = [NSNumber numberWithUnsignedInt:(unsigned int)key]; - - assert(n <= PERPAD_Z); - - /* Build the string we'll look for, and set the value for that key */ - str = [NSString stringWithFormat:@"Pad %d %s", p, PerPadNames[n]]; - [d setObject:val forKey:str]; - [d synchronize]; - - /* Update the mapping if we're running */ - if(p == 0) { - c = c1; - } - else { - c = c2; - } - - /* This will effectively make sure we don't update until we've started. */ - if(c) { - PerSetKey(key, n, c); - } -} - -u32 PERCocoaGetKey(u8 n, int p) { - NSString *str; - id result; - NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; - - assert(n <= PERPAD_Z); - - /* Fetch the key data */ - str = [NSString stringWithFormat:@"Pad %d %s", p, PerPadNames[n]]; - result = [d objectForKey:str]; - - if(result && [result isKindOfClass:[NSNumber class]]) { - return (u32)[result unsignedIntValue]; - } - else { - return (u32)-1; - } -} -static int PERCocoaInit(void) { - /* Fill in pad 1 */ - c1 = PerPadAdd(&PORTDATA1); - - PerSetKey(PERCocoaGetKey(PERPAD_UP, 0), PERPAD_UP, c1); - PerSetKey(PERCocoaGetKey(PERPAD_DOWN, 0), PERPAD_DOWN, c1); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT, 0), PERPAD_LEFT, c1); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT, 0), PERPAD_RIGHT, c1); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT_TRIGGER, 0), PERPAD_LEFT_TRIGGER, c1); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT_TRIGGER, 0), PERPAD_RIGHT_TRIGGER, c1); - PerSetKey(PERCocoaGetKey(PERPAD_START, 0), PERPAD_START, c1); - PerSetKey(PERCocoaGetKey(PERPAD_A, 0), PERPAD_A, c1); - PerSetKey(PERCocoaGetKey(PERPAD_B, 0), PERPAD_B, c1); - PerSetKey(PERCocoaGetKey(PERPAD_C, 0), PERPAD_C, c1); - PerSetKey(PERCocoaGetKey(PERPAD_X, 0), PERPAD_X, c1); - PerSetKey(PERCocoaGetKey(PERPAD_Y, 0), PERPAD_Y, c1); - PerSetKey(PERCocoaGetKey(PERPAD_Z, 0), PERPAD_Z, c1); - - /* Fill in pad 2 */ - c2 = PerPadAdd(&PORTDATA2); - - PerSetKey(PERCocoaGetKey(PERPAD_UP, 1), PERPAD_UP, c2); - PerSetKey(PERCocoaGetKey(PERPAD_DOWN, 1), PERPAD_DOWN, c2); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT, 1), PERPAD_LEFT, c2); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT, 1), PERPAD_RIGHT, c2); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT_TRIGGER, 1), PERPAD_LEFT_TRIGGER, c2); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT_TRIGGER, 1), PERPAD_RIGHT_TRIGGER, c2); - PerSetKey(PERCocoaGetKey(PERPAD_START, 1), PERPAD_START, c2); - PerSetKey(PERCocoaGetKey(PERPAD_A, 1), PERPAD_A, c2); - PerSetKey(PERCocoaGetKey(PERPAD_B, 1), PERPAD_B, c2); - PerSetKey(PERCocoaGetKey(PERPAD_C, 1), PERPAD_C, c2); - PerSetKey(PERCocoaGetKey(PERPAD_X, 1), PERPAD_X, c2); - PerSetKey(PERCocoaGetKey(PERPAD_Y, 1), PERPAD_Y, c2); - PerSetKey(PERCocoaGetKey(PERPAD_Z, 1), PERPAD_Z, c2); - - return 0; -} - -static void PERCocoaDeInit(void) { -} - -static int PERCocoaHandleEvents(void) { - return YabauseExec(); -} - -static void PERCocoaNothing(void) { -} - -static u32 PERCocoaScan(void) { - return 0; -} - -static void PERCocoaFlush(void) { -} diff --git a/yabause/src/cocoa/Yabause-Info.plist b/yabause/src/cocoa/Yabause-Info.plist deleted file mode 100644 index d4f860c666..0000000000 --- a/yabause/src/cocoa/Yabause-Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - Yabause.icns - CFBundleIdentifier - org.yabause.yabause.cocoa - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleShortVersionString - 0.9.12 - LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} - CFBundleVersion - - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSHumanReadableCopyright - Copyright © Yabause Team - - diff --git a/yabause/src/cocoa/Yabause.icns b/yabause/src/cocoa/Yabause.icns deleted file mode 100644 index ee74849a60..0000000000 Binary files a/yabause/src/cocoa/Yabause.icns and /dev/null differ diff --git a/yabause/src/cocoa/Yabause.xcodeproj/project.pbxproj b/yabause/src/cocoa/Yabause.xcodeproj/project.pbxproj deleted file mode 100644 index b9bdb37090..0000000000 --- a/yabause/src/cocoa/Yabause.xcodeproj/project.pbxproj +++ /dev/null @@ -1,808 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXBuildFile section */ - 2A1145191385E5010087C872 /* YabauseButtonFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1145181385E5010087C872 /* YabauseButtonFormatter.m */; }; - 2A3392711162E100000DA0E9 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A3392701162E100000DA0E9 /* GLUT.framework */; }; - 2A474DF01163A013006993EA /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A474DEF1163A013006993EA /* AudioUnit.framework */; }; - 2A474DF21163A013006993EA /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A474DF11163A013006993EA /* CoreAudio.framework */; }; - 2A7AB7CC117D1C1B00E47298 /* vidsoft.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7AB7CB117D1C1B00E47298 /* vidsoft.c */; }; - 2A7D39D3115BA16100DE3BD1 /* bios.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3987115BA16100DE3BD1 /* bios.c */; }; - 2A7D39D4115BA16100DE3BD1 /* cd-macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3989115BA16100DE3BD1 /* cd-macosx.c */; }; - 2A7D39D5115BA16100DE3BD1 /* cdbase.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D398A115BA16100DE3BD1 /* cdbase.c */; }; - 2A7D39D6115BA16100DE3BD1 /* cheat.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D398C115BA16100DE3BD1 /* cheat.c */; }; - 2A7D39D7115BA16100DE3BD1 /* coffelf.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D398E115BA16100DE3BD1 /* coffelf.c */; }; - 2A7D39D8115BA16100DE3BD1 /* cs0.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3991115BA16100DE3BD1 /* cs0.c */; }; - 2A7D39D9115BA16100DE3BD1 /* cs1.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3993115BA16100DE3BD1 /* cs1.c */; }; - 2A7D39DA115BA16100DE3BD1 /* cs2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3995115BA16100DE3BD1 /* cs2.c */; }; - 2A7D39DB115BA16100DE3BD1 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3997115BA16100DE3BD1 /* debug.c */; }; - 2A7D39DC115BA16100DE3BD1 /* error.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3999115BA16100DE3BD1 /* error.c */; }; - 2A7D39DD115BA16100DE3BD1 /* m68kc68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D399B115BA16100DE3BD1 /* m68kc68k.c */; }; - 2A7D39DE115BA16100DE3BD1 /* m68kcore.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D399D115BA16100DE3BD1 /* m68kcore.c */; }; - 2A7D39DF115BA16100DE3BD1 /* m68kd.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D399F115BA16100DE3BD1 /* m68kd.c */; }; - 2A7D39E1115BA16100DE3BD1 /* macjoy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A2115BA16100DE3BD1 /* macjoy.c */; }; - 2A7D39E2115BA16100DE3BD1 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A4115BA16100DE3BD1 /* memory.c */; }; - 2A7D39E3115BA16100DE3BD1 /* movie.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A6115BA16100DE3BD1 /* movie.c */; }; - 2A7D39E4115BA16100DE3BD1 /* netlink.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A8115BA16100DE3BD1 /* netlink.c */; }; - 2A7D39E5115BA16100DE3BD1 /* peripheral.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39AA115BA16100DE3BD1 /* peripheral.c */; }; - 2A7D39E6115BA16100DE3BD1 /* permacjoy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39AC115BA16100DE3BD1 /* permacjoy.c */; }; - 2A7D39E7115BA16100DE3BD1 /* profile.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39AE115BA16100DE3BD1 /* profile.c */; }; - 2A7D39E9115BA16100DE3BD1 /* scu.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B2115BA16100DE3BD1 /* scu.c */; }; - 2A7D39EA115BA16100DE3BD1 /* sh2core.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B4115BA16100DE3BD1 /* sh2core.c */; }; - 2A7D39EB115BA16100DE3BD1 /* sh2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B6115BA16100DE3BD1 /* sh2d.c */; }; - 2A7D39EC115BA16100DE3BD1 /* sh2idle.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B8115BA16100DE3BD1 /* sh2idle.c */; }; - 2A7D39ED115BA16100DE3BD1 /* sh2int.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39BA115BA16100DE3BD1 /* sh2int.c */; }; - 2A7D39EE115BA16100DE3BD1 /* sh2trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39BC115BA16100DE3BD1 /* sh2trace.c */; }; - 2A7D39EF115BA16100DE3BD1 /* smpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39BE115BA16100DE3BD1 /* smpc.c */; }; - 2A7D39F1115BA16100DE3BD1 /* vdp1.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C2115BA16100DE3BD1 /* vdp1.c */; }; - 2A7D39F2115BA16100DE3BD1 /* vdp2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C4115BA16100DE3BD1 /* vdp2.c */; }; - 2A7D39F3115BA16100DE3BD1 /* vdp2debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C6115BA16100DE3BD1 /* vdp2debug.c */; }; - 2A7D39F4115BA16100DE3BD1 /* vidogl.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C8115BA16100DE3BD1 /* vidogl.c */; }; - 2A7D39F5115BA16100DE3BD1 /* vidshared.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39CA115BA16100DE3BD1 /* vidshared.c */; }; - 2A7D39F6115BA16100DE3BD1 /* vidgcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39CC115BA16100DE3BD1 /* vidgcd.c */; }; - 2A7D39F7115BA16100DE3BD1 /* yabause.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39CE115BA16100DE3BD1 /* yabause.c */; }; - 2A7D39F8115BA16100DE3BD1 /* ygl.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39D0115BA16100DE3BD1 /* ygl.c */; }; - 2A7D3A1E115BA29F00DE3BD1 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A7D3A1D115BA29F00DE3BD1 /* OpenGL.framework */; }; - 2A7D3A31115BA35200DE3BD1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A7D3A30115BA35200DE3BD1 /* CoreFoundation.framework */; }; - 2A7D3A33115BA35200DE3BD1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A7D3A32115BA35200DE3BD1 /* IOKit.framework */; }; - 2A7D3A48115BA3AF00DE3BD1 /* c68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A41115BA3AF00DE3BD1 /* c68k.c */; }; - 2A7D3A49115BA3AF00DE3BD1 /* c68kexec.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A43115BA3AF00DE3BD1 /* c68kexec.c */; settings = {COMPILER_FLAGS = "-O0"; }; }; - 2A7D3A4B115BA3AF00DE3BD1 /* gen68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */; }; - 2A7D3A5A115BA41200DE3BD1 /* gen68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */; }; - 2A7D3A9B115BAB9E00DE3BD1 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A7D3A99115BAB9E00DE3BD1 /* MainMenu.xib */; }; - 2A7D3AD5115BB01500DE3BD1 /* Yabause.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2A7D3AD4115BB01500DE3BD1 /* Yabause.icns */; }; - 2A82CCA1116171DB00F15B02 /* PerCocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A82CCA0116171DB00F15B02 /* PerCocoa.m */; }; - 2A9D7600116645D700A580EB /* sndmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A9D75FE116645D700A580EB /* sndmac.c */; }; - 2A9D760E11665F2800A580EB /* controller.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A9D760D11665F2800A580EB /* controller.png */; }; - 2A9D7621116667C300A580EB /* YabausePrefsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A9D761F116667C300A580EB /* YabausePrefsController.m */; }; - 2AD10F9E118BBC850088FB2C /* scsp2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F97118BBC850088FB2C /* scsp2.c */; }; - 2AD10F9F118BBC850088FB2C /* snddummy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F99118BBC850088FB2C /* snddummy.c */; }; - 2AD10FA0118BBC850088FB2C /* sndwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F9A118BBC850088FB2C /* sndwav.c */; }; - 2AD10FDB118BCFA00088FB2C /* thr-dummy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F9B118BBC850088FB2C /* thr-dummy.c */; }; - 2AF0CA51116146A400196BED /* YabauseGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0CA4F116146A400196BED /* YabauseGLView.m */; }; - 2AF0CA9911614DD500196BED /* YabauseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0CA9811614DD500196BED /* YabauseController.m */; }; - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - F07BF9E414A1C2C500775818 /* yglshader.c in Sources */ = {isa = PBXBuildFile; fileRef = F07BF9E314A1C2C500775818 /* yglshader.c */; }; - F07E62CB15054DCC00DF8A4E /* titan.c in Sources */ = {isa = PBXBuildFile; fileRef = F07E62CA15054DCC00DF8A4E /* titan.c */; }; - F0E47FAD156C34EC001A1B51 /* osdcore.c in Sources */ = {isa = PBXBuildFile; fileRef = F0E47FAC156C34EC001A1B51 /* osdcore.c */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 2A7D3A7A115BA63900DE3BD1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2A7D3A54115BA3E700DE3BD1; - remoteInfo = gen68k; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 2A1145171385E5010087C872 /* YabauseButtonFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabauseButtonFormatter.h; sourceTree = ""; }; - 2A1145181385E5010087C872 /* YabauseButtonFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabauseButtonFormatter.m; sourceTree = ""; }; - 2A3392701162E100000DA0E9 /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = System/Library/Frameworks/GLUT.framework; sourceTree = SDKROOT; }; - 2A474DEF1163A013006993EA /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; - 2A474DF11163A013006993EA /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - 2A7AB7CB117D1C1B00E47298 /* vidsoft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vidsoft.c; path = ../vidsoft.c; sourceTree = SOURCE_ROOT; }; - 2A7AB7CE117D1CBE00E47298 /* vidsoft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vidsoft.h; path = ../vidsoft.h; sourceTree = SOURCE_ROOT; }; - 2A7D3987115BA16100DE3BD1 /* bios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bios.c; path = ../bios.c; sourceTree = SOURCE_ROOT; }; - 2A7D3988115BA16100DE3BD1 /* bios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bios.h; path = ../bios.h; sourceTree = SOURCE_ROOT; }; - 2A7D3989115BA16100DE3BD1 /* cd-macosx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "cd-macosx.c"; path = "../cd-macosx.c"; sourceTree = SOURCE_ROOT; }; - 2A7D398A115BA16100DE3BD1 /* cdbase.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cdbase.c; path = ../cdbase.c; sourceTree = SOURCE_ROOT; }; - 2A7D398B115BA16100DE3BD1 /* cdbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cdbase.h; path = ../cdbase.h; sourceTree = SOURCE_ROOT; }; - 2A7D398C115BA16100DE3BD1 /* cheat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cheat.c; path = ../cheat.c; sourceTree = SOURCE_ROOT; }; - 2A7D398D115BA16100DE3BD1 /* cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cheat.h; path = ../cheat.h; sourceTree = SOURCE_ROOT; }; - 2A7D398E115BA16100DE3BD1 /* coffelf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = coffelf.c; path = ../coffelf.c; sourceTree = SOURCE_ROOT; }; - 2A7D398F115BA16100DE3BD1 /* coffelf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = coffelf.h; path = ../coffelf.h; sourceTree = SOURCE_ROOT; }; - 2A7D3990115BA16100DE3BD1 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../core.h; sourceTree = SOURCE_ROOT; }; - 2A7D3991115BA16100DE3BD1 /* cs0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cs0.c; path = ../cs0.c; sourceTree = SOURCE_ROOT; }; - 2A7D3992115BA16100DE3BD1 /* cs0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cs0.h; path = ../cs0.h; sourceTree = SOURCE_ROOT; }; - 2A7D3993115BA16100DE3BD1 /* cs1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cs1.c; path = ../cs1.c; sourceTree = SOURCE_ROOT; }; - 2A7D3994115BA16100DE3BD1 /* cs1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cs1.h; path = ../cs1.h; sourceTree = SOURCE_ROOT; }; - 2A7D3995115BA16100DE3BD1 /* cs2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cs2.c; path = ../cs2.c; sourceTree = SOURCE_ROOT; }; - 2A7D3996115BA16100DE3BD1 /* cs2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cs2.h; path = ../cs2.h; sourceTree = SOURCE_ROOT; }; - 2A7D3997115BA16100DE3BD1 /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug.c; path = ../debug.c; sourceTree = SOURCE_ROOT; }; - 2A7D3998115BA16100DE3BD1 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debug.h; path = ../debug.h; sourceTree = SOURCE_ROOT; }; - 2A7D3999115BA16100DE3BD1 /* error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = error.c; path = ../error.c; sourceTree = SOURCE_ROOT; }; - 2A7D399A115BA16100DE3BD1 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = error.h; path = ../error.h; sourceTree = SOURCE_ROOT; }; - 2A7D399B115BA16100DE3BD1 /* m68kc68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kc68k.c; path = ../m68kc68k.c; sourceTree = SOURCE_ROOT; }; - 2A7D399C115BA16100DE3BD1 /* m68kc68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68kc68k.h; path = ../m68kc68k.h; sourceTree = SOURCE_ROOT; }; - 2A7D399D115BA16100DE3BD1 /* m68kcore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kcore.c; path = ../m68kcore.c; sourceTree = SOURCE_ROOT; }; - 2A7D399E115BA16100DE3BD1 /* m68kcore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68kcore.h; path = ../m68kcore.h; sourceTree = SOURCE_ROOT; }; - 2A7D399F115BA16100DE3BD1 /* m68kd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kd.c; path = ../m68kd.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A0115BA16100DE3BD1 /* m68kd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68kd.h; path = ../m68kd.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A1115BA16100DE3BD1 /* m68kq68.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kq68.c; path = ../m68kq68.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A2115BA16100DE3BD1 /* macjoy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = macjoy.c; path = ../macjoy.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A3115BA16100DE3BD1 /* macjoy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macjoy.h; path = ../macjoy.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A4115BA16100DE3BD1 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memory.c; path = ../memory.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A5115BA16100DE3BD1 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../memory.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A6115BA16100DE3BD1 /* movie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = movie.c; path = ../movie.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A7115BA16100DE3BD1 /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = movie.h; path = ../movie.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A8115BA16100DE3BD1 /* netlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netlink.c; path = ../netlink.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A9115BA16100DE3BD1 /* netlink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netlink.h; path = ../netlink.h; sourceTree = SOURCE_ROOT; }; - 2A7D39AA115BA16100DE3BD1 /* peripheral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = peripheral.c; path = ../peripheral.c; sourceTree = SOURCE_ROOT; }; - 2A7D39AB115BA16100DE3BD1 /* peripheral.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = peripheral.h; path = ../peripheral.h; sourceTree = SOURCE_ROOT; }; - 2A7D39AC115BA16100DE3BD1 /* permacjoy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = permacjoy.c; path = ../permacjoy.c; sourceTree = SOURCE_ROOT; }; - 2A7D39AD115BA16100DE3BD1 /* permacjoy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = permacjoy.h; path = ../permacjoy.h; sourceTree = SOURCE_ROOT; }; - 2A7D39AE115BA16100DE3BD1 /* profile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = profile.c; path = ../profile.c; sourceTree = SOURCE_ROOT; }; - 2A7D39AF115BA16100DE3BD1 /* profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = profile.h; path = ../profile.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B0115BA16100DE3BD1 /* scsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scsp.c; path = ../scsp.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B1115BA16100DE3BD1 /* scsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scsp.h; path = ../scsp.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B2115BA16100DE3BD1 /* scu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scu.c; path = ../scu.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B3115BA16100DE3BD1 /* scu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scu.h; path = ../scu.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B4115BA16100DE3BD1 /* sh2core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2core.c; path = ../sh2core.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B5115BA16100DE3BD1 /* sh2core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2core.h; path = ../sh2core.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B6115BA16100DE3BD1 /* sh2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2d.c; path = ../sh2d.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B7115BA16100DE3BD1 /* sh2d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2d.h; path = ../sh2d.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B8115BA16100DE3BD1 /* sh2idle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2idle.c; path = ../sh2idle.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B9115BA16100DE3BD1 /* sh2idle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2idle.h; path = ../sh2idle.h; sourceTree = SOURCE_ROOT; }; - 2A7D39BA115BA16100DE3BD1 /* sh2int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2int.c; path = ../sh2int.c; sourceTree = SOURCE_ROOT; }; - 2A7D39BB115BA16100DE3BD1 /* sh2int.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2int.h; path = ../sh2int.h; sourceTree = SOURCE_ROOT; }; - 2A7D39BC115BA16100DE3BD1 /* sh2trace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2trace.c; path = ../sh2trace.c; sourceTree = SOURCE_ROOT; }; - 2A7D39BD115BA16100DE3BD1 /* sh2trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2trace.h; path = ../sh2trace.h; sourceTree = SOURCE_ROOT; }; - 2A7D39BE115BA16100DE3BD1 /* smpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smpc.c; path = ../smpc.c; sourceTree = SOURCE_ROOT; }; - 2A7D39BF115BA16100DE3BD1 /* smpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = smpc.h; path = ../smpc.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C2115BA16100DE3BD1 /* vdp1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vdp1.c; path = ../vdp1.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C3115BA16100DE3BD1 /* vdp1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vdp1.h; path = ../vdp1.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C4115BA16100DE3BD1 /* vdp2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vdp2.c; path = ../vdp2.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C5115BA16100DE3BD1 /* vdp2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vdp2.h; path = ../vdp2.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C6115BA16100DE3BD1 /* vdp2debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vdp2debug.c; path = ../vdp2debug.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C7115BA16100DE3BD1 /* vdp2debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vdp2debug.h; path = ../vdp2debug.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C8115BA16100DE3BD1 /* vidogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vidogl.c; path = ../vidogl.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C9115BA16100DE3BD1 /* vidogl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vidogl.h; path = ../vidogl.h; sourceTree = SOURCE_ROOT; }; - 2A7D39CA115BA16100DE3BD1 /* vidshared.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vidshared.c; path = ../vidshared.c; sourceTree = SOURCE_ROOT; }; - 2A7D39CB115BA16100DE3BD1 /* vidshared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vidshared.h; path = ../vidshared.h; sourceTree = SOURCE_ROOT; }; - 2A7D39CC115BA16100DE3BD1 /* vidgcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vidgcd.c; sourceTree = ""; }; - 2A7D39CD115BA16100DE3BD1 /* vidgcd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vidgcd.h; sourceTree = ""; }; - 2A7D39CE115BA16100DE3BD1 /* yabause.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yabause.c; path = ../yabause.c; sourceTree = SOURCE_ROOT; }; - 2A7D39CF115BA16100DE3BD1 /* yabause.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yabause.h; path = ../yabause.h; sourceTree = SOURCE_ROOT; }; - 2A7D39D0115BA16100DE3BD1 /* ygl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ygl.c; path = ../ygl.c; sourceTree = SOURCE_ROOT; }; - 2A7D39D1115BA16100DE3BD1 /* ygl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ygl.h; path = ../ygl.h; sourceTree = SOURCE_ROOT; }; - 2A7D39D2115BA16100DE3BD1 /* yui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yui.h; path = ../yui.h; sourceTree = SOURCE_ROOT; }; - 2A7D3A1D115BA29F00DE3BD1 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; - 2A7D3A30115BA35200DE3BD1 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 2A7D3A32115BA35200DE3BD1 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; - 2A7D3A41115BA3AF00DE3BD1 /* c68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = c68k.c; path = ../c68k/c68k.c; sourceTree = SOURCE_ROOT; }; - 2A7D3A42115BA3AF00DE3BD1 /* c68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = c68k.h; path = ../c68k/c68k.h; sourceTree = SOURCE_ROOT; }; - 2A7D3A43115BA3AF00DE3BD1 /* c68kexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = c68kexec.c; path = ../c68k/c68kexec.c; sourceTree = SOURCE_ROOT; }; - 2A7D3A44115BA3AF00DE3BD1 /* c68kmac.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = c68kmac.inc; path = ../c68k/c68kmac.inc; sourceTree = SOURCE_ROOT; }; - 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gen68k.c; path = ../c68k/gen68k.c; sourceTree = SOURCE_ROOT; }; - 2A7D3A46115BA3AF00DE3BD1 /* gen68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gen68k.h; path = ../c68k/gen68k.h; sourceTree = SOURCE_ROOT; }; - 2A7D3A47115BA3AF00DE3BD1 /* gen68k.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = gen68k.inc; path = ../c68k/gen68k.inc; sourceTree = SOURCE_ROOT; }; - 2A7D3A55115BA3E700DE3BD1 /* gen68k */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gen68k; sourceTree = BUILT_PRODUCTS_DIR; }; - 2A7D3A9A115BAB9E00DE3BD1 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; - 2A7D3AD4115BB01500DE3BD1 /* Yabause.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Yabause.icns; sourceTree = ""; }; - 2A82CC9F116171DB00F15B02 /* PerCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerCocoa.h; sourceTree = ""; }; - 2A82CCA0116171DB00F15B02 /* PerCocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PerCocoa.m; sourceTree = ""; }; - 2A9D75FE116645D700A580EB /* sndmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sndmac.c; path = ../sndmac.c; sourceTree = SOURCE_ROOT; }; - 2A9D75FF116645D700A580EB /* sndmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sndmac.h; path = ../sndmac.h; sourceTree = SOURCE_ROOT; }; - 2A9D760D11665F2800A580EB /* controller.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = controller.png; path = resources/controller.png; sourceTree = ""; }; - 2A9D761F116667C300A580EB /* YabausePrefsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabausePrefsController.m; sourceTree = ""; }; - 2A9D7620116667C300A580EB /* YabausePrefsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabausePrefsController.h; sourceTree = ""; }; - 2AD10F97118BBC850088FB2C /* scsp2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scsp2.c; path = ../scsp2.c; sourceTree = SOURCE_ROOT; }; - 2AD10F98118BBC850088FB2C /* scsp2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scsp2.h; path = ../scsp2.h; sourceTree = SOURCE_ROOT; }; - 2AD10F99118BBC850088FB2C /* snddummy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = snddummy.c; path = ../snddummy.c; sourceTree = SOURCE_ROOT; }; - 2AD10F9A118BBC850088FB2C /* sndwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sndwav.c; path = ../sndwav.c; sourceTree = SOURCE_ROOT; }; - 2AD10F9B118BBC850088FB2C /* thr-dummy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "thr-dummy.c"; path = "../thr-dummy.c"; sourceTree = SOURCE_ROOT; }; - 2AD10F9C118BBC850088FB2C /* thr-macosx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "thr-macosx.c"; path = "../thr-macosx.c"; sourceTree = SOURCE_ROOT; }; - 2AD10F9D118BBC850088FB2C /* threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = threads.h; path = ../threads.h; sourceTree = SOURCE_ROOT; }; - 2AF0CA4F116146A400196BED /* YabauseGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabauseGLView.m; sourceTree = ""; }; - 2AF0CA50116146A400196BED /* YabauseGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabauseGLView.h; sourceTree = ""; }; - 2AF0CA9711614DD500196BED /* YabauseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabauseController.h; sourceTree = ""; }; - 2AF0CA9811614DD500196BED /* YabauseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabauseController.m; sourceTree = ""; }; - 8D1107310486CEB800E47090 /* Yabause-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Yabause-Info.plist"; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* Yabause.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Yabause.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F07BF9E314A1C2C500775818 /* yglshader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yglshader.c; path = ../yglshader.c; sourceTree = SOURCE_ROOT; }; - F07E62CA15054DCC00DF8A4E /* titan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = titan.c; path = ../titan/titan.c; sourceTree = SOURCE_ROOT; }; - F07E62CC15054DF500DF8A4E /* titan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = titan.h; path = ../titan/titan.h; sourceTree = SOURCE_ROOT; }; - F0E47FAC156C34EC001A1B51 /* osdcore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = osdcore.c; path = ../osdcore.c; sourceTree = SOURCE_ROOT; }; - F0E47FAE156C34FB001A1B51 /* osdcore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = osdcore.h; path = ../osdcore.h; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2A7D3A53115BA3E700DE3BD1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D11072E0486CEB800E47090 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - 2A7D3A1E115BA29F00DE3BD1 /* OpenGL.framework in Frameworks */, - 2A7D3A31115BA35200DE3BD1 /* CoreFoundation.framework in Frameworks */, - 2A7D3A33115BA35200DE3BD1 /* IOKit.framework in Frameworks */, - 2A3392711162E100000DA0E9 /* GLUT.framework in Frameworks */, - 2A474DF01163A013006993EA /* AudioUnit.framework in Frameworks */, - 2A474DF21163A013006993EA /* CoreAudio.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { - isa = PBXGroup; - children = ( - 2A1145171385E5010087C872 /* YabauseButtonFormatter.h */, - 2A1145181385E5010087C872 /* YabauseButtonFormatter.m */, - 2AF0CA9711614DD500196BED /* YabauseController.h */, - 2AF0CA9811614DD500196BED /* YabauseController.m */, - 2AF0CA50116146A400196BED /* YabauseGLView.h */, - 2AF0CA4F116146A400196BED /* YabauseGLView.m */, - 2A9D7620116667C300A580EB /* YabausePrefsController.h */, - 2A9D761F116667C300A580EB /* YabausePrefsController.m */, - ); - name = Classes; - sourceTree = ""; - }; - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 2A3392701162E100000DA0E9 /* GLUT.framework */, - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - 2A7D3A1D115BA29F00DE3BD1 /* OpenGL.framework */, - 2A7D3A30115BA35200DE3BD1 /* CoreFoundation.framework */, - 2A7D3A32115BA35200DE3BD1 /* IOKit.framework */, - 2A474DEF1163A013006993EA /* AudioUnit.framework */, - 2A474DF11163A013006993EA /* CoreAudio.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 29B97324FDCFA39411CA2CEA /* AppKit.framework */, - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, - 29B97325FDCFA39411CA2CEA /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D1107320486CEB800E47090 /* Yabause.app */, - 2A7D3A55115BA3E700DE3BD1 /* gen68k */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* Yabause */ = { - isa = PBXGroup; - children = ( - 2A7D3972115BA0DD00DE3BD1 /* Emulation Core */, - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = Yabause; - sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - 29B97316FDCFA39411CA2CEA /* main.m */, - 2A82CC9F116171DB00F15B02 /* PerCocoa.h */, - 2A82CCA0116171DB00F15B02 /* PerCocoa.m */, - 2A7D39CD115BA16100DE3BD1 /* vidgcd.h */, - 2A7D39CC115BA16100DE3BD1 /* vidgcd.c */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 2A9D760D11665F2800A580EB /* controller.png */, - 2A7D3AD4115BB01500DE3BD1 /* Yabause.icns */, - 8D1107310486CEB800E47090 /* Yabause-Info.plist */, - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - 2A7D3A99115BAB9E00DE3BD1 /* MainMenu.xib */, - ); - name = Resources; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 2A7D3972115BA0DD00DE3BD1 /* Emulation Core */ = { - isa = PBXGroup; - children = ( - F0E47FAE156C34FB001A1B51 /* osdcore.h */, - F0E47FAC156C34EC001A1B51 /* osdcore.c */, - F07E62CC15054DF500DF8A4E /* titan.h */, - F07E62CA15054DCC00DF8A4E /* titan.c */, - F07BF9E314A1C2C500775818 /* yglshader.c */, - 2A7D3A3E115BA38900DE3BD1 /* C68K */, - 2A7D3987115BA16100DE3BD1 /* bios.c */, - 2A7D3988115BA16100DE3BD1 /* bios.h */, - 2A7D3989115BA16100DE3BD1 /* cd-macosx.c */, - 2A7D398A115BA16100DE3BD1 /* cdbase.c */, - 2A7D398B115BA16100DE3BD1 /* cdbase.h */, - 2A7D398C115BA16100DE3BD1 /* cheat.c */, - 2A7D398D115BA16100DE3BD1 /* cheat.h */, - 2A7D398E115BA16100DE3BD1 /* coffelf.c */, - 2A7D398F115BA16100DE3BD1 /* coffelf.h */, - 2A7D3990115BA16100DE3BD1 /* core.h */, - 2A7D3991115BA16100DE3BD1 /* cs0.c */, - 2A7D3992115BA16100DE3BD1 /* cs0.h */, - 2A7D3993115BA16100DE3BD1 /* cs1.c */, - 2A7D3994115BA16100DE3BD1 /* cs1.h */, - 2A7D3995115BA16100DE3BD1 /* cs2.c */, - 2A7D3996115BA16100DE3BD1 /* cs2.h */, - 2A7D3997115BA16100DE3BD1 /* debug.c */, - 2A7D3998115BA16100DE3BD1 /* debug.h */, - 2A7D3999115BA16100DE3BD1 /* error.c */, - 2A7D399A115BA16100DE3BD1 /* error.h */, - 2A7D399B115BA16100DE3BD1 /* m68kc68k.c */, - 2A7D399C115BA16100DE3BD1 /* m68kc68k.h */, - 2A7D399D115BA16100DE3BD1 /* m68kcore.c */, - 2A7D399E115BA16100DE3BD1 /* m68kcore.h */, - 2A7D399F115BA16100DE3BD1 /* m68kd.c */, - 2A7D39A0115BA16100DE3BD1 /* m68kd.h */, - 2A7D39A1115BA16100DE3BD1 /* m68kq68.c */, - 2A7D39A2115BA16100DE3BD1 /* macjoy.c */, - 2A7D39A3115BA16100DE3BD1 /* macjoy.h */, - 2A7D39A4115BA16100DE3BD1 /* memory.c */, - 2A7D39A5115BA16100DE3BD1 /* memory.h */, - 2A7D39A6115BA16100DE3BD1 /* movie.c */, - 2A7D39A7115BA16100DE3BD1 /* movie.h */, - 2A7D39A8115BA16100DE3BD1 /* netlink.c */, - 2A7D39A9115BA16100DE3BD1 /* netlink.h */, - 2A7D39AA115BA16100DE3BD1 /* peripheral.c */, - 2A7D39AB115BA16100DE3BD1 /* peripheral.h */, - 2A7D39AC115BA16100DE3BD1 /* permacjoy.c */, - 2A7D39AD115BA16100DE3BD1 /* permacjoy.h */, - 2A7D39AE115BA16100DE3BD1 /* profile.c */, - 2A7D39AF115BA16100DE3BD1 /* profile.h */, - 2A7D39B0115BA16100DE3BD1 /* scsp.c */, - 2A7D39B1115BA16100DE3BD1 /* scsp.h */, - 2AD10F97118BBC850088FB2C /* scsp2.c */, - 2AD10F98118BBC850088FB2C /* scsp2.h */, - 2A7D39B2115BA16100DE3BD1 /* scu.c */, - 2A7D39B3115BA16100DE3BD1 /* scu.h */, - 2A7D39B4115BA16100DE3BD1 /* sh2core.c */, - 2A7D39B5115BA16100DE3BD1 /* sh2core.h */, - 2A7D39B6115BA16100DE3BD1 /* sh2d.c */, - 2A7D39B7115BA16100DE3BD1 /* sh2d.h */, - 2A7D39B8115BA16100DE3BD1 /* sh2idle.c */, - 2A7D39B9115BA16100DE3BD1 /* sh2idle.h */, - 2A7D39BA115BA16100DE3BD1 /* sh2int.c */, - 2A7D39BB115BA16100DE3BD1 /* sh2int.h */, - 2A7D39BC115BA16100DE3BD1 /* sh2trace.c */, - 2A7D39BD115BA16100DE3BD1 /* sh2trace.h */, - 2A7D39BE115BA16100DE3BD1 /* smpc.c */, - 2A7D39BF115BA16100DE3BD1 /* smpc.h */, - 2AD10F99118BBC850088FB2C /* snddummy.c */, - 2A9D75FE116645D700A580EB /* sndmac.c */, - 2A9D75FF116645D700A580EB /* sndmac.h */, - 2AD10F9A118BBC850088FB2C /* sndwav.c */, - 2AD10F9B118BBC850088FB2C /* thr-dummy.c */, - 2AD10F9C118BBC850088FB2C /* thr-macosx.c */, - 2AD10F9D118BBC850088FB2C /* threads.h */, - 2A7D39C2115BA16100DE3BD1 /* vdp1.c */, - 2A7D39C3115BA16100DE3BD1 /* vdp1.h */, - 2A7D39C4115BA16100DE3BD1 /* vdp2.c */, - 2A7D39C5115BA16100DE3BD1 /* vdp2.h */, - 2A7D39C6115BA16100DE3BD1 /* vdp2debug.c */, - 2A7D39C7115BA16100DE3BD1 /* vdp2debug.h */, - 2A7D39C8115BA16100DE3BD1 /* vidogl.c */, - 2A7D39C9115BA16100DE3BD1 /* vidogl.h */, - 2A7D39CA115BA16100DE3BD1 /* vidshared.c */, - 2A7D39CB115BA16100DE3BD1 /* vidshared.h */, - 2A7AB7CE117D1CBE00E47298 /* vidsoft.h */, - 2A7AB7CB117D1C1B00E47298 /* vidsoft.c */, - 2A7D39CE115BA16100DE3BD1 /* yabause.c */, - 2A7D39CF115BA16100DE3BD1 /* yabause.h */, - 2A7D39D0115BA16100DE3BD1 /* ygl.c */, - 2A7D39D1115BA16100DE3BD1 /* ygl.h */, - 2A7D39D2115BA16100DE3BD1 /* yui.h */, - ); - name = "Emulation Core"; - sourceTree = ""; - }; - 2A7D3A3E115BA38900DE3BD1 /* C68K */ = { - isa = PBXGroup; - children = ( - 2A7D3A41115BA3AF00DE3BD1 /* c68k.c */, - 2A7D3A42115BA3AF00DE3BD1 /* c68k.h */, - 2A7D3A43115BA3AF00DE3BD1 /* c68kexec.c */, - 2A7D3A44115BA3AF00DE3BD1 /* c68kmac.inc */, - 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */, - 2A7D3A46115BA3AF00DE3BD1 /* gen68k.h */, - 2A7D3A47115BA3AF00DE3BD1 /* gen68k.inc */, - ); - name = C68K; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2A7D3A54115BA3E700DE3BD1 /* gen68k */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2A7D3A59115BA40C00DE3BD1 /* Build configuration list for PBXNativeTarget "gen68k" */; - buildPhases = ( - 2A7D3A52115BA3E700DE3BD1 /* Sources */, - 2A7D3A53115BA3E700DE3BD1 /* Frameworks */, - 2A7D3A6F115BA5A200DE3BD1 /* Run gen68k */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = gen68k; - productName = gen68k; - productReference = 2A7D3A55115BA3E700DE3BD1 /* gen68k */; - productType = "com.apple.product-type.tool"; - }; - 8D1107260486CEB800E47090 /* Yabause */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Yabause" */; - buildPhases = ( - 8D1107290486CEB800E47090 /* Resources */, - 8D11072C0486CEB800E47090 /* Sources */, - 8D11072E0486CEB800E47090 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 2A7D3A7B115BA63900DE3BD1 /* PBXTargetDependency */, - ); - name = Yabause; - productInstallPath = "$(HOME)/Applications"; - productName = Yabause; - productReference = 8D1107320486CEB800E47090 /* Yabause.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Yabause" */; - compatibilityVersion = "Xcode 2.4"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* Yabause */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 2A7D3A54115BA3E700DE3BD1 /* gen68k */, - 8D1107260486CEB800E47090 /* Yabause */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, - 2A7D3A9B115BAB9E00DE3BD1 /* MainMenu.xib in Resources */, - 2A7D3AD5115BB01500DE3BD1 /* Yabause.icns in Resources */, - 2A9D760E11665F2800A580EB /* controller.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 2A7D3A6F115BA5A200DE3BD1 /* Run gen68k */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(PROJECT_DIR)/../gen68k/gen68k.c", - "$(PROJECT_DIR)/../gen68k/gen68k.h", - "$(PROJECT_DIR)/../gen68k/gen68k.inc", - "$(PROJECT_DIR)/../gen68k/c68kmac.inc", - "$(PROJECT_DIR)/../gen68k/c68kexec.c", - "$(PROJECT_DIR)/../gen68k/c68k.c", - "$(PROJECT_DIR)/../gen68k/c68k.h", - ); - name = "Run gen68k"; - outputPaths = ( - "$(PROJECT_DIR)/../gen68k/c68k_op0.inc", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cd ../c68k\n\"$BUILD_DIR/$CONFIGURATION/gen68k\""; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2A7D3A52115BA3E700DE3BD1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2A7D3A5A115BA41200DE3BD1 /* gen68k.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D11072C0486CEB800E47090 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072D0486CEB800E47090 /* main.m in Sources */, - 2A7D39D3115BA16100DE3BD1 /* bios.c in Sources */, - 2A7D39D4115BA16100DE3BD1 /* cd-macosx.c in Sources */, - 2A7D39D5115BA16100DE3BD1 /* cdbase.c in Sources */, - 2A7D39D6115BA16100DE3BD1 /* cheat.c in Sources */, - 2A7D39D7115BA16100DE3BD1 /* coffelf.c in Sources */, - 2A7D39D8115BA16100DE3BD1 /* cs0.c in Sources */, - 2A7D39D9115BA16100DE3BD1 /* cs1.c in Sources */, - 2A7D39DA115BA16100DE3BD1 /* cs2.c in Sources */, - 2A7D39DB115BA16100DE3BD1 /* debug.c in Sources */, - 2A7D39DC115BA16100DE3BD1 /* error.c in Sources */, - 2A7D39DD115BA16100DE3BD1 /* m68kc68k.c in Sources */, - 2A7D39DE115BA16100DE3BD1 /* m68kcore.c in Sources */, - 2A7D39DF115BA16100DE3BD1 /* m68kd.c in Sources */, - 2A7D39E1115BA16100DE3BD1 /* macjoy.c in Sources */, - 2A7D39E2115BA16100DE3BD1 /* memory.c in Sources */, - 2A7D39E3115BA16100DE3BD1 /* movie.c in Sources */, - 2A7D39E4115BA16100DE3BD1 /* netlink.c in Sources */, - 2A7D39E5115BA16100DE3BD1 /* peripheral.c in Sources */, - 2A7D39E6115BA16100DE3BD1 /* permacjoy.c in Sources */, - 2A7D39E7115BA16100DE3BD1 /* profile.c in Sources */, - 2A7D39E9115BA16100DE3BD1 /* scu.c in Sources */, - 2A7D39EA115BA16100DE3BD1 /* sh2core.c in Sources */, - 2A7D39EB115BA16100DE3BD1 /* sh2d.c in Sources */, - 2A7D39EC115BA16100DE3BD1 /* sh2idle.c in Sources */, - 2A7D39ED115BA16100DE3BD1 /* sh2int.c in Sources */, - 2A7D39EE115BA16100DE3BD1 /* sh2trace.c in Sources */, - 2A7D39EF115BA16100DE3BD1 /* smpc.c in Sources */, - 2A7D39F1115BA16100DE3BD1 /* vdp1.c in Sources */, - 2A7D39F2115BA16100DE3BD1 /* vdp2.c in Sources */, - 2A7D39F3115BA16100DE3BD1 /* vdp2debug.c in Sources */, - 2A7D39F4115BA16100DE3BD1 /* vidogl.c in Sources */, - 2A7D39F5115BA16100DE3BD1 /* vidshared.c in Sources */, - 2A7D39F6115BA16100DE3BD1 /* vidgcd.c in Sources */, - 2A7D39F7115BA16100DE3BD1 /* yabause.c in Sources */, - 2A7D39F8115BA16100DE3BD1 /* ygl.c in Sources */, - 2A7D3A48115BA3AF00DE3BD1 /* c68k.c in Sources */, - 2A7D3A49115BA3AF00DE3BD1 /* c68kexec.c in Sources */, - 2A7D3A4B115BA3AF00DE3BD1 /* gen68k.c in Sources */, - 2AF0CA51116146A400196BED /* YabauseGLView.m in Sources */, - 2AF0CA9911614DD500196BED /* YabauseController.m in Sources */, - 2A82CCA1116171DB00F15B02 /* PerCocoa.m in Sources */, - 2A9D7600116645D700A580EB /* sndmac.c in Sources */, - 2A9D7621116667C300A580EB /* YabausePrefsController.m in Sources */, - 2A7AB7CC117D1C1B00E47298 /* vidsoft.c in Sources */, - 2AD10F9E118BBC850088FB2C /* scsp2.c in Sources */, - 2AD10F9F118BBC850088FB2C /* snddummy.c in Sources */, - 2AD10FA0118BBC850088FB2C /* sndwav.c in Sources */, - 2AD10FDB118BCFA00088FB2C /* thr-dummy.c in Sources */, - 2A1145191385E5010087C872 /* YabauseButtonFormatter.m in Sources */, - F07BF9E414A1C2C500775818 /* yglshader.c in Sources */, - F07E62CB15054DCC00DF8A4E /* titan.c in Sources */, - F0E47FAD156C34EC001A1B51 /* osdcore.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 2A7D3A7B115BA63900DE3BD1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 2A7D3A54115BA3E700DE3BD1 /* gen68k */; - targetProxy = 2A7D3A7A115BA63900DE3BD1 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C165DFE840E0CC02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 2A7D3A99115BAB9E00DE3BD1 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 2A7D3A9A115BAB9E00DE3BD1 /* English */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 2A7D3A57115BA3E800DE3BD1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = C68K_GEN; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = gen68k; - }; - name = Debug; - }; - 2A7D3A58115BA3E800DE3BD1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - GCC_PREPROCESSOR_DEFINITIONS = C68K_GEN; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = gen68k; - ZERO_LINK = NO; - }; - name = Release; - }; - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(NATIVE_ARCH_ACTUAL)"; - COPY_PHASE_STRIP = NO; - ENABLE_OPENMP_SUPPORT = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_UNROLL_LOOPS = YES; - GCC_VERSION = 4.2; - INFOPLIST_FILE = "Yabause-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - OTHER_CFLAGS = "-fnested-functions"; - PRODUCT_NAME = Yabause; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_OPENMP_SUPPORT = NO; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_UNROLL_LOOPS = YES; - GCC_VERSION = 4.2; - INFOPLIST_FILE = "Yabause-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "-fnested-functions"; - PRODUCT_NAME = Yabause; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(NATIVE_ARCH_ACTUAL)"; - ENABLE_OPENMP_SUPPORT = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = ( - "USE_SCSP2=1", - CRAB_REWRITE, - NO_CLI, - HAVE_LIBGL, - HAVE_LIBGLUT, - HAVE_SYS_TIME_H, - HAVE_GETTIMEOFDAY, - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", - ); - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "VERSION=\\\"0.9.10\\\""; - GCC_VERSION = 4.2; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = ""; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.6.sdk"; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = ( - "USE_SCSP2=1", - CRAB_REWRITE, - NO_CLI, - HAVE_LIBGL, - HAVE_LIBGLUT, - HAVE_SYS_TIME_H, - HAVE_GETTIMEOFDAY, - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", - ); - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "VERSION=\\\"0.9.10\\\""; - GCC_VERSION = 4.2; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH_PRE_XCODE_3_1 = "$(NATIVE_ARCH_ACTUAL)"; - OTHER_CFLAGS = ""; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.6.sdk"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2A7D3A59115BA40C00DE3BD1 /* Build configuration list for PBXNativeTarget "gen68k" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2A7D3A57115BA3E800DE3BD1 /* Debug */, - 2A7D3A58115BA3E800DE3BD1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Yabause" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Yabause" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/yabause/src/cocoa/YabauseButtonFormatter.h b/yabause/src/cocoa/YabauseButtonFormatter.h deleted file mode 100644 index e283c5b424..0000000000 --- a/yabause/src/cocoa/YabauseButtonFormatter.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabauseButtonFormatter_h -#define YabauseButtonFormatter_h - -#import - - -@interface YabauseButtonFormatter : NSFormatter { -} - -- (NSString *)stringForObjectValue:(id)obj; -- (BOOL)getObjectValue:(id *)obj - forString:(NSString *)str - errorDescription:(NSString **)err; - -- (BOOL)control:(NSControl*)control - textView:(NSTextView*)textView - doCommandBySelector:(SEL)commandSelector; - -@end /* @interface YabauseButtonFormatter */ - -#endif /* !YabauseButtonFormatter_h */ diff --git a/yabause/src/cocoa/YabauseButtonFormatter.m b/yabause/src/cocoa/YabauseButtonFormatter.m deleted file mode 100644 index 258846b893..0000000000 --- a/yabause/src/cocoa/YabauseButtonFormatter.m +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "YabauseButtonFormatter.h" -#include - -@implementation YabauseButtonFormatter - -- (NSString *)stringForObjectValue:(id)obj -{ - if(![obj isKindOfClass:[NSString class]]) { - return nil; - } - - if([obj length] >= 1) { - return [obj substringToIndex:1]; - } - else { - return [NSString string]; - } -} - -- (BOOL)getObjectValue:(id *)obj - forString:(NSString *)str - errorDescription:(NSString **)err -{ - if(obj) { - if([str length] >= 1) { - *obj = [NSString stringWithString:[str substringToIndex:1]]; - } - else { - *obj = [NSString string]; - } - } - - return YES; -} - -- (BOOL)isPartialStringValid:(NSString **)partialStringPtr - proposedSelectedRange:(NSRangePointer)proposedSelRangePtr - originalString:(NSString *)origString - originalSelectedRange:(NSRange)origSelRange - errorDescription:(NSString **)error -{ - NSString *rs = [[*partialStringPtr substringToIndex:1] uppercaseString]; - - *partialStringPtr = rs; - *proposedSelRangePtr = NSMakeRange(0, [rs length]); - - return NO; -} - -- (BOOL)control:(NSControl*)control - textView:(NSTextView*)textView - doCommandBySelector:(SEL)commandSelector -{ - BOOL result = NO; - - /* handle all the fun special cases... */ - if(commandSelector == @selector(insertNewline:)) { - [textView insertText:@"\u23CE"]; - result = YES; - } - else if(commandSelector == @selector(insertTab:)) { - [textView insertText:@"\u21E5"]; - result = YES; - } - else if(commandSelector == @selector(cancelOperation:)) { - [textView insertText:@"\u241B"]; - result = YES; - } - else if(commandSelector == @selector(deleteBackward:)) { - [textView insertText:@"\u232B"]; - result = YES; - } - else if(commandSelector == @selector(moveLeft:)) { - [textView insertText:@"\u2190"]; - result = YES; - } - else if(commandSelector == @selector(moveUp:)) { - [textView insertText:@"\u2191"]; - result = YES; - } - else if(commandSelector == @selector(moveRight:)) { - [textView insertText:@"\u2192"]; - result = YES; - } - else if(commandSelector == @selector(moveDown:)) { - [textView insertText:@"\u2193"]; - result = YES; - } - - return result; -} - -@end /* @implementation YabauseButtonFormatter */ diff --git a/yabause/src/cocoa/YabauseController.h b/yabause/src/cocoa/YabauseController.h deleted file mode 100644 index 02bebff99e..0000000000 --- a/yabause/src/cocoa/YabauseController.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2010, 2012 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabauseController_h -#define YabauseController_h - -#import - -@class YabauseGLView; -@class YabausePrefsController; - -@interface YabauseController : NSObject { - IBOutlet YabauseGLView *view; - IBOutlet NSPanel *prefsPane; - IBOutlet YabausePrefsController *prefs; - IBOutlet NSMenuItem *frameskip; - IBOutlet NSWindow *logWindow; - IBOutlet NSTextView *logView; - BOOL _running; - BOOL _paused; - NSLock *_runLock; - NSThread *_emuThd; - char *_bramFile; - char *_isoFile; - BOOL _doneExecuting; -} - -- (void)awakeFromNib; -- (void)dealloc; - -/* NSWindow delegate methods */ -- (BOOL)windowShouldClose:(id)sender; - -/* NSApplication delegate methods */ -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app; - -- (IBAction)showPreferences:(id)sender; -- (IBAction)runBIOS:(id)sender; -- (IBAction)runCD:(id)sender; -- (IBAction)runISO:(id)sender; -- (IBAction)toggleFullscreen:(id)sender; -- (IBAction)toggle:(id)sender; -- (IBAction)toggleFrameskip:(id)sender; -- (IBAction)pause:(id)sender; -- (IBAction)reset:(id)sender; - -- (YabauseGLView *)view; - -@end - -extern YabauseController *controller; - -#endif /* !YabauseController_h */ diff --git a/yabause/src/cocoa/YabauseController.m b/yabause/src/cocoa/YabauseController.m deleted file mode 100644 index 313bff1339..0000000000 --- a/yabause/src/cocoa/YabauseController.m +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright 2010, 2012 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "YabauseController.h" -#include "YabauseGLView.h" -#include "YabausePrefsController.h" - -#include "vdp1.h" -#include "vdp2.h" -#include "scsp.h" -#include "peripheral.h" -#include "cdbase.h" -#include "yabause.h" -#include "yui.h" -#include "PerCocoa.h" -#include "m68kc68k.h" -#include "cs0.h" - -YabauseController *controller; - -@interface YabauseController (InternalFunctions) -- (void)startEmulationWithCDCore:(int)cdcore CDPath:(const char *)fn; -- (void)emulationThread:(id)ignored; -- (void)terminateEmulation; -@end - -/* Menu Item tags. */ -enum { - tagVDP1 = 1, - tagNBG0 = 2, - tagNBG1 = 3, - tagNBG2 = 4, - tagNBG3 = 5, - tagRBG0 = 6, - tagFPS = 7 -}; - -static void FlipToggle(NSMenuItem *item) { - if([item state] == NSOffState) { - [item setState:NSOnState]; - } - else { - [item setState:NSOffState]; - } -} - -@implementation YabauseController - -- (void)awakeFromNib -{ - NSUserDefaults *p = [NSUserDefaults standardUserDefaults]; - - controller = self; - _running = NO; - _paused = NO; - _runLock = [[NSLock alloc] init]; - _emuThd = nil; - _bramFile = NULL; - _doneExecuting = NO; - - if([p boolForKey:@"Enable Frameskip"]) { - [frameskip setState:NSOnState]; - EnableAutoFrameSkip(); - } - else { - [frameskip setState:NSOffState]; - DisableAutoFrameSkip(); - } -} - -- (void)dealloc -{ - [_runLock release]; - [super dealloc]; -} - -- (BOOL)windowShouldClose:(id)sender -{ - [self terminateEmulation]; - return YES; -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app -{ - [self terminateEmulation]; - return NSTerminateNow; -} - -- (IBAction)showPreferences:(id)sender -{ - [prefsPane makeKeyAndOrderFront:self]; -} - -- (IBAction)runBIOS:(id)sender -{ - /* This will simply start up the system with the dummy CD core, so there's - no way it'll actually read that there's a disc to be played. */ - [self startEmulationWithCDCore:CDCORE_DUMMY CDPath:NULL]; -} - -- (IBAction)runCD:(id)sender -{ - [self startEmulationWithCDCore:CDCORE_ARCH CDPath:NULL]; -} - -- (IBAction)runISO:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - NSArray *types = [NSArray arrayWithObjects:@"iso", @"cue", nil]; - - [p setAllowedFileTypes:types]; - if([p runModal] == NSFileHandlingPanelOKButton) { - NSString *fn = [[[p URLs] objectAtIndex:0] path]; - [self startEmulationWithCDCore:CDCORE_ISO - CDPath:[fn fileSystemRepresentation]]; - } -} - -- (IBAction)toggleFullscreen:(id)sender -{ - /* The view handles any heavy lifting here... */ - [view toggleFullscreen]; -} - -- (IBAction)toggle:(id)sender -{ - /* None of these will work unless we're running... */ - if(!_running) { - return; - } - - /* Flip the checkmark on the button. */ - FlipToggle((NSMenuItem *)sender); - - /* Do whatever this toggle is asking us to do. */ - switch([sender tag]) { - case tagVDP1: - ToggleVDP1(); - break; - - case tagNBG0: - ToggleNBG0(); - break; - - case tagNBG1: - ToggleNBG1(); - break; - - case tagNBG2: - ToggleNBG2(); - break; - - case tagNBG3: - ToggleNBG3(); - break; - - case tagRBG0: - ToggleRBG0(); - break; - - case tagFPS: - ToggleFPS(); - break; - } -} - -- (IBAction)toggleFrameskip:(id)sender -{ - NSUserDefaults *p = [NSUserDefaults standardUserDefaults]; - - if([sender state] == NSOnState) { - DisableAutoFrameSkip(); - [sender setState:NSOffState]; - [p setBool:NO forKey:@"Enable Frameskip"]; - } - else { - EnableAutoFrameSkip(); - [sender setState:NSOnState]; - [p setBool:YES forKey:@"Enable Frameskip"]; - } -} - -- (IBAction)pause:(id)sender -{ - if(_running) { - if(!_paused) { - _paused = YES; - - /* Mute the audio before we actually pause otherwise the user might - not like the result... */ - ScspMuteAudio(SCSP_MUTE_SYSTEM); - [_runLock lock]; - [sender setState:NSOnState]; - } - else { - _paused = NO; - [_runLock unlock]; - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - [sender setState:NSOffState]; - } - } -} - -- (IBAction)reset:(id)sender -{ - if(_running) { - /* Act as if the user pressed the reset button on the console. */ - YabauseResetButton(); - } -} - -- (YabauseGLView *)view -{ - return view; -} - -@end /* @implementation YabauseController */ - -@implementation YabauseController (InternalFunctions) - -- (void)startEmulationWithCDCore:(int)cdcore CDPath:(const char *)fn -{ - if(!_running) { - yabauseinit_struct yinit; - int initok; - NSString *bios = [prefs biosPath]; - NSString *mpeg = [prefs mpegPath]; - NSString *bram = [prefs bramPath]; - NSString *cart = [prefs cartPath]; - - yinit.percoretype = PERCORE_COCOA; - yinit.sh2coretype = SH2CORE_DEFAULT; - yinit.vidcoretype = [prefs videoCore]; - yinit.sndcoretype = [prefs soundCore]; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.cdcoretype = cdcore; - yinit.carttype = [prefs cartType]; - yinit.regionid = [prefs region]; - yinit.biospath = ([bios length] > 0 && ![prefs emulateBios]) ? - [bios UTF8String] : NULL; - yinit.cdpath = fn; - yinit.buppath = NULL; - yinit.mpegpath = ([mpeg length] > 0) ? [mpeg UTF8String] : NULL; - yinit.videoformattype = ([prefs region] < 10) ? VIDEOFORMATTYPE_NTSC : - VIDEOFORMATTYPE_PAL; - yinit.frameskip = [frameskip state] == NSOnState; - yinit.clocksync = 0; - yinit.basetime = 0; - yinit.usethreads = 0; - - /* Set up the internal save ram if specified. */ - if([bram length] > 0) { - const char *tmp = [bram UTF8String]; - yinit.buppath = _bramFile = strdup(tmp); - } - - if(fn) - _isoFile = strdup(fn); - - /* Set up the cartridge stuff based on what was selected. */ - if(yinit.carttype == CART_NETLINK) { - yinit.cartpath = NULL; - yinit.netlinksetting = ([cart length] > 0) ? - [cart UTF8String] : NULL; - } - else { - yinit.cartpath = ([cart length] > 0) ? [cart UTF8String] : NULL; - yinit.netlinksetting = NULL; - } - - if(cdcore == CDCORE_DUMMY && !yinit.biospath) { - NSRunAlertPanel(@"Yabause Error", @"You must specify a BIOS file " - "(and have BIOS emulation disabled) in order to " - "run the BIOS.", @"OK", NULL, NULL); - return; - } - - [[view openGLContext] makeCurrentContext]; - initok = YabauseInit(&yinit); - [NSOpenGLContext clearCurrentContext]; - if (initok != 0) { - return; - } - - YabauseSetDecilineMode(1); - - _running = YES; - _doneExecuting = NO; - - [view showWindow]; - - /* The emulation itself takes place in a separate thread from the main - GUI thread. */ - [NSThread detachNewThreadSelector:@selector(emulationThread:) - toTarget:self - withObject:nil]; - } -} - -- (void)emulationThread:(id)ignored -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGLContextObj cxt; - - _emuThd = [NSThread currentThread]; - - /* Make the OpenGL context current for this thread, otherwise we will be - drawing to nothingness. */ - [[view openGLContext] makeCurrentContext]; - - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - - while(_running) { - /* If we get paused from the GUI, we'll end up waiting in this lock - here... Maybe not the most clear way to do it, but it works. */ - [_runLock lock]; - - /* Make sure the main thread doesn't attempt to flip the buffer before - this thread is done rendering. */ - cxt = CGLGetCurrentContext(); - CGLLockContext(cxt); - - /* Shortcut a function call here... We should technically be doing a - PERCore->HandleEvents(), but that function simply calls YabauseExec() - anyway... so cut out the middleman. */ - YabauseExec(); - - CGLUnlockContext(cxt); - [_runLock unlock]; - } - - ScspMuteAudio(SCSP_MUTE_SYSTEM); - - _doneExecuting = YES; - [pool release]; -} - -- (void)terminateEmulation -{ - _running = NO; - - /* Wait for the thread to die, and then clean up after it. */ - if(_emuThd) { - while(!_doneExecuting) { - sched_yield(); - } - - YabauseDeInit(); - - free(_bramFile); - _bramFile = NULL; - free(_isoFile); - _isoFile = NULL; - - _emuThd = nil; - } -} - -@end /* @implementation YabauseController (InternalFunctions) */ diff --git a/yabause/src/cocoa/YabauseGLView.h b/yabause/src/cocoa/YabauseGLView.h deleted file mode 100644 index 110d1317a3..0000000000 --- a/yabause/src/cocoa/YabauseGLView.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabauseGLView_h -#define YabauseGLView_h - -#import -#include -#include - -@interface YabauseGLView : NSOpenGLView { - IBOutlet NSWindow *window; - BOOL _isFullscreen; - NSPoint _mouseLoc; -} - -- (id)initWithFrame:(NSRect)frameRect; - -- (void)toggleFullscreen; - -- (BOOL)acceptsFirstResponder; -- (void)keyDown:(NSEvent *)event; -- (void)keyUp:(NSEvent *)event; - -- (void)showWindow; - -- (void)reshape; -- (void)drawRect:(NSRect)rect; - -@end - -#endif /* !YabauseGLView_h */ diff --git a/yabause/src/cocoa/YabauseGLView.m b/yabause/src/cocoa/YabauseGLView.m deleted file mode 100644 index 3a196ca407..0000000000 --- a/yabause/src/cocoa/YabauseGLView.m +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "YabauseGLView.h" - -#include "peripheral.h" -#include "vdp1.h" - -@interface YabauseGLView (InternalFunctions) -- (NSScreen *)screen; -- (CGDirectDisplayID)screenID; - -/* These are nice to have, but not really necessary to things... */ -- (float)width; -- (float)height; -@end - -@implementation YabauseGLView - -- (id)initWithFrame:(NSRect)frameRect -{ - NSOpenGLPixelFormatAttribute attrs[] = { - NSOpenGLPFAWindow, - NSOpenGLPFANoRecovery, - NSOpenGLPFAColorSize, 32, - NSOpenGLPFADepthSize, 32, - NSOpenGLPFADoubleBuffer, - 0 - }; - - NSOpenGLPixelFormat *fmt; - - fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; - - if(fmt == nil) { - [fmt release]; - return nil; - } - - if(!(self = [super initWithFrame:frameRect pixelFormat:fmt])) { - [fmt release]; - return nil; - } - - _isFullscreen = NO; - - [fmt release]; - - return self; -} - -- (void)toggleFullscreen -{ - CGError err; - CGDisplayFadeReservationToken token; - CGDirectDisplayID d = [self screenID]; - - err = CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, - &token); - - if(err == kCGErrorSuccess) { - CGDisplayFade(token, 0.5, kCGDisplayBlendNormal, - kCGDisplayBlendSolidColor, 0, 0, 0, 1); - } - - if(!_isFullscreen) { - [self enterFullScreenMode:[self screen] withOptions:nil]; - - /* Hide the cursor, but store its location so we can restore it later. - Also, disassociate the mouse and the cursor position. */ - CGDisplayHideCursor(d); - _mouseLoc = [NSEvent mouseLocation]; - CGDisplayMoveCursorToPoint(d, CGPointZero); - CGAssociateMouseAndMouseCursorPosition(FALSE); - } - else { - CGPoint mousePoint; - int height = CGDisplayPixelsHigh(d); - - mousePoint.x = _mouseLoc.x; - mousePoint.y = height - _mouseLoc.y; - - /* Show the mouse pointer, and reassociate it with the mouse. */ - CGAssociateMouseAndMouseCursorPosition(TRUE); - CGDisplayMoveCursorToPoint(d, mousePoint); - CGDisplayShowCursor(d); - - [self exitFullScreenModeWithOptions:nil]; - [[self window] makeFirstResponder:self]; - } - - if(err == kCGErrorSuccess) { - CGDisplayFade(token, 0.5, kCGDisplayBlendNormal, - kCGDisplayBlendSolidColor, 0, 0, 0, 0); - CGReleaseDisplayFadeReservation(token); - } - - if(VIDCore) - VIDCore->Resize([self width], [self height], 0); - - _isFullscreen = !_isFullscreen; -} - -- (BOOL)acceptsFirstResponder -{ - return YES; -} - -- (void)keyDown:(NSEvent *)event -{ - if([[event charactersIgnoringModifiers] length] >= 1) { - PerKeyDown([[event charactersIgnoringModifiers] characterAtIndex:0]); - } -} - -- (void)keyUp:(NSEvent *)event -{ - if([[event charactersIgnoringModifiers] length] >= 1) { - PerKeyUp([[event charactersIgnoringModifiers] characterAtIndex:0]); - } -} - -- (void)showWindow -{ - [window makeKeyAndOrderFront:self]; -} - -- (void)reshape -{ - CGLContextObj cxt = CGLGetCurrentContext(); - - /* Make sure that the emulation thread doesn't attempt to do any OpenGL - calls during the resize event, otherwise one of the two will crash. */ - CGLLockContext(cxt); - - if(VIDCore) - VIDCore->Resize([self width], [self height], 0); - - CGLUnlockContext(cxt); - - [super reshape]; -} - -- (void)drawRect:(NSRect)rect -{ - CGLContextObj cxt = CGLGetCurrentContext(); - - /* Make sure that the emulation thread doesn't attempt to do any OpenGL - calls during the flush to the screen. */ - CGLLockContext(cxt); - [[self openGLContext] flushBuffer]; - CGLUnlockContext(cxt); -} - -@end /* @implementation YabauseGLView */ - -@implementation YabauseGLView (InternalFunctions) - -- (NSScreen *)screen -{ - NSArray *screens = [NSScreen screens]; - NSEnumerator *i = [screens objectEnumerator]; - NSScreen *obj; - NSRect f = [window frame]; - NSRect sf; - - /* Look for the screen that has the main window on it. */ - while((obj = (NSScreen *)[i nextObject])) { - sf = [obj frame]; - - if(f.origin.x >= sf.origin.x && f.origin.y >= sf.origin.y && - f.origin.x <= sf.origin.x + sf.size.width && - f.origin.y <= sf.origin.y + sf.size.height) { - return obj; - } - } - - /* Punt. */ - return [NSScreen mainScreen]; -} - -- (CGDirectDisplayID)screenID -{ - NSScreen *s = [self screen]; - NSDictionary *d = [s deviceDescription]; - NSNumber *n = (NSNumber *)[d objectForKey:@"NSScreenNumber"]; - - return (CGDirectDisplayID)[n unsignedIntValue]; -} - -- (float)width -{ - return [self bounds].size.width; -} - -- (float)height -{ - return [self bounds].size.height; -} - -@end /* @implementation YabauseGLView (InternalFunctions) */ diff --git a/yabause/src/cocoa/YabausePrefsController.h b/yabause/src/cocoa/YabausePrefsController.h deleted file mode 100644 index d82df96eb1..0000000000 --- a/yabause/src/cocoa/YabausePrefsController.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2010-2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabausePrefsController_h -#define YabausePrefsController_h - -#import - -@interface YabausePrefsController : NSObject { - IBOutlet NSTextField *biosPath; - IBOutlet NSTextField *bramPath; - IBOutlet NSButton *cartBrowse; - IBOutlet NSTextField *cartPath; - IBOutlet NSPopUpButton *cartType; - IBOutlet NSButton *emulateBios; - IBOutlet NSTextField *mpegPath; - IBOutlet NSPopUpButton *region; - IBOutlet NSPopUpButton *soundCore; - IBOutlet NSPopUpButton *videoCore; - IBOutlet NSPanel *prefsPane; - IBOutlet NSPanel *buttonAssignment; - IBOutlet NSTextField *buttonBox; - - int _cartType; - int _region; - int _soundCore; - int _videoCore; - - NSUserDefaults *_prefs; -} - -- (void)awakeFromNib; -- (void)dealloc; - -/* NSTextField delegate methods */ -- (void)controlTextDidEndEditing:(NSNotification *)notification; - -- (IBAction)cartSelected:(id)sender; -- (IBAction)regionSelected:(id)sender; -- (IBAction)soundCoreSelected:(id)sender; -- (IBAction)videoCoreSelected:(id)sender; -- (IBAction)biosBrowse:(id)sender; -- (IBAction)mpegBrowse:(id)sender; -- (IBAction)bramBrowse:(id)sender; -- (IBAction)cartBrowse:(id)sender; -- (IBAction)biosToggle:(id)sender; -- (IBAction)buttonSelect:(id)sender; - -- (IBAction)buttonSetOk:(id)sender; -- (IBAction)buttonSetCancel:(id)sender; - -- (int)cartType; -- (int)region; -- (int)soundCore; -- (int)videoCore; -- (NSString *)biosPath; -- (BOOL)emulateBios; -- (NSString *)mpegPath; -- (NSString *)bramPath; -- (NSString *)cartPath; - -@end - -#endif /* !YabausePrefsController_h */ diff --git a/yabause/src/cocoa/YabausePrefsController.m b/yabause/src/cocoa/YabausePrefsController.m deleted file mode 100644 index 66692a44af..0000000000 --- a/yabause/src/cocoa/YabausePrefsController.m +++ /dev/null @@ -1,449 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "YabausePrefsController.h" - -#include "cs0.h" -#include "vidogl.h" -#include "vidsoft.h" -#include "scsp.h" -#include "smpc.h" -#include "sndmac.h" -#include "PerCocoa.h" - -@implementation YabausePrefsController - -- (void)awakeFromNib -{ - _cartType = CART_NONE; - _region = REGION_AUTODETECT; - _soundCore = SNDCORE_MAC; - _videoCore = VIDCORE_SOFT; - - _prefs = [[NSUserDefaults standardUserDefaults] retain]; - - /* Fill in all the settings. */ - if([_prefs objectForKey:@"BIOS Path"]) { - [biosPath setStringValue:[_prefs stringForKey:@"BIOS Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"BIOS Path"]; - } - - if([_prefs objectForKey:@"Emulate BIOS"]) { - [emulateBios setState:[_prefs boolForKey:@"Emulate BIOS"] ? - NSOnState : NSOffState]; - } - else { - [_prefs setBool:YES forKey:@"Emulate BIOS"]; - } - - if([_prefs objectForKey:@"MPEG ROM Path"]) { - [mpegPath setStringValue:[_prefs objectForKey:@"MPEG ROM Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"MPEG ROM Path"]; - } - - if([_prefs objectForKey:@"BRAM Path"]) { - [bramPath setStringValue:[_prefs objectForKey:@"BRAM Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"BRAM Path"]; - } - - if([_prefs objectForKey:@"Cartridge Path"]) { - [cartPath setStringValue:[_prefs objectForKey:@"Cartridge Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"Cartridge Path"]; - } - - if([_prefs objectForKey:@"Cartridge Type"]) { - _cartType = [_prefs integerForKey:@"Cartridge Type"]; - - if(_cartType != CART_NONE && _cartType != CART_DRAM8MBIT && - _cartType != CART_DRAM32MBIT) { - [cartPath setEnabled:YES]; - [cartBrowse setEnabled:YES]; - [[cartPath cell] setPlaceholderString:@"Not Set"]; - } - - [cartType selectItemWithTag:_cartType]; - } - else { - [_prefs setInteger:CART_NONE forKey:@"Cartridge Type"]; - } - - if([_prefs objectForKey:@"Region"]) { - _region = [_prefs integerForKey:@"Region"]; - [region selectItemWithTag:_region]; - } - else { - [_prefs setInteger:REGION_AUTODETECT forKey:@"Region"]; - } - - if([_prefs objectForKey:@"Sound Core"]) { - _soundCore = [_prefs integerForKey:@"Sound Core"]; - [soundCore selectItemWithTag:_soundCore]; - } - else { - [_prefs setInteger:SNDCORE_MAC forKey:@"Sound Core"]; - } - - if([_prefs objectForKey:@"Video Core"]) { - _videoCore = [_prefs integerForKey:@"Video Core"]; - [videoCore selectItemWithTag:_videoCore]; - } - else { - [_prefs setInteger:VIDCORE_OGL forKey:@"Video Core"]; - } - - [_prefs synchronize]; -} - -- (void)dealloc -{ - [_prefs release]; - [super dealloc]; -} - -- (void)controlTextDidEndEditing:(NSNotification *)notification -{ - id obj = [notification object]; - - if(obj == biosPath) { - [_prefs setObject:[biosPath stringValue] forKey:@"BIOS Path"]; - } - else if(obj == bramPath) { - [_prefs setObject:[bramPath stringValue] forKey:@"BRAM Path"]; - } - else if(obj == mpegPath) { - [_prefs setObject:[mpegPath stringValue] forKey:@"MPEG ROM Path"]; - } - else if(obj == cartPath) { - [_prefs setObject:[cartPath stringValue] forKey:@"Cartridge Path"]; - } - - [_prefs synchronize]; -} - -- (IBAction)cartSelected:(id)sender -{ - _cartType = [[sender selectedItem] tag]; - - switch(_cartType) { - case CART_NONE: - case CART_DRAM8MBIT: - case CART_DRAM32MBIT: - [cartPath setEnabled:NO]; - [cartPath setStringValue:@""]; - [cartBrowse setEnabled:NO]; - [[cartPath cell] setPlaceholderString: - @"No file required for the selected cartridge"]; - break; - - default: - [cartPath setEnabled:YES]; - [cartBrowse setEnabled:YES]; - [[cartPath cell] setPlaceholderString:@"Not Set"]; - break; - } - - /* Update the preferences file. */ - [_prefs setObject:[cartPath stringValue] forKey:@"Cartridge Path"]; - [_prefs setInteger:_cartType forKey:@"Cartridge Type"]; - [_prefs synchronize]; -} - -- (IBAction)regionSelected:(id)sender -{ - _region = [[sender selectedItem] tag]; - - /* Update the preferences file. */ - [_prefs setInteger:_region forKey:@"Region"]; - [_prefs synchronize]; -} - -- (IBAction)soundCoreSelected:(id)sender -{ - _soundCore = [[sender selectedItem] tag]; - - /* Update the preferences file. */ - [_prefs setInteger:_soundCore forKey:@"Sound Core"]; - [_prefs synchronize]; -} - -- (IBAction)videoCoreSelected:(id)sender -{ - _videoCore = [[sender selectedItem] tag]; - - /* Update the preferences file. */ - [_prefs setInteger:_videoCore forKey:@"Video Core"]; - [_prefs synchronize]; -} - -- (IBAction)biosBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select a Saturn BIOS ROM"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [biosPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[biosPath stringValue] forKey:@"BIOS Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)mpegBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select a MPEG ROM"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [mpegPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[mpegPath stringValue] forKey:@"MPEG ROM Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)bramBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select a BRAM File"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [bramPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[bramPath stringValue] forKey:@"BRAM Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)cartBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select the Cartridge File"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [cartPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[cartPath stringValue] forKey:@"Cartridge Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)biosToggle:(id)sender -{ - /* Update the preferences file. */ - [_prefs setBool:([sender state] == NSOnState) forKey:@"Emulate BIOS"]; - [_prefs synchronize]; -} - -- (IBAction)buttonSelect:(id)sender -{ - NSInteger rv; - NSInteger tag = [sender tag]; - int port = tag > 12 ? 1 : 0; - u8 num = tag > 12 ? tag - 13 : tag; - u32 value = PERCocoaGetKey(num, port); - unichar ch; - - /* Fill in current setting from prefs */ - if(value != (u32)-1) { - switch(value) { - case '\r': - ch = 0x23CE; - break; - - case '\t': - ch = 0x21E5; - break; - - case 27: - ch = 0x241B; - break; - - case 127: - ch = 0x232B; - break; - - case NSLeftArrowFunctionKey: - ch = 0x2190; - break; - - case NSUpArrowFunctionKey: - ch = 0x2191; - break; - - case NSRightArrowFunctionKey: - ch = 0x2192; - break; - - case NSDownArrowFunctionKey: - ch = 0x2193; - break; - - default: - ch = toupper(((int)value)); - } - - [buttonBox setStringValue:[NSString stringWithCharacters:&ch length:1]]; - } - else { - [buttonBox setStringValue:@""]; - } - - /* Open up the sheet and ask for the user's input */ - [NSApp beginSheet:buttonAssignment - modalForWindow:prefsPane - modalDelegate:self - didEndSelector:nil - contextInfo:NULL]; - - rv = [NSApp runModalForWindow:buttonAssignment]; - [NSApp endSheet:buttonAssignment]; - [buttonAssignment orderOut:nil]; - - /* Did the user accept what they put in? */ - if(rv == NSOKButton) { - NSString *s = [buttonBox stringValue]; - u32 val; - - /* This shouldn't happen... */ - if([s length] < 1) { - return; - } - - switch([s characterAtIndex:0]) { - case 0x23CE: /* Return */ - val = '\r'; - break; - - case 0x21E5: /* Tab */ - val = '\t'; - break; - - case 0x241B: /* Escape */ - val = 27; - break; - - case 0x232B: /* Backspace */ - val = 127; - break; - - case 0x2190: /* Left */ - val = NSLeftArrowFunctionKey; - break; - - case 0x2191: /* Up */ - val = NSUpArrowFunctionKey; - break; - - case 0x2192: /* Right */ - val = NSRightArrowFunctionKey; - break; - - case 0x2193: /* Down */ - val = NSDownArrowFunctionKey; - break; - - default: - val = tolower([s characterAtIndex:0]); - } - - /* Update the key mapping, if we're already running. This will also save - the key to the preferences. */ - if(tag > 12) { - PERCocoaSetKey(val, tag - 13, 1); - } - else { - PERCocoaSetKey(val, tag, 0); - } - } -} - -- (IBAction)buttonSetOk:(id)sender -{ - [NSApp stopModalWithCode:NSOKButton]; -} - -- (IBAction)buttonSetCancel:(id)sender -{ - [NSApp stopModalWithCode:NSCancelButton]; -} - -- (int)cartType -{ - return _cartType; -} - -- (int)region -{ - return _region; -} - -- (int)soundCore -{ - return _soundCore; -} - -- (int)videoCore -{ - return _videoCore; -} - -- (NSString *)biosPath -{ - return [biosPath stringValue]; -} - -- (BOOL)emulateBios -{ - return [emulateBios state] == NSOnState; -} - -- (NSString *)mpegPath -{ - return [mpegPath stringValue]; -} - -- (NSString *)bramPath -{ - return [bramPath stringValue]; -} - -- (NSString *)cartPath -{ - return [cartPath stringValue]; -} - -@end /* @implementation YabausePrefsController */ diff --git a/yabause/src/cocoa/main.m b/yabause/src/cocoa/main.m deleted file mode 100644 index 56c0be7036..0000000000 --- a/yabause/src/cocoa/main.m +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright 2010, 2012 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#import -#include - -#include "yui.h" -#include "peripheral.h" -#include "m68kcore.h" -#include "m68kc68k.h" -#include "permacjoy.h" -#include "sndmac.h" -#include "vidogl.h" -#include "vidsoft.h" -#include "vidgcd.h" -#include "cs0.h" -#include "vdp2.h" - -#include "PerCocoa.h" -#include "YabauseController.h" -#include "YabauseGLView.h" - -M68K_struct *M68KCoreList[] = { - &M68KDummy, - &M68KC68K, - NULL -}; - -SH2Interface_struct *SH2CoreList[] = { - &SH2Interpreter, - &SH2DebugInterpreter, - NULL -}; - -PerInterface_struct *PERCoreList[] = { - &PERDummy, - &PERCocoa, - &PERMacJoy, - NULL -}; - -CDInterface *CDCoreList[] = { - &DummyCD, - &ISOCD, - &ArchCD, - NULL -}; - -SoundInterface_struct *SNDCoreList[] = { - &SNDDummy, - &SNDMac, - NULL -}; - -VideoInterface_struct *VIDCoreList[] = { - &VIDDummy, - &VIDOGL, - &VIDSoft, - &VIDGCD, - NULL -}; - -void YuiErrorMsg(const char *string) { - NSString *str = [NSString stringWithUTF8String:string]; - dispatch_async(dispatch_get_main_queue(), ^{ - NSRunAlertPanel(@"Yabause Error", str, @"OK", NULL, NULL); - }); -} - -void YuiSetVideoAttribute(int type, int val) { -} - -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) { - return 0; -} - -void YuiSwapBuffers(void) { - [[controller view] setNeedsDisplay:YES]; -} - -int main(int argc, char *argv[]) { - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/yabause/src/cocoa/resources/controller.png b/yabause/src/cocoa/resources/controller.png deleted file mode 100644 index 88e2a4344b..0000000000 Binary files a/yabause/src/cocoa/resources/controller.png and /dev/null differ diff --git a/yabause/src/cocoa/vidgcd.c b/yabause/src/cocoa/vidgcd.c deleted file mode 100644 index 311f987123..0000000000 --- a/yabause/src/cocoa/vidgcd.c +++ /dev/null @@ -1,3274 +0,0 @@ -/* Copyright 2003-2004 Guillaume Duhamel - Copyright 2004-2008 Theo Berkau - Copyright 2006 Fabien Coulon - Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "vidgcd.h" -#include "vidshared.h" -#include "debug.h" -#include "vdp2.h" - -#ifdef HAVE_LIBGL -#define USE_OPENGL -#endif - -#ifdef USE_OPENGL -#include "ygl.h" -#endif - -#include "yui.h" - -#include -#include -#include - -#if defined WORDS_BIGENDIAN -static INLINE u32 COLSAT2YAB16(int priority,u32 temp) { return (priority | (temp & 0x7C00) << 1 | (temp & 0x3E0) << 14 | (temp & 0x1F) << 27); } -static INLINE u32 COLSAT2YAB32(int priority,u32 temp) { return (((temp & 0xFF) << 24) | ((temp & 0xFF00) << 8) | ((temp & 0xFF0000) >> 8) | priority); } -static INLINE u32 COLSAT2YAB32_2(int priority,u32 temp1,u32 temp2) { return (((temp2 & 0xFF) << 24) | ((temp2 & 0xFF00) << 8) | ((temp1 & 0xFF) << 8) | priority); } -static INLINE u32 COLSATSTRIPPRIORITY(u32 pixel) { return (pixel | 0xFF); } -#else -static INLINE u32 COLSAT2YAB16(int priority,u32 temp) { return (priority << 24 | (temp & 0x1F) << 3 | (temp & 0x3E0) << 6 | (temp & 0x7C00) << 9); } -static INLINE u32 COLSAT2YAB32(int priority, u32 temp) { return (priority << 24 | (temp & 0xFF0000) | (temp & 0xFF00) | (temp & 0xFF)); } -static INLINE u32 COLSAT2YAB32_2(int priority,u32 temp1,u32 temp2) { return (priority << 24 | ((temp1 & 0xFF) << 16) | (temp2 & 0xFF00) | (temp2 & 0xFF)); } -static INLINE u32 COLSATSTRIPPRIORITY(u32 pixel) { return (0xFF000000 | pixel); } -#endif - -#define COLOR_ADDt(b) (b>0xFF?0xFF:(b<0?0:b)) -#define COLOR_ADDb(b1,b2) COLOR_ADDt((signed) (b1) + (b2)) -#ifdef WORDS_BIGENDIAN -#define COLOR_ADD(l,r,g,b) (COLOR_ADDb(l & 0xFF, r) << 24) | \ - (COLOR_ADDb((l >> 8) & 0xFF, g) << 16) | \ - (COLOR_ADDb((l >> 16) & 0xFF, b) << 8) | \ - ((l >> 24) & 0xFF) -#else -#define COLOR_ADD(l,r,g,b) COLOR_ADDb((l & 0xFF), r) | \ - (COLOR_ADDb((l >> 8) & 0xFF, g) << 8) | \ - (COLOR_ADDb((l >> 16) & 0xFF, b) << 16) | \ - (l & 0xFF000000) -#endif - -static void PushUserClipping(int mode); -static void PopUserClipping(void); - -int VIDGCDInit(void); -void VIDGCDDeInit(void); -void VIDGCDResize(unsigned int, unsigned int, int); -int VIDGCDIsFullscreen(void); -int VIDGCDVdp1Reset(void); -void VIDGCDVdp1DrawStart(void); -void VIDGCDVdp1DrawEnd(void); -void VIDGCDVdp1NormalSpriteDraw(void); -void VIDGCDVdp1ScaledSpriteDraw(void); -void VIDGCDVdp1DistortedSpriteDraw(void); -void VIDGCDVdp1PolygonDraw(void); -void VIDGCDVdp1PolylineDraw(void); -void VIDGCDVdp1LineDraw(void); -void VIDGCDVdp1UserClipping(void); -void VIDGCDVdp1SystemClipping(void); -void VIDGCDVdp1LocalCoordinate(void); -int VIDGCDVdp2Reset(void); -void VIDGCDVdp2DrawStart(void); -void VIDGCDVdp2DrawEnd(void); -void VIDGCDVdp2DrawScreens(void); -void VIDGCDVdp2SetResolution(u16 TVMD); -void FASTCALL VIDGCDVdp2SetPriorityNBG0(int priority); -void FASTCALL VIDGCDVdp2SetPriorityNBG1(int priority); -void FASTCALL VIDGCDVdp2SetPriorityNBG2(int priority); -void FASTCALL VIDGCDVdp2SetPriorityNBG3(int priority); -void FASTCALL VIDGCDVdp2SetPriorityRBG0(int priority); -void VIDGCDOnScreenDebugMessage(char *string, ...); -void VIDGCDGetGlSize(int *width, int *height); -void VIDGCDVdp1SwapFrameBuffer(void); -void VIDGCDVdp1EraseFrameBuffer(void); - -VideoInterface_struct VIDGCD = { -VIDCORE_GCD, -"Grand Central Dispatch Software Video Interface", -VIDGCDInit, -VIDGCDDeInit, -VIDGCDResize, -VIDGCDIsFullscreen, -VIDGCDVdp1Reset, -VIDGCDVdp1DrawStart, -VIDGCDVdp1DrawEnd, -VIDGCDVdp1NormalSpriteDraw, -VIDGCDVdp1ScaledSpriteDraw, -VIDGCDVdp1DistortedSpriteDraw, -//for the actual hardware, polygons are essentially identical to distorted sprites -//the actual hardware draws using diagonal lines, which is why using half-transparent processing -//on distorted sprites and polygons is not recommended since the hardware overdraws to prevent gaps -//thus, with half-transparent processing some pixels will be processed more than once, producing moire patterns in the drawn shapes -VIDGCDVdp1DistortedSpriteDraw, -VIDGCDVdp1PolylineDraw, -VIDGCDVdp1LineDraw, -VIDGCDVdp1UserClipping, -VIDGCDVdp1SystemClipping, -VIDGCDVdp1LocalCoordinate, -VIDGCDVdp2Reset, -VIDGCDVdp2DrawStart, -VIDGCDVdp2DrawEnd, -VIDGCDVdp2DrawScreens, -VIDGCDVdp2SetResolution, -VIDGCDVdp2SetPriorityNBG0, -VIDGCDVdp2SetPriorityNBG1, -VIDGCDVdp2SetPriorityNBG2, -VIDGCDVdp2SetPriorityNBG3, -VIDGCDVdp2SetPriorityRBG0, -VIDGCDOnScreenDebugMessage, -VIDGCDGetGlSize, -}; - -static u32 *dispbuffer=NULL; -static u8 *vdp1framebuffer[2]= { NULL, NULL }; -static u8 *vdp1frontframebuffer; -static u8 *vdp1backframebuffer; -static u32 *vdp2framebuffer=NULL; - -static int vdp1width; -static int vdp1height; -static int vdp1clipxstart; -static int vdp1clipxend; -static int vdp1clipystart; -static int vdp1clipyend; -static int vdp1pixelsize; -static int vdp1spritetype; -int vdp2width; -int vdp2height; -static int nbg0priority=0; -static int nbg1priority=0; -static int nbg2priority=0; -static int nbg3priority=0; -static int rbg0priority=0; -#ifdef USE_OPENGL -static int outputwidth; -static int outputheight; -#endif -static int resxratio; -static int resyratio; - -static char message[512]; -static int msglength; - -typedef struct { s16 x; s16 y; } vdp1vertex; - -typedef struct -{ - int pagepixelwh, pagepixelwh_bits, pagepixelwh_mask; - int planepixelwidth, planepixelwidth_bits, planepixelwidth_mask; - int planepixelheight, planepixelheight_bits, planepixelheight_mask; - int screenwidth; - int screenheight; - int oldcellx, oldcelly, oldcellcheck; - int xmask, ymask; - u32 planetbl[16]; -} screeninfo_struct; - -struct { - vdp2draw_struct info; - u8 prioritytable[8]; - u32 coloroffset; - int islinewindow; - clipping_struct clip[2]; - u32 linewnd0addr, linewnd1addr; - int priosused[8]; -} vdp1draw_info; - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void vdp2putpixel32(s32 x, s32 y, u32 color, int priority) -{ - vdp2framebuffer[(y * vdp2width) + x] = COLSAT2YAB32(priority, color); -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u8 Vdp2GetPixelPriority(u32 pixel) -{ -#if defined WORDS_BIGENDIAN - return pixel; -#else - return pixel >> 24; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void puthline16(s32 x, s32 y, s32 width, u16 color, int priority) -{ - u32 *buffer = vdp2framebuffer + (y * vdp2width) + x; - u32 dot=COLSAT2YAB16(priority, color); - int i; - - for (i = 0; i < width; i++) - buffer[i] = dot; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL Vdp2ColorRamGetColor(u32 addr) -{ - switch(Vdp2Internal.ColorMode) - { - case 0: - { - u32 tmp; - addr <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, addr & 0xFFF); - return (((tmp & 0x1F) << 3) | ((tmp & 0x03E0) << 6) | ((tmp & 0x7C00) << 9)); - } - case 1: - { - u32 tmp; - addr <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, addr & 0xFFF); - return (((tmp & 0x1F) << 3) | ((tmp & 0x03E0) << 6) | ((tmp & 0x7C00) << 9)); - } - case 2: - { - addr <<= 2; - return T2ReadLong(Vdp2ColorRam, addr & 0xFFF); - } - default: break; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void Vdp2PatternAddr(vdp2draw_struct *info) -{ - switch(info->patterndatasize) - { - case 1: - { - u16 tmp = T1ReadWord(Vdp2Ram, info->addr); - - info->addr += 2; - info->specialfunction = (info->supplementdata >> 9) & 0x1; - - switch(info->colornumber) - { - case 0: // in 16 colors - info->paladdr = ((tmp & 0xF000) >> 8) | ((info->supplementdata & 0xE0) << 3); - break; - default: // not in 16 colors - info->paladdr = (tmp & 0x7000) >> 4; - break; - } - - switch(info->auxmode) - { - case 0: - info->flipfunction = (tmp & 0xC00) >> 10; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0x3FF) | ((info->supplementdata & 0x1F) << 10); - break; - case 2: - info->charaddr = ((tmp & 0x3FF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x1C) << 10); - break; - } - break; - case 1: - info->flipfunction = 0; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0xFFF) | ((info->supplementdata & 0x1C) << 10); - break; - case 2: - info->charaddr = ((tmp & 0xFFF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x10) << 10); - break; - } - break; - } - - break; - } - case 2: { - u16 tmp1 = T1ReadWord(Vdp2Ram, info->addr); - u16 tmp2 = T1ReadWord(Vdp2Ram, info->addr+2); - info->addr += 4; - info->charaddr = tmp2 & 0x7FFF; - info->flipfunction = (tmp1 & 0xC000) >> 14; - info->paladdr = (tmp1 & 0x7F) << 4; - info->specialfunction = (tmp1 & 0x2000) >> 13; - break; - } - } - - if (!(Vdp2Regs->VRSIZE & 0x8000)) - info->charaddr &= 0x3FFF; - - info->charaddr *= 0x20; // selon Runik - if (info->specialprimode == 1) { - info->priority = (info->priority & 0xE) | (info->specialfunction & 1); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoNothing(UNUSED void *info, u32 pixel) -{ - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoColorOffset(void *info, u32 pixel) -{ - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoColorCalc(void *info, u32 pixel) -{ -#if 0 - u8 oldr, oldg, oldb; - u8 r, g, b; - u32 oldpixel = 0x00FFFFFF; // fix me - - static int topratio[32] = { - 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - }; - static int bottomratio[32] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 - }; - - // separate color components for top and second pixel - r = (pixel & 0xFF) * topratio[((vdp2draw_struct *)info)->alpha] >> 5; - g = ((pixel >> 8) & 0xFF) * topratio[((vdp2draw_struct *)info)->alpha] >> 5; - b = ((pixel >> 16) & 0xFF) * topratio[((vdp2draw_struct *)info)->alpha] >> 5; - -#ifdef WORDS_BIGENDIAN - oldr = ((oldpixel >> 24) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldg = ((oldpixel >> 16) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldb = ((oldpixel >> 8) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; -#else - oldr = (oldpixel & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldg = ((oldpixel >> 8) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldb = ((oldpixel >> 16) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; -#endif - - // add color components and reform the pixel - pixel = ((b + oldb) << 16) | ((g + oldg) << 8) | (r + oldr); -#endif - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoColorCalcWithColorOffset(void *info, u32 pixel) -{ - pixel = DoColorCalc(info, pixel); - - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void ReadVdp2ColorOffset(vdp2draw_struct *info, int clofmask, int ccmask) -{ - if (Vdp2Regs->CLOFEN & clofmask) - { - // color offset enable - if (Vdp2Regs->CLOFSL & clofmask) - { - // color offset B - info->cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info->cor |= 0xFFFFFF00; - - info->cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info->cog |= 0xFFFFFF00; - - info->cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info->cob |= 0xFFFFFF00; - } - else - { - // color offset A - info->cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info->cor |= 0xFFFFFF00; - - info->cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info->cog |= 0xFFFFFF00; - - info->cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info->cob |= 0xFFFFFF00; - } - - if (info->cor == 0 && info->cog == 0 && info->cob == 0) - { - if (Vdp2Regs->CCCTL & ccmask) - info->PostPixelFetchCalc = &DoColorCalc; - else - info->PostPixelFetchCalc = &DoNothing; - } - else - { - if (Vdp2Regs->CCCTL & ccmask) - info->PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info->PostPixelFetchCalc = &DoColorOffset; - } - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & ccmask) - info->PostPixelFetchCalc = &DoColorCalc; - else - info->PostPixelFetchCalc = &DoNothing; - } - -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE int Vdp2FetchPixel(vdp2draw_struct *info, int x, int y, u32 *color) -{ - u32 dot; - - switch(info->colornumber) - { - case 0: // 4 BPP - dot = T1ReadByte(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) / 2) & 0x7FFFF)); - if (!(x & 0x1)) dot >>= 4; - if (!(dot & 0xF) && info->transparencyenable) return 0; - else - { - *color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | (dot & 0xF))); - return 1; - } - case 1: // 8 BPP - dot = T1ReadByte(Vdp2Ram, ((info->charaddr + (y * info->cellw) + x) & 0x7FFFF)); - if (!(dot & 0xFF) && info->transparencyenable) return 0; - else - { - *color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | (dot & 0xFF))); - return 1; - } - case 2: // 16 BPP(palette) - dot = T1ReadWord(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) * 2) & 0x7FFFF)); - if ((dot == 0) && info->transparencyenable) return 0; - else - { - *color = Vdp2ColorRamGetColor(info->coloroffset + dot); - return 1; - } - case 3: // 16 BPP(RGB) - dot = T1ReadWord(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) * 2) & 0x7FFFF)); - if (!(dot & 0x8000) && info->transparencyenable) return 0; - else - { - *color = COLSAT2YAB16(0, dot); - return 1; - } - case 4: // 32 BPP - dot = T1ReadLong(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) * 4) & 0x7FFFF)); - if (!(dot & 0x80000000) && info->transparencyenable) return 0; - else - { - *color = COLSAT2YAB32(0, dot); - return 1; - } - default: - return 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE int TestWindow(int wctl, int enablemask, int inoutmask, clipping_struct *clip, int x, int y) -{ - if (wctl & enablemask) - { - if (wctl & inoutmask) - { - // Draw inside of window - if (x < clip->xstart || x > clip->xend || - y < clip->ystart || y > clip->yend) - return 0; - } - else - { - // Draw outside of window - if (x >= clip->xstart && x <= clip->xend && - y >= clip->ystart && y <= clip->yend) - return 0; - - //it seems to overflow vertically on hardware - if(clip->yend > vdp2height && (x >= clip->xstart && x <= clip->xend )) - return 0; - } - } - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void GeneratePlaneAddrTable(vdp2draw_struct *info, u32 *planetbl) -{ - int i; - - for (i = 0; i < (info->mapwh*info->mapwh); i++) - { - info->PlaneAddr(info, i); - planetbl[i] = info->addr; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void FASTCALL Vdp2MapCalcXY(vdp2draw_struct *info, int *x, int *y, - screeninfo_struct *sinfo) -{ - int planenum; - const int pagesize_bits=info->pagewh_bits*2; - const int cellwh=(2 + info->patternwh); - - const int check = ((y[0] >> cellwh) << 16) | (x[0] >> cellwh); - //if ((x[0] >> cellwh) != sinfo->oldcellx || (y[0] >> cellwh) != sinfo->oldcelly) - if(check != sinfo->oldcellcheck) - { - sinfo->oldcellx = x[0] >> cellwh; - sinfo->oldcelly = y[0] >> cellwh; - sinfo->oldcellcheck = (sinfo->oldcelly << 16) | sinfo->oldcellx; - - // Calculate which plane we're dealing with - planenum = ((y[0] >> sinfo->planepixelheight_bits) * info->mapwh) + (x[0] >> sinfo->planepixelwidth_bits); - x[0] = (x[0] & sinfo->planepixelwidth_mask); - y[0] = (y[0] & sinfo->planepixelheight_mask); - - // Fetch and decode pattern name data - info->addr = sinfo->planetbl[planenum]; - - // Figure out which page it's on(if plane size is not 1x1) - info->addr += (( ((y[0] >> sinfo->pagepixelwh_bits) << pagesize_bits) << info->planew_bits) + - ( (x[0] >> sinfo->pagepixelwh_bits) << pagesize_bits) + - (((y[0] & sinfo->pagepixelwh_mask) >> cellwh) << info->pagewh_bits) + - ((x[0] & sinfo->pagepixelwh_mask) >> cellwh)) << (info->patterndatasize_bits+1); - - Vdp2PatternAddr(info); // Heh, this could be optimized - } - - // Figure out which pixel in the tile we want - if (info->patternwh == 1) - { - x[0] &= 8-1; - y[0] &= 8-1; - - switch(info->flipfunction & 0x3) - { - case 0: //none - break; - case 1: //horizontal flip - x[0] = 8 - 1 - x[0]; - break; - case 2: // vertical flip - y[0] = 8 - 1 - y[0]; - break; - case 3: //flip both - x[0] = 8 - 1 - x[0]; - y[0] = 8 - 1 - y[0]; - break; - } - } - else - { - if (info->flipfunction) - { - y[0] &= 16 - 1; - if (info->flipfunction & 0x2) - { - if (!(y[0] & 8)) - y[0] = 8 - 1 - y[0] + 16; - else - y[0] = 16 - 1 - y[0]; - } - else if (y[0] & 8) - y[0] += 8; - - if (info->flipfunction & 0x1) - { - if (!(x[0] & 8)) - y[0] += 8; - - x[0] &= 8-1; - x[0] = 8 - 1 - x[0]; - } - else if (x[0] & 8) - { - y[0] += 8; - x[0] &= 8-1; - } - else - x[0] &= 8-1; - } - else - { - y[0] &= 16 - 1; - - if (y[0] & 8) - y[0] += 8; - if (x[0] & 8) - y[0] += 8; - x[0] &= 8-1; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void SetupScreenVars(vdp2draw_struct *info, screeninfo_struct *sinfo) -{ - if (!info->isbitmap) - { - sinfo->pagepixelwh=64*8; - sinfo->pagepixelwh_bits = 9; - sinfo->pagepixelwh_mask = 511; - - sinfo->planepixelwidth=info->planew*sinfo->pagepixelwh; - sinfo->planepixelwidth_bits = 8+info->planew; - sinfo->planepixelwidth_mask = (1<<(sinfo->planepixelwidth_bits))-1; - - sinfo->planepixelheight=info->planeh*sinfo->pagepixelwh; - sinfo->planepixelheight_bits = 8+info->planeh; - sinfo->planepixelheight_mask = (1<<(sinfo->planepixelheight_bits))-1; - - sinfo->screenwidth=info->mapwh*sinfo->planepixelwidth; - sinfo->screenheight=info->mapwh*sinfo->planepixelheight; - sinfo->oldcellx=-1; - sinfo->oldcelly=-1; - sinfo->xmask = sinfo->screenwidth-1; - sinfo->ymask = sinfo->screenheight-1; - GeneratePlaneAddrTable(info, sinfo->planetbl); - } - else - { - sinfo->pagepixelwh = 0; - sinfo->pagepixelwh_bits = 0; - sinfo->pagepixelwh_mask = 0; - sinfo->planepixelwidth=0; - sinfo->planepixelwidth_bits=0; - sinfo->planepixelwidth_mask=0; - sinfo->planepixelheight=0; - sinfo->planepixelheight_bits=0; - sinfo->planepixelheight_mask=0; - sinfo->screenwidth=0; - sinfo->screenheight=0; - sinfo->oldcellx=0; - sinfo->oldcelly=0; - sinfo->oldcellcheck=0; - sinfo->xmask = info->cellw-1; - sinfo->ymask = info->cellh-1; - } -} - -////////////////////////////////////////////////////////////////////////////// - -/* FIXME: This function will not work on Big Endian systems. Since its only here - in vidgcd, and the only thing that this vidcore will work on right now is - Mac OS X 10.6 (which is only available for Little Endian systems), its ok for - the time being... */ -static INLINE u32 FASTCALL Vdp2Blend(vdp2draw_struct *info, u32 src, u32 dst) { - u32 alpha, s1, s2, d1, d2, o1, o2, pri; - - pri = Vdp2GetPixelPriority(dst); - - /* If we're not doing color calculation on this plane, then there's no need - to do any blending... */ - if(info->PostPixelFetchCalc != &DoColorCalc && - info->PostPixelFetchCalc != &DoColorCalcWithColorOffset) { - /* If the old pixel is of higher priority, use it. */ - if(pri > info->priority) { - return dst; - } - - return src; - } - - if(pri < info->priority) { - pri = info->priority; - } - - alpha = 255 - (((info->alpha) << 3) + 0x07); - - /* Magic alpha blending! */ - s1 = src & 0x00FF00FF; - s2 = src & 0x0000FF00; - d1 = dst & 0x00FF00FF; - d2 = dst & 0x0000FF00; - - o1 = (d1 + (((s1 - d1) * alpha) >> 8)) & 0x00FF00FF; - o2 = (d2 + (((s2 - d2) * alpha) >> 8)) & 0x0000FF00; - - return o1 | o2 | (pri << 24); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL GCDVdp2DrawScroll(vdp2draw_struct *_info, u32 *_textdata, int width, int height) -{ - int i, j; - clipping_struct _clip[2], _clip1, _clip2; - u32 _linewnd0addr, _linewnd1addr; - screeninfo_struct _sinfo; - int scrollx, scrolly; - int *mosaic_y, *mosaic_x; - int linescrollmult = (_info->islinescroll & 1) + - ((_info->islinescroll & 2) >> 1) + ((_info->islinescroll & 4) >> 2); - - _info->coordincx *= (float)resxratio; - _info->coordincy *= (float)resyratio; - - SetupScreenVars(_info, &_sinfo); - - scrollx = _info->x; - scrolly = _info->y; - - _clip[0].xstart = _clip[0].ystart = _clip[0].xend = _clip[0].yend = 0; - _clip[1].xstart = _clip[1].ystart = _clip[1].xend = _clip[1].yend = 0; - ReadWindowData(_info->wctl, _clip); - _clip1 = _clip[0]; - _clip2 = _clip[1]; - _linewnd0addr = _linewnd1addr = 0; - ReadLineWindowData(&_info->islinewindow, _info->wctl, &_linewnd0addr, &_linewnd1addr); - - { - static int tables_initialized = 0; - static int mosaic_table[16][1024]; - if(!tables_initialized) - { - tables_initialized = 1; - for(i=0;i<16;i++) - { - int m = i+1; - for(j=0;j<1024;j++) - mosaic_table[i][j] = j/m*m; - } - } - mosaic_x = mosaic_table[_info->mosaicxmask-1]; - mosaic_y = mosaic_table[_info->mosaicymask-1]; - } - - dispatch_apply(height, dispatch_get_global_queue(2, 0), ^(size_t j) { - int x, y, i; - u32 *textdata = _textdata + (j * width); - u32 linewnd0addr = _linewnd0addr, linewnd1addr = _linewnd1addr; - screeninfo_struct sinfo = _sinfo; - clipping_struct clip[2] = { _clip1, _clip2 }; - vdp2draw_struct inf = *_info; - vdp2draw_struct *info = &inf; - int Y; - int linescrollx = 0; - - // if line window is enabled, adjust clipping values - if(info->islinewindow) { - // Fetch new xstart and xend values from table - if (info->islinewindow & 0x1) - { - // Window 0 - linewnd0addr = _linewnd0addr + j * 4; - clip[0].xstart = (T1ReadWord(Vdp2Ram, linewnd0addr) & 0x3FF) >> 1; // fix me - linewnd0addr += 2; - clip[0].xend = (T1ReadWord(Vdp2Ram, linewnd0addr) & 0x3FF) >> 1; // fix me - } - if (info->islinewindow & 0x2) - { - // Window 1 - linewnd1addr = _linewnd1addr + j * 4; - clip[1].xstart = (T1ReadWord(Vdp2Ram, linewnd1addr) & 0x3FF) >> 1; // fix me - linewnd1addr += 2; - clip[1].xend = (T1ReadWord(Vdp2Ram, linewnd1addr) & 0x3FF) >> 1; // fix me - } - } - - // precalculate the coordinate for the line(it's faster) and do line - // scroll - if (info->islinescroll) - { - /* Figure out where we actually are in the line scroll table. */ - info->linescrolltbl += linescrollmult * (j << 2); - - if (info->islinescroll & 0x1) - { - linescrollx = (T1ReadLong(Vdp2Ram, info->linescrolltbl) >> 16) & 0x7FF; - info->linescrolltbl += 4; - } - if (info->islinescroll & 0x2) - { - info->y = (T1ReadWord(Vdp2Ram, info->linescrolltbl) & 0x7FF) + scrolly; - info->linescrolltbl += 4; - y = info->y; - } - else - //y = info->y+((int)(info->coordincy *(float)(info->mosaicymask > 1 ? (j / info->mosaicymask * info->mosaicymask) : j))); - y = info->y + info->coordincy*mosaic_y[j]; - if (info->islinescroll & 0x4) - { - info->coordincx = (T1ReadLong(Vdp2Ram, info->linescrolltbl) & 0x7FF00) / (float)65536.0; - info->linescrolltbl += 4; - } - } - else - //y = info->y+((int)(info->coordincy *(float)(info->mosaicymask > 1 ? (j / info->mosaicymask * info->mosaicymask) : j))); - y = info->y + info->coordincy * mosaic_y[j]; - - y &= sinfo.ymask; - - if (info->isverticalscroll) - { - // this is *wrong*, vertical scroll use a different value per cell - // info->verticalscrolltbl should be incremented by info->verticalscrollinc - // each time there's a cell change and reseted at the end of the line... - // or something like that :) - y += T1ReadLong(Vdp2Ram, info->verticalscrolltbl) >> 16; - y &= 0x1FF; - } - - Y=y; - - for (i = 0; i < width; i++) - { - u32 color; - - // See if screen position is clipped, if it isn't, continue - // AND window logic - if(!TestWindow(info->wctl, 0x2, 0x1, &clip[0], i, j) && !TestWindow(info->wctl, 0x8, 0x4, &clip[1], i, j) && (info->wctl & 0x80) == 0x80) - { - textdata++; - continue; - } - //OR window logic - else if ((info->wctl & 0x80) == 0) - { - if (!TestWindow(info->wctl, 0x2, 0x1, &clip[0], i, j)) - { - textdata++; - continue; - } - - // Window 1 - if (!TestWindow(info->wctl, 0x8, 0x4, &clip[1], i,j)) - { - textdata++; - continue; - } - } - - //x = info->x+((int)(info->coordincx*(float)((info->mosaicxmask > 1) ? (i / info->mosaicxmask * info->mosaicxmask) : i))); - x = info->x + mosaic_x[i]*info->coordincx; - x &= sinfo.xmask; - - if (linescrollx) { - x += linescrollx; - x &= 0x3FF; - } - - if (!info->isbitmap) - { - // Tile - y=Y; - // need to calculate this without history! - Vdp2MapCalcXY(info, &x, &y, &sinfo); - } - - // If priority of screen is less than current top pixel and per - // pixel priority isn't used, skip it -#ifndef CRAB_REWRITE - if (Vdp2GetPixelPriority(textdata[0]) > info->priority) - { - textdata++; - continue; - } -#endif - - // Fetch Pixel, if it isn't transparent, continue - if (!Vdp2FetchPixel(info, x, y, &color)) - { - textdata++; - continue; - } - - // check special priority somewhere here - - // Apply color offset and color calculation/special color calculation - // and then continue. - // We almost need to know well ahead of time what the top - // and second pixel is in order to work this. - -#ifndef CRAB_REWRITE - textdata[0] = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - textdata++; -#else - color = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - *textdata++ = Vdp2Blend(info, color, *textdata); -#endif - } - }); -} - -////////////////////////////////////////////////////////////////////////////// - -static void SetupRotationInfo(vdp2draw_struct *info, vdp2rotationparameterfp_struct *p) -{ - if (info->rotatenum == 0) - { - Vdp2ReadRotationTableFP(0, p); - info->PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterAPlaneAddr; - } - else - { - Vdp2ReadRotationTableFP(1, &p[1]); - info->PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterBPlaneAddr; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL Vdp2DrawRotationFP(vdp2draw_struct *info, vdp2rotationparameterfp_struct *parameter) -{ - int i, j; - int x, y; - screeninfo_struct sinfo; - vdp2rotationparameterfp_struct *p=¶meter[info->rotatenum]; - - SetupRotationInfo(info, parameter); - - if (!p->coefenab) - { - fixed32 xmul, ymul, C, F; - - // Since coefficients aren't being used, we can simplify the drawing process - if (IsScreenRotatedFP(p)) - { - // No rotation - info->x = touint(mulfixed(p->kx, (p->Xst - p->Px)) + p->Px + p->Mx); - info->y = touint(mulfixed(p->ky, (p->Yst - p->Py)) + p->Py + p->My); - info->coordincx = tofloat(p->kx); - info->coordincy = tofloat(p->ky); - } - else - { - u32 *textdata=vdp2framebuffer; - - GenerateRotatedVarFP(p, &xmul, &ymul, &C, &F); - - // Do simple rotation - CalculateRotationValuesFP(p); - - SetupScreenVars(info, &sinfo); - - for (j = 0; j < vdp2height; j++) - { - for (i = 0; i < vdp2width; i++) - { - u32 color; - - x = GenerateRotatedXPosFP(p, i, xmul, ymul, C) & sinfo.xmask; - y = GenerateRotatedYPosFP(p, i, xmul, ymul, F) & sinfo.ymask; - xmul += p->deltaXst; - - // Convert coordinates into graphics - if (!info->isbitmap) - { - // Tile - Vdp2MapCalcXY(info, &x, &y, &sinfo); - } - - // If priority of screen is less than current top pixel and per - // pixel priority isn't used, skip it - if (Vdp2GetPixelPriority(textdata[0]) > info->priority) - { - textdata++; - continue; - } - - // Fetch pixel - if (!Vdp2FetchPixel(info, x, y, &color)) - { - textdata++; - continue; - } - - textdata[0] = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - textdata++; - } - ymul += p->deltaYst; - } - - return; - } - } - else - { - fixed32 xmul, ymul, C, F; - fixed32 coefx, coefy; - u32 *textdata=vdp2framebuffer; - - GenerateRotatedVarFP(p, &xmul, &ymul, &C, &F); - - // Rotation using Coefficient Tables(now this stuff just gets wacky. It - // has to be done in software, no exceptions) - CalculateRotationValuesFP(p); - - SetupScreenVars(info, &sinfo); - coefx = coefy = 0; - - for (j = 0; j < vdp2height; j++) - { - if (p->deltaKAx == 0) - { - Vdp2ReadCoefficientFP(p, - p->coeftbladdr + - touint(coefy) * - p->coefdatasize); - } - - for (i = 0; i < vdp2width; i++) - { - u32 color; - - if (p->deltaKAx != 0) - { - Vdp2ReadCoefficientFP(p, - p->coeftbladdr + - toint(coefy + coefx) * - p->coefdatasize); - coefx += p->deltaKAx; - } - - if (p->msb) - { - textdata++; - continue; - } - - x = GenerateRotatedXPosFP(p, i, xmul, ymul, C) & sinfo.xmask; - y = GenerateRotatedYPosFP(p, i, xmul, ymul, F) & sinfo.ymask; - xmul += p->deltaXst; - - // Convert coordinates into graphics - if (!info->isbitmap) - { - // Tile - Vdp2MapCalcXY(info, &x, &y, &sinfo); - } - - // If priority of screen is less than current top pixel and per - // pixel priority isn't used, skip it - if (Vdp2GetPixelPriority(textdata[0]) > info->priority) - { - textdata++; - continue; - } - - // Fetch pixel - if (!Vdp2FetchPixel(info, x, y, &color)) - { - textdata++; - continue; - } - - textdata[0] = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - textdata++; - } - ymul += p->deltaYst; - coefx = 0; - coefy += p->deltaKAst; - } - return; - } - - GCDVdp2DrawScroll(info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawBackScreen(void) -{ - int i; - - // Only draw black if TVMD's DISP and BDCLMD bits are cleared - if ((Vdp2Regs->TVMD & 0x8000) == 0 && (Vdp2Regs->TVMD & 0x100) == 0) - { - // Draw Black - for (i = 0; i < (vdp2width * vdp2height); i++) - vdp2framebuffer[i] = 0; - } - else - { - // Draw Back Screen - u32 scrAddr; - u16 dot; - - if (Vdp2Regs->VRSIZE & 0x8000) - scrAddr = (((Vdp2Regs->BKTAU & 0x7) << 16) | Vdp2Regs->BKTAL) * 2; - else - scrAddr = (((Vdp2Regs->BKTAU & 0x3) << 16) | Vdp2Regs->BKTAL) * 2; - - if (Vdp2Regs->BKTAU & 0x8000) - { - // Per Line - for (i = 0; i < vdp2height; i++) - { - dot = T1ReadWord(Vdp2Ram, scrAddr); - scrAddr += 2; - - puthline16(0, i, vdp2width, dot, 0); - } - } - else - { - // Single Color - dot = T1ReadWord(Vdp2Ram, scrAddr); - - for (i = 0; i < (vdp2width * vdp2height); i++) - vdp2framebuffer[i] = COLSAT2YAB16(0, dot); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG0(void) -{ - vdp2draw_struct info; - vdp2rotationparameterfp_struct parameter[2]; - - if (Vdp2Regs->BGON & 0x20) - { - // RBG1 mode - info.enable = Vdp2Regs->BGON & 0x20; - - // Read in Parameter B - Vdp2ReadRotationTableFP(1, ¶meter[1]); - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x2) != 0) - { - // Bitmap Mode - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> 2, 0x3); - - info.charaddr = (Vdp2Regs->MPOFR & 0x70) * 0x2000; - info.paladdr = (Vdp2Regs->BMPNA & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 4; - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 12); - ReadPatternData(&info, Vdp2Regs->PNCN0, Vdp2Regs->CHCTLA & 0x1); - } - - info.rotatenum = 1; - info.rotatemode = 0; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterBPlaneAddr; - } - else if (Vdp2Regs->BGON & 0x1) - { - // NBG0 mode - info.enable = Vdp2Regs->BGON & 0x1; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x2) != 0) - { - // Bitmap Mode - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> 2, 0x3); - - info.x = Vdp2Regs->SCXIN0 & 0x7FF; - info.y = Vdp2Regs->SCYIN0 & 0x7FF; - - info.charaddr = (Vdp2Regs->MPOFN & 0x7) * 0x20000; - info.paladdr = (Vdp2Regs->BMPNA & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ); - - info.x = Vdp2Regs->SCXIN0 & 0x7FF; - info.y = Vdp2Regs->SCYIN0 & 0x7FF; - ReadPatternData(&info, Vdp2Regs->PNCN0, Vdp2Regs->CHCTLA & 0x1); - } - - info.coordincx = (Vdp2Regs->ZMXN0.all & 0x7FF00) / (float) 65536; - info.coordincy = (Vdp2Regs->ZMYN0.all & 0x7FF00) / (float) 65536; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG0PlaneAddr; - } - else - // Not enabled - return; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x100); - info.specialprimode = Vdp2Regs->SFPRMD & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x70) >> 4; - - if (Vdp2Regs->CCCTL & 0x1) - info.alpha = Vdp2Regs->CCRNA & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7) << 8; - ReadVdp2ColorOffset(&info, 0x1, 0x1); - info.priority = nbg0priority; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x1); - ReadLineScrollData(&info, Vdp2Regs->SCRCTL & 0xFF, Vdp2Regs->LSTA0.all); - if (Vdp2Regs->SCRCTL & 1) - { - info.isverticalscroll = 1; - info.verticalscrolltbl = (Vdp2Regs->VCSTA.all & 0x7FFFE) << 1; - if (Vdp2Regs->SCRCTL & 0x100) - info.verticalscrollinc = 8; - else - info.verticalscrollinc = 4; - } - else - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLA; - - if (info.enable == 1) - { - // NBG0 draw - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); - } - else - { - // RBG1 draw - Vdp2DrawRotationFP(&info, parameter); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG1(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x2; - info.transparencyenable = !(Vdp2Regs->BGON & 0x200); - info.specialprimode = (Vdp2Regs->SFPRMD >> 2) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x3000) >> 12; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x200) != 0) - { - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> 10, 0x3); - - info.x = Vdp2Regs->SCXIN1 & 0x7FF; - info.y = Vdp2Regs->SCYIN1 & 0x7FF; - - info.charaddr = ((Vdp2Regs->MPOFN & 0x70) >> 4) * 0x20000; - info.paladdr = Vdp2Regs->BMPNA & 0x700; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 2); - - info.x = Vdp2Regs->SCXIN1 & 0x7FF; - info.y = Vdp2Regs->SCYIN1 & 0x7FF; - - ReadPatternData(&info, Vdp2Regs->PNCN1, Vdp2Regs->CHCTLA & 0x100); - } - - if (Vdp2Regs->CCCTL & 0x2) - info.alpha = (Vdp2Regs->CCRNA >> 8) & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x70) << 4; - ReadVdp2ColorOffset(&info, 0x2, 0x2); - info.coordincx = (Vdp2Regs->ZMXN1.all & 0x7FF00) / (float) 65536; - info.coordincy = (Vdp2Regs->ZMYN1.all & 0x7FF00) / (float) 65536; - - info.priority = nbg1priority; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG1PlaneAddr; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x2); - ReadLineScrollData(&info, Vdp2Regs->SCRCTL >> 8, Vdp2Regs->LSTA1.all); - if (Vdp2Regs->SCRCTL & 0x100) - { - info.isverticalscroll = 1; - if (Vdp2Regs->SCRCTL & 0x1) - { - info.verticalscrolltbl = 4 + ((Vdp2Regs->VCSTA.all & 0x7FFFE) << 1); - info.verticalscrollinc = 8; - } - else - { - info.verticalscrolltbl = (Vdp2Regs->VCSTA.all & 0x7FFFE) << 1; - info.verticalscrollinc = 4; - } - } - else - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLA >> 8; - - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG2(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x4; - info.transparencyenable = !(Vdp2Regs->BGON & 0x400); - info.specialprimode = (Vdp2Regs->SFPRMD >> 4) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x2) >> 1; - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 4); - info.x = Vdp2Regs->SCXN2 & 0x7FF; - info.y = Vdp2Regs->SCYN2 & 0x7FF; - ReadPatternData(&info, Vdp2Regs->PNCN2, Vdp2Regs->CHCTLB & 0x1); - - if (Vdp2Regs->CCCTL & 0x4) - info.alpha = Vdp2Regs->CCRNB & 0x1F; - - info.coloroffset = Vdp2Regs->CRAOFA & 0x700; - ReadVdp2ColorOffset(&info, 0x4, 0x4); - info.coordincx = info.coordincy = 1; - - info.priority = nbg2priority; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG2PlaneAddr; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x4); - info.islinescroll = 0; - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLB; - info.isbitmap = 0; - - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG3(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x8; - info.transparencyenable = !(Vdp2Regs->BGON & 0x800); - info.specialprimode = (Vdp2Regs->SFPRMD >> 6) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x20) >> 5; - - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 6); - info.x = Vdp2Regs->SCXN3 & 0x7FF; - info.y = Vdp2Regs->SCYN3 & 0x7FF; - ReadPatternData(&info, Vdp2Regs->PNCN3, Vdp2Regs->CHCTLB & 0x10); - - if (Vdp2Regs->CCCTL & 0x8) - info.alpha = (Vdp2Regs->CCRNB >> 8) & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7000) >> 4; - ReadVdp2ColorOffset(&info, 0x8, 0x8); - info.coordincx = info.coordincy = 1; - - info.priority = nbg3priority; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG3PlaneAddr; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x8); - info.islinescroll = 0; - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLB >> 8; - info.isbitmap = 0; - - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawRBG0(void) -{ - vdp2draw_struct info; - vdp2rotationparameterfp_struct parameter[2]; - - info.enable = Vdp2Regs->BGON & 0x10; - info.priority = rbg0priority; - if (!(info.enable & Vdp2External.disptoggle)) - return; - info.transparencyenable = !(Vdp2Regs->BGON & 0x1000); - info.specialprimode = (Vdp2Regs->SFPRMD >> 8) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x7000) >> 12; - - // Figure out which Rotation Parameter we're using - switch (Vdp2Regs->RPMD & 0x3) - { - case 0: - // Parameter A - info.rotatenum = 0; - info.rotatemode = 0; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterAPlaneAddr; - break; - case 1: - // Parameter B - info.rotatenum = 1; - info.rotatemode = 0; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterBPlaneAddr; - break; - case 2: - // Parameter A+B switched via coefficients - case 3: - // Parameter A+B switched via rotation parameter window - default: - info.rotatenum = 0; - info.rotatemode = 1 + (Vdp2Regs->RPMD & 0x1); - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterAPlaneAddr; - break; - } - - Vdp2ReadRotationTableFP(info.rotatenum, ¶meter[info.rotatenum]); - - if((info.isbitmap = Vdp2Regs->CHCTLB & 0x200) != 0) - { - // Bitmap Mode - ReadBitmapSize(&info, Vdp2Regs->CHCTLB >> 10, 0x1); - - if (info.rotatenum == 0) - // Parameter A - info.charaddr = (Vdp2Regs->MPOFR & 0x7) * 0x20000; - else - // Parameter B - info.charaddr = (Vdp2Regs->MPOFR & 0x70) * 0x2000; - - info.paladdr = (Vdp2Regs->BMPNB & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 4; - - if (info.rotatenum == 0) - // Parameter A - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 8); - else - // Parameter B - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 12); - - ReadPatternData(&info, Vdp2Regs->PNCR, Vdp2Regs->CHCTLB & 0x100); - } - - if (Vdp2Regs->CCCTL & 0x10) - info.alpha = Vdp2Regs->CCRR & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFB & 0x7) << 8; - - ReadVdp2ColorOffset(&info, 0x10, 0x10); - info.coordincx = info.coordincy = 1; - - ReadMosaicData(&info, 0x10); - info.islinescroll = 0; - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLC; - - Vdp2DrawRotationFP(&info, parameter); -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDInit(void) -{ - // Initialize output buffer - if ((dispbuffer = (u32 *)calloc(sizeof(u32), 704 * 512)) == NULL) - return -1; - - // Initialize VDP1 framebuffer 1 - if ((vdp1framebuffer[0] = (u8 *)calloc(sizeof(u8), 0x40000)) == NULL) - return -1; - - // Initialize VDP1 framebuffer 2 - if ((vdp1framebuffer[1] = (u8 *)calloc(sizeof(u8), 0x40000)) == NULL) - return -1; - - // Initialize VDP2 framebuffer - if ((vdp2framebuffer = (u32 *)calloc(sizeof(u32), 704 * 512)) == NULL) - return -1; - - vdp1backframebuffer = vdp1framebuffer[0]; - vdp1frontframebuffer = vdp1framebuffer[1]; - vdp2width = 320; - vdp2height = 224; - -#ifdef USE_OPENGL - YuiSetVideoAttribute(DOUBLEBUFFER, 1); - - if (!YglScreenInit(8, 8, 8, 24)) - { - if (!YglScreenInit(4, 4, 4, 24)) - { - if (!YglScreenInit(5, 6, 5, 16)) - { - YuiErrorMsg("Couldn't set GL mode\n"); - return -1; - } - } - } - - glClear(GL_COLOR_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, 320, 224, 0, 1, 0); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glOrtho(-320, 320, -224, 224, 1, 0); - outputwidth = 320; - outputheight = 224; - msglength = 0; -#endif - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDDeInit(void) -{ - if (dispbuffer) - { - free(dispbuffer); - dispbuffer = NULL; - } - - if (vdp1framebuffer[0]) - free(vdp1framebuffer[0]); - - if (vdp1framebuffer[1]) - free(vdp1framebuffer[1]); - - if (vdp2framebuffer) - free(vdp2framebuffer); -} - -////////////////////////////////////////////////////////////////////////////// - -static int IsFullscreen = 0; - -void VIDGCDResize(unsigned int w, unsigned int h, int on) -{ -#ifdef USE_OPENGL - IsFullscreen = on; - - if (on) - YuiSetVideoMode(w, h, 32, 1); - else - YuiSetVideoMode(w, h, 32, 0); - - glClear(GL_COLOR_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, w, h, 0, 1, 0); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glOrtho(-w, w, -h, h, 1, 0); - - glViewport(0, 0, w, h); - outputwidth = w; - outputheight = h; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDIsFullscreen(void) { - return IsFullscreen; -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDVdp1Reset(void) -{ - vdp1clipxstart = 0; - vdp1clipxend = 512; - vdp1clipystart = 0; - vdp1clipyend = 256; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1DrawStart(void) -{ - if (Vdp1Regs->TVMR & 0x1) - { - if (Vdp1Regs->TVMR & 0x2) - { - // Rotation 8-bit - vdp1width = 512; - vdp1height = 512; - } - else - { - // Normal 8-bit - vdp1width = 1024; - vdp1width = 256; - } - - vdp1pixelsize = 1; - } - else - { - // Rotation/Normal 16-bit - vdp1width = 512; - vdp1height = 256; - vdp1pixelsize = 2; - } - - VIDGCDVdp1EraseFrameBuffer(); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1DrawEnd(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u16 Vdp1ReadPattern16( u32 base, u32 offset ) { - - u16 dot = T1ReadByte(Vdp1Ram, ( base + (offset>>1)) & 0x7FFFF); - if ((offset & 0x1) == 0) dot >>= 4; // Even pixel - else dot &= 0xF; // Odd pixel - return dot; -} - -static INLINE u16 Vdp1ReadPattern64( u32 base, u32 offset ) { - - return T1ReadByte(Vdp1Ram, ( base + offset ) & 0x7FFFF) & 0x3F; -} - -static INLINE u16 Vdp1ReadPattern128( u32 base, u32 offset ) { - - return T1ReadByte(Vdp1Ram, ( base + offset ) & 0x7FFFF) & 0x7F; -} - -static INLINE u16 Vdp1ReadPattern256( u32 base, u32 offset ) { - - return T1ReadByte(Vdp1Ram, ( base + offset ) & 0x7FFFF) & 0xFF; -} - -static INLINE u16 Vdp1ReadPattern64k( u32 base, u32 offset ) { - - return T1ReadWord(Vdp1Ram, ( base + 2*offset) & 0x7FFFF); -} - -//////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 alphablend16(u32 d, u32 s, u32 level) -{ - int r,g,b,sr,sg,sb,dr,dg,db; - - int invlevel = 256-level; - sr = s & 0x001f; dr = d & 0x001f; - r = (sr*level + dr*invlevel)>>8; r&= 0x1f; - sg = s & 0x03e0; dg = d & 0x03e0; - g = (sg*level + dg*invlevel)>>8; g&= 0x03e0; - sb = s & 0x7c00; db = d & 0x7c00; - b = (sb*level + db*invlevel)>>8; b&= 0x7c00; - return r|g|b; -} - -typedef struct _COLOR_PARAMS -{ - double r,g,b; -} COLOR_PARAMS; - -COLOR_PARAMS leftColumnColor; - -vdp1cmd_struct cmd; - -int currentPixel; -int currentPixelIsVisible; -int characterWidth; -int characterHeight; - -static int getpixel(int linenumber, int currentlineindex) { - - u32 characterAddress; - u32 colorlut; - u16 colorbank; - u8 SPD; - int endcode; - int endcodesEnabled; - int untexturedColor = 0; - int isTextured = 1; - int currentShape = cmd.CMDCTRL & 0x7; - int flip; - - characterAddress = cmd.CMDSRCA << 3; - colorbank = cmd.CMDCOLR; - colorlut = (u32)colorbank << 3; - SPD = ((cmd.CMDPMOD & 0x40) != 0);//show the actual color of transparent pixels if 1 (they won't be drawn transparent) - endcodesEnabled = (( cmd.CMDPMOD & 0x80) == 0 )?1:0; - flip = (cmd.CMDCTRL & 0x30) >> 4; - - //4 polygon, 5 polyline or 6 line - if(currentShape == 4 || currentShape == 5 || currentShape == 6) { - isTextured = 0; - untexturedColor = cmd.CMDCOLR; - } - - switch( flip ) { - case 1: - // Horizontal flipping - currentlineindex = characterWidth - currentlineindex-1; - break; - case 2: - // Vertical flipping - linenumber = characterHeight - linenumber-1; - - break; - case 3: - // Horizontal/Vertical flipping - linenumber = characterHeight - linenumber-1; - currentlineindex = characterWidth - currentlineindex-1; - break; - } - - switch ((cmd.CMDPMOD >> 3) & 0x7) - { - case 0x0: //4bpp bank - endcode = 0xf; - currentPixel = Vdp1ReadPattern16( characterAddress + (linenumber*(characterWidth>>1)), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - currentPixelIsVisible = 0xf; - break; - - case 0x1://4bpp lut - endcode = 0xf; - currentPixel = Vdp1ReadPattern16( characterAddress + (linenumber*(characterWidth>>1)), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - if (!(currentPixel == 0 && !SPD)) - currentPixel = T1ReadWord(Vdp1Ram, (currentPixel * 2 + colorlut) & 0x7FFFF); - currentPixelIsVisible = 0xffff; - break; - case 0x2://8pp bank (64 color) - //is there a hardware bug with endcodes in this color mode? - //there are white lines around some characters in scud - //using an endcode of 63 eliminates the white lines - //but also causes some dropout due to endcodes being triggered that aren't triggered on hardware - //the closest thing i can do to match the hardware is make all pixels with color index 63 transparent - //this needs more hardware testing - - endcode = 63; - currentPixel = Vdp1ReadPattern64( characterAddress + (linenumber*(characterWidth)), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - currentPixel = 0; - // return 1; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - currentPixelIsVisible = 0x3f; - break; - case 0x3://128 color - endcode = 0xff; - currentPixel = Vdp1ReadPattern128( characterAddress + (linenumber*characterWidth), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - currentPixelIsVisible = 0x7f; - break; - case 0x4://256 color - endcode = 0xff; - currentPixel = Vdp1ReadPattern256( characterAddress + (linenumber*characterWidth), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - currentPixelIsVisible = 0xff; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - break; - case 0x5://16bpp bank - endcode = 0x7fff; - currentPixel = Vdp1ReadPattern64k( characterAddress + (linenumber*characterWidth*2), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - currentPixelIsVisible = 0xffff; - break; - } - - if(!isTextured) - currentPixel = untexturedColor; - - //force the MSB to be on if MSBON is set - currentPixel |= cmd.CMDPMOD & (1 << 15); - - return 0; -} - -static int gouraudAdjust( int color, int tableValue ) -{ - color += (tableValue - 0x10); - - if ( color < 0 ) color = 0; - if ( color > 0x1f ) color = 0x1f; - - return color; -} - -static void putpixel(int x, int y) { - - u16* iPix = &((u16 *)vdp1backframebuffer)[(y * vdp1width) + x]; - int mesh = cmd.CMDPMOD & 0x0100; - int SPD = ((cmd.CMDPMOD & 0x40) != 0);//show the actual color of transparent pixels if 1 (they won't be drawn transparent) - int currentShape = cmd.CMDCTRL & 0x7; - int isTextured=1; - - if(mesh && (x^y)&1) - return; - - if(currentShape == 4 || currentShape == 5 || currentShape == 6) - isTextured = 0; - - if (cmd.CMDPMOD & 0x0400) PushUserClipping((cmd.CMDPMOD >> 9) & 0x1); - - if (x >= vdp1clipxstart && - x < vdp1clipxend && - y >= vdp1clipystart && - y < vdp1clipyend) - {} - else - return; - - if (cmd.CMDPMOD & 0x0400) PopUserClipping(); - - - if ( SPD || (currentPixel & currentPixelIsVisible)) - { - switch( cmd.CMDPMOD & 0x7 )//we want bits 0,1,2 - { - case 0: // replace - if (!((currentPixel == 0) && !SPD)) - *(iPix) = currentPixel; - break; - case 1: // shadow, TODO - *(iPix) = currentPixel; - break; - case 2: // half luminance - *(iPix) = ((currentPixel & ~0x8421) >> 1) | (1 << 15); - break; - case 3: // half transparent - if ( *(iPix) & (1 << 15) )//only if MSB of framebuffer data is set - *(iPix) = alphablend16( *(iPix), currentPixel, (1 << 7) ) | (1 << 15); - else - *(iPix) = currentPixel; - break; - case 4: //gouraud - #define COLOR(r,g,b) (((r)&0x1F)|(((g)&0x1F)<<5)|(((b)&0x1F)<<10) |0x8000 ) - - //handle the special case demonstrated in the sgl chrome demo - //if we are in a paletted bank mode and the other two colors are unused, adjust the index value instead of rgb - if( - (((cmd.CMDPMOD >> 3) & 0x7) != 5) && - (((cmd.CMDPMOD >> 3) & 0x7) != 1) && - (int)leftColumnColor.g == 16 && - (int)leftColumnColor.b == 16) - { - int c = (int)(leftColumnColor.r-0x10); - if(c < 0) c = 0; - currentPixel = currentPixel+c; - *(iPix) = currentPixel; - break; - } - *(iPix) = COLOR( - gouraudAdjust( - currentPixel&0x001F, - (int)leftColumnColor.r), - - gouraudAdjust( - (currentPixel&0x03e0) >> 5, - (int)leftColumnColor.g), - - gouraudAdjust( - (currentPixel&0x7c00) >> 10, - (int)leftColumnColor.b) - ); - break; - default: - *(iPix) = alphablend16( COLOR((int)leftColumnColor.r,(int)leftColumnColor.g, (int)leftColumnColor.b), currentPixel, (1 << 7) ) | (1 << 15); - break; - } - - if(*iPix & 0x8000) { - vdp1draw_info.priosused[vdp1draw_info.prioritytable[0]] = 1; - } - else if(*iPix) { - u16 p = *iPix; - int s, prio, c; - - Vdp1ProcessSpritePixel(vdp1spritetype, &p, &s, &prio, &c); - vdp1draw_info.priosused[prio] = 1; - } - } -} - -//TODO consolidate the following 3 functions -static int bresenham( int x1, int y1, int x2, int y2, int x[], int y[]) -{ - int dx, dy, xf, yf, a, b, c, i; - - if (x2>x1) { - dx = x2-x1; - xf = 1; - } - else { - dx = x1-x2; - xf = -1; - } - - if (y2>y1) { - dy = y2-y1; - yf = 1; - } - else { - dy = y1-y2; - yf = -1; - } - - //burning rangers tries to draw huge shapes - //this will at least let it run - if(dx > 999 || dy > 999) - return INT_MAX; - - if (dx>dy) { - a = dy+dy; - c = a-dx; - b = c-dx; - for (i=0;i<=dx;i++) { - x[i] = x1; y[i] = y1; - x1 += xf; - if (c<0) { - c += a; - } - else { - c += b; - y1 += yf; - } - } - return dx+1; - } - else { - a = dx+dx; - c = a-dy; - b = c-dy; - for (i=0;i<=dy;i++) { - x[i] = x1; y[i] = y1; - y1 += yf; - if (c<0) { - c += a; - } - else { - c += b; - x1 += xf; - } - } - return dy+1; - } -} - -static int DrawLine( int x1, int y1, int x2, int y2, double linenumber, double texturestep, double xredstep, double xgreenstep, double xbluestep) -{ - int dx, dy, xf, yf, a, b, c, i; - int endcodesdetected=0; - int previousStep = 123456789; - - if (x2>x1) { - dx = x2-x1; - xf = 1; - } - else { - dx = x1-x2; - xf = -1; - } - - if (y2>y1) { - dy = y2-y1; - yf = 1; - } - else { - dy = y1-y2; - yf = -1; - } - - if (dx>dy) { - a = dy+dy; - c = a-dx; - b = c-dx; - for (i=0;i<=dx;i++) { - leftColumnColor.r+=xredstep; - leftColumnColor.g+=xgreenstep; - leftColumnColor.b+=xbluestep; - - if(getpixel(linenumber,(int)i*texturestep)) { - if(currentPixel != previousStep) { - previousStep = (int)i*texturestep; - endcodesdetected++; - } - } - else - putpixel(x1,y1); - - previousStep = currentPixel; - - if(endcodesdetected==2) - break; - - x1 += xf; - if (c<0) { - c += a; - } - else { - getpixel(linenumber,(int)i*texturestep); - putpixel(x1,y1); - c += b; - y1 += yf; -/* - //same as sega's way, but just move the code down here instead - //and use the pixel we already have instead of the next one - if(xf>1&&yf>1) putpixel(x1,y1-1); //case 1 - if(xf<1&&yf<1) putpixel(x1,y1+1); //case 2 - if(xf<1&&yf>1) putpixel(x1+1,y1); //case 7 - if(xf>1&&yf<1) putpixel(x1-1,y1); //case 8*/ - } - } - return dx+1; - } - else { - a = dx+dx; - c = a-dy; - b = c-dy; - for (i=0;i<=dy;i++) { - leftColumnColor.r+=xredstep; - leftColumnColor.g+=xgreenstep; - leftColumnColor.b+=xbluestep; - - if(getpixel(linenumber,(int)i*texturestep)) { - if(currentPixel != previousStep) { - previousStep = (int)i*texturestep; - endcodesdetected++; - } - } - else - putpixel(x1,y1); - - previousStep = currentPixel; - - if(endcodesdetected==2) - break; - - y1 += yf; - if (c<0) { - c += a; - } - else { - getpixel(linenumber,(int)i*texturestep); - putpixel(x1,y1); - c += b; - x1 += xf; -/* - if(xf>1&&yf>1) putpixel(x1,y1-1); //case 3 - if(xf<1&&yf<1) putpixel(x1,y1+1); //case 4 - if(xf<1&&yf>1) putpixel(x1+1,y1); //case 5 - if(xf>1&&yf<1) putpixel(x1-1,y1); //case 6*/ - - } - } - return dy+1; - } -} - -static int getlinelength(int x1, int y1, int x2, int y2) { - int dx, dy, xf, yf, a, b, c, i; - - if (x2>x1) { - dx = x2-x1; - xf = 1; - } - else { - dx = x1-x2; - xf = -1; - } - - if (y2>y1) { - dy = y2-y1; - yf = 1; - } - else { - dy = y1-y2; - yf = -1; - } - - if (dx>dy) { - a = dy+dy; - c = a-dx; - b = c-dx; - for (i=0;i<=dx;i++) { - - x1 += xf; - if (c<0) { - c += a; - } - else { - c += b; - y1 += yf; - } - } - return dx+1; - } - else { - a = dx+dx; - c = a-dy; - b = c-dy; - for (i=0;i<=dy;i++) { - y1 += yf; - if (c<0) { - c += a; - } - else { - c += b; - x1 += xf; - } - } - return dy+1; - } -} - -static INLINE double interpolate(double start, double end, int numberofsteps) { - - double stepvalue = 0; - - if(numberofsteps == 0) - return 1; - - stepvalue = (end - start) / numberofsteps; - - return stepvalue; -} - -typedef union _COLOR { // xbgr x555 - struct { -#ifdef WORDS_BIGENDIAN - u16 x:1; - u16 b:5; - u16 g:5; - u16 r:5; -#else - u16 r:5; - u16 g:5; - u16 b:5; - u16 x:1; -#endif - }; - u16 value; -} COLOR; - - -COLOR gouraudA; -COLOR gouraudB; -COLOR gouraudC; -COLOR gouraudD; - -static void gouraudTable(void) -{ - int gouraudTableAddress; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - gouraudTableAddress = (((unsigned int)cmd.CMDGRDA) << 3); - - gouraudA.value = T1ReadWord(Vdp1Ram,gouraudTableAddress); - gouraudB.value = T1ReadWord(Vdp1Ram,gouraudTableAddress+2); - gouraudC.value = T1ReadWord(Vdp1Ram,gouraudTableAddress+4); - gouraudD.value = T1ReadWord(Vdp1Ram,gouraudTableAddress+6); -} - -int xleft[1000]; -int yleft[1000]; -int xright[1000]; -int yright[1000]; - -//a real vdp1 draws with arbitrary lines -//this is why endcodes are possible -//this is also the reason why half-transparent shading causes moire patterns -//and the reason why gouraud shading can be applied to a single line draw command -static void drawQuad(s32 tl_x, s32 tl_y, s32 bl_x, s32 bl_y, s32 tr_x, s32 tr_y, s32 br_x, s32 br_y){ - - int totalleft; - int totalright; - int total; - int i; - - COLOR_PARAMS topLeftToBottomLeftColorStep = {0,0,0}, topRightToBottomRightColorStep = {0,0,0}; - - //how quickly we step through the line arrays - double leftLineStep = 1; - double rightLineStep = 1; - - //a lookup table for the gouraud colors - COLOR colors[4]; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - characterWidth = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - characterHeight = cmd.CMDSIZE & 0xFF; - - totalleft = bresenham(tl_x,tl_y,bl_x,bl_y,xleft,yleft); - totalright = bresenham(tr_x,tr_y,br_x,br_y,xright,yright); - - //just for now since burning rangers will freeze up trying to draw huge shapes - if(totalleft == INT_MAX || totalright == INT_MAX) - return; - - total = totalleft > totalright ? totalleft : totalright; - - - if(cmd.CMDPMOD & (1 << 2)) { - - gouraudTable(); - - { colors[0] = gouraudA; colors[1] = gouraudD; colors[2] = gouraudB; colors[3] = gouraudC; } - - topLeftToBottomLeftColorStep.r = interpolate(colors[0].r,colors[1].r,total); - topLeftToBottomLeftColorStep.g = interpolate(colors[0].g,colors[1].g,total); - topLeftToBottomLeftColorStep.b = interpolate(colors[0].b,colors[1].b,total); - - topRightToBottomRightColorStep.r = interpolate(colors[2].r,colors[3].r,total); - topRightToBottomRightColorStep.g = interpolate(colors[2].g,colors[3].g,total); - topRightToBottomRightColorStep.b = interpolate(colors[2].b,colors[3].b,total); - } - - //we have to step the equivalent of less than one pixel on the shorter side - //to make sure textures stretch properly and the shape is correct - if(total == totalleft && totalleft != totalright) { - //left side is larger - leftLineStep = 1; - rightLineStep = (double)totalright / totalleft; - } - else if(totalleft != totalright){ - //right side is larger - rightLineStep = 1; - leftLineStep = (double)totalleft / totalright; - } - - for(i = 0; i < total; i++) { - - int xlinelength; - - double xtexturestep; - double ytexturestep; - - COLOR_PARAMS rightColumnColor; - - COLOR_PARAMS leftToRightStep = {0,0,0}; - - //get the length of the line we are about to draw - xlinelength = getlinelength( - xleft[(int)(i*leftLineStep)], - yleft[(int)(i*leftLineStep)], - xright[(int)(i*rightLineStep)], - yright[(int)(i*rightLineStep)]); - - //so from 0 to the width of the texture / the length of the line is how far we need to step - xtexturestep=interpolate(0,characterWidth,xlinelength); - - //now we need to interpolate the y texture coordinate across multiple lines - ytexturestep=interpolate(0,characterHeight,total); - - //gouraud interpolation - if(cmd.CMDPMOD & (1 << 2)) { - - //for each new line we need to step once more through each column - //and add the orignal color + the number of steps taken times the step value to the bottom of the shape - //to get the current colors to use to interpolate across the line - - leftColumnColor.r = colors[0].r +(topLeftToBottomLeftColorStep.r*i); - leftColumnColor.g = colors[0].g +(topLeftToBottomLeftColorStep.g*i); - leftColumnColor.b = colors[0].b +(topLeftToBottomLeftColorStep.b*i); - - rightColumnColor.r = colors[2].r +(topRightToBottomRightColorStep.r*i); - rightColumnColor.g = colors[2].g +(topRightToBottomRightColorStep.g*i); - rightColumnColor.b = colors[2].b +(topRightToBottomRightColorStep.b*i); - - //interpolate colors across to get the right step values - leftToRightStep.r = interpolate(leftColumnColor.r,rightColumnColor.r,xlinelength); - leftToRightStep.g = interpolate(leftColumnColor.g,rightColumnColor.g,xlinelength); - leftToRightStep.b = interpolate(leftColumnColor.b,rightColumnColor.b,xlinelength); - } - - DrawLine( - xleft[(int)(i*leftLineStep)], - yleft[(int)(i*leftLineStep)], - xright[(int)(i*rightLineStep)], - yright[(int)(i*rightLineStep)], - ytexturestep*i, - xtexturestep, - leftToRightStep.r, - leftToRightStep.g, - leftToRightStep.b - ); - } -} - -void VIDGCDVdp1NormalSpriteDraw() { - - s16 topLeftx,topLefty,topRightx,topRighty,bottomRightx,bottomRighty,bottomLeftx,bottomLefty; - int spriteWidth; - int spriteHeight; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - topLeftx = cmd.CMDXA + Vdp1Regs->localX; - topLefty = cmd.CMDYA + Vdp1Regs->localY; - spriteWidth = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - spriteHeight = cmd.CMDSIZE & 0xFF; - - topRightx = topLeftx + (spriteWidth - 1); - topRighty = topLefty; - bottomRightx = topLeftx + (spriteWidth - 1); - bottomRighty = topLefty + (spriteHeight - 1); - bottomLeftx = topLeftx; - bottomLefty = topLefty + (spriteHeight - 1); - - drawQuad(topLeftx,topLefty,bottomLeftx,bottomLefty,topRightx,topRighty,bottomRightx,bottomRighty); -} - -void VIDGCDVdp1ScaledSpriteDraw(){ - - s32 topLeftx,topLefty,topRightx,topRighty,bottomRightx,bottomRighty,bottomLeftx,bottomLefty; - int spriteWidth; - int spriteHeight; - int x0,y0,x1,y1; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x0 = cmd.CMDXA + Vdp1Regs->localX; - y0 = cmd.CMDYA + Vdp1Regs->localY; - - switch ((cmd.CMDCTRL >> 8) & 0xF) - { - case 0x0: // Only two coordinates - default: - x1 = ((int)cmd.CMDXC) - x0 + Vdp1Regs->localX + 1; - y1 = ((int)cmd.CMDYC) - y0 + Vdp1Regs->localY + 1; - break; - case 0x5: // Upper-left - x1 = ((int)cmd.CMDXB) + 1; - y1 = ((int)cmd.CMDYB) + 1; - break; - case 0x6: // Upper-Center - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1/2; - x1++; - y1++; - break; - case 0x7: // Upper-Right - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1; - x1++; - y1++; - break; - case 0x9: // Center-left - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - y0 = y0 - y1/2; - x1++; - y1++; - break; - case 0xA: // Center-center - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1/2; - y0 = y0 - y1/2; - x1++; - y1++; - break; - case 0xB: // Center-right - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1; - y0 = y0 - y1/2; - x1++; - y1++; - break; - case 0xD: // Lower-left - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - y0 = y0 - y1; - x1++; - y1++; - break; - case 0xE: // Lower-center - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1/2; - y0 = y0 - y1; - x1++; - y1++; - break; - case 0xF: // Lower-right - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1; - y0 = y0 - y1; - x1++; - y1++; - break; - } - - spriteWidth = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - spriteHeight = cmd.CMDSIZE & 0xFF; - - topLeftx = x0; - topLefty = y0; - - topRightx = x1 + x0 - 1; - topRighty = topLefty; - - bottomRightx = x1 + x0 - 1; - bottomRighty = y1 + y0 - 1; - - bottomLeftx = topLeftx; - bottomLefty = y1 + y0 - 1; - - drawQuad(topLeftx,topLefty,bottomLeftx,bottomLefty,topRightx,topRighty,bottomRightx,bottomRighty); -} - -void VIDGCDVdp1DistortedSpriteDraw() { - - s32 xa,ya,xb,yb,xc,yc,xd,yd; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - xa = (s32)(cmd.CMDXA + Vdp1Regs->localX); - ya = (s32)(cmd.CMDYA + Vdp1Regs->localY); - - xb = (s32)(cmd.CMDXB + Vdp1Regs->localX); - yb = (s32)(cmd.CMDYB + Vdp1Regs->localY); - - xc = (s32)(cmd.CMDXC + Vdp1Regs->localX); - yc = (s32)(cmd.CMDYC + Vdp1Regs->localY); - - xd = (s32)(cmd.CMDXD + Vdp1Regs->localX); - yd = (s32)(cmd.CMDYD + Vdp1Regs->localY); - - drawQuad(xa,ya,xd,yd,xb,yb,xc,yc); -} - -static void gouraudLineSetup(double * redstep, double * greenstep, double * bluestep, int length, COLOR table1, COLOR table2) { - - gouraudTable(); - - *redstep =interpolate(table1.r,table2.r,length); - *greenstep =interpolate(table1.g,table2.g,length); - *bluestep =interpolate(table1.b,table2.b,length); - - leftColumnColor.r = table1.r; - leftColumnColor.g = table1.g; - leftColumnColor.b = table1.b; -} - -void VIDGCDVdp1PolylineDraw(void) -{ - int X[4]; - int Y[4]; - double redstep = 0, greenstep = 0, bluestep = 0; - int length; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - X[0] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C)); - Y[0] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E)); - X[1] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x10)); - Y[1] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x12)); - X[2] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14)); - Y[2] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16)); - X[3] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x18)); - Y[3] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x1A)); - - length = getlinelength(X[0], Y[0], X[1], Y[1]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudA, gouraudB); - DrawLine(X[0], Y[0], X[1], Y[1], 0,0,redstep,greenstep,bluestep); - - length = getlinelength(X[1], Y[1], X[2], Y[2]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudB, gouraudC); - DrawLine(X[1], Y[1], X[2], Y[2], 0,0,redstep,greenstep,bluestep); - - length = getlinelength(X[2], Y[2], X[3], Y[3]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudD, gouraudC); - DrawLine(X[3], Y[3], X[2], Y[2], 0,0,redstep,greenstep,bluestep); - - length = getlinelength(X[3], Y[3], X[0], Y[0]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudA,gouraudD); - DrawLine(X[0], Y[0], X[3], Y[3], 0,0,redstep,greenstep,bluestep); -} - -void VIDGCDVdp1LineDraw(void) -{ - int x1, y1, x2, y2; - double redstep = 0, greenstep = 0, bluestep = 0; - int length; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x1 = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C)); - y1 = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E)); - x2 = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x10)); - y2 = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x12)); - - length = getlinelength(x1, y1, x2, y2); - gouraudLineSetup(&redstep,&bluestep,&greenstep,length, gouraudA, gouraudB); - DrawLine(x1, y1, x2, y2, 0,0,redstep,greenstep,bluestep); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1UserClipping(void) -{ - Vdp1Regs->userclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->userclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); - Vdp1Regs->userclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->userclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); - -#if 0 - vdp1clipxstart = Vdp1Regs->userclipX1; - vdp1clipxend = Vdp1Regs->userclipX2; - vdp1clipystart = Vdp1Regs->userclipY1; - vdp1clipyend = Vdp1Regs->userclipY2; - - // This needs work - if (vdp1clipxstart > Vdp1Regs->systemclipX1) - vdp1clipxstart = Vdp1Regs->userclipX1; - else - vdp1clipxstart = Vdp1Regs->systemclipX1; - - if (vdp1clipxend < Vdp1Regs->systemclipX2) - vdp1clipxend = Vdp1Regs->userclipX2; - else - vdp1clipxend = Vdp1Regs->systemclipX2; - - if (vdp1clipystart > Vdp1Regs->systemclipY1) - vdp1clipystart = Vdp1Regs->userclipY1; - else - vdp1clipystart = Vdp1Regs->systemclipY1; - - if (vdp1clipyend < Vdp1Regs->systemclipY2) - vdp1clipyend = Vdp1Regs->userclipY2; - else - vdp1clipyend = Vdp1Regs->systemclipY2; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -static void PushUserClipping(int mode) -{ - if (mode == 1) - { - VDP1LOG("User clipping mode 1 not implemented\n"); - return; - } - - vdp1clipxstart = Vdp1Regs->userclipX1; - vdp1clipxend = Vdp1Regs->userclipX2; - vdp1clipystart = Vdp1Regs->userclipY1; - vdp1clipyend = Vdp1Regs->userclipY2; - - // This needs work - if (vdp1clipxstart > Vdp1Regs->systemclipX1) - vdp1clipxstart = Vdp1Regs->userclipX1; - else - vdp1clipxstart = Vdp1Regs->systemclipX1; - - if (vdp1clipxend < Vdp1Regs->systemclipX2) - vdp1clipxend = Vdp1Regs->userclipX2; - else - vdp1clipxend = Vdp1Regs->systemclipX2; - - if (vdp1clipystart > Vdp1Regs->systemclipY1) - vdp1clipystart = Vdp1Regs->userclipY1; - else - vdp1clipystart = Vdp1Regs->systemclipY1; - - if (vdp1clipyend < Vdp1Regs->systemclipY2) - vdp1clipyend = Vdp1Regs->userclipY2; - else - vdp1clipyend = Vdp1Regs->systemclipY2; -} - -////////////////////////////////////////////////////////////////////////////// - -static void PopUserClipping(void) -{ - vdp1clipxstart = Vdp1Regs->systemclipX1; - vdp1clipxend = Vdp1Regs->systemclipX2; - vdp1clipystart = Vdp1Regs->systemclipY1; - vdp1clipyend = Vdp1Regs->systemclipY2; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1SystemClipping(void) -{ - Vdp1Regs->systemclipX1 = 0; - Vdp1Regs->systemclipY1 = 0; - Vdp1Regs->systemclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->systemclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); - - vdp1clipxstart = Vdp1Regs->systemclipX1; - vdp1clipxend = Vdp1Regs->systemclipX2; - vdp1clipystart = Vdp1Regs->systemclipY1; - vdp1clipyend = Vdp1Regs->systemclipY2; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1LocalCoordinate(void) -{ - Vdp1Regs->localX = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->localY = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDVdp2Reset(void) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2DrawStart(void) -{ - int wctl; - Vdp2DrawBackScreen(); - - vdp1draw_info.prioritytable[0] = Vdp2Regs->PRISA & 0x7; - vdp1draw_info.prioritytable[1] = (Vdp2Regs->PRISA >> 8) & 0x7; - vdp1draw_info.prioritytable[2] = Vdp2Regs->PRISB & 0x7; - vdp1draw_info.prioritytable[3] = (Vdp2Regs->PRISB >> 8) & 0x7; - vdp1draw_info.prioritytable[4] = Vdp2Regs->PRISC & 0x7; - vdp1draw_info.prioritytable[5] = (Vdp2Regs->PRISC >> 8) & 0x7; - vdp1draw_info.prioritytable[6] = Vdp2Regs->PRISD & 0x7; - vdp1draw_info.prioritytable[7] = (Vdp2Regs->PRISD >> 8) & 0x7; - - vdp1draw_info.coloroffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - vdp1spritetype = Vdp2Regs->SPCTL & 0xF; - - if(Vdp2Regs->CLOFEN & 0x40) { - // color offset enable - if(Vdp2Regs->CLOFSL & 0x40) { - // color offset B - vdp1draw_info.info.cor = Vdp2Regs->COBR & 0xFF; - if(Vdp2Regs->COBR & 0x100) - vdp1draw_info.info.cor |= 0xFFFFFF00; - - vdp1draw_info.info.cog = Vdp2Regs->COBG & 0xFF; - if(Vdp2Regs->COBG & 0x100) - vdp1draw_info.info.cog |= 0xFFFFFF00; - - vdp1draw_info.info.cob = Vdp2Regs->COBB & 0xFF; - if(Vdp2Regs->COBB & 0x100) - vdp1draw_info.info.cob |= 0xFFFFFF00; - } - else { - // color offset A - vdp1draw_info.info.cor = Vdp2Regs->COAR & 0xFF; - if(Vdp2Regs->COAR & 0x100) - vdp1draw_info.info.cor |= 0xFFFFFF00; - - vdp1draw_info.info.cog = Vdp2Regs->COAG & 0xFF; - if(Vdp2Regs->COAG & 0x100) - vdp1draw_info.info.cog |= 0xFFFFFF00; - - vdp1draw_info.info.cob = Vdp2Regs->COAB & 0xFF; - if(Vdp2Regs->COAB & 0x100) - vdp1draw_info.info.cob |= 0xFFFFFF00; - } - - if(vdp1draw_info.info.cor == 0 && vdp1draw_info.info.cog == 0 && vdp1draw_info.info.cob == 0) { - if(Vdp2Regs->CCCTL & 0x40) - vdp1draw_info.info.PostPixelFetchCalc = &DoColorCalc; - else - vdp1draw_info.info.PostPixelFetchCalc = &DoNothing; - } - else { - if(Vdp2Regs->CCCTL & 0x40) - vdp1draw_info.info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - vdp1draw_info.info.PostPixelFetchCalc = &DoColorOffset; - } - } - else { // color offset disable - if(Vdp2Regs->CCCTL & 0x40) - vdp1draw_info.info.PostPixelFetchCalc = &DoColorCalc; - else - vdp1draw_info.info.PostPixelFetchCalc = &DoNothing; - } - - wctl = Vdp2Regs->WCTLC >> 8; - vdp1draw_info.clip[0].xstart = vdp1draw_info.clip[0].ystart = 0; - vdp1draw_info.clip[0].xend = vdp1draw_info.clip[0].yend = 0; - vdp1draw_info.clip[1].xstart = vdp1draw_info.clip[1].ystart = 0; - vdp1draw_info.clip[1].xend = vdp1draw_info.clip[1].yend = 0; - ReadWindowData(wctl, vdp1draw_info.clip); - vdp1draw_info.linewnd0addr = vdp1draw_info.linewnd1addr = 0; - ReadLineWindowData(&vdp1draw_info.islinewindow, wctl, &vdp1draw_info.linewnd0addr, &vdp1draw_info.linewnd1addr); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2DrawEnd(void) -{ -#ifndef CRAB_REWRITE - int i, i2; - u16 pixel; - u8 prioritytable[8]; - u32 vdp1coloroffset; - int colormode = Vdp2Regs->SPCTL & 0x20; - vdp2draw_struct info; - u32 *dst=dispbuffer; - u32 *vdp2src=vdp2framebuffer; - int islinewindow; - clipping_struct clip[2]; - u32 linewnd0addr, linewnd1addr; - int wctl; - - // Figure out whether to draw vdp1 framebuffer or vdp2 framebuffer pixels - // based on priority - if (Vdp1External.disptoggle) - { - prioritytable[0] = Vdp2Regs->PRISA & 0x7; - prioritytable[1] = (Vdp2Regs->PRISA >> 8) & 0x7; - prioritytable[2] = Vdp2Regs->PRISB & 0x7; - prioritytable[3] = (Vdp2Regs->PRISB >> 8) & 0x7; - prioritytable[4] = Vdp2Regs->PRISC & 0x7; - prioritytable[5] = (Vdp2Regs->PRISC >> 8) & 0x7; - prioritytable[6] = Vdp2Regs->PRISD & 0x7; - prioritytable[7] = (Vdp2Regs->PRISD >> 8) & 0x7; - - vdp1coloroffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - vdp1spritetype = Vdp2Regs->SPCTL & 0xF; - - if (Vdp2Regs->CLOFEN & 0x40) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x40) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (info.cor == 0 && info.cog == 0 && info.cob == 0) - { - if (Vdp2Regs->CCCTL & 0x40) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - else - { - if (Vdp2Regs->CCCTL & 0x40) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x40) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - wctl = Vdp2Regs->WCTLC >> 8; - clip[0].xstart = clip[0].ystart = clip[0].xend = clip[0].yend = 0; - clip[1].xstart = clip[1].ystart = clip[1].xend = clip[1].yend = 0; - ReadWindowData(wctl, clip); - linewnd0addr = linewnd1addr = 0; - ReadLineWindowData(&islinewindow, wctl, &linewnd0addr, &linewnd1addr); - - for (i2 = 0; i2 < vdp2height; i2++) - { - ReadLineWindowClip(islinewindow, clip, &linewnd0addr, &linewnd1addr); - - for (i = 0; i < vdp2width; i++) - { - // See if screen position is clipped, if it isn't, continue - // Window 0 - if (!TestWindow(wctl, 0x2, 0x1, &clip[0], i, i2)) - { - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - vdp2src++; - dst++; - continue; - } - - // Window 1 - if (!TestWindow(wctl, 0x8, 0x4, &clip[1], i, i2)) - { - vdp2src++; - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - dst++; - continue; - } - - if (vdp1pixelsize == 2) - { - // 16-bit pixel size - pixel = ((u16 *)vdp1frontframebuffer)[(i2 * vdp1width) + i]; - - if (pixel == 0) - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - else if (pixel & 0x8000 && colormode) - { - // 16 BPP - if (prioritytable[0] >= Vdp2GetPixelPriority(vdp2src[0])) - { - // if pixel is 0x8000, only draw pixel if sprite window - // is disabled/sprite type 2-7. sprite types 0 and 1 are - // -always- drawn and sprite types 8-F are always - // transparent. - if (pixel != 0x8000 || vdp1spritetype < 2 || (vdp1spritetype < 8 && !(Vdp2Regs->SPCTL & 0x10))) - dst[0] = info.PostPixelFetchCalc(&info, COLSAT2YAB16(0xFF, pixel)); - else - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - else - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - else - { - // Color bank - int priority; - int shadow; - int colorcalc; - priority = 0; // Avoid compiler warning - Vdp1ProcessSpritePixel(vdp1spritetype, &pixel, &shadow, &priority, &colorcalc); - if (prioritytable[priority] >= Vdp2GetPixelPriority(vdp2src[0])) - dst[0] = info.PostPixelFetchCalc(&info, COLSAT2YAB32(0xFF, Vdp2ColorRamGetColor(vdp1coloroffset + pixel))); - else - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - } - else - { - // 8-bit pixel size - pixel = vdp1frontframebuffer[(i2 * vdp1width) + i]; - - if (pixel == 0) - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - else - { - // Color bank(fix me) - LOG("8-bit Color Bank draw - %02X\n", pixel); - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - } - vdp2src++; - dst++; - } - } - } - else - { - // Render VDP2 only - for (i = 0; i < (vdp2width*vdp2height); i++) - dispbuffer[i] = COLSATSTRIPPRIORITY(vdp2framebuffer[i]); - } -#endif - - VIDGCDVdp1SwapFrameBuffer(); - - if (OSDUseBuffer()) - OSDDisplayMessages(dispbuffer, vdp2width, vdp2height); - -#ifdef USE_OPENGL - glRasterPos2i(0, 0); - glPixelZoom((float)outputwidth / (float)vdp2width, 0 - ((float)outputheight / (float)vdp2height)); -#ifndef CRAB_REWRITE - glDrawPixels(vdp2width, vdp2height, GL_RGBA, GL_UNSIGNED_BYTE, dispbuffer); -#else - glDisable(GL_BLEND); - glDrawPixels(vdp2width, vdp2height, GL_RGBA, GL_UNSIGNED_BYTE, vdp2framebuffer); -#endif - - if (! OSDUseBuffer()) - OSDDisplayMessages(NULL, -1, -1); -#endif - - YuiSwapBuffers(); -} - -/* FIXME: Support Vdp1 8-bit mode sometime... */ -static void Vdp1DrawPriority(int prio) { - int colormode = Vdp2Regs->SPCTL & 0x20; - vdp2draw_struct *info = &vdp1draw_info.info; - int islinewindow = vdp1draw_info.islinewindow; - int wctl= Vdp2Regs->WCTLC >> 8; - - // Figure out whether to draw vdp1 framebuffer or vdp2 framebuffer pixels - // based on priority - if(Vdp1External.disptoggle) { - dispatch_apply(vdp2height, dispatch_get_global_queue(2, 0), ^(size_t i2) { - u16 *fb16 = (u16 *)(vdp1frontframebuffer) + (i2 * vdp1width); - u32 *fb = vdp2framebuffer + (i2 * vdp2width); - int i; - u16 pixel; - u32 linewnd0addr = vdp1draw_info.linewnd0addr; - u32 linewnd1addr = vdp1draw_info.linewnd1addr; - - ReadLineWindowClip(islinewindow, vdp1draw_info.clip, &linewnd0addr, &linewnd1addr); - - for(i = 0; i < vdp2width; ++i, ++fb16, ++fb) { - // See if screen position is clipped, if it isn't, continue - // Window 0 - if(!TestWindow(wctl, 0x2, 0x1, &vdp1draw_info.clip[0], i, i2)) { - continue; - } - - // Window 1 - if(!TestWindow(wctl, 0x8, 0x4, &vdp1draw_info.clip[1], i, i2)) { - continue; - } - - if (vdp1pixelsize == 2) { - // 16-bit pixel size - pixel = *fb16; - - if(pixel & 0x8000 && colormode && vdp1draw_info.prioritytable[0] == prio && - prio >= Vdp2GetPixelPriority(*fb)) { - // 16 BPP - // if pixel is 0x8000, only draw pixel if sprite window - // is disabled/sprite type 2-7. sprite types 0 and 1 are - // -always- drawn and sprite types 8-F are always - // transparent. - if(pixel != 0x8000 || vdp1spritetype < 2 || (vdp1spritetype < 8 && !(Vdp2Regs->SPCTL & 0x10))) - *fb = info->PostPixelFetchCalc(info, COLSAT2YAB16(0xFF, pixel)); - } - else if(pixel) { - // Color bank - int priority; - int shadow; - int colorcalc; - priority = 0; // Avoid compiler warning - Vdp1ProcessSpritePixel(vdp1spritetype, &pixel, &shadow, &priority, &colorcalc); - priority = vdp1draw_info.prioritytable[priority]; - if(priority == prio && priority >= Vdp2GetPixelPriority(*fb)) - *fb = info->PostPixelFetchCalc(info, COLSAT2YAB32(0xFF, Vdp2ColorRamGetColor(vdp1draw_info.coloroffset + pixel))); - } - } - //else - //{ - // // 8-bit pixel size - // pixel = vdp1frontframebuffer[(i2 * vdp1width) + i]; - // - // if (pixel == 0) - // dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - // else - // { - // // Color bank(fix me) - // LOG("8-bit Color Bank draw - %02X\n", pixel); - // dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - // } - //} - } - }); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2DrawScreens(void) -{ - int i; - - /* Draw all the screens, from the lowest priority one forward. */ - for(i = 1; i < 8; ++i) - { - if (nbg3priority == i) - Vdp2DrawNBG3(); - if (nbg2priority == i) - Vdp2DrawNBG2(); - if (nbg1priority == i) - Vdp2DrawNBG1(); - if (nbg0priority == i) - Vdp2DrawNBG0(); - if (rbg0priority == i) - Vdp2DrawRBG0(); - - /* Draw anything in VDP1 that should be shown at this priority level. */ - if(vdp1draw_info.priosused[i]) - Vdp1DrawPriority(i); - vdp1draw_info.priosused[i] = 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2SetResolution(u16 TVMD) -{ - // This needs some work - - // Horizontal Resolution - switch (TVMD & 0x7) - { - case 0: - vdp2width = 320; - resxratio=1; - break; - case 1: - vdp2width = 352; - resxratio=1; - break; - case 2: // 640 - vdp2width = 320; - resxratio=2; - break; - case 3: // 704 - vdp2width = 352; - resxratio=2; - break; - case 4: - vdp2width = 320; - resxratio=1; - break; - case 5: - vdp2width = 352; - resxratio=1; - break; - case 6: // 640 - vdp2width = 320; - resxratio=2; - break; - case 7: // 704 - vdp2width = 352; - resxratio=2; - break; - } - - // Vertical Resolution - switch ((TVMD >> 4) & 0x3) - { - case 0: - vdp2height = 224; - break; - case 1: - vdp2height = 240; - break; - case 2: - vdp2height = 256; - break; - default: break; - } - resyratio=1; - - // Check for interlace - switch ((TVMD >> 6) & 0x3) - { - case 3: // Double-density Interlace -// vdp2height *= 2; - resyratio=2; - break; - case 2: // Single-density Interlace - case 0: // Non-interlace - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG0(int priority) -{ - nbg0priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG1(int priority) -{ - nbg1priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG2(int priority) -{ - nbg2priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG3(int priority) -{ - nbg3priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityRBG0(int priority) -{ - rbg0priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDOnScreenDebugMessage(char *string, ...) -{ - va_list arglist; - - va_start(arglist, string); - vsprintf(message, string, arglist); - va_end(arglist); - msglength = strlen(message); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDGetScreenSize(int *width, int *height) -{ - *width = vdp2width; - *height = vdp2height; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1SwapFrameBuffer(void) -{ - u8 *temp = vdp1frontframebuffer; - vdp1frontframebuffer = vdp1backframebuffer; - vdp1backframebuffer = temp; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1EraseFrameBuffer(void) -{ - int s, s2; - int w,h; - - h = (Vdp1Regs->EWRR & 0x1FF) + 1; - if (h > vdp1height) h = vdp1height; - w = ((Vdp1Regs->EWRR >> 6) & 0x3F8) + 8; - if (w > vdp1width) w = vdp1width; - - s = Vdp1Regs->EWLR & 0x1FF; - s2 = (Vdp1Regs->EWLR >> 6) & 0x1F8; - - dispatch_apply(h - s, dispatch_get_global_queue(2, 0), ^(size_t i2) { - int i; - i2 += s; - for (i = s2; i < w; i++) { - ((u16 *)vdp1backframebuffer)[(i2 * vdp1width) + i] = Vdp1Regs->EWDR; - } - }); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDGetGlSize(int *width, int *height) -{ -#ifdef USE_OPENGL - *width = outputwidth; - *height = outputheight; -#else - *width = vdp2width; - *height = vdp2height; -#endif -} diff --git a/yabause/src/cocoa/vidgcd.h b/yabause/src/cocoa/vidgcd.h deleted file mode 100644 index 99ada32a99..0000000000 --- a/yabause/src/cocoa/vidgcd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef VIDGCD_H -#define VIDGCD_H - -#include "vdp1.h" - -#define VIDCORE_GCD 10 - -extern VideoInterface_struct VIDGCD; - -#endif diff --git a/yabause/src/coffelf.c b/yabause/src/coffelf.c deleted file mode 100644 index 54e53c1f3e..0000000000 --- a/yabause/src/coffelf.c +++ /dev/null @@ -1,388 +0,0 @@ -/* Copyright 2007 Theo Berkau - Copyright 2009 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "core.h" -#include "debug.h" -#include "sh2core.h" -#include "yabause.h" -#include "coffelf.h" - -typedef struct -{ - u8 magic[2]; - u16 numsections; - u32 timedate; - u32 symtabptr; - u32 numsymtabs; - u16 optheader; - u16 flags; -} coff_header_struct; - -typedef struct -{ - u8 magic[2]; - u16 versionstamp; - u32 textsize; - u32 datasize; - u32 bsssize; - u32 entrypoint; - u32 textaddr; - u32 dataaddr; -} aout_header_struct; - -typedef struct -{ - s8 name[8]; - u32 physaddr; - u32 virtaddr; - u32 sectionsize; - u32 sectionptr; - u32 relptr; - u32 linenoptr; - u16 numreloc; - u16 numlineno; - u32 flags; -} section_header_struct; - -typedef struct -{ - u8 ident[16]; - u16 type; - u16 machine; - u32 version; - u32 entry; - u32 phdr; - u32 shdr; - u32 flags; - u16 hdrsize; - u16 phdrsize; - u16 phdrcount; - u16 shdrsize; - u16 shdrcount; - u16 shdrstridx; -} elf_header_struct; - -#define ELF_MACHINE_SH 42 - -typedef struct -{ - u32 name; - u32 type; - u32 flags; - u32 addr; - u32 offs; - u32 size; - u32 link; - u32 inf; - u32 align; - u32 esize; -} elf_section_header_struct; - -#define ELF_SECTION_TYPE_NODATA 8 -#define ELF_SECTION_FLAG_ALLOC 2 - -#define WordSwap(x) x = ((x & 0xFF00) >> 8) + ((x & 0x00FF) << 8); -#define DoubleWordSwap(x) x = (((x & 0xFF000000) >> 24) + \ - ((x & 0x00FF0000) >> 8) + \ - ((x & 0x0000FF00) << 8) + \ - ((x & 0x000000FF) << 24)); - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemoryLoadCoff(const char *filename) -{ - coff_header_struct coff_header; - aout_header_struct aout_header; - section_header_struct *section_headers=NULL; - FILE *fp; - u8 *buffer; - u32 i, j; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - fread((void *)&coff_header, sizeof(coff_header), 1, fp); -#ifndef WORDS_BIGENDIAN - WordSwap(coff_header.numsections); - DoubleWordSwap(coff_header.timedate); - DoubleWordSwap(coff_header.timedate); - DoubleWordSwap(coff_header.symtabptr); - DoubleWordSwap(coff_header.numsymtabs); - WordSwap(coff_header.optheader); - WordSwap(coff_header.flags); -#endif - - if (coff_header.magic[0] != 0x05 || coff_header.magic[1] != 0x00 || - coff_header.optheader != sizeof(aout_header)) - { - // Not SH COFF or is missing the optional header - fclose(fp); - return -1; - } - - fread((void *)&aout_header, sizeof(aout_header), 1, fp); -#ifndef WORDS_BIGENDIAN - WordSwap(aout_header.versionstamp); - DoubleWordSwap(aout_header.textsize); - DoubleWordSwap(aout_header.datasize); - DoubleWordSwap(aout_header.bsssize); - DoubleWordSwap(aout_header.entrypoint); - DoubleWordSwap(aout_header.textaddr); - DoubleWordSwap(aout_header.dataaddr); -#endif - - // Read in each section header - if ((section_headers = (section_header_struct *)malloc(sizeof(section_header_struct) * coff_header.numsections)) == NULL) - { - fclose(fp); - return -2; - } - - // read in section headers - for (i = 0; i < coff_header.numsections; i++) - { - fread((void *)§ion_headers[i], sizeof(section_header_struct), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(section_headers[i].physaddr); - DoubleWordSwap(section_headers[i].virtaddr); - DoubleWordSwap(section_headers[i].sectionsize); - DoubleWordSwap(section_headers[i].sectionptr); - DoubleWordSwap(section_headers[i].relptr); - DoubleWordSwap(section_headers[i].linenoptr); - WordSwap(section_headers[i].numreloc); - WordSwap(section_headers[i].numlineno); - DoubleWordSwap(section_headers[i].flags); -#endif - } - - YabauseResetNoLoad(); - - // Setup the vector table area, etc. - YabauseSpeedySetup(); - - // Read in sections, load them to ram - for (i = 0; i < coff_header.numsections; i++) - { - if (section_headers[i].sectionsize == 0 || - section_headers[i].sectionptr == 0) - // Skip to the next section - continue; - - if ((buffer = (u8 *)malloc(section_headers[i].sectionsize)) == NULL) - { - fclose(fp); - free(section_headers); - return -2; - } - - fseek(fp, section_headers[i].sectionptr, SEEK_SET); - fread((void *)buffer, 1, section_headers[i].sectionsize, fp); - - for (j = 0; j < section_headers[i].sectionsize; j++) - MappedMemoryWriteByte(section_headers[i].physaddr+j, buffer[j]); - SH2WriteNotify(section_headers[i].physaddr, - section_headers[i].sectionsize); - - free(buffer); - } - - // Clean up - free(section_headers); - fclose(fp); - - SH2GetRegisters(MSH2, &MSH2->regs); - MSH2->regs.PC = aout_header.entrypoint; - SH2SetRegisters(MSH2, &MSH2->regs); - return 0; -} - - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemoryLoadElf(const char *filename) -{ - elf_header_struct elf_hdr; - elf_section_header_struct *sections = NULL; - FILE *fp; - u16 i; - u32 j; - u8 *buffer; - - fp = fopen(filename, "rb"); - - if(fp == NULL) - return -1; - - fread(&elf_hdr, sizeof(elf_header_struct), 1, fp); - - if(elf_hdr.ident[0] != 0x7F || elf_hdr.ident[1] != 'E' || - elf_hdr.ident[2] != 'L' || elf_hdr.ident[3] != 'F' || - elf_hdr.ident[4] != 1) - { - /* Doesn't appear to be a valid ELF file. */ - fclose(fp); - return -1; - } - - if(elf_hdr.ident[5] != 2) - { - /* Doesn't appear to be a big-endian file. */ - fclose(fp); - return -1; - } - -#ifndef WORDS_BIGENDIAN - WordSwap(elf_hdr.type); - WordSwap(elf_hdr.machine); - DoubleWordSwap(elf_hdr.version); - DoubleWordSwap(elf_hdr.entry); - DoubleWordSwap(elf_hdr.phdr); - DoubleWordSwap(elf_hdr.shdr); - DoubleWordSwap(elf_hdr.flags); - WordSwap(elf_hdr.hdrsize); - WordSwap(elf_hdr.phdrsize); - WordSwap(elf_hdr.phdrcount); - WordSwap(elf_hdr.shdrsize); - WordSwap(elf_hdr.shdrcount); - WordSwap(elf_hdr.shdrstridx); -#endif - - LOG("Loading ELF file %s\n", filename); - LOG("Type: %d\n", elf_hdr.type); - LOG("Machine code: %d\n", elf_hdr.machine); - LOG("Version: %d\n", elf_hdr.version); - LOG("Entry point: 0x%08X\n", elf_hdr.entry); - LOG("Program header offset: %d\n", elf_hdr.phdr); - LOG("Section header offset: %d\n", elf_hdr.shdr); - LOG("Flags: %d\n", elf_hdr.flags); - LOG("ELF Header Size: %d\n", elf_hdr.hdrsize); - LOG("Program header size: %d\n", elf_hdr.phdrsize); - LOG("Program header count: %d\n", elf_hdr.phdrcount); - LOG("Section header size: %d\n", elf_hdr.shdrsize); - LOG("Section header count: %d\n", elf_hdr.shdrcount); - LOG("String table section: %d\n", elf_hdr.shdrstridx); - - if(elf_hdr.machine != ELF_MACHINE_SH) - { - /* Not a SuperH ELF file. */ - fclose(fp); - return -1; - } - - /* Allocate space for the section headers. */ - sections = - (elf_section_header_struct *)malloc(sizeof(elf_section_header_struct) * - elf_hdr.shdrcount); - if(sections == NULL) - { - fclose(fp); - return -2; - } - - /* Look at the actual section headers. */ - fseek(fp, elf_hdr.shdr, SEEK_SET); - - /* Read in each section header. */ - for(i = 0; i < elf_hdr.shdrcount; ++i) - { - fread(sections + i, sizeof(elf_section_header_struct), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(sections[i].name); - DoubleWordSwap(sections[i].type); - DoubleWordSwap(sections[i].flags); - DoubleWordSwap(sections[i].addr); - DoubleWordSwap(sections[i].offs); - DoubleWordSwap(sections[i].size); - DoubleWordSwap(sections[i].link); - DoubleWordSwap(sections[i].inf); - DoubleWordSwap(sections[i].align); - DoubleWordSwap(sections[i].esize); -#endif - - LOG("Section header %d:\n", i); - LOG("Name index: %d\n", sections[i].name); - LOG("Type: %d\n", sections[i].type); - LOG("Flags: 0x%X\n", sections[i].flags); - LOG("In-memory address: 0x%08X\n", sections[i].addr); - LOG("In-file offset: %d\n", sections[i].offs); - LOG("Size: %d\n", sections[i].size); - LOG("Link field: %d\n", sections[i].link); - LOG("Info field: %d\n", sections[i].inf); - LOG("Alignment: %d\n", sections[i].align); - LOG("Entry size: %d\n", sections[i].esize); - } - - YabauseResetNoLoad(); - - /* Set up the vector table area, etc. */ - YabauseSpeedySetup(); - - /* Read in the sections and load them to RAM. */ - for(i = 0; i < elf_hdr.shdrcount; ++i) - { - /* Does the header request actual storage for this section? */ - if(sections[i].flags & ELF_SECTION_FLAG_ALLOC) - { - /* Check if the section contains data, or if its just a marker for a - section of zero bytes. */ - if(sections[i].type == ELF_SECTION_TYPE_NODATA) - { - for(j = 0; j < sections[i].size; ++j) - { - MappedMemoryWriteByte(sections[i].addr + j, 0); - } - } - else - { - buffer = (u8 *)malloc(sections[i].size); - - if(buffer == NULL) - { - fclose(fp); - free(sections); - return -2; - } - - fseek(fp, sections[i].offs, SEEK_SET); - fread(buffer, 1, sections[i].size, fp); - - for(j = 0; j < sections[i].size; ++j) - { - MappedMemoryWriteByte(sections[i].addr + j, buffer[j]); - } - - free(buffer); - } - } - } - - /* Clean up. */ - free(sections); - fclose(fp); - - /* Set up our entry point. */ - SH2GetRegisters(MSH2, &MSH2->regs); - MSH2->regs.PC = elf_hdr.entry; - SH2SetRegisters(MSH2, &MSH2->regs); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/coffelf.h b/yabause/src/coffelf.h deleted file mode 100644 index 8085982ba9..0000000000 --- a/yabause/src/coffelf.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2007 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef COFFELF_H -#define COFFELF_H - -int MappedMemoryLoadCoff(const char *filename); -int MappedMemoryLoadElf(const char *filename); - -#endif - diff --git a/yabause/src/config.h.in b/yabause/src/config.h.in deleted file mode 100644 index afea5ec0a2..0000000000 --- a/yabause/src/config.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#cmakedefine HAVE_C68K 1 -#cmakedefine HAVE_Q68 1 -#cmakedefine SH2_DYNAREC 1 diff --git a/yabause/src/core.h b/yabause/src/core.h deleted file mode 100644 index 78a01b6fce..0000000000 --- a/yabause/src/core.h +++ /dev/null @@ -1,298 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CORE_H -#define CORE_H - -#include -#include - -#ifndef ALIGNED -#ifdef _MSC_VER -#define ALIGNED(x) __declspec(align(x)) -#else -#define ALIGNED(x) __attribute__((aligned(x))) -#endif -#endif - -#ifndef STDCALL -#ifdef _MSC_VER -#define STDCALL __stdcall -#else -#define STDCALL -#endif -#endif - -#ifndef FASTCALL -#ifdef __MINGW32__ -#define FASTCALL __attribute__((fastcall)) -#elif defined (__i386__) -#define FASTCALL __attribute__((regparm(3))) -#else -#define FASTCALL -#endif -#endif - -/* When building multiple arches on OS X you must use the compiler- - provided endian flags instead of the one provided by autoconf */ -#if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__) - #undef WORDS_BIGENDIAN - #ifdef __BIG_ENDIAN__ - #define WORDS_BIGENDIAN - #endif -#endif - - -#ifndef INLINE -#ifdef _MSC_VER -#define INLINE _inline -#else -#define INLINE inline -#endif -#endif - -#ifdef GEKKO -/* Wii have both stdint.h and "yabause" definitions of fixed -size types */ -#include -typedef unsigned long pointer; - -#else /* ! GEKKO */ - -#ifdef HAVE_STDINT_H - -#include -typedef uint8_t u8; -typedef int8_t s8; -typedef uint16_t u16; -typedef int16_t s16; -typedef uint32_t u32; -typedef int32_t s32; -typedef uint64_t u64; -typedef int64_t s64; -typedef uintptr_t pointer; - -#else // !HAVE_STDINT_H - -typedef unsigned char u8; -typedef unsigned short u16; - -typedef signed char s8; -typedef signed short s16; - -#if defined(__LP64__) -// Generic 64-bit -typedef unsigned int u32; -typedef unsigned long u64; -typedef unsigned long pointer; - -typedef signed int s32; -typedef signed long s64; - -#elif defined(_MSC_VER) -typedef unsigned long u32; -typedef unsigned __int64 u64; -typedef unsigned long long u64; -#ifdef _WIN64 -typedef __int64 pointer; -#else -typedef unsigned long pointer; -#endif - -typedef signed long s32; -typedef __int64 s64; -typedef signed long long s64; - -#else -// 32-bit Linux GCC/MINGW/etc. -typedef unsigned long u32; -typedef unsigned long long u64; -typedef unsigned long pointer; - -typedef signed long s32; -typedef signed long long s64; -#endif - -#endif // !HAVE_STDINT_H - -#endif // !GEKKO - -typedef struct { - unsigned int size; - unsigned int done; -} IOCheck_struct; - -static INLINE void ywrite(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) { - check->done += (unsigned int)fwrite(ptr, size, nmemb, stream); - check->size += (unsigned int)nmemb; -} - -static INLINE void yread(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) { - check->done += (unsigned int)fread(ptr, size, nmemb, stream); - check->size += (unsigned int)nmemb; -} - -static INLINE int StateWriteHeader(FILE *fp, const char *name, int version) { - IOCheck_struct check; - fprintf(fp, "%s", name); - check.done = 0; - check.size = 0; - ywrite(&check, (void *)&version, sizeof(version), 1, fp); - ywrite(&check, (void *)&version, sizeof(version), 1, fp); // place holder for size - return (check.done == check.size) ? ftell(fp) : -1; -} - -static INLINE int StateFinishHeader(FILE *fp, int offset) { - /* - IOCheck_struct check; - int size = 0; - size = ftell(fp) - offset; - fseek(fp, offset - 4, SEEK_SET); - check.done = 0; - check.size = 0; - ywrite(&check, (void *)&size, sizeof(size), 1, fp); // write true size - fseek(fp, 0, SEEK_END); - return (check.done == check.size) ? (size + 12) : -1; - */ - return 0; -} - -static INLINE int StateCheckRetrieveHeader(FILE *fp, const char *name, int *version, int *size) { - char id[4]; - size_t ret; - - if ((ret = fread((void *)id, 1, 4, fp)) != 4) - return -1; - - if (strncmp(name, id, 4) != 0) - return -2; - - if ((ret = fread((void *)version, 4, 1, fp)) != 1) - return -1; - - if (fread((void *)size, 4, 1, fp) != 1) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -// Terrible, but I'm not sure how to do the equivalent in inline -#ifdef HAVE_C99_VARIADIC_MACROS -#define AddString(s, ...) \ - { \ - sprintf(s, __VA_ARGS__); \ - s += strlen(s); \ - } -#else -#define AddString(s, r...) \ - { \ - sprintf(s, ## r); \ - s += strlen(s); \ - } -#endif - -////////////////////////////////////////////////////////////////////////////// - -#ifdef HAVE_LIBMINI18N -#include "mini18n.h" -#else -#ifndef _ -#define _(a) (a) -#endif -#endif - -////////////////////////////////////////////////////////////////////////////// - -/* Minimum/maximum values */ - -#undef MIN -#undef MAX -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -////////////////////////////////////////////////////////////////////////////// - -/* - * BSWAP16(x) swaps two bytes in a 16-bit value (AABB -> BBAA) or adjacent - * bytes in a 32-bit value (AABBCCDD -> BBAADDCC). - * - * BSWAP32(x) reverses four bytes in a 32-bit value (AABBCCDD -> DDCCBBAA). - * - * WSWAP32(x) swaps two 16-bit words in a 32-bit value (AABBCCDD -> CCDDAABB). - * - * Any of these can be left undefined if there is no platform-specific - * optimization for them; the defaults below will then be used instead. - */ - -#ifdef PSP -# define BSWAP16(x) ((typeof(x)) __builtin_allegrex_wsbh((x))) -# define BSWAP32(x) ((typeof(x)) __builtin_allegrex_wsbw((x))) -# define WSWAP32(x) ((typeof(x)) __builtin_allegrex_rotr((x), 16)) -#endif - -/* Defaults: */ - -#ifndef BSWAP16 -# define BSWAP16(x) (((u32)(x)>>8 & 0x00FF00FF) | ((u32)(x) & 0x00FF00FF) << 8) -#endif -#ifndef BSWAP32 -# define BSWAP32(x) ((u32)(x)>>24 | ((u32)(x)>>8 & 0xFF00) | ((u32)(x) & 0xFF00)<<8 | (u32)(x)<<24) -#endif -#ifndef WSWAP32 -# define WSWAP32(x) ((u32)(x)>>16 | (u32)(x)<<16) -#endif - -////////////////////////////////////////////////////////////////////////////// - -#ifdef __GNUC__ - -#define UNUSED __attribute ((unused)) - -#ifdef DEBUG -#define USED_IF_DEBUG -#else -#define USED_IF_DEBUG __attribute ((unused)) -#endif - -#ifdef SMPC_DEBUG -#define USED_IF_SMPC_DEBUG -#else -#define USED_IF_SMPC_DEBUG __attribute ((unused)) -#endif - -/* LIKELY(x) indicates that x is likely to be true (nonzero); - * UNLIKELY(x) indicates that x is likely to be false (zero). - * Use like: "if (UNLIKELY(a < b)) {...}" */ -#define LIKELY(x) (__builtin_expect(!!(x), 1)) -#define UNLIKELY(x) (__builtin_expect(!!(x), 0)) - -#else - -#define UNUSED -#define USED_IF_DEBUG -#define USED_IF_SMPC_DEBUG -#define LIKELY(x) (x) -#define UNLIKELY(x) (x) - -#endif - -#endif diff --git a/yabause/src/cs0.c b/yabause/src/cs0.c deleted file mode 100644 index d5299f4d7d..0000000000 --- a/yabause/src/cs0.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2006 Ex-Cyber - Copyright 2005 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "cs0.h" -#include "error.h" - -cartridge_struct *CartridgeArea; - -////////////////////////////////////////////////////////////////////////////// -// Dummy/No Cart Functions -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DummyCs0ReadByte(UNUSED u32 addr) -{ - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DummyCs0ReadWord(UNUSED u32 addr) -{ - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DummyCs0ReadLong(UNUSED u32 addr) -{ - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs0WriteByte(UNUSED u32 addr, UNUSED u8 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs0WriteWord(UNUSED u32 addr, UNUSED u16 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs0WriteLong(UNUSED u32 addr, UNUSED u32 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DummyCs1ReadByte(UNUSED u32 addr) -{ - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DummyCs1ReadWord(UNUSED u32 addr) -{ - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DummyCs1ReadLong(UNUSED u32 addr) -{ - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs1WriteByte(UNUSED u32 addr, UNUSED u8 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs1WriteWord(UNUSED u32 addr, UNUSED u16 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs1WriteLong(UNUSED u32 addr, UNUSED u32 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DummyCs2ReadByte(UNUSED u32 addr) -{ - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DummyCs2ReadWord(UNUSED u32 addr) -{ - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DummyCs2ReadLong(UNUSED u32 addr) -{ - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs2WriteByte(UNUSED u32 addr, UNUSED u8 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs2WriteWord(UNUSED u32 addr, UNUSED u16 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs2WriteLong(UNUSED u32 addr, UNUSED u32 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// -// Action Replay 4M Plus funcions -////////////////////////////////////////////////////////////////////////////// - -typedef enum - { - FL_READ, - FL_SDP, - FL_CMD, - FL_ID, - FL_IDSDP, - FL_IDCMD, - FL_WRITEBUF, - FL_WRITEARRAY - } flashstate; - -u8 flreg0 = 0; -u8 flreg1 = 0; - -flashstate flstate0; -flashstate flstate1; - -u8 flbuf0[128]; -u8 flbuf1[128]; - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL FlashCs0ReadByte(u32 addr) -{ - flashstate* state; - u8* reg; - - if (addr & 1) - { - state = &flstate1; - reg = &flreg1; - } - else - { - state = &flstate0; - reg = &flreg0; - } - - switch (*state) - { - case FL_ID: - case FL_IDSDP: - case FL_IDCMD: - if (addr & 2) return 0xD5; - else return 0x1F; - case FL_WRITEARRAY: *reg ^= 0x02; - case FL_WRITEBUF: return *reg; - case FL_SDP: - case FL_CMD: *state = FL_READ; - case FL_READ: - default: return T2ReadByte(CartridgeArea->rom, addr); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL FlashCs0ReadWord(u32 addr) -{ - return ((u16)(FlashCs0ReadByte(addr) << 8) | (u16)(FlashCs0ReadByte(addr+1))); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL FlashCs0ReadLong(u32 addr) -{ - return ((u32)FlashCs0ReadWord(addr) << 16) |(u32) FlashCs0ReadWord(addr + 2); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL FlashCs0WriteByte(u32 addr, u8 val) -{ - flashstate* state; - u8* reg; - u8* buf; - - if (addr & 1) - { - state = &flstate1; - reg = &flreg1; - buf = flbuf1; - } - else - { - state = &flstate0; - reg = &flreg0; - buf = flbuf0; - } - - switch (*state) - { - case FL_READ: - if (((addr & 0xfffe) == 0xaaaa) && (val == 0xaa)) - *state = FL_SDP; - return; - case FL_WRITEBUF: - buf[(addr >> 1) & 0x7f] = val; - if (((addr >> 1) & 0x7f) == 0x7f) - { - int i; - int j = addr & 0x1; - addr &= 0xffffff00; - for (i = 0; i <= 127; i++) - { - T2WriteByte(CartridgeArea->rom, (addr + i*2 + j), buf[i]); - } - *state = FL_READ; - } - return; - case FL_SDP: - if (((addr & 0xfffe) == 0x5554) && (val == 0x55)) - *state = FL_CMD; - else *state = FL_READ; - return; - case FL_ID: - if (((addr & 0xfffe) == 0xaaaa) && (val == 0xaa)) - *state = FL_IDSDP; - else *state = FL_ID; - return; - case FL_IDSDP: - if (((addr & 0xfffe) == 0x5554) && (val == 0x55)) - *state = FL_READ; - else *state=FL_ID; - return; - case FL_IDCMD: - if (((addr & 0xfffe) == 0xaaaa) && (val == 0xf0)) - *state = FL_READ; - else *state = FL_ID; - return; - case FL_CMD: - if ((addr & 0xfffe) != 0xaaaa) - { - *state = FL_READ; - return; - } - - switch (val) - { - case 0xa0: - *state = FL_WRITEBUF; - return; - case 0x90: - *state = FL_ID; - return; - default: - *state = FL_READ; - return; - } - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL FlashCs0WriteWord(u32 addr, u16 val) -{ - FlashCs0WriteByte(addr, (u8)(val >> 8)); - FlashCs0WriteByte(addr + 1, (u8)(val & 0xff)); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL FlashCs0WriteLong(u32 addr, u32 val) -{ - FlashCs0WriteWord(addr, (u16)(val >> 16)); - FlashCs0WriteWord(addr + 2, (u16)(val & 0xffff)); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL AR4MCs0ReadByte(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - return FlashCs0ReadByte(addr); -// return biosarea->getByte(addr); -// else // Outport -// fprintf(stderr, "Commlink Outport Byte read\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag read\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Byte read\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Dram area - return T1ReadByte(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL AR4MCs0ReadWord(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - return FlashCs0ReadWord(addr); -// else // Outport -// fprintf(stderr, "Commlink Outport Word read\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag read\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Word read\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadWord(CartridgeArea->dram, addr & 0x3FFFFF); - case 0x12: - case 0x1E: - if (0x80000) - return 0xFFFD; - break; - case 0x13: - case 0x16: - case 0x17: - case 0x1A: - case 0x1B: - case 0x1F: - return 0xFFFD; - default: // The rest doesn't matter - break; - } - - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL AR4MCs0ReadLong(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - return FlashCs0ReadLong(addr); -// else // Outport -// fprintf(stderr, "Commlink Outport Long read\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag read\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Long read\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadLong(CartridgeArea->dram, addr & 0x3FFFFF); - case 0x12: - case 0x1E: - if (0x80000) - return 0xFFFDFFFD; - break; - case 0x13: - case 0x16: - case 0x17: - case 0x1A: - case 0x1B: - case 0x1F: - return 0xFFFDFFFD; - default: // The rest doesn't matter - break; - } - - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL AR4MCs0WriteByte(u32 addr, u8 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - FlashCs0WriteByte(addr, val); -// else // Outport -// fprintf(stderr, "Commlink Outport byte write\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag write\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Byte write\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteByte(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL AR4MCs0WriteWord(u32 addr, u16 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - FlashCs0WriteWord(addr, val); -// else // Outport -// fprintf(stderr, "Commlink Outport Word write\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag write\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Word write\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteWord(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL AR4MCs0WriteLong(u32 addr, u32 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - FlashCs0WriteLong(addr, val); -// else // Outport -// fprintf(stderr, "Commlink Outport Long write\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag write\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Long write\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteLong(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// 8 Mbit Dram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DRAM8MBITCs0ReadByte(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - return T1ReadByte(CartridgeArea->dram, addr & 0x7FFFF); - case 0x06: // Dram area - return T1ReadByte(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF)); - default: // The rest doesn't matter - break; - } - - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DRAM8MBITCs0ReadWord(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - return T1ReadWord(CartridgeArea->dram, addr & 0x7FFFF); - case 0x06: // Dram area - return T1ReadWord(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF)); - default: // The rest doesn't matter - break; - } - - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DRAM8MBITCs0ReadLong(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - return T1ReadLong(CartridgeArea->dram, addr & 0x7FFFF); - case 0x06: // Dram area - return T1ReadLong(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF)); - default: // The rest doesn't matter - break; - } - - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM8MBITCs0WriteByte(u32 addr, u8 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - T1WriteByte(CartridgeArea->dram, addr & 0x7FFFF, val); - break; - case 0x06: // Dram area - T1WriteByte(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF), val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM8MBITCs0WriteWord(u32 addr, u16 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - T1WriteWord(CartridgeArea->dram, addr & 0x7FFFF, val); - break; - case 0x06: // Dram area - T1WriteWord(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF), val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM8MBITCs0WriteLong(u32 addr, u32 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - T1WriteLong(CartridgeArea->dram, addr & 0x7FFFF, val); - break; - case 0x06: // Dram area - T1WriteLong(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF), val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// 32 Mbit Dram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DRAM32MBITCs0ReadByte(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Dram area - return T1ReadByte(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DRAM32MBITCs0ReadWord(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadWord(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DRAM32MBITCs0ReadLong(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadLong(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM32MBITCs0WriteByte(u32 addr, u8 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteByte(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM32MBITCs0WriteWord(u32 addr, u16 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteWord(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM32MBITCs0WriteLong(u32 addr, u32 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteLong(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// 4 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP4MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP4MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP4MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP4MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP4MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP4MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 8 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP8MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP8MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP8MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP8MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP8MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP8MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 16 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP16MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0x3FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP16MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0x3FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP16MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0x3FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP16MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0x3FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP16MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0x3FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP16MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0x3FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 32 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP32MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0x7FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP32MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0x7FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP32MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0x7FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP32MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0x7FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP32MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0x7FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP32MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0x7FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 16 Mbit Rom -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL ROM16MBITCs0ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->rom, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL ROM16MBITCs0ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->rom, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL ROM16MBITCs0ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->rom, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL ROM16MBITCs0WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->rom, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL ROM16MBITCs0WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->rom, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL ROM16MBITCs0WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->rom, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// Sega Saturn Modem(Japanese) -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL JapModemCs0ReadByte(u32 addr) -{ - if (addr & 0x1) - return 0xA5; - else - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL JapModemCs0ReadWord(UNUSED u32 addr) -{ - return 0xFFA5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL JapModemCs0ReadLong(UNUSED u32 addr) -{ - return 0xFFA5FFA5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL JapModemCs1ReadByte(UNUSED u32 addr) -{ - return 0xA5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL JapModemCs1ReadWord(UNUSED u32 addr) -{ - return 0xA5A5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL JapModemCs1ReadLong(UNUSED u32 addr) -{ - return 0xA5A5A5A5; -} - -////////////////////////////////////////////////////////////////////////////// -// General Cart functions -////////////////////////////////////////////////////////////////////////////// - -int CartInit(const char * filename, int type) -{ - if ((CartridgeArea = (cartridge_struct *)calloc(1, sizeof(cartridge_struct))) == NULL) - return -1; - - CartridgeArea->carttype = type; - CartridgeArea->filename = filename; - - switch(type) - { - case CART_PAR: // Action Replay 4M Plus(or equivalent) - { - if ((CartridgeArea->rom = T2MemoryInit(0x40000)) == NULL) - return -1; - - if ((CartridgeArea->dram = T1MemoryInit(0x400000)) == NULL) - return -1; - - // Use 32 Mbit Dram id - CartridgeArea->cartid = 0x5C; - - // Load AR firmware to memory - if (T123Load(CartridgeArea->rom, 0x40000, 2, filename) != 0) - return -1; - flstate0 = FL_READ; - flstate1 = FL_READ; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &AR4MCs0ReadByte; - CartridgeArea->Cs0ReadWord = &AR4MCs0ReadWord; - CartridgeArea->Cs0ReadLong = &AR4MCs0ReadLong; - CartridgeArea->Cs0WriteByte = &AR4MCs0WriteByte; - CartridgeArea->Cs0WriteWord = &AR4MCs0WriteWord; - CartridgeArea->Cs0WriteLong = &AR4MCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_BACKUPRAM4MBIT: // 4 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x100000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x21; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x100000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x100000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP4MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP4MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP4MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP4MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP4MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP4MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - - break; - } - case CART_BACKUPRAM8MBIT: // 8 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x200000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x22; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x200000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x200000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP8MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP8MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP8MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP8MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP8MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP8MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - - break; - } - case CART_BACKUPRAM16MBIT: // 16 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x400000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x23; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x400000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x400000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP16MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP16MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP16MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP16MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP16MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP16MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_BACKUPRAM32MBIT: // 32 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x800000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x24; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x800000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x800000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP32MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP32MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP32MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP32MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP32MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP32MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_DRAM8MBIT: // 8 Mbit Dram Cart - { - if ((CartridgeArea->dram = T1MemoryInit(0x100000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x5A; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DRAM8MBITCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DRAM8MBITCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DRAM8MBITCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DRAM8MBITCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DRAM8MBITCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DRAM8MBITCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_DRAM32MBIT: // 32 Mbit Dram Cart - { - if ((CartridgeArea->dram = T1MemoryInit(0x400000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x5C; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DRAM32MBITCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DRAM32MBITCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DRAM32MBITCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DRAM32MBITCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DRAM32MBITCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DRAM32MBITCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_ROM16MBIT: // 16 Mbit Rom Cart - { - if ((CartridgeArea->rom = T1MemoryInit(0x200000)) == NULL) - return -1; - - CartridgeArea->cartid = 0xFF; // I have no idea what the real id is - - // Load Rom to memory - if (T123Load(CartridgeArea->rom, 0x200000, 1, filename) != 0) - return -1; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &ROM16MBITCs0ReadByte; - CartridgeArea->Cs0ReadWord = &ROM16MBITCs0ReadWord; - CartridgeArea->Cs0ReadLong = &ROM16MBITCs0ReadLong; - CartridgeArea->Cs0WriteByte = &ROM16MBITCs0WriteByte; - CartridgeArea->Cs0WriteWord = &ROM16MBITCs0WriteWord; - CartridgeArea->Cs0WriteLong = &ROM16MBITCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_JAPMODEM: // Sega Saturn Modem(Japanese) - { - CartridgeArea->cartid = 0xFF; - - CartridgeArea->Cs0ReadByte = &JapModemCs0ReadByte; - CartridgeArea->Cs0ReadWord = &JapModemCs0ReadWord; - CartridgeArea->Cs0ReadLong = &JapModemCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &JapModemCs1ReadByte; - CartridgeArea->Cs1ReadWord = &JapModemCs1ReadWord; - CartridgeArea->Cs1ReadLong = &JapModemCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - default: // No Cart - { - CartridgeArea->cartid = 0xFF; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void CartDeInit(void) -{ - if (CartridgeArea) - { - if (CartridgeArea->carttype == CART_PAR) - { - if (CartridgeArea->rom) - { - if (T123Save(CartridgeArea->rom, 0x40000, 2, CartridgeArea->filename) != 0) - YabSetError(YAB_ERR_FILEWRITE, (void *)CartridgeArea->filename); - T2MemoryDeInit(CartridgeArea->rom); - } - } - else - { - if (CartridgeArea->rom) - T1MemoryDeInit(CartridgeArea->rom); - } - - if (CartridgeArea->bupram) - { - u32 size=0; - - switch (CartridgeArea->carttype) - { - case CART_BACKUPRAM4MBIT: // 4 Mbit Backup Ram - { - size = 0x100000; - break; - } - case CART_BACKUPRAM8MBIT: // 8 Mbit Backup Ram - { - size = 0x200000; - break; - } - case CART_BACKUPRAM16MBIT: // 16 Mbit Backup Ram - { - size = 0x400000; - break; - } - case CART_BACKUPRAM32MBIT: // 32 Mbit Backup Ram - { - size = 0x800000; - break; - } - } - - if (size != 0) - { - if (T123Save(CartridgeArea->bupram, size, 1, CartridgeArea->filename) != 0) - YabSetError(YAB_ERR_FILEWRITE, (void *)CartridgeArea->filename); - - T1MemoryDeInit(CartridgeArea->bupram); - } - } - - if (CartridgeArea->dram) - T1MemoryDeInit(CartridgeArea->dram); - - free(CartridgeArea); - } - CartridgeArea = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -int CartSaveState(FILE * fp) -{ - int offset; - - offset = StateWriteHeader(fp, "CART", 1); - - // Write cart type - fwrite((void *)&CartridgeArea->carttype, 4, 1, fp); - - // Write the areas associated with the cart type here - switch (CartridgeArea->carttype) - { - case CART_DRAM8MBIT: - fwrite(CartridgeArea->dram, 1, 0x100000, fp); - break; - case CART_DRAM32MBIT: - fwrite(CartridgeArea->dram, 1, 0x400000, fp); - break; - } - - return StateFinishHeader(fp, offset); -} - -////////////////////////////////////////////////////////////////////////////// - -int CartLoadState(FILE * fp, UNUSED int version, int size) -{ - int newtype; - - // Read cart type - fread((void *)&newtype, 4, 1, fp); - - // Check to see if old cart type and new cart type match, if they don't, - // reallocate memory areas - if (CartridgeArea->carttype != newtype) - { - // ... - } - switch (CartridgeArea->carttype) - { - case CART_DRAM8MBIT: - fread(CartridgeArea->dram, 1, 0x100000, fp); - break; - case CART_DRAM32MBIT: - fread(CartridgeArea->dram, 1, 0x400000, fp); - break; - } - - // Read the areas associated with the cart type here - - return size; -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/cs0.h b/yabause/src/cs0.h deleted file mode 100644 index c61edd3774..0000000000 --- a/yabause/src/cs0.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2005 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CS0_H -#define CS0_H - -#include "memory.h" - -#define CART_NONE 0 -#define CART_PAR 1 -#define CART_BACKUPRAM4MBIT 2 -#define CART_BACKUPRAM8MBIT 3 -#define CART_BACKUPRAM16MBIT 4 -#define CART_BACKUPRAM32MBIT 5 -#define CART_DRAM8MBIT 6 -#define CART_DRAM32MBIT 7 -#define CART_NETLINK 8 -#define CART_ROM16MBIT 9 -#define CART_JAPMODEM 10 - -typedef struct -{ - int carttype; - int cartid; - const char *filename; - - u8 FASTCALL (*Cs0ReadByte)(u32 addr); - u16 FASTCALL (*Cs0ReadWord)(u32 addr); - u32 FASTCALL (*Cs0ReadLong)(u32 addr); - void FASTCALL (*Cs0WriteByte)(u32 addr, u8 val); - void FASTCALL (*Cs0WriteWord)(u32 addr, u16 val); - void FASTCALL (*Cs0WriteLong)(u32 addr, u32 val); - - u8 FASTCALL (*Cs1ReadByte)(u32 addr); - u16 FASTCALL (*Cs1ReadWord)(u32 addr); - u32 FASTCALL (*Cs1ReadLong)(u32 addr); - void FASTCALL (*Cs1WriteByte)(u32 addr, u8 val); - void FASTCALL (*Cs1WriteWord)(u32 addr, u16 val); - void FASTCALL (*Cs1WriteLong)(u32 addr, u32 val); - - u8 FASTCALL (*Cs2ReadByte)(u32 addr); - u16 FASTCALL (*Cs2ReadWord)(u32 addr); - u32 FASTCALL (*Cs2ReadLong)(u32 addr); - void FASTCALL (*Cs2WriteByte)(u32 addr, u8 val); - void FASTCALL (*Cs2WriteWord)(u32 addr, u16 val); - void FASTCALL (*Cs2WriteLong)(u32 addr, u32 val); - - void *rom; - void *bupram; - void *dram; -} cartridge_struct; - -extern cartridge_struct *CartridgeArea; - -int CartInit(const char *filename, int); -void CartDeInit(void); - -int CartSaveState(FILE *fp); -int CartLoadState(FILE *fp, int version, int size); - -#endif diff --git a/yabause/src/cs1.c b/yabause/src/cs1.c deleted file mode 100644 index 6461d269da..0000000000 --- a/yabause/src/cs1.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright 2003-2005 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "cs1.h" -#include "cs0.h" - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL Cs1ReadByte(u32 addr) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFF) - return CartridgeArea->cartid; - - return CartridgeArea->Cs1ReadByte(addr); -} - -////////////////////////////////////////////////////////////////////////////// - -u16 FASTCALL Cs1ReadWord(u32 addr) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFE) - return (0xFF00 | CartridgeArea->cartid); - - return CartridgeArea->Cs1ReadWord(addr); -} - -////////////////////////////////////////////////////////////////////////////// - -u32 FASTCALL Cs1ReadLong(u32 addr) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFC) - return (0xFF00FF00 | (CartridgeArea->cartid << 16) | CartridgeArea->cartid); - - return CartridgeArea->Cs1ReadLong(addr); -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs1WriteByte(u32 addr, u8 val) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFF) - return; - - CartridgeArea->Cs1WriteByte(addr, val); -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs1WriteWord(u32 addr, u16 val) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFE) - return; - - CartridgeArea->Cs1WriteWord(addr, val); -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs1WriteLong(u32 addr, u32 val) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFC) - return; - - CartridgeArea->Cs1WriteLong(addr, val); -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/cs1.h b/yabause/src/cs1.h deleted file mode 100644 index 2ebdee2e20..0000000000 --- a/yabause/src/cs1.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2003-2005 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CS1_H -#define CS1_H - -#include "cs0.h" -#include "memory.h" - -u8 FASTCALL Cs1ReadByte(u32); -u16 FASTCALL Cs1ReadWord(u32); -u32 FASTCALL Cs1ReadLong(u32); -void FASTCALL Cs1WriteByte(u32, u8); -void FASTCALL Cs1WriteWord(u32, u16); -void FASTCALL Cs1WriteLong(u32, u32); - -#endif diff --git a/yabause/src/cs2.c b/yabause/src/cs2.c deleted file mode 100644 index 92484ac6de..0000000000 --- a/yabause/src/cs2.c +++ /dev/null @@ -1,3720 +0,0 @@ -/* Copyright 2003 Guillaume Duhamel - Copyright 2004-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include "cs2.h" -#include "debug.h" -#include "error.h" -#include "netlink.h" -#include "scsp.h" -#include "scu.h" -#include "smpc.h" -#include "yui.h" - -#define CDB_HIRQ_CMOK 0x0001 -#define CDB_HIRQ_DRDY 0x0002 -#define CDB_HIRQ_CSCT 0x0004 -#define CDB_HIRQ_BFUL 0x0008 -#define CDB_HIRQ_PEND 0x0010 -#define CDB_HIRQ_DCHG 0x0020 -#define CDB_HIRQ_ESEL 0x0040 -#define CDB_HIRQ_EHST 0x0080 -#define CDB_HIRQ_ECPY 0x0100 -#define CDB_HIRQ_EFLS 0x0200 -#define CDB_HIRQ_SCDQ 0x0400 -#define CDB_HIRQ_MPED 0x0800 -#define CDB_HIRQ_MPCM 0x1000 -#define CDB_HIRQ_MPST 0x2000 - -#define CDB_STAT_BUSY 0x00 -#define CDB_STAT_PAUSE 0x01 -#define CDB_STAT_STANDBY 0x02 -#define CDB_STAT_PLAY 0x03 -#define CDB_STAT_SEEK 0x04 -#define CDB_STAT_SCAN 0x05 -#define CDB_STAT_OPEN 0x06 -#define CDB_STAT_NODISC 0x07 -#define CDB_STAT_RETRY 0x08 -#define CDB_STAT_ERROR 0x09 -#define CDB_STAT_FATAL 0x0A -#define CDB_STAT_PERI 0x20 -#define CDB_STAT_TRNS 0x40 -#define CDB_STAT_WAIT 0x80 -#define CDB_STAT_REJECT 0xFF - -#define CDB_PLAYTYPE_SECTOR 0x01 -#define CDB_PLAYTYPE_FILE 0x02 - -Cs2 * Cs2Area = NULL; -ip_struct *cdip = NULL; - -extern CDInterface *CDCoreList[]; - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void doCDReport(u8 status) -{ - Cs2Area->reg.CR1 = (status << 8) | ((Cs2Area->options & 0xF) << 4) | (Cs2Area->repcnt & 0xF); - Cs2Area->reg.CR2 = (Cs2Area->ctrladdr << 8) | Cs2Area->track; - Cs2Area->reg.CR3 = (u16)((Cs2Area->index << 8) | ((Cs2Area->FAD >> 16) & 0xFF)); - Cs2Area->reg.CR4 = (u16) Cs2Area->FAD; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void doMPEGReport(u8 status) -{ - Cs2Area->reg.CR1 = (status << 8) | Cs2Area->actionstatus; - Cs2Area->reg.CR2 = Cs2Area->vcounter; - Cs2Area->reg.CR3 = (Cs2Area->pictureinfo << 8) | Cs2Area->mpegaudiostatus; - Cs2Area->reg.CR4 = Cs2Area->mpegvideostatus; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL Cs2ReadByte(u32 addr) -{ - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - if(Cs2Area->carttype == CART_NETLINK) - return NetlinkReadByte(addr); - else - { - // only netlink seems to use byte-access - switch (addr) - { - case 0x95001: - case 0x95005: - case 0x95009: - case 0x9500D: - case 0x95011: - case 0x95015: - case 0x95019: - case 0x9501D: - return 0xFF; - default: - break; - } - } - - LOG("Unimplemented cs2 byte read: %08X\n", addr); - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs2WriteByte(u32 addr, u8 val) -{ - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - if(Cs2Area->carttype == CART_NETLINK) - { - NetlinkWriteByte(addr, val); - return; - } - else - { - // only netlink seems to use byte-access - switch (addr) - { - case 0x2503D: - case 0x95011: - case 0x9501D: - return; - default: - break; - } - } - - LOG("Unimplemented cs2 byte write: %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -u16 FASTCALL Cs2ReadWord(u32 addr) { - u16 val = 0; - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - switch(addr) { - case 0x90008: - case 0x9000A: - val = Cs2Area->reg.HIRQ; - - if (Cs2Area->isbufferfull) - val |= CDB_HIRQ_BFUL; - else - val &= ~CDB_HIRQ_BFUL; - - if (Cs2Area->isdiskchanged) - val |= CDB_HIRQ_DCHG; - else - val &= ~CDB_HIRQ_DCHG; - - if (Cs2Area->isonesectorstored) - val |= CDB_HIRQ_CSCT; - else - val &= ~CDB_HIRQ_CSCT; - - Cs2Area->reg.HIRQ = val; - -// CDLOG("cs2\t: Hirq read, Hirq mask = %x - ret: %x\n", Memory::getWord(0x9000C), val); - return val; - case 0x9000C: - case 0x9000E: return Cs2Area->reg.HIRQMASK; - case 0x90018: - case 0x9001A: return Cs2Area->reg.CR1; - case 0x9001C: - case 0x9001E: return Cs2Area->reg.CR2; - case 0x90020: - case 0x90022: return Cs2Area->reg.CR3; - case 0x90024: - case 0x90026: Cs2Area->_command = 0; - return Cs2Area->reg.CR4; - case 0x90028: - case 0x9002A: return Cs2Area->reg.MPEGRGB; - case 0x98000: - // transfer info - switch (Cs2Area->infotranstype) { - case 0: - // Get Toc Data - if (Cs2Area->transfercount % 4 == 0) - val = (u16)((Cs2Area->TOC[Cs2Area->transfercount >> 2] & 0xFFFF0000) >> 16); - else - val = (u16)Cs2Area->TOC[Cs2Area->transfercount >> 2]; - - Cs2Area->transfercount += 2; - Cs2Area->cdwnum += 2; - - if (Cs2Area->transfercount > (0xCC * 2)) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = -1; - } - break; - case 1: - // Get File Info(1 file info) - val = (Cs2Area->transfileinfo[Cs2Area->transfercount] << 8) | - Cs2Area->transfileinfo[Cs2Area->transfercount + 1]; - Cs2Area->transfercount += 2; - Cs2Area->cdwnum += 2; - - if (Cs2Area->transfercount > (0x6 * 2)) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = -1; - } - - break; - case 2: - // Get File Info(254 file info) - - // Do we need to retrieve the next file info? - if (Cs2Area->transfercount % (0x6 * 2) == 0) { - // yes we do - Cs2SetupFileInfoTransfer(2 + (Cs2Area->transfercount / (0x6 * 2))); - } - - val = (Cs2Area->transfileinfo[Cs2Area->transfercount % (0x6 * 2)] << 8) | - Cs2Area->transfileinfo[Cs2Area->transfercount % (0x6 * 2) + 1]; - - Cs2Area->transfercount += 2; - Cs2Area->cdwnum += 2; - - if (Cs2Area->transfercount > (254 * (0x6 * 2))) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = -1; - } - - break; - default: break; - } - break; - default: - LOG("cs2\t: Undocumented register read %08X\n", addr); -// val = T3ReadWord(Cs2Area->mem, addr); - break; - } - - return val; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs2WriteWord(u32 addr, u16 val) { - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - switch(addr) { - case 0x90008: - case 0x9000A: - Cs2Area->reg.HIRQ &= val; - return; - case 0x9000C: - case 0x9000E: Cs2Area->reg.HIRQMASK = val; - return; - case 0x90018: - case 0x9001A: Cs2Area->status &= ~CDB_STAT_PERI; - Cs2Area->_command = 1; - Cs2Area->reg.CR1 = val; - return; - case 0x9001C: - case 0x9001E: Cs2Area->reg.CR2 = val; - return; - case 0x90020: - case 0x90022: Cs2Area->reg.CR3 = val; - return; - case 0x90024: - case 0x90026: Cs2Area->reg.CR4 = val; - Cs2SetCommandTiming(Cs2Area->reg.CR1 >> 8); - return; - case 0x90028: - case 0x9002A: Cs2Area->reg.MPEGRGB = val; - return; - default: - LOG("cs2\t:Undocumented register write %08X\n", addr); -// T3WriteWord(Cs2Area->mem, addr, val); - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -u32 FASTCALL Cs2ReadLong(u32 addr) { - s32 i; - u32 val = 0; - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - switch(addr) { - case 0x90008: - val = Cs2Area->reg.HIRQ; - - if (Cs2Area->isbufferfull) - val |= CDB_HIRQ_BFUL; - else - val &= ~CDB_HIRQ_BFUL; - - if (Cs2Area->isdiskchanged) - val |= CDB_HIRQ_DCHG; - else - val &= ~CDB_HIRQ_DCHG; - - if (Cs2Area->isonesectorstored) - val |= CDB_HIRQ_CSCT; - else - val &= ~CDB_HIRQ_CSCT; - - Cs2Area->reg.HIRQ = (u16)val; - - val |= (val << 16); - return val; - case 0x9000C: return ((Cs2Area->reg.HIRQMASK << 16) | Cs2Area->reg.HIRQMASK); - case 0x90018: return ((Cs2Area->reg.CR1 << 16) | Cs2Area->reg.CR1); - case 0x9001C: return ((Cs2Area->reg.CR2 << 16) | Cs2Area->reg.CR2); - case 0x90020: return ((Cs2Area->reg.CR3 << 16) | Cs2Area->reg.CR3); - case 0x90024: Cs2Area->_command = 0; - return ((Cs2Area->reg.CR4 << 16) | Cs2Area->reg.CR4); - case 0x90028: return ((Cs2Area->reg.MPEGRGB << 16) | Cs2Area->reg.MPEGRGB); - case 0x18000: - // transfer data - if (Cs2Area->datatranstype != -1) - { - // get sector - - // Make sure we still have sectors to transfer - if (Cs2Area->datanumsecttrans < Cs2Area->datasectstotrans) - { - // Transfer Data - const u8 *ptr = &Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->data[Cs2Area->datatransoffset]; -#ifdef WORDS_BIGENDIAN - val = *((const u32 *) ptr); -#else - val = BSWAP32(*((const u32 *) ptr)); -#endif - - // increment datatransoffset/cdwnum - Cs2Area->cdwnum += 4; - Cs2Area->datatransoffset += 4; - - // Make sure we're not beyond the sector size boundry - if (Cs2Area->datatransoffset >= Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->size) - { - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans++; - } - } - else - { - if (Cs2Area->datatranstype == 2) - { - // Ok, so we don't have any more sectors to - // transfer, might as well delete them all. - - Cs2Area->datatranstype = -1; - - // free blocks - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos+Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - // sort remaining blocks - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - CDLOG("cs2\t: datatranspartition->size = %x\n", Cs2Area->datatranspartition->size); - } - } - } - break; - default: - LOG("cs2\t: Undocumented register read %08X\n", addr); -// val = T3ReadLong(Cs2Area->mem, addr); - break; - } - - return val; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs2WriteLong(UNUSED u32 addr, UNUSED u32 val) { - LOG("cs2\t: Long writing isn't implemented\n"); -// T3WriteLong(Cs2Area->mem, addr, val); -} - -////////////////////////////////////////////////////////////////////////////// - -/* Copy "count" 32-bit words from the CD buffer to type-1 memory "dest" (a - * native pointer), as though 0x25818000 had been read that many times */ - -void FASTCALL Cs2RapidCopyT1(void *dest, u32 count) -{ - u8 *dest8 = (u8 *) dest; - - if (Cs2Area->datatranstype != -1) - { - // Copy as many sectors as we have left, one sector at a time - - while (count > 0 && Cs2Area->datanumsecttrans < Cs2Area->datasectstotrans) - { - const u8 *src = &Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->data[Cs2Area->datatransoffset]; - const u32 size = Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->size; - const u32 max = size - Cs2Area->datatransoffset; - const u32 copy = (max < count*4) ? max : count*4; - memcpy(dest8, src, copy); - dest8 += copy; - count -= copy/4; - Cs2Area->datatransoffset += copy; - Cs2Area->cdwnum += copy; - - // Update the sector index if we reached the end of the sector - if (Cs2Area->datatransoffset >= size) - { - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans++; - } - } - - // If we're in delete mode and we read through everything in memory, - // delete the sectors - if (Cs2Area->datatranstype == 2 - && Cs2Area->datanumsecttrans >= Cs2Area->datasectstotrans) - { - u32 i; - - Cs2Area->datatranstype = -1; - - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos+Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - CDLOG("cs2\t: datatranspartition->size = %x\n", Cs2Area->datatranspartition->size); - } - } - - if (count > 0) - { - // We tried to copy more data than was stored, so fill the rest of - // the buffer with dummy data - memset(dest8, 0xCD, count*4); - } -} - -////////////////////////////////////////////////////////////////////////////// - -/* Copy "count" 32-bit words from the CD buffer to type-2 memory "dest" (a - * native pointer), as though 0x25818000 had been read that many times */ - -void FASTCALL Cs2RapidCopyT2(void *dest, u32 count) -{ - u32 *dest32 = (u32 *) dest; - - if (Cs2Area->datatranstype != -1) - { - // Copy as many sectors as we have left, one sector at a time; copy - // four words at a time where possible to improve data parallelism - - while (count > 0 && Cs2Area->datanumsecttrans < Cs2Area->datasectstotrans) - { - const u8 *src = &Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->data[Cs2Area->datatransoffset]; - const u32 size = Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->size; - const u32 max = size - Cs2Area->datatransoffset; - const u32 copy = (max < count*4) ? max : count*4; - u32 i = 0; - if (copy >= 16) { - for (; i < copy-12; i += 16, src += 16, dest32 += 4) - { - u32 word0, word1, word2, word3; -#ifdef WORDS_BIGENDIAN - word0 = ((u32 *)src)[0]; - word1 = ((u32 *)src)[1]; - word2 = ((u32 *)src)[2]; - word3 = ((u32 *)src)[3]; -#else - word0 = BSWAP16(((u32 *)src)[0]); - word1 = BSWAP16(((u32 *)src)[1]); - word2 = BSWAP16(((u32 *)src)[2]); - word3 = BSWAP16(((u32 *)src)[3]); -#endif - dest32[0] = word0; - dest32[1] = word1; - dest32[2] = word2; - dest32[3] = word3; - } - } - for (; i < copy; i += 4, src += 4, dest32++) - { -#ifdef WORDS_BIGENDIAN - *dest32 = *(u32 *)src; -#else - *dest32 = BSWAP16(*(u32 *)src); -#endif - } - count -= copy/4; - Cs2Area->datatransoffset += copy; - Cs2Area->cdwnum += copy; - - if (Cs2Area->datatransoffset >= size) - { - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans++; - } - } - - if (Cs2Area->datatranstype == 2 - && Cs2Area->datanumsecttrans >= Cs2Area->datasectstotrans) - { - u32 i; - - Cs2Area->datatranstype = -1; - - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos+Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - CDLOG("cs2\t: datatranspartition->size = %x\n", Cs2Area->datatranspartition->size); - } - } - - if (count > 0) - { - memset(dest32, 0xCD, count*4); - } -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2Init(int carttype, int coreid, const char *cdpath, const char *mpegpath, const char *netlinksetting) { - int ret; - - if ((Cs2Area = (Cs2 *) malloc(sizeof(Cs2))) == NULL) - return -1; - memset(Cs2Area, 0, sizeof(*Cs2Area)); - - Cs2Area->carttype = carttype; - Cs2Area->mpegpath = mpegpath; - Cs2Area->cdi=NULL; - - if ((ret = Cs2ChangeCDCore(coreid, cdpath)) != 0) - return ret; - - Cs2Reset(); - - // If Modem is connected, set the registers - if(Cs2Area->carttype == CART_NETLINK) - { - if ((ret = NetlinkInit(netlinksetting)) != 0) - return ret; - } - - if ((cdip = (ip_struct *) calloc(sizeof(ip_struct), 1)) == NULL) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2ChangeCDCore(int coreid, const char *cdpath) -{ - int i; - - // Make sure the old core is freed - if (Cs2Area->cdi != NULL) - Cs2Area->cdi->DeInit(); - - // So which core do we want? - if (coreid == CDCORE_DEFAULT) - coreid = 0; // Assume we want the first one - - // Go through core list and find the id - for (i = 0; CDCoreList[i] != NULL; i++) - { - if (CDCoreList[i]->id == coreid) - { - // Set to current core - Cs2Area->cdi = CDCoreList[i]; - break; - } - } - - if (Cs2Area->cdi == NULL) - { - Cs2Area->cdi = &DummyCD; - return -1; - } - - if (Cs2Area->cdi->Init(cdpath) != 0) - { - // This might be helpful. - YabSetError(YAB_ERR_CANNOTINIT, (void *)Cs2Area->cdi->Name); - - // Since it failed, instead of it being fatal, we'll just use the dummy - // core instead - Cs2Area->cdi = &DummyCD; - } - - Cs2Area->isdiskchanged = 1; - Cs2Area->status = CDB_STAT_PAUSE; - SmpcRecheckRegion(); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2DeInit(void) { - if(Cs2Area != NULL) { - if (Cs2Area->cdi != NULL) { - Cs2Area->cdi->DeInit(); - } - - if(Cs2Area->carttype == CART_NETLINK) - NetlinkDeInit(); - - free(Cs2Area); - } - Cs2Area = NULL; - - if (cdip) - free(cdip); - cdip = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Reset(void) { - u32 i, i2; - - switch (Cs2Area->cdi->GetStatus()) - { - case 0: - case 1: - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->FAD = 150; - Cs2Area->options = 0; - Cs2Area->repcnt = 0; - Cs2Area->ctrladdr = 0x41; - Cs2Area->track = 1; - Cs2Area->index = 1; - break; - case 2: - Cs2Area->status = CDB_STAT_NODISC; - - Cs2Area->FAD = 0xFFFFFFFF; - Cs2Area->options = 0xFF; - Cs2Area->repcnt = 0xFF; - Cs2Area->ctrladdr = 0xFF; - Cs2Area->track = 0xFF; - Cs2Area->index = 0xFF; - break; - case 3: - Cs2Area->status = CDB_STAT_OPEN; - - Cs2Area->FAD = 0xFFFFFFFF; - Cs2Area->options = 0xFF; - Cs2Area->repcnt = 0xFF; - Cs2Area->ctrladdr = 0xFF; - Cs2Area->track = 0xFF; - Cs2Area->index = 0xFF; - break; - default: break; - } - - Cs2Area->infotranstype = -1; - Cs2Area->datatranstype = -1; - Cs2Area->transfercount = 0; - Cs2Area->cdwnum = 0; - Cs2Area->getsectsize = Cs2Area->putsectsize = 2048; - Cs2Area->isdiskchanged = 1; - Cs2Area->isbufferfull = 0; - Cs2Area->isonesectorstored = 0; - Cs2Area->isaudio = 0; - - Cs2Area->reg.CR1 = ( 0 <<8) | 'C'; - Cs2Area->reg.CR2 = ('D'<<8) | 'B'; - Cs2Area->reg.CR3 = ('L'<<8) | 'O'; - Cs2Area->reg.CR4 = ('C'<<8) | 'K'; - Cs2Area->reg.HIRQ = 0xFFFF; - Cs2Area->reg.HIRQMASK = 0xFFFF; - - Cs2Area->playFAD = 0xFFFFFFFF; - Cs2Area->playendFAD = 0xFFFFFFFF; - Cs2Area->playtype = 0; - Cs2Area->maxrepeat = 0; - - // set authentication variables to 0(not authenticated) - Cs2Area->satauth = 0; - Cs2Area->mpgauth = 0; - - // clear filter conditions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->filter[i].FAD = 0; - Cs2Area->filter[i].range = 0xFFFFFFFF; - Cs2Area->filter[i].mode = 0; - Cs2Area->filter[i].chan = 0; - Cs2Area->filter[i].smmask = 0; - Cs2Area->filter[i].cimask = 0; - Cs2Area->filter[i].fid = 0; - Cs2Area->filter[i].smval = 0; - Cs2Area->filter[i].cival = 0; - Cs2Area->filter[i].condtrue = 0; - Cs2Area->filter[i].condfalse = 0xFF; - } - - // clear partitions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->partition[i].size = -1; - Cs2Area->partition[i].numblocks = 0; - - for (i2 = 0; i2 < MAX_BLOCKS; i2++) - { - Cs2Area->partition[i].block[i2] = NULL; - Cs2Area->partition[i].blocknum[i2] = 0xFF; - } - } - - // clear blocks - for (i = 0; i < MAX_BLOCKS; i++) - { - Cs2Area->block[i].size = -1; - memset(Cs2Area->block[i].data, 0, 2352); - } - - Cs2Area->blockfreespace = 200; - - // initialize TOC - memset(Cs2Area->TOC, 0xFF, sizeof(Cs2Area->TOC)); - - // clear filesystem stuff - Cs2Area->curdirsect = 0; - Cs2Area->curdirsize = 0; - Cs2Area->curdirfidoffset = 0; - memset(&Cs2Area->fileinfo, 0, sizeof(Cs2Area->fileinfo)); - Cs2Area->numfiles = 0; - - Cs2Area->lastbuffer = 0xFF; - - Cs2Area->_command = 0; - Cs2Area->_periodiccycles = 0; - Cs2Area->_commandtiming = 0; - Cs2SetTiming(0); - - // MPEG specific stuff - Cs2Area->mpegcon[0].audcon = Cs2Area->mpegcon[0].vidcon = 0x00; - Cs2Area->mpegcon[0].audlay = Cs2Area->mpegcon[0].vidlay = 0x00; - Cs2Area->mpegcon[0].audbufdivnum = Cs2Area->mpegcon[0].vidbufdivnum = 0xFF; - Cs2Area->mpegcon[1].audcon = Cs2Area->mpegcon[1].vidcon = 0x00; - Cs2Area->mpegcon[1].audlay = Cs2Area->mpegcon[1].vidlay = 0x00; - Cs2Area->mpegcon[1].audbufdivnum = Cs2Area->mpegcon[1].vidbufdivnum = 0xFF; - - // should verify the following - Cs2Area->mpegstm[0].audstm = Cs2Area->mpegstm[0].vidstm = 0x00; - Cs2Area->mpegstm[0].audstmid = Cs2Area->mpegstm[0].vidstmid = 0x00; - Cs2Area->mpegstm[0].audchannum = Cs2Area->mpegstm[0].vidchannum = 0x00; - Cs2Area->mpegstm[1].audstm = Cs2Area->mpegstm[1].vidstm = 0x00; - Cs2Area->mpegstm[1].audstmid = Cs2Area->mpegstm[1].vidstmid = 0x00; - Cs2Area->mpegstm[1].audchannum = Cs2Area->mpegstm[1].vidchannum = 0x00; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Exec(u32 timing) { - Cs2Area->_periodiccycles += timing * 3; - - if (Cs2Area->_commandtiming > 0) - { - if (Cs2Area->_commandtiming < timing) - { - Cs2Execute(); - Cs2Area->_commandtiming = 0; - } - else - Cs2Area->_commandtiming -= timing; - } - - if (Cs2Area->_periodiccycles >= Cs2Area->_periodictiming) - { - Cs2Area->_periodiccycles -= Cs2Area->_periodictiming; - - // Get Drive's current status and compare with old status -// switch(cd->getStatus()) // this shouldn't be called every periodic response - switch(0) - { - case 0: - case 1: - if ((Cs2Area->status & 0xF) == CDB_STAT_NODISC || - (Cs2Area->status & 0xF) == CDB_STAT_OPEN) - { - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->isdiskchanged = 1; - } - break; - case 2: - // may need to change this - if ((Cs2Area->status & 0xF) != CDB_STAT_NODISC) - Cs2Area->status = CDB_STAT_NODISC; - break; - case 3: - // may need to change this - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN) - Cs2Area->status = CDB_STAT_OPEN; - break; - default: break; - } - - switch (Cs2Area->status & 0xF) { - case CDB_STAT_PAUSE: - { -// if (FAD >= playFAD && FAD < playendFAD) -// status = CDB_STAT_PLAY; -// else - break; - } - case CDB_STAT_PLAY: - { - partition_struct * playpartition; - int ret = Cs2ReadFilteredSector(Cs2Area->FAD, &playpartition); - - switch (ret) - { - case 0: - // Sector Read OK - Cs2Area->FAD++; - Cs2Area->cdi->ReadAheadFAD(Cs2Area->FAD); - - if (playpartition != NULL) - { - // We can use this sector - CDLOG("partition number = %d blocks = %d blockfreespace = %d fad = %x playpartition->size = %x isbufferfull = %x\n", (playpartition - Cs2Area->partition), playpartition->numblocks, Cs2Area->blockfreespace, Cs2Area->FAD, playpartition->size, Cs2Area->isbufferfull); - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CSCT; - Cs2Area->isonesectorstored = 1; - - if (Cs2Area->FAD >= Cs2Area->playendFAD) { - // Make sure we don't have to do a repeat - if (Cs2Area->repcnt >= Cs2Area->maxrepeat) { - // we're done - Cs2Area->status = CDB_STAT_PAUSE; - Cs2SetTiming(0); - Cs2Area->reg.HIRQ |= CDB_HIRQ_PEND; - - if (Cs2Area->playtype == CDB_PLAYTYPE_FILE) - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS; - - CDLOG("PLAY HAS ENDED\n"); - } - else { - - Cs2Area->FAD = Cs2Area->playFAD; - if (Cs2Area->repcnt < 0xE) - Cs2Area->repcnt++; - Cs2Area->track = Cs2FADToTrack(Cs2Area->FAD); - - CDLOG("PLAY HAS REPEATED\n"); - } - } - if (Cs2Area->isbufferfull) { - CDLOG("BUFFER IS FULL\n"); -// status = CDB_STAT_PAUSE; - } - } - else - { - CDLOG("Sector filtered out\n"); - if (Cs2Area->FAD >= Cs2Area->playendFAD) { - // Make sure we don't have to do a repeat - if (Cs2Area->repcnt >= Cs2Area->maxrepeat) { - // we're done - Cs2Area->status = CDB_STAT_PAUSE; - Cs2SetTiming(0); - Cs2Area->reg.HIRQ |= CDB_HIRQ_PEND; - - if (Cs2Area->playtype == CDB_PLAYTYPE_FILE) - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS; - - CDLOG("PLAY HAS ENDED\n"); - } - else { - Cs2Area->FAD = Cs2Area->playFAD; - if (Cs2Area->repcnt < 0xE) - Cs2Area->repcnt++; - Cs2Area->track = Cs2FADToTrack(Cs2Area->FAD); - - CDLOG("PLAY HAS REPEATED\n"); - } - } - } - break; - case -1: - // Things weren't setup correctly - break; - case -2: - // Do a read retry - break; - } - - break; - } - case CDB_STAT_SEEK: - break; - case CDB_STAT_SCAN: - break; - case CDB_STAT_RETRY: - break; - default: break; - } - - if (Cs2Area->_command) - return; - - Cs2Area->status |= CDB_STAT_PERI; - - // adjust registers appropriately here(fix me) - doCDReport(Cs2Area->status); - - Cs2Area->reg.HIRQ |= CDB_HIRQ_SCDQ; - } - - if(Cs2Area->carttype == CART_NETLINK) - NetlinkExec(timing); -} - -////////////////////////////////////////////////////////////////////////////// - -/* Returns the number of (emulated) microseconds before the next sector - * will have been completely read in */ -int Cs2GetTimeToNextSector(void) { - if ((Cs2Area->status & 0xF) != CDB_STAT_PLAY) { - return 0; - } else { - // Round up, since the caller wants to know when it'll be safe to check - int time = (Cs2Area->_periodictiming - Cs2Area->_periodiccycles + 2) / 3; - return time<0 ? 0 : time; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Command(void) { - Cs2Area->_command = 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetTiming(int playing) { - if (playing) { - if (Cs2Area->isaudio || Cs2Area->speed1x == 1) - Cs2Area->_periodictiming = 40000; // 13333.333... * 3 - else - Cs2Area->_periodictiming = 20000; // 6666.666... * 3 - } - else { - Cs2Area->_periodictiming = 50000; // 16666.666... * 3 - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetCommandTiming(u8 cmd) { - switch(cmd) { - default: - Cs2Area->_commandtiming = 1; - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Execute(void) { - u16 instruction = Cs2Area->reg.CR1 >> 8; - - Cs2Area->reg.HIRQ &= ~CDB_HIRQ_CMOK; - - switch (instruction) { - case 0x00: - CDLOG("cs2\t: Command: getStatus\n"); - Cs2GetStatus(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x01: - CDLOG("cs2\t: Command: getHardwareInfo\n"); - Cs2GetHardwareInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x02: - CDLOG("cs2\t: Command: getToc\n"); - Cs2GetToc(); - break; - case 0x03: - CDLOG("cs2\t: Command: getSessionInfo\n"); - Cs2GetSessionInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x04: - CDLOG("cs2\t: Command: initializeCDSystem %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2InitializeCDSystem(); - break; - case 0x06: - CDLOG("cs2\t: Command: endDataTransfer %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2EndDataTransfer(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x10: - CDLOG("cs2\t: Command: playDisc %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2PlayDisc(); - break; - case 0x11: - CDLOG("cs2\t: Command: seekDisc %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2SeekDisc(); - break; - case 0x20: - CDLOG("cs2\t: Command: getSubcodeQRW %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSubcodeQRW(); - break; - case 0x30: - CDLOG("cs2\t: Command: setCDDeviceConnection %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2SetCDDeviceConnection(); - break; - case 0x32: - CDLOG("cs2\t: Command: getLastBufferDestination %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetLastBufferDestination(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x40: - CDLOG("cs2\t: Command: setFilterRange\n"); - Cs2SetFilterRange(); - break; - case 0x42: - CDLOG("cs2\t: Command: setFilterSubheaderConditions\n"); - Cs2SetFilterSubheaderConditions(); - break; - case 0x43: - CDLOG("cs2\t: Command: getFilterSubheaderConditions\n"); - Cs2GetFilterSubheaderConditions(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x44: - CDLOG("cs2\t: Command: setFilterMode\n"); - Cs2SetFilterMode(); - break; - case 0x45: - CDLOG("cs2\t: Command: getFilterMode\n"); - Cs2GetFilterMode(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x46: - CDLOG("cs2\t: Command: setFilterConnection\n"); - Cs2SetFilterConnection(); - break; - case 0x48: - CDLOG("cs2\t: Command: resetSelector %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ResetSelector(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x50: - CDLOG("cs2\t: Command: getBufferSize\n"); - Cs2GetBufferSize(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x51: -// CDLOG("cs2\t: Command: getSectorNumber %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSectorNumber(); -// CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x52: - CDLOG("cs2\t: Command: calculateActualSize %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CalculateActualSize(); - break; - case 0x53: - CDLOG("cs2\t: Command: getActualSize\n"); - Cs2GetActualSize(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x54: - CDLOG("cs2\t: Command: getSectorInfo %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSectorInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x60: - CDLOG("cs2\t: Command: setSectorLength %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2SetSectorLength(); - break; - case 0x61: - CDLOG("cs2\t: Command: getSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSectorData(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x62: - CDLOG("cs2\t: Command: deleteSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2DeleteSectorData(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x63: - CDLOG("cs2\t: Command: getThenDeleteSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetThenDeleteSectorData(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x64: - CDLOG("cs2\t: Command: putSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2PutSectorData(); - break; - case 0x67: - CDLOG("cs2\t: Command: getCopyError\n"); - Cs2GetCopyError(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x70: - CDLOG("cs2\t: Command: changeDirectory %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ChangeDirectory(); - break; - case 0x71: - CDLOG("cs2\t: Command: readDirectory %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ReadDirectory(); - break; - case 0x72: - CDLOG("cs2\t: Command: getFileSystemScope\n"); - Cs2GetFileSystemScope(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x73: - CDLOG("cs2\t: Command: getFileInfo %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetFileInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x74: - CDLOG("cs2\t: Command: readFile %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ReadFile(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x75: - CDLOG("cs2\t: Command: abortFile\n"); - Cs2AbortFile(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x90: - CDLOG("cs2\t: Command: mpegGetStatus\n"); - Cs2MpegGetStatus(); - break; - case 0x91: - CDLOG("cs2\t: Command: mpegGetInterrupt\n"); - Cs2MpegGetInterrupt(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x92: - CDLOG("cs2\t: Command: mpegSetInterruptMask\n"); - Cs2MpegSetInterruptMask(); - break; - case 0x93: - CDLOG("cs2\t: Command: mpegInit\n"); - Cs2MpegInit(); - break; - case 0x94: - CDLOG("cs2\t: Command: mpegSetMode\n"); - Cs2MpegSetMode(); - break; - case 0x95: - CDLOG("cs2\t: Command: mpegPlay\n"); - Cs2MpegPlay(); - break; - case 0x96: - CDLOG("cs2\t: Command: mpegSetDecodingMethod\n"); - Cs2MpegSetDecodingMethod(); - break; - case 0x9A: - CDLOG("cs2\t: Command: mpegSetConnection\n"); - Cs2MpegSetConnection(); - break; - case 0x9B: - CDLOG("cs2\t: Command: mpegGetConnection\n"); - Cs2MpegGetConnection(); - break; - case 0x9D: - CDLOG("cs2\t: Command: mpegSetStream\n"); - Cs2MpegSetStream(); - break; - case 0x9E: - CDLOG("cs2\t: Command: mpegGetStream\n"); - Cs2MpegGetStream(); - break; - case 0xA0: - CDLOG("cs2\t: Command: mpegDisplay\n"); - Cs2MpegDisplay(); - break; - case 0xA1: - CDLOG("cs2\t: Command: mpegSetWindow\n"); - Cs2MpegSetWindow(); - break; - case 0xA2: - CDLOG("cs2\t: Command: mpegSetBorderColor\n"); - Cs2MpegSetBorderColor(); - break; - case 0xA3: - CDLOG("cs2\t: Command: mpegSetFade\n"); - Cs2MpegSetFade(); - break; - case 0xA4: - CDLOG("cs2\t: Command: mpegSetVideoEffects\n"); - Cs2MpegSetVideoEffects(); - break; - case 0xAF: - CDLOG("cs2\t: Command: mpegSetLSI\n"); - Cs2MpegSetLSI(); - break; - case 0xE0: - CDLOG("cs2\t: Command: cmdE0 %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CmdE0(); - break; - case 0xE1: - CDLOG("cs2\t: Command: cmdE1 %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CmdE1(); - break; - case 0xE2: - CDLOG("cs2\t: Command: cmdE2 %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CmdE2(); - break; - default: - CDLOG("cs2\t: Command %02x not implemented\n", instruction); - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetStatus(void) { - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetHardwareInfo(void) { - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN && (Cs2Area->status & 0xF) != CDB_STAT_NODISC) - Cs2Area->isdiskchanged = 0; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - // hardware flags/CD Version - Cs2Area->reg.CR2 = 0x0201; // mpeg card exists - // mpeg version, it actually is required(at least by the bios) - - if (Cs2Area->mpgauth) - Cs2Area->reg.CR3 = 0x1; - else - Cs2Area->reg.CR3 = 0; - - // drive info/revision - Cs2Area->reg.CR4 = 0x0400; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetToc(void) { - Cs2Area->cdi->ReadTOC(Cs2Area->TOC); - - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = 0; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0xCC; - Cs2Area->reg.CR3 = 0x0; - Cs2Area->reg.CR4 = 0x0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; - Cs2Area->status = CDB_STAT_PAUSE; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSessionInfo(void) { - - switch (Cs2Area->reg.CR1 & 0xFF) { - case 0: - Cs2Area->reg.CR3 = (u16)(0x0100 | ((Cs2Area->TOC[101] & 0xFF0000) >> 16)); - Cs2Area->reg.CR4 = (u16)Cs2Area->TOC[101]; - break; - case 1: - Cs2Area->reg.CR3 = 0x0100; // return Session number(high byte)/and first byte of Session lba - Cs2Area->reg.CR4 = 0; // lower word of Session lba - break; - default: - Cs2Area->reg.CR3 = 0xFFFF; - Cs2Area->reg.CR4 = 0xFFFF; - break; - } - - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2InitializeCDSystem(void) { - u16 val = 0; - u8 initflag = Cs2Area->reg.CR1 & 0xFF; - - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN && (Cs2Area->status & 0xF) != CDB_STAT_NODISC) - { - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->FAD = 150; - } - - if (initflag & 0x1) - { - // Reset CD block software - } - - if (initflag & 0x2) - { - // Decode RW subcode - } - - if (initflag & 0x4) - { - // Don't confirm Mode 2 subheader - } - - if (initflag & 0x8) - { - // Retry reading Form 2 sectors - } - - if (initflag & 0x10) - Cs2Area->speed1x = 1; - else - Cs2Area->speed1x = 0; - - val = Cs2Area->reg.HIRQ & 0xFFE5; - Cs2Area->isbufferfull = 0; - - if (Cs2Area->isdiskchanged) - val |= CDB_HIRQ_DCHG; - else - val &= ~CDB_HIRQ_DCHG; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ = val | CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2EndDataTransfer(void) { - s32 i; - if (Cs2Area->cdwnum) - { - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((Cs2Area->cdwnum >> 17) & 0xFF)); - Cs2Area->reg.CR2 = (u16)(Cs2Area->cdwnum >> 1); - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - else - { - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0xFF; // FIXME - Cs2Area->reg.CR2 = 0xFFFF; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - - // stop any transfers that may be going(this is still probably wrong), and - // set/clear the appropriate flags - - switch (Cs2Area->datatranstype) - { - case 0: - // Get Sector Data - Cs2Area->reg.HIRQ |= CDB_HIRQ_EHST; - break; - case 2: - { - // Get Then Delete Sector - - // Make sure we actually have to free something - if (Cs2Area->datatranspartition->size <= 0) break; - - Cs2Area->datatranstype = -1; - - // free blocks - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos + Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - // sort remaining blocks - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - if (Cs2Area->blockfreespace == 200) Cs2Area->isonesectorstored = 0; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_EHST; - break; - } - default: break; - } - - Cs2Area->cdwnum = 0; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2PlayDisc(void) { - u32 pdspos; - u32 pdepos; - u32 pdpmode; - - // Get all the arguments - pdspos = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - pdepos = ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4; - pdpmode = Cs2Area->reg.CR3 >> 8; - - // Convert Start Position to playFAD - if (pdspos == 0xFFFFFF || pdpmode == 0xFF) // This still isn't right - { - // No Change - } - else if (pdspos & 0x800000) - { - // FAD Mode - Cs2Area->playFAD = (pdspos & 0xFFFFF); - - Cs2SetupDefaultPlayStats(Cs2FADToTrack(Cs2Area->playFAD), 0); - - if (!(pdpmode & 0x80)) - // Move pickup to start position - Cs2Area->FAD = Cs2Area->playFAD; - } - else - { - // Track Mode - - // If track == 0, set it to the first available track, or something like that - if (pdspos == 0) - pdspos = 0x0100; - - if (!(pdpmode & 0x80)) - { - Cs2SetupDefaultPlayStats((u8)(pdspos >> 8), 1); - Cs2Area->playFAD = Cs2Area->FAD; - Cs2Area->track = (u8)(pdspos >> 8); - Cs2Area->index = (u8)pdspos; - } - else - { - // Preserve Pickup Position - Cs2SetupDefaultPlayStats((u8)(pdspos >> 8), 0); - } - } - - pdpmode &= 0x7F; - - // Only update max repeat if bits 0-6 aren't all set - if (pdpmode != 0x7F) - Cs2Area->maxrepeat = pdpmode; - - // Convert End Position to playendFAD - if (pdepos == 0xFFFFFF) - { - // No Change - } - else if (pdepos & 0x800000) - { - // FAD Mode - Cs2Area->playendFAD = Cs2Area->playFAD+(pdepos & 0xFFFFF); - } - else if (pdepos != 0) - { - // Track Mode - if ((pdepos & 0xFF) == 0) - Cs2Area->playendFAD = Cs2TrackToFAD((u16)(pdepos | 0x0063)); - else - Cs2Area->playendFAD = Cs2TrackToFAD((u16)pdepos); - } - else - { - // Default Mode - Cs2Area->playendFAD = Cs2TrackToFAD(0xFFFF); - } - - // setup play mode here -#if CDDEBUG - if (pdpmode != 0) - CDLOG("cs2\t: playDisc: Unsupported play mode = %02X\n", pdpmode); -#endif - - Cs2SetTiming(1); - - Cs2Area->status = CDB_STAT_PLAY; - Cs2Area->playtype = CDB_PLAYTYPE_SECTOR; - Cs2Area->cdi->ReadAheadFAD(Cs2Area->FAD); - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SeekDisc(void) { - if (Cs2Area->reg.CR1 & 0x80) - { - // Seek by FAD - u32 sdFAD; - - sdFAD = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - - if (sdFAD == 0xFFFFFF) - Cs2Area->status = CDB_STAT_PAUSE; - else - { - CDLOG("cs2\t: seekDisc - FAD Mode not supported\n"); - } - } - else - { - // Were we given a valid track number? - if (Cs2Area->reg.CR2 >> 8) - { - // Seek by index - Cs2Area->status = CDB_STAT_PAUSE; - Cs2SetupDefaultPlayStats((Cs2Area->reg.CR2 >> 8), 1); - Cs2Area->index = Cs2Area->reg.CR2 & 0xFF; - } - else - { - // Error - Cs2Area->status = CDB_STAT_STANDBY; - Cs2Area->options = 0xFF; - Cs2Area->repcnt = 0xFF; - Cs2Area->ctrladdr = 0xFF; - Cs2Area->track = 0xFF; - Cs2Area->index = 0xFF; - Cs2Area->FAD = 0xFFFFFFFF; - } - } - - Cs2SetTiming(0); - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSubcodeQRW(void) { - // According to Tyranid's doc, the subcode type is stored in the low byte - // of CR2. However, Sega's CDC library writes the type to the low byte - // of CR1. Somehow I'd sooner believe Sega is right. - switch(Cs2Area->reg.CR1 & 0xFF) { - case 0: - // Get Q Channel - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0; - Cs2Area->reg.CR2 = 5; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - - // setup transfer here(fix me) - break; - case 1: - // Get RW Channel - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0; - Cs2Area->reg.CR2 = 12; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - - // setup transfer here(fix me) - break; - default: break; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetCDDeviceConnection(void) { - u32 scdcfilternum; - - scdcfilternum = (Cs2Area->reg.CR3 >> 8); - - if (scdcfilternum == 0xFF) - Cs2Area->outconcddev = NULL; - else if (scdcfilternum < 0x24) - Cs2Area->outconcddev = Cs2Area->filter + scdcfilternum; - - Cs2Area->outconcddevnum = (u8)scdcfilternum; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetLastBufferDestination(void) { - Cs2Area->reg.CR1 = (Cs2Area->status << 8); - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = Cs2Area->lastbuffer << 8; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterRange(void) { - u8 sfrfilternum; - - sfrfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->filter[sfrfilternum].FAD = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - Cs2Area->filter[sfrfilternum].range = ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4; - - // return default cd stats - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterSubheaderConditions(void) { - u8 sfscfilternum; - - sfscfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->filter[sfscfilternum].chan = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->filter[sfscfilternum].smmask = Cs2Area->reg.CR2 >> 8; - Cs2Area->filter[sfscfilternum].cimask = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->filter[sfscfilternum].fid = Cs2Area->reg.CR3 & 0xFF;; - Cs2Area->filter[sfscfilternum].smval = Cs2Area->reg.CR4 >> 8; - Cs2Area->filter[sfscfilternum].cival = Cs2Area->reg.CR4 & 0xFF; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFilterSubheaderConditions(void) { - u8 gfscfilternum; - - gfscfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->filter[gfscfilternum].chan; - Cs2Area->reg.CR2 = (Cs2Area->filter[gfscfilternum].smmask << 8) | Cs2Area->filter[gfscfilternum].cimask; - Cs2Area->reg.CR3 = Cs2Area->filter[gfscfilternum].fid; - Cs2Area->reg.CR4 = (Cs2Area->filter[gfscfilternum].smval << 8) | Cs2Area->filter[gfscfilternum].cival; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterMode(void) { - u8 sfmfilternum; - - sfmfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->filter[sfmfilternum].mode = Cs2Area->reg.CR1 & 0xFF; - - if (Cs2Area->filter[sfmfilternum].mode & 0x80) - { - // Initialize filter conditions - Cs2Area->filter[sfmfilternum].mode = 0; - Cs2Area->filter[sfmfilternum].FAD = 0; - Cs2Area->filter[sfmfilternum].range = 0; - Cs2Area->filter[sfmfilternum].chan = 0; - Cs2Area->filter[sfmfilternum].smmask = 0; - Cs2Area->filter[sfmfilternum].cimask = 0; - Cs2Area->filter[sfmfilternum].smval = 0; - Cs2Area->filter[sfmfilternum].cival = 0; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFilterMode(void) { - u8 gfmfilternum; - - gfmfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->filter[gfmfilternum].mode; - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterConnection(void) { - u8 sfcfilternum; - - sfcfilternum = Cs2Area->reg.CR3 >> 8; - - if (Cs2Area->reg.CR1 & 0x1) - { - // Set connection for true condition - Cs2Area->filter[sfcfilternum].condtrue = Cs2Area->reg.CR2 >> 8; - } - - if (Cs2Area->reg.CR1 & 0x2) - { - // Set connection for false condition - Cs2Area->filter[sfcfilternum].condfalse = Cs2Area->reg.CR2 & 0xFF; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ResetSelector(void) { - // still needs a bit of work - u32 i, i2; - - if ((Cs2Area->reg.CR1 & 0xFF) == 0) - { - // Reset specified partition buffer only - u32 rsbufno = Cs2Area->reg.CR3 >> 8; - - // sort remaining blocks - if (rsbufno < MAX_SELECTORS) - { - // clear partition - for (i = 0; i < Cs2Area->partition[rsbufno].numblocks; i++) - { - Cs2FreeBlock(Cs2Area->partition[rsbufno].block[i]); - Cs2Area->partition[rsbufno].block[i] = NULL; - Cs2Area->partition[rsbufno].blocknum[i] = 0xFF; - } - - Cs2Area->partition[rsbufno].size = -1; - Cs2Area->partition[rsbufno].numblocks = 0; - } - - if (Cs2Area->blockfreespace > 0) Cs2Area->isbufferfull = 0; - if (Cs2Area->blockfreespace == 200) Cs2Area->isonesectorstored = 0; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; - return; - } - - // parse flags and reset the specified area(fix me) - if (Cs2Area->reg.CR1 & 0x80) - { - // reset false filter output connections - for (i = 0; i < MAX_SELECTORS; i++) - Cs2Area->filter[i].condfalse = 0xFF; - } - - if (Cs2Area->reg.CR1 & 0x40) - { - // reset true filter output connections - for (i = 0; i < MAX_SELECTORS; i++) - Cs2Area->filter[i].condtrue = (u8)i; - } - - if (Cs2Area->reg.CR1 & 0x10) - { - // reset filter conditions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->filter[i].FAD = 0; - Cs2Area->filter[i].range = 0xFFFFFFFF; - Cs2Area->filter[i].mode = 0; - Cs2Area->filter[i].chan = 0; - Cs2Area->filter[i].smmask = 0; - Cs2Area->filter[i].cimask = 0; - Cs2Area->filter[i].fid = 0; - Cs2Area->filter[i].smval = 0; - Cs2Area->filter[i].cival = 0; - } - } - - if (Cs2Area->reg.CR1 & 0x8) - { - // reset partition output connectors - } - - if (Cs2Area->reg.CR1 & 0x4) - { - // reset partitions buffer data - Cs2Area->isbufferfull = 0; - - // clear partitions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->partition[i].size = -1; - Cs2Area->partition[i].numblocks = 0; - - for (i2 = 0; i2 < MAX_BLOCKS; i2++) - { - Cs2Area->partition[i].block[i2] = NULL; - Cs2Area->partition[i].blocknum[i2] = 0xFF; - } - } - - // clear blocks - for (i = 0; i < MAX_BLOCKS; i++) - { - Cs2Area->block[i].size = -1; - memset(Cs2Area->block[i].data, 0, 2352); - } - - Cs2Area->isonesectorstored = 0; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetBufferSize(void) { - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = (u16)Cs2Area->blockfreespace; - Cs2Area->reg.CR3 = MAX_SELECTORS << 8; - Cs2Area->reg.CR4 = MAX_BLOCKS; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSectorNumber(void) { - u32 gsnbufno; - - gsnbufno = Cs2Area->reg.CR3 >> 8; - - if (Cs2Area->partition[gsnbufno].size == -1) - Cs2Area->reg.CR4 = 0; - else - Cs2Area->reg.CR4 = Cs2Area->partition[gsnbufno].numblocks; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CalculateActualSize(void) { - u16 i; - u32 casbufno; - u16 cassectoffset; - u16 casnumsect; - - cassectoffset = Cs2Area->reg.CR2; - casbufno = Cs2Area->reg.CR3 >> 8; - casnumsect = Cs2Area->reg.CR4; - - if (Cs2Area->partition[casbufno].size != 0) - { - Cs2Area->calcsize = 0; - - for (i = 0; i < casnumsect; i++) - { - if (Cs2Area->partition[casbufno].block[cassectoffset]) - Cs2Area->calcsize += (Cs2Area->partition[casbufno].block[cassectoffset]->size / 2); - } - } - else - Cs2Area->calcsize = 0; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetActualSize(void) { - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((Cs2Area->calcsize >> 16) & 0xFF)); - Cs2Area->reg.CR2 = (u16)Cs2Area->calcsize; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSectorInfo(void) { - u32 gsisctnum; - u32 gsibufno; - - gsisctnum = Cs2Area->reg.CR2 & 0xFF; - gsibufno = Cs2Area->reg.CR3 >> 8; - if (gsibufno < MAX_SELECTORS) { - if (gsisctnum < Cs2Area->partition[gsibufno].numblocks) { - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((Cs2Area->partition[gsibufno].block[gsisctnum]->FAD >> 16) & 0xFF)); - Cs2Area->reg.CR2 = (u16)Cs2Area->partition[gsibufno].block[gsisctnum]->FAD; - Cs2Area->reg.CR3 = (Cs2Area->partition[gsibufno].block[gsisctnum]->fn << 8) | Cs2Area->partition[gsibufno].block[gsisctnum]->cn; - Cs2Area->reg.CR4 = (Cs2Area->partition[gsibufno].block[gsisctnum]->sm << 8) | Cs2Area->partition[gsibufno].block[gsisctnum]->ci; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; - return; - } - else - { - CDLOG("cs2\t: getSectorInfo: Unsupported Partition Number\n"); - } - } - - Cs2Area->reg.CR1 = (CDB_STAT_REJECT << 8) | (Cs2Area->reg.CR1 & 0xFF); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetSectorLength(void) { - switch (Cs2Area->reg.CR1 & 0xFF) { - case 0: - Cs2Area->getsectsize = 2048; - break; - case 1: - Cs2Area->getsectsize = 2336; - break; - case 2: - Cs2Area->getsectsize = 2340; - break; - case 3: - Cs2Area->getsectsize = 2352; - break; - default: break; - } - - switch (Cs2Area->reg.CR2 >> 8) { - case 0: - Cs2Area->putsectsize = 2048; - break; - case 1: - Cs2Area->putsectsize = 2336; - break; - case 2: - Cs2Area->putsectsize = 2340; - break; - case 3: - Cs2Area->putsectsize = 2352; - break; - default: break; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void CalcSectorOffsetNumber(u32 bufno, u32 *sectoffset, u32 *sectnum) -{ - if (*sectoffset == 0xFFFF) - { - // Last sector - CDLOG("FIXME - Sector offset of 0xFFFF not supported\n"); - } - else if (*sectnum == 0xFFFF) - { - // From sectoffset to last sector in partition - *sectnum = Cs2Area->partition[bufno].numblocks - *sectoffset; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSectorData(void) -{ - u32 gsdsectoffset; - u32 gsdbufno; - u32 gsdsectnum; - - gsdsectoffset = Cs2Area->reg.CR2; - gsdbufno = Cs2Area->reg.CR3 >> 8; - gsdsectnum = Cs2Area->reg.CR4; - - if (gsdbufno >= MAX_SELECTORS) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - if (Cs2Area->partition[gsdbufno].numblocks == 0) - { - CDLOG("No sectors available\n"); - - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - CalcSectorOffsetNumber(gsdbufno, &gsdsectoffset, &gsdsectnum); - - // Setup Data Transfer - Cs2Area->cdwnum = 0; - Cs2Area->datatranstype = 0; - Cs2Area->datatranspartition = Cs2Area->partition + gsdbufno; - Cs2Area->datatranspartitionnum = (u8)gsdbufno; - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans = 0; - Cs2Area->datatranssectpos = (u16)gsdsectoffset; - Cs2Area->datasectstotrans = (u16)gsdsectnum; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY | CDB_HIRQ_EHST; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2DeleteSectorData(void) -{ - u32 dsdsectoffset; - u32 dsdbufno; - u32 dsdsectnum; - u32 i; - - dsdsectoffset = Cs2Area->reg.CR2; - dsdbufno = Cs2Area->reg.CR3 >> 8; - dsdsectnum = Cs2Area->reg.CR4; - - if (dsdbufno >= MAX_SELECTORS) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - if (Cs2Area->partition[dsdbufno].numblocks == 0) - { - CDLOG("No sectors available\n"); - - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - CalcSectorOffsetNumber(dsdbufno, &dsdsectoffset, &dsdsectnum); - - for (i = dsdsectoffset; i < (dsdsectoffset+dsdsectnum); i++) - { - Cs2Area->partition[dsdbufno].size -= Cs2Area->partition[dsdbufno].block[i]->size; - Cs2FreeBlock(Cs2Area->partition[dsdbufno].block[i]); - Cs2Area->partition[dsdbufno].block[i] = NULL; - Cs2Area->partition[dsdbufno].blocknum[i] = 0xFF; - } - - // sort remaining blocks - Cs2SortBlocks(&Cs2Area->partition[dsdbufno]); - - Cs2Area->partition[dsdbufno].numblocks -= (u8)dsdsectnum; - - if (Cs2Area->blockfreespace == 200) - Cs2Area->isonesectorstored = 0; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetThenDeleteSectorData(void) -{ - u32 gtdsdsectoffset; - u32 gtdsdbufno; - u32 gtdsdsectnum; - - gtdsdsectoffset = Cs2Area->reg.CR2; - gtdsdbufno = Cs2Area->reg.CR3 >> 8; - gtdsdsectnum = Cs2Area->reg.CR4; - - if (gtdsdbufno >= MAX_SELECTORS) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - if (Cs2Area->partition[gtdsdbufno].numblocks == 0) - { - CDLOG("No sectors available\n"); - - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - CalcSectorOffsetNumber(gtdsdbufno, >dsdsectoffset, >dsdsectnum); - - // Setup Data Transfer - Cs2Area->cdwnum = 0; - Cs2Area->datatranstype = 2; - Cs2Area->datatranspartition = Cs2Area->partition + gtdsdbufno; - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans = 0; - Cs2Area->datatranssectpos = (u16)gtdsdsectoffset; - Cs2Area->datasectstotrans = (u16)gtdsdsectnum; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY | CDB_HIRQ_EHST; - - return; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2PutSectorData(void) { - u32 psdfiltno; - - psdfiltno = Cs2Area->reg.CR3 >> 8; - - if (psdfiltno < MAX_SELECTORS) - { - // I'm not really sure what I'm supposed to really be doing or returning - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - } - else - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetCopyError(void) { - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ChangeDirectory(void) { - u32 cdfilternum; - - cdfilternum = (Cs2Area->reg.CR3 >> 8); - - if (cdfilternum == 0xFF) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - else if (cdfilternum < 0x24) - { - if (Cs2ReadFileSystem(Cs2Area->filter + cdfilternum, ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4, 0) != 0) - { - CDLOG("cs2\t: ReadFileSystem failed\n"); - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ReadDirectory(void) { - u32 rdfilternum; - - rdfilternum = (Cs2Area->reg.CR3 >> 8); - - if (rdfilternum == 0xFF) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - else if (rdfilternum < 0x24) - { - if (Cs2ReadFileSystem(Cs2Area->filter + rdfilternum, ((Cs2Area->reg.CR3 & 0xFF) << 8) | Cs2Area->reg.CR4, 1) != 0) - { - CDLOG("cs2\t: ReadFileSystem failed\n"); - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFileSystemScope(void) { - // may need to fix this - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = (u16)(Cs2Area->numfiles - 2); - Cs2Area->reg.CR3 = 0x0100; - Cs2Area->reg.CR4 = 0x0002; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFileInfo(void) { - u32 gfifid; - - gfifid = ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4; - - if (gfifid == 0xFFFFFF) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = 2; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0x05F4; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - else - { - Cs2SetupFileInfoTransfer(gfifid); - - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = 1; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0x06; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ReadFile(void) { - u32 rfoffset, rffilternum, rffid, rfsize; - - rfoffset = ((Cs2Area->reg.CR1 & 0xFF) << 8) | Cs2Area->reg.CR2; - rffilternum = Cs2Area->reg.CR3 >> 8; - rffid = ((Cs2Area->reg.CR3 & 0xFF) << 8) | Cs2Area->reg.CR4; - rfsize = ((Cs2Area->fileinfo[rffid].size + Cs2Area->getsectsize - 1) / - Cs2Area->getsectsize) - rfoffset; - - Cs2SetupDefaultPlayStats(Cs2FADToTrack(Cs2Area->fileinfo[rffid].lba + rfoffset), 0); - Cs2Area->maxrepeat = 0; - - Cs2Area->playFAD = Cs2Area->FAD = Cs2Area->fileinfo[rffid].lba + rfoffset; - Cs2Area->playendFAD = Cs2Area->playFAD + rfsize; - - Cs2Area->options = 0x8; - - Cs2SetTiming(1); - - Cs2Area->outconcddev = Cs2Area->filter + rffilternum; - - Cs2Area->status = CDB_STAT_PLAY; - Cs2Area->playtype = CDB_PLAYTYPE_FILE; - Cs2Area->cdi->ReadAheadFAD(Cs2Area->FAD); - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2AbortFile(void) { - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN && - (Cs2Area->status & 0xF) != CDB_STAT_NODISC) - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->isonesectorstored = 0; - Cs2Area->datatranstype = -1; - Cs2Area->cdwnum = 0; - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetStatus(void) { - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetInterrupt(void) { - u32 mgiworkinterrupt; - - // mpeg interrupt should be retrieved here - mgiworkinterrupt = 0; - - // mask interupt - mgiworkinterrupt &= Cs2Area->mpegintmask; - - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((mgiworkinterrupt >> 16) & 0xFF)); - Cs2Area->reg.CR2 = (u16) mgiworkinterrupt; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetInterruptMask(void) { - Cs2Area->mpegintmask = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegInit(void) { - - if (Cs2Area->mpgauth) - Cs2Area->reg.CR1 = Cs2Area->status << 8; - else - Cs2Area->reg.CR1 = 0xFF00; - - // double-check this - if (Cs2Area->reg.CR2 == 0x0001) // software timer/reset? - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM | CDB_HIRQ_MPED | CDB_HIRQ_MPST; - else - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPED | CDB_HIRQ_MPST; - - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - - // future mpeg-related variables should be initialized here -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetMode(void) { - // fix me - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegPlay(void) { - // fix me - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetDecodingMethod(void) { - // fix me - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetConnection(void) { - int mscnext = (Cs2Area->reg.CR3 >> 8); - - if (mscnext == 0) - { - // Current - Cs2Area->mpegcon[0].audcon = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegcon[0].audlay = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegcon[0].audbufdivnum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegcon[0].vidcon = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegcon[0].vidlay = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegcon[0].vidbufdivnum = Cs2Area->reg.CR4 & 0xFF; - } - else - { - // Next - Cs2Area->mpegcon[1].audcon = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegcon[1].audlay = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegcon[1].audbufdivnum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegcon[1].vidcon = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegcon[1].vidlay = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegcon[1].vidbufdivnum = Cs2Area->reg.CR4 & 0xFF; - } - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetConnection(void) { - int mgcnext = (Cs2Area->reg.CR3 >> 8); - - if (mgcnext == 0) - { - // Current - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegcon[0].audcon; - Cs2Area->reg.CR2 = (Cs2Area->mpegcon[0].audlay << 8) | Cs2Area->mpegcon[0].audbufdivnum; - Cs2Area->reg.CR3 = Cs2Area->mpegcon[0].vidcon; - Cs2Area->reg.CR4 = (Cs2Area->mpegcon[0].vidlay << 8) | Cs2Area->mpegcon[0].vidbufdivnum; - } - else - { - // Next - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegcon[1].audcon; - Cs2Area->reg.CR2 = (Cs2Area->mpegcon[1].audlay << 8) | Cs2Area->mpegcon[1].audbufdivnum; - Cs2Area->reg.CR3 = Cs2Area->mpegcon[1].vidcon; - Cs2Area->reg.CR4 = (Cs2Area->mpegcon[1].vidlay << 8) | Cs2Area->mpegcon[1].vidbufdivnum; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetStream(void) { - int mssnext = (Cs2Area->reg.CR3 >> 8); - - if (mssnext == 0) - { - // Current - Cs2Area->mpegstm[0].audstm = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegstm[0].audstmid = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegstm[0].audchannum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegstm[0].vidstm = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegstm[0].vidstmid = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegstm[0].vidchannum = Cs2Area->reg.CR4 & 0xFF; - } - else - { - // Next - Cs2Area->mpegstm[1].audstm = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegstm[1].audstmid = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegstm[1].audchannum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegstm[1].vidstm = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegstm[1].vidstmid = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegstm[1].vidchannum = Cs2Area->reg.CR4 & 0xFF; - } - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetStream(void) { - int mgsnext = (Cs2Area->reg.CR3 >> 8); - - if (mgsnext == 0) - { - // Current - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegstm[0].audstm; - Cs2Area->reg.CR2 = (Cs2Area->mpegstm[0].audstmid << 8) | Cs2Area->mpegstm[0].audchannum; - Cs2Area->reg.CR3 = Cs2Area->mpegstm[0].vidstm; - Cs2Area->reg.CR4 = (Cs2Area->mpegstm[0].vidstmid << 8) | Cs2Area->mpegstm[0].vidchannum; - } - else - { - // Next - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegstm[1].audstm; - Cs2Area->reg.CR2 = (Cs2Area->mpegstm[1].audstmid << 8) | Cs2Area->mpegstm[1].audchannum; - Cs2Area->reg.CR3 = Cs2Area->mpegstm[1].vidstm; - Cs2Area->reg.CR4 = (Cs2Area->mpegstm[1].vidstmid << 8) | Cs2Area->mpegstm[1].vidchannum; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegDisplay(void) { - // fix me(should be setting display setting) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetWindow(void) { - // fix me(should be setting windows settings) - - // return default mpeg stats - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetBorderColor(void) { - // fix me(should be setting border color) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetFade(void) { - // fix me(should be setting fade setting) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetVideoEffects(void) { - // fix me(should be setting video effects settings) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetLSI(void) { - // fix me(should be setting the LSI, among other things) - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CmdE0(void) { - int mpegauth; - - mpegauth = Cs2Area->reg.CR2 & 0xFF; - - - if ((Cs2Area->status & 0xF) != CDB_STAT_NODISC && - (Cs2Area->status & 0xF) != CDB_STAT_OPEN) - { - // Set registers all to invalid values(aside from status) - Cs2Area->status = CDB_STAT_BUSY; - - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0xFF; - Cs2Area->reg.CR2 = 0xFFFF; - Cs2Area->reg.CR3 = 0xFFFF; - Cs2Area->reg.CR4 = 0xFFFF; - - if (mpegauth == 1) - { - Cs2Area->reg.HIRQ |= CDB_HIRQ_MPED; - Cs2Area->mpgauth = 2; - } - else - { - // if authentication passes(obviously it always does), CDB_HIRQ_CSCT is set - Cs2Area->isonesectorstored = 1; - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS | CDB_HIRQ_CSCT; - Cs2Area->satauth = 4; - } - - // Set registers all back to normal values - - Cs2Area->status = CDB_STAT_PAUSE; - } - else - { - if (mpegauth == 1) - { - Cs2Area->reg.HIRQ |= CDB_HIRQ_MPED; - Cs2Area->mpgauth = 2; - } - else - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS | CDB_HIRQ_CSCT; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CmdE1(void) { - Cs2Area->reg.CR1 = (Cs2Area->status << 8); - if (Cs2Area->reg.CR2) - Cs2Area->reg.CR2 = Cs2Area->mpgauth; - else - Cs2Area->reg.CR2 = Cs2Area->satauth; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CmdE2(void) { - u16 i; - FILE * mpgfp; - partition_struct * mpgpartition; - - // fix me - Cs2Area->mpgauth |= 0x300; - - Cs2Area->outconmpegrom = Cs2Area->filter + 0; - Cs2Area->outconmpegromnum = 0; - - if (Cs2Area->mpegpath && (mpgfp = fopen(Cs2Area->mpegpath, "rb")) != NULL) - { - u32 readoffset = ((Cs2Area->reg.CR1 & 0xFF) << 8) | Cs2Area->reg.CR2; - u16 readsize = Cs2Area->reg.CR4; - - fseek(mpgfp, readoffset * Cs2Area->getsectsize, SEEK_SET); - if ((mpgpartition = Cs2GetPartition(Cs2Area->outconmpegrom)) != NULL && !Cs2Area->isbufferfull) - { - IOCheck_struct check; - mpgpartition->size = 0; - - for (i = 0; i < readsize; i++) - { - mpgpartition->block[mpgpartition->numblocks] = Cs2AllocateBlock(&mpgpartition->blocknum[mpgpartition->numblocks]); - - if (mpgpartition->block[mpgpartition->numblocks] != NULL) { - // read data - yread(&check, (void *)mpgpartition->block[mpgpartition->numblocks]->data, 1, Cs2Area->getsectsize, mpgfp); - - mpgpartition->numblocks++; - mpgpartition->size += Cs2Area->getsectsize; - } - } - - Cs2Area->isonesectorstored = 1; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CSCT; - } - - fclose(mpgfp); - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPED; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 Cs2FADToTrack(u32 val) { - int i; - for (i = 0; i < 99; i++) - { - if (Cs2Area->TOC[i] == 0xFFFFFFFF) return 0xFF; - - if (val >= (Cs2Area->TOC[i] & 0xFFFFFF) && val < (Cs2Area->TOC[i + 1] & 0xFFFFFF)) - return (i + 1); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 Cs2TrackToFAD(u16 trackandindex) { - if (trackandindex == 0xFFFF) - // leadout position - return (Cs2Area->TOC[101] & 0x00FFFFFF); - if (trackandindex != 0x0000) - { - // regular track - // (really, we should be fetching subcode q's here) - if ((trackandindex & 0xFF) == 0x01) - // Return Start of Track - return (Cs2Area->TOC[(trackandindex >> 8) - 1] & 0x00FFFFFF); - else if ((trackandindex & 0xFF) == 0x63) - // Return End of Track - return ((Cs2Area->TOC[(trackandindex >> 8)] & 0x00FFFFFF) - 1); - } - - // assume it's leadin - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetupDefaultPlayStats(u8 track_number, int writeFAD) { - if (track_number != 0xFF) - { - Cs2Area->options = 0; - Cs2Area->repcnt = 0; - Cs2Area->ctrladdr = (u8)(Cs2Area->TOC[track_number - 1] >> 24); - Cs2Area->index = 1; - Cs2Area->track = track_number; - if (writeFAD) - Cs2Area->FAD = Cs2Area->TOC[track_number - 1] & 0x00FFFFFF; - } -} - -////////////////////////////////////////////////////////////////////////////// - -block_struct * Cs2AllocateBlock(u8 * blocknum) { - u32 i; - // find a free block - for(i = 0; i < 200; i++) - { - if (Cs2Area->block[i].size == -1) - { - Cs2Area->blockfreespace--; - - if (Cs2Area->blockfreespace <= 0) Cs2Area->isbufferfull = 1; - - Cs2Area->block[i].size = Cs2Area->getsectsize; - - *blocknum = (u8)i; - return (Cs2Area->block + i); - } - } - - Cs2Area->isbufferfull = 1; - - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2FreeBlock(block_struct * blk) { - if (blk == NULL) return; - blk->size = -1; - Cs2Area->blockfreespace++; - Cs2Area->isbufferfull = 0; - Cs2Area->reg.HIRQ &= ~CDB_HIRQ_BFUL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SortBlocks(partition_struct * part) { - unsigned int from, to; - - for (from = to = 0; from < MAX_BLOCKS; from++) - { - if (part->block[from] != NULL) - { - if (to != from) - { - part->block[to] = part->block[from]; - } - to++; - } - } - - for (; to < MAX_BLOCKS; to++) { - part->block[to] = NULL; - } -} - -////////////////////////////////////////////////////////////////////////////// - -partition_struct * Cs2GetPartition(filter_struct * curfilter) -{ - // go through various filter conditions here(fix me) - - return &Cs2Area->partition[curfilter->condtrue]; -} - -////////////////////////////////////////////////////////////////////////////// - -partition_struct * Cs2FilterData(filter_struct * curfilter, int isaudio) -{ - int condresults = 1; - partition_struct * fltpartition = NULL; - - // fix me, this is pretty bad. Though I guess it's a start - - for (;;) - { - // detect which type of sector we're dealing with - // If it's not mode 2, ignore the subheader conditions - if (Cs2Area->workblock.data[0xF] == 0x02 && !isaudio) - { - // Mode 2 - // go through various subheader filter conditions here(fix me) - - if (curfilter->mode & 0x01) - { - // File Number Check - if (Cs2Area->workblock.fn != curfilter->fid) - condresults = 0; - } - - if (curfilter->mode & 0x02) - { - // Channel Number Check - if (Cs2Area->workblock.cn != curfilter->chan) - condresults = 0; - } - - if (curfilter->mode & 0x04) - { - // Sub Mode Check - if ((Cs2Area->workblock.sm & curfilter->smmask) != curfilter->smval) - condresults = 0; - } - - if (curfilter->mode & 0x08) - { - // Coding Information Check - CDLOG("cs2\t: FilterData: Coding Information Check. Coding Information = %02X. Filter's Coding Information Mask = %02X, Coding Information Value = %02X\n", Cs2Area->workblock.ci, curfilter->cimask, curfilter->cival); - if ((Cs2Area->workblock.ci & curfilter->cimask) != curfilter->cival) - condresults = 0; - } - - if (curfilter->mode & 0x10) - { - // Reverse Subheader Conditions - CDLOG("cs2\t: FilterData: Reverse Subheader Conditions\n"); - condresults ^= 1; - } - } - - if (curfilter->mode & 0x40) - { - // FAD Range Check - if (Cs2Area->workblock.FAD < curfilter->FAD || - Cs2Area->workblock.FAD > (curfilter->FAD+curfilter->range)) - condresults = 0; - } - - if (condresults == 1) - { - Cs2Area->lastbuffer = curfilter->condtrue; - fltpartition = &Cs2Area->partition[curfilter->condtrue]; - break; - } - else - { - Cs2Area->lastbuffer = curfilter->condfalse; - - if (curfilter->condfalse == 0xFF) - return NULL; - // loop and try filter that was connected to the false connector - curfilter = &Cs2Area->filter[curfilter->condfalse]; - } - } - - // Allocate block - fltpartition->block[fltpartition->numblocks] = Cs2AllocateBlock(&fltpartition->blocknum[fltpartition->numblocks]); - - if (fltpartition->block[fltpartition->numblocks] == NULL) - return NULL; - - // Copy workblock settings to allocated block - fltpartition->block[fltpartition->numblocks]->size = Cs2Area->workblock.size; - fltpartition->block[fltpartition->numblocks]->FAD = Cs2Area->workblock.FAD; - fltpartition->block[fltpartition->numblocks]->cn = Cs2Area->workblock.cn; - fltpartition->block[fltpartition->numblocks]->fn = Cs2Area->workblock.fn; - fltpartition->block[fltpartition->numblocks]->sm = Cs2Area->workblock.sm; - fltpartition->block[fltpartition->numblocks]->ci = Cs2Area->workblock.ci; - - // convert raw sector to type specified in getsectsize - switch(Cs2Area->workblock.size) - { - case 2048: // user data only - if (Cs2Area->workblock.data[0xF] == 0x02) - // m2f1 - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 24, Cs2Area->workblock.size); - else - // m1 - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 16, Cs2Area->workblock.size); - break; - case 2324: // m2f2 user data only - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 24, Cs2Area->workblock.size); - break; - case 2336: // m2f2 skip sync+header data - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 16, Cs2Area->workblock.size); - break; - case 2340: // m2f2 skip sync data - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 12, Cs2Area->workblock.size); - break; - case 2352: // Copy data as is - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data, Cs2Area->workblock.size); - break; - default: break; - } - - // Modify Partition values - if (fltpartition->size == -1) fltpartition->size = 0; - fltpartition->size += fltpartition->block[fltpartition->numblocks]->size; - fltpartition->numblocks++; - - return fltpartition; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2CopyDirRecord(u8 * buffer, dirrec_struct * dirrec) -{ - u8 * temp_pointer; - - temp_pointer = buffer; - - memcpy(&dirrec->recordsize, buffer, sizeof(dirrec->recordsize)); - buffer += sizeof(dirrec->recordsize); - - memcpy(&dirrec->xarecordsize, buffer, sizeof(dirrec->xarecordsize)); - buffer += sizeof(dirrec->xarecordsize); - -#ifdef WORDS_BIGENDIAN - buffer += sizeof(dirrec->lba); - memcpy(&dirrec->lba, buffer, sizeof(dirrec->lba)); - buffer += sizeof(dirrec->lba); -#else - memcpy(&dirrec->lba, buffer, sizeof(dirrec->lba)); - buffer += (sizeof(dirrec->lba) * 2); -#endif - -#ifdef WORDS_BIGENDIAN - buffer += sizeof(dirrec->size); - memcpy(&dirrec->size, buffer, sizeof(dirrec->size)); - buffer += sizeof(dirrec->size); -#else - memcpy(&dirrec->size, buffer, sizeof(dirrec->size)); - buffer += (sizeof(dirrec->size) * 2); -#endif - - dirrec->dateyear = buffer[0]; - dirrec->datemonth = buffer[1]; - dirrec->dateday = buffer[2]; - dirrec->datehour = buffer[3]; - dirrec->dateminute = buffer[4]; - dirrec->datesecond = buffer[5]; - dirrec->gmtoffset = buffer[6]; - buffer += 7; - - dirrec->flags = buffer[0]; - buffer += sizeof(dirrec->flags); - - dirrec->fileunitsize = buffer[0]; - buffer += sizeof(dirrec->fileunitsize); - - dirrec->interleavegapsize = buffer[0]; - buffer += sizeof(dirrec->interleavegapsize); - -#ifdef WORDS_BIGENDIAN - buffer += sizeof(dirrec->volumesequencenumber); - memcpy(&dirrec->volumesequencenumber, buffer, sizeof(dirrec->volumesequencenumber)); - buffer += sizeof(dirrec->volumesequencenumber); -#else - memcpy(&dirrec->volumesequencenumber, buffer, sizeof(dirrec->volumesequencenumber)); - buffer += (sizeof(dirrec->volumesequencenumber) * 2); -#endif - - dirrec->namelength = buffer[0]; - buffer += sizeof(dirrec->namelength); - - memset(dirrec->name, 0, sizeof(dirrec->name)); - memcpy(dirrec->name, buffer, dirrec->namelength); - buffer += dirrec->namelength; - - // handle padding - buffer += (1 - dirrec->namelength % 2); - - memset(&dirrec->xarecord, 0, sizeof(dirrec->xarecord)); - - // sadily, this is the best way I can think of for detecting XA records - - if ((dirrec->recordsize - (buffer - temp_pointer)) == 14) - { - memcpy(&dirrec->xarecord.groupid, buffer, sizeof(dirrec->xarecord.groupid)); - buffer += sizeof(dirrec->xarecord.groupid); - - memcpy(&dirrec->xarecord.userid, buffer, sizeof(dirrec->xarecord.userid)); - buffer += sizeof(dirrec->xarecord.userid); - - memcpy(&dirrec->xarecord.attributes, buffer, sizeof(dirrec->xarecord.attributes)); - buffer += sizeof(dirrec->xarecord.attributes); - -#ifndef WORDS_BIGENDIAN - // byte swap it - dirrec->xarecord.attributes = ((dirrec->xarecord.attributes & 0xFF00) >> 8) + - ((dirrec->xarecord.attributes & 0x00FF) << 8); -#endif - - memcpy(&dirrec->xarecord.signature, buffer, sizeof(dirrec->xarecord.signature)); - buffer += sizeof(dirrec->xarecord.signature); - - memcpy(&dirrec->xarecord.filenumber, buffer, sizeof(dirrec->xarecord.filenumber)); - buffer += sizeof(dirrec->xarecord.filenumber); - - memcpy(dirrec->xarecord.reserved, buffer, sizeof(dirrec->xarecord.reserved)); - buffer += sizeof(dirrec->xarecord.reserved); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2ReadFileSystem(filter_struct * curfilter, u32 fid, int isoffset) -{ - u8 * workbuffer; - u32 i; - dirrec_struct dirrec; - u8 numsectorsleft = 0; - u32 curdirlba = 0; - partition_struct * rfspartition; - u32 blocksectsize = Cs2Area->getsectsize; - - Cs2Area->outconcddev = curfilter; - - if (isoffset) - { - // readDirectory operation - - // make sure we have a valid current directory - if (Cs2Area->curdirsect == 0) - return -1; - - Cs2Area->curdirfidoffset = fid - 2; - curdirlba = Cs2Area->curdirsect; - numsectorsleft = (u8)Cs2Area->curdirsize; - } - else - { - // changeDirectory operation - - if (fid == 0xFFFFFF) - { - // Figure out root directory's location - - // Read sector 16 - if ((rfspartition = Cs2ReadUnFilteredSector(166)) == NULL) - return -2; - - blocksectsize = rfspartition->block[rfspartition->numblocks - 1]->size; - - // Retrieve directory record's lba - Cs2CopyDirRecord(rfspartition->block[rfspartition->numblocks - 1]->data + 0x9C, &dirrec); - - // Free Block - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - - curdirlba = Cs2Area->curdirsect = dirrec.lba; - Cs2Area->curdirsize = (dirrec.size / blocksectsize) - 1; - numsectorsleft = (u8)Cs2Area->curdirsize; - Cs2Area->curdirfidoffset = 0; - } - else - { - // Read in new directory record of specified directory - - // make sure we have a valid current directory - if (Cs2Area->curdirsect == 0) - return -1; - - curdirlba = Cs2Area->curdirsect = Cs2Area->fileinfo[fid - Cs2Area->curdirfidoffset].lba - 150; - Cs2Area->curdirsize = (Cs2Area->fileinfo[fid - Cs2Area->curdirfidoffset].size / blocksectsize) - 1; - numsectorsleft = (u8)Cs2Area->curdirsize; - Cs2Area->curdirfidoffset = 0; - } - } - - // Make sure any old records are cleared - memset(Cs2Area->fileinfo, 0, sizeof(dirrec_struct) * MAX_FILES); - - // now read in first sector of directory record - if ((rfspartition = Cs2ReadUnFilteredSector(curdirlba+150)) == NULL) - return -2; - - curdirlba++; - workbuffer = rfspartition->block[rfspartition->numblocks - 1]->data; - - // Fill in first two entries of fileinfo - for (i = 0; i < 2; i++) - { - Cs2CopyDirRecord(workbuffer, Cs2Area->fileinfo + i); - Cs2Area->fileinfo[i].lba += 150; - workbuffer += Cs2Area->fileinfo[i].recordsize; - - if (workbuffer[0] == 0) - { - Cs2Area->numfiles = i; - break; - } - } - - // If doing a ReadDirectory operation, parse sector entries until we've - // found the fid that matches fid - if (isoffset) - { - for (i = 2; i < fid; i++) - { - Cs2CopyDirRecord(workbuffer, Cs2Area->fileinfo + 2); - workbuffer += Cs2Area->fileinfo[2].recordsize; - - if (workbuffer[0] == 0) - { - if (numsectorsleft > 0) - { - // Free previous read sector - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - - // Read in next sector of directory record - if ((rfspartition = Cs2ReadUnFilteredSector(curdirlba+150)) == NULL) - return -2; - - curdirlba++; - - numsectorsleft--; - workbuffer = rfspartition->block[rfspartition->numblocks - 1]->data; - } - else - { - break; - } - } - } - } - - // Now generate the last 254 entries(the first two should've already been - // generated earlier) - for (i = 2; i < MAX_FILES; i++) - { - Cs2CopyDirRecord(workbuffer, Cs2Area->fileinfo + i); - Cs2Area->fileinfo[i].lba += 150; - workbuffer += Cs2Area->fileinfo[i].recordsize; - - if (workbuffer[0] == 0) - { - if (numsectorsleft > 0) - { - // Free previous read sector - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - - // Read in next sector of directory record - if ((rfspartition = Cs2ReadUnFilteredSector(curdirlba+150)) == NULL) - return -2; - - curdirlba++; - numsectorsleft--; - workbuffer = rfspartition->block[rfspartition->numblocks - 1]->data; - } - else - { - Cs2Area->numfiles = i; - break; - } - } - } - - // Free the remaining sector - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - -//#if CDDEBUG -// for (i = 0; i < MAX_FILES; i++) -// { -// CDLOG("fileinfo[%d].name = %s\n", i, Cs2Area->fileinfo[i].name); -// } -//#endif - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetupFileInfoTransfer(u32 fid) { - Cs2Area->transfileinfo[0] = (u8)(Cs2Area->fileinfo[fid].lba >> 24); - Cs2Area->transfileinfo[1] = (u8)(Cs2Area->fileinfo[fid].lba >> 16); - Cs2Area->transfileinfo[2] = (u8)(Cs2Area->fileinfo[fid].lba >> 8); - Cs2Area->transfileinfo[3] = (u8)Cs2Area->fileinfo[fid].lba; - - Cs2Area->transfileinfo[4] = (u8)(Cs2Area->fileinfo[fid].size >> 24); - Cs2Area->transfileinfo[5] = (u8)(Cs2Area->fileinfo[fid].size >> 16); - Cs2Area->transfileinfo[6] = (u8)(Cs2Area->fileinfo[fid].size >> 8); - Cs2Area->transfileinfo[7] = (u8)Cs2Area->fileinfo[fid].size; - - Cs2Area->transfileinfo[8] = Cs2Area->fileinfo[fid].interleavegapsize; - Cs2Area->transfileinfo[9] = Cs2Area->fileinfo[fid].fileunitsize; - Cs2Area->transfileinfo[10] = (u8) fid; - Cs2Area->transfileinfo[11] = Cs2Area->fileinfo[fid].flags; -} - -////////////////////////////////////////////////////////////////////////////// - -partition_struct * Cs2ReadUnFilteredSector(u32 rufsFAD) { - partition_struct * rufspartition; - char syncheader[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00}; - - if ((rufspartition = Cs2GetPartition(Cs2Area->outconcddev)) != NULL && !Cs2Area->isbufferfull) - { - // Allocate Block - rufspartition->block[rufspartition->numblocks] = Cs2AllocateBlock(&rufspartition->blocknum[rufspartition->numblocks]); - - if (rufspartition->block[rufspartition->numblocks] == NULL) - return NULL; - - // read a sector using cd interface function - if (!Cs2Area->cdi->ReadSectorFAD(rufsFAD, Cs2Area->workblock.data)) - return NULL; - - // convert raw sector to type specified in getsectsize - switch(Cs2Area->getsectsize) - { - case 2048: // user data only - if (Cs2Area->workblock.data[0xF] == 0x02) - { - // is it form1/form2 data? - if (!(Cs2Area->workblock.data[0x12] & 0x20)) - { - // form 1 - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 24, 2048); - Cs2Area->workblock.size = Cs2Area->getsectsize; - } - else - { - // form 2 - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 24, 2324); - Cs2Area->workblock.size = 2324; - } - } - else - { - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 16, 2048); - Cs2Area->workblock.size = Cs2Area->getsectsize; - } - break; - case 2336: // skip sync+header data - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 16, 2336); - Cs2Area->workblock.size = Cs2Area->getsectsize; - break; - case 2340: // skip sync data - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 12, 2340); - Cs2Area->workblock.size = Cs2Area->getsectsize; - break; - case 2352: // no conversion needed - Cs2Area->workblock.size = Cs2Area->getsectsize; - break; - default: break; - } - - // if mode 2 track, setup the subheader values - if (memcmp(syncheader, Cs2Area->workblock.data, 12) == 0 && - Cs2Area->workblock.data[0xF] == 0x02) - { - rufspartition->block[rufspartition->numblocks]->fn = Cs2Area->workblock.data[0x10]; - rufspartition->block[rufspartition->numblocks]->cn = Cs2Area->workblock.data[0x11]; - rufspartition->block[rufspartition->numblocks]->sm = Cs2Area->workblock.data[0x12]; - rufspartition->block[rufspartition->numblocks]->ci = Cs2Area->workblock.data[0x13]; - } - - Cs2Area->workblock.FAD = rufsFAD; - - // Modify Partition values - if (rufspartition->size == -1) rufspartition->size = 0; - rufspartition->size += rufspartition->block[rufspartition->numblocks]->size; - rufspartition->numblocks++; - - return rufspartition; - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2ReadFilteredSector(u32 rfsFAD, partition_struct **partition) { - char syncheader[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00}; - int isaudio = 0; - - if (Cs2Area->outconcddev != NULL && !Cs2Area->isbufferfull) - { - // read a sector using cd interface function to workblock.data - if (!Cs2Area->cdi->ReadSectorFAD(rfsFAD, Cs2Area->workblock.data)) - { - *partition = NULL; - return -2; - } - - Cs2Area->workblock.size = Cs2Area->getsectsize; - Cs2Area->workblock.FAD = rfsFAD; - - if (memcmp(syncheader, Cs2Area->workblock.data, 12) != 0) isaudio = 1; - - // force 1x speed if reading from an audio track - Cs2Area->isaudio = isaudio; - Cs2SetTiming(1); - - // if mode 2 track, setup the subheader values - if (isaudio) - { - ScspReceiveCDDA(Cs2Area->workblock.data); - *partition = NULL; - return 0; - } - else if (Cs2Area->workblock.data[0xF] == 0x02) - { - // if it's form 2 data the sector size should be 2324 - if (Cs2Area->workblock.data[0x12] & 0x20) Cs2Area->workblock.size = 2324; - - Cs2Area->workblock.fn = Cs2Area->workblock.data[0x10]; - Cs2Area->workblock.cn = Cs2Area->workblock.data[0x11]; - Cs2Area->workblock.sm = Cs2Area->workblock.data[0x12]; - Cs2Area->workblock.ci = Cs2Area->workblock.data[0x13]; - } - - - // pass workblock to filter function(after it identifies partition, - // it should allocate the partition block, setup/change the partition - // values, and copy workblock to the allocated block) - *partition = Cs2FilterData(Cs2Area->outconcddev, isaudio); - return 0; - } - - *partition = NULL; - return -1; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 Cs2GetIP(int autoregion) { - partition_struct * gripartition; - u8 ret = 0; - - Cs2Area->outconcddev = Cs2Area->filter + 0; - Cs2Area->outconcddevnum = 0; - - // read in lba 0/FAD 150 - if ((gripartition = Cs2ReadUnFilteredSector(150)) != NULL) - { - char *buf=(char*)gripartition->block[gripartition->numblocks - 1]->data; - - // Make sure we're dealing with a saturn game - if (memcmp(buf, "SEGA SEGASATURN", 15) == 0) - { - memcpy(cdip->system, buf, 16); - cdip->system[16]='\0'; - memcpy(cdip->company, buf+0x10, 16); - cdip->company[16]='\0'; - sscanf(buf+0x20, "%s", cdip->itemnum); - memcpy(cdip->version, buf+0x2A, 6); - cdip->version[6]='\0'; - sprintf(cdip->date, "%c%c/%c%c/%c%c%c%c", buf[0x34], buf[0x35], buf[0x36], buf[0x37], buf[0x30], buf[0x31], buf[0x32], buf[0x33]); - sscanf(buf+0x38, "%s", cdip->cdinfo); - sscanf(buf+0x40, "%s", cdip->region); - sscanf(buf+0x50, "%s", cdip->peripheral); - memcpy(cdip->gamename, buf+0x60, 112); - cdip->gamename[112]='\0'; -#ifdef WORDS_BIGENDIAN - memcpy(&cdip->ipsize, buf+0xE0, sizeof(u32)); - memcpy(&cdip->msh2stack, buf+0xE8, sizeof(u32)); - memcpy(&cdip->ssh2stack, buf+0xEC, sizeof(u32)); - memcpy(&cdip->firstprogaddr, buf+0xF0, sizeof(u32)); - memcpy(&cdip->firstprogsize, buf+0xF4, sizeof(u32)); -#else - cdip->ipsize = (buf[0xE0] << 24) | (buf[0xE1] << 16) | - (buf[0xE2] << 8) | buf[0xE3]; - cdip->msh2stack = (buf[0xE8] << 24) | (buf[0xE9] << 16) | - (buf[0xEA] << 8) | buf[0xEB]; - cdip->ssh2stack = (buf[0xEC] << 24) | (buf[0xED] << 16) | - (buf[0xEE] << 8) | buf[0xEF]; - cdip->firstprogaddr = (buf[0xF0] << 24) | (buf[0xF1] << 16) | - (buf[0xF2] << 8) | buf[0xF3]; - cdip->firstprogsize = (buf[0xF4] << 24) | (buf[0xF5] << 16) | - (buf[0xF6] << 8) | buf[0xF7]; -#endif - - if (autoregion) - { - // Read first available region, that'll be what we'll use - switch (cdip->region[0]) - { - case 'J': - ret = 1; - break; - case 'T': - ret = 2; - break; - case 'U': - ret = 4; - break; - case 'B': - ret = 5; - break; - case 'K': - ret = 6; - break; - case 'A': - ret = 0xA; - break; - case 'E': - ret = 0xC; - break; - case 'L': - ret = 0xD; - break; - default: break; - } - } - } - - // Free Block - gripartition->size -= gripartition->block[gripartition->numblocks - 1]->size; - Cs2FreeBlock(gripartition->block[gripartition->numblocks - 1]); - gripartition->blocknum[gripartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(gripartition); - gripartition->numblocks -= 1; - } - - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 Cs2GetRegionID(void) -{ - return Cs2GetIP(1); -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2SaveState(FILE * fp) { - int offset, i; - IOCheck_struct check; - - // This is mostly kludge, but it will have to do until I have time to rewrite it all - - offset = StateWriteHeader(fp, "CS2 ", 2); - - // Write cart type - ywrite(&check, (void *) &Cs2Area->carttype, 4, 1, fp); - - // Write cd block registers - ywrite(&check, (void *) &Cs2Area->reg, sizeof(blockregs_struct), 1, fp); - - // Write current Status variables(needs a rewrite) - ywrite(&check, (void *) &Cs2Area->FAD, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->status, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->options, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->repcnt, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->ctrladdr, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->track, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->index, 1, 1, fp); - - // Write other cd block internal variables - ywrite(&check, (void *) &Cs2Area->satauth, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->mpgauth, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->transfercount, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->cdwnum, 4, 1, fp); - ywrite(&check, (void *) Cs2Area->TOC, 4, 102, fp); - ywrite(&check, (void *) &Cs2Area->playFAD, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->playendFAD, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->getsectsize, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->putsectsize, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->calcsize, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->infotranstype, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatranstype, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->isonesectorstored, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->isdiskchanged, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->isbufferfull, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->speed1x, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->isaudio, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->transfileinfo, 1, 12, fp); - ywrite(&check, (void *) &Cs2Area->lastbuffer, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->_command, 1, 1, fp); - { - u32 temp = (Cs2Area->_periodictiming + 3) / 3; - ywrite(&check, (void *) &temp, 4, 1, fp); - } - ywrite(&check, (void *) &Cs2Area->_commandtiming, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconcddevnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconmpegfbnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconmpegbufnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconmpegromnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconhostnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatranspartitionnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatransoffset, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->datanumsecttrans, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatranssectpos, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->datasectstotrans, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->blockfreespace, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->curdirsect, 4, 1, fp); - - // Write CD buffer - ywrite(&check, (void *)Cs2Area->block, sizeof(block_struct), MAX_BLOCKS, fp); - - // Write partition data - for (i = 0; i < MAX_SELECTORS; i++) - { - ywrite(&check, (void *)&Cs2Area->partition[i].size, 4, 1, fp); - ywrite(&check, (void *)Cs2Area->partition[i].blocknum, 1, MAX_BLOCKS, fp); - ywrite(&check, (void *)&Cs2Area->partition[i].numblocks, 1, 1, fp); - } - - // Write filter data - ywrite(&check, (void *)Cs2Area->filter, sizeof(filter_struct), MAX_SELECTORS, fp); - - // Write File Info Table - ywrite(&check, (void *)Cs2Area->fileinfo, sizeof(dirrec_struct), MAX_FILES, fp); - - // Write MPEG card registers here - - // Write current MPEG card status variables - ywrite(&check, (void *)&Cs2Area->actionstatus, 1, 1, fp); - ywrite(&check, (void *)&Cs2Area->pictureinfo, 1, 1, fp); - ywrite(&check, (void *)&Cs2Area->mpegaudiostatus, 1, 1, fp); - ywrite(&check, (void *)&Cs2Area->mpegvideostatus, 2, 1, fp); - ywrite(&check, (void *)&Cs2Area->vcounter, 2, 1, fp); - - // Write other MPEG card internal variables - ywrite(&check, (void *)&Cs2Area->mpegintmask, 4, 1, fp); - ywrite(&check, (void *)Cs2Area->mpegcon, sizeof(mpegcon_struct), 2, fp); - ywrite(&check, (void *)Cs2Area->mpegstm, sizeof(mpegstm_struct), 2, fp); - - return StateFinishHeader(fp, offset); -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2LoadState(FILE * fp, int version, int size) { - int i, i2; - IOCheck_struct check; - - // This is mostly kludge, but it will have to do until I have time to rewrite it all - - // Read cart type - yread(&check, (void *)&Cs2Area->carttype, 4, 1, fp); - - // Read cd block registers - yread(&check, (void *)&Cs2Area->reg, sizeof(blockregs_struct), 1, fp); - - // Read current Status variables(needs a reRead) - yread(&check, (void *)&Cs2Area->FAD, 4, 1, fp); - yread(&check, (void *)&Cs2Area->status, 1, 1, fp); - yread(&check, (void *)&Cs2Area->options, 1, 1, fp); - yread(&check, (void *)&Cs2Area->repcnt, 1, 1, fp); - yread(&check, (void *)&Cs2Area->ctrladdr, 1, 1, fp); - yread(&check, (void *)&Cs2Area->track, 1, 1, fp); - yread(&check, (void *)&Cs2Area->index, 1, 1, fp); - - // Read other cd block internal variables - yread(&check, (void *)&Cs2Area->satauth, 2, 1, fp); - yread(&check, (void *)&Cs2Area->mpgauth, 2, 1, fp); - yread(&check, (void *)&Cs2Area->transfercount, 4, 1, fp); - yread(&check, (void *)&Cs2Area->cdwnum, 4, 1, fp); - yread(&check, (void *)Cs2Area->TOC, 4, 102, fp); - yread(&check, (void *)&Cs2Area->playFAD, 4, 1, fp); - yread(&check, (void *)&Cs2Area->playendFAD, 4, 1, fp); - yread(&check, (void *)&Cs2Area->getsectsize, 4, 1, fp); - yread(&check, (void *)&Cs2Area->putsectsize, 4, 1, fp); - yread(&check, (void *)&Cs2Area->calcsize, 4, 1, fp); - yread(&check, (void *)&Cs2Area->infotranstype, 4, 1, fp); - yread(&check, (void *)&Cs2Area->datatranstype, 4, 1, fp); - yread(&check, (void *)&Cs2Area->isonesectorstored, 1, 1, fp); - yread(&check, (void *)&Cs2Area->isdiskchanged, 1, 1, fp); - yread(&check, (void *)&Cs2Area->isbufferfull, 1, 1, fp); - yread(&check, (void *)&Cs2Area->speed1x, 1, 1, fp); - if (version > 1) - yread(&check, (void *)&Cs2Area->isaudio, 1, 1, fp); - yread(&check, (void *)&Cs2Area->transfileinfo, 1, 12, fp); - yread(&check, (void *)&Cs2Area->lastbuffer, 1, 1, fp); - yread(&check, (void *)&Cs2Area->_command, 1, 1, fp); - { - u32 temp; - yread(&check, (void *)&temp, 4, 1, fp); - // Derive the actual, accurate value (always a multiple of 10) - Cs2Area->_periodictiming = ((temp * 3) / 10) * 10; - } - yread(&check, (void *)&Cs2Area->_commandtiming, 4, 1, fp); - yread(&check, (void *)&Cs2Area->outconcddevnum, 1, 1, fp); - if (Cs2Area->outconcddevnum == 0xFF) - Cs2Area->outconcddev = NULL; - else - Cs2Area->outconcddev = Cs2Area->filter + Cs2Area->outconcddevnum; - - yread(&check, (void *)&Cs2Area->outconmpegfbnum, 1, 1, fp); - if (Cs2Area->outconmpegfbnum == 0xFF) - Cs2Area->outconmpegfb = NULL; - else - Cs2Area->outconmpegfb = Cs2Area->filter + Cs2Area->outconmpegfbnum; - - yread(&check, (void *)&Cs2Area->outconmpegbufnum, 1, 1, fp); - if (Cs2Area->outconmpegbufnum == 0xFF) - Cs2Area->outconmpegbuf = NULL; - else - Cs2Area->outconmpegbuf = Cs2Area->filter + Cs2Area->outconmpegbufnum; - - yread(&check, (void *)&Cs2Area->outconmpegromnum, 1, 1, fp); - if (Cs2Area->outconmpegromnum == 0xFF) - Cs2Area->outconmpegrom = NULL; - else - Cs2Area->outconmpegrom = Cs2Area->filter + Cs2Area->outconmpegromnum; - - yread(&check, (void *)&Cs2Area->outconhostnum, 1, 1, fp); - if (Cs2Area->outconhostnum == 0xFF) - Cs2Area->outconhost = NULL; - else - Cs2Area->outconhost = Cs2Area->filter + Cs2Area->outconhostnum; - - yread(&check, (void *)&Cs2Area->datatranspartitionnum, 1, 1, fp); - yread(&check, (void *)&Cs2Area->datatransoffset, 4, 1, fp); - yread(&check, (void *)&Cs2Area->datanumsecttrans, 4, 1, fp); - yread(&check, (void *)&Cs2Area->datatranssectpos, 2, 1, fp); - yread(&check, (void *)&Cs2Area->datasectstotrans, 2, 1, fp); - yread(&check, (void *)&Cs2Area->blockfreespace, 4, 1, fp); - yread(&check, (void *)&Cs2Area->curdirsect, 4, 1, fp); - - // Read CD buffer - yread(&check, (void *)Cs2Area->block, sizeof(block_struct), MAX_BLOCKS, fp); - - // Read partition data - for (i = 0; i < MAX_SELECTORS; i++) - { - yread(&check, (void *)&Cs2Area->partition[i].size, 4, 1, fp); - yread(&check, (void *)Cs2Area->partition[i].blocknum, 1, MAX_BLOCKS, fp); - yread(&check, (void *)&Cs2Area->partition[i].numblocks, 1, 1, fp); - - for (i2 = 0; i2 < MAX_BLOCKS; i2++) - { - if (Cs2Area->partition[i].blocknum[i2] == 0xFF) - Cs2Area->partition[i].block[i2] = NULL; - else - Cs2Area->partition[i].block[i2] = Cs2Area->block + Cs2Area->partition[i].blocknum[i2]; - } - } - - // Read filter data - yread(&check, (void *)Cs2Area->filter, sizeof(filter_struct), MAX_SELECTORS, fp); - - // Read File Info Table - yread(&check, (void *)Cs2Area->fileinfo, sizeof(dirrec_struct), MAX_FILES, fp); - - // Read MPEG card registers here - - // Read current MPEG card status variables - yread(&check, (void *)&Cs2Area->actionstatus, 1, 1, fp); - yread(&check, (void *)&Cs2Area->pictureinfo, 1, 1, fp); - yread(&check, (void *)&Cs2Area->mpegaudiostatus, 1, 1, fp); - yread(&check, (void *)&Cs2Area->mpegvideostatus, 2, 1, fp); - yread(&check, (void *)&Cs2Area->vcounter, 2, 1, fp); - - // Read other MPEG card internal variables - yread(&check, (void *)&Cs2Area->mpegintmask, 4, 1, fp); - yread(&check, (void *)Cs2Area->mpegcon, sizeof(mpegcon_struct), 2, fp); - yread(&check, (void *)Cs2Area->mpegstm, sizeof(mpegstm_struct), 2, fp); - - return size; -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/cs2.h b/yabause/src/cs2.h deleted file mode 100644 index 2c0a494242..0000000000 --- a/yabause/src/cs2.h +++ /dev/null @@ -1,359 +0,0 @@ -/* Copyright 2003 Guillaume Duhamel - Copyright 2004-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CS2_H -#define CS2_H - -#include "memory.h" -#include "cdbase.h" -#include "cs0.h" - -#define MAX_BLOCKS 200 -#define MAX_SELECTORS 24 -#define MAX_FILES 256 - -typedef struct -{ - s32 size; - u32 FAD; - u8 cn; - u8 fn; - u8 sm; - u8 ci; - u8 data[2352]; -} block_struct; - -typedef struct -{ - u32 FAD; - u32 range; - u8 mode; - u8 chan; - u8 smmask; - u8 cimask; - u8 fid; - u8 smval; - u8 cival; - u8 condtrue; - u8 condfalse; -} filter_struct; - -typedef struct -{ - s32 size; - block_struct *block[MAX_BLOCKS]; - u8 blocknum[MAX_BLOCKS]; - u8 numblocks; -} partition_struct; - -typedef struct -{ - u16 groupid; - u16 userid; - u16 attributes; - u16 signature; - u8 filenumber; - u8 reserved[5]; -} xarec_struct; - -typedef struct -{ - u8 recordsize; - u8 xarecordsize; - u32 lba; - u32 size; - u8 dateyear; - u8 datemonth; - u8 dateday; - u8 datehour; - u8 dateminute; - u8 datesecond; - u8 gmtoffset; - u8 flags; - u8 fileunitsize; - u8 interleavegapsize; - u16 volumesequencenumber; - u8 namelength; - char name[32]; - xarec_struct xarecord; -} dirrec_struct; - -typedef struct -{ - u8 audcon; - u8 audlay; - u8 audbufdivnum; - u8 vidcon; - u8 vidlay; - u8 vidbufdivnum; -} mpegcon_struct; - -typedef struct -{ - u8 audstm; - u8 audstmid; - u8 audchannum; - u8 vidstm; - u8 vidstmid; - u8 vidchannum; -} mpegstm_struct; - -typedef struct -{ - u32 DTR; - u16 UNKNOWN; - u16 HIRQ; - u16 HIRQMASK; // Masks bits from HIRQ -only- when generating A-bus interrupts - u16 CR1; - u16 CR2; - u16 CR3; - u16 CR4; - u16 MPEGRGB; -} blockregs_struct; - -typedef struct { - blockregs_struct reg; - u32 FAD; - u8 status; - - // cd specific stats - u8 options; - u8 repcnt; - u8 ctrladdr; - u8 track; - u8 index; - - // mpeg specific stats - u8 actionstatus; - u8 pictureinfo; - u8 mpegaudiostatus; - u16 mpegvideostatus; - u16 vcounter; - - // authentication variables - u16 satauth; - u16 mpgauth; - - // internal varaibles - u32 transfercount; - u32 cdwnum; - u32 TOC[102]; - u32 playFAD; - u32 playendFAD; - unsigned int maxrepeat; - u32 getsectsize; - u32 putsectsize; - u32 calcsize; - s32 infotranstype; - s32 datatranstype; - int isonesectorstored; - int isdiskchanged; - int isbufferfull; - int speed1x; - int isaudio; - u8 transfileinfo[12]; - u8 lastbuffer; - - filter_struct filter[MAX_SELECTORS]; - filter_struct *outconcddev; - filter_struct *outconmpegfb; - filter_struct *outconmpegbuf; - filter_struct *outconmpegrom; - filter_struct *outconhost; - u8 outconcddevnum; - u8 outconmpegfbnum; - u8 outconmpegbufnum; - u8 outconmpegromnum; - u8 outconhostnum; - - partition_struct partition[MAX_SELECTORS]; - - partition_struct *datatranspartition; - u8 datatranspartitionnum; - s32 datatransoffset; - u32 datanumsecttrans; - u16 datatranssectpos; - u16 datasectstotrans; - - u32 blockfreespace; - block_struct block[MAX_BLOCKS]; - block_struct workblock; - - u32 curdirsect; - u32 curdirsize; - u32 curdirfidoffset; - dirrec_struct fileinfo[MAX_FILES]; - u32 numfiles; - - const char *mpegpath; - - u32 mpegintmask; - - mpegcon_struct mpegcon[2]; - mpegstm_struct mpegstm[2]; - - int _command; - u32 _periodiccycles; // microseconds * 3 - u32 _periodictiming; // microseconds * 3 - u32 _commandtiming; - CDInterface * cdi; - - int carttype; - int playtype; -} Cs2; - -typedef struct { - char system[17]; - char company[17]; - char itemnum[11]; - char version[7]; - char date[11]; - char cdinfo[9]; - char region[11]; - char peripheral[17]; - char gamename[113]; - u32 ipsize; - u32 msh2stack; - u32 ssh2stack; - u32 firstprogaddr; - u32 firstprogsize; -} ip_struct; - -extern Cs2 * Cs2Area; -extern ip_struct * cdip; - -int Cs2Init(int, int, const char *, const char *, const char *); -int Cs2ChangeCDCore(int coreid, const char *cdpath); -void Cs2DeInit(void); - -u8 FASTCALL Cs2ReadByte(u32); -u16 FASTCALL Cs2ReadWord(u32); -u32 FASTCALL Cs2ReadLong(u32); -void FASTCALL Cs2WriteByte(u32, u8); -void FASTCALL Cs2WriteWord(u32, u16); -void FASTCALL Cs2WriteLong(u32, u32); - -void FASTCALL Cs2RapidCopyT1(void *dest, u32 count); -void FASTCALL Cs2RapidCopyT2(void *dest, u32 count); - -void Cs2Exec(u32); -int Cs2GetTimeToNextSector(void); -void Cs2Execute(void); -void Cs2Reset(void); -void Cs2SetTiming(int); -void Cs2Command(void); -void Cs2SetCommandTiming(u8 cmd); - -// command name command code -void Cs2GetStatus(void); // 0x00 -void Cs2GetHardwareInfo(void); // 0x01 -void Cs2GetToc(void); // 0x02 -void Cs2GetSessionInfo(void); // 0x03 -void Cs2InitializeCDSystem(void); // 0x04 -// Open Tray // 0x05 -void Cs2EndDataTransfer(void); // 0x06 -void Cs2PlayDisc(void); // 0x10 -void Cs2SeekDisc(void); // 0x11 -// Scan Disc // 0x12 -void Cs2GetSubcodeQRW(void); // 0x20 -void Cs2SetCDDeviceConnection(void); // 0x30 -// get CD Device Connection // 0x31 -void Cs2GetLastBufferDestination(void); // 0x32 -void Cs2SetFilterRange(void); // 0x40 -// get Filter Range // 0x41 -void Cs2SetFilterSubheaderConditions(void);// 0x42 -void Cs2GetFilterSubheaderConditions(void);// 0x43 -void Cs2SetFilterMode(void); // 0x44 -void Cs2GetFilterMode(void); // 0x45 -void Cs2SetFilterConnection(void); // 0x46 -// Get Filter Connection // 0x47 -void Cs2ResetSelector(void); // 0x48 -void Cs2GetBufferSize(void); // 0x50 -void Cs2GetSectorNumber(void); // 0x51 -void Cs2CalculateActualSize(void); // 0x52 -void Cs2GetActualSize(void); // 0x53 -void Cs2GetSectorInfo(void); // 0x54 -void Cs2SetSectorLength(void); // 0x60 -void Cs2GetSectorData(void); // 0x61 -void Cs2DeleteSectorData(void); // 0x62 -void Cs2GetThenDeleteSectorData(void); // 0x63 -void Cs2PutSectorData(void); // 0x64 -// Copy Sector Data // 0x65 -// Move Sector Data // 0x66 -void Cs2GetCopyError(void); // 0x67 -void Cs2ChangeDirectory(void); // 0x70 -void Cs2ReadDirectory(void); // 0x71 -void Cs2GetFileSystemScope(void); // 0x72 -void Cs2GetFileInfo(void); // 0x73 -void Cs2ReadFile(void); // 0x74 -void Cs2AbortFile(void); // 0x75 -void Cs2MpegGetStatus(void); // 0x90 -void Cs2MpegGetInterrupt(void); // 0x91 -void Cs2MpegSetInterruptMask(void); // 0x92 -void Cs2MpegInit(void); // 0x93 -void Cs2MpegSetMode(void); // 0x94 -void Cs2MpegPlay(void); // 0x95 -void Cs2MpegSetDecodingMethod(void); // 0x96 -// MPEG Out Decoding Sync // 0x97 -// MPEG Get Timecode // 0x98 -// MPEG Get Pts // 0x99 -void Cs2MpegSetConnection(void); // 0x9A -void Cs2MpegGetConnection(void); // 0x9B -// MPEG Change Connection // 0x9C -void Cs2MpegSetStream(void); // 0x9D -void Cs2MpegGetStream(void); // 0x9E -// MPEG Get Picture Size // 0x9F -void Cs2MpegDisplay(void); // 0xA0 -void Cs2MpegSetWindow(void); // 0xA1 -void Cs2MpegSetBorderColor(void); // 0xA2 -void Cs2MpegSetFade(void); // 0xA3 -void Cs2MpegSetVideoEffects(void); // 0xA4 -// MPEG Get Image // 0xA5 -// MPEG Set Image // 0xA6 -// MPEG Read Image // 0xA7 -// MPEG Write Image // 0xA8 -// MPEG Read Sector // 0xA9 -// MPEG Write Sector // 0xAA -// MPEG Get LSI // 0xAE -void Cs2MpegSetLSI(void); // 0xAF -void Cs2CmdE0(void); // 0xE0 -void Cs2CmdE1(void); // 0xE1 -void Cs2CmdE2(void); // 0xE2 - -u8 Cs2FADToTrack(u32 val); -u32 Cs2TrackToFAD(u16 trackandindex); -void Cs2SetupDefaultPlayStats(u8 track_number, int writeFAD); -block_struct * Cs2AllocateBlock(u8 * blocknum); -void Cs2FreeBlock(block_struct * blk); -void Cs2SortBlocks(partition_struct * part); -partition_struct * Cs2GetPartition(filter_struct * curfilter); -partition_struct * Cs2FilterData(filter_struct * curfilter, int isaudio); -int Cs2CopyDirRecord(u8 * buffer, dirrec_struct * dirrec); -int Cs2ReadFileSystem(filter_struct * curfilter, u32 fid, int isoffset); -void Cs2SetupFileInfoTransfer(u32 fid); -partition_struct * Cs2ReadUnFilteredSector(u32 rufsFAD); -//partition_struct * Cs2ReadFilteredSector(u32 rfsFAD); -int Cs2ReadFilteredSector(u32 rfsFAD, partition_struct **partition); -u8 Cs2GetIP(int autoregion); -u8 Cs2GetRegionID(void); -int Cs2SaveState(FILE *); -int Cs2LoadState(FILE *, int, int); - -#endif diff --git a/yabause/src/debug.c b/yabause/src/debug.c deleted file mode 100644 index 295b21a00e..0000000000 --- a/yabause/src/debug.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "debug.h" - -#include -#include -#include - -////////////////////////////////////////////////////////////////////////////// - -Debug * DebugInit(const char * n, DebugOutType t, char * s) { - Debug * d; - - if ((d = (Debug *) malloc(sizeof(Debug))) == NULL) - return NULL; - - d->output_type = t; - - if ((d->name = strdup(n)) == NULL) - { - free(d); - return NULL; - } - - switch(t) { - case DEBUG_STREAM: - d->output.stream = fopen(s, "w"); - break; - case DEBUG_STRING: - d->output.string = s; - break; - case DEBUG_STDOUT: - d->output.stream = stdout; - break; - case DEBUG_STDERR: - d->output.stream = stderr; - break; - case DEBUG_CALLBACK: - d->output.callback = (void (*) (char*))s; - break; - } - - return d; -} - -////////////////////////////////////////////////////////////////////////////// - -void DebugDeInit(Debug * d) { - if (d == NULL) - return; - - switch(d->output_type) { - case DEBUG_STREAM: - if (d->output.stream) - fclose(d->output.stream); - break; - case DEBUG_STRING: - case DEBUG_STDOUT: - case DEBUG_STDERR: - case DEBUG_CALLBACK: - break; - } - if (d->name) - free(d->name); - free(d); -} - -////////////////////////////////////////////////////////////////////////////// - -void DebugChangeOutput(Debug * d, DebugOutType t, char * s) { - if (t != d->output_type) { - if (d->output_type == DEBUG_STREAM) - { - if (d->output.stream) - fclose(d->output.stream); - } - d->output_type = t; - } - switch(t) { - case DEBUG_STREAM: - d->output.stream = fopen(s, "w"); - break; - case DEBUG_STRING: - d->output.string = s; - break; - case DEBUG_CALLBACK: - d->output.callback = (void (*) (char*))s; - break; - case DEBUG_STDOUT: - d->output.stream = stdout; - break; - case DEBUG_STDERR: - d->output.stream = stderr; - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void DebugPrintf(Debug * d, const char * file, u32 line, const char * format, ...) { - va_list l; - static char strtmp[512]; - static int strhash; - - if (d == NULL) - return; - - va_start(l, format); - - switch(d->output_type) { - case DEBUG_STDOUT: - case DEBUG_STDERR: - case DEBUG_STREAM: - if (d->output.stream == NULL) - break; - fprintf(d->output.stream, "%s (%s:%ld): ", d->name, file, (long)line); - vfprintf(d->output.stream, format, l); - break; - case DEBUG_STRING: - { - int i; - if (d->output.string == NULL) - break; - - i = sprintf(d->output.string, "%s (%s:%ld): ", d->name, file, (long)line); - vsprintf(d->output.string + i, format, l); - } - break; - case DEBUG_CALLBACK: - { - int i; - int strnewhash = 0; - i = sprintf(strtmp, "%s (%s:%ld): ", d->name, file, (long)line); - i += vsprintf(strtmp + i, format, l); - for ( ; i>0 ; i-- ) strnewhash += (int)(strtmp[i]); - if ( strnewhash != strhash ) d->output.callback( strtmp ); - strhash = strnewhash; - } - break; - } - - va_end(l); -} - -////////////////////////////////////////////////////////////////////////////// - -Debug * MainLog; - -////////////////////////////////////////////////////////////////////////////// - -void LogStart(void) { - MainLog = DebugInit("main", DEBUG_STDOUT, NULL); -// MainLog = DebugInit("main", DEBUG_STREAM, "stdout.txt"); -} - -////////////////////////////////////////////////////////////////////////////// - -void LogStop(void) { - DebugDeInit(MainLog); - MainLog = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void LogChangeOutput(DebugOutType t, char * s) { - - DebugChangeOutput( MainLog, t, s ); -} diff --git a/yabause/src/debug.h b/yabause/src/debug.h deleted file mode 100644 index 91935b322e..0000000000 --- a/yabause/src/debug.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright 2005-2006 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef DEBUG_H -#define DEBUG_H - -#include "core.h" -#include - -typedef enum { DEBUG_STRING, DEBUG_STREAM , DEBUG_STDOUT, DEBUG_STDERR, DEBUG_CALLBACK } DebugOutType; - -typedef struct { - DebugOutType output_type; - union { - FILE * stream; - char * string; - void (*callback) (char*); - } output; - char * name; -} Debug; - -Debug * DebugInit(const char *, DebugOutType, char *); -void DebugDeInit(Debug *); - -void DebugChangeOutput(Debug *, DebugOutType, char *); - -void DebugPrintf(Debug *, const char *, u32, const char *, ...); - -extern Debug * MainLog; - -void LogStart(void); -void LogStop(void); -void LogChangeOutput(DebugOutType t, char * s); - -#ifdef DEBUG -#define LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define LOG(...) -#endif - -#ifdef CDDEBUG -#define CDLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define CDLOG(...) -#endif - -#ifdef SCSP_DEBUG -#define SCSPLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define SCSPLOG(...) -#endif - -#ifdef VDP1_DEBUG -#define VDP1LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define VDP1LOG(...) -#endif - -#ifdef VDP2_DEBUG -#define VDP2LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define VDP2LOG(...) -#endif - -#ifdef SMPC_DEBUG -#define SMPCLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define SMPCLOG(...) -#endif - -#endif diff --git a/yabause/src/dreamcast/CMakeLists.txt b/yabause/src/dreamcast/CMakeLists.txt deleted file mode 100644 index e76d009e4c..0000000000 --- a/yabause/src/dreamcast/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -project(yabause-dc) - -if(NOT dreamcast) - return() -endif(NOT dreamcast) - -enable_language(ASM-ATT) -include_directories(${PORT_INCLUDE_DIRS}) -add_definitions(${PORT_CFLAGS}) - -set(yabause_dc_SOURCES - cd.s - localtime.c - perdc.c - viddc.c - yui.c) - -set(yabause_dc_HEADERS - localtime.h - perdc.h - viddc.h) - -link_directories(..) -add_executable(yabause-dc ${yabause_dc_SOURCES}) -set_target_properties(yabause-dc PROPERTIES OUTPUT_NAME yabause.elf) -target_link_libraries(yabause-dc ${YABAUSE_LIBRARIES}) -target_link_libraries(yabause-dc ${PORT_LIBRARIES}) -target_link_libraries(yabause-dc yabause) -target_link_libraries(yabause-dc m) diff --git a/yabause/src/dreamcast/Makefile.am b/yabause/src/dreamcast/Makefile.am deleted file mode 100644 index a0bce0a82d..0000000000 --- a/yabause/src/dreamcast/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST=cd.s localtime.c localtime.h perdc.c perdc.h viddc.c viddc.h yui.c diff --git a/yabause/src/dreamcast/cd.s b/yabause/src/dreamcast/cd.s deleted file mode 100644 index 817d1e93d6..0000000000 --- a/yabause/src/dreamcast/cd.s +++ /dev/null @@ -1,234 +0,0 @@ -! Copyright 2008 Lawrence Sebald -! -! This file is part of Yabause. -! -! Yabause 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. -! -! Yabause 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 Yabause; if not, write to the Free Software -! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -! Ok, so this is the start of me assemblerizing different parts of the core -! of the Dreamcast port of Yabause. I picked the CD core since its one of the -! parts of the emulator that is least likely to change in the future -! (hopefully anyway), and its somewhat simple to start with. - - .file "cd.s" - .little - .text - .align 2 - -! static int DCCDInit(const char *cdrom_name) -! Initialize the GD drive to read 2352 byte sectors. -DCCDInit: - sts.l pr, @-r15 -.do_reinit: - mov.l .cdrom_exec_cmd, r0 - mov #0, r5 - jsr @r0 - mov #24, r4 ! CMD_INIT - cmp/eq #1, r0 ! ERR_NO_DISC - bt .init_return_success - cmp/eq #3, r0 ! ERR_SYS - bt .init_return_error - mov.l .gdc_syscall_vector, r1 - mova .DCCDInitParams, r0 - mov #10, r7 - mov.l @r1, r1 - mov r0, r4 - mov #0, r6 - jsr @r1 - mov #0, r5 - lds.l @r15+, pr - rts - nop -.init_return_success: - lds.l @r15+, pr - rts - mov #0, r0 -.init_return_error: - lds.l @r15+, pr - rts - mov #-1, r0 - .align 4 -.cdrom_exec_cmd: - .long _cdrom_exec_cmd -.DCCDInitParams: - .long 0 ! 0 = set - .long 4096 ! Magic value for RAW sector reads - .long 0x0400 ! Ditto - .long 2352 ! Sector Size? (Maybe not for RAW though?) - -! static int DCCDGetStatus(void) -! Execute the BIOS syscall of the Dreamcast to get the GD drive status, -! translating that into the format expected by the core of Yabause. -DCCDGetStatus: - sts.l pr, @-r15 -.status_startgame: - mov.l .gdc_syscall_vector, r1 - mova .get_status_scratchpad, r0 - mov #4, r7 - mov.l @r1, r1 - mov #0, r5 - mov r0, r4 - jsr @r1 - mov #0, r6 - cmp/eq #2, r0 ! 2 = Disc change error - bt .status_reinit - cmp/eq #0, r0 - bf .status_error -.status_endgame: ! status in 1st entry in scratchpad - mova .get_status_scratchpad, r0 - mov #0x07, r2 - mov.l @r0, r1 - mova .get_status_return_value, r0 - and r2, r1 - add r1, r0 - lds.l @r15+, pr - rts - mov.b @r0, r0 -.status_reinit: - mov.l .get_status_init_func, r0 - jsr @r0 - mov #0, r4 - cmp/eq #0, r0 - bt .status_startgame -.status_error: - lds.l @r15+, pr - rts - mov #2, r0 - - .align 4 -.gdc_syscall_vector: - .long 0x8c0000bc -.get_status_scratchpad: - .long 0 - .long 0 -.get_status_return_value: - .byte 0, 1, 1, 0, 0, 0, 3, 2 -.get_status_init_func: - .long DCCDInit - -! static int DCCDDeInit(void) -! Deinitialize the CD Drive of the Dreamcast (i.e., undo the odd -! initialization stuff that the code does for Yabause). -DCCDDeInit: - mov.l .cdrom_reinit, r0 - sts.l pr, @-r15 - jsr @r0 - nop - lds.l @r15+, pr - rts - nop ! Leave the return value from cdrom_reinit as the return here. - -! static int DCCDReadSectorFAD(u32 FAD, void *buffer) -! Read a single 2352 byte sector from the given position on the disc. -DCCDReadSectorFAD: - sts.l pr, @-r15 - mov r4, r2 - mov.l r4, @-r15 - mov r5, r4 - mov.l .cdrom_read_sectors, r0 - mov.l r5, @-r15 - mov r2, r5 -.read_sector_start: - jsr @r0 - mov #1, r6 - cmp/eq #2, r0 - bt .read_reinit - cmp/eq #0, r0 - add #8, r15 - bf/s .read_error - lds.l @r15+, pr - rts - mov #1, r0 -.read_reinit: - mov.l .DCCDInit, r0 - jsr @r0 - mov #0, r4 - cmp/eq #0, r0 - mov.l @r15, r4 - mov.l .cdrom_read_sectors, r0 - bt/s .read_sector_start - mov.l @(4, r15), r5 - add #8, r15 -.read_error: - rts - mov #0, r0 - -! static int DCCDReadAheadFAD(u32 FAD) -! No-op (for the moment). -DCCDReadAheadFAD: - rts - nop - -! static s32 DCCDReadTOC(u32 *TOC); -! Read the TOC of the CD inserted in the drive. -! Amusingly enough, I just realized that the format that Yabause expects -! and what the Dreamcast spews out are exactly the same. Go figure! -DCCDReadTOC: - sts.l pr, @-r15 - mov.l .cdrom_read_toc, r0 - mov.l r4, @-r15 -.readtoc_start: - jsr @r0 - mov #0, r5 - cmp/eq #2, r0 - bt .readtoc_reinit - cmp/eq #0, r0 - add #4, r15 - bf/s .readtoc_error - mov #0xCC, r0 - lds.l @r15+, pr - extu.b r0, r0 - rts - shll r0 -.readtoc_reinit: - mov.l .DCCDInit, r0 - jsr @r0 - mov #0, r4 - cmp/eq #0, r0 - mov.l @r15, r4 - bt/s .readtoc_start - mov.l .cdrom_read_toc, r0 - add #4, r15 -.readtoc_error: - rts - mov #0, r0 - - .align 4 -.cdrom_reinit: - .long _cdrom_reinit -.cdrom_read_sectors: - .long _cdrom_read_sectors -.DCCDInit: - .long DCCDInit -.cdrom_read_toc: - .long _cdrom_read_toc - - .section .rodata - .align 2 -.CDInterfaceName: - .string "Dreamcast CD Drive" - - .data - .align 4 - .globl _ArchCD - .size _ArchCD, 32 -_ArchCD: - .long 2 - .long .CDInterfaceName - .long DCCDInit - .long DCCDDeInit - .long DCCDGetStatus - .long DCCDReadTOC - .long DCCDReadSectorFAD - .long DCCDReadAheadFAD diff --git a/yabause/src/dreamcast/dreamcast.cmake b/yabause/src/dreamcast/dreamcast.cmake deleted file mode 100644 index 0c39a1b97f..0000000000 --- a/yabause/src/dreamcast/dreamcast.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# CMake toolchain file for building Yabause on the Dreamcast -set(CMAKE_SYSTEM_NAME Generic) - -# Use the gnu_wrappers for the various GNU utilities -set(CMAKE_C_COMPILER kos-cc) -set(CMAKE_CXX_COMPILER kos-c++) -set(CMAKE_ASM_COMPILER kos-as) - -# KOS Sets this nicely for us. -set(CMAKE_FIND_ROOT_PATH $ENV{KOS_CC_BASE}) - -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -# Set some stuff so that it doesn't complain about the lack of a normal looking -# pthreads flag/library for the compiler. -set(THREADS_HAVE_PTHREAD_ARG 1) -set(CMAKE_HAVE_THREADS_LIBRARY 1) - -# Set a flag so we know we're trying to compile for Dreamcast -set(dreamcast 1) diff --git a/yabause/src/dreamcast/localtime.c b/yabause/src/dreamcast/localtime.c deleted file mode 100644 index e13d56a031..0000000000 --- a/yabause/src/dreamcast/localtime.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * localtime_r.c - * Original Author: Adapted from tzcode maintained by Arthur David Olson. - * - * Converts the calendar time pointed to by tim_p into a broken-down time - * expressed as local time. Returns a pointer to a structure containing the - * broken-down time. - */ - -/* This file was taken from newlib , it's a - * modified version of Arthur David Olsons localtime.c from tzcode which - * is under Public Domain */ - -#include -#include -#include "localtime.h" - -#define SECSPERMIN 60L -#define MINSPERHOUR 60L -#define HOURSPERDAY 24L -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) -#define DAYSPERWEEK 7 -#define MONSPERYEAR 12 - -#define YEAR_BASE 1900 -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY 4 - -#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) - -static const int mon_lengths[2][MONSPERYEAR] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -} ; - -static const int year_lengths[2] = { - 365, - 366 -} ; - -struct tm * internal_localtime_r(const time_t * tim_p, struct tm *res) -{ - long days, rem; - int y; - int yleap; - const int *ip; - - days = ((long) *tim_p) / SECSPERDAY; - rem = ((long) *tim_p) % SECSPERDAY; - while (rem < 0) - { - rem += SECSPERDAY; - --days; - } - while (rem >= SECSPERDAY) - { - rem -= SECSPERDAY; - ++days; - } - - /* compute hour, min, and sec */ - res->tm_hour = (int) (rem / SECSPERHOUR); - rem %= SECSPERHOUR; - res->tm_min = (int) (rem / SECSPERMIN); - res->tm_sec = (int) (rem % SECSPERMIN); - - /* compute day of week */ - if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) - res->tm_wday += DAYSPERWEEK; - - /* compute year & day of year */ - y = EPOCH_YEAR; - if (days >= 0) - { - for (;;) - { - yleap = isleap(y); - if (days < year_lengths[yleap]) - break; - y++; - days -= year_lengths[yleap]; - } - } - else - { - do - { - --y; - yleap = isleap(y); - days += year_lengths[yleap]; - } while (days < 0); - } - - res->tm_year = y - YEAR_BASE; - res->tm_yday = days; - ip = mon_lengths[yleap]; - for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon) - days -= ip[res->tm_mon]; - res->tm_mday = days + 1; - - /* set daylight saving time flag */ - res->tm_isdst = -1; - - return (res); -} diff --git a/yabause/src/dreamcast/localtime.h b/yabause/src/dreamcast/localtime.h deleted file mode 100644 index fb894aad44..0000000000 --- a/yabause/src/dreamcast/localtime.h +++ /dev/null @@ -1,3 +0,0 @@ -/* internal_localtime_r() function declaration, included by smpc.c */ - -extern struct tm * internal_localtime_r(const time_t * tim_p, struct tm *res); diff --git a/yabause/src/dreamcast/perdc.c b/yabause/src/dreamcast/perdc.c deleted file mode 100644 index 2ebab80ace..0000000000 --- a/yabause/src/dreamcast/perdc.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2005-2008 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "perdc.h" -#include "../yabause.h" -#include "../yui.h" -#include "../vdp2.h" - -#include -#include - -int PERDCInit(void); -void PERDCDeInit(void); -int PERDCHandleEvents(void); -void PERDCNothing(void); -u32 PERDCScan(void); - -static PerPad_struct *pad1; - -PerInterface_struct PERDC = { - PERCORE_DC, - "Dreamcast Input Interface", - PERDCInit, - PERDCDeInit, - PERDCHandleEvents, - PERDCNothing, - PERDCScan, - 0, - PERDCNothing -}; - -int PERDCInit(void) { - PerPortReset(); - pad1 = PerPadAdd(&PORTDATA1); - return 0; -} - -void PERDCDeInit(void) { -} - -int PERDCHandleEvents(void) { - maple_device_t *dev; - - dev = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); - if(dev != NULL) { - cont_state_t *state = (cont_state_t *) maple_dev_status(dev); - - if(state != NULL) { - if(state->buttons & CONT_DPAD_UP) - *pad1->padbits &= 0xEF; - else - *pad1->padbits |= 0x10; - - if(state->buttons & CONT_DPAD_DOWN) - *pad1->padbits &= 0xDF; - else - *pad1->padbits |= 0x20; - - if(state->buttons & CONT_DPAD_RIGHT) - *pad1->padbits &= 0x7F; - else - *pad1->padbits |= 0x80; - - if(state->buttons & CONT_DPAD_LEFT) - *pad1->padbits &= 0xBF; - else - *pad1->padbits |= 0x40; - - if(state->buttons & CONT_START) - *pad1->padbits &= 0xF7; - else - *pad1->padbits |= 0x08; - - if(state->buttons & CONT_A) - *pad1->padbits &= 0xFB; - else - *pad1->padbits |= 0x04; - - if(state->buttons & CONT_B) - *pad1->padbits &= 0xFE; - else - *pad1->padbits |= 0x01; - - if(state->buttons & CONT_X) - *(pad1->padbits + 1) &= 0xBF; - else - *(pad1->padbits + 1) |= 0x40; - - if(state->buttons & CONT_Y) - *(pad1->padbits + 1) &= 0xDF; - else - *(pad1->padbits + 1) |= 0x20; - - if(state->rtrig > 20) - *(pad1->padbits + 1) &= 0x7F; - else - *(pad1->padbits + 1) |= 0x80; - - if(state->ltrig > 20) - *(pad1->padbits + 1) &= 0xF7; - else - *(pad1->padbits + 1) |= 0x08; - - if(state->joyx > 20) - *pad1->padbits &= 0xFD; - else - *pad1->padbits |= 0x02; - - if(state->joyy > 20) - *(pad1->padbits + 1) &= 0xEF; - else - *(pad1->padbits + 1) |= 0x10; - - } - } - - YabauseExec(); - - return 0; -} - -void PERDCNothing(void) { - /* Nothing */ -} - -u32 PERDCScan(void) { - /* Nothing */ - return 0; -} diff --git a/yabause/src/dreamcast/perdc.h b/yabause/src/dreamcast/perdc.h deleted file mode 100644 index 2dcbe64f41..0000000000 --- a/yabause/src/dreamcast/perdc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2005 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERDC_H -#define PERDC_H - -#include "../peripheral.h" - -#define PERCORE_DC 2 - -extern PerInterface_struct PERDC; - -#endif diff --git a/yabause/src/dreamcast/sh2rec/sh2exec.s b/yabause/src/dreamcast/sh2rec/sh2exec.s deleted file mode 100644 index f2ff5f9aaa..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2exec.s +++ /dev/null @@ -1,100 +0,0 @@ -! Copyright 2010 Lawrence Sebald -! -! This file is part of Yabause. -! -! Yabause 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. -! -! Yabause 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 Yabause; if not, write to the Free Software -! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -! Code for calling upon the code generated by sh2rec (SuperH). - - .file "sh2exec.s" - .little - .text - .balign 8 - -! void sh2rec_exec(SH2_struct *cxt, u32 cycles) -! Execute the specified number of cycles on the given SH2 context - .globl _sh2rec_exec -_sh2rec_exec: - stc.l gbr, @-r15 ! Save call-preserved stuff - sts.l mach, @-r15 ! Ditto - sts.l macl, @-r15 ! Ditto - mov.l r8, @-r15 ! Ditto - mov r4, r8 ! Put the SH2 struct in r8 - mov.l r9, @-r15 ! More call-preserved stuff - add #76, r4 ! Point at MACH in the SH2 struct - mov.l r10, @-r15 ! More call-preserved stuff - mov.l r11, @-r15 ! Last one for now... - lds.l @r4+, mach ! Load the SH2 MACH into our MACH - lds.l @r4+, macl ! Ditto for MACL - mov.l checkInterrupts, r0 ! We need to check for interrupts... - mov.l sh2memfuncsptr, r9 ! Memory access function pointer table - sts.l pr, @-r15 ! Helps to know where to go back to - mov r5, r11 ! This is important enough to keep here - mov.l r5, @-r15 ! Save this on the stack too - mov r8, r4 ! We need the original SH2_struct back - jsr @r0 ! Call sh2rec_check_interrupts - ldc r8, gbr ! Put the SH2 struct in gbr (delay slot) - mov.l findBlock, r1 ! Grab the sh2rec_find_block function - mov.l @(88, gbr), r0 ! Grab the PC we are at -.exec_loop: ! This is where the fun is! - jsr @r1 ! Call sh2rec_find_block - mov r0, r4 ! Move the PC to argument 1 (delay slot) - mov.l @r0, r2 ! Grab where the code is - mov.l @(8, r0), r1 ! Figure out the number of cycles used - jsr @r2 ! Call the block - sub r1, r11 ! Chop off the cycles (delay slot) - cmp/pl r11 ! Are we done? - mov.l findBlock, r1 ! Grab the sh2rec_find_block function - bt .exec_loop ! Continue on if needed - ! When we are done, we will be here. - mov.l r0, @(88, gbr) ! Save the next PC value - mov.l @r15+, r5 ! Pop the requested number of cycles - mov r8, r4 ! Keep this for sanity for now - add #84, r8 ! Point just after MACL in SH2 struct - sts.l macl, @-r8 ! Store the SH2 MACL back in the struct - sts.l mach, @-r8 ! Ditto for MACH - lds.l @r15+, pr ! Restore stuff from the stack - sub r11, r5 ! Our counter is negitive, so this works - mov.l cycleOffset, r2 ! Where is the cycles member at? - mov.l @r15+, r11 ! More restoring... - add r2, r4 ! Point r4 at the cycles member - mov.l @r15+, r10 - mov.l @r15+, r9 - mov.l @r15+, r8 - lds.l @r15+, macl - lds.l @r15+, mach - mov.l r5, @r4 ! Save the cycles we spent - rts ! Return to the caller - ldc.l @r15+, gbr ! Last thing to restore (delay slot) - - .balign 4 -sh2memfuncsptr: - .long sh2memfuncs -checkInterrupts: - .long _sh2rec_check_interrupts -findBlock: - .long _sh2rec_find_block -cycleOffset: - .long 5516 - - .data - .balign 4 -sh2memfuncs: - .long _MappedMemoryReadByte - .long _MappedMemoryReadWord - .long _MappedMemoryReadLong - .long _MappedMemoryWriteByte - .long _MappedMemoryWriteWord - .long _MappedMemoryWriteLong diff --git a/yabause/src/dreamcast/sh2rec/sh2rec.c b/yabause/src/dreamcast/sh2rec/sh2rec.c deleted file mode 100644 index 2295da27ed..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec.c +++ /dev/null @@ -1,2908 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* SH2 Dynarec Core (for SH4) */ - -#include -#include -#include -#include - -#include "sh2core.h" -#include "sh2rec.h" -#include "sh2rec_htab.h" -#include "sh2int.h" - -/* Registers */ -#define R0 0 -#define R1 1 -#define R2 2 -#define R3 3 -#define R4 4 -#define R5 5 -#define R6 6 -#define R7 7 -#define R8 8 -#define R9 9 -#define R10 10 -#define R11 11 -#define R12 12 -#define R13 13 -#define R14 14 -#define R15 15 - -/* Control Registers (use with emitSTC/emitLDC) */ -#define R_SR 0 -#define R_GBR 1 -#define R_VBR 2 - -/* System Registers (use with emitSTS/emitLDS) */ -#define R_MACH 0 -#define R_MACL 1 -#define R_PR 2 - -/* ALU Ops, to be used with the emitALU function */ -#define OP_ADD 0x300C -#define OP_ADDC 0x300E -#define OP_AND 0x2009 -#define OP_EXTSB 0x600E -#define OP_EXTSW 0x600F -#define OP_EXTUB 0x600C -#define OP_EXTUW 0x600D -#define OP_NEG 0x600B -#define OP_NEGC 0x600A -#define OP_NOT 0x6007 -#define OP_OR 0x200B -#define OP_SUB 0x3008 -#define OP_SUBC 0x300A -#define OP_SWAPB 0x6008 -#define OP_SWAPW 0x6009 -#define OP_XOR 0x200A -#define OP_XTRCT 0x200D - -/* Shift/Rotate Ops, to be used with the emitSHIFT function */ -#define OP_ROTCL 0x4024 -#define OP_ROTCR 0x4025 -#define OP_ROTL 0x4004 -#define OP_ROTR 0x4005 -#define OP_SHAL 0x4020 -#define OP_SHAR 0x4021 -#define OP_SHLL 0x4000 -#define OP_SHLR 0x4001 - -/* Comparison Ops, to be used with the emitALU function */ -#define OP_CMPEQ 0x3000 -#define OP_CMPGE 0x3003 -#define OP_CMPGT 0x3007 -#define OP_CMPHI 0x3006 -#define OP_CMPHS 0x3002 -#define OP_CMPSTR 0x200C -#define OP_TST 0x2008 - -/* Multiplication ops, to be used with the emitALU function */ -#define OP_DMULS 0x300D -#define OP_DMULU 0x3005 -#define OP_MULL 0x0007 -#define OP_MULS 0x200F -#define OP_MULU 0x200E - -#ifdef SH2REC__DEBUG -#define EMIT_INST {\ - printf("%s\n", __PRETTY_FUNCTION__); \ - printf("Emitting %04x at %p\n", inst, (void *)b->ptr); \ - *b->ptr++ = inst; \ -} -#else -#define EMIT_INST *b->ptr++ = inst -#endif - -#ifdef SH2REC__DEBUG -#define EMIT_32 {\ - uint32_t *__ptr = (uint32_t *)b->ptr; \ - printf("%s\n", __PRETTY_FUNCTION__); \ - printf("Emitting %08x at %p\n", (unsigned int)v, (void *)__ptr); \ - *__ptr = v; \ - b->ptr += 2; \ -} -#else -#define EMIT_32 uint32_t *__ptr = (uint32_t *)b->ptr; *__ptr = v; b->ptr += 2 -#endif - -static inline void emit16(sh2rec_block_t *b, uint16_t inst) { - EMIT_INST; -} - -static inline void emit32(sh2rec_block_t *b, uint32_t v) { - EMIT_32; -} - -static inline void emitMOV(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x6003 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVWI(sh2rec_block_t *b, int d, int n) { - uint16_t inst = 0x9000 | (n << 8) | (d); - EMIT_INST; -} - -static inline void emitMOVLI(sh2rec_block_t *b, int d, int n) { - uint16_t inst = 0xD000 | (n << 8) | (d); - EMIT_INST; -} - -static inline void emitMOVLS(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2002 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVLL(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x6002 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVWM(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2005 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVLM(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2006 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVLP(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x6006 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVI(sh2rec_block_t *b, int imm, int n) { - uint16_t inst = 0xE000 | (n << 8) | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitMOVLL4(sh2rec_block_t *b, int m, int d, int n) { - uint16_t inst = 0x5000 | (n << 8) | (m << 4) | (d); - EMIT_INST; -} - -static inline void emitMOVLS4(sh2rec_block_t *b, int m, int d, int n) { - uint16_t inst = 0x1000 | (n << 8) | (m << 4) | (d); - EMIT_INST; -} - -static inline void emitMOVLLG(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC600 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitMOVLSG(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC200 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitMOVT(sh2rec_block_t *b, int n) { - uint16_t inst = 0x0029 | (n << 8); - EMIT_INST; -} - -static inline void emitALU(sh2rec_block_t *b, int m, int n, uint16_t op) { - uint16_t inst = (n << 8) | (m << 4) | op; - EMIT_INST; -} - -static inline void emitSHIFT(sh2rec_block_t *b, int n, uint16_t op) { - uint16_t inst = (n << 8) | op; - EMIT_INST; -} - -static inline void emitADDI(sh2rec_block_t *b, int imm, int n) { - uint16_t inst = 0x7000 | (n << 8) | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitANDI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC900 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitORI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xCB00 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitXORI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xCA00 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitSHLL2(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4008 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLL8(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4018 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLL16(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4028 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLR2(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4009 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLR8(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4019 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLR16(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4029 | (n << 8); - EMIT_INST; -} - -static inline void emitCMPIM(sh2rec_block_t *b, int imm) { - uint16_t inst = 0x8800 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitCMPPL(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4015 | (n << 8); - EMIT_INST; -} - -static inline void emitCMPPZ(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4011 | (n << 8); - EMIT_INST; -} - -static inline void emitADDV(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x300F | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitSUBV(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x300B | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitLDS(sh2rec_block_t *b, int m, int sr) { - uint16_t inst = 0x400A | (m << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitSTS(sh2rec_block_t *b, int sr, int n) { - uint16_t inst = 0x000A | (n << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitLDC(sh2rec_block_t *b, int m, int sr) { - uint16_t inst = 0x400E | (m << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitSTC(sh2rec_block_t *b, int sr, int n) { - uint16_t inst = 0x0002 | (n << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitDT(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4010 | (n << 8); - EMIT_INST; -} - -static inline void emitTSTI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC800 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitBRA(sh2rec_block_t *b, int d) { - uint16_t inst = 0xA000 | (d); - EMIT_INST; -} - -static inline void emitDIV0S(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2007 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitDIV1(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x3004 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitRTS(sh2rec_block_t *b) { - uint16_t inst = 0x000B; - EMIT_INST; -} - -static inline void emitNOP(sh2rec_block_t *b) { - uint16_t inst = 0x0009; - EMIT_INST; -} - -static inline void emitJSR(sh2rec_block_t *b, int m) { - uint16_t inst = 0x400B | (m << 8); - EMIT_INST; -} - -static inline void emitMACL(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x000F | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMACW(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x400F | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitCLRMAC(sh2rec_block_t *b) { - uint16_t inst = 0x0028; - EMIT_INST; -} - -static inline void emitBF(sh2rec_block_t *b, int disp) { - uint16_t inst = 0x8B00 | (disp & 0xFF); - EMIT_INST; -} - -static inline void emitBT(sh2rec_block_t *b, int disp) { - uint16_t inst = 0x8900 | (disp & 0xFF); - EMIT_INST; -} - -static inline void generateALUOP(uint16_t inst, sh2rec_block_t *b, int op) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, op); /* R2 <- R2 o R3 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ -} - -static inline void generateSHIFT(uint16_t inst, sh2rec_block_t *b, int op) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitSHIFT(b, R2, op); /* R2 <- R2 op */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ -} - -static inline void generateCOMP(uint16_t inst, sh2rec_block_t *b, int op) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, op); /* R2 op R3 */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ -} - -static void generateADD(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_ADD); - b->pc += 2; -} - -static void generateADDI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitADDI(b, imm, R2); /* R2 <- R2 + #imm */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateADDC(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, OP_ADDC); /* R2 = R2 + R3 + T (carry to T) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateADDV(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitADDV(b, R3, R2); /* R2 = R2 + R3 (overflow to T Bit) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateAND(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_AND); - b->pc += 2; -} - -static void generateANDI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitANDI(b, imm); /* R0 <- R0 & #imm */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateANDM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitMOVLM(b, R4, R15); /* Push R4 on the stack (delay slot) */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitANDI(b, imm); /* R0 <- R0 & #imm */ - emitMOVLP(b, R15, R4); /* Pop R4 off the stack */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateBF(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 2; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, 4, R2); /* R2 <- sh2[PC] + 2 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBT(b, 2); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - emitADDI(b, 2, R0); /* R0 <- R0 + 2 */ - emitRTS(b); /* Return to sender! */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - if(((uint32_t)b->ptr) & 0x03) - emit16(b, 0); /* Padding if we need it */ - emit32(b, val); /* The next PC value (if not taken) */ - - b->cycles += 2; /* 2 Cycles (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateBFS(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 4; - int n = (((uint32_t)b->ptr) & 0x03) ? 3 : 4; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, n, R2); /* R2 <- sh2[PC] + 4 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBT(b, 1); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - } - - emit32(b, val); /* The next PC value (if not taken) */ - emitMOVLM(b, R0, R15); /* Push the next PC on the stack */ - - /* Deal with the delay slot here */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - ++b->cycles; /* 1 Cycle (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateBRA(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_BCD(inst); - int32_t val; - - if(disp & 0x00000800) { - disp |= 0xFFFFF000; - } - - val = b->pc + 4 + (disp << 1); - - emitMOVLI(b, 1, R2); /* R2 <- sh2[PC] + 4 + disp */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - } - - emit32(b, (uint32_t )val); /* The next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBRAF(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - uint32_t val = b->pc + 4; - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 2, R0); /* R0 <- sh2[PC] + 4 */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] */ - emitBRA(b, 3); /* Branch around the constant */ - emitALU(b, R0, R2, OP_ADD); /* R2 <- R0 + R2 (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitMOVLI(b, 1, R0); /* R0 <- sh2[PC] + 4 */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] */ - emitBRA(b, 2); /* Branch around the constant */ - emitALU(b, R0, R2, OP_ADD); /* R2 <- R0 + R2 (delay slot) */ - } - - emit32(b, val); /* The value to use as the base for PC */ - emitMOVLM(b, R2, R15); /* Push the next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBSR(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_BCD(inst); - int32_t val; - int32_t val2 = b->pc + 4; - - if(disp & 0x00000800) { - disp |= 0xFFFFF000; - } - - val = b->pc + 4 + (disp << 1); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 2, R2); /* R2 <- sh2[PC] + 4 + disp */ - emitMOVLI(b, 2, R0); /* R0 <- sh2[PC] + 4 */ - emitBRA(b, 5); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitMOVLI(b, 1, R2); /* R2 <- sh2[PC] + 4 + disp */ - emitMOVLI(b, 2, R0); /* R0 <- sh2[PC] + 4 */ - emitBRA(b, 4); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - } - - emit32(b, (uint32_t)val); /* The next PC */ - emit32(b, (uint32_t)val2); /* The value for PR */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBSRF(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - uint32_t val = b->pc + 4; - - emitMOVLI(b, 1, R0); /* R0 <- sh2[PC] + 4 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - } - - emit32(b, val); /* The value to put in PR */ - emitALU(b, R0, R2, OP_ADD); /* R2 <- R0 + R2 (branch target) */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - emitMOVLM(b, R2, R15); /* Push the next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBT(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 2; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, 4, R2); /* R2 <- sh2[PC] + 4 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBF(b, 2); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - emitADDI(b, 2, R0); /* R0 <- R0 + 2 */ - emitRTS(b); /* Return to sender! */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - if(((uint32_t)b->ptr) & 0x03) - emit16(b, 0); /* Padding if we need it */ - emit32(b, val); /* The next PC value (if not taken) */ - - b->cycles += 2; /* 2 Cycles (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateBTS(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 4; - int n = (((uint32_t)b->ptr) & 0x03) ? 3 : 4; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, n, R2); /* R2 <- sh2[PC] + 2 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBF(b, 1); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - } - - emit32(b, val); /* The next PC value (if not taken) */ - emitMOVLM(b, R0, R15); /* Push the next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - ++b->cycles; /* 1 Cycle (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateCLRMAC(uint16_t inst, sh2rec_block_t *b) { - emitCLRMAC(b); /* MACL/MACH <- 0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCLRT(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVI(b, 0xFE, R1); /* R1 <- 0xFFFFFFFE */ - emitALU(b, R3, R0, OP_AND); /* Clear T bit */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCMPEQ(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPEQ); - b->pc += 2; -} - -static void generateCMPGE(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPGE); - b->pc += 2; -} - -static void generateCMPGT(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPGT); - b->pc += 2; -} - -static void generateCMPHI(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPHI); - b->pc += 2; -} - -static void generateCMPHS(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPHS); - b->pc += 2; -} - -static void generateCMPSTR(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPSTR); - b->pc += 2; -} - -static void generateCMPPL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitCMPPL(b, R2); /* cmp/pl R2 */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCMPPZ(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitCMPPZ(b, R2); /* cmp/pz R2 */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCMPIM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOV(b, R0, R2); /* R2 <- R0 */ - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitSHIFT(b, R2, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitCMPIM(b, imm); /* cmp/eq R0, #imm */ - emitSHIFT(b, R2, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOV(b, R2, R0); /* R0 <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDIV0S(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVI(b, 0x03, R4); /* R4 <- 0x03 */ - emitANDI(b, 0xF2); /* Clear M, Q, and T */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHLL8(b, R4); /* R4 <<= 8 */ - emitSHIFT(b, R0, OP_SHLR); /* Chop off the T from the SH2 reg */ - emitDIV0S(b, R3, R2); /* div0s to grab the M, Q, T bits needed */ - emitSTC(b, R_SR, R5); /* Save SR to R5 */ - emitALU(b, R4, R5, OP_AND); /* Grab M, Q from the SR */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitALU(b, R5, R0, OP_OR); /* Save M, Q into the SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDIV0U(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitANDI(b, 0xF2); /* Mask off M, Q, and T bits */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDIV1(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVI(b, 0x03, R4); /* R4 <- 0x03 */ - emitSHLL8(b, R4); /* R4 <<= 8 */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitMOV(b, R4, R6); /* R6 <- R4 */ - emitALU(b, R0, R6, OP_AND); /* Grab SH2 M and Q bits */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T in place */ - emitSTC(b, R_SR, R5); /* Save SR to R5 */ - emitALU(b, R4, R7, OP_NOT); /* Set up the mask to clear M and Q */ - emitALU(b, R7, R5, OP_AND); /* Clear M, Q */ - emitALU(b, R6, R5, OP_OR); /* Put SH2's M and Q in place */ - emitLDC(b, R5, R_SR); /* Put the modified SR in place */ - emitDIV1(b, R3, R2); /* Do the division! */ - emitSTC(b, R_SR, R5); /* Save updated SR to R5 */ - emitALU(b, R4, R5, OP_AND); /* Grab M and Q from the SR */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitANDI(b, 0xF3); /* Clear M and Q from the SH2 reg */ - emitALU(b, R5, R0, OP_OR); /* Save M and Q into the SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDMULS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_DMULS); /* MACH/MACL <- (s32)R2 * (s32)R3 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateDMULU(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_DMULU); /* MACH/MACL <- (u32)R2 * (u32)R3 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateDT(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitDT(b, R2); /* R2 = R2 - 1 (T Bit = non-zero) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateEXTSB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTSB); - b->pc += 2; -} - -static void generateEXTSW(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTSW); - b->pc += 2; -} - -static void generateEXTUB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTUB); - b->pc += 2; -} - -static void generateEXTUW(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTUW); - b->pc += 2; -} - -static void generateJMP(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* Grab the next PC value */ - emitMOVLM(b, R0, R15); /* Push the next PC on the stack */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateJSR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - uint32_t val = b->pc + 4; - - emitMOVLI(b, 1, R0); /* R0 <- sh2[PC] + 4 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - } - - emit32(b, val); /* The value to put in PR */ - emitMOVLM(b, R2, R15); /* Push the next PC */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateLDCSR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVWI(b, 2, R2); /* R2 <- 0x03F3 */ - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitBRA(b, 1); /* Jump beyond the constant */ - emitALU(b, R2, R0, OP_AND); /* R0 <- R0 & R2 (delay slot) */ - emit16(b, 0x03F3); /* 0x03F3, grabbed by the emitMOVWI */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDCGBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitMOVLSG(b, 17); /* sh2[GBR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDCVBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitMOVLSG(b, 18); /* sh2[VBR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDCMSR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVWI(b, 2, R2); /* R2 <- 0x03F3 */ - emitBRA(b, 1); /* Jump beyond the constant */ - emitALU(b, R2, R0, OP_AND); /* R0 <- R0 & R2 (delay slot) */ - emit16(b, 0x03F3); /* 0x03F3, grabbed by the emitMOVWI */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateLDCMGBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 17); /* sh2[GBR] <- R0 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateLDCMVBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 18); /* sh2[VBR] <- R0 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateLDSMACH(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitLDS(b, R0, R_MACH); /* MACH <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMACL(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitLDS(b, R0, R_MACL); /* MACL <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSPR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMMACH(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitLDS(b, R0, R_MACH); /* MACH <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMMACL(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitLDS(b, R0, R_MACL); /* MACL <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMPR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMACL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitADDI(b, 4, R4); /* R4 <- R4 + 4 */ - emitMOVLS4(b, R4, regm, R8); /* sh2[Rm] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitADDI(b, -4, R4); /* R4 <- R4 - 4 (delay slot) */ - emitMOVLM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitADDI(b, 4, R4); /* R4 <- R4 + 4 */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitADDI(b, -4, R4); /* R4 <- R4 - 4 (delay slot) */ - emitSTC(b, R_SR, R2); /* R2 <- SR */ - emitMOVI(b, 0xFD, R3); /* R3 <- 0xFFFFFFFD */ - emitMOVLM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitALU(b, R2, R3, OP_AND); /* R3 <- R2 & R3 (Mask out S Bit) */ - emitANDI(b, 0x02); /* R0 <- R0 & 0x02 (S Bit) */ - emitALU(b, R0, R3, OP_OR); /* R3 <- R0 | R3 (Put SH2 S Bit in) */ - emitLDC(b, R3, R_SR); /* SR <- R3 */ - emitMACL(b, R15, R15); /* Perform the MAC.L */ - emitLDC(b, R2, R_SR); /* SR <- R2 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateMACW(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitADDI(b, 2, R4); /* R4 <- R4 + 2 */ - emitMOVLS4(b, R4, regm, R8); /* sh2[Rm] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitADDI(b, -2, R4); /* R4 <- R4 - 2 (delay slot) */ - emitMOVWM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitADDI(b, 2, R4); /* R4 <- R4 + 2 */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitADDI(b, -2, R4); /* R4 <- R4 - 2 (delay slot) */ - emitMOVWM(b, R0, R15); /* Push R0 onto the stack */ - emitSTC(b, R_SR, R2); /* R2 <- SR */ - emitMOVI(b, 0xFD, R3); /* R3 <- 0xFFFFFFFD */ - emitMOVLM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitALU(b, R2, R3, OP_AND); /* R3 <- R2 & R3 (Mask out S Bit) */ - emitANDI(b, 0x02); /* R0 <- R0 & 0x02 (S Bit) */ - emitALU(b, R0, R3, OP_OR); /* R3 <- R0 | R3 (Put SH2 S Bit in) */ - emitLDC(b, R3, R_SR); /* SR <- R3 */ - emitMACW(b, R15, R15); /* Perform the MAC.W */ - emitLDC(b, R2, R_SR); /* SR <- R2 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateMOV(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R2); /* R2 <- sh2[Rm] */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 3, R0); /* R0 <- MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 4, R0); /* R0 <- MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 5, R0); /* R0 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBM(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 3, R0); /* R0 <- MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -1, R4); /* R4 -= 1 */ - emitJSR(b, R0); /* Call MappedMemoryWriteByte */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWM(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 4, R0); /* R0 <- MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -2, R4); /* R4 -= 2 */ - emitJSR(b, R0); /* Call MappedMemoryWriteWord */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLM(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 5, R0); /* R0 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitJSR(b, R0); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBP(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 1, R1); /* R1 <- 1 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWP(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 2, R1); /* R1 <- 2 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLP(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBS0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitMOVLL4(b, R9, 3, R0); /* R0 <- MappedMemoryWriteByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitJSR(b, R0); /* Call MappedMemoryWriteByte */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWS0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitMOVLL4(b, R9, 4, R0); /* R0 <- MappedMemoryWriteWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitJSR(b, R0); /* Call MappedMemoryWriteWord */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLS0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitMOVLL4(b, R9, 5, R0); /* R0 <- MappedMemoryWriteLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitJSR(b, R0); /* Call MappedMemoryWriteLong */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBL0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWL0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLL0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - - emitMOVI(b, imm, R2); /* R2 <- #imm */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - uint32_t addr = b->pc + 4 + (imm << 1); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 2); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emit32(b, addr); /* MOV.W effective address */ - } - else { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 3); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emit16(b, 0); /* Padding, for alignment issues */ - emit32(b, addr); /* MOV.W effective address */ - } - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitNOP(b); /* XXXX: Nothing to put here */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - uint32_t addr = ((b->pc + 4) & 0xFFFFFFFC) + (imm << 2); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 2); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emit32(b, addr); /* MOV.L effective address */ - } - else { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 3); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emit16(b, 0); /* Padding, for alignment issues */ - emit32(b, addr); /* MOV.L effective address */ - } - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitNOP(b); /* XXXX: Nothing to put here */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBLG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend displacement */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWLG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLL4(b, R9, 1, R1); /* R1 <- MappedMemoryReadWord */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitSHIFT(b, R4, OP_SHLL); /* Double displacement */ - emitJSR(b, R1); /* Call MappedMemoryReadWord */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLLG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MappedMemoryReadLong */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitSHLL2(b, R4); /* Quadruple displacement */ - emitJSR(b, R1); /* Call MappedMemoryReadLong */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBSG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend Displacement */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWSG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend Displacement */ - emitMOVLL4(b, R9, 4, R1); /* R1 <- MappedMemoryWriteWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitSHIFT(b, R4, OP_SHLL); /* Double displacement */ - emitJSR(b, R1); /* Call MappedMemoryWriteWord */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLSG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend Displacement */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitSHLL2(b, R4); /* Quadruple displacement */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBS4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWS4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 1; - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVLL4(b, R9, 4, R1); /* R1 <- MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryWriteWord */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLS4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 2; - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBL4(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst); - - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWL4(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 1; - - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 1, R1); /* R1 <- MappedMemoryReadWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryReadWord */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLL4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 2; - - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryReadLong */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVA(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - uint32_t addr = ((b->pc + 4) & 0xFFFFFFFC) + (imm << 2); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 1, R2); /* R2 <- calculated effective addr */ - emitBRA(b, 2); /* Jump beyond the constant */ - emitMOVLS4(b, R2, 0, R8); /* sh2[R0] <- R2 */ - emit32(b, addr); /* MOVA effective address */ - } - else { - emitMOVLI(b, 1, R2); /* R2 <- calculated effective addr */ - emitBRA(b, 3); /* Jump beyond the constant */ - emitMOVLS4(b, R2, 0, R8); /* sh2[R0] <- R2 */ - emit16(b, 0); /* Padding, for alignment issues */ - emit32(b, addr); /* MOVA effective address */ - } - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVT(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitANDI(b, 0x01); /* Grab T Bit */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- T Bit */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMULL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_MULL); /* MACL <- R2 * R3 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateMULS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_MULS); /* MACL <- (s16)R2 * (s16)R3 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMULU(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_MULU); /* MACL <- (u16)R2 * (u16)R3 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNEG(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_NEG); /* R2 <- 0 - R3 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNEGC(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, OP_NEGC); /* R2 = 0 - R3 - T (borrow to T) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNOP(uint16_t inst, sh2rec_block_t *b) { - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNOT(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_NOT); - b->pc += 2; -} - -static void generateOR(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_OR); - b->pc += 2; -} - -static void generateORI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitORI(b, imm); /* R0 <- R0 | #imm */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateORM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitMOVLM(b, R4, R15); /* Push R4 on the stack (delay slot) */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitORI(b, imm); /* R0 <- R0 | #imm */ - emitMOVLP(b, R15, R4); /* Pop R4 off the stack */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateROTCL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTCL); - b->pc += 2; -} - -static void generateROTCR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTCR); - b->pc += 2; -} - -static void generateROTL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTL); - b->pc += 2; -} - -static void generateROTR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTR); - b->pc += 2; -} - -static void generateRTE(uint16_t inst, sh2rec_block_t *b) { - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] (delay slot) */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MappedMemoryReadLong */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] */ - emitMOVI(b, 4, R2); /* R2 <- 4 */ - emitALU(b, R2, R4, OP_ADD); /* R4 <- R4 + R2 */ - emitMOVLM(b, R0, R15); /* Push the next PC */ - emitALU(b, R4, R2, OP_ADD); /* R2 <- R4 + R2 */ - emitJSR(b, R1); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R2, 15, R8); /* sh2[R15] <- R2 (delay slot) */ - emitMOVWI(b, 1, R1); /* R1 <- 0x000003F3 */ - emitBRA(b, 1); /* Branch around the constant */ - emitALU(b, R1, R0, OP_AND); /* R0 <- R0 & R1 */ - emit16(b, 0x03F3); /* Mask for SR register */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 4; /* 4 Cycles */ -} - -static void generateRTS(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 21); /* R0 <- sh2[PR] */ - emitMOVLM(b, R0, R15); /* Push the PR on the stack */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateSETT(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitORI(b, 0x01); /* Set T Bit */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHAL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHAL); - b->pc += 2; -} - -static void generateSHAR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHAR); - b->pc += 2; -} - -static void generateSHLL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHLL); - b->pc += 2; -} - -static void generateSHLL2(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLL2(b, R2); /* R2 <- R2 << 2 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLL8(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLL8(b, R2); /* R2 <- R2 << 8 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLL16(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLL16(b, R2); /* R2 <- R2 << 16 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHLR); - b->pc += 2; -} - -static void generateSHLR2(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLR2(b, R2); /* R2 <- R2 >> 2 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLR8(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLR8(b, R2); /* R2 <- R2 >> 8 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLR16(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLR16(b, R2); /* R2 <- R2 >> 16 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSLEEP(uint16_t inst, sh2rec_block_t *b) { - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateSTCSR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTCGBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTCVBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 18); /* R0 <- sh2[VBR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTCMSR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateSTCMGBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateSTCMVBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 18); /* R0 <- sh2[VBR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateSTSMACH(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACH, R0); /* R0 <- MACH */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMACL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACL, R0); /* R0 <- MACL */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSPR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 21); /* R0 <- sh2[PR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMMACH(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACH, R5); /* R5 <- MACH */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMMACL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACL, R5); /* R5 <- MACL */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMPR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 21); /* R0 <- sh2[PR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSUB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_SUB); - b->pc += 2; -} - -static void generateSUBC(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, OP_SUBC); /* R2 = R2 - R3 - T (borrow to T) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSUBV(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitSUBV(b, R3, R2); /* R2 = R2 - R3 (underflow to T Bit) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSWAPB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_SWAPB); - b->pc += 2; -} - -static void generateSWAPW(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_SWAPW); - b->pc += 2; -} - -static void generateTAS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] (delay slot) */ - emitMOV(b, R0, R5); /* R5 <- R0 (byte read) */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVI(b, 0x80, R2); /* R2 <- 0x80 */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R5, R5, OP_TST); /* T <- 1 if byte == 0, 0 otherwise */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitALU(b, R2, R5, OP_OR); /* R5 <- R5 | 0x80 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 4; /* 4 Cycles */ - b->pc += 2; -} - -static void generateTRAPA(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - int disp = (((uint32_t)(b->ptr)) & 0x03) ? 5 : 6; - uint32_t val = b->pc + 2; - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MemoryMappedWriteLong */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitADDI(b, -4, R4); /* R4 <- R4 - 4 */ - emitJSR(b, R1); /* Call MemoryMappedWriteLong */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MemoryMappedWriteLong */ - emitADDI(b, -8, R4); /* R4 <- R4 - 8 */ - emitMOVLI(b, disp, R5); /* R5 <- Updated PC value (to be stacked) */ - emitJSR(b, R1); /* Call MemoryMappedWriteLong */ - emitMOVLS4(b, R4, 15, R8); /* sh2[R15] <- R4 (delay slot) */ - emitMOVI(b, imm, R4); /* R4 <- immediate data */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero-extend R4 */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MemoryMappedReadLong */ - emitMOVLLG(b, 18); /* R0 <- sh2[VBR] */ - emitSHLL2(b, R4); /* R4 <- R4 << 2 */ - emitJSR(b, R1); /* Call MemoryMappedReadLong */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitRTS(b); /* Return to sender! */ - emitNOP(b); /* XXXX: Nothing here */ - if(((uint32_t)b->ptr) & 0x03) - emit16(b, 0); /* Padding for the alignment */ - emit32(b, val); /* The PC value to be loaded by the MOVLI */ - - b->cycles += 8; /* 8 Cycles */ -} - -static void generateTST(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_TST); - b->pc += 2; -} - -static void generateTSTI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOV(b, R0, R2); /* R2 <- R0 */ - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitSHIFT(b, R2, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitTSTI(b, imm); /* tst #imm, r0 */ - emitSHIFT(b, R2, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOV(b, R2, R0); /* R0 <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateTSTM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 (delay slot) */ - emitMOV(b, R0, R5); /* R5 <- R0 (byte read) */ - emitMOVI(b, imm, R3); /* R3 <- immediate value */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R5, OP_TST); /* T <- 1 if (R5 & imm) == 0, 0 otherwise */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateXOR(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_XOR); - b->pc += 2; -} - -static void generateXORI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitXORI(b, imm); /* R0 <- R0 ^ #imm */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateXORM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitMOVLM(b, R4, R15); /* Push R4 on the stack (delay slot) */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitXORI(b, imm); /* R0 <- R0 ^ #imm */ - emitMOVLP(b, R15, R4); /* Pop R4 off the stack */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateXTRCT(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_XTRCT); - b->pc += 2; -} - -int sh2rec_rec_inst(sh2rec_block_t *b, int isdelay) { - uint16_t inst = MappedMemoryReadWord(b->pc); - int done = 0; - - switch(INSTRUCTION_A(inst)) { - case 0: - switch(INSTRUCTION_D(inst)) { - case 2: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTCSR(inst, b); break; - case 1: generateSTCGBR(inst, b); break; - case 2: generateSTCVBR(inst, b); break; - default: return -1; - } - break; - - case 3: - switch(INSTRUCTION_C(inst)) { - case 0: generateBSRF(inst, b); done = 1; break; - case 2: generateBRAF(inst, b); done = 1; break; - default: return -1; - } - break; - - case 4: generateMOVBS0(inst, b); break; - case 5: generateMOVWS0(inst, b); break; - case 6: generateMOVLS0(inst, b); break; - case 7: generateMULL(inst, b); break; - case 8: - switch(INSTRUCTION_C(inst)) { - case 0: generateCLRT(inst, b); break; - case 1: generateSETT(inst, b); break; - case 2: generateCLRMAC(inst, b); break; - default: return -1; - } - break; - - case 9: - switch(INSTRUCTION_C(inst)) { - case 0: generateNOP(inst, b); break; - case 1: generateDIV0U(inst, b); break; - case 2: generateMOVT(inst, b); break; - default: return -1; - } - break; - - case 10: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTSMACH(inst, b); break; - case 1: generateSTSMACL(inst, b); break; - case 2: generateSTSPR(inst, b); break; - default: return -1; - } - break; - - case 11: - switch(INSTRUCTION_C(inst)) { - case 0: generateRTS(inst, b); done = 1; break; - case 1: generateSLEEP(inst, b); break; - case 2: generateRTE(inst, b); done = 1; break; - default: return -1; - } - break; - - case 12: generateMOVBL0(inst, b); break; - case 13: generateMOVWL0(inst, b); break; - case 14: generateMOVLL0(inst, b); break; - case 15: generateMACL(inst, b); break; - default: return -1; - } - break; - - case 1: generateMOVLS4(inst, b); break; - case 2: - switch(INSTRUCTION_D(inst)) { - case 0: generateMOVBS(inst, b); break; - case 1: generateMOVWS(inst, b); break; - case 2: generateMOVLS(inst, b); break; - case 4: generateMOVBM(inst, b); break; - case 5: generateMOVWM(inst, b); break; - case 6: generateMOVLM(inst, b); break; - case 7: generateDIV0S(inst, b); break; - case 8: generateTST(inst, b); break; - case 9: generateAND(inst, b); break; - case 10: generateXOR(inst, b); break; - case 11: generateOR(inst, b); break; - case 12: generateCMPSTR(inst, b); break; - case 13: generateXTRCT(inst, b); break; - case 14: generateMULU(inst, b); break; - case 15: generateMULS(inst, b); break; - default: return -1; - } - break; - - case 3: - switch(INSTRUCTION_D(inst)) { - case 0: generateCMPEQ(inst, b); break; - case 2: generateCMPHS(inst, b); break; - case 3: generateCMPGE(inst, b); break; - case 4: generateDIV1(inst, b); break; - case 5: generateDMULU(inst, b); break; - case 6: generateCMPHI(inst, b); break; - case 7: generateCMPGT(inst, b); break; - case 8: generateSUB(inst, b); break; - case 10: generateSUBC(inst, b); break; - case 11: generateSUBV(inst, b); break; - case 12: generateADD(inst, b); break; - case 13: generateDMULS(inst, b); break; - case 14: generateADDC(inst, b); break; - case 15: generateADDV(inst, b); break; - default: return -1; - } - break; - - case 4: - switch(INSTRUCTION_D(inst)) { - case 0: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLL(inst, b); break; - case 1: generateDT(inst, b); break; - case 2: generateSHAL(inst, b); break; - default: return -1; - } - break; - - case 1: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLR(inst, b); break; - case 1: generateCMPPZ(inst, b); break; - case 2: generateSHAR(inst, b); break; - default: return -1; - } - break; - - case 2: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTSMMACH(inst, b); break; - case 1: generateSTSMMACL(inst, b); break; - case 2: generateSTSMPR(inst, b); break; - default: return -1; - } - break; - - case 3: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTCMSR(inst, b); break; - case 1: generateSTCMGBR(inst, b); break; - case 2: generateSTCMVBR(inst, b); break; - default: return -1; - } - break; - - case 4: - switch(INSTRUCTION_C(inst)) { - case 0: generateROTL(inst, b); break; - case 2: generateROTCL(inst, b); break; - default: return -1; - } - break; - - case 5: - switch(INSTRUCTION_C(inst)) { - case 0: generateROTR(inst, b); break; - case 1: generateCMPPL(inst, b); break; - case 2: generateROTCR(inst, b); break; - default: return -1; - } - break; - - case 6: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDSMMACH(inst, b); break; - case 1: generateLDSMMACL(inst, b); break; - case 2: generateLDSMPR(inst, b); break; - default: return -1; - } - break; - - case 7: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDCMSR(inst, b); break; - case 1: generateLDCMGBR(inst, b); break; - case 2: generateLDCMVBR(inst, b); break; - default: return -1; - } - break; - - case 8: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLL2(inst, b); break; - case 1: generateSHLL8(inst, b); break; - case 2: generateSHLL16(inst, b); break; - default: return -1; - } - break; - - case 9: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLR2(inst, b); break; - case 1: generateSHLR8(inst, b); break; - case 2: generateSHLR16(inst, b); break; - default: return -1; - } - break; - - case 10: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDSMACH(inst, b); break; - case 1: generateLDSMACL(inst, b); break; - case 2: generateLDSPR(inst, b); break; - default: return -1; - } - break; - - case 11: - switch(INSTRUCTION_C(inst)) { - case 0: generateJSR(inst, b); done = 1; break; - case 1: generateTAS(inst, b); break; - case 2: generateJMP(inst, b); done = 1; break; - default: return -1; - } - break; - - case 14: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDCSR(inst, b); break; - case 1: generateLDCGBR(inst, b); break; - case 2: generateLDCVBR(inst, b); break; - default: return -1; - } - break; - - case 15: generateMACW(inst, b); break; - default: return -1; - } - break; - - case 5: generateMOVLL4(inst, b); break; - - case 6: - switch(INSTRUCTION_D(inst)) { - case 0: generateMOVBL(inst, b); break; - case 1: generateMOVWL(inst, b); break; - case 2: generateMOVLL(inst, b); break; - case 3: generateMOV(inst, b); break; - case 4: generateMOVBP(inst, b); break; - case 5: generateMOVWP(inst, b); break; - case 6: generateMOVLP(inst, b); break; - case 7: generateNOT(inst, b); break; - case 8: generateSWAPB(inst, b); break; - case 9: generateSWAPW(inst, b); break; - case 10: generateNEGC(inst, b); break; - case 11: generateNEG(inst, b); break; - case 12: generateEXTUB(inst, b); break; - case 13: generateEXTUW(inst, b); break; - case 14: generateEXTSB(inst, b); break; - case 15: generateEXTSW(inst, b); break; - } - break; - - case 7: generateADDI(inst, b); break; - - case 8: - switch(INSTRUCTION_B(inst)) { - case 0: generateMOVBS4(inst, b); break; - case 1: generateMOVWS4(inst, b); break; - case 4: generateMOVBL4(inst, b); break; - case 5: generateMOVWL4(inst, b); break; - case 8: generateCMPIM(inst, b); break; - case 9: generateBT(inst, b); done = 1; break; - case 11: generateBF(inst, b); done = 1; break; - case 13: generateBTS(inst, b); done = 1; break; - case 15: generateBFS(inst, b); done = 1; break; - default: return -1; - } - break; - - case 9: generateMOVWI(inst, b); break; - case 10: generateBRA(inst, b); done = 1; break; - case 11: generateBSR(inst, b); done = 1; break; - - case 12: - switch(INSTRUCTION_B(inst)) { - case 0: generateMOVBSG(inst, b); break; - case 1: generateMOVWSG(inst, b); break; - case 2: generateMOVLSG(inst, b); break; - case 3: generateTRAPA(inst, b); done = 1; break; - case 4: generateMOVBLG(inst, b); break; - case 5: generateMOVWLG(inst, b); break; - case 6: generateMOVLLG(inst, b); break; - case 7: generateMOVA(inst, b); break; - case 8: generateTSTI(inst, b); break; - case 9: generateANDI(inst, b); break; - case 10: generateXORI(inst, b); break; - case 11: generateORI(inst, b); break; - case 12: generateTSTM(inst, b); break; - case 13: generateANDM(inst, b); break; - case 14: generateXORM(inst, b); break; - case 15: generateORM(inst, b); break; - } - break; - - case 13: generateMOVLI(inst, b); break; - case 14: generateMOVI(inst, b); break; - default: return -1; - } - - return done; -} - -int sh2rec_rec_block(sh2rec_block_t *b) { - int done = 0; - - while(!done) { - done = sh2rec_rec_inst(b, 0); - } - - /* Flush the icache, so we don't execute stale data */ - icache_flush_range((uint32)b->block, ((u32)b->ptr) - ((u32)b->block)); - - return 0; -} - -/* In sh2exec.s */ -extern void sh2rec_exec(SH2_struct *cxt, u32 cycles); - -static int sh2rec_init(void) { - /* Initialize anything important here */ - sh2rec_htab_init(); - return 0; -} - -static void sh2rec_deinit(void) { - /* Clean stuff up here */ - sh2rec_htab_reset(); -} - -static void sh2rec_reset(void) { - /* Reset to a sane state */ - sh2rec_htab_reset(); -} - -/* This function borrowed from the interpreter core */ -void sh2rec_check_interrupts(SH2_struct *c) { - if(c->NumberOfInterrupts != 0) { - if(c->interrupts[c->NumberOfInterrupts-1].level > c->regs.SR.part.I) { - c->regs.R[15] -= 4; - MappedMemoryWriteLong(c->regs.R[15], c->regs.SR.all); - c->regs.R[15] -= 4; - MappedMemoryWriteLong(c->regs.R[15], c->regs.PC); - c->regs.SR.part.I = c->interrupts[c->NumberOfInterrupts - 1].level; - c->regs.PC = MappedMemoryReadLong(c->regs.VBR + (c->interrupts[c->NumberOfInterrupts-1].vector << 2)); - c->NumberOfInterrupts--; - c->isSleeping = 0; - } - } -} - -sh2rec_block_t *sh2rec_find_block(u32 pc) { - sh2rec_block_t *b = sh2rec_htab_lookup(pc); - - if(!b) { - b = sh2rec_htab_block_create(pc, 4096); - sh2rec_rec_block(b); - } - - return b; -} - -SH2Interface_struct SH2Dynarec = { - SH2CORE_DYNAREC, - "SH2 -> SH4 Dynarec", - - sh2rec_init, /* Init */ - sh2rec_deinit, /* DeInit */ - sh2rec_reset, /* Reset */ - sh2rec_exec, /* Exec */ - - SH2InterpreterGetRegisters, /* GetRegisters */ - SH2InterpreterGetGPR, /* GetGPR */ - SH2InterpreterGetSR, /* GetSR */ - SH2InterpreterGetGBR, /* GetGBR */ - SH2InterpreterGetVBR, /* GetVBR */ - SH2InterpreterGetMACH, /* GetMACH */ - SH2InterpreterGetMACL, /* GetMACL */ - SH2InterpreterGetPR, /* GetPR */ - SH2InterpreterGetPC, /* GetPC */ - - SH2InterpreterSetRegisters, /* SetRegisters */ - SH2InterpreterSetGPR, /* SetGPR */ - SH2InterpreterSetSR, /* SetSR */ - SH2InterpreterSetGBR, /* SetGBR */ - SH2InterpreterSetVBR, /* SetVBR */ - SH2InterpreterSetMACH, /* SetMACH */ - SH2InterpreterSetMACL, /* SetMACL */ - SH2InterpreterSetPR, /* SetPR */ - SH2InterpreterSetPC, /* SetPC */ - - SH2InterpreterSendInterrupt, /* SendInterrupt */ - SH2InterpreterGetInterrupts, /* GetInterrupts */ - SH2InterpreterSetInterrupts, /* SetInterrupts */ - - NULL /* WriteNotify */ -}; diff --git a/yabause/src/dreamcast/sh2rec/sh2rec.h b/yabause/src/dreamcast/sh2rec/sh2rec.h deleted file mode 100644 index cd5a87ac2f..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2REC_H -#define SH2REC_H - -#define SH2CORE_DYNAREC 10 - -#define INSTRUCTION_A(x) ((x & 0xF000) >> 12) -#define INSTRUCTION_B(x) ((x & 0x0F00) >> 8) -#define INSTRUCTION_C(x) ((x & 0x00F0) >> 4) -#define INSTRUCTION_D(x) (x & 0x000F) -#define INSTRUCTION_CD(x) (x & 0x00FF) -#define INSTRUCTION_BCD(x) (x & 0x0FFF) - -typedef struct sh2rec_block { - u16 *block; - u32 start_pc; - int cycles; - int length; - - u16 *ptr; - u32 pc; -} sh2rec_block_t; - -/* Recompile a single instruction */ -int sh2rec_rec_inst(sh2rec_block_t *b, int isdelay); - -/* Recompile a block at the PC specified in the block */ -int sh2rec_rec_block(sh2rec_block_t *b); - -extern SH2Interface_struct SH2Dynarec; - -#endif /* !SH2REC_H */ diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_htab.c b/yabause/src/dreamcast/sh2rec/sh2rec_htab.c deleted file mode 100644 index 1a0e58b091..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_htab.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include - -#include "core.h" -#include "sh2core.h" -#include "sh2rec.h" -#include "sh2rec_htab.h" -#include "sh2rec_mem.h" - -typedef struct htab_entry { - sh2rec_block_t block; - - struct htab_entry *next; -} htab_entry_t; - -/* The actual hash table. It can't be resized dynamically, and is essentially - just an array of singly-linked lists. */ -static htab_entry_t *table[SH2REC_HTAB_ENTRIES]; - -/* Internal functions */ -static void htab_free_chain(htab_entry_t *ent) { - htab_entry_t *i, *tmp; - - i = ent; - while(i) { - tmp = i->next; - free(i->block.block); - free(i); - i = tmp; - } -} - -/* Hash an address into something slightly nicer to work with. The large - constant in here is about 2^32 / phi (where phi is the golden ratio). Why use - the golden ratio? Because its always fun to use in code. */ -static inline int hash_addr(u32 addr) { - return ((addr ^ 2654435761U) >> 2) & (SH2REC_HTAB_ENTRIES - 1); -} - -/* Public functions */ -void sh2rec_htab_init(void) { - memset(table, 0, sizeof(htab_entry_t *) * SH2REC_HTAB_ENTRIES); -} - -void sh2rec_htab_reset(void) { - int i; - - for(i = 0; i < SH2REC_HTAB_ENTRIES; ++i) { - if(table[i]) { - htab_free_chain(table[i]); - } - } - - memset(table, 0, sizeof(htab_entry_t *) * SH2REC_HTAB_ENTRIES); -} - -sh2rec_block_t *sh2rec_htab_lookup(u32 addr) { - htab_entry_t *i = table[hash_addr(addr)]; - - /* Look through the chain for the entry we're after */ - while(i) { - if(i->block.start_pc == addr) { - return &i->block; - } - - i = i->next; - } - - /* Didn't find it, punt. */ - return NULL; -} - -/* Create a new block assuming an old one does not exist. */ -sh2rec_block_t *sh2rec_htab_block_create(u32 addr, int length) { - uint8_t *ptr; - htab_entry_t *ent; - int index = hash_addr(addr); - - ptr = (uint8_t *)sh2rec_mem_alloc(length + sizeof(htab_entry_t)); - -#ifdef DEBUG - if(!ptr) { - return NULL; - } -#endif - - /* Allocate space for the block */ - ent = (htab_entry_t *)ptr; - ent->block.block = (u16 *)(ptr + sizeof(htab_entry_t)); - - /* Fill in the struct */ - ent->block.start_pc = addr; - ent->block.cycles = 0; - ent->block.pc = addr; - ent->block.length = length; - ent->block.ptr = ent->block.block; - - /* Put the item in the list (puts it at the head of the index in the table - where it would go) */ - ent->next = table[index]; - table[index] = ent; - - return &ent->block; -} - -void sh2rec_htab_block_remove(u32 addr) { - int index = hash_addr(addr); - htab_entry_t *i, *tmp, *last; - - i = table[index]; - last = NULL; - - /* Look through everything for the entry we're supposed to remove */ - while(i) { - tmp = i->next; - - /* Is this the entry we're looking for? */ - if(i->block.start_pc == addr) { - /* Unhook the entry from the list */ - if(last) { - last->next = tmp; - } - else { - table[index] = tmp; - } - - /* Free any memory used by the block */ - sh2rec_mem_free(i); - - return; - } - - last = i; - i = tmp; - } -} diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_htab.h b/yabause/src/dreamcast/sh2rec/sh2rec_htab.h deleted file mode 100644 index 11b096f1b1..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_htab.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2REC_HTAB_H -#define SH2REC_HTAB_H - -/* This MUST be set to a power of two. It is done this way to avoid using a mod - operation to get the entry where the object will go, since division (and thus - modulus) is quite expensive on SuperH. */ -#define SH2REC_HTAB_ENTRIES 4096 - -void sh2rec_htab_init(void); -void sh2rec_htab_reset(void); - -sh2rec_block_t *sh2rec_htab_lookup(u32 addr); -sh2rec_block_t *sh2rec_htab_block_create(u32 addr, int length); -void sh2rec_htab_block_remove(u32 addr); - -#endif /* !SH2REC_HTAB_H */ diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_mem.c b/yabause/src/dreamcast/sh2rec/sh2rec_mem.c deleted file mode 100644 index 8d8c09d47f..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_mem.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "sh2rec_mem.h" - -typedef struct block_s { - uint8_t *ptr; - int size; - struct block_s *prev; - struct block_s *next; -} sh2rec_mem_block; - -typedef struct usedblock_s { - sh2rec_mem_block base; - sh2rec_mem_block *freespace; -} sh2rec_mem_usedblock; - -typedef struct allocblock_s { - struct allocblock_s *next; -} sh2rec_mem_allocblock; - -static sh2rec_mem_block *freeblocks = NULL; -static sh2rec_mem_usedblock *usedblocks = NULL; -static sh2rec_mem_usedblock *usedblocks_tail = NULL; -static sh2rec_mem_allocblock *allocblocks = NULL; - -static int cur_allocation = 0; - -#define BSSIZE (sizeof(sh2rec_mem_allocblock) + sizeof(sh2rec_mem_block) + \ - sizeof(sh2rec_mem_usedblock)) - -int sh2rec_mem_init(void) { - sh2rec_mem_block *initblock; - sh2rec_mem_allocblock *allocblock; - uint8_t *block; - - /* Allocate our initial space for storing rec'd instructions in */ - block = (uint8_t *)malloc(SH2REC_MEM_INITIAL); - -#ifdef DEBUG - if(!block) { - return -1; - } -#endif - - /* Carve our structures out of the beginning of the block */ - allocblock = (sh2rec_mem_allocblock *)block; - initblock = (sh2rec_mem_block *)(block + sizeof(sh2rec_mem_allocblock)); - cur_allocation = SH2REC_MEM_INITIAL; - - /* Fill in the rest of the structs */ - initblock->size = SH2REC_MEM_INITIAL - sizeof(sh2rec_mem_allocblock) - - sizeof(sh2rec_mem_block); - initblock->prev = NULL; - initblock->next = NULL; - - allocblock->next = NULL; - allocblocks = allocblock; - - /* The whole block is free, so put it in the free list */ - freeblocks = initblock; - - return 0; -} - -void sh2rec_mem_shutdown(void) { - sh2rec_mem_allocblock *i, *tmp; - - /* Loop through and free any blocks we allocated */ - i = allocblocks; - while(i) { - tmp = i->next; - free(i); - i = tmp; - } - - /* Clean up the stale pointers */ - allocblocks = NULL; - freeblocks = NULL; - usedblocks = NULL; -} - -void *sh2rec_mem_alloc(int sz) { - sh2rec_mem_block *i; - sh2rec_mem_usedblock *rv; - sh2rec_mem_allocblock *b; - int szlook = sz + SH2REC_MEM_FUDGE + sizeof(sh2rec_mem_usedblock); - uint8_t *block; - - /* Look for a free block of enough size */ - i = freeblocks; - while(i) { - if(i->size >= szlook) { - /* We've found a candidate, so, start working with it */ - rv = (sh2rec_mem_usedblock *)i->ptr; - rv->freespace = i; - rv->base.ptr = i->ptr + sizeof(sh2rec_mem_usedblock); - rv->base.size = sz; - rv->base.prev = (sh2rec_mem_block *)usedblocks_tail; - rv->base.next = NULL; - - /* Update the tail */ - if(usedblocks_tail) { - usedblocks_tail->base.next = (sh2rec_mem_block *)rv; - } - - usedblocks_tail = rv; - - /* The freeblock is now smaller, so reflect that */ - i->size -= sz + sizeof(sh2rec_mem_usedblock); - - return rv; - } - - i = i->next; - } - - /* We didn't find one, so allocate a new block */ - block = malloc(SH2REC_MEM_ALLOCSZ); - -#ifdef DEBUG - if(!block) { - return NULL; - } -#endif - - /* Fill in the allocblock */ - b = (sh2rec_mem_allocblock *)block; - b->next = allocblocks; - allocblocks = b; - - /* Now, create a freeblock, and work from that */ - i = (sh2rec_mem_block *)(block + sizeof(sh2rec_mem_allocblock)); - i->ptr = block + BSSIZE + sz; - i->prev = NULL; - i->next = freeblocks; - i->size = SH2REC_MEM_ALLOCSZ - BSSIZE - sz; - freeblocks = i; - - /* Create the usedblock */ - rv = (sh2rec_mem_usedblock *)(i->ptr - sz); - rv->freespace = i; - rv->base.ptr = i->ptr; - rv->base.size = sz; - rv->base.prev = (sh2rec_mem_block *)usedblocks_tail; - rv->base.next = NULL; - - /* Update the tail */ - if(usedblocks_tail) { - usedblocks_tail->base.next = (sh2rec_mem_block *)rv; - } - - usedblocks_tail = rv; - - /* Keep track of our allocation */ - cur_allocation += SH2REC_MEM_ALLOCSZ; - - return rv; -} - -int sh2rec_mem_expand(void *block, int amt) { - sh2rec_mem_usedblock *b = (sh2rec_mem_usedblock *)block; - - /* If the freeblock has space, allow it */ - if(b->freespace->size > amt) { - b->freespace->size -= amt; - b->base.size += amt; - b->freespace->ptr += amt; - return 1; - } - - return 0; -} - -void sh2rec_mem_free(void *block) { - sh2rec_mem_usedblock *b = (sh2rec_mem_usedblock *)block; - - /* Remove the usedblock from the chain */ - if(b->base.next) { - b->base.next->prev = b->base.prev; - } - - if(b->base.prev) { - b->base.prev->next = b->base.next; - } - - if(b == usedblocks) { - usedblocks = (sh2rec_mem_usedblock *)b->base.next; - } - - if(b == usedblocks_tail) { - usedblocks_tail = (sh2rec_mem_usedblock *)b->base.prev; - } - - /* Treat the usedblock like its a freeblock (it is an extension of the - freeblock), and just link it into the free blocks list */ - b->freespace = NULL; - b->base.next = freeblocks; - b->base.prev = NULL; - b->base.size += sizeof(sh2rec_mem_usedblock) - sizeof(sh2rec_mem_block); - freeblocks = (sh2rec_mem_block *)b; -} diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_mem.h b/yabause/src/dreamcast/sh2rec/sh2rec_mem.h deleted file mode 100644 index 7fb679eb12..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_mem.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2REC_MEM_H -#define SH2REC_MEM_H - -/* Initial allocation of memory: 1MB */ -#define SH2REC_MEM_INITIAL (1024 * 1024) - -/* Size of future allocations: 256KB */ -#define SH2REC_MEM_ALLOCSZ (256 * 1024) - -/* Maximum allocation of memory: 2MB */ -#define SH2REC_MEM_MAX (2 * 1024 * 1024) - -/* Fudge factor... make sure at least this much is in any block above the - inital request */ -#define SH2REC_MEM_FUDGE 48 - -int sh2rec_mem_init(void); -void sh2rec_mem_shutdown(void); - -void *sh2rec_mem_alloc(int sz); -int sh2rec_mem_expand(void *block, int amt); -void sh2rec_mem_free(void *block); - -#endif /* !SH2REC_MEM_H */ diff --git a/yabause/src/dreamcast/viddc.c b/yabause/src/dreamcast/viddc.c deleted file mode 100644 index 52ea022f35..0000000000 --- a/yabause/src/dreamcast/viddc.c +++ /dev/null @@ -1,2836 +0,0 @@ -/* Copyright 2003-2006 Guillaume Duhamel - Copyright 2004-2009 Lawrence Sebald - Copyright 2004-2006 Theo Berkau - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "viddc.h" -#include "../debug.h" -#include "../vdp2.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define SAT2YAB1(temp) ((temp & 0x8000) | (temp & 0x1F) << 10 | \ - (temp & 0x3E0) | (temp & 0x7C00) >> 10) -#define SAT2YAB32(alpha, temp) (alpha << 24 | (temp & 0x1F) << 3 | \ - (temp & 0x3E0) << 6 | (temp & 0x7C00) << 9) - -#define SAT2YAB2(dot1, dot2) ((dot1 & 0xF8) << 7 | (dot2 & 0xF800) >> 6 | \ - (dot2 & 0x00F8) >> 3 | 0x8000) -#define SAT2YAB2_32(alpha, dot1, dot2) (alpha << 24 | ((dot1 & 0xFF) << 16) | \ - (dot2 & 0xFF00) | (dot2 & 0xFF)) - -#define COLOR_ADDt32(b) (b > 0xFF ? 0xFF : (b < 0 ? 0 : b)) -#define COLOR_ADDb32(b1,b2) COLOR_ADDt32((signed) (b1) + (b2)) - -#define COLOR_ADD32(l,r,g,b) COLOR_ADDb32((l & 0xFF), r) | \ - (COLOR_ADDb32((l >> 8) & 0xFF, g) << 8) | \ - (COLOR_ADDb32((l >> 16) & 0xFF, b) << 16) | \ - (l & 0xFF000000) - -#define COLOR_ADDt(b) (b > 0xF8 ? 0xF8 : (b < 0x08 ? 0 : b)) -#define COLOR_ADDb(b1,b2) COLOR_ADDt((signed) (b1) + (b2)) -#define COLOR_ADD(l,r,g,b) ((COLOR_ADDb((l >> 7) & 0xF8, \ - r) & 0xF8) << 7) | \ - ((COLOR_ADDb((l >> 2) & 0xF8, \ - g) & 0xF8) << 2) | \ - ((COLOR_ADDb((l << 3) & 0xF8, \ - b) & 0xF8) >> 3) | \ - (l & 0x8000) - - -static pvr_init_params_t pvr_params = { - /* Enable Opaque, Translucent, and Punch-Thru polygons with binsize 16 */ - { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, - PVR_BINSIZE_16 }, - /* 512KB Vertex Buffer */ - 512 * 1024, - /* DMA Enabled */ - 1, - /* FSAA Disabled */ - 0 -}; - -struct sprite_info { - uint32 pvr_base; - uint32 vdp1_base; - float uf, vf; - int w, h; -}; - -typedef struct { - int cellw, cellh; - int flipfunction; - int priority; - - int mapwh; - int planew, planeh; - int pagewh; - int patternwh; - int patterndatasize; - int specialfunction; - u32 addr, charaddr, paladdr; - int colornumber; - int isbitmap; - u16 supplementdata; - int auxmode; - int enable; - int x, y; - int alpha; - int coloroffset; - int transparencyenable; - int specialprimode; - - s32 cor; - s32 cog; - s32 cob; - - float coordincx, coordincy; - void (* PlaneAddr)(void *, int); - u16 (* PostPixelFetchCalc)(void *, u16); - int patternpixelwh; - int draww; - int drawh; -} vdp2draw_struct; - -static struct sprite_info cur_spr; - -static struct sprite_info cache[1024]; -int cached_spr = 0; - -/* Polygon Headers */ -static pvr_sprite_hdr_t op_poly_hdr; -static pvr_sprite_hdr_t tr_poly_hdr; -static pvr_sprite_hdr_t tr_sprite_hdr; -static pvr_sprite_hdr_t pt_sprite_hdr; - -/* DMA Vertex Buffers 256KB Each */ -static uint8 vbuf_opaque[1024 * 256] __attribute__((aligned(32))); -static uint8 vbuf_translucent[1024 * 256] __attribute__((aligned(32))); -static uint8 vbuf_punchthru[1024 * 256] __attribute__((aligned(32))); - -/* VDP2 Framebuffer */ -static uint16 *vdp2_fb; -static int vdp2_fbnum = 0; -static uint16 vdp2_fbs[2][512 * 256] __attribute__((aligned(32))); -static uint8 vdp2_prio[352][240]; -static semaphore_t *dmadone; - -static pvr_ptr_t vdp2_tex; -static uint32 cur_vdp2; - -/* Priority levels, sprites drawn last get drawn on top */ -static float priority_levels[8]; - -/* Texture space for VDP1 sprites */ -static pvr_ptr_t tex_space; -static uint32 cur_addr; - -/* Misc parameters */ -static int vdp1cor = 0; -static int vdp1cog = 0; -static int vdp1cob = 0; - -static int nbg0priority = 0; -static int nbg1priority = 0; -static int nbg2priority = 0; -static int nbg3priority = 0; -static int rbg0priority = 0; - -static int vdp2width = 320; -static int vdp2height = 224; - -/* Frame counter */ -static time_t lastup; -static int framecount; - -static int power_of_two(int num) { - int ret = 8; - - while(ret < num) - ret <<= 1; - - return ret; -} - -static inline void vdp2putpixel(s32 x, s32 y, u16 color, int priority) { - vdp2_fb[(y * 512) + x] = color; - vdp2_prio[x][y] = (uint8) priority; -} - -static u32 Vdp2ColorRamGetColor32(u32 colorindex, int alpha) { - switch(Vdp2Internal.ColorMode) { - case 0: - case 1: - { - u32 tmp; - colorindex <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, colorindex & 0xFFF); - return SAT2YAB32(alpha, tmp); - } - case 2: - { - u32 tmp1, tmp2; - colorindex <<= 2; - colorindex &= 0xFFF; - tmp1 = T2ReadWord(Vdp2ColorRam, colorindex); - tmp2 = T2ReadWord(Vdp2ColorRam, colorindex+2); - return SAT2YAB2_32(alpha, tmp1, tmp2); - } - default: - break; - } - - return 0; -} - -static uint16 Vdp2ColorRamGetColor(u32 colorindex) { - u16 tmp; - - switch(Vdp2Internal.ColorMode) { - case 0: - case 1: - { - colorindex <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, colorindex & 0xFFF); - return SAT2YAB1(tmp) | 0x8000; - } - case 2: - { - u16 tmp2; - colorindex <<= 2; - colorindex &= 0xFFF; - tmp = T2ReadWord(Vdp2ColorRam, colorindex); - tmp2 = T2ReadWord(Vdp2ColorRam, colorindex+2); - return SAT2YAB2(tmp, tmp2) | 0x8000; - } - default: - break; - } - - return 0; -} - -static int Vdp1ReadTexture(vdp1cmd_struct *cmd, pvr_sprite_hdr_t *hdr) { - u32 charAddr = cmd->CMDSRCA << 3; - uint16 dot, dot2; - int queuepos = 0; - uint32 *store_queue; - uint32 cur_base; - u8 SPD = ((cmd->CMDPMOD & 0x40) != 0); - int k; - - int wi = power_of_two(cur_spr.w); - int he = power_of_two(cur_spr.h); - - for(k = 0; k < cached_spr; ++k) { - if(cache[k].vdp1_base == charAddr) { - if(cache[k].w == cur_spr.w && cache[k].h == cur_spr.h) { - cur_base = cache[k].pvr_base; - goto fillHeader; - } - } - } - - cur_base = cur_addr; - - /* Set up both Store Queues for transfer to VRAM */ - QACR0 = 0x00000004; - QACR1 = 0x00000004; - - switch((cmd->CMDPMOD >> 3) & 0x07) { - case 0: - { - // 4 bpp Bank mode - u16 temp; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - int i, j; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF); - - if(((dot & 0xF) == 0) && !SPD) dot2 = 0; - else { - temp = Vdp2ColorRamGetColor(((dot & 0x0F) | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(((dot >> 4) == 0) && !SPD) dot = 0; - else { - temp = Vdp2ColorRamGetColor(((dot >> 4) | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - ++charAddr; - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 1: - { - // 4 bpp LUT mode - u16 temp; - u32 colorLut = cmd->CMDCOLR * 8; - int i, j; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF); - - if(((dot & 0xF) == 0) && !SPD) dot2 = 0; - else { - temp = T1ReadWord(Vdp1Ram, ((dot & 0xF) * 2 + - colorLut) & 0x7FFFF); - - if(temp & 0x8000) - dot2 = COLOR_ADD(SAT2YAB1(temp), vdp1cor, vdp1cog, - vdp1cob); - else - dot2 = COLOR_ADD(Vdp2ColorRamGetColor(temp), - vdp1cor, vdp1cog, vdp1cob); - } - - if(((dot >> 4) == 0) && !SPD) dot = 0; - else { - temp = T1ReadWord(Vdp1Ram, ((dot >> 4) * 2 + colorLut) & - 0x7FFFF); - if (temp & 0x8000) - dot = COLOR_ADD(SAT2YAB1(temp), vdp1cor, vdp1cog, - vdp1cob); - else - dot = COLOR_ADD(Vdp2ColorRamGetColor(temp), vdp1cor, - vdp1cog, vdp1cob); - } - - ++charAddr; - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 2: - { - // 8 bpp (64 color) Bank mode - int i, j; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - u16 temp; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF) & 0x3F; - dot2 = T1ReadByte(Vdp1Ram, (charAddr + 1) & 0x7FFFF) & 0x3F; - charAddr = charAddr + 2; - - if(dot || SPD) { - temp = Vdp2ColorRamGetColor((dot | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(dot2 || SPD) { - temp = Vdp2ColorRamGetColor((dot2 | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 3: - { - // 8 bpp (128 color) Bank mode - int i, j; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - u16 temp; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF) & 0x7F; - dot2 = T1ReadByte(Vdp1Ram, (charAddr + 1) & 0x7FFFF) & 0x7F; - charAddr = charAddr + 2; - - if(dot || SPD) { - temp = Vdp2ColorRamGetColor((dot | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(dot2 || SPD) { - temp = Vdp2ColorRamGetColor((dot2 | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 4: - { - // 8 bpp (256 color) Bank mode - int i, j; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - u16 temp; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF); - dot2 = T1ReadByte(Vdp1Ram, (charAddr + 1) & 0x7FFFF); - charAddr = charAddr + 2; - - if(dot || SPD) { - temp = Vdp2ColorRamGetColor((dot | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(dot2 || SPD) { - temp = Vdp2ColorRamGetColor((dot2 | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 5: - { - // 16 bpp Bank mode - int i, j; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadWord(Vdp1Ram, charAddr & 0x7FFFF); - dot2 = T1ReadWord(Vdp1Ram, (charAddr + 2) & 0x7FFFF); - charAddr = charAddr + 4; - - if(dot || SPD) - dot = COLOR_ADD(SAT2YAB1(dot), vdp1cor, vdp1cog, - vdp1cob); - - if(dot2 || SPD) - dot2 = COLOR_ADD(SAT2YAB1(dot2), vdp1cor, vdp1cog, - vdp1cob); - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - default: - VDP1LOG("Unimplemented sprite color mode: %X\n", - (cmd->CMDPMOD >> 3) & 0x7); - return 0; - } - - if(cached_spr < 1023) { - cache[cached_spr].vdp1_base = cmd->CMDSRCA << 3; - cache[cached_spr].pvr_base = cur_base; - cache[cached_spr].w = cur_spr.w; - cache[cached_spr].h = cur_spr.h; - - cached_spr++; - } - -fillHeader: - - cur_spr.uf = (float) cur_spr.w / wi; - cur_spr.vf = (float) cur_spr.h / he; - - hdr->mode2 &= (~(PVR_TA_PM2_USIZE_MASK | PVR_TA_PM2_VSIZE_MASK)); - - switch (wi) { - case 8: break; - case 16: hdr->mode2 |= (1 << PVR_TA_PM2_USIZE_SHIFT); break; - case 32: hdr->mode2 |= (2 << PVR_TA_PM2_USIZE_SHIFT); break; - case 64: hdr->mode2 |= (3 << PVR_TA_PM2_USIZE_SHIFT); break; - case 128: hdr->mode2 |= (4 << PVR_TA_PM2_USIZE_SHIFT); break; - case 256: hdr->mode2 |= (5 << PVR_TA_PM2_USIZE_SHIFT); break; - case 512: hdr->mode2 |= (6 << PVR_TA_PM2_USIZE_SHIFT); break; - case 1024: hdr->mode2 |= (7 << PVR_TA_PM2_USIZE_SHIFT); break; - default: assert_msg(0, "Invalid texture U size"); break; - } - - switch (he) { - case 8: break; - case 16: hdr->mode2 |= (1 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 32: hdr->mode2 |= (2 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 64: hdr->mode2 |= (3 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 128: hdr->mode2 |= (4 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 256: hdr->mode2 |= (5 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 512: hdr->mode2 |= (6 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 1024: hdr->mode2 |= (7 << PVR_TA_PM2_VSIZE_SHIFT); break; - default: assert_msg(0, "Invalid texture V size"); break; - } - - hdr->mode3 = ((cur_base & 0x00FFFFF8) >> 3) | (PVR_TXRFMT_NONTWIDDLED); - - /* Make sure everything is aligned nicely... */ - cur_addr = (cur_addr & 0x03FFFFE0) + 0x20; - - return 1; -} - -static u8 Vdp1ReadPriority(vdp1cmd_struct *cmd) { - u8 SPCLMD = Vdp2Regs->SPCTL; - u8 sprite_register; - u8 *sprprilist = (u8 *)&Vdp2Regs->PRISA; - - if ((SPCLMD & 0x20) && (cmd->CMDCOLR & 0x8000)) { - // RGB data, use register 0 - return Vdp2Regs->PRISA & 0x07; - } - else { - u8 sprite_type = SPCLMD & 0x0F; - switch(sprite_type) { - case 0: - sprite_register = ((cmd->CMDCOLR & 0x8000) | - (~cmd->CMDCOLR & 0x4000)) >> 14; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 1: - sprite_register = ((cmd->CMDCOLR & 0xC000) | - (~cmd->CMDCOLR & 0x2000)) >> 13; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 3: - sprite_register = ((cmd->CMDCOLR & 0x4000) | - (~cmd->CMDCOLR & 0x2000)) >> 13; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 4: - sprite_register = ((cmd->CMDCOLR & 0x4000) | - (~cmd->CMDCOLR & 0x2000)) >> 13; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 5: - sprite_register = ((cmd->CMDCOLR & 0x6000) | - (~cmd->CMDCOLR & 0x1000)) >> 12; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 6: - sprite_register = ((cmd->CMDCOLR & 0x6000) | - (~cmd->CMDCOLR & 0x1000)) >> 12; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 7: - sprite_register = ((cmd->CMDCOLR & 0x6000) | - (~cmd->CMDCOLR & 0x1000)) >> 12; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - default: - VDP1LOG("sprite type %d not implemented\n", sprite_type); - return 0x07; - break; - } - } -} - -/* This has all been imported from the vidsoft.c file. It will be updated, - hopefully (roughly) synchronized with updates to it */ - -////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - int xstart, ystart; - int xend, yend; - int pixeloffset; - int lineincrement; -} clipping_struct; - -static void inline HandleClipping(vdp2draw_struct *info, clipping_struct *clip) -{ - clip->pixeloffset=0; - clip->lineincrement=0; - - // Handle clipping(both window and screen clipping) - if (info->x < 0) - { - clip->xstart = 0; - clip->xend = (info->x+info->cellw); - clip->pixeloffset = 0 - info->x; - clip->lineincrement = 0 - info->x; - } - else - { - clip->xstart = info->x; - - if ((info->x+info->cellw) > vdp2width) - { - clip->xend = vdp2width; - clip->lineincrement = (info->x+info->cellw) - vdp2width; - } - else - clip->xend = (info->x+info->cellw); - } - - if (info->y < 0) - { - clip->ystart = 0; - clip->yend = (info->y+info->cellh); - clip->pixeloffset = (info->cellw * (0 - info->y)) + clip->pixeloffset; - } - else - { - clip->ystart = info->y; - - if ((info->y+info->cellh) >= vdp2height) - clip->yend = vdp2height; - else - clip->yend = (info->y+info->cellh); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Vdp2DrawScrollBitmap(vdp2draw_struct *info) -{ - int i, i2; - clipping_struct clip; - - HandleClipping(info, &clip); - - switch (info->colornumber) - { - case 0: // 4 BPP(16 colors) - // fix me - printf("vdp2 bitmap 4 bpp draw\n"); - return; - case 1: // 8 BPP(256 colors) - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 color = T1ReadByte(Vdp2Ram, info->charaddr); - info->charaddr++; - - if (color == 0 && info->transparencyenable) { - vdp2putpixel(i2, i, 0, info->priority); - } - else { - color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | color)); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color) | 0x8000, info->priority); - } - } - - info->charaddr += clip.lineincrement; - } - - return; - case 2: - printf("vdp2 bitmap 16bpp palette draw\n"); - break; - case 3: // 15 BPP - clip.pixeloffset *= 2; - clip.lineincrement *= 2; - - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 color = T1ReadWord(Vdp2Ram, info->charaddr); - info->charaddr += 2; - - if ((color & 0x8000) == 0 && info->transparencyenable) - vdp2_fb[(i * vdp2width) + i2] = 0; - else - vdp2_fb[(i * vdp2width) + i2] = info->PostPixelFetchCalc(info, SAT2YAB1(color)) | 0x8000; - - vdp2_prio[i][i2] = info->priority; - } - - info->charaddr += clip.lineincrement; - } - - return; - case 4: // 24 BPP - clip.pixeloffset *= 4; - clip.lineincrement *= 4; - - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u32 color = T1ReadLong(Vdp2Ram, info->charaddr); - info->charaddr += 4; - - if ((color & 0x80000000) == 0 && info->transparencyenable) - vdp2putpixel(i2, i, 0, info->priority); - else { - u16 dot = ((color & 0xF80000) >> 19 | - (color & 0x00F800) >> 6 | - (color & 0x0000F8) << 7 | 0x8000); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, dot), info->priority); - } - } - - info->charaddr += clip.lineincrement; - - } - return; - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -#define Vdp2DrawCell4bpp(mask, shift) \ - if ((dot & mask) == 0 && info->transparencyenable) { \ - vdp2putpixel(i2, i, 0, info->priority); \ - } \ - else \ - { \ - color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | ((dot & mask) >> shift))); \ - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color), info->priority); \ - } - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawCell(vdp2draw_struct *info) -{ - u32 color; - int i, i2; - clipping_struct clip; - u32 newcharaddr; - - HandleClipping(info, &clip); - - if (info->flipfunction & 0x1) - { - // Horizontal flip - } - - if (info->flipfunction & 0x2) - { - // Vertical flip - // clip.pixeloffset = (info.w * info.h) - clip.pixeloffset; - // clip.lineincrement = 0 - clip.lineincrement; - } - - switch(info->colornumber) - { - case 0: // 4 BPP - if ((clip.lineincrement | clip.pixeloffset) == 0) - { - for (i = clip.ystart; i < clip.yend; i++) - { - u32 dot; - u16 color; - - i2 = clip.xstart; - - // Fetch Pixel 1/2/3/4/5/6/7/8 - dot = T1ReadLong(Vdp2Ram, info->charaddr); - info->charaddr+=4; - - // Draw 8 Pixels - Vdp2DrawCell4bpp(0xF0000000, 28) - i2++; - Vdp2DrawCell4bpp(0x0F000000, 24) - i2++; - Vdp2DrawCell4bpp(0x00F00000, 20) - i2++; - Vdp2DrawCell4bpp(0x000F0000, 16) - i2++; - Vdp2DrawCell4bpp(0x0000F000, 12) - i2++; - Vdp2DrawCell4bpp(0x00000F00, 8) - i2++; - Vdp2DrawCell4bpp(0x000000F0, 4) - i2++; - Vdp2DrawCell4bpp(0x0000000F, 0) - i2++; - } - } - else - { - u8 dot; - - newcharaddr = info->charaddr + ((info->cellw * info->cellh) >> 1); - - info->charaddr <<= 1; - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - dot = T1ReadByte(Vdp2Ram, info->charaddr >> 1); - info->charaddr++; - - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u32 color; - - // Draw two pixels - if(info->charaddr & 0x1) - { - Vdp2DrawCell4bpp(0xF0, 4) - info->charaddr++; - } - else - { - Vdp2DrawCell4bpp(0x0F, 0) - dot = T1ReadByte(Vdp2Ram, info->charaddr >> 1); - info->charaddr++; - } - } - info->charaddr += clip.lineincrement; - } - - info->charaddr = newcharaddr; - } - break; - case 1: // 8 BPP - newcharaddr = info->charaddr + (info->cellw * info->cellh); - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 color = T1ReadByte(Vdp2Ram, info->charaddr); - info->charaddr++; - - if (color == 0 && info->transparencyenable) { - vdp2putpixel(i2, i, 0, info->priority); - } - else { - color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | color)); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color), info->priority); - } - } - - info->charaddr += clip.lineincrement; - } - - info->charaddr = newcharaddr; - - break; - case 2: // 16 BPP(palette) - printf("vdp2 cell draw 16bpp palette\n"); - break; - - case 3: // 16 BPP(RGB) - printf("vdp2 cell draw 16bpp\n"); - break; - case 4: // 32 BPP - newcharaddr = info->charaddr + (info->cellw * info->cellh); - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 dot1, dot2; - dot1 = T1ReadWord(Vdp2Ram, info->charaddr & 0x7FFFF); - info->charaddr += 2; - dot2 = T1ReadWord(Vdp2Ram, info->charaddr & 0x7FFFF); - info->charaddr += 2; - - if (!(dot1 & 0x8000) && info->transparencyenable) - continue; - - color = SAT2YAB2(dot1, dot2); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color), info->priority); - } - - info->charaddr += clip.lineincrement; - } - - info->charaddr = newcharaddr; - - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawPattern(vdp2draw_struct *info) -{ - // if (info->specialprimode == 1) - // tile.priority = (info->priority & 0xFFFFFFFE) | info->specialfunction; - // else - // tile.priority = info->priority; - - switch(info->patternwh) - { - case 1: - Vdp2DrawCell(info); - info->x += 8; - info->y += 8; - break; - case 2: - Vdp2DrawCell(info); - info->x += 8; - Vdp2DrawCell(info); - info->x -= 8; - info->y += 8; - Vdp2DrawCell(info); - info->x += 8; - Vdp2DrawCell(info); - info->x += 8; - info->y += 8; - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2PatternAddr(vdp2draw_struct *info) -{ - switch(info->patterndatasize) - { - case 1: - { - u16 tmp = T1ReadWord(Vdp2Ram, info->addr); - - info->addr += 2; - info->specialfunction = (info->supplementdata >> 9) & 0x1; - - switch(info->colornumber) - { - case 0: // in 16 colors - info->paladdr = ((tmp & 0xF000) >> 8) | ((info->supplementdata & 0xE0) << 3); - break; - default: // not in 16 colors - info->paladdr = (tmp & 0x7000) >> 4; - break; - } - - switch(info->auxmode) - { - case 0: - info->flipfunction = (tmp & 0xC00) >> 10; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0x3FF) | ((info->supplementdata & 0x1F) << 10); - break; - case 2: - info->charaddr = ((tmp & 0x3FF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x1C) << 10); - break; - } - break; - case 1: - info->flipfunction = 0; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0xFFF) | ((info->supplementdata & 0x1C) << 10); - break; - case 2: - info->charaddr = ((tmp & 0xFFF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x10) << 10); - break; - } - break; - } - - break; - } - case 2: { - u16 tmp1 = T1ReadWord(Vdp2Ram, info->addr); - u16 tmp2 = T1ReadWord(Vdp2Ram, info->addr+2); - info->addr += 4; - info->charaddr = tmp2 & 0x7FFF; - info->flipfunction = (tmp1 & 0xC000) >> 14; - info->paladdr = (tmp1 & 0x7F) << 4; - info->specialfunction = (tmp1 & 0x2000) >> 13; - break; - } - } - - if (!(Vdp2Regs->VRSIZE & 0x8000)) - info->charaddr &= 0x3FFF; - - info->charaddr *= 0x20; // selon Runik -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawPage(vdp2draw_struct *info) -{ - int X, Y; - int i, j; - - X = info->x; - for(i = 0;i < info->pagewh;i++) - { - Y = info->y; - info->x = X; - for(j = 0;j < info->pagewh;j++) - { - info->y = Y; - if ((info->x >= -info->patternpixelwh) && - (info->y >= -info->patternpixelwh) && - (info->x <= info->draww) && - (info->y <= info->drawh)) - { - Vdp2PatternAddr(info); - Vdp2DrawPattern(info); - } - else - { - info->addr += info->patterndatasize * 2; - info->x += info->patternpixelwh; - info->y += info->patternpixelwh; - } - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawPlane(vdp2draw_struct *info) -{ - int X, Y; - int i, j; - - X = info->x; - for(i = 0;i < info->planeh;i++) - { - Y = info->y; - info->x = X; - for(j = 0;j < info->planew;j++) - { - info->y = Y; - Vdp2DrawPage(info); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawMap(vdp2draw_struct *info) -{ - int i, j; - int X, Y; - u32 lastplane; - - X = info->x; - lastplane=0xFFFFFFFF; - - info->patternpixelwh = 8 * info->patternwh; - info->draww = (int)((float)vdp2width / info->coordincx); - info->drawh = (int)((float)vdp2height / info->coordincy); - - for(i = 0;i < info->mapwh;i++) - { - Y = info->y; - info->x = X; - for(j = 0;j < info->mapwh;j++) - { - info->y = Y; - info->PlaneAddr(info, info->mapwh * i + j); - if (info->addr != lastplane) - { - Vdp2DrawPlane(info); - lastplane = info->addr; - } - } - } -} - -static int VIDDCInit(void) { - pvr_sprite_cxt_t op_poly_cxt, tr_poly_cxt; - pvr_sprite_cxt_t pt_sprite_cxt, tr_sprite_cxt; - - vid_set_mode(DM_320x240, PM_RGB565); - - if(pvr_init(&pvr_params)) { - fprintf(stderr, "VIDDCInit() - error initializing PVR\n"); - return -1; - } - - dmadone = sem_create(1); - - pvr_set_vertbuf(PVR_LIST_OP_POLY, vbuf_opaque, 1024 * 256); - pvr_set_vertbuf(PVR_LIST_TR_POLY, vbuf_translucent, 1024 * 256); - pvr_set_vertbuf(PVR_LIST_PT_POLY, vbuf_punchthru, 1024 * 256); - - tex_space = pvr_mem_malloc(1024 * 1024 * 2); - vdp2_tex = pvr_mem_malloc(512 * 256 * 4 * 2); - cur_addr = (uint32)tex_space; - - printf("PVR Memory Available: %lu\n", pvr_mem_available()); - - sq_set(tex_space, 0xFF, 1024 * 1024 * 2); - - pvr_sprite_cxt_col(&op_poly_cxt, PVR_LIST_OP_POLY); - pvr_sprite_cxt_col(&tr_poly_cxt, PVR_LIST_TR_POLY); - - op_poly_cxt.gen.culling = PVR_CULLING_NONE; - tr_poly_cxt.gen.culling = PVR_CULLING_NONE; - - pvr_sprite_compile(&op_poly_hdr, &op_poly_cxt); - pvr_sprite_compile(&tr_poly_hdr, &tr_poly_cxt); - - pvr_sprite_cxt_txr(&tr_sprite_cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB1555 | - PVR_TXRFMT_NONTWIDDLED, 1024, 1024, tex_space, - PVR_FILTER_NONE); - pvr_sprite_cxt_txr(&pt_sprite_cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_ARGB1555 | - PVR_TXRFMT_NONTWIDDLED, 1024, 1024, tex_space, - PVR_FILTER_NONE); - - pt_sprite_cxt.gen.culling = PVR_CULLING_NONE; - tr_sprite_cxt.gen.culling = PVR_CULLING_NONE; - - pvr_sprite_compile(&tr_sprite_hdr, &tr_sprite_cxt); - pvr_sprite_compile(&pt_sprite_hdr, &pt_sprite_cxt); - - tr_sprite_hdr.argb = PVR_PACK_COLOR(0.5f, 1.0f, 1.0f, 1.0f); - - priority_levels[0] = 0.0f; - priority_levels[1] = 1.0f; - priority_levels[2] = 2.0f; - priority_levels[3] = 3.0f; - priority_levels[4] = 4.0f; - priority_levels[5] = 5.0f; - priority_levels[6] = 6.0f; - priority_levels[7] = 7.0f; - - framecount = 0; - lastup = time(NULL); - - return 0; -} - -static void VIDDCDeInit(void) { - pvr_set_vertbuf(PVR_LIST_OP_POLY, NULL, 0); - pvr_set_vertbuf(PVR_LIST_TR_POLY, NULL, 0); - pvr_set_vertbuf(PVR_LIST_PT_POLY, NULL, 0); - - pvr_mem_free(tex_space); - sem_destroy(dmadone); - - pvr_shutdown(); - vid_set_mode(DM_640x480, PM_RGB565); -} - -static void VIDDCResize(unsigned int w, unsigned int h, int unused) { -} - -static int VIDDCIsFullscreen(void) { - return 1; -} - -static int VIDDCVdp1Reset(void) { - return 0; -} - -static void VIDDCVdp1DrawStart(void) { - if(Vdp2Regs->CLOFEN & 0x40) { - // color offset enable - if(Vdp2Regs->CLOFSL & 0x40) { - // color offset B - vdp1cor = Vdp2Regs->COBR & 0xFF; - if(Vdp2Regs->COBR & 0x100) - vdp1cor |= 0xFFFFFF00; - - vdp1cog = Vdp2Regs->COBG & 0xFF; - if(Vdp2Regs->COBG & 0x100) - vdp1cog |= 0xFFFFFF00; - - vdp1cob = Vdp2Regs->COBB & 0xFF; - if(Vdp2Regs->COBB & 0x100) - vdp1cob |= 0xFFFFFF00; - } - else { - // color offset A - vdp1cor = Vdp2Regs->COAR & 0xFF; - if(Vdp2Regs->COAR & 0x100) - vdp1cor |= 0xFFFFFF00; - - vdp1cog = Vdp2Regs->COAG & 0xFF; - if(Vdp2Regs->COAG & 0x100) - vdp1cog |= 0xFFFFFF00; - - vdp1cob = Vdp2Regs->COAB & 0xFF; - if(Vdp2Regs->COAB & 0x100) - vdp1cob |= 0xFFFFFF00; - } - } - else // color offset disable - vdp1cor = vdp1cog = vdp1cob = 0; -} - -static void VIDDCVdp1DrawEnd(void) { - cached_spr = 0; - priority_levels[0] = 0.0f; - priority_levels[1] = 1.0f; - priority_levels[2] = 2.0f; - priority_levels[3] = 3.0f; - priority_levels[4] = 4.0f; - priority_levels[5] = 5.0f; - priority_levels[6] = 6.0f; - priority_levels[7] = 7.0f; -} - -static void VIDDCVdp1NormalSpriteDraw(void) { - int x, y, num; - u8 z; - vdp1cmd_struct cmd; - pvr_sprite_txr_t sprite; - pvr_list_t list; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x = Vdp1Regs->localX + cmd.CMDXA; - y = Vdp1Regs->localY + cmd.CMDYA; - cur_spr.w = ((cmd.CMDSIZE >> 8) & 0x3F) << 3; - cur_spr.h = cmd.CMDSIZE & 0xFF; - - if ((cmd.CMDPMOD & 0x07) == 0x03) { - list = PVR_LIST_TR_POLY; - num = Vdp1ReadTexture(&cmd, &tr_sprite_hdr); - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_TR_POLY, &tr_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - else { - num = Vdp1ReadTexture(&cmd, &pt_sprite_hdr); - list = PVR_LIST_PT_POLY; - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - - z = Vdp1ReadPriority(&cmd); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = x; - sprite.ay = y; - sprite.az = priority_levels[z]; - - sprite.bx = x + cur_spr.w; - sprite.by = y; - sprite.bz = priority_levels[z]; - - sprite.cx = x + cur_spr.w; - sprite.cy = y + cur_spr.h; - sprite.cz = priority_levels[z]; - - sprite.dx = x; - sprite.dy = y + cur_spr.h; - - sprite.auv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? cur_spr.uf : 0.0f), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.buv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.cuv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? 0.0f : cur_spr.vf)); - pvr_list_prim(list, &sprite, sizeof(sprite)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1ScaledSpriteDraw(void) { - vdp1cmd_struct cmd; - s16 rw = 0, rh = 0; - s16 x, y; - u8 z; - pvr_sprite_txr_t sprite; - pvr_list_t list; - int num; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x = cmd.CMDXA + Vdp1Regs->localX; - y = cmd.CMDYA + Vdp1Regs->localY; - cur_spr.w = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - cur_spr.h = cmd.CMDSIZE & 0xFF; - - if((cmd.CMDPMOD & 0x07) == 0x03) { - list = PVR_LIST_TR_POLY; - num = Vdp1ReadTexture(&cmd, &tr_sprite_hdr); - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_TR_POLY, &tr_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - else { - num = Vdp1ReadTexture(&cmd, &pt_sprite_hdr); - list = PVR_LIST_PT_POLY; - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - - // Setup Zoom Point - switch ((cmd.CMDCTRL & 0xF00) >> 8) { - case 0x0: // Only two coordinates - rw = cmd.CMDXC - x + Vdp1Regs->localX + 1; - rh = cmd.CMDYC - y + Vdp1Regs->localY + 1; - break; - case 0x5: // Upper-left - rw = cmd.CMDXB + 1; - rh = cmd.CMDYB + 1; - break; - case 0x6: // Upper-Center - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw / 2; - ++rw; - ++rh; - break; - case 0x7: // Upper-Right - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw; - ++rw; - ++rh; - break; - case 0x9: // Center-left - rw = cmd.CMDXB; - rh = cmd.CMDYB; - y = y - rh / 2; - ++rw; - ++rh; - break; - case 0xA: // Center-center - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw / 2; - y = y - rh / 2; - ++rw; - ++rh; - break; - case 0xB: // Center-right - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw; - y = y - rh / 2; - ++rw; - ++rh; - break; - case 0xD: // Lower-left - rw = cmd.CMDXB; - rh = cmd.CMDYB; - y = y - rh; - ++rw; - ++rh; - break; - case 0xE: // Lower-center - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw / 2; - y = y - rh; - ++rw; - ++rh; - break; - case 0xF: // Lower-right - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw; - y = y - rh; - ++rw; - ++rh; - break; - default: - break; - } - - z = Vdp1ReadPriority(&cmd); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = x; - sprite.ay = y; - sprite.az = priority_levels[z]; - - sprite.bx = x + rw; - sprite.by = y; - sprite.bz = priority_levels[z]; - - sprite.cx = x + rw; - sprite.cy = y + rh; - sprite.cz = priority_levels[z]; - - sprite.dx = x; - sprite.dy = y + rh; - - sprite.auv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? cur_spr.uf : 0.0f), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.buv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.cuv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? 0.0f : cur_spr.vf)); - pvr_list_prim(list, &sprite, sizeof(sprite)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1DistortedSpriteDraw(void) { - vdp1cmd_struct cmd; - u8 z; - pvr_sprite_txr_t sprite; - pvr_list_t list; - int num; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - cur_spr.w = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - cur_spr.h = cmd.CMDSIZE & 0xFF; - - if((cmd.CMDPMOD & 0x7) == 0x3) { - list = PVR_LIST_TR_POLY; - num = Vdp1ReadTexture(&cmd, &tr_sprite_hdr); - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_TR_POLY, &tr_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - else { - num = Vdp1ReadTexture(&cmd, &pt_sprite_hdr); - list = PVR_LIST_PT_POLY; - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - - z = Vdp1ReadPriority(&cmd); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = cmd.CMDXA + Vdp1Regs->localX; - sprite.ay = cmd.CMDYA + Vdp1Regs->localY; - sprite.az = priority_levels[z]; - - sprite.bx = cmd.CMDXB + Vdp1Regs->localX + 1; - sprite.by = cmd.CMDYB + Vdp1Regs->localY; - sprite.bz = priority_levels[z]; - - sprite.cx = cmd.CMDXC + Vdp1Regs->localX + 1; - sprite.cy = cmd.CMDYC + Vdp1Regs->localY + 1; - sprite.cz = priority_levels[z]; - - sprite.dx = cmd.CMDXD + Vdp1Regs->localX; - sprite.dy = cmd.CMDYD + Vdp1Regs->localY + 1; - - sprite.auv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? cur_spr.uf : 0.0f), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.buv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.cuv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? 0.0f : cur_spr.vf)); - pvr_list_prim(list, &sprite, sizeof(sprite)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1PolygonDraw(void) { - s16 X[4]; - s16 Y[4]; - u16 color; - u16 CMDPMOD; - u8 alpha, z; - pvr_list_t list; - pvr_sprite_col_t spr; - pvr_sprite_hdr_t *hdr; - - X[0] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Y[0] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); - X[1] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x10); - Y[1] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x12); - X[2] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Y[2] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); - X[3] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x18); - Y[3] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x1A); - - color = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x06); - CMDPMOD = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x04); - - /* Don't bother rendering completely transparent polygons */ - if((!(color & 0x8000) && !(CMDPMOD & 0x0040)) || !color) { - return; - } - - if((CMDPMOD & 0x0007) == 0x0003) { - alpha = 0x80; - list = PVR_LIST_TR_POLY; - hdr = &tr_poly_hdr; - } - else { - alpha = 0xFF; - list = PVR_LIST_OP_POLY; - hdr = &op_poly_hdr; - } - - if(color & 0x8000) { - hdr->argb = COLOR_ADD32(SAT2YAB32(alpha, color), vdp1cor, vdp1cog, - vdp1cob); - } - else { - hdr->argb = COLOR_ADD32(Vdp2ColorRamGetColor32(color, alpha), vdp1cor, - vdp1cog, vdp1cob); - } - - pvr_list_prim(list, hdr, sizeof(pvr_sprite_hdr_t)); - - z = Vdp2Regs->PRISA & 0x07; - - spr.flags = PVR_CMD_VERTEX_EOL; - spr.d1 = spr.d2 = spr.d3 = spr.d4 = 0; - spr.az = spr.bz = spr.cz = priority_levels[z]; - - spr.ax = X[0]; - spr.ay = Y[0]; - spr.bx = X[1]; - spr.by = Y[1]; - spr.cx = X[2]; - spr.cy = Y[2]; - spr.dx = X[3]; - spr.dy = Y[3]; - - pvr_list_prim(list, &spr, sizeof(pvr_sprite_col_t)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1PolylineDraw(void) { -} - -static void VIDDCVdp1LineDraw(void) { -} - -static void VIDDCVdp1UserClipping(void) { - Vdp1Regs->userclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Vdp1Regs->userclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); - Vdp1Regs->userclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->userclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -static void VIDDCVdp1SystemClipping(void) { - Vdp1Regs->systemclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Vdp1Regs->systemclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); - Vdp1Regs->systemclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->systemclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -static void VIDDCVdp1LocalCoordinate(void) { - Vdp1Regs->localX = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Vdp1Regs->localY = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoNothing(void *info, u16 pixel) -{ - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoColorOffset(void *info, u16 pixel) -{ - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoColorCalc(void *info, u16 pixel) -{ - // should be doing color calculation here - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoColorCalcWithColorOffset(void *info, u16 pixel) -{ - // should be doing color calculation here - - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -static void Vdp2DrawBackScreen() { - u32 scrAddr; - u16 dot; - pvr_sprite_col_t spr; - - if(Vdp2Regs->VRSIZE & 0x8000) - scrAddr = (((Vdp2Regs->BKTAU & 0x07) << 16) | Vdp2Regs->BKTAL) << 1; - else - scrAddr = (((Vdp2Regs->BKTAU & 0x03) << 16) | Vdp2Regs->BKTAL) << 1; - - if(Vdp2Regs->BKTAU & 0x8000) { - int i; - - for(i = 0; i < vdp2height; ++i) { - dot = T1ReadWord(Vdp2Ram, scrAddr); - scrAddr += 2; - - op_poly_hdr.argb = SAT2YAB32(0xFF, dot); - pvr_list_prim(PVR_LIST_OP_POLY, &op_poly_hdr, - sizeof(pvr_sprite_hdr_t)); - - spr.flags = PVR_CMD_VERTEX_EOL; - spr.ax = 0.0f; - spr.ay = i + 1; - spr.az = 0.1f; - spr.bx = 0.0f; - spr.by = i; - spr.bz = 0.1f; - spr.cx = vdp2width; - spr.cy = i; - spr.cz = 0.1f; - spr.dx = vdp2width; - spr.dy = i + 1; - spr.d1 = spr.d2 = spr.d3 = spr.d4 = 0; - pvr_list_prim(PVR_LIST_OP_POLY, &spr, sizeof(pvr_sprite_col_t)); - } - } - else { - dot = T1ReadWord(Vdp2Ram, scrAddr); - - op_poly_hdr.argb = SAT2YAB32(0xFF, dot); - pvr_list_prim(PVR_LIST_OP_POLY, &op_poly_hdr, sizeof(pvr_sprite_hdr_t)); - - spr.flags = PVR_CMD_VERTEX_EOL; - spr.ax = 0.0f; - spr.ay = vdp2height; - spr.az = 0.1f; - spr.bx = 0.0f; - spr.by = 0.0f; - spr.bz = 0.1f; - spr.cx = vdp2width; - spr.cy = 0.0f; - spr.cz = 0.1f; - spr.dx = vdp2width; - spr.dy = vdp2height; - spr.d1 = spr.d2 = spr.d3 = spr.d4 = 0; - pvr_list_prim(PVR_LIST_OP_POLY, &spr, sizeof(pvr_sprite_col_t)); - } -} - -static void Vdp2DrawLineColorScreen() { -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG0PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x7) << 6; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN0 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN0 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN0 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN0 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) - //{ - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else - { - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG0(void) -{ - vdp2draw_struct info; - - /* FIXME should start by checking if it's a normal - * or rotate scroll screen - */ - info.enable = Vdp2Regs->BGON & 0x1; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x100); - info.specialprimode = Vdp2Regs->SFPRMD & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x70) >> 4; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x2) != 0) - { - // Bitmap Mode - - switch((Vdp2Regs->CHCTLA & 0xC) >> 2) - { - case 0: info.cellw = 512; - info.cellh = 256; - break; - case 1: info.cellw = 512; - info.cellh = 512; - break; - case 2: info.cellw = 1024; - info.cellh = 256; - break; - case 3: info.cellw = 1024; - info.cellh = 512; - break; - } - - info.x = - ((Vdp2Regs->SCXIN0 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN0 & 0x7FF) % info.cellh); - - info.charaddr = (Vdp2Regs->MPOFN & 0x7) * 0x20000; - info.paladdr = (Vdp2Regs->BMPNA & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 2; - - switch(Vdp2Regs->PLSZ & 0x3) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - - info.x = - ((Vdp2Regs->SCXIN0 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYIN0 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN0 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLA & 0x1) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN0 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN0 & 0x4000) >> 14; - } - - if (Vdp2Regs->CCCTL & 0x1) - info.alpha = ((~Vdp2Regs->CCRNA & 0x1F) << 3) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7) << 8; - - if (Vdp2Regs->CLOFEN & 0x1) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x1) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x1) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x1) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = (float) 65536 / (Vdp2Regs->ZMXN0.all & 0x7FF00); - info.coordincy = (float) 65536 / (Vdp2Regs->ZMYN0.all & 0x7FF00); - - info.priority = nbg0priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG0PlaneAddr; - - if (info.isbitmap) - Vdp2DrawScrollBitmap(&info); - else - Vdp2DrawMap(&info); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG1PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x70) << 2; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN1 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN1 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN1 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN1 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) - //{ - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else - { - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG1(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x2; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x200); - info.specialprimode = (Vdp2Regs->SFPRMD >> 2) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x3000) >> 12; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x200) != 0) - { - switch((Vdp2Regs->CHCTLA & 0xC00) >> 10) - { - case 0: info.cellw = 512; - info.cellh = 256; - break; - case 1: info.cellw = 512; - info.cellh = 512; - break; - case 2: info.cellw = 1024; - info.cellh = 256; - break; - case 3: info.cellw = 1024; - info.cellh = 512; - break; - } - - info.x = - ((Vdp2Regs->SCXIN1 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN1 & 0x7FF) % info.cellh); - - info.charaddr = ((Vdp2Regs->MPOFN & 0x70) >> 4) * 0x20000; - info.paladdr = Vdp2Regs->BMPNA & 0x700; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - info.mapwh = 2; - - switch((Vdp2Regs->PLSZ & 0xC) >> 2) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - - info.x = - ((Vdp2Regs->SCXIN1 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYIN1 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN1 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLA & 0x100) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN1 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN1 & 0x4000) >> 14; - } - - if (Vdp2Regs->CCCTL & 0x2) - info.alpha = ((~Vdp2Regs->CCRNA & 0x1F00) >> 5) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x70) << 4; - - if (Vdp2Regs->CLOFEN & 0x2) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x2) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x2) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x2) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = (float) 65536 / (Vdp2Regs->ZMXN1.all & 0x7FF00); - info.coordincy = (float) 65536 / (Vdp2Regs->ZMXN1.all & 0x7FF00); - - info.priority = nbg1priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG1PlaneAddr; - - if (info.isbitmap) - { - Vdp2DrawScrollBitmap(&info); -/* - // Handle Scroll Wrapping(Let's see if we even need do to it to begin - // with) - if (info.x < (vdp2width - info.cellw)) - { - info.vertices[0] = (info.x+info.cellw) * info.coordincx; - info.vertices[2] = (info.x + (info.cellw<<1)) * info.coordincx; - info.vertices[4] = (info.x + (info.cellw<<1)) * info.coordincx; - info.vertices[6] = (info.x+info.cellw) * info.coordincx; - - YglCachedQuad((YglSprite *)&info, tmp); - - if (info.y < (vdp2height - info.cellh)) - { - info.vertices[1] = (info.y+info.cellh) * info.coordincy; - info.vertices[3] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[5] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[7] = (info.y+info.cellh) * info.coordincy; - - YglCachedQuad((YglSprite *)&info, tmp); - } - } - else if (info.y < (vdp2height - info.cellh)) - { - info.vertices[1] = (info.y+info.cellh) * info.coordincy; - info.vertices[3] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[5] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[7] = (info.y+info.cellh) * info.coordincy; - - YglCachedQuad((YglSprite *)&info, tmp); - } -*/ - } - else - Vdp2DrawMap(&info); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG2PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x700) >> 2; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN2 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN2 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN2 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN2 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) - //{ - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else - { - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG2(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x4; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x400); - info.specialprimode = (Vdp2Regs->SFPRMD >> 4) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x2) >> 1; - info.mapwh = 2; - - switch((Vdp2Regs->PLSZ & 0x30) >> 4) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - info.x = - ((Vdp2Regs->SCXN2 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYN2 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN2 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLB & 0x1) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN2 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN2 & 0x4000) >> 14; - - if (Vdp2Regs->CCCTL & 0x4) - info.alpha = ((~Vdp2Regs->CCRNB & 0x1F) << 3) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = Vdp2Regs->CRAOFA & 0x700; - - if (Vdp2Regs->CLOFEN & 0x4) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x4) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x4) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x4) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = info.coordincy = 1; - - info.priority = nbg2priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG2PlaneAddr; - - Vdp2DrawMap(&info); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG3PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x7000) >> 6; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN3 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN3 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN3 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN3 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) { - if (info->patterndatasize == 1) { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else { - if (info->patterndatasize == 1) { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG3(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x8; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x800); - info.specialprimode = (Vdp2Regs->SFPRMD >> 6) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x20) >> 5; - - info.mapwh = 2; - - switch((Vdp2Regs->PLSZ & 0xC0) >> 6) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - info.x = - ((Vdp2Regs->SCXN3 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYN3 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN3 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLB & 0x10) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN3 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN3 & 0x4000) >> 14; - - if (Vdp2Regs->CCCTL & 0x8) - info.alpha = ((~Vdp2Regs->CCRNB & 0x1F00) >> 5) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7000) >> 4; - - if (Vdp2Regs->CLOFEN & 0x8) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x8) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x8) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x8) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = info.coordincy = 1; - - info.priority = nbg3priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG3PlaneAddr; - - Vdp2DrawMap(&info); - - return 1; -} - -static int VIDDCVdp2Reset(void) { - return 0; -} - -static void VIDDCVdp2DrawStart(void) { - cur_addr = (uint32) tex_space; - cur_vdp2 = (uint32) vdp2_tex; - - pvr_wait_ready(); - pvr_scene_begin(); - - Vdp2DrawBackScreen(); - Vdp2DrawLineColorScreen(); -} - -static void VIDDCVdp2DrawEnd(void) { - /* Make sure we don't have any texture dma still going on... */ - sem_wait(dmadone); - sem_signal(dmadone); - - pvr_scene_finish(); - - ++framecount; - - if(lastup + 10 <= time(NULL)) { - printf("%d frames in %d seconds FPS: %f\n", framecount, time(NULL) - - lastup, ((float)(framecount)) / (time(NULL) - lastup)); - framecount = 0; - lastup = time(NULL); - } -} - -static void dma_callback(ptr_t data __attribute__((unused))) { - sem_signal(dmadone); -} - -static void Vdp2Draw(int priority) { - pvr_sprite_txr_t sprite; - - pt_sprite_hdr.mode2 &= (~(PVR_TA_PM2_USIZE_MASK | PVR_TA_PM2_VSIZE_MASK)); - pt_sprite_hdr.mode2 |= (6 << PVR_TA_PM2_USIZE_SHIFT) | - (5 << PVR_TA_PM2_VSIZE_SHIFT); - pt_sprite_hdr.mode3 = ((cur_vdp2 & 0x00FFFFF8) >> 3) | - (PVR_TXRFMT_NONTWIDDLED); - - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, sizeof(pvr_sprite_hdr_t)); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = 0; - sprite.ay = 0; - sprite.az = priority_levels[priority]; - - sprite.bx = vdp2width; - sprite.by = 0; - sprite.bz = priority_levels[priority]; - - sprite.cx = vdp2width; - sprite.cy = vdp2height; - sprite.cz = priority_levels[priority]; - - sprite.dx = 0; - sprite.dy = vdp2height; - - sprite.auv = PVR_PACK_16BIT_UV(0.0f, 0.0f); - sprite.buv = PVR_PACK_16BIT_UV(vdp2width / 512.0f, 0.0f); - sprite.cuv = PVR_PACK_16BIT_UV(vdp2width / 512.0f, vdp2height / 256.0f); - pvr_list_prim(PVR_LIST_PT_POLY, &sprite, sizeof(pvr_sprite_txr_t)); - - priority_levels[priority] += 0.000001f; -} - -static void VIDDCVdp2DrawScreens(void) { - int i; - - vdp2_fb = vdp2_fbs[0]; - vdp2_fbnum = 0; - - for(i = 1; i < 8; i++) { - if(nbg3priority == i) { - if(Vdp2DrawNBG3()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } - if(nbg2priority == i) { - if(Vdp2DrawNBG2()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } - if(nbg1priority == i) { - if(Vdp2DrawNBG1()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } - if(nbg0priority == i) { - if(Vdp2DrawNBG0()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } -// if (rbg0priority == i) -// Vdp2DrawRBG0(); - } -} - -static void VIDDCVdp2SetResolution(u16 TVMD) { - int w = 0, h = 0; - - switch(TVMD & 0x03) { - case 0: - w = 320; - break; - case 1: - w = 352; - break; - case 2: - w = 640; - break; - case 3: - w = 704; - break; - } - - switch((TVMD >> 4) & 0x03) { - case 0: - h = 224; - break; - case 1: - h = 240; - break; - case 2: - h = 256; - break; - } - - switch((TVMD >> 6) & 0x03) { - case 2: - case 3: - h <<= 1; - default: - break; - } - - vdp2width = w; - vdp2height = h; - - if(w > 352 || h > 256) { - printf("Unsupported resolution set %d x %d\n", w, h); - printf("Bailing out!\n"); - exit(-1); - } -} - -static void VIDDCVdp2SetPriorityNBG0(int priority) { - nbg0priority = priority; -} - -static void VIDDCVdp2SetPriorityNBG1(int priority) { - nbg1priority = priority; -} - -static void VIDDCVdp2SetPriorityNBG2(int priority) { - nbg2priority = priority; -} - -static void VIDDCVdp2SetPriorityNBG3(int priority) { - nbg3priority = priority; -} - -static void VIDDCVdp2SetPriorityRBG0(int priority) { - rbg0priority = priority; -} - -VideoInterface_struct VIDDC = { - VIDCORE_DC, - "Dreamcast PVR Video Interface", - VIDDCInit, - VIDDCDeInit, - VIDDCResize, - VIDDCIsFullscreen, - VIDDCVdp1Reset, - VIDDCVdp1DrawStart, - VIDDCVdp1DrawEnd, - VIDDCVdp1NormalSpriteDraw, - VIDDCVdp1ScaledSpriteDraw, - VIDDCVdp1DistortedSpriteDraw, - VIDDCVdp1PolygonDraw, - VIDDCVdp1PolylineDraw, - VIDDCVdp1LineDraw, - VIDDCVdp1UserClipping, - VIDDCVdp1SystemClipping, - VIDDCVdp1LocalCoordinate, - VIDDCVdp2Reset, - VIDDCVdp2DrawStart, - VIDDCVdp2DrawEnd, - VIDDCVdp2DrawScreens, - VIDDCVdp2SetResolution, - VIDDCVdp2SetPriorityNBG0, - VIDDCVdp2SetPriorityNBG1, - VIDDCVdp2SetPriorityNBG2, - VIDDCVdp2SetPriorityNBG3, - VIDDCVdp2SetPriorityRBG0 -}; diff --git a/yabause/src/dreamcast/viddc.h b/yabause/src/dreamcast/viddc.h deleted file mode 100644 index e824200944..0000000000 --- a/yabause/src/dreamcast/viddc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2005 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef VIDDC_H -#define VIDDC_H - -#include "../vdp1.h" - -#define VIDCORE_DC 3 -extern VideoInterface_struct VIDDC; - -#endif diff --git a/yabause/src/dreamcast/yui.c b/yabause/src/dreamcast/yui.c deleted file mode 100644 index 17762e09f2..0000000000 --- a/yabause/src/dreamcast/yui.c +++ /dev/null @@ -1,234 +0,0 @@ -/* Copyright 2003 Guillaume Duhamel - Copyright 2004-2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../yui.h" -#include "../peripheral.h" -#include "../cs0.h" -#include "../m68kcore.h" -#include "../m68kc68k.h" -#include "perdc.h" -#include "viddc.h" -#include "sh2rec/sh2rec.h" - -SH2Interface_struct *SH2CoreList[] = { - &SH2Interpreter, - &SH2Dynarec, - NULL -}; - -PerInterface_struct *PERCoreList[] = { - &PERDC, - NULL -}; - -CDInterface *CDCoreList[] = { - &ArchCD, - &DummyCD, - NULL -}; - -SoundInterface_struct *SNDCoreList[] = { - &SNDDummy, - NULL -}; - -VideoInterface_struct *VIDCoreList[] = { - &VIDDummy, - &VIDDC, - NULL -}; - -M68K_struct * M68KCoreList[] = { - &M68KDummy, - &M68KC68K, -#ifdef HAVE_Q68 - &M68KQ68, -#endif - NULL -}; - -static const char *bios = "/ram/saturn.bin"; -static int emulate_bios = 0; - -int YuiInit(int sh2core) { - yabauseinit_struct yinit; - - yinit.percoretype = PERCORE_DC; - yinit.sh2coretype = sh2core; - yinit.vidcoretype = VIDCORE_DC; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.sndcoretype = SNDCORE_DUMMY; - yinit.cdcoretype = CDCORE_ARCH; - yinit.carttype = CART_NONE; - yinit.regionid = REGION_AUTODETECT; - yinit.biospath = emulate_bios ? NULL : bios; - yinit.cdpath = NULL; - yinit.buppath = NULL; - yinit.mpegpath = NULL; - yinit.cartpath = NULL; - yinit.frameskip = 0; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yinit.clocksync = 0; - yinit.basetime = 0; - - if(YabauseInit(&yinit) != 0) - return -1; - - for(;;) { - PERCore->HandleEvents(); - } - - return 0; -} - -void YuiErrorMsg(const char *error_text) { - fprintf(stderr, "Error: %s\n", error_text); - arch_exit(); -} - -void YuiSwapBuffers(void) { - /* Nothing here. */ -} - -int DoGui() { - struct coord { - int x; - int y; - }; - - struct coord snowflakes[1024]; - int i; - int offset; - int start_pressed = 0; - int phase = 0; - int core = SH2CORE_INTERPRETER; - - srand(time(NULL)); - - for(i = 0; i < 1024; ++i) { - snowflakes[i].x = (rand() % 640); - snowflakes[i].y = -(rand() % 480); - } - - while(!start_pressed) { - offset = 64 * 640 + 64; /* 64 pixels in from the left, 64 down */ - - bfont_draw_str(vram_s + offset, 640, 0, "Yabause " VERSION); - offset += 640 * 128; - - if(phase == 0) { - FILE *fp; - - fp = fopen("/cd/saturn.bin", "r"); - if(fp) { - fclose(fp); - - fs_copy("/cd/saturn.bin", bios); - phase = 1; - continue; - } - - bfont_draw_str(vram_s + offset, 640, 0, - "Please insert a CD containing the Saturn BIOS"); - offset += 640 * 24; - bfont_draw_str(vram_s + offset, 640, 0, - "on the root of the disc, named saturn.bin."); - offset += 640 * 48; - bfont_draw_str(vram_s + offset, 640, 0, - "Or, to use the BIOS emulation feature, insert"); - offset += 640 * 24; - bfont_draw_str(vram_s + offset, 640, 0, - "a Sega Saturn CD and press Start."); - } - else { - bfont_draw_str(vram_s + offset, 640, 0, - "Please insert a Sega Saturn CD"); - offset += 640 * 24; - bfont_draw_str(vram_s + offset, 640, 0, "and press start."); - } - - for(i = 0; i < 1024; ++i) { - int dx = 1 - (rand() % 3); - - if(snowflakes[i].y >= 0) - vram_s[640 * snowflakes[i].y + snowflakes[i].x] = 0x0000; - - snowflakes[i].x += dx; - snowflakes[i].y += 1; - - if(snowflakes[i].x < 0) - snowflakes[i].x = 639; - else if(snowflakes[i].x > 639) - snowflakes[i].x = 0; - - if(snowflakes[i].y > 479) - snowflakes[i].y = 0; - - if(snowflakes[i].y >= 0) - vram_s[640 * snowflakes[i].y + snowflakes[i].x] = 0xD555; - } - - MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st) - if(st->buttons & CONT_START) { - if(phase == 0) { - emulate_bios = 1; - } - - start_pressed = 1; - } - - if(st->buttons & CONT_Y) { - core = SH2CORE_DYNAREC; - - if(phase == 0) { - emulate_bios = 1; - } - - start_pressed = 1; - } - MAPLE_FOREACH_END() - - vid_waitvbl(); - vid_flip(1); - } - - return core; -} - -int main(int argc, char *argv[]) { - int core; - - printf("...\n"); - - bfont_set_encoding(BFONT_CODE_ISO8859_1); - core = DoGui(); - YuiInit(core); - - return 0; -} diff --git a/yabause/src/dx.h b/yabause/src/dx.h deleted file mode 100644 index c52e0b4540..0000000000 --- a/yabause/src/dx.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2008 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef DX_H -#define DX_H - -#ifdef __MINGW32__ -// I have to do this because for some reason because the dxerr8.h header is fubared -const char* __stdcall DXGetErrorString8A(HRESULT hr); -#define DXGetErrorString8 DXGetErrorString8A -const char* __stdcall DXGetErrorDescription8A(HRESULT hr); -#define DXGetErrorDescription8 DXGetErrorDescription8A -#else -#ifndef DXERRH_IS_BROKEN -#include - -#define DXGetErrorString8 DXGetErrorString9A -#define DXGetErrorDescription8 DXGetErrorDescription9A -#else -#include - -#define DXGetErrorString8 DXGetErrorStringA -#define DXGetErrorDescription8 DXGetErrorDescriptionA - -#endif -#endif - -#endif diff --git a/yabause/src/error.c b/yabause/src/error.c deleted file mode 100644 index 8dd4beba92..0000000000 --- a/yabause/src/error.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "error.h" -#include "yui.h" - -////////////////////////////////////////////////////////////////////////////// - -static void AllocAmendPrintString(const char *string1, const char *string2) -{ - char *string; - - if ((string = (char *)malloc(strlen(string1) + strlen(string2) + 2)) == NULL) - return; - - sprintf(string, "%s%s\n", string1, string2); - YuiErrorMsg(string); - - free(string); -} - -////////////////////////////////////////////////////////////////////////////// - -void YabSetError(int type, const void *extra) -{ - char tempstr[512]; - SH2_struct *sh; - - switch (type) - { - case YAB_ERR_FILENOTFOUND: - AllocAmendPrintString(_("File not found: "), extra); - break; - case YAB_ERR_MEMORYALLOC: - YuiErrorMsg(_("Error allocating memory\n")); - break; - case YAB_ERR_FILEREAD: - AllocAmendPrintString(_("Error reading file: "), extra); - break; - case YAB_ERR_FILEWRITE: - AllocAmendPrintString(_("Error writing file: "), extra); - break; - case YAB_ERR_CANNOTINIT: - AllocAmendPrintString(_("Cannot initialize "), extra); - break; - case YAB_ERR_SH2INVALIDOPCODE: - sh = (SH2_struct *)extra; - SH2GetRegisters(sh, &sh->regs); - sprintf(tempstr, "%s SH2 invalid opcode\n\n" - "R0 = %08lX\tR12 = %08lX\n" - "R1 = %08lX\tR13 = %08lX\n" - "R2 = %08lX\tR14 = %08lX\n" - "R3 = %08lX\tR15 = %08lX\n" - "R4 = %08lX\tSR = %08lX\n" - "R5 = %08lX\tGBR = %08lX\n" - "R6 = %08lX\tVBR = %08lX\n" - "R7 = %08lX\tMACH = %08lX\n" - "R8 = %08lX\tMACL = %08lX\n" - "R9 = %08lX\tPR = %08lX\n" - "R10 = %08lX\tPC = %08lX\n" - "R11 = %08lX\n", sh->isslave ? "Slave" : "Master", - (long)sh->regs.R[0], (long)sh->regs.R[12], - (long)sh->regs.R[1], (long)sh->regs.R[13], - (long)sh->regs.R[2], (long)sh->regs.R[14], - (long)sh->regs.R[3], (long)sh->regs.R[15], - (long)sh->regs.R[4], (long)sh->regs.SR.all, - (long)sh->regs.R[5], (long)sh->regs.GBR, - (long)sh->regs.R[6], (long)sh->regs.VBR, - (long)sh->regs.R[7], (long)sh->regs.MACH, - (long)sh->regs.R[8], (long)sh->regs.MACL, - (long)sh->regs.R[9], (long)sh->regs.PR, - (long)sh->regs.R[10], (long)sh->regs.PC, - (long)sh->regs.R[11]); - YuiErrorMsg(tempstr); - break; - case YAB_ERR_SH2READ: - YuiErrorMsg(_("SH2 read error\n")); // fix me - break; - case YAB_ERR_SH2WRITE: - YuiErrorMsg(_("SH2 write error\n")); // fix me - break; - case YAB_ERR_SDL: - AllocAmendPrintString(_("SDL Error: "), extra); - break; - case YAB_ERR_OTHER: - YuiErrorMsg((char *)extra); - break; - case YAB_ERR_UNKNOWN: - default: - YuiErrorMsg(_("Unknown error occurred\n")); - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/error.h b/yabause/src/error.h deleted file mode 100644 index 6d18c330e0..0000000000 --- a/yabause/src/error.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ERROR_H -#define ERROR_H - -#define YAB_ERR_UNKNOWN 0 -#define YAB_ERR_FILENOTFOUND 1 -#define YAB_ERR_MEMORYALLOC 2 -#define YAB_ERR_FILEREAD 3 -#define YAB_ERR_FILEWRITE 4 -#define YAB_ERR_CANNOTINIT 5 - -#define YAB_ERR_SH2INVALIDOPCODE 6 -#define YAB_ERR_SH2READ 7 -#define YAB_ERR_SH2WRITE 8 - -#define YAB_ERR_SDL 9 - -#define YAB_ERR_OTHER 10 - -void YabSetError(int type, const void *extra); -#endif diff --git a/yabause/src/font.h b/yabause/src/font.h deleted file mode 100644 index 7ce4910aa6..0000000000 --- a/yabause/src/font.h +++ /dev/null @@ -1,1301 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -static const char * font[] = { -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .. ", -" .##.", -" .##. ", -" .##. ", -" .##. ", -" .##. ", -" .##. ", -" .##. ", -".##. ", -" .. ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -".##.#.##.", -".##.#.##.", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" .... ", -" .####. ", -" .####. ", -" ..##. ", -" .##. ", -" .##. ", -" ...##.. ", -".#######.", -".#######.", -" ....... ", -" ...... ", -".######. ", -".#######.", -" .....##.", -".#######.", -".######. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -" .....##.", -".#######.", -".#######.", -" .....##.", -".#######.", -".#######.", -" ....... ", -" .. ", -".##. ", -".##... ", -".##.##. ", -".##.##.. ", -".#######.", -".#######.", -" ...##.. ", -" .##. ", -" .. ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".######. ", -".#######.", -" .....##.", -".#######.", -".######. ", -" ...... ", -" ...... ", -" .######.", -".#######.", -".##..... ", -".######. ", -".#######.", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" ....... ", -".#######.", -".#######.", -" .....##.", -" .##.", -" .##.", -" .##.", -" .##.", -" .##.", -" .. ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -" .######.", -".######. ", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -".#######.", -" .######.", -" .....##.", -".#######.", -".#######.", -" ....... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -".#######.", -".#######.", -".##...##.", -".##. .##.", -".##. .##.", -" .. .. ", -" ...... ", -".######. ", -".#######.", -".##...##.", -".######. ", -".######. ", -".##...##.", -".#######.", -".######. ", -" ...... ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".##. ", -".##. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" ...... ", -".######. ", -".#######.", -".##...##.", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -".######. ", -" ...... ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".####. ", -".####. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".####. ", -".####. ", -".##.. ", -".##. ", -".##. ", -" .. ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".##..###.", -".##..###.", -".##...##.", -".#######.", -".#######.", -" ....... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -".#######.", -".##...##.", -".##. .##.", -".##. .##.", -" .. .. ", -" ....... ", -".#######.", -".#######.", -" ..###.. ", -" .###. ", -" .###. ", -" ..###.. ", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -" ....###.", -" .###.", -" .. .###.", -".##..###.", -".#######.", -" ..####. ", -" .... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##..###.", -".######. ", -".#####. ", -".##.###. ", -".##..###.", -".##. .##.", -" .. .. ", -" .. ", -".##. ", -".##. ", -".##. ", -".##. ", -".##. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" .. .. ", -".##. .##.", -".###.###.", -".#######.", -".##.#.##.", -".##...##.", -".##. .##.", -".##. .##.", -".##. .##.", -" .. .. ", -" .. .. ", -".##. .##.", -".###..##.", -".####.##.", -".##.####.", -".##..###.", -".##. .##.", -".##. .##.", -".##. .##.", -" .. .. ", -" ... ", -" .###. ", -" .#####. ", -".###.###.", -".##. .##.", -".##. .##.", -".###.###.", -" .#####. ", -" .###. ", -" ... ", -" ...... ", -".######. ", -".#######. ", -".##...##.", -".#######.", -".######. ", -".##.... ", -".##. ", -".##. ", -" .. ", -" ... ", -" .###. ", -" .#####. ", -".##...##.", -".##...##.", -".##.#.##.", -".##..###.", -" .######.", -" .###.#.", -" ... . ", -" ...... ", -".######. ", -".#######.", -".##...##.", -".#######.", -".######. ", -".##..###.", -".##. .##.", -".##. .##.", -" .. .. ", -" ..... ", -" .#####. ", -".######. ", -".##.... ", -".######. ", -".######. ", -" ....##. ", -".######. ", -".#####. ", -" ..... ", -" ....... ", -".#######.", -".#######.", -" ..###.. ", -" .###. ", -" .###. ", -" .###. ", -" .###. ", -" .###. ", -" ... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##. .##.", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##. .##.", -" .##.##. ", -" .##.##. ", -" .##.##. ", -" .###. ", -" .###. ", -" ... ", -" .. .. ", -".##...##.", -".##.#.##.", -".##.#.##.", -" .#####. ", -" .#####. ", -" .#####. ", -" .###. ", -" .#.#. ", -" . . ", -" .. .. ", -".##. .##.", -".##. .##.", -".##. .##.", -" .##.##. ", -" .###. ", -" .##.##. ", -".##. .##.", -".##. .##.", -" .. .. ", -" .. .. ", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -".#######.", -" .....##.", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -" ....##. ", -" .##. ", -" .##. ", -" .##.... ", -".#######.", -".#######.", -" ....... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -}; diff --git a/yabause/src/gameshw/dsplist.txt b/yabause/src/gameshw/dsplist.txt deleted file mode 100644 index b1b5eea808..0000000000 --- a/yabause/src/gameshw/dsplist.txt +++ /dev/null @@ -1,64 +0,0 @@ -Games using SCU dsp --------------------- -Battle Monsters -Blazing Tornado -Blue Chicago Blues - J.B.Harold -Blue Seed -Bubble Symphony -Capcom Generations 1 -Capcom Generations 4 -Cotton Boomerang -Crimewave -Daisuki -Dark Savior -Dead or Alive -Don Pachi -Doom -Dragon Ball Z Shinbuthoden -DX Jinsei Game - The Game of Life -Fatal Fury 3 -Find Love 2 -?Gal Panic SS -Galaxy Force 2(sega ages) -Grandia -Grandia: Digital Museum -GT24 -Guardian Force -Guyferd -Jissen Pachinko Hisshouhou! Twin -Lunar 2: Eternal Blue -Mega Man X4 -Momotaroudouchuuki -Nadesico -Mighty Hits -Planet Joker -Psychic Killer Taromaru -Real Bout FF -Real Bout FF Special -Samurai Shodown RPG -Sega Ages Memorial Selection - Vol. 1 -?Shining Force 3 Scenario 1 -Shining Force 3 Scenario 2 -Shining Force 3 Scenario 3 -Sky Target -Slam Dunk - I love Basketball (heavy usage) -Slayers Royal -Sonic R -Stakes Winner SS -Steeldom -?Street Fighter Collection Disc 1 -Super Real Mahjong P7 -Sword & Sorcery -Tenga Seiha -?Tengai Makyou Dai Yon no Mokujiroku - The Apocalypse IV -Toshinden Ura -The Yakuyaken Special -?Thunderforce Gold Pack 1 -Victory Boxing -Virtua Racing -Virtua Fighter Remix -Winter Heat -Wonder 3 -Worms -Yellow Brick Road -Zero4 Champ DooZy-J Type-R diff --git a/yabause/src/gtk/CMakeLists.txt b/yabause/src/gtk/CMakeLists.txt deleted file mode 100644 index c0d2e4354d..0000000000 --- a/yabause/src/gtk/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -project(yabause-gtk) - -yab_port_start() - -find_package(GTK2 2.10 COMPONENTS gtk) - -if (NOT GTK2_FOUND) - return() -endif (NOT GTK2_FOUND) - -set(PORT_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS}) -set(PORT_LIBRARIES ${GTK2_LIBRARIES}) - -if (OPENGL_FOUND) - find_path(GDKGLEXT_CONFIG_INCLUDE_DIR gdkglext-config.h PATHS ${CMAKE_SYSTEM_PREFIX_PATH} PATH_SUFFIXES lib/gtkglext-1.0/include) - find_path(GTKGLEXT_INCLUDE_DIR gtk/gtkgl.h PATH_SUFFIXES gtkglext-1.0) - find_library(GDKGLEXT_LIBRARY gdkglext-x11-1.0) - find_library(GTKGLEXT_LIBRARY gtkglext-x11-1.0) - if (NOT GDKGLEXT_CONFIG_INCLUDE_DIR OR NOT GTKGLEXT_INCLUDE_DIR OR NOT GDKGLEXT_LIBRARY OR NOT GTKGLEXT_LIBRARY) - message(STATUS "Found OpenGL and Gtk+ but not libgtkglext, skipping Gtk+ port.") - return() - endif () - set(PORT_INCLUDE_DIRS ${PORT_INCLUDE_DIRS} ${GTKGLEXT_INCLUDE_DIR} ${GDKGLEXT_CONFIG_INCLUDE_DIR}) - set(PORT_LIBRARIES ${PORT_LIBRARIES} ${GTKGLEXT_LIBRARY} ${GDKGLEXT_LIBRARY}) - add_definitions(-DHAVE_LIBGTKGLEXT=1) -endif (OPENGL_FOUND) -include_directories(${PORT_INCLUDE_DIRS}) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/include/gdk-pixbuf-2.0") - -set(yabause_gtk_SOURCES - gtk-compat.c - gtkglwidget.c - main.c - menu.c - pergtk.c - settings.c - yuicheckbutton.c - yuifileentry.c - yuiinputentry.c - yuim68k.c - yuimem.c - yuipage.c - yuirange.c - yuiresolution.c - yuiscreenshot.c - yuiscsp.c - yuiscudsp.c - yuish.c - yuitransfer.c - yuivdp1.c - yuivdp2.c - yuiviewer.c - yuiwindow.c) - -add_executable(yabause-gtk ${yabause_gtk_SOURCES}) -target_link_libraries(yabause-gtk yabause ${YABAUSE_LIBRARIES} ${PORT_LIBRARIES}) - -yab_port_success(yabause-gtk) -configure_file(yabause.desktop.in ${YAB_PORT_NAME}.desktop) - -install(TARGETS yabause-gtk DESTINATION "bin") -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${YAB_PORT_NAME}.desktop DESTINATION "share/applications") -install(FILES "doc/yabause.1" DESTINATION "${YAB_MAN_DIR}/man1" RENAME "${YAB_PORT_NAME}.1") -install(FILES "yabause.png" DESTINATION "share/pixmaps") diff --git a/yabause/src/gtk/Makefile.am b/yabause/src/gtk/Makefile.am deleted file mode 100644 index d1686ebd9f..0000000000 --- a/yabause/src/gtk/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -SUBDIRS = doc -Applicationsdir = $(datadir)/applications -pixmapdir = $(datadir)/pixmaps -pixmap_DATA = yabause.png -bin_PROGRAMS = yabause -EXTRA_DIST = yabause.png - -yabause_SOURCES = gtkglwidget.c gtkglwidget.h main.c settings.c menu.c gtk-compat.c gtk-compat.h \ - yuifileentry.c yuifileentry.h yuirange.c yuirange.h yuiinputentry.c yuiinputentry.h yuipage.c yuipage.h \ - yuiresolution.c yuiresolution.h yuiwindow.c yuiwindow.h yuivdp1.c yuivdp1.h yuivdp2.c yuivdp2.h \ - yuiscsp.c yuiscsp.h pergtk.c pergtk.h yuiscreenshot.c yuiscreenshot.h \ - yuish.c yuish.h yuitransfer.c yuitransfer.h yuim68k.c yuim68k.h yuiscudsp.c yuiscudsp.h yuimem.c yuimem.h \ - yuiviewer.c yuiviewer.h settings.h \ - yuicheckbutton.c yuicheckbutton.h -yabause_CFLAGS = $(YAB_CFLAGS) -yabause_LDADD = ../libyabause.a $(YAB_LIBS) -yabause_CPPFLAGS = -DYTSDIR=\"$(datadir)/$(PACKAGE)/yts\" - -if ARCH_IS_LINUX -if USE_DYNAREC -if CPU_IS_X64 -yabause_CFLAGS += -DSH2_DYNAREC=1 -endif -if CPU_IS_X86 -yabause_CFLAGS += -DSH2_DYNAREC=1 -endif -if CPU_IS_ARM -yabause_CFLAGS += -DSH2_DYNAREC=1 -mcpu=cortex-a8 -mfpu=vfp -mfloat-abi=softfp -endif -endif -endif diff --git a/yabause/src/gtk/doc/Makefile.am b/yabause/src/gtk/doc/Makefile.am deleted file mode 100644 index 327b7de40f..0000000000 --- a/yabause/src/gtk/doc/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -dist_man_MANS = yabause.1 diff --git a/yabause/src/gtk/doc/yabause.1 b/yabause/src/gtk/doc/yabause.1 deleted file mode 100644 index 6d0c781e9d..0000000000 --- a/yabause/src/gtk/doc/yabause.1 +++ /dev/null @@ -1,93 +0,0 @@ -.TH YABAUSE 1 "April 16, 2010" "yabause-0.9.11" -.SH NAME -yabause \- Yet Another Buggy And Uncomplete Saturn Emulator -.SH SYNOPSIS -.B yabause -[ \fB\-afh\fP ] [ \fB\-ns\fP ] [ \fB\-b \fP ] [ \fB\-c \fP ] [ \fB\-i \fP ] -[ \fB\-\-binary=[:
]\fP ] -.SH DESCRIPTION -\fBYabause\fP is a Sega Saturn emulator. \fBYabause\fP needs either a bios file, a game or a binary to run. -Games can be loaded from a real cd device or from dump files. -.SH OPTIONS -.TP -.BI \-a -.TP -.BI \-\-autostart -Automatically start emulation. -.TP -.BI \-\-autoframeskip=0|1 -Enable or disable auto frame skipping / limiting. -.TP -.BI \-\-autoload -Automatically start emulation and load a save state. -.TP -.BI \-b -.TP -.BI \-\-bios -Choose a bios file. -.TP -.BI \-\-binary -Use a binary file. Content of the file will be loaded to 0x06004000 and execution will start from that address. -You can provide an alternative address to load and run the binary with the \-\-binary=:
syntax. -When using this option, emulation is automatically started and you shouldn't use it in cunjunction with \-a. -This option is intended for homebrew developers wanting to test their programs in \fBYabause\fP. -.TP -.BI \-c -.TP -.BI \-\-cdrom -Choose the cdrom device. -.TP -.BI \-f -.TP -.BI \-\-fullscreen -Start the emulator in fullscreen. -.TP -.BI \-h -Display a short help text. -.TP -.BI \-i -.TP -.BI \-\-iso -Choose a dump file. The dump can be either in iso or bin/cue file format. -.TP -.BI \-ns -.TP -.BI \-\-nosound -Turns sound off. This option actually set the sound core to the dummy one. -.SH FILES -.TP -\fB\fR -An executable for the Saturn, usually with a BIN extension. -.TP -\fB\fR -A Saturn ROM BIOS image. -.TP -\fB\fR -A CDROM device file. -.TP -\fB\fR -A Saturn game dump. -.SH AUTHORS -Copyright (c) 2002-2010 Yabause Team - -Web: http://yabause.org - -Please don't ask for roms, bios files or any other -copyrighted stuff. -.SH COPYRIGHT -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be -useful,but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301 USA - -See the GNU General Public License details in COPYING. diff --git a/yabause/src/gtk/gtk-compat.c b/yabause/src/gtk/gtk-compat.c deleted file mode 100644 index 3fa155c3a7..0000000000 --- a/yabause/src/gtk/gtk-compat.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "gtk-compat.h" - -#if !GLIB_CHECK_VERSION(2, 8, 0) -gboolean g_file_set_contents(const gchar * filename, const gchar * contents, gssize len, GError ** error) { - FILE * file = fopen(filename, "w"); - - if (len == -1) - fprintf(file, "%s", contents); - else - fwrite(contents, 1, len, file); - - fclose(file); -} -#endif diff --git a/yabause/src/gtk/gtk-compat.h b/yabause/src/gtk/gtk-compat.h deleted file mode 100644 index f18a74c156..0000000000 --- a/yabause/src/gtk/gtk-compat.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_GTK_COMPAT_H -#define YUI_GTK_COMPAT_H - -#include - -#if ((GLIB_MAJOR_VERSION < 2) || ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION < 8))) -gboolean g_file_set_contents(const gchar *, const gchar *, gssize, GError **); -#endif - -#endif diff --git a/yabause/src/gtk/gtkglwidget.c b/yabause/src/gtk/gtkglwidget.c deleted file mode 100644 index 85cdc2db02..0000000000 --- a/yabause/src/gtk/gtkglwidget.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "gtkglwidget.h" -#ifdef HAVE_LIBGTKGLEXT -#include -#endif -#include "../vidsoft.h" -#include "../peripheral.h" - -#define X_NOSCALE 160 -#define Y_NOSCALE 120 - -static void yui_gl_class_init (YuiGlClass * klass); -static void yui_gl_init (YuiGl * yfe); -static gboolean yui_gl_resize (GtkWidget *w,GdkEventConfigure *event, gpointer data); - -void yui_gl_draw(YuiGl * glxarea) { -#ifdef HAVE_LIBGTKGLEXT - GdkGLContext *glcontext = gtk_widget_get_gl_context (GTK_WIDGET(glxarea)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (GTK_WIDGET(glxarea)); - - if (!gdk_gl_drawable_make_current (gldrawable, glcontext)) { - g_print("Cannot set gl drawable current\n"); - return; - } - - gdk_gl_drawable_swap_buffers(gldrawable); -#else - int buf_width, buf_height; - GdkPixbuf * pixbuf, * scaledpixbuf; - - VIDCore->GetGlSize( &buf_width, &buf_height ); - glxarea->pixels_width = GTK_WIDGET(glxarea)->allocation.width; - glxarea->pixels_height = GTK_WIDGET(glxarea)->allocation.height; - glxarea->pixels_rowstride = glxarea->pixels_width * 4; - glxarea->pixels_rowstride += (glxarea->pixels_rowstride % 4)? (4 - (glxarea->pixels_rowstride % 4)): 0; - - if (dispbuffer == NULL) return; - - pixbuf = gdk_pixbuf_new_from_data((const guchar *) dispbuffer, GDK_COLORSPACE_RGB, TRUE, 8, - buf_width, buf_height, buf_width*4, NULL, NULL); - - if (( glxarea->pixels_width < buf_width + X_NOSCALE )&&( glxarea->pixels_height < buf_height + Y_NOSCALE )) { - - gdk_draw_pixbuf(GTK_WIDGET(glxarea)->window, NULL, pixbuf, 0, 0, - (glxarea->pixels_width-buf_width)/2, (glxarea->pixels_height-buf_height)/2, - buf_width, buf_height, GDK_RGB_DITHER_NONE, 0, 0); - } else { - - scaledpixbuf = gdk_pixbuf_scale_simple(pixbuf, - glxarea->pixels_width, glxarea->pixels_height, GDK_INTERP_NEAREST ); - gdk_draw_pixbuf(GTK_WIDGET(glxarea)->window, NULL, - scaledpixbuf, 0, 0, 0, 0, glxarea->pixels_width, glxarea->pixels_height, - GDK_RGB_DITHER_NONE, 0, 0); - g_object_unref(scaledpixbuf); - } - g_object_unref(pixbuf); -#endif - glxarea->is_init = 1; -} - -void yui_gl_draw_pause(YuiGl * glxarea) { -#ifdef HAVE_LIBGTKGLEXT - if (glxarea->pixels) { - /* The "correct" raster position would be (0, height) but it's not a - * valid position, so I have to use this hack... found here: - * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ */ - glRasterPos2i(0, 0); - glBitmap(0, 0, 0, 0, 0, - glxarea->pixels_height, NULL); - glPixelZoom(1, 1); - glDrawPixels(glxarea->pixels_width, glxarea->pixels_height, GL_RGB, GL_UNSIGNED_BYTE, glxarea->pixels); - yui_gl_draw(glxarea); - } else { - gdk_draw_rectangle(GTK_WIDGET(glxarea)->window, GTK_WIDGET(glxarea)->style->bg_gc[GTK_WIDGET_STATE (glxarea)], - TRUE, 0, 0, GTK_WIDGET(glxarea)->allocation.width, GTK_WIDGET(glxarea)->allocation.height); - } -#else - if (dispbuffer) - yui_gl_draw(glxarea); -#endif -} - -static gboolean yui_gl_resize(GtkWidget *w,GdkEventConfigure *event, gpointer data) { -#ifdef HAVE_LIBGTKGLEXT - GdkGLContext *glcontext = gtk_widget_get_gl_context (w); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (w); - - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - return FALSE; - - glViewport(0, 0, event->width, event->height); - if ( YUI_GL(w)->is_init ) VIDCore->Resize(event->width, event->height, FALSE ); -#endif - return FALSE; -} - -int beforehiding = 0; - -static gboolean gonna_hide(gpointer data) { - beforehiding--; - - if (beforehiding == 0) { - static char source_data[] = { 0 }; - static char mask_data[] = { 0 }; - - GdkCursor *cursor; - GdkPixmap *source, *mask; - GdkColor fg = { 0, 65535, 65535, 65535 }; - GdkColor bg = { 0, 0, 0, 0 }; - - source = gdk_bitmap_create_from_data(NULL, source_data, 1, 1); - mask = gdk_bitmap_create_from_data(NULL, mask_data, 1, 1); - cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 1, 1); - gdk_pixmap_unref(source); - gdk_pixmap_unref(mask); - - gdk_window_set_cursor(GTK_WIDGET(data)->window, cursor); - - return FALSE; - } else { - return TRUE; - } -} - -extern void * padbits; -extern GKeyFile * keyfile; -int oldx = 0; -int oldy = 0; - -static gboolean yui_gl_hide_cursor(GtkWidget * widget, GdkEventMotion * event, gpointer user_data) { - if (PerGetId(padbits) == PERMOUSE) { - int x = event->x; - int y = event->y; - double speed = g_key_file_get_double(keyfile, "General", "MouseSpeed", NULL); - - PerMouseMove(padbits, speed * (x - oldx), -speed * (y - oldy)); - oldx = x; - oldy = y; - } - - if (beforehiding == 0) { - gdk_window_set_cursor(widget->window, NULL); - g_timeout_add(1000, gonna_hide, widget); - } - - beforehiding = 2; - - return FALSE; -} - -static gboolean yui_gl_button_press(GtkWidget * widget, GdkEventButton * event, gpointer user_data) { - if (PerGetId(padbits) == PERMOUSE) { - switch(event->button) { - case 1: - PerMouseLeftPressed(padbits); - break; - case 2: - PerMouseMiddlePressed(padbits); - break; - case 3: - PerMouseRightPressed(padbits); - break; - } - } - return FALSE; -} - -static gboolean yui_gl_button_release(GtkWidget * widget, GdkEventButton * event, gpointer user_data) { - if (PerGetId(padbits) == PERMOUSE) { - switch(event->button) { - case 1: - PerMouseLeftReleased(padbits); - break; - case 2: - PerMouseMiddleReleased(padbits); - break; - case 3: - PerMouseRightReleased(padbits); - break; - } - } - return FALSE; -} - -GtkWidget * yui_gl_new(void) { - GtkWidget * drawingArea; -#ifdef HAVE_LIBGTKGLEXT - int attribs[] = { - GDK_GL_RGBA, - GDK_GL_RED_SIZE, 1, - GDK_GL_GREEN_SIZE, 1, - GDK_GL_BLUE_SIZE, 1, - - GDK_GL_DOUBLEBUFFER, - - GDK_GL_DEPTH_SIZE ,1, - GDK_GL_STENCIL_SIZE ,8, - GDK_GL_ATTRIB_LIST_NONE - }; -#endif - - drawingArea = GTK_WIDGET(g_object_new(yui_gl_get_type(), NULL)); - YUI_GL(drawingArea)->is_init = 0; - -#ifdef HAVE_LIBGTKGLEXT - gtk_widget_set_gl_capability(drawingArea, gdk_gl_config_new(attribs), NULL, TRUE, GDK_GL_RGBA_TYPE); -#endif - - g_signal_connect (GTK_OBJECT(drawingArea),"configure_event", GTK_SIGNAL_FUNC(yui_gl_resize),0); - - gtk_widget_set_events(drawingArea, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - - g_signal_connect(GTK_OBJECT(drawingArea), "motion-notify-event", GTK_SIGNAL_FUNC(yui_gl_hide_cursor),0); - g_signal_connect(GTK_OBJECT(drawingArea), "button-press-event", GTK_SIGNAL_FUNC(yui_gl_button_press),0); - g_signal_connect(GTK_OBJECT(drawingArea), "button-release-event", GTK_SIGNAL_FUNC(yui_gl_button_release),0); - - return drawingArea; -} - -void yui_gl_dump_screen(YuiGl * glxarea) { -#ifdef HAVE_LIBGTKGLEXT - int size; - - glxarea->pixels_width = GTK_WIDGET(glxarea)->allocation.width; - glxarea->pixels_height = GTK_WIDGET(glxarea)->allocation.height; - glxarea->pixels_rowstride = glxarea->pixels_width * 3; - glxarea->pixels_rowstride += (glxarea->pixels_rowstride % 4)? (4 - (glxarea->pixels_rowstride % 4)): 0; - - size = glxarea->pixels_rowstride * glxarea->pixels_height; - - if (glxarea->pixels) free(glxarea->pixels); - glxarea->pixels = malloc(sizeof(GLubyte) * size); - if (glxarea->pixels == NULL) return; - - glReadPixels(0, 0, glxarea->pixels_width, glxarea->pixels_height, GL_RGB, GL_UNSIGNED_BYTE, glxarea->pixels); -#else - int buf_width, buf_height; - int i, j; - int size; - int cur = 0; - u8 * pixels; - u8 * buffer; - - VIDCore->GetGlSize( &buf_width, &buf_height ); - size = buf_width * buf_height * 3; - - glxarea->pixels_width = buf_width; - glxarea->pixels_height = buf_height; - glxarea->pixels_rowstride = glxarea->pixels_width * 3; - glxarea->pixels_rowstride += (glxarea->pixels_rowstride % 4)? (4 - (glxarea->pixels_rowstride % 4)): 0; - - if (! glxarea->pixels) glxarea->pixels = malloc(sizeof(u8) * size); - - pixels = (u8 *)glxarea->pixels; - pixels += size - (buf_width * 3); - buffer = (u8 *)dispbuffer; - - for(i = 0;i < buf_height;i++) { - for(j = 0;j < buf_width;j++) { - *pixels++ = buffer[cur]; - *pixels++ = buffer[cur + 1]; - *pixels++ = buffer[cur + 2]; - cur += 4; - } - pixels -= buf_width * 6; - } -#endif -} - -GType yui_gl_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiGlClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_gl_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiGl), - 0, - (GInstanceInitFunc) yui_gl_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "YuiGl", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_gl_class_init (UNUSED YuiGlClass * klass) { -} - -static void yui_gl_init (YuiGl * y) { - y->pixels = NULL; -} diff --git a/yabause/src/gtk/gtkglwidget.h b/yabause/src/gtk/gtkglwidget.h deleted file mode 100644 index 481b1844fa..0000000000 --- a/yabause/src/gtk/gtkglwidget.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_GL_H -#define YUI_GL_H - -#include - -#ifdef HAVE_LIBGTKGLEXT -#include -#include -#endif - -G_BEGIN_DECLS - -#define YUI_GL_TYPE (yui_gl_get_type ()) -#define YUI_GL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_GL_TYPE, YuiGl)) -#define YUI_GL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_GL_TYPE, YuiGlClass)) -#define IS_YUI_GL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_GL_TYPE)) -#define IS_YUI_GL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_GL_TYPE)) - -typedef struct _YuiGl YuiGl; -typedef struct _YuiGlClass YuiGlClass; - -struct _YuiGl -{ - GtkDrawingArea hbox; - - guint * pixels; - gint pixels_width; - gint pixels_height; - gint pixels_rowstride; - gint is_init; -}; - -struct _YuiGlClass -{ - GtkDrawingAreaClass parent_class; -}; - -GType yui_gl_get_type (void); -GtkWidget * yui_gl_new (void); - -void yui_gl_draw (YuiGl *); -void yui_gl_draw_pause (YuiGl *); -void yui_gl_dump_screen (YuiGl *); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/main.c b/yabause/src/gtk/main.c deleted file mode 100644 index 3749abfa84..0000000000 --- a/yabause/src/gtk/main.c +++ /dev/null @@ -1,624 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "gtkglwidget.h" -#include "yuiwindow.h" - -#include "../yabause.h" -#include "../yui.h" -#include "../peripheral.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vidogl.h" -#include "../vidsoft.h" -#include "../cs0.h" -#include "../cs2.h" -#include "../cdbase.h" -#include "../scsp.h" -#include "../sndsdl.h" -#include "../sndal.h" -#include "../persdljoy.h" -#ifdef ARCH_IS_LINUX -#include "../perlinuxjoy.h" -#endif -#include "../debug.h" -#include "../m68kcore.h" -#include "../m68kc68k.h" -#include "pergtk.h" -#include "../psp/psp-sh2.h" - -#include "settings.h" - -static char biospath[256] = "\0"; -static char cdpath[256] = "\0"; -static char buppath[256] = "\0"; -static char mpegpath[256] = "\0"; -static char cartpath[256] = "\0"; - -M68K_struct * M68KCoreList[] = { -&M68KDummy, -#ifdef HAVE_C68K -&M68KC68K, -#endif -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -#ifdef TEST_PSP_SH2 -&SH2PSP, -#endif -#ifdef SH2_DYNAREC -&SH2Dynarec, -#endif -NULL -}; - -PerInterface_struct *PERCoreList[] = { -&PERDummy, -&PERGTK, -#ifdef HAVE_LIBSDL -&PERSDLJoy, -#endif -#ifdef ARCH_IS_LINUX -&PERLinuxJoy, -#endif -NULL -}; - -CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -#ifndef UNKNOWN_ARCH -&ArchCD, -#endif -NULL -}; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -#ifdef HAVE_LIBSDL -&SNDSDL, -#endif -#ifdef HAVE_LIBAL -&SNDAL, -#endif -NULL -}; - -VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -#ifdef HAVE_LIBGTKGLEXT -&VIDOGL, -#endif -&VIDSoft, -NULL -}; - -#ifdef YAB_PORT_OSD -OSD_struct *OSDCoreList[] = { -&OSDDummy, -#ifdef HAVE_LIBGLUT -&OSDGlut, -#endif -&OSDSoft, -NULL -}; -#endif - -GtkWidget * yui; -GKeyFile * keyfile; -yabauseinit_struct yinit; - -static int yui_main(gpointer data) { - PERCore->HandleEvents(); - return TRUE; -} - -static GtkWidget * yui_new(void) { - yui = yui_window_new(NULL, G_CALLBACK(YabauseInit), &yinit, yui_main, G_CALLBACK(YabauseReset)); - - gtk_widget_show(yui); - - return yui; -} - -static void yui_settings_init(void) { - yinit.m68kcoretype = M68KCORE_C68K; - yinit.percoretype = PERCORE_GTK; - yinit.sh2coretype = SH2CORE_DEFAULT; -#ifdef HAVE_LIBGTKGLEXT - yinit.vidcoretype = VIDCORE_OGL; -#else - yinit.vidcoretype = VIDCORE_SOFT; -#endif - yinit.sndcoretype = SNDCORE_DUMMY; - yinit.cdcoretype = CDCORE_DEFAULT; - yinit.carttype = CART_NONE; - yinit.regionid = 0; - yinit.biospath = biospath; - yinit.cdpath = cdpath; - yinit.buppath = buppath; - yinit.mpegpath = mpegpath; - yinit.cartpath = cartpath; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yinit.osdcoretype = OSDCORE_DEFAULT; -} - -gchar * inifile; - -static int safe_strcmp(const char * s1, const char * s2) { - if (s1) { - if (s2) { - return strcmp(s1, s2); - } else { - return 1; - } - } else { - if (s2) { - return -1; - } else { - return 0; - } - } -} - -extern void * padbits; -void * padbits; - -static gboolean yui_settings_load(void) { - int i, tmp; - long tmptime; - gchar * stmp; - gboolean mustRestart = FALSE; - - g_key_file_load_from_file(keyfile, inifile, G_KEY_FILE_NONE, 0); - - /* bios */ - stmp = g_key_file_get_value(keyfile, "General", "BiosPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.biospath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(biospath, stmp, 256); - yinit.biospath = biospath; - } - else yinit.biospath = NULL; - - /* cd core */ - stmp = g_key_file_get_value(keyfile, "General", "CDROMDrive", 0); - if (stmp && !*stmp) stmp = NULL; - if((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.cdpath)) { - Cs2ChangeCDCore(yinit.cdcoretype, stmp); - } - if (stmp) g_strlcpy(cdpath, stmp, 256); - - tmp = yinit.cdcoretype; - yinit.cdcoretype = g_key_file_get_integer(keyfile, "General", "CDROMCore", 0); - if((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.cdcoretype)) { - Cs2ChangeCDCore(yinit.cdcoretype, yinit.cdpath); - } - - /* region */ - { - char * region = g_key_file_get_value(keyfile, "General", "Region", 0); - tmp = yinit.regionid; - if ((region == 0) || !strcmp(region, "Auto")) { - yinit.regionid = 0; - } else { - switch(region[0]) { - case 'J': yinit.regionid = 1; break; - case 'T': yinit.regionid = 2; break; - case 'U': yinit.regionid = 4; break; - case 'B': yinit.regionid = 5; break; - case 'K': yinit.regionid = 6; break; - case 'A': yinit.regionid = 0xA; break; - case 'E': yinit.regionid = 0xC; break; - case 'L': yinit.regionid = 0xD; break; - } - } - - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.regionid)) { - mustRestart = TRUE; - } - } - - /* cart */ - stmp = g_key_file_get_value(keyfile, "General", "CartPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.cartpath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(cartpath, stmp, 256); - yinit.cartpath = cartpath; - } - else yinit.cartpath = NULL; - - tmp = yinit.carttype; - yinit.carttype = g_key_file_get_integer(keyfile, "General", "CartType", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.carttype)) { - mustRestart = TRUE; - } - - /* backup ram */ - stmp = g_key_file_get_value(keyfile, "General", "BackupRamPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.buppath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(buppath, stmp, 256); - yinit.buppath = buppath; - } - else yinit.buppath = NULL; - - /* mpeg rom */ - stmp = g_key_file_get_value(keyfile, "General", "MpegRomPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.mpegpath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(mpegpath, stmp, 256); - yinit.mpegpath = mpegpath; - } - else yinit.mpegpath = NULL; - - /* sh2 */ - tmp = yinit.sh2coretype; - yinit.sh2coretype = g_key_file_get_integer(keyfile, "General", "SH2Int", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.sh2coretype)) { - mustRestart = TRUE; - } - - /* m68k */ - tmp = yinit.m68kcoretype; - yinit.m68kcoretype = g_key_file_get_integer(keyfile, "General", "M68kInt", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.m68kcoretype)) { - mustRestart = TRUE; - } - - /* video core */ - tmp = yinit.vidcoretype; - yinit.vidcoretype = g_key_file_get_integer(keyfile, "General", "VideoCore", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.vidcoretype)) { - VideoChangeCore(yinit.vidcoretype); - VIDCore->Resize( - GTK_WIDGET(YUI_WINDOW(yui)->area)->allocation.width, - GTK_WIDGET(YUI_WINDOW(yui)->area)->allocation.height, - FALSE); - } - - /* osd core */ - tmp = yinit.osdcoretype; - yinit.osdcoretype = g_key_file_get_integer(keyfile, "General", "OSDCore", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.osdcoretype)) { - OSDChangeCore(yinit.osdcoretype); - } - - /* sound core */ - tmp = yinit.sndcoretype; - yinit.sndcoretype = g_key_file_get_integer(keyfile, "General", "SoundCore", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.sndcoretype)) { - ScspChangeSoundCore(yinit.sndcoretype); - } - - ScspSetVolume(g_key_file_get_integer(keyfile, "General", "Volume", NULL)); - - /* peripheral core */ - yinit.percoretype = g_key_file_get_integer(keyfile, "General", "PerCore", 0); - - /* audio sync */ - tmp = g_key_file_get_boolean(keyfile, "General", "AudioSync", 0); - ScspSetFrameAccurate(tmp); - - /* clock sync */ - tmp = yinit.clocksync; - yinit.clocksync = g_key_file_get_boolean(keyfile, "General", "ClockSync", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.clocksync)) { - mustRestart = TRUE; - } - tmptime = yinit.basetime; - tmp = g_key_file_get_boolean(keyfile, "General", "FixedBaseTime", 0); - if (tmp && yinit.clocksync) { - /* Find timestamp of 1998-01-01 12:00 in the local time zone */ - time_t utc = 883656000; // 1998-01-01 12:00 UTC - struct tm tm; - long local, noon; - localtime_r(&utc, &tm); - local = tm.tm_hour*3600 + tm.tm_min*60 + tm.tm_sec; - if (tm.tm_mday == 2) // 1998-01-02 - local += 86400; - else if (tm.tm_mday == 31) // 1997-12-31 - local -= 86400; - noon = 12*3600 + 0*60 + 0; - yinit.basetime = (long)utc + (noon - local); - } else { - yinit.basetime = 0; - } - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmptime != yinit.basetime)) { - mustRestart = TRUE; - } - - /* threads */ - tmp = g_key_file_get_boolean(keyfile, "General", "UseThreads", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.usethreads)) { - mustRestart = TRUE; - } - yinit.usethreads = tmp; - - PerInit(yinit.percoretype); - - PerPortReset(); - switch(g_key_file_get_integer(keyfile, "General", "PerType", NULL)) - { - case PERMOUSE: - padbits = PerMouseAdd(&PORTDATA1); - i = 0; - - while(PerMouseNames[i]) { - char tmp[100]; - u32 key; - sprintf(tmp, "Mouse.%s.1", PerMouseNames[i]); - key = g_key_file_get_integer(keyfile, PERCore->Name, tmp, 0); - PerSetKey(key, i + 13, padbits); - i++; - } - break; - case PERPAD: - default: - padbits = PerPadAdd(&PORTDATA1); - i = 0; - - while(PerPadNames[i]) { - char tmp[100]; - u32 key; - sprintf(tmp, "Pad.%s.1", PerPadNames[i]); - key = g_key_file_get_integer(keyfile, PERCore->Name, tmp, 0); - PerSetKey(key, i, padbits); - i++; - } - } - - yui_resize(g_key_file_get_integer(keyfile, "General", "Width", 0), - g_key_file_get_integer(keyfile, "General", "Height", 0), - g_key_file_get_integer(keyfile, "General", "Fullscreen", 0)); - - yinit.videoformattype = g_key_file_get_integer(keyfile, "General", "VideoFormat", 0); - - yui_window_set_frameskip(YUI_WINDOW(yui), g_key_file_get_integer(keyfile, "General", "Frameskip", NULL)); - - return mustRestart; -} - -void YuiErrorMsg(const char * string) { - GtkWidget* warningDlg = gtk_message_dialog_new (GTK_WINDOW(yui), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, string, NULL); - gtk_dialog_run (GTK_DIALOG(warningDlg)); - gtk_widget_destroy (warningDlg); -} - -int main(int argc, char *argv[]) { -#ifndef NO_CLI - int i; -#endif - LogStart(); - LogChangeOutput( DEBUG_STDERR, NULL ); - inifile = g_build_filename(g_get_user_config_dir(), "yabause", "gtk", "yabause.ini", NULL); - - if (! g_file_test(inifile, G_FILE_TEST_EXISTS)) { - // no inifile found, but it could be in the old location - gchar * oldinifile = g_build_filename(g_get_user_config_dir(), "yabause.ini", NULL); - - // we need to create the directory for the new file anyways - gchar * xdgpath = g_build_filename(g_get_user_config_dir(), "yabause", "gtk", NULL); - - if (! g_file_test(xdgpath, G_FILE_TEST_EXISTS)) - g_mkdir_with_parents(xdgpath, 0755); - g_free(xdgpath); - - if (g_file_test(oldinifile, G_FILE_TEST_EXISTS)) { - // ok, we found an old .ini file, let's copy the content - gchar * data; - - g_file_get_contents(oldinifile, &data, NULL, NULL); - g_file_set_contents(inifile, data, -1, NULL); - } - - g_free(oldinifile); - } - - keyfile = g_key_file_new(); - - gtk_init(&argc, &argv); -#ifdef HAVE_LIBGTKGLEXT - gtk_gl_init(&argc, &argv); -#endif - - yui_settings_init(); - -#ifdef HAVE_LIBMINI18N - mini18n_set_domain(YTSDIR); - g_key_file_load_from_file(keyfile, inifile, G_KEY_FILE_NONE, 0); - mini18n_set_locale(g_key_file_get_value(keyfile, "General", "TranslationPath", NULL)); -#endif - - yui = yui_new(); - - yui_settings_load(); - - gtk_window_move(GTK_WINDOW(yui), g_key_file_get_integer(keyfile, "Gtk", "X", 0), g_key_file_get_integer(keyfile, "Gtk", "Y", 0)); - -#ifndef NO_CLI - //handle command line arguments - for (i = 1; i < argc; ++i) { - if (argv[i]) { - //show usage - if (0 == strcmp(argv[i], "-h") || 0 == strcmp(argv[i], "-?") || 0 == strcmp(argv[i], "--help")) { - print_usage(argv[0]); - return 0; - } - - //set bios - if (0 == strcmp(argv[i], "-b") && argv[i + 1]) { - g_strlcpy(biospath, argv[i + 1], 256); - yinit.biospath = biospath; - } else if (strstr(argv[i], "--bios=")) { - g_strlcpy(biospath, argv[i] + strlen("--bios="), 256); - yinit.biospath = biospath; - } - //set iso - else if (0 == strcmp(argv[i], "-i") && argv[i + 1]) { - g_strlcpy(cdpath, argv[i + 1], 256); - yinit.cdcoretype = 1; - } else if (strstr(argv[i], "--iso=")) { - g_strlcpy(cdpath, argv[i] + strlen("--iso="), 256); - yinit.cdcoretype = 1; - } - //set cdrom - else if (0 == strcmp(argv[i], "-c") && argv[i + 1]) { - g_strlcpy(cdpath, argv[i + 1], 256); - yinit.cdcoretype = 2; - } else if (strstr(argv[i], "--cdrom=")) { - g_strlcpy(cdpath, argv[i] + strlen("--cdrom="), 256); - yinit.cdcoretype = 2; - } - // Set sound - else if (strcmp(argv[i], "-ns") == 0 || strcmp(argv[i], "--nosound") == 0) { - yinit.sndcoretype = 0; - } - // Autoload - else if (strcmp(argv[i], "--autoload") == 0) { - yui_window_start(YUI_WINDOW(yui)); - YuiLoadState(); - yui_window_run(YUI_WINDOW(yui)); - } - // Autostart - else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--autostart") == 0) { - yui_window_run(YUI_WINDOW(yui)); - } - // Fullscreen - else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--fullscreen") == 0) { - yui_window_set_fullscreen(YUI_WINDOW(yui), TRUE); - } - // Auto frame skip - else if (strstr(argv[i], "--autoframeskip=")) { - int fscount; - int fsenable; - fscount = sscanf(argv[i] + strlen("--autoframeskip="), "%d", &fsenable); - if (fscount > 0) - yui_window_set_frameskip(YUI_WINDOW(yui), fsenable); - } - // Binary - else if (strstr(argv[i], "--binary=")) { - char binname[1024]; - unsigned int binaddress; - int bincount; - - bincount = sscanf(argv[i] + strlen("--binary="), "%[^:]:%x", binname, &binaddress); - if (bincount > 0) { - if (bincount < 2) binaddress = 0x06004000; - - yui_window_run(YUI_WINDOW(yui)); - MappedMemoryLoadExec(binname, binaddress); - } - } - } - } -#endif - - gtk_main (); - - YabauseDeInit(); - LogStop(); - - return 0; -} - -void YuiSetVideoAttribute(int type, int val) { -} - -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) { - return 0; -} - -void YuiSwapBuffers(void) { - yui_window_update(YUI_WINDOW(yui)); -} - -void yui_conf(void) { - gint result; - GtkWidget * dialog; - - dialog = create_dialog1(); - - result = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - switch(result) { - case GTK_RESPONSE_OK: - { - gboolean mustRestart; - g_file_set_contents(inifile, g_key_file_to_data(keyfile, 0, 0), -1, 0); - mustRestart = yui_settings_load(); - if (mustRestart) { - GtkWidget* warningDlg = gtk_message_dialog_new (GTK_WINDOW(yui), - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - "You must restart Yabause before the changes take effect."); - - gtk_dialog_run (GTK_DIALOG(warningDlg)); - gtk_widget_destroy (warningDlg); - } - break; - } - case GTK_RESPONSE_CANCEL: - g_key_file_load_from_file(keyfile, inifile, G_KEY_FILE_NONE, 0); - break; - } -} - -void yui_resize(guint width, guint height, gboolean fullscreen) { - if (width <= 0) width = 320; - if (height <= 0) height = 224; - - if (g_key_file_get_integer(keyfile, "General", "KeepRatio", 0)) - { - GdkGeometry geometry; - geometry.min_aspect = (float) width / height; - geometry.max_aspect = (float) width / height; - gtk_window_set_geometry_hints(GTK_WINDOW(yui), YUI_WINDOW(yui)->area, &geometry, GDK_HINT_ASPECT); - } - else - { - gtk_window_set_geometry_hints(GTK_WINDOW(yui), YUI_WINDOW(yui)->area, NULL, 0); - } - - gtk_window_resize(GTK_WINDOW(yui), width, height + YUI_WINDOW(yui)->menu->allocation.height); - - yui_window_set_fullscreen(YUI_WINDOW(yui), fullscreen); -} diff --git a/yabause/src/gtk/menu.c b/yabause/src/gtk/menu.c deleted file mode 100644 index 8ecd9cffbf..0000000000 --- a/yabause/src/gtk/menu.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "settings.h" -#include "yuiwindow.h" -#include "yuivdp1.h" -#include "yuivdp2.h" -#include "yuish.h" -#include "yuitransfer.h" -#include "yuim68k.h" -#include "yuiscudsp.h" -#include "yuiscsp.h" -#include "yuimem.h" -#include "yuiscreenshot.h" - -static void openAboutDialog(GtkWidget * w, gpointer data) { - gtk_show_about_dialog(data, - "name", "Yabause", - "version", VERSION, - "website", "http://yabause.org", - NULL); -} - -void YuiSaveState(void) { - char * dir = g_key_file_get_value(keyfile, "General", "StatePath", NULL); - - YabSaveStateSlot(dir, 1); -} - -void YuiLoadState(void) { - char * dir = g_key_file_get_value(keyfile, "General", "StatePath", NULL); - - YabLoadStateSlot(dir, 1); -} - -GtkWidget* create_menu(YuiWindow * window1) { - GtkWidget *menubar1; - GtkWidget *menuitem1; - GtkWidget *menuitem1_menu; - GtkWidget *new1; - GtkWidget *view1; - GtkWidget *view1_menu; - GtkWidget *fps1; - GtkWidget *frameLimiter; - GtkWidget *layer1; - GtkWidget *layer1_menu; - GtkWidget *log; - GtkWidget *menuitem3; - GtkWidget *menuitem3_menu; - GtkWidget *msh; - GtkWidget *ssh; - GtkWidget *vdp2; - GtkWidget *vdp1; - GtkWidget *m68k; - GtkWidget *scudsp; - GtkWidget *scsp; - GtkWidget *menuitem4; - GtkWidget *menuitem4_menu; - GtkWidget *about1; - GtkWidget *transfer; - GtkWidget *memory; - GtkWidget *screenshot; - - menubar1 = gtk_menu_bar_new (); - - menuitem1 = gtk_menu_item_new_with_mnemonic ("_Yabause"); - gtk_container_add (GTK_CONTAINER (menubar1), menuitem1); - - menuitem1_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu); - - new1 = gtk_image_menu_item_new_from_stock("gtk-preferences", NULL); - g_signal_connect(new1, "activate", yui_conf, 0); - gtk_container_add (GTK_CONTAINER (menuitem1_menu), new1); - - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "run"))); - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "pause"))); - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "reset"))); - - transfer = gtk_menu_item_new_with_mnemonic (_("Transfer")); - gtk_container_add (GTK_CONTAINER (menuitem1_menu), transfer); - g_signal_connect_swapped(transfer, "activate", G_CALLBACK(yui_transfer_new), window1); - - screenshot = gtk_menu_item_new_with_mnemonic (_("Screenshot")); - gtk_container_add (GTK_CONTAINER (menuitem1_menu), screenshot); - g_signal_connect_swapped(screenshot, "activate", G_CALLBACK(yui_screenshot_new), window1); - - frameLimiter = gtk_check_menu_item_new_with_mnemonic (_("Frame Skip/Limiter")); - { - GtkAction * action = gtk_action_group_get_action(window1->action_group, "frameskip"); - gtk_action_connect_proxy(action, frameLimiter); - } - gtk_container_add (GTK_CONTAINER (menuitem1_menu), frameLimiter); - - { - GtkWidget * savestate_menu; - GtkWidget * savestate; - GtkWidget * savestate_save; - GtkWidget * savestate_load; - - savestate = gtk_menu_item_new_with_mnemonic(_("Save State")); - gtk_container_add(GTK_CONTAINER(menuitem1_menu), savestate); - - savestate_menu = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(savestate), savestate_menu); - - savestate_save = gtk_menu_item_new_with_mnemonic(_("Save")); - gtk_container_add(GTK_CONTAINER(savestate_menu), savestate_save); - g_signal_connect_swapped(savestate_save, "activate", G_CALLBACK(YuiSaveState), NULL); - - savestate_load = gtk_menu_item_new_with_mnemonic(_("Load")); - gtk_container_add(GTK_CONTAINER(savestate_menu), savestate_load); - g_signal_connect_swapped(savestate_load, "activate", G_CALLBACK(YuiLoadState), NULL); - } - - gtk_container_add (GTK_CONTAINER (menuitem1_menu), gtk_separator_menu_item_new ()); - - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "quit"))); - - view1 = gtk_menu_item_new_with_mnemonic (_("_View")); - gtk_container_add (GTK_CONTAINER (menubar1), view1); - - view1_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (view1), view1_menu); - - fps1 = gtk_check_menu_item_new_with_mnemonic (_("FPS")); - g_signal_connect(fps1, "activate", G_CALLBACK(ToggleFPS), NULL); - gtk_container_add (GTK_CONTAINER (view1_menu), fps1); - - layer1 = gtk_menu_item_new_with_mnemonic (_("Layer")); - gtk_container_add (GTK_CONTAINER (view1_menu), layer1); - - layer1_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (layer1), layer1_menu); - - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_vdp1"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg0"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg1"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg2"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg3"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_rbg0"))); - - gtk_container_add(GTK_CONTAINER(view1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "fullscreen"))); - - log = gtk_menu_item_new_with_mnemonic (_("Log")); - g_signal_connect_swapped(log, "activate", G_CALLBACK(yui_window_show_log), window1); - gtk_container_add(GTK_CONTAINER(view1_menu), log); - - menuitem3 = gtk_menu_item_new_with_mnemonic (_("_Debug")); - gtk_container_add (GTK_CONTAINER (menubar1), menuitem3); - - menuitem3_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem3), menuitem3_menu); - - msh = gtk_menu_item_new_with_mnemonic ("MSH2"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), msh); - g_signal_connect_swapped(msh, "activate", G_CALLBACK(yui_msh_new), window1); - - ssh = gtk_menu_item_new_with_mnemonic ("SSH2"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), ssh); - g_signal_connect_swapped(ssh, "activate", G_CALLBACK(yui_ssh_new), window1); - - vdp2 = gtk_menu_item_new_with_mnemonic ("Vdp1"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), vdp2); - g_signal_connect_swapped(vdp2, "activate", G_CALLBACK(yui_vdp1_new), window1); - - vdp1 = gtk_menu_item_new_with_mnemonic ("Vdp2"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), vdp1); - g_signal_connect_swapped(vdp1, "activate", G_CALLBACK(yui_vdp2_new), window1); - - m68k = gtk_menu_item_new_with_mnemonic ("M68K"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), m68k); - g_signal_connect_swapped(m68k, "activate", G_CALLBACK(yui_m68k_new), window1); - - scudsp = gtk_menu_item_new_with_mnemonic ("SCU-DSP"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), scudsp); - g_signal_connect_swapped(scudsp, "activate", G_CALLBACK(yui_scudsp_new), window1); - - scsp = gtk_menu_item_new_with_mnemonic ("SCSP"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), scsp); - g_signal_connect_swapped(scsp, "activate", G_CALLBACK(yui_scsp_new), window1); - - gtk_container_add (GTK_CONTAINER (menuitem3_menu), gtk_separator_menu_item_new ()); - - memory = gtk_menu_item_new_with_mnemonic (_("Memory dump")); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), memory); - g_signal_connect_swapped(memory, "activate", G_CALLBACK(yui_mem_new), window1); - - menuitem4 = gtk_menu_item_new_with_mnemonic (_("_Help")); - gtk_container_add (GTK_CONTAINER (menubar1), menuitem4); - - menuitem4_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menuitem4_menu); - - about1 = gtk_image_menu_item_new_from_stock ("gtk-about", NULL); - gtk_container_add (GTK_CONTAINER (menuitem4_menu), about1); - g_signal_connect(about1, "activate", G_CALLBACK(openAboutDialog), window1); - - return menubar1; -} - diff --git a/yabause/src/gtk/pergtk.c b/yabause/src/gtk/pergtk.c deleted file mode 100644 index 734674bf14..0000000000 --- a/yabause/src/gtk/pergtk.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright 2005-2006 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "pergtk.h" -#include -#include "../yabause.h" -#include "../vdp2.h" -#include "../yui.h" - -int PERGTKInit(void); -void PERGTKDeInit(void); -int PERGTKHandleEvents(void); -void PERGTKNothing(void); - -u32 PERGTKScan(void); -void PERGTKFlush(void); -void PERGTKKeyName(u32 key, char * name, int size); - -PerInterface_struct PERGTK = { -PERCORE_GTK, -"GTK Input Interface", -PERGTKInit, -PERGTKDeInit, -PERGTKHandleEvents, -PERGTKNothing, -PERGTKScan, -0, -PERGTKFlush -#ifdef PERKEYNAME -,PERGTKKeyName -#endif -}; - -////////////////////////////////////////////////////////////////////////////// - -int PERGTKInit(void) { - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKDeInit(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKNothing(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -int PERGTKHandleEvents(void) { - YabauseExec(); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERGTKScan(void) { - g_print("this is wrong, the gtk peripheral can't scan\n"); - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKFlush(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKKeyName(u32 key, char * name, int size) -{ - g_strlcpy(name, gdk_keyval_name(key), size); -} diff --git a/yabause/src/gtk/pergtk.h b/yabause/src/gtk/pergtk.h deleted file mode 100644 index 0d441196f9..0000000000 --- a/yabause/src/gtk/pergtk.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERGTK_H -#define PERGTK_H - -#include "../peripheral.h" - -#define PERCORE_GTK 2 - -extern PerInterface_struct PERGTK; - -#endif diff --git a/yabause/src/gtk/settings.c b/yabause/src/gtk/settings.c deleted file mode 100644 index 4af555def1..0000000000 --- a/yabause/src/gtk/settings.c +++ /dev/null @@ -1,569 +0,0 @@ -/* Copyright 2006-2011 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "settings.h" - -#include "yuicheckbutton.h" -#include "yuifileentry.h" -#include "yuirange.h" -#include "yuipage.h" -#include "yuiinputentry.h" -#include "yuiresolution.h" - -#include "../scsp.h" - -typedef struct { - int id; - const char *Name; -} GenericInterface_struct; - -void cores_to_range(void * pointer, YuiRangeItem ** items) { - GenericInterface_struct ** cores; - GenericInterface_struct * core; - int i; - - if (*items != NULL) return; - - cores = pointer; - - i = 0; - core = cores[i]; - while(core) { - i++; - core = cores[i]; - } - *items = malloc(sizeof(YuiRangeItem) * (i + 1)); - i = 0; - core = cores[i]; - while(core) { - char buffer[1024]; - (*items)[i].name = strdup(core->Name); - sprintf(buffer, "%d", core->id); - (*items)[i].value = strdup(buffer); - i++; - core = cores[i]; - } - (*items)[i].name = NULL; - (*items)[i].value = NULL; -} - -extern CDInterface *SH2CoreList[]; -extern CDInterface *M68KCoreList[]; -extern CDInterface *CDCoreList[]; -extern CDInterface *VIDCoreList[]; -extern CDInterface *OSDCoreList[]; -extern CDInterface *SNDCoreList[]; -extern CDInterface *PERCoreList[]; - -YuiRangeItem * sh2interpreters = NULL; -YuiRangeItem * m68kinterpreters = NULL; -YuiRangeItem * cdcores = NULL; -YuiRangeItem * vidcores = NULL; -YuiRangeItem * osdcores = NULL; -YuiRangeItem * sndcores = NULL; -YuiRangeItem * percores = NULL; - -YuiRangeItem regions[] = { - { "Auto" , "Auto-detect" }, - { "J" , "Japan (NTSC)" }, - { "T", "Asia (NTSC)" }, - { "U", "North America (NTSC)" }, - { "B", "Central/South America (NTSC)" }, - { "K", "Korea (NTSC)" }, - { "A", "Asia (PAL)" }, - { "E", "Europe + others (PAL)" }, - { "L", "Central/South America (PAL)" }, - { 0, 0 } -}; - -YuiRangeItem carttypes[] = { - { "0", "None" }, - { "1", "Pro Action Replay" }, - { "2", "4 Mbit Backup Ram" }, - { "3", "8 Mbit Backup Ram" }, - { "4", "16 Mbit Backup Ram" }, - { "5", "32 Mbit Backup Ram" }, - { "6", "8 Mbit Dram" }, - { "7", "32 Mbit Dram" }, - { "8", "Netlink" }, - { "9", "16 Mbit ROM" }, - { 0, 0 } -}; - -const gchar * keys1[] = { "Up", "Right", "Down", "Left", "R", "L", 0 }; -const gchar * keys2[] = { "A", "B", "C", "X", "Y", "Z", "Start", 0 }; - -YuiRangeItem vidformats[] = { - { "0", "NTSC" }, - { "1", "PAL" }, - { 0, 0 } -}; - -YuiRangeItem mousepercores[] = { - { "2", "Gtk Input Interface" }, - { 0, 0 } -}; - -static void hide_show_cart_path(YuiRange * instance, gpointer data) { - gint i = yui_range_get_active(instance); - - if (i == 8) { - gtk_widget_hide(data); - } else { - gtk_widget_show(data); - } -} - -static void hide_show_netlink(YuiRange * instance, gpointer data) { - gint i = yui_range_get_active(instance); - - if (i != 8) { - gtk_widget_hide(data); - } else { - gtk_widget_show(data); - } -} - -static void percore_changed(GtkWidget * widget, gpointer data) { - const char * core_s = percores[gtk_combo_box_get_active(GTK_COMBO_BOX(widget))].value; - GList * entrylist = data; - int core; - sscanf(core_s, "%d", &core); - - PerDeInit(); - PerInit(core); - - while(entrylist) { - yui_input_entry_update(entrylist->data); - entrylist = g_list_next(entrylist); - } -} - -static void pertype_display_pad(GtkWidget * box) -{ - GtkWidget * table4, * table5; - GtkWidget * box_percore = gtk_vbox_new(FALSE, 10); - GtkWidget * select_percore = yui_range_new(keyfile, "General", "PerCore", percores); - GList * entrylist = NULL; - - gtk_container_set_border_width(GTK_CONTAINER(select_percore), 0); - - gtk_container_set_border_width(GTK_CONTAINER(box_percore), 10); - - gtk_box_pack_start(GTK_BOX (box_percore), select_percore, FALSE, FALSE, 0); - - table4 = yui_input_entry_new(keyfile, "Pad", keys1); - entrylist = g_list_append(entrylist, table4); - - gtk_box_pack_start (GTK_BOX (box_percore), table4, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), box_percore, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new(), TRUE, TRUE, 0); - - table5 = yui_input_entry_new(keyfile, "Pad", keys2); - entrylist = g_list_append(entrylist, table5); - - gtk_container_set_border_width(GTK_CONTAINER(table5), 10); - - gtk_box_pack_start (GTK_BOX (box), table5, TRUE, TRUE, 0); - - g_signal_connect(GTK_COMBO_BOX(YUI_RANGE(select_percore)->combo), "changed", G_CALLBACK(percore_changed), entrylist); - - gtk_widget_show_all(box); -} - -static void mouse_speed_change(GtkWidget * range, gpointer data) -{ - g_key_file_set_double(keyfile, "General", "MouseSpeed", gtk_range_get_value(GTK_RANGE(range))); -} - -static void pertype_display_mouse(GtkWidget * box) -{ - GtkWidget * scale; - GtkWidget * table5; - GtkWidget * box_percore = gtk_vbox_new(FALSE, 10); - GtkWidget * select_percore = yui_range_new(keyfile, "General", "MousePerCore", mousepercores); - GList * entrylist = NULL; - - gtk_container_set_border_width(GTK_CONTAINER(select_percore), 0); - gtk_container_set_border_width(GTK_CONTAINER(box_percore), 10); - gtk_box_pack_start(GTK_BOX (box_percore), select_percore, FALSE, FALSE, 0); - - scale = gtk_hscale_new_with_range(0, 10, 0.1); - gtk_range_set_value(GTK_RANGE(scale), g_key_file_get_double(keyfile, "General", "MouseSpeed", NULL)); - g_signal_connect(scale, "value-changed", G_CALLBACK(mouse_speed_change), NULL); - gtk_box_pack_start(GTK_BOX (box_percore), scale, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (box), box_percore, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new(), TRUE, TRUE, 0); - - table5 = yui_input_entry_new(keyfile, "Mouse", PerMouseNames); - entrylist = g_list_append(entrylist, table5); - gtk_container_set_border_width(GTK_CONTAINER(table5), 10); - gtk_box_pack_start (GTK_BOX (box), table5, TRUE, TRUE, 0); - - g_signal_connect(GTK_COMBO_BOX(YUI_RANGE(select_percore)->combo), "changed", G_CALLBACK(percore_changed), entrylist); - gtk_widget_show_all(box); -} - -static void pertype_changed(GtkWidget * widget, gpointer data) { - GtkTreePath * path; - gchar * strpath; - int i; - GtkWidget * box = data; - GList * children; - GtkWidget * child; - - children = gtk_container_get_children(GTK_CONTAINER(box)); - for(i = 1;i < 4;i++) { - child = g_list_nth_data(children, i); - if (child != NULL) gtk_widget_destroy(child); - } - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, NULL); - - if (path) { - int i; - - strpath = gtk_tree_path_to_string(path); - sscanf(strpath, "%d", &i); - - switch(i) { - case 0: - g_key_file_set_integer(keyfile, "General", "PerType", PERPAD); - pertype_display_pad(box); - break; - case 1: - g_key_file_set_integer(keyfile, "General", "PerType", PERMOUSE); - pertype_display_mouse(box); - break; - } - - g_free(strpath); - gtk_tree_path_free(path); - } -} - -static void frameskip_toggled(GtkWidget * widget, gpointer data) { - g_key_file_set_integer(keyfile, "General", "Frameskip", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); -} - -static void disable_enable_audio_sync(YuiCheckButton *audiosync) { - ScspSetFrameAccurate(yui_check_button_get_active(audiosync)); -} - -static void disable_enable_fixed_base_time(YuiCheckButton *clocksync, YuiCheckButton *fixedbasetime) { - gtk_widget_set_sensitive(GTK_WIDGET(fixedbasetime), - yui_check_button_get_active(clocksync)); -} - -static void volume_changed(GtkRange * range, gpointer data) { - g_key_file_set_integer(keyfile, "General", "Volume", (int) gtk_range_get_value(range)); -} - -GtkWidget* create_dialog1(void) { - GtkWidget *dialog1; - GtkWidget *notebook1; - GtkWidget *vbox17; - GtkWidget *hbox22; - GtkWidget *button11; - GtkWidget *button12; - GtkWidget * general, * video_sound, * cart_memory, *advanced, * sound; - GtkWidget * box; - u8 perid; - - cores_to_range(SH2CoreList, &sh2interpreters); - cores_to_range(M68KCoreList, &m68kinterpreters); - cores_to_range(CDCoreList, &cdcores); - cores_to_range(VIDCoreList, &vidcores); - cores_to_range(OSDCoreList, &osdcores); - cores_to_range(SNDCoreList, &sndcores); - cores_to_range(PERCoreList, &percores); - - dialog1 = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (dialog1), "Yabause configuration"); - gtk_window_set_icon_name (GTK_WINDOW (dialog1), "gtk-preferences"); - gtk_window_set_type_hint (GTK_WINDOW (dialog1), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_resizable(GTK_WINDOW(dialog1), FALSE); - - notebook1 = gtk_notebook_new (); - gtk_widget_show(notebook1); - - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog1)->vbox), notebook1, TRUE, TRUE, 0); - - /* - * General configuration - */ - general = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(general), _("Bios")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "BiosPath", YUI_FILE_ENTRY_BROWSE, NULL)); - - box = yui_page_add(YUI_PAGE(general), _("Cdrom")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "CDROMCore", cdcores)); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "CDROMDrive", YUI_FILE_ENTRY_BROWSE, NULL)); - - box = yui_page_add(YUI_PAGE(general), _("Save States")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "StatePath", YUI_FILE_ENTRY_BROWSE | YUI_FILE_ENTRY_DIRECTORY, NULL)); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), general, gtk_label_new (_("General"))); - gtk_widget_show_all(general); - - /* - * Video configuration - */ - video_sound = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(video_sound), _("Video Core")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "VideoCore", vidcores)); - -#ifdef YAB_PORT_OSD - box = yui_page_add(YUI_PAGE(video_sound), _("OSD Core")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "OSDCore", osdcores)); -#endif - - box = yui_page_add(YUI_PAGE(video_sound), _("Resolution")); - gtk_container_add(GTK_CONTAINER(box), yui_resolution_new(keyfile, "General")); - - box = yui_page_add(YUI_PAGE(video_sound), _("Video Format")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "VideoFormat", vidformats)); - - box = yui_page_add(YUI_PAGE(video_sound), _("Frame Skip/Limiter")); - { - GtkWidget * frameskip = gtk_check_button_new_with_label("Enable frame skipping/limiting"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskip), g_key_file_get_integer(keyfile, "General", "Frameskip", NULL)); - gtk_container_set_border_width(GTK_CONTAINER(frameskip), 10); - g_signal_connect(frameskip, "toggled", G_CALLBACK(frameskip_toggled), NULL); - gtk_container_add(GTK_CONTAINER(box), frameskip); - } - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), video_sound, gtk_label_new (_("Video"))); - gtk_widget_show_all(video_sound); - - /* - * Sound configuration - */ - sound = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(sound), _("Sound Core")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "SoundCore", sndcores)); - - { - GtkWidget * volume; - - box = yui_page_add(YUI_PAGE(sound), _("Volume")); - gtk_container_set_border_width(GTK_CONTAINER(box), 10); - volume = gtk_hscale_new_with_range(0, 100, 1); - gtk_range_set_value(GTK_RANGE(volume), g_key_file_get_integer(keyfile, "General", "Volume", NULL)); - g_signal_connect(volume, "value-changed", G_CALLBACK(volume_changed), NULL); - gtk_container_add(GTK_CONTAINER(box), volume); - } - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), sound, gtk_label_new (_("Sound"))); - gtk_widget_show_all(sound); - - /* - * Cart/Memory configuration - */ - cart_memory = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(cart_memory), _("Cartridge")); - { - GtkWidget * w1, * w2, * w3; - - w1 = yui_range_new(keyfile, "General", "CartType", carttypes); - gtk_container_add(GTK_CONTAINER(box), w1); - - w2 = yui_file_entry_new(keyfile, "General", "CartPath", YUI_FILE_ENTRY_BROWSE, NULL); - gtk_container_add(GTK_CONTAINER(box), w2); - - w3 = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(w3), yui_file_entry_new(keyfile, "General", "NetlinkHost", 0, "Host"), TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(w3), yui_file_entry_new(keyfile, "General", "NetlinkPort", 0, "Port"), TRUE, TRUE, 0); - gtk_container_add(GTK_CONTAINER(box), w3); - - g_signal_connect(w1, "changed", G_CALLBACK(hide_show_cart_path), w2); - g_signal_connect(w1, "changed", G_CALLBACK(hide_show_netlink), w3); - - box = yui_page_add(YUI_PAGE(cart_memory), _("Memory")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "BackupRamPath", YUI_FILE_ENTRY_BROWSE, NULL)); - - box = yui_page_add(YUI_PAGE(cart_memory), _("Mpeg ROM")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "MpegRomPath", YUI_FILE_ENTRY_BROWSE, NULL)); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), cart_memory, gtk_label_new (_("Cart/Memory"))); - gtk_widget_show_all(cart_memory); - - if (yui_range_get_active(YUI_RANGE(w1)) == 8) gtk_widget_hide(w2); - else gtk_widget_hide(w3); - } - - /* - * Input Configuration - */ - vbox17 = gtk_vbox_new (FALSE, 0); - - hbox22 = gtk_hbox_new (FALSE, 0); - - { - GtkWidget * controllerscroll; - GtkTreeStore * controllerlist; - GtkWidget * controllerlistview; - GtkCellRenderer * controllerrenderer; - GtkTreeViewColumn * controllercolumn; - GtkTreeIter iter; - GtkTreePath * path; - - controllerscroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(controllerscroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - controllerlist = gtk_tree_store_new(1, G_TYPE_STRING); - controllerlistview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(controllerlist)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(controllerlistview), FALSE); - - controllerrenderer = gtk_cell_renderer_text_new(); - controllercolumn = gtk_tree_view_column_new_with_attributes("Controller", controllerrenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (controllerlistview), controllercolumn); - - gtk_tree_store_append(controllerlist, &iter, NULL); - gtk_tree_store_set(controllerlist, &iter, 0, "Pad", -1); - - gtk_tree_store_append(controllerlist, &iter, NULL); - gtk_tree_store_set(controllerlist, &iter, 0, "Mouse", -1); - - gtk_container_add(GTK_CONTAINER(controllerscroll), controllerlistview); - gtk_box_pack_start (GTK_BOX (hbox22), controllerscroll, TRUE, TRUE, 0); - - gtk_tree_view_expand_all(GTK_TREE_VIEW(controllerlistview)); - - g_signal_connect(controllerlistview, "cursor-changed", G_CALLBACK(pertype_changed), hbox22); - perid = g_key_file_get_integer(keyfile, "General", "PerType", NULL); - switch(perid) - { - case PERMOUSE: - path = gtk_tree_path_new_from_string("1"); - break; - case PERPAD: - default: - path = gtk_tree_path_new_from_string("0"); - break; - } - - gtk_tree_view_set_cursor(GTK_TREE_VIEW(controllerlistview), path, NULL, FALSE); - gtk_tree_path_free(path); - } - - gtk_box_pack_start (GTK_BOX (vbox17), hbox22, TRUE, TRUE, 0); - - //pertype_display_pad(hbox22); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), vbox17, gtk_label_new (_("Input"))); - gtk_widget_show_all(vbox17); - - /* - * Advanced configuration - */ - - advanced = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(advanced), _("Region")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "Region", regions)); - - box = yui_page_add(YUI_PAGE(advanced), _("SH2 Interpreter")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "SH2Int", sh2interpreters)); - - box = yui_page_add(YUI_PAGE(advanced), _("M68k Interpreter")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "M68kInt", m68kinterpreters)); - - box = yui_page_add(YUI_PAGE(advanced), _("Audio Sync")); - { - GtkWidget *button = yui_check_button_new( - _("Synchronize audio output with emulation"), - keyfile, "General", "AudioSync" - ); - gtk_container_add(GTK_CONTAINER(box), button); - g_signal_connect(button, "changed", - G_CALLBACK(disable_enable_audio_sync), NULL); - } - - box = yui_page_add(YUI_PAGE(advanced), _("Clock Sync")); - { - GtkWidget *button1, *button2; - - button1 = yui_check_button_new( - _("Synchronize internal clock with emulation"), - keyfile, "General", "ClockSync" - ); - gtk_container_add(GTK_CONTAINER(box), button1); - - button2 = yui_check_button_new( - _("Always start from 1998-01-01 12:00"), - keyfile, "General", "FixedBaseTime" - ); - gtk_container_add(GTK_CONTAINER(box), button2); - if (!yui_check_button_get_active(YUI_CHECK_BUTTON(button1))) - gtk_widget_set_sensitive(button2, FALSE); - - g_signal_connect(button1, "changed", - G_CALLBACK(disable_enable_fixed_base_time), button2); - } - - box = yui_page_add(YUI_PAGE(advanced), _("Threads")); - { - GtkWidget *button = yui_check_button_new( - _("Use multithreaded emulation (EXPERIMENTAL!)"), - keyfile, "General", "UseThreads" - ); - gtk_container_add(GTK_CONTAINER(box), button); - } - -#ifdef HAVE_LIBMINI18N - box = yui_page_add(YUI_PAGE(advanced), _("Translation")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "TranslationPath", YUI_FILE_ENTRY_BROWSE, NULL)); -#endif - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), advanced, gtk_label_new (_("Advanced"))); - gtk_widget_show_all(advanced); - - /* - * Dialog buttons - */ - button11 = gtk_button_new_from_stock ("gtk-cancel"); - - gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button11, GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS (button11, GTK_CAN_DEFAULT); - gtk_widget_show(button11); - - button12 = gtk_button_new_from_stock ("gtk-ok"); - - gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button12, GTK_RESPONSE_OK); - GTK_WIDGET_SET_FLAGS (button12, GTK_CAN_DEFAULT); - gtk_widget_show(button12); - - gtk_widget_show(dialog1); - - return dialog1; -} - -void yui_texture_free(guchar *pixels, gpointer data) { - free(pixels); -} diff --git a/yabause/src/gtk/settings.h b/yabause/src/gtk/settings.h deleted file mode 100644 index a36f146045..0000000000 --- a/yabause/src/gtk/settings.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SETTINGS_H -#define YUI_SETTINGS_H - -#include - -#include "../vdp1.h" -#include "../vdp2.h" -#include "../scsp.h" -#include "../yabause.h" -#include "../cdbase.h" -#include "../peripheral.h" - -#include "yuiwindow.h" - -extern GKeyFile * keyfile; -extern yabauseinit_struct yinit; - -extern void YuiSaveState(void); -extern void YuiLoadState(void); - -GtkWidget* create_dialog1(void); -GtkWidget* create_menu(YuiWindow *); - -void yui_conf(void); -void yui_resize(guint, guint, gboolean); - -void gtk_yui_toggle_fullscreen(void); - -void yui_texture_free(guchar *pixels, gpointer data); - -#endif diff --git a/yabause/src/gtk/yabause.desktop.in b/yabause/src/gtk/yabause.desktop.in deleted file mode 100644 index 2da69a2a6f..0000000000 --- a/yabause/src/gtk/yabause.desktop.in +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Type=Application -Name=Yabause (Gtk port) -Comment=Sega Saturn emulator -TryExec=yabause -Exec=@YAB_PORT_NAME@ -Icon=yabause -Categories=GNOME;GTK;Game; diff --git a/yabause/src/gtk/yabause.png b/yabause/src/gtk/yabause.png deleted file mode 100644 index bfa6208a0c..0000000000 Binary files a/yabause/src/gtk/yabause.png and /dev/null differ diff --git a/yabause/src/gtk/yuicheckbutton.c b/yabause/src/gtk/yuicheckbutton.c deleted file mode 100644 index 93d6673df1..0000000000 --- a/yabause/src/gtk/yuicheckbutton.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuicheckbutton.h" - -static void yui_check_button_class_init(YuiCheckButtonClass * klass); -static void yui_check_button_init (YuiCheckButton * ycb); -static void yui_check_button_toggled (GtkToggleButton * button, YuiCheckButton * ycb); - -GType yui_check_button_get_type (void) { - static GType ycb_type = 0; - - if (!ycb_type) - { - static const GTypeInfo ycb_info = - { - sizeof (YuiCheckButtonClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_check_button_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiCheckButton), - 0, - (GInstanceInitFunc) yui_check_button_init, - NULL, - }; - - ycb_type = g_type_register_static(GTK_TYPE_CHECK_BUTTON, "YuiCheckButton", &ycb_info, 0); - } - - return ycb_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 -#define PROP_KEY 3 - -static void yui_check_button_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_CHECK_BUTTON(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_CHECK_BUTTON(object)->group = g_value_get_pointer(value); - break; - case PROP_KEY: - YUI_CHECK_BUTTON(object)->key = g_value_get_pointer(value); - break; - } -} - -static void yui_check_button_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -enum { YUI_CHECK_BUTTON_CHANGED_SIGNAL, LAST_SIGNAL }; - -static guint yui_check_button_signals[LAST_SIGNAL] = { 0 }; - -static void yui_check_button_class_init (YuiCheckButtonClass * klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_check_button_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_check_button_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); - - param = g_param_spec_pointer("key", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY, param); - - yui_check_button_signals[YUI_CHECK_BUTTON_CHANGED_SIGNAL] = g_signal_new ("changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiCheckButtonClass, yui_check_button_change), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -static void yui_check_button_init (YuiCheckButton * ycb) { -} - -GtkWidget * yui_check_button_new(const gchar * label, GKeyFile * keyfile, const gchar * group, const gchar * key) { - GtkWidget * button; - YuiCheckButton * ycb; - gboolean current; - - button = GTK_WIDGET(g_object_new(yui_check_button_get_type(), - "label", label, - "key-file", keyfile, "group", group, "key", key, NULL)); - ycb = YUI_CHECK_BUTTON(button); - - gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(ycb), TRUE); - - current = g_key_file_get_boolean(ycb->keyfile, ycb->group, ycb->key, NULL); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ycb), current); - - g_signal_connect(GTK_TOGGLE_BUTTON(ycb), "toggled", G_CALLBACK(yui_check_button_toggled), ycb); - - return button; -} - -static void yui_check_button_toggled(GtkToggleButton * button, YuiCheckButton * ycb) { - g_key_file_set_boolean(ycb->keyfile, ycb->group, ycb->key, - gtk_toggle_button_get_active(button)); - g_signal_emit(G_OBJECT(ycb), yui_check_button_signals[YUI_CHECK_BUTTON_CHANGED_SIGNAL], 0); -} - -gboolean yui_check_button_get_active(YuiCheckButton * ycb) { - return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ycb)); -} diff --git a/yabause/src/gtk/yuicheckbutton.h b/yabause/src/gtk/yuicheckbutton.h deleted file mode 100644 index 3a468bcb41..0000000000 --- a/yabause/src/gtk/yuicheckbutton.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_CHECK_BUTTON_H -#define YUI_CHECK_BUTTON_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_CHECK_BUTTON_TYPE (yui_check_button_get_type ()) -#define YUI_CHECK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_CHECK_BUTTON_TYPE, YuiCheckButton)) -#define YUI_CHECK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_CHECK_BUTTON_TYPE, YuiCheckButtonClass)) -#define IS_YUI_CHECK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_CHECK_BUTTON_TYPE)) -#define IS_YUI_CHECK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_CHECK_BUTTON_TYPE)) - -typedef struct _YuiCheckButton YuiCheckButton; -typedef struct _YuiCheckButtonClass YuiCheckButtonClass; - -struct _YuiCheckButton -{ - GtkCheckButton button; - - GKeyFile * keyfile; - gchar * group; - gchar * key; -}; - -struct _YuiCheckButtonClass -{ - GtkCheckButtonClass parent_class; - - void (* yui_check_button_change) (YuiCheckButton * ycb); -}; - -GType yui_check_button_get_type (void); -GtkWidget * yui_check_button_new (const gchar * label, GKeyFile * keyfile, const gchar * group, const gchar * key); -gboolean yui_check_button_get_active (YuiCheckButton * ycb); - -G_END_DECLS - -#endif /* YUI_CHECK_BUTTON_H */ diff --git a/yabause/src/gtk/yuifileentry.c b/yabause/src/gtk/yuifileentry.c deleted file mode 100644 index 11385d7b94..0000000000 --- a/yabause/src/gtk/yuifileentry.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuifileentry.h" - -static void yui_file_entry_class_init (YuiFileEntryClass * klass); -static void yui_file_entry_init (YuiFileEntry * yfe); -static void yui_file_entry_browse (GtkWidget * widget, gpointer user_data); -static void yui_file_entry_changed (GtkWidget * widget, YuiFileEntry * yfe); - -GType yui_file_entry_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiFileEntryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_file_entry_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiFileEntry), - 0, - (GInstanceInitFunc) yui_file_entry_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_HBOX, "YuiFileEntry", &yfe_info, 0); - } - - return yfe_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 -#define PROP_KEY 3 - -static void yui_file_entry_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_FILE_ENTRY(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_FILE_ENTRY(object)->group = g_value_get_pointer(value); - break; - case PROP_KEY: - YUI_FILE_ENTRY(object)->key = g_value_get_pointer(value); - break; - } -} - -static void yui_file_entry_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -static void yui_file_entry_class_init (YuiFileEntryClass * klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_file_entry_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_file_entry_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); - - param = g_param_spec_pointer("key", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY, param); -} - -static void yui_file_entry_init (YuiFileEntry * yfe) { - gtk_container_set_border_width(GTK_CONTAINER(yfe), 10); -} - -GtkWidget * yui_file_entry_new(GKeyFile * keyfile, const gchar * group, const gchar * key, gint flags, const gchar * label) { - GtkWidget * entry; - YuiFileEntry * yfe; - gchar * entryText; - - entry = GTK_WIDGET(g_object_new(yui_file_entry_get_type(), "spacing", 10, - "key-file", keyfile, "group", group, "key", key, NULL)); - yfe = YUI_FILE_ENTRY(entry); - - yfe->flags = flags; - - if (label) { - gtk_box_pack_start(GTK_BOX(yfe), gtk_label_new_with_mnemonic(label), FALSE, FALSE, 0); - } - - yfe->entry = gtk_entry_new (); - gtk_box_pack_start(GTK_BOX(yfe), yfe->entry, TRUE, TRUE, 0); - - if (flags & YUI_FILE_ENTRY_BROWSE) { - yfe->button = gtk_button_new_with_mnemonic ("Browse"); - g_signal_connect(yfe->button, "clicked", G_CALLBACK(yui_file_entry_browse), yfe); - gtk_box_pack_start(GTK_BOX(yfe), yfe->button, FALSE, FALSE, 0); - } - - entryText = g_key_file_get_value(yfe->keyfile, yfe->group, yfe->key, 0); - if ( !entryText ) entryText = ""; - gtk_entry_set_text(GTK_ENTRY(yfe->entry), entryText ); - g_signal_connect(GTK_ENTRY(yfe->entry), "changed", G_CALLBACK(yui_file_entry_changed), yfe); - - return entry; -} - -static void yui_file_entry_browse(GtkWidget * widget, gpointer user_data) { - GtkWidget * file_selector; - gint result; - const gchar * filename; - YuiFileEntry * yfe = user_data; - GtkFileChooserAction action; - - if (yfe->flags & YUI_FILE_ENTRY_DIRECTORY) { - action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; - } else { - action = GTK_FILE_CHOOSER_ACTION_OPEN; - } - - file_selector = gtk_file_chooser_dialog_new ("Please choose a file", NULL, action, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - filename = gtk_entry_get_text(GTK_ENTRY(yfe->entry)); - if (filename[0] != '\0') - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_selector), filename); - - gtk_widget_show(file_selector); - - result = gtk_dialog_run(GTK_DIALOG(file_selector)); - - switch(result) { - case GTK_RESPONSE_ACCEPT: - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)); - gtk_entry_set_text(GTK_ENTRY(yfe->entry), filename); - break; - case GTK_RESPONSE_CANCEL: - break; - } - - gtk_widget_destroy(file_selector); -} - -static void yui_file_entry_changed(GtkWidget * entry, YuiFileEntry * yfe) { - g_key_file_set_value(yfe->keyfile, yfe->group, yfe->key, gtk_entry_get_text(GTK_ENTRY(yfe->entry))); -} diff --git a/yabause/src/gtk/yuifileentry.h b/yabause/src/gtk/yuifileentry.h deleted file mode 100644 index f223d8851f..0000000000 --- a/yabause/src/gtk/yuifileentry.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_FILE_ENTRY_H -#define YUI_FILE_ENTRY_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_FILE_ENTRY_TYPE (yui_file_entry_get_type ()) -#define YUI_FILE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_FILE_ENTRY_TYPE, YuiFileEntry)) -#define YUI_FILE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_FILE_ENTRY_TYPE, YuiFileEntryClass)) -#define IS_YUI_FILE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_FILE_ENTRY_TYPE)) -#define IS_YUI_FILE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_FILE_ENTRY_TYPE)) - -#define YUI_FILE_ENTRY_BROWSE 1 -#define YUI_FILE_ENTRY_DIRECTORY 2 - -typedef struct _YuiFileEntry YuiFileEntry; -typedef struct _YuiFileEntryClass YuiFileEntryClass; - -struct _YuiFileEntry -{ - GtkHBox hbox; - - GtkWidget * entry; - GtkWidget * button; - - GKeyFile * keyfile; - gchar * group; - gchar * key; - - int flags; -}; - -struct _YuiFileEntryClass -{ - GtkHBoxClass parent_class; - - void (* yui_file_entry) (YuiFileEntry * yfe); -}; - -GType yui_file_entry_get_type (void); -GtkWidget* yui_file_entry_new (GKeyFile *, const gchar *, const gchar *, gint flags, const gchar * label); - -G_END_DECLS - -#endif /* YUI_FILE_ENTRY_H */ diff --git a/yabause/src/gtk/yuiinputentry.c b/yabause/src/gtk/yuiinputentry.c deleted file mode 100644 index 03a49579e4..0000000000 --- a/yabause/src/gtk/yuiinputentry.c +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include "yuiinputentry.h" -#include "settings.h" - -static void yui_input_entry_class_init (YuiInputEntryClass *klass); -static void yui_input_entry_init (YuiInputEntry *yie); -gboolean yui_input_entry_keypress(GtkWidget * widget, GdkEventKey * event, gpointer name); -gboolean yui_input_entry_focus_in(GtkWidget * widget, GdkEventFocus * event, gpointer user_data); -gboolean yui_input_entry_focus_out(GtkWidget * widget, GdkEventFocus * event, gpointer user_data); - -GType yui_input_entry_get_type (void) { - static GType yie_type = 0; - - if (!yie_type) { - static const GTypeInfo yie_info = { - sizeof (YuiInputEntryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_input_entry_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiInputEntry), - 0, - (GInstanceInitFunc) yui_input_entry_init, - NULL, - }; - - yie_type = g_type_register_static (GTK_TYPE_TABLE, "YuiInputEntry", &yie_info, 0); - } - - return yie_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 - -static void yui_input_entry_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_INPUT_ENTRY(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_INPUT_ENTRY(object)->group = g_value_get_pointer(value); - break; - } -} - -static void yui_input_entry_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -static void yui_input_entry_class_init (YuiInputEntryClass *klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_input_entry_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_input_entry_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); -} - -static void yui_input_entry_init(YuiInputEntry *yie) { - gtk_container_set_border_width(GTK_CONTAINER(yie), 0); - gtk_table_set_row_spacings(GTK_TABLE(yie), 10); - gtk_table_set_col_spacings(GTK_TABLE(yie), 10); -} - -GtkWidget* yui_input_entry_new(GKeyFile * keyfile, const gchar * group, const gchar * keys[]) { - GtkWidget * widget; - GtkWidget * label; - GtkWidget * entry; - guint keyName; - int row = 0; - - widget = GTK_WIDGET(g_object_new(yui_input_entry_get_type(), "key-file", keyfile, "group", group, NULL)); - - while(keys[row]) { - char tmp[100]; - gtk_table_resize(GTK_TABLE(widget), row + 1, 2); - label = gtk_label_new(keys[row]); - - gtk_table_attach(GTK_TABLE(widget), label, 0, 1, row , row + 1, - (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - - entry = gtk_entry_new (); - gtk_entry_set_width_chars(GTK_ENTRY(entry), 10); - - sprintf(tmp, "%s.%s.1", group, keys[row]); - keyName = g_key_file_get_integer(keyfile, PERCore->Name, tmp, 0); - if (keyName > 0) { - char buffer[50]; -#ifdef PERKEYNAME - PERCore->KeyName(keyName, buffer, 50); -#else - sprintf(buffer, "%x", keyName); -#endif - gtk_entry_set_text(GTK_ENTRY(entry), buffer); - } - - if (PERCore) { - //if (PERCore->canScan) - g_signal_connect(entry, "focus-in-event", G_CALLBACK(yui_input_entry_focus_in), (gpointer) keys[row]); - g_signal_connect(entry, "focus-out-event", G_CALLBACK(yui_input_entry_focus_out), NULL); - //else - g_signal_connect(entry, "key-press-event", G_CALLBACK(yui_input_entry_keypress), (gpointer) keys[row]); - } else { - gtk_widget_set_sensitive(entry, FALSE); - } - - gtk_table_attach(GTK_TABLE(widget), entry, 1, 2, row, row + 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); - row++; - } - - return widget; -} - -gboolean yui_input_entry_keypress(GtkWidget * widget, GdkEventKey * event, gpointer name) { - char tmp[100]; - - if (PERCore->canScan) return FALSE; - -#ifdef PERKEYNAME - PERCore->KeyName(event->keyval, tmp, 100); -#else - sprintf(tmp, "%x", event->keyval); -#endif - gtk_entry_set_text(GTK_ENTRY(widget), tmp); - sprintf(tmp, "%s.%s.1", YUI_INPUT_ENTRY(gtk_widget_get_parent(widget))->group, (char *)name); - g_key_file_set_integer(YUI_INPUT_ENTRY(gtk_widget_get_parent(widget))->keyfile, - PERCore->Name, tmp, event->keyval); - - return TRUE; -} - -gboolean is_watching = FALSE; -GtkEntry * entry_hack = NULL; - -static gboolean watch_joy(gpointer name) { - u32 i; - - if (! is_watching) return TRUE; - - if (! PERCore->canScan) { - is_watching = FALSE; - return TRUE; - } - - i = PERCore->Scan(); - - if (i == 0) { - return TRUE; - } else { - char tmp[100]; - - sprintf(tmp, "Pad.%s.1", (char *)name); // should be group.name - g_key_file_set_integer(keyfile, PERCore->Name, tmp, i); -#ifdef PERKEYNAME - PERCore->KeyName(i, tmp, 100); -#else - sprintf(tmp, "%x", (int)i); -#endif - gtk_entry_set_text(entry_hack, tmp); - is_watching = FALSE; - return FALSE; - } -} - -gboolean yui_input_entry_focus_in(GtkWidget * widget, GdkEventFocus * event, gpointer name) { - if (! PERCore->canScan) return TRUE; - - PERCore->Flush(); - entry_hack = GTK_ENTRY(widget); - - if (!is_watching) { - g_timeout_add(100, watch_joy, name); - is_watching = TRUE; - } - - return FALSE; -} - -gboolean yui_input_entry_focus_out(GtkWidget * widget, GdkEventFocus * event, gpointer name) { - is_watching = FALSE; - - return FALSE; -} - -void yui_input_entry_update(YuiInputEntry * yie) { - GList * wlist = gtk_container_get_children(GTK_CONTAINER(yie)); - u32 key; - GtkEntry * entry = NULL; - char tmp[100]; - - while(wlist) { - if (strcmp(gtk_widget_get_name(wlist->data), "GtkEntry") == 0) { - entry = wlist->data; - } - if (strcmp(gtk_widget_get_name(wlist->data), "GtkLabel") == 0) { - sprintf(tmp, "%s.%s.1", yie->group, gtk_label_get_text(wlist->data)); - key = g_key_file_get_integer(yie->keyfile, PERCore->Name, tmp, 0); - if (key > 0) { -#ifdef PERKEYNAME - PERCore->KeyName(key, tmp, 100); -#else - sprintf(tmp, "%x", (int)key); -#endif - gtk_entry_set_text(entry, tmp); - } else { - gtk_entry_set_text(entry, ""); - } - } - wlist = g_list_next(wlist); - } -} diff --git a/yabause/src/gtk/yuiinputentry.h b/yabause/src/gtk/yuiinputentry.h deleted file mode 100644 index 99d391b9f2..0000000000 --- a/yabause/src/gtk/yuiinputentry.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_INPUT_ENTRY_H -#define YUI_INPUT_ENTRY_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_INPUT_ENTRY_TYPE (yui_input_entry_get_type ()) -#define YUI_INPUT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_INPUT_ENTRY_TYPE, YuiInputEntry)) -#define YUI_INPUT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_INPUT_ENTRY_TYPE, YuiInputEntryClass)) -#define IS_YUI_INPUT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_INPUT_ENTRY_TYPE)) -#define IS_YUI_INPUT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_INPUT_ENTRY_TYPE)) - -typedef struct _YuiInputEntry YuiInputEntry; -typedef struct _YuiInputEntryClass YuiInputEntryClass; - -struct _YuiInputEntry -{ - GtkTable table; - - GKeyFile * keyfile; - gchar * group; -}; - -struct _YuiInputEntryClass { - GtkTableClass parent_class; - - void (* yui_input_entry) (YuiInputEntry *yie); -}; - -GType yui_input_entry_get_type (void); -GtkWidget* yui_input_entry_new (GKeyFile * keyfile, const gchar * group, const gchar * keys[]); -void yui_input_entry_update (YuiInputEntry *yie); - -G_END_DECLS - -#endif /* __YUI_INPUT_ENTRY_H__ */ diff --git a/yabause/src/gtk/yuim68k.c b/yabause/src/gtk/yuim68k.c deleted file mode 100644 index 1d92d1af8e..0000000000 --- a/yabause/src/gtk/yuim68k.c +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuim68k.h" -#include "../m68kd.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_m68k_class_init (YuiM68kClass * klass); -static void yui_m68k_init (YuiM68k * yfe); -static void yui_m68k_clear(YuiM68k * m68k); -static void yui_m68k_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k); -static void yui_m68k_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k); -static void yui_m68k_step( GtkWidget* widget, YuiM68k * m68k ); -static void yui_m68k_breakpoint_handler(u32 addr); - -static YuiM68k *yui_m68k; -static YuiWindow * yui; - -GType yui_m68k_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiM68kClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_m68k_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiM68k), - 0, - (GInstanceInitFunc) yui_m68k_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiM68k", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_m68k_class_init (UNUSED YuiM68kClass * klass) { -} - -static void yui_m68k_init (YuiM68k * m68k) { - gtk_window_set_title(GTK_WINDOW(m68k), "M68K"); - gtk_window_set_resizable( GTK_WINDOW(m68k), FALSE ); - - m68k->vbox = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( m68k->vbox ),4 ); - gtk_container_add (GTK_CONTAINER (m68k), m68k->vbox); - - m68k->hboxmain = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( m68k->hboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( m68k->vbox ), m68k->hboxmain, FALSE, FALSE, 4 ); - - m68k->hbox = gtk_hbutton_box_new(); - gtk_container_set_border_width( GTK_CONTAINER( m68k->hbox ),4 ); - gtk_box_pack_start( GTK_BOX( m68k->vbox ), m68k->hbox, FALSE, FALSE, 4 ); - - m68k->vboxmain = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( m68k->vboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( m68k->hboxmain ), m68k->vboxmain, FALSE, FALSE, 4 ); - - /* unassembler frame */ - - m68k->uFrame = gtk_frame_new("Disassembled code"); - gtk_box_pack_start( GTK_BOX( m68k->vboxmain ), m68k->uFrame, FALSE, FALSE, 4 ); - - m68k->uLabel = gtk_label_new(NULL); - gtk_container_add (GTK_CONTAINER (m68k->uFrame), m68k->uLabel ); - - /* Register list */ - - m68k->regListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - m68k->regList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(m68k->regListStore) ); - m68k->regListRenderer1 = gtk_cell_renderer_text_new(); - m68k->regListRenderer2 = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(m68k->regListRenderer2), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - m68k->regListColumn1 = gtk_tree_view_column_new_with_attributes("Register", m68k->regListRenderer1, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(m68k->regList), m68k->regListColumn1); - m68k->regListColumn2 = gtk_tree_view_column_new_with_attributes("Value", m68k->regListRenderer2, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(m68k->regList), m68k->regListColumn2); - gtk_box_pack_start( GTK_BOX( m68k->hboxmain ), m68k->regList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(m68k->regListRenderer2), "edited", GTK_SIGNAL_FUNC(yui_m68k_editedReg), m68k ); - - /* breakpoint list */ - - m68k->bpListStore = gtk_list_store_new(1,G_TYPE_STRING); - m68k->bpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(m68k->bpListStore) ); - m68k->bpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(m68k->bpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - m68k->bpListColumn = gtk_tree_view_column_new_with_attributes("Breakpoints", m68k->bpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(m68k->bpList), m68k->bpListColumn); - gtk_box_pack_start( GTK_BOX( m68k->hboxmain ), m68k->bpList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(m68k->bpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_m68k_editedBp), m68k ); - - g_signal_connect(G_OBJECT(m68k), "delete-event", GTK_SIGNAL_FUNC(yui_m68k_destroy), NULL); -} - - -GtkWidget * yui_m68k_new(YuiWindow * y) { - GtkWidget * dialog; - GClosure *closureF7; - GtkAccelGroup *accelGroup; - const m68kcodebreakpoint_struct *cbp; - gint i; - yui = y; - - if ( yui_m68k ) return GTK_WIDGET(yui_m68k); - - dialog = GTK_WIDGET(g_object_new(yui_m68k_get_type(), NULL)); - yui_m68k = YUI_M68K(dialog); - - if (!( yui->state & YUI_IS_INIT )) { - yui_window_run(yui); - yui_window_pause(yui); - } - - M68KSetBreakpointCallBack(&yui_m68k_breakpoint_handler); - - for (i = 0; i < 23 ; i++) { - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( yui_m68k->regListStore ), &iter ); - } - - cbp = M68KGetBreakpointList(); - - for (i = 0; i < MAX_BREAKPOINTS ; i++) { - - GtkTreeIter iter; - yui_m68k->cbp[i] = cbp[i].addr; - gtk_list_store_append( GTK_LIST_STORE( yui_m68k->bpListStore ), &iter ); - if (cbp[i].addr != 0xFFFFFFFF) { - - gchar tempstr[20]; - sprintf(tempstr, "%08X", (int)cbp[i].addr); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->bpListStore ), &iter, 0, tempstr, -1 ); - } else gtk_list_store_set( GTK_LIST_STORE( yui_m68k->bpListStore ), &iter, 0, "", -1 ); - } - - { - GtkWidget * but2, * but3, * but4; - - yui_m68k->buttonStep = gtk_button_new_with_label( "Step [F7]" ); - gtk_box_pack_start( GTK_BOX( yui_m68k->hbox ), yui_m68k->buttonStep, FALSE, FALSE, 2 ); - g_signal_connect( yui_m68k->buttonStep, "clicked", G_CALLBACK(yui_m68k_step), yui_m68k ); - - but2 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), but2); - gtk_box_pack_start(GTK_BOX(yui_m68k->hbox), but2, FALSE, FALSE, 2); - - but3 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), but3); - gtk_box_pack_start(GTK_BOX(yui_m68k->hbox), but3, FALSE, FALSE, 2); - - but4 = gtk_button_new_from_stock("gtk-close"); - g_signal_connect_swapped(but4, "clicked", G_CALLBACK(yui_m68k_destroy), dialog); - gtk_box_pack_start(GTK_BOX(yui_m68k->hbox), but4, FALSE, FALSE, 2); - } - yui_m68k->paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_m68k_update), yui_m68k); - yui_m68k->running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_m68k_clear), yui_m68k); - accelGroup = gtk_accel_group_new (); - closureF7 = g_cclosure_new (G_CALLBACK (yui_m68k_step), yui_m68k, NULL); - gtk_accel_group_connect( accelGroup, GDK_F7, 0, 0, closureF7 ); - gtk_window_add_accel_group( GTK_WINDOW( dialog ), accelGroup ); - - yui_m68k_update(yui_m68k); - if ( yui->state & YUI_IS_RUNNING ) yui_m68k_clear(yui_m68k); - - gtk_widget_show_all(GTK_WIDGET(yui_m68k)); - - return dialog; -} - -static void yui_m68k_update_reglist( YuiM68k *m68k, m68kregs_struct *regs) { - /* refresh the registery list */ - - GtkTreeIter iter; - char regstr[32]; - char valuestr[32]; - int i; - - for ( i = 0 ; i < 8 ; i++ ) { - - if ( i==0 ) gtk_tree_model_get_iter_first( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - else gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(regstr, "D%d", i ); - sprintf(valuestr, "%08x", (int)regs->D[i]); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, regstr, 1, valuestr, -1 ); - } - for ( i = 0 ; i < 8 ; i++ ) { - - gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(regstr, "A%d", i ); - sprintf(valuestr, "%08x", (int)regs->A[i]); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, regstr, 1, valuestr, -1 ); - } - - gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(valuestr, "%08x", (int)regs->SR); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, "SR", 1, valuestr, -1 ); - - gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(valuestr, "%08x", (int)regs->PC); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, "PC", 1, valuestr, -1 ); -} - -static void m68ksetRegister( YuiM68k *m68k, int nReg, u32 value ) { - /* set register number to value in proc */ - - m68kregs_struct m68kregs; - M68KGetRegisters(&m68kregs); - - if ( nReg < 8 ) m68kregs.D[nReg] = value; - else if ( nReg < 16 ) m68kregs.A[nReg-8] = value; - if ( nReg == 16 ) m68kregs.SR = value; - if ( nReg == 17 ) m68kregs.PC = value; - - M68KSetRegisters(&m68kregs); -} - -static void yui_m68k_update_codelist( YuiM68k *m68k, u32 addr) { - /* refrem68k the assembler view. points the line to be highlighted. */ - - int i; - static char tagPC[] = ""; - static char tagEnd[] = "\n"; - char buf[64*24+40]; - char *curs = buf; - char lineBuf[64]; - u8 bOnPC = 0; - u32 offset; - - if ( addr - m68k->lastCode >= 22 ) offset = addr; - else offset = m68k->lastCode; - m68k->lastCode = offset; - - for (i=0; i < 24; i++) { - - if ( offset == addr ) { bOnPC = 1; strcpy( curs, tagPC ); curs += strlen(tagPC); } - offset = M68KDisasm(offset, lineBuf); - strcpy( curs, lineBuf ); - curs += strlen(lineBuf); - if ( bOnPC ) { bOnPC = 0; strcpy( curs, tagEnd ); curs += strlen(tagEnd); } - else { strcpy( curs, "\n" ); curs += 1;} - } - *curs = 0; - gtk_label_set_markup( GTK_LABEL(m68k->uLabel), buf ); -} - -static void yui_m68k_step( GtkWidget* widget, YuiM68k * m68k ) { - - M68KStep(); - yui_window_invalidate( yui ); /* update all dialogs, including us */ -} - -static void yui_m68k_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k) { - /* registry number value has been set to */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( m68k->regListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ( endptr - arg2 == strlen(arg2) ) { - - sprintf(bptext, "%08X", (int)addr); - m68ksetRegister( m68k, i, addr ); - gtk_list_store_set( GTK_LIST_STORE( m68k->regListStore ), &iter, 1, bptext, -1 ); - } - yui_window_invalidate( yui ); -} - -static void yui_m68k_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( m68k->bpListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ((endptr - arg2 < strlen(arg2)) || (!addr)) addr = 0xFFFFFFFF; - if ( m68k->cbp[i] != 0xFFFFFFFF) M68KDelCodeBreakpoint(m68k->cbp[i]); - m68k->cbp[i] = 0xFFFFFFFF; - - if ((addr!=0xFFFFFFFF)&&(M68KAddCodeBreakpoint(addr) == 0)) { - - sprintf(bptext, "%08X", (int)addr); - m68k->cbp[i] = addr; - } else strcpy(bptext,""); - gtk_list_store_set( GTK_LIST_STORE( m68k->bpListStore ), &iter, 0, bptext, -1 ); -} - -static void debugPauseLoop(void) { /* secondary gtk event loop for the "breakpoint pause" state */ - - while ( !(yui->state & YUI_IS_RUNNING) ) - if ( gtk_main_iteration() ) return; -} - -static void yui_m68k_breakpoint_handler (u32 addr) { - - yui_window_pause(yui); - { - m68kregs_struct regs; - YuiM68k* m68k = YUI_M68K(yui_m68k_new( yui )); - - M68KGetRegisters(®s); - yui_m68k_update_codelist(m68k,regs.PC); - yui_m68k_update_reglist(m68k,®s); - } - debugPauseLoop(); /* execution is suspended inside a normal cycle - enter secondary gtk loop */ -} - - -void yui_m68k_update(YuiM68k * m68k) { - m68kregs_struct m68kregs; - M68KGetRegisters(&m68kregs); - yui_m68k_update_codelist(m68k,m68kregs.PC); - yui_m68k_update_reglist(m68k, &m68kregs); - gtk_widget_set_sensitive(m68k->uLabel, TRUE); - gtk_widget_set_sensitive(m68k->bpList, TRUE); - gtk_widget_set_sensitive(m68k->regList, TRUE); - gtk_widget_set_sensitive(m68k->buttonStep, TRUE); -} - -void yui_m68k_destroy(YuiM68k * m68k) { - g_signal_handler_disconnect(yui, m68k->running_handler); - g_signal_handler_disconnect(yui, m68k->paused_handler); - - yui_m68k = NULL; - - gtk_widget_destroy(GTK_WIDGET(m68k)); -} - -static void yui_m68k_clear(YuiM68k * m68k) { - - gtk_widget_set_sensitive(m68k->uLabel, FALSE); - gtk_widget_set_sensitive(m68k->bpList, FALSE); - gtk_widget_set_sensitive(m68k->regList, FALSE); - gtk_widget_set_sensitive(m68k->buttonStep, FALSE); -} diff --git a/yabause/src/gtk/yuim68k.h b/yabause/src/gtk/yuim68k.h deleted file mode 100644 index 6b1fae9030..0000000000 --- a/yabause/src/gtk/yuim68k.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_M68K_H -#define YUI_M68K_H - -#include -#include -#include - -#include "../scsp.h" -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_M68K_TYPE (yui_m68k_get_type ()) -#define YUI_M68K(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_M68K_TYPE, YuiM68k)) -#define YUI_M68K_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_M68K_TYPE, YuiM68kClass)) -#define IS_YUI_M68K(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_M68K_TYPE)) -#define IS_YUI_M68K_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_M68K_TYPE)) - -typedef struct _YuiM68k YuiM68k; -typedef struct _YuiM68kClass YuiM68kClass; - -struct _YuiM68k -{ - GtkWindow dialog; - - GtkWidget *vbox, *vboxmain; - GtkWidget *hbox, *hboxmain; - GtkWidget * buttonStep, * buttonStepOver; - GtkWidget * bpList, *regList, *uLabel, *uFrame; - GtkListStore *bpListStore, *regListStore; - GtkCellRenderer *bpListRenderer, *regListRenderer1, *regListRenderer2; - GtkTreeViewColumn *bpListColumn, *regListColumn1, *regListColumn2; - u32 cbp[MAX_BREAKPOINTS]; /* the list of breakpoint positions, as they can be found in the list widget */ - u32 lastCode; /* offset of last unassembly. Try to reuse it to prevent sliding. */ - gulong paused_handler; - gulong running_handler; -}; - -struct _YuiM68kClass -{ - GtkWindowClass parent_class; - - void (* yui_m68k) (YuiM68k * yv); -}; - -GType yui_m68k_get_type (void); -GtkWidget* yui_m68k_new(YuiWindow * y); -void yui_m68k_update (YuiM68k * m68k); -void yui_m68k_destroy (YuiM68k * sh); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuimem.c b/yabause/src/gtk/yuimem.c deleted file mode 100644 index 6100ca387d..0000000000 --- a/yabause/src/gtk/yuimem.c +++ /dev/null @@ -1,301 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuimem.h" -#include "settings.h" - -static void yui_mem_class_init (YuiMemClass * klass); -static void yui_mem_init (YuiMem * yfe); -static void yui_mem_clear (YuiMem * vdp1); -static void yui_mem_address_changed (GtkWidget * w, YuiMem * ym); -static void yui_mem_content_changed ( GtkCellRendererText *cellrenderertext, gchar *arg1, gchar *arg2, YuiMem *ym); -static gboolean yui_mem_pagedown_pressed (GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym); -static gboolean yui_mem_pageup_pressed (GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym); -static void yui_mem_update (YuiMem * ym); -static void yui_mem_combo_changed(GtkWidget * w, YuiMem * ym); -static void yui_mem_pagedown_clicked (GtkToolButton * button, YuiMem * ym); -static void yui_mem_pageup_clicked (GtkToolButton * button, YuiMem * ym); - -struct { gchar* name; u32 address; } quickAddress[] = - { {"VDP2_VRAM_A0", 0x25E00000 }, - {"VDP2_VRAM_A1", 0x25E20000 }, - {"VDP2_VRAM_B0", 0x25E40000 }, - {"VDP2_VRAM_B1", 0x25E60000 }, - {"VDP2_CRAM", 0x25F00000 }, - {"LWRAM", 0x20200000 }, - {"HWRAM", 0x26000000 }, - {"SpriteVRAM", 0x25C00000 }, - {0, 0 } }; - -GType yui_mem_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiMemClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_mem_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiMem), - 0, - (GInstanceInitFunc) yui_mem_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiMem", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_mem_class_init (UNUSED YuiMemClass * klass) { -} - -static void yui_mem_init (YuiMem * yv) { - GtkWidget * view; - GtkCellRenderer * renderer; - GtkTreeViewColumn * column; - GtkAccelGroup *accelGroup; - GtkToolItem * comboItem, * upbutton, * downbutton; - GtkWidget * testbox, * vbox; - gint i; - - gtk_window_set_title(GTK_WINDOW(yv), "Memory dump"); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(yv), vbox); - - yv->toolbar = gtk_toolbar_new(); - gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS); - gtk_box_pack_start(GTK_BOX(vbox), yv->toolbar, FALSE, FALSE, 0); - - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), gtk_separator_tool_item_new(), 0); - - comboItem = gtk_tool_item_new(); - gtk_tool_item_set_expand(comboItem, FALSE); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), comboItem, 1); - - downbutton = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN); - g_signal_connect(downbutton, "clicked", G_CALLBACK(yui_mem_pagedown_clicked), yv); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), downbutton, 2); - - upbutton = gtk_tool_button_new_from_stock(GTK_STOCK_GO_UP); - g_signal_connect(upbutton, "clicked", G_CALLBACK(yui_mem_pageup_clicked), yv); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), upbutton, 3); - - yv->quickCombo = gtk_combo_box_entry_new_text(); - - gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(yv->quickCombo))), 8); - - for ( i = 0 ; quickAddress[i].name ; i++ ) - gtk_combo_box_insert_text( GTK_COMBO_BOX( yv->quickCombo ), i, quickAddress[i].name ); - gtk_combo_box_set_active( GTK_COMBO_BOX(yv->quickCombo), 0 ); - g_signal_connect(yv->quickCombo, "changed", G_CALLBACK(yui_mem_combo_changed), yv ); - g_signal_connect(gtk_bin_get_child(GTK_BIN(yv->quickCombo)), "activate", G_CALLBACK(yui_mem_address_changed), yv ); - - testbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(testbox), yv->quickCombo, TRUE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(comboItem), testbox); - - yv->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); - view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store)); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Dump", renderer, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - g_object_set(G_OBJECT(renderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - g_signal_connect(G_OBJECT(renderer), "edited", GTK_SIGNAL_FUNC(yui_mem_content_changed), yv ); - gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_mem_destroy), NULL); - - accelGroup = gtk_accel_group_new (); - gtk_accel_group_connect( accelGroup, GDK_Page_Up, 0, 0, - g_cclosure_new (G_CALLBACK(yui_mem_pageup_pressed), yv, NULL) ); - gtk_accel_group_connect( accelGroup, GDK_Page_Down, 0, 0, - g_cclosure_new (G_CALLBACK(yui_mem_pagedown_pressed), yv, NULL) ); - gtk_window_add_accel_group( GTK_WINDOW( yv ), accelGroup ); - - yv->address = 0; - yv->wLine = 8; - - gtk_window_set_default_size(GTK_WINDOW(yv), 300, -1); -} - -GtkWidget * yui_mem_new(YuiWindow * y) { - GtkWidget * dialog; - YuiMem * yv; - - dialog = GTK_WIDGET(g_object_new(yui_mem_get_type(), NULL)); - yv = YUI_MEM(dialog); - - yv->yui = y; - - if (!( yv->yui->state & YUI_IS_INIT )) { - yui_window_run(yv->yui); - yui_window_pause(yv->yui); - } - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), 0); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), 1); - } - - yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_mem_update), yv); - yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_mem_clear), yv); - - if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_mem_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_mem_destroy(YuiMem * ym) { - g_signal_handler_disconnect(ym->yui, ym->running_handler); - g_signal_handler_disconnect(ym->yui, ym->paused_handler); - - gtk_widget_destroy(GTK_WIDGET(ym)); -} - -static void yui_mem_clear(YuiMem * vdp1) { -} - -static void yui_mem_address_changed(GtkWidget * w, YuiMem * ym) { - sscanf(gtk_entry_get_text(GTK_ENTRY(w)), "%x", &ym->address); - yui_mem_update(ym); -} - -static void yui_mem_combo_changed(GtkWidget * w, YuiMem * ym) { - - gint i = gtk_combo_box_get_active( GTK_COMBO_BOX(w) ); - - if (i > -1) { - ym->address = quickAddress[i].address; - yui_mem_update(ym); - } -} - -static gint hexaDigitToInt( gchar c ) { - - if (( c >= '0' )&&( c <= '9' )) return c-'0'; - if (( c >= 'a' )&&( c <= 'f' )) return c-'a' + 0xA; - if (( c >= 'A' )&&( c <= 'F' )) return c-'A' + 0xA; - return -1; -} - -static gboolean yui_mem_pageup_pressed(GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym) { - - ym->address -= 2*ym->wLine; - yui_mem_update(ym); - - return TRUE; -} - -static gboolean yui_mem_pagedown_pressed(GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym) { - - ym->address += 2*ym->wLine; - yui_mem_update(ym); - - return TRUE; -} - -static void yui_mem_pagedown_clicked (GtkToolButton * button, YuiMem * ym) { - ym->address += 2*ym->wLine; - yui_mem_update(ym); -} - -static void yui_mem_pageup_clicked (GtkToolButton * button, YuiMem * ym) { - ym->address -= 2*ym->wLine; - yui_mem_update(ym); -} - -static void yui_mem_content_changed( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiMem *ym) { - /* dump line has been modified - new content is */ - - GtkTreeIter iter; - gint i = atoi(arg1); - gint j,k; - gchar *curs; - u32 addr = ym->address + i*ym->wLine; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( ym->store ), &iter, arg1 ); - - /* check the format : wLine*2 hexa digits */ - for ( curs = arg2, j=0 ; *curs ; curs++ ) - if ( hexaDigitToInt( *curs ) != -1 ) j++; - - if ( j != ym->wLine * 2 ) return; - - /* convert */ - for ( curs = arg2, k=-1 ; *curs ; curs++ ) { - - if ( hexaDigitToInt( *curs )!=-1 ) { - - if ( k==-1 ) k = hexaDigitToInt( *curs ); - else { MappedMemoryWriteByte( addr++, 16*k + hexaDigitToInt( *curs ) ); k = -1; - } - } - } - yui_window_invalidate(ym->yui); -} - -static void yui_mem_update(YuiMem * ym) { - int i, j; - GtkTreeIter iter; - char address[10]; - char dump[30]; - - gtk_list_store_clear(ym->store); - - for(i = 0;i < 6;i++) { - sprintf(address, "%08x", ym->address + (8 * i)); - for(j = 0;j < 8;j++) { - sprintf(dump + (j * 3), "%02x ", MappedMemoryReadByte(ym->address + (8 * i) + j)); - } - - gtk_list_store_append(ym->store, &iter); - gtk_list_store_set(GTK_LIST_STORE(ym->store ), &iter, 0, address, 1, dump, -1); - } - - sprintf( address, "%08X", ym->address ); - gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN(ym->quickCombo))), address ); -} diff --git a/yabause/src/gtk/yuimem.h b/yabause/src/gtk/yuimem.h deleted file mode 100644 index c597070b43..0000000000 --- a/yabause/src/gtk/yuimem.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_MEM_H -#define YUI_MEM_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_MEM_TYPE (yui_mem_get_type ()) -#define YUI_MEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_MEM_TYPE, YuiMem)) -#define YUI_MEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_MEM_TYPE, YuiMemClass)) -#define IS_YUI_MEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_MEM_TYPE)) -#define IS_YUI_MEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_MEM_TYPE)) - -typedef struct _YuiMem YuiMem; -typedef struct _YuiMemClass YuiMemClass; - -struct _YuiMem -{ - GtkWindow dialog; - - GtkWidget * toolbar; - - GtkListStore * store; - GtkWidget * quickCombo; - - guint wLine; - guint32 address; - gulong paused_handler; - gulong running_handler; - - YuiWindow * yui; -}; - -struct _YuiMemClass -{ - GtkWindowClass parent_class; - - void (* yui_mem) (YuiMem * yv); -}; - -GType yui_mem_get_type(void); -GtkWidget * yui_mem_new (YuiWindow * yui); -void yui_mem_fill (YuiMem * vdp1); -void yui_mem_destroy (YuiMem * vdp1); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuipage.c b/yabause/src/gtk/yuipage.c deleted file mode 100644 index 2259ed956c..0000000000 --- a/yabause/src/gtk/yuipage.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuifileentry.h" -#include "yuirange.h" -#include "yuiresolution.h" -#include "yuipage.h" -#include "../core.h" - -static void yui_page_class_init (YuiPageClass * klass); -static void yui_page_init (YuiPage * yfe); - -GType yui_page_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiPageClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_page_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiPage), - 0, - (GInstanceInitFunc) yui_page_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_VBOX, "YuiPage", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_page_class_init (UNUSED YuiPageClass * klass) { -} - -static void yui_page_init (UNUSED YuiPage * yp) { -} - -GtkWidget * yui_page_new(GKeyFile * keyfile) { - GtkWidget * widget; - YuiPage * yp; - - widget = GTK_WIDGET(g_object_new(yui_page_get_type(), NULL)); - yp = YUI_PAGE(widget); - - yp->keyfile = keyfile; - - return widget; -} - -GtkWidget * yui_page_add(YuiPage * yp, const gchar * name) { - GtkWidget * label; - GtkWidget * frame; - GtkWidget * box; - gchar buffer[1024]; - - frame = gtk_frame_new(NULL); - - gtk_box_pack_start(GTK_BOX(yp), frame, FALSE, TRUE, 0); - gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); - - box = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), box); - - sprintf(buffer, "%s", name); - - label = gtk_label_new(buffer); - gtk_frame_set_label_widget(GTK_FRAME(frame), label); - gtk_label_set_use_markup(GTK_LABEL(label), TRUE); - - return box; -} diff --git a/yabause/src/gtk/yuipage.h b/yabause/src/gtk/yuipage.h deleted file mode 100644 index 8bd767e7d6..0000000000 --- a/yabause/src/gtk/yuipage.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_PAGE_H -#define YUI_PAGE_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_PAGE_TYPE (yui_page_get_type ()) -#define YUI_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_PAGE_TYPE, YuiPage)) -#define YUI_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_PAGE_TYPE, YuiPageClass)) -#define IS_YUI_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_PAGE_TYPE)) -#define IS_YUI_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_PAGE_TYPE)) - -#define YUI_FILE_SETTING 1 -#define YUI_RANGE_SETTING 2 -#define YUI_RESOLUTION_SETTING 3 - -typedef struct _YuiPage YuiPage; -typedef struct _YuiPageClass YuiPageClass; - -struct _YuiPage -{ - GtkVBox vbox; - - GKeyFile * keyfile; -}; - -struct _YuiPageClass -{ - GtkHBoxClass parent_class; - - void (* yui_page) (YuiPage * yfe); -}; - -GType yui_page_get_type (void); -GtkWidget * yui_page_new (GKeyFile * keyfile); - -GtkWidget * yui_page_add (YuiPage * yp, const gchar * name); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuirange.c b/yabause/src/gtk/yuirange.c deleted file mode 100644 index dc8efeba7d..0000000000 --- a/yabause/src/gtk/yuirange.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuirange.h" - -static void yui_range_class_init (YuiRangeClass * klass); -static void yui_range_init (YuiRange * yfe); -static void yui_range_changed (GtkWidget * widget, YuiRange * yfe); - -GType yui_range_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiRangeClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_range_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiRange), - 0, - (GInstanceInitFunc) yui_range_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_HBOX, "YuiRange", &yfe_info, 0); - } - - return yfe_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 -#define PROP_KEY 3 -#define PROP_ITEMS 4 - -static void yui_range_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_RANGE(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_RANGE(object)->group = g_value_get_pointer(value); - break; - case PROP_KEY: - YUI_RANGE(object)->key = g_value_get_pointer(value); - break; - case PROP_ITEMS: - YUI_RANGE(object)->items = g_value_get_pointer(value); - break; - } -} - -static void yui_range_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -enum { YUI_RANGE_CHANGED_SIGNAL, LAST_SIGNAL }; - -static guint yui_range_signals[LAST_SIGNAL] = { 0 }; - -static void yui_range_class_init (YuiRangeClass * klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_range_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_range_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); - - param = g_param_spec_pointer("key", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY, param); - - param = g_param_spec_pointer("items", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ITEMS, param); - - yui_range_signals[YUI_RANGE_CHANGED_SIGNAL] = g_signal_new ("changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiRangeClass, yui_range_change), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -static void yui_range_init (YuiRange * yfe) { - gtk_container_set_border_width(GTK_CONTAINER(yfe), 10); - - yfe->combo = gtk_combo_box_new_text(); - - gtk_box_pack_start(GTK_BOX(yfe), yfe->combo, TRUE, TRUE, 0); -} - -GtkWidget * yui_range_new(GKeyFile * keyfile, const gchar * group, const gchar * key, YuiRangeItem * items) { - GtkWidget * entry; - YuiRange * yfe; - gchar * current; - guint i; - - entry = GTK_WIDGET(g_object_new(yui_range_get_type(), "spacing", 10, - "key-file", keyfile, "group", group, "key", key, "items", items, NULL)); - yfe = YUI_RANGE(entry); - - current = g_key_file_get_value(yfe->keyfile, yfe->group, yfe->key, 0); - i = 0; - while(yfe->items[i].name) { - gtk_combo_box_append_text(GTK_COMBO_BOX(yfe->combo), yfe->items[i].name); - if (current && !strcmp(yfe->items[i].value, current)) - gtk_combo_box_set_active(GTK_COMBO_BOX(yfe->combo), i); - i++; - } - if ( !current ) { - gtk_combo_box_set_active(GTK_COMBO_BOX(yfe->combo), 0); - g_key_file_set_value(yfe->keyfile, yfe->group, yfe->key, items[0].value); - } - - g_signal_connect(GTK_COMBO_BOX(yfe->combo), "changed", G_CALLBACK(yui_range_changed), yfe); - - return entry; -} - -static void yui_range_changed(GtkWidget * entry, YuiRange * yfe) { - g_key_file_set_value(yfe->keyfile, yfe->group, yfe->key, - yfe->items[gtk_combo_box_get_active(GTK_COMBO_BOX(yfe->combo))].value); - g_signal_emit(G_OBJECT(yfe), yui_range_signals[YUI_RANGE_CHANGED_SIGNAL], 0); -} - -gint yui_range_get_active(YuiRange * range) { - return gtk_combo_box_get_active(GTK_COMBO_BOX(range->combo)); -} diff --git a/yabause/src/gtk/yuirange.h b/yabause/src/gtk/yuirange.h deleted file mode 100644 index f973c87e4b..0000000000 --- a/yabause/src/gtk/yuirange.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_RANGE_H -#define YUI_RANGE_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_RANGE_TYPE (yui_range_get_type ()) -#define YUI_RANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_RANGE_TYPE, YuiRange)) -#define YUI_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_RANGE_TYPE, YuiRangeClass)) -#define IS_YUI_RANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_RANGE_TYPE)) -#define IS_YUI_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_RANGE_TYPE)) - -typedef struct _YuiRangeItem YuiRangeItem; -typedef struct _YuiRange YuiRange; -typedef struct _YuiRangeClass YuiRangeClass; - -struct _YuiRangeItem -{ - const gchar * value; - const gchar * name; -}; - -struct _YuiRange -{ - GtkHBox hbox; - - GtkWidget * combo; - - GKeyFile * keyfile; - gchar * group; - gchar * key; - - YuiRangeItem * items; -}; - -struct _YuiRangeClass -{ - GtkHBoxClass parent_class; - - void (* yui_range_change) (YuiRange * yfe); -}; - -GType yui_range_get_type (void); -GtkWidget * yui_range_new (GKeyFile * keyfile, const gchar * group, const gchar * key, YuiRangeItem * items); -gint yui_range_get_active (YuiRange * range); - -G_END_DECLS - -#endif /* YUI_RANGE_H */ diff --git a/yabause/src/gtk/yuiresolution.c b/yabause/src/gtk/yuiresolution.c deleted file mode 100644 index 41a7afa6c5..0000000000 --- a/yabause/src/gtk/yuiresolution.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "yuiresolution.h" - -static void yui_resolution_class_init (YuiResolutionClass *klass); -static void yui_resolution_init (YuiResolution *yie); -static void yui_resolution_width_changed (GtkWidget * w, YuiResolution * yr); -static void yui_resolution_height_changed (GtkWidget * w, YuiResolution * yr); -static void yui_resolution_options_changed (GtkWidget * w, YuiResolution * yr); - -GType yui_resolution_get_type (void) { - static GType yie_type = 0; - - if (!yie_type) { - static const GTypeInfo yie_info = { - sizeof (YuiResolutionClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_resolution_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiResolution), - 0, - (GInstanceInitFunc) yui_resolution_init, - NULL, - }; - - yie_type = g_type_register_static (GTK_TYPE_HBOX, "YuiResolution", &yie_info, 0); - } - - return yie_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 - -static void yui_resolution_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_RESOLUTION(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_RESOLUTION(object)->group = g_value_get_pointer(value); - break; - } -} - -static void yui_resolution_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -static void yui_resolution_class_init (YuiResolutionClass *klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_resolution_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_resolution_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); -} - -static void yui_resolution_init(YuiResolution * yr) { - GtkWidget * label_w; - GtkWidget * label_h; - - gtk_container_set_border_width (GTK_CONTAINER (yr), 10); - - label_w = gtk_label_new ("Width"); - gtk_box_pack_start(GTK_BOX(yr), label_w, TRUE, TRUE, 0); - - yr->entry_w = gtk_entry_new (); - gtk_entry_set_width_chars(GTK_ENTRY(yr->entry_w), 8); - gtk_box_pack_start(GTK_BOX(yr), yr->entry_w, TRUE, TRUE, 0); - - label_h = gtk_label_new ("Height"); - gtk_box_pack_start(GTK_BOX(yr), label_h, TRUE, TRUE, 0); - - yr->entry_h = gtk_entry_new (); - gtk_entry_set_width_chars(GTK_ENTRY(yr->entry_h), 8); - gtk_box_pack_start(GTK_BOX(yr), yr->entry_h, TRUE, TRUE, 0); - - yr->options = gtk_combo_box_new_text(); - gtk_combo_box_append_text(GTK_COMBO_BOX(yr->options), "Window"); - gtk_combo_box_append_text(GTK_COMBO_BOX(yr->options), "Fullscreen"); - gtk_combo_box_append_text(GTK_COMBO_BOX(yr->options), "Keep ratio"); - gtk_box_pack_start(GTK_BOX(yr), yr->options, TRUE, TRUE, 0); - - g_signal_connect(yr->entry_w, "changed", G_CALLBACK(yui_resolution_width_changed), yr); - g_signal_connect(yr->entry_h, "changed", G_CALLBACK(yui_resolution_height_changed), yr); - g_signal_connect(yr->options, "changed", G_CALLBACK(yui_resolution_options_changed), yr); -} - -GtkWidget* yui_resolution_new(GKeyFile * keyfile, const gchar * group) { - GtkWidget * widget; - YuiResolution * yr; - gchar *widthText, *heightText; - - widget = GTK_WIDGET(g_object_new(yui_resolution_get_type(), "key-file", keyfile, "group", group, NULL)); - yr = YUI_RESOLUTION(widget); - - widthText = g_key_file_get_value(yr->keyfile, yr->group, "Width", 0); - if ( !widthText ) widthText = ""; - heightText = g_key_file_get_value(yr->keyfile, yr->group, "Height", 0); - if ( !heightText ) heightText = ""; - gtk_entry_set_text(GTK_ENTRY(yr->entry_w), widthText ); - gtk_entry_set_text(GTK_ENTRY(yr->entry_h), heightText ); - if (g_key_file_get_integer(yr->keyfile, yr->group, "Fullscreen", 0) == 1) - gtk_combo_box_set_active(GTK_COMBO_BOX(yr->options), 1); - else if (g_key_file_get_integer(yr->keyfile, yr->group, "KeepRatio", 0) == 1) - gtk_combo_box_set_active(GTK_COMBO_BOX(yr->options), 2); - else - gtk_combo_box_set_active(GTK_COMBO_BOX(yr->options), 0); - - return widget; -} - -static void yui_resolution_width_changed(GtkWidget * w, YuiResolution * yr) { - g_key_file_set_value(yr->keyfile, yr->group, "Width", gtk_entry_get_text(GTK_ENTRY(w))); -} - -static void yui_resolution_height_changed(GtkWidget * w, YuiResolution * yr) { - g_key_file_set_value(yr->keyfile, yr->group, "Height", gtk_entry_get_text(GTK_ENTRY(w))); -} - -static void yui_resolution_options_changed(GtkWidget * w, YuiResolution * yr) { - gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(yr->options)); - switch(active) { - case 0: - g_key_file_set_integer(yr->keyfile, yr->group, "Fullscreen", 0); - g_key_file_set_integer(yr->keyfile, yr->group, "KeepRatio", 0); - break; - case 1: - g_key_file_set_integer(yr->keyfile, yr->group, "Fullscreen", 1); - g_key_file_set_integer(yr->keyfile, yr->group, "KeepRatio", 0); - break; - case 2: - g_key_file_set_integer(yr->keyfile, yr->group, "Fullscreen", 0); - g_key_file_set_integer(yr->keyfile, yr->group, "KeepRatio", 1); - break; - } -} diff --git a/yabause/src/gtk/yuiresolution.h b/yabause/src/gtk/yuiresolution.h deleted file mode 100644 index ae9088e3e8..0000000000 --- a/yabause/src/gtk/yuiresolution.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_RESOLUTION_H -#define YUI_RESOLUTION_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_RESOLUTION_TYPE (yui_resolution_get_type ()) -#define YUI_RESOLUTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_RESOLUTION_TYPE, YuiResolution)) -#define YUI_RESOLUTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_RESOLUTION_TYPE, YuiResolutionClass)) -#define IS_YUI_RESOLUTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_RESOLUTION_TYPE)) -#define IS_YUI_RESOLUTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_RESOLUTION_TYPE)) - - -typedef struct _YuiResolution YuiResolution; -typedef struct _YuiResolutionClass YuiResolutionClass; - -struct _YuiResolution -{ - GtkHBox table; - - GtkWidget * entry_w; - GtkWidget * entry_h; - GtkWidget * options; - - GKeyFile * keyfile; - gchar * group; -}; - -struct _YuiResolutionClass { - GtkHBoxClass parent_class; - - void (* yui_resolution) (YuiResolution *yie); -}; - -GType yui_resolution_get_type (void); -GtkWidget* yui_resolution_new (GKeyFile * keyfile, const gchar * group); - -G_END_DECLS - -#endif /* YUI_RESOLUTION_H */ diff --git a/yabause/src/gtk/yuiscreenshot.c b/yabause/src/gtk/yuiscreenshot.c deleted file mode 100644 index 5f53f1ea24..0000000000 --- a/yabause/src/gtk/yuiscreenshot.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright 2006-2007 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yuiscreenshot.h" -#include "gtkglwidget.h" -#include "yuiviewer.h" -#include "../core.h" - -static void yui_screenshot_class_init (YuiScreenshotClass * klass); -static void yui_screenshot_init (YuiScreenshot * yfe); -static void yui_screenshot_update (YuiScreenshot * ys, gpointer data); -static gboolean yui_screenshot_draw(YuiScreenshot * ys); - -GType yui_screenshot_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiScreenshotClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_screenshot_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiScreenshot), - 0, - (GInstanceInitFunc) yui_screenshot_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiScreenshot", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_screenshot_class_init (UNUSED YuiScreenshotClass * klass) { -} - -static YuiWindow * yui; - -static void yui_screenshot_init (YuiScreenshot * yv) { - GtkWidget * box; - GtkWidget * button_box; - GtkWidget * button; - - gtk_window_set_title(GTK_WINDOW(yv), "Screenshot"); - gtk_container_set_border_width(GTK_CONTAINER(yv), 4); - - box = gtk_vbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(yv), box); - - yv->image = yui_viewer_new(); - gtk_box_pack_start(GTK_BOX(box), yv->image, FALSE, FALSE, 0); - gtk_widget_set_size_request(GTK_WIDGET(yv->image), 320, 224); - - button_box = gtk_hbutton_box_new(); - gtk_box_pack_start(GTK_BOX(box), button_box, FALSE, FALSE, 0); - - button = gtk_button_new_from_stock(GTK_STOCK_REFRESH); - gtk_box_pack_start(GTK_BOX(button_box), button, FALSE, FALSE, 0); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(yui_screenshot_update), yv); - - button = gtk_button_new_from_stock(GTK_STOCK_SAVE); - gtk_box_pack_start(GTK_BOX(button_box), button, FALSE, FALSE, 0); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(yui_viewer_save), yv->image); - - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(button_box), button, FALSE, FALSE, 0); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_widget_destroy), yv); -} - -GtkWidget * yui_screenshot_new(YuiWindow * y) { - GtkWidget * dialog; - YuiScreenshot * yv; - - yui = y; - - dialog = GTK_WIDGET(g_object_new(yui_screenshot_get_type(), NULL)); - yv = YUI_SCREENSHOT(dialog); - - gtk_widget_show_all(dialog); - - yui_gl_dump_screen(YUI_GL(yui->area)); - yui_screenshot_draw(yv); - - return dialog; -} - -static void yui_screenshot_update(YuiScreenshot * ys, UNUSED gpointer data) { - yui_gl_dump_screen(YUI_GL(yui->area)); - yui_screenshot_draw(ys); -} - -static gboolean yui_screenshot_draw(YuiScreenshot * ys) { - GdkPixbuf * pixbuf, * correct; - - pixbuf = gdk_pixbuf_new_from_data((const guchar *) YUI_GL(yui->area)->pixels, GDK_COLORSPACE_RGB, FALSE, 8, - YUI_GL(yui->area)->pixels_width, YUI_GL(yui->area)->pixels_height, YUI_GL(yui->area)->pixels_rowstride, NULL, NULL); - correct = gdk_pixbuf_flip(pixbuf, FALSE); - - yui_viewer_draw_pixbuf(YUI_VIEWER(ys->image), correct, YUI_GL(yui->area)->pixels_width, YUI_GL(yui->area)->pixels_height); - - g_object_unref(pixbuf); - g_object_unref(correct); - - return TRUE; -} diff --git a/yabause/src/gtk/yuiscreenshot.h b/yabause/src/gtk/yuiscreenshot.h deleted file mode 100644 index 8a820f727d..0000000000 --- a/yabause/src/gtk/yuiscreenshot.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SCREENSHOT_H -#define YUI_SCREENSHOT_H - -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SCREENSHOT_TYPE (yui_screenshot_get_type ()) -#define YUI_SCREENSHOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SCREENSHOT_TYPE, YuiScreenshot)) -#define YUI_SCREENSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SCREENSHOT_TYPE, YuiScreenshotClass)) -#define IS_YUI_SCREENSHOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SCREENSHOT_TYPE)) -#define IS_YUI_SCREENSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SCREENSHOT_TYPE)) - -typedef struct _YuiScreenshot YuiScreenshot; -typedef struct _YuiScreenshotClass YuiScreenshotClass; - -struct _YuiScreenshot -{ - GtkWindow dialog; - - GtkWidget * image; -}; - -struct _YuiScreenshotClass -{ - GtkWindowClass parent_class; -}; - -GType yui_screenshot_get_type (void); -GtkWidget * yui_screenshot_new (YuiWindow * yui); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiscsp.c b/yabause/src/gtk/yuiscsp.c deleted file mode 100644 index fd74c9f30a..0000000000 --- a/yabause/src/gtk/yuiscsp.c +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuiscsp.h" -#include "../scsp.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_scsp_class_init (YuiScspClass * klass); -static void yui_scsp_init (YuiScsp * yfe); -static void yui_scsp_spin_cursor_changed(GtkWidget * spin, YuiScsp * scsp); -static void yui_scsp_clear(YuiScsp * scsp); - -GType yui_scsp_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiScspClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_scsp_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiScsp), - 0, - (GInstanceInitFunc) yui_scsp_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiScsp", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_scsp_class_init (UNUSED YuiScspClass * klass) { -} - -static void yui_scsp_init (YuiScsp * yv) { - gtk_window_set_title(GTK_WINDOW(yv), "SCSP"); - - yv->vbox = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(yv->vbox), 4); - gtk_container_add(GTK_CONTAINER(yv), yv->vbox); - - yv->spin = gtk_spin_button_new_with_range(0, 31, 1); - gtk_spin_button_set_range(GTK_SPIN_BUTTON(yv->spin), 0, 31); - gtk_box_pack_start(GTK_BOX(yv->vbox), yv->spin, FALSE, FALSE, 4); - g_signal_connect(G_OBJECT(yv->spin), "value-changed", GTK_SIGNAL_FUNC(yui_scsp_spin_cursor_changed), yv); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_scsp_destroy), NULL); - - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - GtkWidget * text = gtk_text_view_new(); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); - yv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)); - gtk_container_add(GTK_CONTAINER(scroll), text); - gtk_box_pack_start(GTK_BOX(yv->vbox), scroll, TRUE, TRUE, 4); - } - - yv->hbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(yv->hbox), 4); - gtk_box_pack_start(GTK_BOX(yv->vbox ), yv->hbox, FALSE, FALSE, 4); - - yv->cursor = 0; -} - -static gulong paused_handler; -static gulong running_handler; -static YuiWindow * yui; - -GtkWidget * yui_scsp_new(YuiWindow * y) { - GtkWidget * dialog; - YuiScsp * yv; - - yui = y; - - dialog = GTK_WIDGET(g_object_new(yui_scsp_get_type(), NULL)); - yv = YUI_SCSP(dialog); - - { - GtkWidget * but2, * but3, * but4; - but2 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), but2); - gtk_box_pack_start(GTK_BOX(yv->hbox), but2, FALSE, FALSE, 2); - - but3 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), but3); - gtk_box_pack_start(GTK_BOX(yv->hbox), but3, FALSE, FALSE, 2); - - but4 = gtk_button_new_from_stock("gtk-close"); - g_signal_connect_swapped(but4, "clicked", G_CALLBACK(yui_scsp_destroy), dialog); - gtk_box_pack_start(GTK_BOX(yv->hbox), but4, FALSE, FALSE, 2); - } - paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_scsp_update), yv); - running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_scsp_clear), yv); - - if ((yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_scsp_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_scsp_fill(YuiScsp * scsp) { - gchar nameTemp[1024]; - - yui_scsp_clear(scsp); - - ScspSlotDebugStats(scsp->cursor, nameTemp ); - - gtk_text_buffer_set_text(scsp->buffer, g_strstrip(nameTemp), -1); -} - -static void yui_scsp_spin_cursor_changed(GtkWidget * spin, YuiScsp * scsp) { - scsp->cursor = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin)); - yui_scsp_fill(scsp); -} - -void yui_scsp_update(YuiScsp * scsp) { - yui_scsp_fill(scsp); -} - -void yui_scsp_destroy(YuiScsp * scsp) { - g_signal_handler_disconnect(yui, running_handler); - g_signal_handler_disconnect(yui, paused_handler); - - gtk_widget_destroy(GTK_WIDGET(scsp)); -} - -static void yui_scsp_clear(YuiScsp * scsp) { - gtk_text_buffer_set_text(scsp->buffer, "", -1); -} diff --git a/yabause/src/gtk/yuiscsp.h b/yabause/src/gtk/yuiscsp.h deleted file mode 100644 index 1c2cb82f54..0000000000 --- a/yabause/src/gtk/yuiscsp.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SCSP_H -#define YUI_SCSP_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SCSP_TYPE (yui_scsp_get_type ()) -#define YUI_SCSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SCSP_TYPE, YuiScsp)) -#define YUI_SCSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SCSP_TYPE, YuiScspClass)) -#define IS_YUI_SCSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SCSP_TYPE)) -#define IS_YUI_SCSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SCSP_TYPE)) - -typedef struct _YuiScsp YuiScsp; -typedef struct _YuiScspClass YuiScspClass; - -struct _YuiScsp -{ - GtkWindow dialog; - - GtkWidget * vbox; - GtkWidget * hbox; - GtkWidget * commName; - GtkWidget * commDesc; - GtkWidget * spin; - - GtkTextBuffer * buffer; - - gint cursor; -}; - -struct _YuiScspClass -{ - GtkWindowClass parent_class; - - void (* yui_scsp) (YuiScsp * yv); -}; - -GType yui_scsp_get_type (void); -GtkWidget * yui_scsp_new (YuiWindow * yui); -void yui_scsp_fill (YuiScsp * scsp); -void yui_scsp_update (YuiScsp * scsp); -void yui_scsp_destroy (YuiScsp * scsp); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiscudsp.c b/yabause/src/gtk/yuiscudsp.c deleted file mode 100644 index 3a8f311a50..0000000000 --- a/yabause/src/gtk/yuiscudsp.c +++ /dev/null @@ -1,425 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuiscudsp.h" -#include "../scu.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_scudsp_class_init (YuiScudspClass * klass); -static void yui_scudsp_init (YuiScudsp * yfe); -static void yui_scudsp_clear(YuiScudsp * scudsp); -static void yui_scudsp_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp); -static void yui_scudsp_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp); -static void yui_scudsp_step( GtkWidget* widget, YuiScudsp * scudsp ); -static void yui_scudsp_breakpoint_handler (u32 addr); - -static YuiScudsp *yui_scudsp; -static YuiWindow * yui; - -GType yui_scudsp_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiScudspClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_scudsp_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiScudsp), - 0, - (GInstanceInitFunc) yui_scudsp_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiScudsp", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_scudsp_class_init (UNUSED YuiScudspClass * klass) { -} - -static void yui_scudsp_init (YuiScudsp * scudsp) { - gtk_window_set_title(GTK_WINDOW(scudsp), "SCU-DSP"); - gtk_window_set_resizable( GTK_WINDOW(scudsp), FALSE ); - - scudsp->vbox = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->vbox ),4 ); - gtk_container_add (GTK_CONTAINER (scudsp), scudsp->vbox); - - scudsp->hboxmain = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->hboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( scudsp->vbox ), scudsp->hboxmain, FALSE, FALSE, 4 ); - - scudsp->hbox = gtk_hbutton_box_new(); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->hbox ),4 ); - gtk_box_pack_start( GTK_BOX( scudsp->vbox ), scudsp->hbox, FALSE, FALSE, 4 ); - - scudsp->vboxmain = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->vboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( scudsp->hboxmain ), scudsp->vboxmain, FALSE, FALSE, 4 ); - - /* unassembler frame */ - - scudsp->uFrame = gtk_frame_new("Disassembled code"); - gtk_box_pack_start( GTK_BOX( scudsp->vboxmain ), scudsp->uFrame, FALSE, FALSE, 4 ); - - scudsp->uLabel = gtk_label_new(NULL); - gtk_container_add (GTK_CONTAINER (scudsp->uFrame), scudsp->uLabel ); - - /* Register list */ - - scudsp->regListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - scudsp->regList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(scudsp->regListStore) ); - scudsp->regListRenderer1 = gtk_cell_renderer_text_new(); - scudsp->regListRenderer2 = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(scudsp->regListRenderer2), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - scudsp->regListColumn1 = gtk_tree_view_column_new_with_attributes("Register", scudsp->regListRenderer1, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(scudsp->regList), scudsp->regListColumn1); - scudsp->regListColumn2 = gtk_tree_view_column_new_with_attributes("Value", scudsp->regListRenderer2, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(scudsp->regList), scudsp->regListColumn2); - gtk_box_pack_start( GTK_BOX( scudsp->hboxmain ), scudsp->regList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(scudsp->regListRenderer2), "edited", GTK_SIGNAL_FUNC(yui_scudsp_editedReg), scudsp ); - - /* breakpoint list */ - - scudsp->bpListStore = gtk_list_store_new(1,G_TYPE_STRING); - scudsp->bpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(scudsp->bpListStore) ); - scudsp->bpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(scudsp->bpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - scudsp->bpListColumn = gtk_tree_view_column_new_with_attributes("Breakpoints", scudsp->bpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(scudsp->bpList), scudsp->bpListColumn); - gtk_box_pack_start( GTK_BOX( scudsp->hboxmain ), scudsp->bpList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(scudsp->bpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_scudsp_editedBp), scudsp ); - - g_signal_connect(G_OBJECT(scudsp), "delete-event", GTK_SIGNAL_FUNC(yui_scudsp_destroy), NULL); -} - - -GtkWidget * yui_scudsp_new(YuiWindow * y) { - GtkWidget * dialog; - GClosure *closureF7; - GtkAccelGroup *accelGroup; - const scucodebreakpoint_struct *cbp; - gint i; - yui = y; - - if ( yui_scudsp ) return GTK_WIDGET(yui_scudsp); - - dialog = GTK_WIDGET(g_object_new(yui_scudsp_get_type(), NULL)); - yui_scudsp = YUI_SCUDSP(dialog); - - if (!( yui->state & YUI_IS_INIT )) { - yui_window_run(yui); - yui_window_pause(yui); - } - - ScuDspSetBreakpointCallBack(&yui_scudsp_breakpoint_handler); - - for (i = 0; i < 23 ; i++) { - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( yui_scudsp->regListStore ), &iter ); - } - - cbp = ScuDspGetBreakpointList(); - - for (i = 0; i < MAX_BREAKPOINTS; i++) { - - GtkTreeIter iter; - yui_scudsp->cbp[i] = cbp[i].addr; - gtk_list_store_append( GTK_LIST_STORE( yui_scudsp->bpListStore ), &iter ); - if (cbp[i].addr != 0xFFFFFFFF) { - - gchar tempstr[20]; - sprintf(tempstr, "%08X", (int)cbp[i].addr); - gtk_list_store_set( GTK_LIST_STORE( yui_scudsp->bpListStore ), &iter, 0, tempstr, -1 ); - } else gtk_list_store_set( GTK_LIST_STORE( yui_scudsp->bpListStore ), &iter, 0, "", -1 ); - } - - { - GtkWidget * but2, * but3, * but4; - - yui_scudsp->buttonStep = gtk_button_new_with_label( "Step [F7]" ); - gtk_box_pack_start( GTK_BOX( yui_scudsp->hbox ), yui_scudsp->buttonStep, FALSE, FALSE, 2 ); - g_signal_connect( yui_scudsp->buttonStep, "clicked", G_CALLBACK(yui_scudsp_step), yui_scudsp ); - - but2 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), but2); - gtk_box_pack_start(GTK_BOX(yui_scudsp->hbox), but2, FALSE, FALSE, 2); - - but3 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), but3); - gtk_box_pack_start(GTK_BOX(yui_scudsp->hbox), but3, FALSE, FALSE, 2); - - but4 = gtk_button_new_from_stock("gtk-close"); - g_signal_connect_swapped(but4, "clicked", G_CALLBACK(yui_scudsp_destroy), dialog); - gtk_box_pack_start(GTK_BOX(yui_scudsp->hbox), but4, FALSE, FALSE, 2); - } - yui_scudsp->paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_scudsp_update), yui_scudsp); - yui_scudsp->running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_scudsp_clear), yui_scudsp); - accelGroup = gtk_accel_group_new (); - closureF7 = g_cclosure_new (G_CALLBACK (yui_scudsp_step), yui_scudsp, NULL); - gtk_accel_group_connect( accelGroup, GDK_F7, 0, 0, closureF7 ); - gtk_window_add_accel_group( GTK_WINDOW( dialog ), accelGroup ); - - yui_scudsp_update(yui_scudsp); - if ( yui->state & YUI_IS_RUNNING ) yui_scudsp_clear(yui_scudsp); - - gtk_widget_show_all(GTK_WIDGET(yui_scudsp)); - - return dialog; -} - - -static void yui_scudsp_update_reglist( YuiScudsp *scudsp, scudspregs_struct *regs) { - /* refrescudsp the registery list */ - - GtkTreeIter iter; - char valuestr[32]; - - gtk_tree_model_get_iter_first( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); - sprintf(valuestr, "%d", regs->ProgControlPort.part.PR); - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, "PR", 1, valuestr, -1 ); - - #define SCUDSPUPDATEREGLISTp(rreg,format) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); \ - sprintf(valuestr, #format, (int)regs->ProgControlPort.part.rreg); \ - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - #define SCUDSPUPDATEREGLIST(rreg,format) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); \ - sprintf(valuestr, #format, (int)regs->rreg); \ - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - #define SCUDSPUPDATEREGLISTx(rreg,vreg,format) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); \ - sprintf(valuestr, #format, (int)(vreg)); \ - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - - SCUDSPUPDATEREGLISTp(EP,%d); - SCUDSPUPDATEREGLISTp(T0,%d); - SCUDSPUPDATEREGLISTp(S,%d); - SCUDSPUPDATEREGLISTp(Z,%d); - SCUDSPUPDATEREGLISTp(C,%d); - SCUDSPUPDATEREGLISTp(V,%d); - SCUDSPUPDATEREGLISTp(E,%d); - SCUDSPUPDATEREGLISTp(ES,%d); - SCUDSPUPDATEREGLISTp(EX,%d); - SCUDSPUPDATEREGLISTp(LE,%d); - SCUDSPUPDATEREGLISTp(P,%02X); - SCUDSPUPDATEREGLIST(TOP,%02X); - SCUDSPUPDATEREGLIST(LOP,%02X); - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); - sprintf(valuestr, "%08X", (int)(((u32)(regs->CT[0]))<<24 | ((u32)(regs->CT[1]))<<16 | ((u32)(regs->CT[2]))<<8 | ((u32)(regs->CT[3]))) ); - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, "CT", 1, valuestr, -1 ); - SCUDSPUPDATEREGLISTx(RA,regs->RA0,%08X); - SCUDSPUPDATEREGLISTx(WA,regs->WA0,%08X); - SCUDSPUPDATEREGLIST(RX,%08X); - SCUDSPUPDATEREGLIST(RY,%08X); - SCUDSPUPDATEREGLISTx(PH,regs->P.part.H & 0xFFFF,%04X); - SCUDSPUPDATEREGLISTx(PL,regs->P.part.L & 0xFFFFFFFF,%08X); - SCUDSPUPDATEREGLISTx(ACH,regs->AC.part.H & 0xFFFF,%04X); - SCUDSPUPDATEREGLISTx(ACL,regs->AC.part.L & 0xFFFFFFFF,%08X); -} - -static void scudspsetRegister( YuiScudsp *scudsp, int nReg, u32 value ) { - /* set register number to value in proc */ - - scudspregs_struct scudspregs; - ScuDspGetRegisters(&scudspregs); - - switch ( nReg ) { - case 0: scudspregs.ProgControlPort.part.PR = value; break; - case 1: scudspregs.ProgControlPort.part.EP = value; break; - case 2: scudspregs.ProgControlPort.part.T0 = value; break; - case 3: scudspregs.ProgControlPort.part.S = value; break; - case 4: scudspregs.ProgControlPort.part.Z = value; break; - case 5: scudspregs.ProgControlPort.part.C = value; break; - case 6: scudspregs.ProgControlPort.part.V = value; break; - case 7: scudspregs.ProgControlPort.part.E = value; break; - case 8: scudspregs.ProgControlPort.part.ES = value; break; - case 9: scudspregs.ProgControlPort.part.EX = value; break; - case 10: scudspregs.ProgControlPort.part.LE = value; break; - case 11: scudspregs.ProgControlPort.part.P = value; break; - case 12: scudspregs.TOP = value; break; - case 13: scudspregs.LOP = value; break; - case 14: - scudspregs.CT[0] = (value>>24) & 0xff; - scudspregs.CT[1] = (value>>16) & 0xff; - scudspregs.CT[2] = (value>>8) & 0xff; - scudspregs.CT[3] = (value) & 0xff; - break; - case 15: scudspregs.RA0 = value; break; - case 16: scudspregs.WA0 = value; break; - case 17: scudspregs.RX = value; break; - case 18: scudspregs.RY = value; break; - case 19: scudspregs.P.part.H = value; break; - case 20: scudspregs.P.part.L = value; break; - case 21: scudspregs.AC.part.H = value; break; - case 22: scudspregs.AC.part.L = value; break; - } - - ScuDspSetRegisters(&scudspregs); -} - -static void yui_scudsp_update_codelist( YuiScudsp *scudsp, u32 addr) { - /* refresh the assembler view. points the line to be highlighted. */ - - int i; - static char tagPC[] = ""; - static char tagEnd[] = "\n"; - char buf[100*24+40]; - char *curs = buf; - char lineBuf[100]; - u32 offset; - - if ( addr - scudsp->lastCode >= 20 ) offset = addr - 8; - else offset = scudsp->lastCode; - scudsp->lastCode = offset; - - for (i=0; i < 24; i++) { - - if ( offset + i == addr ) { strcpy( curs, tagPC ); curs += strlen(tagPC); } - ScuDspDisasm(offset+i, lineBuf); - strcpy( curs, lineBuf ); - curs += strlen(lineBuf); - if ( offset + i == addr ) { strcpy( curs, tagEnd ); curs += strlen(tagEnd); } - else { strcpy( curs, "\n" ); curs += 1;} - } - *curs = 0; - - gtk_label_set_markup( GTK_LABEL(scudsp->uLabel), buf ); -} - -static void yui_scudsp_step( GtkWidget* widget, YuiScudsp * scudsp ) { - - ScuDspStep(); - yui_window_invalidate( yui ); /* update all dialogs, including us */ -} - -static void yui_scudsp_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp) { - /* registry number value has been set to */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( scudsp->regListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ( endptr - arg2 == strlen(arg2) ) { - - sprintf(bptext, "%08X", (int)addr); - scudspsetRegister( scudsp, i, addr ); - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 1, bptext, -1 ); - } - yui_window_invalidate( yui ); -} - -static void yui_scudsp_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( scudsp->bpListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ((endptr - arg2 < strlen(arg2)) || (!addr)) addr = 0xFFFFFFFF; - if ( scudsp->cbp[i] != 0xFFFFFFFF) ScuDspDelCodeBreakpoint(scudsp->cbp[i]); - scudsp->cbp[i] = 0xFFFFFFFF; - - if ((addr!=0xFFFFFFFF)&&(ScuDspAddCodeBreakpoint(addr) == 0)) { - - sprintf(bptext, "%08X", (int)addr); - scudsp->cbp[i] = addr; - } else strcpy(bptext,""); - gtk_list_store_set( GTK_LIST_STORE( scudsp->bpListStore ), &iter, 0, bptext, -1 ); -} - -static void debugPauseLoop(void) { /* secondary gtk event loop for the "breakpoint pause" state */ - - while ( !(yui->state & YUI_IS_RUNNING) ) - if ( gtk_main_iteration() ) return; -} - -static void yui_scudsp_breakpoint_handler (u32 addr) { - - yui_window_pause(yui); - { - scudspregs_struct scudspregs; - YuiScudsp* scudsp = YUI_SCUDSP(yui_scudsp_new( yui )); - - ScuDspGetRegisters(&scudspregs); - yui_scudsp_update_reglist(scudsp, &scudspregs); - yui_scudsp_update_codelist(scudsp, scudspregs.PC); - } - debugPauseLoop(); /* execution is suspended inside a normal cycle - enter secondary gtk loop */ -} - - -void yui_scudsp_update(YuiScudsp * scudsp) { - scudspregs_struct scudspregs; - ScuDspGetRegisters(&scudspregs); - yui_scudsp_update_codelist(scudsp,scudspregs.PC); - yui_scudsp_update_reglist(scudsp, &scudspregs); - gtk_widget_set_sensitive(scudsp->uLabel, TRUE); - gtk_widget_set_sensitive(scudsp->bpList, TRUE); - gtk_widget_set_sensitive(scudsp->regList, TRUE); - gtk_widget_set_sensitive(scudsp->buttonStep, TRUE); -} - -void yui_scudsp_destroy(YuiScudsp * scudsp) { - g_signal_handler_disconnect(yui, scudsp->running_handler); - g_signal_handler_disconnect(yui, scudsp->paused_handler); - - yui_scudsp = NULL; - - gtk_widget_destroy(GTK_WIDGET(scudsp)); -} - -static void yui_scudsp_clear(YuiScudsp * scudsp) { - - gtk_widget_set_sensitive(scudsp->uLabel, FALSE); - gtk_widget_set_sensitive(scudsp->bpList, FALSE); - gtk_widget_set_sensitive(scudsp->regList, FALSE); - gtk_widget_set_sensitive(scudsp->buttonStep, FALSE); -} diff --git a/yabause/src/gtk/yuiscudsp.h b/yabause/src/gtk/yuiscudsp.h deleted file mode 100644 index 7cdc285264..0000000000 --- a/yabause/src/gtk/yuiscudsp.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SCUDSP_H -#define YUI_SCUDSP_H - -#include -#include -#include - -#include "../scu.h" -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SCUDSP_TYPE (yui_scudsp_get_type ()) -#define YUI_SCUDSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SCUDSP_TYPE, YuiScudsp)) -#define YUI_SCUDSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SCUDSP_TYPE, YuiScudspClass)) -#define IS_YUI_SCUDSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SCUDSP_TYPE)) -#define IS_YUI_SCUDSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SCUDSP_TYPE)) - -typedef struct _YuiScudsp YuiScudsp; -typedef struct _YuiScudspClass YuiScudspClass; - -struct _YuiScudsp -{ - GtkWindow dialog; - - GtkWidget *vbox, *vboxmain; - GtkWidget *hbox, *hboxmain; - GtkWidget * buttonStep, * buttonStepOver; - GtkWidget * bpList, *regList, *uLabel, *uFrame; - GtkListStore *bpListStore, *regListStore; - GtkCellRenderer *bpListRenderer, *regListRenderer1, *regListRenderer2; - GtkTreeViewColumn *bpListColumn, *regListColumn1, *regListColumn2; - u32 cbp[MAX_BREAKPOINTS]; /* the list of breakpoint positions, as they can be found in the list widget */ - u32 lastCode; /* offset of last unassembly. Try to reuse it to prevent sliding. */ - gulong paused_handler; - gulong running_handler; -}; - -struct _YuiScudspClass -{ - GtkWindowClass parent_class; - - void (* yui_scudsp) (YuiScudsp * yv); -}; - -GType yui_scudsp_get_type (void); -GtkWidget * yui_scudsp_new(YuiWindow * y); -void yui_scudsp_update(YuiScudsp * scudsp); -void yui_scudsp_destroy(YuiScudsp * scudsp); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuish.c b/yabause/src/gtk/yuish.c deleted file mode 100644 index 0c8dc3cc3e..0000000000 --- a/yabause/src/gtk/yuish.c +++ /dev/null @@ -1,1102 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - Copyright 2008 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuish.h" -#include "../sh2core.h" -#include "../sh2d.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_sh_class_init (YuiShClass * klass); -static void yui_sh_init (YuiSh * yfe); -static void yui_sh_clear(YuiSh * sh); -static void yui_sh_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_editedMbp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_editedMbpFlags( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_step( GtkWidget* widget, YuiSh * sh2 ); -static void SH2BreakpointHandler (SH2_struct *context, u32 addr); -static gint yui_sh_popup(GtkWidget * widget, GdkEvent * event, gpointer data); -static gint yui_sh_bp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data); -static gint yui_sh_mbp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data); -static void yui_sh_popup_add_bp(GtkMenuItem * menuitem, gpointer user_data); -static void yui_sh_popup_del_bp(GtkMenuItem * menuitem, gpointer user_data); -static void SH2UpdateBreakpointList(YuiSh * sh2); -static void SH2UpdateMemoryBreakpointList(YuiSh * sh2); -static void yui_sh_bp_add(GtkEntry * entry, gpointer user_data); -static void yui_sh_button_bp_add(GtkWidget * widget, gpointer user_data); -static void yui_sh_mbp_add(GtkEntry * entry, gpointer user_data); -static void yui_sh_mbp_toggle_flag(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_mbp_remove(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_mbp_clear(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_bp_remove(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_bp_clear(GtkWidget * menuitem, gpointer user_data); - -static YuiSh *yui_msh, *yui_ssh; -static YuiWindow * yui; - -GType yui_sh_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiShClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_sh_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiSh), - 0, - (GInstanceInitFunc) yui_sh_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiSh", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_sh_class_init (UNUSED YuiShClass * klass) { -} - -static void yui_sh_init (YuiSh * sh2) { - //GtkWidget *vboxBp; - - sh2->breakpointEnabled = MSH2->breakpointEnabled; - - gtk_window_set_title(GTK_WINDOW(sh2), "SH"); - - sh2->vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width( GTK_CONTAINER( sh2->vbox ), 0); - gtk_container_add (GTK_CONTAINER (sh2), sh2->vbox); - - sh2->toolbar = gtk_toolbar_new(); - gtk_toolbar_set_style(GTK_TOOLBAR(sh2->toolbar), GTK_TOOLBAR_ICONS); - gtk_box_pack_start(GTK_BOX(sh2->vbox), sh2->toolbar, FALSE, FALSE, 0); - - sh2->hboxmain = gtk_hbox_new(FALSE, 4); - gtk_box_pack_start( GTK_BOX( sh2->vbox ), sh2->hboxmain, FALSE, FALSE, 0); - - /* Register list */ - - sh2->regListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - sh2->regList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(sh2->regListStore) ); - sh2->regListRenderer1 = gtk_cell_renderer_text_new(); - sh2->regListRenderer2 = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(sh2->regListRenderer2), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - sh2->regListColumn1 = gtk_tree_view_column_new_with_attributes(_("Register"), sh2->regListRenderer1, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->regList), sh2->regListColumn1); - sh2->regListColumn2 = gtk_tree_view_column_new_with_attributes(_("Value"), sh2->regListRenderer2, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->regList), sh2->regListColumn2); - gtk_box_pack_start( GTK_BOX( sh2->hboxmain ), sh2->regList, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(sh2->regListRenderer2), "edited", GTK_SIGNAL_FUNC(yui_sh_editedReg), sh2 ); - - sh2->store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - sh2->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (sh2->store)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(sh2->view), FALSE); - { - GtkWidget * scroll; - GtkCellRenderer *renderer; - GtkCellRenderer *icon; - GtkTreeViewColumn *column; - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - icon = gtk_cell_renderer_pixbuf_new(); - g_object_set(icon, "xalign", 0, NULL); - column = gtk_tree_view_column_new_with_attributes("Icon", icon, "stock-id", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (sh2->view), column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (sh2->view), column); - - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 2, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (sh2->view), column); - - gtk_container_add(GTK_CONTAINER(scroll), sh2->view); - gtk_box_pack_start(GTK_BOX(sh2->hboxmain), scroll, TRUE, TRUE, 0); - } - - if (sh2->breakpointEnabled) { - GtkWidget * menu = gtk_menu_new(); - GtkWidget * item; - - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", G_CALLBACK(yui_sh_popup_add_bp), sh2); - - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", G_CALLBACK(yui_sh_popup_del_bp), sh2); - - gtk_widget_show_all(menu); - - g_signal_connect(sh2->view, "button-press-event", G_CALLBACK(yui_sh_popup), menu); - } - - /* breakpoint list */ - - sh2->vboxBp = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start( GTK_BOX( sh2->hboxmain ), sh2->vboxBp, FALSE, FALSE, 0 ); - - sh2->bpListStore = gtk_list_store_new(1,G_TYPE_STRING); - sh2->bpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(sh2->bpListStore) ); - sh2->bpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(sh2->bpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - sh2->bpListColumn = gtk_tree_view_column_new_with_attributes("Code breaks", sh2->bpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->bpList), sh2->bpListColumn); - gtk_box_pack_start( GTK_BOX( sh2->vboxBp ), sh2->bpList, TRUE, TRUE, 0 ); - g_signal_connect(G_OBJECT(sh2->bpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_sh_editedBp), sh2 ); - - { - GtkWidget * bp_form_box; - GtkWidget * bp_input; - GtkWidget * bp_add; - - bp_form_box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(sh2->vboxBp), bp_form_box, FALSE, FALSE, 0); - - bp_input = gtk_entry_new(); - gtk_entry_set_width_chars(GTK_ENTRY(bp_input), 8); - g_signal_connect(bp_input, "activate", G_CALLBACK(yui_sh_bp_add), sh2); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_input, TRUE, TRUE, 0); - - bp_add = gtk_button_new(); - gtk_container_add(GTK_CONTAINER(bp_add), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); - gtk_button_set_relief(GTK_BUTTON(bp_add), GTK_RELIEF_NONE); - g_signal_connect(bp_add, "clicked", G_CALLBACK(yui_sh_button_bp_add), bp_input); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_add, FALSE, FALSE, 0); - } - - { - GtkWidget * bp_item; - sh2->bp_menu = gtk_menu_new(); - - bp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->bp_menu), bp_item); - g_signal_connect(bp_item, "activate", G_CALLBACK(yui_sh_bp_remove), sh2); - - bp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->bp_menu), bp_item); - g_signal_connect(bp_item, "activate", G_CALLBACK(yui_sh_bp_clear), sh2); - - gtk_widget_show_all(sh2->bp_menu); - - g_signal_connect(sh2->bpList, "button-press-event", G_CALLBACK(yui_sh_bp_popup), sh2); - } - - /* memory breakpoint list */ - - sh2->mbpListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - sh2->mbpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(sh2->mbpListStore) ); - sh2->mbpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(sh2->mbpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - sh2->mbpListColumn = gtk_tree_view_column_new_with_attributes("Memory breaks", sh2->mbpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->mbpList), sh2->mbpListColumn); - - { - GtkCellRenderer * flags_renderer; - GtkTreeViewColumn * flags_column; - - flags_renderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(flags_renderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL); - g_signal_connect(G_OBJECT(flags_renderer), "edited", GTK_SIGNAL_FUNC(yui_sh_editedMbpFlags), sh2 ); - - flags_column = gtk_tree_view_column_new_with_attributes("Flags", flags_renderer, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->mbpList), flags_column); - } - - gtk_box_pack_start( GTK_BOX( sh2->vboxBp ), sh2->mbpList, TRUE, TRUE, 0 ); - g_signal_connect(G_OBJECT(sh2->mbpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_sh_editedMbp), sh2 ); - - { - GtkWidget * mbp_item; - - sh2->mbp_menu = gtk_menu_new(); - - sh2->mbp_menu_item[0] = gtk_check_menu_item_new_with_label("Byte read"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[0]); - g_signal_connect(sh2->mbp_menu_item[0], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[1] = gtk_check_menu_item_new_with_label("Word read"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[1]); - g_signal_connect(sh2->mbp_menu_item[1], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[2] = gtk_check_menu_item_new_with_label("Long read"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[2]); - g_signal_connect(sh2->mbp_menu_item[2], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[3] = gtk_check_menu_item_new_with_label("Byte write"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[3]); - g_signal_connect(sh2->mbp_menu_item[3], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[4] = gtk_check_menu_item_new_with_label("Word write"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[4]); - g_signal_connect(sh2->mbp_menu_item[4], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[5] = gtk_check_menu_item_new_with_label("Long write"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[5]); - g_signal_connect(sh2->mbp_menu_item[5], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), gtk_separator_menu_item_new()); - - mbp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), mbp_item); - g_signal_connect(mbp_item, "activate", G_CALLBACK(yui_sh_mbp_remove), sh2); - - mbp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), mbp_item); - g_signal_connect(mbp_item, "activate", G_CALLBACK(yui_sh_mbp_clear), sh2); - - gtk_widget_show_all(sh2->mbp_menu); - - g_signal_connect(sh2->mbpList, "button-press-event", G_CALLBACK(yui_sh_mbp_popup), sh2); - } - - { - GtkWidget * bp_form_box; - GtkWidget * bp_input; - GtkWidget * bp_add; - - bp_form_box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(sh2->vboxBp), bp_form_box, FALSE, FALSE, 0); - - bp_input = gtk_entry_new(); - gtk_entry_set_width_chars(GTK_ENTRY(bp_input), 8); - g_signal_connect(bp_input, "activate", G_CALLBACK(yui_sh_mbp_add), sh2); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_input, TRUE, TRUE, 0); - - bp_add = gtk_button_new(); - gtk_container_add(GTK_CONTAINER(bp_add), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); - gtk_button_set_relief(GTK_BUTTON(bp_add), GTK_RELIEF_NONE); - g_signal_connect(bp_add, "clicked", G_CALLBACK(yui_sh_button_bp_add), bp_input); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_add, FALSE, FALSE, 0); - } - - g_signal_connect(G_OBJECT(sh2), "delete-event", GTK_SIGNAL_FUNC(yui_sh_destroy), NULL); - - gtk_window_set_default_size(GTK_WINDOW(sh2), 650, -1); -} - - -static GtkWidget * yui_sh_new(YuiWindow * y, gboolean bMaster) { - GtkWidget * dialog; - GClosure *closureF7; //, *closureF8; - GtkAccelGroup *accelGroup; - YuiSh * sh2; - gint i; - yui = y; - - if (!( yui->state & YUI_IS_INIT )) { - yui_window_run(yui); - yui_window_pause(yui); - } - - if ( bMaster && yui_msh ) return GTK_WIDGET(yui_msh); - if ( !bMaster && yui_ssh ) return GTK_WIDGET(yui_ssh); - - dialog = GTK_WIDGET(g_object_new(yui_sh_get_type(), NULL)); - sh2 = YUI_SH(dialog); - - //sh2->breakpointEnabled = MSH2->breakpointEnabled; -/* - if ( !sh2->breakpointEnabled ) - gtk_box_pack_start( GTK_BOX( sh2->vboxmain ), - gtk_label_new("Breakpoints are disabled (fast interpreter)"), FALSE, FALSE, 4 ); -*/ - - sh2->bMaster = bMaster; - sh2->debugsh = bMaster ? MSH2 : SSH2; - - SH2SetBreakpointCallBack(sh2->debugsh, (void (*)(void *, u32))SH2BreakpointHandler); - - gtk_window_set_title(GTK_WINDOW(sh2), bMaster?"Master SH2":"Slave SH2"); - - for (i = 0; i < 23 ; i++) { - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( sh2->regListStore ), &iter ); - } - - SH2UpdateBreakpointList(sh2); - - SH2UpdateMemoryBreakpointList(sh2); - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(sh2->toolbar), GTK_TOOL_ITEM(play_button), 0); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(sh2->toolbar), GTK_TOOL_ITEM(pause_button), 1); - - sh2->buttonStep = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN); - g_signal_connect(sh2->buttonStep, "clicked", G_CALLBACK(yui_sh_step), sh2); - gtk_toolbar_insert(GTK_TOOLBAR(sh2->toolbar), GTK_TOOL_ITEM(sh2->buttonStep), 2); -#if GTK_CHECK_VERSION(2,12,0) - gtk_widget_set_tooltip_text(GTK_WIDGET(sh2->buttonStep), "step"); -#endif - } - - sh2->paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_sh_update), sh2); - sh2->running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_sh_clear), sh2); - accelGroup = gtk_accel_group_new (); - closureF7 = g_cclosure_new (G_CALLBACK (yui_sh_step), sh2, NULL); - gtk_accel_group_connect( accelGroup, GDK_F7, 0, 0, closureF7 ); - gtk_window_add_accel_group( GTK_WINDOW( dialog ), accelGroup ); - - yui_sh_update(sh2); - if ( yui->state & YUI_IS_RUNNING ) yui_sh_clear(sh2); - - gtk_widget_show_all(GTK_WIDGET(sh2)); - if ( !sh2->breakpointEnabled ) { -/* - gtk_widget_hide( sh2->bpList ); - gtk_widget_hide( sh2->mbpList ); -*/ - gtk_widget_hide(sh2->vboxBp); - } - - return dialog; -} - -GtkWidget * yui_msh_new(YuiWindow * y) { - return GTK_WIDGET( yui_msh = YUI_SH(yui_sh_new( y, TRUE )) ); -} - -GtkWidget * yui_ssh_new(YuiWindow * y) { - return GTK_WIDGET( yui_ssh = YUI_SH(yui_sh_new( y, FALSE )) ); -} - -static void SH2UpdateRegList( YuiSh *sh2, sh2regs_struct *regs) { - /* refresh the registery list */ - - GtkTreeIter iter; - char regstr[32]; - char valuestr[32]; - int i; - - for (i = 0; i < 16; i++) { - sprintf(regstr, "R%02d", i); - sprintf(valuestr, "%08X", (int)regs->R[i] ); - if ( !i ) gtk_tree_model_get_iter_first( GTK_TREE_MODEL( sh2->regListStore ), &iter ); - else gtk_tree_model_iter_next( GTK_TREE_MODEL( sh2->regListStore ), &iter ); - gtk_list_store_set( GTK_LIST_STORE( sh2->regListStore ), &iter, 0, regstr, 1, valuestr, -1 ); - } - - #define SH2UPDATEREGLIST(rreg) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( sh2->regListStore ), &iter ); \ - sprintf(valuestr, "%08X", (int)regs->rreg); \ - gtk_list_store_set( GTK_LIST_STORE( sh2->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - - SH2UPDATEREGLIST(SR.all); - SH2UPDATEREGLIST(GBR); - SH2UPDATEREGLIST(VBR); - SH2UPDATEREGLIST(MACH); - SH2UPDATEREGLIST(MACL); - SH2UPDATEREGLIST(PR); - SH2UPDATEREGLIST(PC); -} - -static void sh2setRegister( YuiSh *sh2, int nReg, u32 value ) { - /* set register number to value in proc */ - - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - - if ( nReg < 16 ) sh2regs.R[nReg] = value; - switch ( nReg ) { - case 16: sh2regs.SR.all = value; break; - case 17: sh2regs.GBR = value; break; - case 18: sh2regs.VBR = value; break; - case 19: sh2regs.MACH = value; break; - case 20: sh2regs.MACL = value; break; - case 21: sh2regs.PR = value; break; - case 22: sh2regs.PC = value; break; - } - - SH2SetRegisters(sh2->debugsh, &sh2regs); -} - -void SH2UpdateBreakpointList(YuiSh * sh2) { - const codebreakpoint_struct *cbp; - int i; - - gtk_list_store_clear(GTK_LIST_STORE( sh2->bpListStore )); - - cbp = SH2GetBreakpointList(sh2->debugsh); - - for (i = 0; i < MAX_BREAKPOINTS-1; i++) { - - if (cbp[i].addr != 0xFFFFFFFF) { - gchar tempstr[20]; - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( sh2->bpListStore ), &iter ); - - sprintf(tempstr, "%08X", (int)cbp[i].addr); - gtk_list_store_set( GTK_LIST_STORE( sh2->bpListStore ), &iter, 0, tempstr, -1 ); - } - } -} - -void SH2UpdateMemoryBreakpointList(YuiSh * sh2) { - const memorybreakpoint_struct *cmbp; - int i; - - gtk_list_store_clear( sh2->mbpListStore ); - - cmbp = SH2GetMemoryBreakpointList(sh2->debugsh); - - for (i = 0; i < MAX_BREAKPOINTS; i++) { - - if (cmbp[i].addr != 0xFFFFFFFF) { - gchar tempstr[30]; - gchar flagstr[30]; - gchar *curs = flagstr; - u32 flags = cmbp[i].flags; - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( sh2->mbpListStore ), &iter ); - - sprintf(tempstr, "%08X", (int)cmbp[i].addr); - if ( flags & BREAK_BYTEREAD ) *(curs++) = 'b'; - if ( flags & BREAK_WORDREAD ) *(curs++) = 'w'; - if ( flags & BREAK_LONGREAD ) *(curs++) = 'l'; - if ( flags & BREAK_BYTEWRITE ) *(curs++) = 'B'; - if ( flags & BREAK_WORDWRITE ) *(curs++) = 'W'; - if ( flags & BREAK_LONGWRITE ) *(curs++) = 'L'; - *curs = 0; - - gtk_list_store_set( GTK_LIST_STORE( sh2->mbpListStore ), &iter, 0, tempstr, -1 ); - gtk_list_store_set( GTK_LIST_STORE( sh2->mbpListStore ), &iter, 1, flagstr, -1 ); - } - } -} - -static void SH2UpdateCodeList( YuiSh *sh2, u32 addr) { - /* refresh the assembler view. points the line to be highlighted. */ - - int i, j; - char lineBuf[64]; - u32 offset; - GtkTreeIter iter; - unsigned int address; - char address_s[20]; - char command_s[64]; - codebreakpoint_struct *cbp; - - gtk_list_store_clear(sh2->store); - - if ( addr - sh2->lastCode >= 20*2 ) offset = addr - (8*2); - else offset = sh2->lastCode; - sh2->lastCode = offset; - - cbp = SH2GetBreakpointList(sh2->debugsh); - - for (i = 0; i < 24; i++) { - SH2Disasm(offset+2*i, MappedMemoryReadWord(offset+2*i), 0, lineBuf); - - sscanf(lineBuf, "0x%8X: %[^\n]", &address, command_s); - sprintf(address_s, "0x%08X", address); - - gtk_list_store_append(sh2->store, &iter); - if ( offset + 2*i == addr ) { - gtk_list_store_set(sh2->store, &iter, 0, GTK_STOCK_GO_FORWARD, -1); - } else { - for (j = 0;j < MAX_BREAKPOINTS - 1;j++) { - if (cbp[j].addr == address) { - gtk_list_store_set(sh2->store, &iter, 0, GTK_STOCK_STOP, -1); - } - } - } - - gtk_list_store_set(sh2->store, &iter, 1, address_s, -1); - - gtk_list_store_set(sh2->store, &iter, 2, command_s, -1); - } -} - -static void yui_sh_step( GtkWidget* widget, YuiSh * sh2 ) { - - SH2Step(sh2->debugsh); - yui_window_invalidate( yui ); /* update all dialogs, including us */ -} - -static void yui_sh_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* registry number value has been set to */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->regListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ( endptr - arg2 == strlen(arg2) ) { - - sprintf(bptext, "%08X", (int)addr); - sh2setRegister( sh2, i, addr ); - gtk_list_store_set( GTK_LIST_STORE( sh2->regListStore ), &iter, 1, bptext, -1 ); - } - yui_window_invalidate( yui ); -} - -static void yui_sh_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - char *endptr; - unsigned int addr; - gchar * oldaddr_s; - unsigned int oldaddr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->bpListStore ), &iter, arg1 ); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->bpListStore ), &iter, 0, &oldaddr_s, -1); - sscanf(oldaddr_s, "%8X", &oldaddr); - g_free(oldaddr_s); - - SH2DelCodeBreakpoint(sh2->debugsh, oldaddr); - - addr = strtoul(arg2, &endptr, 16 ); - if ((endptr - arg2 < strlen(arg2)) || (!addr)) addr = 0xFFFFFFFF; - - if (addr != 0xFFFFFFFF) { - SH2AddCodeBreakpoint(sh2->debugsh, addr); - } - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -static void yui_sh_editedMbp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - gchar *endptr; - unsigned int addr; - gchar * oldaddr_s, * flags_s; - unsigned int oldaddr; - u32 flags; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->mbpListStore ), &iter, arg1 ); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->mbpListStore ), &iter, 0, &oldaddr_s, -1); - sscanf(oldaddr_s, "%8X", &oldaddr); - g_free(oldaddr_s); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->mbpListStore ), &iter, 1, &flags_s, -1); - - SH2DelMemoryBreakpoint(sh2->debugsh, oldaddr); - - addr = strtoul(arg2, &endptr, 16 ); - if (!addr) addr = 0xFFFFFFFF; - - if (addr!=0xFFFFFFFF) { - - flags = 0; - endptr = flags_s; - while ( *endptr ) { - - switch (*endptr) { - - case 'b': flags |= BREAK_BYTEREAD; break; - case 'w': flags |= BREAK_WORDREAD; break; - case 'l': flags |= BREAK_LONGREAD; break; - case 'B': flags |= BREAK_BYTEWRITE; break; - case 'W': flags |= BREAK_WORDWRITE; break; - case 'L': flags |= BREAK_LONGWRITE; break; - } - endptr++; - } - - if ( !flags ) flags = BREAK_BYTEREAD|BREAK_WORDREAD|BREAK_LONGREAD|BREAK_BYTEWRITE|BREAK_WORDWRITE|BREAK_LONGWRITE; - SH2AddMemoryBreakpoint(sh2->debugsh, addr, flags); - } - - SH2UpdateMemoryBreakpointList(sh2); -} - -static void yui_sh_editedMbpFlags( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - gchar *endptr; - unsigned int addr; - gchar * addr_s; - u32 flags = 0; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->mbpListStore ), &iter, arg1 ); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->mbpListStore ), &iter, 0, &addr_s, -1); - sscanf(addr_s, "%8X", &addr); - g_free(addr_s); - - SH2DelMemoryBreakpoint(sh2->debugsh, addr); - - endptr = arg2; - - while ( *endptr ) { - - switch (*endptr) { - - case 'b': flags |= BREAK_BYTEREAD; break; - case 'w': flags |= BREAK_WORDREAD; break; - case 'l': flags |= BREAK_LONGREAD; break; - case 'B': flags |= BREAK_BYTEWRITE; break; - case 'W': flags |= BREAK_WORDWRITE; break; - case 'L': flags |= BREAK_LONGWRITE; break; - } - endptr++; - } - - SH2AddMemoryBreakpoint(sh2->debugsh, addr, flags); - - SH2UpdateMemoryBreakpointList(sh2); -} - -static void debugPauseLoop(void) { /* secondary gtk event loop for the "breakpoint pause" state */ - - while ( !(yui->state & YUI_IS_RUNNING) ) - if ( gtk_main_iteration() ) return; -} - -static void SH2BreakpointHandler (SH2_struct *context, u32 addr) { - - yui_window_pause(yui); - { - sh2regs_struct sh2regs; - YuiSh* sh2 = YUI_SH(yui_sh_new( yui, context == MSH2 )); - - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateRegList(sh2, &sh2regs); - SH2UpdateCodeList(sh2, sh2regs.PC); - } - debugPauseLoop(); /* execution is suspended inside a normal cycle - enter secondary gtk loop */ -} - - -void yui_sh_update(YuiSh * sh) { - sh2regs_struct sh2regs; - SH2GetRegisters(sh->debugsh, &sh2regs); - SH2UpdateCodeList(sh,sh2regs.PC); - SH2UpdateRegList(sh, &sh2regs); - gtk_widget_set_sensitive(sh->bpList, TRUE); - gtk_widget_set_sensitive(sh->mbpList, TRUE); - gtk_widget_set_sensitive(sh->regList, TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(sh->buttonStep), - !sh->debugsh->isIdle && !(( sh->debugsh == SSH2 )&&( !yabsys.IsSSH2Running ))); -} - -void yui_sh_destroy(YuiSh * sh) { - g_signal_handler_disconnect(yui, sh->running_handler); - g_signal_handler_disconnect(yui, sh->paused_handler); - - if ( sh->bMaster ) yui_msh = NULL; - else yui_ssh = NULL; - - gtk_widget_destroy(GTK_WIDGET(sh)); -} - -static void yui_sh_clear(YuiSh * sh) { - - gtk_widget_set_sensitive(sh->bpList, FALSE); - gtk_widget_set_sensitive(sh->mbpList, FALSE); - gtk_widget_set_sensitive(sh->regList, FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(sh->buttonStep), FALSE); - - gtk_list_store_clear(sh->store); -} - -gint yui_sh_popup(GtkWidget * widget, GdkEvent * event, gpointer data) -{ - GtkMenu *menu; - GdkEventButton *event_button; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (GTK_IS_MENU (data), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - menu = GTK_MENU(data); - - if (event->type == GDK_BUTTON_PRESS) { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) { - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); - } - } - - return FALSE; -} - -void yui_sh_popup_add_bp(GtkMenuItem * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - GtkTreeView * view = GTK_TREE_VIEW(sh2->view); - GtkTreeSelection * selection; - GtkTreeModel * model; - GtkTreeIter iter; - gchar * address_s; - unsigned int address; - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 1, &address_s, -1); - - sscanf(address_s, "0x%08X", &address); - - SH2AddCodeBreakpoint(sh2->debugsh, address); - - g_free(address_s); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -void yui_sh_popup_del_bp(GtkMenuItem * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - GtkTreeView * view = GTK_TREE_VIEW(sh2->view); - GtkTreeSelection * selection; - GtkTreeModel * model; - GtkTreeIter iter; - gchar * address_s; - unsigned int address; - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 1, &address_s, -1); - - sscanf(address_s, "0x%08X", &address); - - SH2DelCodeBreakpoint(sh2->debugsh, address); - - g_free(address_s); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -static void yui_sh_bp_add(GtkEntry * entry, gpointer user_data) { - YuiSh * sh2 = user_data; - const gchar * address_s; - unsigned int address; - - address_s = gtk_entry_get_text(entry); - - if (*address_s == 0) return; - - sscanf(address_s, "%8X", &address); - - SH2AddCodeBreakpoint(sh2->debugsh, address); - - gtk_entry_set_text(entry, ""); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -static void yui_sh_button_bp_add(GtkWidget * widget, gpointer user_data) { - g_signal_emit_by_name(user_data, "activate"); -} - -static void yui_sh_mbp_add(GtkEntry * entry, gpointer user_data) { - YuiSh * sh2 = user_data; - const gchar * address_s; - unsigned int address; - - address_s = gtk_entry_get_text(entry); - - if (*address_s == 0) return; - - sscanf(address_s, "%8X", &address); - - SH2AddMemoryBreakpoint(sh2->debugsh, address, BREAK_BYTEREAD|BREAK_WORDREAD|BREAK_LONGREAD|BREAK_BYTEWRITE|BREAK_WORDWRITE|BREAK_LONGWRITE); - - gtk_entry_set_text(entry, ""); - - SH2UpdateMemoryBreakpointList(sh2); -} - -gint yui_sh_mbp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data) -{ - GtkMenu *menu; - GdkEventButton *event_button; - YuiSh * sh2 = data; - GtkTreeView * view; - GtkTreeSelection * selection; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * flags_s; - char *endptr; - int i; - guint signal_id; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - view = GTK_TREE_VIEW(sh2->mbpList); - menu = GTK_MENU(sh2->mbp_menu); - - if (event->type == GDK_BUTTON_PRESS) { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) { - - GtkTreePath *path; - - selection = gtk_tree_view_get_selection(view); - - if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(view), event->x, event->y, &path, NULL, NULL, NULL)) { - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, path); - gtk_tree_path_free(path); - } - - gtk_tree_selection_get_selected(selection, &model, &iter); - - if (gtk_tree_selection_count_selected_rows(selection) == 0) return FALSE; - - gtk_tree_model_get(model, &iter, 1, &flags_s, -1); - - signal_id = g_signal_lookup("activate", GTK_TYPE_CHECK_MENU_ITEM); - - for(i = 0;i < 6;i++) g_signal_handlers_block_matched(sh2->mbp_menu_item[i], G_SIGNAL_MATCH_DATA, signal_id, 0, NULL, NULL, sh2); - - for(i = 0;i < 6;i++) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[i]), FALSE); - - endptr = flags_s; - while ( *endptr ) { - switch (*endptr) { - - case 'b': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[0]), TRUE); break; - case 'w': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[1]), TRUE); break; - case 'l': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[2]), TRUE); break; - case 'B': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[3]), TRUE); break; - case 'W': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[4]), TRUE); break; - case 'L': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[5]), TRUE); break; - } - endptr++; - } - - for(i = 0;i < 6;i++) g_signal_handlers_unblock_matched(sh2->mbp_menu_item[i], G_SIGNAL_MATCH_DATA, signal_id, 0, NULL, NULL, sh2); - - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); - } - } - - return FALSE; -} - -void yui_sh_mbp_toggle_flag(GtkWidget * menuitem, gpointer user_data) { - GtkTreeSelection * selection; - YuiSh * sh2 = user_data; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * address_s, * flags_s; - unsigned int address; - u32 flags; - GtkTreeView * view; - char *endptr; - - view = GTK_TREE_VIEW(sh2->mbpList); - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 0, &address_s, -1); - gtk_tree_model_get(model, &iter, 1, &flags_s, -1); - sscanf(address_s, "%8X", &address); - - SH2DelMemoryBreakpoint(sh2->debugsh, address); - - flags = 0; - endptr = flags_s; - while ( *endptr ) { - switch (*endptr) { - case 'b': flags |= BREAK_BYTEREAD; break; - case 'w': flags |= BREAK_WORDREAD; break; - case 'l': flags |= BREAK_LONGREAD; break; - case 'B': flags |= BREAK_BYTEWRITE; break; - case 'W': flags |= BREAK_WORDWRITE; break; - case 'L': flags |= BREAK_LONGWRITE; break; - } - endptr++; - } - - if (menuitem == sh2->mbp_menu_item[0]) flags = (flags & ~BREAK_BYTEREAD) | (~flags & BREAK_BYTEREAD); - if (menuitem == sh2->mbp_menu_item[1]) flags = (flags & ~BREAK_WORDREAD) | (~flags & BREAK_WORDREAD); - if (menuitem == sh2->mbp_menu_item[2]) flags = (flags & ~BREAK_LONGREAD) | (~flags & BREAK_LONGREAD); - if (menuitem == sh2->mbp_menu_item[3]) flags = (flags & ~BREAK_BYTEWRITE) | (~flags & BREAK_BYTEWRITE); - if (menuitem == sh2->mbp_menu_item[4]) flags = (flags & ~BREAK_WORDWRITE) | (~flags & BREAK_WORDWRITE); - if (menuitem == sh2->mbp_menu_item[5]) flags = (flags & ~BREAK_LONGWRITE) | (~flags & BREAK_LONGWRITE); - - SH2AddMemoryBreakpoint(sh2->debugsh, address, flags); - - SH2UpdateMemoryBreakpointList(sh2); -} - -void yui_sh_mbp_remove(GtkWidget * menuitem, gpointer user_data) { - GtkTreeSelection * selection; - YuiSh * sh2 = user_data; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * address_s; - unsigned int address; - GtkTreeView * view; - - view = GTK_TREE_VIEW(sh2->mbpList); - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 0, &address_s, -1); - sscanf(address_s, "%8X", &address); - - SH2DelMemoryBreakpoint(sh2->debugsh, address); - - SH2UpdateMemoryBreakpointList(sh2); -} - -void yui_sh_mbp_clear(GtkWidget * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - - SH2ClearMemoryBreakpoints(sh2->debugsh); - - SH2UpdateMemoryBreakpointList(sh2); -} - -gint yui_sh_bp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data) -{ - GtkMenu *menu; - GdkEventButton *event_button; - YuiSh * sh2 = data; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - menu = GTK_MENU(sh2->bp_menu); - - if (event->type == GDK_BUTTON_PRESS) { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) { - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); - } - } - - return FALSE; -} - -void yui_sh_bp_remove(GtkWidget * menuitem, gpointer user_data) { - GtkTreeSelection * selection; - YuiSh * sh2 = user_data; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * address_s; - unsigned int address; - GtkTreeView * view; - - view = GTK_TREE_VIEW(sh2->bpList); - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 0, &address_s, -1); - sscanf(address_s, "%8X", &address); - - SH2DelCodeBreakpoint(sh2->debugsh, address); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -void yui_sh_bp_clear(GtkWidget * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - - SH2ClearCodeBreakpoints(sh2->debugsh); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} diff --git a/yabause/src/gtk/yuish.h b/yabause/src/gtk/yuish.h deleted file mode 100644 index 60b8fe72bd..0000000000 --- a/yabause/src/gtk/yuish.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - Copyright 2008 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SH_H -#define YUI_SH_H - -#include -#include -#include - -#include "../sh2core.h" -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SH_TYPE (yui_sh_get_type ()) -#define YUI_SH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SH_TYPE, YuiSh)) -#define YUI_SH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SH_TYPE, YuiShClass)) -#define IS_YUI_SH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SH_TYPE)) -#define IS_YUI_SH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SH_TYPE)) - -typedef struct _YuiSh YuiSh; -typedef struct _YuiShClass YuiShClass; - -struct _YuiSh -{ - GtkWindow dialog; - - GtkWidget * view; - GtkWidget * toolbar; - GtkWidget *vbox; - GtkWidget *hboxmain; - GtkToolItem * buttonStep; - GtkWidget *bpList, *mbpList, *regList; //, *uLabel, *uFrame; - GtkListStore *bpListStore, *mbpListStore, *regListStore; - GtkCellRenderer *bpListRenderer, *mbpListRenderer, *regListRenderer1, *regListRenderer2; - GtkTreeViewColumn *bpListColumn, *mbpListColumn, *regListColumn1, *regListColumn2; - //u32 cbp[MAX_BREAKPOINTS]; /* the list of breakpoint positions, as they can be found in the list widget */ - //u32 cmbp[MAX_BREAKPOINTS]; /* the list of memory breakpoint positions, as they can be found in the list widget */ - //u32 mbpFlags[MAX_BREAKPOINTS]; - u32 lastCode; /* offset of last unassembly. Try to reuse it to prevent sliding. */ - SH2_struct *debugsh; - gboolean bMaster; - gboolean breakpointEnabled; - gulong paused_handler; - gulong running_handler; - - GtkListStore * store; - - GtkWidget * bp_menu; - GtkWidget * mbp_menu; - GtkWidget * mbp_menu_item[6]; - - GtkWidget * vboxBp; -}; - -struct _YuiShClass -{ - GtkWindowClass parent_class; - - void (* yui_sh) (YuiSh * yv); -}; - -GType yui_sh_get_type (void); -GtkWidget * yui_msh_new(YuiWindow * y); -GtkWidget * yui_ssh_new(YuiWindow * y); -void yui_sh_fill (YuiSh * sh); -void yui_sh_update (YuiSh * sh); -void yui_sh_destroy (YuiSh * sh); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuitransfer.c b/yabause/src/gtk/yuitransfer.c deleted file mode 100644 index 9373101907..0000000000 --- a/yabause/src/gtk/yuitransfer.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuitransfer.h" -#include "../core.h" -#include "../memory.h" - -static void yui_transfer_class_init (YuiTransferClass * klass); -static void yui_transfer_init (YuiTransfer * yfe); -static void yui_transfer_browse (GtkWidget * widget, gpointer user_data); -static void yui_transfer_exec (GtkWidget * widget, YuiTransfer * yt); -static void yui_transfer_load (GtkWidget * entry, YuiTransfer * yt); -static void yui_transfer_load_exec (GtkWidget * entry, YuiTransfer * yt); -static void yui_transfer_store (GtkWidget * entry, YuiTransfer * yt); -static void yui_transfer_check (YuiTransfer * yt); - -GType yui_transfer_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiTransferClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_transfer_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiTransfer), - 0, - (GInstanceInitFunc) yui_transfer_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiTransfer", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_transfer_class_init (UNUSED YuiTransferClass * klass) { -} - -static void yui_transfer_init (YuiTransfer * yt) { - GtkWidget *vbox1; - GtkWidget *hbox1; - GtkWidget *label4; - GtkWidget *button1; - GtkWidget *hbox2; - GtkWidget *label2; - GtkWidget *hbuttonbox1; - GtkWidget *button5; - GtkWidget *hbox3; - GSList *radiobutton1_group = NULL; - GtkWidget *radiobutton1; - GtkWidget *radiobutton2; - GtkWidget *radiobutton3; - const char * tmp; - - gtk_window_set_title (GTK_WINDOW (yt), _("File transfer")); - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (yt), vbox1); - - hbox1 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox1), 10); - - tmp = _("File"); - label4 = gtk_label_new (tmp); - gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5); - gtk_label_set_width_chars (GTK_LABEL (label4), strlen(tmp)); - - yt->file_entry = gtk_entry_new (); - g_signal_connect_swapped(yt->file_entry, "changed", G_CALLBACK(yui_transfer_check), yt); - gtk_box_pack_start (GTK_BOX (hbox1), yt->file_entry, TRUE, TRUE, 0); - - button1 = gtk_button_new_with_mnemonic (_("Browse")); - g_signal_connect(button1, "clicked", G_CALLBACK(yui_transfer_browse), yt->file_entry); - gtk_box_pack_start (GTK_BOX (hbox1), button1, FALSE, FALSE, 0); - - hbox3 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox1), hbox3, FALSE, FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox3), 10); - - radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, _("Load as executable")); - g_signal_connect(radiobutton1, "toggled", G_CALLBACK(yui_transfer_load_exec), yt); - gtk_box_pack_start (GTK_BOX (hbox3), radiobutton1, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton1), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1)); - - radiobutton2 = gtk_radio_button_new_with_mnemonic (NULL, _("Load")); - g_signal_connect(radiobutton2, "toggled", G_CALLBACK(yui_transfer_load), yt); - gtk_box_pack_start (GTK_BOX (hbox3), radiobutton2, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton2), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2)); - - radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("Store")); - g_signal_connect(radiobutton3, "toggled", G_CALLBACK(yui_transfer_store), yt); - gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton3), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3)); - - hbox2 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox2), 10); - - tmp = _("From"); - label2 = gtk_label_new (tmp); - gtk_box_pack_start (GTK_BOX (hbox2), label2, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5); - gtk_label_set_width_chars (GTK_LABEL (label2), strlen(tmp)); - - yt->from_entry = gtk_entry_new (); - g_signal_connect_swapped(yt->from_entry, "changed", G_CALLBACK(yui_transfer_check), yt); - gtk_box_pack_start (GTK_BOX (hbox2), yt->from_entry, TRUE, TRUE, 0); - - tmp = _("To"); - yt->to_label = gtk_label_new (tmp); - gtk_box_pack_start (GTK_BOX (hbox2), yt->to_label, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (yt->to_label), 0, 0.5); - gtk_label_set_width_chars (GTK_LABEL (yt->to_label), strlen(tmp)); - - yt->to_entry = gtk_entry_new (); - g_signal_connect_swapped(yt->to_entry, "changed", G_CALLBACK(yui_transfer_check), yt); - gtk_box_pack_start (GTK_BOX (hbox2), yt->to_entry, TRUE, TRUE, 0); - - hbuttonbox1 = gtk_hbutton_box_new (); - gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox1), 10); - - yt->transfer_button = gtk_button_new_with_mnemonic (_("Transfer")); - gtk_container_add (GTK_CONTAINER (hbuttonbox1), yt->transfer_button); - g_signal_connect(yt->transfer_button, "clicked", G_CALLBACK(yui_transfer_exec), yt); - GTK_WIDGET_SET_FLAGS (yt->transfer_button, GTK_CAN_DEFAULT); - - button5 = gtk_button_new_from_stock ("gtk-cancel"); - gtk_container_add (GTK_CONTAINER (hbuttonbox1), button5); - g_signal_connect_swapped(button5, "clicked", G_CALLBACK(gtk_widget_destroy), yt); - GTK_WIDGET_SET_FLAGS (button5, GTK_CAN_DEFAULT); - - gtk_widget_show_all (GTK_WIDGET(yt)); - - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), FALSE); - - yt->mode = YUI_TRANSFER_LOAD_EXEC; - -} - -GtkWidget * yui_transfer_new(YuiWindow * yw) { - GtkWidget * entry; - YuiTransfer * yfe; - - entry = GTK_WIDGET(g_object_new(yui_transfer_get_type(), NULL)); - yfe = YUI_TRANSFERT(entry); - - gtk_widget_show_all(entry); - - yui_transfer_check(yfe); - - yui_window_start(yw); - - return entry; -} - -static void yui_transfer_browse(UNUSED GtkWidget * widget, gpointer user_data) { - GtkWidget * file_selector; - gint result; - const gchar * filename; - - file_selector = gtk_file_chooser_dialog_new (_("Please choose a file"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - filename = gtk_entry_get_text(GTK_ENTRY(user_data)); - if (filename[0] != '\0') - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_selector), filename); - - gtk_widget_show(file_selector); - - result = gtk_dialog_run(GTK_DIALOG(file_selector)); - - switch(result) { - case GTK_RESPONSE_ACCEPT: - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)); - gtk_entry_set_text(GTK_ENTRY(user_data), filename); - break; - case GTK_RESPONSE_CANCEL: - break; - } - - gtk_widget_destroy(file_selector); -} - -static void yui_transfer_exec(UNUSED GtkWidget * widget, YuiTransfer * yt) { - guint32 from, to; - - switch(yt->mode) { - case YUI_TRANSFER_LOAD: - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->from_entry)), "%x", &from); - MappedMemoryLoad(gtk_entry_get_text(GTK_ENTRY(yt->file_entry)), from); - break; - case YUI_TRANSFER_LOAD_EXEC: - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->from_entry)), "%x", &from); - MappedMemoryLoadExec(gtk_entry_get_text(GTK_ENTRY(yt->file_entry)), from); - break; - case YUI_TRANSFER_STORE: - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->from_entry)), "%x", &from); - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->to_entry)), "%x", &to); - MappedMemorySave(gtk_entry_get_text(GTK_ENTRY(yt->file_entry)), from, to - from); - break; - } - - gtk_widget_destroy(GTK_WIDGET(yt)); -} - -static void yui_transfer_load(GtkWidget * entry, YuiTransfer * yt) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entry))) { - yt->mode = YUI_TRANSFER_LOAD; - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), FALSE); - yui_transfer_check(yt); - } -} - -static void yui_transfer_load_exec(GtkWidget * entry, YuiTransfer * yt) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entry))) { - yt->mode = YUI_TRANSFER_LOAD_EXEC; - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), FALSE); - yui_transfer_check(yt); - } -} - -static void yui_transfer_store(GtkWidget * entry, YuiTransfer * yt) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entry))) { - yt->mode = YUI_TRANSFER_STORE; - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), TRUE); - yui_transfer_check(yt); - } -} - -static void yui_transfer_check(YuiTransfer * yt) { - gboolean ok = FALSE; - - if (*gtk_entry_get_text(GTK_ENTRY(yt->file_entry)) != '\0') { - switch(yt->mode) { - case YUI_TRANSFER_LOAD: - case YUI_TRANSFER_LOAD_EXEC: - if (*gtk_entry_get_text(GTK_ENTRY(yt->from_entry)) != '\0') { - ok = TRUE; - } - break; - case YUI_TRANSFER_STORE: - if ((*gtk_entry_get_text(GTK_ENTRY(yt->from_entry)) != '\0') && (*gtk_entry_get_text(GTK_ENTRY(yt->to_entry)) != '\0')) { - ok = TRUE; - } - break; - } - } - - gtk_widget_set_sensitive(yt->transfer_button, ok); -} diff --git a/yabause/src/gtk/yuitransfer.h b/yabause/src/gtk/yuitransfer.h deleted file mode 100644 index e6af1f1759..0000000000 --- a/yabause/src/gtk/yuitransfer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_TRANSFERT_H -#define YUI_TRANSFERT_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_TRANSFERT_TYPE (yui_transfer_get_type ()) -#define YUI_TRANSFERT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_TRANSFERT_TYPE, YuiTransfer)) -#define YUI_TRANSFERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_TRANSFERT_TYPE, YuiTransferClass)) -#define IS_YUI_TRANSFERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_TRANSFERT_TYPE)) -#define IS_YUI_TRANSFERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_TRANSFERT_TYPE)) - -#define YUI_TRANSFER_LOAD 1 -#define YUI_TRANSFER_LOAD_EXEC 2 -#define YUI_TRANSFER_STORE 3 - -typedef struct _YuiTransfer YuiTransfer; -typedef struct _YuiTransferClass YuiTransferClass; - -struct _YuiTransfer -{ - GtkWindow window; - - GtkWidget * file_entry; - GtkWidget * from_entry; - GtkWidget * to_label; - GtkWidget * to_entry; - GtkWidget * transfer_button; - - int mode; -}; - -struct _YuiTransferClass -{ - GtkWindowClass parent_class; - - void (* yui_transfer) (YuiTransfer * yfe); -}; - -GType yui_transfer_get_type (void); -GtkWidget* yui_transfer_new (YuiWindow * yw); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuivdp1.c b/yabause/src/gtk/yuivdp1.c deleted file mode 100644 index 4b1e3ea5fa..0000000000 --- a/yabause/src/gtk/yuivdp1.c +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright 2006-2007 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yuiviewer.h" -#include "yuivdp1.h" -#include "../vdp1.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_vdp1_class_init (YuiVdp1Class * klass); -static void yui_vdp1_init (YuiVdp1 * yfe); -static void yui_vdp1_view_cursor_changed(GtkWidget * view, YuiVdp1 * vdp1); -static void yui_vdp1_clear(YuiVdp1 * vdp1); -static void yui_vdp1_draw(YuiVdp1 * vdp1); - -GType yui_vdp1_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiVdp1Class), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_vdp1_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiVdp1), - 0, - (GInstanceInitFunc) yui_vdp1_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiVdp1", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_vdp1_class_init (UNUSED YuiVdp1Class * klass) { -} - -static void yui_vdp1_init (YuiVdp1 * yv) { - GtkWidget * hbox, * vbox, * vbox2, * view; - - gtk_window_set_title(GTK_WINDOW(yv), "VDP1"); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); - gtk_container_add(GTK_CONTAINER(yv), vbox); - - yv->toolbar = gtk_toolbar_new(); - - gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS); - - gtk_box_pack_start(GTK_BOX(vbox), yv->toolbar, FALSE, FALSE, 0); - - hbox = gtk_hpaned_new(); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 4); - - yv->store = gtk_list_store_new(2, G_TYPE_STRING, GDK_TYPE_PIXBUF); - view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE); - { - GtkWidget * scroll; - GtkCellRenderer *renderer; - GtkCellRenderer *icon; - GtkTreeViewColumn *column; - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - icon = gtk_cell_renderer_pixbuf_new(); - g_object_set(icon, "xalign", 0, NULL); - column = gtk_tree_view_column_new_with_attributes("Icon", icon, "pixbuf", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - gtk_container_add(GTK_CONTAINER(scroll), view); - gtk_paned_pack1(GTK_PANED(hbox), scroll, FALSE, TRUE); - } - g_signal_connect(view, "cursor-changed", G_CALLBACK(yui_vdp1_view_cursor_changed), yv); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_vdp1_destroy), NULL); - - vbox2 = gtk_vpaned_new(); - gtk_paned_pack2(GTK_PANED(hbox), vbox2, TRUE, TRUE); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - GtkWidget * text = gtk_text_view_new(); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); - yv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)); - gtk_container_add(GTK_CONTAINER(scroll), text); - gtk_paned_pack1(GTK_PANED(vbox2), scroll, FALSE, TRUE); - } - yv->image = yui_viewer_new(); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yv->image); - gtk_paned_pack2(GTK_PANED(vbox2), scroll, TRUE, TRUE); - } - - yv->cursor = 0; - yv->texture = NULL; - - gtk_window_set_default_size(GTK_WINDOW(yv), 500, 450); - - gtk_paned_set_position(GTK_PANED(hbox), 250); - - gtk_paned_set_position(GTK_PANED(vbox2), 200); -} - -GtkWidget * yui_vdp1_new(YuiWindow * y) { - GtkWidget * dialog; - YuiVdp1 * yv; - - dialog = GTK_WIDGET(g_object_new(yui_vdp1_get_type(), NULL)); - yv = YUI_VDP1(dialog); - - yv->yui = y; - - if (!( yv->yui->state & YUI_IS_INIT )) { - yui_window_run(yv->yui); - yui_window_pause(yv->yui); - } - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), -1); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), -1); - } - yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_vdp1_update), yv); - yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_vdp1_clear), yv); - - if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_vdp1_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_vdp1_fill(YuiVdp1 * vdp1) { - gint j; - gchar * string; - gchar nameTemp[1024]; - GtkTreeIter iter; - - yui_vdp1_clear(vdp1); - - j = 0; - - string = Vdp1DebugGetCommandNumberName(j); - while(string && (j < MAX_VDP1_COMMAND)) { - gtk_list_store_append(vdp1->store, &iter); - gtk_list_store_set(vdp1->store, &iter, 0, string, -1); - - { - u32 * icontext; - int wtext, htext; - int rowstride; - GdkPixbuf * pixbuftext, * resized; - float ratio; - - icontext = Vdp1DebugTexture(j, &wtext, &htext); - - if ((icontext != NULL) && (wtext > 0) && (htext > 0)) { - rowstride = wtext * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixbuftext = gdk_pixbuf_new_from_data((const guchar *) icontext, GDK_COLORSPACE_RGB, TRUE, 8, - wtext, htext, rowstride, yui_texture_free, NULL); - - ratio = (float) 16 / htext; - if (htext > 16) { - resized = gdk_pixbuf_scale_simple(pixbuftext, wtext * ratio, 16, GDK_INTERP_BILINEAR); - } else { - resized = gdk_pixbuf_scale_simple(pixbuftext, wtext, htext, GDK_INTERP_BILINEAR); - } - - gtk_list_store_set(vdp1->store, &iter, 1, resized, -1); - - g_object_unref(pixbuftext); - g_object_unref(resized); - } - } - - j++; - string = Vdp1DebugGetCommandNumberName(j); - } - - Vdp1DebugCommand(vdp1->cursor, nameTemp); - gtk_text_buffer_set_text(vdp1->buffer, g_strstrip(nameTemp), -1); - vdp1->texture = Vdp1DebugTexture(vdp1->cursor, &vdp1->w, &vdp1->h); - yui_vdp1_draw(vdp1); -} - -static void yui_vdp1_view_cursor_changed(GtkWidget * view, YuiVdp1 * vdp1) { - GtkTreePath * path; - gchar * strpath; - int i; - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &path, NULL); - - if (path) { - gchar nameTemp[1024]; - - yui_viewer_clear(YUI_VIEWER(vdp1->image)); - - strpath = gtk_tree_path_to_string(path); - - sscanf(strpath, "%i", &i); - - vdp1->cursor = i; - - Vdp1DebugCommand(i, nameTemp); - gtk_text_buffer_set_text(vdp1->buffer, g_strstrip(nameTemp), -1); - vdp1->texture = Vdp1DebugTexture(i, &vdp1->w, &vdp1->h); - yui_vdp1_draw(vdp1); - - g_free(strpath); - gtk_tree_path_free(path); - } -} - -void yui_vdp1_update(YuiVdp1 * vdp1) { - gint i; - for(i = 0 ; i < MAX_VDP1_COMMAND ; i++ ) if ( !Vdp1DebugGetCommandNumberName(i)) break; - vdp1->cursor = 0; - yui_vdp1_fill(vdp1); -} - -void yui_vdp1_destroy(YuiVdp1 * vdp1) { - g_signal_handler_disconnect(vdp1->yui, vdp1->running_handler); - g_signal_handler_disconnect(vdp1->yui, vdp1->paused_handler); - - gtk_widget_destroy(GTK_WIDGET(vdp1)); -} - -static void yui_vdp1_clear(YuiVdp1 * vdp1) { - gtk_list_store_clear(vdp1->store); - gtk_text_buffer_set_text(vdp1->buffer, "", -1); - yui_viewer_clear(YUI_VIEWER(vdp1->image)); -} - -static void yui_vdp1_draw(YuiVdp1 * vdp1) { - GdkPixbuf * pixbuf; - int rowstride; - - if ((vdp1->texture != NULL) && (vdp1->w > 0) && (vdp1->h > 0)) { - rowstride = vdp1->w * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixbuf = gdk_pixbuf_new_from_data((const guchar *) vdp1->texture, GDK_COLORSPACE_RGB, TRUE, 8, - vdp1->w, vdp1->h, rowstride, yui_texture_free, NULL); - - yui_viewer_draw_pixbuf(YUI_VIEWER(vdp1->image), pixbuf, vdp1->w, vdp1->h); - - g_object_unref(pixbuf); - } -} diff --git a/yabause/src/gtk/yuivdp1.h b/yabause/src/gtk/yuivdp1.h deleted file mode 100644 index 0ecc246595..0000000000 --- a/yabause/src/gtk/yuivdp1.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_VDP1_H -#define YUI_VDP1_H - -#include - -#include "yuiwindow.h" -#include "../core.h" - -G_BEGIN_DECLS - -#define YUI_VDP1_TYPE (yui_vdp1_get_type ()) -#define YUI_VDP1(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_VDP1_TYPE, YuiVdp1)) -#define YUI_VDP1_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_VDP1_TYPE, YuiVdp1Class)) -#define IS_YUI_VDP1(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_VDP1_TYPE)) -#define IS_YUI_VDP1_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_VDP1_TYPE)) - -#define MAX_VDP1_COMMAND 4000 - -typedef struct _YuiVdp1 YuiVdp1; -typedef struct _YuiVdp1Class YuiVdp1Class; - -struct _YuiVdp1 -{ - GtkWindow dialog; - - GtkWidget * image; - GtkWidget * toolbar; - - GtkListStore * store; - GtkTextBuffer * buffer; - - gint cursor; - u32 * texture; - int w; - int h; - - gulong paused_handler; - gulong running_handler; - YuiWindow * yui; -}; - -struct _YuiVdp1Class -{ - GtkWindowClass parent_class; - - void (* yui_vdp1) (YuiVdp1 * yv); -}; - -GType yui_vdp1_get_type (void); -GtkWidget * yui_vdp1_new (YuiWindow * yui); -void yui_vdp1_fill (YuiVdp1 * vdp1); -void yui_vdp1_update (YuiVdp1 * vdp1); -void yui_vdp1_destroy (YuiVdp1 * vdp1); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuivdp2.c b/yabause/src/gtk/yuivdp2.c deleted file mode 100644 index 46bdc82c54..0000000000 --- a/yabause/src/gtk/yuivdp2.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuivdp2.h" -#include "../vdp2.h" -#include "../yabause.h" -#include "settings.h" -#include "../vdp2debug.h" -#include "yuiviewer.h" - -static void yui_vdp2_sync(GtkAction * action, YuiVdp2 * yv); -static const char * yui_vdp2_action_names[] = { NULL, "toggle_nbg0", "toggle_nbg1", "toggle_nbg2", "toggle_nbg3", "toggle_rbg0" }; - -static void yui_vdp2_class_init (YuiVdp2Class * klass); -static void yui_vdp2_init (YuiVdp2 * yfe); -static void yui_vdp2_clear(YuiVdp2 * vdp2); -static void yui_vdp2_view_cursor_changed(GtkWidget * view, YuiVdp2 * vdp2); -static void yui_vdp2_draw(YuiVdp2 * vdp2, u32 * texture, int w, int h); - -GType yui_vdp2_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiVdp2Class), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_vdp2_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiVdp2), - 0, - (GInstanceInitFunc) yui_vdp2_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiVdp2", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_vdp2_class_init (UNUSED YuiVdp2Class * klass) { -} - -static void yui_vdp2_toggle(GtkCellRendererToggle * crt, const gchar * path, YuiVdp2 * yv) { - int val; - GtkAction * action = NULL; - - sscanf(path, "%d", &val); - if (! yui_vdp2_action_names[val]) return; - - action = gtk_action_group_get_action(yv->yui->action_group, yui_vdp2_action_names[val]); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), ! gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))); -} - -static void yui_vdp2_sync(GtkAction * action, YuiVdp2 * yv) { - GtkTreeIter iter; - const gchar * name; - - name = gtk_action_get_name(action) + 7; - - if (!strcmp("nbg0", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "1"); - else if (!strcmp("nbg1", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "2"); - else if (!strcmp("nbg2", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "3"); - else if (!strcmp("nbg3", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "4"); - else if (!strcmp("rbg0", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "5"); - - gtk_list_store_set(yv->store, &iter, 1, gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)), -1); -} - -static void yui_vdp2_init (YuiVdp2 * yv) { - GtkWidget * text; - GtkWidget * scroll; - GtkWidget * box, * box2; - GtkWidget * hpane; - GtkWidget * view; - const char * screens[] = { "General", "NBG0/RBG1", "NBG1", "NBG2", "NBG3", "RBG0" }; - unsigned int i; - - gtk_window_set_title(GTK_WINDOW(yv), "VDP2"); - - box = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(box), 0); - gtk_container_add(GTK_CONTAINER(yv), box); - - yv->toolbar = gtk_toolbar_new(); - gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS); - gtk_box_pack_start(GTK_BOX(box), yv->toolbar, FALSE, FALSE, 0); - - hpane = gtk_hpaned_new(); - gtk_container_add(GTK_CONTAINER(box), hpane); - - yv->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); - view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE); - { - GtkWidget * scroll; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - renderer = gtk_cell_renderer_toggle_new(); - gtk_cell_renderer_toggle_set_activatable(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE); - g_signal_connect(renderer, "toggled", G_CALLBACK(yui_vdp2_toggle), yv); - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "active", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - gtk_container_add(GTK_CONTAINER(scroll), view); - gtk_paned_pack1(GTK_PANED(hpane), scroll, FALSE, TRUE); - } - g_signal_connect(view, "cursor-changed", G_CALLBACK(yui_vdp2_view_cursor_changed), yv); - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_paned_pack2(GTK_PANED(hpane), scroll, TRUE, TRUE); - box2 = gtk_vpaned_new(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), box2); - - for(i = 0;i < (sizeof(screens) / sizeof(screens[0]));i++) { - GtkTreeIter iter; - gtk_list_store_append(yv->store, &iter); - gtk_list_store_set(yv->store, &iter, 0, screens[i], -1); - } - - text = gtk_text_view_new(); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), text); - gtk_paned_pack1(GTK_PANED(box2), scroll, FALSE, TRUE); - } - - yv->buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); - - yv->image = yui_viewer_new(); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yv->image); - gtk_paned_pack2(GTK_PANED(box2), scroll, TRUE, TRUE); - } - - gtk_window_set_default_size(GTK_WINDOW(yv), 500, 450); - - gtk_paned_set_position(GTK_PANED(hpane), 120); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_vdp2_destroy), NULL); -} - -GtkWidget * yui_vdp2_new(YuiWindow * y) { - GtkWidget * dialog; - YuiVdp2 * yv; - int i; - - dialog = GTK_WIDGET(g_object_new(yui_vdp2_get_type(), NULL)); - yv = YUI_VDP2(dialog); - - yv->yui = y; - - if (!( yv->yui->state & YUI_IS_INIT )) { - yui_window_run(yv->yui); - yui_window_pause(yv->yui); - } - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), -1); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), -1); - } - yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_vdp2_update), yv); - yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_vdp2_clear), yv); - - for(i = 0;i < (sizeof(yui_vdp2_action_names) / sizeof(yui_vdp2_action_names[0]));i++) { - GtkAction * action; - - if (! yui_vdp2_action_names[i]) continue; - - action = gtk_action_group_get_action(yv->yui->action_group, yui_vdp2_action_names[i]); - yui_vdp2_sync(action, yv); - g_signal_connect(action, "toggled", G_CALLBACK(yui_vdp2_sync), yv); - } - - if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_vdp2_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_vdp2_update(YuiVdp2 * vdp2) { - gchar nameTemp[VDP2_DEBUG_STRING_SIZE]; - gboolean isscrenabled; - - yui_viewer_clear(YUI_VIEWER(vdp2->image)); - - switch(vdp2->cursor) { - case 0: - Vdp2DebugStatsGeneral(nameTemp, &isscrenabled); - break; - case 1: - Vdp2DebugStatsNBG0(nameTemp, &isscrenabled); - break; - case 2: - Vdp2DebugStatsNBG1(nameTemp, &isscrenabled); - break; - case 3: - Vdp2DebugStatsNBG2(nameTemp, &isscrenabled); - break; - case 4: - Vdp2DebugStatsNBG3(nameTemp, &isscrenabled); - break; - case 5: - Vdp2DebugStatsRBG0(nameTemp, &isscrenabled); - break; - } - - if (vdp2->cursor > 0) { - u32 * texture; - int w, h; - texture = Vdp2DebugTexture(vdp2->cursor - 1, &w, &h); - yui_vdp2_draw(vdp2, texture, w, h); - } - - if (isscrenabled) { - gtk_text_buffer_set_text(vdp2->buffer, nameTemp, -1); - } else { - gtk_text_buffer_set_text(vdp2->buffer, "", -1); - } -} - -void yui_vdp2_destroy(YuiVdp2 * vdp2) { - g_signal_handler_disconnect(vdp2->yui, vdp2->paused_handler); - g_signal_handler_disconnect(vdp2->yui, vdp2->running_handler); - gtk_widget_destroy(GTK_WIDGET(vdp2)); -} - -static void yui_vdp2_clear(YuiVdp2 * vdp2) { - gtk_text_buffer_set_text(vdp2->buffer, "", -1); -} - -void yui_vdp2_view_cursor_changed(GtkWidget * view, YuiVdp2 * vdp2) { - GtkTreePath * path; - gchar * strpath; - int i; - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &path, NULL); - - if (path) { - strpath = gtk_tree_path_to_string(path); - - sscanf(strpath, "%i", &i); - - vdp2->cursor = i; - - yui_vdp2_update(vdp2); - - g_free(strpath); - gtk_tree_path_free(path); - } -} - -static void yui_vdp2_draw(YuiVdp2 * vdp2, u32 * texture, int w, int h) { - GdkPixbuf * pixbuf; - int rowstride; - - if ((texture != NULL) && (w > 0) && (h > 0)) { - rowstride = w * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixbuf = gdk_pixbuf_new_from_data((const guchar *) texture, GDK_COLORSPACE_RGB, TRUE, 8, - w, h, rowstride, yui_texture_free, NULL); - - yui_viewer_draw_pixbuf(YUI_VIEWER(vdp2->image), pixbuf, w, h); - - g_object_unref(pixbuf); - } -} diff --git a/yabause/src/gtk/yuivdp2.h b/yabause/src/gtk/yuivdp2.h deleted file mode 100644 index 710d7f4068..0000000000 --- a/yabause/src/gtk/yuivdp2.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_VDP2_H -#define YUI_VDP2_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_VDP2_TYPE (yui_vdp2_get_type ()) -#define YUI_VDP2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_VDP2_TYPE, YuiVdp2)) -#define YUI_VDP2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_VDP2_TYPE, YuiVdp2Class)) -#define IS_YUI_VDP2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_VDP2_TYPE)) -#define IS_YUI_VDP2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_VDP2_TYPE)) - -typedef struct _YuiVdp2 YuiVdp2; -typedef struct _YuiVdp2Class YuiVdp2Class; - -struct _YuiVdp2 -{ - GtkWindow dialog; - - GtkWidget * image; - GtkTextBuffer * buffer; - GtkWidget * toolbar; - - GtkListStore * store; - - gint cursor; - - gulong paused_handler; - gulong running_handler; - - YuiWindow * yui; -}; - -struct _YuiVdp2Class -{ - GtkWindowClass parent_class; -}; - -GType yui_vdp2_get_type (void); -GtkWidget * yui_vdp2_new (YuiWindow * yui); -void yui_vdp2_fill (YuiVdp2 * vdp2); -void yui_vdp2_update (YuiVdp2 * vdp2); -void yui_vdp2_destroy (YuiVdp2 * vdp2); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiviewer.c b/yabause/src/gtk/yuiviewer.c deleted file mode 100644 index e8ac5a07ea..0000000000 --- a/yabause/src/gtk/yuiviewer.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright 2006-2007 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yuiviewer.h" -#include "gtkglwidget.h" -#include "../core.h" - -static void yui_viewer_class_init (YuiViewerClass * klass); -static void yui_viewer_init (YuiViewer * yfe); -static void yui_viewer_expose (GtkWidget * widget, GdkEventExpose *event, gpointer data); - -GType yui_viewer_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiViewerClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_viewer_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiViewer), - 0, - (GInstanceInitFunc) yui_viewer_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "YuiViewer", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_viewer_class_init (UNUSED YuiViewerClass * klass) { -} - -static gint -my_popup_handler (GtkWidget *widget, GdkEvent *event) -{ - GtkMenu *menu; - GdkEventButton *event_button; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - /* The "widget" is the menu that was supplied when - * * g_signal_connect_swapped() was called. - * */ - menu = GTK_MENU (widget); - - if (event->type == GDK_BUTTON_PRESS) - { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) - { - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, - event_button->button, event_button->time); - return TRUE; - } - } - - return FALSE; -} - -static void yui_viewer_init (YuiViewer * yv) { - GtkWidget * menu; - GtkWidget * item; - - gtk_widget_set_events(GTK_WIDGET(yv), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - - menu = gtk_menu_new(); - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, NULL); - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - - gtk_widget_show_all(menu); - - g_signal_connect_swapped(yv, "button-press-event", G_CALLBACK(my_popup_handler), menu); - g_signal_connect(yv, "expose-event", G_CALLBACK(yui_viewer_expose), NULL); - g_signal_connect_swapped(item, "activate", G_CALLBACK(yui_viewer_save), yv); - - yv->pixbuf = NULL; -} - -GtkWidget * yui_viewer_new(void) { - GtkWidget * dialog; - - dialog = GTK_WIDGET(g_object_new(yui_viewer_get_type(), NULL)); - - return dialog; -} - -static void yui_viewer_expose(GtkWidget * widget, GdkEventExpose *event, gpointer data) { - YuiViewer * yv = YUI_VIEWER(widget); - - if (yv->pixbuf != NULL) { - gdk_draw_pixbuf(widget->window, NULL, yv->pixbuf, 0, 0, 0, 0, yv->w, yv->h, GDK_RGB_DITHER_NONE, 0, 0); - } -} - -void yui_viewer_save(YuiViewer * yv) { - GtkWidget * file_selector; - gint result; - char * filename; - int rowstride; - - file_selector = gtk_file_chooser_dialog_new ("Please choose a file", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); - - gtk_widget_show(file_selector); - - result = gtk_dialog_run(GTK_DIALOG(file_selector)); - - switch(result) { - case GTK_RESPONSE_ACCEPT: - rowstride = yv->w * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)); - - gdk_pixbuf_save(yv->pixbuf, filename, "png", NULL, NULL); - - break; - case GTK_RESPONSE_CANCEL: - break; - } - - gtk_widget_destroy(file_selector); -} - -void yui_viewer_draw_pixbuf(YuiViewer * yv, GdkPixbuf * pixbuf, int w, int h) { - if (yv->pixbuf) { - g_object_unref(yv->pixbuf); - } - yv->pixbuf = g_object_ref(pixbuf); - yv->w = w; - yv->h = h; - gdk_window_clear(GTK_WIDGET(yv)->window); - gtk_widget_queue_draw_area(GTK_WIDGET(yv), 0, 0, w, h); -} - -void yui_viewer_clear(YuiViewer * yv) { - if (GTK_WIDGET(yv)->window != NULL) { - gdk_window_clear(GTK_WIDGET(yv)->window); - } -} diff --git a/yabause/src/gtk/yuiviewer.h b/yabause/src/gtk/yuiviewer.h deleted file mode 100644 index 35b2e92f30..0000000000 --- a/yabause/src/gtk/yuiviewer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_VIEWER_H -#define YUI_VIEWER_H - -#include - -G_BEGIN_DECLS - -#define YUI_VIEWER_TYPE (yui_viewer_get_type ()) -#define YUI_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_VIEWER_TYPE, YuiViewer)) -#define YUI_VIEWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_VIEWER_TYPE, YuiViewerClass)) -#define IS_YUI_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_VIEWER_TYPE)) -#define IS_YUI_VIEWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_VIEWER_TYPE)) - -typedef struct _YuiViewer YuiViewer; -typedef struct _YuiViewerClass YuiViewerClass; - -struct _YuiViewer -{ - GtkDrawingArea parent; - - int w; - int h; - GdkPixbuf * pixbuf; -}; - -struct _YuiViewerClass -{ - GtkDrawingAreaClass parent_class; -}; - -GType yui_viewer_get_type (void); -GtkWidget * yui_viewer_new (void); -void yui_viewer_draw_pixbuf(YuiViewer * yv, GdkPixbuf * pixbuf, int w, int h); -void yui_viewer_save (YuiViewer * yv); -void yui_viewer_clear (YuiViewer * yv); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiwindow.c b/yabause/src/gtk/yuiwindow.c deleted file mode 100644 index 694484f599..0000000000 --- a/yabause/src/gtk/yuiwindow.c +++ /dev/null @@ -1,373 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuiwindow.h" -#include "gtkglwidget.h" -#include "../yabause.h" - -#include "settings.h" - -static void yui_window_class_init (YuiWindowClass * klass); -static void yui_window_init (YuiWindow * yfe); -static gboolean yui_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data); -static gboolean yui_window_keyrelease(GtkWidget *widget, GdkEventKey *event, gpointer user_data); -static void yui_window_keep_clean(GtkWidget * widget, GdkEventExpose * event, YuiWindow * yui); -static void yui_window_toggle_fullscreen(GtkWidget * w, YuiWindow * yui); -static void yui_window_toggle_frameskip(GtkWidget * w, YuiWindow * yui); - -static void yui_window_create_actions(YuiWindow * yw) { - GtkAction * action; - GtkToggleAction * taction; - - action = gtk_action_new("run", _("Run"), _("start emulation"), "gtk-media-play"); - gtk_action_group_add_action_with_accel(yw->action_group, action, "r"); - g_signal_connect_swapped(action, "activate", G_CALLBACK(yui_window_run), yw); - - action = gtk_action_new("pause", _("Pause"), _("pause emulation"), "gtk-media-pause"); - gtk_action_group_add_action_with_accel(yw->action_group, action, "p"); - g_signal_connect_swapped(action, "activate", G_CALLBACK(yui_window_pause), yw); - - action = gtk_action_new("reset", _("Reset"), _("reset emulation"), NULL); - gtk_action_group_add_action_with_accel(yw->action_group, action, NULL); - g_signal_connect_swapped(action, "activate", G_CALLBACK(yui_window_reset), yw); - - taction = gtk_toggle_action_new("fullscreen", _("Fullscreen"), NULL, "gtk-fullscreen"); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), "f"); - g_signal_connect(taction, "activate", G_CALLBACK(yui_window_toggle_fullscreen), yw); - - taction = gtk_toggle_action_new("frameskip", _("Frame Skip/Limiter"), NULL, NULL); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(yui_window_toggle_frameskip), yw); - - action = gtk_action_new("quit", _("Quit"), NULL, "gtk-quit"); - gtk_action_group_add_action_with_accel(yw->action_group, action, "q"); - g_signal_connect(action, "activate", G_CALLBACK(gtk_main_quit), yw); - - taction = gtk_toggle_action_new("toggle_vdp1", _("VDP1"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleVDP1), NULL); - - taction = gtk_toggle_action_new("toggle_nbg0", _("NBG0"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG0), NULL); - - taction = gtk_toggle_action_new("toggle_nbg1", _("NBG1"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG1), NULL); - - taction = gtk_toggle_action_new("toggle_nbg2", _("NBG2"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG2), NULL); - - taction = gtk_toggle_action_new("toggle_nbg3", _("NBG3"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG3), NULL); - - taction = gtk_toggle_action_new("toggle_rbg0", _("RBG0"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleRBG0), NULL); -} - -GType yui_window_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiWindowClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_window_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiWindow), - 0, - (GInstanceInitFunc) yui_window_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiWindow", &yfe_info, 0); - } - - return yfe_type; -} - -enum { YUI_WINDOW_RUNNING_SIGNAL, YUI_WINDOW_PAUSED_SIGNAL, LAST_SIGNAL }; - -static guint yui_window_signals[LAST_SIGNAL] = { 0, 0 }; - -static void yui_window_class_init (YuiWindowClass * klass) { - yui_window_signals[YUI_WINDOW_RUNNING_SIGNAL] = g_signal_new ("running", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiWindowClass, yui_window_running), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - yui_window_signals[YUI_WINDOW_PAUSED_SIGNAL] = g_signal_new ("paused", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiWindowClass, yui_window_paused), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -static void yui_set_accel_group(gpointer action, gpointer group) { - gtk_action_set_accel_group(action, group); -} - -static gboolean yui_window_log_delete(GtkWidget *widget, GdkEvent *event, YuiWindow *yw ) { - - yui_window_show_log( yw ); - - return TRUE; /* hide instead of killing */ -} - -extern gchar * inifile; - -static void yui_window_destroy(GtkWidget * window) { - gint x, y; - char buffer[512]; - - gtk_window_get_position(GTK_WINDOW(window), &x, &y); - - sprintf(buffer, "%d", x); - g_key_file_set_value(keyfile, "Gtk", "X", buffer); - sprintf(buffer, "%d", y); - g_key_file_set_value(keyfile, "Gtk", "Y", buffer); - - g_file_set_contents(inifile, g_key_file_to_data(keyfile, 0, 0), -1, 0); - gtk_main_quit(); -} - -static void yui_window_init (YuiWindow * yw) { - GtkAccelGroup * accel_group = gtk_accel_group_new(); - GtkWidget * scroll; - - yw->action_group = gtk_action_group_new("yui"); - yui_window_create_actions(yw); - gtk_action_set_sensitive(gtk_action_group_get_action(yw->action_group, "pause"), FALSE); - gtk_action_set_sensitive(gtk_action_group_get_action(yw->action_group, "reset"), FALSE); - { - GList * list = gtk_action_group_list_actions(yw->action_group); - g_list_foreach(list, yui_set_accel_group, accel_group); - } - gtk_window_add_accel_group(GTK_WINDOW(yw), accel_group); - - { - const gchar * const * data_dir; - gboolean pngfound = FALSE; - gchar * pngfile; - - data_dir = g_get_system_data_dirs(); - while (!pngfound && (*data_dir != NULL)) { - pngfile = g_build_filename(*data_dir, "pixmaps", "yabause.png", NULL); - if (g_file_test(pngfile, G_FILE_TEST_EXISTS)) { - gtk_window_set_icon(GTK_WINDOW(yw), gdk_pixbuf_new_from_file(pngfile, NULL)); - pngfound = TRUE; - } - data_dir++; - } - - if (!pngfound) { - gtk_window_set_icon(GTK_WINDOW(yw), gdk_pixbuf_new_from_file("yabause.png", NULL)); - } - } - - gtk_window_set_title (GTK_WINDOW(yw), "Yabause"); - - yw->box = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(yw), yw->box); - - yw->menu = create_menu(yw); - gtk_box_pack_start(GTK_BOX(yw->box), yw->menu, FALSE, FALSE, 0); - - yw->area = yui_gl_new(); - gtk_box_pack_start(GTK_BOX(yw->box), yw->area, TRUE, TRUE, 0); - gtk_widget_set_size_request(GTK_WIDGET(yw->area), 320, 224); - - g_signal_connect(G_OBJECT(yw), "delete-event", G_CALLBACK(yui_window_destroy), NULL); - g_signal_connect(G_OBJECT(yw), "key-press-event", G_CALLBACK(yui_window_keypress), yw); - g_signal_connect(G_OBJECT(yw), "key-release-event", G_CALLBACK(yui_window_keyrelease), yw); - - yw->logpopup = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title( GTK_WINDOW( yw->logpopup ), "Yabause Logs" ); - gtk_widget_set_size_request( yw->logpopup, 500, 300 ); - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add(GTK_CONTAINER(yw->logpopup), scroll); - g_signal_connect(G_OBJECT(yw->logpopup), "delete-event", G_CALLBACK(yui_window_log_delete), yw); - - yw->log = gtk_text_view_new(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yw->log); - - gtk_widget_show(yw->box); - gtk_widget_show_all(yw->menu); - gtk_widget_show(yw->area); - - yw->clean_handler = g_signal_connect(yw->area, "expose-event", G_CALLBACK(yui_window_keep_clean), yw); - yw->state = 0; -} - -GtkWidget * yui_window_new(YuiAction * act, GCallback ifunc, gpointer idata, - GSourceFunc rfunc, GCallback resetfunc) { - GtkWidget * widget; - YuiWindow * yw; - - widget = GTK_WIDGET(g_object_new(yui_window_get_type(), NULL)); - yw = YUI_WINDOW(widget); - - yw->actions = act; - yw->init_func = ifunc; - yw->init_data = idata; - yw->run_func = rfunc; - yw->reset_func = resetfunc; - - return widget; -} - -void yui_window_toggle_fullscreen(GtkWidget * w, YuiWindow * yui) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "fullscreen"); - static unsigned int beforefswidth = 1; - static unsigned int beforefsheight = 1; - - if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))) { - beforefswidth = GTK_WIDGET(yui)->allocation.width; - beforefsheight = GTK_WIDGET(yui)->allocation.height; - gtk_widget_hide(yui->menu); - gtk_window_fullscreen(GTK_WINDOW(yui)); - } else { - gtk_window_unfullscreen(GTK_WINDOW(yui)); - gtk_widget_show(yui->menu); - gtk_window_resize(GTK_WINDOW(yui), beforefswidth, beforefsheight); - } -} - -void yui_window_toggle_frameskip(GtkWidget * w, YuiWindow * yui) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "frameskip"); - gboolean active = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); - - if (active) - EnableAutoFrameSkip (); - else - DisableAutoFrameSkip (); -} - -static gboolean yui_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { - PerKeyDown(event->keyval); - - return FALSE; -} - -static gboolean yui_window_keyrelease(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { - PerKeyUp(event->keyval); - - return FALSE; -} - -void yui_window_update(YuiWindow * yui) { - - if (!(yui->state & YUI_IS_RUNNING)) yui_gl_draw_pause(YUI_GL(yui->area)); - else yui_gl_draw(YUI_GL(yui->area)); -} - -void yui_window_log(YuiWindow * yui, const char * message) { - GtkTextBuffer * buffer; - GtkTextIter iter; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(yui->log)); - gtk_text_buffer_get_start_iter(buffer, &iter); - gtk_text_buffer_insert(buffer, &iter, message, -1); -} - -void yui_window_show_log(YuiWindow * yui) { - static int i = 0; - if (i) - gtk_widget_hide(yui->logpopup); - else - gtk_widget_show_all(yui->logpopup); - i = !i; -} - -static void yui_window_keep_clean(GtkWidget * widget, GdkEventExpose * event, YuiWindow * yui) { -#ifdef HAVE_LIBGTKGLEXT - glClear(GL_COLOR_BUFFER_BIT); -#endif - yui_window_update(yui); -} - -void yui_window_start(YuiWindow * yui) { - if ((yui->state & YUI_IS_INIT) == 0) { - if (((int (*)(gpointer)) yui->init_func)(yui->init_data) == 0) { - yui->state |= YUI_IS_INIT; - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "reset"), TRUE); - VIDCore->Resize(GTK_WIDGET(yui->area)->allocation.width, GTK_WIDGET(yui->area)->allocation.height, FALSE); - } - } -} - -void yui_window_run(YuiWindow * yui) { - yui_window_start(yui); - - if ((yui->state & YUI_IS_INIT) && ((yui->state & YUI_IS_RUNNING) == 0)) { - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - g_idle_add(yui->run_func, GINT_TO_POINTER(1)); - g_signal_emit(G_OBJECT(yui), yui_window_signals[YUI_WINDOW_RUNNING_SIGNAL], 0); - yui->state |= YUI_IS_RUNNING; - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "run"), FALSE); - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "pause"), TRUE); - } -} - -void yui_window_pause(YuiWindow * yui) { - if (yui->state & YUI_IS_RUNNING) { - yui_gl_dump_screen(YUI_GL(yui->area)); - ScspMuteAudio(SCSP_MUTE_SYSTEM); - g_idle_remove_by_data(GINT_TO_POINTER(1)); - g_signal_emit(G_OBJECT(yui), yui_window_signals[YUI_WINDOW_PAUSED_SIGNAL], 0); - yui->state &= ~YUI_IS_RUNNING; - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "run"), TRUE); - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "pause"), FALSE); - } -} - -void yui_window_reset(YuiWindow * yui) { - if (yui->state & YUI_IS_INIT) { - yui->reset_func(); - } -} - -void yui_window_invalidate(YuiWindow * yui) { - - /* Emit a pause signal while already in pause means refresh all debug views */ - - if ( !(yui->state & YUI_IS_RUNNING )) - g_signal_emit(G_OBJECT(yui), yui_window_signals[YUI_WINDOW_PAUSED_SIGNAL], 0); -} - -void yui_window_set_fullscreen(YuiWindow * yui, gboolean f) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "fullscreen"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), f); -} - -void yui_window_set_frameskip(YuiWindow * yui, gboolean f) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "frameskip"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), f); -} diff --git a/yabause/src/gtk/yuiwindow.h b/yabause/src/gtk/yuiwindow.h deleted file mode 100644 index c0aa0da364..0000000000 --- a/yabause/src/gtk/yuiwindow.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_WINDOW_H -#define YUI_WINDOW_H - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_WINDOW_TYPE (yui_window_get_type ()) -#define YUI_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_WINDOW_TYPE, YuiWindow)) -#define YUI_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_WINDOW_TYPE, YuiWindowClass)) -#define IS_YUI_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_WINDOW_TYPE)) -#define IS_YUI_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_WINDOW_TYPE)) - -typedef struct _YuiAction YuiAction; -typedef struct _YuiWindow YuiWindow; -typedef struct _YuiWindowClass YuiWindowClass; - -struct _YuiAction { - guint key; - const char * name; - void (*press)(void); - void (*release)(void); -}; - -#define YUI_IS_INIT 1 -#define YUI_IS_RUNNING 2 - -struct _YuiWindow { - GtkWindow hbox; - - GtkWidget * logpopup; - GtkWidget * box; - GtkWidget * menu; - GtkWidget * area; - GtkWidget * log; - - YuiAction * actions; - gulong clean_handler; - GCallback init_func; - gpointer init_data; - GSourceFunc run_func; - GCallback reset_func; - - guint state; - - GtkActionGroup * action_group; -}; - -struct _YuiWindowClass { - GtkWindowClass parent_class; - - void (* yui_window_running) (YuiWindow * yw); - void (* yui_window_paused) (YuiWindow * yw); -}; - -GType yui_window_get_type (void); -GtkWidget * yui_window_new (YuiAction * act, GCallback ifunc, gpointer idata, - GSourceFunc rfunc, GCallback resetfunc); -void yui_window_update (YuiWindow * yui); -void yui_window_log (YuiWindow * yui, const char * message); -void yui_window_show_log (YuiWindow * yui); -void yui_window_start (YuiWindow * yui); -void yui_window_run (YuiWindow * yui); -void yui_window_pause (YuiWindow * yui); -void yui_window_reset (YuiWindow * yui); -void yui_window_invalidate (YuiWindow * yui); -void yui_window_set_fullscreen(YuiWindow * yui, gboolean f); -void yui_window_set_frameskip(YuiWindow * yui, gboolean f); - -G_END_DECLS - -#endif /* YUI_WINDOW_H */ diff --git a/yabause/src/libyabause/libyabause.sln b/yabause/src/libyabause/libyabause.sln deleted file mode 100644 index db264d091b..0000000000 --- a/yabause/src/libyabause/libyabause.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyabause", "libyabause.vcxproj", "{88FB48B5-EA33-4CA9-B585-C23992C061A8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Debug|Win32.ActiveCfg = Debug|Win32 - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Debug|Win32.Build.0 = Debug|Win32 - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Release|Win32.ActiveCfg = Release|Win32 - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/yabause/src/libyabause/libyabause.vcxproj b/yabause/src/libyabause/libyabause.vcxproj deleted file mode 100644 index 5891c41d48..0000000000 --- a/yabause/src/libyabause/libyabause.vcxproj +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {88FB48B5-EA33-4CA9-B585-C23992C061A8} - Win32Proj - libyabause - - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - false - true - Unicode - - - - - - - - - - - - - true - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) - 4244;4996;4018;4146 - true - false - - - Windows - true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) - - - copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\output\dll\$(TargetFileName) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) - 4244;4996;4018;4146 - true - - - Windows - true - true - true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) - - - copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\output\dll\$(TargetFileName) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/yabause/src/libyabause/libyabause.vcxproj.filters b/yabause/src/libyabause/libyabause.vcxproj.filters deleted file mode 100644 index 3c30dacc79..0000000000 --- a/yabause/src/libyabause/libyabause.vcxproj.filters +++ /dev/null @@ -1,270 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/yabause/src/libyabause/yui.cpp b/yabause/src/libyabause/yui.cpp deleted file mode 100644 index df2b049671..0000000000 --- a/yabause/src/libyabause/yui.cpp +++ /dev/null @@ -1,610 +0,0 @@ -//bizhawk -#define HEADLESS - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include "../windows/glext.h" - -extern "C" { -#include "../cs0.h" -#include "../m68kcore.h" -#include "../peripheral.h" -#include "../vidsoft.h" -#include "../vdp2.h" -#include "../yui.h" -#include "../movie.h" -#include "../vidogl.h" -} - -void (*inputcallback)(void) = NULL; - -extern "C" __declspec(dllexport) void libyabause_setinputcallback(void (*cb)(void)) -{ - inputcallback = cb; -} - -void (*tracecallback)(const char* dis, const char* regs) = NULL; - -extern "C" __declspec(dllexport) void libyabause_settracecallback(void (*cb)(const char* dis, const char* regs)) -{ - tracecallback = cb; -} - -CDInterface FECD = -{ - 2, - "FECD", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - -SoundInterface_struct FESND; - - -extern "C" SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -NULL -}; - -extern "C" PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -extern "C" CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -&FECD, -NULL -}; - -extern "C" SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -&FESND, -NULL -}; - -extern "C" VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDOGL, -&VIDSoft, -NULL -}; - -extern "C" M68K_struct *M68KCoreList[] = { -&M68KDummy, -&M68KC68K, -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -/* If Yabause encounters any fatal errors, it sends the error text to this function */ -void YuiErrorMsg(const char *string) -{ - MessageBoxA(NULL, string, "Yabooze dun goofed", 0); -} - - -int red_size; -int green_size; -int blue_size; -int depth_size; - -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; -PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; -PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; - -int LoadExtensions() -{ - glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbufferEXT"); - if( glBindRenderbuffer == NULL ) return 0; - glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); - if(glDeleteRenderbuffers==NULL) return 0; - glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffersEXT"); - if( glGenRenderbuffers == NULL ) return 0; - glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorageEXT"); - if( glRenderbufferStorage == NULL ) return 0; - glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebufferEXT"); - if( glBindFramebuffer==NULL) return 0; - glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); - if( glDeleteFramebuffers==NULL) return 0; - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffersEXT"); - if( glGenFramebuffers == NULL ) return 0; - glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); - if( glCheckFramebufferStatus == NULL ) return 0; - glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); - if( glFramebufferRenderbuffer == NULL ) return 0; - - return 1; -} - -/* Sets attribute for the Video display. The values passed to this function - depends on what Video core is being used at the time. This may end up - being moved to the Video Core. */ -void YuiSetVideoAttribute(int type, int val) -{ - // only called in GL mode - switch (type) - { - case RED_SIZE: - red_size = val; - break; - case GREEN_SIZE: - green_size = val; - break; - case BLUE_SIZE: - blue_size = val; - break; - case DEPTH_SIZE: - depth_size = val; - break; - case DOUBLEBUFFER: - break; - } -} - - -GLuint fbuff = 0; -GLuint color = 0; -GLuint depth = 0; - -int glwidth, glheight; - -u8 *glbuff = NULL; - -/* Tells the yui it wants to setup the display to display the specified video - format. It's up to the yui to setup the actual display. This may end - up being moved to the Video Core. */ -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) -{ - // only called in GL mode - if (bpp != 32 || red_size != 8 || green_size != 8 || blue_size != 8 || depth_size != 24) - return -1; // failure - - if (fbuff) - glDeleteFramebuffers(1, &fbuff); - if (color) - glDeleteRenderbuffers(1, &color); - if (depth) - glDeleteRenderbuffers(1, &depth); - glGenFramebuffers(1, &fbuff); - glGenRenderbuffers(1, &color); - glGenRenderbuffers(1, &depth); - - glBindFramebuffer(GL_FRAMEBUFFER, fbuff); - - glBindRenderbuffer(GL_RENDERBUFFER, depth); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); - - glBindRenderbuffer(GL_RENDERBUFFER, color); - glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, width, height); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color); - - //glBindRenderbuffer(GL_RENDERBUFFER, 0); - - if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - return -1; - - glwidth = width; - glheight = height; - - if (glbuff) - free(glbuff); - glbuff = (u8*) malloc(glwidth * glheight * 4); - - return 0; // success -} - -int usinggl = 0; -HWND glWND; -HDC glDC; -HGLRC glRC; - -void KillGLContext() -{ - wglMakeCurrent(NULL, NULL); - wglDeleteContext(glRC); - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); -} - -int StartGLContext() -{ - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_SUPPORT_OPENGL; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cAlphaBits = 8; - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; - pfd.iLayerType = PFD_MAIN_PLANE; - - glWND = CreateWindow(L"EDIT", 0, 0, 0, 0, 512, 512, 0, 0, 0, 0); - if (!glWND) - return 0; - glDC = GetDC(glWND); - if (!glDC) - { - DestroyWindow(glWND); - return 0; - } - int PixelFormat = ChoosePixelFormat(glDC, &pfd); - if (!PixelFormat) - { - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - if (!SetPixelFormat(glDC, PixelFormat, &pfd)) - { - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - glRC = wglCreateContext(glDC); - if (!glRC) - { - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - if (!wglMakeCurrent(glDC, glRC)) - { - wglDeleteContext(glRC); - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - return 1; -} - - - -s16 *sndbuff = NULL; -int sndbuffpos = 0; -u32 *vidbuff = NULL; - -PerPad_struct *ctrl1; -PerPad_struct *ctrl2; - -extern "C" int vdp2height; -extern "C" int vdp2width; -extern "C" GLuint FboTexture; - -/* Tells the yui to exchange front and back video buffers. This may end - up being moved to the Video Core. */ -void YuiSwapBuffers(void) -{ - if (vidbuff) - { - if (!usinggl) - { - u8 *src = (u8*)dispbuffer; - u8 *dst = (u8*)vidbuff; - - for (int j = 0; j < vdp2height; j++) - for (int i = 0; i < vdp2width; i++) - { - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = 0xff; - src += 4; - dst += 4; - } - } - else - { - #ifdef CAN_RETURN_TEXTURE_IDS - //simply write the FboTexture into the videobuffer for later magic detection in frontend - memcpy(vidbuff,&FboTexture,4); - #else - glReadPixels(0, 0, glwidth, glheight, GL_BGRA, GL_UNSIGNED_BYTE, glbuff); - - u32 *src = (u32*)glbuff; - u32 *dst = (u32*)vidbuff; - - dst += glwidth * (glheight - 1); - - for (int j = 0; j < glheight; j++) - { - memcpy(dst, src, glwidth * 4); - src += glwidth; - dst -= glwidth; - } - #endif - } - } -} - -static void FESNDUpdateAudio(UNUSED u32 *leftchanbuffer, UNUSED u32 *rightchanbuffer, UNUSED u32 num_samples) -{ - /* - static s16 stereodata16[44100 / 50]; - ScspConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)stereodata16, num_samples); - */ -} - -static u32 FESNDGetAudioSpace(void) -{ - return 44100; -} -// some garbage from the sound system, we'll have to fix this all up -extern "C" void DRV_AviSoundUpdate(void* soundData, int soundLen) -{ - // soundLen should be number of sample pairs (4 byte units) - if (sndbuff) - { - s16 *src = (s16*)soundData; - s16 *dst = sndbuff; - dst += sndbuffpos * 2; - memcpy (dst, src, soundLen * 4); - sndbuffpos += soundLen; - } -} - -// must hold at least 704x512 pixels -extern "C" __declspec(dllexport) void libyabause_setvidbuff(u32 *buff) -{ - vidbuff = buff; -} - -extern "C" __declspec(dllexport) void libyabause_setsndbuff(s16 *buff) -{ - sndbuff = buff; -} - -extern "C" __declspec(dllexport) void libyabause_softreset() -{ - YabauseResetButton(); -} - -extern "C" __declspec(dllexport) void libyabause_hardreset() -{ - YabauseReset(); -} - -extern "C" __declspec(dllexport) int libyabause_loadstate(const char *fn) -{ - return !YabLoadState(fn); -} - -extern "C" __declspec(dllexport) int libyabause_savestate(const char *fn) -{ - return !YabSaveState(fn); -} - -extern "C" __declspec(dllexport) int libyabause_savesaveram(const char *fn) -{ - return !T123Save(BupRam, 0x10000, 1, fn); -} - -extern "C" __declspec(dllexport) int libyabause_loadsaveram(const char *fn) -{ - return !T123Load(BupRam, 0x10000, 1, fn); -} - -extern "C" __declspec(dllexport) int libyabause_saveramodified() -{ - return BupRamWritten; -} - -extern "C" __declspec(dllexport) void libyabause_clearsaveram() -{ - FormatBackupRam(BupRam, 0x10000); -} - -typedef struct -{ - void *data; - const char *name; - int length; -} memoryarea; - -memoryarea normmemareas[] = -{ - {NULL, "Boot Rom", 512 * 1024}, - {NULL, "Backup Ram", 64 * 1024}, - {NULL, "Work Ram Low", 1024 * 1024}, - {NULL, "Sound Ram", 512 * 1024}, - {NULL, "VDP1 Ram", 512 * 1024}, - {NULL, "VDP1 Framebuffer", 512 * 1024}, - {NULL, "VDP2 Ram", 512 * 1024}, - {NULL, "VDP2 CRam", 4 * 1024}, - {NULL, "Work Ram High", 1024 * 1024}, - {NULL, NULL, 0} -}; - -extern "C" __declspec(dllexport) memoryarea *libyabause_getmemoryareas() -{ - normmemareas[0].data = BiosRom; - normmemareas[1].data = BupRam; - normmemareas[2].data = LowWram; - normmemareas[3].data = SoundRam; - normmemareas[4].data = Vdp1Ram; - normmemareas[5].data = Vdp1FrameBuffer; - normmemareas[6].data = Vdp2Ram; - normmemareas[7].data = Vdp2ColorRam; - normmemareas[8].data = HighWram; - return &normmemareas[0]; -} - -extern "C" __declspec(dllexport) int libyabause_frameadvance(int *w, int *h, int *nsamp) -{ - LagFrameFlag = 1; - sndbuffpos = 0; - YabauseEmulate(); - if (usinggl) - { - *w = glwidth; - *h = glheight; - } - else - { - *w = vdp2width; - *h = vdp2height; - } - *nsamp = sndbuffpos; - return LagFrameFlag; -} - -extern "C" __declspec(dllexport) void libyabause_deinit() -{ - PerPortReset(); - YabauseDeInit(); - if (usinggl) - { - KillGLContext(); - usinggl = 0; - } - if (glbuff) - { - free(glbuff); - glbuff = NULL; - } -} - -extern "C" __declspec(dllexport) void libyabause_setpads(u8 p11, u8 p12, u8 p21, u8 p22) -{ - ctrl1->padbits[0] = p11; - ctrl1->padbits[1] = p12; - ctrl2->padbits[0] = p21; - ctrl2->padbits[1] = p22; -} - -int glnativefactor = 0; - -extern "C" __declspec(dllexport) void libyabause_glresize(int w, int h) -{ - if (usinggl && !glnativefactor) - VIDCore->Resize(w, h, 0); -} - -extern "C" __declspec(dllexport) void libyabause_glsetnativefactor(int n) -{ - if (!usinggl) - return; - if (n > 4) - n = 4; - if (n < 0) - n = 0; - glnativefactor = n; - if (n) - VIDCore->Resize(vdp2width_gl * n, vdp2height_gl * n, 0); -} - -void (*vdp2hookfcn)(u16 v) = NULL; - -void vdp2newhook(u16 v) -{ - vdp2hookfcn(v); - if (glnativefactor) - { - if (glwidth != vdp2width_gl * glnativefactor || glheight != vdp2height_gl * glnativefactor) - VIDCore->Resize(vdp2width_gl * glnativefactor, vdp2height_gl * glnativefactor, 0); - } -} - -extern "C" __declspec(dllexport) int libyabause_init -( - CDInterface *_CD, - const char *biosfn, - int usegl, - int carttype, - int quickload, - int clocksync, - int clockbase -) -{ - usinggl = usegl; - - if (usegl) - { - //headless cores should not create GL contexts, but use the one from the invoking frontend - #ifndef HEADLESS - if(!StartGLContext()) - return 0; - #endif - if(!LoadExtensions()) - return 0; - } - - FECD.DeInit = _CD->DeInit; - FECD.GetStatus = _CD->GetStatus; - FECD.Init = _CD->Init; - FECD.ReadAheadFAD = _CD->ReadAheadFAD; - FECD.ReadSectorFAD = _CD->ReadSectorFAD; - FECD.ReadTOC = _CD->ReadTOC; - - // only overwrite a few SNDDummy functions - memcpy(&FESND, &SNDDummy, sizeof(FESND)); - FESND.id = 2; - FESND.Name = "FESND"; - FESND.GetAudioSpace = FESNDGetAudioSpace; - FESND.UpdateAudio = FESNDUpdateAudio; - - yabauseinit_struct yinit; - memset(&yinit, 0, sizeof(yabauseinit_struct)); - yinit.percoretype = PERCORE_DUMMY; - yinit.sh2coretype = SH2CORE_INTERPRETER; - if (usegl) - yinit.vidcoretype = VIDCORE_OGL; - else - yinit.vidcoretype = VIDCORE_SOFT; - yinit.sndcoretype = 2; //SNDCORE_DUMMY; - yinit.cdcoretype = 2; // CDCORE_ISO; //CDCORE_DUMMY; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.cartpath = CART_NONE; - yinit.regionid = REGION_AUTODETECT; - yinit.biospath = biosfn; - yinit.cdpath = "Saturnus"; //NULL; - yinit.buppath = NULL; - yinit.mpegpath = NULL; - yinit.carttype = carttype; - yinit.netlinksetting = NULL; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yabsys.usequickload = quickload; - yinit.usethreads = 0; - yinit.frameskip = 0; - yinit.clocksync = clocksync; - yinit.basetime = clockbase; // same format as return from time(); 0 to use time() - - if (usegl && !vdp2hookfcn) - { - // hook vdp2setresolution - vdp2hookfcn = VIDOGL.Vdp2SetResolution; - VIDOGL.Vdp2SetResolution = vdp2newhook; - } - - if (YabauseInit(&yinit) != 0) - return 0; - - SpeedThrottleDisable(); - DisableAutoFrameSkip(); - ScspSetFrameAccurate(1); - - OSDChangeCore(OSDCORE_DUMMY); - - ctrl1 = PerPadAdd(&PORTDATA1); - ctrl2 = PerPadAdd(&PORTDATA2); - - return 1; -} diff --git a/yabause/src/logo.bmp b/yabause/src/logo.bmp deleted file mode 100644 index 5fc521042a..0000000000 Binary files a/yabause/src/logo.bmp and /dev/null differ diff --git a/yabause/src/logo.png b/yabause/src/logo.png deleted file mode 100644 index bfa6208a0c..0000000000 Binary files a/yabause/src/logo.png and /dev/null differ diff --git a/yabause/src/logo.svg b/yabause/src/logo.svg deleted file mode 100644 index 68062d74e2..0000000000 --- a/yabause/src/logo.svg +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Yabause Logo - - - - - - - - - - - - - - - - - - - diff --git a/yabause/src/m68kc68k.c b/yabause/src/m68kc68k.c deleted file mode 100644 index 5ab05390f5..0000000000 --- a/yabause/src/m68kc68k.c +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "m68kc68k.h" -#include "c68k/c68k.h" -#include "memory.h" -#include "yabause.h" - -/** - * PROFILE_68K: Perform simple profiling of the 68000 emulation, reporting - * the average time per 68000 clock cycle. (Realtime execution would be - * around 88.5 nsec/cycle.) - */ -// #define PROFILE_68K - - -static u8 *SoundDummy=NULL; - -static int M68KC68KInit(void) { - int i; - - // Setup a 64k buffer filled with invalid 68k instructions to serve - // as a default map - if ((SoundDummy = T2MemoryInit(0x10000)) != NULL) - memset(SoundDummy, 0xFF, 0x10000); - - C68k_Init(&C68K, NULL); // not sure if I need the int callback or not - - for (i = 0x10; i < 0x100; i++) - M68K->SetFetch(i << 16, (i << 16) + 0xFFFF, (pointer)SoundDummy); - - return 0; -} - -static void M68KC68KDeInit(void) { - if (SoundDummy) - T2MemoryDeInit(SoundDummy); - SoundDummy = NULL; -} - -static void M68KC68KReset(void) { - C68k_Reset(&C68K); -} - -static s32 FASTCALL M68KC68KExec(s32 cycle) { -#ifdef PROFILE_68K - static u32 tot_cycles = 0, tot_usec = 0, tot_ticks = 0, last_report = 0; - u32 start, end; - start = (u32) YabauseGetTicks(); - int retval = C68k_Exec(&C68K, cycle); - end = (u32) YabauseGetTicks(); - tot_cycles += cycle; - tot_ticks += end - start; - if (tot_cycles/1000000 > last_report) { - tot_usec += (u64)tot_ticks * 1000000 / yabsys.tickfreq; - tot_ticks = 0; - fprintf(stderr, "%ld cycles in %.3f sec = %.3f nsec/cycle\n", - (long)tot_cycles, (double)tot_usec/1000000, - ((double)tot_usec / (double)tot_cycles) * 1000); - last_report = tot_cycles/1000000; - } - return retval; -#else - return C68k_Exec(&C68K, cycle); -#endif -} - -static void M68KC68KSync(void) { -} - -static u32 M68KC68KGetDReg(u32 num) { - return C68k_Get_DReg(&C68K, num); -} - -static u32 M68KC68KGetAReg(u32 num) { - return C68k_Get_AReg(&C68K, num); -} - -static u32 M68KC68KGetPC(void) { - return C68k_Get_PC(&C68K); -} - -static u32 M68KC68KGetSR(void) { - return C68k_Get_SR(&C68K); -} - -static u32 M68KC68KGetUSP(void) { - return C68k_Get_USP(&C68K); -} - -static u32 M68KC68KGetMSP(void) { - return C68k_Get_MSP(&C68K); -} - -static void M68KC68KSetDReg(u32 num, u32 val) { - C68k_Set_DReg(&C68K, num, val); -} - -static void M68KC68KSetAReg(u32 num, u32 val) { - C68k_Set_AReg(&C68K, num, val); -} - -static void M68KC68KSetPC(u32 val) { - C68k_Set_PC(&C68K, val); -} - -static void M68KC68KSetSR(u32 val) { - C68k_Set_SR(&C68K, val); -} - -static void M68KC68KSetUSP(u32 val) { - C68k_Set_USP(&C68K, val); -} - -static void M68KC68KSetMSP(u32 val) { - C68k_Set_MSP(&C68K, val); -} - -static void M68KC68KSetFetch(u32 low_adr, u32 high_adr, pointer fetch_adr) { - C68k_Set_Fetch(&C68K, low_adr, high_adr, fetch_adr); -} - -static void FASTCALL M68KC68KSetIRQ(s32 level) { - C68k_Set_IRQ(&C68K, level); -} - -static void FASTCALL M68KC68KWriteNotify(u32 address, u32 size) { - /* nothing to do */ -} - -static void M68KC68KSetReadB(M68K_READ *Func) { - C68k_Set_ReadB(&C68K, Func); -} - -static void M68KC68KSetReadW(M68K_READ *Func) { - C68k_Set_ReadW(&C68K, Func); -} - -static void M68KC68KSetWriteB(M68K_WRITE *Func) { - C68k_Set_WriteB(&C68K, Func); -} - -static void M68KC68KSetWriteW(M68K_WRITE *Func) { - C68k_Set_WriteW(&C68K, Func); -} - -M68K_struct M68KC68K = { - 1, - "C68k Interface", - M68KC68KInit, - M68KC68KDeInit, - M68KC68KReset, - M68KC68KExec, - M68KC68KSync, - M68KC68KGetDReg, - M68KC68KGetAReg, - M68KC68KGetPC, - M68KC68KGetSR, - M68KC68KGetUSP, - M68KC68KGetMSP, - M68KC68KSetDReg, - M68KC68KSetAReg, - M68KC68KSetPC, - M68KC68KSetSR, - M68KC68KSetUSP, - M68KC68KSetMSP, - M68KC68KSetFetch, - M68KC68KSetIRQ, - M68KC68KWriteNotify, - M68KC68KSetReadB, - M68KC68KSetReadW, - M68KC68KSetWriteB, - M68KC68KSetWriteW -}; diff --git a/yabause/src/m68kc68k.h b/yabause/src/m68kc68k.h deleted file mode 100644 index a179715918..0000000000 --- a/yabause/src/m68kc68k.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef M68KC68K_H -#define M68KC68K_H - -#include "m68kcore.h" - -extern M68K_struct M68KC68K; - -#endif diff --git a/yabause/src/m68kcore.c b/yabause/src/m68kcore.c deleted file mode 100644 index 614c8e3562..0000000000 --- a/yabause/src/m68kcore.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "m68kcore.h" -#include "m68kc68k.h" -#include "memory.h" - -extern u8 * SoundRam; - -M68K_struct * M68K = NULL; - -extern M68K_struct * M68KCoreList[]; - -int M68KInit(int coreid) { - int i; - - M68K = &M68KDummy; - - // Go through core list and find the id - for (i = 0; M68KCoreList[i] != NULL; i++) - { - if (M68KCoreList[i]->id == coreid) - { - // Set to current core - M68K = M68KCoreList[i]; - break; - } - } - - return 0; -} - -static int M68KDummyInit(void) { - return 0; -} - -static void M68KDummyDeInit(void) { -} - -static void M68KDummyReset(void) { -} - -static s32 FASTCALL M68KDummyExec(UNUSED s32 cycle) { - T2WriteWord(SoundRam, 0x700, 0); - T2WriteWord(SoundRam, 0x710, 0); - T2WriteWord(SoundRam, 0x720, 0); - T2WriteWord(SoundRam, 0x730, 0); - T2WriteWord(SoundRam, 0x740, 0); - T2WriteWord(SoundRam, 0x750, 0); - T2WriteWord(SoundRam, 0x760, 0); - T2WriteWord(SoundRam, 0x770, 0); - - T2WriteWord(SoundRam, 0x790, 0); - T2WriteWord(SoundRam, 0x792, 0); - return 0; -} - -static void M68KDummySync(void) { -} - -static u32 M68KDummyGetDReg(UNUSED u32 num) { - return 0; -} - -static u32 M68KDummyGetAReg(UNUSED u32 num) { - return 0; -} - -static u32 M68KDummyGetPC(void) { - return 0; -} - -static u32 M68KDummyGetSR(void) { - return 0; -} - -static u32 M68KDummyGetUSP(void) { - return 0; -} - -static u32 M68KDummyGetMSP(void) { - return 0; -} - -static void M68KDummySetDReg(UNUSED u32 num, UNUSED u32 val) { -} - -static void M68KDummySetAReg(UNUSED u32 num, UNUSED u32 val) { -} - -static void M68KDummySetPC(UNUSED u32 val) { -} - -static void M68KDummySetSR(UNUSED u32 val) { -} - -static void M68KDummySetUSP(UNUSED u32 val) { -} - -static void M68KDummySetMSP(UNUSED u32 val) { -} - -static void M68KDummySetFetch(UNUSED u32 low_adr, UNUSED u32 high_adr, UNUSED pointer fetch_adr) { -} - -static void FASTCALL M68KDummySetIRQ(UNUSED s32 level) { -} - -static void FASTCALL M68KDummyWriteNotify(u32 address, u32 size) { -} - -static void M68KDummySetReadB(UNUSED M68K_READ *Func) { -} - -static void M68KDummySetReadW(UNUSED M68K_READ *Func) { -} - -static void M68KDummySetWriteB(UNUSED M68K_WRITE *Func) { -} - -static void M68KDummySetWriteW(UNUSED M68K_WRITE *Func) { -} - -M68K_struct M68KDummy = { - 0, - "Dummy 68k Interface", - M68KDummyInit, - M68KDummyDeInit, - M68KDummyReset, - M68KDummyExec, - M68KDummySync, - M68KDummyGetDReg, - M68KDummyGetAReg, - M68KDummyGetPC, - M68KDummyGetSR, - M68KDummyGetUSP, - M68KDummyGetMSP, - M68KDummySetDReg, - M68KDummySetAReg, - M68KDummySetPC, - M68KDummySetSR, - M68KDummySetUSP, - M68KDummySetMSP, - M68KDummySetFetch, - M68KDummySetIRQ, - M68KDummyWriteNotify, - M68KDummySetReadB, - M68KDummySetReadW, - M68KDummySetWriteB, - M68KDummySetWriteW -}; diff --git a/yabause/src/m68kcore.h b/yabause/src/m68kcore.h deleted file mode 100644 index e20f88ab3c..0000000000 --- a/yabause/src/m68kcore.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef M68KCORE_H -#define M68KCORE_H - -#include "core.h" - -#define M68KCORE_DEFAULT -1 -#define M68KCORE_DUMMY 0 -#define M68KCORE_C68K 1 -#define M68KCORE_Q68 2 - -typedef u32 FASTCALL M68K_READ(const u32 adr); -typedef void FASTCALL M68K_WRITE(const u32 adr, u32 data); - -typedef struct { - int id; - const char *Name; - - int (*Init)(void); - void (*DeInit)(void); - void (*Reset)(void); - - s32 FASTCALL (*Exec)(s32 cycle); - void (*Sync)(void); - - u32 (*GetDReg)(u32 num); - u32 (*GetAReg)(u32 num); - u32 (*GetPC)(void); - u32 (*GetSR)(void); - u32 (*GetUSP)(void); - u32 (*GetMSP)(void); - - void (*SetDReg)(u32 num, u32 val); - void (*SetAReg)(u32 num, u32 val); - void (*SetPC)(u32 val); - void (*SetSR)(u32 val); - void (*SetUSP)(u32 val); - void (*SetMSP)(u32 val); - - void (*SetFetch)(u32 low_adr, u32 high_adr, pointer fetch_adr); - void FASTCALL (*SetIRQ)(s32 level); - void FASTCALL (*WriteNotify)(u32 address, u32 size); - - void (*SetReadB)(M68K_READ *Func); - void (*SetReadW)(M68K_READ *Func); - void (*SetWriteB)(M68K_WRITE *Func); - void (*SetWriteW)(M68K_WRITE *Func); -} M68K_struct; - -extern M68K_struct * M68K; - -int M68KInit(int coreid); - -extern M68K_struct M68KDummy; -extern M68K_struct M68KC68K; -extern M68K_struct M68KQ68; - -#endif diff --git a/yabause/src/m68kd.c b/yabause/src/m68kd.c deleted file mode 100644 index 735c2315a6..0000000000 --- a/yabause/src/m68kd.c +++ /dev/null @@ -1,1327 +0,0 @@ -/* Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "core.h" -#include "m68kd.h" -#include "scsp.h" // for c68k_word_read() - -typedef struct -{ - u16 mask; - u16 inst; - const char *name; - int (*disasm)(u32, u16, char *); -} m68kdis_struct; - -////////////////////////////////////////////////////////////////////////////// - -static int setsizestr(u16 size, char *outstring) -{ - switch (size & 0x3) - { - case 0x1: - return sprintf(outstring, ".b "); - case 0x3: - return sprintf(outstring, ".w "); - case 0x2: - return sprintf(outstring, ".l "); - default: - return sprintf(outstring, " "); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int setsizestr2(u16 size, char *outstring) -{ - switch (size & 0x3) - { - case 0x0: - return sprintf(outstring, ".b "); - case 0x1: - return sprintf(outstring, ".w "); - case 0x2: - return sprintf(outstring, ".l "); - default: - return sprintf(outstring, " "); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int setimmstr(u32 addr, u16 size, int *addsize, char *outstring) -{ - switch (size & 0x3) - { - case 0x0: - *addsize+=2; - return sprintf(outstring, "#0x%X", (unsigned int)(c68k_word_read(addr) & 0xFF)); - case 0x1: - *addsize+=2; - return sprintf(outstring, "#0x%X", (unsigned int)c68k_word_read(addr)); - case 0x2: - *addsize+=4; - return sprintf(outstring, "#0x%X", (unsigned int)((c68k_word_read(addr) << 16) | c68k_word_read(addr+2))); - default: - return 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int seteafieldstr(u32 addr, u16 modereg, int *addsize, char *outstring) -{ - switch ((modereg >> 3) & 0x7) - { - case 0x0: - // Dn - return sprintf(outstring, "d%d", modereg & 0x7); - case 0x1: - // An - return sprintf(outstring, "a%d", modereg & 0x7); - case 0x2: - // (An) - return sprintf(outstring, "(a%d)", modereg & 0x7); - case 0x3: - // (An)+ - return sprintf(outstring, "(a%d)+", modereg & 0x7); - case 0x4: - // -(An) - return sprintf(outstring, "-(a%d)", modereg & 0x7); - case 0x5: - // (d16, An) - *addsize += 2; - return sprintf(outstring, "0x%X(a%d)", (unsigned int)c68k_word_read(addr), modereg & 0x7); - case 0x6: - // (d8,An,Xn) - // fix me - *addsize += 2; - return sprintf(outstring, "0x%X(a%d, Xn)", (unsigned int)(c68k_word_read(addr) & 0xFF), modereg & 0x7); - case 0x7: - switch (modereg & 0x7) - { - case 0x0: - // (xxx).W - *addsize += 2; // fix me? - return sprintf(outstring, "(0x%X).w", (unsigned int)c68k_word_read(addr)); - case 0x1: - // (xxx).L - *addsize += 4; // fix me? - return sprintf(outstring, "(0x%X).l", (unsigned int)((c68k_word_read(addr) << 16) | c68k_word_read(addr+2))); - case 0x4: - // # - *addsize += 2; // fix me? - return sprintf(outstring, "#0x%X", (unsigned int)c68k_word_read(addr)); - case 0x2: - // (d16,PC) - *addsize += 2; - return sprintf(outstring, "0x%X(PC)", (unsigned int)c68k_word_read(addr)); - case 0x3: - // (d8,PC,Xn) - // fix me - return 0; - default: break; - } - default: break; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int setcondstr(u16 cond, char *outstring) -{ - switch (cond & 0xF) - { - case 0x0: - // True - return sprintf(outstring, "t "); - case 0x1: - // False - return sprintf(outstring, "f "); - case 0x2: - // High - return sprintf(outstring, "hi"); - case 0x3: - // Low or Same - return sprintf(outstring, "ls"); - case 0x4: - // Carry Clear - return sprintf(outstring, "cc"); - case 0x5: - // Carry Set - return sprintf(outstring, "cs"); - case 0x6: - // Not Equal - return sprintf(outstring, "ne"); - case 0x7: - // Equal - return sprintf(outstring, "eq"); - case 0x8: - // Overflow Clear - return sprintf(outstring, "vc"); - case 0x9: - // Overflow Set - return sprintf(outstring, "vs"); - case 0xA: - // Plus - return sprintf(outstring, "pl"); - case 0xB: - // Minus - return sprintf(outstring, "mi"); - case 0xC: - // Greater or Equal - return sprintf(outstring, "ge"); - case 0xD: - // Less Than - return sprintf(outstring, "lt"); - case 0xE: - // Greater Than - return sprintf(outstring, "gt"); - case 0xF: - // Less or Equal - return sprintf(outstring, "le"); - default: break; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int setbranchdispstr(u32 addr, u16 op, int *addsize, char *outstring) -{ - if ((op & 0xFF) == 0xFF) - { - // 32-bit displacement - *addsize += 4; - return sprintf(outstring, ".l %X", (unsigned int)(addr + ((c68k_word_read(addr) << 16) | c68k_word_read(addr+2)))); - } - else if ((op & 0xFF) == 0x00) - { - // 16-bit displacement - *addsize += 2; - return sprintf(outstring, ".w %X", (unsigned int)((s32)addr + (s32)(s16)c68k_word_read(addr))); - } - - // 8-bit displacement - return sprintf(outstring, ".s %X", (unsigned int)((s32)addr + (s32)(s8)(op & 0xFF))); -} - -////////////////////////////////////////////////////////////////////////////// - -static int disabcd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "abcd"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disadd(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "add"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - - if (op & 0x100) - { - // Dn, - outstring += sprintf(outstring, "d%d, ", (op >> 9) & 7); - seteafieldstr(addr+size, op, &size, outstring); - } - else - { - // , Dn - outstring += seteafieldstr(addr+size, op, &size, outstring); - sprintf(outstring, ", d%d", (op >> 9) & 7); - } - - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disadda(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "adda"); - if ((op & 0x1C0) == 0xC0) - outstring += sprintf(outstring, ".w "); - else - outstring += sprintf(outstring, ".l "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disaddi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "addi"); - outstring += setsizestr2(op >> 6, outstring); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disaddq(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "addq"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - outstring += sprintf(outstring, "#%d, ", (op >> 9) & 7); // fix me - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disaddx(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "addx"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disand(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "and"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disandi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "andi"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disanditoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "andi to CCR"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disasl(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "asl"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disasr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "asr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbcc(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "b"); - outstring += setcondstr(op >> 8, outstring); - setbranchdispstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbkpt(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bkpt"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbra(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bra"); - setbranchdispstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbchg(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bchg"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbclrd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bclr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbclrs(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bclr "); - outstring += setimmstr(addr+size, 0, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbsetd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bset"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbsets(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bset "); - outstring += setimmstr(addr+size, 0, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbtstd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "btst"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbtsts(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "btst "); - outstring += setimmstr(addr+size, 0, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbsr(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bsr"); - setbranchdispstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dischk(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "chk"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disclr(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "clr"); - outstring += setsizestr2((op >> 6), outstring); - outstring += sprintf(outstring, " "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disdbcc(u32 addr, u16 op, char *outstring) -{ - outstring += sprintf(outstring, "db"); - outstring += setcondstr(op >> 8, outstring); - outstring += sprintf(outstring, " "); - sprintf(outstring, " d%d, %X", op & 0x7, (unsigned int)((s32)addr+2+(s32)(s16)c68k_word_read(addr+2))); - return 4; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpb(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "cmp.b "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpw(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "cmp.w "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpl(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "cmp.l "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpaw(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpa.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpal(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpa.l"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpi"); - outstring += setsizestr2((op >> 6), outstring); - outstring += sprintf(outstring, " "); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disdivs(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "divs.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disdivu(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "divu.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpm(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpm"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseorb(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eor.b"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseorw(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eor.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseorl(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eor.l"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseori(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eori"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseoritoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "eori to ccr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disexg(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "exg"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disext(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ext"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disillegal(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "illegal"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disjmp(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "jmp "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disjsr(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "jsr "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislea(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "lea "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislink(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "link"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislsl(UNUSED u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "lsl"); - outstring += setsizestr2(op >> 6, outstring); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislsr(UNUSED u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "lsr"); - outstring += setsizestr2(op >> 6, outstring); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismove(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move"); - outstring += setsizestr((op >> 12), outstring); - outstring += sprintf(outstring, " "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, ((op >> 3) & 0x38) | ((op >> 9) & 0x7), &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovea(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "movea"); - outstring += setsizestr((op >> 12), outstring); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovetoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move to ccr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovefromsr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move from sr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovetosr(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - sprintf(outstring, ", sr"); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovem(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - outstring += sprintf(outstring, "movem"); - // fix me - return 4; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovep(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "movep"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismoveq(UNUSED u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "moveq #0x%X, d%d", op & 0xFF, (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismuls(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "muls"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismulu(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "mulu"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnbcd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "nbcd"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disneg(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "neg"); - outstring += setsizestr2((op >> 6), outstring); - outstring += sprintf(outstring, " "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnegx(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "negx"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnop(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "nop"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnot(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "not"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disor(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ori to CCR"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disori(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ori"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disoritoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ori to CCR"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dispea(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "pea"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disrol(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "rol"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disror(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ror"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disroxl(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "roxl"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disroxr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "roxr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disrtr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "rtr"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disrts(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "rts"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissbcd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "sbcd"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disscc(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "scc"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissub(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "sub"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissuba(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "suba"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissubi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "subi"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissubq(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "subq"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " #%d, ", (op >> 9) & 7); // fix me - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissubx(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "subx"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disswap(UNUSED u32 addr, u16 op, char *outstring) -{ - sprintf(outstring, "swap d%d", op & 0x7); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distas(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "tas"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distrap(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "trap"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distrapv(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "trapv"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distst(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "tst"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disunlk(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "unlk"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static m68kdis_struct instruction[] = { - { 0xFFFF, 0x023C, "andi #??, CCR", disanditoccr }, - { 0xFFFF, 0x0A3C, "eori #??, CCR", diseoritoccr }, - { 0xFFFF, 0x4AFC, "illegal", disillegal }, - { 0xFFFF, 0x4E71, "nop", disnop }, - { 0xFFFF, 0x003C, "ori #??, CCR", disoritoccr }, - { 0xFFFF, 0x4E77, "rtr", disrtr }, - { 0xFFFF, 0x4E75, "rts", disrts }, - { 0xFFFF, 0x4E76, "trapv", distrapv }, - { 0xFFF8, 0x4848, "bkpt", disbkpt }, - { 0xFFF8, 0x4E50, "link", dislink }, - { 0xFFF8, 0x4840, "swap", disswap }, - { 0xFFF8, 0x4E58, "unlk", disunlk }, - { 0xFFF0, 0x4E40, "trap", distrap }, - { 0xF1F8, 0xD100, "addx.b", disaddx }, - { 0xF1F8, 0xD140, "addx.w", disaddx }, - { 0xF1F8, 0xD180, "addx.l", disaddx }, - { 0xF1F8, 0xB108, "cmpm.b", discmpm }, - { 0xF1F8, 0xB148, "cmpm.w", discmpm }, - { 0xF1F8, 0xB188, "cmpm.l", discmpm }, - { 0xFFC0, 0xE1C0, "asl", disasl }, - { 0xFFC0, 0xE0C0, "asr", disasr }, - { 0xFFC0, 0x0880, "bclr", disbclrs }, - { 0xFFC0, 0x08C0, "bset", disbsets }, - { 0xFFC0, 0x0800, "btst", disbtsts }, - { 0xFFC0, 0x4EC0, "jmp", disjmp }, - { 0xFFC0, 0x4E80, "jsr", disjsr }, - { 0xFFC0, 0x44C0, "move ??, CCR", dismovetoccr }, - { 0xFFC0, 0x40C0, "move SR, ??", dismovefromsr }, - { 0xFFC0, 0x46C0, "move ??, SR", dismovetosr }, - { 0xFFC0, 0x4800, "nbcd", disnbcd }, - { 0xFFC0, 0x4840, "pea", dispea }, - { 0xFFC0, 0x4AC0, "tas", distas }, - { 0xFE38, 0x4800, "ext", disext }, - { 0xF1F0, 0xC100, "abcd", disabcd }, - { 0xF1F0, 0x8100, "sbcd", dissbcd }, - { 0xF0F8, 0x50C8, "dbcc", disdbcc }, - { 0xFB80, 0x4880, "movem", dismovem }, - { 0xFF00, 0x0600, "addi", disaddi }, - { 0xFF00, 0x0200, "andi", disandi }, - { 0xFF00, 0x6000, "bra", disbra }, - { 0xFF00, 0x6100, "bsr", disbsr }, - { 0xFF00, 0x4200, "clr", disclr }, - { 0xFF00, 0x0C00, "cmpi", discmpi }, - { 0xFF00, 0x0A00, "eori", diseori }, - { 0xFF00, 0x4400, "neg", disneg }, - { 0xFF00, 0x4000, "negx", disnegx }, - { 0xFF00, 0x4600, "not", disnot }, - { 0xFF00, 0x0000, "ori", disori }, - { 0xFF00, 0x0400, "subi", dissubi }, - { 0xFF00, 0x4A00, "tst", distst }, - { 0xF118, 0xE108, "lsl", dislsl }, - { 0xF118, 0xE008, "lsr", dislsr }, - { 0xF118, 0xE118, "rol", disrol }, - { 0xF118, 0xE018, "ror", disror }, - { 0xF118, 0xE110, "roxl", disroxl }, - { 0xF118, 0xE010, "roxr", disroxr }, - { 0xF1C0, 0xD0C0, "adda.w", disadda }, - { 0xF1C0, 0xD1C0, "adda.l", disadda }, - { 0xF1C0, 0x0140, "bchg", disbchg }, - { 0xF1C0, 0x0180, "bclr", disbclrd }, - { 0xF1C0, 0x01C0, "bset", disbsetd }, - { 0xF1C0, 0x0100, "btst", disbtstd }, - { 0xF1C0, 0xB000, "cmp.b", discmpb }, - { 0xF1C0, 0xB040, "cmp.w", discmpw }, - { 0xF1C0, 0xB080, "cmp.l", discmpl }, - { 0xF1C0, 0xB0C0, "cmpa.w", discmpaw }, - { 0xF1C0, 0xB1C0, "cmpa.l", discmpal }, - { 0xF1C0, 0x81C0, "divs.w", disdivs }, - { 0xF1C0, 0x80C0, "divu.w", disdivu }, - { 0xF1C0, 0xB100, "eor.b", diseorb }, - { 0xF1C0, 0xB140, "eor.w", diseorw }, - { 0xF1C0, 0xB180, "eor.l", diseorl }, - { 0xF1C0, 0x41C0, "lea", dislea }, - { 0xF1C0, 0xC1C0, "muls", dismuls }, - { 0xF1C0, 0xC0C0, "mulu", dismulu }, - { 0xF130, 0x9100, "subx", dissubx }, - { 0xF038, 0x0008, "movep", dismovep }, - { 0xF0C0, 0x50C0, "scc", disscc }, - { 0xC1C0, 0x0040, "movea", dismovea }, - { 0xF040, 0x4000, "chk", dischk }, - { 0xF100, 0x5000, "addq", disaddq }, - { 0xF100, 0xC100, "exg", disexg }, - { 0xF100, 0x7000, "moveq", dismoveq }, - { 0xF100, 0x5100, "subq", dissubq }, - { 0xF000, 0xD000, "add", disadd }, // fix me - { 0xF000, 0xC000, "and", disand }, - { 0xF000, 0x6000, "bcc", disbcc }, - { 0xF000, 0x8000, "or", disor }, - { 0xF000, 0x9000, "sub", dissub }, // fix me - { 0xF000, 0x9000, "suba", dissuba }, // fix me - { 0xC000, 0x0000, "move", dismove }, - { 0x0000, 0x0000, NULL, NULL } -}; - -////////////////////////////////////////////////////////////////////////////// - -u32 M68KDisasm(u32 addr, char *outstring) -{ - int i; - - outstring += sprintf(outstring, "%05X: ", (unsigned int)addr); - - for (i = 0; instruction[i].name != NULL; i++) - { - u16 op = (u16)c68k_word_read(addr); - - if ((op & instruction[i].mask) == instruction[i].inst) - { - addr += instruction[i].disasm(addr, op, outstring); - return addr; - } - } - - sprintf(outstring, "unknown"); - return (addr+2); -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/m68kd.h b/yabause/src/m68kd.h deleted file mode 100644 index 16383e901e..0000000000 --- a/yabause/src/m68kd.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2004 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef M68KD_H -#define M68KD_H - -#include "core.h" - -u32 M68KDisasm(u32 addr, char *outstring); - -#endif diff --git a/yabause/src/m68kq68.c b/yabause/src/m68kq68.c deleted file mode 100644 index 0f1605112f..0000000000 --- a/yabause/src/m68kq68.c +++ /dev/null @@ -1,534 +0,0 @@ -/* src/m68kpsp.c: Q68 emulator interface - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yabause.h" -#include "m68kcore.h" - -#include "q68/q68.h" - -/*************************************************************************/ - -/** - * NEED_TRAMPOLINE: Defined on platforms where we need trampoline - * functions to convert read/write calls from the native format to the - * FASTCALL format used by Yabause. - */ -#ifdef CPU_X86 -# define NEED_TRAMPOLINE -#endif - -/** - * PROFILE_68K: Perform simple profiling of the 68000 emulation, reporting - * the average time per 68000 clock cycle. (Realtime execution would be - * around 88.5 nsec/cycle.) - * - * Note that this profiling has an overhead of two YabauseGetTicks() calls - * for each M68K->Exec() call; on PSP, this amounts to about 3.8 usec per - * Exec(), or 52.8 nsec/cycle at 72 cycles/call. - */ -// #define PROFILE_68K - -// #define COUNT_OPCODES // see COUNT_OPCODES in q68-core.c - -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int m68kq68_init(void); -static void m68kq68_deinit(void); -static void m68kq68_reset(void); - -static FASTCALL s32 m68kq68_exec(s32 cycles); -static void m68kq68_sync(void); - -static u32 m68kq68_get_dreg(u32 num); -static u32 m68kq68_get_areg(u32 num); -static u32 m68kq68_get_pc(void); -static u32 m68kq68_get_sr(void); -static u32 m68kq68_get_usp(void); -static u32 m68kq68_get_ssp(void); - -static void m68kq68_set_dreg(u32 num, u32 val); -static void m68kq68_set_areg(u32 num, u32 val); -static void m68kq68_set_pc(u32 val); -static void m68kq68_set_sr(u32 val); -static void m68kq68_set_usp(u32 val); -static void m68kq68_set_ssp(u32 val); - -static FASTCALL void m68kq68_set_irq(s32 level); -static FASTCALL void m68kq68_write_notify(u32 address, u32 size); - -static void m68kq68_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr); -static void m68kq68_set_readb(M68K_READ *func); -static void m68kq68_set_readw(M68K_READ *func); -static void m68kq68_set_writeb(M68K_WRITE *func); -static void m68kq68_set_writew(M68K_WRITE *func); - -static uint32_t dummy_read(uint32_t address); -static void dummy_write(uint32_t address, uint32_t data); - -#ifdef NEED_TRAMPOLINE -static uint32_t readb_trampoline(uint32_t address); -static uint32_t readw_trampoline(uint32_t address); -static void writeb_trampoline(uint32_t address, uint32_t data); -static void writew_trampoline(uint32_t address, uint32_t data); -#endif - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -M68K_struct M68KQ68 = { - .id = M68KCORE_Q68, - .Name = "Q68 68k Emulator Interface", - - .Init = m68kq68_init, - .DeInit = m68kq68_deinit, - .Reset = m68kq68_reset, - - .Exec = m68kq68_exec, - .Sync = m68kq68_sync, - - .GetDReg = m68kq68_get_dreg, - .GetAReg = m68kq68_get_areg, - .GetPC = m68kq68_get_pc, - .GetSR = m68kq68_get_sr, - .GetUSP = m68kq68_get_usp, - .GetMSP = m68kq68_get_ssp, - - .SetDReg = m68kq68_set_dreg, - .SetAReg = m68kq68_set_areg, - .SetPC = m68kq68_set_pc, - .SetSR = m68kq68_set_sr, - .SetUSP = m68kq68_set_usp, - .SetMSP = m68kq68_set_ssp, - - .SetIRQ = m68kq68_set_irq, - .WriteNotify = m68kq68_write_notify, - - .SetFetch = m68kq68_set_fetch, - .SetReadB = m68kq68_set_readb, - .SetReadW = m68kq68_set_readw, - .SetWriteB = m68kq68_set_writeb, - .SetWriteW = m68kq68_set_writew, -}; - -/*-----------------------------------------------------------------------*/ - -/* Virtual processor state block */ - -static Q68State *state; - - -#ifdef NEED_TRAMPOLINE - -/* Read/write functions passed to Set{Read,Write}[BW], called via the - * trampolines */ -static M68K_READ *real_readb, *real_readw; -static M68K_WRITE *real_writeb, *real_writew; - -#endif - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * m68kq68_init: Initialize the virtual processpr. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on failure - */ -static int m68kq68_init(void) -{ - if (!(state = q68_create())) { - return -1; - } - q68_set_irq(state, 0); - q68_set_readb_func(state, dummy_read); - q68_set_readw_func(state, dummy_read); - q68_set_writeb_func(state, dummy_write); - q68_set_writew_func(state, dummy_write); - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_deinit: Destroy the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void m68kq68_deinit(void) -{ - q68_destroy(state); - state = NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_reset: Reset the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void m68kq68_reset(void) -{ - q68_reset(state); -} - -/*************************************************************************/ - -/** - * m68kq68_exec: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles actually executed - */ -static FASTCALL s32 m68kq68_exec(s32 cycles) -{ -#ifdef PROFILE_68K - static uint32_t tot_cycles = 0, tot_usec = 0, tot_ticks = 0; - static uint32_t last_report = 0; - uint32_t start, end; - start = (uint32_t) YabauseGetTicks(); - int retval = q68_run(state, cycles); - end = (uint32_t) YabauseGetTicks(); - tot_cycles += cycles; - tot_ticks += end - start; - if (tot_cycles/1000000 > last_report) { - tot_usec += (uint64_t)tot_ticks * 1000000 / yabsys.tickfreq; - tot_ticks = 0; - fprintf(stderr, "%ld cycles in %.3f sec = %.3f nsec/cycle\n", - (long)tot_cycles, (double)tot_usec/1000000, - ((double)tot_usec / (double)tot_cycles) * 1000); - last_report = tot_cycles/1000000; -# ifdef COUNT_OPCODES - if (last_report % 100 == 0) { - extern uint32_t q68_ops[128], q68_4xxx_ops[32]; - int i; - fprintf(stderr, "Opcodes per 1M cycles:\n"); - for (i = 0; i < 128; i++) { - fprintf(stderr, "%s%8ld%s", i%8==0 ? " " : "", - (long)((q68_ops[i] + last_report/2) / last_report), - i%8==7 ? "\n" : ""); - } - fprintf(stderr, "$4xxx opcodes per 1M cycles:\n"); - for (i = 0; i < 32; i++) { - fprintf(stderr, "%s%8ld%s", i%8==0 ? " " : "", - (long)((q68_4xxx_ops[i] + last_report/2) / last_report), - i%8==7 ? "\n" : ""); - } - } -# endif // COUNT_OPCODES - } - return retval; -#else // !PROFILE_68K - return q68_run(state, cycles); -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_sync: Wait for background execution to finish. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void m68kq68_sync(void) -{ - /* Nothing to do */ -} - -/*************************************************************************/ - -/** - * m68kq68_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of - * the specified register. - * - * [Parameters] - * num: Register number (m68kq68_get_dreg(), m68kq68_get_areg() only) - * [Return value] - * None - */ - -static u32 m68kq68_get_dreg(u32 num) -{ - return q68_get_dreg(state, num); -} - -static u32 m68kq68_get_areg(u32 num) -{ - return q68_get_areg(state, num); -} - -static u32 m68kq68_get_pc(void) -{ - return q68_get_pc(state); -} - -static u32 m68kq68_get_sr(void) -{ - return q68_get_sr(state); -} - -static u32 m68kq68_get_usp(void) -{ - return q68_get_usp(state); -} - -static u32 m68kq68_get_ssp(void) -{ - return q68_get_ssp(state); -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * num: Register number (m68kq68_set_dreg(), m68kq68_set_areg() only) - * val: Value to set - * [Return value] - * None - */ - -static void m68kq68_set_dreg(u32 num, u32 val) -{ - q68_set_dreg(state, num, val); -} - -static void m68kq68_set_areg(u32 num, u32 val) -{ - q68_set_areg(state, num, val); -} - -static void m68kq68_set_pc(u32 val) -{ - q68_set_pc(state, val); -} - -static void m68kq68_set_sr(u32 val) -{ - q68_set_sr(state, val); -} - -static void m68kq68_set_usp(u32 val) -{ - q68_set_usp(state, val); -} - -static void m68kq68_set_ssp(u32 val) -{ - q68_set_ssp(state, val); -} - -/*************************************************************************/ - -/** - * m68kq68_set_irq: Deliver an interrupt to the processor. - * - * [Parameters] - * level: Interrupt level (0-7) - * [Return value] - * None - */ -static FASTCALL void m68kq68_set_irq(s32 level) -{ - q68_set_irq(state, level); -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_write_notify: Inform the 68k emulator that the given address - * range has been modified. - * - * [Parameters] - * address: 68000 address of modified data - * size: Size of modified data in bytes - * [Return value] - * None - */ -static FASTCALL void m68kq68_write_notify(u32 address, u32 size) -{ - q68_touch_memory(state, address, size); -} - -/*************************************************************************/ - -/** - * m68kq68_set_fetch: Set the instruction fetch pointer for a region of - * memory. Not used by Q68. - * - * [Parameters] - * low_addr: Low address of memory region to set - * high_addr: High address of memory region to set - * fetch_addr: Pointer to corresponding memory region (NULL to disable) - * [Return value] - * None - */ -static void m68kq68_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr) -{ -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_set_{readb,readw,writeb,writew}: Set functions for reading or - * writing bytes or words in memory. - * - * [Parameters] - * func: Function to set - * [Return value] - * None - */ - -static void m68kq68_set_readb(M68K_READ *func) -{ -#ifdef NEED_TRAMPOLINE - real_readb = func; - q68_set_readb_func(state, readb_trampoline); -#else - q68_set_readb_func(state, (Q68ReadFunc *)func); -#endif -} - -static void m68kq68_set_readw(M68K_READ *func) -{ -#ifdef NEED_TRAMPOLINE - real_readw = func; - q68_set_readw_func(state, readw_trampoline); -#else - q68_set_readw_func(state, (Q68ReadFunc *)func); -#endif -} - -static void m68kq68_set_writeb(M68K_WRITE *func) -{ -#ifdef NEED_TRAMPOLINE - real_writeb = func; - q68_set_writeb_func(state, writeb_trampoline); -#else - q68_set_writeb_func(state, (Q68WriteFunc *)func); -#endif -} - -static void m68kq68_set_writew(M68K_WRITE *func) -{ -#ifdef NEED_TRAMPOLINE - real_writew = func; - q68_set_writew_func(state, writew_trampoline); -#else - q68_set_writew_func(state, (Q68WriteFunc *)func); -#endif -} - -/*************************************************************************/ - -/** - * dummy_read: Default read function, always returning 0 for any address. - * - * [Parameters] - * address: Address to read from - * [Return value] - * Value read (always zero) - */ -static uint32_t dummy_read(uint32_t address) -{ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * dummy_write: Default write function, ignoring all writes. - * - * [Parameters] - * address: Address to write to - * data: Value to write - * [Return value] - * None - */ -static void dummy_write(uint32_t address, uint32_t data) -{ -} - -/*-----------------------------------------------------------------------*/ - -#ifdef NEED_TRAMPOLINE - -/** - * read[bw]_trampoline, write[bw]_trampoline: Adjust calling conventions - * between the M68k emulator and Yabause's M68k core. - * - * [Parameters] - * address: Address to read from - * data: Value to write (only for write_trampoline) - * [Return value] - * Value read (only for read_trampoline) - */ - -static uint32_t readb_trampoline(uint32_t address) { - return (*real_readb)(address); -} - -static uint32_t readw_trampoline(uint32_t address) { - return (*real_readw)(address); -} - -static void writeb_trampoline(uint32_t address, uint32_t data) { - return (*real_writeb)(address, data); -} - -static void writew_trampoline(uint32_t address, uint32_t data) { - return (*real_writew)(address, data); -} - -#endif // NEED_TRAMPOLINE - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/macjoy.c b/yabause/src/macjoy.c deleted file mode 100644 index 0d202a50ae..0000000000 --- a/yabause/src/macjoy.c +++ /dev/null @@ -1,516 +0,0 @@ -/* This file was imported form CrabEmu ( http://crabemu.sourceforge.net/ ) -- - A Sega Master System emulator for Mac OS X (among other targets). The rest - of the file is left intact from CrabEmu to make things easier if this were - to be upgraded in the future. */ - -/* - This file is part of CrabEmu. - - Copyright (C) 2008 Lawrence Sebald - - CrabEmu is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - CrabEmu 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 CrabEmu; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "macjoy.h" - -static int joy_count = 0; -static joydata_t *joys = NULL; - -static void joy_find_elements(CFMutableDictionaryRef prop, joydata_t *joy); - -/* Compare two buttons for sorting. */ -static int joy_cmp_buttons(const void *e1, const void *e2) { - const joy_elemdata_t *b1 = (const joy_elemdata_t *)e1; - const joy_elemdata_t *b2 = (const joy_elemdata_t *)e2; - - return b1->number < b2->number ? -1 : - (b1->number > b2->number ? 1 : 0); -} - -/* Get the io_iterator_t object needed to iterate through the list of HID - devices. */ -static void joy_get_iterator(mach_port_t port, io_iterator_t *iter) { - CFMutableDictionaryRef d; - IOReturn rv; - - /* Create a matching dictionary that will be used to search the device - tree. */ - if(!(d = IOServiceMatching(kIOHIDDeviceKey))) { - return; - } - - /* Get all matching devices from IOKit. */ - rv = IOServiceGetMatchingServices(port, d, iter); - - if(rv != kIOReturnSuccess || !(*iter)) { - return; - } -} - -/* Create the interface needed to do stuff with the device. */ -static int joy_create_interface(io_object_t hidDevice, joydata_t *joy) { - IOCFPlugInInterface **plugin; - SInt32 score = 0; - - /* Create the plugin that we will use to actually get the device interface - that is needed. */ - if(IOCreatePlugInInterfaceForService(hidDevice, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, &plugin, - &score) != kIOReturnSuccess) { - return 0; - } - - /* Grab the device interface from the plugin. */ - if((*plugin)->QueryInterface(plugin, - CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), - (LPVOID)&joy->iface) != S_OK) { - return 0; - } - - /* The plugin has done all it needs to, release it. */ - (*plugin)->Release(plugin); - - return 1; -} - -/* Fill in a elemdata_t structure with information about the given physical - element. */ -static void joy_fill_elem(CFTypeRef elem, joy_elemdata_t *ptr) { - CFTypeRef ref; - int num; - - memset(ptr, 0, sizeof(joy_elemdata_t)); - - /* Grab the element cookie. */ - if((ref = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementCookieKey)))) { - if(CFNumberGetValue(ref, kCFNumberIntType, &num)) { - ptr->cookie = (IOHIDElementCookie)num; - } - } - - /* Grab the element's minimum value. */ - if((ref = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementMinKey)))) { - if(CFNumberGetValue(ref, kCFNumberIntType, &num)) { - ptr->min = num; - } - } - - /* Grab the element's maximum value. */ - if((ref = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementMaxKey)))) { - if(CFNumberGetValue(ref, kCFNumberIntType, &num)) { - ptr->max = num; - } - } -} - -/* Callback function to handle each sub-element of the controller class. */ -static void joy_elem_array_hnd(const void *value, void *parameter) { - CFTypeRef elem = (CFTypeRef)value; - CFTypeID t = CFGetTypeID(value); - joydata_t *joy = (joydata_t *)parameter; - long elemType, elemPage, elemUsage; - CFTypeRef type, page, usage; - void *ptr; - int et; - - /* Make sure we're dealing with a dictionary. */ - if(t == CFDictionaryGetTypeID()) { - /* Grab the type of the element. */ - type = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementTypeKey)); - - if(!type) { - return; - } - - /* Grab the HID usage page. */ - page = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementUsagePageKey)); - - if(!page) { - return; - } - - /* Grab the HID usage type. */ - usage = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementUsageKey)); - - if(!usage) { - return; - } - - /* Get the integer values from the data grabbed above. */ - if(!CFNumberGetValue(type, kCFNumberLongType, &elemType)) { - return; - } - - if(!CFNumberGetValue(page, kCFNumberLongType, &elemPage)) { - return; - } - - if(!CFNumberGetValue(usage, kCFNumberLongType, &elemUsage)) { - return; - } - - /* If the element is listed as a button, axis, or misc input, check - what it actually is. */ - if(elemType == kIOHIDElementTypeInput_Button || - elemType == kIOHIDElementTypeInput_Axis || - elemType == kIOHIDElementTypeInput_Misc) { - switch(elemPage) { - case kHIDPage_Button: - ptr = realloc(joy->buttons, (joy->buttons_count + 1) * - sizeof(joy_elemdata_t)); - - if(ptr) { - joy->buttons = (joy_elemdata_t *)ptr; - joy_fill_elem(elem, joy->buttons + joy->buttons_count); - joy->buttons[joy->buttons_count].number = elemUsage; - ++joy->buttons_count; - } - break; - - case kHIDPage_GenericDesktop: - switch(elemUsage) { - case kHIDUsage_GD_X: - et = JOY_TYPE_X_AXIS; - goto axis; - - case kHIDUsage_GD_Y: - et = JOY_TYPE_Y_AXIS; - goto axis; - - case kHIDUsage_GD_Z: - et = JOY_TYPE_Z_AXIS; - goto axis; - - case kHIDUsage_GD_Rx: - et = JOY_TYPE_X2_AXIS; - goto axis; - - case kHIDUsage_GD_Ry: - et = JOY_TYPE_Y2_AXIS; - goto axis; - - case kHIDUsage_GD_Rz: - et = JOY_TYPE_Z2_AXIS; -axis: - ptr = realloc(joy->axes, (joy->axes_count + 1) * - sizeof(joy_elemdata_t)); - - if(ptr) { - joy->axes = (joy_elemdata_t *)ptr; - joy_fill_elem(elem, joy->axes + - joy->axes_count); - joy->axes[joy->axes_count].type = et; - ++joy->axes_count; - } - break; - - case kHIDUsage_GD_Hatswitch: - ptr = realloc(joy->hats, (joy->hats_count + 1) * - sizeof(joy_elemdata_t)); - - if(ptr) { - joy->hats = (joy_elemdata_t *)ptr; - joy_fill_elem(elem, joy->hats + - joy->hats_count); - ++joy->hats_count; - } - break; - } - break; - } - - } - /* If we've found another element array, effectively recurse. */ - else if(elemType == kIOHIDElementTypeCollection) { - joy_find_elements((CFMutableDictionaryRef)elem, joy); - } - } -} - -/* Process all the sub-elements of a given property list. */ -static void joy_find_elements(CFMutableDictionaryRef prop, joydata_t *joy) { - CFTypeRef elem; - CFTypeID type; - - if((elem = CFDictionaryGetValue(prop, CFSTR(kIOHIDElementKey)))) { - type = CFGetTypeID(elem); - - if(type == CFArrayGetTypeID()) { - /* Call our function on each element of the array. */ - CFRange r = { 0, CFArrayGetCount(elem) }; - CFArrayApplyFunction(elem, r, &joy_elem_array_hnd, (void *)joy); - } - } -} - -/* Read the device passed in, and add it to our joystick list if appropriate. */ -static void joy_read_device(io_object_t dev) { - CFMutableDictionaryRef props = 0; - - /* Create a dictionary to read the device's properties. */ - if(IORegistryEntryCreateCFProperties(dev, &props, kCFAllocatorDefault, - kNilOptions) == KERN_SUCCESS) { - CFTypeRef inf; - SInt32 page, usage; - void *ptr; - - /* Grab the primary usage page of the device. */ - inf = CFDictionaryGetValue(props, CFSTR(kIOHIDPrimaryUsagePageKey)); - - if(!inf || !CFNumberGetValue((CFNumberRef)inf, kCFNumberSInt32Type, - &page)) { - goto out; - } - - /* Ignore devices that are not in the Generic Desktop page. */ - if(page != kHIDPage_GenericDesktop) { - goto out; - } - - /* Grab the primary device usage. */ - inf = CFDictionaryGetValue(props, CFSTR(kIOHIDPrimaryUsageKey)); - - if(!inf || !CFNumberGetValue((CFNumberRef)inf, kCFNumberSInt32Type, - &usage)) { - goto out; - } - - /* Ignore devices that are not either a Game Pad or Joystick. */ - if(usage != kHIDUsage_GD_GamePad && usage != kHIDUsage_GD_Joystick) { - goto out; - } - - /* Allocate space for the new joystick structure. */ - ptr = realloc(joys, (joy_count + 1) * sizeof(joydata_t)); - - if(ptr == NULL) { - goto out; - } - - joys = (joydata_t *)ptr; - memset(joys + joy_count, 0, sizeof(joydata_t)); - - /* Grab and store the name of the device. */ - inf = CFDictionaryGetValue(props, CFSTR(kIOHIDProductKey)); - - if(!CFStringGetCString((CFStringRef)inf, joys[joy_count].name, 256, - kCFStringEncodingUTF8)) { - goto out; - } - - /* Create the device interface needed to interact with the device. */ - if(!joy_create_interface(dev, joys + joy_count)) { - goto out; - } - - /* Find all elements of the device. */ - joy_find_elements(props, joys + joy_count); - - qsort(joys[joy_count].buttons, joys[joy_count].buttons_count, - sizeof(joy_elemdata_t), &joy_cmp_buttons); - - ++joy_count; - } - -out: - CFRelease(props); -} - -/* Release the given joystick's interface and clean up any memory used by it. */ -static void joy_release_joystick(joydata_t *joy) { - (*joy->iface)->Release(joy->iface); - - joy->iface = NULL; - - if(joy->buttons) - free(joy->buttons); - - if(joy->axes) - free(joy->axes); - - if(joy->hats) - free(joy->hats); -} - -/* Scan the system for any joysticks connected. */ -int joy_scan_joysticks(void) { - io_iterator_t iter = 0; - io_object_t dev; - - if(joys != NULL) { - return -1; - } - - /* Get the iterator needed for going through the list of devices. */ - joy_get_iterator(kIOMasterPortDefault, &iter); - - if(iter != 0) { - while((dev = IOIteratorNext(iter))) { - joy_read_device(dev); - IOObjectRelease(dev); - } - - /* Release the iterator. */ - IOObjectRelease(iter); - } - - return joy_count; -} - -/* Clean up any data allocated by the program for joysticks. */ -void joy_release_joysticks(void) { - int i; - - for(i = 0; i < joy_count; ++i) { - joy_close_joystick(joys + i); - joy_release_joystick(joys + i); - } - - if(joys != NULL) { - free(joys); - joys = NULL; - } - - joy_count = 0; -} - -/* Get the joystick at a given index in our list of joysticks. */ -joydata_t *joy_get_joystick(int index) { - if(index < 0 || index >= joy_count) { - return NULL; - } - - return &joys[index]; -} - -/* Grab the device for exclusive use by this program. The device must be closed - properly (with the joy_close_joystick function, or you may need to - unplug/replug the joystick to get it to work again). */ -int joy_open_joystick(joydata_t *joy) { - if((*joy->iface)->open(joy->iface, 0)) { - return 0; - } - - joy->open = 1; - - return 1; -} - -/* Close the device and return its resources to the system. */ -int joy_close_joystick(joydata_t *joy) { - IOReturn rv; - - if(!joy->open) { - return 1; - } - - rv = (*joy->iface)->close(joy->iface); - - if(rv == kIOReturnNotOpen) { - /* The device wasn't open so it can't be closed. */ - return 1; - } - else if(rv != kIOReturnSuccess) { - return 0; - } - - joy->open = 0; - - return 1; -} - -/* Read a given element from the joystick. The joystick must be open for this - function to actually do anything useful. */ -int joy_read_element(joydata_t *joy, joy_elemdata_t *elem) { - IOHIDEventStruct ev; - - memset(&ev, 0, sizeof(IOHIDEventStruct)); - - (*joy->iface)->getElementValue(joy->iface, elem->cookie, &ev); - - return ev.value; -} - -/* Read the value of a given button. Returns -1 on failure. */ -int joy_read_button(joydata_t *joy, int num) { - /* Subtract 1 from the number to get the index. */ - --num; - - if(num >= joy->buttons_count) { - return -1; - } - - return joy_read_element(joy, joy->buttons + num); -} - -/* Read the value of a given axis. Returns 0 on failure (or if the axis reports - that its value is 0). */ -int joy_read_axis(joydata_t *joy, int index) { - float value; - - if(index >= joy->axes_count) { - return 0; - } - - value = joy_read_element(joy, joy->axes + index) / - (float)(joy->axes[index].max + 1); - - return (int)(value * 32768); -} - -/* Read the value of a given hat. Returns -1 on failure. */ -int joy_read_hat(joydata_t *joy, int index) { - int value; - - if(index >= joy->hats_count) { - return -1; - } - - value = joy_read_element(joy, joy->hats + index) - joy->hats[index].min; - - /* 4-position hat switch -- Make it look like an 8-position one. */ - if(joy->hats[index].max - joy->hats[index].min + 1 == 4) { - value <<= 1; - } - - switch(value) { - case 0: - return JOY_HAT_UP; - case 1: - return JOY_HAT_UP | JOY_HAT_RIGHT; - case 2: - return JOY_HAT_RIGHT; - case 3: - return JOY_HAT_RIGHT | JOY_HAT_DOWN; - case 4: - return JOY_HAT_DOWN; - case 5: - return JOY_HAT_DOWN | JOY_HAT_LEFT; - case 6: - return JOY_HAT_LEFT; - case 7: - return JOY_HAT_LEFT | JOY_HAT_UP; - default: - return JOY_HAT_CENTER; - } -} diff --git a/yabause/src/macjoy.h b/yabause/src/macjoy.h deleted file mode 100644 index 837296185a..0000000000 --- a/yabause/src/macjoy.h +++ /dev/null @@ -1,101 +0,0 @@ -/* This file was imported form CrabEmu ( http://crabemu.sourceforge.net/ ) -- - A Sega Master System emulator for Mac OS X (among other targets). The rest - of the file is left intact from CrabEmu to make things easier if this were - to be upgraded in the future. */ - -/* - This file is part of CrabEmu. - - Copyright (C) 2008 Lawrence Sebald - - CrabEmu is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - CrabEmu 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 CrabEmu; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef JOYSTICK_H -#define JOYSTICK_H - -#include - -/* Values for the joy_elemdata_t type element. */ -#define JOY_TYPE_NOT_APPLICABLE 0 -#define JOY_TYPE_X_AXIS 1 -#define JOY_TYPE_Y_AXIS 2 -#define JOY_TYPE_Z_AXIS 3 -#define JOY_TYPE_X2_AXIS 4 -#define JOY_TYPE_Y2_AXIS 5 -#define JOY_TYPE_Z2_AXIS 6 - -/* Structure for holding basic information about each element. */ -typedef struct joy_elemdata_s { - IOHIDElementCookie cookie; - int type; - int number; - int min; - int max; -} joy_elemdata_t; - -/* Structure for holding information about each joystick connected. */ -typedef struct joydata_s { - IOHIDDeviceInterface **iface; - int open; - int buttons_count; - int axes_count; - int hats_count; - - joy_elemdata_t *buttons; - joy_elemdata_t *axes; - joy_elemdata_t *hats; - - char name[256]; -} joydata_t; - -/* Values for hat switches. ORed together and returned from joy_read_hat. */ -#define JOY_HAT_CENTER 0 -#define JOY_HAT_UP (1 << 0) -#define JOY_HAT_DOWN (1 << 1) -#define JOY_HAT_RIGHT (1 << 2) -#define JOY_HAT_LEFT (1 << 3) - -/* Scan the system for any joysticks connected. */ -int joy_scan_joysticks(void); - -/* Clean up any data allocated by the program for joysticks. */ -void joy_release_joysticks(void); - -/* Get the joystick at a given index in our list of joysticks. */ -joydata_t *joy_get_joystick(int index); - -/* Grab the device for exclusive use by this program. The device must be closed - properly (with the joy_close_joystick function, or you may need to - unplug/replug the joystick to get it to work again). */ -int joy_open_joystick(joydata_t *joy); - -/* Close the device and return its resources to the system. */ -int joy_close_joystick(joydata_t *joy); - -/* Read a given element from the joystick. The joystick must be open for this - function to actually do anything useful. */ -int joy_read_element(joydata_t *joy, joy_elemdata_t *elem); - -/* Read the value of a given button. Returns -1 on failure. */ -int joy_read_button(joydata_t *joy, int num); - -/* Read the value of a given axis. Returns 0 on failure (or if the axis reports - that its value is 0). */ -int joy_read_axis(joydata_t *joy, int index); - -/* Read the value of a given hat. Returns -1 on failure. */ -int joy_read_hat(joydata_t *joy, int index); - -#endif /* !JOYSTICK_H */ diff --git a/yabause/src/memory.c b/yabause/src/memory.c deleted file mode 100644 index 2318154264..0000000000 --- a/yabause/src/memory.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef PSP // see FIXME in T1MemoryInit() -# include -#endif -#include -#include -#include -#include - -#include "memory.h" -#include "coffelf.h" -#include "cs0.h" -#include "cs1.h" -#include "cs2.h" -#include "debug.h" -#include "error.h" -#include "sh2core.h" -#include "scsp.h" -#include "scu.h" -#include "smpc.h" -#include "vdp1.h" -#include "vdp2.h" -#include "yabause.h" -#include "yui.h" -#include "movie.h" - -#ifdef HAVE_LIBGL -#define USE_OPENGL -#endif - -#ifdef USE_OPENGL -#include "ygl.h" -#endif - -#include "vidsoft.h" -#include "vidogl.h" - -////////////////////////////////////////////////////////////////////////////// - -writebytefunc WriteByteList[0x1000]; -writewordfunc WriteWordList[0x1000]; -writelongfunc WriteLongList[0x1000]; - -readbytefunc ReadByteList[0x1000]; -readwordfunc ReadWordList[0x1000]; -readlongfunc ReadLongList[0x1000]; - -u8 *HighWram; -u8 *LowWram; -u8 *BiosRom; -u8 *BupRam; - -/* This flag is set to 1 on every write to backup RAM. Ports can freely - * check or clear this flag to determine when backup RAM has been written, - * e.g. for implementing autosave of backup RAM. */ -u8 BupRamWritten; - -////////////////////////////////////////////////////////////////////////////// - -u8 * T1MemoryInit(u32 size) -{ -#ifdef PSP // FIXME: could be ported to all arches, but requires stdint.h - // for uintptr_t - u8 * base; - u8 * mem; - - if ((base = calloc((size * sizeof(u8)) + sizeof(u8 *) + 64, 1)) == NULL) - return NULL; - - mem = base + sizeof(u8 *); - mem = mem + (64 - ((uintptr_t) mem & 63)); - *(u8 **)(mem - sizeof(u8 *)) = base; // Save base pointer below memory block - - return mem; -#else - return calloc(size, sizeof(u8)); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -void T1MemoryDeInit(u8 * mem) -{ -#ifdef PSP - if (mem) - free(*(u8 **)(mem - sizeof(u8 *))); -#else - free(mem); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -T3Memory * T3MemoryInit(u32 size) -{ - T3Memory * mem; - - if ((mem = (T3Memory *) calloc(1, sizeof(T3Memory))) == NULL) - return NULL; - - if ((mem->base_mem = (u8 *) calloc(size, sizeof(u8))) == NULL) - return NULL; - - mem->mem = mem->base_mem + size; - - return mem; -} - -////////////////////////////////////////////////////////////////////////////// - -void T3MemoryDeInit(T3Memory * mem) -{ - free(mem->base_mem); - free(mem); -} - -////////////////////////////////////////////////////////////////////////////// - -Dummy * DummyInit(UNUSED u32 s) -{ - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void DummyDeInit(UNUSED Dummy * d) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL UnhandledMemoryReadByte(USED_IF_DEBUG u32 addr) -{ - LOG("Unhandled byte read %08X\n", (unsigned int)addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL UnhandledMemoryReadWord(USED_IF_DEBUG u32 addr) -{ - LOG("Unhandled word read %08X\n", (unsigned int)addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL UnhandledMemoryReadLong(USED_IF_DEBUG u32 addr) -{ - LOG("Unhandled long read %08X\n", (unsigned int)addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL UnhandledMemoryWriteByte(USED_IF_DEBUG u32 addr, UNUSED u8 val) -{ - LOG("Unhandled byte write %08X\n", (unsigned int)addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL UnhandledMemoryWriteWord(USED_IF_DEBUG u32 addr, UNUSED u16 val) -{ - LOG("Unhandled word write %08X\n", (unsigned int)addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL UnhandledMemoryWriteLong(USED_IF_DEBUG u32 addr, UNUSED u32 val) -{ - LOG("Unhandled long write %08X\n", (unsigned int)addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL HighWramMemoryReadByte(u32 addr) -{ - return T2ReadByte(HighWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL HighWramMemoryReadWord(u32 addr) -{ - return T2ReadWord(HighWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL HighWramMemoryReadLong(u32 addr) -{ - return T2ReadLong(HighWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL HighWramMemoryWriteByte(u32 addr, u8 val) -{ - T2WriteByte(HighWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL HighWramMemoryWriteWord(u32 addr, u16 val) -{ - T2WriteWord(HighWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL HighWramMemoryWriteLong(u32 addr, u32 val) -{ - T2WriteLong(HighWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL LowWramMemoryReadByte(u32 addr) -{ - return T2ReadByte(LowWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL LowWramMemoryReadWord(u32 addr) -{ - return T2ReadWord(LowWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL LowWramMemoryReadLong(u32 addr) -{ - return T2ReadLong(LowWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL LowWramMemoryWriteByte(u32 addr, u8 val) -{ - T2WriteByte(LowWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL LowWramMemoryWriteWord(u32 addr, u16 val) -{ - T2WriteWord(LowWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL LowWramMemoryWriteLong(u32 addr, u32 val) -{ - T2WriteLong(LowWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BiosRomMemoryReadByte(u32 addr) -{ - return T2ReadByte(BiosRom, addr & 0x7FFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BiosRomMemoryReadWord(u32 addr) -{ - return T2ReadWord(BiosRom, addr & 0x7FFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BiosRomMemoryReadLong(u32 addr) -{ - return T2ReadLong(BiosRom, addr & 0x7FFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosRomMemoryWriteByte(UNUSED u32 addr, UNUSED u8 val) -{ - // read-only -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosRomMemoryWriteWord(UNUSED u32 addr, UNUSED u16 val) -{ - // read-only -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosRomMemoryWriteLong(UNUSED u32 addr, UNUSED u32 val) -{ - // read-only -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BupRamMemoryReadByte(u32 addr) -{ - return T1ReadByte(BupRam, addr & 0xFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BupRamMemoryReadWord(USED_IF_DEBUG u32 addr) -{ - LOG("bup\t: BackupRam read word - %08X\n", addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BupRamMemoryReadLong(USED_IF_DEBUG u32 addr) -{ - LOG("bup\t: BackupRam read long - %08X\n", addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BupRamMemoryWriteByte(u32 addr, u8 val) -{ - T1WriteByte(BupRam, (addr & 0xFFFF) | 0x1, val); - BupRamWritten = 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BupRamMemoryWriteWord(USED_IF_DEBUG u32 addr, UNUSED u16 val) -{ - LOG("bup\t: BackupRam write word - %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BupRamMemoryWriteLong(USED_IF_DEBUG u32 addr, UNUSED u32 val) -{ - LOG("bup\t: BackupRam write long - %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FillMemoryArea(unsigned short start, unsigned short end, - readbytefunc r8func, readwordfunc r16func, - readlongfunc r32func, writebytefunc w8func, - writewordfunc w16func, writelongfunc w32func) -{ - int i; - - for (i=start; i < (end+1); i++) - { - ReadByteList[i] = r8func; - ReadWordList[i] = r16func; - ReadLongList[i] = r32func; - WriteByteList[i] = w8func; - WriteWordList[i] = w16func; - WriteLongList[i] = w32func; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void MappedMemoryInit() -{ - // Initialize everyting to unhandled to begin with - FillMemoryArea(0x000, 0xFFF, &UnhandledMemoryReadByte, - &UnhandledMemoryReadWord, - &UnhandledMemoryReadLong, - &UnhandledMemoryWriteByte, - &UnhandledMemoryWriteWord, - &UnhandledMemoryWriteLong); - - // Fill the rest - FillMemoryArea(0x000, 0x00F, &BiosRomMemoryReadByte, - &BiosRomMemoryReadWord, - &BiosRomMemoryReadLong, - &BiosRomMemoryWriteByte, - &BiosRomMemoryWriteWord, - &BiosRomMemoryWriteLong); - FillMemoryArea(0x010, 0x017, &SmpcReadByte, - &SmpcReadWord, - &SmpcReadLong, - &SmpcWriteByte, - &SmpcWriteWord, - &SmpcWriteLong); - FillMemoryArea(0x018, 0x01F, &BupRamMemoryReadByte, - &BupRamMemoryReadWord, - &BupRamMemoryReadLong, - &BupRamMemoryWriteByte, - &BupRamMemoryWriteWord, - &BupRamMemoryWriteLong); - FillMemoryArea(0x020, 0x02F, &LowWramMemoryReadByte, - &LowWramMemoryReadWord, - &LowWramMemoryReadLong, - &LowWramMemoryWriteByte, - &LowWramMemoryWriteWord, - &LowWramMemoryWriteLong); - FillMemoryArea(0x100, 0x17F, &UnhandledMemoryReadByte, - &UnhandledMemoryReadWord, - &UnhandledMemoryReadLong, - &UnhandledMemoryWriteByte, - &SSH2InputCaptureWriteWord, - &UnhandledMemoryWriteLong); - FillMemoryArea(0x180, 0x1FF, &UnhandledMemoryReadByte, - &UnhandledMemoryReadWord, - &UnhandledMemoryReadLong, - &UnhandledMemoryWriteByte, - &MSH2InputCaptureWriteWord, - &UnhandledMemoryWriteLong); - FillMemoryArea(0x200, 0x3FF, CartridgeArea->Cs0ReadByte, - CartridgeArea->Cs0ReadWord, - CartridgeArea->Cs0ReadLong, - CartridgeArea->Cs0WriteByte, - CartridgeArea->Cs0WriteWord, - CartridgeArea->Cs0WriteLong); - FillMemoryArea(0x400, 0x4FF, &Cs1ReadByte, - &Cs1ReadWord, - &Cs1ReadLong, - &Cs1WriteByte, - &Cs1WriteWord, - &Cs1WriteLong); - FillMemoryArea(0x580, 0x58F, &Cs2ReadByte, - &Cs2ReadWord, - &Cs2ReadLong, - &Cs2WriteByte, - &Cs2WriteWord, - &Cs2WriteLong); - FillMemoryArea(0x5A0, 0x5AF, &SoundRamReadByte, - &SoundRamReadWord, - &SoundRamReadLong, - &SoundRamWriteByte, - &SoundRamWriteWord, - &SoundRamWriteLong); - FillMemoryArea(0x5B0, 0x5BF, &scsp_r_b, - &scsp_r_w, - &scsp_r_d, - &scsp_w_b, - &scsp_w_w, - &scsp_w_d); - FillMemoryArea(0x5C0, 0x5C7, &Vdp1RamReadByte, - &Vdp1RamReadWord, - &Vdp1RamReadLong, - &Vdp1RamWriteByte, - &Vdp1RamWriteWord, - &Vdp1RamWriteLong); - FillMemoryArea(0x5C8, 0x5CF, &Vdp1FrameBufferReadByte, - &Vdp1FrameBufferReadWord, - &Vdp1FrameBufferReadLong, - &Vdp1FrameBufferWriteByte, - &Vdp1FrameBufferWriteWord, - &Vdp1FrameBufferWriteLong); - FillMemoryArea(0x5D0, 0x5D7, &Vdp1ReadByte, - &Vdp1ReadWord, - &Vdp1ReadLong, - &Vdp1WriteByte, - &Vdp1WriteWord, - &Vdp1WriteLong); - FillMemoryArea(0x5E0, 0x5EF, &Vdp2RamReadByte, - &Vdp2RamReadWord, - &Vdp2RamReadLong, - &Vdp2RamWriteByte, - &Vdp2RamWriteWord, - &Vdp2RamWriteLong); - FillMemoryArea(0x5F0, 0x5F7, &Vdp2ColorRamReadByte, - &Vdp2ColorRamReadWord, - &Vdp2ColorRamReadLong, - &Vdp2ColorRamWriteByte, - &Vdp2ColorRamWriteWord, - &Vdp2ColorRamWriteLong); - FillMemoryArea(0x5F8, 0x5FB, &Vdp2ReadByte, - &Vdp2ReadWord, - &Vdp2ReadLong, - &Vdp2WriteByte, - &Vdp2WriteWord, - &Vdp2WriteLong); - FillMemoryArea(0x5FE, 0x5FE, &ScuReadByte, - &ScuReadWord, - &ScuReadLong, - &ScuWriteByte, - &ScuWriteWord, - &ScuWriteLong); - FillMemoryArea(0x600, 0x7FF, &HighWramMemoryReadByte, - &HighWramMemoryReadWord, - &HighWramMemoryReadLong, - &HighWramMemoryWriteByte, - &HighWramMemoryWriteWord, - &HighWramMemoryWriteLong); -} - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL MappedMemoryReadByte(u32 addr) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - return ReadByteList[(addr >> 16) & 0xFFF](addr); - } -/* - case 0x2: - { - // Purge Area - break; - } -*/ - case 0x4: - case 0x6: - // Data Array - return DataArrayReadByte(addr); - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - return OnchipReadByte(addr); - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - break; - } - default: - { - return UnhandledMemoryReadByte(addr); - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u16 FASTCALL MappedMemoryReadWord(u32 addr) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - return ReadWordList[(addr >> 16) & 0xFFF](addr); - } -/* - case 0x2: - { - // Purge Area - break; - } -*/ - case 0x4: - case 0x6: - // Data Array - return DataArrayReadWord(addr); - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - return OnchipReadWord(addr); - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - break; - } - default: - { - return UnhandledMemoryReadWord(addr); - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 FASTCALL MappedMemoryReadLong(u32 addr) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - return ReadLongList[(addr >> 16) & 0xFFF](addr); - } -/* - case 0x2: - { - // Purge Area - break; - } -*/ - case 0x3: - { - // Address Array - return AddressArrayReadLong(addr); - } - case 0x4: - case 0x6: - // Data Array - return DataArrayReadLong(addr); - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - return OnchipReadLong(addr); - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - break; - } - default: - { - return UnhandledMemoryReadLong(addr); - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL MappedMemoryWriteByte(u32 addr, u8 val) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - WriteByteList[(addr >> 16) & 0xFFF](addr, val); - return; - } -/* - case 0x2: - { - // Purge Area - return; - } -*/ - case 0x4: - case 0x6: - // Data Array - DataArrayWriteByte(addr, val); - return; - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - OnchipWriteByte(addr, val); - return; - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - return; - } - default: - { - UnhandledMemoryWriteByte(addr, val); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL MappedMemoryWriteWord(u32 addr, u16 val) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - WriteWordList[(addr >> 16) & 0xFFF](addr, val); - return; - } -/* - case 0x2: - { - // Purge Area - return; - } -*/ - case 0x4: - case 0x6: - // Data Array - DataArrayWriteWord(addr, val); - return; - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - OnchipWriteWord(addr, val); - return; - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - return; - } - default: - { - UnhandledMemoryWriteWord(addr, val); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL MappedMemoryWriteLong(u32 addr, u32 val) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - WriteLongList[(addr >> 16) & 0xFFF](addr, val); - return; - } - case 0x2: - { - // Purge Area - return; - } - case 0x3: - { - // Address Array - AddressArrayWriteLong(addr, val); - return; - } - case 0x4: - case 0x6: - // Data Array - DataArrayWriteLong(addr, val); - return; - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - OnchipWriteLong(addr, val); - return; - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - return; - } - default: - { - UnhandledMemoryWriteLong(addr, val); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemoryLoad(const char *filename, u32 addr) -{ - FILE *fp; - u32 filesize; - u8 *buffer; - u32 i; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - // Calculate file size - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - if ((buffer = (u8 *)malloc(filesize)) == NULL) - { - fclose(fp); - return -2; - } - - fread((void *)buffer, 1, filesize, fp); - fclose(fp); - - for (i = 0; i < filesize; i++) - MappedMemoryWriteByte(addr+i, buffer[i]); - - free(buffer); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemorySave(const char *filename, u32 addr, u32 size) -{ - FILE *fp; - u8 *buffer; - u32 i; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "wb")) == NULL) - return -1; - - if ((buffer = (u8 *)malloc(size)) == NULL) - { - fclose(fp); - return -2; - } - - for (i = 0; i < size; i++) - buffer[i] = MappedMemoryReadByte(addr+i); - - fwrite((void *)buffer, 1, size, fp); - fclose(fp); - free(buffer); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void MappedMemoryLoadExec(const char *filename, u32 pc) -{ - char *p; - size_t i; - - if ((p = strrchr(filename, '.'))) - { - p = strdup(p); - for (i = 0; i < strlen(p); i++) - p[i] = toupper(p[i]); - if (strcmp(p, ".COF") == 0 || strcmp(p, ".COFF") == 0) - { - MappedMemoryLoadCoff(filename); - free(p); - return; - } - else if(strcmp(p, ".ELF") == 0) - { - MappedMemoryLoadElf(filename); - free(p); - return; - } - - free(p); - } - - YabauseResetNoLoad(); - - // Setup the vector table area, etc. - YabauseSpeedySetup(); - - MappedMemoryLoad(filename, pc); - SH2GetRegisters(MSH2, &MSH2->regs); - MSH2->regs.PC = pc; - SH2SetRegisters(MSH2, &MSH2->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -int LoadBios(const char *filename) -{ - return T123Load(BiosRom, 0x80000, 2, filename); -} - -////////////////////////////////////////////////////////////////////////////// - -int LoadBackupRam(const char *filename) -{ - return T123Load(BupRam, 0x10000, 1, filename); -} - -////////////////////////////////////////////////////////////////////////////// - -void FormatBackupRam(void *mem, u32 size) -{ - int i, i2; - u32 i3; - u8 header[32] = { - 0xFF, 'B', 0xFF, 'a', 0xFF, 'c', 0xFF, 'k', - 0xFF, 'U', 0xFF, 'p', 0xFF, 'R', 0xFF, 'a', - 0xFF, 'm', 0xFF, ' ', 0xFF, 'F', 0xFF, 'o', - 0xFF, 'r', 0xFF, 'm', 0xFF, 'a', 0xFF, 't' - }; - - // Fill in header - for(i2 = 0; i2 < 4; i2++) - for(i = 0; i < 32; i++) - T1WriteByte(mem, (i2 * 32) + i, header[i]); - - // Clear the rest - for(i3 = 0x80; i3 < size; i3+=2) - { - T1WriteByte(mem, i3, 0xFF); - T1WriteByte(mem, i3+1, 0x00); - } -} - -////////////////////////////////////////////////////////////////////////////// - -// FIXME: Here's a (possibly incomplete) list of data that should be added -// to the next version of the save state file: -// yabsys.DecilineStop (new format) -// yabsys.SH2CycleFrac (new field) -// yabsys.DecilineUSed (new field) -// yabsys.UsecFrac (new field) -// [scsp2.c] It would be nice to redo the format entirely because so -// many fields have changed format/size from the old scsp.c -// [scsp2.c] scsp_clock, scsp_clock_frac, ScspState.sample_timer (timing) -// [scsp2.c] cdda_buf, cdda_next_in, cdda_next_out (CDDA buffer) -// [sh2core.c] frc.div changed to frc.shift -// [sh2core.c] wdt probably needs to be written as well - -int YabSaveState(const char *filename) -{ - u32 i; - FILE *fp; - int offset; - IOCheck_struct check; - u8 *buf; - int totalsize; - int outputwidth; - int outputheight; - int movieposition; - int temp; - u32 temp32; - - check.done = 0; - check.size = 0; - - //use a second set of savestates for movies - filename = MakeMovieStateName(filename); - if (!filename) - return -1; - - if ((fp = fopen(filename, "wb")) == NULL) - return -1; - - // Write signature - fprintf(fp, "YSS"); - - // Write endianness byte -#ifdef WORDS_BIGENDIAN - fputc(0x00, fp); -#else - fputc(0x01, fp); -#endif - - // Write version(fix me) - i = 1;//2; - ywrite(&check, (void *)&i, sizeof(i), 1, fp); - - // Skip the next 4 bytes for now - i = 0; - ywrite(&check, (void *)&i, sizeof(i), 1, fp); - - //write frame number - //ywrite(&check, (void *)&framecounter, 4, 1, fp); - - //this will be updated with the movie position later - //ywrite(&check, (void *)&framecounter, 4, 1, fp); - - // Go through each area and write each state - i += CartSaveState(fp); - i += Cs2SaveState(fp); - i += SH2SaveState(MSH2, fp); - i += SH2SaveState(SSH2, fp); - i += SoundSaveState(fp); - i += ScuSaveState(fp); - i += SmpcSaveState(fp); - i += Vdp1SaveState(fp); - i += Vdp2SaveState(fp); - - offset = StateWriteHeader(fp, "OTHR", 1); - - // Other data - ywrite(&check, (void *)BupRam, 0x10000, 1, fp); // do we really want to save this? - ywrite(&check, (void *)HighWram, 0x100000, 1, fp); - ywrite(&check, (void *)LowWram, 0x100000, 1, fp); - - ywrite(&check, (void *)&yabsys.DecilineCount, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.LineCount, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.VBlankLineCount, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.MaxLineCount, sizeof(int), 1, fp); - temp = yabsys.DecilineStop >> YABSYS_TIMING_BITS; - ywrite(&check, (void *)&temp, sizeof(int), 1, fp); - temp = (yabsys.CurSH2FreqType == CLKTYPE_26MHZ) ? 268 : 286; - ywrite(&check, (void *)&temp, sizeof(int), 1, fp); - //temp32 = (yabsys.UsecFrac * temp / 10) >> YABSYS_TIMING_BITS; - ywrite(&check, (void *)&yabsys.UsecFrac, sizeof(u32), 1, fp); - ywrite(&check, (void *)&yabsys.CurSH2FreqType, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.IsPal, sizeof(int), 1, fp); - /* - VIDCore->GetGlSize(&outputwidth, &outputheight); - - totalsize=outputwidth * outputheight * sizeof(u32); - - if ((buf = (u8 *)malloc(totalsize)) == NULL) - { - return -2; - } - - YuiSwapBuffers(); - #ifdef USE_OPENGL - glPixelZoom(1,1); - glReadBuffer(GL_BACK); - glReadPixels(0, 0, outputwidth, outputheight, GL_RGBA, GL_UNSIGNED_BYTE, buf); - #endif - YuiSwapBuffers(); - - ywrite(&check, (void *)&outputwidth, sizeof(outputwidth), 1, fp); - ywrite(&check, (void *)&outputheight, sizeof(outputheight), 1, fp); - - ywrite(&check, (void *)buf, totalsize, 1, fp); - - movieposition=ftell(fp); - //write the movie to the end of the savestate - SaveMovieInState(fp, check); - */ - i += StateFinishHeader(fp, offset); - /* - // Go back and update size - fseek(fp, 8, SEEK_SET); - ywrite(&check, (void *)&i, sizeof(i), 1, fp); - fseek(fp, 16, SEEK_SET); - ywrite(&check, (void *)&movieposition, sizeof(movieposition), 1, fp); - */ - fclose(fp); - - OSDPushMessage(OSDMSG_STATUS, 150, "STATE SAVED"); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int YabLoadState(const char *filename) -{ - FILE *fp; - char id[3]; - u8 endian; - int headerversion, version, size, chunksize, headersize; - IOCheck_struct check; - u8* buf; - int totalsize; - int outputwidth; - int outputheight; - int curroutputwidth; - int curroutputheight; - int movieposition; - int temp; - u32 temp32; - - filename = MakeMovieStateName(filename); - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - headersize = 0xC; - - // Read signature - yread(&check, (void *)id, 1, 3, fp); - - if (strncmp(id, "YSS", 3) != 0) - { - fclose(fp); - return -2; - } - - // Read header - yread(&check, (void *)&endian, 1, 1, fp); - yread(&check, (void *)&headerversion, 4, 1, fp); - yread(&check, (void *)&size, 4, 1, fp); - switch(headerversion) - { - case 1: - /* This is the "original" version of the format */ - break; - case 2: - /* version 2 adds video recording */ - yread(&check, (void *)&framecounter, 4, 1, fp); - movieposition=ftell(fp); - yread(&check, (void *)&movieposition, 4, 1, fp); - headersize = 0x14; - break; - default: - /* we're trying to open a save state using a future version - * of the YSS format, that won't work, sorry :) */ - fclose(fp); - return -3; - break; - } - -#ifdef WORDS_BIGENDIAN - if (endian == 1) -#else - if (endian == 0) -#endif - { - // should setup reading so it's byte-swapped - YabSetError(YAB_ERR_OTHER, (void *)"Load State byteswapping not supported"); - fclose(fp); - return -3; - } - - // Make sure size variable matches actual size minus header - //fseek(fp, 0, SEEK_END); - - //if (size != (ftell(fp) - headersize)) - //{ - // fclose(fp); - // return -2; - //} - //fseek(fp, headersize, SEEK_SET); - - // Verify version here - - ScspMuteAudio(SCSP_MUTE_SYSTEM); - - if (StateCheckRetrieveHeader(fp, "CART", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - CartLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "CS2 ", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - Cs2LoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "MSH2", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SH2LoadState(MSH2, fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SSH2", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SH2LoadState(SSH2, fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SCSP", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SoundLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SCU ", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - ScuLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SMPC", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SmpcLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "VDP1", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - Vdp1LoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "VDP2", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - Vdp2LoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "OTHR", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - // Other data - yread(&check, (void *)BupRam, 0x10000, 1, fp); - yread(&check, (void *)HighWram, 0x100000, 1, fp); - yread(&check, (void *)LowWram, 0x100000, 1, fp); - - yread(&check, (void *)&yabsys.DecilineCount, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.LineCount, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.VBlankLineCount, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.MaxLineCount, sizeof(int), 1, fp); - yread(&check, (void *)&temp, sizeof(int), 1, fp); - yread(&check, (void *)&temp, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.UsecFrac, sizeof(u32), 1, fp); - yread(&check, (void *)&yabsys.CurSH2FreqType, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.IsPal, sizeof(int), 1, fp); - //YabauseChangeTiming(yabsys.CurSH2FreqType); - //yabsys.UsecFrac = (temp32 << YABSYS_TIMING_BITS) * temp / 10; - - /* - if (headerversion > 1) { - - yread(&check, (void *)&outputwidth, sizeof(outputwidth), 1, fp); - yread(&check, (void *)&outputheight, sizeof(outputheight), 1, fp); - - totalsize=outputwidth * outputheight * sizeof(u32); - - if ((buf = (u8 *)malloc(totalsize)) == NULL) - { - return -2; - } - - yread(&check, (void *)buf, totalsize, 1, fp); - - YuiSwapBuffers(); - - #ifdef USE_OPENGL - if(VIDCore->id == VIDCORE_SOFT) - glRasterPos2i(0, outputheight); - if(VIDCore->id == VIDCORE_OGL) - glRasterPos2i(0, outputheight/2); - #endif - - VIDCore->GetGlSize(&curroutputwidth, &curroutputheight); - #ifdef USE_OPENGL - glPixelZoom((float)curroutputwidth / (float)outputwidth, ((float)curroutputheight / (float)outputheight)); - glDrawPixels(outputwidth, outputheight, GL_RGBA, GL_UNSIGNED_BYTE, buf); - #endif - YuiSwapBuffers(); - - fseek(fp, movieposition, SEEK_SET); - MovieReadState(fp, filename); - } - */ - fclose(fp); - - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - - OSDPushMessage(OSDMSG_STATUS, 150, "STATE LOADED"); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int YabSaveStateSlot(const char *dirpath, u8 slot) -{ - char filename[512]; - - if (cdip == NULL) - return -1; - -#ifdef WIN32 - sprintf(filename, "%s\\%s_%03d.yss", dirpath, cdip->itemnum, slot); -#else - sprintf(filename, "%s/%s_%03d.yss", dirpath, cdip->itemnum, slot); -#endif - return YabSaveState(filename); -} - -////////////////////////////////////////////////////////////////////////////// - -int YabLoadStateSlot(const char *dirpath, u8 slot) -{ - char filename[512]; - - if (cdip == NULL) - return -1; - -#ifdef WIN32 - sprintf(filename, "%s\\%s_%03d.yss", dirpath, cdip->itemnum, slot); -#else - sprintf(filename, "%s/%s_%03d.yss", dirpath, cdip->itemnum, slot); -#endif - return YabLoadState(filename); -} - -////////////////////////////////////////////////////////////////////////////// - -static int MappedMemoryAddMatch(u32 addr, u32 val, int searchtype, result_struct *result, u32 *numresults) -{ - result[numresults[0]].addr = addr; - result[numresults[0]].val = val; - numresults[0]++; - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE int SearchIncrementAndCheckBounds(result_struct *prevresults, - u32 *maxresults, - u32 numresults, u32 *i, - u32 inc, u32 *newaddr, - u32 endaddr) -{ - if (prevresults) - { - if (i[0] >= maxresults[0]) - { - maxresults[0] = numresults; - return 1; - } - newaddr[0] = prevresults[i[0]].addr; - i[0]++; - } - else - { - newaddr[0] = inc; - - if (newaddr[0] > endaddr || numresults >= maxresults[0]) - { - maxresults[0] = numresults; - return 1; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int SearchString(u32 startaddr, u32 endaddr, int searchtype, - const char *searchstr, result_struct *results, - u32 *maxresults) -{ - u8 *buf=NULL; - u32 *buf32=NULL; - u32 buflen=0; - u32 counter; - u32 addr; - u32 numresults=0; - - buflen=(u32)strlen(searchstr); - - if ((buf32=(u32 *)malloc(buflen*sizeof(u32))) == NULL) - return 0; - - buf = (u8 *)buf32; - - // Copy string to buffer - switch (searchtype & 0x70) - { - case SEARCHSTRING: - strcpy((char *)buf, searchstr); - break; - case SEARCHREL8BIT: - case SEARCHREL16BIT: - { - char *text; - char *searchtext=strdup(searchstr); - - // Calculate buffer length and read values into table - buflen = 0; - for (text=strtok((char *)searchtext, " ,"); text != NULL; text=strtok(NULL, " ,")) - { - buf32[buflen] = strtoul(text, NULL, 0); - buflen++; - } - free(searchtext); - - break; - } - } - - addr = startaddr; - counter = 0; - - for (;;) - { - // Fetch byte/word/etc. - switch (searchtype & 0x70) - { - case SEARCHSTRING: - { - u8 val = MappedMemoryReadByte(addr); - addr++; - - if (val == buf[counter]) - { - counter++; - if (counter == buflen) - MappedMemoryAddMatch(addr-buflen, val, searchtype, results, &numresults); - } - else - counter = 0; - break; - } - case SEARCHREL8BIT: - { - int diff; - u32 j; - u8 val2; - u8 val = MappedMemoryReadByte(addr); - - for (j = 1; j < buflen; j++) - { - // grab the next value - val2 = MappedMemoryReadByte(addr+j); - - // figure out the diff - diff = (int)val2 - (int)val; - - // see if there's a match - if (((int)buf32[j] - (int)buf32[j-1]) != diff) - break; - - if (j == (buflen - 1)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - - val = val2; - } - - addr++; - - break; - } - case SEARCHREL16BIT: - { - int diff; - u32 j; - u16 val2; - u16 val = MappedMemoryReadWord(addr); - - for (j = 1; j < buflen; j++) - { - // grab the next value - val2 = MappedMemoryReadWord(addr+(j*2)); - - // figure out the diff - diff = (int)val2 - (int)val; - - // see if there's a match - if (((int)buf32[j] - (int)buf32[j-1]) != diff) - break; - - if (j == (buflen - 1)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - - val = val2; - } - - addr+=2; - break; - } - } - - if (addr > endaddr || numresults >= maxresults[0]) - break; - } - - free(buf); - maxresults[0] = numresults; - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -result_struct *MappedMemorySearch(u32 startaddr, u32 endaddr, int searchtype, - const char *searchstr, - result_struct *prevresults, u32 *maxresults) -{ - u32 i=0; - result_struct *results; - u32 numresults=0; - unsigned long searchval; - int issigned=0; - u32 addr; - - if ((results = (result_struct *)malloc(sizeof(result_struct) * maxresults[0])) == NULL) - return NULL; - - switch (searchtype & 0x70) - { - case SEARCHSTRING: - case SEARCHREL8BIT: - case SEARCHREL16BIT: - { - // String/8-bit relative/16-bit relative search(not supported, yet) - if (SearchString(startaddr, endaddr, searchtype, searchstr, - results, maxresults) == 0) - { - maxresults[0] = 0; - free(results); - return NULL; - } - - return results; - } - case SEARCHHEX: - sscanf(searchstr, "%08lx", &searchval); - break; - case SEARCHUNSIGNED: - searchval = (unsigned long)atoi(searchstr); - issigned = 0; - break; - case SEARCHSIGNED: - searchval = (unsigned long)atoi(searchstr); - issigned = 1; - break; - } - - if (prevresults) - { - addr = prevresults[i].addr; - i++; - } - else - addr = startaddr; - - // Regular value search - for (;;) - { - u32 val=0; - u32 newaddr; - - // Fetch byte/word/etc. - switch (searchtype & 0x3) - { - case SEARCHBYTE: - val = MappedMemoryReadByte(addr); - // sign extend if neccessary - if (issigned) - val = (s8)val; - - if (SearchIncrementAndCheckBounds(prevresults, maxresults, numresults, &i, addr+1, &newaddr, endaddr)) - return results; - break; - case SEARCHWORD: - val = MappedMemoryReadWord(addr); - // sign extend if neccessary - if (issigned) - val = (s16)val; - - if (SearchIncrementAndCheckBounds(prevresults, maxresults, numresults, &i, addr+2, &newaddr, endaddr)) - return results; - break; - case SEARCHLONG: - val = MappedMemoryReadLong(addr); - - if (SearchIncrementAndCheckBounds(prevresults, maxresults, numresults, &i, addr+4, &newaddr, endaddr)) - return results; - break; - default: - maxresults[0] = 0; - if (results) - free(results); - return NULL; - } - - // Do a comparison - switch (searchtype & 0xC) - { - case SEARCHEXACT: - if (val == searchval) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - break; - case SEARCHLESSTHAN: - if ((!issigned && val < searchval) || (issigned && (signed)val < (signed)searchval)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - break; - case SEARCHGREATERTHAN: - if ((!issigned && val > searchval) || (issigned && (signed)val > (signed)searchval)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - break; - default: - maxresults[0] = 0; - if (results) - free(results); - return NULL; - } - - addr = newaddr; - } - - maxresults[0] = numresults; - return results; -} diff --git a/yabause/src/memory.h b/yabause/src/memory.h deleted file mode 100644 index 7cab523ea7..0000000000 --- a/yabause/src/memory.h +++ /dev/null @@ -1,409 +0,0 @@ -/* Copyright 2005-2006 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef MEMORY_H -#define MEMORY_H - -#include -#include "core.h" - -/* Type 1 Memory, faster for byte (8 bits) accesses */ - -u8 * T1MemoryInit(u32); -void T1MemoryDeInit(u8 *); - -static INLINE u8 T1ReadByte(u8 * mem, u32 addr) -{ - return mem[addr]; -} - -static INLINE u16 T1ReadWord(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u16 *) (mem + addr)); -#else - return BSWAP16(*((u16 *) (mem + addr))); -#endif -} - -static INLINE u32 T1ReadLong(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u32 *) (mem + addr)); -#else - return BSWAP32(*((u32 *) (mem + addr))); -#endif -} - -static INLINE void T1WriteByte(u8 * mem, u32 addr, u8 val) -{ - mem[addr] = val; -} - -static INLINE void T1WriteWord(u8 * mem, u32 addr, u16 val) -{ -#ifdef WORDS_BIGENDIAN - *((u16 *) (mem + addr)) = val; -#else - *((u16 *) (mem + addr)) = BSWAP16(val); -#endif -} - -static INLINE void T1WriteLong(u8 * mem, u32 addr, u32 val) -{ -#ifdef WORDS_BIGENDIAN - *((u32 *) (mem + addr)) = val; -#else - *((u32 *) (mem + addr)) = BSWAP32(val); -#endif -} - -/* Type 2 Memory, faster for word (16 bits) accesses */ - -#define T2MemoryInit(x) (T1MemoryInit(x)) -#define T2MemoryDeInit(x) (T1MemoryDeInit(x)) - -static INLINE u8 T2ReadByte(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return mem[addr]; -#else - return mem[addr ^ 1]; -#endif -} - -static INLINE u16 T2ReadWord(u8 * mem, u32 addr) -{ - return *((u16 *) (mem + addr)); -} - -static INLINE u32 T2ReadLong(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u32 *) (mem + addr)); -#else - return WSWAP32(*((u32 *) (mem + addr))); -#endif -} - -static INLINE void T2WriteByte(u8 * mem, u32 addr, u8 val) -{ -#ifdef WORDS_BIGENDIAN - mem[addr] = val; -#else - mem[addr ^ 1] = val; -#endif -} - -static INLINE void T2WriteWord(u8 * mem, u32 addr, u16 val) -{ - *((u16 *) (mem + addr)) = val; -} - -static INLINE void T2WriteLong(u8 * mem, u32 addr, u32 val) -{ -#ifdef WORDS_BIGENDIAN - *((u32 *) (mem + addr)) = val; -#else - *((u32 *) (mem + addr)) = WSWAP32(val); -#endif -} - -/* Type 3 Memory, faster for long (32 bits) accesses */ - -typedef struct -{ - u8 * base_mem; - u8 * mem; -} T3Memory; - -T3Memory * T3MemoryInit(u32); -void T3MemoryDeInit(T3Memory *); - -static INLINE u8 T3ReadByte(T3Memory * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return mem->mem[addr]; -#else - return (mem->mem - addr - 1)[0]; -#endif -} - -static INLINE u16 T3ReadWord(T3Memory * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u16 *) (mem->mem + addr)); -#else - return ((u16 *) (mem->mem - addr - 2))[0]; -#endif -} - -static INLINE u32 T3ReadLong(T3Memory * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u32 *) (mem->mem + addr)); -#else - return ((u32 *) (mem->mem - addr - 4))[0]; -#endif -} - -static INLINE void T3WriteByte(T3Memory * mem, u32 addr, u8 val) -{ -#ifdef WORDS_BIGENDIAN - mem->mem[addr] = val; -#else - (mem->mem - addr - 1)[0] = val; -#endif -} - -static INLINE void T3WriteWord(T3Memory * mem, u32 addr, u16 val) -{ -#ifdef WORDS_BIGENDIAN - *((u16 *) (mem->mem + addr)) = val; -#else - ((u16 *) (mem->mem - addr - 2))[0] = val; -#endif -} - -static INLINE void T3WriteLong(T3Memory * mem, u32 addr, u32 val) -{ -#ifdef WORDS_BIGENDIAN - *((u32 *) (mem->mem + addr)) = val; -#else - ((u32 *) (mem->mem - addr - 4))[0] = val; -#endif -} - -static INLINE int T123Load(void * mem, u32 size, int type, const char *filename) -{ - FILE *fp; - u32 filesizecheck; - u8 *buffer; - u32 i; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - // Calculate file size - //fseek(fp, 0, SEEK_END); - //filesize = ftell(fp); - //fseek(fp, 0, SEEK_SET); - - //if (filesize > size) - // return -1; - - if ((buffer = (u8 *)malloc(size)) == NULL) - { - fclose(fp); - return -1; - } - - filesizecheck = (u32)fread((void *)buffer, 1, size, fp); - // make sure there are no bytes left in the file - if (filesizecheck != size || fgetc(fp) != EOF) - { - free(buffer); - fclose(fp); - return -1; - } - - fclose(fp); - - switch (type) - { - case 1: - { - for (i = 0; i < size; i++) - T1WriteByte((u8 *) mem, i, buffer[i]); - break; - } - case 2: - { - for (i = 0; i < size; i++) - T2WriteByte((u8 *) mem, i, buffer[i]); - break; - } - case 3: - { - for (i = 0; i < size; i++) - T3WriteByte((T3Memory *) mem, i, buffer[i]); - break; - } - default: - { - free(buffer); - return -1; - } - } - - free(buffer); - - return 0; -} - -static INLINE int T123Save(void * mem, u32 size, int type, const char *filename) -{ - FILE *fp; - u8 *buffer; - u32 i; - u32 sizecheck; - - if (filename == NULL) - return 0; - - if (filename[0] == 0x00) - return 0; - - if ((buffer = (u8 *)malloc(size)) == NULL) - return -1; - - switch (type) - { - case 1: - { - for (i = 0; i < size; i++) - buffer[i] = T1ReadByte((u8 *) mem, i); - break; - } - case 2: - { - for (i = 0; i < size; i++) - buffer[i] = T2ReadByte((u8 *) mem, i); - break; - } - case 3: - { - for (i = 0; i < size; i++) - buffer[i] = T3ReadByte((T3Memory *) mem, i); - break; - } - default: - { - free(buffer); - return -1; - } - } - - if ((fp = fopen(filename, "wb")) == NULL) - { - free(buffer); - return -1; - } - - sizecheck = (u32)fwrite((void *)buffer, 1, size, fp); - fclose(fp); - free(buffer); - - if (sizecheck != size) return -1; - - return 0; -} - -/* Dummy memory, always returns 0 */ - -typedef void Dummy; - -Dummy * DummyInit(u32); -void DummyDeInit(Dummy *); - -static INLINE u8 DummyReadByte(Dummy UNUSED * d, u32 UNUSED a) { return 0; } -static INLINE u16 DummyReadWord(Dummy UNUSED * d, u32 UNUSED a) { return 0; } -static INLINE u32 DummyReadLong(Dummy UNUSED * d, u32 UNUSED a) { return 0; } - -static INLINE void DummyWriteByte(Dummy UNUSED * d, u32 UNUSED a, u8 UNUSED v) {} -static INLINE void DummyWriteWord(Dummy UNUSED * d, u32 UNUSED a, u16 UNUSED v) {} -static INLINE void DummyWriteLong(Dummy UNUSED * d, u32 UNUSED a, u32 UNUSED v) {} - -void MappedMemoryInit(void); -u8 FASTCALL MappedMemoryReadByte(u32 addr); -u16 FASTCALL MappedMemoryReadWord(u32 addr); -u32 FASTCALL MappedMemoryReadLong(u32 addr); -void FASTCALL MappedMemoryWriteByte(u32 addr, u8 val); -void FASTCALL MappedMemoryWriteWord(u32 addr, u16 val); -void FASTCALL MappedMemoryWriteLong(u32 addr, u32 val); -#ifdef __cplusplus -extern "C" { -#endif -extern u8 *HighWram; -#ifdef __cplusplus -} -#endif -extern u8 *LowWram; -extern u8 *BiosRom; -extern u8 *BupRam; -extern u8 BupRamWritten; - -typedef void (FASTCALL *writebytefunc)(u32, u8); -typedef void (FASTCALL *writewordfunc)(u32, u16); -typedef void (FASTCALL *writelongfunc)(u32, u32); - -typedef u8 (FASTCALL *readbytefunc)(u32); -typedef u16 (FASTCALL *readwordfunc)(u32); -typedef u32 (FASTCALL *readlongfunc)(u32); - -extern writebytefunc WriteByteList[0x1000]; -extern writewordfunc WriteWordList[0x1000]; -extern writelongfunc WriteLongList[0x1000]; - -extern readbytefunc ReadByteList[0x1000]; -extern readwordfunc ReadWordList[0x1000]; -extern readlongfunc ReadLongList[0x1000]; - -typedef struct { -u32 addr; -u32 val; -} result_struct; - -#define SEARCHBYTE 0 -#define SEARCHWORD 1 -#define SEARCHLONG 2 - -#define SEARCHEXACT (0 << 2) -#define SEARCHLESSTHAN (1 << 2) -#define SEARCHGREATERTHAN (2 << 2) - -#define SEARCHUNSIGNED (0 << 4) -#define SEARCHSIGNED (1 << 4) -#define SEARCHHEX (2 << 4) -#define SEARCHSTRING (3 << 4) -#define SEARCHREL8BIT (6 << 4) -#define SEARCHREL16BIT (7 << 4) - -result_struct *MappedMemorySearch(u32 startaddr, u32 endaddr, int searchtype, - const char *searchstr, - result_struct *prevresults, u32 *maxresults); - -int MappedMemoryLoad(const char *filename, u32 addr); -int MappedMemorySave(const char *filename, u32 addr, u32 size); -void MappedMemoryLoadExec(const char *filename, u32 pc); - -int LoadBios(const char *filename); -int LoadBackupRam(const char *filename); -void FormatBackupRam(void *mem, u32 size); - -int YabSaveState(const char *filename); -int YabLoadState(const char *filename); -int YabSaveStateSlot(const char *dirpath, u8 slot); -int YabLoadStateSlot(const char *dirpath, u8 slot); - -#endif diff --git a/yabause/src/movie.c b/yabause/src/movie.c deleted file mode 100644 index 5ca936c116..0000000000 --- a/yabause/src/movie.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "peripheral.h" -#include "scsp.h" -#include "movie.h" -#include "cs2.h" -#include "vdp2.h" // for DisplayMessage() prototype -#include "yabause.h" - -int RecordingFileOpened; -int PlaybackFileOpened; - -struct MovieStruct Movie; - -char MovieStatus[40]; -int movieLoaded = 0; //Boolean value, 1 if a movie is playing or recording - -//Counting -int framecounter; -int lagframecounter; -int LagFrameFlag; -int FrameAdvanceVariable=0; - -int headersize=512; - -////////////////////////////////////////////////////////////////////////////// - -static void ReadHeader(FILE* fp) { - - fseek(fp, 0, SEEK_SET); - - fseek(fp, 172, SEEK_SET); - fread(&Movie.Rerecords, sizeof(Movie.Rerecords), 1, fp); - - fseek(fp, headersize, SEEK_SET); -} - -////////////////////////////////////////////////////////////////////////////// - -static void WriteHeader(FILE* fp) { - - fseek(fp, 0, SEEK_SET); - - fwrite("YMV", sizeof("YMV"), 1, fp); - fwrite(VERSION, sizeof(VERSION), 1, fp); - fwrite(cdip->cdinfo, sizeof(cdip->cdinfo), 1, fp); - fwrite(cdip->itemnum, sizeof(cdip->itemnum), 1, fp); - fwrite(cdip->version, sizeof(cdip->version), 1, fp); - fwrite(cdip->date, sizeof(cdip->date), 1, fp); - fwrite(cdip->gamename, sizeof(cdip->gamename), 1, fp); - fwrite(cdip->region, sizeof(cdip->region), 1, fp); - fwrite(&Movie.Rerecords, sizeof(Movie.Rerecords), 1, fp); - fwrite(&yabsys.emulatebios, sizeof(yabsys.emulatebios), 1, fp); - fwrite(&yabsys.IsPal, sizeof(yabsys.IsPal), 1, fp); - - fseek(fp, headersize, SEEK_SET); -} - -////////////////////////////////////////////////////////////////////////////// - -static void ClearInput(void) { - - //do something.... -} - -////////////////////////////////////////////////////////////////////////////// - -const char* Buttons[8] = {"B", "C", "A", "S", "U", "D", "R", "L"}; -const char* Spaces[8] = {" ", " ", " ", " ", " ", " ", " ", " "}; -const char* Buttons2[8] = {"", "", "", "L", "Z", "Y", "X", "R"}; -const char* Spaces2[8] = {"", "", "", " ", " ", " ", " ", " "}; - -char str[40]; -char InputDisplayString[40]; - -static void SetInputDisplayCharacters(void) { - - int x; - - strcpy(str, ""); - - for (x = 0; x < 8; x++) { - - if(PORTDATA1.data[2] & (1 << x)) { - strcat(str, Spaces[x]); - } - else - strcat(str, Buttons[x]); - - } - - for (x = 0; x < 8; x++) { - - if(PORTDATA1.data[3] & (1 << x)) { - strcat(str, Spaces2[x]); - } - else - strcat(str, Buttons2[x]); - - } - - strcpy(InputDisplayString, str); -} - -////////////////////////////////////////////////////////////////////////////// - -static void IncrementLagAndFrameCounter(void) -{ - if(LagFrameFlag == 1) - lagframecounter++; - - framecounter++; -} - -////////////////////////////////////////////////////////////////////////////// - -int framelength=16; - -void DoMovie(void) { - - int x; - - IncrementLagAndFrameCounter(); - LagFrameFlag=1; - SetInputDisplayCharacters(); - - //Read/Write Controller Data - if(Movie.Status == Recording) { - for (x = 0; x < 8; x++) { - fwrite(&PORTDATA1.data[x], 1, 1, Movie.fp); - } - for (x = 0; x < 8; x++) { - fwrite(&PORTDATA2.data[x], 1, 1, Movie.fp); - } - } - - if(Movie.Status == Playback) { - for (x = 0; x < 8; x++) { - fread(&PORTDATA1.data[x], 1, 1, Movie.fp); - } - for (x = 0; x < 8; x++) { - fread(&PORTDATA2.data[x], 1, 1, Movie.fp); - } - - //if we get to the end of the movie - if(((ftell(Movie.fp)-headersize)/framelength) >= Movie.Frames) { - fclose(Movie.fp); - PlaybackFileOpened=0; - Movie.Status = Stopped; - ClearInput(); - strcpy(MovieStatus, "Playback Stopped"); - } - } - - //Stop Recording/Playback - if(Movie.Status != Recording && RecordingFileOpened) { - fclose(Movie.fp); - RecordingFileOpened=0; - Movie.Status = Stopped; - strcpy(MovieStatus, "Recording Stopped"); - } - - if(Movie.Status != Playback && PlaybackFileOpened && Movie.ReadOnly != 0) { - fclose(Movie.fp); - PlaybackFileOpened=0; - Movie.Status = Stopped; - strcpy(MovieStatus, "Playback Stopped"); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void MovieLoadState(const char * filename) { - - - if (Movie.ReadOnly == 1 && Movie.Status == Playback) { - //Movie.Status = Playback; - fseek (Movie.fp,headersize+(framecounter * framelength),SEEK_SET); - } - - if(Movie.Status == Recording) { - fseek (Movie.fp,headersize+(framecounter * framelength),SEEK_SET); - Movie.Rerecords++; - } - - if(Movie.Status == Playback && Movie.ReadOnly == 0) { - Movie.Status = Recording; - RecordingFileOpened=1; - strcpy(MovieStatus, "Recording Resumed"); - TruncateMovie(Movie); - fseek (Movie.fp,headersize+(framecounter * framelength),SEEK_SET); - Movie.Rerecords++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void TruncateMovie(struct MovieStruct Movie) { - - //when we resume recording, shorten the movie so that there isn't - //potential garbage data at the end - -/*//TODO - struct MovieBufferStruct tempbuffer; - fseek(Movie.fp,0,SEEK_SET); - tempbuffer=ReadMovieIntoABuffer(Movie.fp); - fclose(Movie.fp); - - //clear the file and write it again - Movie.fp=fopen(Movie.filename,"wb"); - fwrite(tempbuffer.data,framelength,framecounter,Movie.fp); - fclose(Movie.fp); - - Movie.fp=fopen(Movie.filename,"r+b"); -*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int MovieGetSize(FILE* fp) { - int size; - int fpos; - - fpos = ftell(fp);//save current pos - - fseek (fp,0,SEEK_END); - size=ftell(fp); - - Movie.Frames=(size-headersize)/ framelength; - - fseek(fp, fpos, SEEK_SET); //reset back to correct pos - return(size); -} - -////////////////////////////////////////////////////////////////////////////// - -void MovieToggleReadOnly(void) { - - if(Movie.Status == Playback) { - - if(Movie.ReadOnly == 1) - { - Movie.ReadOnly=0; - DisplayMessage("Movie is now read+write."); - } - else - { - Movie.ReadOnly=1; - DisplayMessage("Movie is now read only."); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void StopMovie(void) { - - if(Movie.Status == Recording && RecordingFileOpened) { - WriteHeader(Movie.fp); - fclose(Movie.fp); - RecordingFileOpened=0; - Movie.Status = Stopped; - ClearInput(); - strcpy(MovieStatus, "Recording Stopped"); - } - - if(Movie.Status == Playback && PlaybackFileOpened && Movie.ReadOnly != 0) { - fclose(Movie.fp); - PlaybackFileOpened=0; - Movie.Status = Stopped; - ClearInput(); - strcpy(MovieStatus, "Playback Stopped"); - } -} - -////////////////////////////////////////////////////////////////////////////// - -int SaveMovie(const char *filename) { - - char* str=malloc(1024); - - if(Movie.Status == Playback) - StopMovie(); - - if ((Movie.fp = fopen(filename, "w+b")) == NULL) - return -1; - - strcpy(str, filename); - Movie.filename=str; - RecordingFileOpened=1; - framecounter=0; - Movie.Status=Recording; - strcpy(MovieStatus, "Recording Started"); - Movie.Rerecords=0; - WriteHeader(Movie.fp); - YabauseReset(); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int PlayMovie(const char *filename) { - - char* str=malloc(1024); - - if(Movie.Status == Recording) - StopMovie(); - - - if ((Movie.fp = fopen(filename, "r+b")) == NULL) - return -1; - - strcpy(str, filename); - Movie.filename=str; - PlaybackFileOpened=1; - framecounter=0; - Movie.ReadOnly = 1; - Movie.Status=Playback; - Movie.Size = MovieGetSize(Movie.fp); - strcpy(MovieStatus, "Playback Started"); - ReadHeader(Movie.fp); - YabauseReset(); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void SaveMovieInState(FILE* fp, IOCheck_struct check) { - - struct MovieBufferStruct tempbuffer; - - fseek(fp, 0, SEEK_END); - - if(Movie.Status == Recording || Movie.Status == Playback) { - tempbuffer=ReadMovieIntoABuffer(Movie.fp); - - fwrite(&tempbuffer.size, 4, 1, fp); - fwrite(tempbuffer.data, tempbuffer.size, 1, fp); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void MovieReadState(FILE* fp, const char * filename) { - - ReadMovieInState(fp); - MovieLoadState(filename);//file pointer and truncation - -} - -void ReadMovieInState(FILE* fp) { - - struct MovieBufferStruct tempbuffer; - int fpos; - - //overwrite the main movie on disk if we are recording or read+write playback - if(Movie.Status == Recording || (Movie.Status == Playback && Movie.ReadOnly == 0)) { - - fpos=ftell(fp);//where we are in the savestate - fread(&tempbuffer.size, 4, 1, fp);//size - if ((tempbuffer.data = (char *)malloc(tempbuffer.size)) == NULL) - { - return; - } - fread(tempbuffer.data, 1, tempbuffer.size, fp);//movie - fseek(fp, fpos, SEEK_SET);//reset savestate position - - rewind(Movie.fp); - fwrite(tempbuffer.data, 1, tempbuffer.size, Movie.fp); - rewind(Movie.fp); - } -} - -////////////////////////////////////////////////////////////////////////////// - -struct MovieBufferStruct ReadMovieIntoABuffer(FILE* fp) { - - int fpos; - struct MovieBufferStruct tempbuffer; - - fpos = ftell(fp);//save current pos - - fseek (fp,0,SEEK_END); - tempbuffer.size=ftell(fp); //get size - rewind(fp); - - tempbuffer.data = (char*) malloc (sizeof(char)*tempbuffer.size); - fread (tempbuffer.data, 1, tempbuffer.size, fp); - - fseek(fp, fpos, SEEK_SET); //reset back to correct pos - return(tempbuffer); -} - -////////////////////////////////////////////////////////////////////////////// - -const char *MakeMovieStateName(const char *filename) { - - static char *retbuf = NULL; // Save the pointer to avoid memory leaks - if(Movie.Status == Recording || Movie.Status == Playback) { - const unsigned long newsize = strlen(filename) + 5 + 1; - free(retbuf); - retbuf = malloc(newsize); - if (!retbuf) { - return NULL; // out of memory - } - sprintf(retbuf, "%smovie", filename); - return retbuf; - } else { - return filename; // unchanged - } - -} - -////////////////////////////////////////////////////////////////////////////// - -//debugging only -void TestWrite(struct MovieBufferStruct tempbuffer) { - - FILE* tempbuffertest; - - tempbuffertest=fopen("rmiab.txt", "wb"); - fwrite (tempbuffer.data, 1, tempbuffer.size, tempbuffertest); - fclose(tempbuffertest); -} - -////////////////////////////////////////////////////////////////////////////// - -void PauseOrUnpause(void) { - - if(FrameAdvanceVariable == RunNormal) { - FrameAdvanceVariable=Paused; - ScspMuteAudio(SCSP_MUTE_SYSTEM); - } - else { - FrameAdvanceVariable=RunNormal; - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - } -} - -////////////////////////////////////////////////////////////////////////////// - -int IsMovieLoaded(void) -{ - if (RecordingFileOpened || PlaybackFileOpened) - return 1; - else - return 0; -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/movie.h b/yabause/src/movie.h deleted file mode 100644 index ccb70f54cb..0000000000 --- a/yabause/src/movie.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef MOVIE_H -#define MOVIE_H - -#include "core.h" - -#define Stopped 1 -#define Recording 2 -#define Playback 3 - -#define RunNormal 0 -#define Paused 1 -#define NeedAdvance 2 - -void DoMovie(void); - -struct MovieStruct -{ - int Status; - FILE *fp; - int ReadOnly; - int Rerecords; - int Size; - int Frames; - const char* filename; -}; - -extern struct MovieStruct Movie; - -struct MovieBufferStruct -{ - int size; - char* data; -}; - -struct MovieBufferStruct ReadMovieIntoABuffer(FILE* fp); - -void MovieLoadState(const char * filename); - -void SaveMovieInState(FILE* fp, IOCheck_struct check); -void ReadMovieInState(FILE* fp); - -void TestWrite(struct MovieBufferStruct tempbuffer); - -void MovieToggleReadOnly(void); - -void TruncateMovie(struct MovieStruct Movie); - -void DoFrameAdvance(void); - -int SaveMovie(const char *filename); -int PlayMovie(const char *filename); -void StopMovie(void); - -const char *MakeMovieStateName(const char *filename); - -void MovieReadState(FILE* fp, const char * filename); - -void PauseOrUnpause(void); - -int IsMovieLoaded(void); - -extern int framecounter; -extern int LagFrameFlag; -extern int lagframecounter; -extern char MovieStatus[40]; -extern char InputDisplayString[40]; -extern int FrameAdvanceVariable; -#endif diff --git a/yabause/src/netlink.c b/yabause/src/netlink.c deleted file mode 100644 index 5d857fab85..0000000000 --- a/yabause/src/netlink.c +++ /dev/null @@ -1,854 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef USESOCKET -#ifdef __MINGW32__ -// I blame mingw for this -#define _WIN32_WINNT 0x501 -#endif -#endif - -#include -#ifdef USESOCKET -#ifdef WIN32 -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif -#endif -#include "cs2.h" -#include "error.h" -#include "netlink.h" -#include "debug.h" -#include "scu.h" - -Netlink *NetlinkArea = NULL; - -#define NL_RESULTCODE_OK 0 -#define NL_RESULTCODE_CONNECT 1 -#define NL_RESULTCODE_RING 2 -#define NL_RESULTCODE_NOCARRIER 3 -#define NL_RESULTCODE_ERROR 4 -#define NL_RESULTCODE_CONNECT1200 5 -#define NL_RESULTCODE_NODIALTONE 6 -#define NL_RESULTCODE_BUSY 7 -#define NL_RESULTCODE_NOANSWER 8 - -#define CONNECTTYPE_SERVER 0 -#define CONNECTTYPE_CLIENT 1 - -#define CONNECTSTATUS_IDLE 0 -#define CONNECTSTATUS_WAIT 1 -#define CONNECTSTATUS_CONNECT 2 -#define CONNECTSTATUS_CONNECTED 3 - -#define MODEMSTATE_COMMAND 0 -#define MODEMSTATE_ONLINE 1 - -#ifdef USESOCKET -static int NetworkInit(void); -static void NetworkDeInit(void); -static int NetworkConnect(const char *ip, const char *port); -static int NetworkWaitForConnect(const char *port); -static int NetworkSend(const void *buffer, int length); -static int NetworkReceive(void *buffer, int maxlength); - -#ifndef WIN32 -#define closesocket close -#endif -#endif - -////////////////////////////////////////////////////////////////////////////// - -UNUSED static void NetlinkLSRChange(u8 val) -{ - // If IER bit 2 is set and if any of the error or alarms bits are set(and - // they weren't previously), trigger an interrupt - if ((NetlinkArea->reg.IER & 0x4) && ((NetlinkArea->reg.LSR ^ val) & val & 0x1E)) - { - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x6; - ScuSendExternalInterrupt12(); - } - - NetlinkArea->reg.LSR = val; -} - -////////////////////////////////////////////////////////////////////////////// - -#ifndef USESOCKET -UNUSED -#endif -static void NetlinkMSRChange(u8 set, u8 clear) -{ - u8 change; - - change = ((NetlinkArea->reg.MSR >> 4) ^ set) & set; - change |= (((NetlinkArea->reg.MSR >> 4) ^ 0xFF) ^ clear) & clear; - - // If IER bit 3 is set and CTS/DSR/RI/RLSD changes, trigger interrupt - if ((NetlinkArea->reg.IER & 0x8) && change) - { - NetlinkArea->reg.IIR = NetlinkArea->reg.IIR & 0xF0; - ScuSendExternalInterrupt12(); - } - - NetlinkArea->reg.MSR &= ~(clear << 4); - NetlinkArea->reg.MSR |= (set << 4) | change; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL NetlinkReadByte(u32 addr) -{ - u8 ret; - - switch (addr) - { - case 0x95001: // Receiver Buffer/Divisor Latch Low Byte - { - if (NetlinkArea->reg.LCR & 0x80) // Divisor Latch Low Byte - return NetlinkArea->reg.DLL; - else // Receiver Buffer - { - if (NetlinkArea->outbuffersize == 0) - return 0x00; - - ret = NetlinkArea->outbuffer[NetlinkArea->outbufferstart]; - NetlinkArea->outbufferstart++; - NetlinkArea->outbuffersize--; - - // If the buffer is empty now, make sure the data available - // bit in LSR is cleared - if (NetlinkArea->outbuffersize == 0) - { - NetlinkArea->outbufferstart = NetlinkArea->outbufferend = 0; - NetlinkArea->reg.LSR &= ~0x01; - } - - // If interrupt has been triggered because of RBR having data, reset it - if ((NetlinkArea->reg.IER & 0x1) && (NetlinkArea->reg.IIR & 0xF) == 0x4) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - - return ret; - } - - return 0; - } - case 0x95009: // Interrupt Identification Register - { - // If interrupt has been triggered because THB is empty, reset it - if ((NetlinkArea->reg.IER & 0x2) && (NetlinkArea->reg.IIR & 0xF) == 0x2) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - return NetlinkArea->reg.IIR; - } - case 0x9500D: // Line Control Register - { - return NetlinkArea->reg.LCR; - } - case 0x95011: // Modem Control Register - { - return NetlinkArea->reg.MCR; - } - case 0x95015: // Line Status Register - { - return NetlinkArea->reg.LSR; - } - case 0x95019: // Modem Status Register - { - // If interrupt has been triggered because of MSR change, reset it - if ((NetlinkArea->reg.IER & 0x8) && (NetlinkArea->reg.IIR & 0xF) == 0) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - ret = NetlinkArea->reg.MSR; - NetlinkArea->reg.MSR &= 0xF0; - return ret; - } - case 0x9501D: // Scratch - { - return NetlinkArea->reg.SCR; - } - default: - break; - } - - LOG("Unimplemented Netlink byte read: %08X\n", addr); - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL NetlinkDoATResponse(const char *string) -{ - strcpy((char *)&NetlinkArea->outbuffer[NetlinkArea->outbufferend], string); - NetlinkArea->outbufferend += (u32)strlen(string); - NetlinkArea->outbuffersize += (u32)strlen(string); -} - -////////////////////////////////////////////////////////////////////////////// - -static int FASTCALL NetlinkFetchATParameter(u8 val, u32 *offset) -{ - if (val >= '0' && val <= '9') - { - (*offset)++; - return (val - 0x30); - } - else - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL NetlinkWriteByte(u32 addr, u8 val) -{ - switch (addr) - { - case 0x2503D: // ??? - { - return; - } - case 0x95001: // Transmitter Holding Buffer/Divisor Latch Low Byte - { - if (NetlinkArea->reg.LCR & 0x80) // Divisor Latch Low Byte - { - NetlinkArea->reg.DLL = val; - } - else // Transmitter Holding Buffer - { - NetlinkArea->inbuffer[NetlinkArea->inbufferend] = val; - NetlinkArea->inbufferend++; - NetlinkArea->inbuffersize++; - - // If interrupt has been triggered because THB is empty, reset it - if ((NetlinkArea->reg.IER & 0x2) && (NetlinkArea->reg.IIR & 0xF) == 0x2) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - - if (NetlinkArea->modemstate == MODEMSTATE_COMMAND) - { - - if (val == 0x0D && - (strncmp((char *)&NetlinkArea->inbuffer[NetlinkArea->inbufferstart], "AT", 2) == 0 || - strncmp((char *)&NetlinkArea->inbuffer[NetlinkArea->inbufferstart], "at", 2) == 0)) // fix me - { - u32 i=NetlinkArea->inbufferstart+2; - int resultcode=NL_RESULTCODE_OK; - int parameter; - - LOG("Program issued %s\n", NetlinkArea->inbuffer); - - // If echo is enabled, do it - if (NetlinkArea->isechoenab) - NetlinkDoATResponse((char *)NetlinkArea->inbuffer); - - // Handle AT command - while(NetlinkArea->inbuffer[i] != 0xD) - { - switch (toupper(NetlinkArea->inbuffer[i])) - { - case '%': - break; - case '&': - // Figure out second part of command - i++; - - switch (toupper(NetlinkArea->inbuffer[i])) - { - case 'C': - // Data Carrier Detect Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'D': - // Data Terminal Ready Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'F': - // Factory reset - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'K': - // Local Flow Control Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'Q': - // Communications Mode Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'S': - // Data Set Ready Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - default: break; - } - break; - case ')': - case '*': - case ':': - case '?': - case '@': - case '\\': - break; - case 'A': - // Answer Command(no other commands should follow) - break; - case 'D': - // Dial Command - NetlinkArea->connectstatus = CONNECTSTATUS_CONNECT; - - i = NetlinkArea->inbufferend-1; // fix me - break; - case 'E': - // Command State Character Echo Selection - - parameter = NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - - // Parameter can only be 0 or 1 - if (parameter < 2) - NetlinkArea->isechoenab = parameter; - else - resultcode = NL_RESULTCODE_ERROR; - - break; - case 'I': - // Internal Memory Tests - switch(NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i)) - { - case 0: - NetlinkDoATResponse("\r\n28800\r\n"); - break; - default: break; - } - break; - case 'L': - // Speaker Volume Level Selection - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'M': - // Speaker On/Off Selection - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'V': - // Result Code Format Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'W': - // Negotiation Progress Message Selection - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - default: break; - } - - i++; - } - - switch (resultcode) - { - case NL_RESULTCODE_OK: // OK - NetlinkDoATResponse("\r\nOK\r\n"); - break; - case NL_RESULTCODE_CONNECT: // CONNECT - NetlinkDoATResponse("\r\nCONNECT\r\n"); - break; - case NL_RESULTCODE_RING: // RING - NetlinkDoATResponse("\r\nRING\r\n"); - break; - case NL_RESULTCODE_NOCARRIER: // NO CARRIER - NetlinkDoATResponse("\r\nNO CARRIER\r\n"); - break; - case NL_RESULTCODE_ERROR: // ERROR - NetlinkDoATResponse("\r\nERROR\r\n"); - break; - case NL_RESULTCODE_CONNECT1200: // CONNECT 1200 - NetlinkDoATResponse("\r\nCONNECT 1200\r\n"); - break; - case NL_RESULTCODE_NODIALTONE: // NO DIALTONE - NetlinkDoATResponse("\r\nNO DIALTONE\r\n"); - break; - case NL_RESULTCODE_BUSY: // BUSY - NetlinkDoATResponse("\r\nBUSY\r\n"); - break; - case NL_RESULTCODE_NOANSWER: // NO ANSWER - NetlinkDoATResponse("\r\nNO ANSWER\r\n"); - break; - default: break; - } - - memset(NetlinkArea->inbuffer, 0, NetlinkArea->inbuffersize); - NetlinkArea->inbufferstart = NetlinkArea->inbufferend = NetlinkArea->inbuffersize = 0; - - if (NetlinkArea->outbuffersize > 0) - { - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - } - } - } - } - - return; - } - case 0x95005: // Interrupt Enable Register/Divisor Latch High Byte - { - if (NetlinkArea->reg.LCR & 0x80) // Divisor Latch High Byte - { - NetlinkArea->reg.DLM = val; - } - else // Interrupt Enable Register - { - NetlinkArea->reg.IER = val; - } - - return; - } - case 0x95009: // FIFO Control Register - { - NetlinkArea->reg.FCR = val; - - if (val & 0x1) - // set FIFO enabled bits - NetlinkArea->reg.IIR |= 0xC0; - else - // clear FIFO enabled bits - NetlinkArea->reg.IIR &= ~0xC0; - - return; - } - case 0x9500D: // Line Control Register - { - NetlinkArea->reg.LCR = val; - return; - } - case 0x95011: // Modem Control Register - { - NetlinkArea->reg.MCR = val; - return; - } - case 0x95019: // Modem Status Register(read-only) - return; - case 0x9501D: // Scratch - { - NetlinkArea->reg.SCR = val; - return; - } - default: - break; - } - - LOG("Unimplemented Netlink byte write: %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -int NetlinkInit(const char *setting) -{ - if ((NetlinkArea = malloc(sizeof(Netlink))) == NULL) - { - Cs2Area->carttype = CART_NONE; - YabSetError(YAB_ERR_CANNOTINIT, (void *)"Netlink"); - return 0; - } - - memset(NetlinkArea->inbuffer, 0, NETLINK_BUFFER_SIZE); - memset(NetlinkArea->outbuffer, 0, NETLINK_BUFFER_SIZE); - - NetlinkArea->inbufferstart = NetlinkArea->inbufferend = NetlinkArea->inbuffersize = 0; - NetlinkArea->outbufferstart = NetlinkArea->outbufferend = NetlinkArea->outbuffersize = 0; - - NetlinkArea->isechoenab = 1; - NetlinkArea->cycles = 0; - NetlinkArea->modemstate = MODEMSTATE_COMMAND; - - NetlinkArea->reg.RBR = 0x00; - NetlinkArea->reg.IER = 0x00; - NetlinkArea->reg.DLL = 0x00; - NetlinkArea->reg.DLM = 0x00; - NetlinkArea->reg.IIR = 0x01; -// NetlinkArea->reg.FCR = 0x??; // have no idea - NetlinkArea->reg.LCR = 0x00; - NetlinkArea->reg.MCR = 0x00; - NetlinkArea->reg.LSR = 0x60; - NetlinkArea->reg.MSR = 0x30; - NetlinkArea->reg.SCR = 0x01; - - if (setting == NULL || strcmp(setting, "") == 0) - { - // Use Loopback ip and port 1337 - sprintf(NetlinkArea->ipstring, "127.0.0.1"); - sprintf(NetlinkArea->portstring, "1337"); - } - else - { - char *p; - p = strchr(setting, '\n'); - if (p == NULL) - { - strcpy(NetlinkArea->ipstring, setting); - sprintf(NetlinkArea->portstring, "1337"); - } - else - { - memcpy(NetlinkArea->ipstring, setting, (int)(p - setting)); - NetlinkArea->ipstring[(p - setting)] = '\0'; - if (strlen(p+1) == 0) - sprintf(NetlinkArea->portstring, "1337"); - else - strcpy(NetlinkArea->portstring, p+1); - } - } - -#ifdef USESOCKET - return NetworkInit(); -#else - return 0; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -void NetlinkDeInit(void) -{ -#ifdef USESOCKET - NetworkDeInit(); -#endif - - if (NetlinkArea) - free(NetlinkArea); -} - -////////////////////////////////////////////////////////////////////////////// - -void NetlinkExec(u32 timing) -{ - NetlinkArea->cycles += timing; - - if (NetlinkArea->cycles >= 20000) - { - NetlinkArea->cycles -= 20000; - - switch(NetlinkArea->connectstatus) - { - case CONNECTSTATUS_IDLE: - { -#ifdef USESOCKET - if (NetworkWaitForConnect(NetlinkArea->portstring) == 0) - { - NetlinkArea->connectstatus = CONNECTSTATUS_CONNECTED; - NetlinkArea->modemstate = MODEMSTATE_ONLINE; - - // This is probably wrong, but let's give it a try anyways - NetlinkDoATResponse("\r\nRING\r\n\r\nCONNECT\r\n"); - NetlinkMSRChange(0x08, 0x00); - - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - LOG("Connected via idle\n"); - } -#endif - break; - } - case CONNECTSTATUS_CONNECT: - { -#ifdef USESOCKET - if (NetworkConnect(NetlinkArea->ipstring, NetlinkArea->portstring) == 0) - { - NetlinkArea->connectstatus = CONNECTSTATUS_CONNECTED; - NetlinkArea->modemstate = MODEMSTATE_ONLINE; - - NetlinkDoATResponse("\r\nCONNECT\r\n"); - NetlinkMSRChange(0x08, 0x00); - - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - LOG("Connected via connect\n"); - } -#endif - break; - } - case CONNECTSTATUS_CONNECTED: - { -#ifdef USESOCKET - int bytes; - fd_set read_fds; - fd_set write_fds; - struct timeval tv; - - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - - // Let's see if we can even connect at this point - FD_SET(NetlinkArea->connectsocket, &read_fds); - FD_SET(NetlinkArea->connectsocket, &write_fds); - tv.tv_sec = 0; - tv.tv_usec = 0; - - if (select(NetlinkArea->connectsocket+1, &read_fds, &write_fds, NULL, &tv) < 1) - { - LOG("select failed\n"); - return; - } - - if (NetlinkArea->modemstate == MODEMSTATE_ONLINE && NetlinkArea->inbuffersize > 0 && FD_ISSET(NetlinkArea->connectsocket, &write_fds)) - { - LOG("Sending to external source..."); - - // Send via network connection - if ((bytes = NetworkSend(&NetlinkArea->inbuffer[NetlinkArea->inbufferstart], NetlinkArea->inbufferend-NetlinkArea->inbufferstart)) >= 0) - { - LOG("Successfully sent %d byte(s)\n", bytes); - if (NetlinkArea->inbufferend > bytes) - { - NetlinkArea->inbufferstart += bytes; - NetlinkArea->inbuffersize -= bytes; - } - else - NetlinkArea->inbufferstart = NetlinkArea->inbufferend = NetlinkArea->inbuffersize = 0; - } - else - { - LOG("failed.\n"); - } - } - - if (FD_ISSET(NetlinkArea->connectsocket, &read_fds)) - { -// if ((bytes = NetworkReceive(&NetlinkArea->outbuffer[NetlinkArea->outbufferend], NETLINK_BUFFER_SIZE-NetlinkArea->outbufferend)) > 0) - if ((bytes = NetworkReceive(&NetlinkArea->outbuffer[NetlinkArea->outbufferend], 8)) > 0) - { - NetlinkArea->outbufferend += bytes; - NetlinkArea->outbuffersize += bytes; - - NetlinkMSRChange(0x08, 0x00); - - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - LOG("Received %d byte(s) from external source\n", bytes); - } - } -#endif - break; - } - default: break; - } - } -} - -////////////////////////////////////////////////////////////////////////////// -#ifdef USESOCKET - -static int NetworkInit(void) -{ -#ifdef WIN32 - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) - return -1; -#endif - - NetlinkArea->connectsocket = -1; - NetlinkArea->connectstatus = CONNECTSTATUS_IDLE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkConnect(const char *ip, const char *port) -{ - struct addrinfo *result = NULL, - hints; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if (getaddrinfo(ip, port, &hints, &result) != 0) - return -1; - - // Create a Socket - if ((NetlinkArea->connectsocket = socket(result->ai_family, result->ai_socktype, - result->ai_protocol)) == -1) - { - freeaddrinfo(result); - return -1; - } - - // Connect to the socket - if (connect(NetlinkArea->connectsocket, result->ai_addr, (int)result->ai_addrlen) == -1) - { - freeaddrinfo(result); - closesocket(NetlinkArea->connectsocket); - NetlinkArea->connectsocket = -1; - return -1; - } - - freeaddrinfo(result); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkWaitForConnect(const char *port) -{ - struct addrinfo *result = NULL, - hints; - int ListenSocket = -1; - fd_set read_fds; - struct timeval tv; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - - if (getaddrinfo(NULL, port, &hints, &result) != 0) - return -1; - - // Create a socket that the client can connect to - if ((ListenSocket = socket(result->ai_family, result->ai_socktype, - result->ai_protocol)) == -1) - { - freeaddrinfo(result); - return -1; - } - - // Setup the listening socket - if (bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen) == -1) - { - freeaddrinfo(result); - closesocket(ListenSocket); - return -1; - } - - freeaddrinfo(result); - - // Shhh... Let's listen - if (listen(ListenSocket, SOMAXCONN) == -1) - { - closesocket(ListenSocket); - return -1; - } - - FD_ZERO(&read_fds); - - // Let's see if we can even connect at this point - FD_SET(ListenSocket, &read_fds); - tv.tv_sec = 0; - tv.tv_usec = 0; - - if (select(ListenSocket+1, &read_fds, NULL, NULL, &tv) < 1) - { - closesocket(ListenSocket); - return -1; - } - - if (FD_ISSET(ListenSocket, &read_fds)) - { - // Good, time to connect - if ((NetlinkArea->connectsocket = accept(ListenSocket, NULL, NULL)) == -1) - { - closesocket(ListenSocket); - return -1; - } - - // We don't need the listen socket anymore - closesocket(ListenSocket); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkSend(const void *buffer, int length) -{ - int bytessent; - - if ((bytessent = send(NetlinkArea->connectsocket, buffer, length, 0)) == -1) - { - // Fix me, better error handling is needed -// closesocket(NetlinkArea->connectsocket); -// NetlinkArea->connectsocket = -1; - return -1; - } - - return bytessent; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkReceive(void *buffer, int maxlength) -{ - int bytesreceived; - - bytesreceived = recv(NetlinkArea->connectsocket, buffer, maxlength, 0); - - if (bytesreceived == 0) - { - // Fix me, better handling is needed - LOG("Connection closed\n"); - return -1; - } - else if (bytesreceived < 0) - { - // Fix me, better error handling is needed - return -1; - } - - return bytesreceived; -} - -////////////////////////////////////////////////////////////////////////////// - -static void NetworkDeInit(void) -{ - if (NetlinkArea->connectsocket != -1) - closesocket(NetlinkArea->connectsocket); -#ifdef WIN32 - WSACleanup(); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/yabause/src/netlink.h b/yabause/src/netlink.h deleted file mode 100644 index 38c85aed60..0000000000 --- a/yabause/src/netlink.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef NETLINK_H -#define NETLINK_H - -#define NETLINK_BUFFER_SIZE 1024 - -typedef struct -{ - u8 RBR; - u8 THR; - u8 IER; - u8 DLL; - u8 DLM; - u8 IIR; - u8 FCR; - u8 LCR; - u8 MCR; - u8 LSR; - u8 MSR; - u8 SCR; -} netlinkregs_struct; - -typedef struct { - u8 inbuffer[NETLINK_BUFFER_SIZE]; - u8 outbuffer[NETLINK_BUFFER_SIZE]; - u32 inbufferstart, inbufferend, inbuffersize; - u32 outbufferstart, outbufferend, outbuffersize; - netlinkregs_struct reg; - int isechoenab; - int connectsocket; - int connectstatus; - u32 cycles; - int modemstate; - char ipstring[16]; - char portstring[6]; -} Netlink; - -extern Netlink *NetlinkArea; - -u8 FASTCALL NetlinkReadByte(u32 addr); -void FASTCALL NetlinkWriteByte(u32 addr, u8 val); -int NetlinkInit(const char *settingstring); -void NetlinkDeInit(void); -void NetlinkExec(u32 timing); - -#endif diff --git a/yabause/src/osdcore.c b/yabause/src/osdcore.c deleted file mode 100644 index 5f16d04c23..0000000000 --- a/yabause/src/osdcore.c +++ /dev/null @@ -1,399 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "osdcore.h" -#include "vdp1.h" -#include "font.h" - -#include -#include - -#ifndef YAB_PORT_OSD -/* -Heya fellow port developper :) -If you're reading this, that may be because you want to -use your own OSD core in your port and you're about to -do it here... -Don't. -Please define the CPP constant YAB_PORT_OSD and define -your own list of OSD cores in your port. -This definition was added here to avoid breaking "everything" -when we the new OSD system was added. -*/ -OSD_struct *OSDCoreList[] = { -&OSDDummy, -#ifdef HAVE_LIBGLUT -&OSDGlut, -#endif -&OSDSoft, -NULL -}; -#else -extern OSD_struct * OSDCoreList[]; -#endif - -static OSD_struct * OSD = NULL; -static OSDMessage_struct osdmessages[OSDMSG_COUNT]; - -int OSDInit(int coreid) -{ - int i; - - for (i = 0; OSDCoreList[i] != NULL; i++) - { - if (OSDCoreList[i]->id == coreid) - { - OSD = OSDCoreList[i]; - break; - } - } - - if (OSD == NULL) - return -1; - - if (OSD->Init() != 0) - return -1; - - memset(osdmessages, 0, sizeof(osdmessages)); - osdmessages[OSDMSG_FPS].hidden = 1; - osdmessages[OSDMSG_DEBUG].hidden = 1; - - return 0; -} - -void OSDDeInit() { - if (OSD) - OSD->DeInit(); - OSD = NULL; -} - -int OSDChangeCore(int coreid) -{ - int preservefps, fpshidden, dbghidden; - - preservefps = (OSD != NULL); - fpshidden = osdmessages[OSDMSG_FPS].hidden; - dbghidden = osdmessages[OSDMSG_DEBUG].hidden; - - OSDDeInit(); - OSDInit(coreid); - - if (preservefps) - { - osdmessages[OSDMSG_FPS].hidden = fpshidden; - osdmessages[OSDMSG_DEBUG].hidden = dbghidden; - } - - return 0; -} - -void OSDPushMessage(int msgtype, int ttl, const char * format, ...) -{ - va_list arglist; - char message[1024]; - - if (ttl == 0) return; - - va_start(arglist, format); - vsprintf(message, format, arglist); - va_end(arglist); - - osdmessages[msgtype].type = msgtype; - osdmessages[msgtype].message = strdup(message); - osdmessages[msgtype].timetolive = ttl; - osdmessages[msgtype].timeleft = ttl; -} - -int OSDDisplayMessages(u32 * buffer, int w, int h) -{ - int i = 0; - int somethingnew = 0; - - if (OSD == NULL) return somethingnew; - - for(i = 0;i < OSDMSG_COUNT;i++) - if (osdmessages[i].timeleft > 0) - { - if (osdmessages[i].hidden == 0) - { - somethingnew = 1; - OSD->DisplayMessage(osdmessages + i, buffer, w, h); - } - osdmessages[i].timeleft--; - if (osdmessages[i].timeleft == 0) free(osdmessages[i].message); - } - - return somethingnew; -} - -void OSDToggle(int what) -{ - if ((what < 0) || (what >= OSDMSG_COUNT)) return; - - osdmessages[what].hidden = 1 - osdmessages[what].hidden; -} - -int OSDIsVisible(int what) -{ - if ((what < 0) || (what >= OSDMSG_COUNT)) return -1; - - return 1 - osdmessages[what].hidden; -} - -void OSDSetVisible(int what, int visible) -{ - if ((what < 0) || (what >= OSDMSG_COUNT)) return; - - visible = visible == 0 ? 0 : 1; - osdmessages[what].hidden = 1 - visible; -} - -int OSDUseBuffer(void) -{ - if (OSD == NULL) return 0; - - return OSD->UseBuffer(); -} - -void ToggleFPS() -{ - OSDToggle(OSDMSG_FPS); -} - -int GetOSDToggle(void) -{ - return OSDIsVisible(OSDMSG_FPS); -} - -void SetOSDToggle(int toggle) -{ - OSDSetVisible(OSDMSG_FPS, toggle); -} - -void DisplayMessage(const char* str) -{ - OSDPushMessage(OSDMSG_STATUS, 120, str); -} - -static int OSDDummyInit(void); -static void OSDDummyDeInit(void); -static void OSDDummyReset(void); -static void OSDDummyDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h); -static int OSDDummyUseBuffer(void); - -OSD_struct OSDDummy = { - OSDCORE_DUMMY, - "Dummy OSD Interface", - OSDDummyInit, - OSDDummyDeInit, - OSDDummyReset, - OSDDummyDisplayMessage, - OSDDummyUseBuffer, -}; - -int OSDDummyInit(void) -{ - return 0; -} - -void OSDDummyDeInit(void) -{ -} - -void OSDDummyReset(void) -{ -} - -void OSDDummyDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h) -{ -} - -int OSDDummyUseBuffer(void) -{ - return 0; -} - -#ifdef HAVE_LIBGLUT -#ifdef __APPLE__ - #include -#else - #include -#endif - -static int OSDGlutInit(void); -static void OSDGlutDeInit(void); -static void OSDGlutReset(void); -static void OSDGlutDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h); -static int OSDGlutUseBuffer(void); - -OSD_struct OSDGlut = { - OSDCORE_GLUT, - "Glut OSD Interface", - OSDGlutInit, - OSDGlutDeInit, - OSDGlutReset, - OSDGlutDisplayMessage, - OSDGlutUseBuffer -}; - -int OSDGlutInit(void) -{ - int fake_argc = 1; - char * fake_argv[] = { "yabause" }; - static int glutinited = 0; - - if (!glutinited) - { - glutInit(&fake_argc, fake_argv); - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL); - glutinited = 1; - } - - return 0; -} - -void OSDGlutDeInit(void) -{ -} - -void OSDGlutReset(void) -{ -} - -void OSDGlutDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h) -{ - int LeftX=9; - int Width=500; - int TxtY=11; - int Height=13; - int i, msglength; - int vidwidth, vidheight; - - VIDCore->GetGlSize(&vidwidth, &vidheight); - Width = vidwidth - 2 * LeftX; - - switch(message->type) { - case OSDMSG_STATUS: - TxtY = vidheight - (Height + TxtY); - break; - } - - msglength = strlen(message->message); - - glBegin(GL_POLYGON); - glColor3f(0, 0, 0); - glVertex2i(LeftX, TxtY); - glVertex2i(LeftX + Width, TxtY); - glVertex2i(LeftX + Width, TxtY + Height); - glVertex2i(LeftX, TxtY + Height); - glEnd(); - - glColor3f(1.0f, 1.0f, 1.0f); - glRasterPos2i(10, TxtY + 11); - for (i = 0; i < msglength; i++) { - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, message->message[i]); - } - glColor3f(1, 1, 1); -} - -int OSDGlutUseBuffer(void) -{ - return 0; -} -#endif - -static int OSDSoftInit(void); -static void OSDSoftDeInit(void); -static void OSDSoftReset(void); -static void OSDSoftDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h); -static int OSDSoftUseBuffer(void); - -OSD_struct OSDSoft = { - OSDCORE_SOFT, - "Software OSD Interface", - OSDSoftInit, - OSDSoftDeInit, - OSDSoftReset, - OSDSoftDisplayMessage, - OSDSoftUseBuffer -}; - -int OSDSoftInit(void) -{ - return 0; -} - -void OSDSoftDeInit(void) -{ -} - -void OSDSoftReset(void) -{ -} - -void OSDSoftDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h) -{ - int i; - u32 * dot; - char * c; - int loffset = 0; - - if (buffer == NULL) return; - - switch (message->type) - { - case OSDMSG_STATUS: - loffset = h - 48; - break; - } - - c = message->message; - i = 0; - while(*c) - { - if (*c >= 47) - { - int first_line, l, p; - first_line = *c * 10; - for(l = 0;l < 10;l++) - { - for(p = 0;p < 9;p++) - { - if (font[first_line + l][p] == '.') - { - dot = buffer + 20 + ((loffset + l + 20) * w) + (i * 8) + p; - *dot = 0xFF000000; - } - else if (font[first_line + l][p] == '#') - { - dot = buffer + 20 + ((loffset + l + 20) * w) + (i * 8) + p; - *dot = 0xFFFFFFFF; - } - } - } - } - c++; - i++; - } -} - -int OSDSoftUseBuffer(void) -{ - return 1; -} diff --git a/yabause/src/osdcore.h b/yabause/src/osdcore.h deleted file mode 100644 index d13a633561..0000000000 --- a/yabause/src/osdcore.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef OSDCORE_H -#define OSDCORE_H - -#include "core.h" - -#define OSDCORE_DUMMY 0 -#define OSDCORE_GLUT 1 -#define OSDCORE_SOFT 2 - -#ifdef HAVE_LIBGLUT - #define OSDCORE_DEFAULT OSDCORE_GLUT -#else - #define OSDCORE_DEFAULT OSDCORE_SOFT -#endif - -#define OSDMSG_FPS 0 -#define OSDMSG_STATUS 1 -#define OSDMSG_DEBUG 2 -#define OSDMSG_COUNT 3 - -typedef struct { - int type; - char * message; - int timetolive; - int timeleft; - int hidden; -} OSDMessage_struct; - -typedef struct { - int id; - const char *Name; - - int (*Init)(void); - void (*DeInit)(void); - void (*Reset)(void); - - void (*DisplayMessage)(OSDMessage_struct * message, u32 * buffer, int w, int h); - int (*UseBuffer)(void); -} OSD_struct; - -int OSDInit(int coreid); -int OSDChangeCore(int coreid); - -void OSDPushMessage(int msgtype, int ttl, const char * message, ...); -int OSDDisplayMessages(u32 * buffer, int w, int h); -void OSDToggle(int what); -int OSDIsVisible(int what); -void OSDSetVisible(int what, int visible); -int OSDUseBuffer(void); - -extern OSD_struct OSDDummy; -#ifdef HAVE_LIBGLUT -extern OSD_struct OSDGlut; -#endif -extern OSD_struct OSDSoft; - -/* defined for backward compatibility (used to be in vdp2.h) */ -void ToggleFPS(void); -int GetOSDToggle(void); -void SetOSDToggle(int toggle); -void DisplayMessage(const char* str); - -#endif diff --git a/yabause/src/perdx.c b/yabause/src/perdx.c deleted file mode 100644 index b7baa67d7b..0000000000 --- a/yabause/src/perdx.c +++ /dev/null @@ -1,1301 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "debug.h" -#include "peripheral.h" -#include "perdx.h" -#include "vdp1.h" -#include "vdp2.h" -#include "yui.h" -#include "movie.h" - -#define IDD_BUTTONCONFIG 123 -#define IDC_WAITINPUT 1001 -#define IDC_DXDEVICECB 1010 -#define IDC_UPTEXT 1024 -#define IDC_RIGHTTEXT 1025 -#define IDC_DOWNTEXT 1026 -#define IDC_LEFTTEXT 1027 -#define IDC_RTEXT 1028 -#define IDC_LTEXT 1029 -#define IDC_STARTTEXT 1030 -#define IDC_ATEXT 1031 -#define IDC_BTEXT 1032 -#define IDC_CTEXT 1033 -#define IDC_XTEXT 1034 -#define IDC_YTEXT 1035 -#define IDC_ZTEXT 1036 -#define IDC_CUSTOMCANCEL 1037 - -enum { - EMUTYPE_NONE=0, - EMUTYPE_STANDARDPAD, - EMUTYPE_ANALOGPAD, - EMUTYPE_STUNNER, - EMUTYPE_MOUSE, - EMUTYPE_KEYBOARD -}; - -int PERDXInit(void); -void PERDXDeInit(void); -int PERDXHandleEvents(void); -int Check_Skip_Key(); - -PerInterface_struct PERDIRECTX = { -PERCORE_DIRECTX, -"DirectX Input Interface", -PERDXInit, -PERDXDeInit, -PERDXHandleEvents -}; - -LPDIRECTINPUT8 lpDI8 = NULL; -LPDIRECTINPUTDEVICE8 lpDIDevice[256]; // I hope that's enough -GUID GUIDDevice[256]; // I hope that's enough -u32 numguids=0; -u32 numdevices=0; - -u32 numpads=12; -PerPad_struct *pad[12]; -padconf_struct paddevice[12]; -int porttype[2]; - -const char *mouse_names[] = { -"A", -"B", -"C", -"Start", -NULL -}; - -#define TYPE_KEYBOARD 0 -#define TYPE_JOYSTICK 1 -#define TYPE_MOUSE 2 - -#define PAD_DIR_AXISLEFT 0 -#define PAD_DIR_AXISRIGHT 1 -#define PAD_DIR_AXISUP 2 -#define PAD_DIR_AXISDOWN 3 -#define PAD_DIR_POVUP 4 -#define PAD_DIR_POVRIGHT 5 -#define PAD_DIR_POVDOWN 6 -#define PAD_DIR_POVLEFT 7 - -HWND DXGetWindow (); - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD) - { - if (SUCCEEDED(IDirectInput8_CreateDevice(lpDI8, &lpddi->guidInstance, &lpDIDevice[numdevices], - NULL) )) - numdevices++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -void LoadDefaultPort1A(void) -{ - porttype[0] = 1; - porttype[1] = 0; - - pad[0] = PerPadAdd(&PORTDATA1); - - PerSetKey(DIK_UP, PERPAD_UP, pad[0]); - PerSetKey(DIK_DOWN, PERPAD_DOWN, pad[0]); - PerSetKey(DIK_LEFT, PERPAD_LEFT, pad[0]); - PerSetKey(DIK_RIGHT, PERPAD_RIGHT, pad[0]); - PerSetKey(DIK_K, PERPAD_A, pad[0]); - PerSetKey(DIK_L, PERPAD_B, pad[0]); - PerSetKey(DIK_M, PERPAD_C, pad[0]); - PerSetKey(DIK_U, PERPAD_X, pad[0]); - PerSetKey(DIK_I, PERPAD_Y, pad[0]); - PerSetKey(DIK_O, PERPAD_Z, pad[0]); - PerSetKey(DIK_X, PERPAD_LEFT_TRIGGER, pad[0]); - PerSetKey(DIK_Z, PERPAD_RIGHT_TRIGGER, pad[0]); - PerSetKey(DIK_J, PERPAD_START, pad[0]); -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDXInit(void) -{ - DIPROPDWORD dipdw; - char tempstr[512]; - HRESULT ret; - - memset(pad, 0, sizeof(pad)); - memset(paddevice, 0, sizeof(paddevice)); - - if (FAILED((ret = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8, NULL)) )) - { - sprintf(tempstr, "DirectInput8Create error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - IDirectInput8_EnumDevices(lpDI8, DI8DEVCLASS_ALL, EnumPeripheralsCallback, - NULL, DIEDFL_ATTACHEDONLY); - - if (FAILED((ret = IDirectInput8_CreateDevice(lpDI8, &GUID_SysKeyboard, &lpDIDevice[0], - NULL)) )) - { - sprintf(tempstr, "IDirectInput8_CreateDevice error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - if (FAILED((ret = IDirectInputDevice8_SetDataFormat(lpDIDevice[0], &c_dfDIKeyboard)) )) - { - sprintf(tempstr, "IDirectInputDevice8_SetDataFormat error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - if (FAILED((ret = IDirectInputDevice8_SetCooperativeLevel(lpDIDevice[0], DXGetWindow(), - DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY)) )) - { - sprintf(tempstr, "IDirectInputDevice8_SetCooperativeLevel error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 8; // should be enough - - // Setup Buffered input - if (FAILED((ret = IDirectInputDevice8_SetProperty(lpDIDevice[0], DIPROP_BUFFERSIZE, &dipdw.diph)) )) - { - sprintf(tempstr, "IDirectInputDevice8_SetProperty error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - // Make sure Keyboard is acquired already - IDirectInputDevice8_Acquire(lpDIDevice[0]); - - paddevice[0].lpDIDevice = lpDIDevice[0]; - paddevice[0].type = TYPE_KEYBOARD; - paddevice[0].emulatetype = 1; - - PerPortReset(); - LoadDefaultPort1A(); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void StringToGUID(const char *string, GUID *guid) -{ - int data4[8]; - int i; - - sscanf(string, "%08lX-%04hX-%04hX-%02X%02X%02X%02X%02X%02X%02X%02X", (int *)&guid->Data1, (int *)&guid->Data2, (int *)&guid->Data3, &data4[0], &data4[1], &data4[2], &data4[3], &data4[4], &data4[5], &data4[6], &data4[7]); - for (i = 0; i < 8; i++) - guid->Data4[i] = (BYTE)data4[i]; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDXLoadDevices(char *inifilename) -{ - char tempstr[MAX_PATH]; - char string1[20]; - char string2[20]; - GUID guid; - DIDEVCAPS didc; - u32 i; - int j, i2; - int buttonid; - DIPROPDWORD dipdw; - int id; - DWORD coopflags=DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; - BOOL loaddefault=TRUE; - int numpads; - HRESULT hr; - - if (!PERCore) - return; - PerPortReset(); - memset(pad, 0, sizeof(pad)); - - // Check Connection Type - if (GetPrivateProfileStringA("Input", "Port1Type", "", tempstr, MAX_PATH, inifilename) == 0) - { - // Check if it's using the old ini settings for peripherals - if (GetPrivateProfileStringA("Peripheral1", "GUID", "", tempstr, MAX_PATH, inifilename) != 0) - { - // Convert to the newer type of settings - for (i = 0; i < 2; i++) - { - sprintf(string1, "Port%dType", (int)i+1); - WritePrivateProfileStringA("Input", string1, "1", inifilename); - - sprintf(string1, "Peripheral%d", (int)i+1); - sprintf(string2, "Peripheral%dA", (int)i+1); - - if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename)) - WritePrivateProfileStringA(string2, "GUID", tempstr, inifilename); - - if (GetPrivateProfileStringA(string1, "EmulateType", "", tempstr, MAX_PATH, inifilename)) - WritePrivateProfileStringA(string2, "EmulateType", tempstr, inifilename); - - for (i2 = 0; i2 < 13; i2++) - { - if (GetPrivateProfileStringA(string1, PerPadNames[i2], "", tempstr, MAX_PATH, inifilename)) - WritePrivateProfileStringA(string2, PerPadNames[i2], tempstr, inifilename); - } - } - - // Remove old ini entries - for (i = 0; i < 12; i++) - { - sprintf(string1, "Peripheral%d", (int)i+1); - WritePrivateProfileStringA(string1, NULL, NULL, inifilename); - } - - loaddefault = FALSE; - } - } - else - loaddefault = FALSE; - - if (loaddefault) - { - LoadDefaultPort1A(); - return; - } - - // Load new type settings - for (i = 0; i < 2; i++) - { - sprintf(string1, "Port%dType", (int)i+1); - - if (GetPrivateProfileStringA("Input", string1, "", tempstr, MAX_PATH, inifilename) != 0) - { - porttype[i] = atoi(tempstr); - - switch(porttype[i]) - { - case 1: - numpads = 1; - break; - case 2: - numpads = 6; - break; - default: - numpads = 0; - break; - } - - // Load new type settings - for (j = 0; j < numpads; j++) - { - int padindex=(6*i)+j; - padconf_struct *curdevice=&paddevice[padindex]; - sprintf(string1, "Peripheral%d%C", (int)i+1, 'A' + j); - - // Let's first fetch the guid of the device - if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename) == 0) - continue; - - if (GetPrivateProfileStringA(string1, "EmulateType", "0", string2, MAX_PATH, inifilename)) - { - curdevice->emulatetype = atoi(string2); - if (curdevice->emulatetype == 0) - continue; - } - - if (curdevice->lpDIDevice) - { - // Free the default keyboard, etc. - IDirectInputDevice8_Unacquire(curdevice->lpDIDevice); - IDirectInputDevice8_Release(curdevice->lpDIDevice); - } - - StringToGUID(tempstr, &guid); - - // Ok, now that we've got the GUID of the device, let's set it up - if (FAILED(IDirectInput8_CreateDevice(lpDI8, &guid, &lpDIDevice[padindex], - NULL) )) - { - curdevice->lpDIDevice = NULL; - curdevice->emulatetype = 0; - continue; - } - - curdevice->lpDIDevice = lpDIDevice[padindex]; - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevice[padindex], &didc) )) - continue; - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIKeyboard) )) - continue; - curdevice->type = TYPE_KEYBOARD; - coopflags |= DISCL_NOWINKEY; - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIJoystick2) )) - continue; - curdevice->type = TYPE_JOYSTICK; - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIMouse2) )) - continue; - curdevice->type = TYPE_MOUSE; - coopflags = DISCL_FOREGROUND | DISCL_EXCLUSIVE; - } - - hr = IDirectInputDevice8_SetCooperativeLevel(lpDIDevice[i], DXGetWindow(), coopflags); - if (FAILED(hr)) - continue; - - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 8; // should be enough - - // Setup Buffered input - if (FAILED(IDirectInputDevice8_SetProperty(lpDIDevice[padindex], DIPROP_BUFFERSIZE, &dipdw.diph))) - continue; - - IDirectInputDevice8_Acquire(lpDIDevice[padindex]); - - switch(curdevice->emulatetype) - { - case 1: // Standard Pad - id = PERPAD; - break; - case 2: // Analog Pad - case 3: // Stunner - case 5: // Keyboard - id = 0; - break; - case 4: // Mouse - id = PERMOUSE; - break; - default: break; - } - - // Make sure we're added to the smpc list - if (i == 0) - pad[padindex] = PerAddPeripheral(&PORTDATA1, id); - else - pad[padindex] = PerAddPeripheral(&PORTDATA2, id); - - // Now that we're all setup, let's fetch the controls from the ini - if (curdevice->emulatetype != 3 && - curdevice->emulatetype != 4) - { - for (i2 = 0; i2 < 13; i2++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i2], 0, inifilename); - PerSetKey(buttonid, i2, pad[padindex]); - } - } - else if (curdevice->emulatetype == 4) - { - for (i2 = 0; i2 < 4; i2++) - { - buttonid = GetPrivateProfileIntA(string1, mouse_names[i2], 0, inifilename); - PerSetKey(buttonid, PERMOUSE_LEFT+i2, pad[padindex]); - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDXDeInit(void) -{ - u32 i; - - for (i = 0; i < numdevices; i++) - { - if (lpDIDevice[i]) - { - IDirectInputDevice8_Unacquire(lpDIDevice[i]); - IDirectInputDevice8_Release(lpDIDevice[i]); - lpDIDevice[i] = NULL; - } - } - - if (lpDI8) - { - IDirectInput8_Release(lpDI8); - lpDI8 = NULL; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PollKeys(void) -{ - u32 i; - DWORD i2; - DWORD size=8; - DIDEVICEOBJECTDATA didod[8]; - HRESULT hr; - - for (i = 0; i < numpads; i++) - { - if (paddevice[i].lpDIDevice == NULL) - continue; - - hr = IDirectInputDevice8_Poll(paddevice[i].lpDIDevice); - - if (FAILED(hr)) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} - continue; - } - } - - size = 8; - - // Poll events - if (FAILED(IDirectInputDevice8_GetDeviceData(paddevice[i].lpDIDevice, - sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} - continue; - } - } - - if (size == 0) - continue; - - switch (paddevice[i].type) - { - case TYPE_KEYBOARD: - // This probably could be optimized - for (i2 = 0; i2 < size; i2++) - { - if (didod[i2].dwData & 0x80) - PerKeyDown(didod[i2].dwOfs); - else - PerKeyUp(didod[i2].dwOfs); - } - break; - case TYPE_JOYSTICK: - { - // This probably could be optimized - for (i2 = 0; i2 < size; i2++) - { - // X Axis - if (didod[i2].dwOfs == DIJOFS_X) - { - if (didod[i2].dwData < 0x3FFF) - { - PerKeyDown(PAD_DIR_AXISLEFT); - PerKeyUp(PAD_DIR_AXISRIGHT); - } - else if (didod[i2].dwData > 0xBFFF) - { - PerKeyDown(PAD_DIR_AXISRIGHT); - PerKeyUp(PAD_DIR_AXISLEFT); - } - else - { - PerKeyUp(PAD_DIR_AXISLEFT); - PerKeyUp(PAD_DIR_AXISRIGHT); - } - } - // Y Axis - else if (didod[i2].dwOfs == DIJOFS_Y) - { - if (didod[i2].dwData < 0x3FFF) - { - PerKeyDown(PAD_DIR_AXISUP); - PerKeyUp(PAD_DIR_AXISDOWN); - } - else if (didod[i2].dwData > 0xBFFF) - { - PerKeyDown(PAD_DIR_AXISDOWN); - PerKeyUp(PAD_DIR_AXISUP); - } - else - { - PerKeyUp(PAD_DIR_AXISUP); - PerKeyUp(PAD_DIR_AXISDOWN); - } - } - else if (didod[i2].dwOfs == DIJOFS_POV(0)) - { - // POV Center - if (LOWORD(didod[i2].dwData) == 0xFFFF) - { - PerKeyUp(PAD_DIR_POVUP); - PerKeyUp(PAD_DIR_POVRIGHT); - PerKeyUp(PAD_DIR_POVDOWN); - PerKeyUp(PAD_DIR_POVLEFT); - } - // POV Up - else if (didod[i2].dwData < 4500) - { - PerKeyDown(PAD_DIR_POVUP); - PerKeyUp(PAD_DIR_POVRIGHT); - PerKeyUp(PAD_DIR_POVLEFT); - } - // POV Up-right - else if (didod[i2].dwData < 9000) - { - PerKeyDown(PAD_DIR_POVUP); - PerKeyDown(PAD_DIR_POVRIGHT); - } - // POV Right - else if (didod[i2].dwData < 13500) - { - PerKeyDown(PAD_DIR_POVRIGHT); - PerKeyUp(PAD_DIR_POVDOWN); - PerKeyUp(PAD_DIR_POVUP); - } - // POV Right-down - else if (didod[i2].dwData < 18000) - { - PerKeyDown(PAD_DIR_POVRIGHT); - PerKeyDown(PAD_DIR_POVDOWN); - } - // POV Down - else if (didod[i2].dwData < 22500) - { - PerKeyDown(PAD_DIR_POVDOWN); - PerKeyUp(PAD_DIR_POVLEFT); - PerKeyUp(PAD_DIR_POVRIGHT); - } - // POV Down-left - else if (didod[i2].dwData < 27000) - { - PerKeyDown(PAD_DIR_POVDOWN); - PerKeyDown(PAD_DIR_POVLEFT); - } - // POV Left - else if (didod[i2].dwData < 31500) - { - PerKeyDown(PAD_DIR_POVLEFT); - PerKeyUp(PAD_DIR_POVUP); - PerKeyUp(PAD_DIR_POVDOWN); - } - // POV Left-up - else if (didod[i2].dwData < 36000) - { - PerKeyDown(PAD_DIR_POVLEFT); - PerKeyDown(PAD_DIR_POVUP); - } - } - else if (didod[i2].dwOfs >= DIJOFS_BUTTON(0) && didod[i2].dwOfs <= DIJOFS_BUTTON(127)) - { - if (didod[i2].dwData & 0x80) - PerKeyDown(didod[i2].dwOfs); - else - PerKeyUp(didod[i2].dwOfs); - } - } - break; - } - case TYPE_MOUSE: - for (i2 = 0; i2 < size; i2++) - { - if (didod[i2].dwOfs == DIMOFS_X) - // X Axis - PerMouseMove((PerMouse_struct *)pad[i], (s32)didod[i2].dwData, 0); - else if (didod[i2].dwOfs == DIMOFS_Y) - // Y Axis - PerMouseMove((PerMouse_struct *)pad[i], 0, 0-(s32)didod[i2].dwData); - else if (didod[i2].dwOfs >= DIMOFS_BUTTON0 && didod[i2].dwOfs <= DIMOFS_BUTTON7) - { - // Mouse Buttons - if (didod[i2].dwData & 0x80) - PerKeyDown(didod[i2].dwOfs-DIMOFS_BUTTON0); - else - PerKeyUp(didod[i2].dwOfs-DIMOFS_BUTTON0); - } - } - break; - default: break; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDXHandleEvents(void) -{ - PollKeys(); - - if (YabauseExec() != 0) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallbackGamepad (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD) - { - SendMessage((HWND)pvRef, CB_ADDSTRING, 0, (LPARAM)lpddi->tszInstanceName); - memcpy(&GUIDDevice[numguids], &lpddi->guidInstance, sizeof(GUID)); - numguids++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallbackKeyboard (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD) - { - SendMessage((HWND)pvRef, CB_ADDSTRING, 0, (LPARAM)lpddi->tszInstanceName); - memcpy(&GUIDDevice[numguids], &lpddi->guidInstance, sizeof(GUID)); - numguids++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallbackMouse (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_MOUSE) - { - SendMessage((HWND)pvRef, CB_ADDSTRING, 0, (LPARAM)lpddi->tszInstanceName); - memcpy(&GUIDDevice[numguids], &lpddi->guidInstance, sizeof(GUID)); - numguids++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDXListDevices(HWND control, int emulatetype) -{ - LPDIRECTINPUT8 lpDI8temp = NULL; - - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) - return; - - numguids = 0; - - SendMessage(control, CB_RESETCONTENT, 0, 0); - SendMessage(control, CB_ADDSTRING, 0, (LPARAM)_16("None")); - - switch(emulatetype) - { - case EMUTYPE_STANDARDPAD: - case EMUTYPE_ANALOGPAD: - IDirectInput8_EnumDevices(lpDI8temp, DI8DEVCLASS_ALL, EnumPeripheralsCallbackGamepad, - (LPVOID)control, DIEDFL_ATTACHEDONLY); - break; - case EMUTYPE_STUNNER: - case EMUTYPE_MOUSE: - IDirectInput8_EnumDevices(lpDI8temp, DI8DEVCLASS_ALL, EnumPeripheralsCallbackMouse, - (LPVOID)control, DIEDFL_ATTACHEDONLY); - break; - case EMUTYPE_KEYBOARD: - IDirectInput8_EnumDevices(lpDI8temp, DI8DEVCLASS_ALL, EnumPeripheralsCallbackKeyboard, - (LPVOID)control, DIEDFL_ATTACHEDONLY); - break; - default: break; - } - - IDirectInput8_Release(lpDI8temp); -} - -////////////////////////////////////////////////////////////////////////////// - -void ConvertKBIDToName(int buttonid, char *string) -{ - memset(string, 0, MAX_PATH); - - // This fixes some strange inconsistencies - if (buttonid == DIK_PAUSE) - buttonid = DIK_NUMLOCK; - else if (buttonid == DIK_NUMLOCK) - buttonid = DIK_PAUSE; - if (buttonid & 0x80) - buttonid += 0x80; - - GetKeyNameTextA(buttonid << 16, string, MAX_PATH); -} - -////////////////////////////////////////////////////////////////////////////// - -void ConvertJoyIDToName(int buttonid, char *string) -{ - switch (buttonid) - { - case 0x00: - sprintf(string, "Axis Left"); - break; - case 0x01: - sprintf(string, "Axis Right"); - break; - case 0x02: - sprintf(string, "Axis Up"); - break; - case 0x03: - sprintf(string, "Axis Down"); - break; - case 0x04: - sprintf(string, "POV Up"); - break; - case 0x05: - sprintf(string, "POV Right"); - break; - case 0x06: - sprintf(string, "POV Down"); - break; - case 0x07: - sprintf(string, "POV Left"); - break; - default: - if (buttonid >= 0x30) - sprintf(string, "Button %d", buttonid - 0x2F); - break; - } - -} - -////////////////////////////////////////////////////////////////////////////// - -void ConvertMouseIDToName(int buttonid, char *string) -{ - sprintf(string, "Button %d", buttonid+1); -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDXInitControlConfig(HWND hWnd, u8 padnum, int *controlmap, const char *inifilename) -{ - char tempstr[MAX_PATH]; - char string1[20]; - GUID guid; - u32 i; - int idlist[] = { IDC_UPTEXT, IDC_RIGHTTEXT, IDC_DOWNTEXT, IDC_LEFTTEXT, - IDC_RTEXT, IDC_LTEXT, IDC_STARTTEXT, - IDC_ATEXT, IDC_BTEXT, IDC_CTEXT, - IDC_XTEXT, IDC_YTEXT, IDC_ZTEXT - }; - - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - - // Let's first fetch the guid of the device and see if we can get a match - if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename) == 0) - { - if (padnum == 0) - { - // Let's use default values - SendDlgItemMessage(hWnd, IDC_DXDEVICECB, CB_SETCURSEL, 1, 0); - - controlmap[0] = DIK_UP; - controlmap[1] = DIK_RIGHT; - controlmap[2] = DIK_DOWN; - controlmap[3] = DIK_LEFT; - controlmap[4] = DIK_Z; - controlmap[5] = DIK_X; - controlmap[6] = DIK_J; - controlmap[7] = DIK_K; - controlmap[8] = DIK_L; - controlmap[9] = DIK_M; - controlmap[10] = DIK_U; - controlmap[11] = DIK_I; - controlmap[12] = DIK_O; - for (i = 0; i < 13; i++) - { - ConvertKBIDToName(controlmap[i], tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - else - { - SendDlgItemMessage(hWnd, IDC_DXDEVICECB, CB_SETCURSEL, 0, 0); - return -1; - } - } - else - { - LPDIRECTINPUT8 lpDI8temp = NULL; - LPDIRECTINPUTDEVICE8 lpDIDevicetemp; - DIDEVCAPS didc; - int buttonid; - - StringToGUID(tempstr, &guid); - - // Let's find a match - for (i = 0; i < numguids; i++) - { - if (memcmp(&guid, &GUIDDevice[i], sizeof(GUID)) == 0) - { - SendDlgItemMessage(hWnd, IDC_DXDEVICECB, CB_SETCURSEL, i+1, 0); - break; - } - } - - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) - return -1; - - if (FAILED(IDirectInput8_CreateDevice(lpDI8temp, &GUIDDevice[i], &lpDIDevicetemp, - NULL))) - { - IDirectInput8_Release(lpDI8temp); - return -1; - } - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - - for (i = 0; i < 13; i++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i], 0, inifilename); - printf("%2d: %d\n", i, buttonid); - controlmap[i] = buttonid; - ConvertKBIDToName(buttonid, tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - - for (i = 0; i < 13; i++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i], 0, inifilename); - controlmap[i] = buttonid; - ConvertJoyIDToName(buttonid, tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - for (i = 0; i < 13; i++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i], 0, inifilename); - controlmap[i] = buttonid; - ConvertMouseIDToName(buttonid, tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -DIDEVICEOBJECTDATA nextpress; - -int PERDXFetchNextPress(HWND hWnd, u32 guidnum, char *buttonname) -{ - LPDIRECTINPUT8 lpDI8temp = NULL; - LPDIRECTINPUTDEVICE8 lpDIDevicetemp; - DIDEVCAPS didc; - int buttonid=-1; - - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) - return -1; - - if (FAILED(IDirectInput8_CreateDevice(lpDI8temp, &GUIDDevice[guidnum], &lpDIDevicetemp, - NULL))) - { - IDirectInput8_Release(lpDI8temp); - return -1; - } - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIKeyboard))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIJoystick))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIMouse2))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - } - - if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_BUTTONCONFIG), hWnd, (DLGPROC)ButtonConfigDlgProc, (LPARAM)lpDIDevicetemp) == TRUE) - { - // Figure out what kind of code to generate - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - memset(buttonname, 0, MAX_PATH); - buttonid = nextpress.dwOfs; - // This fixes some strange inconsistencies - if (buttonid == DIK_PAUSE) - buttonid = DIK_NUMLOCK; - else if (buttonid == DIK_NUMLOCK) - buttonid = DIK_PAUSE; - if (buttonid & 0x80) - buttonid += 0x80; - - GetKeyNameTextA(buttonid << 16, buttonname, MAX_PATH); - buttonid = nextpress.dwOfs; - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - if (nextpress.dwOfs == DIJOFS_X) - { - if (nextpress.dwData <= 0x8000) - { - sprintf(buttonname, "Axis Left"); - buttonid = 0x00; - } - else - { - sprintf(buttonname, "Axis Right"); - buttonid = 0x01; - } - } - else if (nextpress.dwOfs == DIJOFS_Y) - { - if (nextpress.dwData <= 0x8000) - { - sprintf(buttonname, "Axis Up"); - buttonid = 0x02; - } - else - { - sprintf(buttonname, "Axis Down"); - buttonid = 0x03; - } - } - else if (nextpress.dwOfs == DIJOFS_POV(0)) - { - if (nextpress.dwData < 9000) - { - sprintf(buttonname, "POV Up"); - buttonid = 0x04; - } - else if (nextpress.dwData < 18000) - { - sprintf(buttonname, "POV Right"); - buttonid = 0x05; - } - else if (nextpress.dwData < 27000) - { - sprintf(buttonname, "POV Down"); - buttonid = 0x06; - } - else - { - sprintf(buttonname, "POV Left"); - buttonid = 0x07; - } - } - else if (nextpress.dwOfs >= DIJOFS_BUTTON(0) && nextpress.dwOfs <= DIJOFS_BUTTON(127)) - { - sprintf(buttonname, "Button %d", (int)(nextpress.dwOfs - 0x2F)); - buttonid = nextpress.dwOfs; - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - buttonid = nextpress.dwOfs-DIMOFS_BUTTON0; - sprintf(buttonname, "Button %d", buttonid+1); - } - } - - IDirectInputDevice8_Unacquire(lpDIDevicetemp); - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - - return buttonid; -} - -////////////////////////////////////////////////////////////////////////////// - -HHOOK hook; - -LRESULT CALLBACK KeyboardHook(int code, WPARAM wParam, LPARAM lParam) -{ - if (code >= HC_ACTION) - return TRUE; - - return CallNextHookEx(hook, code, wParam, lParam); -} - -////////////////////////////////////////////////////////////////////////////// - -LRESULT CALLBACK ButtonConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) -{ - static LPDIRECTINPUTDEVICE8 lpDIDevicetemp; - DIPROPDWORD dipdw; - HRESULT hr; - DWORD size; - DIDEVICEOBJECTDATA didod[8]; - DWORD i; - DIDEVCAPS didc; - - switch (uMsg) - { - case WM_INITDIALOG: - { - lpDIDevicetemp = (LPDIRECTINPUTDEVICE8)lParam; - - if (FAILED(IDirectInputDevice8_SetCooperativeLevel(lpDIDevicetemp, hDlg, - DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY))) - return FALSE; - - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 8; // should be enough - - // Setup Buffered input - if (FAILED((hr = IDirectInputDevice8_SetProperty(lpDIDevicetemp, DIPROP_BUFFERSIZE, &dipdw.diph)))) - return FALSE; - - if (!SetTimer(hDlg, 1, 100, NULL)) - return FALSE; - - PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDC_WAITINPUT), TRUE); - hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook, GetModuleHandle(NULL), GetCurrentThreadId()); - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_CUSTOMCANCEL: - { - EndDialog(hDlg, FALSE); - return TRUE; - } - default: break; - } - - break; - } - case WM_TIMER: - { - size = 8; - - if (wParam == 1) - { - memset(&didod, 0, sizeof(DIDEVICEOBJECTDATA) * 8); - - // Let's see if there's any data waiting - hr = IDirectInputDevice8_Poll(lpDIDevicetemp); - - if (FAILED(hr)) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(lpDIDevicetemp) == DIERR_INPUTLOST) {} - return TRUE; - } - } - - // Poll events - if (FAILED(IDirectInputDevice8_GetDeviceData(lpDIDevicetemp, - sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(lpDIDevicetemp) == DIERR_INPUTLOST) {} - return TRUE; - } - } - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) - return TRUE; - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - for (i = 0; i < size; i++) - { - if (didod[i].dwData & 0x80) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - for (i = 0; i < size; i++) - { - if (didod[i].dwOfs == 0 || - didod[i].dwOfs == 4) - { - if (didod[i].dwData <= 0x1000 || - didod[i].dwData >= 0xF000) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - else if (didod[i].dwOfs == 0x20) - { - if (((int)didod[i].dwData) >= 0) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - } - } - else if (didod[i].dwOfs >= 0x30) - { - if (didod[i].dwData & 0x80) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - for (i = 0; i < size; i++) - { - // Make sure it's a button press - if (didod[i].dwOfs >= DIMOFS_BUTTON0 && didod[i].dwOfs <= DIMOFS_BUTTON7) - { - if (didod[i].dwData & 0x80) - { - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - } - } - - return TRUE; - } - - return FALSE; - } - case WM_DESTROY: - { - KillTimer(hDlg, 1); - UnhookWindowsHookEx(hook); - break; - } - } - - return FALSE; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL PERDXWriteGUID(u32 guidnum, u8 padnum, LPCSTR inifilename) -{ - char string1[20]; - char string2[40]; - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - sprintf(string2, "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X", (int)GUIDDevice[guidnum].Data1, (int)GUIDDevice[guidnum].Data2, (int)GUIDDevice[guidnum].Data3, (int)GUIDDevice[guidnum].Data4[0], (int)GUIDDevice[guidnum].Data4[1], (int)GUIDDevice[guidnum].Data4[2], (int)GUIDDevice[guidnum].Data4[3], (int)GUIDDevice[guidnum].Data4[4], (int)GUIDDevice[guidnum].Data4[5], (int)GUIDDevice[guidnum].Data4[6], (int)GUIDDevice[guidnum].Data4[7]); - return WritePrivateProfileStringA(string1, "GUID", string2, inifilename); -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/perdx.h b/yabause/src/perdx.h deleted file mode 100644 index 245ad7d360..0000000000 --- a/yabause/src/perdx.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERDX_H -#define PERDX_H - -#define DIRECTINPUT_VERSION 0x0800 -#include -#include "dx.h" -#include "peripheral.h" - -#define PERCORE_DIRECTX 2 - -extern PerInterface_struct PERDIRECTX; - -extern GUID GUIDDevice[256]; -extern u32 numguids; -extern const char * pad_names[]; -extern PerPad_struct *pad[12]; -extern u32 numpads; -extern int porttype[2]; - -typedef struct -{ - LPDIRECTINPUTDEVICE8 lpDIDevice; - int type; - int emulatetype; -} padconf_struct; - -extern padconf_struct paddevice[12]; - -LRESULT CALLBACK ButtonConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam); - -void KeyStub(PerPad_struct *pad); -void SetupControlUpDown(u8 padnum, u8 controlcode, void (*downfunc)(PerPad_struct *), void (*upfunc)(PerPad_struct *)); - -void PERDXLoadDevices(char *inifilename); -void PERDXListDevices(HWND control, int emulatetype); -int PERDXInitControlConfig(HWND hWnd, u8 padnum, int *controlmap, const char *inifilename); -int PERDXFetchNextPress(HWND hWnd, u32 guidnum, char *buttonname); -BOOL PERDXWriteGUID(u32 guidnum, u8 padnum, LPCSTR inifilename); -#endif diff --git a/yabause/src/peripheral.c b/yabause/src/peripheral.c deleted file mode 100644 index e10d1fbbed..0000000000 --- a/yabause/src/peripheral.c +++ /dev/null @@ -1,724 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "debug.h" -#include "peripheral.h" - -const char * PerPadNames[] = -{ -"Up", -"Right", -"Down", -"Left", -"R", -"L", -"Start", -"A", -"B", -"C", -"X", -"Y", -"Z", -NULL -}; - -const char * PerMouseNames[] = -{ -"A", -"B", -"C", -"Start", -NULL -}; - -PortData_struct PORTDATA1; -PortData_struct PORTDATA2; - -PerInterface_struct * PERCore = NULL; -extern PerInterface_struct * PERCoreList[]; - -typedef struct { - u8 name; - void (*Press)(void *); - void (*Release)(void *); -} PerBaseConfig_struct; - -typedef struct { - u32 key; - PerBaseConfig_struct * base; - void * controller; -} PerConfig_struct; - -#define PERCALLBACK(func) ((void (*) (void *)) func) - -PerBaseConfig_struct perkeybaseconfig[] = { - { PERPAD_UP, PERCALLBACK(PerPadUpPressed), PERCALLBACK(PerPadUpReleased) }, - { PERPAD_RIGHT, PERCALLBACK(PerPadRightPressed), PERCALLBACK(PerPadRightReleased) }, - { PERPAD_DOWN, PERCALLBACK(PerPadDownPressed), PERCALLBACK(PerPadDownReleased) }, - { PERPAD_LEFT, PERCALLBACK(PerPadLeftPressed), PERCALLBACK(PerPadLeftReleased) }, - { PERPAD_RIGHT_TRIGGER, PERCALLBACK(PerPadRTriggerPressed), PERCALLBACK(PerPadRTriggerReleased) }, - { PERPAD_LEFT_TRIGGER, PERCALLBACK(PerPadLTriggerPressed), PERCALLBACK(PerPadLTriggerReleased) }, - { PERPAD_START, PERCALLBACK(PerPadStartPressed), PERCALLBACK(PerPadStartReleased) }, - { PERPAD_A, PERCALLBACK(PerPadAPressed), PERCALLBACK(PerPadAReleased) }, - { PERPAD_B, PERCALLBACK(PerPadBPressed), PERCALLBACK(PerPadBReleased) }, - { PERPAD_C, PERCALLBACK(PerPadCPressed), PERCALLBACK(PerPadCReleased) }, - { PERPAD_X, PERCALLBACK(PerPadXPressed), PERCALLBACK(PerPadXReleased) }, - { PERPAD_Y, PERCALLBACK(PerPadYPressed), PERCALLBACK(PerPadYReleased) }, - { PERPAD_Z, PERCALLBACK(PerPadZPressed), PERCALLBACK(PerPadZReleased) }, -}; - -PerBaseConfig_struct permousebaseconfig[] = { - { PERMOUSE_LEFT, PERCALLBACK(PerMouseLeftPressed), PERCALLBACK(PerMouseLeftReleased) }, - { PERMOUSE_MIDDLE, PERCALLBACK(PerMouseMiddlePressed), PERCALLBACK(PerMouseMiddleReleased) }, - { PERMOUSE_RIGHT, PERCALLBACK(PerMouseRightPressed), PERCALLBACK(PerMouseRightReleased) }, - { PERMOUSE_START, PERCALLBACK(PerMouseStartPressed), PERCALLBACK(PerMouseStartReleased) }, -}; - -static u32 perkeyconfigsize = 0; -static PerConfig_struct * perkeyconfig = NULL; - -static void PerUpdateConfig(PerBaseConfig_struct * baseconfig, int nelems, void * controller); - -////////////////////////////////////////////////////////////////////////////// - -int PerInit(int coreid) { - int i; - - // So which core do we want? - if (coreid == PERCORE_DEFAULT) - coreid = 0; // Assume we want the first one - - // Go through core list and find the id - for (i = 0; PERCoreList[i] != NULL; i++) - { - if (PERCoreList[i]->id == coreid) - { - // Set to current core - PERCore = PERCoreList[i]; - break; - } - } - - if (PERCore == NULL) - return -1; - - if (PERCore->Init() != 0) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerDeInit(void) { - if (PERCore) - PERCore->DeInit(); - PERCore = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadUpPressed(PerPad_struct * pad) { - *pad->padbits &= 0xEF; - SMPCLOG("Up\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadUpReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xEF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadDownPressed(PerPad_struct * pad) { - *pad->padbits &= 0xDF; - SMPCLOG("Down\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadDownReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xDF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRightPressed(PerPad_struct * pad) { - *pad->padbits &= 0x7F; - SMPCLOG("Right\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRightReleased(PerPad_struct * pad) { - *pad->padbits |= ~0x7F; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLeftPressed(PerPad_struct * pad) { - *pad->padbits &= 0xBF; - SMPCLOG("Left\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLeftReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xBF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadStartPressed(PerPad_struct * pad) { - *pad->padbits &= 0xF7; - SMPCLOG("Start\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadStartReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xF7; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadAPressed(PerPad_struct * pad) { - *pad->padbits &= 0xFB; - SMPCLOG("A\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadAReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xFB; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadBPressed(PerPad_struct * pad) { - *pad->padbits &= 0xFE; - SMPCLOG("B\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadBReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xFE; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadCPressed(PerPad_struct * pad) { - *pad->padbits &= 0xFD; - SMPCLOG("C\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadCReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xFD; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadXPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xBF; - SMPCLOG("X\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadXReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xBF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadYPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xDF; - SMPCLOG("Y\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadYReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xDF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadZPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xEF; - SMPCLOG("Z\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadZReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xEF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRTriggerPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0x7F; - SMPCLOG("Right Trigger\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRTriggerReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0x7F; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLTriggerPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xF7; - SMPCLOG("Left Trigger\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLTriggerReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xF7; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseLeftPressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseLeftReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFFE; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseMiddlePressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 4; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseMiddleReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFFB; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseRightPressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 2; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseRightReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFFD; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseStartPressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 8; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseStartReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFF7; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseMove(PerMouse_struct * mouse, s32 dispx, s32 dispy) -{ - int negx, negy, overflowx, overflowy; - u8 diffx, diffy; - - negx = ((mouse->mousebits[0] >> 4) & 1); - negy = ((mouse->mousebits[0] >> 5) & 1); - overflowx = ((mouse->mousebits[0] >> 6) & 1); - overflowy = ((mouse->mousebits[0] >> 7) & 1); - - if (negx) diffx = ~(mouse->mousebits[1]) & 0xFF; - else diffx = mouse->mousebits[1]; - if (negy) diffy = ~(mouse->mousebits[2]) & 0xFF; - else diffy = mouse->mousebits[2]; - - if (dispx > 0) - { - if (negx) - { - if (dispx - diffx > 0) - { - diffx = dispx - diffx; - negx = 0; - } - else diffx -= -dispx; - } - else diffx += dispx; - } - else - { - if (negx) diffx += -dispx; - else - { - if (diffx + dispx > 0) diffx += dispx; - else - { - diffx = -dispx - diffx; - negx = 1; - } - } - } - - if (dispy > 0) - { - if (negy) - { - if (dispy - diffy > 0) - { - diffy = dispy - diffy; - negy = 0; - } - else diffy -= -dispy; - } - else diffy += dispy; - } - else - { - if (negy) diffy += -dispy; - else - { - if (diffy + dispy > 0) diffy += dispy; - else - { - diffy = -dispy - diffy; - negy = 1; - } - } - } - - mouse->mousebits[0] = (overflowy << 7) | (overflowx << 6) | (negy << 5) | (negx << 4) | (mouse->mousebits[0] & 0x0F); - if (negx) mouse->mousebits[1] = ~(diffx); - else mouse->mousebits[1] = diffx; - if (negy) mouse->mousebits[2] = ~(diffy); - else mouse->mousebits[2] = diffy; -} - -////////////////////////////////////////////////////////////////////////////// - -void * PerAddPeripheral(PortData_struct *port, int perid) -{ - int pernum = port->data[0] & 0xF; - int i; - int peroffset=1; - u8 size; - int current = 1; - void * controller; - - if (pernum == 0xF) - return NULL; - - // if only one peripheral is connected use 0xF0, otherwise use 0x00 or 0x10 - if (pernum == 0) - { - pernum = 1; - port->data[0] = 0xF1; - } - else - { - if (pernum == 1) - { - u8 tmp = peroffset; - tmp += (port->data[peroffset] & 0xF) + 1; - - for(i = 0;i < 5;i++) - port->data[tmp + i] = 0xFF; - } - pernum = 6; - port->data[0] = 0x16; - - // figure out where we're at, then add peripheral id + 1 - current = 0; - size = port->data[peroffset] & 0xF; - while ((current < pernum) && (size != 0xF)) - { - peroffset += size + 1; - current++; - size = port->data[peroffset] & 0xF; - } - - if (current == pernum) - { - return NULL; - } - current++; - } - - port->data[peroffset] = perid; - peroffset++; - - // set peripheral data for peripheral to default values and adjust size - // of port data - switch (perid) - { - case PERPAD: - port->data[peroffset] = 0xFF; - port->data[peroffset+1] = 0xFF; - port->size = peroffset+2; - break; - case PERMOUSE: - port->data[peroffset] = 0; - port->data[peroffset + 1] = 0; - port->data[peroffset + 2] = 0; - port->size = peroffset + 3; - break; - default: break; - } - - { - u8 tmp = peroffset; - tmp += (perid & 0xF); - for(i = 0;i < (pernum - current);i++) - { - port->data[tmp + i] = 0xFF; - port->size++; - } - } - - controller = (port->data + (peroffset - 1)); - switch (perid) - { - case PERPAD: - PerUpdateConfig(perkeybaseconfig, 13, controller); - break; - case PERMOUSE: - PerUpdateConfig(permousebaseconfig, 4, controller); - break; - } - return controller; -} - -////////////////////////////////////////////////////////////////////////////// - -int PerGetId(void * peripheral) -{ - u8 * id = peripheral; - return *id; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerRemovePeripheral(UNUSED PortData_struct *port, UNUSED int removeoffset) -{ - // stub -} - -////////////////////////////////////////////////////////////////////////////// - -void PerFlush(PortData_struct * port) -{ - /* FIXME this function only flush data if there's a mouse connected as - * first peripheral */ - u8 perid = port->data[1]; - if (perid == 0xE3) - { - PerMouse_struct * mouse = (PerMouse_struct *) (port->data + 1); - - mouse->mousebits[0] &= 0x0F; - mouse->mousebits[1] = 0; - mouse->mousebits[2] = 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerKeyDown(u32 key) -{ - unsigned int i = 0; - - while(i < perkeyconfigsize) - { - if (key == perkeyconfig[i].key) - { - perkeyconfig[i].base->Press(perkeyconfig[i].controller); - } - i++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerKeyUp(u32 key) -{ - unsigned int i = 0; - - while(i < perkeyconfigsize) - { - if (key == perkeyconfig[i].key) - { - perkeyconfig[i].base->Release(perkeyconfig[i].controller); - } - i++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerSetKey(u32 key, u8 name, void * controller) -{ - unsigned int i = 0; - - while(i < perkeyconfigsize) - { - if ((name == perkeyconfig[i].base->name) && (controller == perkeyconfig[i].controller)) - { - perkeyconfig[i].key = key; - } - i++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPortReset(void) -{ - PORTDATA1.data[0] = 0xF0; - PORTDATA1.size = 1; - PORTDATA2.data[0] = 0xF0; - PORTDATA2.size = 1; - - perkeyconfigsize = 0; - if (perkeyconfig) - free(perkeyconfig); - perkeyconfig = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerUpdateConfig(PerBaseConfig_struct * baseconfig, int nelems, void * controller) -{ - u32 oldsize = perkeyconfigsize; - u32 i, j; - - perkeyconfigsize += nelems; - perkeyconfig = realloc(perkeyconfig, perkeyconfigsize * sizeof(PerConfig_struct)); - j = 0; - for(i = oldsize;i < perkeyconfigsize;i++) - { - perkeyconfig[i].base = baseconfig + j; - perkeyconfig[i].controller = controller; - j++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -PerPad_struct * PerPadAdd(PortData_struct * port) -{ - return PerAddPeripheral(port, PERPAD); -} - -////////////////////////////////////////////////////////////////////////////// - -PerMouse_struct * PerMouseAdd(PortData_struct * port) -{ - return PerAddPeripheral(port, PERMOUSE); -} - -////////////////////////////////////////////////////////////////////////////// -// Dummy Interface -////////////////////////////////////////////////////////////////////////////// - -int PERDummyInit(void); -void PERDummyDeInit(void); -int PERDummyHandleEvents(void); -void PERDummyNothing(void); - -//static PortData_struct port1; -//static PortData_struct port2; - -u32 PERDummyScan(void); -void PERDummyFlush(void); -void PERDummyKeyName(u32 key, char * name, int size); - -PerInterface_struct PERDummy = { -PERCORE_DUMMY, -"Dummy Input Interface", -PERDummyInit, -PERDummyDeInit, -PERDummyHandleEvents, -PERDummyNothing, -PERDummyScan, -0, -PERDummyFlush -#ifdef PERKEYNAME -,PERDummyKeyName -#endif -}; - -////////////////////////////////////////////////////////////////////////////// - -int PERDummyInit(void) { - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyDeInit(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyNothing(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDummyHandleEvents(void) { - if (YabauseExec() != 0) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERDummyScan(void) { - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyFlush(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyKeyName(UNUSED u32 key, char * name, UNUSED int size) { - *name = 0; -} diff --git a/yabause/src/peripheral.h b/yabause/src/peripheral.h deleted file mode 100644 index e5737c87fd..0000000000 --- a/yabause/src/peripheral.h +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERIPHERAL_H -#define PERIPHERAL_H - -#include "core.h" -#include "smpc.h" -#include "yabause.h" - -/** @defgroup peripheral Peripheral - * - * @brief This module provides two kind of functions - * - peripheral core management functions - * - controller ports management functions - * - * @{ - */ - -#define PERPAD 0x02 -#define PERMOUSE 0xE3 - -#define PERCORE_DEFAULT -1 -#define PERCORE_DUMMY 0 - -extern PortData_struct PORTDATA1; -extern PortData_struct PORTDATA2; - -typedef struct -{ - int id; - const char * Name; - int (*Init)(void); - void (*DeInit)(void); - int (*HandleEvents)(void); - void (*PerSetButtonMapping)(void); - u32 (*Scan)(void); - int canScan; - void (*Flush)(void); -#ifdef PERKEYNAME - void (*KeyName)(u32 key, char * name, int size); -#endif -} PerInterface_struct; - -/** @brief Pointer to the current peripheral core. - * - * You should not set this manually but use - * PerInit() and PerDeInit() instead. */ -extern PerInterface_struct * PERCore; - -extern PerInterface_struct PERDummy; - -/** - * @brief Init a peripheral core - * - * Searches through the PERCoreList array for the given coreid. - * If found, PERCore is set to the address of that core and - * the core's Init function is called. - * - * @param coreid the peripheral core to be used - * @return 0 if core has been inited, -1 otherwise - */ -int PerInit(int coreid); -/** - * @brief De-init a peripheral core - * - * Calls the core's DeInit callback and set PERCore to NULL. - */ -void PerDeInit(void); - -/** @brief Adds a peripheral - * - * You shouldn't directly use this function but - * PerPadAdd() or PerMouseAdd() instead. - */ -void * PerAddPeripheral(PortData_struct *port, int perid); -int PerGetId(void * peripheral); -void PerRemovePeripheral(PortData_struct *port, int removeoffset); -void PerPortReset(void); -/** - * Iterate the list of peripherals connected to a port - * and flush them if necesseray. This is needed for mouses. - */ -void PerFlush(PortData_struct * port); - -void PerKeyDown(u32 key); -void PerKeyUp(u32 key); -void PerSetKey(u32 key, u8 name, void * controller); - -/** @defgroup pad Pad - * - * @{ - */ -#define PERPAD_UP 0 -#define PERPAD_RIGHT 1 -#define PERPAD_DOWN 2 -#define PERPAD_LEFT 3 -#define PERPAD_RIGHT_TRIGGER 4 -#define PERPAD_LEFT_TRIGGER 5 -#define PERPAD_START 6 -#define PERPAD_A 7 -#define PERPAD_B 8 -#define PERPAD_C 9 -#define PERPAD_X 10 -#define PERPAD_Y 11 -#define PERPAD_Z 12 - -extern const char * PerPadNames[14]; - -typedef struct -{ - u8 perid; - u8 padbits[2]; -} PerPad_struct; - -/** @brief Adds a pad to one of the controller ports. - * - * @param port can be either &PORTDATA1 or &PORTDATA2 - * @return pointer to a PerPad_struct or NULL if it fails - * */ -PerPad_struct * PerPadAdd(PortData_struct * port); - -void PerPadUpPressed(PerPad_struct * pad); -void PerPadUpReleased(PerPad_struct * pad); - -void PerPadDownPressed(PerPad_struct * pad); -void PerPadDownReleased(PerPad_struct * pad); - -void PerPadRightPressed(PerPad_struct * pad); -void PerPadRightReleased(PerPad_struct * pad); - -void PerPadLeftPressed(PerPad_struct * pad); -void PerPadLeftReleased(PerPad_struct * pad); - -void PerPadStartPressed(PerPad_struct * pad); -void PerPadStartReleased(PerPad_struct * pad); - -void PerPadAPressed(PerPad_struct * pad); -void PerPadAReleased(PerPad_struct * pad); - -void PerPadBPressed(PerPad_struct * pad); -void PerPadBReleased(PerPad_struct * pad); - -void PerPadCPressed(PerPad_struct * pad); -void PerPadCReleased(PerPad_struct * pad); - -void PerPadXPressed(PerPad_struct * pad); -void PerPadXReleased(PerPad_struct * pad); - -void PerPadYPressed(PerPad_struct * pad); -void PerPadYReleased(PerPad_struct * pad); - -void PerPadZPressed(PerPad_struct * pad); -void PerPadZReleased(PerPad_struct * pad); - -void PerPadRTriggerPressed(PerPad_struct * pad); -void PerPadRTriggerReleased(PerPad_struct * pad); - -void PerPadLTriggerPressed(PerPad_struct * pad); -void PerPadLTriggerReleased(PerPad_struct * pad); -/** @} */ - -/** @defgroup mouse Mouse - * - * @{ - * */ -#define PERMOUSE_LEFT 13 -#define PERMOUSE_MIDDLE 14 -#define PERMOUSE_RIGHT 15 -#define PERMOUSE_START 16 - -extern const char * PerMouseNames[5]; - -typedef struct -{ - u8 perid; - u8 mousebits[3]; -} PerMouse_struct; - -/** @brief Adds a mouse to one of the controller ports. - * - * @param port can be either &PORTDATA1 or &PORTDATA2 - * @return pointer to a PerMouse_struct or NULL if it fails - * */ -PerMouse_struct * PerMouseAdd(PortData_struct * port); - -void PerMouseLeftPressed(PerMouse_struct * mouse); -void PerMouseLeftReleased(PerMouse_struct * mouse); - -void PerMouseMiddlePressed(PerMouse_struct * mouse); -void PerMouseMiddleReleased(PerMouse_struct * mouse); - -void PerMouseRightPressed(PerMouse_struct * mouse); -void PerMouseRightReleased(PerMouse_struct * mouse); - -void PerMouseStartPressed(PerMouse_struct * mouse); -void PerMouseStartReleased(PerMouse_struct * mouse); - -void PerMouseMove(PerMouse_struct * mouse, s32 dispx, s32 dispy); -/** @} */ - -/** @} */ - -#endif diff --git a/yabause/src/perlinuxjoy.c b/yabause/src/perlinuxjoy.c deleted file mode 100644 index cc0c984acc..0000000000 --- a/yabause/src/perlinuxjoy.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright 2009 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "debug.h" -#include "perlinuxjoy.h" -#include -#include -#include -#include - -int PERLinuxJoyInit(void); -void PERLinuxJoyDeInit(void); -int PERLinuxJoyHandleEvents(void); -void PERLinuxJoyNothing(void); -u32 PERLinuxJoyScan(void); -void PERLinuxJoyFlush(void); -void PERLinuxKeyName(u32 key, char * name, int size); - -PerInterface_struct PERLinuxJoy = { -PERCORE_LINUXJOY, -"Linux Joystick Interface", -PERLinuxJoyInit, -PERLinuxJoyDeInit, -PERLinuxJoyHandleEvents, -PERLinuxJoyNothing, -PERLinuxJoyScan, -1, -PERLinuxJoyFlush -#ifdef PERKEYNAME -,PERLinuxKeyName -#endif -}; - -static int hJOY = -1; - -#define PACKEVENT(evt) ((evt.value < 0 ? 0x10000 : 0) | (evt.type << 8) | (evt.number)) - -////////////////////////////////////////////////////////////////////////////// - -int PERLinuxJoyInit(void) -{ - hJOY = open("/dev/input/js0", O_RDONLY | O_NONBLOCK); - - if (hJOY == -1) return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxJoyDeInit(void) -{ - if (hJOY != -1) close(hJOY); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxJoyNothing(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -int PERLinuxJoyHandleEvents(void) -{ - struct js_event evt; - - if (hJOY == -1) return -1; - - while (read(hJOY, &evt, sizeof(struct js_event)) > 0) - { - if (evt.value != 0) - { - PerKeyDown(PACKEVENT(evt)); - } - else - { - PerKeyUp(PACKEVENT(evt)); - PerKeyUp(0x10000 | PACKEVENT(evt)); - } - } - - // execute yabause - if ( YabauseExec() != 0 ) - { - return -1; - } - - // return success - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERLinuxJoyScan(void) { - struct js_event evt; - - if (hJOY == -1) return 0; - - if (read(hJOY, &evt, sizeof(struct js_event)) <= 0) return 0; - - return PACKEVENT(evt); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxJoyFlush(void) { - struct js_event evt; - - if (hJOY == -1) return; - - while (read(hJOY, &evt, sizeof(struct js_event)) > 0); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxKeyName(u32 key, char * name, UNUSED int size) -{ - sprintf(name, "%x", (int)key); -} diff --git a/yabause/src/perlinuxjoy.h b/yabause/src/perlinuxjoy.h deleted file mode 100644 index 282eacbab4..0000000000 --- a/yabause/src/perlinuxjoy.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2009 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef PERLINUXJOY_H -#define PERLINUXJOY_H - -#include "peripheral.h" - -/** @addtogroup peripheral - * @{ */ -#define PERCORE_LINUXJOY 4 - -extern PerInterface_struct PERLinuxJoy; -/** @} */ - -#endif - diff --git a/yabause/src/permacjoy.c b/yabause/src/permacjoy.c deleted file mode 100644 index 3073bdb6db..0000000000 --- a/yabause/src/permacjoy.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright 2009 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "macjoy.h" -#include "permacjoy.h" -#include "debug.h" - -int PERMacJoyInit(void); -void PERMacJoyDeInit(void); -int PERMacJoyHandleEvents(void); -void PERMacJoyNothing(void); - -u32 PERMacJoyScan(void); -void PERMacJoyFlush(void); -void PERMacJoyKeyName(u32 key, char *name, int size); - -PerInterface_struct PERMacJoy = { - PERCORE_MACJOY, - "Mac OS X (IOKit) Joystick Interface", - PERMacJoyInit, - PERMacJoyDeInit, - PERMacJoyHandleEvents, - PERMacJoyNothing, - PERMacJoyScan, - 1, - PERMacJoyFlush -#ifdef PERKEYNAME - ,PERMacJoyKeyName -#endif -}; - -static int initted = 0; -static int joycount = 0; -static joydata_t **joys = NULL; - -#define AXIS_POSITIVE_VALUE 0x800000 -#define AXIS_NEGATIVE_VALUE 0xC00000 -#define HAT_VALUE 0xA00000 - -#define MIDDLE(x, y) (((x) + (y)) / 2) - -int PERMacJoyInit(void) { - int i; - - /* Don't bother trying to init the thing again. */ - if(initted) - return 0; - - /* Grab the number of joysticks connected to the system. */ - joycount = joy_scan_joysticks(); - if(joycount == -1) { - joycount = 0; - return -1; - } - - joys = (joydata_t **)malloc(sizeof(joydata_t *) * joycount); - if(!joys) { - joycount = 0; - return -1; - } - - /* Grab each joystick and open it. */ - for(i = 0; i < joycount; ++i) { - joys[i] = joy_get_joystick(i); - - if(joys[i] == NULL) - continue; - - if(!joy_open_joystick(joys[i])) { - joys[i] = NULL; - continue; - } - } - - initted = 1; - - return 0; -} - -void PERMacJoyDeInit(void) { - int i; - - if(!initted) - return; - - /* Close each joystick. */ - for(i = 0; i < joycount; ++i) { - joy_close_joystick(joys[i]); - } - - free(joys); - joys = NULL; - joycount = 0; - initted = 0; -} - -int PERMacJoyHandleEvents(void) { - int i, j, k, data; - joydata_t *joy; - - /* Check each joystick. */ - for(i = 0; i < joycount; ++i) { - joy = joys[i]; - - if(!joy) { - continue; - } - - /* Handle each axis. */ - for(j = 0; j < joy->axes_count; ++j) { - int midpoint = MIDDLE(joy->axes[j].min, joy->axes[j].max); - - data = joy_read_axis(joy, j); - - if(joy->axes[j].max > 0 && - data > MIDDLE(midpoint, joy->axes[j].max)) { - PerKeyDown((i << 24) | AXIS_POSITIVE_VALUE | j); - PerKeyUp((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - else if(joy->axes[j].min < 0 && - data < MIDDLE(midpoint, joy->axes[j].min)) { - PerKeyUp((i << 24) | AXIS_POSITIVE_VALUE | j); - PerKeyDown((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - else { - PerKeyUp((i << 24) | AXIS_POSITIVE_VALUE | j); - PerKeyUp((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - } - - /* Handle each button. */ - for(j = 1; j <= joy->buttons_count; ++j) { - data = joy_read_button(joy, j); - - if(data > joy->buttons[j].min) { - PerKeyDown((i << 24) | j); - } - else { - PerKeyUp((i << 24) | j); - } - } - - /* Handle any hats. */ - for(j = 0; j < joy->hats_count; ++j) { - data = joy_read_element(joy, joy->hats + j); - - for(k = joy->hats[j].min; k < joy->hats[j].max; ++k) { - if(data == k) { - PerKeyDown((i << 24) | HAT_VALUE | (k << 8) | j); - } - else { - PerKeyUp((i << 24) | HAT_VALUE | (k << 8) | j); - } - } - } - } - - if(YabauseExec() != 0) { - return -1; - } - - return 0; -} - -void PERMacJoyNothing(void) { - /* Nothing. */ -} - -u32 PERMacJoyScan(void) { - int i, j, k, data; - joydata_t *joy; - - /* Check each joystick. */ - for(i = 0; i < joycount; ++i) { - joy = joys[i]; - - if(!joy) { - continue; - } - - /* Handle each axis. */ - for(j = 0; j < joy->axes_count; ++j) { - int midpoint = MIDDLE(joy->axes[j].min, joy->axes[j].max); - - data = joy_read_axis(joy, j); - - if(joy->axes[j].max > 0 && - data > MIDDLE(midpoint, joy->axes[j].max)) { - return ((i << 24) | AXIS_POSITIVE_VALUE | j); - } - else if(joy->axes[j].min < 0 && - data < MIDDLE(midpoint, joy->axes[j].min)) { - return ((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - } - - /* Handle each button. */ - for(j = 1; j <= joy->buttons_count; ++j) { - data = joy_read_button(joy, j); - - if(data > joy->buttons[j].min) { - return ((i << 24) | j); - } - } - - /* Handle any hats. */ - for(j = 0; j < joy->hats_count; ++j) { - data = joy_read_element(joy, joy->hats + j); - - for(k = joy->hats[j].min; k < joy->hats[j].max; ++k) { - if(data == k) { - return ((i << 24) | HAT_VALUE | (k << 8) | j); - } - } - } - } - - return 0; -} - -void PERMacJoyFlush(void) { - /* Nothing. */ -} - -void PERMacJoyKeyName(u32 key, char *name, int size) { - snprintf(name, size, "%x", (unsigned int)key); -} diff --git a/yabause/src/permacjoy.h b/yabause/src/permacjoy.h deleted file mode 100644 index 91e11591fd..0000000000 --- a/yabause/src/permacjoy.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2009 Lawrence Sebald - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERMACJOY_H -#define PERMACJOY_H - -#include "peripheral.h" - -#define PERCORE_MACJOY 5 - -extern PerInterface_struct PERMacJoy; - -#endif /* !PERMACJOY_H */ diff --git a/yabause/src/persdljoy.c b/yabause/src/persdljoy.c deleted file mode 100644 index 701fdfe778..0000000000 --- a/yabause/src/persdljoy.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - Copyright 2008 Filipe Azevedo - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef HAVE_LIBSDL -#ifdef __APPLE__ - #include -#else - #include "SDL.h" -#endif - -#include "debug.h" -#include "persdljoy.h" - -#define SDL_MAX_AXIS_VALUE 0x110000 -#define SDL_MIN_AXIS_VALUE 0x100000 -#define SDL_MEDIUM_AXIS_VALUE (int)(32768 / 2) -#define SDL_BUTTON_PRESSED 1 -#define SDL_BUTTON_RELEASED 0 - -int PERSDLJoyInit(void); -void PERSDLJoyDeInit(void); -int PERSDLJoyHandleEvents(void); -void PERSDLJoyNothing(void); - -u32 PERSDLJoyScan(void); -void PERSDLJoyFlush(void); -void PERSDLKeyName(u32 key, char * name, int size); - -PerInterface_struct PERSDLJoy = { -PERCORE_SDLJOY, -"SDL Joystick Interface", -PERSDLJoyInit, -PERSDLJoyDeInit, -PERSDLJoyHandleEvents, -PERSDLJoyNothing, -PERSDLJoyScan, -1, -PERSDLJoyFlush -#ifdef PERKEYNAME -,PERSDLKeyName -#endif -}; - -typedef struct { - SDL_Joystick* mJoystick; - s16* mScanStatus; -} PERSDLJoystick; - -unsigned int SDL_PERCORE_INITIALIZED = 0; -unsigned int SDL_PERCORE_JOYSTICKS_INITIALIZED = 0; -PERSDLJoystick* SDL_PERCORE_JOYSTICKS = 0; - -////////////////////////////////////////////////////////////////////////////// - -int PERSDLJoyInit(void) { - int i, j; - - // does not need init if already done - if ( SDL_PERCORE_INITIALIZED ) - { - return 0; - } - - // init joysticks - if ( SDL_InitSubSystem( SDL_INIT_JOYSTICK ) == -1 ) - { - return -1; - } - - // ignore joysticks event in sdl event loop - SDL_JoystickEventState( SDL_IGNORE ); - - // open joysticks - SDL_PERCORE_JOYSTICKS_INITIALIZED = SDL_NumJoysticks(); - SDL_PERCORE_JOYSTICKS = malloc(sizeof(PERSDLJoystick) * SDL_PERCORE_JOYSTICKS_INITIALIZED); - for ( i = 0; i < SDL_PERCORE_JOYSTICKS_INITIALIZED; i++ ) - { - SDL_Joystick* joy = SDL_JoystickOpen( i ); - - SDL_JoystickUpdate(); - - SDL_PERCORE_JOYSTICKS[ i ].mJoystick = joy; - SDL_PERCORE_JOYSTICKS[ i ].mScanStatus = joy ? malloc(sizeof(s16) * SDL_JoystickNumAxes( joy )) : 0; - - if ( joy ) - { - for ( j = 0; j < SDL_JoystickNumAxes( joy ); j++ ) - { - SDL_PERCORE_JOYSTICKS[ i ].mScanStatus[ j ] = SDL_JoystickGetAxis( joy, j ); - } - } - } - - // success - SDL_PERCORE_INITIALIZED = 1; - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERSDLJoyDeInit(void) { - // close joysticks - if ( SDL_PERCORE_INITIALIZED == 1 ) - { - int i; - for ( i = 0; i < SDL_PERCORE_JOYSTICKS_INITIALIZED; i++ ) - { - if ( SDL_JoystickOpened( i ) ) - { - SDL_JoystickClose( SDL_PERCORE_JOYSTICKS[ i ].mJoystick ); - free( SDL_PERCORE_JOYSTICKS[ i ].mScanStatus ); - } - } - free( SDL_PERCORE_JOYSTICKS ); - } - - SDL_PERCORE_JOYSTICKS_INITIALIZED = 0; - SDL_PERCORE_INITIALIZED = 0; - - // close sdl joysticks - SDL_QuitSubSystem( SDL_INIT_JOYSTICK ); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERSDLJoyNothing(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -int PERSDLJoyHandleEvents(void) { - int joyId; - int i; - SDL_Joystick* joy; - Sint16 cur; - Uint8 buttonState; - - // update joysticks states - SDL_JoystickUpdate(); - - // check each joysticks - for ( joyId = 0; joyId < SDL_PERCORE_JOYSTICKS_INITIALIZED; joyId++ ) - { - joy = SDL_PERCORE_JOYSTICKS[ joyId ].mJoystick; - - if ( !joy ) - { - continue; - } - - // check axis - for ( i = 0; i < SDL_JoystickNumAxes( joy ); i++ ) - { - cur = SDL_JoystickGetAxis( joy, i ); - - if ( cur < -SDL_MEDIUM_AXIS_VALUE ) - { - PerKeyUp( (joyId << 18) | SDL_MAX_AXIS_VALUE | i ); - PerKeyDown( (joyId << 18) | SDL_MIN_AXIS_VALUE | i ); - } - else if ( cur > SDL_MEDIUM_AXIS_VALUE ) - { - PerKeyUp( (joyId << 18) | SDL_MIN_AXIS_VALUE | i ); - PerKeyDown( (joyId << 18) | SDL_MAX_AXIS_VALUE | i ); - } - else - { - PerKeyUp( (joyId << 18) | SDL_MIN_AXIS_VALUE | i ); - PerKeyUp( (joyId << 18) | SDL_MAX_AXIS_VALUE | i ); - } - } - - // check buttons - for ( i = 0; i < SDL_JoystickNumButtons( joy ); i++ ) - { - buttonState = SDL_JoystickGetButton( joy, i ); - - if ( buttonState == SDL_BUTTON_PRESSED ) - { - PerKeyDown( (joyId << 18) | (i +1) ); - } - else if ( buttonState == SDL_BUTTON_RELEASED ) - { - PerKeyUp( (joyId << 18) | (i +1) ); - } - } - } - - // execute yabause - if ( YabauseExec() != 0 ) - { - return -1; - } - - // return success - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERSDLJoyScan( void ) { - // init vars - int joyId; - int i; - SDL_Joystick* joy; - Sint16 cur; - - // update joysticks states - SDL_JoystickUpdate(); - - // check each joysticks - for ( joyId = 0; joyId < SDL_PERCORE_JOYSTICKS_INITIALIZED; joyId++ ) - { - joy = SDL_PERCORE_JOYSTICKS[ joyId ].mJoystick; - - if ( !joy ) - { - continue; - } - - // check axis - for ( i = 0; i < SDL_JoystickNumAxes( joy ); i++ ) - { - cur = SDL_JoystickGetAxis( joy, i ); - - if ( cur != SDL_PERCORE_JOYSTICKS[ joyId ].mScanStatus[ i ] ) - { - if ( cur < -SDL_MEDIUM_AXIS_VALUE ) - { - return (joyId << 18) | SDL_MIN_AXIS_VALUE | i; - } - else if ( cur > SDL_MEDIUM_AXIS_VALUE ) - { - return (joyId << 18) | SDL_MAX_AXIS_VALUE | i; - } - } - } - - // check buttons - for ( i = 0; i < SDL_JoystickNumButtons( joy ); i++ ) - { - if ( SDL_JoystickGetButton( joy, i ) == SDL_BUTTON_PRESSED ) - { - return (joyId << 18) | (i +1); - break; - } - } - } - - return 0; -} - -void PERSDLJoyFlush(void) { -} - -void PERSDLKeyName(u32 key, char * name, UNUSED int size) -{ - sprintf(name, "%x", (int)key); -} - -#endif diff --git a/yabause/src/persdljoy.h b/yabause/src/persdljoy.h deleted file mode 100644 index 0a4aecc336..0000000000 --- a/yabause/src/persdljoy.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERSDLJOY_H -#define PERSDLJOY_H - -#include "peripheral.h" - -/** @addtogroup peripheral - * @{ */ -#define PERCORE_SDLJOY 3 - -extern PerInterface_struct PERSDLJoy; -/** @} */ - -#endif diff --git a/yabause/src/profile.c b/yabause/src/profile.c deleted file mode 100644 index 6b67e99ba6..0000000000 --- a/yabause/src/profile.c +++ /dev/null @@ -1,188 +0,0 @@ -/* copyright Patrick Kooman, 2002 - - Lightweight C & C++ profiler. Works both in - debug- and release mode. For more info, read: - - http://www.2dgame-tutorial.com/sdl/profile.htm - - You are free to use / modify / re-distribute this code. - - */ -#if !defined(SYS_PROFILE_H) && !defined(DONT_PROFILE) - -#include "profile.h" - -/* The time when the profiler initializes */ -clock_t g_init_time ; -/* Entries */ -entry_t g_tag [NUM_TAGS] ; -/* "high-water-mark" */ -int g_i_hwm = 0 ; -/* Is ProfileInit called? */ -int g_init = 0 ; - -/* Looks up given tag and returns the name, - of 0 if not found. */ -static entry_t* LookupTag (char* str_tag) { - int i ; - for (i = 0; i < g_i_hwm; ++i) { - if (strcmp (g_tag [i].str_name, str_tag) == 0) { - return &g_tag [i] ; - } - } - return 0 ; -} - -/* Checks whether the given tag is already started (nesting). - This is true when an entry with the given name is found, - for which the start_time_t is not 0. */ -static int Nested (char* str_tag) { - int i ; - for (i = 0; i < g_i_hwm; ++i) { - if (strcmp (g_tag [i].str_name, str_tag) == 0 && g_tag [i].start_time > -1) { - /* Already 'running': nested*/ - return 1 ; - } - } - /* Not running: not nested */ - return 0 ; -} - -/* Adds the given tag and return the entry it is stored into */ -static entry_t* AddTag (char* str_tag) { - if (g_i_hwm + 1 == NUM_TAGS) { - /* Full */ - return 0 ; - } - /* Copy the name */ - strcpy (g_tag [g_i_hwm].str_name, str_tag) ; - g_tag [g_i_hwm].start_time = -1 ; - /* Increase the high-water-mark but return the current index */ - return &g_tag [g_i_hwm++] ; -} - -/* Compare function for 'qsort' */ -static int CompareEntries (const void* p_1, const void* p_2) { - entry_t* p_entry1, *p_entry2 ; - /* Cast elements to entry_t type */ - p_entry1 = (entry_t*) p_1 ; - p_entry2 = (entry_t*) p_2 ; - /* Compare */ - return p_entry2->l_total_ms - p_entry1->l_total_ms ; -} - -/* Called on the first start-call. It receives the start-time */ -static void Init (void) { - memset (g_tag, 0, sizeof (g_tag)) ; - /* Retreive the time */ - g_init_time = clock () ; - /* Flag that this function has been called */ - g_init = 1 ; - g_i_hwm = 0 ; -} - -/* Prints profiling statistice to stdout, -sorted by percentage (descending) */ -void ProfilePrint (void) { - int i ; - long l_prof_time ; - if (g_i_hwm == 0) { - fprintf (stdout, "ProfilePrint: nothing to print.\n") ; - return ; - } - /* Retreive the time */ - l_prof_time = clock () - g_init_time ; - if (l_prof_time == 0) { - /* Avoid division by 0 */ - fprintf (stdout, "Warning: nothing to show because timer ran for less than 1 clock-tick.") ; - } - /* Print warnings for tags which are not stopped. */ - for (i = 0; i < g_i_hwm; ++i) { - if (g_tag [i].i_stopped == 0) { - g_tag [i].l_total_ms += clock () - g_tag [i].start_time ; - fprintf (stdout, "Warning: \"%s\" started but not stopped. (Done now, but result may be over-expensive!)\n", g_tag [i].str_name) ; - } - } - /* Sort the array desending */ - qsort (&g_tag, g_i_hwm, sizeof (entry_t), CompareEntries) ; - fprintf (stdout, "Profiler results (descending by percentage):\n\n") ; - for (i = 0; i < g_i_hwm; ++i) { - /* Print statistics */ - fprintf (stdout, "< calls: %2d, total ms: %3d, percentage: %3.1f%% > - \"%s\"\n", - g_tag [i].i_calls, - (int) ((double) g_tag [i].l_total_ms / CLOCKS_PER_SEC * 1000), - (double) g_tag [i].l_total_ms / l_prof_time * 100, - g_tag [i].str_name) ; - } -} - -/* Starts timer for given tag. If it does not exist yet, - it is added. - - Note: 1. The tag may not be nested with the same name - 2. The tag may not equal "" */ -void ProfileStart (char* str_tag) { - entry_t* p_entry ; - /* One the first call, we must initialize the profiler. */ - if (!g_init) { - Init () ; - } - /* Test for "" */ - if (*str_tag == '\0') { - fprintf (stdout, "ERROR in ProfileStart: a tag may not be \"\". Call is denied.") ; - return ; - } - /* Search the entry with the given name */ - p_entry = LookupTag (str_tag) ; - if (!p_entry) { - /* New tag, add it*/ - p_entry = AddTag (str_tag) ; - if (!p_entry) { - fprintf (stdout, "WARNING in ProfileStart: no more space to store the tag (\"%s\"). Increase NUM_TAGS in \"profile.h\". Call is denied.\n", str_tag) ; - return ; - } - } - /* Check for nesting of equal tag.*/ - if (Nested (str_tag)) { - fprintf (stdout, "ERROR in ProfileStart: nesting of equal tags not allowed (\"%s\"). Call is denied.\n", str_tag) ; - return ; - } - /* Increase the number of hits */ - ++p_entry->i_calls ; - /* Set the start time */ - p_entry->start_time = clock () ; - p_entry->i_stopped = 0 ; -} - -/* Stops timer for given tag. Checks for existence. - Adds the time between now and the Start call to the - total time.*/ -void ProfileStop (char* str_tag) { - clock_t end_time ; - entry_t* p_entry ; - /* Test for "" */ - if (*str_tag == '\0') { - fprintf (stdout, "ERROR in ProfileStop: a tag may not be \"\". Call is denied.") ; - return ; - } - /* Check for a existing name */ - p_entry = LookupTag (str_tag) ; - if (!p_entry) { - fprintf (stdout, "WARNING in ProfileStop: tag \"%s\" was never started. Call is denied.\n", str_tag) ; - return ; - } - /* Get the time */ - end_time = clock () ; - p_entry->l_total_ms += end_time - p_entry->start_time ; - /* Reset */ - p_entry->start_time = -1 ; - p_entry->i_stopped = 1 ; -} - -/* Resets the profiler. */ -void ProfileReset (void) { - Init () ; -} - -#endif /* !SYS_PROFILE_H && !DONT_PROFILE */ - diff --git a/yabause/src/profile.h b/yabause/src/profile.h deleted file mode 100644 index c89529f39c..0000000000 --- a/yabause/src/profile.h +++ /dev/null @@ -1,65 +0,0 @@ -/* copyright Patrick Kooman, 2002 - - Lightweight C & C++ profiler. Works both in - debug- and release mode. For more info, read: - - http://www.2dgame-tutorial.com/sdl/profile.htm - - You are free to use / modify / re-distribute this code. - - */ -#ifndef _PROFILE_H_ -#define _PROFILE_H_ - -#include -#include -#include -#include -#include - -#ifdef DONT_PROFILE -/* Profiling disabled: compiler won't generate machine instructions now. */ -#define PROFILE_START(t) -#define PROFILE_STOP(t) -#define PROFILE_PRINT() -#define PROFILE_RESET() -#else -/* Profiling enabled */ -#define MAX_TAG_LEN 100 -#define NUM_TAGS 100 - -typedef struct { - char str_name [MAX_TAG_LEN] ; - int i_calls ; - clock_t start_time ; - int i_stopped ; - long l_total_ms ; -} entry_t ; - -/* Compiler calls functions now. */ -#define PROFILE_START(t) ProfileStart (t) -#define PROFILE_STOP(t) ProfileStop (t) -#define PROFILE_PRINT() ProfilePrint () -#define PROFILE_RESET() ProfileReset () - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Start timer for given tag */ -void ProfileStart (char* str_tag) ; -/* Stops timer for given tag and add time to total time for this tag */ -void ProfileStop (char* str_tag) ; -/* Prints result to stdout */ -void ProfilePrint (void) ; -/* Resets the profiler. */ -void ProfileReset (void) ; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NO_PROFILE */ - -#endif /* _PROFILE_H_ */ - diff --git a/yabause/src/psp/Makefile.am b/yabause/src/psp/Makefile.am deleted file mode 100644 index 5d95fbd291..0000000000 --- a/yabause/src/psp/Makefile.am +++ /dev/null @@ -1,82 +0,0 @@ -EXTRA_DIST = icache-funcs-2450.patch me-sectstart.c me-sectend.c \ - psp-logo.png sh2-core.i -CLEANFILES = me.elf me.prx me-exp.c me-test.elf me-test.prx melib.S \ - yabause.elf yabause.prx yabause.sfo EBOOT.PBP - -# yabause.{elf,prx} are only intermediate targets; the final target is -# EBOOT.PBP (but we keep the ELF/PRX files around for testing purposes). -if BUILD_ME_TEST -me_test=me-test.prx -else -me_test= -endif -all-local: EBOOT.PBP me.prx $(me_test) -.SECONDARY: yabause.elf yabause.prx me.elf me-test.elf - -######## - -noinst_PROGRAMS = yabause.elf me.elf me-test.elf - -yabause_elf_SOURCES = config.c control.c display.c filesel.c font.c gu.c \ - init.c localtime.c main.c menu.c misc.c osk.c profile.c \ - psp-cd.c psp-m68k.c psp-per.c psp-sh2.c psp-sound.c \ - psp-video.c psp-video-bitmap.c psp-video-rotate.c \ - psp-video-tilemap.c psp-video-tweaks.c \ - rtl.c rtl-mips.c rtlexec.c rtlinsn.c rtlopt.c rtlunit.c \ - satopt-sh2.c \ - sh2.c sh2-interpret.c sh2-opcodeinfo.c sh2-optimize.c \ - sys.c texcache.c threads.c timing.c yui.c \ - me-utility.c \ - \ - common.h config.h control.h display.h filesel.h font.h \ - gu.h init.h localtime.h menu.h misc.h osk.h profile.h \ - psp-cd.h psp-m68k.h psp-per.h psp-sh2.h psp-sound.h \ - psp-video.h psp-video-internal.h \ - rtl.h rtl-internal.h rtl-mips.h \ - satopt-sh2.h \ - sh2.h sh2-internal.h \ - sys.h texcache.h timing.h \ - me-utility.h -yabause_elf_DEPENDENCIES = me-sectstart.$(OBJEXT) me-sectend.$(OBJEXT) -nodist_yabause_elf_SOURCES = melib.S -yabause_elf_CFLAGS = $(YAB_CFLAGS) -Wpointer-arith -Wshadow -yabause_elf_LDADD = ../libyabause.a $(YAB_LIBS) -lpspsdk -yabause.elf: $(yabause_elf_OBJECTS) $(yabause_elf_DEPENDENCIES) ../libyabause.a - $(yabause_elf_LINK) \ - me-sectstart.$(OBJEXT) \ - $(yabause_elf_OBJECTS) \ - $(yabause_elf_LDADD) \ - $(LIBS) \ - me-sectend.$(OBJEXT) - -me_elf_SOURCES = me.c me.h -nodist_me_elf_SOURCES = me-exp.c -me_elf_CFLAGS = -Wpointer-arith -Wshadow -me_elf_LDFLAGS = -nostartfiles -me_elf_LIBS = -lpspkernel -me.elf: $(me_elf_OBJECTS) - $(me_elf_LINK) $(me_elf_OBJECTS) $(me_elf_LDADD) $(me_elf_LIBS) - -me_test_elf_SOURCES = me-test.c me-utility.c me-utility.h -nodist_me_test_elf_SOURCES = melib.S -me_test_elf_CFLAGS = -Wpointer-arith -Wshadow -me_test_elf_LIBS = -lc -lpspuser -me-test.elf: $(me_test_elf_OBJECTS) - $(me_test_elf_LINK) $(me_test_elf_OBJECTS) $(me_test_elf_LDADD) $(me_test_elf_LIBS) - -######## - -.elf.prx: - psp-fixup-imports $< - psp-prxgen $< $@ - -me-exp.c: me.exp - psp-build-exports -b $< >$@ -melib.S: me.exp - psp-build-exports -s $< - -yabause.sfo: - mksfoex -d MEMSIZE=1 "Yabause $(PACKAGE_VERSION)" $@ - -EBOOT.PBP: psp-logo.png yabause.prx yabause.sfo - pack-pbp $@ yabause.sfo $< NULL NULL NULL NULL yabause.prx NULL diff --git a/yabause/src/psp/common.h b/yabause/src/psp/common.h deleted file mode 100644 index c3ad5886d0..0000000000 --- a/yabause/src/psp/common.h +++ /dev/null @@ -1,258 +0,0 @@ -/* src/psp/common.h: Common header for PSP source files - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_COMMON_H -#define PSP_COMMON_H - -/**************************************************************************/ - -/* Various system headers */ - -#include -#include -#include -#define abs builtin_abs // Avoid shadowing warnings for common identifiers -#define div builtin_div -#include -#undef abs -#undef div -#define index builtin_index -#include -#undef index -#define remainder builtin_remainder -#define y0 builtin_y0 -#define y1 builtin_y1 -#include -#undef remainder -#undef y0 -#undef y1 - - -#define u8 pspsdk_u8 // Avoid type collisions with ../core.h -#define s8 pspsdk_s8 -#define u16 pspsdk_u16 -#define s16 pspsdk_s16 -#define u32 pspsdk_u32 -#define s32 pspsdk_s32 -#define u64 pspsdk_u64 -#define s64 pspsdk_s64 - -#ifdef PSP -# include -# include -# include -# include -# include -# include -# include -# include -# define PSP_SYSTEMPARAM_ID_INT_X_IS_CONFIRM 9 // Presumably, anyway -#endif - -#undef u8 -#undef s8 -#undef u16 -#undef s16 -#undef u32 -#undef s32 -#undef u64 -#undef s64 - -/* Helpful hints for GCC */ -#if defined(__GNUC__) && defined(PSP) -extern void sceKernelExitGame(void) __attribute__((noreturn)); -extern int sceKernelExitThread(int status) __attribute__((noreturn)); -extern int sceKernelExitDeleteThread(int status) __attribute__((noreturn)); -#endif - -/**************************************************************************/ - -/* Thread priority constants */ -enum { - THREADPRI_MAIN = 32, - THREADPRI_CD_READ = 25, - THREADPRI_UTILITY = 21, - THREADPRI_SOUND = 20, - THREADPRI_SYSTEM_CB = 15, -}; - -/*----------------------------------*/ - -/* Program directory (determined from argv[0]) */ -extern char progpath[256]; - -/* Saturn control pad handle (set at initialization time, and used by menu - * code to change button assignments) */ -extern void *padbits; - -/* Flag indicating whether the ME is available for use */ -extern int me_available; - -/* Have we successfully initialized the Yabause core? */ -extern int yabause_initted; - -/**************************************************************************/ - -/* Convenience macros (not PSP-related, except DSTART/DEND) */ - -/*----------------------------------*/ - -/* Get the length of an array */ -#define lenof(a) (sizeof((a)) / sizeof((a)[0])) -/* Bound a value between two limits (inclusive) */ -#define bound(x,low,high) __extension__({ \ - typeof(x) __x = (x); \ - typeof(low) __low = (low); \ - typeof(high) __high = (high); \ - __x < __low ? __low : __x > __high ? __high : __x; \ -}) - -/* Get offset of a structure member */ -#undef offsetof -#ifdef __GNUC__ -# define offsetof(type,member) __builtin_offsetof(type,member) -#else -# define offsetof(type,member) ((uintptr_t)&(((type *)0)->member)) -#endif - -/* Declare a function to be constant (i.e. not touching memory) */ -#undef CONST_FUNCTION -#ifdef __GNUC__ -# define CONST_FUNCTION __attribute__((const)) -#else -# define CONST_FUNCTION /*nothing*/ -#endif - -/* Force a function to be inlined if possible (use in place of "inline") */ -#ifdef __GNUC__ -# define ALWAYS_INLINE inline __attribute__((always_inline)) -#else -# define ALWAYS_INLINE inline -#endif - -/* Prevent a function from being inlined */ -#ifdef __GNUC__ -# define NOINLINE __attribute__((noinline)) -#else -# define NOINLINE /*nothing*/ -#endif - -/*----------------------------------*/ - -/* Convert a float to an int (optimized for PSP, but with alternate - * versions for testing on other systems) */ - -#ifdef PSP - -#define DEFINE_IFUNC(name,insn) \ -static inline CONST_FUNCTION int32_t name(const float x) { \ - float dummy; \ - int32_t result; \ - asm(insn : [result] "=r" (result), [dummy] "=f" (dummy) : [x] "f" (x)); \ - return result; \ -} - -DEFINE_IFUNC(ifloorf, "floor.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") -DEFINE_IFUNC(iceilf, "ceil.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") -DEFINE_IFUNC(itruncf, "trunc.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") -DEFINE_IFUNC(iroundf, "round.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") - -#elif HAVE_FLOORF - -static inline CONST_FUNCTION int ifloorf(float x) {return (int)floorf(x);} -static inline CONST_FUNCTION int iceilf (float x) {return (int)ceilf(x);} -static inline CONST_FUNCTION int itruncf(float x) {return (int)truncf(x);} -static inline CONST_FUNCTION int iroundf(float x) {return (int)roundf(x);} - -#else // !PSP && !HAVE_FLOORF --> use double-precision floor() and ceil() - -static inline CONST_FUNCTION int ifloorf(float x) {return (int)floor(x);} -static inline CONST_FUNCTION int iceilf (float x) {return (int)ceil(x);} -static inline CONST_FUNCTION int itruncf(float x) - {return (x)<0 ? (int)-floor(-x) : (int)floor(x);} -static inline CONST_FUNCTION int iroundf(float x) {return (int)floor(x+0.5f);} - -#endif - -/*----------------------------------*/ - -#ifdef PSP_DEBUG - -/* Debug/error message macro. DMSG("message",...) prints to stderr a line - * in the form: - * func_name(file:line): message - * printf()-style format tokens and arguments are allowed, and no newline - * is required at the end. The format string must be a literal string - * constant. Note that we sprintf() into a buffer and write the buffer - * rather than calling fprintf() directly because fprintf() makes multiple - * low-level write calls, which can slow the program down significantly - * depending on PSPlink's responsiveness on the PC host. */ -/* global shared */ char DMSG_buffer[10000]; -#define DMSG(msg,...) do { \ - snprintf(DMSG_buffer, sizeof(DMSG_buffer), "%s(%s:%d): " msg "\n", \ - __FUNCTION__, __FILE__, __LINE__ , ## __VA_ARGS__); \ - fputs(DMSG_buffer, stderr); \ -} while (0) - -/* Timing macro. Start timing with DSTART(); DEND() will then print the - * elapsed time in microseconds. Both must occur at the same level of - * block nesting. */ -#define DSTART() { const uint32_t __start = sceKernelGetSystemTimeLow() -#define DEND() DMSG("time=%u", sceKernelGetSystemTimeLow() - __start); } - -#else // !PSP_DEBUG - -/* Disable debug output */ -#define DMSG(msg,...) /*nothing*/ -#define DSTART() /*nothing*/ -#define DEND() /*nothing*/ - -#endif - -/*----------------------------------*/ - -/* Test a precondition, and perform the given action if it fails */ - -#define PRECOND(condition,fail_action) do { \ - if (UNLIKELY(!(condition))) { \ - DMSG("PRECONDITION FAILED: %s", #condition); \ - fail_action; \ - } \ -} while (0) - -/**************************************************************************/ - -/* Include the Yabause core header for other common definitions/declarations */ - -#include "../core.h" - -/**************************************************************************/ - -#endif // PSP_COMMON_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/config.c b/yabause/src/psp/config.c deleted file mode 100644 index 3fdf998e98..0000000000 --- a/yabause/src/psp/config.c +++ /dev/null @@ -1,842 +0,0 @@ -/* src/psp/config.c: Configuration data management for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "config.h" -#include "psp-sh2.h" -#include "psp-video.h" -#include "sh2.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Configuration file name (always stored in program directory) */ -#define PATH_INI "yabause.ini" - -/* Data file paths */ -static char path_bios[256] = "bios.bin"; -static char path_cd[256] = "cd.iso"; -static char path_bup[256] = "backup.bin"; - -/* General settings */ -static int start_in_emu = 0; -static int use_me = 0; -static uint32_t me_writeback_period = 1; -static uint32_t me_uncached_boundary = 0x800; -static int bup_autosave = 1; - -/* Button configuration */ -static uint32_t button[6] = { - [CONFIG_BUTTON_A] = PSP_CTRL_CROSS, - [CONFIG_BUTTON_B] = PSP_CTRL_CIRCLE, - [CONFIG_BUTTON_C] = 0, - [CONFIG_BUTTON_X] = PSP_CTRL_SQUARE, - [CONFIG_BUTTON_Y] = PSP_CTRL_TRIANGLE, - [CONFIG_BUTTON_Z] = 0, -}; - -/* Module selections */ -static int module_sh2 = SH2CORE_PSP; -static int module_video = VIDCORE_PSP; - -/* Display settings */ -static int cache_textures = 1; -static int smooth_textures = 0; -static int smooth_hires = 0; -static int enable_rotate = 1; -static int optimize_rotate = 1; -static int frameskip_auto = 0; -static int frameskip_num = 0; -static int frameskip_interlace = 1; -static int frameskip_rotate = 1; -static int show_fps = 0; - -static uint32_t sh2_optimizations = SH2_OPTIMIZE_ASSUME_SAFE_DIVISION - | SH2_OPTIMIZE_BRANCH_TO_RTS - | SH2_OPTIMIZE_FOLD_SUBROUTINES - | SH2_OPTIMIZE_LOCAL_ACCESSES - | SH2_OPTIMIZE_LOCAL_POINTERS - | SH2_OPTIMIZE_MAC_NOSAT - | SH2_OPTIMIZE_POINTERS - | SH2_OPTIMIZE_POINTERS_MAC - | SH2_OPTIMIZE_STACK; -/* All known optimization flags (so we can leave newly-implemented flags at - * their default values when loading the config file) */ -#define SH2_KNOWN_OPTIMIZATIONS (SH2_OPTIMIZE_ASSUME_SAFE_DIVISION \ - | SH2_OPTIMIZE_BRANCH_TO_RTS \ - | SH2_OPTIMIZE_FOLD_SUBROUTINES \ - | SH2_OPTIMIZE_LOCAL_ACCESSES \ - | SH2_OPTIMIZE_LOCAL_POINTERS \ - | SH2_OPTIMIZE_MAC_NOSAT \ - | SH2_OPTIMIZE_POINTERS \ - | SH2_OPTIMIZE_POINTERS_MAC \ - | SH2_OPTIMIZE_STACK) - -/* Deciline (precise timing) mode flag */ -static int deciline_mode = 0; -/* Audio sync flag */ -static int audio_sync = 1; -/* Clock sync flag */ -static int clock_sync = 1; -/* Start-from-fixed-time flag */ -static int clock_fixed_time = 0; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ - -static int parse_string(const char *file, int line, const char *name, - const char *text, char *buffer, unsigned int bufsize); -static int parse_int(const char *file, int line, const char *name, - const char *text, int *value_ret); -static int parse_uint32(const char *file, int line, const char *name, - const char *text, uint32_t *value_ret); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * config_load: Load configuration data from the configuration file. - * Invalid data is ignored, and options not specified in the configuration - * file are left unchanged. - * - * [Parameters] - * None - * [Return value] - * None - */ -void config_load(void) -{ - /* Open the configuration file, aborting if it's not available */ - FILE *f = fopen(PATH_INI, "r"); - if (!f) { - perror("fopen(" PATH_INI ")"); - return; - } - - /* Read the entire file in at once and close the file pointer */ - char *filebuf; - if (fseek(f, 0, SEEK_END) < 0) { - perror("fseek(SEEK_END)"); - close_and_return: - fclose(f); - return; - } - long filesize = ftell(f); - if (filesize < 0) { - perror("ftell()"); - goto close_and_return; - } - if (fseek(f, 0, SEEK_SET) < 0) { - perror("fseek(SEEK_SET)"); - goto close_and_return; - } - filebuf = malloc(filesize+1); // Leave space for a trailing \0 - if (!filebuf) { - fprintf(stderr, "No memory for config file buffer (%ld bytes)\n", - filesize); - goto close_and_return; - } - if (fread(filebuf, filesize, 1, f) != 1) { - fprintf(stderr, "Failed to read config file\n"); - free(filebuf); - goto close_and_return; - } - fclose(f); - filebuf[filesize] = 0; - - /* Parse each line of the configuration file; lines are of the form - * name=value - * with no spaces permitted on either side of the "=". We take care - * to treat names as case-insensitive and to support any of "\r", - * "\r\n" or "\n" as a line terminator, in case people edit the file - * on their own. */ - - char *s, *eol; - int line; - for (s = filebuf, line = 1; *s; s = eol, line++) { - - eol = s + strcspn(s, "\r\n"); - if (*eol == '\r') { - *eol++ = 0; - } - if (*eol == '\n') { - *eol++ = 0; - } - char *name = s; - char *value = strchr(s, '='); - if (!value) { - fprintf(stderr, "%s:%d: Missing `='\n", PATH_INI, line); - continue; - } - *value++ = 0; - - if (stricmp(name, "path_bios") == 0) { - parse_string(PATH_INI, line, name, value, - path_bios, sizeof(path_bios)); - - } else if (stricmp(name, "path_cd") == 0) { - parse_string(PATH_INI, line, name, value, - path_cd, sizeof(path_cd)); - - } else if (stricmp(name, "path_bup") == 0) { - parse_string(PATH_INI, line, name, value, - path_bup, sizeof(path_bup)); - - } else if (stricmp(name, "start_in_emu") == 0) { - parse_int(PATH_INI, line, name, value, &start_in_emu); - - } else if (stricmp(name, "use_me") == 0) { - parse_int(PATH_INI, line, name, value, &use_me); - - } else if (stricmp(name, "me_writeback_period") == 0) { - parse_uint32(PATH_INI, line, name, value, &me_writeback_period); - if (!me_writeback_period - || (me_writeback_period & (me_writeback_period - 1)) - ) { - fprintf(stderr, "config_load(): Invalid value %u for" - " me_writeback_period (must be a power of 2)\n", - me_writeback_period); - me_writeback_period = 1; - } - - } else if (stricmp(name, "me_uncached_boundary") == 0) { - parse_uint32(PATH_INI, line, name, value, &me_uncached_boundary); - if (me_uncached_boundary > 0x80000) { - me_uncached_boundary = 0x80000; - } - - } else if (stricmp(name, "bup_autosave") == 0) { - parse_int(PATH_INI, line, name, value, &bup_autosave); - - } else if (stricmp(name, "button.A") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_A]); - - } else if (stricmp(name, "button.B") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_B]); - - } else if (stricmp(name, "button.C") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_C]); - - } else if (stricmp(name, "button.X") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_X]); - - } else if (stricmp(name, "button.Y") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_Y]); - - } else if (stricmp(name, "button.Z") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_Z]); - - } else if (stricmp(name, "module_sh2") == 0) { - parse_int(PATH_INI, line, name, value, &module_sh2); - - } else if (stricmp(name, "module_video") == 0) { - parse_int(PATH_INI, line, name, value, &module_video); - - } else if (stricmp(name, "cache_textures") == 0) { - parse_int(PATH_INI, line, name, value, &cache_textures); - - } else if (stricmp(name, "smooth_textures") == 0) { - parse_int(PATH_INI, line, name, value, &smooth_textures); - - } else if (stricmp(name, "smooth_hires") == 0) { - parse_int(PATH_INI, line, name, value, &smooth_hires); - - } else if (stricmp(name, "enable_rotate") == 0) { - parse_int(PATH_INI, line, name, value, &enable_rotate); - - } else if (stricmp(name, "optimize_rotate") == 0) { - parse_int(PATH_INI, line, name, value, &optimize_rotate); - - } else if (stricmp(name, "frameskip_auto") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_auto); - - } else if (stricmp(name, "frameskip_num") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_num); - if (frameskip_num < 0) { - frameskip_num = 0; - } else if (frameskip_num > 9) { - frameskip_num = 9; - } - - } else if (stricmp(name, "frameskip_interlace") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_interlace); - - } else if (stricmp(name, "frameskip_rotate") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_rotate); - - } else if (stricmp(name, "show_fps") == 0) { - parse_int(PATH_INI, line, name, value, &show_fps); - - } else if (stricmp(name, "sh2_optimizations") == 0) { - uint32_t newval = strtoul(value, &s, 10); - if (*s != '/') { - fprintf(stderr, "%s:%d: Bad format for `%s' value\n", - PATH_INI, line, name); - continue; - } - uint32_t mask = strtoul(s+1, &s, 10); - if (*s) { - fprintf(stderr, "%s:%d: Bad format for `%s' value\n", - PATH_INI, line, name); - continue; - } - sh2_optimizations &= ~mask; - sh2_optimizations |= newval & mask; - - } else if (stricmp(name, "deciline_mode") == 0) { - parse_int(PATH_INI, line, name, value, &deciline_mode); - - } else if (stricmp(name, "audio_sync") == 0) { - parse_int(PATH_INI, line, name, value, &audio_sync); - - } else if (stricmp(name, "clock_sync") == 0) { - parse_int(PATH_INI, line, name, value, &clock_sync); - - } else if (stricmp(name, "clock_fixed_time") == 0) { - parse_int(PATH_INI, line, name, value, &clock_fixed_time); - - } else { - fprintf(stderr, "%s:%d: Unknown configuration variable `%s'\n", - PATH_INI, line, name); - - } - - } // for (s = filebuf, line = 1; *s; s = eol, line++) -} - -/*-----------------------------------------------------------------------*/ - -/** - * config_save: Save the current configuration to the configuration file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int config_save(void) -{ - FILE *f = fopen(PATH_INI, "w"); - if (!f) { - perror("fopen(" PATH_INI ")"); - return 0; - } - - if (fprintf(f, "path_bios=%s\n", path_bios ) < 0 - || fprintf(f, "path_cd=%s\n", path_cd ) < 0 - || fprintf(f, "path_bup=%s\n", path_bup ) < 0 - || fprintf(f, "start_in_emu=%d\n", start_in_emu ) < 0 - || fprintf(f, "use_me=%d\n", use_me ) < 0 - || fprintf(f, "me_writeback_period=%u\n", me_writeback_period ) < 0 - || fprintf(f, "me_uncached_boundary=%u\n", me_uncached_boundary ) < 0 - || fprintf(f, "bup_autosave=%d\n", bup_autosave ) < 0 - || fprintf(f, "button.A=%u\n", button[CONFIG_BUTTON_A]) < 0 - || fprintf(f, "button.B=%u\n", button[CONFIG_BUTTON_B]) < 0 - || fprintf(f, "button.C=%u\n", button[CONFIG_BUTTON_C]) < 0 - || fprintf(f, "button.X=%u\n", button[CONFIG_BUTTON_X]) < 0 - || fprintf(f, "button.Y=%u\n", button[CONFIG_BUTTON_Y]) < 0 - || fprintf(f, "button.Z=%u\n", button[CONFIG_BUTTON_Z]) < 0 - || fprintf(f, "module_sh2=%d\n", module_sh2 ) < 0 - || fprintf(f, "module_video=%d\n", module_video ) < 0 - || fprintf(f, "cache_textures=%d\n", cache_textures ) < 0 - || fprintf(f, "smooth_textures=%d\n", smooth_textures ) < 0 - || fprintf(f, "smooth_hires=%d\n", smooth_hires ) < 0 - || fprintf(f, "enable_rotate=%d\n", enable_rotate ) < 0 - || fprintf(f, "optimize_rotate=%d\n", optimize_rotate ) < 0 - || fprintf(f, "frameskip_auto=%d\n", frameskip_auto ) < 0 - || fprintf(f, "frameskip_num=%d\n", frameskip_num ) < 0 - || fprintf(f, "frameskip_interlace=%d\n", frameskip_interlace ) < 0 - || fprintf(f, "frameskip_rotate=%d\n", frameskip_rotate ) < 0 - || fprintf(f, "show_fps=%d\n", show_fps ) < 0 - || fprintf(f, "sh2_optimizations=%u/%u\n", sh2_optimizations, - SH2_KNOWN_OPTIMIZATIONS) < 0 - || fprintf(f, "deciline_mode=%d\n", deciline_mode ) < 0 - || fprintf(f, "audio_sync=%d\n", audio_sync ) < 0 - || fprintf(f, "clock_sync=%d\n", clock_sync ) < 0 - || fprintf(f, "clock_fixed_time=%d\n", clock_fixed_time ) < 0 - ) { - perror("fprintf(" PATH_INI ",...)"); - fclose(f); - return 0; - } - - if (fclose(f) < 0) { - perror("fclose(" PATH_INI ")"); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * config_get_*: Retrieve the current value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * [Return value] - * Current value of configuration variable - */ - -const char *config_get_path_bios(void) -{ - return path_bios; -} - -const char *config_get_path_cd(void) -{ - return path_cd; -} - -const char *config_get_path_bup(void) -{ - return path_bup; -} - -int config_get_start_in_emu(void) -{ - return start_in_emu; -} - -int config_get_use_me(void) -{ - return use_me; -} - -uint32_t config_get_me_writeback_period(void) -{ - return me_writeback_period; -} - -uint32_t config_get_me_uncached_boundary(void) -{ - return me_uncached_boundary; -} - -int config_get_bup_autosave(void) -{ - return bup_autosave; -} - -uint32_t config_get_button(ConfigButtonID id) -{ - PRECOND(id >= CONFIG_BUTTON_A && id <= CONFIG_BUTTON_Z, return 0); - return button[id]; -} - -int config_get_module_sh2(void) -{ - return module_sh2; -} - -int config_get_module_video(void) -{ - return module_video; -} - -int config_get_cache_textures(void) -{ - return cache_textures; -} - -int config_get_smooth_textures(void) -{ - return smooth_textures; -} - -int config_get_smooth_hires(void) -{ - return smooth_hires; -} - -int config_get_enable_rotate(void) -{ - return enable_rotate; -} - -int config_get_optimize_rotate(void) -{ - return optimize_rotate; -} - -int config_get_frameskip_auto(void) -{ - return frameskip_auto; -} - -int config_get_frameskip_num(void) -{ - return frameskip_num; -} - -int config_get_frameskip_interlace(void) -{ - return frameskip_interlace; -} - -int config_get_frameskip_rotate(void) -{ - return frameskip_rotate; -} - -int config_get_show_fps(void) -{ - return show_fps; -} - -uint32_t config_get_sh2_optimizations(void) -{ - return sh2_optimizations; -} - -int config_get_deciline_mode(void) -{ - return deciline_mode; -} - -int config_get_audio_sync(void) -{ - return audio_sync; -} - -int config_get_clock_sync(void) -{ - return clock_sync; -} - -int config_get_clock_fixed_time(void) -{ - return clock_fixed_time; -} - -/*-----------------------------------------------------------------------*/ - -/** - * config_set_*: Set the value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * value: New value for configuration variable - * [Return value] - * Nonzero on success, zero on error - */ - -int config_set_path_bios(const char *value) -{ - PRECOND(value != NULL, return 0); - if (strlen(value) > sizeof(path_bios) - 1) { - fprintf(stderr, "config_set_path_bios(): Value too long (max %d" - " characters): %s\n", sizeof(path_bios) - 1, value); - return 0; - } - strcpy(path_bios, value); // Safe - return 1; -} - -int config_set_path_cd(const char *value) -{ - PRECOND(value != NULL, return 0); - if (strlen(value) > sizeof(path_cd) - 1) { - fprintf(stderr, "config_set_path_cd(): Value too long (max %d" - " characters): %s\n", sizeof(path_cd) - 1, value); - return 0; - } - strcpy(path_cd, value); // Safe - return 1; -} - -int config_set_path_bup(const char *value) -{ - PRECOND(value != NULL, return 0); - if (strlen(value) > sizeof(path_bup) - 1) { - fprintf(stderr, "config_set_path_bup(): Value too long (max %d" - " characters): %s\n", sizeof(path_bup) - 1, value); - return 0; - } - strcpy(path_bup, value); // Safe - return 1; -} - -int config_set_start_in_emu(int value) -{ - start_in_emu = value ? 1 : 0; - return 1; -} - -int config_set_use_me(int value) -{ - use_me = value ? 1 : 0; - return 1; -} - -int config_set_me_writeback_period(uint32_t value) -{ - if (value == 0 || (value & (value-1))) { - fprintf(stderr, "config_set_me_writeback_period(): Invalid period %u" - " (must be a power of 2)\n", value); - return 0; - } - me_writeback_period = value; - return 1; -} - -int config_set_me_uncached_boundary(uint32_t value) -{ - if (value > 0x80000) { - fprintf(stderr, "config_set_me_uncached_boundary(): Invalid boundary" - " %u (maximum %u)\n", value, 0x80000); - return 0; - } - me_uncached_boundary = value; - return 1; -} - -int config_set_bup_autosave(int value) -{ - bup_autosave = value ? 1 : 0; - return 1; -} - -int config_set_button(ConfigButtonID id, uint32_t value) -{ - PRECOND(id >= CONFIG_BUTTON_A && id <= CONFIG_BUTTON_Z, return 0); - button[id] = value; - return 1; -} - -int config_set_module_sh2(int value) -{ - module_sh2 = value; - return 1; -} - -int config_set_module_video(int value) -{ - module_video = value; - return 1; -} - -int config_set_cache_textures(int value) -{ - cache_textures = value ? 1 : 0; - return 1; -} - -int config_set_smooth_textures(int value) -{ - smooth_textures = value ? 1 : 0; - return 1; -} - -int config_set_smooth_hires(int value) -{ - smooth_hires = value ? 1 : 0; - return 1; -} - -int config_set_enable_rotate(int value) -{ - enable_rotate = value ? 1 : 0; - return 1; -} - -int config_set_optimize_rotate(int value) -{ - optimize_rotate = value ? 1 : 0; - return 1; -} - -int config_set_frameskip_auto(int value) -{ - frameskip_auto = value ? 1 : 0; - return 1; -} - -int config_set_frameskip_num(int value) -{ - if (value < 0) { - frameskip_num = 0; - } else if (value > 9) { - frameskip_num = 9; - } else { - frameskip_num = value; - } - return 1; -} - -int config_set_frameskip_interlace(int value) -{ - frameskip_interlace = value ? 1 : 0; - return 1; -} - -int config_set_frameskip_rotate(int value) -{ - frameskip_rotate = value ? 1 : 0; - return 1; -} - -int config_set_show_fps(int value) -{ - show_fps = value ? 1 : 0; - return 1; -} - -int config_set_sh2_optimizations(uint32_t value) -{ - sh2_optimizations = value & SH2_KNOWN_OPTIMIZATIONS; - return 1; -} - -int config_set_deciline_mode(int value) -{ - deciline_mode = value ? 1 : 0; - return 1; -} - -int config_set_audio_sync(int value) -{ - audio_sync = value ? 1 : 0; - return 1; -} - -int config_set_clock_sync(int value) -{ - clock_sync = value ? 1 : 0; - return 1; -} - -int config_set_clock_fixed_time(int value) -{ - clock_fixed_time = value ? 1 : 0; - return 1; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * parse_string: Parse a string-type configuration entry. - * - * [Parameters] - * file: Name of configuration file (for error messages) - * line: Line number in configuration file (for error messages) - * name: Configuration entry name (for error messages) - * text: Configuration value text - * buffer: Buffer into which to store string value - * bufsize: Size of buffer (maximum string length + 1) - * [Return value] - * Nonzero on success, zero on error - */ -static int parse_string(const char *file, int line, const char *name, - const char *text, char *buffer, unsigned int bufsize) -{ - PRECOND(text != NULL, return 0); - PRECOND(buffer != NULL, return 0); - - if (strlen(text) > bufsize - 1) { - fprintf(stderr, "%s:%d: String for `%s' too long (max %d" - " characters)\n", file, line, name, bufsize - 1); - return 0; - } - strcpy(buffer, text); // Safe - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * parse_int: Parse an integer-type configuration entry. - * - * [Parameters] - * file: Name of configuration file (for error messages) - * line: Line number in configuration file (for error messages) - * name: Configuration entry name (for error messages) - * text: Configuration value text - * value_ret: Pointer to variable into which to store integer value - * [Return value] - * Nonzero on success, zero on error - */ -static int parse_int(const char *file, int line, const char *name, - const char *text, int *value_ret) -{ - PRECOND(text != NULL, return 0); - PRECOND(value_ret != NULL, return 0); - - char *s; - int newval = strtol(text, &s, 10); - if (*s) { - fprintf(stderr, "%s:%d: Value for `%s' must be a number\n", - file, line, name); - return 0; - } - *value_ret = newval; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * parse_uint32: Parse a 32-bit unsigned integer configuration entry. - * - * [Parameters] - * file: Name of configuration file (for error messages) - * line: Line number in configuration file (for error messages) - * name: Configuration entry name (for error messages) - * text: Configuration value text - * value_ret: Pointer to variable into which to store integer value - * [Return value] - * Nonzero on success, zero on error - */ -static int parse_uint32(const char *file, int line, const char *name, - const char *text, uint32_t *value_ret) -{ - PRECOND(text != NULL, return 0); - PRECOND(value_ret != NULL, return 0); - - char *s; - uint32_t newval = strtoul(text, &s, 10); - if (*s) { - fprintf(stderr, "%s:%d: Value for `%s' must be a nonnegative number\n", - file, line, name); - return 0; - } - *value_ret = newval; - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/config.h b/yabause/src/psp/config.h deleted file mode 100644 index 9b55bdbe05..0000000000 --- a/yabause/src/psp/config.h +++ /dev/null @@ -1,144 +0,0 @@ -/* src/psp/config.h: Header for configuration data management for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_CONFIG_H -#define PSP_CONFIG_H - -/*************************************************************************/ - -/** - * CONFIG_BUTTON_*: Constants identifying Saturn controller buttons which - * are passed to the config_get_button() and config_set_button() functions. - */ -typedef enum ConfigButtonID_ { - CONFIG_BUTTON_A = 0, - CONFIG_BUTTON_B, - CONFIG_BUTTON_C, - CONFIG_BUTTON_X, - CONFIG_BUTTON_Y, - CONFIG_BUTTON_Z, -} ConfigButtonID; - -/** - * config_load: Load configuration data from the configuration file. - * Invalid data is ignored, and options not specified in the configuration - * file are left unchanged. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void config_load(void); - -/** - * config_save: Save the current configuration to the configuration file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -extern int config_save(void); - -/** - * config_get_*: Retrieve the current value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * [Return value] - * Current value of configuration variable - */ -extern const char *config_get_path_bios(void); -extern const char *config_get_path_cd(void); -extern const char *config_get_path_bup(void); -extern int config_get_start_in_emu(void); -extern int config_get_use_me(void); -extern uint32_t config_get_me_writeback_period(void); -extern uint32_t config_get_me_uncached_boundary(void); -extern int config_get_bup_autosave(void); -extern uint32_t config_get_button(ConfigButtonID id); -extern int config_get_module_sh2(void); -extern int config_get_module_video(void); -extern int config_get_cache_textures(void); -extern int config_get_smooth_textures(void); -extern int config_get_smooth_hires(void); -extern int config_get_enable_rotate(void); -extern int config_get_optimize_rotate(void); -extern int config_get_frameskip_auto(void); -extern int config_get_frameskip_num(void); -extern int config_get_frameskip_interlace(void); -extern int config_get_frameskip_rotate(void); -extern int config_get_show_fps(void); -extern uint32_t config_get_sh2_optimizations(void); -extern int config_get_deciline_mode(void); -extern int config_get_audio_sync(void); -extern int config_get_clock_sync(void); -extern int config_get_clock_fixed_time(void); - -/** - * config_set_*: Set the value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * value: New value for configuration variable - * [Return value] - * Nonzero on success, zero on error - */ -extern int config_set_path_bios(const char *value); -extern int config_set_path_cd(const char *value); -extern int config_set_path_bup(const char *value); -extern int config_set_start_in_emu(int value); -extern int config_set_use_me(int value); -extern int config_set_me_writeback_period(uint32_t value); -extern int config_set_me_uncached_boundary(uint32_t value); -extern int config_set_bup_autosave(int value); -extern int config_set_button(ConfigButtonID id, uint32_t value); -extern int config_set_module_sh2(int value); -extern int config_set_module_video(int value); -extern int config_set_cache_textures(int value); -extern int config_set_smooth_textures(int value); -extern int config_set_smooth_hires(int value); -extern int config_set_enable_rotate(int value); -extern int config_set_optimize_rotate(int value); -extern int config_set_frameskip_auto(int value); -extern int config_set_frameskip_num(int value); -extern int config_set_frameskip_interlace(int value); -extern int config_set_frameskip_rotate(int value); -extern int config_set_show_fps(int value); -extern int config_set_sh2_optimizations(uint32_t value); -extern int config_set_deciline_mode(int value); -extern int config_set_audio_sync(int value); -extern int config_set_clock_sync(int value); -extern int config_set_clock_fixed_time(int value); - -/*************************************************************************/ - -#endif // PSP_CONFIG_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/control.c b/yabause/src/psp/control.c deleted file mode 100644 index 74867344aa..0000000000 --- a/yabause/src/psp/control.c +++ /dev/null @@ -1,139 +0,0 @@ -/* src/psp/control.c: PSP controller input management routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "control.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Current bitmask of buttons pressed */ -static uint32_t buttons; - -/* Previous value of "buttons" */ -static uint32_t last_buttons; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * control_init: Initialize the controller input management code. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int control_init(void) -{ - sceCtrlSetSamplingCycle(0); - sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); - buttons = last_buttons = 0; - - return 1; -} - -/*************************************************************************/ - -/** - * control_update: Update the current controller status. - * - * [Parameters] - * None - * [Return value] - * None - */ -void control_update(void) -{ - SceCtrlData pad_data; - sceCtrlPeekBufferPositive(&pad_data, 1); - - last_buttons = buttons; - buttons = pad_data.Buttons; - - /* If the directional pad isn't being used, check the analog pad instead */ - if (!(buttons & 0x00F0)) { - if (pad_data.Lx < 32) { - buttons |= PSP_CTRL_LEFT; - } else if (pad_data.Lx >= 224) { - buttons |= PSP_CTRL_RIGHT; - } - if (pad_data.Ly < 32) { - buttons |= PSP_CTRL_UP; - } else if (pad_data.Ly >= 224) { - buttons |= PSP_CTRL_DOWN; - } - } - - /* The OS doesn't seem to reset the screensaver timeout when the - * analog pad is moved, so take care of that ourselves */ - if (pad_data.Lx < 32 || pad_data.Lx >= 224 - || pad_data.Ly < 32 || pad_data.Ly >= 224 - ) { - scePowerTick(0); - } -} - -/*************************************************************************/ - -/** - * control_state: Return the current controller state. - * - * [Parameters] - * None - * [Return value] - * Current controller state (PSP_CTRL_* bitmask of buttons held down) - */ -uint32_t control_state(void) -{ - return buttons; -} - -/*-----------------------------------------------------------------------*/ - -/** - * control_new_buttons: Return any buttons newly pressed in the last call - * to control_update(). - * - * [Parameters] - * None - * [Return value] - * Newly pressed buttons (PSP_CTRL_* bitmask) - */ -uint32_t control_new_buttons(void) -{ - return buttons & ~last_buttons; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/control.h b/yabause/src/psp/control.h deleted file mode 100644 index e99e84d731..0000000000 --- a/yabause/src/psp/control.h +++ /dev/null @@ -1,79 +0,0 @@ -/* src/psp/control.c: PSP controller input management routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_CONTROL_H -#define PSP_CONTROL_H - -/*************************************************************************/ - -/** - * control_init: Initialize the controller input management code. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -extern int control_init(void); - -/** - * control_update: Update the current controller status. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void control_update(void); - -/** - * control_state: Return the current controller status. - * - * [Parameters] - * None - * [Return value] - * Current controller status (PSP_CTRL_* bitmask of buttons held down) - */ -extern uint32_t control_state(void); - -/** - * control_new_buttons: Return any buttons newly pressed in the last call - * to control_update(). - * - * [Parameters] - * None - * [Return value] - * Newly pressed buttons (PSP_CTRL_* bitmask) - */ -extern uint32_t control_new_buttons(void); - -/*************************************************************************/ - -#endif // PSP_CONTROL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/display.c b/yabause/src/psp/display.c deleted file mode 100644 index 701461a555..0000000000 --- a/yabause/src/psp/display.c +++ /dev/null @@ -1,603 +0,0 @@ -/* src/psp/display.c: PSP display management functions - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "display.h" -#include "gu.h" -#include "sys.h" - -/*************************************************************************/ - -/* Effective display size */ -static unsigned int display_width, display_height; - -/* Display mode (pixel format) and bits per pixel */ -static uint8_t display_mode; -static uint8_t display_bpp; - -/* Currently displayed (front) buffer index */ -static uint8_t displayed_surface; - -/* Work (back) buffer index */ -static uint8_t work_surface; - -/* Pointers into VRAM */ -static void *surfaces[2]; // Display buffers -static uint8_t *vram_spare_ptr; // Spare VRAM (above display buffers) -static uint8_t *vram_next_alloc; // Next spare address to allocate -static uint8_t *vram_top; // Top of VRAM - -/* Display list */ -/* Size note: A single VDP2 background layer, if at resolution 704x512, - * can take up to 500k of display list memory to render. */ -static uint8_t __attribute__((aligned(64))) display_list[3*1024*1024]; - -/* Semaphore flag to indicate whether there is a buffer swap pending; while - * true, the main thread must not access any other variables */ -static int swap_pending; - -/* System clock after the sceDisplayWaitVblankStart() starting the last frame*/ -static uint32_t last_frame_start; - -/* Number of frames between the last two calls to sceDisplayWaitVblankStart()*/ -static unsigned int last_frame_length; - -/*************************************************************************/ - -/* Local routine declarations */ - -__attribute__((noreturn)) - static int buffer_swap_thread(SceSize args, void *argp); - -static void do_buffer_swap(void); - -/*************************************************************************/ -/*************************************************************************/ - -/** - * display_init: Initialize the PSP display. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int display_init(void) -{ - /* Have we already initialized? */ - static int initted = 0; - if (initted) { - return 1; - } - - /* Clear out VRAM */ - memset(sceGeEdramGetAddr(), 0, sceGeEdramGetSize()); - sceKernelDcacheWritebackInvalidateAll(); - - /* Set display mode */ - int32_t res = sceDisplaySetMode(0, DISPLAY_WIDTH, DISPLAY_HEIGHT); - if (res < 0) { - DMSG("sceDisplaySetMode() failed: %s", psp_strerror(res)); - return 0; - } - display_width = DISPLAY_WIDTH; - display_height = DISPLAY_HEIGHT; - display_mode = PSP_DISPLAY_PIXEL_FORMAT_8888; - display_bpp = 32; - - /* Initialize VRAM pointers */ - uint8_t *vram_addr = sceGeEdramGetAddr(); - uint32_t vram_size = sceGeEdramGetSize(); - const uint32_t frame_size = - DISPLAY_STRIDE * DISPLAY_HEIGHT * (display_bpp/8); - int i; - for (i = 0; i < lenof(surfaces); i++) { - surfaces[i] = vram_addr + i*frame_size; - } - vram_spare_ptr = (uint8_t *)(vram_addr + lenof(surfaces)*frame_size); - vram_next_alloc = vram_spare_ptr; - vram_top = vram_addr + vram_size; - displayed_surface = 0; - work_surface = 1; - swap_pending = 0; - - /* Set the currently-displayed buffer */ - sceDisplaySetFrameBuf(surfaces[displayed_surface], DISPLAY_STRIDE, - display_mode, PSP_DISPLAY_SETBUF_IMMEDIATE); - - /* Set up the GU library */ - guInit(); - guStart(GU_DIRECT, display_list); - guDispBuffer(DISPLAY_WIDTH, DISPLAY_HEIGHT, - surfaces[displayed_surface], DISPLAY_STRIDE); - guFinish(); - guSync(0, 0); - - /* Success */ - initted = 1; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_set_size: Set the effective display size. The display will - * be centered on the PSP's screen. - * - * This routine should not be called while drawing a frame (i.e. between - * display_begin_frame() and display_end_frame()). - * - * [Parameters] - * width: Effective display width (pixels) - * height: Effective display height (pixels) - * [Return value] - * None - */ -void display_set_size(int width, int height) -{ - display_width = width; - display_height = height; -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_disp_buffer: Return a pointer to the current displayed (front) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -uint32_t *display_disp_buffer(void) -{ - return (uint32_t *)surfaces[displayed_surface] - + ((DISPLAY_HEIGHT - display_height) / 2) * DISPLAY_STRIDE - + ((DISPLAY_WIDTH - display_width ) / 2); -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_work_buffer: Return a pointer to the current work (back) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -uint32_t *display_work_buffer(void) -{ - return (uint32_t *)surfaces[work_surface] - + ((DISPLAY_HEIGHT - display_height) / 2) * DISPLAY_STRIDE - + ((DISPLAY_WIDTH - display_width ) / 2); -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_spare_vram: Return a pointer to the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Pointer to the VRAM spare area - */ -void *display_spare_vram(void) -{ - return vram_spare_ptr; -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_spare_vram_size: Return the size of the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Size of the VRAM spare area, in bytes - */ -uint32_t display_spare_vram_size(void) -{ - return vram_top - vram_spare_ptr; -} - -/*************************************************************************/ - -/** - * display_alloc_vram: Allocate memory from the spare VRAM area, aligned - * to a multiple of 64 bytes. All allocated VRAM will be automatically - * freed at the next call to display_begin_frame(). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -void *display_alloc_vram(uint32_t size) -{ - if (vram_next_alloc + size > vram_top) { - return NULL; - } - void *ptr = vram_next_alloc; - vram_next_alloc += size; - if ((uintptr_t)vram_next_alloc & 0x3F) { // Make sure it stays aligned - vram_next_alloc += 0x40 - ((uintptr_t)vram_next_alloc & 0x3F); - } - return ptr; -} - -/*************************************************************************/ - -/** - * display_begin_frame: Begin processing for a frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -void display_begin_frame(void) -{ - sceKernelDelayThread(0); // Seems to be needed for the buffer swap to work - while (swap_pending) { - sceKernelDelayThread(100); // 0.1ms - } - - vram_next_alloc = vram_spare_ptr; - - guStart(GU_DIRECT, display_list); - - /* We don't use a depth buffer, so disable depth buffer writing */ - guDepthMask(GU_TRUE); - - /* Clear the work surface--make sure to use the base pointer here, not - * the effective pointer, lest we stomp on spare VRAM while using the - * second buffer */ - guDrawBuffer(GU_PSM_8888, surfaces[work_surface], DISPLAY_STRIDE); - guDisable(GU_SCISSOR_TEST); - guClear(GU_COLOR_BUFFER_BIT); - guCommit(); - - /* Register the effective work surface pointer */ - guDrawBuffer(GU_PSM_8888, display_work_buffer(), DISPLAY_STRIDE); - - /* Set up drawing area parameters (we set the depth parameters too, - * just in case a custom drawing routine wants to use 3D coordinates) */ - guViewport(2048, 2048, display_width, display_height); - guOffset(2048 - display_width/2, 2048 - display_height/2); - guScissor(0, 0, display_width, display_height); - guEnable(GU_SCISSOR_TEST); - guDepthRange(65535, 0); - guDisable(GU_DEPTH_TEST); - -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_end_frame: End processing for the current frame, then swap the - * displayed buffer and work buffer. The current frame will not actually - * be shown until the next vertical blank. - * - * [Parameters] - * None - * [Return value] - * None - */ -void display_end_frame(void) -{ - guFinish(); - swap_pending = 1; - /* Give the new thread a slightly higher priority than us, or else it - * won't actually get a chance to run. */ - if (sys_start_thread("YabauseBufferSwapThread", buffer_swap_thread, - sceKernelGetThreadCurrentPriority() - 1, - 0x1000, 0, NULL) < 0) { - DMSG("Failed to start buffer swap thread"); - swap_pending = 0; - do_buffer_swap(); // Do it ourselves - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_last_frame_length: Returns the length of time the last frame - * was displayed, in hardware frame (1/59.94sec) units. Only valid between - * display_begin_frame() and display_end_frame(). - * - * [Parameters] - * None - * [Return value] - * Length of time the last frame was displayed - */ -unsigned int display_last_frame_length(void) -{ - return last_frame_length; -} - -/*************************************************************************/ - -/** - * display_blit: Draw an image to the display. The image must be in - * native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * [Return value] - * None - */ -void display_blit(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y) -{ -#if 1 // Method 1: DMA the data into VRAM (fastest) - - /* Pointer must be 64-byte aligned, so if it's not, adjust the pointer - * and add an offset to the X coordinate */ - const unsigned int xofs = ((uintptr_t)src & 0x3F) / 4; - const uint32_t * const src_aligned = (const uint32_t *)src - xofs; - - guCopyImage(GU_PSM_8888, xofs, 0, src_width, src_height, src_stride, - src_aligned, dest_x, dest_y, DISPLAY_STRIDE, - display_work_buffer()); - -#elif 1 // Method 2: Draw as a texture (slower, but more general) - - /* Pointer must be 64-byte aligned, so if it's not, adjust the pointer - * and add an offset to the X coordinate */ - const unsigned int xofs = ((uintptr_t)src & 0x3F) / 4; - const uint32_t * const src_aligned = (const uint32_t *)src - xofs; - - /* Set up the vertex array (it's faster to draw multiple vertical - * strips than try to blit the whole thing at once) */ - const int nstrips = (src_width + 15) / 16; - struct { - uint16_t u, v; - int16_t x, y, z; - } *vertices = guGetMemory(sizeof(*vertices) * (2*nstrips)); - /* Note that guGetMemory() never fails, so we don't check for failure */ - int i, x; - for (i = 0, x = 0; x < src_width; i += 2, x += 16) { - int thiswidth = 16; - if (x+16 > src_width) { - thiswidth = src_width - x; - } - vertices[i+0].u = xofs + x; - vertices[i+0].v = 0; - vertices[i+0].x = dest_x + x; - vertices[i+0].y = dest_y; - vertices[i+0].z = 0; - vertices[i+1].u = xofs + x + thiswidth; - vertices[i+1].v = src_height; - vertices[i+1].x = dest_x + x + thiswidth; - vertices[i+1].y = dest_y + src_height; - vertices[i+1].z = 0; - } - - /* Draw the array */ - guEnable(GU_TEXTURE_2D); - guTexFilter(GU_NEAREST, GU_NEAREST); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); - /* Always use a 512x512 texture size (the GE can only handle sizes that - * are powers of 2, and the size itself doesn't seem to affect speed) */ - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexImage(0, 512, 512, src_stride, src_aligned); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2*nstrips, NULL, vertices); - guDisable(GU_TEXTURE_2D); - -#else // Method 3: Copy using the CPU (slowest) - - const uint32_t *src32 = (const uint32_t *)src; - uint32_t *dest32 = display_work_buffer() + dest_y*DISPLAY_STRIDE + dest_x; - int y; - for (y = 0; y < src_height; - y++, src32 += src_stride, dest32 += DISPLAY_STRIDE - ) { - memcpy(dest32, src32, src_width*4); - } - -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_blit_scaled: Scale and draw an image to the display. The image - * must be in native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * dest_width: Width of the displayed image, in pixels - * dest_height: Height of the displayed image, in pixels - * [Return value] - * None - */ -void display_blit_scaled(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y, - int dest_width, int dest_height) -{ - /* Pointer must be 64-byte aligned, so if it's not, adjust the pointer - * and add an offset to the X coordinate */ - const unsigned int xofs = ((uintptr_t)src & 0x3F) / 4; - const uint32_t * const src_aligned = (const uint32_t *)src - xofs; - - /* Set up the vertex array (4 vertices for a 2-triangle strip) */ - struct { - uint16_t u, v; - int16_t x, y, z; - } *vertices = guGetMemory(sizeof(*vertices) * 4); - vertices[0].u = xofs; - vertices[0].v = 0; - vertices[0].x = dest_x; - vertices[0].y = dest_y; - vertices[0].z = 0; - vertices[1].u = xofs; - vertices[1].v = src_height; - vertices[1].x = dest_x; - vertices[1].y = dest_y + dest_height; - vertices[1].z = 0; - vertices[2].u = xofs + src_width; - vertices[2].v = 0; - vertices[2].x = dest_x + dest_width; - vertices[2].y = dest_y; - vertices[2].z = 0; - vertices[3].u = xofs + src_width; - vertices[3].v = src_height; - vertices[3].x = dest_x + dest_width; - vertices[3].y = dest_y + dest_height; - vertices[3].z = 0; - - /* Draw the array */ - guEnable(GU_TEXTURE_2D); - guTexFilter(GU_LINEAR, GU_LINEAR); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexImage(0, 512, 512, src_stride, src_aligned); - guDrawArray(GU_TRIANGLE_STRIP, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 4, NULL, vertices); - guDisable(GU_TEXTURE_2D); -} - -/*************************************************************************/ - -/** - * display_fill_box: Draw a filled box with a specified color. - * - * [Parameters] - * x1, y1: Upper-left coordinates of box - * x2, y2: Lower-right coordinates of box - * color: Color to fill with (0xAABBGGRR) - * [Return value] - * None - */ -void display_fill_box(int x1, int y1, int x2, int y2, uint32_t color) -{ - struct { - uint32_t color; - int16_t x, y, z, pad; - } *vertices = guGetMemory(sizeof(*vertices) * 2); - vertices[0].color = color; - vertices[0].x = x1; - vertices[0].y = y1; - vertices[0].z = 0; - vertices[1].color = color; - vertices[1].x = x2 + 1; - vertices[1].y = y2 + 1; - vertices[1].z = 0; - - guDrawArray(GU_SPRITES, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * buffer_swap_thread: Perform a buffer swap and clear the "swap_pending" - * variable to false. Designed to run as a background thread while the - * main emulation proceeds. - * - * [Parameters] - * args, argp: Thread argument size and pointer (unused) - * [Return value] - * Does not return - */ -static int buffer_swap_thread(SceSize args, void *argp) -{ - do_buffer_swap(); - swap_pending = 0; - sceKernelExitDeleteThread(0); -} - -/*----------------------------------*/ - -/** - * do_buffer_swap: Perform a display buffer swap (call guSync(), swap the - * display and work surfaces, wait for the following vertical blank, and - * calculate the length of time between this newly displayed frame and the - * previous one). Called either from the buffer swap thread or (if the - * swap thread fails to start) from the main thread. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void do_buffer_swap(void) -{ - guSync(0, 0); - sceDisplaySetFrameBuf(surfaces[work_surface], DISPLAY_STRIDE, - display_mode, PSP_DISPLAY_SETBUF_NEXTFRAME); - displayed_surface = work_surface; - work_surface = (work_surface + 1) % lenof(surfaces); - sceDisplayWaitVblankStart(); - - /* Update the frame length variables. If this is the first frame - * we've drawn (signaled by last_frame_start == 0), just set a frame - * length of 1 (1/60 sec) since we have nothing to compare it against. */ - const uint32_t now = sceKernelGetSystemTimeLow(); - const uint32_t last_frame_time = now - last_frame_start; - const uint32_t time_unit = (1001000+30)/60; - if (last_frame_start != 0) { - last_frame_length = (last_frame_time + time_unit/2) / time_unit; - } else { - last_frame_length = 1; - } - /* Make sure we don't accidentally signal the next frame as the - * first frame drawn. */ - last_frame_start = (now != 0) ? now : 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/display.h b/yabause/src/psp/display.h deleted file mode 100644 index 7aa113205e..0000000000 --- a/yabause/src/psp/display.h +++ /dev/null @@ -1,213 +0,0 @@ -/* src/psp/display.h: PSP display management header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_DISPLAY_H -#define PSP_DISPLAY_H - -/*************************************************************************/ - -/* Physical screen layout */ -#define DISPLAY_WIDTH 480 -#define DISPLAY_HEIGHT 272 -#define DISPLAY_STRIDE 512 - -/*-----------------------------------------------------------------------*/ - -/** - * display_init: Initialize the PSP display. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -extern int display_init(void); - -/** - * display_set_size: Set the effective display size. The display will - * be centered on the PSP's screen. - * - * This routine should not be called while drawing a frame (i.e. between - * display_begin_frame() and display_end_frame()). - * - * [Parameters] - * width: Effective display width (pixels) - * height: Effective display height (pixels) - * [Return value] - * None - */ -extern void display_set_size(int width, int height); - -/** - * display_disp_buffer: Return a pointer to the current displayed (front) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -extern uint32_t *display_disp_buffer(void); - -/** - * display_work_buffer: Return a pointer to the current work (back) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -extern uint32_t *display_work_buffer(void); - -/** - * display_spare_vram: Return a pointer to the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Pointer to the VRAM spare area - */ -extern void *display_spare_vram(void); - -/** - * display_spare_vram_size: Return the size of the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Size of the VRAM spare area, in bytes - */ -extern uint32_t display_spare_vram_size(void); - -/*----------------------------------*/ - -/** - * display_alloc_vram: Allocate memory from the spare VRAM area, aligned - * to a multiple of 64 bytes. All allocated VRAM will be automatically - * freed at the next call to display_begin_frame(). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -extern void *display_alloc_vram(uint32_t size); - -/*----------------------------------*/ - -/** - * display_begin_frame: Begin processing for a frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void display_begin_frame(void); - -/** - * display_end_frame: End processing for the current frame, then swap the - * displayed buffer and work buffer. The current frame will not actually - * be shown until the next vertical blank. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void display_end_frame(void); - -/** - * display_last_frame_length: Returns the length of time the last frame - * was displayed, in hardware frame (1/59.94sec) units. Only valid between - * display_begin_frame() and display_end_frame(). - * - * [Parameters] - * None - * [Return value] - * Length of time the last frame was displayed - */ -extern unsigned int display_last_frame_length(void); - -/*----------------------------------*/ - -/** - * display_blit: Draw an image to the display. The image must be in - * native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * [Return value] - * None - */ -extern void display_blit(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y); - -/** - * display_blit_scaled: Scale and draw an image to the display. The image - * must be in native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * dest_width: Width of the displayed image, in pixels - * dest_height: Height of the displayed image, in pixels - * [Return value] - * None - */ -extern void display_blit_scaled(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y, - int dest_width, int dest_height); - -/** - * display_fill_box: Draw a filled box with a specified color. - * - * [Parameters] - * x1, y1: Upper-left coordinates of box - * x2, y2: Lower-right coordinates of box - * color: Color to fill with (0xAABBGGRR) - * [Return value] - * None - */ -extern void display_fill_box(int x1, int y1, int x2, int y2, uint32_t color); - -/*************************************************************************/ - -#endif // PSP_DISPLAY_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/filesel.c b/yabause/src/psp/filesel.c deleted file mode 100644 index 6e60710242..0000000000 --- a/yabause/src/psp/filesel.c +++ /dev/null @@ -1,521 +0,0 @@ -/* src/psp/filesel.c: Simple file selector for use with PSP menu - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "display.h" -#include "filesel.h" -#include "font.h" -#include "sys.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* File selector data structure (exported as opaque type FileSelector) */ - -struct FileSelector_ { - char *title; // Window title - - char *dir; // Current directory (note that we don't support - // changing directories at present) - SceUID scandir_thread; // If nonzero, thread ID of directory scan thread; - // if zero, indicates that scan is complete. - /* The file list MUST NOT be accessed by the main thread while - * scandir_thread is nonzero */ - char **file_list; // List of files in the current directory (each - // entry is malloc'd) - int num_files; // Number of files in file_list[]; negative - // indicates an error scanning the directory - - int top_file; // Index of top file shown in window - int selected_file; // Selected file index (negative = cancelled) - int num_lines; // Number of lines visible in file selector window - // (set after first filesel_draw() call) - uint8_t cursor_timer; // Frame counter for cursor flashing - - uint8_t done; // Nonzero when user selects a file or cancels -}; - -/*************************************************************************/ - -/* Display parameters */ - -/* Window size */ -#define WINDOW_WIDTH 360 -#define WINDOW_HEIGHT 208 - -/* Window colors */ -#define BGCOLOR_TITLE 0xFF804060 // Title bar -#define BGCOLOR_LIST 0xFF604040 // File list area -#define BORDER_COLOR_HI 0xFFFFECEC // Border lines (bright) -#define BORDER_COLOR_LO 0xFF000000 // Border lines (shadow) - -/* Cursor parameters */ -#define CURSOR_COLOR 0x80FFECEC -#define CURSOR_PERIOD 60 // frames - -/* Text colors */ -#define TEXTCOLOR_TITLE 0xFFFFECEC -#define TEXTCOLOR_FILE 0xFFFFECEC -#define TEXTCOLOR_DISABLED 0xFF807474 // "Scanning directory...", etc. -#define TEXTCOLOR_ERROR 0xFF5540FF - -/*************************************************************************/ - -/* Local function declarations */ - -static void scandir_thread(SceSize args, void *argp); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * filesel_create: Create a new file selector. - * - * [Parameters] - * title: File selector window title - * dir: Directory to select file from - * [Return value] - * Newly-created file selector, or NULL on error - */ -FileSelector *filesel_create(const char *title, const char *dir) -{ - PRECOND(title != NULL, goto error_return); - PRECOND(dir != NULL, goto error_return); - - FileSelector *filesel = malloc(sizeof(*filesel)); - if (UNLIKELY(!filesel)) { - DMSG("No memory for FileSelector"); - goto error_return; - } - filesel->title = strdup(title); - if (UNLIKELY(!filesel->title)) { - DMSG("No memory for title"); - goto error_free_filesel; - } - filesel->dir = strdup(dir); - if (UNLIKELY(!filesel->dir)) { - DMSG("No memory for current directory"); - goto error_free_title; - } - filesel->scandir_thread = 0; - filesel->file_list = NULL; - filesel->num_files = 0; - filesel->top_file = 0; - filesel->selected_file = 0; - filesel->num_lines = 0; - filesel->cursor_timer = 0; - filesel->done = 0; - - /* We only ever have one file selector open at once, so we just use a - * static thread name */ - int32_t thread = sys_start_thread("YabauseScanDirThread", scandir_thread, - THREADPRI_MAIN+1, 0x1000, - sizeof(filesel), &filesel); - if (thread & 0x80000000) { - DMSG("Failed to start scandir thread: %s", psp_strerror(thread)); - goto error_free_dir; - } - - filesel->scandir_thread = thread; - return filesel; - - error_free_dir: - free(filesel->dir); - error_free_title: - free(filesel->title); - error_free_filesel: - free(filesel); - error_return: - return NULL; -} - -/*************************************************************************/ - -/** - * filesel_process: Process input for a file selector. - * - * [Parameters] - * filesel: File selector - * buttons: Newly-pressed (or repeating) buttons (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -void filesel_process(FileSelector *filesel, uint32_t buttons) -{ - PRECOND(filesel != NULL, return); - - /* If the user wants to cancel, give that top priority */ - if (buttons & PSP_CTRL_CROSS) { - filesel->selected_file = -1; - filesel->done = 1; - return; - } - - /* If the scanning thread is still running, there's nothing to do */ - if (filesel->scandir_thread) { - return; - } - - /* Update the cursor timer (assume we're called once per frame) */ - filesel->cursor_timer = (filesel->cursor_timer + 1) % CURSOR_PERIOD; - - /* If we have a file list, let the user move the cursor around or - * select a file; note that scrolling is handled at drawing time, when - * we know how many lines will fit in the file list display area */ - if (filesel->num_files > 0) { - if (buttons & PSP_CTRL_UP) { - if (filesel->selected_file > 0) { - filesel->selected_file--; - filesel->cursor_timer = 0; - } - } else if (buttons & PSP_CTRL_DOWN) { - if (filesel->selected_file < filesel->num_files - 1) { - filesel->selected_file++; - filesel->cursor_timer = 0; - } - } else if (buttons & PSP_CTRL_LEFT) { - /* Use the number of visible lines calculated in filesel_draw(). - * If we get here on the very first filesel_process() call, - * filesel->num_lines will be zero, so this becomes a no-op. */ - int num_to_scroll = filesel->num_lines; - if (num_to_scroll > filesel->top_file) { - num_to_scroll = filesel->top_file; - } - filesel->top_file -= num_to_scroll; - filesel->selected_file -= num_to_scroll; - filesel->cursor_timer = 0; - } else if (buttons & PSP_CTRL_RIGHT) { - int max_top = filesel->num_files - filesel->num_lines; - if (max_top < 0) { - max_top = 0; - } - int num_to_scroll = filesel->num_lines; - if (num_to_scroll > max_top - filesel->top_file) { - num_to_scroll = max_top - filesel->top_file; - } - filesel->top_file += num_to_scroll; - filesel->selected_file += num_to_scroll; - filesel->cursor_timer = 0; - } else if (buttons & PSP_CTRL_CIRCLE) { - filesel->done = 1; - } - } -} - -/*************************************************************************/ - -/** - * filesel_draw: Draw a file selector. - * - * [Parameters] - * filesel: File selector - * [Return value] - * None - */ -void filesel_draw(FileSelector *filesel) -{ - PRECOND(filesel != NULL, return); - - const int x1 = DISPLAY_WIDTH/2 - WINDOW_WIDTH/2; - const int y1 = DISPLAY_HEIGHT/2 - WINDOW_HEIGHT/2; - const int x2 = x1 + (WINDOW_WIDTH - 1); - const int y2 = y1 + (WINDOW_HEIGHT - 1); - - /* Draw the outside border */ - - display_fill_box(x1, y1, x2-1, y1, BORDER_COLOR_HI); - display_fill_box(x1+1, y1+1, x2, y1+1, BORDER_COLOR_LO); - display_fill_box(x1, y1+1, x1, y2-1, BORDER_COLOR_HI); - display_fill_box(x1+1, y1+2, x1+1, y2, BORDER_COLOR_LO); - display_fill_box(x2-1, y1+1, x2-1, y2-1, BORDER_COLOR_HI); - display_fill_box(x2, y2+2, x2, y2, BORDER_COLOR_LO); - display_fill_box(x1+1, y2-1, x2-2, y2-1, BORDER_COLOR_HI); - display_fill_box(x1, y2, x2-1, y2, BORDER_COLOR_LO); - - /* Draw the title bar */ - - const int title_text_y = y1+4; - const int title_y2 = title_text_y + FONT_HEIGHT + 2; - display_fill_box(x1+1, title_y2, x2-2, title_y2, BORDER_COLOR_HI); - display_fill_box(x1+2, title_y2+1, x2-1, title_y2+1, BORDER_COLOR_LO); - display_fill_box(x1+2, y1+2, x2-2, title_y2-2, BGCOLOR_TITLE); - font_printf((x1+x2)/2, title_text_y, 0, TEXTCOLOR_TITLE, - "%s", filesel->title); - - /* Draw the file list */ - - display_fill_box(x1+2, title_y2+2, x2-2, y2-2, BGCOLOR_LIST); - const int list_x1 = x1 + 4; - const int list_y1 = title_y2 + 4; - const int list_x2 = x2 - 4; - const int list_y2 = y2 - 4; - const int line_height = FONT_HEIGHT + 2; - const int num_lines = ((list_y2+1) - list_y1) / line_height; - filesel->num_lines = num_lines; // Save for reference in filesel_process() - int y = list_y1 + (((list_y2+1)-list_y1) - (num_lines*line_height)) / 2; - if (filesel->scandir_thread) { - font_printf(list_x1, y, -1, TEXTCOLOR_DISABLED, - "(Scanning directory...)"); - } else if (filesel->num_files < 0) { - font_printf(list_x1, y, -1, TEXTCOLOR_ERROR, - "(Error scanning directory!)"); - } else if (filesel->num_files == 0) { - font_printf(list_x1, y, -1, TEXTCOLOR_DISABLED, - "(No files found.)"); - } else { - /* Scroll the list if needed */ - if (filesel->selected_file < filesel->top_file) { - filesel->top_file = filesel->selected_file; - } else if (filesel->selected_file >= filesel->top_file + num_lines) { - filesel->top_file = filesel->selected_file - (num_lines-1); - } - /* List as many files as will fit in the window */ - int i; - for (i = filesel->top_file; - i < filesel->num_files && i < filesel->top_file + num_lines; - i++, y += line_height - ) { - // FIXME: handle overlength filenames in a more general way - const int maxlen = ((list_x2+1) - list_x1) / 6; - if (strlen(filesel->file_list[i]) > maxlen) { - font_printf(list_x1, y, -1, TEXTCOLOR_FILE, - "%.*s...", maxlen-3, filesel->file_list[i]); - } else { - font_printf(list_x1, y, -1, TEXTCOLOR_FILE, - "%s", filesel->file_list[i]); - } - if (filesel->selected_file == i) { - const float cursor_alpha = - (sinf((filesel->cursor_timer / (float)CURSOR_PERIOD) - * (float)M_TWOPI) + 1) / 2; - const uint32_t cursor_alpha_byte = - floorf((CURSOR_COLOR>>24 & 0xFF) * cursor_alpha + 0.5f); - display_fill_box(list_x1-1, y-1, list_x2+1, y+FONT_HEIGHT, - cursor_alpha_byte<<24 - | (CURSOR_COLOR & 0x00FFFFFF)); - } - } - } -} - -/*************************************************************************/ - -/** - * filesel_done: Return whether a file selector's work is done (i.e., - * whether the user has either selected a file or cancelled the selector). - * - * [Parameters] - * filesel: File selector - * [Return value] - * True (nonzero) if any of the following are true: - * - The user selected a file - * - The user cancelled the file selector - * - An error occurred which prevents the file selector's - * processing from continuing normally - * False (zero) if none of the above are true - */ -int filesel_done(FileSelector *filesel) -{ - PRECOND(filesel != NULL, return 1); - - return filesel->done; -} - -/*-----------------------------------------------------------------------*/ - -/** - * filesel_selected_file: Return the name of the file selected by the - * user, if any. - * - * [Parameters] - * filesel: File selector - * [Return value] - * The name of the file selected by the user, or NULL if the user has - * not selected a file (including if the user has cancelled the file - * selector) - */ -const char *filesel_selected_file(FileSelector *filesel) -{ - PRECOND(filesel != NULL, return NULL); - - if (filesel->done && filesel->selected_file >= 0) { - return filesel->file_list[filesel->selected_file]; - } else { - return NULL; - } -} - -/*************************************************************************/ - -/** - * filesel_destroy: Destroy a file selector. Does nothing if filesel==NULL. - * - * [Parameters] - * filesel: File selector to destroy - * [Return value] - * None - */ -void filesel_destroy(FileSelector *filesel) -{ - if (filesel) { - if (filesel->scandir_thread) { - sceKernelTerminateDeleteThread(filesel->scandir_thread); - } - int i; - for (i = 0; i < filesel->num_files; i++) { - free(filesel->file_list[i]); - } - free(filesel->file_list); - free(filesel->dir); - free(filesel->title); - free(filesel); - } -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * scandir_thread: Thread used to scan a directory for files. Updates the - * file_list[] and num_files fields of the passed-in FileSelector structure. - * - * [Parameters] - * args: Parameter size (must be sizeof(FileSelector *)) - * argp: Parameter pointer (must point to a valid FileSelector pointer) - * [Return value] - * Does not return (terminates and deletes thread when finished) - */ -static void scandir_thread(SceSize args, void *argp) -{ - PRECOND(args == sizeof(FileSelector *), goto exit_thread); - PRECOND(argp != NULL, goto exit_thread); - - FileSelector * const filesel = *(FileSelector **)argp; - - - int dirfd = sceIoDopen(filesel->dir); - if (dirfd < 0) { - DMSG("sceIoDopen(%s): %s", filesel->dir, psp_strerror(dirfd)); - goto signal_error; - } - - SceIoDirent dirent; - memset(&dirent, 0, sizeof(dirent)); - int res; - while ((res = sceIoDread(dirfd, &dirent)) > 0) { - - /* Ignore . (current directory) and .. (parent directory) entries */ - if (strcmp(dirent.d_name,".") == 0 || strcmp(dirent.d_name,"..") == 0){ - continue; - } - - /* Ignore all directories, since we don't support changing directory - * (we could subsume the above test into this one, but we leave them - * separate for clarity) */ - char pathbuf[1000]; - if (UNLIKELY(snprintf(pathbuf, sizeof(pathbuf), "%s/%s", filesel->dir, - dirent.d_name) >= sizeof(pathbuf))) { - DMSG("Pathname buffer overflow: %s/%s", filesel->dir, - dirent.d_name); - continue; - } - struct SceIoStat st; - memset(&st, 0, sizeof(st)); - res = sceIoGetstat(pathbuf, &st); - if (UNLIKELY(res < 0)) { - DMSG("sceIoGetstat(%s): %s", pathbuf, psp_strerror(res)); - continue; - } - if (FIO_S_ISDIR(st.st_mode)) { - continue; - } - - /* Make room for the new file in the array */ - char **new_file_list = - realloc(filesel->file_list, - sizeof(*filesel->file_list) * (filesel->num_files + 1)); - if (UNLIKELY(!new_file_list)) { - DMSG("No memory to expand file list to %d files", - filesel->num_files + 1); - goto clear_file_list; - } - filesel->file_list = new_file_list; - char *new_file = strdup(dirent.d_name); - if (UNLIKELY(!new_file)) { - DMSG("No memory to copy filename: %s", dirent.d_name); - goto clear_file_list; - } - - /* Insert the new file into the file list, keeping the list sorted. - * We don't expect to see very many files in a directory, so we - * don't bother with anything more complex than a linear search. */ - int i; - for (i = 0; i < filesel->num_files; i++) { - if (stricmp(new_file, filesel->file_list[i]) < 0) { - break; - } - } - if (i < filesel->num_files) { - memmove(&filesel->file_list[i+1], &filesel->file_list[i], - sizeof(*filesel->file_list) * (filesel->num_files - i)); - } - filesel->file_list[i] = new_file; - filesel->num_files++; - } - - res = sceIoDclose(dirfd); - if (res != 0) { - DMSG("sceIoDclose(%s): %s", filesel->dir, psp_strerror(dirfd)); - /* Not a critical error, so just let it slide */ - } - - filesel->scandir_thread = 0; - goto exit_thread; - - clear_file_list:; - int i; - for (i = 0; i < filesel->num_files; i++) { - free(filesel->file_list[i]); - } - free(filesel->file_list); - filesel->file_list = NULL; - signal_error: - filesel->num_files = -1; - filesel->scandir_thread = 0; - exit_thread: - sceKernelExitDeleteThread(0); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/filesel.h b/yabause/src/psp/filesel.h deleted file mode 100644 index 9175866090..0000000000 --- a/yabause/src/psp/filesel.h +++ /dev/null @@ -1,114 +0,0 @@ -/* src/psp/filesel.h: PSP file selector header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_FILESEL_H -#define PSP_FILESEL_H - -/*************************************************************************/ - -/* Data type of a file selector instance (contents are opaque) */ -typedef struct FileSelector_ FileSelector; - -/*-----------------------------------------------------------------------*/ - -/** - * filesel_create: Create a new file selector. - * - * [Parameters] - * title: File selector window title - * dir: Directory to select file from - * [Return value] - * Newly-created file selector, or NULL on error - */ -extern FileSelector *filesel_create(const char *title, const char *dir); - -/** - * filesel_process: Process input for a file selector. - * - * [Parameters] - * filesel: File selector - * buttons: Newly-pressed (or repeating) buttons (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -extern void filesel_process(FileSelector *filesel, uint32_t buttons); - -/** - * filesel_draw: Draw a file selector. - * - * [Parameters] - * filesel: File selector - * [Return value] - * None - */ -extern void filesel_draw(FileSelector *filesel); - -/** - * filesel_done: Return whether a file selector's work is done (i.e., - * whether the user has either selected a file or cancelled the selector). - * - * [Parameters] - * filesel: File selector - * [Return value] - * True (nonzero) if any of the following are true: - * - The user selected a file - * - The user cancelled the file selector - * - An error occurred which prevents the file selector's - * processing from continuing normally - * False (zero) if none of the above are true - */ -extern int filesel_done(FileSelector *filesel); - -/** - * filesel_selected_file: Return the name of the file selected by the - * user, if any. - * - * [Parameters] - * filesel: File selector - * [Return value] - * The name of the file selected by the user, or NULL if the user has - * not selected a file (including if the user has cancelled the file - * selector) - */ -extern const char *filesel_selected_file(FileSelector *filesel); - -/** - * filesel_destroy: Destroy a file selector. Does nothing if filesel==NULL. - * - * [Parameters] - * filesel: File selector to destroy - * [Return value] - * None - */ -extern void filesel_destroy(FileSelector *filesel); - -/*************************************************************************/ - -#endif // PSP_FILESEL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/font.c b/yabause/src/psp/font.c deleted file mode 100644 index 4bf141f0fd..0000000000 --- a/yabause/src/psp/font.c +++ /dev/null @@ -1,389 +0,0 @@ -/* src/psp/font.c: Simple font used for PSP menu (public-domain 6x13 font - from X.Org) - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "font.h" -#include "gu.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Character width (the font is fixed-width) */ -#define CHAR_WIDTH 6 - -/* First and last characters in font data */ -#define FONTDATA_FIRSTCHAR 32 -#define FONTDATA_LASTCHAR 127 - -/* Characters (not pixels!) in one row of font data */ -#define FONTDATA_STRIDE 32 - -/* Default character to use for out-of-range characters */ -#define FONTDATA_DEFCHAR '?' - -/* Font data definition (1 byte per pixel, 32 6x13 characters per row). - * This wastes 6 bits per pixel, but it's only 7k anyway so no big deal. */ - -static const __attribute__((aligned(64))) uint8_t fontdata[] = { - 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,1,0,0,0,1,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,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,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,1,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,1,0, - 0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,0,1,1, - 1,1,1,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0, - 0,0,0,0,0,0,0,0,1,2,0,0,0,1,2,1,2,0,0,1,0,1,0,0,0,1,1,1,1,0,1,0, - 1,0,1,2,0,1,0,0,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,0,1,2, - 1,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,1,2, - 0,1,0,1,0,0,0,1,1,2,0,0,1,0,2,2,1,0,0,2,2,2,1,2,0,0,0,1,2,0,1,2, - 2,2,2,2,1,0,2,2,1,0,0,2,2,2,1,2,1,0,2,2,1,0,1,0,2,2,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,1,0,0,0,0,1,0,2,2,1,0, - 0,0,0,0,0,0,0,0,1,2,0,0,0,1,2,1,2,0,0,1,2,1,2,0,1,0,1,2,2,2,0,1, - 0,1,0,2,1,0,1,0,0,0,0,0,1,2,0,0,0,1,0,2,0,0,0,0,0,1,0,0,0,1,1,1, - 0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2, - 1,0,2,0,1,0,1,0,1,2,0,0,1,2,0,0,1,2,0,0,0,1,0,2,0,0,1,1,2,0,1,2, - 0,0,0,0,1,2,0,0,0,2,0,0,0,1,0,2,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,0, - 0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,1,2,0,0,1,2, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,2,0,2,0,1,1,1,1,1,0,1,2,1,2,0,0,0,0, - 2,1,2,0,1,2,1,2,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,1,2,0,1,0,1,2, - 1,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0, - 1,2,0,0,1,2,0,2,1,2,0,0,0,2,0,0,1,2,0,0,1,0,2,0,0,1,0,1,2,0,1,2, - 1,1,0,0,1,2,0,0,0,0,0,0,0,1,2,0,1,2,0,0,1,2,1,2,0,0,1,2,0,1,1,1, - 0,0,0,1,1,1,0,0,0,1,0,2,0,0,1,1,1,1,1,0,0,0,0,1,0,0,0,2,0,0,1,2, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,1,2,1,2,2,0,1,1,1,0,0,0,0, - 1,0,2,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,2,1,2, - 0,2,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,2,0, - 1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1,0,2,0,1,1,1,0,0,0,1,2,1,2,0,1,1, - 0,2,1,0,1,1,1,1,0,0,0,0,1,0,2,0,0,1,1,1,0,2,0,1,1,1,1,2,0,0,1,2, - 2,0,0,0,1,2,2,0,1,0,2,0,0,0,0,2,2,2,2,2,0,0,0,0,1,0,0,0,0,1,0,2, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,2,1,0,0,1, - 0,2,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,2, - 0,0,0,2,1,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,1,0,2,0,0, - 1,2,0,0,1,2,0,0,1,2,0,0,0,0,1,0,2,0,0,0,2,2,1,0,1,0,2,1,2,0,0,2, - 2,0,1,2,1,2,2,2,1,0,0,0,1,2,0,0,1,0,2,2,1,0,0,0,2,2,1,2,0,0,0,2, - 0,0,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1,0,2,0, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,1,2,1,2,2,0,0,1,2,1,2,0,1, - 2,1,0,0,1,2,0,1,1,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,0, - 0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0, - 1,2,0,0,1,2,0,0,1,2,0,0,0,1,0,2,0,0,0,0,0,0,1,2,1,1,1,1,1,0,0,0, - 0,0,1,2,1,2,0,0,1,2,0,1,0,2,0,0,1,2,0,0,1,2,0,0,0,0,1,2,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,0,0,0,1,0,2,0,0,0,1,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,2,1,2,0,1,1,1,1,0,2,1,0, - 1,0,1,0,1,2,0,1,2,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,2,0,0,0, - 0,1,0,1,0,2,0,0,1,2,0,0,1,0,2,0,0,0,1,0,0,0,1,2,0,2,2,1,2,2,1,0, - 0,0,1,2,1,2,0,0,1,2,0,1,2,0,0,0,1,2,0,0,1,2,1,0,0,0,1,2,0,0,1,0, - 0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,2,2,2,2,2,0,1,0,2,0,0,0,0,0,2,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,2,1,2,2,0,1,2, - 0,1,0,2,0,1,1,0,1,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,0,0,0,1,1,1,0,0,1,2,0,0,0,0, - 0,0,1,0,2,0,1,1,1,1,1,0,1,1,1,1,1,0,0,1,1,1,0,2,0,0,0,1,2,0,0,1, - 1,1,0,2,0,1,1,1,0,2,0,1,2,0,0,0,0,1,1,1,0,2,0,1,1,1,0,2,0,1,1,1, - 0,0,0,0,1,2,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, - 0,0,2,0,0,0,2,2,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,2,0,0,0,0, - 0,0,0,2,0,0,0,2,2,2,2,2,0,2,2,2,2,2,0,0,2,2,2,0,0,0,0,0,2,0,0,0, - 2,2,2,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,2,2,2,0,0,0,2,2,2,0,0,0,1,2, - 2,0,0,1,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,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,2,0,0,0,2,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,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,0,0,0,0,0,0,0,2, - 0,0,0,0,2,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,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,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,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,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,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,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,1,1,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1, - 1,1,1,0,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,0,0,1,1,1,0,0,0,0,1,1, - 1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,1,1,0,0, - 1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0,1,0, - 0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,1, - 1,0,0,1,2,2,2,0,1,0,0,0,0,0,0,0,2,1,2,0,0,0,1,0,0,0,0,0,0,0,0,0, - 1,0,2,2,1,0,0,1,0,1,0,0,0,1,2,2,1,0,1,0,2,2,1,0,0,1,2,2,1,0,1,2, - 2,2,2,2,1,2,2,2,2,2,1,0,2,2,1,0,1,2,0,0,1,2,0,0,1,2,2,0,0,0,0,1, - 2,2,1,2,0,0,1,2,1,2,0,0,0,0,1,2,0,0,1,2,1,1,0,0,1,2,1,0,2,2,1,0, - 1,2,2,2,1,0,1,0,2,2,1,0,1,2,2,2,1,0,1,0,2,2,1,0,0,2,1,2,2,2,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,2,2,2, - 1,2,0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,1,2,0,0,1,0,1,0,0,0,0,0,0,0,0, - 1,2,0,0,1,2,1,0,2,0,1,0,0,1,2,0,1,2,1,2,0,0,0,2,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,0,1,0,2,1,2,0,0,0,0,1,1,0,1,1,2,1,1,2,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,0,2,0,0,1,2,0,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,1,0,1,0,2,0,1,0,1,0,2,0,0,0,1, - 0,2,0,1,2,0,0,0,0,1,0,0,0,0,0,0,0,1,2,0,1,0,2,0,1,0,0,0,0,0,0,0, - 1,2,0,1,1,2,1,2,0,0,1,2,0,1,2,0,1,2,1,2,0,0,0,0,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,2,0,1,2,0,0,0,0,1,2,1,0,1,2,1,2,1,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,0,0,0,0,1,2,0,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,1,2,1,2,0,0,1,2,1,2,0,0,0,0,1, - 2,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,2,0,0,0,2,0,0,0,0,0,0, - 1,2,1,0,1,2,1,2,0,0,1,2,0,1,1,1,0,2,1,2,0,0,0,0,0,1,2,0,1,2,1,1, - 1,1,0,0,1,1,1,1,0,0,1,2,0,0,0,0,1,1,1,1,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,1,0,2,0,0,1,2,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2, - 1,1,1,1,0,2,1,2,0,0,1,2,1,1,1,1,0,2,0,1,1,1,0,0,0,0,1,2,0,0,1,2, - 0,0,1,2,0,1,0,1,0,2,1,2,1,0,1,2,0,0,1,0,2,0,0,0,1,0,2,0,0,0,1,0, - 2,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,1,2,1,2,1,1,1,1,1,2,0,1,2,2,1,0,1,2,0,0,0,0,0,1,2,0,1,2,1,2, - 2,2,2,0,1,2,2,2,2,0,1,2,0,1,1,0,1,2,2,2,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,0,0,1,2,0,0,0,0,1,2,0,2,1,2,1,2,0,1,1,2,1,2,0,0,1,2, - 1,2,2,2,2,0,1,2,0,0,1,2,1,2,1,2,2,0,0,0,2,2,1,0,0,0,1,2,0,0,1,2, - 0,0,1,2,0,1,2,1,2,0,1,2,1,2,1,2,0,1,0,1,0,0,0,0,1,2,0,0,0,1,0,2, - 0,0,0,1,2,0,0,0,0,0,0,1,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,1,1,0,2,1,2,2,2,1,2,0,1,2,0,1,2,1,2,0,0,0,0,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,0,1,0,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,1,1,2,1,2,0,0,1,2, - 1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,1,0,0,0,0,0,0,1,2,0,0,1,2,0,0,1,2, - 0,0,1,2,0,1,2,1,2,0,1,2,1,2,1,2,0,1,2,1,2,0,0,0,1,2,0,0,0,1,2,0, - 0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,0,2,2,0,1,2,0,0,1,2,0,1,2,0,1,2,1,2,0,0,1,0,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,2,0,0,1,0,0,1, - 2,0,1,2,0,0,1,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2, - 1,2,0,0,0,0,1,2,1,0,1,2,1,2,0,0,1,0,1,0,0,0,1,2,0,0,1,2,0,0,1,2, - 0,0,1,2,0,0,1,0,2,0,1,2,1,2,1,2,1,0,2,0,1,0,0,0,1,2,0,0,1,0,2,0, - 0,0,0,1,2,0,0,0,0,0,0,0,1,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,1,1,1,0,1,2,0,0,1,2,1,1,1,1,0,2,0,1,1,1,0,2,1,1,1,1,0,2,1,1, - 1,1,1,0,1,2,0,0,0,0,0,1,1,1,0,2,1,2,0,0,1,2,0,1,1,1,0,0,0,1,1,0, - 2,0,1,2,0,0,1,2,1,1,1,1,1,0,1,2,0,0,1,2,1,2,0,0,1,2,0,1,1,1,0,2, - 1,2,0,0,0,0,0,1,1,1,0,2,1,2,0,0,1,2,0,1,1,1,0,2,0,0,1,2,0,0,0,1, - 1,1,0,2,0,0,1,2,0,0,0,1,0,1,0,2,1,2,0,0,1,2,0,0,1,2,0,0,1,1,1,1, - 1,0,0,1,2,0,0,0,0,0,0,0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,2,2,2,2,0,2,0,0,0,2,0,2,2,2,2,0,0,0,2,2,2,0,0,2,2,2,2,0,0,2, - 2,2,2,2,0,2,0,0,0,0,0,0,2,2,2,0,0,2,0,0,0,2,0,0,2,2,2,0,0,0,2,2, - 0,0,0,2,0,0,0,2,0,2,2,2,2,2,0,2,0,0,0,2,0,2,0,0,0,2,0,0,2,2,2,0, - 0,2,0,0,0,0,0,0,2,2,1,0,0,2,0,0,0,2,0,0,2,2,2,0,0,0,0,2,0,0,0,0, - 2,2,2,0,0,0,0,2,0,0,0,0,2,0,2,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,2,2, - 2,2,0,1,1,1,0,0,0,0,0,0,0,2,0,1,1,1,2,0,0,0,0,0,0,0,1,1,1,1,1,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,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,2,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,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,2, - 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, - 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, - 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, - 0,0,1,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,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,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,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,1,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,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,1,0,2,2,0,0,1,0,0,0,0,2,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0, - 0,0,0,0,0,1,0,2,1,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,1,2,0,0,0,0,0,0,1,2,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,1,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,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,0,1,0,1,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0, - 0,0,0,0,0,1,2,0,0,2,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0, - 2,0,1,2,0,0,0,0,0,0,1,2,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,1,2,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,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,0,1,0,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,2,0,1, - 1,1,0,0,0,1,2,0,0,0,0,1,1,1,0,0,1,2,1,1,0,0,0,1,1,0,0,0,0,0,1,1, - 0,0,1,2,0,1,0,0,0,0,1,2,0,0,1,1,0,1,0,0,1,0,1,1,0,0,0,1,1,1,0,0, - 1,1,1,1,0,0,0,1,1,1,1,0,1,0,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,1, - 1,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,2,0,0,2,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,2,2,1,0,1,2,2,2,1,0,1,0,2,2,1,0,1,0,2,2,1,2,1,0, - 2,2,1,0,1,1,1,1,0,0,1,0,2,2,1,0,1,1,0,2,1,0,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,2,0,0,0,1,2,0,0,1,2,1,0,1,0,1,1,0,2,1,0,1,0,2,2,1,0, - 1,2,2,2,1,0,1,0,2,2,1,2,1,1,0,2,1,0,1,0,2,2,1,0,0,1,2,2,2,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,1,0,1,0,2,1,2,0,0,1,2,0,2,2,1, - 2,2,1,1,0,2,0,0,0,0,1,2,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,1,1,2,1,2,0,0,1,2,1,2,0,0,0,2,1,2,0,0,1,2,1,1, - 1,1,1,2,0,1,2,2,2,0,1,2,0,0,1,2,1,2,2,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,1,0,2,0,0,0,0,1,2,0,0,1,2,1,2,1,2,1,2,2,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,2,0,0,2,0,1,1,0,0,2,0,1,2,0,0,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,1,0,1,2,0,0,1,0,2,0,1,2,0,0,1,2,0,0,1,0, - 2,0,0,2,1,0,0,0,0,0,1,2,0,0,0,0,1,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,2,2,1,2,1,2,0,0,1,2,1,2,0,0,0,0,1,2,0,0,1,2,1,2, - 2,2,2,2,0,1,2,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,0,0,0,0,1,2,0,0,1,2,1,2,1,2,1,2,0,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,0,0,0,0,2,1,0,0,0,1,2,0,0,0,1,2, - 0,0,1,2,0,1,0,1,0,2,1,2,1,2,1,2,0,0,1,2,0,0,1,2,0,1,1,2,0,1,0,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,2,0,1,1,2,1,2,0,0,1,2,1,2,0,0,1,0,1,2,0,0,1,2,1,2, - 0,0,1,0,0,1,2,0,0,0,0,1,1,1,1,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,0,1,0,0,0,0,1,2,0,0,1,2,1,2,1,2,1,2,0,0,1,2,1,2,0,0,1,2, - 1,1,1,1,0,2,0,1,1,1,1,2,1,2,0,0,0,0,1,0,0,0,1,0,0,1,2,0,1,0,1,2, - 0,1,1,2,0,1,2,1,2,0,1,2,1,2,1,2,0,1,0,1,0,0,0,1,1,0,1,2,1,0,2,0, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,0,1,2,1,1,1,1,0,2,0,1,1,1,0,2,0,1,1,1,1,2,0,1, - 1,1,0,2,0,1,2,0,0,0,0,0,2,2,1,2,1,2,0,0,1,2,0,1,1,1,0,0,1,0,0,1, - 2,0,1,2,0,0,1,0,0,1,1,1,0,0,1,2,0,2,1,2,1,2,0,0,1,2,0,1,1,1,0,2, - 1,2,2,2,2,0,0,0,2,2,1,2,1,2,0,0,0,0,0,1,1,1,0,2,0,0,1,1,0,2,0,1, - 1,0,1,2,0,0,1,0,2,0,0,1,0,1,0,2,1,0,2,0,1,0,0,0,2,2,1,2,1,1,1,1, - 1,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,2,2,0,2,0,2,2,2,2,0,0,0,2,2,2,0,0,0,2,2,2,2,0,0, - 2,2,2,0,0,0,2,0,0,0,1,0,0,0,1,2,0,2,0,0,0,2,0,0,2,2,2,0,1,2,0,1, - 2,0,0,2,0,0,0,2,0,0,2,2,2,0,0,2,0,0,0,2,0,2,0,0,0,2,0,0,2,2,2,0, - 1,2,0,0,0,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,2,2,2,0,0,0,0,2,2,0,0,0, - 2,2,0,2,0,0,0,2,0,0,0,0,2,0,2,0,0,2,0,0,0,2,1,0,0,0,1,2,0,2,2,2, - 2,2,0,0,0,1,1,0,0,0,0,2,0,0,1,1,0,2,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,1,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, - 2,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, - 1,2,0,0,0,0,0,0,0,0,1,2,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,1,1,1,0,2,0,0,0,0, - 0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,2,2,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,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2, - 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,2,0,0,0,0,0,0,0,0,0,2,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,2,2,2,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, -}; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * font_printf: Draw text to the screen at the given position and with the - * given color. The string can contain printf()-style format specifiers. - * - * It is assumed that a display list has been started with guStart() - * before calling this function. - * - * [Parameters] - * x, y: Upper-left coordinates of first character - * align: Horizontal alignment (<0: left, 0: center, >0: right) - * color: Text color (0xAABBGGRR) - * format: Format string for text - * ...: Arguments for format string - * [Return value] - * X coordinate immediately following the last character printed - */ -int font_printf(int x, int y, int align, uint32_t color, - const char *format, ...) -{ - PRECOND(format != NULL, return x); - - /* Generate the text string to output */ - char buf[1000]; // Plenty long enough even if we start offscreen - va_list args; - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - const int nchars = strlen(buf); - - /* Adjust the starting X coordinate based on the alignment */ - if (align == 0) { - x -= (nchars * CHAR_WIDTH + 1) / 2; - } else if (align > 0) { - x -= nchars * CHAR_WIDTH; - } - - /* Generate vertices for each character of the string */ - struct { - uint16_t u, v; - int16_t x, y, z; - } *vertices = guGetMemory(sizeof(*vertices) * (2*nchars)); - int i; - for (i = 0; i < nchars; i++, x += CHAR_WIDTH) { - uint8_t ch = buf[i]; - if (ch < FONTDATA_FIRSTCHAR || ch > FONTDATA_LASTCHAR) { - ch = FONTDATA_DEFCHAR; - } - const unsigned int index = ch - FONTDATA_FIRSTCHAR; - vertices[i*2+0].u = (index % FONTDATA_STRIDE) * CHAR_WIDTH; - vertices[i*2+0].v = (index / FONTDATA_STRIDE) * FONT_HEIGHT; - vertices[i*2+0].x = x; - vertices[i*2+0].y = y; - vertices[i*2+0].z = 0; - vertices[i*2+1].u = (index % FONTDATA_STRIDE + 1) * CHAR_WIDTH; - vertices[i*2+1].v = (index / FONTDATA_STRIDE + 1) * FONT_HEIGHT; - vertices[i*2+1].x = x + CHAR_WIDTH; - vertices[i*2+1].y = y + FONT_HEIGHT; - vertices[i*2+1].z = 0; - } - sceKernelDcacheWritebackInvalidateRange(vertices, - sizeof(*vertices) * (2*nchars)); - - /* Set up drawing parameters and draw the string. Unfortunately, color - * lookup tables have to be 64-byte aligned, so we can potentially - * waste a lot of memory here for just 3 color table entries... */ - uint32_t *clut = guGetMemory(3*4 + 60); - clut = (uint32_t *)(((uintptr_t)clut + 63) & -64); - clut[0] = 0x00000000; - clut[1] = color; - clut[2] = color & 0xFF000000; // Shadow pixels - guClutMode(GU_PSM_8888, 0, 0xFF, 0); - guClutLoad(8/8, clut); // We only use 3 of the 8 colors, but we have to - // send in a whole block - guEnable(GU_TEXTURE_2D); - guTexFlush(); - guTexMode(GU_PSM_T8, 0, 0, 0); - guTexImage(0, 512, 512, (FONTDATA_STRIDE * CHAR_WIDTH), fontdata); - guTexFilter(GU_NEAREST, GU_NEAREST); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - guAmbientColor(0xFFFFFFFF); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2*nchars, NULL, vertices); - guDisable(GU_TEXTURE_2D); - - /* Return the next X coordinate for potential further drawing */ - return x; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/font.h b/yabause/src/psp/font.h deleted file mode 100644 index 217132f9d0..0000000000 --- a/yabause/src/psp/font.h +++ /dev/null @@ -1,64 +0,0 @@ -/* src/psp/font.h: Header for PSP menu font - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_FONT_H -#define PSP_FONT_H - -/*************************************************************************/ - -/* Height of the font, in pixels */ - -#define FONT_HEIGHT 13 - -/*-----------------------------------------------------------------------*/ - -/** - * font_printf: Draw text to the screen at the given position and with the - * given color. The string can contain printf()-style format specifiers. - * - * It is assumed that a display list has been started with sceGuStart() - * before calling this function. - * - * [Parameters] - * x, y: Upper-left coordinates of first character - * align: Horizontal alignment (<0: left, 0: center, >0: right) - * color: Text color (0xAABBGGRR) - * format: Format string for text - * ...: Arguments for format string - * [Return value] - * X coordinate immediately following the last character printed - */ -extern int font_printf(int x, int y, int align, uint32_t color, - const char *format, ...) - __attribute__((format(printf,5,6))); - -/*************************************************************************/ - -#endif // PSP_FONT_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/gu.c b/yabause/src/psp/gu.c deleted file mode 100644 index 936b15093c..0000000000 --- a/yabause/src/psp/gu.c +++ /dev/null @@ -1,488 +0,0 @@ -/* src/psp/gu.c: sceGu substitute library - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "gu.h" - -/*************************************************************************/ - -#ifndef USE_SCEGU // To the end of the file - -/*************************************************************************/ -/************************** Library-local data ***************************/ -/*************************************************************************/ - -/**** Data exported to inline functions in gu.h ****/ - -/* Current display list pointer */ -uint32_t *gu_list; - -/* Scissor status flag and test region (in GE command form) */ -uint32_t gu_scissorcmd_min, gu_scissorcmd_max; -uint8_t gu_scissor_enabled; - -/* Color/stencil (combined) value and depth value for clear operations */ -uint16_t gu_clear_depth; -uint32_t gu_clear_color_stencil; - -/*----------------------------------*/ - -/**** Data used only within this file ****/ - -/* Nonzero if we're writing a sublist, zero if we're writing the main list */ -static uint8_t gu_is_sublist; - -/* Saved display list pointer (during sublist generation, the main list - * pointer is pushed here) */ -static uint32_t *gu_saved_list; - -/* sceGe ID for current display list */ -static uint32_t gu_list_id; - -/*************************************************************************/ -/*********** Library functions (which aren't defined in gu.h) ************/ -/*************************************************************************/ - -/** - * guInit: Initialize the GU library. - * - * [Parameters] - * None - * [Return value] - * None - */ -void guInit(void) -{ - static const uint32_t ge_init_list[] = { - GECMD_VERTEX_POINTER<<24 | 0x000000, - GECMD_INDEX_POINTER <<24 | 0x000000, - GECMD_ADDRESS_BASE <<24 | 0x000000, - GECMD_VERTEX_FORMAT <<24 | 0x000000, - GECMD_UNKNOWN_13 <<24 | 0x000000, - GECMD_DRAWAREA_LOW <<24 | 0x000000, - GECMD_DRAWAREA_HIGH <<24 | 0x000000, - GECMD_ENA_LIGHTING <<24 | 0x000000, - GECMD_ENA_LIGHT0 <<24 | 0x000000, - GECMD_ENA_LIGHT1 <<24 | 0x000000, - GECMD_ENA_LIGHT2 <<24 | 0x000000, - GECMD_ENA_LIGHT3 <<24 | 0x000000, - GECMD_ENA_ZCLIP <<24 | 0x000000, - GECMD_ENA_FACE_CULL <<24 | 0x000000, - GECMD_ENA_TEXTURE <<24 | 0x000000, - GECMD_ENA_FOG <<24 | 0x000000, - GECMD_ENA_DITHER <<24 | 0x000000, - GECMD_ENA_BLEND <<24 | 0x000000, - GECMD_ENA_ALPHA_TEST<<24 | 0x000000, - GECMD_ENA_DEPTH_TEST<<24 | 0x000000, - GECMD_ENA_STENCIL <<24 | 0x000000, - GECMD_ENA_ANTIALIAS <<24 | 0x000000, - GECMD_ENA_PATCH_CULL<<24 | 0x000000, - GECMD_ENA_COLOR_TEST<<24 | 0x000000, - GECMD_ENA_LOGIC_OP <<24 | 0x000000, - GECMD_BONE_OFFSET <<24 | 0x000000, - GECMD_BONE_UPLOAD <<24 | 0x000000, - GECMD_MORPH_0 <<24 | 0x000000, - GECMD_MORPH_1 <<24 | 0x000000, - GECMD_MORPH_2 <<24 | 0x000000, - GECMD_MORPH_3 <<24 | 0x000000, - GECMD_MORPH_4 <<24 | 0x000000, - GECMD_MORPH_5 <<24 | 0x000000, - GECMD_MORPH_6 <<24 | 0x000000, - GECMD_MORPH_7 <<24 | 0x000000, - GECMD_PATCH_SUBDIV <<24 | 0x000000, - GECMD_PATCH_PRIM <<24 | 0x000000, - GECMD_PATCH_FRONT <<24 | 0x000000, - GECMD_MODEL_START <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x3F8000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x3F8000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x3F8000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_VIEW_START <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x3F8000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x3F8000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x3F8000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_PROJ_START <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_TEXTURE_START <<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x3F8000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x3F8000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x3F8000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_XSCALE <<24 | 0x000000, - GECMD_YSCALE <<24 | 0x000000, - GECMD_ZSCALE <<24 | 0x000000, - GECMD_XPOS <<24 | 0x000000, - GECMD_YPOS <<24 | 0x000000, - GECMD_ZPOS <<24 | 0x000000, - GECMD_USCALE <<24 | 0x3F8000, - GECMD_VSCALE <<24 | 0x3F8000, - GECMD_UOFFSET <<24 | 0x000000, - GECMD_VOFFSET <<24 | 0x000000, - GECMD_XOFFSET <<24 | 0x000000, - GECMD_YOFFSET <<24 | 0x000000, - GECMD_SHADE_MODE <<24 | 0x000000, - GECMD_REV_NORMALS <<24 | 0x000000, - GECMD_COLOR_MATERIAL<<24 | 0x000000, - GECMD_EMISSIVE_COLOR<<24 | 0x000000, - GECMD_AMBIENT_COLOR <<24 | 0x000000, - GECMD_DIFFUSE_COLOR <<24 | 0x000000, - GECMD_SPECULAR_COLOR<<24 | 0x000000, - GECMD_AMBIENT_ALPHA <<24 | 0x000000, - GECMD_SPECULAR_POWER<<24 | 0x000000, - GECMD_LIGHT_AMBCOLOR<<24 | 0x000000, - GECMD_LIGHT_AMBALPHA<<24 | 0x000000, - GECMD_LIGHT_MODEL <<24 | 0x000000, - GECMD_LIGHT0_TYPE <<24 | 0x000000, - GECMD_LIGHT1_TYPE <<24 | 0x000000, - GECMD_LIGHT2_TYPE <<24 | 0x000000, - GECMD_LIGHT3_TYPE <<24 | 0x000000, - GECMD_LIGHT0_XPOS <<24 | 0x000000, - GECMD_LIGHT0_YPOS <<24 | 0x000000, - GECMD_LIGHT0_ZPOS <<24 | 0x000000, - GECMD_LIGHT1_XPOS <<24 | 0x000000, - GECMD_LIGHT1_YPOS <<24 | 0x000000, - GECMD_LIGHT1_ZPOS <<24 | 0x000000, - GECMD_LIGHT2_XPOS <<24 | 0x000000, - GECMD_LIGHT2_YPOS <<24 | 0x000000, - GECMD_LIGHT2_ZPOS <<24 | 0x000000, - GECMD_LIGHT3_XPOS <<24 | 0x000000, - GECMD_LIGHT3_YPOS <<24 | 0x000000, - GECMD_LIGHT3_ZPOS <<24 | 0x000000, - GECMD_LIGHT0_XDIR <<24 | 0x000000, - GECMD_LIGHT0_YDIR <<24 | 0x000000, - GECMD_LIGHT0_ZDIR <<24 | 0x000000, - GECMD_LIGHT1_XDIR <<24 | 0x000000, - GECMD_LIGHT1_YDIR <<24 | 0x000000, - GECMD_LIGHT1_ZDIR <<24 | 0x000000, - GECMD_LIGHT2_XDIR <<24 | 0x000000, - GECMD_LIGHT2_YDIR <<24 | 0x000000, - GECMD_LIGHT2_ZDIR <<24 | 0x000000, - GECMD_LIGHT3_XDIR <<24 | 0x000000, - GECMD_LIGHT3_YDIR <<24 | 0x000000, - GECMD_LIGHT3_ZDIR <<24 | 0x000000, - GECMD_LIGHT0_CATT <<24 | 0x000000, - GECMD_LIGHT0_LATT <<24 | 0x000000, - GECMD_LIGHT0_QATT <<24 | 0x000000, - GECMD_LIGHT1_CATT <<24 | 0x000000, - GECMD_LIGHT1_LATT <<24 | 0x000000, - GECMD_LIGHT1_QATT <<24 | 0x000000, - GECMD_LIGHT2_CATT <<24 | 0x000000, - GECMD_LIGHT2_LATT <<24 | 0x000000, - GECMD_LIGHT2_QATT <<24 | 0x000000, - GECMD_LIGHT3_CATT <<24 | 0x000000, - GECMD_LIGHT3_LATT <<24 | 0x000000, - GECMD_LIGHT3_QATT <<24 | 0x000000, - GECMD_LIGHT0_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT1_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT2_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT3_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT0_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT1_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT2_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT3_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT0_ACOL <<24 | 0x000000, - GECMD_LIGHT0_DCOL <<24 | 0x000000, - GECMD_LIGHT0_SCOL <<24 | 0x000000, - GECMD_LIGHT1_ACOL <<24 | 0x000000, - GECMD_LIGHT1_DCOL <<24 | 0x000000, - GECMD_LIGHT1_SCOL <<24 | 0x000000, - GECMD_LIGHT2_ACOL <<24 | 0x000000, - GECMD_LIGHT2_DCOL <<24 | 0x000000, - GECMD_LIGHT2_SCOL <<24 | 0x000000, - GECMD_LIGHT3_ACOL <<24 | 0x000000, - GECMD_LIGHT3_DCOL <<24 | 0x000000, - GECMD_LIGHT3_SCOL <<24 | 0x000000, - GECMD_FACE_ORDER <<24 | 0x000000, - GECMD_DRAW_ADDRESS <<24 | 0x000000, - GECMD_DRAW_STRIDE <<24 | 0x000000, - GECMD_DEPTH_ADDRESS <<24 | 0x000000, - GECMD_DEPTH_STRIDE <<24 | 0x000000, - GECMD_TEX0_ADDRESS <<24 | 0x000000, - GECMD_TEX1_ADDRESS <<24 | 0x000000, - GECMD_TEX2_ADDRESS <<24 | 0x000000, - GECMD_TEX3_ADDRESS <<24 | 0x000000, - GECMD_TEX4_ADDRESS <<24 | 0x000000, - GECMD_TEX5_ADDRESS <<24 | 0x000000, - GECMD_TEX6_ADDRESS <<24 | 0x000000, - GECMD_TEX7_ADDRESS <<24 | 0x000000, - GECMD_TEX0_STRIDE <<24 | 0x040004, - GECMD_TEX1_STRIDE <<24 | 0x000000, - GECMD_TEX2_STRIDE <<24 | 0x000000, - GECMD_TEX3_STRIDE <<24 | 0x000000, - GECMD_TEX4_STRIDE <<24 | 0x000000, - GECMD_TEX5_STRIDE <<24 | 0x000000, - GECMD_TEX6_STRIDE <<24 | 0x000000, - GECMD_TEX7_STRIDE <<24 | 0x000000, - GECMD_CLUT_ADDRESS_L<<24 | 0x000000, - GECMD_CLUT_ADDRESS_H<<24 | 0x000000, - GECMD_COPY_S_ADDRESS<<24 | 0x000000, - GECMD_COPY_S_STRIDE <<24 | 0x000000, - GECMD_COPY_D_ADDRESS<<24 | 0x000000, - GECMD_COPY_D_STRIDE <<24 | 0x000000, - GECMD_TEX0_SIZE <<24 | 0x000101, - GECMD_TEX1_SIZE <<24 | 0x000000, - GECMD_TEX2_SIZE <<24 | 0x000000, - GECMD_TEX3_SIZE <<24 | 0x000000, - GECMD_TEX4_SIZE <<24 | 0x000000, - GECMD_TEX5_SIZE <<24 | 0x000000, - GECMD_TEX6_SIZE <<24 | 0x000000, - GECMD_TEX7_SIZE <<24 | 0x000000, - GECMD_TEXTURE_MAP <<24 | 0x000000, - GECMD_TEXTURE_ENVMAP<<24 | 0x000000, - GECMD_TEXTURE_MODE <<24 | 0x000000, - GECMD_TEXTURE_PIXFMT<<24 | 0x000000, - GECMD_CLUT_LOAD <<24 | 0x000000, - GECMD_CLUT_MODE <<24 | 0x000000, - GECMD_TEXTURE_FILTER<<24 | 0x000000, - GECMD_TEXTURE_WRAP <<24 | 0x000000, - GECMD_TEXTURE_BIAS <<24 | 0x000000, - GECMD_TEXTURE_FUNC <<24 | 0x000000, - GECMD_TEXTURE_COLOR <<24 | 0x000000, - GECMD_TEXTURE_FLUSH <<24 | 0x000000, - GECMD_COPY_SYNC <<24 | 0x000000, - GECMD_FOG_LIMIT <<24 | 0x000000, - GECMD_FOG_RANGE <<24 | 0x000000, - GECMD_FOG_COLOR <<24 | 0x000000, - GECMD_TEXTURE_SLOPE <<24 | 0x000000, - GECMD_FRAME_PIXFMT <<24 | 0x000000, - GECMD_CLEAR_MODE <<24 | 0x000000, - GECMD_CLIP_MIN <<24 | 0x000000, - GECMD_CLIP_MAX <<24 | 0x000000, - GECMD_CLIP_NEAR <<24 | 0x000000, - GECMD_CLIP_FAR <<24 | 0x000000, - GECMD_COLORTEST_FUNC<<24 | 0x000000, - GECMD_COLORTEST_REF <<24 | 0x000000, - GECMD_COLORTEST_MASK<<24 | 0x000000, - GECMD_ALPHATEST <<24 | 0x000000, - GECMD_STENCILTEST <<24 | 0x000000, - GECMD_STENCIL_OP <<24 | 0x000000, - GECMD_DEPTHTEST <<24 | 0x000000, - GECMD_BLEND_FUNC <<24 | 0x000000, - GECMD_BLEND_SRCFIX <<24 | 0x000000, - GECMD_BLEND_DSTFIX <<24 | 0x000000, - GECMD_DITHER0 <<24 | 0x000000, - GECMD_DITHER1 <<24 | 0x000000, - GECMD_DITHER2 <<24 | 0x000000, - GECMD_DITHER3 <<24 | 0x000000, - GECMD_LOGIC_OP <<24 | 0x000000, - GECMD_DEPTH_MASK <<24 | 0x000000, - GECMD_COLOR_MASK <<24 | 0x000000, - GECMD_ALPHA_MASK <<24 | 0x000000, - GECMD_COPY_S_POS <<24 | 0x000000, - GECMD_COPY_D_POS <<24 | 0x000000, - GECMD_COPY_SIZE <<24 | 0x000000, - GECMD_UNKNOWN_F0 <<24 | 0x000000, - GECMD_UNKNOWN_F1 <<24 | 0x000000, - GECMD_UNKNOWN_F2 <<24 | 0x000000, - GECMD_UNKNOWN_F3 <<24 | 0x000000, - GECMD_UNKNOWN_F4 <<24 | 0x000000, - GECMD_UNKNOWN_F5 <<24 | 0x000000, - GECMD_UNKNOWN_F6 <<24 | 0x000000, - GECMD_UNKNOWN_F7 <<24 | 0x000000, - GECMD_UNKNOWN_F8 <<24 | 0x000000, - GECMD_UNKNOWN_F9 <<24 | 0x000000, - GECMD_FINISH <<24 | 0x000000, - GECMD_END <<24 | 0x000000, - GECMD_NOP <<24 | 0x000000, - GECMD_NOP <<24 | 0x000000, - }; - - int listid = sceGeListEnQueue(ge_init_list, NULL, 0, 0); - sceGeListSync(listid, PSP_GE_LIST_DONE); -} - -/*************************************************************************/ - -/** - * guStart: Start a new display list. - * - * [Parameters] - * type: List type (GU_DIRECT or GU_CALL) - * list: List pointer - */ -void guStart(const int type, void * const list) -{ - if (type == GU_CALL) { - gu_saved_list = gu_list; - gu_is_sublist = 1; - } else { - gu_is_sublist = 0; - gu_list_id = sceGeListEnQueue(list, list, 0, 0); - } - gu_list = list; -} - -/*-----------------------------------------------------------------------*/ - -/** - * guFinish: End the current display list. - * - * [Parameters] - * None - * [Return value] - * None - */ -void guFinish(void) -{ - if (gu_is_sublist) { - *gu_list = GECMD_RETURN<<24; - gu_list = gu_saved_list; - gu_saved_list = NULL; - gu_is_sublist = 0; - } else { - *gu_list++ = GECMD_FINISH<<24; - *gu_list++ = GECMD_END<<24; - guCommit(); - gu_list = NULL; - } -} - -/*************************************************************************/ - -/** - * guCommit: Commit all previously-added commands to memory and start - * GE processing. Does nothing if the current display list is not a - * GU_DIRECT list. - * - * [Parameters] - * None - * [Return value] - * None - */ -void guCommit(void) -{ - if (gu_list && !gu_is_sublist) { - /* If a partially-used cache line hangs around until the next frame - * and the next frame's display list is different, we could end up - * clobbering the display list with old data, so invalidate all the - * cache lines we touched in addition to writing them back to - * memory. */ - sceKernelDcacheWritebackInvalidateAll(); - sceGeListUpdateStallAddr(gu_list_id, gu_list); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * guSync: Wait for GE processing to complete. - * - * [Parameters] - * mode: Synchronization mode (GU_SYNC_*) - * target: Synchronization target (GU_SYNC_WHAT_*) - * [Return value] - * None - */ -void guSync(const int mode, const int target) -{ - if (gu_list_id) { - if (mode != GU_SYNC_FINISH || target != GU_SYNC_WHAT_DONE) { - return; - } - sceGeDrawSync(PSP_GE_LIST_DONE); - sceGeListDeQueue(gu_list_id); - gu_list_id = 0; - } -} - -/*************************************************************************/ - -/** - * guGetMemory: Allocate a block of memory from the current GU_DIRECT - * list. The allocation size will automatically be rounded up to a - * multiple of 4 bytes. - * - * This function may not be called unless there is a current GU_DIRECT - * list. - * - * [Parameters] - * size: Number of bytes to allocate - */ -void *guGetMemory(const uint32_t size) -{ - uint32_t **list_ref = (gu_is_sublist ? &gu_saved_list : &gu_list); - const uint32_t alloc_words = (size + 3) / 4; - uint32_t * const alloc_ptr = (*list_ref) + 2; - uint32_t * const target = alloc_ptr + alloc_words; - (*list_ref)[0] = GECMD_ADDRESS_BASE<<24 - | ((uint32_t)target & 0xFF000000) >> 8; - (*list_ref)[1] = GECMD_JUMP<<24 - | ((uint32_t)target & 0x00FFFFFF); - (*list_ref) = target; - return alloc_ptr; -} - -/*************************************************************************/ - -#endif // USE_SCEGU - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/gu.h b/yabause/src/psp/gu.h deleted file mode 100644 index 87e42cd178..0000000000 --- a/yabause/src/psp/gu.h +++ /dev/null @@ -1,1006 +0,0 @@ -/* src/psp/gu.h: sceGu substitute library header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_GU_H -#define PSP_GU_H - -/* - * This library defines a substitute set of functions for the sceGu library - * used for manipulating display lists. These substitute functions are - * designed for maximum efficiency when dynamically generating display - * lists, and improve on the sceGu library in the following ways: - * - * - The sceGu library functions (at least as implemented in PSPSDK r2450) - * are designed to be robust against data corruption by using uncached - * memory accesses, but such accesses naturally slow the program down - * significantly. The functions defined here avoid this slowdown by - * making judicious use of the CPU's cache, allowing the CPU to access - * memory in cache line units instead of individual words. - * - * - The sceGuDrawArray() function triggers the GE to resume processing - * after writing instructions to the display list. In theory, this can - * improve performance by maximizing parallelism between the GE and the - * main Allegrex CPU; however, when constructing dynamic display lists - * which may by necessity include frequent DrawArray() calls, the - * overhead of synchronization far outweighs any performance gain. This - * library defines a guCommit() function allowing the caller to specify - * exactly when to trigger the GE, and does not do so on its own (except - * when calling guFinish() on a GU_DIRECT display list). - * - * - The sceGuDrawArray also requires the vertex type, vertex pointer, - * vertex count, and primitive type to all be specified in a single - * call. This can waste a significant amount of space when generating - * dynamic vertex arrays in which the vertex type is constant but the - * number of vertices cannot be easily computed or stored. This library - * defines guVertexFormat(), guVertexPointer(), and guDrawPrimitive() - * functions which implement each of the separate functions of - * guDrawArray(), so only the necessary functions need to be called. - * - * - Many of the texture-related functions internally call sceGuTexFlush() - * to flush the texture cache. While robust, this can cause significant - * bloat of the resulting display list. This library never calls - * guTexFlush() automatically; it is thus up to the caller to flush the - * texture cache at appropriate points. - * - * - Most of the substitute functions are defined as inline functions in - * this file, allowing the compiler to avoid the overhead of calling a - * subroutine for each graphics operation and to fold constant parameters - * when computing GE instruction words. GCC, at least, can also optimize - * out the updates of the list pointer variable after each instruction, - * saving a significant amount of code. In an optimal case where all - * function parameters are constant, such as - * sceGuTexFilter(GU_NEAREST, GU_NEAREST); - * execution time can be reduced from >20 cycles to 3 (or even 2) cycles - * per call. - * - * Note that this library is only implemented to the extent necessary for - * Yabause, and needs more work to be usable as a general-purpose library. - */ - -/*************************************************************************/ -/*************************************************************************/ - -/** - * USE_SCEGU: When defined, the guXxx() functions declared in this file - * will instead be aliased to the standard sceGuXxx() library functions, - * and custom functions not defined in the sceGu library such as guCommit() - * are turned into no-ops. The sceGu functions are slower than our custom - * functions, so there is normally no reason to define this symbol except - * for benchmarking or testing. - */ -// #define USE_SCEGU - -/*************************************************************************/ -/************************ GE command definitions *************************/ -/*************************************************************************/ - -typedef enum GECommand_ { - GECMD_NOP = 0x00, - GECMD_VERTEX_POINTER= 0x01, - GECMD_INDEX_POINTER = 0x02, - // 0x03 undefined - GECMD_DRAW_PRIMITIVE= 0x04, - GECMD_DRAW_BEZIER = 0x05, - GECMD_DRAW_SPLINE = 0x06, - GECMD_TEST_BBOX = 0x07, - GECMD_JUMP = 0x08, - GECMD_COND_JUMP = 0x09, - GECMD_CALL = 0x0A, - GECMD_RETURN = 0x0B, - GECMD_END = 0x0C, - // 0x0D undefined - GECMD_SIGNAL = 0x0E, - GECMD_FINISH = 0x0F, - - GECMD_ADDRESS_BASE = 0x10, - // 0x11 undefined - GECMD_VERTEX_FORMAT = 0x12, - GECMD_UNKNOWN_13 = 0x13, // psp_doc: Offset Address (BASE) - GECMD_UNKNOWN_14 = 0x14, // psp_doc: Origin Address (BASE) - GECMD_DRAWAREA_LOW = 0x15, - GECMD_DRAWAREA_HIGH = 0x16, - GECMD_ENA_LIGHTING = 0x17, - GECMD_ENA_LIGHT0 = 0x18, - GECMD_ENA_LIGHT1 = 0x19, - GECMD_ENA_LIGHT2 = 0x1A, - GECMD_ENA_LIGHT3 = 0x1B, - GECMD_ENA_ZCLIP = 0x1C, - GECMD_ENA_FACE_CULL = 0x1D, - GECMD_ENA_TEXTURE = 0x1E, - GECMD_ENA_FOG = 0x1F, - - GECMD_ENA_DITHER = 0x20, - GECMD_ENA_BLEND = 0x21, - GECMD_ENA_ALPHA_TEST= 0x22, - GECMD_ENA_DEPTH_TEST= 0x23, - GECMD_ENA_STENCIL = 0x24, - GECMD_ENA_ANTIALIAS = 0x25, - GECMD_ENA_PATCH_CULL= 0x26, - GECMD_ENA_COLOR_TEST= 0x27, - GECMD_ENA_LOGIC_OP = 0x28, - // 0x29 undefined - GECMD_BONE_OFFSET = 0x2A, - GECMD_BONE_UPLOAD = 0x2B, - GECMD_MORPH_0 = 0x2C, - GECMD_MORPH_1 = 0x2D, - GECMD_MORPH_2 = 0x2E, - GECMD_MORPH_3 = 0x2F, - - GECMD_MORPH_4 = 0x30, - GECMD_MORPH_5 = 0x31, - GECMD_MORPH_6 = 0x32, - GECMD_MORPH_7 = 0x33, - // 0x34 undefined - // 0x35 undefined - GECMD_PATCH_SUBDIV = 0x36, - GECMD_PATCH_PRIM = 0x37, - GECMD_PATCH_FRONT = 0x38, - // 0x39 undefined - GECMD_MODEL_START = 0x3A, - GECMD_MODEL_UPLOAD = 0x3B, - GECMD_VIEW_START = 0x3C, - GECMD_VIEW_UPLOAD = 0x3D, - GECMD_PROJ_START = 0x3E, - GECMD_PROJ_UPLOAD = 0x3F, - - GECMD_TEXTURE_START = 0x40, - GECMD_TEXTURE_UPLOAD= 0x41, - GECMD_XSCALE = 0x42, - GECMD_YSCALE = 0x43, - GECMD_ZSCALE = 0x44, - GECMD_XPOS = 0x45, - GECMD_YPOS = 0x46, - GECMD_ZPOS = 0x47, - GECMD_USCALE = 0x48, - GECMD_VSCALE = 0x49, - GECMD_UOFFSET = 0x4A, - GECMD_VOFFSET = 0x4B, - GECMD_XOFFSET = 0x4C, - GECMD_YOFFSET = 0x4D, - // 0x4E undefined - // 0x4F undefined - - GECMD_SHADE_MODE = 0x50, - GECMD_REV_NORMALS = 0x51, - // 0x52 undefined - GECMD_COLOR_MATERIAL= 0x53, - GECMD_EMISSIVE_COLOR= 0x54, - GECMD_AMBIENT_COLOR = 0x55, - GECMD_DIFFUSE_COLOR = 0x56, - GECMD_SPECULAR_COLOR= 0x57, - GECMD_AMBIENT_ALPHA = 0x58, - // 0x59 undefined - // 0x5A undefined - GECMD_SPECULAR_POWER= 0x5B, - GECMD_LIGHT_AMBCOLOR= 0x5C, - GECMD_LIGHT_AMBALPHA= 0x5D, - GECMD_LIGHT_MODEL = 0x5E, - GECMD_LIGHT0_TYPE = 0x5F, - - GECMD_LIGHT1_TYPE = 0x60, - GECMD_LIGHT2_TYPE = 0x61, - GECMD_LIGHT3_TYPE = 0x62, - GECMD_LIGHT0_XPOS = 0x63, - GECMD_LIGHT0_YPOS = 0x64, - GECMD_LIGHT0_ZPOS = 0x65, - GECMD_LIGHT1_XPOS = 0x66, - GECMD_LIGHT1_YPOS = 0x67, - GECMD_LIGHT1_ZPOS = 0x68, - GECMD_LIGHT2_XPOS = 0x69, - GECMD_LIGHT2_YPOS = 0x6A, - GECMD_LIGHT2_ZPOS = 0x6B, - GECMD_LIGHT3_XPOS = 0x6C, - GECMD_LIGHT3_YPOS = 0x6D, - GECMD_LIGHT3_ZPOS = 0x6E, - GECMD_LIGHT0_XDIR = 0x6F, - - GECMD_LIGHT0_YDIR = 0x70, - GECMD_LIGHT0_ZDIR = 0x71, - GECMD_LIGHT1_XDIR = 0x72, - GECMD_LIGHT1_YDIR = 0x73, - GECMD_LIGHT1_ZDIR = 0x74, - GECMD_LIGHT2_XDIR = 0x75, - GECMD_LIGHT2_YDIR = 0x76, - GECMD_LIGHT2_ZDIR = 0x77, - GECMD_LIGHT3_XDIR = 0x78, - GECMD_LIGHT3_YDIR = 0x79, - GECMD_LIGHT3_ZDIR = 0x7A, - GECMD_LIGHT0_CATT = 0x7B, - GECMD_LIGHT0_LATT = 0x7C, - GECMD_LIGHT0_QATT = 0x7D, - GECMD_LIGHT1_CATT = 0x7E, - GECMD_LIGHT1_LATT = 0x7F, - - GECMD_LIGHT1_QATT = 0x80, - GECMD_LIGHT2_CATT = 0x81, - GECMD_LIGHT2_LATT = 0x82, - GECMD_LIGHT2_QATT = 0x83, - GECMD_LIGHT3_CATT = 0x84, - GECMD_LIGHT3_LATT = 0x85, - GECMD_LIGHT3_QATT = 0x86, - GECMD_LIGHT0_SPOTEXP= 0x87, - GECMD_LIGHT1_SPOTEXP= 0x88, - GECMD_LIGHT2_SPOTEXP= 0x89, - GECMD_LIGHT3_SPOTEXP= 0x8A, - GECMD_LIGHT0_SPOTLIM= 0x8B, - GECMD_LIGHT1_SPOTLIM= 0x8C, - GECMD_LIGHT2_SPOTLIM= 0x8D, - GECMD_LIGHT3_SPOTLIM= 0x8E, - GECMD_LIGHT0_ACOL = 0x8F, - - GECMD_LIGHT0_DCOL = 0x90, - GECMD_LIGHT0_SCOL = 0x91, - GECMD_LIGHT1_ACOL = 0x92, - GECMD_LIGHT1_DCOL = 0x93, - GECMD_LIGHT1_SCOL = 0x94, - GECMD_LIGHT2_ACOL = 0x95, - GECMD_LIGHT2_DCOL = 0x96, - GECMD_LIGHT2_SCOL = 0x97, - GECMD_LIGHT3_ACOL = 0x98, - GECMD_LIGHT3_DCOL = 0x99, - GECMD_LIGHT3_SCOL = 0x9A, - GECMD_FACE_ORDER = 0x9B, - GECMD_DRAW_ADDRESS = 0x9C, - GECMD_DRAW_STRIDE = 0x9D, - GECMD_DEPTH_ADDRESS = 0x9E, - GECMD_DEPTH_STRIDE = 0x9F, - - GECMD_TEX0_ADDRESS = 0xA0, - GECMD_TEX1_ADDRESS = 0xA1, - GECMD_TEX2_ADDRESS = 0xA2, - GECMD_TEX3_ADDRESS = 0xA3, - GECMD_TEX4_ADDRESS = 0xA4, - GECMD_TEX5_ADDRESS = 0xA5, - GECMD_TEX6_ADDRESS = 0xA6, - GECMD_TEX7_ADDRESS = 0xA7, - GECMD_TEX0_STRIDE = 0xA8, - GECMD_TEX1_STRIDE = 0xA9, - GECMD_TEX2_STRIDE = 0xAA, - GECMD_TEX3_STRIDE = 0xAB, - GECMD_TEX4_STRIDE = 0xAC, - GECMD_TEX5_STRIDE = 0xAD, - GECMD_TEX6_STRIDE = 0xAE, - GECMD_TEX7_STRIDE = 0xAF, - - GECMD_CLUT_ADDRESS_L= 0xB0, - GECMD_CLUT_ADDRESS_H= 0xB1, - GECMD_COPY_S_ADDRESS= 0xB2, - GECMD_COPY_S_STRIDE = 0xB3, - GECMD_COPY_D_ADDRESS= 0xB4, - GECMD_COPY_D_STRIDE = 0xB5, - // 0xB6 undefined - // 0xB7 undefined - GECMD_TEX0_SIZE = 0xB8, - GECMD_TEX1_SIZE = 0xB9, - GECMD_TEX2_SIZE = 0xBA, - GECMD_TEX3_SIZE = 0xBB, - GECMD_TEX4_SIZE = 0xBC, - GECMD_TEX5_SIZE = 0xBD, - GECMD_TEX6_SIZE = 0xBE, - GECMD_TEX7_SIZE = 0xBF, - - GECMD_TEXTURE_MAP = 0xC0, - GECMD_TEXTURE_ENVMAP= 0xC1, - GECMD_TEXTURE_MODE = 0xC2, - GECMD_TEXTURE_PIXFMT= 0xC3, - GECMD_CLUT_LOAD = 0xC4, - GECMD_CLUT_MODE = 0xC5, - GECMD_TEXTURE_FILTER= 0xC6, - GECMD_TEXTURE_WRAP = 0xC7, - GECMD_TEXTURE_BIAS = 0xC8, - GECMD_TEXTURE_FUNC = 0xC9, - GECMD_TEXTURE_COLOR = 0xCA, - GECMD_TEXTURE_FLUSH = 0xCB, - GECMD_COPY_SYNC = 0xCC, - GECMD_FOG_LIMIT = 0xCD, - GECMD_FOG_RANGE = 0xCE, - GECMD_FOG_COLOR = 0xCF, - - GECMD_TEXTURE_SLOPE = 0xD0, - // 0xD1 undefined - GECMD_FRAME_PIXFMT = 0xD2, - GECMD_CLEAR_MODE = 0xD3, - GECMD_CLIP_MIN = 0xD4, - GECMD_CLIP_MAX = 0xD5, - GECMD_CLIP_NEAR = 0xD6, - GECMD_CLIP_FAR = 0xD7, - GECMD_COLORTEST_FUNC= 0xD8, - GECMD_COLORTEST_REF = 0xD9, - GECMD_COLORTEST_MASK= 0xDA, - GECMD_ALPHATEST = 0xDB, - GECMD_STENCILTEST = 0xDC, - GECMD_STENCIL_OP = 0xDD, - GECMD_DEPTHTEST = 0xDE, - GECMD_BLEND_FUNC = 0xDF, - - GECMD_BLEND_SRCFIX = 0xE0, - GECMD_BLEND_DSTFIX = 0xE1, - GECMD_DITHER0 = 0xE2, - GECMD_DITHER1 = 0xE3, - GECMD_DITHER2 = 0xE4, - GECMD_DITHER3 = 0xE5, - GECMD_LOGIC_OP = 0xE6, - GECMD_DEPTH_MASK = 0xE7, - GECMD_COLOR_MASK = 0xE8, - GECMD_ALPHA_MASK = 0xE9, - GECMD_COPY = 0xEA, - GECMD_COPY_S_POS = 0xEB, - GECMD_COPY_D_POS = 0xEC, - // 0xED undefined - GECMD_COPY_SIZE = 0xEE, - // 0xEF undefined - - GECMD_UNKNOWN_F0 = 0xF0, - GECMD_UNKNOWN_F1 = 0xF1, - GECMD_UNKNOWN_F2 = 0xF2, - GECMD_UNKNOWN_F3 = 0xF3, - GECMD_UNKNOWN_F4 = 0xF4, - GECMD_UNKNOWN_F5 = 0xF5, - GECMD_UNKNOWN_F6 = 0xF6, - GECMD_UNKNOWN_F7 = 0xF7, - GECMD_UNKNOWN_F8 = 0xF8, - GECMD_UNKNOWN_F9 = 0xF9, - // 0xFA..0xFF undefined -} GECommand; - -/*************************************************************************/ -/*********************** Custom library functions ************************/ -/*************************************************************************/ - -#ifndef USE_SCEGU - -/*************************************************************************/ - -/* Force these functions to be inlined to avoid function call overhead */ -#ifdef __GNUC__ -# define inline inline __attribute__((always_inline)) -#endif - -/* Note: we declare "extern uint32_t *gu_list" within each function rather - * than here so that we don't export the declaration to the caller. */ - -/* Macros for splitting an address into high and low parts */ -#define ADDRESS_HI(ptr) (((uint32_t)(ptr) & 0x3F000000) >> 8) -#define ADDRESS_LO(ptr) ((uint32_t)(ptr) & 0x00FFFFFF) - -/* Helper function to extract the high 24 bits of a float */ -static inline uint32_t trim_float(const float value) { - uint32_t result; - asm(".set push; .set noreorder\n" - "mfc1 %[result], %[value]\n" - "nop\n" - "srl %[result], %[result], 8\n" - ".set pop" - : [result] "=r" (result) - : [value] "f" (value) - ); - return result; -} - -/*************************************************************************/ - -/**** Functions defined in gu.c ****/ - -/* Custom function to commit cached data and start GE processing */ -extern void guCommit(void); - -extern void guFinish(void); -extern void *guGetMemory(const uint32_t size); -extern void guInit(void); -extern void guStart(const int type, void * const list); -extern void guSync(const int mode, const int target); - -/*************************************************************************/ - -/**** Inline functions ****/ - -static inline void guAlphaFunc(const int func, const int value, const int mask) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ALPHATEST<<24 | mask<<16 | value<<8 | func; -} - -static inline void guAmbientColor(const uint32_t color) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_AMBIENT_COLOR<<24 | (color & 0xFFFFFF); - *gu_list++ = GECMD_AMBIENT_ALPHA<<24 | color>>24; -} - -static inline void guBlendFunc(const int func, const int src, const int dest, - const uint32_t srcfix, const uint32_t destfix) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_BLEND_FUNC<<24 | func<<8 | dest<<4 | src; - if (src == GU_FIX) { - *gu_list++ = GECMD_BLEND_SRCFIX<<24 | srcfix; - } - if (dest == GU_FIX) { - *gu_list++ = GECMD_BLEND_DSTFIX<<24 | destfix; - } -} - -static inline void guCallList(const void * const list) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ADDRESS_BASE<<24 | ADDRESS_HI(list); - *gu_list++ = GECMD_CALL<<24 | ADDRESS_LO(list); -} - -static inline void guClear(const int mode) -{ - extern uint32_t *gu_list; - extern uint32_t gu_clear_color_stencil; - extern uint16_t gu_clear_depth; - struct {uint32_t color, xy, z;} *vertices; - vertices = guGetMemory(sizeof(*vertices) * 2); - vertices[0].color = 0; - vertices[0].xy = 0; - vertices[0].z = gu_clear_depth; - vertices[1].color = gu_clear_color_stencil; - vertices[1].xy = 480 | 272<<16; - vertices[1].z = 0; - *gu_list++ = GECMD_CLEAR_MODE<<24 | mode<<8 | 1; - *gu_list++ = GECMD_ENA_BLEND<<24 | 0; - *gu_list++ = GECMD_VERTEX_FORMAT<<24 - | GU_TRANSFORM_2D | GU_COLOR_8888 | GU_VERTEX_16BIT; - *gu_list++ = GECMD_ADDRESS_BASE<<24 | ADDRESS_HI(vertices); - *gu_list++ = GECMD_VERTEX_POINTER<<24 | ADDRESS_LO(vertices); - *gu_list++ = GECMD_DRAW_PRIMITIVE<<24 | GU_SPRITES<<16 | 2; - *gu_list++ = GECMD_CLEAR_MODE<<24 | 0; -} - -static inline void guClearColor(const uint32_t color) -{ - extern uint32_t gu_clear_color_stencil; - gu_clear_color_stencil = (gu_clear_color_stencil & 0xFF000000) - | (color & 0x00FFFFFF); -} - -static inline void guClearDepth(const unsigned int depth) -{ - extern uint16_t gu_clear_depth; - gu_clear_depth = depth; -} - -static inline void guClearStencil(const unsigned int stencil) -{ - extern uint32_t gu_clear_color_stencil; - gu_clear_color_stencil = (gu_clear_color_stencil & 0xFFFFFF) | stencil<<24; -} - -static inline void guClutLoad(const int count, const void * const address) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_CLUT_ADDRESS_L<<24 | ADDRESS_LO(address); - *gu_list++ = GECMD_CLUT_ADDRESS_H<<24 | ADDRESS_HI(address); - *gu_list++ = GECMD_CLUT_LOAD<<24 | count; -} - -static inline void guClutMode(const int format, const int shift, - const int mask, const int unknown) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_CLUT_MODE<<24 | format | shift<<2 | mask<<8; -} - -static inline void guCopyImage(const int mode, - const int src_x, const int src_y, - const int src_w, const int src_h, - const int src_stride, - const void * const src_ptr, - const int dest_x, const int dest_y, - const int dest_stride, - const void * const dest_ptr) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_COPY_S_ADDRESS<<24 | ADDRESS_LO(src_ptr); - *gu_list++ = GECMD_COPY_S_STRIDE<<24 | ADDRESS_HI(src_ptr) | src_stride; - *gu_list++ = GECMD_COPY_S_POS<<24 | src_y<<10 | src_x; - *gu_list++ = GECMD_COPY_D_ADDRESS<<24 | ADDRESS_LO(dest_ptr); - *gu_list++ = GECMD_COPY_D_STRIDE<<24 | ADDRESS_HI(dest_ptr) | dest_stride; - *gu_list++ = GECMD_COPY_D_POS<<24 | dest_y<<10 | dest_x; - *gu_list++ = GECMD_COPY_SIZE<<24 | (src_h-1)<<10 | (src_w-1); - *gu_list++ = GECMD_COPY<<24 | (mode==GU_PSM_8888 ? 1 : 0); -} - -static inline void guDepthBuffer(const void * const address, const int stride) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_DEPTH_ADDRESS<<24 | ADDRESS_LO(address); - *gu_list++ = GECMD_DEPTH_STRIDE<<24 | ADDRESS_HI(address) | stride; -} - -static inline void guDepthFunc(const int function) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_DEPTHTEST<<24 | function; -} - -static inline void guDepthMask(const int mask) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_DEPTH_MASK<<24 | mask; -} - -static inline void guDepthRange(const int near, const int far) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ZSCALE<<24 | trim_float((far - near) / 2.0f); - *gu_list++ = GECMD_ZPOS<<24 | trim_float((far + near) / 2.0f); - *gu_list++ = GECMD_CLIP_NEAR<<24 | (near>24; -} - -static inline void guScissor(const int left, const int top, - const int width, const int height) -{ - extern uint32_t *gu_list; - extern uint32_t gu_scissorcmd_min, gu_scissorcmd_max; - extern uint8_t gu_scissor_enabled; - gu_scissorcmd_min = GECMD_CLIP_MIN<<24 | top<<10 | left; - gu_scissorcmd_max = GECMD_CLIP_MAX<<24 | (top+height-1)<<10 - | (left+width-1); - if (gu_scissor_enabled) { - *gu_list++ = gu_scissorcmd_min; - *gu_list++ = gu_scissorcmd_max; - } -} - -/* - * Note: As with sceGuSetMatrix(), 4x3 matrices are laid out in a 4x4 - * array as follows: - * { {_11, _12, _13, _ignored}, - * {_21, _22, _23, _ignored}, - * {_31, _32, _33, _ignored}, - * {_41, _42, _43, _ignored} } - */ -static inline void guSetMatrix(int type, const float *matrix) -{ - extern uint32_t *gu_list; - if (type == GU_MODEL) { - *gu_list++ = GECMD_MODEL_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 3; j++) { - *gu_list++ = GECMD_MODEL_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } else if (type == GU_VIEW) { - *gu_list++ = GECMD_VIEW_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 3; j++) { - *gu_list++ = GECMD_VIEW_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } else if (type == GU_PROJECTION) { - *gu_list++ = GECMD_PROJ_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 4; j++) { - *gu_list++ = GECMD_PROJ_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } else if (type == GU_TEXTURE) { - *gu_list++ = GECMD_TEXTURE_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 3; j++) { - *gu_list++ = GECMD_TEXTURE_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } -} - -static inline void guShadeModel(const int mode) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_SHADE_MODE<<24 | mode; -} - -static inline void guStencilFunc(const int func, const int ref, const int mask) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_STENCILTEST<<24 | mask<<16 | ref<<8 | func; -} - -static inline void guStencilOp(const int fail, const int zfail, const int zpass) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_STENCIL_OP<<24 | zpass<<16 | zfail<<8 | fail; -} - -static inline void guTexFilter(const int min, const int mag) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_FILTER<<24 | mag<<8 | min; -} - -static inline void guTexFlush(void) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_FLUSH<<24; -} - -static inline void guTexFunc(const int func, const int alpha) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_FUNC<<24 | alpha<<8 | func; -} - -static inline void guTexImage(const int level, const int width, - const int height, const int stride, - const void * const address) -{ - extern uint32_t *gu_list; - const int log2_width = 31 - __builtin_clz(width); - const int log2_height = 31 - __builtin_clz(height); - *gu_list++ = (GECMD_TEX0_ADDRESS+level)<<24 | ADDRESS_LO(address); - *gu_list++ = (GECMD_TEX0_STRIDE+level)<<24 | ADDRESS_HI(address) | stride; - *gu_list++ = (GECMD_TEX0_SIZE+level)<<24 | log2_height<<8 | log2_width; -} - -static inline void guTexLevelMode(const int mode, const float bias) -{ - extern uint32_t *gu_list; - const int bias_int = (int)(bias*16 + 0.5f) & 0xFF; - *gu_list++ = GECMD_TEXTURE_BIAS<<24 | bias_int<<16 | mode; -} - -static inline void guTexMode(const int format, const int mipmaps, - const int unknown, const int swizzle) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_MODE<<24 | (mipmaps ? mipmaps-1 : 0) << 16 - | swizzle; - *gu_list++ = GECMD_TEXTURE_PIXFMT<<24 | format; -} - -static inline void guTexSlope(const float slope) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_SLOPE<<24 | trim_float(slope); -} - -static inline void guTexWrap(const int u_mode, const int v_mode) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_WRAP<<24 | v_mode<<8 | u_mode; -} - -/* Custom function to set vertex format independently of guDrawArray() */ -static inline void guVertexFormat(const uint32_t format) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_VERTEX_FORMAT<<24 | format; -} - -/* Custom function to set vertex pointer independently of guDrawArray() */ -static inline void guVertexPointer(const void * const address) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ADDRESS_BASE<<24 | ADDRESS_HI(address); - *gu_list++ = GECMD_VERTEX_POINTER<<24 | ADDRESS_LO(address); -} - -static inline void guViewport(const int cx, const int cy, - const int width, const int height) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_XPOS<<24 | trim_float(cx); - *gu_list++ = GECMD_YPOS<<24 | trim_float(cy); - *gu_list++ = GECMD_XSCALE<<24 | trim_float(width/2); - *gu_list++ = GECMD_YSCALE<<24 | trim_float(-height/2); -} - -/*************************************************************************/ - -#undef ADDRESS_HI -#undef ADDRESS_LO - -#ifdef __GNUC__ -# undef inline // Cancel the always_inline definition above -#endif - -#endif // !USE_SCEGU - -/*************************************************************************/ -/************************* sceGu library aliases *************************/ -/*************************************************************************/ - -#ifdef USE_SCEGU - -#define guAlphaFunc(func,value,mask) \ - sceGuAlphaFunc((func), (value), (mask)) -#define guAmbientColor(color) \ - sceGuAmbientColor((color)) -#define guBlendFunc(func,src,dest,srcfix,destfix) \ - sceGuBlendFunc((func), (src), (dest), (srcfix), (destfix)) -#define guCallList(list) \ - sceGuCallList((list)) -#define guClear(mode) \ - sceGuClear((mode)) -#define guClearColor(color) \ - sceGuClearColor((color)) -#define guClearDepth(depth) \ - sceGuClearDepth((depth)) -#define guClearStencil(stencil) \ - sceGuClearStencil((stencil)) -#define guClutLoad(count,address) \ - sceGuClutLoad((count), (address)) -#define guClutMode(format,shift,mask,unknown) \ - sceGuClutMode((format), (shift), (mask), (unknown)) -#define guCopyImage(mode,src_x,src_y,src_w,src_h,src_stride,src_ptr,dest_x,dest_y,dest_stride,dest_ptr) \ - sceGuCopyImage((mode), (src_x), (src_y), (src_w), (src_h), (src_stride), \ - (src_ptr), (dest_x), (dest_y), (dest_stride), (dest_ptr)) -#define guDepthBuffer(address,stride) \ - sceGuDepthBuffer((address), (stride)) -#define guDepthFunc(function) \ - sceGuDepthFunc((function)) -#define guDepthMask(mask) \ - sceGuDepthMask((mask)) -#define guDepthRange(near,far) \ - sceGuDepthRange((near), (far)) -#define guDisable(mode) \ - sceGuDisable((mode)) -#define guDispBuffer(width,height,address,stride) \ - sceGuDispBuffer((width), (height), (address), (stride)) -#define guDrawArray(primitive,vertexfmt,count,indexptr,vertexptr) \ - sceGuDrawArray((primitive), (vertexfmt), (count), (indexptr), (vertexptr)) -#define guDrawBuffer(format,address,stride) \ - sceGuDrawBuffer((format), (address), (stride)) -#define guEnable(mode) \ - sceGuEnable((mode)) -#define guFinish() \ - sceGuFinish() -#define guGetMemory(size) \ - sceGuGetMemory((size)) -#define guInit() \ - sceGuInit() -#define guLogicalOp(op) \ - sceGuLogicalOp((op)) -#define guOffset(xofs,yofs) \ - sceGuOffset((xofs), (yofs)) -#define guPixelMask(mask) \ - sceGuPixelMask((mask)) -#define guScissor(left,top,width,height) \ - sceGuScissor((left), (top), (width), (height)) -#define guSetMatrix(type,matrix) \ - sceGuSetMatrix((type), (const ScePspFMatrix4 *)(matrix)) -#define guShadeModel(mode) \ - sceGuShadeModel((mode)) -#define guStart(type,list) \ - sceGuStart((type), (list)) -#define guStencilFunc(func,ref,mask) \ - sceGuStencilFunc((func), (ref), (mask)) -#define guStencilOp(fail,zfail,zpass) \ - sceGuStencilOp((fail), (zfail), (zpass)) -#define guSync(mode,target) \ - sceGuSync((mode), (target)) -#define guTexFilter(min,mag) \ - sceGuTexFilter((min), (mag)) -#define guTexFlush() \ - sceGuTexFlush() -#define guTexFunc(func,alpha) \ - sceGuTexFunc((func), (alpha)) -#define guTexImage(level,width,height,stride,address) \ - sceGuTexImage((level), (width), (height), (stride), (address)) -#define guTexLevelMode(mode, bias) \ - sceGuTexLevelMode((mode), (bias)) -#define guTexMode(format,mipmaps,unknown,swizzle) \ - sceGuTexMode((format), (mipmaps), (unknown), (swizzle)) -#define guTexSlope(slope) \ - sceGuTexSlope((slope)) -#define guTexWrap(u_mode,v_mode) \ - sceGuTexWrap((u_mode), (v_mode)) -#define guViewport(cx,cy,width,height) \ - sceGuViewport((cx), (cy), (width), (height)) - -/* Custom functions */ -#define guCommit() /* no-op */ -#define guDrawPrimitive(primitive,count) \ - sceGuSendCommandi(GECMD_DRAW_PRIMITIVE, (primitive)<<16 | (count)) -#define guVertexFormat(format) \ - sceGuSendCommandi(GECMD_VERTEX_FORMAT, (format)) -#define guVertexPointer(address) do { \ - const uint32_t __address = (uint32_t)(address); \ - sceGuSendCommandi(GECMD_ADDRESS_BASE, (__address & 0xFF000000) >> 8); \ - sceGuSendCommandi(GECMD_VERTEX_POINTER, __address & 0x00FFFFFF); \ -} while (0) - -#endif // USE_SCEGU - -/*************************************************************************/ -/*************************************************************************/ - -#endif // PSP_GU_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/icache-funcs-2450.patch b/yabause/src/psp/icache-funcs-2450.patch deleted file mode 100644 index d928c52648..0000000000 --- a/yabause/src/psp/icache-funcs-2450.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff -urN a/pspsdk-2450/src/user/Makefile.am b/pspsdk-2450/src/user/Makefile.am ---- a/pspsdk-2450/src/user/Makefile.am 2009-01-09 03:15:40 +0900 -+++ b/pspsdk-2450/src/user/Makefile.am 2009-02-10 16:24:00 +0900 -@@ -24,7 +24,7 @@ - - THREADMAN_OBJS = ThreadManForUser_0000.o ThreadManForUser_0001.o ThreadManForUser_0002.o ThreadManForUser_0003.o ThreadManForUser_0004.o ThreadManForUser_0005.o ThreadManForUser_0006.o ThreadManForUser_0007.o ThreadManForUser_0008.o ThreadManForUser_0009.o ThreadManForUser_0010.o ThreadManForUser_0011.o ThreadManForUser_0012.o ThreadManForUser_0013.o ThreadManForUser_0014.o ThreadManForUser_0015.o ThreadManForUser_0016.o ThreadManForUser_0017.o ThreadManForUser_0018.o ThreadManForUser_0019.o ThreadManForUser_0020.o ThreadManForUser_0021.o ThreadManForUser_0022.o ThreadManForUser_0023.o ThreadManForUser_0024.o ThreadManForUser_0025.o ThreadManForUser_0026.o ThreadManForUser_0027.o ThreadManForUser_0028.o ThreadManForUser_0029.o ThreadManForUser_0030.o ThreadManForUser_0031.o ThreadManForUser_0032.o ThreadManForUser_0033.o ThreadManForUser_0034.o ThreadManForUser_0035.o ThreadManForUser_0036.o ThreadManForUser_0037.o ThreadManForUser_0038.o ThreadManForUser_0039.o ThreadManForUser_0040.o ThreadManForUser_0041.o ThreadManForUser_0042.o ThreadManForUser_0043.o ThreadManForUser_0044.o ThreadManForUser_0045.o ThreadManForUser_0046.o ThreadManForUser_0047.o ThreadManForUser_0048.o ThreadManForUser_0049.o ThreadManForUser_0050.o ThreadManForUser_0051.o ThreadManForUser_0052.o ThreadManForUser_0053.o ThreadManForUser_0054.o ThreadManForUser_0055.o ThreadManForUser_0056.o ThreadManForUser_0057.o ThreadManForUser_0058.o ThreadManForUser_0059.o ThreadManForUser_0060.o ThreadManForUser_0061.o ThreadManForUser_0062.o ThreadManForUser_0063.o ThreadManForUser_0064.o ThreadManForUser_0065.o ThreadManForUser_0066.o ThreadManForUser_0067.o ThreadManForUser_0068.o ThreadManForUser_0069.o ThreadManForUser_0070.o ThreadManForUser_0071.o ThreadManForUser_0072.o ThreadManForUser_0073.o ThreadManForUser_0074.o ThreadManForUser_0075.o ThreadManForUser_0076.o ThreadManForUser_0077.o ThreadManForUser_0078.o ThreadManForUser_0079.o ThreadManForUser_0080.o ThreadManForUser_0081.o ThreadManForUser_0082.o ThreadManForUser_0083.o ThreadManForUser_0084.o ThreadManForUser_0085.o ThreadManForUser_0086.o ThreadManForUser_0087.o ThreadManForUser_0088.o ThreadManForUser_0089.o ThreadManForUser_0090.o ThreadManForUser_0091.o ThreadManForUser_0092.o ThreadManForUser_0093.o ThreadManForUser_0094.o ThreadManForUser_0095.o ThreadManForUser_0096.o ThreadManForUser_0097.o ThreadManForUser_0098.o ThreadManForUser_0099.o ThreadManForUser_0100.o ThreadManForUser_0101.o ThreadManForUser_0102.o ThreadManForUser_0103.o ThreadManForUser_0104.o ThreadManForUser_0105.o ThreadManForUser_0106.o ThreadManForUser_0107.o ThreadManForUser_0108.o ThreadManForUser_0109.o ThreadManForUser_0110.o ThreadManForUser_0111.o ThreadManForUser_0112.o ThreadManForUser_0113.o ThreadManForUser_0114.o ThreadManForUser_0115.o ThreadManForUser_0116.o ThreadManForUser_0117.o ThreadManForUser_0118.o ThreadManForUser_0119.o ThreadManForUser_0120.o ThreadManForUser_0121.o ThreadManForUser_0122.o ThreadManForUser_0123.o ThreadManForUser_0124.o ThreadManForUser_0125.o ThreadManForUser_0126.o - --UTILS_OBJS = UtilsForUser_0000.o UtilsForUser_0001.o UtilsForUser_0002.o UtilsForUser_0003.o UtilsForUser_0004.o UtilsForUser_0005.o UtilsForUser_0006.o UtilsForUser_0007.o UtilsForUser_0008.o UtilsForUser_0009.o UtilsForUser_0010.o UtilsForUser_0011.o UtilsForUser_0012.o UtilsForUser_0013.o UtilsForUser_0014.o UtilsForUser_0015.o UtilsForUser_0016.o UtilsForUser_0017.o UtilsForUser_0018.o UtilsForUser_0019.o UtilsForUser_0020.o UtilsForUser_0021.o UtilsForUser_0022.o UtilsForUser_0023.o UtilsForUser_0024.o -+UTILS_OBJS = UtilsForUser_0000.o UtilsForUser_0001.o UtilsForUser_0002.o UtilsForUser_0003.o UtilsForUser_0004.o UtilsForUser_0005.o UtilsForUser_0006.o UtilsForUser_0007.o UtilsForUser_0008.o UtilsForUser_0009.o UtilsForUser_0010.o UtilsForUser_0011.o UtilsForUser_0012.o UtilsForUser_0013.o UtilsForUser_0014.o UtilsForUser_0015.o UtilsForUser_0016.o UtilsForUser_0017.o UtilsForUser_0018.o UtilsForUser_0019.o UtilsForUser_0020.o UtilsForUser_0021.o UtilsForUser_0022.o UtilsForUser_0023.o UtilsForUser_0024.o UtilsForUser_0025.o UtilsForUser_0026.o - - INTERRUPT_OBJS = InterruptManager_0000.o InterruptManager_0001.o InterruptManager_0002.o InterruptManager_0003.o InterruptManager_0004.o InterruptManager_0005.o InterruptManager_0006.o InterruptManager_0007.o InterruptManager_0008.o InterruptManager_0009.o - -diff -urN a/pspsdk-2450/src/user/UtilsForUser.S b/pspsdk-2450/src/user/UtilsForUser.S ---- a/pspsdk-2450/src/user/UtilsForUser.S 2009-01-09 03:15:40 +0900 -+++ b/pspsdk-2450/src/user/UtilsForUser.S 2009-02-10 16:23:29 +0900 -@@ -77,3 +77,9 @@ - #ifdef F_UtilsForUser_0024 - IMPORT_FUNC "UtilsForUser",0xFB05FAD0,sceKernelIcacheReadTag - #endif -+#ifdef F_UtilsForUser_0025 -+ IMPORT_FUNC "UtilsForUser",0x920F104A,sceKernelIcacheInvalidateAll -+#endif -+#ifdef F_UtilsForUser_0026 -+ IMPORT_FUNC "UtilsForUser",0xC2DF770E,sceKernelIcacheInvalidateRange -+#endif -diff -urN a/pspsdk-2450/src/user/psputils.h b/pspsdk-2450/src/user/psputils.h ---- a/pspsdk-2450/src/user/psputils.h 2009-01-09 03:15:40 +0900 -+++ b/pspsdk-2450/src/user/psputils.h 2009-02-10 16:27:07 +0900 -@@ -58,12 +58,12 @@ - void sceKernelDcacheWritebackInvalidateAll(void); - - /** -- * Write back a range of addresses from data cache to memory -+ * Write back a range of addresses from the data cache to memory - */ - void sceKernelDcacheWritebackRange(const void *p, unsigned int size); - - /** -- * Write back and invalidate a range of addresses in data cache -+ * Write back and invalidate a range of addresses in the data cache - */ - void sceKernelDcacheWritebackInvalidateRange(const void *p, unsigned int size); - -@@ -72,6 +72,16 @@ - */ - void sceKernelDcacheInvalidateRange(const void *p, unsigned int size); - -+/** -+ * Invalidate the instruction cache -+ */ -+void sceKernelIcacheInvalidateAll(void); -+ -+/** -+ * Invalidate a range of addresses in the instruction cache -+ */ -+void sceKernelIcacheInvalidateRange(const void *p, unsigned int size); -+ - /** Structure for holding a mersenne twister context */ - typedef struct _SceKernelUtilsMt19937Context { - unsigned int count; diff --git a/yabause/src/psp/init.c b/yabause/src/psp/init.c deleted file mode 100644 index 92c38ac08c..0000000000 --- a/yabause/src/psp/init.c +++ /dev/null @@ -1,281 +0,0 @@ -/* src/psp/init.c: PSP initialization routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" -#include // For struct tm definition - -#include "../cdbase.h" -#include "../cs0.h" -#include "../m68kcore.h" -#include "../peripheral.h" -#include "../scsp.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vidsoft.h" - -#include "config.h" -#include "control.h" -#include "display.h" -#include "init.h" -#include "localtime.h" -#include "menu.h" -#include "sys.h" -#include "psp-cd.h" -#include "psp-m68k.h" -#include "psp-per.h" -#include "psp-sh2.h" -#include "psp-sound.h" -#include "psp-video.h" - -#include "me.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Interface lists */ - -M68K_struct *M68KCoreList[] = { - /* We only support the ME-enabled Q68 interface */ - &M68KPSP, - NULL -}; - -SH2Interface_struct *SH2CoreList[] = { - &SH2Interpreter, - &SH2DebugInterpreter, - &SH2PSP, - NULL -}; - -PerInterface_struct *PERCoreList[] = { - /* We only support the native interface */ - &PERPSP, - NULL -}; - -CDInterface *CDCoreList[] = { - /* We only support the native interface */ - &CDPSP, - NULL -}; - -SoundInterface_struct *SNDCoreList[] = { - /* We only support the native interface */ - &SNDPSP, - NULL -}; - -VideoInterface_struct *VIDCoreList[] = { - &VIDPSP, - &VIDSoft, - NULL -}; - -/*-----------------------------------------------------------------------*/ - -/* Local routine declarations */ - -static void get_base_directory(const char *argv0, char *buffer, int bufsize); - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * init_psp: Perform PSP-related initialization and command-line option - * parsing. Aborts the program if an error occurs. - * - * [Parameters] - * argc: Command line argument count - * argv: Command line argument vector - * [Return value] - * None - */ -void init_psp(int argc, char **argv) -{ - /* Set the CPU to maximum speed, because boy, do we need it */ - scePowerSetClockFrequency(333, 333, 166); - - /* Determine the program's base directory and change to it */ - get_base_directory(argv[0], progpath, sizeof(progpath)); - if (*progpath) { - sceIoChdir(progpath); - } - - /* Start the system callback monitoring thread */ - if (!sys_setup_callbacks()) { - sceKernelExitGame(); - } - - /* Initialize controller input management */ - if (!control_init()) { - DMSG("Failed to initialize controller"); - sceKernelExitGame(); - } - - /* Initialize the display hardware */ - if (!display_init()) { - DMSG("Failed to initialize display"); - sceKernelExitGame(); - } - - /* Initialize localtime() */ - localtime_init(); - - /* Load the ME access library (if possible) */ - int res = sys_load_module("me.prx", PSP_MEMORY_PARTITION_KERNEL); - if (res < 0) { - DMSG("Failed to load me.prx: %s", psp_strerror(res)); - me_available = 0; - } else { - me_available = 1; - } -} - -/*************************************************************************/ - -/** - * init_yabause: Initialize the emulator core. On error, an appropriate - * error message is registered via menu_set_error(). - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -int init_yabause(void) -{ - yabauseinit_struct yinit; - - /* Set a default error message in case the core doesn't set one */ - menu_set_error("Failed to initialize the emulator!"); - - /* Set up general defaults */ - memset(&yinit, 0, sizeof(yinit)); - yinit.m68kcoretype = M68KCORE_PSP; - yinit.percoretype = PERCORE_PSP; - yinit.sh2coretype = config_get_module_sh2(); - yinit.vidcoretype = config_get_module_video(); - yinit.sndcoretype = SNDCORE_PSP; - yinit.cdcoretype = CDCORE_PSP; - yinit.carttype = CART_NONE; - yinit.regionid = 0; - yinit.biospath = config_get_path_bios(); - yinit.cdpath = config_get_path_cd(); - yinit.buppath = config_get_path_bup(); - yinit.mpegpath = NULL; - yinit.cartpath = NULL; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yinit.clocksync = config_get_clock_sync(); - const time_t basetime = 883656000; // 1998-01-01 12:00 UTC - yinit.basetime = config_get_clock_fixed_time() - ? basetime - localtime_utc_offset() - : 0; - yinit.usethreads = 1; - - /* Initialize controller settings */ - PerInit(yinit.percoretype); - PerPortReset(); - padbits = PerPadAdd(&PORTDATA1); - static const struct { - uint8_t key; // Key index from peripheral.h - uint16_t button; // PSP button index (PSP_CTRL_*) - } buttons[] = { - {PERPAD_UP, PSP_CTRL_UP}, - {PERPAD_RIGHT, PSP_CTRL_RIGHT}, - {PERPAD_DOWN, PSP_CTRL_DOWN}, - {PERPAD_LEFT, PSP_CTRL_LEFT}, - {PERPAD_RIGHT_TRIGGER, PSP_CTRL_RTRIGGER}, - {PERPAD_LEFT_TRIGGER, PSP_CTRL_LTRIGGER}, - {PERPAD_START, PSP_CTRL_START}, - }; - int i; - for (i = 0; i < lenof(buttons); i++) { - PerSetKey(buttons[i].button, buttons[i].key, padbits); - } - PerSetKey(config_get_button(CONFIG_BUTTON_A), PERPAD_A, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_B), PERPAD_B, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_C), PERPAD_C, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_X), PERPAD_X, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_Y), PERPAD_Y, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_Z), PERPAD_Z, padbits); - - /* Initialize emulator state */ - if (YabauseInit(&yinit) != 0) { - DMSG("YabauseInit() failed!"); - return 0; - } - YabauseSetDecilineMode(config_get_deciline_mode()); - ScspSetFrameAccurate(config_get_audio_sync()); - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - - /* Success */ - menu_set_error(NULL); - return 1; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * get_base_directory: Extract the program's base directory from argv[0]. - * Stores the empty string in the destination buffer if the base directory - * cannot be determined. - * - * [Parameters] - * argv0: Value of argv[0] - * buffer: Buffer to store directory path into - * bufsize: Size of buffer - * [Return value] - * None - */ -static void get_base_directory(const char *argv0, char *buffer, int bufsize) -{ - *buffer = 0; - if (argv0) { - const char *s = strrchr(argv0, '/'); - if (s != NULL) { - int n = snprintf(buffer, bufsize, "%.*s", s - argv0, argv0); - if (n >= bufsize) { - DMSG("argv[0] too long: %s", argv0); - *buffer = 0; - } - } else { - DMSG("argv[0] has no directory: %s", argv0); - } - } else { - DMSG("argv[0] is NULL!"); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/init.h b/yabause/src/psp/init.h deleted file mode 100644 index 5ecf1c47ef..0000000000 --- a/yabause/src/psp/init.h +++ /dev/null @@ -1,60 +0,0 @@ -/* src/psp/init.h: PSP initialization routine header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_INIT_H -#define PSP_INIT_H - -/*************************************************************************/ - -/** - * init_psp: Perform PSP-related initialization and command-line option - * parsing. Aborts the program if an error occurs. - * - * [Parameters] - * argc: Command line argument count - * argv: Command line argument vector - * [Return value] - * None - */ -extern void init_psp(int argc, char **argv); - -/** - * init_yabause: Initialize the emulator core. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -extern int init_yabause(void); - -/*************************************************************************/ - -#endif // PSP_INIT_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/localtime.c b/yabause/src/psp/localtime.c deleted file mode 100644 index b037ac1a0a..0000000000 --- a/yabause/src/psp/localtime.c +++ /dev/null @@ -1,157 +0,0 @@ -/* src/psp/localtime.c: PSP implementation of localtime() - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" -#include // For struct tm definition - -#include "localtime.h" -#include "sys.h" - -/*************************************************************************/ - -/* Time zone offset from UTC (amount to add to time() result) */ -static int32_t utc_offset; - -/*************************************************************************/ -/*************************************************************************/ - -/** - * localtime_init: Perform initialization required for localtime(). - * Called by PSP initialization code at program startup. - * - * [Parameters] - * None - * [Return value] - * None - */ -void localtime_init(void) -{ - /* Find the PSP's time zone */ - int utc_offset_min; - int32_t result = sceUtilityGetSystemParamInt( - PSP_SYSTEMPARAM_ID_INT_TIMEZONE, &utc_offset_min - ); - if (result == 0) { - utc_offset = utc_offset_min * 60; - } else { - DMSG("Failed to get time zone: %s", psp_strerror(result)); - utc_offset = 0; - } - - /* Check whether daylight saving time is in use */ - int dst; - result = sceUtilityGetSystemParamInt( - PSP_SYSTEMPARAM_ID_INT_DAYLIGHTSAVINGS, &dst - ); - if (result == 0) { - if (dst) { - utc_offset += 60*60; - } - } else { - DMSG("Failed to get DST status: %s", psp_strerror(result)); - } - -} - -/*************************************************************************/ - -/** - * localtime_utc_offset: Return the UTC offset of the current time zone in - * seconds (for example, GMT-1 has a UTC offset of -3600 seconds). - * - * [Parameters] - * None - * [Return value] - * UTC offset in seconds - */ -int32_t localtime_utc_offset(void) -{ - return utc_offset; -} - -/*************************************************************************/ - -/** - * internal_localtime_r: Local, reentrant version of localtime() used by - * ../smpc.c. Breaks down a timestamp integer into Y/M/D h:m:s - * representation. - * - * [Parameters] - * timep: Timestamp to break down - * result: Broken-down time - * [Return value] - * result, or NULL on error - */ -struct tm *internal_localtime_r(const time_t *timep, struct tm *result) -{ - static const uint8_t mdays[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; - - PRECOND(timep != NULL, return NULL); - PRECOND(result != NULL, return NULL); - time_t t = *timep + utc_offset; - - /* Weekday is simple: ((days since 1970/1/1) + Thursday) % 7 */ - result->tm_wday = (t/86400 + 4) % 7; - - /* Calculate year */ - result->tm_year = 70; - int32_t yearsecs = 365*86400; - while (t >= yearsecs) { - t -= yearsecs; - result->tm_year++; - /* Careful here -- tm_year starts at 1900, not 0 */ - int isleap = (result->tm_year%4 == 0 - && (result->tm_year%100 != 0 - || result->tm_year%400 == 100)); - yearsecs = isleap ? 366*86400 : 365*86400; - } - - /* Calculate month */ - int month = 0; - while (t >= mdays[month] * 86400) { - t -= mdays[month] * 86400; - month++; - } - result->tm_mon = month; - - /* The rest is straightforward */ - result->tm_sec = t % 60; - t /= 60; - result->tm_min = t % 60; - t /= 60; - result->tm_hour = t % 24; - t /= 24; - result->tm_mday = t + 1; - - return result; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/localtime.h b/yabause/src/psp/localtime.h deleted file mode 100644 index e8bf653a48..0000000000 --- a/yabause/src/psp/localtime.h +++ /dev/null @@ -1,76 +0,0 @@ -/* src/psp/localtime.h: PSP localtime() header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_LOCALTIME_H -#define PSP_LOCALTIME_H - -#include -#include // For struct tm declaration - -/*************************************************************************/ - -/** - * localtime_init: Perform initialization required for localtime(). - * Called by PSP initialization code at program startup. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void localtime_init(void); - -/** - * localtime_utc_offset: Return the UTC offset of the current time zone in - * seconds (for example, GMT-1 has a UTC offset of -3600 seconds). - * - * [Parameters] - * None - * [Return value] - * UTC offset in seconds - */ -extern int32_t localtime_utc_offset(void); - -/** - * internal_localtime_r: Local, reentrant version of localtime() used by - * ../smpc.c. Breaks down a timestamp integer into Y/M/D h:m:s - * representation. - * - * [Parameters] - * timep: Timestamp to break down - * result: Broken-down time - * [Return value] - * result, or NULL on error - */ -extern struct tm *internal_localtime_r(const time_t *timep, struct tm *result); - -/*************************************************************************/ - -#endif // PSP_LOCALTIME_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/main.c b/yabause/src/psp/main.c deleted file mode 100644 index 7e6be65bb1..0000000000 --- a/yabause/src/psp/main.c +++ /dev/null @@ -1,265 +0,0 @@ -/* src/psp/main.c: PSP entry point and main loop - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" -#include "../peripheral.h" - -#include "config.h" -#include "control.h" -#include "init.h" -#include "menu.h" -#include "misc.h" -#include "osk.h" -#include "psp-video.h" -#include "timing.h" - -#ifdef SYS_PROFILE_H -# include "profile.h" // Can only be ours -#endif - -/*************************************************************************/ -/************************ PSP module information *************************/ -/*************************************************************************/ - -#define MODULE_FLAGS 0 -#define MODULE_VERSION 0 -#define MODULE_REVISION 9 - -PSP_MODULE_INFO("Yabause", MODULE_FLAGS, MODULE_VERSION, MODULE_REVISION); -const PSP_MAIN_THREAD_PRIORITY(THREADPRI_MAIN); -const PSP_MAIN_THREAD_STACK_SIZE_KB(128); -const PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); -const PSP_HEAP_SIZE_KB(-64); // Leave 64k for thread stacks - -/*************************************************************************/ -/****************************** Global data ******************************/ -/*************************************************************************/ - -/* Program directory (determined from argv[0], and exported) */ -char progpath[256]; - -/* Saturn control pad handle (set at initialization time, and used by menu - * code to change button assignments) */ -void *padbits; - -/* Flag indicating whether the ME is available for use */ -int me_available; - -/* Have we successfully initialized the Yabause core? */ -int yabause_initted; - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Flag indicating whether the menu is currently displayed */ -static int in_menu; - -/* Delay timer for backup RAM autosave */ -static int bup_autosave_timer; -#define BUP_AUTOSAVE_DELAY 60 // frames - -/* Timer for autosave overlay message */ -static int bup_autosave_info_timer; -#define BUP_AUTOSAVE_INFO_TIME 300 // frames - -/* Text and color for autosave overlay message */ -#define BUP_AUTOSAVE_INFO_TEXT "Backup RAM saved." -#define BUP_AUTOSAVE_INFO_COLOR 0xFF55FF40 // TEXT_COLOR_OK from menu.c - -/*-----------------------------------------------------------------------*/ - -/* Local routine declarations */ - -static void iterate_main_loop(void); -static void emulate_one_frame(void); -static void check_autosave(void); - -/*************************************************************************/ -/************************** Program entry point **************************/ -/*************************************************************************/ - -/** - * main: Program entry point. Performs initialization and then loops - * indefinitely, running the emulator. - * - * [Parameters] - * argc: Command line argument count - * argv: Command line argument vector - * [Return value] - * Does not return - */ -int main(int argc, char **argv) -{ - in_menu = 0; - bup_autosave_timer = 0; - bup_autosave_info_timer = 0; - - init_psp(argc, argv); - config_load(); - if (!config_get_start_in_emu()) { - /* Don't initialize yet -- the user may need to set filenames first. */ - menu_open(); - in_menu = 1; - } else { - if (init_yabause()) { - yabause_initted = 1; - } else { - /* Start in the menu so the user sees the error message. */ - menu_open(); - in_menu = 1; - } - } - - timing_init(); - for (;;) { - iterate_main_loop(); - } -} - -/*************************************************************************/ -/*********** Main loop iteration routine and helper functions ************/ -/*************************************************************************/ - -/** - * iterate_main_loop: Run one iteration of the main loop. Either emulates - * one Saturn frame or runs the menu for one PSP frame. - * - * [Parameters] - * buttons: Current state of PSP control buttons - * [Return value] - * None - */ -static void iterate_main_loop(void) -{ - timing_sync(); - control_update(); - - if (control_new_buttons() & PSP_CTRL_SELECT) { - if (in_menu) { - if (osk_status()) { - /* If the OSK is active, SELECT is used to switch character - * sets, so we shouldn't respond to it. */ - } else if (!yabause_initted && !init_yabause()) { - /* We failed to start the emulator, so stay in the menu. */ - } else { - yabause_initted = 1; // In case we just successfully initted - menu_close(); - in_menu = 0; - } - } else { - menu_open(); - in_menu = 1; - } - } - - if (in_menu) { - menu_run(); - } else { - emulate_one_frame(); - } -} - -/*************************************************************************/ - -/** - * emulate_one_frame: Run the emulator for one frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void emulate_one_frame(void) -{ - PERCore->HandleEvents(); // Also runs the actual emulation - - check_autosave(); - - /* Reset the screensaver timeout, so people don't have to deal with - * the backlight dimming during FMV */ - scePowerTick(0); - -#ifdef SYS_PROFILE_H // Print out profiling info every 100 frames - static unsigned int frame = 0; - frame++; - if (frame % 100 == 0) { - printf("Profiling statistics at frame %u:\n", frame); - PROFILE_PRINT(); - PROFILE_RESET(); - } -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * check_autosave: Check whether to autosave backup RAM and/or display the - * autosave message. Should be called exactly once per emulated frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void check_autosave(void) -{ - if (BupRamWritten) { - /* Wait BUP_AUTOSAVE_DELAY frames from the last write before we - * update the file, so we don't update on every frame while the - * emulated game is saving its data. */ - bup_autosave_timer = BUP_AUTOSAVE_DELAY; - BupRamWritten = 0; - } else if (bup_autosave_timer > 0) { - bup_autosave_timer--; - if (bup_autosave_timer == 0) { - save_backup_ram(); - bup_autosave_info_timer = BUP_AUTOSAVE_INFO_TIME; - } - } - - if (bup_autosave_info_timer > 0) { - uint32_t color; - if (bup_autosave_info_timer >= BUP_AUTOSAVE_INFO_TIME / 2) { - color = BUP_AUTOSAVE_INFO_COLOR; - } else { - const uint32_t alpha = - (255 * bup_autosave_info_timer) / (BUP_AUTOSAVE_INFO_TIME / 2); - color = alpha<<24 | (BUP_AUTOSAVE_INFO_COLOR & 0x00FFFFFF); - } - psp_video_infoline(color, BUP_AUTOSAVE_INFO_TEXT); - bup_autosave_info_timer--; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me-sectend.c b/yabause/src/psp/me-sectend.c deleted file mode 100644 index 348897b726..0000000000 --- a/yabause/src/psp/me-sectend.c +++ /dev/null @@ -1,5 +0,0 @@ -// Define section end symbols for ../scsp.c -__attribute__((section(".meshared.scsp.sc_write"), aligned(64))) - volatile char __scsp_sectend_sc_write; -__attribute__((section(".meshared.scsp.me_write"), aligned(64))) - volatile char __scsp_sectend_me_write; diff --git a/yabause/src/psp/me-sectstart.c b/yabause/src/psp/me-sectstart.c deleted file mode 100644 index 13d3232a09..0000000000 --- a/yabause/src/psp/me-sectstart.c +++ /dev/null @@ -1,5 +0,0 @@ -// Define section start symbols for ../scsp.c -__attribute__((section(".meshared.scsp.sc_write"), aligned(64))) - volatile char __scsp_sectstart_sc_write[64]; -__attribute__((section(".meshared.scsp.me_write"), aligned(64))) - volatile char __scsp_sectstart_me_write[64]; diff --git a/yabause/src/psp/me-test.c b/yabause/src/psp/me-test.c deleted file mode 100644 index 2ea1ee3b49..0000000000 --- a/yabause/src/psp/me-test.c +++ /dev/null @@ -1,1468 +0,0 @@ -/* src/psp/me-test.c: Test program for PSP Media Engine access library - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include -/* Helpful hint for GCC */ -extern void sceKernelExitGame(void) __attribute__((noreturn)); - -#include "me.h" -#include "me-utility.h" - -/* Macro to get the length of an array */ -#define lenof(a) (sizeof((a)) / sizeof((a)[0])) - -/* Size of the ME's data cache, in bytes */ -#define ME_DCACHE_SIZE (256*64) // 256 cache lines of 64 bytes each - -/*************************************************************************/ -/************************ PSP module information *************************/ -/*************************************************************************/ - -#define MODULE_FLAGS \ - (PSP_MODULE_USER | PSP_MODULE_SINGLE_LOAD | PSP_MODULE_SINGLE_START) -#define MODULE_VERSION 1 -#define MODULE_REVISION 0 - -PSP_MODULE_INFO("me-test", MODULE_FLAGS, MODULE_VERSION, MODULE_REVISION); -const PSP_MAIN_THREAD_PRIORITY(32); -const PSP_MAIN_THREAD_STACK_SIZE_KB(64); -const PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); -const PSP_HEAP_SIZE_KB(-64); - -/*************************************************************************/ -/******************* Forward declarations of routines ********************/ -/*************************************************************************/ - -static int test_meStart(void); -static int test_meCall(void); -static int test_mePoll(void); -static int test_meWait(void); -static int test_meResult(void); -static int test_meException(void); -static int test_meStop(void); -static int test_restart(void); -static int test_meIsME_SC(void); -static int test_meIsME_ME(void); -static int test_meInterruptWait(void); -static int test_meInterruptPoll(void); -static int test_meInterruptClear(void); -static int test_icache(void); -static int test_icache_inval(void); -static int test_dcache_read(void); -static int test_dcache_write(void); -static int test_dcache_inval(void); -static int test_dcache_wbinv(void); - -static int mefunc_return_123(void *param); -static int mefunc_store_456(void *param); -static int mefunc_delay_and_store_789(void *param); -static int mefunc_count_forever(void *param); -static int mefunc_address_error(void *param); -static int mefunc_return_IsME(void *param); -static int mefunc_send_interrupt(void *param); -static int mefunc_dcache_read(void *param); -static int mefunc_dcache_write(void *param); -static int mefunc_dcache_inval(void *param); -static int mefunc_dcache_wbinv(void *param); - -static __attribute__((always_inline)) void delay(const unsigned int cycles); - -/*************************************************************************/ -/***************************** List of tests *****************************/ -/*************************************************************************/ - -typedef struct TestInfo_ { - /* Name of this test */ - const char * const name; - - /* Name of a previous test which must have passed in order to run this - * test (or NULL if none) */ - const char * const precondition; - - /* Routine implementing test */ - int (* const routine)(void); - - /* Result of test (nonzero = passed, zero = failed or not executed) */ - int passed; -} TestInfo; - -static TestInfo tests[] = { - {"meStart", NULL, test_meStart}, - {"meCall", "meStart", test_meCall}, - {"mePoll", "meStart", test_mePoll}, - {"meWait", "meStart", test_meWait}, - {"meResult", "meWait", test_meResult}, - {"meException", "meWait", test_meException}, - {"meStop", "meResult", test_meStop}, - {"restart", "meStop", test_restart}, - - {"meIsME-SC", "restart", test_meIsME_SC}, - {"meIsME-ME", "meIsME-SC", test_meIsME_ME}, - - {"meInterruptWait", "restart", test_meInterruptWait}, - {"meInterruptPoll", "meInterruptWait", test_meInterruptPoll}, - {"meInterruptClear", "meInterruptPoll", test_meInterruptClear}, - - {"icache", "restart", test_icache}, - {"icache-inval", "restart", test_icache_inval}, - {"dcache-read", "restart", test_dcache_read}, - {"dcache-write", "restart", test_dcache_write}, - {"dcache-inval", "restart", test_dcache_inval}, - {"dcache-wbinv", "restart", test_dcache_wbinv}, -}; - -/*************************************************************************/ -/****************************** Entry point ******************************/ -/*************************************************************************/ - -/** - * main: Program entry point. Calls each of the individual tests and - * reports on their success or failure. - * - * [Parameters] - * None - * [Return value] - * Does not return - */ -int main(void) -{ - /* Don't buffer stdout (since we print partial lines as we test). */ - setbuf(stdout, NULL); - - /* Wait a moment to let PSPlink print its "module started" line before - * we start outputting anything, and output a blank line so the first - * line doesn't follow the PSPlink prompt. */ - sceKernelDelayThread(100000); - printf("\n"); - - /* Load the ME library. */ - SceKernelLMOption lmopts; - memset(&lmopts, 0, sizeof(lmopts)); - lmopts.size = sizeof(lmopts); - lmopts.mpidtext = PSP_MEMORY_PARTITION_KERNEL; - lmopts.mpiddata = PSP_MEMORY_PARTITION_KERNEL; - lmopts.position = 0; - lmopts.access = 1; - SceUID modid = sceKernelLoadModule("me.prx", 0, &lmopts); - if (modid < 0) { - fprintf(stderr, "Failed to load me.prx: %08X\n", modid); - sceKernelExitGame(); - } - int dummy; - int res = sceKernelStartModule(modid, strlen("me.prx")+1, "me.prx", - &dummy, NULL); - if (res < 0) { - fprintf(stderr, "Failed to start me.prx: %08X\n", res); - sceKernelUnloadModule(modid); - sceKernelExitGame(); - } - - /* Run all tests in order. */ - unsigned int num_passed = 0, num_skipped = 0; - unsigned int i; - for (i = 0; i < lenof(tests); i++) { - printf("%s...", tests[i].name); - int can_run = 1; - if (tests[i].precondition) { - unsigned int precond_index; - for (precond_index = 0; precond_index < i; precond_index++) { - if (strcmp(tests[i].precondition, - tests[precond_index].name) == 0) { - break; - } - } - if (precond_index >= i) { - printf("skipped (precondition \"%s\" not found or not yet" - " run)\n", tests[i].precondition); - can_run = 0; - } else if (!tests[precond_index].passed) { - printf("skipped (precondition \"%s\" failed or was skipped)", - tests[i].precondition); - can_run = 0; - } - } - if (can_run) { - tests[i].passed = (*tests[i].routine)(); - if (tests[i].passed) { - num_passed++; - printf("passed\n"); - } else { - printf("FAILED\n"); - } - } else { - num_skipped++; - } - } - - /* Print a summary of all results. */ - printf("\n"); - if (num_passed == lenof(tests)) { - printf("All tests passed.\n"); - } else { - printf("%u/%u tests passed (%u failed, %u skipped).\n", - num_passed, lenof(tests), - lenof(tests) - num_passed - num_skipped, num_skipped); - } - printf("\n"); - - /* All done. */ - sceKernelExitGame(); -} - -/*************************************************************************/ -/***************************** Test routines *****************************/ -/*************************************************************************/ - -/** - * test_meStart: Test that the meStart() function succeeds on both the - * first call and a subsequent call. - * - * If the test passes, the ME has been started and can be used in - * subsequent tests. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meStart(void) -{ - int res; - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #1 failed: %08X\n", res); - return 0; - } - - /* Wait for the ME to become ready (done with a manual delay loop since - * we don't assume that any other library functions work yet). */ - delay(1000000); - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #2 failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meCall: Test that the meCall() function can be used to execute a - * routine on the ME. - * - * Assumes that test_meStart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meCall(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_store_456, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - /* Since we don't yet assume meWait() to work properly, delay long - * enough for the function to finish executing before we check whether - * it successfully ran. */ - delay(1000000); - if ((res = *bufptr) != 456) { - fprintf(stderr, "Bad value in buffer (expected 456, got %d)", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_mePoll: Test that the mePoll() function can be used to check - * whether the ME is idle. - * - * Assumes that test_meStart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_mePoll(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_delay_and_store_789, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 0) { - fprintf(stderr, "Bad value in buffer (expected 0, got %d)", res); - return 0; - } - - if ((res = mePoll()) != ME_ERROR_BUSY) { - if (res == 0) { - fprintf(stderr, "mePoll() #1 returned idle\n"); - } else { - fprintf(stderr, "mePoll() #1 failed: %08X\n", res); - } - return 0; - } - - delay(2000000); - if ((res = *bufptr) != 789) { - fprintf(stderr, "Bad value in buffer (expected 789, got %d)", res); - return 0; - } - - if ((res = mePoll()) != 0) { - fprintf(stderr, "mePoll() #2 failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meWait: Test that the meWait() function can be used to wait for - * the ME to become idle. - * - * Assumes that test_meStart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meWait(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_delay_and_store_789, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 0) { - fprintf(stderr, "Bad value in buffer (expected 0, got %d)", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 789) { - fprintf(stderr, "Bad value in buffer (expected 789, got %d)", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meResult: Test that the meResult() function can be used to - * retrieve the result of a routine executed on the ME. - * - * Assumes that test_meWait() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meResult(void) -{ - int res; - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) != 123) { - fprintf(stderr, "meResult() gave wrong result (expected 123, got" - " %d)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meException: Test that the meException() function can be used to - * retrieve the exception status of a routine executed on the ME. - * - * Assumes that test_meWait() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meException(void) -{ - int res; - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meException()) != 0) { - fprintf(stderr, "meException() #1 gave wrong result (expected 0, got" - " %d)\n", res); - return 0; - } - - if ((res = meCall(mefunc_address_error, NULL)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meException()) == 0) { - fprintf(stderr, "meException() #2 gave wrong result (expected" - " nonzero, got zero)\n"); - return 0; - } - - uint32_t BadVAddr = 0, Status = 0, Cause = 0, EPC = 0, ErrorEPC = 0; - meExceptionGetData(&BadVAddr, &Status, &Cause, &EPC, &ErrorEPC); - fprintf(stderr, "Exception data:\n"); - fprintf(stderr, " BadVAddr = %08X\n", BadVAddr); - fprintf(stderr, " Status = %08X\n", Status); - fprintf(stderr, " Cause = %08X\n", Cause); - fprintf(stderr, " EPC = %08X\n", EPC); - fprintf(stderr, " ErrorEPC = %08X\n", ErrorEPC); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meStop: Test that the meStop() function can be used to halt the ME. - * - * Assumes that test_meResult() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meStop(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_count_forever, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - delay(1000000); // Let the counter run for a bit - - /* Stopping the ME while a function is executing is technically an - * undefined operation, but since all the function does is increment a - * counter, we assume it's safe. */ - meStop(); - - delay(1000000); // The ME should be stopped already, but wait to be sure - - int last_count = *bufptr; - delay(1000000); - if ((res = *bufptr) != last_count) { - fprintf(stderr, "meStop() failed to stop ME (counter changed from" - " %d to %d)", last_count, res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_restart: Test that the ME can be safely stopped and restarted - * using the meStop() and meStart() functions. - * - * Assumes that test_meStop() has passed and the ME is currently stopped. - * If the test passes, the ME has been restarted and can be used in - * subsequent tests. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_restart(void) -{ - int res; - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1A failed: %08X\n", res); - return 0; - } - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1B failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) != 123) { - fprintf(stderr, "meResult() #1 gave wrong result (expected 123, got" - " %d)\n", res); - return 0; - } - - meStop(); - delay(1000000); // Wait for the system to settle (just in case) - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2A failed: %08X\n", res); - return 0; - } - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2B failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) != 123) { - fprintf(stderr, "meResult() #2 gave wrong result (expected 123, got" - " %d)\n", res); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * test_meIsME_SC: Test that meUtilityIsME() properly returns zero when - * executing on the SC. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meIsME_SC(void) -{ - int res = meUtilityIsME(); - - if (res != 0) { - fprintf(stderr, "meUtilityIsME() returned nonzero (%d) on SC\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meIsME_ME: Test that meUtilityIsME() properly returns nonzero when - * executing on the ME. - * - * Assumes that test_meIsME() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meIsME_ME(void) -{ - int res; - - if ((res = meCall(mefunc_return_IsME, NULL)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) == 0) { - fprintf(stderr, "meResult() gave wrong result (expected nonzero," - " got 0)\n"); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * test_meInterruptWait: Test that meUtilitySendInterrupt() can be used by - * ME code to send an interrupt to the main CPU, and that meInterruptWait() - * can be used to wait until the interrupt is received. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meInterruptWait(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_send_interrupt, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 0) { - fprintf(stderr, "Bad value in buffer (expected 0, got %d)", res); - return 0; - } - - if ((res = meInterruptWait()) != 0) { - fprintf(stderr, "meInterruptWait() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 654) { - fprintf(stderr, "Bad value in buffer (expected 654, got %d)", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meInterruptPoll: Test that meInterruptPoll() can be used to check - * whether an ME interrupt is pending without clearing the interrupt. Also - * check that meInterruptWait() clears the interrupt after waiting for it. - * - * Assumes that test_meInterruptWait() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meInterruptPoll(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_send_interrupt, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #1 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - delay(2000000); - - if ((res = meInterruptPoll()) != 0) { - fprintf(stderr, "meInterruptPoll() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptWait()) != 0) { - fprintf(stderr, "meInterruptWait() failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #3 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meInterruptClear: Test that meInterruptClear() can be used to - * clear a pending ME interrupt. - * - * Assumes that test_meInterruptPoll() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meInterruptClear(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_send_interrupt, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #1 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - delay(2000000); - - if ((res = meInterruptPoll()) != 0) { - fprintf(stderr, "meInterruptPoll() #2 failed: %08X\n", res); - return 0; - } - - meInterruptClear(); - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #3 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * test_icache: Test that the ME's instruction cache operates as expected. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_icache(void) -{ - static __attribute__((aligned(64))) uint32_t insn_buf[2]; - volatile uint32_t *insn_ptr = - (volatile uint32_t *)((uintptr_t)&insn_buf[0] | 0x40000000); - int res; - - insn_ptr[0] = 0x03E00008; // jr $ra - insn_ptr[1] = 0x34021234; // li $v0, 0x1234 - - /* Note that we use insn_buf (the cacheable version) rather than - * insn_ptr (the uncacheable one), because we want the ME to cache the - * instructions and therefore _not_ pick up our subsequent change. */ - if ((res = meCall((void *)insn_buf, NULL)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x1234) { - fprintf(stderr, "meResult() #1 gave wrong result (expected 0x1234," - " got 0x%X)\n", res); - return 0; - } - - insn_ptr[1] = 0x34025678; // li $v0, 0x5678 (not seen by ME) - - if ((res = meCall((void *)insn_buf, NULL)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x1234) { - fprintf(stderr, "meResult() #2 gave wrong result (expected 0x1234," - " got 0x%X)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_icache_inval: Test that meUtilityIcacheInvalidateAll() can be used - * to invalidate the ME's instruction cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_icache_inval(void) -{ - static __attribute__((aligned(64))) uint32_t insn_buf[8]; - volatile uint32_t *insn_ptr = - (volatile uint32_t *)((uintptr_t)insn_buf | 0x40000000); - int res; - - insn_ptr[0] = 0x27BDFFF8; // addiu $sp, $sp, -8 - insn_ptr[1] = 0xAFBF0004; // sw $ra, 4($sp) - insn_ptr[2] = 0x0080F809; // jalr $a0 - insn_ptr[3] = 0x00000000; // nop - insn_ptr[4] = 0x8FBF0004; // lw $ra, 4($sp) - insn_ptr[5] = 0x34024321; // li $v0, 0x4321 - insn_ptr[6] = 0x03E00008; // jr $ra - insn_ptr[7] = 0x27BD0008; // addiu $sp, $sp, 8 - - /* Use mefunc_return_123() as a do-nothing function to take the place of - * meUtilityIcacheInvalidateAll(). */ - if ((res = meCall((void *)insn_buf, mefunc_return_123)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x4321) { - fprintf(stderr, "meResult() #1 gave wrong result (expected 0x4321," - " got 0x%X)\n", res); - return 0; - } - - /* Change the load instruction from the main CPU, but don't flush the - * ME's cache. */ - - insn_ptr[5] = 0x34025432; // li $v0, 0x5432 (not seen by ME) - - if ((res = meCall((void *)insn_buf, mefunc_return_123)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x4321) { - fprintf(stderr, "meResult() #2 gave wrong result (expected 0x4321," - " got 0x%X)\n", res); - return 0; - } - - /* Change the load instruction and flush the ME's cache. */ - - insn_ptr[5] = 0x34026543; // li $v0, 0x6543 - - if ((res = meCall((void *)insn_buf, meUtilityIcacheInvalidateAll)) != 0) { - fprintf(stderr, "meCall() #3 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #3 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x6543) { - fprintf(stderr, "meResult() #3 gave wrong result (expected 0x6543," - " got 0x%X)\n", res); - return 0; - } - - /* Test once more to make sure the new instruction is properly cached. */ - - insn_ptr[5] = 0x34027654; // li $v0, 0x7654 (not seen by ME) - - if ((res = meCall((void *)insn_buf, mefunc_return_123)) != 0) { - fprintf(stderr, "meCall() #4 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #4 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x6543) { - fprintf(stderr, "meResult() #4 gave wrong result (expected 0x6543," - " got 0x%X)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_read: Test that the ME's data cache operates as expected - * when reading from the cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_read(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0; - } - - if ((res = meCall(mefunc_dcache_read, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - /* Wait long enough for the ME to finish reading from the buffer before - * we update it. */ - delay(ME_DCACHE_SIZE*4); // Experimentally determined to be sufficient - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0xFFFFFFFF; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0) { - fprintf(stderr, "meResult() gave wrong result (expected 0, got %d)\n", - res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_write: Test that the ME's data cache operates as expected - * when writing to the cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_write(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = -1; - } - - if ((res = meCall(mefunc_dcache_write, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - /* Wait long enough for the ME to finish writing to the buffer before - * we read from it. We don't use meWait() because allowing the - * function to return will flush some lines from the cache when the - * library updates its internal state. */ - delay(ME_DCACHE_SIZE*4); - - res = -1; - for (i = 0; i < lenof(buffer); i++) { - res &= bufptr[i]; - } - if (res != -1) { - fprintf(stderr, "Bad buffer contents (expected -1, got %d)\n", res); - meWait(); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_inval: Test that meUtilityDcacheInvalidateAll() can be used - * to invalidate the ME's data cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_inval(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0xFFFFFFFF; - } - - if ((res = meCall(mefunc_dcache_inval, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - res = -1; - for (i = 0; i < lenof(buffer); i++) { - res &= bufptr[i]; - } - if (res != -1) { - fprintf(stderr, "Bad buffer contents (expected -1, got %d)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_wbinv: Test that meUtilityDcacheWritebackInvalidateAll() - * can be used to flush (write back and invalidate) the ME's data cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_wbinv(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0xFFFFFFFF; - } - - if ((res = meCall(mefunc_dcache_wbinv, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - res = 0; - for (i = 0; i < lenof(buffer); i++) { - res |= bufptr[i]; - } - if (res != 0) { - fprintf(stderr, "Bad buffer contents (expected 0, got %d)\n", res); - return 0; - } - - - return 1; -} - -/*************************************************************************/ -/********************** Routines executed on the ME **********************/ -/*************************************************************************/ - -/** - * mefunc_return_123: Return 123 to the caller. - * - * [Parameters] - * param: Unused - * [Return value] - * 123 - */ -static int mefunc_return_123(void *param) -{ - return 123; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_store_456: Store 456 in the location pointed to by the parameter. - * - * [Parameters] - * param: Pointer to an int variable to receive 456. - * [Return value] - * 0 - */ -static int mefunc_store_456(void *param) -{ - *(int *)param = 456; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_delay_and_store_789: Delay for 1M cycles, then Store 789 in the - * location pointed to by the parameter. - * - * [Parameters] - * param: Pointer to an int variable to receive 789 - * [Return value] - * 0 - */ -static int mefunc_delay_and_store_789(void *param) -{ - delay(1000000); - *(int *)param = 789; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_count_forever: Loop indefinitely, continuously incrementing the - * location pointed to by the parameter. - * - * [Parameters] - * param: Pointer to an int variable to be continuously incremented - * [Return value] - * Does not return - */ -static int mefunc_count_forever(void *param) -{ - volatile int *ptr = (volatile int *)param; - for (;;) { - (*ptr)++; - } - return 0; // Not reached, but avoid a compiler warning -} - -/*************************************************************************/ - -/** - * mefunc_address_error: Trigger an address error by accessing an - * unaligned value. - * - * [Parameters] - * param: Unused - * [Return value] - * Does not return - */ -static int mefunc_address_error(void *param) -{ - int dummy = 321; - return *(int *)((uintptr_t)&dummy | 1); -} - -/*************************************************************************/ - -/** - * mefunc_return_IsME(): Return the value returned by meUtilityIsME(). - * - * [Parameters] - * param: Unused - * [Return value] - * Nonzero - */ -static int mefunc_return_IsME(void *param) -{ - return meUtilityIsME(); -} - -/*************************************************************************/ - -/** - * mefunc_send_interrupt: Wait 1M cycles, then store 654 in the location - * pointed to by the parameter and send an interrupt to the main CPU. - * - * [Parameters] - * param: Pointer to an int variable to receive 654 - * [Return value] - * 0 - */ -static int mefunc_send_interrupt(void *param) -{ - delay(1000000); - *(int *)param = 654; - meUtilitySendInterrupt(); - return 0; -} - -/*************************************************************************/ - -/** - * mefunc_dcache_read: Read ME_DCACHE_SIZE/4 words of memory starting at - * the location pointed to by the parameter, wait 1M cycles, then read the - * same words and return their combined bitwise OR. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * Bitwise OR of all words in buffer - */ -static int mefunc_dcache_read(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - uint32_t res; - int i; - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - (void) ptr[i]; - } - - delay(1000000); - - res = 0; - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - res |= ptr[i]; - } - return res; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_dcache_write: Write all zeroes to ME_DCACHE_SIZE/4 words of - * memory starting at the location pointed to by the parameter, then wait - * 1M cycles before returning. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * 0 - */ -static int mefunc_dcache_write(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - int i; - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - ptr[i] = 0; - } - - delay(1000000); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_dcache_inval: Write all zeroes to ME_DCACHE_SIZE/4 words of - * memory starting at the location pointed to by the parameter, then - * invalidate the data cache (thus nullifying the writes) and return. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * 0 - */ -static int mefunc_dcache_inval(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - int i; - - /* Normally, we would have to flush the data cache once to ensure that - * values pushed to the stack (like $ra) were properly stored to memory - * before the invalidate call. In this case, however, we completely - * replace the cache set, so any cached stack values will be implicitly - * flushed by the time we're done. */ - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - ptr[i] = 0; - } - - meUtilityDcacheInvalidateAll(); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_dcache_wbinv: Write all zeroes to ME_DCACHE_SIZE/4 words of - * memory starting at the location pointed to by the parameter, then flush - * the data cache and return. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * 0 - */ -static int mefunc_dcache_wbinv(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - int i; - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - ptr[i] = 0; - } - - meUtilityDcacheWritebackInvalidateAll(); - return 0; -} - -/*************************************************************************/ -/************************ Other utility routines *************************/ -/*************************************************************************/ - -/** - * delay: Delay the calling function for approximately the given number of - * CPU clock cycles. The actual length of the delay may differ from the - * requested length by up to four cycles. - * - * [Parameters] - * cycles: Cycles to delay - * [Return value] - * None - */ -static __attribute__((always_inline)) void delay(const unsigned int cycles) -{ - unsigned int iterations = cycles/4; - asm volatile(" .set push; .set noreorder\n" - "1: bnez %[iterations], 1b\n" - " addiu %[iterations], %[iterations], -1\n" - " .set pop" - : [iterations] "=r" (iterations) - : "0" (iterations) - ); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me-utility.c b/yabause/src/psp/me-utility.c deleted file mode 100644 index 8731520ffe..0000000000 --- a/yabause/src/psp/me-utility.c +++ /dev/null @@ -1,136 +0,0 @@ -/* src/psp/me-utility.c: PSP Media Engine utility routines - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "me.h" -#include "me-utility.h" - -/*************************************************************************/ -/*************************************************************************/ - -/** - * meUtilityIcacheInvalidateAll: Invalidate all entries in the Media - * Engine's instruction cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilityIcacheInvalidateAll(void) -{ - unsigned int cachesize_bits; - asm volatile("mfc0 %0, $16; ext %0, %0, 9, 3" : "=r" (cachesize_bits)); - const unsigned int cachesize = 4096 << cachesize_bits; - - asm volatile("mtc0 $zero, $28"); // TagLo - asm volatile("mtc0 $zero, $29"); // TagHi - unsigned int i; - for (i = 0; i < cachesize; i += 64) { - asm volatile("cache 0x1, 0(%0)" : : "r" (i)); - asm volatile("cache 0x3, 0(%0)" : : "r" (i)); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * meUtilityDcacheInvalidateAll: Invalidate all entries in the Media - * Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilityDcacheInvalidateAll(void) -{ - unsigned int cachesize_bits; - asm volatile("mfc0 %0, $16; ext %0, %0, 6, 3" : "=r" (cachesize_bits)); - const unsigned int cachesize = 4096 << cachesize_bits; - - asm volatile("mtc0 $zero, $28"); // TagLo - asm volatile("mtc0 $zero, $29"); // TagHi - unsigned int i; - for (i = 0; i < cachesize; i += 64) { - asm volatile("cache 0x11, 0(%0)" : : "r" (i)); - asm volatile("cache 0x13, 0(%0)" : : "r" (i)); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * meUtilityDcacheWritebackInvalidateAll: Write back and then invalidate - * all entries in the Media Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilityDcacheWritebackInvalidateAll(void) -{ - unsigned int cachesize_bits; - asm volatile("mfc0 %0, $16; ext %0, %0, 6, 3" : "=r" (cachesize_bits)); - const unsigned int cachesize = 4096 << cachesize_bits; - - unsigned int i; - for (i = 0; i < cachesize; i += 64) { - asm volatile("cache 0x14, 0(%0)" : : "r" (i)); - } - asm volatile("sync"); -} - -/*************************************************************************/ - -/** - * meUtilitySendInterrupt: Send an interrupt to the main CPU. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilitySendInterrupt(void) -{ - asm volatile("sync"); - asm volatile("sw %0, 0x44(%1)" : : "r" (1), "r" (0xBC100000)); - asm volatile("sync"); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me-utility.h b/yabause/src/psp/me-utility.h deleted file mode 100644 index 460f0a60d6..0000000000 --- a/yabause/src/psp/me-utility.h +++ /dev/null @@ -1,105 +0,0 @@ -/* src/psp/me-utility.h: PSP Media Engine utility routine header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ME_UTILITY_H -#define ME_UTILITY_H - -/*************************************************************************/ - -/** - * meUtilityIsME: Return whether the current CPU is the ME (nonzero) or - * the SC (zero). - * - * [Parameters] - * None - * [Return value] - * Nonzero if executing on the ME, zero if executing on the SC - */ -static inline int meUtilityIsME(void) -{ - int test; - asm("xor %0, $k0, %1" : "=r" (test) : "r" (ME_K0_MAGIC)); - return test == 0; -} - -/*----------------------------------*/ - -/** - * meUtilityIcacheInvalidateAll: Invalidate all entries in the Media - * Engine's instruction cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilityIcacheInvalidateAll(void); - -/** - * meUtilityDcacheInvalidateAll: Invalidate all entries in the Media - * Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilityDcacheInvalidateAll(void); - -/** - * meUtilityDcacheWritebackInvalidateAll: Write back and then invalidate - * all entries in the Media Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilityDcacheWritebackInvalidateAll(void); - -/** - * meUtilitySendInterrupt: Send an interrupt to the main CPU. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilitySendInterrupt(void); - -/*************************************************************************/ - -#endif // ME_UTILITY_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me.c b/yabause/src/psp/me.c deleted file mode 100644 index df81d811e3..0000000000 --- a/yabause/src/psp/me.c +++ /dev/null @@ -1,936 +0,0 @@ -/* src/psp/me.c: PSP Media Engine access library - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * This library provides simple, low-level access to the Media Engine CPU. - * Typical usage is as follows (error checks are omitted): - * - * init() { - * meStart(); - * } - * - * main() { - * meCall(function, parameter); - * meWait(); // or use mePoll() in a loop - * if (meException()) { - * // An exception (address error, etc.) occurred - * } else { - * result = meResult(); - * } - * } - * - * Code running on the Media Engine cannot call any external library - * functions which are gated through the syscall interface (which naturally - * includes all firmware functions). However, a few utility functions are - * available in me-utility.[ch] for operations such as cache management. - * - * This library trusts the caller completely, and runs code on the ME in - * kernel mode. Callers must therefore be careful about errors in the - * functions they execute, since improper writes to hardware registers - * could destroy flash or Memory Stick data or have other catastrophic - * results. - * - * Naturally, this library cannot be used alongside any firmware functions - * which make use of the ME, such as audio or video decoding. It is also - * currently impossible to suspend the PSP with the power switch after - * calling meStart(), even if meStop() is later called to halt ME - * processing. (Further investigation is needed to determine why this - * occurs.) - */ - -#include -extern int sceSysregAvcResetEnable(void); // Missing from pspsysreg.h - -#include "me.h" - -/*************************************************************************/ -/************************ PSP module information *************************/ -/*************************************************************************/ - -#define MODULE_FLAGS \ - (PSP_MODULE_KERNEL | PSP_MODULE_SINGLE_LOAD | PSP_MODULE_SINGLE_START) -#define MODULE_VERSION 1 -#define MODULE_REVISION 1 - -PSP_MODULE_INFO("melib", MODULE_FLAGS, MODULE_VERSION, MODULE_REVISION); - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Local function declarations */ - -static void maybe_raise_exception(void); - -static int interrupt_handler(void); - -extern void me_init, me_init_end; -__attribute__((section(".text.me"), noreturn)) void me_loop(void); -__attribute__((section(".text.me"), noreturn)) void me_exception_finish(void); - -/*************************************************************************/ - -/* Has the ME been started? */ - -static int me_started; - -/* Should ME exceptions be fatal to the caller? */ - -static int exceptions_are_fatal; - -/*----------------------------------*/ - -/* Message block for signaling between the main CPU and Media Engine */ - -typedef struct MEMessageBlock_ { - /* ME idle flag; nonzero indicates that the Media Engine is idle and - * ready to accept a new execute request. Set only by the ME; cleared - * only by the main CPU. */ - int idle; - - /* Execute request flag; nonzero indicates that the execute request - * fields below have been filled in and the ME should start executing - * the given function. Set only by the main CPU; cleared only by the - * ME (except when cleared by the main CPU before starting the ME). */ - int request; - - /* Function to be executed. Written only by the main CPU. */ - int (*function)(void *); - - /* Argument to be passed to function. Written only by the main CPU. */ - void *argument; - - /* Return value of last function executed. Written only by the ME. */ - int result; - - /* Exception flag; nonzero indicates that the last function executed on - * the ME triggered an exception. Set only by the ME; cleared only by - * the main CPU. */ - int exception; -} MEMessageBlock; - -static volatile __attribute__((aligned(64))) - MEMessageBlock message_block_buffer; - -/*----------------------------------*/ - -/* Buffer for storing registers on an ME exception (buffer size must be a - * multiple of the cache line size) */ - -typedef struct MEExceptionRegs_ { - uint32_t r[32]; - uint32_t hi, lo; - uint32_t BadVAddr; - uint32_t Status; - uint32_t Cause; - uint32_t EPC; - uint32_t ErrorEPC; - uint32_t pad[9]; -} MEExceptionRegs; - -static __attribute__((aligned(64),used)) MEExceptionRegs exception_registers; - -/*----------------------------------*/ - -/* Event flag used for catching ME interrupts */ - -static SceUID interrupt_flag; - -/*************************************************************************/ -/************************** Module entry points **************************/ -/*************************************************************************/ - -/** - * module_start: Entry point called when the module is started. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int module_start(void); -int module_start(void) -{ - /* Create an event flag for receiving interrupts from the ME. */ - interrupt_flag = sceKernelCreateEventFlag("meInterruptFlag", - PSP_EVENT_WAITMULTIPLE, 0, 0); - if (interrupt_flag < 0) { - return interrupt_flag; - } - - /* Install our interrupt handler (overwriting any handler installed - * by the firmware). */ - sceKernelReleaseIntrHandler(31); - int res = - sceKernelRegisterIntrHandler(31, 2, interrupt_handler, NULL, NULL); - if (res < 0) { - sceKernelDeleteEventFlag(interrupt_flag); - interrupt_flag = 0; - return res; - } - sceKernelEnableIntr(31); - - return 0; -} - -/*************************************************************************/ - -/** - * module_stop: Entry point called when the module is stopped. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int module_stop(void); -int module_stop(void) -{ - if (me_started) { - meStop(); - } - - sceKernelDisableIntr(31); - sceKernelReleaseIntrHandler(31); - - sceKernelDeleteEventFlag(interrupt_flag); - interrupt_flag = 0; - - return 0; -} - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * meStart: Start up the Media Engine. This function must be called - * before any other Media Engine operations are performed. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -int meStart(void) -{ - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - - if (me_started) { - asm volatile("move $k1, %0" : : "r" (old_k1)); - return 0; - } - - /* We generate this pointer on the fly rather than storing it in a - * static variable because attempting to access that static variable - * would pull in the cache line, which is exactly what we're trying - * to avoid. */ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - message_block->idle = 0; - message_block->request = 0; - meInterruptClear(); - - /* Roll our own memcpy() to avoid an unneeded libc reference. */ - const uint32_t *src = (const uint32_t *)&me_init; - const uint32_t *src_top = (const uint32_t *)&me_init_end; - uint32_t *dest = (uint32_t *)0xBFC00040; - for (; src < src_top; src++, dest++) { - *dest = *src; - } - - /* Flush the data cache, just to be safe. */ - sceKernelDcacheWritebackInvalidateAll(); - - int res; - if ((res = sceSysregMeResetEnable()) < 0 - || (res = sceSysregMeBusClockEnable()) < 0 - || (res = sceSysregMeResetDisable()) < 0 - ) { - asm volatile("move $k1, %0" : : "r" (old_k1)); - return res; - } - - me_started = 1; - - asm volatile("move $k1, %0" : : "r" (old_k1)); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meStop: Stop the Media Engine. No other Media Engine functions except - * meStart() may be called after this function returns. - * - * If code is currently executing on the Media Engine when this function is - * called, the effect on system state is undefined. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meStop(void) -{ - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - - sceSysregVmeResetEnable(); - sceSysregAvcResetEnable(); - sceSysregMeResetEnable(); - sceSysregMeBusClockDisable(); - - me_started = 0; - - asm volatile("move $k1, %0" : : "r" (old_k1)); -} - -/*************************************************************************/ - -/** - * meCall: Begin executing the given function on the Media Engine. The - * function must not call any firmware functions, whether directly or - * indirectly. This routine may only be called when the Media Engine is - * idle (i.e., when mePoll() returns zero). - * - * [Parameters] - * function: Function pointer - * argument: Optional argument to function - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -int meCall(int (*function)(void *), void *argument) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - if (!message_block->idle || message_block->request) { - return ME_ERROR_BUSY; - } - - message_block->exception = 0; - message_block->function = function; - message_block->argument = argument; - message_block->request = 1; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mePoll: Check whether the Media Engine is idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine is idle, otherwise an error code (negative) - */ -int mePoll(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - if (!message_block->idle || message_block->request) { - return ME_ERROR_BUSY; - } - maybe_raise_exception(); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meWait: Wait for the Media Engine to become idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine has become (or was already) idle, - * otherwise an error code (negative) - */ -int meWait(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - while (!message_block->idle || message_block->request) { /*spin*/ } - maybe_raise_exception(); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meResult: Return the result (return value) of the most recently - * executed function. The result is undefined if the Media Engine has not - * been started or is not idle, if the most recently executed function did - * not return a result (i.e. had a return type of void), or if the most - * recently executed function triggered an exception. - * - * [Parameters] - * None - * [Return value] - * Result of the most recently executed function - */ -int meResult(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - return message_block->result; -} - -/*************************************************************************/ - -/** - * meException: Return whether the most recently executed function - * triggered an exception. The result is undefined if the Media Engine has - * not been started or is not idle. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the most recently executed function triggered an - * exception, else zero - */ -int meException(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - return message_block->exception; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meExceptionGetData: Retrieve CPU status register values related to the - * most recent exception. The values retrieved are undefined in any case - * where meException() returns zero or has an undefined return value. - * - * NULL can be passed for any unneeded register values. - * - * [Parameters] - * BadVAddr_ret: Pointer to variable to receive BadVAddr register value - * Status_ret: Pointer to variable to receive Status register value - * Cause_ret: Pointer to variable to receive Cause register value - * EPC_ret: Pointer to variable to receive EPC register value - * ErrorEPC_ret: Pointer to variable to receive ErrorEPC register value - * [Return value] - * None - */ -void meExceptionGetData(uint32_t *BadVAddr_ret, uint32_t *Status_ret, - uint32_t *Cause_ret, uint32_t *EPC_ret, - uint32_t *ErrorEPC_ret) -{ - if (!me_started) { - return; - } - - if (BadVAddr_ret) { - *BadVAddr_ret = exception_registers.BadVAddr; - } - if (Status_ret) { - *Status_ret = exception_registers.Status; - } - if (Cause_ret) { - *Cause_ret = exception_registers.Cause; - } - if (EPC_ret) { - *EPC_ret = exception_registers.EPC; - } - if (ErrorEPC_ret) { - *ErrorEPC_ret = exception_registers.ErrorEPC; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * meExceptionSetFatal: Set whether an exception on the Media Engine - * should automatically trigger an exception on the main CPU. If enabled, - * any call to mePoll() or meWait() when an exception is pending will cause - * an address error exception to be generated on the main CPU, with - * exception status information stored in a buffer pointed to by $gp: - * 0($gp) = Status - * 4($gp) = Cause - * 8($gp)= EPC or ErrorEPC (depending on the exception type) - * 12($gp) = BadVAddr - * 16($gp) = Media Engine's $sp - * 20($gp) = Media Engine's $gp - * All general-purpose registers other than $sp and $gp, as well as $hi and - * $lo, are copied from the Media Engine. - * - * Unlike other functions in this library, this function can be called even - * when the ME is not running, and it will always succeed. - * - * By default, exceptions are not fatal. - * - * [Parameters] - * fatal: Nonzero to make exceptions fatal, zero to make them nonfatal - * [Return value] - * None - */ -void meExceptionSetFatal(int fatal) -{ - exceptions_are_fatal = (fatal != 0); -} - -/*************************************************************************/ - -/** - * meInterruptPoll: Return whether an interrupt from the Media Engine is - * pending. Any pending interrupt is _not_ cleared. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt from the Media Engine is pending, otherwise an - * error code (negative) - */ -int meInterruptPoll(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - int res = sceKernelPollEventFlag(interrupt_flag, 1, 0, NULL); - asm volatile("move $k1, %0" : : "r" (old_k1)); - - if (res == SCE_KERNEL_ERROR_EVF_COND) { - return ME_ERROR_NO_INTERRUPT; - } else if (res < 0) { - return res; - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meInterruptWait: Wait for an interrupt from the Media Engine if none is - * already pending, then clear the interrupt and return. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt was received from the Media Engine, otherwise - * an error code (negative) - */ -int meInterruptWait(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - int res = sceKernelWaitEventFlag(interrupt_flag, 1, - PSP_EVENT_WAITCLEAR, NULL, NULL); - asm volatile("move $k1, %0" : : "r" (old_k1)); - - if (res < 0) { - return res; - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meInterruptClear: Clear any pending Media Engine interrupt. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meInterruptClear(void) -{ - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - /* This function is slightly misnamed--it doesn't clear the bits - * specified by the second parameter, but simply performs a bitwise - * AND between the current flag value and the second parameter. */ - sceKernelClearEventFlag(interrupt_flag, 0); - asm volatile("move $k1, %0" : : "r" (old_k1)); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * maybe_raise_exception: If fatal exceptions have been requested via - * meExceptionSetFatal() and an ME exception is pending, load registers as - * described in the meExceptionSetFatal() documentation and generate an - * address error exception. - * - * Assumes that the ME is currently idle. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void maybe_raise_exception(void) -{ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - static uint32_t exception_info[6]; - - if (exceptions_are_fatal && message_block->exception) { - asm volatile(".set push; .set noreorder; .set noat\n" - "move $at, %[exception_registers]\n" - "move $gp, %[exception_info]\n" - "lw $t8, %[Status]($at)\n" - "lw $t9, %[Cause]($at)\n" - "lw $k0, %[EPC]($at)\n" - "andi $v0, $t8, 4\n" - "bnezl $v0, 1f\n" - "lw $k0, %[ErrorEPC]($at)\n" - "1:\n" - "lw $k1, %[BadVAddr]($at)\n" - "lw $v0, 120($at)\n" - "lw $v1, 116($at)\n" - "sw $t8, 0($gp)\n" - "sw $t9, 4($gp)\n" - "sw $k0, 8($gp)\n" - "sw $k1, 12($gp)\n" - "sw $v0, 16($gp)\n" - "sw $v1, 20($gp)\n" - "lw $v0, 128($at)\n" - "lw $v1, 132($at)\n" - "mthi $v0\n" - "mtlo $v1\n" - "lw $v0, 8($at)\n" - "lw $v1, 12($at)\n" - "lw $a0, 16($at)\n" - "lw $a1, 20($at)\n" - "lw $a2, 24($at)\n" - "lw $a3, 28($at)\n" - "lw $t0, 32($at)\n" - "lw $t1, 36($at)\n" - "lw $t2, 40($at)\n" - "lw $t3, 44($at)\n" - "lw $t4, 48($at)\n" - "lw $t5, 52($at)\n" - "lw $t6, 56($at)\n" - "lw $t7, 60($at)\n" - "lw $s0, 64($at)\n" - "lw $s1, 68($at)\n" - "lw $s2, 72($at)\n" - "lw $s3, 76($at)\n" - "lw $s4, 80($at)\n" - "lw $s5, 84($at)\n" - "lw $s6, 88($at)\n" - "lw $s7, 92($at)\n" - "lw $t8, 96($at)\n" - "lw $t9, 100($at)\n" - "lw $k0, 104($at)\n" - "lw $k1, 108($at)\n" - "lw $fp, 120($at)\n" - "lw $ra, 124($at)\n" - "lw $at, 4($at)\n" - "sw $zero, -16162($zero)\n" - ".set pop" - : "=m" (exception_info) - : [exception_info] "r" (&exception_info), - [exception_registers] "r" (&exception_registers), - "m" (exception_registers), - [Status] "i" (offsetof(MEExceptionRegs,Status)), - [Cause] "i" (offsetof(MEExceptionRegs,Cause)), - [BadVAddr] "i" (offsetof(MEExceptionRegs,BadVAddr)), - [EPC] "i" (offsetof(MEExceptionRegs,EPC)), - [ErrorEPC] "i" (offsetof(MEExceptionRegs,ErrorEPC)) - ); - } -} - -/*************************************************************************/ - -/** - * interrupt_handler: Handler for Media Engine interrupts. - * - * [Parameters] - * None - * [Return value] - * Always -1 - */ -static int interrupt_handler(void) -{ - sceKernelSetEventFlag(interrupt_flag, 1); - return -1; -} - -/*************************************************************************/ - -/** - * me_init: Initialization code for the Media Engine. Copied to - * 0xBFC00040 in shared memory space. - */ -asm("\ - .set push; .set noreorder \n\ - \n\ - .globl me_init \n\ - .type me_init, @function \n\ -me_init: \n\ - \n\ - # Set up hardware registers. \n\ - li $k0, 0xBC100000 \n\ - li $v0, 7 \n\ - sw $v0, 0x50($k0) # Enable bus clock \n\ - li $v0, -1 \n\ - sw $v0, 0x04($k0) # Clear pending interrupts \n\ - li $v0, 2 # Assume 64MB for now (watch your pointers!) \n\ - sw $v0, 0x40($k0) # Set memory size \n\ - \n\ - # Clear the caches \n\ - mtc0 $zero, $28 # TagLo \n\ - mtc0 $zero, $29 # TagHi \n\ - mfc0 $v1, $16 # Config \n\ - ext $v0, $v1, 9, 3 # Instruction cache size \n\ - li $a0, 2048 \n\ - sllv $a0, $a0, $v0 \n\ - ext $v0, $v1, 6, 3 # Data cache size \n\ - li $a1, 2048 \n\ - sllv $a1, $a1, $v0 \n\ -1: addiu $a0, $a0, -64 \n\ - bnez $a0, 1b \n\ - cache 0x01, 0($a0) # Shouldn't this be 0x00? \n\ -1: addiu $a1, $a1, -64 \n\ - bnez $a1, 1b \n\ - cache 0x11, 0($a1) \n\ - \n\ - # Enable the FPU (COP1) and clear the interrupt-pending flag. \n\ - li $v0, 0x20000000 \n\ - mtc0 $v0, $12 # Status \n\ - mtc0 $zero, $13 # Cause \n\ - \n\ - # Wait for the hardware to become ready. \n\ - li $k0, 0xBCC00000 \n\ - li $v0, 1 \n\ - sw $v0, 0x10($k0) \n\ -1: lw $v0, 0x10($k0) \n\ - andi $v0, $v0, 1 \n\ - bnez $v0, 1b \n\ - nop \n\ - \n\ - # Set up more hardware registers. \n\ - li $v0, 1 \n\ - sw $v0, 0x70($k0) \n\ - li $v0, 8 \n\ - sw $v0, 0x30($k0) \n\ - li $v0, 2 # Assume 64MB for now (watch your pointers!) \n\ - sw $v0, 0x40($k0) \n\ - sync \n\ - \n\ - # Start the internal clock counter running, in case someone \n\ - # wants to access it. (No Compare interrupts will be generated \n\ - # by default, since Status.IM[7] is cleared above.) \n\ - mtc0 $zero, $9 # Count \n\ - \n\ - # Set the exception handler address. \n\ - lui $v0, %hi(me_exception) \n\ - addiu $v0, %lo(me_exception) \n\ - mtc0 $v0, $25 \n\ - \n\ - # Initialize the stack pointer and call the main loop. \n\ - li $sp, 0x80200000 \n\ - lui $ra, %hi(me_loop) \n\ - addiu $ra, %lo(me_loop) \n\ - jr $ra \n\ - nop \n\ - \n\ - .globl me_init_end \n\ -me_init_end: \n\ - \n\ - .set pop \n\ -"); - -/*-----------------------------------------------------------------------*/ - -/** - * me_loop: Media Engine main loop. Infinitely repeats the cycle of - * waiting for an execute request from the main CPU, then executing the - * requested function. - * - * [Parameters] - * None - * [Return value] - * Does not return - * [Notes] - * This is not declared "static" because the address must be referenced - * by the assembly code in me_init(). - */ -__attribute__((section(".text.me"), noreturn)) void me_loop(void) -{ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - asm("move $k0, %0" : : "r" (ME_K0_MAGIC)); - - for (;;) { - message_block->idle = 1; - while (!message_block->request) { /*spin*/ } - message_block->idle = 0; - int (*function)(void *) = message_block->function; - void *argument = message_block->argument; - message_block->request = 0; - message_block->result = (*function)(argument); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * me_exception: Media Engine exception handler. Stores exception data in - * the local buffer, then clears the ME stack and restarts the main loop. - */ -asm("\ - .set push; .set noreorder; .set noat \n\ - .pushsection .text.me,\"ax\",@progbits \n\ - .balign 64 \n\ - \n\ - .globl me_exception \n\ - .type me_exception, @function \n\ -me_exception: \n\ - \n\ - # Save $v0 and $v1 so we have some work registers available. \n\ - ctc0 $v0, $4 \n\ - ctc0 $v1, $5 \n\ - \n\ - # Save all registers to the exception register buffer. \n\ - lui $v1, %hi(exception_registers) \n\ - addiu $v1, %lo(exception_registers) \n\ - cache 0x18, 0($v1) \n\ - cache 0x18, 64($v1) \n\ - cache 0x18, 128($v1) \n\ - sw $zero, 0($v1) \n\ - sw $at, 4($v1) \n\ - sw $v0, 8($v1) \n\ - cfc0 $v0, $5 \n\ - sw $v0, 12($v1) \n\ - sw $a0, 16($v1) \n\ - sw $a1, 20($v1) \n\ - sw $a2, 24($v1) \n\ - sw $a3, 28($v1) \n\ - sw $t0, 32($v1) \n\ - sw $t1, 36($v1) \n\ - sw $t2, 40($v1) \n\ - sw $t3, 44($v1) \n\ - sw $t4, 48($v1) \n\ - sw $t5, 52($v1) \n\ - sw $t6, 56($v1) \n\ - sw $t7, 60($v1) \n\ - sw $s0, 64($v1) \n\ - sw $s1, 68($v1) \n\ - sw $s2, 72($v1) \n\ - sw $s3, 76($v1) \n\ - sw $s4, 80($v1) \n\ - sw $s5, 84($v1) \n\ - sw $s6, 88($v1) \n\ - sw $s7, 92($v1) \n\ - sw $t8, 96($v1) \n\ - sw $t9, 100($v1) \n\ - sw $k0, 104($v1) \n\ - sw $k1, 108($v1) \n\ - sw $gp, 112($v1) \n\ - sw $sp, 116($v1) \n\ - sw $fp, 120($v1) \n\ - sw $ra, 124($v1) \n\ - mfhi $v0 \n\ - sw $v0, 128($v1) \n\ - mflo $v0 \n\ - sw $v0, 132($v1) \n\ - mfc0 $v0, $8 \n\ - sw $v0, 136($v1) \n\ - mfc0 $v0, $12 \n\ - sw $v0, 140($v1) \n\ - mfc0 $v0, $13 \n\ - sw $v0, 144($v1) \n\ - mfc0 $v0, $14 \n\ - sw $v0, 148($v1) \n\ - mfc0 $v0, $30 \n\ - sw $v0, 152($v1) \n\ - cache 0x1A, 0($v1) \n\ - cache 0x1A, 64($v1) \n\ - cache 0x1A, 128($v1) \n\ - \n\ - # Run the remainder of the handler (compiled C code). \n\ - j me_exception_finish \n\ - nop \n\ - \n\ - .popsection \n\ - .set pop \n\ -"); - -__attribute__((section(".text.me"), noreturn)) void me_exception_finish(void) -{ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - message_block->exception = 1; - asm volatile("li $sp, 0x80200000"); - asm volatile("mtc0 %0, $14; " - "mtc0 %0, $30" : : "r" (me_loop)); - asm volatile("eret"); - for (;;) {} // Unreachable, but tell the compiler we don't return -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me.exp b/yabause/src/psp/me.exp deleted file mode 100644 index 326592b16d..0000000000 --- a/yabause/src/psp/me.exp +++ /dev/null @@ -1,19 +0,0 @@ -PSP_EXPORT_START(syslib, 0, 0x8000) -PSP_EXPORT_FUNC_HASH(module_start) -PSP_EXPORT_VAR_HASH(module_info) -PSP_EXPORT_END - -PSP_EXPORT_START(melib, 0, 0x4001) -PSP_EXPORT_FUNC_HASH(meStart) -PSP_EXPORT_FUNC_HASH(meStop) -PSP_EXPORT_FUNC_HASH(meCall) -PSP_EXPORT_FUNC_HASH(mePoll) -PSP_EXPORT_FUNC_HASH(meWait) -PSP_EXPORT_FUNC_HASH(meResult) -PSP_EXPORT_FUNC_HASH(meException) -PSP_EXPORT_FUNC_HASH(meExceptionGetData) -PSP_EXPORT_FUNC_HASH(meExceptionSetFatal) -PSP_EXPORT_FUNC_HASH(meInterruptPoll) -PSP_EXPORT_FUNC_HASH(meInterruptWait) -PSP_EXPORT_FUNC_HASH(meInterruptClear) -PSP_EXPORT_END diff --git a/yabause/src/psp/me.h b/yabause/src/psp/me.h deleted file mode 100644 index 4194350296..0000000000 --- a/yabause/src/psp/me.h +++ /dev/null @@ -1,231 +0,0 @@ -/* src/psp/me.h: PSP Media Engine access library header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ME_H -#define ME_H - -/*************************************************************************/ - -/* Error codes specific to Media Engine routines */ - -enum { - /* Media Engine has not been successfully started with meStart() */ - ME_ERROR_NOT_STARTED = 0x90000001, - /* Media Engine is currently executing a function */ - ME_ERROR_BUSY = 0x90000002, - /* No Media Engine interrupt is pending */ - ME_ERROR_NO_INTERRUPT = 0x90000003, -}; - -/*----------------------------------*/ - -/* Magic value stored in $k0 to indicate that code is running on the ME */ - -#define ME_K0_MAGIC 0x3E3E3E3E - -/*************************************************************************/ - -/** - * meStart: Start up the Media Engine. This function must be called - * before any other Media Engine operations are performed. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int meStart(void); - -/** - * meStop: Stop the Media Engine. No other Media Engine functions except - * meStart() may be called after this function returns. - * - * If code is currently executing on the Media Engine when this function is - * called, the effect on system state is undefined. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meStop(void); - -/*----------------------------------*/ - -/** - * meCall: Begin executing the given function on the Media Engine. The - * function must not call any firmware functions, whether directly or - * indirectly. This routine may only be called when the Media Engine is - * idle (i.e., when mePoll() returns zero). - * - * [Parameters] - * function: Function pointer - * argument: Optional argument to function - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int meCall(int (*function)(void *), void *argument); - -/** - * mePoll: Check whether the Media Engine is idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine is idle, otherwise an error code (negative) - */ -extern int mePoll(void); - -/** - * meWait: Wait for the Media Engine to become idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine has become (or was already) idle, - * otherwise an error code (negative) - */ -extern int meWait(void); - -/** - * meResult: Return the result (return value) of the most recently - * executed function. The result is undefined if the Media Engine has not - * been started or is not idle, if the most recently executed function did - * not return a result (i.e. had a return type of void), or if the most - * recently executed function triggered an exception. - * - * [Parameters] - * None - * [Return value] - * Result of the most recently executed function - */ -extern int meResult(void); - -/*----------------------------------*/ - -/** - * meException: Return whether the most recently executed function - * triggered an exception. The result is undefined if the Media Engine has - * not been started or is not idle. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the most recently executed function triggered an - * exception, else zero - */ -extern int meException(void); - -/** - * meExceptionGetData: Retrieve CPU status register values related to the - * most recent exception. The values retrieved are undefined in any case - * where meException() returns zero or has an undefined return value. - * - * NULL can be passed for any unneeded register values. - * - * [Parameters] - * BadVAddr_ret: Pointer to variable to receive BadVAddr register value - * Status_ret: Pointer to variable to receive Status register value - * Cause_ret: Pointer to variable to receive Cause register value - * EPC_ret: Pointer to variable to receive EPC register value - * ErrorEPC_ret: Pointer to variable to receive ErrorEPC register value - * [Return value] - * None - */ -extern void meExceptionGetData(uint32_t *BadVAddr_ret, uint32_t *Status_ret, - uint32_t *Cause_ret, uint32_t *EPC_ret, - uint32_t *ErrorEPC_ret); - -/** - * meExceptionSetFatal: Set whether an exception on the Media Engine - * should automatically trigger an exception on the main CPU. If enabled, - * any call to mePoll() or meWait() when an exception is pending will cause - * an address error exception to be generated on the main CPU, with - * exception status information stored in a buffer pointed to by $gp: - * 0($gp) = Status - * 4($gp) = Cause - * 8($gp)= EPC or ErrorEPC (depending on the exception type) - * 12($gp) = BadVAddr - * 16($gp) = Media Engine's $sp - * 20($gp) = Media Engine's $gp - * All general-purpose registers other than $sp and $gp, as well as $hi and - * $lo, are copied from the Media Engine. - * - * Unlike other functions in this library, this function can be called even - * when the ME is not running, and it will always succeed. - * - * By default, exceptions are not fatal. - * - * [Parameters] - * fatal: Nonzero to make exceptions fatal, zero to make them nonfatal - * [Return value] - * None - */ -extern void meExceptionSetFatal(int fatal); - -/*----------------------------------*/ - -/** - * meInterruptPoll: Return whether an interrupt from the Media Engine is - * pending. Any pending interrupt is _not_ cleared. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt from the Media Engine is pending, otherwise an - * error code (negative) - */ -extern int meInterruptPoll(void); - -/** - * meInterruptWait: Wait for an interrupt from the Media Engine if none is - * already pending, then clear the interrupt and return. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt was received from the Media Engine, otherwise - * an error code (negative) - */ -extern int meInterruptWait(void); - -/** - * meInterruptClear: Clear any pending Media Engine interrupt. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meInterruptClear(void); - -/*************************************************************************/ - -#endif // ME_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/menu.c b/yabause/src/psp/menu.c deleted file mode 100644 index 8bc7d5f2d7..0000000000 --- a/yabause/src/psp/menu.c +++ /dev/null @@ -1,2527 +0,0 @@ -/* src/psp/menu.c: PSP menu interface - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../cs2.h" -#include "../memory.h" -#include "../peripheral.h" -#include "../scsp.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vdp1.h" -#include "../vidsoft.h" -#include "../yabause.h" - -#include "config.h" -#include "control.h" -#include "display.h" -#include "filesel.h" -#include "font.h" -#include "gu.h" -#include "menu.h" -#include "misc.h" -#include "osk.h" -#include "psp-sh2.h" -#include "psp-video.h" -#include "sh2.h" -#include "sys.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Button input state from the last frame */ -static uint32_t last_buttons; - -/* Repeat delay, rate, and status */ -#define REPEAT_DELAY 30 // frames -#define REPEAT_RATE 3 // frames -static uint32_t repeat_buttons; // Button(s) to repeat -static uint8_t repeating; // Nonzero = repeat started -static uint8_t repeat_timer; // Counts down from REPEAT_{DELAY,RATE} - -/*----------------------------------*/ - -/* FIXME: This menu stuff is all messy and copy-pastey because I'm too - lazy to do it properly at the moment. I hate writing UIs. */ - -/* Currently selected menu and menu option */ - -typedef enum MenuIndex_ { - MENU_MAIN = 0, - MENU_GENERAL, - MENU_FILES, - MENU_BUTTON, - MENU_VIDEO, - MENU_RENDER, - MENU_FRAME_SKIP, - MENU_ADVANCED, - MENU_OPTIMIZE, - MENU_MEDIA_ENGINE, - MENU_YESNO, // A yes/no dialog implemented as a "menu" -} MenuIndex; - -static uint8_t cur_menu; - - -typedef enum MainMenuOption_ { - OPT_MAIN_GENERAL = 0, - OPT_MAIN_BUTTON, - OPT_MAIN_VIDEO, - OPT_MAIN_ADVANCED, - OPT_MAIN_SAVE, - OPT_MAIN_RESET, -} MainMenuOption; -#define OPT_MAIN__MAX OPT_MAIN_RESET - -typedef enum GeneralMenuOption_ { - OPT_GENERAL_START_IN_EMU = 0, - OPT_GENERAL_FILES, - OPT_GENERAL_BUP_AUTOSAVE, - OPT_GENERAL_BUP_SAVE_NOW, - OPT_GENERAL_BUP_SAVE_AS, -} GeneralMenuOption; -#define OPT_GENERAL__MAX OPT_GENERAL_BUP_SAVE_AS - -typedef enum FilesMenuOption_ { - OPT_FILES_PATH_BIOS = 0, - OPT_FILES_PATH_CD, - OPT_FILES_PATH_BUP, -} FilesMenuOption; -#define OPT_FILES__MAX OPT_FILES_PATH_BUP - -typedef enum ButtonMenuOption_ { - OPT_BUTTON_A, - OPT_BUTTON_B, - OPT_BUTTON_C, - OPT_BUTTON_X, - OPT_BUTTON_Y, - OPT_BUTTON_Z, -} ButtonMenuOption; -#define OPT_BUTTON__MAX OPT_BUTTON_Z - -typedef enum VideoMenuOption_ { - OPT_VIDEO_HW = 0, - OPT_VIDEO_SW, - OPT_VIDEO_RENDER, - OPT_VIDEO_FRAME_SKIP, - OPT_VIDEO_SHOW_FPS, -} VideoMenuOption; -#define OPT_VIDEO__MAX OPT_VIDEO_SHOW_FPS - -typedef enum RenderMenuOption_ { - OPT_RENDER_CACHE_TEXTURES = 0, - OPT_RENDER_SMOOTH_TEXTURES, - OPT_RENDER_SMOOTH_HIRES, - OPT_RENDER_ENABLE_ROTATE, - OPT_RENDER_OPTIMIZE_ROTATE, -} RenderMenuOption; -#define OPT_RENDER__MAX OPT_RENDER_OPTIMIZE_ROTATE - -typedef enum FrameSkipMenuOption_ { - OPT_FRAME_SKIP_AUTO = 0, - OPT_FRAME_SKIP_NUM, - OPT_FRAME_SKIP_INTERLACE, - OPT_FRAME_SKIP_ROTATE, -} FrameSkipMenuOption; -#define OPT_FRAME_SKIP__MAX OPT_FRAME_SKIP_ROTATE - -typedef enum AdvancedMenuOption_ { - OPT_ADVANCED_SH2_RECOMPILER = 0, - OPT_ADVANCED_SH2_OPTIMIZE, - OPT_ADVANCED_MEDIA_ENGINE, - OPT_ADVANCED_DECILINE_MODE, - OPT_ADVANCED_AUDIO_SYNC, - OPT_ADVANCED_CLOCK_SYNC, - OPT_ADVANCED_CLOCK_FIXED_TIME, -} AdvancedMenuOption; -#define OPT_ADVANCED__MAX OPT_ADVANCED_CLOCK_FIXED_TIME - -typedef enum OptimizeMenuOption_ { - OPT_OPTIMIZE_ASSUME_SAFE_DIVISION = 0, - OPT_OPTIMIZE_FOLD_SUBROUTINES, - OPT_OPTIMIZE_BRANCH_TO_RTS, - OPT_OPTIMIZE_LOCAL_ACCESSES, - OPT_OPTIMIZE_POINTERS, - OPT_OPTIMIZE_POINTERS_MAC, - OPT_OPTIMIZE_LOCAL_POINTERS, - OPT_OPTIMIZE_STACK, -#if 0 // FIXME: out of space on the screen; this should be the least dangerous - OPT_OPTIMIZE_MAC_NOSAT, -#endif -} OptimizeMenuOption; -#define OPT_OPTIMIZE__MAX OPT_OPTIMIZE_STACK - -typedef enum MediaEngineMenuOption_ { - OPT_MEDIA_ENGINE_USE_ME = 0, - OPT_MEDIA_ENGINE_WRITEBACK_PERIOD, - OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY, -} MediaEngineMenuOption; -#define OPT_MEDIA_ENGINE__MAX OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY - -typedef enum YesNoMenuOption_ { - OPT_YESNO_YES = 0, - OPT_YESNO_NO, -} YesNoMenuOption; -#define OPT_YESNO__MAX OPT_YESNO_NO - -static uint8_t cur_option; - - -/* Maximum menu option index for current menu (OPT_*__MAX) */ -static uint8_t max_option; - -/* File selector, if a file selector is currently open */ -static FileSelector *filesel; - -/*----------------------------------*/ - -/* Previous menu and option (and max_option value) for the yes/no dialog */ -static uint8_t yesno_menu, yesno_option, yesno_maxopt; - -/* Prompt string for the yes/no dialog (may include newlines) */ -static char yesno_prompt[1000]; - -/*----------------------------------*/ - -/* Saved pathname for "Save backup RAM as..." option */ -static char *save_as_path; - -/*----------------------------------*/ - -/* Flag: Is X the confirm button? */ -static int x_is_confirm; - -/*----------------------------------*/ - - -/* Background image buffer */ -static void *bgimage; -static void *bgimage_base; // Base (unaligned) pointer for later free()ing - -/* Background color for the menu, overlaid on the current emulation screen - * (0xAABBGGRR) */ -#define MENU_BGCOLOR 0xC0332C2C - -/* Flag indicating whether we should draw the background image (cleared - * when the user requests an emulator reset, to show visually that the - * emulator has in fact been reset) */ -static uint8_t draw_bgimage; - -/* Cursor color, flashing period, and timer */ -#define CURSOR_COLOR 0x80FFECEC -#define CURSOR_PERIOD 60 // frames -static uint8_t cursor_timer; - -/* Default text color */ -#define TEXT_COLOR 0xFFFFECEC - -/* Text color for informational messages */ -#define TEXT_COLOR_INFO 0xFFFF8040 - -/* Text color for "Saved"/"Failed" responses to "Save settings" */ -#define TEXT_COLOR_OK 0xFF55FF40 // Also used for "Reset the emulator" -#define TEXT_COLOR_NG 0xFF5540FF // Also used for warning text - -/* Text color for disabled menu options */ -#define TEXT_COLOR_DISABLED 0xFF807676 - -/* Status line current text, text color, display time, and timer */ -static const char *status_text; -static uint32_t status_color; -#define STATUS_DISPTIME 300 // frames -static uint16_t status_timer; - -/*************************************************************************/ - -/* Local function declarations */ - -static void gen_menu_bg(void); - -static void do_reset(void); - -static uint32_t get_new_buttons(const uint32_t buttons); -static void process_input_menu(const uint32_t buttons, - const uint32_t new_buttons); -static void process_option_main(const uint32_t buttons); -static void process_option_general(const uint32_t buttons); -static void process_option_files(const uint32_t buttons); -static void process_option_button(const uint32_t buttons); -static void process_option_video(const uint32_t buttons); -static void process_option_render(const uint32_t buttons); -static void process_option_frame_skip(const uint32_t buttons); -static void process_option_advanced(const uint32_t buttons); -static void process_option_optimize(const uint32_t buttons); -static void process_option_media_engine(const uint32_t buttons); -static void process_option_yesno(const uint32_t buttons); -static void process_input_filesel(const uint32_t new_buttons); -static void process_osk_result(void); - -static void draw_menu(void); -static const char *cur_option_confirm_text(void); -static void draw_menu_option(int option, int x, int y, const char *format, ...) - __attribute__((format(printf,4,5))); -static void draw_disabled_menu_option(int option, int x, int y, - const char *format, ...) - __attribute__((format(printf,4,5))); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * menu_open: Open the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -void menu_open(void) -{ - last_buttons = control_state(); - repeat_buttons = 0; - - cur_menu = MENU_MAIN; - cur_option = 0; - max_option = OPT_MAIN__MAX; - filesel = NULL; - - int res = sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_X_IS_CONFIRM, - &x_is_confirm); - if (res < 0) { - DMSG("Failed to get X_IS_CONFIRM: %s", psp_strerror(res)); - x_is_confirm = 0; // Default to O - } - draw_bgimage = 1; - cursor_timer = 0; - - display_set_size(DISPLAY_WIDTH, DISPLAY_HEIGHT); - gen_menu_bg(); -} - -/*************************************************************************/ - -/** - * menu_run: Perform a single frame's processing for the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -void menu_run(void) -{ - const uint32_t buttons = control_state(); - - /* Update timers */ - cursor_timer = (cursor_timer + 1) % CURSOR_PERIOD; - if (status_timer > 0) { - status_timer--; - } - - /* Update the on-screen keyboard in case it's active */ - osk_update(); - - /* Check for and process input */ - const uint32_t new_buttons = get_new_buttons(buttons); - if (osk_status()) { - process_osk_result(); - } else { - if (filesel) { - process_input_filesel(new_buttons); - } else { - process_input_menu(buttons, new_buttons); - } - } - - /* Draw the menu (and dim the display if the OSK is active) */ - display_begin_frame(); - draw_menu(); - if (osk_status()) { - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0xAA000000); - } - display_end_frame(); - sceDisplayWaitVblankStart(); -} - -/*************************************************************************/ - -/** - * menu_close: Close the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -void menu_close(void) -{ - /* If the on-screen keyboard is active, close it */ - - if (osk_status()) { - osk_close(); - while (osk_status()) { - osk_update(); - sceDisplayWaitVblankStart(); - } - } - - /* If there's a file selector running, kill it */ - - if (filesel) { - filesel_destroy(filesel); - filesel = NULL; - } - - /* Make sure to clear both display buffers */ - - display_begin_frame(); - if (draw_bgimage) { - guCopyImage(GU_PSM_8888, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_STRIDE, bgimage, - 0, 0, DISPLAY_STRIDE, display_work_buffer()); - } else { - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0xFF000000); - } - display_end_frame(); - sceDisplayWaitVblankStart(); - - display_begin_frame(); - if (draw_bgimage) { - guCopyImage(GU_PSM_8888, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_STRIDE, bgimage, - 0, 0, DISPLAY_STRIDE, display_work_buffer()); - } else { - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0xFF000000); - } - display_end_frame(); - sceDisplayWaitVblankStart(); - - /* Free the background image buffer */ - - free(bgimage_base); - bgimage = bgimage_base = NULL; - - /* Clear the status line so any current message doesn't get held over */ - - status_text = ""; - status_timer = 0; -} - -/*************************************************************************/ - -/** - * menu_set_error: Set an error message to be displayed on the menu - * screen. If message is NULL, any message currently displayed is cleared. - * - * [Parameters] - * message: Message text (NULL to clear current message) - * [Return value] - * None - */ -void menu_set_error(const char *message) -{ - static char buf[100]; // Just in case the message is in a local buffer - - if (message) { - snprintf(buf, sizeof(buf), "%s", message); - status_text = buf; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else { - status_text = NULL; - status_timer = 0; - } -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * gen_menu_bg: Generate the background image for the menu (a copy of the - * currently-displayed image). - * - * [Parameters] - * None - * [Return value] - * None - */ -static void gen_menu_bg(void) -{ - bgimage_base = malloc((DISPLAY_STRIDE * DISPLAY_HEIGHT * 4) + 63); - if (UNLIKELY(!bgimage_base)) { - DMSG("Out of memory for bgimage"); - bgimage = NULL; - return; - } - bgimage = (void *)(((uintptr_t)bgimage_base + 63) & -64); - memcpy(bgimage, display_disp_buffer(), - DISPLAY_STRIDE * DISPLAY_HEIGHT * 4); -} - -/*************************************************************************/ - -/** - * do_reset: Reset the emulator in response to a user action. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void do_reset(void) -{ - YabauseReset(); - status_text = "Resetting the emulator."; - status_color = TEXT_COLOR_OK; - status_timer = STATUS_DISPTIME; - draw_bgimage = 0; -} - -/*************************************************************************/ - -/** - * get_new_buttons: Return which controller buttons were pressed this - * frame. This may include fake button presses generated by auto-repeat. - * - * If the on-screen keyboard is open, this function always returns zero; - * however, it should still be called every frame to ensure proper - * behavior when the OSK is closed. - * - * [Parameters] - * buttons: Buttons which are currently held down (PSP_CTRL_* bitmask) - * [Return value] - * Buttons which were newly pressed this frame (PSP_CTRL_* bitmask) - */ -static uint32_t get_new_buttons(const uint32_t buttons) -{ - uint32_t new_buttons = ~last_buttons & buttons; - - if (osk_status()) { - new_buttons = 0; - repeat_buttons = 0; - } - - if (new_buttons) { - /* Only allow repeat of up/down/left/right */ - repeat_buttons = new_buttons & (PSP_CTRL_UP | PSP_CTRL_DOWN - | PSP_CTRL_LEFT | PSP_CTRL_RIGHT); - repeating = 0; - repeat_timer = REPEAT_DELAY; - } else if ((buttons & repeat_buttons) != repeat_buttons) { - repeat_buttons = 0; - } - if (repeat_buttons != 0) { - repeat_timer--; - if (repeat_timer == 0) { - new_buttons = repeat_buttons; - repeating = 1; - repeat_timer = REPEAT_RATE; - } - } - - last_buttons = buttons; - return new_buttons; -} - -/*-----------------------------------------------------------------------*/ - -/** - * process_input_menu: Process input directed to the menu (i.e. not a file - * selector. - * - * [Parameters] - * buttons: Buttons which are currently held down (PSP_CTRL_* bitmask) - * new_buttons: Buttons which were pressed this frame (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -static void process_input_menu(const uint32_t buttons, - const uint32_t new_buttons) -{ - const uint32_t confirm_button = - x_is_confirm ? PSP_CTRL_CROSS : PSP_CTRL_CIRCLE; - const uint32_t cancel_button = - x_is_confirm ? PSP_CTRL_CIRCLE : PSP_CTRL_CROSS; - - if (new_buttons & PSP_CTRL_UP) { - if (cur_menu != MENU_YESNO && cur_option > 0) { - cur_option--; - cursor_timer = 0; - } - - } else if (new_buttons & PSP_CTRL_DOWN) { - if (cur_menu != MENU_YESNO && cur_option < max_option) { - cur_option++; - cursor_timer = 0; - } - - } else if (new_buttons & (PSP_CTRL_LEFT | PSP_CTRL_RIGHT)) { - const int dir = (new_buttons & PSP_CTRL_RIGHT) ? 1 : -1; - - if (cur_menu == MENU_FRAME_SKIP - && cur_option == OPT_FRAME_SKIP_NUM - ) { - const int new_num = config_get_frameskip_num() + dir; - if (!config_set_frameskip_num(new_num)) { - status_text = "Failed to change fixed frame skip count!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - - } else if (cur_menu == MENU_MEDIA_ENGINE - && cur_option == OPT_MEDIA_ENGINE_WRITEBACK_PERIOD - ) { - if (me_available && config_get_use_me()) { - const unsigned int period = config_get_me_writeback_period(); - unsigned int new_period = (dir > 0) ? period<<1 : period>>1; - if (new_period < 1) { - new_period = 1; - } else if (new_period > 64) { // Should be more than enough - new_period = 64; - } - if (!config_set_me_writeback_period(new_period)) { - status_text = "Failed to change ME writeback frequency!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - - } else if (cur_menu == MENU_MEDIA_ENGINE - && cur_option == OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY - ) { - if (me_available && config_get_use_me()) { - const unsigned int value = config_get_me_uncached_boundary(); - unsigned int new_value = (dir > 0) - ? (value==0 ? 0x400 : value<<1) - : value>>1; - if (new_value < 0x400) { // Shouldn't need to deal with - new_value = 0; // fractions of a kilobyte - } else if (new_value > 0x80000) { - new_value = 0x80000; - } - if (!config_set_me_uncached_boundary(new_value)) { - status_text = "Failed to change uncached boundary address!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - - } else if (cur_menu == MENU_YESNO) { - if (dir < 0) { - if (cur_option == OPT_YESNO_NO) { - cur_option = OPT_YESNO_YES; - cursor_timer = 0; - } - } else { - if (cur_option == OPT_YESNO_YES) { - cur_option = OPT_YESNO_NO; - cursor_timer = 0; - } - } - } - - } else if (new_buttons != 0 && cur_menu == MENU_BUTTON) { - if (new_buttons & (PSP_CTRL_CIRCLE | PSP_CTRL_CROSS - | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)) { - process_option_button(buttons); - } else if (new_buttons & PSP_CTRL_START) { - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_BUTTON; - max_option = OPT_MAIN__MAX; - } - - } else if (new_buttons & confirm_button) { - switch ((MenuIndex)cur_menu) { - case MENU_MAIN: process_option_main(buttons); break; - case MENU_GENERAL: process_option_general(buttons); break; - case MENU_FILES: process_option_files(buttons); break; - case MENU_BUTTON: /* impossible (handled above) */ break; - case MENU_VIDEO: process_option_video(buttons); break; - case MENU_RENDER: process_option_render(buttons); break; - case MENU_FRAME_SKIP: process_option_frame_skip(buttons); break; - case MENU_ADVANCED: process_option_advanced(buttons); break; - case MENU_OPTIMIZE: process_option_optimize(buttons); break; - case MENU_MEDIA_ENGINE:process_option_media_engine(buttons); break; - case MENU_YESNO: process_option_yesno(buttons); break; - } - - } else if (new_buttons & cancel_button) { - if (cur_menu != MENU_MAIN) { - switch ((MenuIndex)cur_menu) { - case MENU_MAIN: - case MENU_BUTTON: - /* Impossible, but included to avoid a compiler warning */ - break; - case MENU_GENERAL: - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_GENERAL; - max_option = OPT_MAIN__MAX; - break; - case MENU_FILES: - cur_menu = MENU_GENERAL; - cur_option = OPT_GENERAL_FILES; - max_option = OPT_GENERAL__MAX; - break; - case MENU_VIDEO: - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_VIDEO; - max_option = OPT_MAIN__MAX; - break; - case MENU_RENDER: - cur_menu = MENU_VIDEO; - cur_option = OPT_VIDEO_RENDER; - max_option = OPT_VIDEO__MAX; - break; - case MENU_FRAME_SKIP: - cur_menu = MENU_VIDEO; - cur_option = OPT_VIDEO_FRAME_SKIP; - max_option = OPT_VIDEO__MAX; - break; - case MENU_ADVANCED: - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_ADVANCED; - max_option = OPT_MAIN__MAX; - break; - case MENU_OPTIMIZE: - cur_menu = MENU_ADVANCED; - cur_option = OPT_ADVANCED_SH2_OPTIMIZE; - max_option = OPT_ADVANCED__MAX; - break; - case MENU_MEDIA_ENGINE: - cur_menu = MENU_ADVANCED; - cur_option = OPT_ADVANCED_MEDIA_ENGINE; - max_option = OPT_ADVANCED__MAX; - break; - case MENU_YESNO: - cur_option = OPT_YESNO_NO; - process_option_yesno(confirm_button); - break; - } - } - - } -} - -/*----------------------------------*/ - -/** - * process_option_*: Process a "confirm" button press on the currently - * selected menu option. Each menu has its own handler function. - * - * [Parameters] - * buttons: Buttons which are currently held down (PSP_CTRL_* bitmask) - * [Return value] - * None - */ - -static void process_option_main(const uint32_t buttons) -{ - switch ((MainMenuOption)cur_option) { - - case OPT_MAIN_GENERAL: - cur_menu = MENU_GENERAL; - cur_option = 0; - max_option = OPT_GENERAL__MAX; - break; - - case OPT_MAIN_BUTTON: - cur_menu = MENU_BUTTON; - cur_option = 0; - max_option = OPT_BUTTON__MAX; - break; - - case OPT_MAIN_VIDEO: - cur_menu = MENU_VIDEO; - cur_option = 0; - max_option = OPT_VIDEO__MAX; - break; - - case OPT_MAIN_ADVANCED: - cur_menu = MENU_ADVANCED; - cur_option = 0; - max_option = OPT_ADVANCED__MAX; - break; - - case OPT_MAIN_SAVE: - if (config_save()) { - status_text = "Settings saved."; - status_color = TEXT_COLOR_OK; - } else { - status_text = "Failed to save settings!"; - status_color = TEXT_COLOR_NG; - } - status_timer = STATUS_DISPTIME; - break; - - case OPT_MAIN_RESET: - if (yabause_initted - && (buttons & PSP_CTRL_LTRIGGER) - && (buttons & PSP_CTRL_RTRIGGER) - ) { - do_reset(); - } - - } -} - -/*----------------------------------*/ - -static void process_option_general(const uint32_t buttons) -{ - switch ((GeneralMenuOption)cur_option) { - - case OPT_GENERAL_START_IN_EMU: - if (!config_set_start_in_emu(!config_get_start_in_emu())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_GENERAL_FILES: - cur_menu = MENU_FILES; - cur_option = 0; - max_option = OPT_FILES__MAX; - break; - - case OPT_GENERAL_BUP_AUTOSAVE: - if (!config_set_bup_autosave(!config_get_bup_autosave())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_GENERAL_BUP_SAVE_NOW: { - if (!yabause_initted) { - break; - } - const char *path = config_get_path_bup(); - if (!path || !*path) { // Check this early just in case - status_text = "No backup RAM file configured!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else if (!save_backup_ram()) { - status_text = "Error saving backup RAM!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else { - status_text = "Backup RAM saved."; - status_color = TEXT_COLOR_OK; - status_timer = STATUS_DISPTIME; - } - break; - } // case OPT_GENERAL_BUP_SAVE_NOW - - case OPT_GENERAL_BUP_SAVE_AS: { - if (!yabause_initted) { - break; - } - const unsigned int maxlen = 100; // Reasonable limit - const char *path = config_get_path_bup(); - if (!path) { - path = "backup.bin"; // Just in case - } - if (!osk_open("Enter new backup RAM filename.", path, maxlen)) { - status_text = "Unable to open on-screen keyboard!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - break; - } - /* process_osk_result() will take care of handling the result from - * the OSK and saving the new file. */ - break; - } // case OPT_GENERAL_BUP_SAVE_AS - - } -} - -/*----------------------------------*/ - -static void process_option_files(const uint32_t buttons) -{ - switch ((FilesMenuOption)cur_option) { - - case OPT_FILES_PATH_BIOS: - filesel = filesel_create("Select BIOS image file", progpath); - if (!filesel) { - status_text = "Failed to open file selector!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FILES_PATH_CD: - filesel = filesel_create("Select CD image file (ISO or CUE)", - progpath); - if (!filesel) { - status_text = "Failed to open file selector!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FILES_PATH_BUP: - filesel = filesel_create("Select backup RAM image file", - progpath); - if (!filesel) { - status_text = "Failed to open file selector!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_button(const uint32_t buttons) -{ - static const uint8_t perkey_map[] = { - [CONFIG_BUTTON_A] = PERPAD_A, - [CONFIG_BUTTON_B] = PERPAD_B, - [CONFIG_BUTTON_C] = PERPAD_C, - [CONFIG_BUTTON_X] = PERPAD_X, - [CONFIG_BUTTON_Y] = PERPAD_Y, - [CONFIG_BUTTON_Z] = PERPAD_Z, - }; - - if (buttons & (buttons-1)) { - status_text = "Press only one button at a time."; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - - const unsigned int saturn_button = - CONFIG_BUTTON_A + (cur_option - OPT_BUTTON_A); - const uint32_t psp_button = buttons; - - /* If this button is currently assigned to something else, swap the - * buttons around. */ - unsigned int other_button; - for (other_button = CONFIG_BUTTON_A; other_button <= CONFIG_BUTTON_Z; - other_button++ - ) { - if (config_get_button(other_button) == psp_button) { - break; - } - } - if (other_button <= CONFIG_BUTTON_Z) { - if (!config_set_button(other_button,config_get_button(saturn_button))){ - status_text = "Failed to reassign button!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - PerSetKey(config_get_button(other_button), perkey_map[other_button], - padbits); - } - - if (!config_set_button(saturn_button, psp_button)) { - status_text = "Failed to assign button!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - PerSetKey(psp_button, perkey_map[saturn_button], padbits); -} - -/*----------------------------------*/ - -static void process_option_video(const uint32_t buttons) -{ - switch ((VideoMenuOption)cur_option) { - - case OPT_VIDEO_HW: - if (config_get_module_video() != VIDCORE_PSP) { - if (VideoChangeCore(VIDCORE_PSP) < 0 - || !config_set_module_video(VIDCORE_PSP) - ) { - status_text = "Failed to change video interface!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - break; - - case OPT_VIDEO_SW: - if (config_get_module_video() != VIDCORE_SOFT) { - if (VideoChangeCore(VIDCORE_SOFT) < 0 - || !config_set_module_video(VIDCORE_SOFT) - ) { - status_text = "Failed to change video interface!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - break; - - case OPT_VIDEO_RENDER: - cur_menu = MENU_RENDER; - cur_option = 0; - max_option = OPT_RENDER__MAX; - break; - - case OPT_VIDEO_FRAME_SKIP: - cur_menu = MENU_FRAME_SKIP; - cur_option = 0; - max_option = OPT_FRAME_SKIP__MAX; - break; - - case OPT_VIDEO_SHOW_FPS: - if (!config_set_show_fps(!config_get_show_fps())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_render(const uint32_t buttons) -{ - switch ((RenderMenuOption)cur_option) { - - case OPT_RENDER_CACHE_TEXTURES: - if (!config_set_cache_textures(!config_get_cache_textures())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_SMOOTH_TEXTURES: - if (!config_set_smooth_textures(!config_get_smooth_textures())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_SMOOTH_HIRES: - if (!config_set_smooth_hires(!config_get_smooth_hires())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_ENABLE_ROTATE: - if (!config_set_enable_rotate(!config_get_enable_rotate())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_OPTIMIZE_ROTATE: - if (!config_set_optimize_rotate(!config_get_optimize_rotate())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_frame_skip(const uint32_t buttons) -{ - switch ((FrameSkipMenuOption)cur_option) { - - case OPT_FRAME_SKIP_AUTO: - if (!config_set_frameskip_auto(!config_get_frameskip_auto())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FRAME_SKIP_NUM: - /* Don't do anything for the confirm button */ - break; - - case OPT_FRAME_SKIP_INTERLACE: - if (!config_set_frameskip_interlace(!config_get_frameskip_interlace())){ - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FRAME_SKIP_ROTATE: - if (!config_set_frameskip_rotate(!config_get_frameskip_rotate())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_advanced(const uint32_t buttons) -{ - switch ((AdvancedMenuOption)cur_option) { - - case OPT_ADVANCED_SH2_RECOMPILER: - if ((buttons & PSP_CTRL_LTRIGGER) && (buttons & PSP_CTRL_RTRIGGER)) { - int new_module; - if (config_get_module_sh2() == SH2CORE_PSP) { - new_module = SH2CORE_INTERPRETER; - } else { - new_module = SH2CORE_PSP; - } - if (!config_set_module_sh2(new_module)) { - status_text = "Failed to change SH-2 core!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - if (yabause_initted) { - SH2DeInit(); - SH2Init(new_module); - do_reset(); - } - } - break; - - case OPT_ADVANCED_SH2_OPTIMIZE: - cur_menu = MENU_OPTIMIZE; - cur_option = 0; - max_option = OPT_OPTIMIZE__MAX; - break; - - case OPT_ADVANCED_MEDIA_ENGINE: - if (me_available) { - cur_menu = MENU_MEDIA_ENGINE; - cur_option = 0; - max_option = OPT_MEDIA_ENGINE__MAX; - } - break; - - case OPT_ADVANCED_DECILINE_MODE: - if (!config_set_deciline_mode(!config_get_deciline_mode())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - YabauseSetDecilineMode(config_get_deciline_mode()); - break; - - case OPT_ADVANCED_AUDIO_SYNC: - if (!config_set_audio_sync(!config_get_audio_sync())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - ScspSetFrameAccurate(config_get_audio_sync()); - break; - - case OPT_ADVANCED_CLOCK_SYNC: - if (!config_set_clock_sync(!config_get_clock_sync())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_ADVANCED_CLOCK_FIXED_TIME: - if (!config_set_clock_fixed_time(!config_get_clock_fixed_time())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_optimize(const uint32_t buttons) -{ - uint32_t optflags = config_get_sh2_optimizations(); - - switch ((OptimizeMenuOption)cur_option) { - case OPT_OPTIMIZE_ASSUME_SAFE_DIVISION: - optflags ^= SH2_OPTIMIZE_ASSUME_SAFE_DIVISION; - break; - case OPT_OPTIMIZE_FOLD_SUBROUTINES: - optflags ^= SH2_OPTIMIZE_FOLD_SUBROUTINES; - break; - case OPT_OPTIMIZE_BRANCH_TO_RTS: - optflags ^= SH2_OPTIMIZE_BRANCH_TO_RTS; - break; - case OPT_OPTIMIZE_LOCAL_ACCESSES: - optflags ^= SH2_OPTIMIZE_LOCAL_ACCESSES; - break; - case OPT_OPTIMIZE_POINTERS: - optflags ^= SH2_OPTIMIZE_POINTERS; - break; - case OPT_OPTIMIZE_POINTERS_MAC: - optflags ^= SH2_OPTIMIZE_POINTERS_MAC; - break; - case OPT_OPTIMIZE_LOCAL_POINTERS: - optflags ^= SH2_OPTIMIZE_LOCAL_POINTERS; - break; - case OPT_OPTIMIZE_STACK: - optflags ^= SH2_OPTIMIZE_STACK; - break; -#if 0 // FIXME: out of space on the screen - case OPT_OPTIMIZE_MAC_NOSAT: - optflags ^= SH2_OPTIMIZE_MAC_NOSAT; - break; -#endif - } - - if (!config_set_sh2_optimizations(optflags)) { - status_text = "Failed to set optimization flags!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - sh2_set_optimizations(optflags); -} - -/*----------------------------------*/ - -static void process_option_media_engine(const uint32_t buttons) -{ - switch ((MediaEngineMenuOption)cur_option) { - case OPT_MEDIA_ENGINE_USE_ME: - if (me_available) { - if (!config_set_use_me(!config_get_use_me())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - break; - - case OPT_MEDIA_ENGINE_WRITEBACK_PERIOD: - case OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY: - /* Don't do anything for the confirm button */ - break; - } -} - -/*----------------------------------*/ - -static void process_option_yesno(const uint32_t buttons) -{ - if (yesno_menu == MENU_GENERAL && yesno_option == OPT_GENERAL_BUP_SAVE_AS) { - if (cur_option == OPT_YESNO_YES) { - if (!config_set_path_bup(save_as_path)) { - status_text = "Failed to store new backup RAM filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else if (!save_backup_ram()) { - status_text = "Error saving backup RAM!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else { - static char buf[50]; - snprintf(buf, sizeof(buf), "Backup RAM saved to: %.25s%s", - save_as_path, strlen(save_as_path) > 25 ? "..." : ""); - status_text = buf; - status_color = TEXT_COLOR_OK; - status_timer = STATUS_DISPTIME; - } - } - free(save_as_path); - - } else { - DMSG("Invalid previous menu/option: %u/%u", yesno_menu, yesno_option); - } - - cur_menu = yesno_menu; - cur_option = yesno_option; - max_option = yesno_maxopt; -} - -/*-----------------------------------------------------------------------*/ - -/** - * process_input_filesel: Process input directed to a file selector. - * - * [Parameters] - * new_buttons: Buttons which were pressed this frame (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -static void process_input_filesel(const uint32_t new_buttons) -{ - filesel_process(filesel, new_buttons); - - if (filesel_done(filesel)) { - - const char *filename = filesel_selected_file(filesel); - - if (filename) { - - /* We only need to reset if the emulator has already been - * started */ - int need_reset = yabause_initted; - - /* We can only come here from the "Files" menu, so there's no - * need to check cur_menu */ - - switch ((FilesMenuOption)cur_option) { - - case OPT_FILES_PATH_BIOS: - if (strcmp(config_get_path_bios(), filename) == 0) { - need_reset = 0; - } - if (!config_set_path_bios(filename)) { - status_text = "Failed to set BIOS image filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - if (yabause_initted) { - if (LoadBios(filename) != 0) { - status_text = "Failed to load BIOS image!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - } - break; - - case OPT_FILES_PATH_CD: - if (strcmp(config_get_path_cd(), filename) == 0) { - need_reset = 0; - } - if (!config_set_path_cd(filename)) { - status_text = "Failed to set CD image filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - if (yabause_initted) { - /* Unfortunately, Cs2ChangeCDCore() doesn't return an error - * if the load fails, so we'll just hope it worked. */ - Cs2ChangeCDCore(CDCORE_ISO, filename); - } - break; - - case OPT_FILES_PATH_BUP: - if (strcmp(config_get_path_bup(), filename) == 0) { - need_reset = 0; - } - if (!config_set_path_bup(filename)) { - status_text = - "Failed to set backup RAM image filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - if (yabause_initted) { - if (LoadBackupRam(filename) != 0) { - status_text = "Failed to load backup RAM image!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - } - break; - - default: // impossible - break; - - } - - if (need_reset) { - do_reset(); - } - - } // if (filename) - - filesel_destroy(filesel); - filesel = NULL; - - } // if (filesel_done(filesel)) -} - -/*-----------------------------------------------------------------------*/ - -/** - * process_osk_result: Process the result of input to the on-screen - * keyboard. Assumes the OSK is currently active. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void process_osk_result(void) -{ - PRECOND(osk_status(), return); - - /* The OSK is currently only used for OPT_GENERAL_BUP_SAVE_AS, so we - * don't need to check the current menu or option index. */ - - switch (osk_result()) { - case OSK_RESULT_NONE: - /* We've already requested a close, so nothing else to do. */ - break; - - case OSK_RESULT_ERROR: - status_text = "An error occurred during on-screen keyboard input!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - osk_close(); - break; - - case OSK_RESULT_RUNNING: - break; - - case OSK_RESULT_CANCELLED: - osk_close(); - break; - - case OSK_RESULT_UNCHANGED: - case OSK_RESULT_CHANGED: { - char *path = osk_get_text(); - osk_close(); - if (!path) { - status_text = "An error occurred during on-screen keyboard input!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - break; - } else if (!*path) { - status_text = "No filename was entered!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - free(path); - break; - } else if (path[strcspn(path,":/\\")]) { - status_text = "These characters cannot be used in a filename: / \\ :"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - free(path); - break; - } - - /* Confirm the action with the user. Default to "Yes" if the file - * does not exist, "No" if it already exists. */ - save_as_path = path; - yesno_menu = cur_menu; - yesno_option = cur_option; - yesno_maxopt = max_option; - cur_menu = MENU_YESNO; - max_option = OPT_YESNO__MAX; - FILE *test = fopen(path, "r"); - if (test) { - fclose(test); - cur_option = OPT_YESNO_NO; - snprintf(yesno_prompt, sizeof(yesno_prompt), - "The file \"%.25s%s\" already exists!\n" - "Do you want to overwrite this file?\n", - path, strlen(path) > 25 ? "..." : ""); - } else { - cur_option = OPT_YESNO_YES; - snprintf(yesno_prompt, sizeof(yesno_prompt), - "Save backup RAM to the file%s\"%.50s%s\"?\n", - strlen(path) < 20 ? " " : "\n", - path, strlen(path) > 50 ? "..." : ""); - } - break; - } - } -} - -/*************************************************************************/ - -/** - * draw_menu: Draw the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void draw_menu(void) -{ - /* Set up basic settings */ - - guDisable(GU_TEXTURE_2D); - guEnable(GU_BLEND); - guBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - - /* Draw the background image, if appropriate, and overlay color */ - - if (bgimage && draw_bgimage) { - guCopyImage(GU_PSM_8888, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_STRIDE, bgimage, - 0, 0, DISPLAY_STRIDE, display_work_buffer()); - } - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, MENU_BGCOLOR); - - /* Draw the upper and lower info bars */ - - font_printf(DISPLAY_WIDTH/2, 5, 0, TEXT_COLOR_INFO, - "Yabause %s", PACKAGE_VERSION); - display_fill_box(0, 21, DISPLAY_WIDTH - 1, 21, TEXT_COLOR_INFO); - display_fill_box(0, 22, DISPLAY_WIDTH - 1, 22, 0xFF000000); - - const char *confirm_text = - (filesel != NULL) - ? "U/D/L/R: Move cursor O: Select file X: Previous menu" - : cur_option_confirm_text(); - if (x_is_confirm) { - static char swapbuf[100]; - unsigned int i; - for (i = 0; i < sizeof(swapbuf)-1 && confirm_text[i]; i++) { - if (confirm_text[i] == 'O' && confirm_text[i+1] == ':') { - swapbuf[i] = 'X'; - } else if (confirm_text[i] == 'X' && confirm_text[i+1] == ':') { - swapbuf[i] = 'O'; - } else { - swapbuf[i] = confirm_text[i]; - } - } - swapbuf[i] = 0; - confirm_text = swapbuf; - } - font_printf(DISPLAY_WIDTH/2, DISPLAY_HEIGHT - 16, 0, TEXT_COLOR_INFO, - "Select: Exit menu %s", confirm_text); - display_fill_box(0, DISPLAY_HEIGHT - 22, - DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 22, TEXT_COLOR_INFO); - display_fill_box(0, DISPLAY_HEIGHT - 21, - DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 21, 0xFF000000); - if (status_timer > 0) { - const float alpha = status_timer >= STATUS_DISPTIME/2 ? 1.0f : - (status_timer / (float)(STATUS_DISPTIME/2)); - const uint32_t alpha_byte = - floorf((status_color>>24 & 0xFF) * alpha + 0.5f); - font_printf(DISPLAY_WIDTH/2, DISPLAY_HEIGHT - 27 - FONT_HEIGHT, 0, - alpha_byte<<24 | (status_color & 0x00FFFFFF), - "%s", status_text); - } - - /* Draw the menu options and cursor */ - - const int menu_left_edge = 130; - const int line_height = FONT_HEIGHT*5/4; - const int menu_title_y = (DISPLAY_HEIGHT/2 - line_height/2) - - (7*line_height + FONT_HEIGHT) / 2 - 2*line_height; - const int menu_help_y = (DISPLAY_HEIGHT/2 - line_height/2) - - (7*line_height + FONT_HEIGHT) / 2 + 7*line_height; - const int menu_center_y = (menu_title_y + menu_help_y) / 2 + FONT_HEIGHT/2; - int x, y; - - switch ((MenuIndex)cur_menu) { - - case MENU_MAIN: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Yabause Main Menu"); - y = menu_center_y - (5*line_height + line_height/2 + FONT_HEIGHT) / 2; - draw_menu_option(OPT_MAIN_GENERAL, menu_left_edge, y, - "Configure general options..."); - y += line_height; - draw_menu_option(OPT_MAIN_BUTTON, menu_left_edge, y, - "Configure controller buttons..."); - y += line_height; - draw_menu_option(OPT_MAIN_VIDEO, menu_left_edge, y, - "Configure video options..."); - y += line_height; - draw_menu_option(OPT_MAIN_ADVANCED, menu_left_edge, y, - "Configure advanced settings..."); - y += line_height*3/2; - draw_menu_option(OPT_MAIN_SAVE, menu_left_edge, y, "Save settings"); - y += line_height; - if (yabause_initted) { - draw_menu_option(OPT_MAIN_RESET, menu_left_edge, y, - "Reset emulator"); - } else { - draw_disabled_menu_option(OPT_MAIN_RESET, menu_left_edge, y, - "Reset emulator"); - } - y = menu_help_y; - switch ((MainMenuOption)cur_option) { - case OPT_MAIN_GENERAL: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select data files" - " for use with the emulator, or change"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "other general" - " settings."); - y += line_height; - break; - case OPT_MAIN_BUTTON: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Choose which PSP" - " controls to use for the Saturn"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "controller buttons."); - y += line_height; - break; - case OPT_MAIN_VIDEO: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Choose between" - " hardware and software video rendering,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "or configure display" - " settings."); - y += line_height; - break; - case OPT_MAIN_ADVANCED: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Configure advanced" - " emulation options."); - y += line_height; - break; - case OPT_MAIN_SAVE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the current" - " settings, so Yabause will use them"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "automatically the" - " next time you start it up."); - y += line_height; - break; - case OPT_MAIN_RESET: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Reset the emulator," - " as though you had pressed the"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "Saturn's RESET" - " button. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Hold the L and R buttons"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "while selecting this" - " option."); - break; - } - break; - - case MENU_GENERAL: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure general options"); - y = menu_center_y - (5*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_GENERAL_START_IN_EMU, menu_left_edge, y, - "[%c] Start emulator immediately", - config_get_start_in_emu() ? '*' : ' '); - y += line_height*3/2; - draw_menu_option(OPT_GENERAL_FILES, menu_left_edge, y, - " Select BIOS/CD/backup files..."); - y += line_height*3/2; - draw_menu_option(OPT_GENERAL_BUP_AUTOSAVE, menu_left_edge, y, - "[%c] Auto-save backup RAM", - config_get_bup_autosave() ? '*' : ' '); - y += line_height; - if (yabause_initted) { - draw_menu_option(OPT_GENERAL_BUP_SAVE_NOW, menu_left_edge, y, - " Save backup RAM now"); - } else { - draw_disabled_menu_option(OPT_GENERAL_BUP_SAVE_NOW, menu_left_edge, - y, " Save backup RAM now"); - } - y += line_height; - if (yabause_initted) { - draw_menu_option(OPT_GENERAL_BUP_SAVE_AS, menu_left_edge, y, - " Save backup RAM as..."); - } else { - draw_disabled_menu_option(OPT_GENERAL_BUP_SAVE_AS, menu_left_edge, - y, " Save backup RAM as..."); - } - y = menu_help_y; - switch ((GeneralMenuOption)cur_option) { - case OPT_GENERAL_START_IN_EMU: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Start the Saturn" - " emulation immediately when you start"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "Yabause, rather" - " than displaying this menu. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Remember"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "to \"Save settings\"" - " after changing this option!"); - y += line_height; - break; - case OPT_GENERAL_FILES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the files" - " containing the BIOS image, CD image,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "and backup data you" - " want to use."); - y += line_height; - break; - case OPT_GENERAL_BUP_AUTOSAVE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the contents of" - " backup RAM whenever you save your"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "game in the" - " emulator. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Even if this option is" - " enabled,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "backup RAM is NOT saved" - " when you quit Yabause."); - y += line_height; - break; - case OPT_GENERAL_BUP_SAVE_NOW: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the current" - " contents of backup RAM to your"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "Memory Stick."); - y += line_height; - break; - case OPT_GENERAL_BUP_SAVE_AS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the current" - " contents of backup RAM in a new file"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "on your Memory Stick." - " The new file will be used for"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "automatic and manual" - " saves until you quit Yabause."); - y += line_height; - break; - } - break; - - case MENU_FILES: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Select BIOS/CD/backup files"); - y = menu_center_y - (2*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_FILES_PATH_BIOS, menu_left_edge, y, - "Select BIOS image (%s)", config_get_path_bios()); - y += line_height; - draw_menu_option(OPT_FILES_PATH_CD, menu_left_edge, y, - "Select CD image (%s)", config_get_path_cd()); - y += line_height; - draw_menu_option(OPT_FILES_PATH_BUP, menu_left_edge, y, - "Select backup RAM file (%s)", config_get_path_bup()); - y = menu_help_y; - switch ((FilesMenuOption)cur_option) { - case OPT_FILES_PATH_BIOS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the file" - " containing the Saturn BIOS image."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Changing this file" - " will reset the emulator."); - y += line_height; - break; - case OPT_FILES_PATH_CD: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the file" - " containing the CD image you want to"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "use. This can be either" - " an ISO file or a CUE file."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Changing this file" - " will reset the emulator."); - y += line_height; - break; - case OPT_FILES_PATH_BUP: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the file" - " containing your backup RAM data."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Changing this file" - " will reset the emulator."); - y += line_height; - break; - } - break; - - case MENU_BUTTON: { - static const char saturn_buttons[] = { - [OPT_BUTTON_A] = 'A', - [OPT_BUTTON_B] = 'B', - [OPT_BUTTON_C] = 'C', - [OPT_BUTTON_X] = 'X', - [OPT_BUTTON_Y] = 'Y', - [OPT_BUTTON_Z] = 'Z', - }; - auto inline const char *psp_button_name(const uint32_t bitmask); - auto inline const char *psp_button_name(const uint32_t bitmask) { - static const char * const psp_button_names[] = { - [31 - __builtin_clz(PSP_CTRL_CIRCLE )] = "Circle", - [31 - __builtin_clz(PSP_CTRL_CROSS )] = "Cross", - [31 - __builtin_clz(PSP_CTRL_TRIANGLE)] = "Triangle", - [31 - __builtin_clz(PSP_CTRL_SQUARE )] = "Square", - }; - const unsigned int index = 31 - __builtin_clz(bitmask); - return (index < lenof(psp_button_names) && psp_button_names[index]) - ? psp_button_names[index] : "(None)"; - } - - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure controller buttons"); - y = menu_center_y - (5*line_height + FONT_HEIGHT) / 2; - unsigned int i; - for (i = OPT_BUTTON_A; i <= OPT_BUTTON_Z; i++) { - const uint32_t psp_button = - config_get_button(CONFIG_BUTTON_A + (i - OPT_BUTTON_A)); - draw_menu_option(i, menu_left_edge, y, "%c --- %s", - saturn_buttons[i], psp_button_name(psp_button)); - y += line_height; - } - y = menu_help_y; - font_printf(75, y, -1, TEXT_COLOR_INFO, "Press one of the" - " Circle/Cross/Triangle/Square buttons"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "to assign that PSP button" - " to the Saturn controller's"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "%c button. (L, R, and Start" - " cannot be reassigned.)", saturn_buttons[cur_option]); - y += line_height; - break; - } // case MENU_BUTTON - - case MENU_VIDEO: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure video options"); - y = menu_center_y - (4*line_height + line_height/2 + FONT_HEIGHT) / 2; - draw_menu_option(OPT_VIDEO_HW, menu_left_edge, y, - "(%c) Use hardware video renderer", - config_get_module_video()==VIDCORE_PSP ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_VIDEO_SW, menu_left_edge, y, - "(%c) Use software video renderer", - config_get_module_video()==VIDCORE_SOFT ? '*' : ' '); - y += line_height*3/2; - draw_menu_option(OPT_VIDEO_RENDER, menu_left_edge, y, - " Configure hardware rendering settings..."); - y += line_height; - draw_menu_option(OPT_VIDEO_FRAME_SKIP, menu_left_edge, y, - " Configure frame-skip settings..."); - y += line_height; - draw_menu_option(OPT_VIDEO_SHOW_FPS, menu_left_edge, y, - "[%c] Show FPS", config_get_show_fps() ? '*' : ' '); - y = menu_help_y; - switch ((VideoMenuOption)cur_option) { - case OPT_VIDEO_HW: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The hardware video" - " renderer is fast, but may not always"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "display accurate" - " graphics."); - y += line_height; - break; - case OPT_VIDEO_SW: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The software video" - " renderer is slow, but more faithful"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "to the actual Saturn" - " display."); - y += line_height; - break; - case OPT_VIDEO_RENDER: - font_printf(75, y, -1, TEXT_COLOR_INFO, "This submenu lets you" - " change certain aspects of the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "hardware video" - " renderer's behavior. The options do not"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "affect the software" - " video renderer."); - y += line_height; - break; - case OPT_VIDEO_FRAME_SKIP: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The hardware renderer" - " can be configured to skip drawing"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "some frames to speed" - " up the emulation. This submenu lets"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "you choose whether to" - " skip frames and how many to skip."); - y += line_height; - break; - case OPT_VIDEO_SHOW_FPS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Display the emulator's" - " current speed in frames per second"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "in the upper-right" - " corner of the screen."); - y += line_height; - break; - } - break; - - case MENU_RENDER: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure hardware rendering settings"); - y = menu_center_y - (4*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_RENDER_CACHE_TEXTURES, menu_left_edge, y, - "[%c] Aggressively cache pixel data", - config_get_cache_textures() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_SMOOTH_TEXTURES, menu_left_edge, y, - "[%c] Smooth textures and sprites", - config_get_smooth_textures() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_SMOOTH_HIRES, menu_left_edge, y, - "[%c] Smooth high-resolution graphics", - config_get_smooth_hires() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_ENABLE_ROTATE, menu_left_edge, y, - "[%c] Enable rotated/distorted graphics", - config_get_enable_rotate() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_OPTIMIZE_ROTATE, menu_left_edge, y, - "[%c] Optimize rotated/distorted graphics", - config_get_optimize_rotate() ? '*' : ' '); - y = menu_help_y; - switch ((RenderMenuOption)cur_option) { - case OPT_RENDER_CACHE_TEXTURES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Try to cache native" - " pixel data to speed up drawing."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This may cause the" - " wrong graphics to be shown in"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "rare cases."); - y += line_height; - break; - case OPT_RENDER_SMOOTH_TEXTURES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Apply smoothing" - " (antialiasing) to textures and sprites."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This can reduce" - " jaggedness in 3-D environments, but may"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "also blur images" - " originally intended to look pixelated."); - y += line_height; - break; - case OPT_RENDER_SMOOTH_HIRES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Apply smoothing to" - " high-resolution background graphics."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This can make high" - "-resolution screens look clearer, but"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "may also slow down" - " the emulator."); - y += line_height; - break; - case OPT_RENDER_ENABLE_ROTATE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Rotated or distorted" - " background graphics can slow down"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "the emulator" - " significantly. Disable this option to"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "turn them off."); - y += line_height; - break; - case OPT_RENDER_OPTIMIZE_ROTATE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Some types of rotated" - " graphics can be drawn quickly,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "at the expense of" - " accuracy. Disable this option to"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "always use the" - " accurate (but slow) drawing method."); - y += line_height; - break; - } - break; - - case MENU_FRAME_SKIP: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure frame-skip settings"); - y = menu_center_y - (3*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_FRAME_SKIP_AUTO, menu_left_edge, y, - " Frame-skip mode: [%s]", - config_get_frameskip_auto() ? " Auto " : "Manual"); - y += line_height; - draw_menu_option(OPT_FRAME_SKIP_NUM, menu_left_edge, y, - " Number of frames to skip: [%d]", - config_get_frameskip_num()); - y += line_height; - draw_menu_option(OPT_FRAME_SKIP_INTERLACE, menu_left_edge, y, - "[%c] Limit to 30fps for interlaced display", - config_get_frameskip_interlace() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_FRAME_SKIP_ROTATE, menu_left_edge, y, - "[%c] Halve framerate for rotated backgrounds", - config_get_frameskip_rotate() ? '*' : ' '); - y = menu_help_y; - switch ((FrameSkipMenuOption)cur_option) { - case OPT_FRAME_SKIP_AUTO: - if (config_get_frameskip_auto()) { - font_printf(75, y, -1, TEXT_COLOR_INFO, "In Auto mode, the" - " emulator will automatically choose the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "number of frames to" - " skip depending on the emulation speed."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Note: Auto mode is" - " not currently implemented."); - y += line_height; - } else { - font_printf(75, y, -1, TEXT_COLOR_INFO, "In Manual mode, the" - " emulator will always skip the number"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "of frames set in" - " this menu."); - y += line_height; - } - break; - case OPT_FRAME_SKIP_NUM: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The number of frames" - " to skip for every frame drawn when"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "Manual mode is" - " selected. 0 means \"draw every frame\","); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "1 means \"draw every" - " second frame\", and so on."); - y += line_height; - break; - case OPT_FRAME_SKIP_INTERLACE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Always skip at least" - " one frame when drawing interlaced"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "(high-resolution)" - " screens. Has no effect unless the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "\"number of frames" - " to skip\" is set to zero."); - y += line_height; - break; - case OPT_FRAME_SKIP_ROTATE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Reduce the frame rate" - " by half when rotated or distorted"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "background graphics are" - " displayed."); - y += line_height; - break; - } - break; - - case MENU_ADVANCED: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure advanced emulation options"); - y = menu_center_y - (6*(line_height-2) + 2*((line_height-2)/2) + FONT_HEIGHT) / 2; - draw_menu_option(OPT_ADVANCED_SH2_RECOMPILER, menu_left_edge, y, - "[%c] Use SH-2 recompiler", - config_get_module_sh2()==SH2CORE_PSP ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_SH2_OPTIMIZE, menu_left_edge, y, - " Select SH-2 optimizations..."); - y += (line_height-2)*3/2; - if (me_available) { - draw_menu_option(OPT_ADVANCED_MEDIA_ENGINE, menu_left_edge, y, - " Configure Media Engine options..."); - } else { - draw_disabled_menu_option(OPT_ADVANCED_MEDIA_ENGINE, - menu_left_edge, y, - " Configure Media Engine options..."); - } - y += (line_height-2)*3/2; - draw_menu_option(OPT_ADVANCED_DECILINE_MODE, menu_left_edge, y, - "[%c] Use more precise emulation timing", - config_get_deciline_mode() ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_AUDIO_SYNC, menu_left_edge, y, - "[%c] Sync audio output to emulation", - config_get_audio_sync() ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_CLOCK_SYNC, menu_left_edge, y, - "[%c] Sync Saturn clock to emulation", - config_get_clock_sync() ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_CLOCK_FIXED_TIME, menu_left_edge, y, - "[%c] Always start from 1998-01-01 12:00", - config_get_clock_fixed_time() ? '*' : ' '); - y = menu_help_y; - switch ((AdvancedMenuOption)cur_option) { - case OPT_ADVANCED_SH2_RECOMPILER: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Use the SH-2 recompiler" - " instead of the much slower"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "interpreter. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Changing this option will" - " reset the emulator."); - y += line_height; - break; - case OPT_ADVANCED_SH2_OPTIMIZE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Enable or disable" - " specific optimizations used by the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "SH-2 recompiler."); - y += line_height; - break; - case OPT_ADVANCED_MEDIA_ENGINE: - if (me_available) { - font_printf(75, y, -1, TEXT_COLOR_INFO, "Enable or disable" - " use of the PSP's Media Engine for"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "emulation, and" - " configure various parameters used by"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "the Media Engine."); - y += line_height; - } else { - font_printf(75, y, -1, TEXT_COLOR_NG, "The Media Engine access" - " library (me.prx) was not found,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "so the Media Engine" - " cannot be used for emulation."); - y += line_height; - } - break; - case OPT_ADVANCED_DECILINE_MODE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Increase the precision" - " of the emulator's execution timing."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This slows down the" - " emulation, but may be required for"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "some games to work" - " correctly."); - y += line_height; - break; - case OPT_ADVANCED_AUDIO_SYNC: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Synchronize the" - " generated audio data with the emulation."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This keeps the audio" - " and video in sync, but causes audio"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "dropouts when the" - " emulator runs slower than real time."); - y += line_height; - break; - case OPT_ADVANCED_CLOCK_SYNC: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Synchronize the" - " Saturn's internal clock with the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "emulation, rather" - " than following real time regardless"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "of emulation speed."); - y += line_height; - break; - case OPT_ADVANCED_CLOCK_FIXED_TIME: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Start the Saturn's" - " internal clock at 1998-01-01 12:00"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "every time the" - " emulator is reset. Generally only"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "useful for debugging."); - y += line_height; - break; - } - break; - - case MENU_OPTIMIZE: { - const uint32_t optflags = config_get_sh2_optimizations(); - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Select SH-2 emulation optimizations"); - y = menu_center_y - (7*(line_height-2) + FONT_HEIGHT) / 2; - draw_menu_option(OPT_OPTIMIZE_ASSUME_SAFE_DIVISION, menu_left_edge, y, - "[%c] Assume safe division operations", - optflags & SH2_OPTIMIZE_ASSUME_SAFE_DIVISION ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_FOLD_SUBROUTINES, menu_left_edge, y, - "[%c] Fold short subroutines into callers", - optflags & SH2_OPTIMIZE_FOLD_SUBROUTINES ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_BRANCH_TO_RTS, menu_left_edge, y, - "[%c] Optimize branch/return pairs", - optflags & SH2_OPTIMIZE_BRANCH_TO_RTS ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_LOCAL_ACCESSES, menu_left_edge, y, - "[%c] Optimize accesses to local data", - optflags & SH2_OPTIMIZE_LOCAL_ACCESSES ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_POINTERS, menu_left_edge, y, - "[%c] Optimize pointer register accesses", - optflags & SH2_OPTIMIZE_POINTERS ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_POINTERS_MAC, menu_left_edge, y, - " [%c] Try harder for MAC instructions", - optflags & SH2_OPTIMIZE_POINTERS_MAC ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_LOCAL_POINTERS, menu_left_edge, y, - " [%c] Assume consistent local pointers", - optflags & SH2_OPTIMIZE_LOCAL_ACCESSES ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_STACK, menu_left_edge, y, - "[%c] Optimize stack accesses", - optflags & SH2_OPTIMIZE_STACK ? '*' : ' '); -#if 0 // FIXME: out of space on the screen - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_MAC_NOSAT, menu_left_edge, y, - "[%c] Optimize unsaturated multiplication", - optflags & SH2_OPTIMIZE_MAC_NOSAT ? '*' : ' '); -#endif - y = menu_help_y; - switch ((OptimizeMenuOption)cur_option) { - case OPT_OPTIMIZE_ASSUME_SAFE_DIVISION: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up division" - " operations by assuming that quotients"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "will not overflow" - " and division by zero will not occur."); - y += line_height; - break; - case OPT_OPTIMIZE_FOLD_SUBROUTINES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Fold (inline) short," - " simple subroutines into the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "routines which call" - " them. May cause crashes"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "with games that use" - " self-modifying code."); - y += line_height; - break; - case OPT_OPTIMIZE_BRANCH_TO_RTS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up branches" - " which target RTS instructions."); - y += line_height; - break; - case OPT_OPTIMIZE_LOCAL_ACCESSES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Detect and speed up" - " accesses to function-local data."); - y += line_height; - break; - case OPT_OPTIMIZE_POINTERS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Detect SH-2 registers" - " which are used as data pointers,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "and speed up memory" - " accesses through those registers."); - y += line_height; - break; - case OPT_OPTIMIZE_POINTERS_MAC: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Try harder to optimize" - " pointers to MAC (multiply-and-"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "accumulate) instructions." - " Ineffective unless pointer"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "optimizations are also" - " enabled."); - y += line_height; - break; - case OPT_OPTIMIZE_LOCAL_POINTERS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Assume that pointers" - " loaded from local data or with a"); - y += line_height-2; - font_printf(75, y, -1, TEXT_COLOR_INFO, "MOVA instruction will" - " always access the same region of"); - y += line_height-2; - font_printf(75, y, -1, TEXT_COLOR_INFO, "memory. Ineffective" - " unless pointer and local data"); - y += line_height-2; - font_printf(75, y, -1, TEXT_COLOR_INFO, "optimizations are also" - " enabled."); - y += line_height-2; - break; - case OPT_OPTIMIZE_STACK: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up accesses to" - " the SH-2 stack."); - y += line_height; - break; -#if 0 // FIXME: out of space on the screen - case OPT_OPTIMIZE_MAC_NOSAT: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up multiply-and" - "-accumulate operations which are"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "known not to use" - " saturation."); - y += line_height; -#endif - } - break; - } - - case MENU_MEDIA_ENGINE: { - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure Media Engine options"); - y = menu_center_y - (2*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_MEDIA_ENGINE_USE_ME, menu_left_edge, y, - "[%c] Use Media Engine for emulation", - config_get_use_me() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_MEDIA_ENGINE_WRITEBACK_PERIOD, menu_left_edge, y, - " Cache writeback frequency: [1/%-2u]", - config_get_me_writeback_period()); - y += line_height; - draw_menu_option(OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY, menu_left_edge, y, - " Sound RAM write-through region: [%3uk]", - config_get_me_uncached_boundary() / 1024); - y = menu_help_y; - switch ((MediaEngineMenuOption)cur_option) { - case OPT_MEDIA_ENGINE_USE_ME: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Use the Media Engine" - " CPU for emulation. This option"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "is "); - x = font_printf(x, y, -1, TEXT_COLOR_NG, "EXPERIMENTAL"); - font_printf(x, y, -1, TEXT_COLOR_INFO, "; see the manual" - " for details."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "You must restart" - " Yabause after changing this option."); - y += line_height; - break; - case OPT_MEDIA_ENGINE_WRITEBACK_PERIOD: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The relative" - " frequency of data cache synchronization when"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "using the Media" - " Engine for emulation. 1/1 is safest;"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "lower frequencies" - " may run faster, but may also crash."); - y += line_height; - break; - case OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The size of the" - " region at the beginning of sound RAM"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "which is written" - " through the PSP's cache. Larger values"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "are safer but slower;" - " 2k should be good for most games."); - y += line_height; - break; - } - break; - } - - case MENU_YESNO: { - int nlines; - char buf[100]; - const char *s, *eol; - for (s = yesno_prompt; *s; s = eol+1) { - eol = s + strcspn(s, "\n"); - nlines++; - } - y = DISPLAY_HEIGHT/2 - ((nlines+1) * line_height + FONT_HEIGHT) / 2; - for (s = yesno_prompt; *s; s = eol+1, y += line_height) { - eol = s + strcspn(s, "\n"); - snprintf(buf, sizeof(buf), "%.*s", eol - s, s); - font_printf(DISPLAY_WIDTH/2, y, 0, TEXT_COLOR_INFO, buf); - } - y += line_height; - draw_menu_option(OPT_YESNO_YES, DISPLAY_WIDTH/2 - 45, y, "Yes"); - draw_menu_option(OPT_YESNO_NO, DISPLAY_WIDTH/2 + 30, y, "No"); - } - - } // switch (cur_menu) - - /* If a file selector is open, draw it */ - - if (filesel) { - filesel_draw(filesel); - } -} - -/*----------------------------------*/ - -/** - * cur_option_confirm_text: Return the text to be displayed for the - * "confirm" button help. - * - * [Parameters] - * None - * [Return value] - * String to display for the "confirm" button help - */ -static const char *cur_option_confirm_text(void) -{ - switch ((MenuIndex)cur_menu) { - case MENU_MAIN: - switch ((MainMenuOption)cur_option) { - case OPT_MAIN_SAVE: - return "O: Save settings"; - case OPT_MAIN_RESET: - return yabause_initted ? "L+R+O: Reset emulator" : ""; - default: - return "O: Enter submenu"; - } - case MENU_GENERAL: - switch ((GeneralMenuOption)cur_option) { - case OPT_GENERAL_FILES: - return "O: Enter submenu X: Return to previous menu"; - case OPT_GENERAL_BUP_SAVE_NOW: - case OPT_GENERAL_BUP_SAVE_AS: - if (yabause_initted) { - return "O: Save backup RAM X: Return to previous menu"; - } else { - return "X: Return to previous menu"; - } - default: - return "O: Toggle on/off X: Return to previous menu"; - } - case MENU_FILES: - return "O: Select file X: Return to previous menu"; - case MENU_BUTTON: - return "O/X/Triangle/Square: Assign button Start: Previous menu"; - case MENU_VIDEO: - switch ((VideoMenuOption)cur_option) { - case OPT_VIDEO_RENDER: - case OPT_VIDEO_FRAME_SKIP: - return "O: Enter submenu X: Return to previous menu"; - case OPT_VIDEO_SHOW_FPS: - return "O: Toggle on/off X: Return to previous menu"; - default: - return "O: Select X: Return to previous menu"; - } - case MENU_RENDER: - return "O: Toggle on/off X: Return to previous menu"; - case MENU_FRAME_SKIP: - switch ((FrameSkipMenuOption)cur_option) { - case OPT_FRAME_SKIP_AUTO: - return "O: Change setting X: Return to previous menu"; - case OPT_FRAME_SKIP_NUM: - return "Left/Right: Change setting X: Return to previous menu"; - default: - return "O: Toggle on/off X: Return to previous menu"; - } - case MENU_ADVANCED: - switch ((AdvancedMenuOption)cur_option) { - case OPT_ADVANCED_SH2_RECOMPILER: - return "L+R+O: Toggle on/off X: Return to previous menu"; - case OPT_ADVANCED_SH2_OPTIMIZE: - return "O: Enter submenu X: Return to previous menu"; - case OPT_ADVANCED_MEDIA_ENGINE: - if (me_available) { - return "O: Enter submenu X: Return to previous menu"; - } else { - return "X: Return to previous menu"; - } - default: - return "O: Toggle on/off X: Return to previous menu"; - } - case MENU_OPTIMIZE: - return "O: Toggle on/off X: Return to previous menu"; - case MENU_MEDIA_ENGINE: - switch ((FrameSkipMenuOption)cur_option) { - case OPT_MEDIA_ENGINE_USE_ME: - return "O: Change setting X: Return to previous menu"; - default: - return "Left/Right: Change setting X: Return to previous menu"; - } - case MENU_YESNO: - return "O: Confirm selection X: Cancel"; - } - DMSG("Invalid menu/option %d/%d", cur_menu, cur_option); - return "O: Confirm"; -} - -/*----------------------------------*/ - -/** - * draw_menu_option: Draw a single menu option. If the option is - * currently selected, also draws the menu cursor. - * - * [Parameters] - * option: Option ID (OPT_*) - * x, y: Text position - * format: Format string for option text - * ...: Format arguments - * [Return value] - * None - */ -static void draw_menu_option(int option, int x, int y, const char *format, ...) -{ - PRECOND(format != NULL, return); - - char buf[1000]; - va_list args; - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - int x2 = font_printf(x, y, -1, TEXT_COLOR, "%s", buf); - - if (cur_option == option) { - const float cursor_alpha = - (sinf((cursor_timer / (float)CURSOR_PERIOD) * (float)M_TWOPI) + 1) - / 2; - const uint32_t cursor_alpha_byte = - floorf((CURSOR_COLOR>>24 & 0xFF) * cursor_alpha + 0.5f); - display_fill_box(x-2, y-2, x2+1, (y+FONT_HEIGHT)+1, - cursor_alpha_byte<<24 | (CURSOR_COLOR & 0x00FFFFFF)); - } -} - -/*----------------------------------*/ - -/** - * draw_disabled_menu_option: Draw a single disabled menu option. If the - * option is currently selected, also draws the menu cursor. - * - * [Parameters] - * option: Option ID (OPT_*) - * x, y: Text position - * format: Format string for option text - * ...: Format arguments - * [Return value] - * None - */ -static void draw_disabled_menu_option(int option, int x, int y, - const char *format, ...) -{ - PRECOND(format != NULL, return); - - char buf[1000]; - va_list args; - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - int x2 = font_printf(x, y, -1, TEXT_COLOR_DISABLED, "%s", buf); - - if (cur_option == option) { - const float cursor_alpha = - (sinf((cursor_timer / (float)CURSOR_PERIOD) * (float)M_TWOPI) + 1) - / 2; - const uint32_t cursor_alpha_byte = - floorf((CURSOR_COLOR>>24 & 0xFF) * cursor_alpha + 0.5f); - display_fill_box(x-2, y-2, x2+1, (y+FONT_HEIGHT)+1, - cursor_alpha_byte<<24 | (CURSOR_COLOR & 0x00FFFFFF)); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/menu.h b/yabause/src/psp/menu.h deleted file mode 100644 index 936f685b7a..0000000000 --- a/yabause/src/psp/menu.h +++ /dev/null @@ -1,79 +0,0 @@ -/* src/psp/menu.h: PSP menu interface header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_MENU_H -#define PSP_MENU_H - -/*************************************************************************/ - -/** - * menu_open: Open the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void menu_open(void); - -/** - * menu_run: Perform a single frame's processing for the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void menu_run(void); - -/** - * menu_close: Close the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void menu_close(void); - -/** - * menu_set_error: Set an error message to be displayed on the menu - * screen. If message is NULL, any message currently displayed is cleared. - * - * [Parameters] - * message: Message text (NULL to clear current message) - * [Return value] - * None - */ -extern void menu_set_error(const char *message); - -/*************************************************************************/ - -#endif // PSP_MENU_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/misc.c b/yabause/src/psp/misc.c deleted file mode 100644 index efe5c7a81a..0000000000 --- a/yabause/src/psp/misc.c +++ /dev/null @@ -1,119 +0,0 @@ -/* src/psp/misc.c: PSP support routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" - -#include "config.h" -#include "misc.h" -#include "sys.h" - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * save_backup_ram: Save the contents of backup RAM to the configured - * file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -extern int save_backup_ram(void) -{ - const char *path = config_get_path_bup(); - if (!path || !*path) { - DMSG("No backup RAM file configured!"); - goto error_return; - } - - /* Lock the power switch while writing so the user (hopefully) can't - * shut the PSP off on us. */ - scePowerLock(0); - - int fd = sceIoOpen(path, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0600); - if (fd < 0) { - DMSG("open(%s): %s", path, psp_strerror(fd)); - goto error_unlock_power; - } - - int res = sceIoWrite(fd, BupRam, 0x10000); - if (res != 0x10000) { - DMSG("write(%s): %s", path, psp_strerror(fd)); - sceIoClose(fd); - goto error_unlock_power; - } - - res = sceIoClose(fd); - if (res != 0) { - DMSG("close(%s): %s", path, psp_strerror(fd)); - goto error_unlock_power; - } - - /* All done--don't forget to unlock the power switch before returning! */ - scePowerUnlock(0); - return 1; - - error_unlock_power: - scePowerUnlock(0); - error_return: - return 0; -} - -/*************************************************************************/ - -/** - * psp_writeback_cache_for_scsp: Write back all dirty data from the SC's - * cache for an ScspExec() call, depending on the writeback frequency - * selected by the user. - * - * [Parameters] - * None - * [Return value] - * Nonzero if writeback was executed, zero if writeback was skipped - */ -int psp_writeback_cache_for_scsp(void) -{ - static uint32_t counter; - - counter++; - if (!(counter & (config_get_me_writeback_period() - 1))) { - sceKernelDcacheWritebackAll(); - return 1; - } else { - return 0; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/misc.h b/yabause/src/psp/misc.h deleted file mode 100644 index 8918620ab5..0000000000 --- a/yabause/src/psp/misc.h +++ /dev/null @@ -1,104 +0,0 @@ -/* src/psp/misc.h: PSP support routine header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_MISC_H -#define PSP_MISC_H - -/*************************************************************************/ - -/** - * save_backup_ram: Save the contents of backup RAM to the configured - * file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -extern int save_backup_ram(void); - -/** - * psp_writeback_cache_for_scsp: Write back all dirty data from the SC's - * cache for an ScspExec() call, depending on the writeback frequency - * selected by the user. - * - * [Parameters] - * None - * [Return value] - * Nonzero if writeback was skipped, zero if writeback was executed - */ -extern int psp_writeback_cache_for_scsp(void); - -/*-----------------------------------------------------------------------*/ - -/** - * checksum_fast16, checksum_fast32: Perform a fast checksum of 16-bit or - * 32-bit words in a block by simply summing all words and returning the - * cumulative 32-bit total. - * - * [Parameters] - * ptr: Pointer to memory block to checksum - * count: Number of 16-bit or 32-bit words in block - * [Return value] - * Block checksum - */ -static inline uint32_t checksum_fast16(const uint16_t *ptr, unsigned int count) -{ - uint32_t sum = 0; - for (; count >= 4; count -= 4) { - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - } - while (count--) { - sum += *ptr++; - } - return sum; -} - -static inline uint32_t checksum_fast32(const uint32_t *ptr, unsigned int count) -{ - uint32_t sum = 0; - for (; count >= 4; count -= 4) { - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - } - while (count--) { - sum += *ptr++; - } - return sum; -} - -/*************************************************************************/ - -#endif // PSP_MISC_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/osk.c b/yabause/src/psp/osk.c deleted file mode 100644 index 0e352d5190..0000000000 --- a/yabause/src/psp/osk.c +++ /dev/null @@ -1,479 +0,0 @@ -/* src/psp/osk.c: PSP on-screen keyboard management - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "osk.h" -#include "sys.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Is the on-screen keyboard active? */ -static uint8_t osk_active; - -/* Has a close been requested? */ -static uint8_t osk_closing; - -/* Parameter block pointer (only valid when osk_active != 0). Pointers to - * subsidiary data structures such as string buffers are stored within the - * appropriate parent data structure. */ -static SceUtilityOskParams *osk_params; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations. */ -static void reset_osk(void); -static uint16_t *utf8to16(const char *str); -static char *utf16to8(const uint16_t *str); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * osk_open: Open the on-screen keyboard with the given prompt string and - * default text. - * - * [Parameters] - * prompt: Prompt string - * deftext: Default text - * maxlen: Maximum length (number of _characters_, not bytes) of - * entered text, not including the trailing null - * [Return value] - * Nonzero on success, zero on failure - */ -int osk_open(const char *prompt, const char *deftext, unsigned int maxlen) -{ - PRECOND(prompt != NULL, goto error_return); - PRECOND(deftext != NULL, goto error_return); - PRECOND(maxlen > 0, goto error_return); - PRECOND(strlen(deftext) <= maxlen, goto error_return); - - if (osk_active) { - DMSG("Tried to start a second OSK while one was already active!"); - goto error_return; - } - - osk_params = calloc(1, sizeof(*osk_params)); - if (!osk_params) { - DMSG("No memory for osk_params"); - goto error_return; - } - osk_params->base.size = sizeof(*osk_params); - osk_params->base.graphicsThread = THREADPRI_UTILITY + 1; - osk_params->base.accessThread = THREADPRI_UTILITY + 3; - osk_params->base.fontThread = THREADPRI_UTILITY + 2; - osk_params->base.soundThread = THREADPRI_UTILITY; - osk_params->datacount = 1; - - osk_params->data = calloc(1, sizeof(*osk_params->data)); - if (!osk_params->data) { - DMSG("No memory for data"); - goto error_free_osk_params; - } - osk_params->data->language = PSP_UTILITY_OSK_LANGUAGE_ENGLISH; - osk_params->data->inputtype = PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE - | PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE - | PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT - | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL; - osk_params->data->lines = 1; - /* The order of these field names is apparently reversed in the current - * (r2493) PSPSDK. Set both to maxlen+1 just to be safe; the null - * terminator in "deftext" will keep the OSK from overrunning the end - * of the default text. */ - osk_params->data->outtextlength = maxlen + 1; - osk_params->data->outtextlimit = maxlen + 1; - - osk_params->data->desc = utf8to16(prompt); - if (!osk_params->data->desc) { - DMSG("No memory for prompt buffer"); - goto error_free_data; - } - - osk_params->data->intext = utf8to16(deftext); - if (!osk_params->data->intext) { - DMSG("No memory for default text buffer"); - goto error_free_desc; - } - - osk_params->data->outtext = malloc(2 * (maxlen + 1)); - if (!osk_params->data->outtext) { - DMSG("No memory for output text buffer"); - goto error_free_intext; - } - - int res = sceUtilityOskInitStart(osk_params); - if (res < 0) { - DMSG("sceUtilityOskInitStart() failed: %s", psp_strerror(res)); - return 0; - } - - osk_active = 1; - osk_closing = 0; - return 1; - - error_free_intext: - free(osk_params->data->intext); - error_free_desc: - free(osk_params->data->desc); - error_free_data: - free(osk_params->data); - error_free_osk_params: - free(osk_params); - osk_params = NULL; - error_return: - return 0; -} - -/*************************************************************************/ - -/** - * osk_update: Update the on-screen keyboard if it is active. Must be - * called once per frame while the on-screen keyboard is active; may be - * called at any other time (the function does nothing in that case). - * - * [Parameters] - * None - * [Return value] - * None - */ -void osk_update(void) -{ - if (osk_active) { - const int status = sceUtilityOskGetStatus(); - if (status == PSP_UTILITY_DIALOG_VISIBLE) { - int res = sceUtilityOskUpdate(1); - if (res < 0) { - DMSG("sceUtilityOskUpdate() failed: %s", psp_strerror(res)); - } - } else if (sceUtilityOskGetStatus() == PSP_UTILITY_DIALOG_QUIT) { - sceUtilityOskShutdownStart(); - } else if (sceUtilityOskGetStatus() == PSP_UTILITY_DIALOG_FINISHED) { - if (osk_closing) { - reset_osk(); - } - } - } -} - -/*************************************************************************/ - -/** - * osk_status: Return whether the on-screen keyboard is currently active. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the on-screen keyboard is active, else zero - */ -int osk_status(void) -{ - return osk_active; -} - -/*************************************************************************/ - -/** - * osk_result: Return the result status from the on-screen keyboard. - * - * [Parameters] - * None - * [Return value] - * Result status (OSK_RESULT_*) - */ -OSKResult osk_result(void) -{ - if (!osk_active || osk_closing) { - return OSK_RESULT_NONE; - } else if (sceUtilityOskGetStatus() != PSP_UTILITY_DIALOG_FINISHED) { - return OSK_RESULT_RUNNING; - } else if (osk_params->data->result == PSP_UTILITY_OSK_RESULT_UNCHANGED) { - return OSK_RESULT_UNCHANGED; - } else if (osk_params->data->result == PSP_UTILITY_OSK_RESULT_CHANGED) { - return OSK_RESULT_CHANGED; - } else if (osk_params->data->result == PSP_UTILITY_OSK_RESULT_CANCELLED) { - return OSK_RESULT_CANCELLED; - } else { - DMSG("Weird result value %d from OSK", osk_params->data->result); - return OSK_RESULT_ERROR; - } -} - -/*************************************************************************/ - -/** - * osk_get_text: Return the text entered by the user from the on-screen - * keyboard in a newly malloc()ed buffer. - * - * [Parameters] - * None - * [Return value] - * Entered text, or NULL if not available (e.g., if the OSK was cancelled) - */ -char *osk_get_text(void) -{ - int result = osk_result(); - if (result != OSK_RESULT_UNCHANGED && result != OSK_RESULT_CHANGED) { - return NULL; - } - - char *text = utf16to8(osk_params->data->outtext); - if (!text) { - DMSG("Failed to convert entered text to UTF-8"); - return NULL; - } - - return text; -} - -/*************************************************************************/ - -/** - * osk_close: Close the on-screen keyboard and discard all associated - * resources (including the entered text). If the on-screen keyboard is - * not active, this function does nothing. - * - * Even after calling this function, the caller MUST continue to call - * osk_update() once per frame until osk_status() returns zero. - * - * [Parameters] - * None - * [Return value] - * None - */ -void osk_close(void) -{ - if (osk_active) { - if (sceUtilityOskGetStatus() == PSP_UTILITY_DIALOG_FINISHED) { - /* Free all resources immediately. */ - reset_osk(); - } else { - /* Request a close, and free resources when the OS is done. */ - sceUtilityOskShutdownStart(); - osk_closing = 1; - } - } -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * reset_osk: Free all local resources and reset the OSK to the inactive - * state. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void reset_osk(void) -{ - PRECOND(osk_active, return); - - free(osk_params->data->outtext); - free(osk_params->data->intext); - free(osk_params->data->desc); - free(osk_params->data); - free(osk_params); - osk_params = NULL; - osk_closing = 0; - osk_active = 0; -} - -/*************************************************************************/ - -/** - * utf8to16, utf16to8: Convert a string between 8-bit and 16-bit Unicode - * formats. The returned string is stored in a newly malloc()ed buffer. - * - * [Parameters] - * str: String to convert - * [Return value] - * Converted string, or NULL on error - * [Notes] - * These functions only support Unicode characters with codepoints in - * the range 0-65535 (16-bit characters). - */ -static uint16_t *utf8to16(const char *str) -{ - /* Allocate a buffer big enough for the longest possible result; we'll - * shrink it if necessary when we're done. */ - const uint32_t bufsize = (strlen(str) + 1) * 2; - uint16_t *out = malloc(bufsize); - if (!out) { - DMSG("Can't allocate %u bytes", bufsize); - return NULL; - } - - /* Convert the string, character by character. */ - uint32_t pos = 0, len = 0; - while (str[pos] != 0) { - const uint8_t ch = (uint8_t)str[pos++]; - if (ch < 0x80) { - out[len++] = ch; - } else if (ch < 0xC0) { - /* Continuation bytes are invalid as the first byte of a UTF-8 - * sequence. */ - DMSG("Invalid continuation byte 0x%02X at offset %u", ch, pos-1); - goto fail; - } else if (ch < 0xE0) { - const uint8_t ch_1 = (uint8_t)str[pos++]; - if (ch_1 < 0x80 || ch_1 >= 0xC0) { - /* The required continuation byte is missing, so treat this - * character as unknown and restart processing on the - * second byte (which we just checked). */ - DMSG("Missing continuation byte at offset %u (got 0x%02X)", - pos-1, ch_1); - goto fail; - } else if (ch < 0xC2) { - /* Characters with codepoints less than 128 must be coded - * using the single-byte format; for example, C1 9C for the - * backslash character (U+005C) is invalid. This is a - * common attack vector against security vulnerabilities, - * so we explicitly disallow such invalid forms. */ - DMSG("Invalid extended form 0x%02X 0x%02X at offset %u", - pos-2, ch, ch_1); - goto fail; - } else { - out[len++] = (ch & 0x1F) << 6 - | (ch_1 & 0x3F) << 0; - } - } else if (ch < 0xF0) { - const uint8_t ch_1 = (uint8_t)str[pos++]; - const uint8_t ch_2 = (uint8_t)str[pos++]; - if (ch_1 < 0x80 || ch_1 >= 0xC0) { - DMSG("Missing continuation byte at offset %u (got 0x%02X)", - pos-2, ch_1); - goto fail; - } else if (ch_2 < 0x80 || ch_2 >= 0xC0) { - DMSG("Missing continuation byte at offset %u (got 0x%02X)", - pos-1, ch_2); - goto fail; - } else if (ch == 0xE0 && ch_1 < 0xA0) { - DMSG("Invalid extended form 0x%02X 0x%02X 0x%02X at offset %u", - pos-3, ch, ch_1, ch_2); - goto fail; - } else { - out[len++] = (ch & 0x0F) << 12 - | (ch_1 & 0x3F) << 6 - | (ch_2 & 0x3F) << 0; - if (out[len-1] >= 0xD800 && out[len-1] < 0xE000) { - DMSG("Invalid surrogate 0x%04X at offset %u", - out[len-1], pos-3); - goto fail; - } - } - } else { - DMSG("Out-of-range codepoint with first byte 0x%02X at offset %u", - ch, pos-1); - goto fail; - } - } - - /* Append a terminating null. */ - out[len++] = 0; - - /* If we ended up with fewer characters than we allocated space for, - * shrink the output buffer before returning it. */ - if (len*2 < bufsize) { - /* This should never fail, but just in case, save the result in a - * temporary variable and check for NULL first. */ - uint16_t *new_out = realloc(out, len*2); - if (new_out) { - out = new_out; - } - } - - return out; - - fail: - free(out); - return NULL; -} - -/*----------------------------------*/ - -static char *utf16to8(const uint16_t *str) -{ - /* strlen() only works on byte streams, so we have to calculate the - * input string length manually. */ - uint32_t str_len = 0; - while (str[str_len] != 0) { - str_len++; - } - - const uint32_t bufsize = str_len*3 + 1; - char *out = malloc(bufsize); - if (!out) { - DMSG("Can't allocate %u bytes", bufsize); - return NULL; - } - - uint32_t pos = 0, len = 0; - while (str[pos] != 0) { - const uint16_t ch = str[pos++]; - if (ch < 0x80) { - out[len++] = ch; - } else if (ch < 0x800) { - out[len++] = 0xC0 | (ch>>6 & 0x1F); - out[len++] = 0x80 | (ch>>0 & 0x3F); - } else if (ch >= 0xD800 && ch < 0xE000) { - DMSG("Surrogate 0x%04X found at offset %u (not supported)", - ch, pos-1); - goto fail; - } else { - out[len++] = 0xE0 | (ch>>12 & 0x0F); - out[len++] = 0x80 | (ch>> 6 & 0x3F); - out[len++] = 0x80 | (ch>> 0 & 0x3F); - } - } - - out[len++] = 0; - - if (len < bufsize) { - char *new_out = realloc(out, len); - if (new_out) { - out = new_out; - } - } - - return out; - - fail: - free(out); - return NULL; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/osk.h b/yabause/src/psp/osk.h deleted file mode 100644 index 342a04fcc5..0000000000 --- a/yabause/src/psp/osk.h +++ /dev/null @@ -1,124 +0,0 @@ -/* src/psp/osk.h: PSP on-screen keyboard management header - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_OSK_H -#define PSP_OSK_H - -/*************************************************************************/ - -/* Result codes returned from osk_result(). */ - -typedef enum OSKResult_ { - OSK_RESULT_NONE = 0, - OSK_RESULT_RUNNING, - OSK_RESULT_UNCHANGED, - OSK_RESULT_CHANGED, - OSK_RESULT_CANCELLED, - OSK_RESULT_ERROR, -} OSKResult; - -/*-----------------------------------------------------------------------*/ - -/** - * osk_open: Open the on-screen keyboard with the given prompt string and - * default text. - * - * [Parameters] - * prompt: Prompt string - * deftext: Default text - * maxlen: Maximum length (number of _characters_, not bytes) of - * entered text, not including the trailing null - * [Return value] - * Nonzero on success, zero on failure - */ -extern int osk_open(const char *prompt, const char *deftext, - unsigned int maxlen); - -/** - * osk_update: Update the on-screen keyboard if it is active. Must be - * called once per frame while the on-screen keyboard is active; may be - * called at any other time (the function does nothing in that case). - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void osk_update(void); - -/** - * osk_status: Return whether the on-screen keyboard is currently active. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the on-screen keyboard is active, else zero - */ -extern int osk_status(void); - -/** - * osk_result: Return the result status from the on-screen keyboard. - * - * [Parameters] - * None - * [Return value] - * Result status (OSK_RESULT_*) - */ -extern OSKResult osk_result(void); - -/** - * osk_get_text: Return the text entered by the user from the on-screen - * keyboard in a newly malloc()ed buffer. - * - * [Parameters] - * None - * [Return value] - * Entered text, or NULL if not available (e.g., if the OSK was cancelled) - */ -extern char *osk_get_text(void); - -/** - * osk_close: Close the on-screen keyboard and discard all associated - * resources (including the entered text). If the on-screen keyboard is - * not active, this function does nothing. - * - * Even after calling this function, the caller MUST continue to call - * osk_update() once per frame until osk_status() returns zero. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void osk_close(void); - -/*************************************************************************/ - -#endif // PSP_OSK_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/profile.c b/yabause/src/psp/profile.c deleted file mode 100644 index 0e5e4b8746..0000000000 --- a/yabause/src/psp/profile.c +++ /dev/null @@ -1,233 +0,0 @@ -/* src/psp/profile.c: Profiling support for Yabause core - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef SYS_PROFILE_H // i.e. profiling enabled -- continues to end of file - -#include -#include -#include -#include "profile.h" - -/*************************************************************************/ - -/* Names for each tracking slot */ -const char * const prof_names[PROF__END] = { - [PROF__UNKNOWN ] = "(unknown)", - [PROF_Total_Emulation] = "Total Emulation", - [PROF_MSH2 ] = "MSH2", - [PROF_68K ] = "68K", - [PROF_SCSP ] = "SCSP", - [PROF_SCU ] = "SCU", - [PROF_SSH2 ] = "SSH2", - [PROF_CDB ] = "CDB", - [PROF_CDIO ] = "CDIO", - [PROF_SMPC ] = "SMPC", - [PROF_hblankin ] = "hblankin", - [PROF_hblankout ] = "hblankout", - [PROF_VDP1_VDP2 ] = "VDP1/VDP2", - [PROF_vblankin ] = "vblankin", - [PROF__OVERHEAD ] = "(profiling overhead)", -}; - -/* Latest start time for each tracking slot */ -static uint32_t prof_start[PROF__END]; - -/* Total run time (microseconds) for each tracking slot */ -static uint64_t prof_total[PROF__END]; - -/* Number of calls for each tracking slot */ -static uint32_t prof_calls[PROF__END]; - -/* Approximate profiling overhead per call (microseconds) */ -static double prof_overhead = 0; -/* Profiling overhead per call that appears in slot totals (microseconds) */ -static double visible_overhead = 0; - -/*************************************************************************/ -/*************************************************************************/ - -/** - * psp_profile_reset: Reset all profiling counters. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_profile_reset(void) -{ - memset(prof_start, 0, sizeof(prof_start)); - memset(prof_total, 0, sizeof(prof_total)); - memset(prof_calls, 0, sizeof(prof_calls)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_profile_start: Start the profile timer for the given slot with the - * given timestamp. - * - * [Parameters] - * slot: Tracking slot (0..PROF__END-1) - * timestamp: 32-bit system timestamp from sceKernelGetSystemTimeLow() - * [Return value] - * None - */ -__attribute__((noinline)) // To avoid throwing off overhead measurements -void psp_profile_start(int slot, uint32_t timestamp) -{ - /* Make sure this runs quickly, since it counts against the slot's run - * time */ - prof_start[slot] = timestamp; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_profile_stop: Stop the profile timer for the given slot, and update - * the call count and total run time. - * - * [Parameters] - * slot: Tracking slot (0..PROF__END-1) - * timestamp: 32-bit system timestamp from sceKernelGetSystemTimeLow() - * [Return value] - * None - * [Notes] - * The run time for a single call must not exceed 2^32-1 microseconds - * (about 71.5 minutes), or the profiling totals will be inaccurate. - */ -__attribute__((noinline)) -void psp_profile_stop(int slot, uint32_t timestamp) -{ - const uint32_t run_time = timestamp - prof_start[slot]; - prof_total[slot] += run_time; - prof_calls[slot]++; -} - -/*************************************************************************/ - -/** - * psp_profile_print: Print profiling statistics. Information for each slot - * with a nonzero call count is printed on one line, sorted in descending - * order by total run time. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_profile_print(void) -{ - int order[PROF__END]; - double usec[PROF__END]; - int num_slots = 0; - int i, j; - - /* First calculate the approximate profiling overhead per call, if we - * haven't done so already */ - if (!prof_overhead) { - uint32_t start = sceKernelGetSystemTimeLow(); - for (i = 0; i < 1000; i++) { - psp_profile_start(PROF__OVERHEAD, sceKernelGetSystemTimeLow()); - psp_profile_stop(PROF__OVERHEAD, sceKernelGetSystemTimeLow()); - } - uint32_t end = sceKernelGetSystemTimeLow(); - prof_overhead = (end - start) / 1000.0; - - uint32_t visible_sum = 0; - for (i = 0; i < 1000; i++) { - uint32_t this_time = sceKernelGetSystemTimeLow(); - psp_profile_start(PROF__OVERHEAD, this_time); - visible_sum += sceKernelGetSystemTimeLow() - this_time; - } - visible_overhead = visible_sum / 1000.0; - } - - /* Find which slots need to be printed, and calculate their data along - * with total overhead */ - uint32_t total_calls = 0; - double total_overhead = 0; - for (i = 0; i < PROF__OVERHEAD; i++) { - if (prof_calls[i] > 0) { - order[num_slots++] = i; - if (i == PROF_Total_Emulation) { - /* We'll subtract the total overhead from this value once - * we know it */ - usec[i] = (double)prof_total[i]; - } else { - const double overhead = visible_overhead * prof_calls[i]; - usec[i] = (double)prof_total[i] - overhead; - } - } - total_calls += prof_calls[i]; - total_overhead += prof_overhead * prof_calls[i]; - } - /* Invisible overhead from the PROF_Total_Emulation slot isn't included - * in the first place, so don't try to subtract it out */ - total_overhead -= (prof_overhead - visible_overhead) - * prof_calls[PROF_Total_Emulation]; - usec[PROF_Total_Emulation] -= total_overhead; - - /* Sort the slots by total run time. There aren't many slots, so a - * selection sort will do fine */ - for (i = 0; i < num_slots-1; i++) { - int best = i; - for (j = i+1; j < num_slots; j++) { - if (usec[order[j]] > usec[order[best]]) { - best = j; - } - } - if (best != i) { - const int tmp = order[i]; - order[i] = order[best]; - order[best] = tmp; - } - } - - /* Print out the sorted info, adjusting for overhead */ - printf(" Calls Total (s) usec/call %% of max Name\n"); - const double max_usec = usec[order[0]]; - for (i = 0; i < num_slots; i++) { - const double sec = usec[order[i]] / 1000000.0; - const double avg = (sec / prof_calls[order[i]]) * 1000000.0; - const double pct= (usec[order[i]] / max_usec) * 100.0; - printf("%8u %9.3f %9.2f %5.1f%% %s\n", - prof_calls[order[i]], sec, avg, pct, prof_names[order[i]]); - } - printf("%8u %9.3f %9.2f %5.1f%% %s\n", - total_calls, total_overhead / 1000000.0, - (total_overhead / total_calls), - (total_overhead / max_usec) * 100.0, "(profiling overhead)"); -} - -/*************************************************************************/ -/*************************************************************************/ - -#endif // #ifdef SYS_PROFILE_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/profile.h b/yabause/src/psp/profile.h deleted file mode 100644 index 3a0bc8460f..0000000000 --- a/yabause/src/psp/profile.h +++ /dev/null @@ -1,106 +0,0 @@ -/* src/psp/profile.h: Profiling header for Yabause core - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_PROFILE_H -#define PSP_PROFILE_H - -#include // for sceKernelGetSystemTimeLow() - -/*************************************************************************/ - -/* Tracking slots */ -enum { - PROF__UNKNOWN = 0, // For any non-matching name - PROF_Total_Emulation, - PROF_MSH2, - PROF_68K, - PROF_SCSP, - PROF_SCU, - PROF_SSH2, - PROF_CDB, - PROF_CDIO, - PROF_SMPC, - PROF_hblankin, - PROF_hblankout, - PROF_VDP1_VDP2, - PROF_vblankin, - PROF__OVERHEAD, // Internal use only (for calculating profiling overhead) - PROF__END -}; - -/*-----------------------------------------------------------------------*/ - -/* Helper macro that converts string parameters to PROFILE_{START,STOP}() - * into PROF_* indices. Note that as long as the parameter is a string - * literal, compiler optimization will convert the whole thing into a - * single compile-time constant. */ - -#define PROFILE_INDEX(name) \ - (strcmp((name),"Total Emulation") == 0 ? PROF_Total_Emulation : \ - strcmp((name),"MSH2" ) == 0 ? PROF_MSH2 : \ - strcmp((name),"68K" ) == 0 ? PROF_68K : \ - strcmp((name),"SCSP" ) == 0 ? PROF_SCSP : \ - strcmp((name),"SCU" ) == 0 ? PROF_SCU : \ - strcmp((name),"SSH2" ) == 0 ? PROF_SSH2 : \ - strcmp((name),"CDB" ) == 0 ? PROF_CDB : \ - strcmp((name),"CDIO" ) == 0 ? PROF_CDIO : \ - strcmp((name),"SMPC" ) == 0 ? PROF_SMPC : \ - strcmp((name),"hblankin" ) == 0 ? PROF_hblankin : \ - strcmp((name),"hblankout" ) == 0 ? PROF_hblankout : \ - strcmp((name),"VDP1/VDP2" ) == 0 ? PROF_VDP1_VDP2 : \ - strcmp((name),"vblankin" ) == 0 ? PROF_vblankin : \ - PROF__UNKNOWN) - -/*-----------------------------------------------------------------------*/ - -/* Macros called by the Yabause core. */ - -#define PROFILE_START(name) \ - psp_profile_start(PROFILE_INDEX((name)), sceKernelGetSystemTimeLow()) - -#define PROFILE_STOP(name) \ - psp_profile_stop(PROFILE_INDEX((name)), sceKernelGetSystemTimeLow()) - -#define PROFILE_PRINT() psp_profile_print() - -#define PROFILE_RESET() psp_profile_reset() - -/*-----------------------------------------------------------------------*/ - -/* Function declarations */ - -extern void psp_profile_reset(void); -extern void psp_profile_start(int slot, uint32_t timestamp); -extern void psp_profile_stop(int slot, uint32_t timestamp); -extern void psp_profile_print(void); - -/*************************************************************************/ - -#endif // PSP_PROFILE_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-cd.c b/yabause/src/psp/psp-cd.c deleted file mode 100644 index da56e64c64..0000000000 --- a/yabause/src/psp/psp-cd.c +++ /dev/null @@ -1,952 +0,0 @@ -/* src/psp/psp-cd.c: PSP virtual CD interface module - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../cdbase.h" - -#include "psp-cd.h" -#include "sys.h" - -#ifdef SYS_PROFILE_H -# include "profile.h" // Can only be our own -#else -# define DONT_PROFILE -# include "../profile.h" -#endif - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_cd_init(const char *path); -static void psp_cd_deinit(void); -static int psp_cd_get_status(void); -static s32 psp_cd_read_toc(u32 *toc_buffer); -static int psp_cd_read_sector(u32 sector, void *buffer); -static void psp_cd_read_ahead(u32 sector); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -CDInterface CDPSP = { - .id = CDCORE_PSP, - .Name = "PSP Virtual CD Interface", - .Init = psp_cd_init, - .DeInit = psp_cd_deinit, - .GetStatus = psp_cd_get_status, - .ReadTOC = psp_cd_read_toc, - .ReadSectorFAD = psp_cd_read_sector, - .ReadAheadFAD = psp_cd_read_ahead, -}; - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* File descriptor for ISO image (0 = none open) */ -static int iso_fd; - -/* Table-of-contents data for ISO image */ -static uint32_t iso_toc[102]; - -/* Sector indices and corresponding file offsets for each track */ -static struct { - uint32_t first_sector; // First sector in track (0 = nonexistent track) - uint32_t last_sector; // Last sector in track (inclusive) - uint32_t file_offset; // File offset of first sector, in bytes - uint32_t sector_size; // Size of each sector in the track, in bytes -} tracks[99]; // tracks[0] = track 1, tracks[1] = track 2, etc. - -/*----------------------------------*/ - -/* Read-ahead buffers and sectors loaded into them. We read multiple - * sectors at once to minimize the overhead from system calls. */ - -#define READ_UNIT 8 // Number of sectors to read at once - -static __attribute__((aligned(16))) - uint8_t readahead_buffer[READ_UNIT*2][2352]; -static uint32_t readahead_sector[READ_UNIT*2]; - -/*----------------------------------*/ - -/* CD read thread ID */ -static int cd_read_thid; - -/* Variables for communication with CD read thread (see cd_read_thread() - * documentation for details) */ -static volatile uint8_t cd_read_idle; -static volatile uint8_t cd_read_requested; -static volatile uint8_t cd_read_terminate; -static volatile uint8_t cd_read_index; -static volatile uint32_t cd_read_sector; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ - -static int examine_iso(int fd); -static int examine_cue(int fd); -static int32_t msf_to_sector(const char *msf); - -static void cd_read_thread(void); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_cd_init: Initialize the virtual CD interface. - * - * [Parameters] - * path: Pathname for physical device to associate with virtual CD drive - * [Return value] - * Zero on success, negative on error - */ -static int psp_cd_init(const char *path) -{ - if (!path || !*path) { - DMSG("No file given, behaving like an empty drive"); - goto error_return; - } - - /* Open the requested file. */ - iso_fd = sceIoOpen(path, PSP_O_RDONLY, 0); - if (iso_fd < 0) { - DMSG("Failed to open %s: %s", path, psp_strerror(iso_fd)); - goto error_return; - } - - /* Is it a CUE file? */ - char buf[4]; - if (sceIoRead(iso_fd, buf, 4) != 4) { - DMSG("Failed to read 4 bytes from %s", path); - goto error_close_iso; - } - const int is_cue = (memcmp(buf, "FILE", 4) == 0); - - /* Record information about the ISO image. */ - memset(iso_toc, 0xFF, sizeof(iso_toc)); - memset(tracks, 0, sizeof(tracks)); - if (is_cue) { - int new_fd = examine_cue(iso_fd); - if (new_fd) { - sceIoClose(iso_fd); - iso_fd = new_fd; - } else { - DMSG("Failed to parse CUE file %s", path); - goto error_close_iso; - } - } else { - if (!examine_iso(iso_fd)) { - DMSG("Failed to examine ISO file %s", path); - goto error_close_iso; - } - } - - /* Start up the CD-reading thread. */ - memset(readahead_sector, 0, sizeof(readahead_sector)); - cd_read_idle = 0; - cd_read_requested = 0; - cd_read_terminate = 0; - cd_read_sector = 0; - cd_read_index = 0; - cd_read_thid = sys_start_thread("YabauseCDReader", cd_read_thread, - THREADPRI_CD_READ, 0x1000, 0, NULL); - if (cd_read_thid < 0) { - DMSG("Failed to start CD reader thread: %s", - psp_strerror(cd_read_thid)); - goto error_close_iso; - } - - /* Success! */ - return 0; - - /* On error, we return success and behave like an empty drive. */ - error_close_iso: - sceIoClose(iso_fd); - error_return: - iso_fd = 0; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_cd_deinit: Shut down the virtual CD interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_cd_deinit(void) -{ - if (iso_fd) { - cd_read_terminate = 1; - sceKernelWakeupThread(cd_read_thid); - unsigned int tries = 0; - while (!sys_delete_thread_if_stopped(cd_read_thid, NULL)) { - if (++tries > 100) { - DMSG("CD reader thread failed to terminate, killing it"); - sceKernelTerminateDeleteThread(cd_read_thid); - break; - } - sceKernelDelayThread(1000); // 1ms - } - cd_read_thid = 0; - sceIoClose(iso_fd); - iso_fd = 0; - } -} - -/*************************************************************************/ - -/** - * psp_cd_get_status: Return the status of the physical device associated - * with the virtual CD drive. - * - * [Parameters] - * None - * [Return value] - * 0: CD present, disc spinning - * 1: CD present, disc not spinning - * 2: CD not present - * 3: Tray open - */ -static int psp_cd_get_status(void) -{ - return iso_fd ? 0 : 2; -} - -/*************************************************************************/ - -/** - * psp_cd_read_toc: Return the TOC (table of contents) data for the disc - * currently inserted in the virtual CD drive. - * - * [Parameters] - * toc_buffer: Buffer into which TOC data is to be stored - * [Return value] - * Number of bytes returned - */ -static s32 psp_cd_read_toc(u32 *toc) -{ - if (!iso_fd) { - return 0; - } - - memcpy(toc, iso_toc, sizeof(iso_toc)); - return sizeof(iso_toc); -} - -/*************************************************************************/ - -/** - * psp_cd_read_sector: Read a 2352-byte raw sector from the virtual CD. - * - * [Parameters] - * sector: Linear sector number to read - * buffer: Buffer into which sector data is to be stored - * [Return value] - * Nonzero on success, zero on failure - */ -static int psp_cd_read_sector(u32 sector, void *buffer) -{ - if (!iso_fd) { - return 0; - } - - /* If the requested sector is already loaded, just return it. */ - unsigned int index; - for (index = 0; index < lenof(readahead_sector); index++) { - if (readahead_sector[index] == sector) { - memcpy(buffer, readahead_buffer[index], 2352); - return 1; - } - } - - /* The sector might have been in the middle of being read in, so wait - * for any pending read operation to complete and check again. */ - unsigned int tries = 0; - while (!cd_read_idle) { - if (++tries > 100) { - DMSG("Timeout waiting for CD reader to become idle"); - break; - } - sceKernelDelayThread(100); // 0.1ms - } - for (index = 0; index < lenof(readahead_sector); index++) { - if (readahead_sector[index] == sector) { - memcpy(buffer, readahead_buffer[index], 2352); - return 1; - } - } - - /* The sector isn't available after all, so start a new read request - * and wait for it to complete. */ - while (cd_read_requested) { - if (++tries > 100) { - DMSG("Timeout waiting for request"); - return 0; - } - sceKernelDelayThread(100); // 0.1ms - } - cd_read_sector = sector; - cd_read_index = 0; - cd_read_requested = 1; - sceKernelWakeupThread(cd_read_thid); - tries = 0; - while (cd_read_requested || !cd_read_idle) { - if (++tries > 1000) { - DMSG("Timeout waiting for read"); - return 0; - } - sceKernelDelayThread(100); // 0.1ms - } - - /* Ensure the sector was actually loaded, and return it. */ - if (readahead_sector[0] != sector) { - DMSG("Failed to read sector %u", (unsigned int)sector); - return 0; - } - memcpy(buffer, readahead_buffer[0], 2352); - return 1; -} - -/*************************************************************************/ - -/** - * psp_cd_read_ahead: Start an asynchronous read of the given sector from - * the virtual CD. - * - * [Parameters] - * sector: Linear sector number to read - * [Return value] - * 1 on success, 0 on failure - */ -static void psp_cd_read_ahead(u32 sector) -{ - if (!iso_fd) { - return; - } - - /* See whether the requested sector has already been read in. */ - unsigned int index; - for (index = 0; index < lenof(readahead_sector); index++) { - if (readahead_sector[index] == sector) { - break; - } - } - - uint32_t req_sector; // Sector to request - unsigned int req_index; // Target buffer index to request - - if (index < lenof(readahead_sector)) { - /* If the sector has already been read in, we normally don't need - * do anything. But if we're approaching the end of the current - * group of READ_UNIT sector buffers and the following sectors - * haven't yet been read in, start that read now. */ - if (index % READ_UNIT < READ_UNIT/2) { - return; - } - const unsigned int group_index = (index / READ_UNIT) * READ_UNIT; - const unsigned int next_group = - (group_index + READ_UNIT) % lenof(readahead_sector); - const uint32_t next_group_sector = - readahead_sector[group_index + (READ_UNIT-1)]; - if (!next_group_sector) { - return; // We must have reached the end of the track - } - if (readahead_sector[next_group] == next_group_sector) { - return; // Following sectors are already read in - } - req_sector = next_group_sector; - req_index = next_group; - } else { - /* The sector wasn't available, so start a new read operation. */ - req_sector = sector; - req_index = 0; - } - - /* If there's a pending read request, we can't do anything (so as not - * to block). */ - if (cd_read_requested) { - DMSG("Async read in progress, skipping readahead"); - return; - } - - /* Pass the requested sector and buffer index to the read thread. */ - cd_read_sector = req_sector; - cd_read_index = req_index; - cd_read_requested = 1; - sceKernelWakeupThread(cd_read_thid); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * examine_iso: Examine a raw ISO image and fill in the iso_toc[] and - * tracks[] arrays with its information. - * - * [Parameters] - * fd: File descriptor for ISO image - * [Return value] - * Nonzero on success, zero on error - */ -static int examine_iso(int fd) -{ - /* Retrieve the size of the ISO image. */ - - const uint32_t file_size = sceIoLseek(fd, 0, PSP_SEEK_END); - if ((int32_t)file_size < 0) { - DMSG("Failed to retrieve ISO file size: %s", psp_strerror(file_size)); - return 0; - } else if (file_size == 0) { - DMSG("ISO file is empty!"); - return 0; - } - - /* Guess at the sector size based on the file size. */ - - unsigned int sector_size; - if (file_size % 2048 == 0 && file_size % 2352 == 0) { - /* It could be either 2048 or 2352 bytes per sector. Try and find - * an ISO filesystem header to tell which it is. */ - char buf[8]; - sceIoLseek(fd, 2048*16, PSP_SEEK_SET); - if (sceIoRead(fd, buf, 8) != 8) { - DMSG("Failed to read 8 bytes from offset 2048*16"); - return 0; - } - if (memcmp(buf, "\1CD001\1"/*\0*/, 8) == 0) { - sector_size = 2048; - } else { - sceIoLseek(fd, 2352*16+16, PSP_SEEK_SET); - if (sceIoRead(fd, buf, 8) != 8) { - DMSG("Failed to read 8 bytes from offset 2352*16+16"); - return 0; - } - if (memcmp(buf, "\1CD001\1"/*\0*/, 8) == 0) { - sector_size = 2352; - } else { - DMSG("Can't find an ISO9660 header, assuming 2048-byte" - " sectors"); - sector_size = 2048; - } - } - } else if (file_size % 2048 == 0) { - /* Not a multiple of 2352 bytes, so presumably 2048-byte sectors. */ - sector_size = 2048; - } else if (file_size % 2352 == 0) { - /* Not a multiple of 2048 bytes, so presumably 2352-byte sectors. */ - sector_size = 2352; - } else { - DMSG("Can't figure out sector size, assuming 2048-byte sectors"); - sector_size = 2048; - } - - /* Fill in the TOC and track table. */ - - const uint32_t num_sectors = file_size / sector_size; - - iso_toc[ 0] = 0x41000000 | 150; - iso_toc[ 99] = 0x41010000; - iso_toc[100] = 0x41010100; - iso_toc[101] = 0x41000000 | num_sectors; - - tracks[0].first_sector = 150; - tracks[0].last_sector = 150 + num_sectors - 1; - tracks[0].file_offset = 0; - tracks[0].sector_size = sector_size; - - /* All done! */ - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * examine_cue: Examine a CUE file, open the corresponding ISO image file, - * and fill in the iso_toc[] and tracks[] arrays with the image information. - * - * [Parameters] - * fd: File descriptor for CUE file - * [Return value] - * File descriptor for ISO image (nonzero) on success, zero on error - */ -static int examine_cue(int fd) -{ - /* Load the entire CUE file into memory. */ - - const uint32_t file_size = sceIoLseek(fd, 0, PSP_SEEK_END); - if ((int32_t)file_size < 0) { - DMSG("Failed to retrieve CUE file size: %s", psp_strerror(file_size)); - goto error_return; - } else if (file_size == 0) { - /* This should be impossible, since we read from the file to - * determine that it's a CUE file, but let's play it safe anyway... */ - DMSG("CUE file is empty!"); - goto error_return; - } else if (file_size > 1000000) { - /* Way too big to be a CUE file, so give up rather than trying to - * load tons of data into memory just to find out that it's bad. */ - DMSG("CUE file is too big! (%u bytes)", file_size); - goto error_return; - } - - char *cue_buffer = malloc(file_size); - if (!cue_buffer) { - DMSG("Failed to allocate buffer for CUE file (%u bytes)", file_size); - goto error_return; - } - sceIoLseek(fd, 0, PSP_SEEK_SET); - if (sceIoRead(fd, cue_buffer, file_size) != file_size) { - DMSG("Failed to read CUE file into memory"); - goto error_free_cue_buffer; - } - - /* The first line should be FILE "image-file" [...], giving the - * filename of the corresponding disc image. Strip any directory name - * from the image and attempt to open the file. */ - - char *s, *eol; - int new_fd; - uint32_t image_size; - - eol = cue_buffer + strcspn(cue_buffer, "\r\n"); - if (*eol) { - *eol++ = 0; - } - eol += strspn(eol, "\r\n"); - if (strncmp(cue_buffer, "FILE \"", 6) != 0) { - DMSG("Invalid CUE format: File does not begin with `FILE \"'"); - goto error_free_cue_buffer; - } - char *path = cue_buffer + 6; - s = strchr(path, '"'); - if (!s) { - DMSG("Invalid CUE format: FILE path missing closing quote"); - goto error_free_cue_buffer; - } - *s = 0; - - new_fd = sceIoOpen(path, PSP_O_RDONLY, 0); - if (new_fd < 0) { - DMSG("Failed to open image file %s: %s", path, psp_strerror(new_fd)); - goto error_free_cue_buffer; - } - - image_size = sceIoLseek(new_fd, 0, PSP_SEEK_END); - if ((int32_t)image_size < 0) { - DMSG("Failed to retrieve size of image file %s: %s", path, - psp_strerror(image_size)); - goto error_close_new_fd; - } - - /* Process each remaining line in the CUE file. */ - - int linenum = 1; - unsigned int current_track = 0; - uint32_t pregap_accum = 150; // Accumulated pregap sectors - - while (*eol) { - char *line = eol; - linenum++; - eol += strcspn(eol, "\r\n"); - if (*eol) { - *eol++ = 0; - } - eol += strspn(eol, "\r\n"); - - /* Get the tag, skipping leading spaces; if it's an empty line, - * just skip to the next one. */ - - line += strspn(line, " \t"); - if (!*line) { - continue; - } - char *tag = line; - line += strcspn(line, " \t"); - if (*line) { - *line++ = 0; - } - line += strspn(line, " \t"); - - /* Parse remaining parameters based on the tag type. */ - - if (strcmp(tag, "TRACK") == 0) { - - char *track_str = line; - line += strcspn(line, " \t"); - if (*line) { - *line++ = 0; - } - line += strspn(line, " \t"); - current_track = strtoul(track_str, &s, 10); - if (*s || current_track < 1 || current_track > 99) { - DMSG("Invalid CUE format (line %u): Bad track number %s", - linenum, track_str); - goto error_close_new_fd; - } - - char *mode = line; - if (strcmp(mode, "AUDIO") == 0) { - iso_toc[current_track-1] = 0x01000000; // Sector # comes later - tracks[current_track-1].sector_size = 2352; - } else if (strcmp(mode, "MODE1/2352") == 0 - || strcmp(mode, "MODE2/2352") == 0 - ) { - iso_toc[current_track-1] = 0x41000000; - tracks[current_track-1].sector_size = 2352; - } else if (strcmp(mode, "MODE1/2048") == 0 - || strcmp(mode, "MODE2/2048") == 0 - ) { - iso_toc[current_track-1] = 0x41000000; - tracks[current_track-1].sector_size = 2048; - } - - } else if (strcmp(tag, "INDEX") == 0) { - - if (!current_track) { - DMSG("Invalid CUE format (line %u): INDEX tag with no" - " current track", linenum); - goto error_close_new_fd; - } - - char *index_str = line; - line += strcspn(line, " \t"); - if (*line) { - *line++ = 0; - } - line += strspn(line, " \t"); - const unsigned int index = strtoul(index_str, &s, 10); - if (*s) { - DMSG("Invalid CUE format (line %u): Bad index number %s", - linenum, index_str); - goto error_close_new_fd; - } - if (index != 1) { - continue; // We only care about index #1 - } - - char *msf = line; - const int32_t sector = msf_to_sector(msf); - if (sector < 0) { - DMSG("Invalid CUE format (line %u): Bad MSF string %s", - linenum, msf); - goto error_close_new_fd; - } - - iso_toc[current_track-1] |= sector + pregap_accum; - tracks[current_track-1].first_sector = sector + pregap_accum; - /* Temporarily store the accumulated pregap in last_sector */ - tracks[current_track-1].last_sector = pregap_accum; - - } else if (strcmp(tag, "PREGAP") == 0) { - - if (!current_track) { - DMSG("Invalid CUE format (line %u): PREGAP tag with no" - " current track", linenum); - goto error_close_new_fd; - } - - char *msf = line; - const int32_t pregap_sectors = msf_to_sector(msf); - if (pregap_sectors < 0) { - DMSG("Invalid CUE format (line %u): Bad MSF string %s", - linenum, msf); - goto error_close_new_fd; - } - - pregap_accum += pregap_sectors; - - } else { - - /* Either an invalid tag or one we don't care about, so skip it. */ - - } - - } // while (*eol) - - if (!tracks[0].first_sector) { - DMSG("Invalid CUE file: Track 1 missing"); - goto error_close_new_fd; - } - - /* Fill in the remaining fields in the track table. */ - - if (tracks[0].first_sector != tracks[0].last_sector) { - DMSG("First track does not start at file offset 0, assuming sector" - " size %u for skipped sectors", tracks[0].sector_size); - const uint32_t track1_skipped = - tracks[0].first_sector - tracks[0].last_sector; - tracks[0].file_offset = track1_skipped * tracks[0].sector_size; - } else { - tracks[0].file_offset = 0; - } - - unsigned int track; - for (track = 2; track <= current_track; track++) { - if (!tracks[track-1].first_sector) { - DMSG("Invalid CUE file: Intermediate track %u missing", track); - goto error_close_new_fd; - } - const uint32_t pregap = tracks[track-1].last_sector; - const uint32_t added_pregap = pregap - tracks[track-2].last_sector; - tracks[track-2].last_sector = - tracks[track-1].first_sector - added_pregap - 1; - const uint32_t last_track_sectors = - tracks[track-2].last_sector - tracks[track-2].first_sector + 1; - tracks[track-1].file_offset = - tracks[track-2].file_offset - + (last_track_sectors * tracks[track-2].sector_size); - } - - const uint32_t last_track_size = image_size - tracks[track-2].file_offset; - const uint32_t last_track_sectors = - last_track_size / tracks[track-2].sector_size; - tracks[track-2].last_sector = - tracks[track-2].first_sector + last_track_sectors - 1; - - /* Generate the final TOC entries. */ - - iso_toc[ 99] = (iso_toc[0] & 0xFF000000) | 0x00010000; - iso_toc[100] = (iso_toc[current_track-1] & 0xFF000000) - | (current_track << 16); - iso_toc[101] = (iso_toc[current_track-1] & 0xFF000000) - | (tracks[current_track-1].last_sector + 1); - - /* All done! */ - - free(cue_buffer); - return new_fd; - - - /* Error handling. */ - - error_close_new_fd: - sceIoClose(new_fd); - error_free_cue_buffer: - free(cue_buffer); - error_return: - return 0; -} - -/*----------------------------------*/ - -/** - * msf_to_sector: Convert a time (Minutes:Seconds:Frames) string to the - * corresponding sector index. Helper function for examine_cue(). - * - * [Parameters] - * msf: Time string (MM:SS:FF) - * [Return value] - * Corresponding sector index (nonzero), or negative if string is invalid - */ -static int32_t msf_to_sector(const char *msf) -{ - uint32_t minutes, seconds, frames; - const char *s; - - if (!msf - || (minutes = strtoul(msf, (char **)&s, 10)) > 99 - || *s++ != ':' - || (seconds = strtoul(s, (char **)&s, 10)) > 59 - || *s++ != ':' - || (frames = strtoul(s, (char **)&s, 10)) > 74 - || *s != 0 - ) { - return -1; - } - - return (minutes*60 + seconds)*75 + frames; -} - -/*************************************************************************/ -/**************************** CD read thread *****************************/ -/*************************************************************************/ - -/** - * cd_read_thread: Thread which performs reads from the CD image file as - * requested by the main program. - * - * The main program should follow these steps to request a read: - * 1) Wait for cd_read_requested to become zero. - * 2) Store the desired sector address (150-...) in cd_read_sector. - * 3) Store the desired target readahead buffer index in cd_read_index. - * This value must be a multiple of READ_UNIT. - * 4) Store 1 in cd_read_requested. - * 5) Call sceKernelWakeupThread() to wake up the read thread. - * The main program can determine whether all pending requests have been - * completed by checking cd_read_idle for a nonzero value. - * - * Sectors which have been read in are stored in the read-ahead buffer; - * for any nonzero entry in readahead_sector[], the corresponding entry in - * readahead_buffer[] contains the raw data for that sector (converted, if - * necessary, from the format in the file--i.e., 2048-byte sectors in the - * file are filled out to 2352-byte sectors in readahead_buffer[]). - * - * To terminate the thread, the main program should store 1 in - * cd_read_terminate and wake up the thread. - * - * The file descriptor (iso_fd) and track table (tracks[]) must not be - * modified while the thread is running. - * - * [Parameters] - * None - * [Return value] - * Does not return - */ -static void cd_read_thread(void) -{ - PROFILE_START("CDIO"); - - while (!cd_read_terminate) { - - /* Wait for a trigger write from the main program. */ - while (!cd_read_requested && !cd_read_terminate) { - cd_read_idle = 1; - /* Since the read thread runs at a higher priority than the - * main program thread, there is (barring an OS bug) no danger - * of a race condition causing the read thread to be - * interrupted by the main thread between the while() test and - * this sleep call. */ - PROFILE_STOP("CDIO"); - sceKernelSleepThread(); - PROFILE_START("CDIO"); - } - if (cd_read_terminate) { - break; - } - cd_read_idle = 0; - - /* Save the requested sector number, then clear the request trigger. */ - const uint32_t sector = cd_read_sector; - const unsigned int index = cd_read_index; - cd_read_requested = 0; - - /* Figure out which track the sector is in and retrieve the track - * information. */ - unsigned int track; - for (track = 0; track < lenof(tracks); track++) { - if (sector >= tracks[track].first_sector - && sector <= tracks[track].last_sector - ) { - break; - } - } - if (track >= lenof(tracks)) { - DMSG("Failed to find track for sector %u", (unsigned int)sector); - continue; - } - const uint32_t first_sector = tracks[track].first_sector; - const uint32_t file_offset = tracks[track].file_offset; - const uint32_t sector_size = tracks[track].sector_size; - - /* Clear out all sector information previously stored in this group - * of buffers. */ - unsigned int i; - for (i = index; i < index + READ_UNIT; i++) { - readahead_sector[i] = 0; - } - - /* Check how many sectors we should read from this location (avoid - * reading beyond the end of the track). */ - unsigned int sectors_to_read = READ_UNIT; - if (sectors_to_read > (tracks[track].last_sector+1) - sector) { - sectors_to_read = (tracks[track].last_sector+1) - sector; - } - - /* Seek to the proper location in the disc image. */ - const uint32_t relative_sector = sector - first_sector; - const uint32_t relative_offset = relative_sector * sector_size; - const uint32_t absolute_offset = file_offset + relative_offset; - uint32_t res = sceIoLseek(iso_fd, absolute_offset, PSP_SEEK_SET); - if (res != absolute_offset) { - DMSG("sceIoLseek(%u, %u, SEEK_SET): %s", iso_fd, absolute_offset, - psp_strerror(res)); - continue; - } - - /* Read the sector data from the disc image. */ - if (sector_size == 2352) { - PROFILE_STOP("CDIO"); - res = sceIoRead(iso_fd, readahead_buffer[index], - 2352 * sectors_to_read); - PROFILE_START("CDIO"); - } else if (sector_size == 2048) { - static const uint8_t sector_header[16] = - {0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0}; - memcpy(readahead_buffer[index], sector_header, 16); - PROFILE_STOP("CDIO"); - res = sceIoRead(iso_fd, (uint8_t *)readahead_buffer[index] + 16, - 2048 * sectors_to_read); - PROFILE_START("CDIO"); - for (i = sectors_to_read-1; i >= 1; i--) { - /* We have to move the data first, or the sector header - * could overwrite part of the sector we're moving. */ - memmove((uint8_t *)readahead_buffer[index+i] + 16, - (uint8_t *)readahead_buffer[index] + 16 + 2048*i, - 2048); - memcpy(readahead_buffer[index+i], sector_header, 16); - } - } else { - DMSG("IMPOSSIBLE: bad sector_size %u for track %u", - sector_size, track); - continue; - } - if (res != sector_size * sectors_to_read) { - DMSG("sceIoRead(%u, buffer[%u], %u): %s", iso_fd, index, - sector_size, res < 0 ? psp_strerror(res) : "Short read"); - continue; - } - - /* Fill in readahead_sector[] with the newly-read-in sectors. */ - for (i = 0; i < sectors_to_read; i++) { - readahead_sector[index+i] = sector+i; - } - - } // while (!cd_read_terminate) - - PROFILE_STOP("CDIO"); - sceKernelExitThread(0); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-cd.h b/yabause/src/psp/psp-cd.h deleted file mode 100644 index fc801aac53..0000000000 --- a/yabause/src/psp/psp-cd.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-cd.h: PSP virtual CD interface module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_CD_H -#define PSP_CD_H - -#include "../cdbase.h" // for CDInterface - -/*************************************************************************/ - -/* Module interface definition */ -extern CDInterface CDPSP; - -/* Unique module ID (must be different from any in ../cdbase.h) */ -#define CDCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_CD_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-logo.png b/yabause/src/psp/psp-logo.png deleted file mode 100644 index c7af604add..0000000000 Binary files a/yabause/src/psp/psp-logo.png and /dev/null differ diff --git a/yabause/src/psp/psp-m68k.c b/yabause/src/psp/psp-m68k.c deleted file mode 100644 index 4de2d692d7..0000000000 --- a/yabause/src/psp/psp-m68k.c +++ /dev/null @@ -1,630 +0,0 @@ -/* src/psp/psp-m68k.c: PSP M68k emulator interface (uses Q68) - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "../core.h" -#include "../error.h" -#include "../m68kcore.h" -#include "../memory.h" -#include "../scsp.h" - -#include "../q68/q68.h" -#include "../q68/q68-const.h" // for Q68_JIT_PAGE_BITS - -#include "common.h" -#include "config.h" -#include "psp-m68k.h" -#include "sys.h" - -#include "me.h" -#include "me-utility.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_m68k_init(void); -static void psp_m68k_deinit(void); -static void psp_m68k_reset(void); - -static FASTCALL s32 psp_m68k_exec(s32 cycles); -static void psp_m68k_sync(void); - -static u32 psp_m68k_get_dreg(u32 num); -static u32 psp_m68k_get_areg(u32 num); -static u32 psp_m68k_get_pc(void); -static u32 psp_m68k_get_sr(void); -static u32 psp_m68k_get_usp(void); -static u32 psp_m68k_get_ssp(void); - -static void psp_m68k_set_dreg(u32 num, u32 val); -static void psp_m68k_set_areg(u32 num, u32 val); -static void psp_m68k_set_pc(u32 val); -static void psp_m68k_set_sr(u32 val); -static void psp_m68k_set_usp(u32 val); -static void psp_m68k_set_ssp(u32 val); - -static FASTCALL void psp_m68k_set_irq(s32 level); -static FASTCALL void psp_m68k_write_notify(u32 address, u32 size); - -static void psp_m68k_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr); -static void psp_m68k_set_readb(M68K_READ *func); -static void psp_m68k_set_readw(M68K_READ *func); -static void psp_m68k_set_writeb(M68K_WRITE *func); -static void psp_m68k_set_writew(M68K_WRITE *func); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -M68K_struct M68KPSP = { - .id = M68KCORE_PSP, - .Name = "PSP M68k Emulator Interface", - - .Init = psp_m68k_init, - .DeInit = psp_m68k_deinit, - .Reset = psp_m68k_reset, - - .Exec = psp_m68k_exec, - .Sync = psp_m68k_sync, - - .GetDReg = psp_m68k_get_dreg, - .GetAReg = psp_m68k_get_areg, - .GetPC = psp_m68k_get_pc, - .GetSR = psp_m68k_get_sr, - .GetUSP = psp_m68k_get_usp, - .GetMSP = psp_m68k_get_ssp, - - .SetDReg = psp_m68k_set_dreg, - .SetAReg = psp_m68k_set_areg, - .SetPC = psp_m68k_set_pc, - .SetSR = psp_m68k_set_sr, - .SetUSP = psp_m68k_set_usp, - .SetMSP = psp_m68k_set_ssp, - - .SetIRQ = psp_m68k_set_irq, - .WriteNotify = psp_m68k_write_notify, - - .SetFetch = psp_m68k_set_fetch, - .SetReadB = psp_m68k_set_readb, - .SetReadW = psp_m68k_set_readw, - .SetWriteB = psp_m68k_set_writeb, - .SetWriteW = psp_m68k_set_writew, -}; - -/*************************************************************************/ - -/* Virtual processor state block */ -static Q68State *q68_state; - -/* JIT code arena block pointer (for free() on cleanup) */ -void *jit_arena_base; - -/*----------------------------------*/ - -/* Local function declarations */ - -static void flush_cache(void); - -static void local_malloc_init(void *base, uint32_t size); -static void *local_malloc(size_t size); -static void *local_realloc(void *ptr, size_t size); -static void local_free(void *ptr); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_m68k_init: Initialize the virtual processpr. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on failure - */ -static int psp_m68k_init(void) -{ - /* Allocate a memory block for the Q68 memory pool; make sure it's - * 64-byte aligned to avoid cache line collisions */ - const uint32_t jit_arena_size = 2 * 1024 * 1024; - jit_arena_base = malloc(jit_arena_size + (64*2-1)); - if (!jit_arena_base) { - DMSG("Failed to allocate memory arena for JIT code"); - q68_destroy(q68_state); - q68_state = NULL; - return -1; - } - local_malloc_init((void *)(((uintptr_t)jit_arena_base + 0x3F) & -0x40), - jit_arena_size); - - if (!(q68_state = q68_create_ex(local_malloc, local_realloc, local_free))) { - DMSG("Failed to create Q68 state block"); - return -1; - } - q68_set_irq(q68_state, 0); - q68_set_jit_flush_func(q68_state, flush_cache); - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_deinit: Destroy the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_m68k_deinit(void) -{ - free(jit_arena_base); - jit_arena_base = NULL; - q68_destroy(q68_state); - q68_state = NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_reset: Reset the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_m68k_reset(void) -{ - q68_reset(q68_state); -} - -/*************************************************************************/ - -/** - * psp_m68k_exec: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles actually executed - */ -static FASTCALL s32 psp_m68k_exec(s32 cycles) -{ - return q68_run(q68_state, cycles); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_sync: Wait for background execution to finish. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_m68k_sync(void) -{ - /* No-op */ -} - -/*************************************************************************/ - -/** - * psp_m68k_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of - * the specified register. - * - * [Parameters] - * num: Register number (psp_m68k_get_dreg(), psp_m68k_get_areg() only) - * [Return value] - * None - */ - -static u32 psp_m68k_get_dreg(u32 num) -{ - return q68_get_dreg(q68_state, num); -} - -static u32 psp_m68k_get_areg(u32 num) -{ - return q68_get_areg(q68_state, num); -} - -static u32 psp_m68k_get_pc(void) -{ - return q68_get_pc(q68_state); -} - -static u32 psp_m68k_get_sr(void) -{ - return q68_get_sr(q68_state); -} - -static u32 psp_m68k_get_usp(void) -{ - return q68_get_usp(q68_state); -} - -static u32 psp_m68k_get_ssp(void) -{ - return q68_get_ssp(q68_state); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * num: Register number (psp_m68k_set_dreg(), psp_m68k_set_areg() only) - * val: Value to set - * [Return value] - * None - */ - -static void psp_m68k_set_dreg(u32 num, u32 val) -{ - q68_set_dreg(q68_state, num, val); -} - -static void psp_m68k_set_areg(u32 num, u32 val) -{ - q68_set_areg(q68_state, num, val); -} - -static void psp_m68k_set_pc(u32 val) -{ - q68_set_pc(q68_state, val); -} - -static void psp_m68k_set_sr(u32 val) -{ - q68_set_sr(q68_state, val); -} - -static void psp_m68k_set_usp(u32 val) -{ - q68_set_usp(q68_state, val); -} - -static void psp_m68k_set_ssp(u32 val) -{ - q68_set_ssp(q68_state, val); -} - -/*************************************************************************/ - -/** - * psp_m68k_set_irq: Deliver an interrupt to the processor. - * - * [Parameters] - * level: Interrupt level (0-7) - * [Return value] - * None - */ -static FASTCALL void psp_m68k_set_irq(s32 level) -{ - q68_set_irq(q68_state, level); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_write_notify: Inform the 68k emulator that the given address - * range has been modified. - * - * [Parameters] - * address: 68000 address of modified data - * size: Size of modified data in bytes - * [Return value] - * None - */ -static FASTCALL void psp_m68k_write_notify(u32 address, u32 size) -{ - /* NOTE: If the SCSP/M68k is running in a separate thread, and the - * main thread calls this function with the result of freeing an - * allocated JIT block at the same time the M68k tries to allocate - * or free a JIT block in its thread, a crash is likely. Hopefully - * there are no actual games that try writing to M68k code space - * while the M68k is running. */ - q68_touch_memory(q68_state, address, size); -} - -/*************************************************************************/ - -/** - * psp_m68k_set_fetch: Set the instruction fetch pointer for a region of - * memory. Not used by Q68. - * - * [Parameters] - * low_addr: Low address of memory region to set - * high_addr: High address of memory region to set - * fetch_addr: Pointer to corresponding memory region (NULL to disable) - * [Return value] - * None - */ -static void psp_m68k_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr) -{ -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_set_{readb,readw,writeb,writew}: Set functions for reading or - * writing bytes or words in memory. - * - * [Parameters] - * func: Function to set - * [Return value] - * None - */ - -static void psp_m68k_set_readb(M68K_READ *func) -{ - q68_set_readb_func(q68_state, (Q68ReadFunc *)func); -} - -static void psp_m68k_set_readw(M68K_READ *func) -{ - q68_set_readw_func(q68_state, (Q68ReadFunc *)func); -} - -static void psp_m68k_set_writeb(M68K_WRITE *func) -{ - q68_set_writeb_func(q68_state, (Q68WriteFunc *)func); -} - -static void psp_m68k_set_writew(M68K_WRITE *func) -{ - q68_set_writew_func(q68_state, (Q68WriteFunc *)func); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * flush_cache: Flush the data and instruction caches of the current CPU. - * Called by Q68 after a new block of code has been translated. - */ -static void flush_cache(void) -{ - if (meUtilityIsME()) { - meUtilityDcacheWritebackInvalidateAll(); - meUtilityIcacheInvalidateAll(); - } else { - sceKernelDcacheWritebackInvalidateAll(); - sceKernelIcacheInvalidateAll(); - } -} - -/*************************************************************************/ - -/* For the moment, we use a very simplistic memory allocator to manage JIT - * memory. Since we only allocate or free during 68k code translation, - * this should hopefully be good enough. */ - -/* Memory management structure prefixed to each block */ -typedef struct BlockInfo_ BlockInfo; -struct BlockInfo_ { - BlockInfo *next, *prev; // Next and previous blocks sorted by address - uint32_t size; // Size of this block (excluding this structure) - int free; // Nonzero if this is a free block - uint32_t pad[12]; // Pad to 1 cache line (64 bytes) -}; - -/* Base of memory region used for local_malloc() and friends */ -static BlockInfo *local_malloc_base; - -/*-----------------------------------------------------------------------*/ - -/** - * local_malloc_init: Initialize the memory arena used by local_malloc() - * and friends. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void local_malloc_init(void *base, uint32_t size) -{ - local_malloc_base = base; - local_malloc_base->next = NULL; - local_malloc_base->prev = NULL; - local_malloc_base->size = size - sizeof(BlockInfo); - local_malloc_base->free = 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * local_malloc: Allocate a block of local memory. - * - * [Parameters] - * size: Size of memory block to allocate - * [Return value] - * Allocated memory block, or NULL on failure - */ -static void *local_malloc(size_t size) -{ - /* Round the size up to a multiple of sizeof(BlockInfo) for simplicity */ - size = (size + sizeof(BlockInfo)-1) - / sizeof(BlockInfo) * sizeof(BlockInfo); - - /* Find a free block of sufficient size and return it, splitting the - * block if appropriate */ - BlockInfo *block; - for (block = local_malloc_base; block; block = block->next) { - if (!block->free) { - continue; - } - if (block->size >= size) { - void *ptr = (void *)((uintptr_t)block + sizeof(BlockInfo)); - if (block->size > size) { - BlockInfo *split_block = (BlockInfo *)((uintptr_t)ptr + size); - split_block->next = block->next; - if (split_block->next) { - split_block->next->prev = split_block; - } - split_block->prev = block; - block->next = split_block; - split_block->size = block->size - (size + sizeof(BlockInfo)); - split_block->free = 1; - } - block->size = size; - block->free = 0; - return ptr; - } - } - - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * local_realloc: Adjust the size of a block of local memory. - * - * [Parameters] - * ptr: Pointer to memory block to adjust - * size: New size of memory block - * [Return value] - * Allocated memory block, or NULL on failure - */ -static void *local_realloc(void *ptr, size_t size) -{ - if (size == 0) { - local_free(ptr); - return NULL; - } - - if (ptr == NULL) { - return local_malloc(size); - } - - BlockInfo *block = (BlockInfo *)((uintptr_t)ptr - sizeof(BlockInfo)); - const size_t oldsize = block->size; - size = (size + sizeof(BlockInfo)-1) - / sizeof(BlockInfo) * sizeof(BlockInfo); - if (size < oldsize - sizeof(BlockInfo)) { - /* Adjust the block size downward and split off the remaining space - * into a new free block (or add it to the next block, if the next - * block is a free block) */ - block->size = size; - BlockInfo *newblock = (BlockInfo *) - ((uintptr_t)block + sizeof(BlockInfo) + size); - if (block->next && block->next->free) { - newblock->next = block->next->next; - newblock->prev = block; - newblock->size = block->next->size; - newblock->free = 1; - if (newblock->next) { - newblock->next->prev = newblock; - } - block->next = newblock; - newblock->size += oldsize - size; - } else { - newblock->next = block->next; - newblock->prev = block; - if (block->next) { - block->next->prev = newblock; - } - block->next = newblock; - newblock->size = oldsize - size - sizeof(BlockInfo); - newblock->free = 1; - } - return ptr; - } else if (size <= sizeof(BlockInfo)) { - /* No need to adjust anything; just return the same block */ - return ptr; - } else if (block->next && block->next->free - && (sizeof(BlockInfo) + block->next->size) >= size - oldsize) { - /* Append the next block to this one, then resize downward with a - * recursive call */ - block->size += sizeof(BlockInfo) + block->next->size; - block->next = block->next->next; - if (block->next) { - block->next->prev = block; - } - return local_realloc(ptr, size); - } else { - /* No simple path, so alloc/copy/free */ - void *newptr = local_malloc(size); - if (!newptr) { - return NULL; - } - const size_t copysize = (oldsize < size) ? oldsize : size; - memcpy(newptr, ptr, copysize); - local_free(ptr); - return newptr; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * local_free: Free a block of local memory. - * - * [Parameters] - * ptr: Pointer to memory block to free - * [Return value] - * None - */ -static void local_free(void *ptr) -{ - if (ptr != NULL) { - BlockInfo *block = (BlockInfo *)((uintptr_t)ptr - sizeof(BlockInfo)); - block->free = 1; - if (block->prev && block->prev->free) { - block->prev->next = block->next; - if (block->next) { - block->next->prev = block->prev; - } - block->prev->size += block->size + sizeof(BlockInfo); - block = block->prev; - } - if (block->next && block->next->free) { - block->size += block->next->size + sizeof(BlockInfo); - block->next = block->next->next; - if (block->next) { - block->next->prev = block; - } - } - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-m68k.h b/yabause/src/psp/psp-m68k.h deleted file mode 100644 index 86662b676b..0000000000 --- a/yabause/src/psp/psp-m68k.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-m68k.h: PSP M68k emulator interface module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_M68K_H -#define PSP_M68K_H - -#include "../m68kcore.h" // for M68K_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern M68K_struct M68KPSP; - -/* Unique module ID (must be different from any in ../m68kcore.h) */ -#define M68KCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_M68K_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-per.c b/yabause/src/psp/psp-per.c deleted file mode 100644 index 8560e7816a..0000000000 --- a/yabause/src/psp/psp-per.c +++ /dev/null @@ -1,162 +0,0 @@ -/* src/psp/psp-per.c: PSP peripheral interface module - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../peripheral.h" - -#include "control.h" -#include "psp-per.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_per_init(void); -static void psp_per_deinit(void); -static int psp_per_handle_events(void); -#ifdef PERKEYNAME -static void psp_per_key_name(u32 key, char *name, int size); -#endif - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -PerInterface_struct PERPSP = { - .id = PERCORE_PSP, - .Name = "PSP Peripheral Interface", - .Init = psp_per_init, - .DeInit = psp_per_deinit, - .HandleEvents = psp_per_handle_events, - .canScan = 0, -#ifdef PERKEYNAME - .KeyName = psp_per_key_name, -#endif -}; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_per_init: Initialize the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_per_init(void) -{ - /* Nothing to do */ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_per_deinit: Shut down the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_per_deinit(void) -{ - /* Nothing to do */ -} - -/*************************************************************************/ - -/** - * psp_per_handle_events: Process pending peripheral events, and run one - * iteration of the emulation. - * - * For the PSP, the main loop is located in main.c; we only update the - * current button status here. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_per_handle_events(void) -{ - static uint32_t last_buttons; - - const uint32_t buttons = control_state(); - const uint32_t changed_buttons = buttons ^ last_buttons; - last_buttons = buttons; - - int i; - for (i = 0; i < 16; i++) { - const uint32_t button = 1 << i; - if (changed_buttons & button) { - if (buttons & button) { - PerKeyDown(button); - } else { - PerKeyUp(button); - } - } - } - - YabauseExec(); - return 0; -} - -/*************************************************************************/ - -#ifdef PERKEYNAME - -/** - * psp_per_key_name: Return the name corresponding to a system-dependent - * key value. - * - * [Parameters] - * key: Key value to return name for - * name: Buffer into which name is to be stored - * size: Size of buffer in bytes - * [Return value] - * None - */ -static void psp_per_key_name(u32 key, char *name, int size) -{ - /* Not supported on PSP */ - *name = 0; -} - -#endif // PERKEYNAME - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-per.h b/yabause/src/psp/psp-per.h deleted file mode 100644 index fa274574b6..0000000000 --- a/yabause/src/psp/psp-per.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-per.h: PSP peripheral interface module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_PER_H -#define PSP_PER_H - -#include "../peripheral.h" // for PerInterface_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern PerInterface_struct PERPSP; - -/* Unique module ID (must be different from any in ../peripheral.h) */ -#define PERCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_PER_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sh2.c b/yabause/src/psp/psp-sh2.c deleted file mode 100644 index ac972cde01..0000000000 --- a/yabause/src/psp/psp-sh2.c +++ /dev/null @@ -1,670 +0,0 @@ -/* src/psp/psp-sh2.c: Yabause interface for PSP SH-2 emulator - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../bios.h" -#include "../error.h" -#include "../memory.h" -#include "../sh2core.h" -#include "../sh2trace.h" -#include "../vdp1.h" -#include "../vdp2.h" - -#include "config.h" -#include "psp-sh2.h" -#include "rtl.h" -#include "sh2.h" -#include "sh2-internal.h" // For TRACE, etc. (so we don't call sh2_trace_add_cycles() if not needed) - -#include "satopt-sh2.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_sh2_init(void); -static void psp_sh2_deinit(void); -static void psp_sh2_reset(void); -static FASTCALL void psp_sh2_exec(SH2_struct *state, u32 cycles); - -static void psp_sh2_get_registers(SH2_struct *yabause_state, - sh2regs_struct *regs); -static u32 psp_sh2_get_GPR(SH2_struct *yabause_state, int num); -static u32 psp_sh2_get_SR(SH2_struct *yabause_state); -static u32 psp_sh2_get_GBR(SH2_struct *yabause_state); -static u32 psp_sh2_get_VBR(SH2_struct *yabause_state); -static u32 psp_sh2_get_MACH(SH2_struct *yabause_state); -static u32 psp_sh2_get_MACL(SH2_struct *yabause_state); -static u32 psp_sh2_get_PR(SH2_struct *yabause_state); -static u32 psp_sh2_get_PC(SH2_struct *yabause_state); - -static void psp_sh2_set_registers(SH2_struct *yabause_state, - const sh2regs_struct *regs); -static void psp_sh2_set_GPR(SH2_struct *yabause_state, int num, u32 value); -static void psp_sh2_set_SR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_GBR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_VBR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_MACH(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_MACL(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_PR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_PC(SH2_struct *yabause_state, u32 value); - -static void psp_sh2_send_interrupt(SH2_struct *yabause_state, - u8 vector, u8 level); -static int psp_sh2_get_interrupts(SH2_struct *yabause_state, - interrupt_struct interrupts[MAX_INTERRUPTS]); -static void psp_sh2_set_interrupts(SH2_struct *yabause_state, - int num_interrupts, - const interrupt_struct interrupts[MAX_INTERRUPTS]); - -static void psp_sh2_write_notify(u32 start, u32 length); - - -/* Module interface definition */ - -SH2Interface_struct SH2PSP = { - .id = SH2CORE_PSP, - .Name = "PSP SH-2 Core", - - .Init = psp_sh2_init, - .DeInit = psp_sh2_deinit, - .Reset = psp_sh2_reset, - .Exec = psp_sh2_exec, - - .GetRegisters = psp_sh2_get_registers, - .GetGPR = psp_sh2_get_GPR, - .GetSR = psp_sh2_get_SR, - .GetGBR = psp_sh2_get_GBR, - .GetVBR = psp_sh2_get_VBR, - .GetMACH = psp_sh2_get_MACH, - .GetMACL = psp_sh2_get_MACL, - .GetPR = psp_sh2_get_PR, - .GetPC = psp_sh2_get_PC, - - .SetRegisters = psp_sh2_set_registers, - .SetGPR = psp_sh2_set_GPR, - .SetSR = psp_sh2_set_SR, - .SetGBR = psp_sh2_set_GBR, - .SetVBR = psp_sh2_set_VBR, - .SetMACH = psp_sh2_set_MACH, - .SetMACL = psp_sh2_set_MACL, - .SetPR = psp_sh2_set_PR, - .SetPC = psp_sh2_set_PC, - - .SendInterrupt = psp_sh2_send_interrupt, - .GetInterrupts = psp_sh2_get_interrupts, - .SetInterrupts = psp_sh2_set_interrupts, - - .WriteNotify = psp_sh2_write_notify, -}; - -/*************************************************************************/ -/************************ Local data definitions *************************/ -/*************************************************************************/ - -/* Master and slave SH-2 state blocks */ -static SH2State *master_SH2, *slave_SH2; - -/* Write buffers for low and high RAM */ -static void *write_buffer_lram, *write_buffer_hram; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ -static void flush_caches(void *start, uint32_t length); -static void invalid_opcode_handler(SH2State *state, uint32_t PC, - uint16_t opcode); -static FASTCALL void trace_insn_handler(SH2State *state, uint32_t address); - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * psp_sh2_init: Initialize the SH-2 core. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_sh2_init(void) -{ - master_SH2 = sh2_create(); - slave_SH2 = sh2_create(); - if (!master_SH2 || !slave_SH2) { - return -1; - } - master_SH2->userdata = MSH2; - slave_SH2->userdata = SSH2; - - write_buffer_lram = sh2_alloc_direct_write_buffer(0x100000); - write_buffer_hram = sh2_alloc_direct_write_buffer(0x100000); - if (UNLIKELY(!write_buffer_lram) || UNLIKELY(!write_buffer_hram)) { - DMSG("WARNING: Failed to allocate RAM write buffers, performance" - " will suffer"); - } - - if (UNLIKELY(!sh2_init())) { - return -1; - } -#ifdef PSP - sh2_set_optimizations(config_get_sh2_optimizations()); - /* If we can allocate >24MB of memory, we must be on a PSP-2000 (Slim) - * or newer model; otherwise, assume we're on a PSP-1000 (Phat) and - * reduce the JIT data size limit to avoid crowding out other data. */ - void *memsize_test = malloc(24*1024*1024 + 1); - if (memsize_test) { - free(memsize_test); - sh2_set_jit_data_limit(20*1000000); - } else { - sh2_set_jit_data_limit(8*1000000); - } -#else // !PSP - sh2_set_optimizations(SH2_OPTIMIZE_ASSUME_SAFE_DIVISION - | SH2_OPTIMIZE_BRANCH_TO_RTS - | SH2_OPTIMIZE_FOLD_SUBROUTINES - | SH2_OPTIMIZE_LOCAL_ACCESSES - | SH2_OPTIMIZE_LOCAL_POINTERS - | SH2_OPTIMIZE_MAC_NOSAT - | SH2_OPTIMIZE_POINTERS - | SH2_OPTIMIZE_POINTERS_MAC - | SH2_OPTIMIZE_STACK); - /* Give the SH-2 core some breathing room for saving RTL blocks */ - sh2_set_jit_data_limit(200*1000000); -#endif - sh2_set_manual_optimization_callback(saturn_optimize_sh2); - sh2_set_cache_flush_callback(flush_caches); - sh2_set_invalid_opcode_callback(invalid_opcode_handler); - sh2_set_trace_insn_callback(trace_insn_handler); - sh2_set_trace_storeb_callback(sh2_trace_writeb); - sh2_set_trace_storew_callback(sh2_trace_writew); - sh2_set_trace_storel_callback(sh2_trace_writel); - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_deinit: Perform cleanup for the SH-2 core. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sh2_deinit(void) -{ - sh2_destroy(master_SH2); - sh2_destroy(slave_SH2); - - free(write_buffer_lram); - free(write_buffer_hram); - write_buffer_lram = write_buffer_hram = NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_reset: Reset the SH-2 core. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sh2_reset(void) -{ - /* Sanity checks on pointers -- none of these are actually possible - * on the PSP, but it couldn't hurt to have them for testing this code - * on other platforms. */ - if ((uintptr_t)BiosRom == 0x00000000UL - || (uintptr_t)BiosRom == 0x00080000UL - || (uintptr_t)BiosRom == 0x20000000UL - || (uintptr_t)BiosRom == 0x20080000UL - || (uintptr_t)BiosRom == 0xA0000000UL - || (uintptr_t)BiosRom == 0xA0080000UL - || (uintptr_t)LowWram == 0x00200000UL - || (uintptr_t)LowWram == 0x20200000UL - || (uintptr_t)LowWram == 0xA0200000UL - || ((uintptr_t)HighWram & 0xFE0FFFFF) == 0x06000000UL - || ((uintptr_t)HighWram & 0xFE0FFFFF) == 0x26000000UL - || ((uintptr_t)HighWram & 0xFE0FFFFF) == 0xA6000000UL - ) { - DMSG("WARNING: ROM/RAM located at an inconvenient place;" - " performance will suffer!\nROM=%p LRAM=%p HRAM=%p", - BiosRom, LowWram, HighWram); - } - -#define SET_PAGE(sh2_addr,psp_addr,size,writebuf) do { \ - if (!(psp_addr)) { \ - DMSG("WARNING: %s == NULL", #psp_addr); \ - } else { \ - sh2_set_direct_access((sh2_addr) | 0x00000000, (psp_addr), \ - (size), 1, (writebuf)); \ - sh2_set_direct_access((sh2_addr) | 0x20000000, (psp_addr), \ - (size), 1, (writebuf)); \ - sh2_set_direct_access((sh2_addr) | 0xA0000000, (psp_addr), \ - (size), 1, (writebuf)); \ - } \ -} while (0) -#define SET_EXEC_PAGE(sh2_addr,psp_addr,size) do { \ - if (!(psp_addr)) { \ - DMSG("WARNING: %s == NULL", #psp_addr); \ - } else { \ - sh2_set_direct_access((sh2_addr) | 0x00000000, (psp_addr), \ - (size), 0, 0); \ - sh2_set_direct_access((sh2_addr) | 0x20000000, (psp_addr), \ - (size), 0, 0); \ - sh2_set_direct_access((sh2_addr) | 0xA0000000, (psp_addr), \ - (size), 0, 0); \ - } \ -} while (0) -#define SET_BYTE_PAGE(sh2_addr,psp_addr,size) do { \ - if (!(psp_addr)) { \ - DMSG("WARNING: %s == NULL", #psp_addr); \ - } else { \ - sh2_set_byte_direct_access((sh2_addr) | 0x00000000, (psp_addr), \ - (size)); \ - sh2_set_byte_direct_access((sh2_addr) | 0x20000000, (psp_addr), \ - (size)); \ - sh2_set_byte_direct_access((sh2_addr) | 0xA0000000, (psp_addr), \ - (size)); \ - } \ -} while (0) - - SET_EXEC_PAGE(0x00000000, BiosRom, 0x80000); - SET_EXEC_PAGE(0x00080000, BiosRom, 0x80000); - if (write_buffer_lram) { - SET_PAGE(0x00200000, LowWram, 0x100000, write_buffer_lram); - } - if (write_buffer_hram) { - uint32_t base; - for (base = 0x06000000; base < 0x08000000; base += 0x00100000) { - SET_PAGE(base, HighWram, 0x100000, write_buffer_hram); - } - } - SET_BYTE_PAGE(0x05C00000, Vdp1Ram, 0x80000); - SET_BYTE_PAGE(0x05E00000, Vdp2Ram, 0x80000); - SET_BYTE_PAGE(0x05E80000, Vdp2Ram, 0x80000); - -#undef SET_PAGE -#undef SET_EXEC_PAGE -#undef SET_BYTE_PAGE - - sh2_reset(master_SH2); - sh2_reset(slave_SH2); -} - -/*************************************************************************/ - -/** - * psp_sh2_exec: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * cycles: Number of clock cycles to execute - * [Return value] - * None - */ -static FASTCALL void psp_sh2_exec(SH2_struct *yabause_state, u32 cycles) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - - state->cycles = yabause_state->cycles; - -#if defined(TRACE) || defined(TRACE_STEALTH) || defined(TRACE_LITE) - /* Avoid accumulating leftover cycles multiple times, since the trace - * code automatically adds state->cycles to the cycle accumulator when - * printing a trace line */ - sh2_trace_add_cycles(-(state->cycles)); -#endif - sh2_run(state, cycles); -#if defined(TRACE) || defined(TRACE_STEALTH) || defined(TRACE_LITE) - sh2_trace_add_cycles(state->cycles); -#endif - - yabause_state->cycles = state->cycles; -} - -/*************************************************************************/ - -/** - * psp_sh2_get_registers: Retrieve the values of all SH-2 registers. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * regs: Structure to receive register values - * [Return value] - * None - */ -static void psp_sh2_get_registers(SH2_struct *yabause_state, - sh2regs_struct *regs) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - memcpy(regs, state, sizeof(*regs)); -} - -/*----------------------------------*/ - -/** - * psp_sh2_get_{GPR,SR,GBR,VBR,MACH,MACL,PR,PC}: Return the value of the - * named register. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * num: General purpose register number to get (get_GPR() only) - * [Return value] - * Register's value - */ -static u32 psp_sh2_get_GPR(SH2_struct *yabause_state, int num) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->R[num]; -} - -static u32 psp_sh2_get_SR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->SR; -} - -static u32 psp_sh2_get_GBR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->GBR; -} - -static u32 psp_sh2_get_VBR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->VBR; -} - -static u32 psp_sh2_get_MACH(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->MACH; -} - -static u32 psp_sh2_get_MACL(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->MACL; -} - -static u32 psp_sh2_get_PR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->PR; -} - -static u32 psp_sh2_get_PC(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->PC; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_set_registers: Set the values of all SH-2 registers. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * regs: Structure containing new values for registers - * [Return value] - * None - */ -static void psp_sh2_set_registers(SH2_struct *yabause_state, - const sh2regs_struct *regs) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - memcpy(state, regs, sizeof(*regs)); -} - -/*----------------------------------*/ - -/** - * psp_sh2_set_{GPR,SR,GBR,VBR,MACH,MACL,PR,PC}: Set the value of the - * named register. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * num: General purpose register number to get (get_GPR() only) - * value: New value for register - * [Return value] - * None - */ -static void psp_sh2_set_GPR(SH2_struct *yabause_state, int num, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->R[num] = value; -} - -static void psp_sh2_set_SR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->SR = value; -} - -static void psp_sh2_set_GBR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->GBR = value; -} - -static void psp_sh2_set_VBR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->VBR = value; -} - -static void psp_sh2_set_MACH(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->MACH = value; -} - -static void psp_sh2_set_MACL(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->MACL = value; -} - -static void psp_sh2_set_PR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->PR = value; -} - -static void psp_sh2_set_PC(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->PC = value; -} - -/*************************************************************************/ - -/** - * psp_sh2_send_interrupt: Send an interrupt to the given SH-2 processor. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * [Return value] - * None - */ -static void psp_sh2_send_interrupt(SH2_struct *yabause_state, - u8 vector, u8 level) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - if (UNLIKELY(vector > 127)) { - return; - } - sh2_signal_interrupt(state, vector, level); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_set_interrupts: Set the state of the interrupt stack. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * interrupts: Array to receive interrupt data - * [Return value] - * Number of pending interrupts - */ -static int psp_sh2_get_interrupts(SH2_struct *yabause_state, - interrupt_struct interrupts[MAX_INTERRUPTS]) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - int i; - for (i = 0; i < state->interrupt_stack_top && i < MAX_INTERRUPTS; i++) { - interrupts[i].level = state->interrupt_stack[i].level; - interrupts[i].vector = state->interrupt_stack[i].vector; - } - return state->interrupt_stack_top; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_set_interrupts: Set the state of the interrupt stack. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * num_interrupts: Number of pending interrupts - * interrupts: Array of pending interrupts - * [Return value] - * None - */ -static void psp_sh2_set_interrupts(SH2_struct *yabause_state, - int num_interrupts, - const interrupt_struct interrupts[MAX_INTERRUPTS]) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->interrupt_stack_top = 0; - int i; - for (i = 0; i < num_interrupts; i++) { - if (UNLIKELY(interrupts[i].vector > 127)) { - return; - } - sh2_signal_interrupt(state, interrupts[i].vector, interrupts[i].level); - } -} - -/*************************************************************************/ - -/** - * psp_sh2_write_notify: Called when an external agent modifies memory. - * - * [Parameters] - * address: Beginning of address range to which data was written - * size: Size of address range to which data was written (in bytes) - * [Return value] - * None - */ -static void psp_sh2_write_notify(u32 address, u32 size) -{ - sh2_write_notify(address, size); -} - -/*************************************************************************/ -/**************************** Local functions ****************************/ -/*************************************************************************/ - -/** - * flush_caches: Callback function to flush the native CPU's caches. - * - * [Parameters] - * start: Pointer to start of range - * length: Length of range in bytes - * [Return value] - * None - */ -static void flush_caches(void *start, uint32_t length) -{ -#ifdef PSP // Protect so we can test this SH-2 core on other platforms - sceKernelDcacheWritebackInvalidateRange(start, length); - sceKernelIcacheInvalidateRange(start, length); -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * invalid_opcode_handler: Callback function for invalid opcodes detected - * in the instruction stream. - * - * [Parameters] - * state: Processor state block pointer - * PC: PC at which the invalid instruction was found - * opcode: The invalid opcode itself - * [Return value] - * None - */ -static void invalid_opcode_handler(SH2State *state, uint32_t PC, - uint16_t opcode) -{ - SH2_struct *yabause_state = (SH2_struct *)(state->userdata); - uint32_t saved_PC = state->PC; - state->PC = PC; // Show the proper PC in the error message - yabause_state->instruction = opcode; - YabSetError(YAB_ERR_SH2INVALIDOPCODE, yabause_state); - state->PC = saved_PC; -} - -/*-----------------------------------------------------------------------*/ - -/** - * trace_insn_handler: Callback function for tracing instructions. - * Updates the appropriate Yabause SH2_struct's registers and cycle count, - * then calls out to the common SH-2 tracing functionality. - * - * [Parameters] - * state: Processor state block pointer - * address: Address of instruction to trace - * [Return value] - * None - */ -static FASTCALL void trace_insn_handler(SH2State *state, uint32_t address) -{ - SH2_struct *yabause_state = (SH2_struct *)(state->userdata); - yabause_state->cycles = state->cycles; - sh2_trace(yabause_state, address); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sh2.h b/yabause/src/psp/psp-sh2.h deleted file mode 100644 index e69dbddaf0..0000000000 --- a/yabause/src/psp/psp-sh2.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-sh2.h: Header for SH-2 emulator for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_SH2_H -#define PSP_SH2_H - -#include "../sh2core.h" // for SH2Interface_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern SH2Interface_struct SH2PSP; - -/* Unique module ID (must be different from any in ../sh2{core,int}.h) */ -#define SH2CORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_SH2_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sound.c b/yabause/src/psp/psp-sound.c deleted file mode 100644 index c01982266a..0000000000 --- a/yabause/src/psp/psp-sound.c +++ /dev/null @@ -1,720 +0,0 @@ -/* src/psp/psp-sound.c: PSP sound output module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" -#include "../scsp.h" - -#include "config.h" -#include "me.h" -#include "me-utility.h" -#include "sys.h" -#include "psp-sound.h" - -/* Macro for uncached access to variables / structure fields */ -#define UNCACHED(var) (*((typeof(&var))((uint32_t)(&var) | 0x40000000))) - -/*************************************************************************/ -/************************* Configuration options *************************/ -/*************************************************************************/ - -/** - * DUMP_AUDIO: When defined, the program will write a dump of all audio - * data sent to the hardware (except filler data sent when the emulator - * falls behind real time) to "audio.pcm" in the current directory. - */ -// #define DUMP_AUDIO - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_sound_init(void); -static void psp_sound_deinit(void); -static int psp_sound_reset(void); -static int psp_sound_change_video_format(int vertfreq); -static void psp_sound_update_audio(u32 *leftchanbuffer, u32 *rightchanbuffer, - u32 num_samples); -static u32 psp_sound_get_audio_space(void); -static void psp_sound_mute_audio(void); -static void psp_sound_unmute_audio(void); -static void psp_sound_set_volume(int volume); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -SoundInterface_struct SNDPSP = { - .id = SNDCORE_PSP, - .Name = "PSP Sound Interface", - .Init = psp_sound_init, - .DeInit = psp_sound_deinit, - .Reset = psp_sound_reset, - .ChangeVideoFormat = psp_sound_change_video_format, - .UpdateAudio = psp_sound_update_audio, - .GetAudioSpace = psp_sound_get_audio_space, - .MuteAudio = psp_sound_mute_audio, - .UnMuteAudio = psp_sound_unmute_audio, - .SetVolume = psp_sound_set_volume, -}; - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Playback rate in Hz (unchangeable) */ -#define PLAYBACK_RATE 44100 - -/* Playback buffer size in samples (larger values = less chance of skipping - * but greater lag) */ -#define BUFFER_SIZE 256 - -/* Number of BUFFER_SIZE-sized audio buffers in the playback buffer (see - * description below) */ -#define NUM_BUFFERS 8 - -/* - * Playback buffer descriptor, implementing a lockless ring buffer with the - * following semantics: - * WRITER (main program): - * (1) Waits for .write_ready[.next_write] to become nonzero. - * (2) Writes BUFFER_SIZE samples of data into .buffer[.next_write]. - * (3) Sets .write_ready[.next_write] to zero. - * (4) Increments .next_write to point to the next audio buffer. - * READER (playback thread): - * (1) Waits for .write_ready[.next_play] to become zero. - * (2) Submits .buffer[.next_play] to the OS (which blocks until the - * previous buffer finishes playing). - * (3) Sets .write_ready[.cur_play] to nonzero. - * (4) Sets .cur_play to .next_play. - * (5) Increments .next_play to point to the next audio buffer. - * - * Note that at least three audio buffers are required in the ring buffer: - * - One currently being played by the hardware. - * - One queued for playback by the hardware. - * - One into which the main program is writing. - * A minimum of at least four buffers is recommended to allow overflow - * room, since the sample generation rate will typically not be locked to - * the hardware playback rate. - */ -typedef struct PSPSoundBufferDesc_ { - __attribute__((aligned(64))) int16_t buffer[NUM_BUFFERS][BUFFER_SIZE*2]; - /* Keep this on its own cache line for uncached access by both SC and ME */ - __attribute__((aligned(64))) - volatile uint8_t write_ready[NUM_BUFFERS]; - // When nonzero, data can be stored in buffer[next_write] - /* Start a new cache line here (these are written by the ME) */ - __attribute__((aligned(64))) - unsigned int next_write; - // Index of next buffer to store data into - unsigned int saved_samples; - // Number of samples accumulated in next_write buffer - /* Start another new cache line here (these are written by the SC) */ - __attribute__((aligned(64))) - int started; // Nonzero if channel is playing - int channel; // Channel number allocated for this buffer - unsigned int cur_play; - // Index of buffer currently being played by the hardware - unsigned int next_play; - // Index of next buffer to submit for playback - /* Internal use: */ - SceUID thread; // Playback thread handle - int stop; // Flag to tell thread to terminate -} PSPSoundBufferDesc; -static PSPSoundBufferDesc stereo_buffer; - -/* Mute flag (used by Mute and UnMute methods) */ -static int muted = 1; - -#ifdef DUMP_AUDIO -/* Audio output file */ -static int dump_fd; -#endif - -/*----------------------------------*/ - -/* Uncached pointer to sound RAM (to save generating it on every access) */ -static uint8_t *SoundRam_uncached; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ - -static FASTCALL u8 psp_SoundRamReadByte(u32 address); -static FASTCALL u16 psp_SoundRamReadWord(u32 address); -static FASTCALL u32 psp_SoundRamReadLong(u32 address); -static FASTCALL void psp_SoundRamWriteByte(u32 address, u8 data); -static FASTCALL void psp_SoundRamWriteWord(u32 address, u16 data); -static FASTCALL void psp_SoundRamWriteLong(u32 address, u32 data); - -static int start_channel(PSPSoundBufferDesc *buffer_desc); -void stop_channel(PSPSoundBufferDesc *buffer_desc); -static int playback_thread(SceSize args, void *argp); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_sound_init: Initialize the sound interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_sound_init(void) -{ - if (stereo_buffer.started) { - /* Already initialized! */ - return 0; - } - -#ifdef DUMP_AUDIO - dump_fd = sceIoOpen("audio.pcm", - PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0600); - if (dump_fd < 0) { - DMSG("open(audio.pcm): %s", psp_strerror(dump_fd)); - dump_fd = 0; - } -#endif - - if (!start_channel(&stereo_buffer)) { - DMSG("Failed to start playback"); - return -1; - } - - /* If the Media Engine is in use, reassign the sound RAM access - * functions so we read/write through the cache as appropriate. */ - if (me_available && config_get_use_me()) { - SoundRam_uncached = (uint8_t *)((uintptr_t)SoundRam | 0x40000000); - unsigned int i; - for (i = 0x5A0; i < 0x5B0; i++) { - ReadByteList [i] = psp_SoundRamReadByte; - ReadWordList [i] = psp_SoundRamReadWord; - ReadLongList [i] = psp_SoundRamReadLong; - WriteByteList[i] = psp_SoundRamWriteByte; - WriteWordList[i] = psp_SoundRamWriteWord; - WriteLongList[i] = psp_SoundRamWriteLong; - } - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_deinit: Shut down the sound interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sound_deinit(void) -{ - stop_channel(&stereo_buffer); - - unsigned int i; - for (i = 0x5A0; i < 0x5B0; i++) { - ReadByteList [i] = SoundRamReadByte; - ReadWordList [i] = SoundRamReadWord; - ReadLongList [i] = SoundRamReadLong; - WriteByteList[i] = SoundRamWriteByte; - WriteWordList[i] = SoundRamWriteWord; - WriteLongList[i] = SoundRamWriteLong; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_reset: Reset the sound interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_sound_reset(void) -{ - /* Nothing to do */ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_change_video_format: Handle a change in the video refresh - * frequency. - * - * [Parameters] - * vertfreq: New refresh frequency (Hz) - * [Return value] - * Zero on success, negative on error - */ -static int psp_sound_change_video_format(int vertfreq) -{ - /* Nothing to do */ - return 0; -} - -/*************************************************************************/ - -/** - * psp_sound_update_audio: Output audio data. - * - * [Parameters] - * leftchanbuffer: Left channel sample array, as _signed_ 16-bit samples - * rightchanbuffer: Right channel sample array, as _signed_ 16-bit samples - * num_samples: Number of samples in sample arrays - * [Return value] - * None - */ -static void psp_sound_update_audio(u32 *leftchanbuffer, u32 *rightchanbuffer, - u32 num_samples) -{ - const unsigned int next_write = stereo_buffer.next_write; - - if (!leftchanbuffer || !rightchanbuffer - || !UNCACHED(stereo_buffer.write_ready[next_write]) - || num_samples == 0 - || num_samples > BUFFER_SIZE - stereo_buffer.saved_samples - ) { - if (!meUtilityIsME()) { // Can't write to stderr on the ME - DMSG("Invalid parameters: %p %p %u (status: wr=%d ss=%d)", - leftchanbuffer, rightchanbuffer, (unsigned int)num_samples, - UNCACHED(stereo_buffer.write_ready[next_write]), - stereo_buffer.saved_samples); - } - return; - } - - const int32_t *in_l = (int32_t *)leftchanbuffer; - const int32_t *in_r = (int32_t *)rightchanbuffer; - int16_t *out = - &stereo_buffer.buffer[next_write][stereo_buffer.saved_samples * 2]; - - uint32_t i; - for (i = 0; i < num_samples; i++) { - const int32_t lval = *in_l++; - const int32_t rval = *in_r++; - *out++ = bound(lval, -0x8000, 0x7FFF); - *out++ = bound(rval, -0x8000, 0x7FFF); - } - - stereo_buffer.saved_samples += num_samples; - if (stereo_buffer.saved_samples >= BUFFER_SIZE) { - if (meUtilityIsME()) { - /* Make sure the playback thread sees all the audio data */ - meUtilityDcacheWritebackInvalidateAll(); - } - UNCACHED(stereo_buffer.write_ready[next_write]) = 0; - stereo_buffer.saved_samples = 0; - stereo_buffer.next_write = (next_write + 1) % NUM_BUFFERS; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_get_audio_space: Return the number of samples immediately - * available for outputting audio data. - * - * [Parameters] - * None - * [Return value] - * Number of samples available - */ -static u32 psp_sound_get_audio_space(void) -{ - if (UNCACHED(stereo_buffer.write_ready[stereo_buffer.next_write])) { - return BUFFER_SIZE - stereo_buffer.saved_samples; - } else { - return 0; - } -} - -/*************************************************************************/ - -/** - * psp_sound_mute_audio: Disable audio output. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sound_mute_audio(void) -{ - muted = 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_mute_audio: Enable audio output. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sound_unmute_audio(void) -{ - muted = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_set_volume: Set the audio output volume. - * - * [Parameters] - * volume: New volume (0-100, 100 = full volume) - * [Return value] - * None - */ -static void psp_sound_set_volume(int volume) -{ - const int pspvol = (PSP_AUDIO_VOLUME_MAX * volume + 50) / 100; - if (stereo_buffer.started) { - sceAudioChangeChannelVolume(stereo_buffer.channel, pspvol, pspvol); - } -} - -/*************************************************************************/ -/********************* PSP-local interface functions *********************/ -/*************************************************************************/ - -/** - * psp_sound_pause: Stop audio output. Called when the system is being - * suspended. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_sound_pause(void) -{ - if (stereo_buffer.started) { - sceKernelSuspendThread(stereo_buffer.thread); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_unpause: Resume audio output. Called when the system is - * resuming from a suspend. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_sound_unpause(void) -{ - if (stereo_buffer.started) { - sceKernelResumeThread(stereo_buffer.thread); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_exit: Terminate all playback in preparation for exiting. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_sound_exit(void) -{ - if (stereo_buffer.started) { - stop_channel(&stereo_buffer); - } -} - -/*************************************************************************/ -/* Sound RAM access functions (for use when the 68k is running on the ME) */ -/*************************************************************************/ - -/** - * psp_SoundRamRead{Byte,Word,Long}: Sound RAM read access functions for - * use when the sound CPU is being emulated on the Media Engine. These - * functions access sound RAM using uncached pointers. - * - * 2Mbit mode (MEM4MB == 0) is not supported by these functions. - * - * [Parameters] - * address: Address to read from - * [Return value] - * Data loaded from given address - */ -static FASTCALL u8 psp_SoundRamReadByte(u32 address) -{ - address &= 0x7FFFF; - return T2ReadByte(SoundRam_uncached, address); -} - -static FASTCALL u16 psp_SoundRamReadWord(u32 address) -{ - address &= 0x7FFFF; - return T2ReadWord(SoundRam_uncached, address); -} - -static FASTCALL u32 psp_SoundRamReadLong(u32 address) -{ - address &= 0x7FFFF; - return T2ReadLong(SoundRam_uncached, address); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_SoundRamWrite{Byte,Word,Long}: Sound RAM write access functions for - * use when the sound CPU is being emulated on the Media Engine. These - * functions do _not_ access sound RAM using uncached pointers; data is - * assumed to be flushed by the SCSP at periodic intervals. - * - * 2Mbit mode (MEM4MB == 0) is not supported by these functions. - * - * [Parameters] - * address: Address to write to - * data: Data to store - * [Return value] - * None - */ -static FASTCALL void psp_SoundRamWriteByte(u32 address, u8 data) -{ - address &= 0x7FFFF; - if (address < config_get_me_uncached_boundary()) { - T2WriteByte(SoundRam_uncached, address, data); - } else { - T2WriteByte(SoundRam, address, data); - } - M68KWriteNotify(address, 1); -} - -static FASTCALL void psp_SoundRamWriteWord(u32 address, u16 data) -{ - address &= 0x7FFFF; - if (address < config_get_me_uncached_boundary()) { - T2WriteWord(SoundRam_uncached, address, data); - } else { - T2WriteWord(SoundRam, address, data); - } - M68KWriteNotify(address, 2); -} - -static FASTCALL void psp_SoundRamWriteLong(u32 address, u32 data) -{ - address &= 0x7FFFF; - if (address < config_get_me_uncached_boundary()) { - T2WriteLong(SoundRam_uncached, address, data); - } else { - T2WriteLong(SoundRam, address, data); - } - M68KWriteNotify(address, 4); -} - -/*************************************************************************/ -/****************** Low-level audio channel management *******************/ -/*************************************************************************/ - -/** - * start_channel: Allocate a new channel and starts playback. - * - * [Parameters] - * buffer_desc: Playback buffer descriptor - * [Return value] - * Nonzero on success, zero on error - */ -static int start_channel(PSPSoundBufferDesc *buffer_desc) -{ - if (!buffer_desc) { - DMSG("buffer_desc == NULL"); - return 0; - } - if (buffer_desc->started) { - DMSG("Buffer is already started!"); - return 0; - } - - /* Allocate a hardware channel */ - buffer_desc->channel = sceAudioChReserve( - PSP_AUDIO_NEXT_CHANNEL, BUFFER_SIZE, PSP_AUDIO_FORMAT_STEREO - ); - if (buffer_desc->channel < 0) { - DMSG("Failed to allocate channel: %s", - psp_strerror(buffer_desc->channel)); - return 0; - } - - /* Initialize the ring buffer */ - buffer_desc->cur_play = NUM_BUFFERS - 1; - buffer_desc->next_play = 0; - buffer_desc->next_write = 0; - int i; - for (i = 0; i < NUM_BUFFERS; i++) { - buffer_desc->write_ready[i] = 1; - } - buffer_desc->stop = 0; - /* Also write everything out of the cache so it's ready for the ME */ - sceKernelDcacheWritebackAll(); - - /* Start the playback thread */ - char thname[100]; - snprintf(thname, sizeof(thname), "YabauseSoundCh%d", buffer_desc->channel); - SceUID handle = sys_start_thread(thname, playback_thread, - THREADPRI_SOUND, 0x1000, - sizeof(buffer_desc), &buffer_desc); - if (handle < 0) { - DMSG("Failed to create thread: %s", psp_strerror(handle)); - sceAudioChRelease(buffer_desc->channel); - return 0; - } - buffer_desc->thread = handle; - - /* Success */ - buffer_desc->started = 1; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * stop_channel: Stop playback from the given playback buffer. - * - * [Parameters] - * buffer_desc: Playback buffer descriptor - * [Return value] - * None - */ -void stop_channel(PSPSoundBufferDesc *buffer_desc) -{ - if (!buffer_desc) { - DMSG("buffer_desc == NULL"); - return; - } - if (!buffer_desc->started) { - DMSG("Buffer has not been started!"); - return; - } - - /* Signal the thread to stop, then wait for it (if we try to stop the - * thread in the middle of an audio write, we won't be able to free - * the hardware channel) */ - buffer_desc->stop = 1; - int tries; - for (tries = (1000 * (2*BUFFER_SIZE)/PLAYBACK_RATE); tries > 0; tries--) { - if (sys_delete_thread_if_stopped(buffer_desc->thread, NULL)) { - break; - } - sceKernelDelayThread(1000); // Wait for 1ms before trying again - } - - if (!tries) { - /* The thread didn't stop on its own, so terminate it with - * extreme prejudice */ - sceKernelTerminateDeleteThread(buffer_desc->thread); - sceAudioChRelease(buffer_desc->channel); - memset(buffer_desc, 0, sizeof(*buffer_desc)); - } -} - -/*************************************************************************/ - -/** - * playback_thread: Sound playback thread. Continually sends the ring - * buffer data to the OS until signaled to stop. - * - * [Parameters] - * args: Thread argument size - * argp: Thread argument pointer - * [Return value] - * Always zero - */ -static int playback_thread(SceSize args, void *argp) -{ - PSPSoundBufferDesc * const buffer_desc = *(PSPSoundBufferDesc **)argp; - - /* Temporary buffer for dummy audio data when the emulator falls behind - * real time (filled with the last sample sent to avoid clicks). This - * thread is only launched once, so "static" is safe. */ - static uint32_t dummy_buffer[BUFFER_SIZE]; // 1 stereo sample = 32 bits - static uint32_t last_sample; // Last stereo sample played - - while (!buffer_desc->stop) { - const unsigned int next_play = buffer_desc->next_play; -//static int x;int now=sceKernelGetSystemTimeLow();if(now-x>100000){printf("--- audio stat: %u %u %u %u cp=%u np=%u nw=%u\n",UNCACHED(buffer_desc->write_ready[0]),UNCACHED(buffer_desc->write_ready[1]),UNCACHED(buffer_desc->write_ready[2]),UNCACHED(buffer_desc->write_ready[3]),buffer_desc->cur_play,next_play,UNCACHED(buffer_desc->next_write));x=now;} - if (!UNCACHED(buffer_desc->write_ready[next_play])) { // i.e., ready for playback - const void *buffer = buffer_desc->buffer[next_play]; - last_sample = ((const uint32_t *)buffer)[BUFFER_SIZE - 1]; - sceAudioOutputBlocking(buffer_desc->channel, muted ? 0 : 0x8000, - buffer); -#ifdef DUMP_AUDIO - sceIoWrite(dump_fd, buffer, BUFFER_SIZE*4); -#endif - UNCACHED(buffer_desc->write_ready[buffer_desc->cur_play]) = 1; - buffer_desc->cur_play = next_play; - buffer_desc->next_play = (next_play + 1) % NUM_BUFFERS; - } else { - const uint32_t sample = last_sample; // Help out optimizer - uint32_t *ptr32 = dummy_buffer; - unsigned int i; - for (i = 0; i < BUFFER_SIZE; i += 8) { - ptr32[i+0] = sample; - ptr32[i+1] = sample; - ptr32[i+2] = sample; - ptr32[i+3] = sample; - ptr32[i+4] = sample; - ptr32[i+5] = sample; - ptr32[i+6] = sample; - ptr32[i+7] = sample; - } - sceAudioOutputBlocking(buffer_desc->channel, muted ? 0 : 0x8000, - dummy_buffer); - } - } - - sceAudioChRelease(buffer_desc->channel); - memset(buffer_desc, 0, sizeof(*buffer_desc)); - return 0; -} - -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sound.h b/yabause/src/psp/psp-sound.h deleted file mode 100644 index 89b46495d1..0000000000 --- a/yabause/src/psp/psp-sound.h +++ /dev/null @@ -1,80 +0,0 @@ -/* src/psp/psp-sound.h: PSP sound output module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_SOUND_H -#define PSP_SOUND_H - -#include "../scsp.h" // for SoundInterface_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern SoundInterface_struct SNDPSP; - -/* Unique module ID (must be different from any in scsp.h) */ -#define SNDCORE_PSP 0x5CE // "SCE" - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_pause: Stop audio output. Called when the system is being - * suspended. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_sound_pause(void); - -/** - * psp_sound_unpause: Resume audio output. Called when the system is - * resuming from a suspend. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_sound_unpause(void); - -/** - * psp_sound_exit: Terminate all playback in preparation for exiting. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_sound_exit(void); - -/*************************************************************************/ - -#endif // PSP_SOUND_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-bitmap.c b/yabause/src/psp/psp-video-bitmap.c deleted file mode 100644 index 1083865437..0000000000 --- a/yabause/src/psp/psp-video-bitmap.c +++ /dev/null @@ -1,314 +0,0 @@ -/* src/psp/psp-video-bitmap.c: Bitmapped background graphics handling for - PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidshared.h" - -#include "display.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" -#include "texcache.h" - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * vdp2_draw_bitmap: Draw a graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_bitmap(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Set up vertices */ - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 2); - vertices[0].u = 0; - vertices[0].v = 0; - vertices[0].x = info->x * info->coordincx; - vertices[0].y = info->y * info->coordincy; - vertices[0].z = 0; - vertices[1].u = info->cellw; - vertices[1].v = info->cellh; - vertices[1].x = (info->x + info->cellw) * info->coordincx; - vertices[1].y = (info->y + info->cellh) * info->coordincy; - vertices[1].z = 0; - - /* FIXME: only very basic clipping processing at the moment; see - * vidsoft.c for more details on how this works */ - if ((info->wctl & 0x3) == 0x3) { - vertices[0].x = clip[0].xstart; - vertices[0].y = clip[0].ystart; - vertices[1].x = clip[0].xend + 1; - vertices[1].y = clip[0].yend + 1; - vertices[1].u = (vertices[1].x - vertices[0].x) / info->coordincx; - vertices[1].v = (vertices[1].y - vertices[0].y) / info->coordincy; - /* Offset the bitmap address appropriately */ - const int bpp = (info->colornumber==4 ? 32 : - info->colornumber>=2 ? 16 : - info->colornumber==1 ? 8 : 4); - const int xofs = clip[0].xstart - info->x; - const int yofs = clip[0].ystart - info->y; - info->charaddr += (yofs * info->cellw + xofs) * bpp / 8; - } - - /* Draw the bitmap */ - texcache_load_bitmap( - info->charaddr, - (vertices[1].u - vertices[0].u + 7) & -8, - vertices[1].v - vertices[0].v, - info->cellw, info->colornumber, info->transparencyenable, - info->coloroffset, info->paladdr << 4, - info->cor, info->cog, info->cob, - 0 // Bitmaps are likely to change, so don't cache them persistently - ); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_bitmap_t8: Draw an 8-bit indexed graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_bitmap_t8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Set up vertices */ - // FIXME: this will break with a final (clipped) width above 512; - // need to split the texture in half in that case - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 2); - vertices[0].u = 0; - vertices[0].v = 0; - vertices[0].x = info->x * info->coordincx; - vertices[0].y = info->y * info->coordincy; - vertices[0].z = 0; - vertices[1].u = info->cellw; - vertices[1].v = info->cellh; - vertices[1].x = (info->x + info->cellw) * info->coordincx; - vertices[1].y = (info->y + info->cellh) * info->coordincy; - vertices[1].z = 0; - - /* FIXME: only very basic clipping processing at the moment; see - * vidsoft.c for more details on how this works */ - if ((info->wctl & 0x3) == 0x3) { - vertices[0].x = clip[0].xstart; - vertices[0].y = clip[0].ystart; - vertices[1].x = clip[0].xend + 1; - vertices[1].y = clip[0].yend + 1; - vertices[1].u = (vertices[1].x - vertices[0].x) / info->coordincx; - vertices[1].v = (vertices[1].y - vertices[0].y) / info->coordincy; - /* Offset the bitmap address appropriately */ - const int bpp = (info->colornumber==4 ? 32 : - info->colornumber>=2 ? 16 : - info->colornumber==1 ? 8 : 4); - const int xofs = clip[0].xstart - info->x; - const int yofs = clip[0].ystart - info->y; - info->charaddr += (yofs * info->cellw + xofs) * bpp / 8; - } - - /* Set up the color table */ - guClutMode(GU_PSM_8888, 0, 0xFF, 0); - void *ptr = vdp2_gen_t8_clut( - info->coloroffset, info->paladdr<<4, - info->transparencyenable, info->cor, info->cog, info->cob - ); - if (LIKELY(ptr)) { - guClutLoad(256/8, ptr); - } - - /* Draw the bitmap */ - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexMode(GU_PSM_T8, 0, 0, 0); - guTexImage(0, 512, 512, info->cellw, &Vdp2Ram[info->charaddr & 0x7FFFF]); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_bitmap_32: Draw a 32-bit ARGB1888 unscaled graphics layer - * bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_bitmap_32(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Determine the area to be drawn */ - unsigned int x0, y0, width, height; - /* FIXME: only very basic clipping processing at the moment; see - * vidsoft.c for more details on how this works */ - if ((info->wctl & 0x3) == 0x3) { - x0 = clip[0].xstart; - y0 = clip[0].ystart; - width = (clip[0].xend + 1) - x0; - height = (clip[0].yend + 1) - y0; - /* Offset the bitmap address appropriately */ - const int xofs = clip[0].xstart - info->x; - const int yofs = clip[0].ystart - info->y; - info->charaddr += (yofs * info->cellw + xofs) * 4; - } else { - x0 = info->x; - y0 = info->y; - width = info->cellw; - height = info->cellh; - } - - /* Set up vertices (using optimized 64-byte-wide strips) */ - // FIXME: this will work incorrectly on bitmaps wider than 512 pixels, - // if there are any such (VDP2 RAM is only big enough for 512x256) - const uint32_t nverts = ((width+15) / 16) * 2; - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * nverts); - unsigned int x, i; - for (x = i = 0; x < width; x += 16, i += 2) { - const unsigned int thisw = (width-x > 16 ? 16 : width-x); - vertices[i+0].u = x; - vertices[i+0].v = 0; - vertices[i+0].x = x0 + x; - vertices[i+0].y = y0; - vertices[i+0].z = 0; - vertices[i+1].u = x + thisw; - vertices[i+1].v = height; - vertices[i+1].x = x0 + x + thisw; - vertices[i+1].y = y0 + height; - vertices[i+1].z = 0; - } - - /* Set up GE parameters for drawing */ - guTexFlush(); - guTexMode(GU_PSM_T32, 0, 0, 0); - guTexImage(0, 512, 512, info->cellw, &Vdp2Ram[info->charaddr & 0x7FFFF]); - guAmbientColor(0xFFFFFFFF); - guTexFunc(GU_TFX_REPLACE, 1); - guDisable(GU_BLEND); - - /* If transparency is enabled, set up an offscreen buffer for - * rendering; if we can't (not enough spare VRAM), just draw with - * transparency disabled */ - uint32_t *offscreen_buffer = NULL; - uint32_t offscreen_stride = 0; - if (info->transparencyenable) { - offscreen_stride = (width + 3) & -4; - offscreen_buffer = display_alloc_vram(offscreen_stride * height); - if (offscreen_buffer) { - /* Adjust the draw buffer pointer so we don't have to mess - * with the vertex coordinates */ - const uint32_t offset = - vertices[0].y * offscreen_stride + vertices[0].x; - guDrawBuffer(GU_PSM_8888, - offscreen_buffer - offset, offscreen_stride); - } - } - - /* Draw each of the RGB components independently */ - unsigned int rgb; - for (rgb = 0; rgb < 3; rgb++) { - /* Set up the color table for this component */ - const int ofs = (rgb==0 ? info->cor : rgb==1 ? info->cog : info->cob); - void *clut = vdp2_gen_32_clut(ofs); - if (clut) { - guClutMode(GU_PSM_8888, (3-rgb)*8, 0xFF, 0); - guClutLoad(256/8, clut); - } - - /* Blit this component to the screen. If we're using transparency, - * also clear the alpha byte on the first blit so we only need a - * single "set" operation later. */ - if (offscreen_buffer && rgb == 0) { - guStencilOp(GU_ZERO, GU_ZERO, GU_ZERO); // Clear alpha bytes - guEnable(GU_STENCIL_TEST); - } - guPixelMask(~(0xFF0000FF << (rgb*8))); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - if (offscreen_buffer && rgb == 0) { - guDisable(GU_STENCIL_TEST); - } - } - guPixelMask(0); - - /* Mask off transparent pixels and blit back to the display buffer - * if appropriate */ - if (offscreen_buffer) { - static const __attribute__((aligned(64))) uint32_t mask_clut[8] = - {0, ~0}; - guClutMode(GU_PSM_8888, 7, 0x1, 0); - guClutLoad(1, mask_clut); - guAlphaFunc(GU_EQUAL, 0xFF, 0xFF); // Only pass non-transparent pixels - guEnable(GU_ALPHA_TEST); - guStencilFunc(GU_ALWAYS, 0xFF, 0xFF); // Set drawn alpha bytes to 255 - guStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); - guEnable(GU_STENCIL_TEST); - guPixelMask(0xFFFFFF); // Only modify the alpha byte - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - guPixelMask(0); - guStencilOp(GU_KEEP, GU_KEEP, GU_KEEP); - guDisable(GU_STENCIL_TEST); - guDisable(GU_ALPHA_TEST); - - guDrawBuffer(GU_PSM_8888, display_work_buffer(), DISPLAY_STRIDE); - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexImage(0, 512, 512, offscreen_stride, offscreen_buffer); - guTexFunc(GU_TFX_REPLACE, 1); - guEnable(GU_BLEND); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - } - - /* Turn blending back on before returning (in case we didn't do so for - * transparency handling), since everyone else expects it to be on */ - guEnable(GU_BLEND); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-internal.h b/yabause/src/psp/psp-video-internal.h deleted file mode 100644 index 5fc4120ffe..0000000000 --- a/yabause/src/psp/psp-video-internal.h +++ /dev/null @@ -1,431 +0,0 @@ -/* src/psp/psp-video-internal.h: Internal header for PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_VIDEO_INTERNAL_H -#define PSP_VIDEO_INTERNAL_H - -#include "../vdp1.h" -#include "../vdp2.h" -#include "../vidshared.h" - -/*************************************************************************/ -/************************** Internal constants ***************************/ -/*************************************************************************/ - -/* Graphics layer identifiers. */ - -enum {BG_NBG0 = 0, BG_NBG1, BG_NBG2, BG_NBG3, BG_RBG0}; - -/*************************************************************************/ -/******************* Map drawing routine declarations ********************/ -/*************************************************************************/ - -/** - * vdp2_draw_bitmap: Draw a graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_bitmap(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_bitmap_t8: Draw an 8-bit indexed graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_bitmap_t8(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_bitmap_32: Draw a 32-bit ARGB1888 unscaled graphics layer - * bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_bitmap_32(vdp2draw_struct *info, - const clipping_struct *clip); - -/*----------------------------------*/ - -/** - * vdp2_draw_map_rotated: Draw a rotated graphics layer. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_rotated(vdp2draw_struct *info, - const clipping_struct *clip); - -/*----------------------------------*/ - -/** - * vdp2_draw_map_8x8: Draw a graphics layer composed of 8x8 patterns of - * any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_8x8(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_map_8x8_t8: Draw a graphics layer composed of 8-bit indexed - * color 8x8 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_8x8_t8(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_map_16x16: Draw a graphics layer composed of 16x16 patterns - * of any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_16x16(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_map_16x16_t8: Draw a graphics layer composed of 8-bit indexed - * color 16x16 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_16x16_t8(vdp2draw_struct *info, - const clipping_struct *clip); - -/*************************************************************************/ -/**************** Game-specific optimizations and tweaks *****************/ -/*************************************************************************/ - -/** - * psp_video_apply_tweaks: Apply game-specific optimizations and tweaks - * for faster/better PSP video output. Called at the beginning of drawing - * each frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_video_apply_tweaks(void); - -/*************************************************************************/ - -/** - * CustomDrawRoutine: Type of a custom drawing routine for a graphics - * layer, used with psp_video_set_draw_routine(). - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * Nonzero if the graphics layer was drawn, zero if not - */ -typedef int CustomDrawRoutine(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * psp_video_set_draw_routine: Set a custom drawing routine for a specific - * graphics layer. If "is_fast" is true when setting a routine for RBG0, - * the frame rate will not be halved regardless of the related setting in - * the configuration menu. - * - * [Parameters] - * layer: Graphics layer (BG_*) - * func: Drawing routine (NULL to clear any previous setting) - * is_fast: For BG_RBG0, indicates whether the routine is fast enough - * to be considered a non-distorted layer for the purposes - * of frame rate adjustment; ignored for other layers - * [Return value] - * None - */ -extern void psp_video_set_draw_routine(int layer, CustomDrawRoutine *func, - int is_fast); - -/*************************************************************************/ -/**************** Other utility routines and declarations ****************/ -/*************************************************************************/ - -/* Displayed width and height */ -extern unsigned int disp_width, disp_height; - -/* Scale (right-shift) applied to X and Y coordinates */ -extern unsigned int disp_xscale, disp_yscale; - -/* Total number of frames to skip before we draw the next one */ -extern unsigned int frames_to_skip; - -/* Number of frames skipped so far since we drew the last one */ -extern unsigned int frames_skipped; - -/* VDP1 color component offset values (-0xFF...+0xFF) */ -extern int32_t vdp1_rofs, vdp1_gofs, vdp1_bofs; - -/*************************************************************************/ - -/** - * vdp2_is_persistent: Return whether the tile at the given address in - * VDP2 RAM is persistently cacheable. - * - * [Parameters] - * address: Tile address in VDP2 RAM - * [Return value] - * Nonzero if tile texture can be persistently cached, else zero - */ -extern int vdp2_is_persistent(uint32_t address); - -/*************************************************************************/ - -/** - * vdp2_calc_pattern_address, vdp2_calc_pattern_address_8x8, - * vdp2_calc_pattern_address_16x16: Calculate the address and associated - * data of the next pattern. The _8x8 and _16x16 versions are for use when - * the size of the pattern (8x8 or 16x16 pixels) is known at calling time. - * - * [Parameters] - * info: Graphics layer data - * [Return value] - * None - */ -static inline void vdp2_calc_pattern_address(vdp2draw_struct *info) -{ - if (info->patterndatasize == 1) { - const uint16_t data = T1ReadWord(Vdp2Ram, info->addr); - /* We don't support per-pixel priority, so don't waste time - * parsing this bit */ - //info->specialfunction = (info->supplementdata >> 9) & 1; - if (info->colornumber == 0) { // 4bpp - info->paladdr = ((data >> 12) & 0xF) - | ((info->supplementdata >> 1) & 0x70); - } else { // >=8bpp - info->paladdr = (data >> 8) & 0x70; - } - if (!info->auxmode) { - info->flipfunction = (data >> 10) & 0x3; - if (info->patternwh == 1) { - info->charaddr = (info->supplementdata & 0x1F) << 10 - | (data & 0x3FF); - } else { - info->charaddr = (info->supplementdata & 0x1C) << 10 - | (data & 0x3FF) << 2 - | (info->supplementdata & 0x3); - } - } else { - info->flipfunction = 0; - if (info->patternwh == 1) { - info->charaddr = (info->supplementdata & 0x1C) << 10 - | (data & 0xFFF); - } else { - info->charaddr = (info->supplementdata & 0x10) << 10 - | (data & 0xFFF) << 2 - | (info->supplementdata & 0x3); - } - } - } else { // patterndatasize == 2 - const uint32_t data = T1ReadLong(Vdp2Ram, info->addr); - info->charaddr = data & 0x7FFF; - info->flipfunction = data >> 30; - info->paladdr = (data >> 16) & 0x007F; - /* Ignored, as above */ - //info->specialfunction = (data1 >> 29) & 1; - } - - /* We don't support 1MB of VDP2 RAM, so always mask off the high bit */ - //if (!(Vdp2Regs->VRSIZE & 0x8000)) { - info->charaddr &= 0x3FFF; - //} - - info->charaddr <<= 5; -} - -/*----------------------------------*/ - -static inline void vdp2_calc_pattern_address_8x8(vdp2draw_struct *info) -{ - if (info->patterndatasize == 1) { - const uint16_t data = T1ReadWord(Vdp2Ram, info->addr); - //info->specialfunction = (info->supplementdata >> 9) & 1; - if (info->colornumber == 0) { // 4bpp - info->paladdr = ((data >> 12) & 0xF) - | ((info->supplementdata >> 1) & 0x70); - } else { // >=8bpp - info->paladdr = (data >> 8) & 0x70; - } - if (!info->auxmode) { - info->flipfunction = (data >> 10) & 0x3; - info->charaddr = (info->supplementdata & 0xF) << 10 - | (data & 0x3FF); - } else { - info->flipfunction = 0; - info->charaddr = (info->supplementdata & 0xC) << 10 - | (data & 0xFFF); - } - } else { // patterndatasize == 2 - const uint32_t data = T1ReadLong(Vdp2Ram, info->addr); - info->charaddr = data & 0x3FFF; - info->flipfunction = data >> 30; - info->paladdr = (data >> 16) & 0x007F; - /* Ignored, as above */ - //info->specialfunction = (data1 >> 29) & 1; - } - - info->charaddr <<= 5; -} - -/*----------------------------------*/ - -static inline void vdp2_calc_pattern_address_16x16(vdp2draw_struct *info) -{ - if (info->patterndatasize == 1) { - const uint16_t data = T1ReadWord(Vdp2Ram, info->addr); - //info->specialfunction = (info->supplementdata >> 9) & 1; - if (info->colornumber == 0) { // 4bpp - info->paladdr = ((data >> 12) & 0xF) - | ((info->supplementdata >> 1) & 0x70); - } else { // >=8bpp - info->paladdr = (data >> 8) & 0x70; - } - if (!info->auxmode) { - info->flipfunction = (data >> 10) & 0x3; - info->charaddr = (info->supplementdata & 0xC) << 10 - | (data & 0x3FF) << 2 - | (info->supplementdata & 0x3); - } else { - info->flipfunction = 0; - info->charaddr = (data & 0xFFF) << 2 - | (info->supplementdata & 0x3); - } - } else { // patterndatasize == 2 - const uint32_t data = T1ReadLong(Vdp2Ram, info->addr); - info->charaddr = data & 0x3FFF; - info->flipfunction = data >> 30; - info->paladdr = (data >> 16) & 0x007F; - /* Ignored, as above */ - //info->specialfunction = (data1 >> 29) & 1; - } - - info->charaddr <<= 5; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_gen_t8_clut: Generate a 256-color color table for an 8-bit indexed - * tile given the base color index and color offset values. Helper routine - * for the T8 map drawing functions. - * - * [Parameters] - * color_base: Base color index - * color_ofs: Color offset (ORed with pixel value) - * transparent: Nonzero if color index 0 should be transparent - * rofs, gofs, bofs: Red/green/blue adjustment values - * [Return value] - * Allocated color table pointer - */ -static inline uint32_t *vdp2_gen_t8_clut( - int color_base, int color_ofs, int transparent, - int rofs, int gofs, int bofs) -{ - uint32_t *clut = pspGuGetMemoryMerge(256*4 + 60); - clut = (uint32_t *)(((uintptr_t)clut + 63) & -64); // Must be aligned - int i; - for (i = 0; i < 256; i++) { - clut[i] = adjust_color_32_32( - global_clut_32[color_base + (color_ofs | i)], rofs, gofs, bofs - ); - } - if (transparent) { - clut[0] = 0x00000000; - } - return clut; -} - -/*----------------------------------*/ - -/** - * vdp2_gen_32_clut: Generate a 256-color color table for one color - * component of a 32-bit pixel given the color offset value. Helper - * routine for the 32bpp bitmap drawing function. - * - * [Parameters] - * color_base: Base color index - * color_ofs: Color offset (ORed with pixel value) - * transparent: Nonzero if color index 0 should be transparent - * rofs, gofs, bofs: Red/green/blue adjustment values - * [Return value] - * Allocated color table pointer - */ -static inline uint32_t *vdp2_gen_32_clut(int ofs) -{ - uint32_t *clut = pspGuGetMemoryMerge(256*4 + 60); - clut = (uint32_t *)(((uintptr_t)clut + 63) & -64); // Must be aligned - int i; - for (i = 0; i < 256; i++) { - clut[i] = 0xFF000000 | (bound(i+ofs, 0, 255) * 0x010101); - } - return clut; -} - -/*************************************************************************/ -/*************************************************************************/ - -#endif // PSP_VIDEO_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-rotate.c b/yabause/src/psp/psp-video-rotate.c deleted file mode 100644 index 348e6e2e8e..0000000000 --- a/yabause/src/psp/psp-video-rotate.c +++ /dev/null @@ -1,1688 +0,0 @@ -/* src/psp/psp-video-rotate.c: Rotated background graphics handling for - PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidshared.h" - -#include "config.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/** - * USE_FIXED_POINT: If defined, floating-point operations will be replaced - * by signed 16.16 fixed-point operations. This may slightly change - * behavior due to the differing precision of computations. - * - * This currently (2010/3/9) gives an improvement of 5-10% with multiple - * coefficients per row or 3-5% with one coefficient per row. - */ -#define USE_FIXED_POINT - -/*************************************************************************/ - -/**** Floating-point / fixed-point operations ****/ - -#ifdef USE_FIXED_POINT - -# define FIXEDFLOAT int32_t -# define UFIXEDFLOAT uint32_t -# define FIXED_MULT(a,b) ((int32_t)(((int64_t)(a) * (int64_t)(b)) >> 16)) -# define FIXED_TOINT(n) ((n) >> 16) -# define FIXED_TOFLOAT(n) ((n) / 65536.0f) - -#else // !USE_FIXED_POINT - -# define FIXEDFLOAT float -# define UFIXEDFLOAT float -# define FIXED_MULT(a,b) ((a) * (b)) -# define FIXED_TOINT(n) ifloorf((n)) -# define FIXED_TOFLOAT(n) ((n)) - -#endif // USE_FIXED_POINT - -/**** Coordinate transformation parameter structure ****/ - -typedef struct RotationParams_ RotationParams; -struct RotationParams_ { - /* Transformation parameters read from VDP2 RAM (arranged for easy - * VFPU loading, in case that ever becomes useful) */ - __attribute__((aligned(16))) FIXEDFLOAT Xst; - FIXEDFLOAT Yst, Zst, pad0w; - FIXEDFLOAT deltaXst, deltaYst, pad1z, pad1w; - FIXEDFLOAT deltaX, deltaY, pad2z, pad2w; - FIXEDFLOAT A, B, C, pad3w; - FIXEDFLOAT D, E, F, pad4w; - FIXEDFLOAT Px, Py, Pz, pad5w; - FIXEDFLOAT Cx, Cy, Cz, pad6w; - FIXEDFLOAT Mx, My, pad7z, pad7w; - FIXEDFLOAT kx, ky, pad8z, pad8w; //May be updated in coefficient table mode - - /* Computed transformation parameters */ - FIXEDFLOAT Xp, Yp, pad9z, pad9w; //May be updated in coefficient table mode - FIXEDFLOAT mat11, mat12, mat13, mat1_pad; - FIXEDFLOAT mat21, mat22, mat23, mat2_pad; - - /* Coefficient table parameters read from VDP2 RAM */ - UFIXEDFLOAT KAst; - FIXEDFLOAT deltaKAst; - FIXEDFLOAT deltaKAx; - - /* Coefficient table base address and flags */ - uint32_t coeftbladdr; - uint8_t coefenab; - uint8_t coefmode; - uint8_t coefdatasize; // Size of a single coefficient in bytes (2 or 4) - uint8_t coefdatashift; // log2(coefdatasize) - - /* Miscellaneous parameters */ - uint8_t screenover; // FIXME: What is this for? -}; - -/*************************************************************************/ - -/**** Macros for pixel address calculation and pixel getting ****/ - -/** - * INIT_CALC_PIXELNUM: Precompute values used by the CALC_PIXELNUM macro. - */ -#define INIT_CALC_PIXELNUM \ - const int srcx_mask = info->isbitmap \ - ? info->cellw - 1 \ - : (8 * 64 * info->planew * 4) - 1; \ - const int srcy_mask = info->isbitmap \ - ? info->cellh - 1 \ - : (8 * 64 * info->planeh * 4) - 1; \ - const int page_shift = 3 + 6; \ - const int page_mask = (1 << page_shift) - 1; \ - const int tile_shift = (info->patternwh==2) ? 4 : 3; \ - /* Remember the last tile seen, to save the time of looking it up \ - * while we're on nearby pixels */ \ - int last_tilex = -1, last_tiley = -1 - -/*----------------------------------*/ - -/** - * INIT_PAGEMAP: Initialize a page map array for the given parameter - * set (either 0 or 1). pagemap should be declared as: - * uint32_t pagemap[8][8]; - */ -#define INIT_PAGEMAP(pagemap,set) do { \ - int plane_aoffset = ((Vdp2Regs->MPOFR >> ((set) * 4)) & 7) << 6; \ - const uint8_t *plane_map = set ? (const uint8_t *)&Vdp2Regs->MPABRB \ - : (const uint8_t *)&Vdp2Regs->MPABRA;\ - const int plane_bits = info->planew_bits + info->planeh_bits; \ - const int plane_ashift = 11 + (info->patternwh==1 ? 2 : 0) \ - + (info->patterndatasize==2 ? 1 : 0); \ - const int plane_amask = (0xFF >> (plane_ashift - 11)) \ - ^ ((1 << plane_bits) - 1); \ - unsigned int planenum = 0; \ - unsigned int plane_y; \ - for (plane_y = 0; plane_y < 4; plane_y++) { \ - unsigned int plane_x; \ - for (plane_x = 0; plane_x < 4; plane_x++, planenum++) { \ - uint32_t address = \ - ((plane_aoffset | plane_map[planenum]) & plane_amask) \ - << plane_ashift; \ - unsigned int pagenum = 0; \ - unsigned int page_y; \ - for (page_y = 0; page_y < info->planeh; page_y++) { \ - unsigned int page_x; \ - for (page_x = 0; page_x < info->planew; page_x++, pagenum++) {\ - const int tilenum = \ - pagenum << (2*(page_shift-tile_shift)); \ - pagemap[plane_y*info->planeh + page_y] \ - [plane_x*info->planew + page_x] = \ - address + (tilenum << (info->patterndatasize_bits+1));\ - } \ - } \ - } \ - } \ -} while (0) - -/*----------------------------------*/ - -/** - * CALC_TILEADDR_8x8, CALC_TILEADDR_16x16: Calculate the tile data address - * associated with the tile coordinate (tilex,tiley) for 8x8 or 16x16 tiles. - * Helper macros for CALC_PIXELNUM. - */ -#define CALC_TILEADDR_8x8(tilex,tiley,pagemap) do { \ - const int page_x = srcx >> page_shift; \ - const int page_y = srcy >> page_shift; \ - info->addr = pagemap[page_y][page_x]; \ - const int tile_x = (srcx & page_mask) >> 3; \ - const int tile_y = (srcy & page_mask) >> 3; \ - const int tilenum = tile_y << (page_shift - 3) | tile_x; \ - info->addr += tilenum << (info->patterndatasize_bits + 1); \ -} while (0) - -#define CALC_TILEADDR_16x16(tilex,tiley,pagemap) do { \ - const int page_x = srcx >> page_shift; \ - const int page_y = srcy >> page_shift; \ - info->addr = pagemap[page_y][page_x]; \ - const int tile_x = (srcx & page_mask) >> 4; \ - const int tile_y = (srcy & page_mask) >> 4; \ - const int tilenum = tile_y << (page_shift - 4) | tile_x; \ - info->addr += tilenum << (info->patterndatasize_bits + 1); \ -} while (0) - -/*----------------------------------*/ - -/** - * CALC_PIXELNUM: Calculate the pixel index associated with the - * transformed coordinates (srcx,srcy), store it in the variable - * "pixelnum", and update the "info" structure's fields as necessary for - * the associated tile (if the graphics layer is in tilemap mode). - * - * This is implemented as a macro so it can make use of precomputed - * constant values within the calling routine. - * - * Optimization note: The use of nearly identical code in the - * if(tile_shift==4) and else branches may look awkward, but it allows the - * compiler to use known values rather than having to repeatedly check and - * branch on the tile size, giving a speed increase of 3-5%. Greater - * optimization could be achieved by pulling such tests further out of the - * critical path, at the cost of code size explosion; one alternative - * would be dynamic compilation/assembly of rotation code based on the - * graphics layer's parameters. - */ -#define CALC_PIXELNUM(pagemap) do { \ - srcx &= srcx_mask; \ - srcy &= srcy_mask; \ - if (info->isbitmap) { \ - pixelnum = srcy << info->cellw_bits | srcx; \ - } else if (tile_shift == 4) { \ - const int tilex = srcx >> 4; \ - const int tiley = srcy >> 4; \ - if (tilex != last_tilex || tiley != last_tiley) { \ - last_tilex = tilex; \ - last_tiley = tiley; \ - CALC_TILEADDR_16x16(tilex, tiley, pagemap); \ - vdp2_calc_pattern_address_16x16(info); \ - } \ - srcx &= 15; \ - srcy &= 15; \ - if (info->flipfunction & 1) { \ - srcx ^= 15; \ - } \ - if (info->flipfunction & 2) { \ - srcy ^= 15; \ - } \ - pixelnum = (srcy & 8) << (7-3) \ - | (srcx & 8) << (6-3) \ - | (srcy & 7) << 3 \ - | (srcx & 7); \ - } else { /* tile_shift == 3 */ \ - const int tilex = srcx >> 3; \ - const int tiley = srcy >> 3; \ - if (tilex != last_tilex || tiley != last_tiley) { \ - last_tilex = tilex; \ - last_tiley = tiley; \ - CALC_TILEADDR_8x8(tilex, tiley, pagemap); \ - vdp2_calc_pattern_address_8x8(info); \ - } \ - srcx &= 7; \ - srcy &= 7; \ - if (info->flipfunction & 1) { \ - srcx ^= 7; \ - } \ - if (info->flipfunction & 2) { \ - srcy ^= 7; \ - } \ - pixelnum = srcy << 3 | srcx; \ - } \ -} while (0) - -/*-----------------------------------------------------------------------*/ - -/** - * SELECT_GET_PIXEL: Declares "get_pixel" as a function pointer to an - * appropriate pixel-getting function based on the graphics layer's - * parameters. - */ - -#define SELECT_GET_PIXEL \ - const int need_adjust = \ - (info->alpha != 0xFF) || info->cor || info->cog || info->cob; \ - uint32_t (*get_pixel)(vdp2draw_struct *, unsigned int); \ - switch (info->colornumber) { \ - case 0: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_t4_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_t4_transparent \ - : rotation_get_pixel_t4; \ - break; \ - case 1: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_t8_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_t8_transparent \ - : rotation_get_pixel_t8; \ - break; \ - case 2: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_t16_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_t16_transparent \ - : rotation_get_pixel_t16; \ - break; \ - case 3: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_16_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_16_transparent \ - : rotation_get_pixel_16; \ - break; \ - case 4: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_32_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_32_transparent \ - : rotation_get_pixel_32; \ - break; \ - default: \ - DMSG("Invalid pixel format %d", info->colornumber); \ - return; \ - } - -/*************************************************************************/ - -/**** Local function declarations ****/ - -static void render_mode0(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2], int which); -static void render_mode0_region(uint32_t *pixelbuf, vdp2draw_struct *info, - RotationParams param_set[2], int which, - unsigned int x0, unsigned int y0, - unsigned int xlim, unsigned int ylim); - -static void render_mode1(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]); -static int mode1_is_split_screen(const RotationParams param_set[2], - int *top_set_ret, int *switch_y_ret); - -static void render_mode2(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]); - -static void get_rotation_parameters(vdp2draw_struct *info, int which, - RotationParams *param_ret); - -__attribute__((unused)) -static int get_rotation_coefficient(RotationParams *param, uint32_t address); -static int get_rotation_coefficient_size2_mode0(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size2_mode1(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size2_mode2(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size2_mode3(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode0(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode1(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode2(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode3(RotationParams *param, - const void *address); - -static void transform_coordinates(const RotationParams *param, int x, int y, - FIXEDFLOAT *srcx_ret, FIXEDFLOAT *srcy_ret); - -static uint32_t rotation_get_pixel_t4(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t8(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t16(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_16(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_32(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t4_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t8_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t16_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_16_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_32_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t4_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t8_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t16_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_16_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_32_adjust(vdp2draw_struct *info, - unsigned int pixelnum); - -/*-----------------------------------------------------------------------*/ - -/* Table of coefficient-reading functions, indexed by - * [param.coefdatasize==4][param.coefmode] */ - -static int (*get_coef_table[2][4])(RotationParams *, const void *) = { - {get_rotation_coefficient_size2_mode0, - get_rotation_coefficient_size2_mode1, - get_rotation_coefficient_size2_mode2, - get_rotation_coefficient_size2_mode3}, - {get_rotation_coefficient_size4_mode0, - get_rotation_coefficient_size4_mode1, - get_rotation_coefficient_size4_mode2, - get_rotation_coefficient_size4_mode3} -}; - -/*************************************************************************/ -/************************** Interface function ***************************/ -/*************************************************************************/ - -/** - * vdp2_draw_map_rotated: Draw a rotated graphics layer. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_rotated(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Parse rotation parameters. */ - - static __attribute__((aligned(16))) RotationParams param_set[2]; - get_rotation_parameters(info, 0, ¶m_set[0]); - get_rotation_parameters(info, 1, ¶m_set[1]); - - /* Allocate a buffer for drawing the texture. Note that we swizzle - * the texture for faster drawing, since it's allocated in system - * RAM (which the GE is slow at accessing). */ - - uint32_t *pixelbuf = guGetMemory(disp_width * disp_height * 4 + 60); - pixelbuf = (uint32_t *)(((uintptr_t)pixelbuf + 63) & -64); - - /* Render all pixels. */ - - switch (info->rotatemode) { - case 0: - render_mode0(pixelbuf, info, clip, param_set, info->rotatenum); - break; - case 1: - render_mode1(pixelbuf, info, clip, param_set); - break; - case 2: - render_mode2(pixelbuf, info, clip, param_set); - break; - } - - /* Set up vertices for optimized GE drawing. */ - - const unsigned int nverts = (disp_width / 16) * 2; - VertexUVXYZ *vertices = guGetMemory(sizeof(*vertices) * nverts); - VertexUVXYZ *vptr; - unsigned int x; - for (x = 0, vptr = vertices; x < disp_width; x += 16, vptr += 2) { - vptr[0].u = x; - vptr[0].v = 0; - vptr[0].x = x >> disp_xscale; - vptr[0].y = 0; - vptr[0].z = 0; - vptr[1].u = x + 16; - vptr[1].v = disp_height; - vptr[1].x = (x + 16) >> disp_xscale; - vptr[1].y = disp_height >> disp_yscale; - vptr[1].z = 0; - } - - /* Send the texture to the GE. */ - - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 1 /*swizzled*/); - if (disp_width <= 512) { - guTexImage(0, 512, 512, disp_width, pixelbuf); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - } else { - guTexImage(0, 512, 512, disp_width, pixelbuf); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts/2, NULL, vertices); - for (x = disp_width/2, vptr = vertices + nverts/2; x < disp_width; - x += 16, vptr += 2 - ) { - vptr[0].u = x - disp_width/2; - vptr[1].u = (x + 16) - disp_width/2; - } - guTexImage(0, 512, 512, disp_width, pixelbuf + (disp_width/2) * 8); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts/2, NULL, vertices + nverts/2); - } - guCommit(); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * render_mode0: Render a rotated/distorted graphics layer in mode 0 - * (fixed parameter set). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * clip: Clipping window data - * param_set: Array of rotation parameter sets - * which: Which parameter set to use (0 or 1) - * [Return value] - * None - */ -static void render_mode0(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2], int which) -{ - /* - * If the parameter set uses a fixed transformation matrix that doesn't - * actually perform any rotation, we can just call the regular map - * drawing functions with appropriately scaled parameters: - * - * [srcX] ( [screenX]) [kx] [Xp] - * [srcY] = (M [screenY]) * [ky] + [Yp] - * ( [ 1 ]) - * - * [srcX] ([mat11 0 mat13] [screenX]) [kx] [Xp] - * [srcY] = ([ 0 mat22 mat23] [screenY]) * [ky] + [Yp] - * ( [ 1 ]) - * - * srcX = (mat11*screenX + mat13) * kx + Xp - * srcY = (mat22*screenY + mat23) * ky + Yp - * - * srcX = (mat11*kx)*screenX + (mat13*kx + Xp) - * srcY = (mat22*ky)*screenY + (mat23*ky + Yp) - * - * (srcX - (mat13*kx + Xp)) / (mat11*kx) = screenX - * (srcY - (mat23*ky + Yp)) / (mat22*ky) = screenX - * - * screenX = (1/(mat11*kx))*srcX - ((mat13*kx + Xp) / (mat11*kx)) - * screenY = (1/(mat22*ky))*srcX - ((mat23*ky + Yp) / (mat22*ky)) - */ - - RotationParams *param = ¶m_set[which]; - if (!param->coefenab && param->mat12 == 0.0f && param->mat21 == 0.0f) { - const float xmul = - 1 / FIXED_TOFLOAT(FIXED_MULT(param->mat11, param->kx)); - const float ymul = - 1 / FIXED_TOFLOAT(FIXED_MULT(param->mat22, param->ky)); - info->coordincx = xmul; - info->coordincy = ymul; - info->x = -FIXED_TOFLOAT(FIXED_MULT(param->mat13, param->kx) + param->Xp) * xmul; - info->y = -FIXED_TOFLOAT(FIXED_MULT(param->mat23, param->ky) + param->Yp) * ymul; - void (*draw_func)(vdp2draw_struct *info, const clipping_struct *clip); - if (info->isbitmap) { - draw_func = &vdp2_draw_bitmap; - } else if (info->patternwh == 2) { - draw_func = &vdp2_draw_map_16x16; - } else { - draw_func = &vdp2_draw_map_8x8; - } - return (*draw_func)(info, clip); - } - - /* - * There's rotation and/or distortion going on, so we'll have to render - * the image manually. (Sadly, the PSP doesn't have shaders, so we - * can't translate the coefficients into a texture coordinate map and - * render that way.) - */ - - render_mode0_region(pixelbuf, info, param_set, which, - 0, 0, disp_width, disp_height); -} - -/*----------------------------------*/ - -/** - * render_mode0_region: Render the given portion of a rotated/distorted - * graphics layer in mode 0 (fixed parameter set). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * param_set: Array of rotation parameter sets - * which: Which parameter set to use (0 or 1) - * x0, y0: Top-left coordinates of region to render - * xlim, ylim: Bottom-right coordinates of region to render plus one - * [Return value] - * None - */ -static void render_mode0_region(uint32_t *pixelbuf, vdp2draw_struct *info, - RotationParams param_set[2], int which, - unsigned int x0, unsigned int y0, - unsigned int xlim, unsigned int ylim) -{ - RotationParams *param = ¶m_set[which]; - - /* Precalculate tilemap/bitmap coordinate masks, shift counts, and - * tile page addresses. */ - - INIT_CALC_PIXELNUM; - uint32_t pagemap[8][8]; - if (!info->isbitmap) { - INIT_PAGEMAP(pagemap, which); - } - - /* Choose appropriate coefficient-read and pixel-read functions. */ - - int (*get_coef)(RotationParams *, const void *) = - get_coef_table[param->coefdatasize==4][param->coefmode]; - SELECT_GET_PIXEL; - - /* Actually render the graphics layer. */ - - /* These two variables are intentionally float rather than FIXEDFLOAT - * because coef_y can exceed the range of a fixed-point value. */ - float coef_dy = FIXED_TOFLOAT(param->deltaKAst); - float coef_y = y0 * coef_dy; - unsigned int y; - - for (y = y0; y < ylim; y++, coef_y += coef_dy) { - - const uint32_t coef_base = param->coeftbladdr - + (ifloorf(coef_y) << param->coefdatashift); - const uint8_t *coef_baseptr = Vdp2Ram + (coef_base & 0x7FFFF); - uint32_t * const dest_base = pixelbuf + (y/8)*(disp_width*8) + (y%8)*4; - - if (!param->coefenab) { - - /* Constant parameters for the whole screen (FIXME: we could - * draw this in hardware if we had code to rotate vertices) */ - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x0, y, &srcx_f, &srcy_f); - const FIXEDFLOAT delta_srcx = FIXED_MULT(param->mat11, param->kx); - const FIXEDFLOAT delta_srcy = FIXED_MULT(param->mat21, param->ky); - unsigned int x; - for (x = x0; x < xlim; - x++, srcx_f += delta_srcx, srcy_f += delta_srcy - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap); - *dest = (*get_pixel)(info, pixelnum); - } - - } else if (param->deltaKAx == 0) { - - /* One coefficient for the whole row */ - if (!(*get_coef)(param, coef_baseptr)) { - /* Empty row */ - uint32_t *dest = dest_base + (x0/4)*32; - unsigned int x = x0; - if (UNLIKELY(x & 3)) { - for (; x & 3; x++) { - dest[x & 3] = 0; - } - dest += 32; - } - for (; x < (xlim & ~3); x += 4, dest += 32) { - dest[0] = dest[1] = dest[2] = dest[3] = 0; - } - for (; x < xlim; x++) { - dest[x & 3] = 0; - } - continue; - } - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x0, y, &srcx_f, &srcy_f); - const FIXEDFLOAT delta_srcx = FIXED_MULT(param->mat11, param->kx); - const FIXEDFLOAT delta_srcy = FIXED_MULT(param->mat21, param->ky); - unsigned int x; - for (x = x0; x < xlim; - x++, srcx_f += delta_srcx, srcy_f += delta_srcy - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap); - *dest = (*get_pixel)(info, pixelnum); - } - - } else { // param->coefenab && param->deltaKAx != 0 - - /* Multiple coefficients per row */ - const FIXEDFLOAT coef_dx = param->deltaKAx; - FIXEDFLOAT coef_x = 0; - int last_coef_x = -1; - int empty_pixel = 0; - unsigned int x; - for (x = x0; x < xlim; x++, coef_x += coef_dx) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - if (FIXED_TOINT(coef_x) != last_coef_x) { - last_coef_x = FIXED_TOINT(coef_x); - const uint8_t *coef_ptr = - coef_baseptr + (last_coef_x << param->coefdatashift); - empty_pixel = !(*get_coef)(param, coef_ptr); - } - if (empty_pixel) { - *dest = 0; - } else { - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x, y, &srcx_f, &srcy_f); - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap); - *dest = (*get_pixel)(info, pixelnum); - } - } - - } // if (!param->coefenab) - - } // for (y = y0; y < ylim; y++, coef_y += coef_dy) -} - -/*-----------------------------------------------------------------------*/ - -/** - * render_mode1: Render a rotated/distorted graphics layer in mode 1 - * (parameter set selected by top bit of coefficient). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * clip: Clipping window data - * param_set: Array of rotation parameter sets - * [Return value] - * None - */ -static void render_mode1(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]) -{ - /* Set up a second vdp2draw_struct for the second parameter set. */ - - vdp2draw_struct *info0 = info; - vdp2draw_struct info1_buf = *info; - vdp2draw_struct *info1 = &info1_buf; - info1->charaddr = ((Vdp2Regs->MPOFR >> 4) & 7) << 17; - info1->planew_bits = (Vdp2Regs->PLSZ >> 12) & 1; - info1->planeh_bits = (Vdp2Regs->PLSZ >> 13) & 1; - info1->planew = 1 << info->planew_bits; - info1->planeh = 1 << info->planeh_bits; - if (info1->planew != info0->planew || info1->planeh != info0->planeh) { - DMSG("WARNING: mixed plane sizes not supported for RPMD=2" - " (set A: %dx%d, set B: %dx%d)", info0->planew, info0->planeh, - info1->planew, info1->planeh); - } - - /* If set A has one coefficient per row, it might simply be splitting - * the screen into two differently-rendered regions (such as sky and - * ground). We can potentially draw that more efficiently as mode 0. */ - - int top_set, switch_y; - if (mode1_is_split_screen(param_set, &top_set, &switch_y)) { - if (switch_y < 0) { - return render_mode0(pixelbuf, info, clip, param_set, top_set); - } else { - render_mode0_region(pixelbuf, top_set==0 ? info0 : info1, - param_set, top_set, - 0, 0, disp_width, switch_y); - return render_mode0_region(pixelbuf, top_set==0 ? info1 : info0, - param_set, top_set ^ 1, - 0, switch_y, disp_width, disp_height); - } - } - - /* Precalculate tilemap/bitmap coordinate masks, shift counts, and - * tile page addresses. */ - - INIT_CALC_PIXELNUM; - uint32_t pagemap[2][8][8]; - if (!info->isbitmap) { - INIT_PAGEMAP(pagemap[0], 0); - INIT_PAGEMAP(pagemap[1], 1); - } - - /* Choose appropriate coefficient-read and pixel-read functions. */ - - int (*get_coef0)(RotationParams *, const void *) = - get_coef_table[param_set[0].coefdatasize==4][param_set[0].coefmode]; - int (*get_coef1)(RotationParams *, const void *) = - get_coef_table[param_set[1].coefdatasize==4][param_set[1].coefmode]; - SELECT_GET_PIXEL; - - /* Actually render the graphics layer. */ - - /* These are intentionally float rather than FIXEDFLOAT, as in - * render_mode0_region(). */ - float coef0_dy = FIXED_TOFLOAT(param_set[0].deltaKAst); - float coef0_y = 0; - float coef1_dy = FIXED_TOFLOAT(param_set[1].deltaKAst); - float coef1_y = 0; - unsigned int y; - - for (y = 0; y < disp_height; - y++, coef0_y += coef0_dy, coef1_y += coef1_dy - ) { - - const uint32_t coef0_base = param_set[0].coeftbladdr - + (ifloorf(coef0_y) << param_set[0].coefdatashift); - const uint8_t *coef0_baseptr = Vdp2Ram + (coef0_base & 0x7FFFF); - const uint32_t coef1_base = param_set[1].coeftbladdr - + (ifloorf(coef1_y) << param_set[1].coefdatashift); - const uint8_t *coef1_baseptr = Vdp2Ram + (coef1_base & 0x7FFFF); - uint32_t * const dest_base = pixelbuf + (y/8)*(disp_width*8) + (y%8)*4; - - if (param_set[0].deltaKAx == 0 - && (!param_set[1].coefenab || param_set[1].deltaKAx == 0) - ) { - - /* One coefficient for the whole row in both sets */ - int which; - if ((*get_coef0)(¶m_set[0], coef0_baseptr)) { - which = 0; - info = info0; - } else if (!param_set[1].coefenab - || (*get_coef1)(¶m_set[1], coef1_baseptr)) { - which = 1; - info = info1; - } else { - /* Empty row */ - uint32_t *dest = dest_base; - unsigned int x; - for (x = 0; x < disp_width; x += 4, dest += 32) { - dest[0] = dest[1] = dest[2] = dest[3] = 0; - } - continue; - } - RotationParams *param = ¶m_set[which]; - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, 0, y, &srcx_f, &srcy_f); - const FIXEDFLOAT delta_srcx = FIXED_MULT(param->mat11, param->kx); - const FIXEDFLOAT delta_srcy = FIXED_MULT(param->mat21, param->ky); - unsigned int x; - for (x = 0; x < disp_width; - x++, srcx_f += delta_srcx, srcy_f += delta_srcy - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap[which]); - *dest = (*get_pixel)(info, pixelnum); - } - - } else { - - /* Multiple coefficients per row in one or both sets */ - const FIXEDFLOAT coef0_dx = param_set[0].deltaKAx; - FIXEDFLOAT coef0_x = 0; - const FIXEDFLOAT coef1_dx = param_set[1].deltaKAx; - FIXEDFLOAT coef1_x = 0; - int last_coef0_x = -1; - int last_coef1_x = (param_set[1].coefenab ? -1 : 0); - int have_coef0 = 1; - int have_coef1 = 1; - unsigned int x; - for (x = 0; x < disp_width; - x++, coef0_x += coef0_dx, coef1_x += coef1_dx - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - if (FIXED_TOINT(coef0_x) != last_coef0_x) { - last_coef0_x = FIXED_TOINT(coef0_x); - const uint8_t *coef0_ptr = coef0_baseptr - + (last_coef0_x << param_set[0].coefdatashift); - have_coef0 = (*get_coef0)(¶m_set[0], coef0_ptr); - } - if (FIXED_TOINT(coef1_x) != last_coef1_x) { - last_coef1_x = FIXED_TOINT(coef1_x); - const uint8_t *coef1_ptr = coef1_baseptr - + (last_coef1_x << param_set[1].coefdatashift); - have_coef1 = (*get_coef1)(¶m_set[1], coef1_ptr); - } - int which; - if (have_coef0) { - which = 0; - info = info0; - } else if (have_coef1) { - which = 1; - info = info1; - } else { // Empty pixel - *dest = 0; - continue; - } - RotationParams *param = ¶m_set[which]; - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x, y, &srcx_f, &srcy_f); - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap[which]); - *dest = (*get_pixel)(info, pixelnum); - } - - } - - } // for (y = 0; y < disp_height; y++, coef_y += coef_dy) -} - -/*----------------------------------*/ - -/** - * mode1_is_split_screen: Return whether the parameters and coefficients - * for a mode 1 rotated/distorted graphics layer have the effect of - * splitting the screen into a top and bottom region, each with one of the - * two parameter sets. Parameters which specify a single parameter set for - * the entire screen are considered to be a split screen with an empty - * bottom portion for the purposes of this function. - * - * If this function returns true, *top_set_ret will be set to the index of - * the parameter set used for the top line of the screen, and *switch_y_ret - * will be set to the first line at which the other parameter set is used. - * If the entire screen uses a single parameter set (effectively mode 0), - * *switch_y_ret will be set to -1. - * - * [Parameters] - * param_set: Array of rotation parameter sets - * top_set_ret: Pointer to variable to receive the index of the - * parameter set used on screen line 0 - * switch_y_ret: Pointer to variable to receive the first line at which - * the alternate parameter set is used - * [Return value] - * True (nonzero) if the rotation parameters have the effect of - * splitting the screen, else false (zero) - */ -static int mode1_is_split_screen(const RotationParams param_set[2], - int *top_set_ret, int *switch_y_ret) -{ - /* If parameter set A doesn't have coefficients enabled, set B can - * never be selected, so this is just the same as mode 0 with set A. */ - - if (!param_set[0].coefenab) { - *top_set_ret = 0; - *switch_y_ret = -1; - return 1; - } - - /* If there is more than one coefficient per line, assume that the - * rotation operation is more complex than a simple split-screen effect. */ - - if (param_set[0].deltaKAx != 0) { - return 0; - } - - /* Scan over the set A coefficients (now known to be one per line) and - * see how many times the selected set changes. */ - - int cur_set = -1; - *top_set_ret = -1; - *switch_y_ret = -1; - - /* These are intentionally float rather than FIXEDFLOAT, as in - * render_mode0_region(). */ - float coef0_dy = FIXED_TOFLOAT(param_set[0].deltaKAst); - float coef0_y = 0; - int y; - - for (y = 0; y < disp_height; y++, coef0_y += coef0_dy) { - - const uint32_t coef0_addr = param_set[0].coeftbladdr - + (ifloorf(coef0_y) << param_set[0].coefdatashift); - const uint8_t * const coef0_ptr = Vdp2Ram + (coef0_addr & 0x7FFFF); - /* VDP memory is organized by bytes, so coef0_ptr is now pointing - * to the top byte of the coefficient value regardless of the data - * size setting. */ - const int set = (*(int8_t *)coef0_ptr < 0) ? 1 : 0; - - if (y == 0) { - *top_set_ret = cur_set = set; - } else if (set != cur_set) { - if (*switch_y_ret < 0) { - *switch_y_ret = y; - } else { - /* This is the second change we've seen, so it's not a - * split-screen effect. */ -printf("set change 2 at %d\n",y); - return 0; - } - cur_set = set; - } - - } - - /* If we got this far, it must be a split-screen effect. */ - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * render_mode2: Render a rotated/distorted graphics layer in mode 2 - * (parameter set selected by clipping window). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * clip: Clipping window data - * param_set: Array of rotation parameter sets - * [Return value] - * None - */ -static void render_mode2(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]) -{ - /* - * FIXME: This logic gets the Panzer Dragoon Saga name entry screen's - * background to display properly, but since PDS is the only example - * of this mode to which I have access, I have no clue whether this is - * the Right Thing To Do. I'm using the height of the clip window (set - * as <0,0>-<352,224> by the game) based on vidsoft.c comments, but it - * could also be just a top-half/bottom-half-of-screen thing. - */ - - render_mode0_region(pixelbuf, info, param_set, 0, - 0, 0, disp_width, clip[0].yend / 2); - - info->charaddr = ((Vdp2Regs->MPOFR >> 4) & 7) << 17; - info->planew_bits = (Vdp2Regs->PLSZ >> 12) & 1; - info->planeh_bits = (Vdp2Regs->PLSZ >> 13) & 1; - info->planew = 1 << info->planew_bits; - info->planeh = 1 << info->planeh_bits; - render_mode0_region(pixelbuf, info, param_set, 1, - 0, clip[0].yend / 2, disp_width, disp_height); -} - -/*************************************************************************/ - -/** - * get_rotation_parameters: Retrieve the rotation parameters for a rotated - * graphics layer and perform necessary precalculations. - * - * [Parameters] - * info: Graphics layer data - * which: Which parameter set to retrieve (0 or 1) - * param_ret: Pointer to structure to receive parsed parameters - * [Return value] - * None - */ -static void get_rotation_parameters(vdp2draw_struct *info, int which, - RotationParams *param_ret) -{ - uint32_t addr = (Vdp2Regs->RPTA.all << 1) & 0x7FF7C; - unsigned int KTCTL, KTAOF; - if (which == 0) { - KTCTL = Vdp2Regs->KTCTL & 0xFF; - KTAOF = Vdp2Regs->KTAOF & 0xFF; - param_ret->screenover = (Vdp2Regs->PLSZ >> 10) & 3; - } else { - addr |= 0x80; - KTCTL = (Vdp2Regs->KTCTL >> 8) & 0xFF; - KTAOF = (Vdp2Regs->KTAOF >> 8) & 0xFF; - param_ret->screenover = (Vdp2Regs->PLSZ >> 14) & 3; - } - param_ret->coefenab = KTCTL & 1; - param_ret->coefdatashift = (KTCTL & 2) ? 1 : 2; - param_ret->coefdatasize = 1 << param_ret->coefdatashift; - param_ret->coefmode = (KTCTL >> 2) & 3; - param_ret->coeftbladdr = ((KTAOF & 7) << param_ret->coefdatashift) << 16; - -#ifdef USE_FIXED_POINT - #define GET_SHORT(nbits) \ - (addr += 2, (int32_t)((int16_t)T1ReadWord(Vdp2Ram,addr-2) \ - << (16-nbits)) << nbits) - #define GET_SIGNED_FLOAT(nbits) \ - (addr += 4, ((((int32_t)T1ReadLong(Vdp2Ram,addr-4) \ - << (32-nbits)) >> (32-nbits)) & ~0x3F)) - #define GET_UNSIGNED_FLOAT(nbits) \ - (addr += 4, (((uint32_t)T1ReadLong(Vdp2Ram,addr-4) \ - & (0xFFFFFFFFU >> (32-nbits))) & ~0x3F)) -#else // !USE_FIXED_POINT - #define GET_SHORT(nbits) \ - (addr += 2, ((int16_t)T1ReadWord(Vdp2Ram,addr-2) \ - << (16-nbits)) >> (16-nbits)) - #define GET_SIGNED_FLOAT(nbits) \ - (addr += 4, ((((int32_t)T1ReadLong(Vdp2Ram,addr-4) \ - << (32-nbits)) >> (32-nbits)) & ~0x3F) / 65536.0f) - #define GET_UNSIGNED_FLOAT(nbits) \ - (addr += 4, (((uint32_t)T1ReadLong(Vdp2Ram,addr-4) \ - & (0xFFFFFFFFU >> (32-nbits))) & ~0x3F) / 65536.0f) -#endif // !USE_FIXED_POINT - - param_ret->Xst = GET_SIGNED_FLOAT(29); - param_ret->Yst = GET_SIGNED_FLOAT(29); - param_ret->Zst = GET_SIGNED_FLOAT(29); - param_ret->deltaXst = GET_SIGNED_FLOAT(19); - param_ret->deltaYst = GET_SIGNED_FLOAT(19); - param_ret->deltaX = GET_SIGNED_FLOAT(19); - param_ret->deltaY = GET_SIGNED_FLOAT(19); - param_ret->A = GET_SIGNED_FLOAT(20); - param_ret->B = GET_SIGNED_FLOAT(20); - param_ret->C = GET_SIGNED_FLOAT(20); - param_ret->D = GET_SIGNED_FLOAT(20); - param_ret->E = GET_SIGNED_FLOAT(20); - param_ret->F = GET_SIGNED_FLOAT(20); - param_ret->Px = GET_SHORT(14); - param_ret->Py = GET_SHORT(14); - param_ret->Pz = GET_SHORT(14); - addr += 2; - param_ret->Cx = GET_SHORT(14); - param_ret->Cy = GET_SHORT(14); - param_ret->Cz = GET_SHORT(14); - addr += 2; - param_ret->Mx = GET_SIGNED_FLOAT(30); - param_ret->My = GET_SIGNED_FLOAT(30); - param_ret->kx = GET_SIGNED_FLOAT(24); - param_ret->ky = GET_SIGNED_FLOAT(24); - if (param_ret->coefenab) { - param_ret->KAst = GET_UNSIGNED_FLOAT(32); - param_ret->deltaKAst = GET_SIGNED_FLOAT(26); - param_ret->deltaKAx = GET_SIGNED_FLOAT(26); - param_ret->coeftbladdr += - FIXED_TOINT(param_ret->KAst) * param_ret->coefdatasize; - } else { - param_ret->KAst = 0; - param_ret->deltaKAst = 0; - param_ret->deltaKAx = 0; - } - - #undef GET_SHORT - #undef GET_SIGNED_FLOAT - #undef GET_UNSIGNED_FLOAT - - /* - * The coordinate transformation performed for rotated graphics layers - * works out to the following: - * - * [srcX] ( [screenX]) [kx] [Xp] - * [srcY] = (M [screenY]) * [ky] + [Yp] - * ( [ 1 ]) - * - * where the "*" operator is multiplication by components (not matrix - * multiplication), M is the 2x3 constant matrix product: - * - * [A B C] [deltaX deltaXst (Xst - Px)] - * M = [D E F] [deltaY deltaYst (Yst - Py)] - * [ 0 0 (Zst - Pz)] - * - * and is a constant vector computed as: - * - * [Xp] ([A B C] [Px - Cx]) [Cx] [Mx] - * [Yp] = ([D E F] [Py - Cy]) + [Cy] + [My] - * ( [Pz - Cz]) - */ - - param_ret->mat11 = FIXED_MULT(param_ret->A, param_ret->deltaX) - + FIXED_MULT(param_ret->B, param_ret->deltaY); - param_ret->mat12 = FIXED_MULT(param_ret->A, param_ret->deltaXst) - + FIXED_MULT(param_ret->B, param_ret->deltaYst); - param_ret->mat13 = FIXED_MULT(param_ret->A, (param_ret->Xst - param_ret->Px)) - + FIXED_MULT(param_ret->B, (param_ret->Yst - param_ret->Py)) - + FIXED_MULT(param_ret->C, (param_ret->Zst - param_ret->Pz)); - param_ret->mat21 = FIXED_MULT(param_ret->D, param_ret->deltaX) - + FIXED_MULT(param_ret->E, param_ret->deltaY); - param_ret->mat22 = FIXED_MULT(param_ret->D, param_ret->deltaXst) - + FIXED_MULT(param_ret->E, param_ret->deltaYst); - param_ret->mat23 = FIXED_MULT(param_ret->D, (param_ret->Xst - param_ret->Px)) - + FIXED_MULT(param_ret->E, (param_ret->Yst - param_ret->Py)) - + FIXED_MULT(param_ret->F, (param_ret->Zst - param_ret->Pz)); - param_ret->Xp = FIXED_MULT(param_ret->A, (param_ret->Px - param_ret->Cx)) - + FIXED_MULT(param_ret->B, (param_ret->Py - param_ret->Cy)) - + FIXED_MULT(param_ret->C, (param_ret->Pz - param_ret->Cz)) - + param_ret->Cx - + param_ret->Mx; - param_ret->Yp = FIXED_MULT(param_ret->D, (param_ret->Px - param_ret->Cx)) - + FIXED_MULT(param_ret->E, (param_ret->Py - param_ret->Cy)) - + FIXED_MULT(param_ret->F, (param_ret->Pz - param_ret->Cz)) - + param_ret->Cy - + param_ret->My; -} - -/*-----------------------------------------------------------------------*/ - -/** - * get_rotation_coefficient: Retrieve a single rotation coefficient for a - * rotated graphics layer and update the rotation parameter set accordingly. - * - * This function is only to demonstrate the behavior of coefficient - * processing, and is not actually called; the per-mode-and-size optimized - * versions below are used instead. - * - * [Parameters] - * param: Rotation parameter set - * address: Address in VDP2 RAM of coefficient - * [Return value] - * Zero if this pixel is blank, else nonzero - */ -__attribute__((unused)) -static int get_rotation_coefficient(RotationParams *param, uint32_t address) -{ - FIXEDFLOAT value; - if (param->coefdatasize == 2) { - const int16_t data = T1ReadWord(Vdp2Ram, address & 0x7FFFE); - if (data < 0) { - return 0; - } -#ifdef USE_FIXED_POINT - value = (int32_t)(data << 1) << 5; -#else - value = (float)((data << 1) >> 1) / 1024.0f; -#endif - } else { - const int32_t data = T1ReadLong(Vdp2Ram, address & 0x7FFFC); - if (data < 0) { - return 0; - } -#ifdef USE_FIXED_POINT - value = (data << 8) >> 8; -#else - value = (float)((data << 8) >> 8) / 65536.0f; -#endif - } - switch (param->coefmode) { - case 0: param->kx = param->ky = value; break; - case 1: param->kx = value; break; - case 2: param->ky = value; break; - case 3: -#ifdef USE_FIXED_POINT - param->Xp = value << 8; -#else - param->Xp = value * 256.0f; -#endif - break; - } - return 1; -} - -/*----------------------------------*/ - -/** - * get_rotation_coefficient_sizeX_modeY: Retrieve a single rotation - * coefficient for a rotated graphics layer and update the rotation - * parameter set accordingly. Each routine is optimized for the specific - * case of param->coefdatasize == X and param->coefmode == Y. - * - * [Parameters] - * param: Rotation parameter set - * address: Native address of coefficient - * [Return value] - * Zero if this pixel is blank, else nonzero - */ - -static int get_rotation_coefficient_size2_mode0(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->kx = param->ky = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 5; -#else - (float)(data << 1) / 2048.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size2_mode1(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->kx = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 5; -#else - (float)(data << 1) / 2048.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size2_mode2(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->ky = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 5; -#else - (float)(data << 1) / 2048.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size2_mode3(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->Xp = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 13; -#else - (float)(data << 1) / 8.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode0(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->kx = param->ky = -#ifdef USE_FIXED_POINT - (data << 8) >> 8; -#else - (float)(data << 8) / 16777216.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode1(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->kx = -#ifdef USE_FIXED_POINT - (data << 8) >> 8; -#else - (float)(data << 8) / 16777216.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode2(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->ky = -#ifdef USE_FIXED_POINT - (data << 8) >> 8; -#else - (float)(data << 8) / 16777216.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode3(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->Xp = -#ifdef USE_FIXED_POINT - data << 8; -#else - (float)(data << 8) / 65536.0f; -#endif - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * transform_coordinates: Transform screen coordinates to source - * coordinates based on the current rotation parameters. - * - * [Parameters] - * param: Rotation parameter set - * x, y: Screen coordinates - * srcx_ret, srcy_ret: Pointers to variables to receive source coordinates - * [Return value] - * None - */ -static void transform_coordinates(const RotationParams *param, int x, int y, - FIXEDFLOAT *srcx_ret, FIXEDFLOAT *srcy_ret) -{ - *srcx_ret = FIXED_MULT(param->mat11*x + param->mat12*y + param->mat13, - param->kx) + param->Xp; - *srcy_ret = FIXED_MULT(param->mat21*x + param->mat22*y + param->mat23, - param->ky) + param->Yp; -} - -/*************************************************************************/ - -/** - * rotation_get_pixel_*: Retrieve a pixel from tiles or bitmaps of various - * pixel formats, with transparency disabled. info->charaddr is assumed to - * contain the offset of the tile or bitmap in VDP2 RAM. - * - * [Parameters] - * info: Graphics layer data - * pixelnum: Index of pixel to retrieve (y*w+x) - * [Return value] - * Pixel value as 0xAABBGGRR - */ - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t4(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum/2; - /* For speed, we assume the tile/bitmap won't wrap around the end of - * VDP2 RAM */ - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t byte = *ptr; - const uint8_t pixel = (pixelnum & 1) ? byte & 0x0F : byte >> 4; - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t8(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum; - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t pixel = *ptr; - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t16(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - const unsigned int colornum = info->coloroffset + pixel; - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_16(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - return 0xFF000000 - | (pixel & 0x7C00) << 9 - | (pixel & 0x03E0) << 6 - | (pixel & 0x001F) << 3; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_32(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*4; - const uint32_t *ptr = (const uint32_t *)(Vdp2Ram + address); - const uint32_t pixel = BSWAP32(*ptr); - return 0xFF000000 | pixel; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rotation_get_pixel_*_transparent: Retrieve a pixel from tiles or - * bitmaps of various pixel formats, with transparency enabled. - * info->charaddr is assumed to contain the offset of the tile or bitmap in - * VDP2 RAM. - * - * [Parameters] - * info: Graphics layer data - * pixelnum: Index of pixel to retrieve (y*w+x) - * [Return value] - * Pixel value as 0xAABBGGRR - */ - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t4_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum/2; - /* For speed, we assume the tile/bitmap won't wrap around the end of - * VDP2 RAM */ - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t byte = *ptr; - const uint8_t pixel = (pixelnum & 1) ? byte & 0x0F : byte >> 4; - if (!pixel) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t8_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum; - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t pixel = *ptr; - if (!pixel) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t16_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!pixel) { - return 0x00000000; - } - const unsigned int colornum = info->coloroffset + pixel; - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_16_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!(pixel & 0x8000)) { - return 0x00000000; - } - return 0xFF000000 - | (pixel & 0x7C00) << 9 - | (pixel & 0x03E0) << 6 - | (pixel & 0x001F) << 3; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_32_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*4; - const uint32_t *ptr = (const uint32_t *)(Vdp2Ram + address); - const uint32_t pixel = BSWAP32(*ptr); - if (!(pixel & 0x80000000)) { - return 0x00000000; - } - return 0xFF000000 | pixel; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rotation_get_pixel_*_adjust: Retrieve a pixel from tiles or bitmaps of - * various pixel formats, and apply alpha and color adjustments. - * info->charaddr is assumed to contain the offset of the tile or bitmap in - * VDP2 RAM. - * - * [Parameters] - * info: Graphics layer data - * pixelnum: Index of pixel to retrieve (y*w+x) - * [Return value] - * Pixel value as 0xAABBGGRR - */ - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t4_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum/2; - /* For speed, we assume the tile/bitmap won't wrap around the end of - * VDP2 RAM */ - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t byte = *ptr; - const uint8_t pixel = (pixelnum & 1) ? byte & 0x0F : byte >> 4; - if (!pixel && info->transparencyenable) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return (adjust_color_32_32(global_clut_32[colornum & 0x7FF], - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t8_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum; - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t pixel = *ptr; - if (!pixel && info->transparencyenable) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return (adjust_color_32_32(global_clut_32[colornum & 0x7FF], - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t16_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!pixel && info->transparencyenable) { - return 0x00000000; - } - const unsigned int colornum = info->coloroffset + pixel; - return (adjust_color_32_32(global_clut_32[colornum & 0x7FF], - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_16_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!(pixel & 0x8000) && info->transparencyenable) { - return 0x00000000; - } - return (adjust_color_16_32(pixel, - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_32_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*4; - const uint32_t *ptr = (const uint32_t *)(Vdp2Ram + address); - const uint32_t pixel = BSWAP32(*ptr); - if (!(pixel & 0x80000000) && info->transparencyenable) { - return 0x00000000; - } - return (adjust_color_32_32(pixel, - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-tilemap.c b/yabause/src/psp/psp-video-tilemap.c deleted file mode 100644 index 2a83c1b9b9..0000000000 --- a/yabause/src/psp/psp-video-tilemap.c +++ /dev/null @@ -1,551 +0,0 @@ -/* src/psp/psp-video-tilemap.c: Tile-mapped background graphics handling - for PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidshared.h" - -#include "display.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" -#include "texcache.h" - -/*************************************************************************/ -/************************** Tile-drawing macros **************************/ -/*************************************************************************/ - -/* - * Macros to work through the Saturn's remarkably nested tile layout (used - * in map drawing routines). Use like: - * - * TILE_LOOP_BEGIN(tilesize) { - * ... // Draw a single tile based on "info" and "vertices" - * } TILE_LOOP_END; - * - * where "tilesize" is 8 or 16 (info->patternwh * 8). Note that we iterate - * over the highest-level "maps" twice to handle wraparound. - */ - -#define TILE_LOOP_BEGIN(tilesize) \ - int x1start = info->x; \ - unsigned int y1; \ - for (y1 = 0; y1 < info->mapwh*2 && info->y < info->drawh; y1++) { \ - int y2start = info->y; \ - info->x = x1start; \ - unsigned int x1; \ - for (x1 = 0; x1 < info->mapwh*2 && info->x < info->draww; x1++) {\ - info->PlaneAddr(info, ((y1 % info->mapwh) * info->mapwh) \ - + (x1 % info->mapwh)); \ - int x2start = info->x; \ - info->y = y2start; \ - unsigned int y2; \ - for (y2 = 0; y2 < info->planeh; y2++) { \ - int y3start = info->y; \ - info->x = x2start; \ - unsigned int x2; \ - for (x2 = 0; x2 < info->planew; x2++) { \ - int x3start = info->x; \ - info->y = y3start; \ - unsigned int y3; \ - for (y3 = 0; y3 < info->pagewh; \ - y3++, info->y += (tilesize) \ - ) { \ - if (UNLIKELY(info->y <= -(tilesize) \ - || info->y >= info->drawh)) { \ - info->addr += info->patterndatasize * 2 \ - * info->pagewh; \ - continue; \ - } \ - info->x = x3start; \ - unsigned int x3; \ - for (x3 = 0; x3 < info->pagewh; \ - x3++, info->x += (tilesize), \ - info->addr += info->patterndatasize * 2 \ - ) { \ - if (UNLIKELY(info->x <= -(tilesize) \ - || info->x >= info->draww)) { \ - continue; \ - } \ - vdp2_calc_pattern_address(info); - -#define TILE_LOOP_END \ - } /* Inner (pattern) X */ \ - } /* Inner (pattern) Y */ \ - } /* Middle (page) X */ \ - } /* Middle (page) Y */ \ - } /* Outer (plane) X */ \ - } /* Outer (plane) Y */ - -/*-----------------------------------------------------------------------*/ - -/* Additional macros used by tile map drawing routines */ - -/*----------------------------------*/ - -/* Set up the clipping region for the graphics layer; half_height should be - * 1 when rendering T8 tiles with the double-stride, two-pass optimization */ -#define SET_CLIP_REGION(half_height) \ - guScissor(clip->xstart, \ - half_height ? clip->ystart/2 : clip->ystart, \ - clip->xend - clip->xstart, \ - half_height ? clip->yend/2 - clip->ystart/2 \ - : clip->yend - clip->ystart) - -/* Reset the clipping region to default */ -#define UNSET_CLIP_REGION \ - guScissor(0, 0, disp_width, disp_height) - -/*----------------------------------*/ - -/* Declare tiledatasize as the size of a single tile's data in bytes. */ -#define GET_TILEDATASIZE \ - int tiledatasize; \ - switch (info->colornumber) { \ - case 0: /* 4bpp */ tiledatasize = 8*8/2; break; \ - case 1: /* 8bpp */ tiledatasize = 8*8*1; break; \ - case 2: /* 16bpp */ tiledatasize = 8*8*2; break; \ - case 3: /* 16bpp */ tiledatasize = 8*8*2; break; \ - case 4: /* 32bpp */ tiledatasize = 8*8*4; break; \ - default: DMSG("Bad tile pixel type %d", info->colornumber); \ - tiledatasize = 0; break; \ - } - -/* Allocate memory for "vertspertile" vertices per "size"x"size" tile. */ -#define GET_VERTICES(size,vertspertile) \ - /* We add 4 here to handle up to 15 pixels of partial tiles \ - * on each edge of the display area */ \ - const int tilew = info->draww / (size) + 4; \ - const int tileh = info->drawh / (size) + 4; \ - const int nvertices = tilew * tileh * (vertspertile); \ - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * nvertices); - -/* Initialize variables for 8-bit indexed tile palette handling. There can - * be up to 128 different palettes, selectable on a per-tile basis, so to - * save time, we only create (on the fly) those which are actually used. */ -#define INIT_T8_PALETTE \ - uint32_t *palettes[128]; \ - memset(palettes, 0, sizeof(palettes)); \ - int cur_palette = -1; /* So it's always set the first time */ \ - guClutMode(GU_PSM_8888, 0, 0xFF, 0); - -/* Set the texture pixel format for 8-bit indexed tiles. 16-byte-wide - * textures are effectively swizzled already, so set the swizzled flag for - * whatever speed boost it gives us. */ -#define INIT_T8_TEXTURE \ - guTexMode(GU_PSM_T8, 0, 0, 1); - -/* Set the vertex type for 8-bit indexed tiles. */ -#define INIT_T8_VERTEX \ - guVertexFormat(GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D); - -/* Initialize the work buffer pointers for 8-bit indexed tiles. */ -#define INIT_T8_WORK_BUFFER \ - uint32_t * const work_buffer_0 = display_work_buffer(); \ - uint32_t * const work_buffer_1 = work_buffer_0 + DISPLAY_STRIDE; - -/* Initialize a variable for tracking empty tiles (initialize with an - * impossible address so it matches nothing by default). */ -#define INIT_EMPTY_TILE \ - uint32_t empty_tile_addr = 1; - -/*----------------------------------*/ - -/* Check whether this is a known empty tile, and skip the loop body if so. */ -static const uint8_t CHECK_EMPTY_TILE_bppshift_lut[8] = {2,3,4,4,5,5,5,5}; -#define CHECK_EMPTY_TILE(tilesize) \ - if (info->charaddr == empty_tile_addr) { \ - continue; \ - } \ - if (info->transparencyenable && empty_tile_addr == 1) { \ - const uint32_t bppshift = \ - CHECK_EMPTY_TILE_bppshift_lut[info->colornumber]; \ - const uint32_t tile_nwords = ((tilesize)*(tilesize)/32) << bppshift; \ - empty_tile_addr = info->charaddr; \ - const uint32_t *ptr = (const uint32_t *)&Vdp2Ram[info->charaddr]; \ - const uint32_t *top = ptr + tile_nwords; \ - for (; ptr < top; ptr++) { \ - if (*ptr != 0) { \ - empty_tile_addr = 1; \ - break; \ - } \ - } \ - if (empty_tile_addr != 1) { \ - /* The tile was empty, so we don't need to draw anything */ \ - continue; \ - } \ - } - -/* Declare flip_* and priority with the proper values for "size"x"size" - * tiles (either 8x8 or 16x16). */ -#define GET_FLIP_PRI(size) \ - const int flip_u0 = (info->flipfunction & 1) << ((size)==16 ? 4 : 3); \ - const int flip_u1 = flip_u0 ^ (size); \ - const int flip_v0 = (info->flipfunction & 2) << ((size)==16 ? 3 : 2); \ - const int flip_v1 = flip_v0 ^ (size); \ - int priority; \ - if (info->specialprimode == 1) { \ - priority = (info->priority & ~1) | info->specialfunction; \ - } else { \ - priority = info->priority; \ - } - -/* Declare flip_* and priority for 8-bit indexed tiles. */ -static const int flip_t8_u[4][4] = - { {0,8,8,16}, {8,0,16,8}, {8,16,0,8}, {16,8,8,0} }; -#define GET_FLIP_PRI_T8 \ - const int flip_u0 = flip_t8_u[info->flipfunction][0]; \ - const int flip_u1 = flip_t8_u[info->flipfunction][1]; \ - const int flip_u2 = flip_t8_u[info->flipfunction][2]; \ - const int flip_u3 = flip_t8_u[info->flipfunction][3]; \ - const int flip_v0 = (info->flipfunction & 2) << 1; \ - const int flip_v1 = flip_v0 ^ 4; \ - int priority; \ - if (info->specialprimode == 1) { \ - priority = (info->priority & ~1) | info->specialfunction; \ - } else { \ - priority = info->priority; \ - } - -/* Update the current palette for an 8-bit indexed tile, if necessary. */ -#define UPDATE_T8_PALETTE \ - if (info->paladdr != cur_palette) { \ - cur_palette = info->paladdr; \ - if (UNLIKELY(!palettes[cur_palette])) { \ - palettes[cur_palette] = vdp2_gen_t8_clut( \ - info->coloroffset, info->paladdr<<4, \ - info->transparencyenable, info->cor, info->cog, info->cob \ - ); \ - } \ - if (LIKELY(palettes[cur_palette])) { \ - const uint32_t * const clut = palettes[cur_palette];\ - guClutLoad(256/8, clut); \ - } \ - } - -/* Define 2 vertices for a generic 8x8 or 16x16 tile. */ -#define SET_VERTICES(tilex,tiley,xsize,ysize) \ - vertices[0].u = flip_u0; \ - vertices[0].v = flip_v0; \ - vertices[0].x = (tilex); \ - vertices[0].y = (tiley); \ - vertices[0].z = 0; \ - vertices[1].u = flip_u1; \ - vertices[1].v = flip_v1; \ - vertices[1].x = (tilex) + (xsize); \ - vertices[1].y = (tiley) + (ysize); \ - vertices[1].z = 0; - -/* Define 2 vertices for the even lines of an 8-bit indexed 8x8 tile. */ -#define SET_VERTICES_T8_EVEN(tilex,tiley,xsize,ysize) \ - vertices[0].u = flip_u0; \ - vertices[0].v = yofs + flip_v0; \ - vertices[0].x = (tilex); \ - vertices[0].y = (tiley) / 2; \ - vertices[0].z = 0; \ - vertices[1].u = flip_u1; \ - vertices[1].v = yofs + flip_v1; \ - vertices[1].x = (tilex) + (xsize); \ - vertices[1].y = ((tiley) + (ysize)) / 2; \ - vertices[1].z = 0; - -/* Define 2 vertices for the odd lines of an 8-bit indexed 8x8 tile. */ -#define SET_VERTICES_T8_ODD(tilex,tiley,xsize,ysize) \ - vertices[2].u = flip_u2; \ - vertices[2].v = flip_v0; \ - vertices[2].x = (tilex); \ - vertices[2].y = (tiley) / 2; \ - vertices[2].z = 0; \ - vertices[3].u = flip_u3; \ - vertices[3].v = flip_v1; \ - vertices[3].x = (tilex) + (xsize); \ - vertices[3].y = ((tiley) + (ysize)) / 2; \ - vertices[3].z = 0; - -/* Load the texture pointer for an 8-bit indexed 8x8 tile. */ -#define LOAD_T8_TILE \ - guTexFlush(); \ - guTexImage(0, 512, 512, 16, src); - -/* Set the even-lines work buffer for 8-bit indexed 8x8 tiles. */ -#define SET_T8_BUFFER_0 \ - guDrawBuffer(GU_PSM_8888, work_buffer_0, DISPLAY_STRIDE*2); - -/* Draw the even lines of an 8-bit indexed 8x8 tile */ -#define RENDER_T8_EVEN \ - guVertexPointer(vertices); \ - guDrawPrimitive(GU_SPRITES, 2); - -/* Set the odd-lines work buffer for 8-bit indexed 8x8 tiles. */ -#define SET_T8_BUFFER_1 \ - guDrawBuffer(GU_PSM_8888, work_buffer_1, DISPLAY_STRIDE*2); - -/* Draw the odd lines of an 8-bit indexed 8x8 tile. */ -#define RENDER_T8_ODD \ - guVertexPointer(vertices+2); \ - guDrawPrimitive(GU_SPRITES, 2); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * vdp2_draw_map_8x8: Draw a graphics layer composed of 8x8 patterns of - * any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_8x8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Allocate vertex memory and perform other initialization */ - SET_CLIP_REGION(0); - GET_VERTICES(8, 2); - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(8) { - CHECK_EMPTY_TILE(8); - GET_FLIP_PRI(8); - SET_VERTICES(info->x * info->coordincx, info->y * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - texcache_load_tile(8, info->charaddr, info->colornumber, - info->transparencyenable, - info->coloroffset, info->paladdr << 4, - info->cor, info->cog, info->cob, - vdp2_is_persistent(info->charaddr)); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); - vertices += 2; - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_map_8x8_t8: Draw a graphics layer composed of 8-bit indexed - * color 8x8 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_8x8_t8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Check the current screen mode; if we're in interlaced mode, we can - * cheat by treating each 8x8 tile as a 16x4 texture and drawing only - * the left or right half, thus omitting alternate lines for free. */ - const int interlaced = (disp_height > 272); - - /* Allocate vertex memory and perform other initialization. Note that - * we need 2 sprites to draw each tile if we're not optimizing - * interlaced graphics. */ - SET_CLIP_REGION(!interlaced); - GET_VERTICES(8, interlaced ? 2 : 4); - INIT_T8_PALETTE; - INIT_T8_TEXTURE; - INIT_T8_VERTEX; - INIT_T8_WORK_BUFFER; - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(8) { - CHECK_EMPTY_TILE(8); - GET_FLIP_PRI_T8; - UPDATE_T8_PALETTE; - - /* Set up vertices and draw the tile */ - const uint8_t *src = &Vdp2Ram[info->charaddr]; - int yofs = ((uintptr_t)src & 63) / 16; - src = (const uint8_t *)((uintptr_t)src & ~63); - SET_VERTICES_T8_EVEN(info->x * info->coordincx, - info->y * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - if (!interlaced) { - SET_VERTICES_T8_ODD(info->x * info->coordincx, - info->y * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - } else { - /* We don't modify the work buffer stride in this case, so double - * the Y coordinates (which were set assuming a doubled stride) */ - vertices[0].y *= 2; - vertices[1].y *= 2; - } - LOAD_T8_TILE; - if (!interlaced) { - SET_T8_BUFFER_0; - } - RENDER_T8_EVEN; - if (!interlaced) { - SET_T8_BUFFER_1; - RENDER_T8_ODD; - vertices += 4; - } else { - /* Interlaced, so drop odd lines of tile */ - vertices += 2; - } - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; - if (!interlaced) { - guDrawBuffer(GU_PSM_8888, work_buffer_0, DISPLAY_STRIDE); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_map_16x16: Draw a graphics layer composed of 16x16 patterns - * of any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_16x16(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Determine tile data size */ - GET_TILEDATASIZE; - - /* Allocate vertex memory and perform other initialization */ - SET_CLIP_REGION(0); - GET_VERTICES(16, 2); - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(16) { - CHECK_EMPTY_TILE(16); - GET_FLIP_PRI(16); - - SET_VERTICES(info->x * info->coordincx, info->y * info->coordincy, - 16 * info->coordincx, 16 * info->coordincy); - texcache_load_tile(16, info->charaddr, info->colornumber, - info->transparencyenable, - info->coloroffset, info->paladdr << 4, - info->cor, info->cog, info->cob, - vdp2_is_persistent(info->charaddr)); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); - vertices += 2; - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_map_16x16_t8: Draw a graphics layer composed of 8-bit indexed - * color 16x16 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_16x16_t8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Check the current screen mode */ - const int interlaced = (disp_height > 272); - - /* Allocate vertex memory and perform other initialization */ - SET_CLIP_REGION(!interlaced); - GET_VERTICES(8, interlaced ? 2 : 4); - INIT_T8_PALETTE; - INIT_T8_TEXTURE; - INIT_T8_VERTEX; - INIT_T8_WORK_BUFFER; - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(16) { - CHECK_EMPTY_TILE(16); - GET_FLIP_PRI_T8; - UPDATE_T8_PALETTE; - - const uint8_t *src = &Vdp2Ram[info->charaddr]; - int yofs = ((uintptr_t)src & 63) / 16; - src = (const uint8_t *)((uintptr_t)src & ~63); - int tilenum; - for (tilenum = 0; tilenum < 4; tilenum++, src += 8*8*1) { - const int tilex = info->x + (8 * ((tilenum % 2) ^ (info->flipfunction & 1))); - const int tiley = info->y + (8 * ((tilenum / 2) ^ ((info->flipfunction & 2) >> 1))); - SET_VERTICES_T8_EVEN(tilex * info->coordincx, - tiley * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - if (!interlaced) { - SET_VERTICES_T8_ODD(tilex * info->coordincx, - tiley * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - } else { - vertices[0].y *= 2; - vertices[1].y *= 2; - } - - LOAD_T8_TILE; - if (!interlaced) { - SET_T8_BUFFER_0; - } - RENDER_T8_EVEN; - if (!interlaced) { - SET_T8_BUFFER_1; - RENDER_T8_ODD; - vertices += 4; - } else { - vertices += 2; - } - } - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; - if (!interlaced) { - guDrawBuffer(GU_PSM_8888, work_buffer_0, DISPLAY_STRIDE); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-tweaks.c b/yabause/src/psp/psp-video-tweaks.c deleted file mode 100644 index 615d005495..0000000000 --- a/yabause/src/psp/psp-video-tweaks.c +++ /dev/null @@ -1,1884 +0,0 @@ -/* src/psp/psp-video-tweaks.c: Game-specific tweaks for PSP video module - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" -#include "../vdp2.h" -#include "../vidshared.h" - -#include "config.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Local routine declarations (internal helpers are declared in their - * respective sections) */ - -static void Azel_fix_registers(void); -static int Azel_draw_NBG1(vdp2draw_struct *info, - const clipping_struct *clip); -static void Azel_reset_cache(void); -static void Azel_cache_RBG0(void); -static int Azel_draw_RBG0(vdp2draw_struct *info, - const clipping_struct *clip); - -/*************************************************************************/ -/************************** Interface function ***************************/ -/*************************************************************************/ - -/** - * psp_video_apply_tweaks: Apply game-specific optimizations and tweaks - * for faster/better PSP video output. Called at the beginning of drawing - * each frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_video_apply_tweaks(void) -{ - /**** Azel: Panzer Dragoon RPG (JP) ****/ - - if (memcmp(HighWram+0x42F34, "APDNAR\0003", 8) == 0) { - - /* For reasons unknown (but possibly an emulator bug), VDP1 and - * RBG0 are one frame out of sync, with RBG0 lagging behind. - * However, if the game is in 30fps mode and we're also skipping - * one frame (or in fact any number of odd frames) per frame drawn, - * we can hide this lag by always skipping the frame in which the - * VDP1 command table is updated. The game finalizes the command - * list by updating the jump target at VDP1 address 0x00082, so we - * watch for changes and use that to sync the frame skipper. */ - static uint8_t just_adjusted = 0; // Avoid infinite loops, just in case - static uint16_t last_00082 = 0xFFFF; // Impossible value - const uint16_t this_00082 = T1ReadWord(Vdp1Ram, 0x00082); - const int game_framerate = T2ReadLong(HighWram, 0x4BC94); - if (!just_adjusted - && game_framerate == 2 - && this_00082 != last_00082 - && frames_to_skip % 2 == 1 - && frames_skipped % 2 == 1 - ) { - frames_skipped--; - just_adjusted = 1; - } else { - just_adjusted = 0; - } - last_00082 = this_00082; - - /* Fix bogus/suboptimal register settings. */ - Azel_fix_registers(); - - /* Apply the top/bottom black border to NBG1 implemented using - * line scrolling. */ - psp_video_set_draw_routine(BG_NBG1, Azel_draw_NBG1, 0); - - /* Draw sky/ground RBG0 graphics more efficiently, if requested. */ - if (config_get_optimize_rotate() && (Vdp2Regs->BGON & 0x0010)) { - Azel_cache_RBG0(); - psp_video_set_draw_routine(BG_RBG0, Azel_draw_RBG0, 1); - } else { - Azel_reset_cache(); - psp_video_set_draw_routine(BG_RBG0, NULL, 0); - } - - } -} - -/*************************************************************************/ -/**************************** Local functions ****************************/ -/*************************************************************************/ - -/**** Azel: Panzer Dragoon RPG (JP) optimizers ****/ - -/*-----------------------------------------------------------------------*/ - -/* Exported variables for RBG0 slope and first coefficient reciprocal, - * set by the optimized RBG0 coefficient generator in satopt-sh2.c. */ -#define SLOPE_UNSET 1e10f -float psp_video_tweaks_Azel_RBG0_slope = SLOPE_UNSET; -float psp_video_tweaks_Azel_RBG0_first_recip; - -/*----------------------------------*/ - -/* Do we have data for RBG0 cached? */ -static uint8_t Azel_RBG0_cached; - -/* Palette indices (0-7) for sky (flat) and ground (scaled) planes. */ -static uint8_t Azel_sky_palette, Azel_ground_palette; - -/* Does the sky wrap vertically? */ -static uint8_t Azel_sky_wrap_v; - -/* Is the ground texture already reduced by half? */ -static uint8_t Azel_ground_reduced; - -/* VDP2 plane addresses for sky and ground planes. */ -static uint32_t Azel_sky_plane_address, Azel_ground_plane_address; - -/* Checksum for plane data. */ -static uint32_t Azel_plane_data_checksum; - -/* Pixel buffers for cached plane data. */ -static uint8_t *Azel_sky_cache, *Azel_ground_cache; - -/* Data structure used for coordinate calculation. */ -struct Azel_RBG0_coord {int x, y, overdraw_x, overdraw_y;}; - -/*----------------------------------*/ - -static void Azel_cache_plane(uint32_t plane_address, uint32_t tile_base, - uint8_t *dest); -static void Azel_make_mipmap(const uint8_t *in, unsigned int size, - uint8_t *out, unsigned int stride); -static void Azel_get_rotation_matrix(uint32_t address, float matrix[2][3], - float *kx_ret, float *ky_ret, - float *Xp_ret, float *Yp_ret); -static void Azel_transform_coordinates(const float x, const float y, - float *u_ret, float *v_ret, - float M[2][3], - const float kx, const float ky, - const float Xp, const float Yp); -static inline void Azel_compute_switch( - uint32_t coef_base, uint32_t coef_switch_index, - const uint32_t coef_index_UL, const uint32_t coef_index_UR, - const uint32_t coef_index_LL, const uint32_t coef_index_LR, - float coef_dx, float coef_dy, - int *switch_x0, int *switch_y0, int *switch_x1, int *switch_y1); -static inline void Azel_compute_vertices( - int UL_is_sky, int UR_is_sky, int LL_is_sky, int LR_is_sky, - int switch_x0, int switch_y0, int switch_x1, int switch_y1, - struct Azel_RBG0_coord coord[2][5], unsigned int nverts[2]); - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_fix_registers: Fix VDP2 registers which are set improperly (but do - * not exhibit problems on a real Saturn due to hardware idiosyncrasies) or - * inefficiently (so that they waste more resources than necessary). - * - * [Parameters] - * None - * [Return value] - * None - */ -static void Azel_fix_registers(void) -{ - /* Fix bogus sprite alpha setting in the Uru underwater tunnel. */ - if (Vdp2Regs->PNCN1 == 0xC100 - && Vdp2Regs->MPABN1 == 0x0B0B - && Vdp2Regs->MPCDN1 == 0x0B0B - && Vdp2Regs->RPTA.all == 0x14000 - && T1ReadLong(Vdp2Ram, 0x28054) == 0x80640000 - && T1ReadLong(Vdp2Ram, 0x28058) == 0x10000 - && (int32_t)T1ReadLong(Vdp2Ram, 0x20190 + 223*4) < 0 - && Vdp2Regs->SPCTL == 0x1523 - && Vdp2Regs->CCCTL == 0x0053 - && Vdp2Regs->SFCCMD == 0x0008 - && Vdp2Regs->PRISA == 0x0405 - && Vdp2Regs->PRINA == 0x0604 - && Vdp2Regs->CCRSA == 0x000C - && Vdp2Regs->CCRNA == 0x101F - ) { - Vdp2Regs->CCRSA &= 0xFF00; - } - - /* Fix bogus sprite alpha setting in the imperial base. */ - if (Vdp2Regs->BGON == 0x011B - && Vdp2Regs->SFSEL == 0x0002 - && Vdp2Regs->CHCTLA == 0x0101 - && Vdp2Regs->CHCTLB == 0x1100 - && Vdp2Regs->PNCN0 == 0x8080 - && Vdp2Regs->PNCN1 == 0xC100 - && Vdp2Regs->PLSZ == 0x0000 - && Vdp2Regs->MPABN0 == 0x3E3E - && Vdp2Regs->MPABN0 == 0x3E3E - && Vdp2Regs->MPABN1 == 0x0B0B - && Vdp2Regs->MPCDN1 == 0x0B0B - && T1ReadLong(Vdp2Ram, 0x1F000) == 0x02010202 - && T1ReadLong(Vdp2Ram, 0x1008C) == 0x99889999 - && Vdp2Regs->SPCTL == 0x1423 - && (Vdp2Regs->CCCTL & ~0x0010) == 0x0143 - && Vdp2Regs->SFCCMD == 0x0008 - && Vdp2Regs->PRISA == 0x0404 - && (Vdp2Regs->PRINA & ~0x0001) == 0x0604 - && (Vdp2Regs->PRINA & 0xF) == (Vdp2Regs->CCCTL>>4 & 0xF) - && Vdp2Regs->CCRSA == 0x180D - && Vdp2Regs->CCRNA == 0x1017 - ) { - Vdp2Regs->CCRSA &= 0xFF00; - } - - /* Fix missing(?) alpha setting for the NBG0 cloud overlay used in - * Mel-Kava and in Atolm battles. (NBG0 is at the third-highest - * priority level; how does it get color calculation enabled in the - * first place?) */ - if ((Vdp2Regs->BGON & ~0x0100) == 0x001B - && Vdp2Regs->SFSEL == 0x0002 - && Vdp2Regs->CHCTLA == 0x0101 - && Vdp2Regs->CHCTLB == 0x1100 - && (Vdp2Regs->PNCN0 & ~0x0020) == 0x8080 - && Vdp2Regs->PNCN1 == 0xC100 - && Vdp2Regs->PLSZ == 0x0000 - && Vdp2Regs->MPABN0 == 0x3C3C - && Vdp2Regs->MPABN0 == 0x3C3C - && Vdp2Regs->MPABN1 == 0x0B0B - && Vdp2Regs->MPCDN1 == 0x0B0B - && T1ReadLong(Vdp2Ram, 0x1E000) == 0x02010202 - && T1ReadLong(Vdp2Ram, 0x100F8) == 0x11111222 - && (Vdp2Regs->CCCTL & ~0x0010) == 0x0103 - && Vdp2Regs->SFCCMD == 0x0008 - && (Vdp2Regs->PRINA & ~0x0001) == 0x0604 - && (Vdp2Regs->PRINA & 0x1) == (Vdp2Regs->CCCTL>>4 & 0x1) - && Vdp2Regs->CCRNA == 0x1000 - ) { - Vdp2Regs->CCRNA |= 0x0017; - } - - /* Display movies with transparency disabled to improve draw speed. */ - if ((Vdp2Regs->CHCTLA & 0x0070) == 0x0040) { - Vdp2Regs->BGON |= 0x0100; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_draw_NBG1: Draw NBG1, along with any black borders specified by - * the line scroll table. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * Nonzero if the graphics layer was drawn, zero if not - */ -static int Azel_draw_NBG1(vdp2draw_struct *info, - const clipping_struct *clip) -{ - /* First check whether this is an optimizable case, and punt back to - * the default if not. */ - - if ((Vdp2Regs->SCRCTL & 0x3F00) != 0x400) { - return 0; // No black bars to draw - } - if (UNLIKELY(info->isbitmap || info->patternwh != 2)) { - DMSG("Bad NBG1 parameters: isbitmap=%d patternwh=%d", - info->isbitmap, info->patternwh); - return 0; - } - - /* Draw the screen itself as usual. */ - - vdp2_draw_map_16x16(info, clip); - - /* Render black bars for lines scrolled off the screen (i.e., to black) - * in the line scroll table. */ - - const uint32_t address = (Vdp2Regs->LSTA1.all & 0x3FFFE) << 1; - const uint8_t *table = &Vdp2Ram[address]; - - guDisable(GU_TEXTURE_2D); - - int in_black_bar = 0; - unsigned int black_bar_top = 0; - unsigned int y; - for (y = 0; y <= disp_height; y++, table += 4) { // Deliberately "<=" - if (y < disp_height && *table != 0) { - if (!in_black_bar) { - black_bar_top = y; - in_black_bar = 1; - } - } else { - if (in_black_bar) { - struct {uint32_t color; int16_t x, y, z, pad;} *vertices; - vertices = guGetMemory(sizeof(*vertices) * 2); - vertices[0].color = 0xFF000000; - vertices[0].x = 0; - vertices[0].y = black_bar_top >> disp_yscale; - vertices[0].z = 0; - vertices[1].color = 0xFF000000; - vertices[1].x = disp_width >> disp_xscale; - vertices[1].y = y >> disp_yscale; - vertices[1].z = 0; - guDrawArray(GU_SPRITES, - GU_TRANSFORM_2D | GU_COLOR_8888 | GU_VERTEX_16BIT, - 2, NULL, vertices); - in_black_bar = 0; - } - } - } - - guEnable(GU_TEXTURE_2D); - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_reset_cache: Clear all cached RBG0 data. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void Azel_reset_cache(void) -{ - Azel_RBG0_cached = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_cache_RBG0: Check whether the current RBG0 data matches the cached - * data, and cache it if not. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void Azel_cache_RBG0(void) -{ - /* Look up the graphics layer format and make sure it's what we're - * looking for. */ - - const unsigned int colornumber = Vdp2Regs->CHCTLB>>12 & 0x7; - const unsigned int patternwh = Vdp2Regs->CHCTLB & 0x100 ? 2 : 1; - const unsigned int patterndatasize = Vdp2Regs->PNCR & 0x8000 ? 2 : 4; - const unsigned int auxmode = Vdp2Regs->PNCR & 0x4000 ? 1 : 0; - const unsigned int supplementdata = Vdp2Regs->PNCR & 0x3FF; - const unsigned int planewh_A = Vdp2Regs->PLSZ>>8 & 0x3; - const unsigned int planewh_B = Vdp2Regs->PLSZ>>12 & 0x3; - const unsigned int rpmd = Vdp2Regs->RPMD & 0x3; - const unsigned int raovr = Vdp2Regs->PLSZ>>10 & 0x3; - const unsigned int raopn = Vdp2Regs->OVPNRA; - if (colornumber != 1 || patternwh != 2 || patterndatasize != 2 - || auxmode || planewh_A != 0 || planewh_B != 0 - || (rpmd != 2 && !(rpmd == 0 && raovr == 1 && raopn == 0x5000)) - ) { - DMSG("Wrong RBG0 format for cache: colornumber=%u patternwh=%u" - " patterndatasize=%u auxmode=%u planewh=%u/%u rpmd=%u", - colornumber, patternwh, patterndatasize, auxmode, planewh_A, - planewh_B, rpmd); - Azel_RBG0_cached = 0; - return; - } - - /* Calculate the plane data addresses for the sky and ground planes, - * and check that they haven't changed from the cached values. */ - - const unsigned int plane_size = - (64/patternwh) * (64/patternwh) * patterndatasize; - const unsigned int sky_plane = - (Vdp2Regs->MPOFR>>4 & 7) << 6 | (Vdp2Regs->MPABRB & 0xFF); - const unsigned int ground_plane = - (Vdp2Regs->MPOFR>>0 & 7) << 6 | (Vdp2Regs->MPABRA & 0xFF); - const unsigned int sky_plane_address = sky_plane * plane_size; - const unsigned int ground_plane_address = ground_plane * plane_size; - if (Azel_RBG0_cached - && (sky_plane_address != Azel_sky_plane_address - || ground_plane_address != Azel_ground_plane_address) - ) { - DMSG("Plane addresses changed, now sky=%05X ground=%05X", - sky_plane_address, ground_plane_address); - Azel_RBG0_cached = 0; - } - - /* Calculate a checksum for the plane data and check it against the - * cached checksum. If the plane data matches, we assume the tile - * (pixel) data matches as well. */ - - uint16_t sum1 = 1, sum2 = 0; - const uint16_t *ptr, *top; - for (ptr = (const uint16_t *)&Vdp2Ram[sky_plane_address], - top = ptr + plane_size/2; ptr < top; ptr++ - ) { - const uint16_t data = BSWAP16(*ptr); - sum1 += data; - sum2 += sum1; - } - for (ptr = (const uint16_t *)&Vdp2Ram[ground_plane_address], - top = ptr + plane_size/2; ptr < top; ptr++ - ) { - const uint16_t data = BSWAP16(*ptr); - sum1 += data; - sum2 += sum1; - } - const uint32_t checksum = sum1 | sum2<<16; - if (checksum != Azel_plane_data_checksum) { - DMSG("Plane data checksum changed, now 0x%08X", checksum); - Azel_RBG0_cached = 0; - } - - /* If Azel_RBG0_cached is still set, the current RBG0 data already - * matches the cache, so we don't have to do anything else. */ - - if (Azel_RBG0_cached) { - return; - } - - /* Allocate a cache buffer if we haven't done so yet. (We don't free - * the buffers once we allocate them, on the assumption that only one - * game will be played per Yabause boot.) */ - - if (!Azel_sky_cache) { - uint8_t *base = malloc(63 + 512*512 - + 512*512 + 256*256 + 128*128 + 64*64); - if (!base) { - DMSG("No memory for sky/ground pixel buffers"); - return; - } - uintptr_t base_aligned = ((uintptr_t)base + 63) & -64; - Azel_sky_cache = (uint8_t *)base_aligned; - Azel_ground_cache = (uint8_t *)(base_aligned + 512*512); - } - - /* Cache the graphics data (two 512x512-pixel planes) in - * Azel_{sky,ground}_cache as 512x512 T8 swizzled textures. Also add - * mipmaps for the ground texture to improve drawing performance for - * distant regions. */ - - Azel_cache_plane(sky_plane_address, - (supplementdata & 0xC) << 15 | (supplementdata & 3) << 5, - Azel_sky_cache); - if ((Vdp2Regs->RPMD & 3) == 0 - && Vdp2Regs->MPABRA == 0x0100 - && Vdp2Regs->MPEFRA == 0x0203 - ) { - /* Special case for the dome area of the Uru underground dungeon, - * which is a shrunken 1024x1024 map. We reduce it to 512x512 and - * adjust the scale factors appropriately when drawing. */ - Azel_ground_reduced = 1; - uint8_t *temp = malloc(512*512); - if (!temp) { - DMSG("No temporary memory for reducing dome RBG0"); - return; - } - Azel_cache_plane(ground_plane_address, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache, 512); - Azel_cache_plane(ground_plane_address + 0x800, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache + 256*8, 512); - Azel_cache_plane(ground_plane_address + 0x1800, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache + 512*256, 512); - Azel_cache_plane(ground_plane_address + 0x1000, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache + 512*256 + 256*8, 512); - free(temp); - } else { - Azel_ground_reduced = 0; - Azel_cache_plane(ground_plane_address, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - Azel_ground_cache); - } - Azel_make_mipmap(Azel_ground_cache, 512, - Azel_ground_cache + 512*512, 256); - Azel_make_mipmap(Azel_ground_cache + 512*512, 256, - Azel_ground_cache + 512*512 + 256*256, 128); - Azel_make_mipmap(Azel_ground_cache + 512*512 + 256*256, 128, - Azel_ground_cache + 512*512 + 256*256 + 128*128, 64); - - /* Record other data in relevant variables and set the cached flag. */ - - Azel_sky_palette = Vdp2Ram[sky_plane_address] >> 4; - Azel_ground_palette = Vdp2Ram[ground_plane_address] >> 4; - Azel_sky_wrap_v = (Vdp2Regs->MPEFRB == Vdp2Regs->MPABRB); - Azel_sky_plane_address = sky_plane_address; - Azel_ground_plane_address = ground_plane_address; - Azel_plane_data_checksum = checksum; - Azel_RBG0_cached = 1; - psp_video_tweaks_Azel_RBG0_slope = SLOPE_UNSET; -} - -/*----------------------------------*/ - -/** - * Azel_cache_plane: Cache a single plane of graphics data as a 512x512 - * T8-format swizzled texture. - * - * [Parameters] - * plane_address: Address of plane data in VDP2 RAM - * tile_base: Base address of tile (pixel) data in VDP2 RAM - * dest: Pointer to output buffer (512*512 bytes) - * [Return value] - * None - */ -static void Azel_cache_plane(uint32_t plane_address, uint32_t tile_base, - uint8_t *dest) -{ - const uint16_t *src = (const uint16_t *)&Vdp2Ram[plane_address]; - - unsigned int tile_y; - for (tile_y = 0; tile_y < 32; tile_y++) { - uint8_t *out_ptr = &dest[(tile_y * 16) * 512]; - unsigned int tile_x; - for (tile_x = 0; tile_x < 32; tile_x++, src++, out_ptr += 128) { - const uint16_t data = BSWAP16(*src); - unsigned int tile_index = (data & 0x3FF) << 2; - unsigned int flip_x = (data & 0x400) ? 8 : 0; - unsigned int flip_y = (data & 0x800) ? 15 : 0; - const uint8_t *tile_data = &Vdp2Ram[tile_base + (tile_index<<5)]; - unsigned int char_y; - for (char_y = 0; char_y < 2; char_y++) { - unsigned int char_x; - for (char_x = 0; char_x < 2; char_x++) { - unsigned int pixel_y; - for (pixel_y = 0; pixel_y < 8; pixel_y++, tile_data += 8) { - const unsigned int y = (char_y*8 + pixel_y) ^ flip_y; - uint8_t * const y_ptr = - &out_ptr[((y/8) * (512*8)) + ((y%8) * 16) - + ((char_x*8) ^ flip_x)]; - const uint32_t pix0_3 = - ((const uint32_t *)tile_data)[0]; - const uint32_t pix4_7 = - ((const uint32_t *)tile_data)[1]; - if (flip_x) { - ((uint32_t *)y_ptr)[0] = BSWAP32(pix4_7); - ((uint32_t *)y_ptr)[1] = BSWAP32(pix0_3); - } else { - ((uint32_t *)y_ptr)[0] = pix0_3; - ((uint32_t *)y_ptr)[1] = pix4_7; - } - } // pixel_y - } // char_x - } // char_y - } // tile_x - } // tile_y -} - -/*----------------------------------*/ - -/** - * Azel_make_mipmap: Create a half-size mipmap from the given pixel buffer - * by dropping every second pixel. - * - * [Parameters] - * in: Input pixel buffer - * size: Size (width and height) of input pixel buffer - * out: Output pixel buffer - * stride: Line length of output buffer (normally size/2) - * [Return value] - * None - */ -static void Azel_make_mipmap(const uint8_t *in, unsigned int size, - uint8_t *out, unsigned int stride) -{ -#define SHRINK \ - asm(".set push; .set noreorder\n" \ - "srl %[temp], %[a], 16\n" \ - "ins %[a], %[temp], 8, 8\n" \ - "ins %[a], %[b], 16, 8\n" \ - "srl %[b], %[b], 16\n" \ - "ins %[a], %[b], 24, 8\n" \ - "srl %[temp], %[c], 16\n" \ - "ins %[c], %[temp], 8, 8\n" \ - "ins %[c], %[d], 16, 8\n" \ - "srl %[d], %[d], 16\n" \ - "ins %[c], %[d], 24, 8\n" \ - ".set pop" \ - : [a] "=r" (a), [b] "=r" (b), [c] "=r" (c), [d] "=r" (d), \ - [temp] "=&r" (temp) \ - : "0" (a), "1" (b), "2" (c), "3" (d) \ - ) - - unsigned int y; - for (y = 0; y < size; y += 16, in += size*8, out += (stride - size/2)*8) { - unsigned int x; - for (x = 0; x < size; x += 32, in += 128, out += 64) { - unsigned int line; - for (line = 0; line < 4; line++, in += 32, out += 16) { - uint32_t a, b, c, d, temp; - - a = ((const uint32_t *)in)[0]; - b = ((const uint32_t *)in)[1]; - c = ((const uint32_t *)in)[2]; - d = ((const uint32_t *)in)[3]; - SHRINK; - ((uint32_t *)out)[0] = a; - ((uint32_t *)out)[1] = c; - - a = ((const uint32_t *)in)[32]; - b = ((const uint32_t *)in)[33]; - c = ((const uint32_t *)in)[34]; - d = ((const uint32_t *)in)[35]; - SHRINK; - ((uint32_t *)out)[2] = a; - ((uint32_t *)out)[3] = c; - - a = ((const uint32_t *)in)[size*2+0]; - b = ((const uint32_t *)in)[size*2+1]; - c = ((const uint32_t *)in)[size*2+2]; - d = ((const uint32_t *)in)[size*2+3]; - SHRINK; - ((uint32_t *)out)[16] = a; - ((uint32_t *)out)[17] = c; - - a = ((const uint32_t *)in)[size*2+32]; - b = ((const uint32_t *)in)[size*2+33]; - c = ((const uint32_t *)in)[size*2+34]; - d = ((const uint32_t *)in)[size*2+35]; - SHRINK; - ((uint32_t *)out)[18] = a; - ((uint32_t *)out)[19] = c; - } - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_draw_RBG0: Draw a sky/ground RBG0 layer from cached data. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * Nonzero if the graphics layer was drawn, zero if not - */ -static int Azel_draw_RBG0(vdp2draw_struct *info, - const clipping_struct *clip) -{ - /* Define a macro to read a coefficient as a signed value, given its - * index (longword offset into VDP2 RAM). coef_mask is defined below. */ - #define READ_COEF(index) \ - ((int32_t)T1ReadLong(Vdp2Ram, (index)*4) & coef_mask) - - if (!Azel_RBG0_cached) { - return 0; - } - - /* Make sure it's an RPMD mode 2 layer with 4-byte, mode-0 coefficients - * for the ground (set A) and no coefficients for the sky (set B). - * However, also allow mode 0 with certain parameter settings used in - * the Uru underground dungeon. */ - - if ((Vdp2Regs->RPMD & 3) != 2 - && !((Vdp2Regs->RPMD & 3) == 0 - && (Vdp2Regs->PLSZ>>10 & 3) == 1 - && Vdp2Regs->OVPNRA == 0x5000) - ) { - DMSG("Can't optimize RBG0 (bad rotatemode=%d)", info->rotatemode); - return 0; - } - const int has_sky = ((Vdp2Regs->RPMD & 3) == 2); - const uint32_t param_address = (Vdp2Regs->RPTA.all << 1) & 0x7FF7C; - const uint32_t coef_base_high = (Vdp2Regs->KTAOF & 1) << 18; - if ((Vdp2Regs->KTCTL & 0x0F0F) != 0x0001) { - DMSG("Can't optimize RBG0 (bad KTCTL=%04X)", Vdp2Regs->KTCTL); - return 0; - } - - /* Load rotation matrix parameters. */ - - float sky_M[2][3], sky_kx, sky_ky, sky_Xp, sky_Yp; - float ground_M[2][3], ground_Xp, ground_Yp; - Azel_get_rotation_matrix(param_address + 0x80, - sky_M, &sky_kx, &sky_ky, &sky_Xp, &sky_Yp); - Azel_get_rotation_matrix(param_address, - ground_M, NULL, NULL, &ground_Xp, &ground_Yp); - - const float coef_base = coef_base_high/4 - + (uint32_t)T1ReadLong(Vdp2Ram, param_address+0x54) / 65536.0f; - const float coef_dy = - ((int32_t)T1ReadLong(Vdp2Ram, param_address+0x58) << 6) / 4194304.0f; - const float coef_dx = - ((int32_t)T1ReadLong(Vdp2Ram, param_address+0x5C) << 6) / 4194304.0f; - const float coef_right_offset = (disp_width - 1) * coef_dx; - - /* Find the beginning and end of the coefficient table, and determine - * where the sky/ground boundary is. For a non-rotated background, - * the table length will simply be the number of lines on the screen, - * but when the background is rotated, we need to check all four - * corners of the screen to find the table's extent. - * - * Coefficient values are treated as signed 8.16 bit fixed point, but - * the program does not clamp its coefficient values properly; as a - * result, the coefficient value can spill over into the sign bit or - * the ignored high bits for lines very close to the horizon. We treat - * these as sky lines in order to avoid mathematical trouble when - * drawing. Due to this, we optimize the (data > 0 && data < 0x800000) - * test into ((unsigned)data < 0x800000) for more efficient processing. - * However, there are some areas (such as Mel-Kava) which intentionally - * store data into the upper 8 bits, which we detect by finding four - * consecutive coefficients with upper 8 bits between 0x01-0x7F and - * lower 24 bits less than 0x800000; in that case we mask off bits - * 24-30 when reading the coefficients. - * - * We also check to see whether the ground coefficients are zero (as - * seems to happen sometimes during a scene change) in order to avoid - * division by zero when rendering. We assume that either all or no - * coefficients are zero, so we only check the first one in the ground - * region. */ - - const float coef_index_UL = coef_base; - const float coef_index_UR = coef_index_UL + coef_right_offset; - const float coef_index_LL = coef_base + (disp_height - 1) * coef_dy; - const float coef_index_LR = coef_index_LL + coef_right_offset; - const uint32_t first_coef_index = - MIN(MIN(ifloorf(coef_index_UL), ifloorf(coef_index_UR)), - MIN(ifloorf(coef_index_LL), ifloorf(coef_index_LR))); - const uint32_t last_coef_index = - MAX(MAX(ifloorf(coef_index_UL), ifloorf(coef_index_UR)), - MAX(ifloorf(coef_index_LL), ifloorf(coef_index_LR))); - const uint32_t num_coefs = last_coef_index + first_coef_index - 1; - - int high_bits_used_count = 0; - int32_t coef_mask = -1; - int ground_is_zero; - unsigned int coef_switch_index; - - retry_coef_scan: - - if ((uint32_t)READ_COEF(first_coef_index) >= 0x800000) { - - ground_is_zero = 0; - unsigned int offset; - for (offset = 0; offset < num_coefs; offset++) { - const uint32_t data = READ_COEF(first_coef_index + offset); - if (coef_mask == -1) { - if ((data>>24 >= 0x01 && data>>24 <= 0x7F) - && (data & 0xFFFFFF) < 0x800000 - ) { - high_bits_used_count++; - if (high_bits_used_count >= 4) { - coef_mask = (int32_t)0x80FFFFFF; - goto retry_coef_scan; - } - } else { - high_bits_used_count = 0; - } - } - if (data < 0x800000) { - ground_is_zero = (data == 0); - break; - } - } - coef_switch_index = first_coef_index + offset; - - } else { - - ground_is_zero = (READ_COEF(first_coef_index) == 0); - unsigned int offset; - for (offset = 0; offset < num_coefs; offset++) { - const uint32_t data = READ_COEF(first_coef_index + offset); - if (data >= 0x800000) { - break; - } - } - coef_switch_index = first_coef_index + offset; - - } - - /* Determine the endpoints of the sky/ground dividing line, if any. */ - - const int has_switch = (coef_switch_index <= last_coef_index); - int switch_x0, switch_y0, switch_x1, switch_y1; - - if (has_switch) { - Azel_compute_switch(coef_base, coef_switch_index, coef_index_UL, - coef_index_UR, coef_index_LL, coef_index_LR, - coef_dx, coef_dy, &switch_x0, &switch_y0, - &switch_x1, &switch_y1); - if (UNLIKELY(switch_x0 < 0 || switch_x1 < 0)) { - DMSG("Failed to find swith line endpoints (base=%05X dx=%.3f" - " dy=%.3f", ifloorf(coef_base)*4, coef_dx, coef_dy); - return 0; - } - } else { // !has_switch - /* Set the switch line at the bottom of the screen for simplicity. */ - switch_x0 = 0; - switch_y0 = disp_height; - switch_x1 = disp_width; - switch_y1 = disp_height; - } // if (has_switch) - - /* Work out the vertex coordinates of the sky and ground regions. - * Depending on where the switch line falls, these could be three-, - * four-, or five-sided polygons. To avoid unnecessary code - * duplication, we first compute the vertices themselves, then choose - * which vertex set (coord[0] or coord[1]) to use for the sky and - * ground regions. - * - * The "overdraw_x" and "overdraw_y" fields are set to either +1 or - * -1 to indicate the direction each coordinate should be shifted for - * overdrawing when rendering the sky region. */ - - struct Azel_RBG0_coord coord[2][5]; - unsigned int nverts[2]; - - const int UL_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_UL)) >= 0x800000); - const int UR_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_UR)) >= 0x800000); - const int LL_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_LL)) >= 0x800000); - const int LR_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_LR)) >= 0x800000); - - Azel_compute_vertices(UL_is_sky, UR_is_sky, LL_is_sky, LR_is_sky, - switch_x0, switch_y0, switch_x1, switch_y1, - coord, nverts); - - const unsigned int sky_coord_set = UL_is_sky ? 0 : 1; - unsigned int ground_coord_set = sky_coord_set ^ 1; // May be changed later - - /* Generate color tables for the two background portions. */ - - void *sky_clut, *ground_clut; - sky_clut = vdp2_gen_t8_clut(Azel_sky_palette << 8, 0, - info->transparencyenable, - info->cor, info->cog, info->cob); - if (!sky_clut) { - DMSG("Failed to generate sky CLUT (palette %u)", Azel_sky_palette); - return 0; - } - ground_clut = vdp2_gen_t8_clut(Azel_ground_palette << 8, 0, - info->transparencyenable, - info->cor, info->cog, info->cob); - if (!ground_clut) { - DMSG("Failed to generate ground CLUT (palette %u)", - Azel_ground_palette); - return 0; - } - - /* Set up a vertex structure for rendering. */ - - struct {float u, v, x, y, z;} *vertices; - const uint32_t vertex_type = GU_TEXTURE_32BITF | GU_VERTEX_32BITF; - - /* Draw the sky (flat) portion of the background. We overdraw by one - * pixel in each direction to avoid the possibility of undrawn pixels - * along the switch (horizon) line, since the ground coordinates are - * adjusted by the Z factor and may end up slightly different from the - * original values in the coord[] array. */ - - if (has_sky && nverts[sky_coord_set] > 0) { - - vertices = guGetMemory(sizeof(*vertices) * nverts[sky_coord_set]); - unsigned int i; - for (i = 0; i < nverts[sky_coord_set]; i++) { - vertices[i].x = - coord[sky_coord_set][i].x + coord[sky_coord_set][i].overdraw_x; - vertices[i].y = - coord[sky_coord_set][i].y + coord[sky_coord_set][i].overdraw_y; - vertices[i].z = 0; - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - sky_M, sky_kx, sky_ky, sky_Xp, sky_Yp); - /* We deliberately shift the "sky" portion 2 pixels in the - * overdraw direction because there are occasionally - * transparent gaps where the background color shows through - * (e.g. 禁止区域). */ - if (UL_is_sky || UR_is_sky) { - vertices[i].v -= 2; - } else { - vertices[i].v += 2; - } - } - - guClutMode(GU_PSM_8888, 0, 255, 0); - guClutLoad(32, sky_clut); - guTexMode(GU_PSM_T8, 0, 0, 1); - guTexImage(0, 512, 512, 512, Azel_sky_cache); - guTexWrap(GU_REPEAT, Azel_sky_wrap_v ? GU_REPEAT : GU_CLAMP); - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_2D | vertex_type, - nverts[sky_coord_set], NULL, vertices); - - } // if (nverts[sky_coord_set] > 0) - - /* Draw the ground (scaled) portion of the background. The scale - * factors in the coefficient table are essentially distance (Z) - * values, so we set up a projection matrix that allows us to draw - * a small number of 3D triangles instead of rendering each line - * individually. For ease of coordinate handling, the projection - * matrix maps 3D coordinate (x,y,1) directly to screen coordinate - * (x+disp_width/2,y+disp_height/2). */ - - guClutMode(GU_PSM_8888, 0, 255, 0); - guClutLoad(32, ground_clut); - guTexMode(GU_PSM_T8, 0, 0, 1); - if ((Vdp2Regs->PLSZ>>10 & 3) == 0) { - guTexWrap(GU_REPEAT, GU_REPEAT); - } else { - guTexWrap(GU_CLAMP, GU_CLAMP); - } - - float Mproj[4][4]; - Mproj[0][0] = 2.0f / disp_width; - Mproj[0][1] = 0; - Mproj[0][2] = 0; - Mproj[0][3] = 0; - Mproj[1][0] = 0; - Mproj[1][1] = -2.0f / disp_height; - Mproj[1][2] = 0; - Mproj[1][3] = 0; - Mproj[2][0] = 0; - Mproj[2][1] = 0; - Mproj[2][2] = 1.0f / 128; // Coefficient value range is [0,128). - Mproj[2][3] = 1; - Mproj[3][0] = 0; - Mproj[3][1] = 0; - Mproj[3][2] = 0; - Mproj[3][3] = 0; - guSetMatrix(GU_PROJECTION, &Mproj[0][0]); - - if (nverts[ground_coord_set] == 0) { - - /* Nothing to do. */ - - } else if (ground_is_zero) { - - /* Degenerate case: ground coefficients are all zero. This - * should only happen while changing scenes, so we don't bother - * drawing anything. */ - - } else if (coef_switch_index == last_coef_index) { - - /* Degenerate case: only one ground coefficient (we also come here - * if we detect a slope of zero). We can't compute appropriate 3D - * coordinates for this case, but since it's effectively flat like - * the sky, just draw it that way. */ - - draw_as_flat:; - const int32_t data = READ_COEF(coef_switch_index); - const float kx = data / 65536.0f; - const float ky = kx; - - vertices = guGetMemory(sizeof(*vertices) * nverts[ground_coord_set]); - unsigned int i; - for (i = 0; i < nverts[ground_coord_set]; i++) { - vertices[i].x = coord[ground_coord_set][i].x; - vertices[i].y = coord[ground_coord_set][i].y; - vertices[i].z = 0; - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - ground_M, kx, ky, ground_Xp, ground_Yp); - } - if (kx >= 6.0f) { - guTexImage(0, 64, 64, 64, - Azel_ground_cache + 512*512 + 256*256 + 128*128); - } else if (kx >= 3.0f) { - guTexImage(0, 128, 128, 128, Azel_ground_cache + 512*512 + 256*256); - } else if (kx >= 1.5f) { - guTexImage(0, 256, 256, 256, Azel_ground_cache + 512*512); - } else { - guTexImage(0, 512, 512, 512, Azel_ground_cache); - } - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_2D | vertex_type, - nverts[ground_coord_set], NULL, vertices); - - } else { - - /* Determine the indices of the first and last ground coefficients. */ - - uint32_t first_ground_index, last_ground_index; - if ((uint32_t)READ_COEF(first_coef_index) < 0x800000) { - first_ground_index = first_coef_index; - if (has_switch) { - last_ground_index = coef_switch_index - 1; - } else { - last_ground_index = last_coef_index; - } - } else { - first_ground_index = coef_switch_index; - last_ground_index = last_coef_index; - } - - /* Compute the approximate plane slope from the average of the - * slopes from the first coefficient to all other coefficients. - * (For certain "ground" textures, like water, the actual - * coefficients are modulated by a small amount to produce a - * "shimmering" effect, so they won't give a single, consistent - * result from one coefficient to the next; thus we take the - * average and use that instead.) - * - * If we have a hint from the satopt-sh2.c optimizer, we use that - * instead; however, it seems to be delayed by a frame, so we use - * a local static variable to accomplish the same thing. */ - - static float slope_hint_delayed = SLOPE_UNSET; - static float first_recip_hint_delayed; - const float slope_hint = slope_hint_delayed; - const float first_recip_hint = first_recip_hint_delayed; - slope_hint_delayed = psp_video_tweaks_Azel_RBG0_slope; - first_recip_hint_delayed = psp_video_tweaks_Azel_RBG0_first_recip; - - float slope = 0; - const int32_t first_data = READ_COEF(first_ground_index); - float first_recip; - if (slope_hint != SLOPE_UNSET && slope_hint_delayed != SLOPE_UNSET) { - slope = slope_hint; - first_recip = first_recip_hint; - if (slope != 0) { - /* This may be slightly off (e.g. due to an out-of-range - * coefficient), so adjust as necessary. */ - float diff; - if (slope > 0) { - diff = first_recip - 65536.0f/first_data; - } else { - const float last_recip = - first_recip + slope * (last_ground_index - first_ground_index); - const float recip_test = - 65536.0f / READ_COEF(last_ground_index); - diff = last_recip - recip_test; - } - if (fabsf(diff) > (slope/2)) { - first_recip -= roundf(diff / fabsf(slope)) * fabsf(slope); - } - } - } else { - first_recip = 65536.0f / first_data; - uint32_t i; - for (i = first_ground_index + 1; i <= last_ground_index; i++) { - const int32_t data = READ_COEF(i); - const float recip = 65536.0f / data; - slope += (recip - first_recip) / (i - first_ground_index); - } - slope /= last_ground_index - first_ground_index; - } - - if (slope == 0) { // Avoid division by zero below. - goto draw_as_flat; - } - - /* Go over the coefficient list and find the variance from the - * linear slope we just derived, to determine whether or not we - * need to apply our own "shimmering" effect. */ - - float variance = 0; - uint32_t index; - for (index = first_ground_index; index <= last_ground_index; index++) { - const int32_t data = READ_COEF(index); - const float recip = 65536.0f / data; - const float expected = - first_recip + slope * (index - first_ground_index); - const float error = (recip - expected) / slope; - variance += error * error; - } - variance /= last_ground_index - first_ground_index + 1; - const int do_shimmer = (variance > 0.01f); - const float shimmer_step = - (sceKernelGetSystemTimeLow() & 0x7FFFFF) / (float)0x800000; - - /* If the entire screen is "ground" and the slope is positive, - * move the switch line to the top of the screen so we draw - * the proper portion as mipmapped. */ - - if (switch_y0 == disp_height && slope > 0) { - switch_y0 = switch_y1 = 0; - } - - /* If the ground plane needs to be split into separate mipmapped - * and normal regions, first draw the distant (mipmapped) part of - * the plane. - * FIXME: This section is making me nauseous, which is a sign that - * it's poorly written and desperately needs refactoring--or perhaps - * a complete rethinking... - */ - - index = (slope > 0) ? first_ground_index : last_ground_index + 1; - int32_t mipmap_scale; - for (mipmap_scale = 8; - mipmap_scale > 1 && (slope > 0 ? index <= last_ground_index - : index > first_ground_index); - mipmap_scale /= 2 - ) { - - /* Find the index of the coefficient at which the mipmap scale - * switches. We normally use mipmaps only at scales above the - * mipmap's level, but we're more aggressive about using - * mipmaps in water areas because we need the speed in Uru. */ - - const float mipmap_scale_recip = - (do_shimmer ? 2.0f : 1.0f) / mipmap_scale; - const int32_t mipmap_switch_offset = - iceilf((mipmap_scale_recip - first_recip) / slope); - if (mipmap_switch_offset < 0) { - continue; - } - uint32_t mipmap_switch_index = - first_ground_index + mipmap_switch_offset; - if (mipmap_switch_index > last_ground_index + 1) { - mipmap_switch_index = last_ground_index + 1; - } - if (slope > 0) { - /* If there's only a small section to draw for this mipmap - * level, skip this iteration and draw it as part of the - * next, since we'll probably get better use of the GE's - * texture cache that way. */ - if (mipmap_switch_index <= index + 4) { - continue; - } - /* If we've covered the entire region with this mipmap - * level--or if this would leave only a small amount to - * draw with the next level, which again would make poor - * use of the texture cache, break out of the loop and let - * the last pass handle it with the already-computed - * vertices. Note that we explicitly don't update "index" - * in this case so the last pass is not skipped. */ - if (mipmap_switch_index > last_ground_index - 4) { - break; - } - } else { // slope < 0 - if (mipmap_switch_index >= index - 4) { - continue; - } - if (index <= first_ground_index + 4) { - index--; - } - } - index = mipmap_switch_index; // Save it for next time around. - - /* Compute switch line coordinates for the mipmap line. */ - - int mipmap_x0, mipmap_y0, mipmap_x1, mipmap_y1; - Azel_compute_switch(coef_base, mipmap_switch_index, coef_index_UL, - coef_index_UR, coef_index_LL, coef_index_LR, - coef_dx, coef_dy, &mipmap_x0, &mipmap_y0, - &mipmap_x1, &mipmap_y1); - - /* Compute vertices for the mipmapped region. This is a - * rectangle if the horizon line is horizontal or vertical, but - * may be a four-, five-, or six-sided polygon if the horizon - * is tilted. */ - - struct {int x, y;} mipmap_coords[6]; - unsigned int mipmap_nverts; - if (coef_dx == 0 || coef_dy == 0) { - mipmap_coords[0].x = switch_x0; - mipmap_coords[0].y = switch_y0; - mipmap_coords[1].x = switch_x1; - mipmap_coords[1].y = switch_y1; - mipmap_coords[2].x = mipmap_x0; - mipmap_coords[2].y = mipmap_y0; - mipmap_coords[3].x = mipmap_x1; - mipmap_coords[3].y = mipmap_y1; - mipmap_nverts = 4; - } else { - /* First determine which line is on top (has smaller - * Y coordinates), to simplify computations. We make use - * of the knowledge that Azel_compute_switch() assigns - * coordinates in the preference order top > left > right - * > bottom edge. Also swap the lower line's coordinates - * if necessary so they are in the same order as the upper - * line; depending on the position of the lines, the - * preference order may result in coordinates being - * swapped. */ - int switch_is_top, invert_second; - if (switch_y0 == 0) { - if (mipmap_y0 != 0) { - switch_is_top = 1; - invert_second = (switch_x1 < switch_x0 - && mipmap_x0 == 0); - } else if (switch_x1 < switch_x0) { - switch_is_top = (switch_x0 < mipmap_x0); - invert_second = 0; - } else { - switch_is_top = (switch_x0 > mipmap_x0); - invert_second = 0; - } - } else if (mipmap_y0 == 0) { - switch_is_top = 0; - invert_second = (mipmap_x1 < mipmap_x0 - && switch_x0 == 0); - } else if (switch_x0 == mipmap_x0) { - switch_is_top = (switch_y0 < mipmap_y0); - invert_second = 0; - } else { - /* One line connects the left and right edges, while - * the other runs from the right edge to the bottom. - * The line connecting the left and right edges is on - * top, and the coordinate order is switched. */ - switch_is_top = (switch_x0 == 0); - invert_second = 1; - } - const int x0 = switch_is_top ? switch_x0 : mipmap_x0; - const int y0 = switch_is_top ? switch_y0 : mipmap_y0; - const int x1 = switch_is_top ? switch_x1 : mipmap_x1; - const int y1 = switch_is_top ? switch_y1 : mipmap_y1; - const int x2 = (invert_second - ? (switch_is_top ? mipmap_x1 : switch_x1) - : (switch_is_top ? mipmap_x0 : switch_x0)); - const int y2 = (invert_second - ? (switch_is_top ? mipmap_y1 : switch_y1) - : (switch_is_top ? mipmap_y0 : switch_y0)); - const int x3 = (invert_second - ? (switch_is_top ? mipmap_x0 : switch_x0) - : (switch_is_top ? mipmap_x1 : switch_x1)); - const int y3 = (invert_second - ? (switch_is_top ? mipmap_y0 : switch_y0) - : (switch_is_top ? mipmap_y1 : switch_y1)); - /* The first two vertices are always the endpoints of the - * top line. Depending on where the region is located on - * the screen, one or two corners may also be included; we - * insert either a corner or an endpoint of the lower line - * as vertices 2 and 3, then add any remaining endpoints as - * vertices 4 and 5 if necessary. */ - mipmap_nverts = 4; - mipmap_coords[0].x = x0; - mipmap_coords[0].y = y0; - mipmap_coords[1].x = x1; - mipmap_coords[1].y = y1; - if ((y0 == 0 && x0 != 0 && x0 != disp_width) && y2 != 0) { - /* Region includes the upper-left or upper-right corner. */ - mipmap_coords[2].y = 0; - if (x2 == 0) { - mipmap_coords[2].x = 0; - } else { - mipmap_coords[2].x = disp_width; - } - mipmap_coords[mipmap_nverts].x = x2; - mipmap_coords[mipmap_nverts].y = y2; - mipmap_nverts++; - if (x1 == 0 && y1 != disp_height && x3 != 0) { - /* Region also includes the lower-left corner. */ - mipmap_coords[3].x = 0; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else if (x1 == disp_width && y1 != disp_height - && x3 != disp_width) { - /* Region also includes the lower-right corner. */ - mipmap_coords[3].x = disp_width; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else { - mipmap_coords[3].x = x3; - mipmap_coords[3].y = y3; - } - } else if ((x0 == 0 && y0 != 0 && y0 != disp_height) && x2 != 0) { - /* Region includes the lower-left corner. (In this - * case, the top line slants up-and-right and ends on - * the right edge of the screen.) */ - mipmap_coords[2].x = 0; - mipmap_coords[2].y = disp_height; - mipmap_coords[mipmap_nverts].x = x2; - mipmap_coords[mipmap_nverts].y = y2; - mipmap_nverts++; - mipmap_coords[3].x = x3; - mipmap_coords[3].y = y3; - } else { - /* Endpoint 0 of the horizon and mipmap lines are on - * the same edge of the screen. */ - mipmap_coords[2].x = x2; - mipmap_coords[2].y = y2; - if ((y0 == 0 || x0 == disp_width) - && (x1 == 0 && y1 != disp_height) - && x3 != 0 - ) { - /* Region includes the lower-left corner. */ - mipmap_coords[3].x = 0; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else if ((y0 == 0 || x0 == 0) - && (x1 == disp_width && y1 != disp_height) - && x3 != disp_width - ) { - /* Region includes the lower-right corner. */ - mipmap_coords[3].x = disp_width; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else { - mipmap_coords[3].x = x3; - mipmap_coords[3].y = y3; - } - } - } - - /* Draw the mipmapped region computed above. */ - - vertices = guGetMemory(sizeof(*vertices) * mipmap_nverts); - unsigned int i; - for (i = 0; i < mipmap_nverts; i++) { - vertices[i].x = mipmap_coords[i].x; - vertices[i].y = mipmap_coords[i].y; - const float coef_offset = coef_base - + vertices[i].x * coef_dx - + vertices[i].y * coef_dy - - first_ground_index; - vertices[i].z = - 1 / MAX(first_recip + coef_offset * slope, 1/127.5f); - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - ground_M, - vertices[i].z, vertices[i].z, - ground_Xp, ground_Yp); - vertices[i].u /= 512; - vertices[i].v /= 512; - if (do_shimmer) { - vertices[i].v += 0.01f * sinf(shimmer_step * (2*(float)M_PI)); - } - vertices[i].x = (vertices[i].x - disp_width/2) * vertices[i].z; - vertices[i].y = (vertices[i].y - disp_height/2) * vertices[i].z; - } - const unsigned int texture_size = 512 / mipmap_scale; - const uint8_t *texture_data = Azel_ground_cache; - for (i = 512; i > texture_size; i /= 2) { - texture_data += i * i; - } - guTexImage(0, texture_size, texture_size, texture_size, - texture_data); - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_3D | vertex_type, - mipmap_nverts, NULL, vertices); - - /* Recompute the vertex sets based on the mipmap line, so the - * final render iteration (with the full-size ground texture) - * skips the part we just drew. Since Azel_compute_vertices() - * uses the *_is_sky variables to determine whether the top or - * bottom portion is "ground", we need to tweak those variables - * in case the entire screen is "ground" so we get the proper - * region registered. Note that we don't check the actual - * coefficients, because that may give incorrect results due to - * the "shimmering" effect; instead, we compare the coefficient - * indices to the mipmap switch index. */ - - int UL_sky_2, UR_sky_2, LL_sky_2, LR_sky_2; - if (slope > 0) { - UL_sky_2 = (coef_index_UL < mipmap_switch_index); - UR_sky_2 = (coef_index_UR < mipmap_switch_index); - LL_sky_2 = (coef_index_LL < mipmap_switch_index); - LR_sky_2 = (coef_index_LR < mipmap_switch_index); - } else { - UL_sky_2 = (coef_index_UL >= mipmap_switch_index); - UR_sky_2 = (coef_index_UR >= mipmap_switch_index); - LL_sky_2 = (coef_index_LL >= mipmap_switch_index); - LR_sky_2 = (coef_index_LR >= mipmap_switch_index); - } - Azel_compute_vertices(UL_sky_2, UR_sky_2, LL_sky_2, LR_sky_2, - mipmap_x0, mipmap_y0, mipmap_x1, mipmap_y1, - coord, nverts); - ground_coord_set = (UL_sky_2 ? 1 : 0); - - /* Copy the mipmap line coordinates to switch_* for the next - * mipmap loop. */ - - switch_x0 = mipmap_x0; - switch_y0 = mipmap_y0; - switch_x1 = mipmap_x1; - switch_y1 = mipmap_y1; - - } // if using mipmap - - /* Generate and render vertices for the lowest-scale portion of the - * the plane, if any. */ - - if (slope > 0 ? index <= last_ground_index - : index > first_ground_index) { - vertices = guGetMemory(sizeof(*vertices) * nverts[ground_coord_set]); - unsigned int i; - for (i = 0; i < nverts[ground_coord_set]; i++) { - vertices[i].x = coord[ground_coord_set][i].x; - vertices[i].y = coord[ground_coord_set][i].y; - const float coef_offset = coef_base - + vertices[i].x * coef_dx - + vertices[i].y * coef_dy - - first_ground_index; - vertices[i].z = - 1 / MAX(first_recip + coef_offset * slope, 1/127.5f); - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - ground_M, - vertices[i].z, vertices[i].z, - ground_Xp, ground_Yp); - vertices[i].u /= (Azel_ground_reduced ? 1024 : 512); - vertices[i].v /= (Azel_ground_reduced ? 1024 : 512); - if (do_shimmer) { - /* Fake the "shimmering" effect with a simple sinusoidal - * offset. The PSP doesn't have enough hardware operators - * to do what we really want (which is multiply each - * texture coordinate by a*sin(b*y/z), where a and b are - * constants). */ - vertices[i].v += 0.01f * sinf(shimmer_step * (2*(float)M_PI)); - } - vertices[i].x = (vertices[i].x - disp_width/2) * vertices[i].z; - vertices[i].y = (vertices[i].y - disp_height/2) * vertices[i].z; - } - const unsigned int texture_size = 512 / mipmap_scale; - const uint8_t *texture_data = Azel_ground_cache; - for (i = 512; i > texture_size; i /= 2) { - texture_data += i * i; - } - guTexImage(0, texture_size, texture_size, texture_size, - texture_data); - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_3D | vertex_type, - nverts[ground_coord_set], NULL, vertices); - } - - } // if (ground_min == ground_max) - - /* All done. Make sure to reset the wrapping flags since other code - * will expect wraparound to be disabled. */ - - guTexWrap(GU_CLAMP, GU_CLAMP); - return 1; - - #undef READ_COEF -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_get_rotation_matrix: Calculate the rotation matrix and scaling - * parameters for a sky or ground parameter set. Helper function for - * Azel_draw_RBG0(). - * - * [Parameters] - * address: Address of parameter set in VDP2 RAM - * M: Pointer to 2x3 array to receive rotation matrix values - * kx_ret: Pointer to variable to receive X scale value (NULL allowed) - * ky_ret: Pointer to variable to receive Y scale value (NULL allowed) - * Xp_ret: Pointer to variable to receive X offset value - * Yp_ret: Pointer to variable to receive Y offset value - * [Return value] - * None - */ -static void Azel_get_rotation_matrix(uint32_t address, float M[2][3], - float *kx_ret, float *ky_ret, - float *Xp_ret, float *Yp_ret) -{ - /* The GET_* macros are borrowed from psp-video-rotate.c. */ - - #define GET_SHORT(nbits) \ - (address += 2, (int32_t)((int16_t)T1ReadWord(Vdp2Ram,address-2) \ - << (16-nbits)) >> (16-nbits)) - #define GET_SIGNED_FLOAT(nbits) \ - (address += 4, ((((int32_t)T1ReadLong(Vdp2Ram,address-4) \ - << (32-nbits)) >> (32-nbits)) & ~0x3F) / 65536.0f) - #define GET_UNSIGNED_FLOAT(nbits) \ - (address += 4, (((uint32_t)T1ReadLong(Vdp2Ram,address-4) \ - & (0xFFFFFFFFU >> (32-nbits))) & ~0x3F) / 65536.0f) - - const float Xst = GET_SIGNED_FLOAT(29); - const float Yst = GET_SIGNED_FLOAT(29); - const float Zst = GET_SIGNED_FLOAT(29); - const float deltaXst = GET_SIGNED_FLOAT(19); - const float deltaYst = GET_SIGNED_FLOAT(19); - const float deltaX = GET_SIGNED_FLOAT(19); - const float deltaY = GET_SIGNED_FLOAT(19); - const float A = GET_SIGNED_FLOAT(20); - const float B = GET_SIGNED_FLOAT(20); - const float C = GET_SIGNED_FLOAT(20); - const float D = GET_SIGNED_FLOAT(20); - const float E = GET_SIGNED_FLOAT(20); - const float F = GET_SIGNED_FLOAT(20); - const float Px = GET_SHORT(14); - const float Py = GET_SHORT(14); - const float Pz = GET_SHORT(14); - address += 2; - const float Cx = GET_SHORT(14); - const float Cy = GET_SHORT(14); - const float Cz = GET_SHORT(14); - address += 2; - const float Mx = GET_SIGNED_FLOAT(30); - const float My = GET_SIGNED_FLOAT(30); - const float kx = GET_SIGNED_FLOAT(24); - const float ky = GET_SIGNED_FLOAT(24); - - #undef GET_SHORT - #undef GET_SIGNED_FLOAT - #undef GET_UNSIGNED_FLOAT - - M[0][0] = (A * deltaX) + (B * deltaY); - M[0][1] = (A * deltaXst) + (B * deltaYst); - M[0][2] = (A * (Xst - Px)) + (B * (Yst - Py)) + (C * (Zst - Pz)); - M[1][0] = (D * deltaX) + (E * deltaY); - M[1][1] = (D * deltaXst) + (E * deltaYst); - M[1][2] = (D * (Xst - Px)) + (E * (Yst - Py)) + (F * (Zst - Pz)); - *Xp_ret = (A * (Px - Cx)) + (B * (Py - Cy)) + (C * (Pz - Cz)) + Cx + Mx; - *Yp_ret = (D * (Px - Cx)) + (E * (Py - Cy)) + (F * (Pz - Cz)) + Cy + My; - - if (kx_ret) { - *kx_ret = kx; - } - if (ky_ret) { - *ky_ret = ky; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_transform_coordinates: Transform screen to texture coordinates - * given the rotation matrix and scaling parameters for a sky or ground - * parameter set. Helper function for Azel_draw_RBG0(). - * - * [Parameters] - * x, y: Screen coordinates to transform - * u_ret, v_ret: Pointers to variables to receive transformed coordinates - * M: Pointer to 2x3 array containing rotation matrix values - * kx, ky: X/Y scale values - * Xp, Yp: X/Y offset values - * [Return value] - * None - */ -static void Azel_transform_coordinates(const float x, const float y, - float *u_ret, float *v_ret, - float M[2][3], - const float kx, const float ky, - const float Xp, const float Yp) -{ - *u_ret = (M[0][0]*x + M[0][1]*y + M[0][2]) * kx + Xp; - *v_ret = (M[1][0]*x + M[1][1]*y + M[1][2]) * ky + Yp; -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_compute_switch: Compute the endpoints of the switch (horizon) line - * between sky and ground. Helper function for Azel_draw_RBG0(). - * - * [Parameters] - * All parameters are local variables or pointers thereto passed from - * Azel_draw_RBG0() - * [Return value] - * None - */ -static inline void Azel_compute_switch( - uint32_t coef_base, uint32_t coef_switch_index, - const uint32_t coef_index_UL, const uint32_t coef_index_UR, - const uint32_t coef_index_LL, const uint32_t coef_index_LR, - float coef_dx, float coef_dy, - int *switch_x0, int *switch_y0, int *switch_x1, int *switch_y1) -{ - *switch_x0 = *switch_y0 = *switch_x1 = *switch_y1 = -1; - - if (coef_dx == 0) { - - *switch_x0 = 0; - *switch_y0 = iceilf((coef_switch_index - coef_base) / coef_dy); - *switch_x1 = disp_width; - *switch_y1 = *switch_y0; - - } else if (coef_dy == 0) { - - *switch_x0 = iceilf((coef_switch_index - coef_base) / coef_dx); - *switch_y0 = 0; - *switch_x1 = *switch_x0; - *switch_y1 = disp_height; - - } else { // coef_dx != 0 && coef_dy != 0 - - const float top_x = - (int32_t)(coef_switch_index - coef_index_UL) / coef_dx; - if (top_x > -1 && top_x <= disp_width) { - *switch_x0 = iceilf(top_x); - *switch_y0 = 0; - } - const float bottom_x = - (int32_t)(coef_switch_index - coef_index_LL) / coef_dx; - if (bottom_x > -1 && bottom_x <= disp_width) { - *switch_x1 = iceilf(bottom_x); - *switch_y1 = disp_height; - } - const float left_y = - (int32_t)(coef_switch_index - coef_index_UL) / coef_dy; - if (left_y > -1 && left_y <= disp_height) { - if (*switch_x0 < 0) { - *switch_x0 = 0; - *switch_y0 = iceilf(left_y); - } else if (*switch_x1 < 0) { - *switch_x1 = 0; - *switch_y1 = iceilf(left_y); - } - } - const float right_y = - (int32_t)(coef_switch_index - coef_index_UR) / coef_dy; - if (right_y > -1 && right_y <= disp_height) { - if (*switch_x0 < 0) { - *switch_x0 = disp_width; - *switch_y0 = iceilf(right_y); - } else if (*switch_x1 < 0) { - *switch_x1 = disp_width; - *switch_y1 = iceilf(right_y); - } - } - - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_compute_vertices: Compute the two sets of vertices for drawing - * sky and ground sections of an RBG0 layer. Helper function for - * Azel_draw_RBG0(). - * - * [Parameters] - * All parameters are local variables/arrays passed from Azel_draw_RBG0() - * [Return value] - * None - */ -static inline void Azel_compute_vertices( - int UL_is_sky, int UR_is_sky, int LL_is_sky, int LR_is_sky, - int switch_x0, int switch_y0, int switch_x1, int switch_y1, - struct Azel_RBG0_coord coord[2][5], unsigned int nverts[2]) -{ - coord[0][0].x = 0; - coord[0][0].y = 0; - coord[0][0].overdraw_x = -1; - coord[0][0].overdraw_y = -1; - - if (UR_is_sky == UL_is_sky) { - - coord[0][1].x = disp_width; - coord[0][1].y = 0; - coord[0][1].overdraw_x = +1; - coord[0][1].overdraw_y = -1; - - if (LL_is_sky == LR_is_sky) { - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - coord[0][3].x = switch_x1; - coord[0][3].y = switch_y1; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - nverts[0] = 4; - - if (LL_is_sky == UL_is_sky) { - nverts[1] = 0; - } else { - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = -1; - coord[1][2].x = 0; - coord[1][2].y = disp_height; - coord[1][2].overdraw_x = -1; - coord[1][2].overdraw_y = +1; - coord[1][3].x = disp_width; - coord[1][3].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - nverts[1] = 4; - } - - } else if (LL_is_sky == UL_is_sky) { - - coord[0][2].x = 0; - coord[0][2].y = disp_height; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - coord[0][3].x = switch_x0; - coord[0][3].y = switch_y0; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - coord[0][4].x = switch_x1; - coord[0][4].y = switch_y1; - coord[0][4].overdraw_x = +1; - coord[0][4].overdraw_y = +1; - nverts[0] = 5; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = +1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = -1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = disp_width; - coord[1][2].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - nverts[1] = 3; - - } else { // LR_is_sky == UL_is_sky - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - coord[0][3].x = disp_width; - coord[0][3].y = disp_height; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - coord[0][4].x = switch_x1; - coord[0][4].y = switch_y1; - coord[0][4].overdraw_x = -1; - coord[0][4].overdraw_y = +1; - nverts[0] = 5; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = 0; - coord[1][2].y = disp_height; - coord[1][2].overdraw_x = -1; - coord[1][2].overdraw_y = +1; - nverts[1] = 3; - - } - - } else if (LL_is_sky == UL_is_sky) { - - coord[0][1].x = 0; - coord[0][1].y = disp_height; - coord[0][1].overdraw_x = -1; - coord[0][1].overdraw_y = +1; - - if (LR_is_sky != UL_is_sky) { - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = +1; - coord[0][2].overdraw_y = -1; - coord[0][3].x = switch_x1; - coord[0][3].y = switch_y1; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - nverts[0] = 4; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = -1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = disp_width; - coord[1][2].y = 0; - coord[1][2].overdraw_x = +1; - coord[1][2].overdraw_y = -1; - coord[1][3].x = disp_width; - coord[1][3].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - nverts[1] = 4; - - } else { // LR_is_sky == UL_is_sky - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = +1; - coord[0][2].overdraw_y = -1; - coord[0][3].x = disp_width; - coord[0][3].y = disp_height; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - coord[0][4].x = switch_x1; - coord[0][4].y = switch_y1; - coord[0][4].overdraw_x = +1; - coord[0][4].overdraw_y = -1; - nverts[0] = 5; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = disp_width; - coord[1][2].y = 0; - coord[1][2].overdraw_x = +1; - coord[1][2].overdraw_y = -1; - nverts[1] = 3; - - } - - } else { - - coord[0][1].x = switch_x0; - coord[0][1].y = switch_y0; - coord[0][1].overdraw_x = +1; - coord[0][1].overdraw_y = -1; - coord[0][2].x = switch_x1; - coord[0][2].y = switch_y1; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - nverts[0] = 3; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = disp_width; - coord[1][1].y = 0; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = -1; - coord[1][2].x = switch_x1; - coord[1][2].y = switch_y1; - coord[1][2].overdraw_x = -1; - coord[1][2].overdraw_y = -1; - coord[1][3].x = disp_width; - coord[1][3].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - coord[1][4].x = 0; - coord[1][4].y = disp_height; - coord[1][4].overdraw_x = -1; - coord[1][4].overdraw_y = +1; - nverts[1] = 5; - - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video.c b/yabause/src/psp/psp-video.c deleted file mode 100644 index de30aaa4e3..0000000000 --- a/yabause/src/psp/psp-video.c +++ /dev/null @@ -1,2160 +0,0 @@ -/* src/psp/psp-video.c: PSP video interface module - Copyright 2009-2010 Andrew Church - Based on src/vidogl.c by Guillaume Duhamel and others - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vdp1.h" -#include "../vdp2.h" -#include "../vidshared.h" - -#include "config.h" -#include "display.h" -#include "font.h" -#include "gu.h" -#include "misc.h" -#include "psp-video.h" -#include "psp-video-internal.h" -#include "texcache.h" -#include "timing.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_video_init(void); -static void psp_video_deinit(void); -static void psp_video_resize(unsigned int width, unsigned int height, - int fullscreen); -static int psp_video_is_fullscreen(void); -static void psp_video_debug_message(char *format, ...); - -static int psp_vdp1_reset(void); -static void psp_vdp1_draw_start(void); -static void psp_vdp1_draw_end(void); -static void psp_vdp1_normal_sprite_draw(void); -static void psp_vdp1_scaled_sprite_draw(void); -static void psp_vdp1_distorted_sprite_draw(void); -static void psp_vdp1_polygon_draw(void); -static void psp_vdp1_polyline_draw(void); -static void psp_vdp1_line_draw(void); -static void psp_vdp1_user_clipping(void); -static void psp_vdp1_system_clipping(void); -static void psp_vdp1_local_coordinate(void); - -static int psp_vdp2_reset(void); -static void psp_vdp2_draw_start(void); -static void psp_vdp2_draw_end(void); -static void psp_vdp2_draw_screens(void); -static void psp_vdp2_set_resolution(u16 TVMD); -static void FASTCALL psp_vdp2_set_priority_NBG0(int priority); -static void FASTCALL psp_vdp2_set_priority_NBG1(int priority); -static void FASTCALL psp_vdp2_set_priority_NBG2(int priority); -static void FASTCALL psp_vdp2_set_priority_NBG3(int priority); -static void FASTCALL psp_vdp2_set_priority_RBG0(int priority); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -VideoInterface_struct VIDPSP = { - .id = VIDCORE_PSP, - .Name = "PSP Video Interface", - .Init = psp_video_init, - .DeInit = psp_video_deinit, - .Resize = psp_video_resize, - .IsFullscreen = psp_video_is_fullscreen, - .OnScreenDebugMessage = psp_video_debug_message, - - .Vdp1Reset = psp_vdp1_reset, - .Vdp1DrawStart = psp_vdp1_draw_start, - .Vdp1DrawEnd = psp_vdp1_draw_end, - .Vdp1NormalSpriteDraw = psp_vdp1_normal_sprite_draw, - .Vdp1ScaledSpriteDraw = psp_vdp1_scaled_sprite_draw, - .Vdp1DistortedSpriteDraw = psp_vdp1_distorted_sprite_draw, - .Vdp1PolygonDraw = psp_vdp1_polygon_draw, - .Vdp1PolylineDraw = psp_vdp1_polyline_draw, - .Vdp1LineDraw = psp_vdp1_line_draw, - .Vdp1UserClipping = psp_vdp1_user_clipping, - .Vdp1SystemClipping = psp_vdp1_system_clipping, - .Vdp1LocalCoordinate = psp_vdp1_local_coordinate, - - .Vdp2Reset = psp_vdp2_reset, - .Vdp2DrawStart = psp_vdp2_draw_start, - .Vdp2DrawEnd = psp_vdp2_draw_end, - .Vdp2DrawScreens = psp_vdp2_draw_screens, - .Vdp2SetResolution = psp_vdp2_set_resolution, - .Vdp2SetPriorityNBG0 = psp_vdp2_set_priority_NBG0, - .Vdp2SetPriorityNBG1 = psp_vdp2_set_priority_NBG1, - .Vdp2SetPriorityNBG2 = psp_vdp2_set_priority_NBG2, - .Vdp2SetPriorityNBG3 = psp_vdp2_set_priority_NBG3, - .Vdp2SetPriorityRBG0 = psp_vdp2_set_priority_RBG0, -}; - -/*************************************************************************/ -/************************* Global and local data *************************/ -/*************************************************************************/ - -/**** Exported data ****/ - -/* Color table generated from VDP2 color RAM */ -__attribute__((aligned(64))) uint16_t global_clut_16[0x800]; -__attribute__((aligned(64))) uint32_t global_clut_32[0x800]; - -/* Displayed width and height */ -unsigned int disp_width, disp_height; - -/* Scale (right-shift) applied to X and Y coordinates */ -unsigned int disp_xscale, disp_yscale; - -/* Total number of frames to skip before we draw the next one */ -unsigned int frames_to_skip; - -/* Number of frames skipped so far since we drew the last one */ -unsigned int frames_skipped; - -/* VDP1 color component offset values (-0xFF...+0xFF) */ -int32_t vdp1_rofs, vdp1_gofs, vdp1_bofs; - -/*-----------------------------------------------------------------------*/ - -/**** Internal data ****/ - -/*----------------------------------*/ - -/* Pending infoline text (malloc()ed, or NULL if none) and color */ -static char *infoline_text; -static uint32_t infoline_color; - -/*----------------------------------*/ - -/* Current average frame rate (rolling average) */ -static float average_fps; - -/* Flag indicating whether graphics should be drawn this frame */ -static uint8_t draw_graphics; - -/* Background priorities (NBG0, NBG1, NBG2, NBG3, RBG0) */ -static uint8_t bg_priority[5]; - -/*----------------------------------*/ - -/* Custom drawing function specified for each background layer */ -static CustomDrawRoutine *custom_draw_func[5]; - -/* Is the RBG0 drawing function fast enough to consider it a normal layer - * for timing purposes? */ -static uint8_t RBG0_draw_func_is_fast; - -/* Did we draw a slow RBG0 this frame? */ -static uint8_t drew_slow_RBG0; - -/*----------------------------------*/ - -/* Rendering data for sprites, polygons, and lines (a copy of all - * parameters except priority passed to vdp1_render_queue() */ -typedef struct VDP1RenderData_ { - uint32_t texture_key; - int primitive; - int vertex_type; - int count; - const void *indices; - const void *vertices; -} VDP1RenderData; - -/* VDP1 render queues (one for each priority level) */ -typedef struct VDP1RenderQueue_ { - VDP1RenderData *queue; // Array of entries (dynamically expanded) - int size; // Size of queue array, in entries - int len; // Number of entries currently in array -} VDP1RenderQueue; -static VDP1RenderQueue vdp1_queue[8]; - -/* Amount to expand a queue's array when it gets full */ -#define VDP1_QUEUE_EXPAND_SIZE 1000 - -/*----------------------------------*/ - -/* Flags indicating whether each 4k page of VDP1/2 RAM contains any - * persistently-cached texture data */ -static uint8_t vdp1_page_cached[0x80], vdp2_page_cached[0x80]; - -/* Checksum of each VDP1/2 RAM page containing cached texture data */ -static uint32_t vdp1_page_checksum[0x80], vdp2_page_checksum[0x80]; - -/* State of color offset settings at last cache reset */ -static uint32_t vdp1_cached_cofs; -static uint32_t vdp2_cached_cofs_regs; // CLOFEN<<16 | CLOFSL -static uint32_t vdp2_cached_cofs_A, vdp2_cached_cofs_B; - -/*************************************************************************/ - -/**** Local function declarations ****/ - -static int vdp1_is_persistent(vdp1cmd_struct *cmd); -static void vdp1_draw_lines(vdp1cmd_struct *cmd, int poly); -static void vdp1_draw_quad(vdp1cmd_struct *cmd, int textured); -static uint32_t vdp1_convert_color(uint16_t color16, int textured, - unsigned int CMDPMOD); -static uint32_t vdp1_get_cmd_color(vdp1cmd_struct *cmd); -static uint32_t vdp1_get_cmd_color_pri(vdp1cmd_struct *cmd, int textured, - int *priority_ret); -static uint16_t vdp1_process_sprite_color(uint16_t color16, int *priority_ret, - int *alpha_ret); -static uint32_t vdp1_cache_sprite_texture( - vdp1cmd_struct *cmd, int width, int height, int *priority_ret, - int *alpha_ret); -static inline void vdp1_queue_render( - int priority, uint32_t texture_key, int primitive, - int vertex_type, int count, const void *indices, const void *vertices); -static void vdp1_run_queue(int priority); - -static inline void vdp2_get_color_offsets(uint16_t mask, int32_t *rofs_ret, - int32_t *gofs_ret, int32_t *bofs_ret); - -static void vdp2_draw_bg(void); -static void vdp2_draw_graphics(int layer); - -/*************************************************************************/ -/********************** General interface functions **********************/ -/*************************************************************************/ - -/** - * psp_video_init: Initialize the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_video_init(void) -{ - /* Set some reasonable defaults. */ - disp_width = 320; - disp_height = 224; - disp_xscale = 0; - disp_yscale = 0; - - /* Always draw the first frame. */ - frames_to_skip = 0; - frames_skipped = 0; - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_video_deinit: Shut down the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_video_deinit(void) -{ - /* We don't implement shutting down, so nothing to do. */ -} - -/*************************************************************************/ - -/** - * psp_video_resize: Resize the display window. A no-op on PSP. - * - * [Parameters] - * width: New window width - * height: New window height - * fullscreen: Nonzero to use fullscreen mode, else zero - * [Return value] - * None - */ -static void psp_video_resize(unsigned int width, unsigned int height, - int fullscreen) -{ -} - -/*************************************************************************/ - -/** - * psp_video_is_fullscreen: Return whether the display is currently in - * fullscreen mode. Always returns true (nonzero) on PSP. - * - * [Parameters] - * None - * [Return value] - * Nonzero if in fullscreen mode, else zero - */ -static int psp_video_is_fullscreen(void) -{ - return 1; -} - -/*************************************************************************/ - -/** - * psp_video_debug_message: Display a debug message on the screen. - * - * [Parameters] - * format: printf()-style format string - * [Return value] - * None - */ -static void psp_video_debug_message(char *format, ...) -{ - /* Not implemented */ -} - -/*************************************************************************/ -/********************* PSP-only interface functions **********************/ -/*************************************************************************/ - -/** - * psp_video_infoline: Display an information line on the bottom of the - * screen. The text will be displayed for one frame only; call this - * function every frame to keep the text visible. - * - * [Parameters] - * color: Text color (0xAABBGGRR) - * text: Text string - * [Return value] - * None - */ -void psp_video_infoline(uint32_t color, const char *text) -{ - infoline_text = strdup(text); - if (UNLIKELY(!infoline_text)) { - DMSG("Failed to strdup(%s)", text); - } - infoline_color = color; -} - -/*************************************************************************/ - -/** - * psp_video_set_draw_routine: Set a custom drawing routine for a specific - * graphics layer. If "is_fast" is true when setting a routine for RBG0, - * the frame rate will not be halved regardless of the related setting in - * the configuration menu. - * - * [Parameters] - * layer: Graphics layer (BG_*) - * func: Drawing routine (NULL to clear any previous setting) - * is_fast: For BG_RBG0, indicates whether the routine is fast enough - * to be considered a non-distorted layer for the purposes - * of frame rate adjustment; ignored for other layers - * [Return value] - * None - */ -void psp_video_set_draw_routine(int layer, CustomDrawRoutine *func, - int is_fast) -{ - PRECOND(layer >= BG_NBG0 && layer <= BG_RBG0, return); - custom_draw_func[layer] = func; - if (layer == BG_RBG0) { - RBG0_draw_func_is_fast = is_fast; - } -} - -/*************************************************************************/ - -/** - * vdp2_is_persistent: Return whether the tile at the given address in - * VDP2 RAM is persistently cacheable. - * - * [Parameters] - * address: Tile address in VDP2 RAM - * [Return value] - * Nonzero if tile texture can be persistently cached, else zero - */ -int vdp2_is_persistent(uint32_t address) -{ - const unsigned int page = address >> 12; - if (!vdp2_page_cached[page]) { - vdp2_page_checksum[page] = - checksum_fast32((const uint32_t *)(Vdp2Ram + (page<<12)), 1024); - vdp2_page_cached[page] = 1; - } - return 1; -} - -/*************************************************************************/ -/******************* VDP1-specific interface functions *******************/ -/*************************************************************************/ - -/** - * psp_vdp1_reset: Reset the VDP1 state. - * - * [Parameters] - * None - * [Return value] - * Unknown (always zero) - */ -static int psp_vdp1_reset(void) -{ - /* Nothing to do. */ - return 0; -} - -/*************************************************************************/ - -/** - * psp_vdp1_draw_start: Prepare for VDP1 drawing. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_draw_start(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - /* Clear out all the rendering queues (just to be safe). */ - int priority; - for (priority = 0; priority < 8; priority++) { - vdp1_queue[priority].len = 0; - } - - /* Get the color offsets. */ - vdp2_get_color_offsets(1<<6, &vdp1_rofs, &vdp1_gofs, &vdp1_bofs); -} - -/*************************************************************************/ - - -/** - * psp_vdp1_draw_end: Finish VDP1 drawing. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_draw_end(void) -{ - /* Nothing to do */ -} - -/*************************************************************************/ - - -/** - * psp_vdp1_normal_sprite_draw: Draw an unscaled rectangular sprite. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_normal_sprite_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - int width = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - int height = cmd.CMDSIZE & 0xFF; - cmd.CMDXB = cmd.CMDXA + width; cmd.CMDYB = cmd.CMDYA; - cmd.CMDXC = cmd.CMDXA + width; cmd.CMDYC = cmd.CMDYA + height; - cmd.CMDXD = cmd.CMDXA; cmd.CMDYD = cmd.CMDYA + height; - - vdp1_draw_quad(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_scaled_sprite_draw: Draw a scaled rectangular sprite. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_scaled_sprite_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - if (!(cmd.CMDCTRL & 0x0F00)) { - /* Size is directly specified. */ - cmd.CMDXC++; cmd.CMDYC++; - cmd.CMDXB = cmd.CMDXC; cmd.CMDYB = cmd.CMDYA; - cmd.CMDXD = cmd.CMDXA; cmd.CMDYD = cmd.CMDYC; - } else { - /* Scale around a particular point (left/top, center, right/bottom). */ - int new_w = cmd.CMDXB + 1; - int new_h = cmd.CMDYB + 1; - if ((cmd.CMDCTRL & 0x300) == 0x200) { - cmd.CMDXA -= cmd.CMDXB / 2; - } else if ((cmd.CMDCTRL & 0x300) == 0x300) { - cmd.CMDXA -= cmd.CMDXB; - } - if ((cmd.CMDCTRL & 0xC00) == 0x800) { - cmd.CMDYA -= cmd.CMDYB / 2; - } else if ((cmd.CMDCTRL & 0xC00) == 0xC00) { - cmd.CMDYA -= cmd.CMDYB; - } - cmd.CMDXB = cmd.CMDXA + new_w; cmd.CMDYB = cmd.CMDYA; - cmd.CMDXC = cmd.CMDXA + new_w; cmd.CMDYC = cmd.CMDYA + new_h; - cmd.CMDXD = cmd.CMDXA; cmd.CMDYD = cmd.CMDYA + new_h; - } - - vdp1_draw_quad(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_distorted_sprite_draw: Draw a sprite on an arbitrary - * quadrilateral. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_distorted_sprite_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_quad(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_polygon_draw: Draw an untextured quadrilateral. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_polygon_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_quad(&cmd, 0); -} - -/*************************************************************************/ - -/** - * psp_vdp1_polyline_draw: Draw four connected lines. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_polyline_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_lines(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_line_draw: Draw a single line. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_line_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_lines(&cmd, 0); -} - -/*************************************************************************/ - -/** - * psp_vdp1_user_clipping: Set the user clipping coordinates. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_user_clipping(void) -{ - Vdp1Regs->userclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->userclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); - Vdp1Regs->userclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->userclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -/*************************************************************************/ - -/** - * psp_vdp1_system_clipping: Set the system clipping coordinates. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_system_clipping(void) -{ - Vdp1Regs->systemclipX1 = 0; - Vdp1Regs->systemclipY1 = 0; - Vdp1Regs->systemclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->systemclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -/*************************************************************************/ - -/** - * psp_vdp1_local_coordinate: Set coordinate offset values used in drawing - * primitives. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_local_coordinate(void) -{ - Vdp1Regs->localX = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->localY = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); -} - -/*************************************************************************/ -/******************* VDP2-specific interface functions *******************/ -/*************************************************************************/ - -/** - * psp_vdp2_reset: Reset the VDP2 state. - * - * [Parameters] - * None - * [Return value] - * Unknown (always zero) - */ -static int psp_vdp2_reset(void) -{ - /* Nothing to do */ - return 0; -} - -/*************************************************************************/ - -/** - * psp_vdp2_draw_start: Begin drawing a video frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp2_draw_start(void) -{ - /* Apply any game-specific optimizations or tweaks. (This may involve - * adjusting the frame-skip variables, so we call it before the - * frame-skip check.) */ - psp_video_apply_tweaks(); - - /* If we're skipping this frame, we don't do anything, not even start - * a new output frame (because that forces a VBlank sync, which may - * waste time if the previous frame completed quickly). */ - if (frames_skipped < frames_to_skip) { - return; - } - - /* Load the global color lookup tables from VDP2 color RAM. */ - const uint16_t *cram = (const uint16_t *)Vdp2ColorRam; - if (Vdp2Internal.ColorMode == 2) { // 32-bit color table - int i; - for (i = 0; i < 0x400; i++) { - uint16_t xb = cram[i*2+0]; - uint16_t gr = cram[i*2+1]; - uint16_t color16 = 0x8000 | (xb<<7 & 0x7C00) - | (gr<<2 & 0x3E0) | (gr>>3 & 0x1F); - uint32_t color32 = 0xFF000000 | xb<<16 | gr; - global_clut_16[i] = color16; - global_clut_16[i+0x400] = color16; - global_clut_32[i] = color32; - global_clut_32[i+0x400] = color32; - } - } else { // 16-bit color table - int i; - for (i = 0; i < 0x800; i++) { - uint16_t color16 = 0x8000 | cram[i]; - uint32_t color32 = 0xFF000000 | (color16 & 0x7C00) << 9 - | (color16 & 0x03E0) << 6 - | (color16 & 0x001F) << 3; - global_clut_16[i] = color16; - global_clut_32[i] = color32; - } - } - - /* Start a new frame. */ - display_set_size(disp_width >> disp_xscale, disp_height >> disp_yscale); - display_begin_frame(); - - /* Clear the texture cache of transient data; also clear persistent - * data if any source RAM or color offsets were changed, or if - * persistent caching is disabled in the first place. */ - const uint32_t vdp1_cofs = (vdp1_rofs & 0x1FF) << 18 - | (vdp1_gofs & 0x1FF) << 9 - | (vdp1_bofs & 0x1FF) << 0; - const uint32_t vdp2_cofs_regs = Vdp2Regs->CLOFEN << 16 | Vdp2Regs->CLOFSL; - const uint32_t vdp2_cofs_A = (Vdp2Regs->COAR & 0x1FF) << 18 - | (Vdp2Regs->COAG & 0x1FF) << 9 - | (Vdp2Regs->COAB & 0x1FF) << 0; - const uint32_t vdp2_cofs_B = (Vdp2Regs->COBR & 0x1FF) << 18 - | (Vdp2Regs->COBG & 0x1FF) << 9 - | (Vdp2Regs->COBB & 0x1FF) << 0; - int need_reset = 0; - if (!config_get_cache_textures()) { - need_reset = 1; - } else if (vdp1_cofs != vdp1_cached_cofs - || vdp2_cofs_regs != vdp2_cached_cofs_regs - || vdp2_cofs_A != vdp2_cached_cofs_A - || vdp2_cofs_B != vdp2_cached_cofs_B) { - DMSG("Color offsets changed, clearing cache"); - need_reset = 1; - } else { - unsigned int page; - for (page = 0; page < 0x80; page++) { - if (vdp1_page_cached[page]) { - const uint32_t sum = - checksum_fast32((const uint32_t *)(Vdp1Ram + (page<<12)), 1024); - if (sum != vdp1_page_checksum[page]) { - DMSG("VDP1 page 0x%05X checksum changed (%08X -> %08X)," - " clearing cache", - page<<12, vdp1_page_checksum[page], sum); - need_reset = 1; - break; - } - } - if (vdp2_page_cached[page]) { - const uint32_t sum = - checksum_fast32((const uint32_t *)(Vdp2Ram + (page<<12)), 1024); - if (sum != vdp2_page_checksum[page]) { - DMSG("VDP2 page 0x%05X checksum changed (%08X -> %08X)," - " clearing cache", - page<<12, vdp2_page_checksum[page], sum); - need_reset = 1; - break; - } - } - } - } - if (need_reset) { - texcache_reset(); - memset(vdp1_page_cached, 0, sizeof(vdp1_page_cached)); - memset(vdp2_page_cached, 0, sizeof(vdp2_page_cached)); - } else { - texcache_clean(); - } - vdp1_cached_cofs = vdp1_cofs; - vdp2_cached_cofs_regs = vdp2_cofs_regs; - vdp2_cached_cofs_A = vdp2_cofs_A; - vdp2_cached_cofs_B = vdp2_cofs_B; - - /* Initialize the render state. */ - guTexFilter(GU_NEAREST, GU_NEAREST); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - guBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - guEnable(GU_BLEND); // We treat everything as alpha-enabled - - /* Reset the draw-graphics flag (it will be set by draw_screens() if - * graphics are active). */ - draw_graphics = 0; -} - -/*************************************************************************/ - -/** - * psp_vdp2_draw_end: Finish drawing a video frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp2_draw_end(void) -{ - if (frames_skipped >= frames_to_skip) { - - /* Draw all graphics by priority. */ - int priority; - for (priority = 0; priority < 8; priority++) { - /* Draw background graphics first... */ - if (draw_graphics && priority > 0) { - if (bg_priority[BG_NBG3] == priority) { - vdp2_draw_graphics(BG_NBG3); - } - if (bg_priority[BG_NBG2] == priority) { - vdp2_draw_graphics(BG_NBG2); - } - if (bg_priority[BG_NBG1] == priority) { - vdp2_draw_graphics(BG_NBG1); - } - if (bg_priority[BG_NBG0] == priority) { - vdp2_draw_graphics(BG_NBG0); - } - if (bg_priority[BG_RBG0] == priority) { - vdp2_draw_graphics(BG_RBG0); - } - } - /* Then draw sprites on top... */ - vdp1_run_queue(priority); - /* And clear the rendering queue. */ - vdp1_queue[priority].len = 0; - } - - /* Always compute average FPS (even if we're not showing it), so - * the value is accurate as soon as the display is turned on. - * We use a rolling average that decays by 50% every second. */ - unsigned int frame_length = display_last_frame_length(); - if (frame_length == 0) { - frame_length = 1; // Just in case (avoid division by 0) - } - unsigned int frame_count = 1 + frames_skipped; - const float fps = (frame_count*60.0f) / frame_length; - if (!average_fps) { - /* When first starting up, just set the average to the first - * frame's frame rate. */ - average_fps = fps; - } else { - const float weight = powf(2.0f, -(1/fps)); - average_fps = (average_fps * weight) + (fps * (1-weight)); - } - if (config_get_show_fps()) { - unsigned int show_fps = iroundf(average_fps*10); - if (show_fps > 600) { - /* FPS may momentarily exceed 60.0 due to timing jitter, - * but we never show more than 60.0. */ - show_fps = 600; - } - font_printf((disp_width >> disp_xscale) - 2, 2, 1, 0xAAFF8040, - "FPS: %2d.%d (%d/%2d)", show_fps/10, show_fps%10, - frame_count, frame_length); - } - - if (infoline_text) { - font_printf((disp_width >> disp_xscale) / 2, - (disp_height >> disp_yscale) - FONT_HEIGHT - 2, 0, - infoline_color, "%s", infoline_text); - free(infoline_text); - infoline_text = NULL; - } - - display_end_frame(); - - } // if (frames_skipped >= frames_to_skip) - - if (frames_skipped < frames_to_skip) { - frames_skipped++; - timing_skip_next_sync(); // Let the emulation continue uninterrupted - } else { - frames_skipped = 0; - if (config_get_frameskip_auto()) { - // FIXME: auto frame skipping not yet implemented - frames_to_skip = 0; - } else { - frames_to_skip = config_get_frameskip_num(); - } - if (drew_slow_RBG0) { - frames_to_skip += 1 + frames_to_skip; - } - if (disp_height > 272 && frames_to_skip == 0 - && config_get_frameskip_interlace() - ) { - frames_to_skip = 1; - } - drew_slow_RBG0 = 0; - } -} - -/*************************************************************************/ - -/** - * psp_vdp2_draw_screens: Draw the VDP2 background and graphics layers. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp2_draw_screens(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - /* Draw the background color(s). */ - vdp2_draw_bg(); - - /* Flag the background graphics to be drawn. */ - draw_graphics = 1; -} - -/*************************************************************************/ - -/** - * psp_vdp2_set_resolution: Change the resolution of the Saturn display. - * - * [Parameters] - * TVMD: New value of the VDP2 TVMD register - * [Return value] - * None - */ -static void psp_vdp2_set_resolution(u16 TVMD) -{ - /* Set the display width from bits 0-1. */ - disp_width = (TVMD & 1) ? 352 : 320; - if (TVMD & 2) { - disp_width *= 2; - } - - /* Set the display height from bits 4-5. Note that 0x30 is an invalid - * value for these bits and should not occur in practice; valid heights - * are 0x00=224, 0x10=240, and (for PAL) 0x20=256. */ - disp_height = 224 + (TVMD & 0x30); - if ((TVMD & 0xC0) == 0xC0) { - disp_height *= 2; // Interlaced mode - } - - /* Hi-res or interlaced displays won't fit on the PSP screen, so cut - * everything in half when using them. */ - disp_xscale = (disp_width > 352); - disp_yscale = (disp_height > 256); -} - -/*************************************************************************/ - -/** - * psp_vdp2_set_priority_{NBG[0-3],RBG0}: Set the priority of the given - * background graphics layer. - * - * [Parameters] - * priority: Priority to set - * [Return value] - * None - */ -static void FASTCALL psp_vdp2_set_priority_NBG0(int priority) -{ - bg_priority[BG_NBG0] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_NBG1(int priority) -{ - bg_priority[BG_NBG1] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_NBG2(int priority) -{ - bg_priority[BG_NBG2] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_NBG3(int priority) -{ - bg_priority[BG_NBG3] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_RBG0(int priority) -{ - bg_priority[BG_RBG0] = priority; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * vdp1_is_persistent: Return whether the given sprite drawing command - * identifies a texture in a persistently-cacheable area of VDP1 RAM. - * - * [Parameters] - * cmd: VDP1 command structure - * [Return value] - * Nonzero if texture can be persistently cached, else zero - */ -static int vdp1_is_persistent(vdp1cmd_struct *cmd) -{ - const unsigned int first_page = cmd->CMDSRCA >> 9; - const unsigned int width_8 = (cmd->CMDSIZE >> 8) & 0x3F; - const unsigned int height = cmd->CMDSIZE & 0xFF; - const unsigned int last_page = (cmd->CMDSRCA + (width_8 * height)) >> 9; - unsigned int page; - for (page = first_page; page <= last_page; page++) { - if (!vdp1_page_cached[page]) { - vdp1_page_checksum[page] = - checksum_fast32((const uint32_t *)(Vdp1Ram + (page<<12)), 1024); - vdp1_page_cached[page] = 1; - } - } - if ((cmd->CMDPMOD>>3 & 7) == 1) { - page = cmd->CMDCOLR >> 9; - if (!vdp1_page_cached[page]) { - vdp1_page_checksum[page] = - checksum_fast32((const uint32_t *)(Vdp1Ram + (page<<12)), 1024); - vdp1_page_cached[page] = 1; - } - } - return 1; -} - -/*************************************************************************/ - -/** - * vdp1_draw_lines: Draw one or four lines based on the given VDP1 command. - * - * [Parameters] - * cmd: VDP1 command pointer - * poly: Nonzero = draw four connected lines, zero = draw a single line - * [Return value] - * None - */ -static void vdp1_draw_lines(vdp1cmd_struct *cmd, int poly) -{ - /* Get the line color and priority. */ - // FIXME: vidogl.c suggests that the priority processing done for - // sprites and polygons is not done here; is that correct? - const uint32_t color32 = vdp1_get_cmd_color(cmd); - const int priority = Vdp2Regs->PRISA & 0x7; - - /* If it's Gouraud-shaded, pick up the four endpoint colors. (Only - * the first two of these are used for single lines.) */ - uint32_t color_A, color_B, color_C, color_D; - if (cmd->CMDPMOD & 4) { // Gouraud shading bit - const uint32_t alpha = color32 & 0xFF000000; - if (vdp1_rofs | vdp1_gofs | vdp1_bofs) { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 0); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 2); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 4); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 6); - color_A = alpha | (adjust_color_16_32(temp_A, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_B = alpha | (adjust_color_16_32(temp_B, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_C = alpha | (adjust_color_16_32(temp_C, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_D = alpha | (adjust_color_16_32(temp_D, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - } else { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 0); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 2); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 4); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 6); - color_A = alpha | (temp_A & 0x7C00) << 9 - | (temp_A & 0x03E0) << 6 - | (temp_A & 0x001F) << 3; - color_B = alpha | (temp_B & 0x7C00) << 9 - | (temp_B & 0x03E0) << 6 - | (temp_B & 0x001F) << 3; - color_C = alpha | (temp_C & 0x7C00) << 9 - | (temp_C & 0x03E0) << 6 - | (temp_C & 0x001F) << 3; - color_D = alpha | (temp_D & 0x7C00) << 9 - | (temp_D & 0x03E0) << 6 - | (temp_D & 0x001F) << 3; - } - } else { - color_A = color_B = color_C = color_D = color32; - } - - /* Set up the vertex array. */ - int nvertices = poly ? 5 : 2; - struct {uint32_t color; int16_t x, y, z, pad;} *vertices; - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * nvertices); - vertices[0].color = color_A; - vertices[0].x = (cmd->CMDXA + Vdp1Regs->localX) >> disp_xscale; - vertices[0].y = (cmd->CMDYA + Vdp1Regs->localY) >> disp_yscale; - vertices[0].z = 0; - vertices[1].color = color_B; - vertices[1].x = (cmd->CMDXB + Vdp1Regs->localX) >> disp_xscale; - vertices[1].y = (cmd->CMDYB + Vdp1Regs->localY) >> disp_xscale; - vertices[1].z = 0; - if (poly) { - vertices[2].color = color_C; - vertices[2].x = (cmd->CMDXC + Vdp1Regs->localX) >> disp_xscale; - vertices[2].y = (cmd->CMDYC + Vdp1Regs->localY) >> disp_yscale; - vertices[2].z = 0; - vertices[3].color = color_D; - vertices[3].x = (cmd->CMDXD + Vdp1Regs->localX) >> disp_xscale; - vertices[3].y = (cmd->CMDYD + Vdp1Regs->localY) >> disp_yscale; - vertices[3].z = 0; - vertices[4] = vertices[0]; - } - - /* Queue the line(s). */ - vdp1_queue_render(priority, 0, GU_LINE_STRIP, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nvertices, NULL, vertices); -} - -/*************************************************************************/ - -/** - * vdp1_draw_quad: Draw a quadrilateral based on the given VDP1 command. - * - * [Parameters] - * cmd: VDP1 command pointer - * textured: Nonzero if the quadrilateral is textured (i.e. a sprite) - * [Return value] - * None - */ -static void vdp1_draw_quad(vdp1cmd_struct *cmd, int textured) -{ - /* Get the width, height, and flip arguments for sprites (unused for - * untextured polygons). */ - - int width, height; - unsigned int gouraud_flip = 0; // XOR bitmask for Gouraud color addresses - if (textured) { - width = ((cmd->CMDSIZE >> 8) & 0x3F) * 8; - height = cmd->CMDSIZE & 0xFF; - if (width == 0 || height == 0) { - return; - } - /* If flipping is specified, swap the relevant coordinates in the - * "cmd" structure; this helps avoid texture glitches when the - * vertex order of a texture is changed (e.g. Panzer Dragoon Saga). - * We use inline assembly so we can load and store in 32-bit units - * without GCC complaining about strict aliasing violations. */ - switch (cmd->CMDCTRL & 0x30) { - case 0x10: { // Flip horizontally - gouraud_flip = 2; - uint32_t tempA, tempB, tempC, tempD; - asm(".set push; .set noreorder\n" - "lw %[tempA], 12(%[cmd])\n" - "lw %[tempB], 16(%[cmd])\n" - "lw %[tempC], 20(%[cmd])\n" - "lw %[tempD], 24(%[cmd])\n" - "sw %[tempA], 16(%[cmd])\n" - "sw %[tempB], 12(%[cmd])\n" - "sw %[tempC], 24(%[cmd])\n" - "sw %[tempD], 20(%[cmd])\n" - ".set pop" - : [tempA] "=&r" (tempA), [tempB] "=&r" (tempB), - [tempC] "=&r" (tempC), [tempD] "=&r" (tempD), - "=m" (cmd->CMDXA), "=m" (cmd->CMDYA), "=m" (cmd->CMDXB), - "=m" (cmd->CMDYB), "=m" (cmd->CMDXC), "=m" (cmd->CMDYC), - "=m" (cmd->CMDXD), "=m" (cmd->CMDYD) - : [cmd] "r" (cmd) - ); - break; - } // case 0x10 - case 0x20: { // Flip vertically - gouraud_flip = 6; - uint32_t tempA, tempB, tempC, tempD; - asm(".set push; .set noreorder\n" - "lw %[tempA], 12(%[cmd])\n" - "lw %[tempB], 16(%[cmd])\n" - "lw %[tempC], 20(%[cmd])\n" - "lw %[tempD], 24(%[cmd])\n" - "sw %[tempA], 24(%[cmd])\n" - "sw %[tempB], 20(%[cmd])\n" - "sw %[tempC], 16(%[cmd])\n" - "sw %[tempD], 12(%[cmd])\n" - ".set pop" - : [tempA] "=&r" (tempA), [tempB] "=&r" (tempB), - [tempC] "=&r" (tempC), [tempD] "=&r" (tempD), - "=m" (cmd->CMDXA), "=m" (cmd->CMDYA), "=m" (cmd->CMDXB), - "=m" (cmd->CMDYB), "=m" (cmd->CMDXC), "=m" (cmd->CMDYC), - "=m" (cmd->CMDXD), "=m" (cmd->CMDYD) - : [cmd] "r" (cmd) - ); - break; - } // case 0x20 - case 0x30: { // Flip horizontally and vertically - gouraud_flip = 4; - uint32_t tempA, tempB, tempC, tempD; - asm(".set push; .set noreorder\n" - "lw %[tempA], 12(%[cmd])\n" - "lw %[tempB], 16(%[cmd])\n" - "lw %[tempC], 20(%[cmd])\n" - "lw %[tempD], 24(%[cmd])\n" - "sw %[tempA], 20(%[cmd])\n" - "sw %[tempB], 24(%[cmd])\n" - "sw %[tempC], 12(%[cmd])\n" - "sw %[tempD], 16(%[cmd])\n" - ".set pop" - : [tempA] "=&r" (tempA), [tempB] "=&r" (tempB), - [tempC] "=&r" (tempC), [tempD] "=&r" (tempD), - "=m" (cmd->CMDXA), "=m" (cmd->CMDYA), "=m" (cmd->CMDXB), - "=m" (cmd->CMDYB), "=m" (cmd->CMDXC), "=m" (cmd->CMDYC), - "=m" (cmd->CMDXD), "=m" (cmd->CMDYD) - : [cmd] "r" (cmd) - ); - break; - } // case 0x30 - } // switch (cmd->CMDCTRL & 0x30) - } else { - width = height = 0; - } - - - /* Get the polygon color and priority, and load the texture if it's - * a sprite. */ - - int priority, sprite_alpha; - uint32_t color32 = vdp1_get_cmd_color_pri(cmd, textured, &priority); - uint32_t texture_key; - if (textured) { - texture_key = vdp1_cache_sprite_texture(cmd, width, height, - &priority, &sprite_alpha); - if (UNLIKELY(!texture_key)) { - DMSG("WARNING: failed to cache texture for A=(%d,%d) B=(%d,%d)" - " C=(%d,%d) D=(%d,%d)", - cmd->CMDXA + Vdp1Regs->localX, cmd->CMDYA + Vdp1Regs->localY, - cmd->CMDXB + Vdp1Regs->localX, cmd->CMDYB + Vdp1Regs->localY, - cmd->CMDXC + Vdp1Regs->localX, cmd->CMDYC + Vdp1Regs->localY, - cmd->CMDXD + Vdp1Regs->localX, cmd->CMDYD + Vdp1Regs->localY); - } - /* Convert alpha to 0-255 */ - sprite_alpha = (sprite_alpha << 3) | (sprite_alpha >> 2); - } else { - texture_key = 0; - sprite_alpha = 0xFF; - } - - /* Apply alpha depending on the color calculation settings. */ - - if (Vdp2Regs->CCCTL & 0x40) { - const unsigned int ref_priority = Vdp2Regs->SPCTL>>8 & 0x7; - switch (Vdp2Regs->SPCTL>>12 & 0x3) { - case 0: - if (priority <= ref_priority) { - color32 = (sprite_alpha << 24) | (color32 & 0x00FFFFFF); - } - break; - case 1: - if (priority == ref_priority) { - color32 = (sprite_alpha << 24) | (color32 & 0x00FFFFFF); - } - break; - case 2: - if (priority >= ref_priority) { - color32 = (sprite_alpha << 24) | (color32 & 0x00FFFFFF); - } - break; - case 3: - /* Alpha blending enabled based on high bit of color value - * (not supported in this renderer) */ - break; - } - } - - /* We don't support mesh shading; treat it as half-alpha instead. */ - - if (cmd->CMDPMOD & 0x100) { // Mesh shading bit - const unsigned int alpha = color32 >> 24; - color32 = ((alpha+1)/2) << 24 | (color32 & 0x00FFFFFF); - } - - /* If it's a Gouraud-shaded polygon, pick up the four corner colors. */ - - uint32_t color_A, color_B, color_C, color_D; - if (cmd->CMDPMOD & 4) { // Gouraud shading bit - const uint32_t alpha = color32 & 0xFF000000; - if (vdp1_rofs | vdp1_gofs | vdp1_bofs) { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (0^gouraud_flip)); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (2^gouraud_flip)); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (4^gouraud_flip)); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (6^gouraud_flip)); - color_A = alpha | (adjust_color_16_32(temp_A, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_B = alpha | (adjust_color_16_32(temp_B, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_C = alpha | (adjust_color_16_32(temp_C, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_D = alpha | (adjust_color_16_32(temp_D, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - } else { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (0^gouraud_flip)); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (2^gouraud_flip)); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (4^gouraud_flip)); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (6^gouraud_flip)); - color_A = alpha | (temp_A & 0x7C00) << 9 - | (temp_A & 0x03E0) << 6 - | (temp_A & 0x001F) << 3; - color_B = alpha | (temp_B & 0x7C00) << 9 - | (temp_B & 0x03E0) << 6 - | (temp_B & 0x001F) << 3; - color_C = alpha | (temp_C & 0x7C00) << 9 - | (temp_C & 0x03E0) << 6 - | (temp_C & 0x001F) << 3; - color_D = alpha | (temp_D & 0x7C00) << 9 - | (temp_D & 0x03E0) << 6 - | (temp_D & 0x001F) << 3; - } - } else { - color_A = color_B = color_C = color_D = color32; - } - - /* Set up the vertex array using a strip of 2 triangles. The Saturn - * coordinate order is A,B,C,D clockwise around the texture, so we flip - * around C and D in our vertex array. For simplicity, we assign both - * the color and U/V coordinates regardless of whether the polygon is - * textured or not; the GE is fast enough that it can handle all the - * processing in time. */ - - struct {int16_t u, v; uint32_t color; int16_t x, y, z, pad;} *vertices; - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 4); - vertices[0].u = 0; - vertices[0].v = 0; - vertices[0].color = color_A; - vertices[0].x = (cmd->CMDXA + Vdp1Regs->localX) >> disp_xscale; - vertices[0].y = (cmd->CMDYA + Vdp1Regs->localY) >> disp_yscale; - vertices[0].z = 0; - vertices[1].u = width; - vertices[1].v = 0; - vertices[1].color = color_B; - vertices[1].x = (cmd->CMDXB + Vdp1Regs->localX) >> disp_xscale; - vertices[1].y = (cmd->CMDYB + Vdp1Regs->localY) >> disp_yscale; - vertices[1].z = 0; - vertices[2].u = 0; - vertices[2].v = height; - vertices[2].color = color_D; - vertices[2].x = (cmd->CMDXD + Vdp1Regs->localX) >> disp_xscale; - vertices[2].y = (cmd->CMDYD + Vdp1Regs->localY) >> disp_yscale; - vertices[2].z = 0; - vertices[3].u = width; - vertices[3].v = height; - vertices[3].color = color_C; - vertices[3].x = (cmd->CMDXC + Vdp1Regs->localX) >> disp_xscale; - vertices[3].y = (cmd->CMDYC + Vdp1Regs->localY) >> disp_yscale; - vertices[3].z = 0; - - /* Queue the draw operation. */ - - vdp1_queue_render(priority, texture_key, - GU_TRIANGLE_STRIP, GU_TEXTURE_16BIT | GU_COLOR_8888 - | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 4, NULL, vertices); -} - -/*************************************************************************/ - -/** - * vdp1_convert_color: Convert a VDP1 16-bit color value and pixel mode to - * a 32-bit color value. Helper function for vdp1_get_cmd_color() and - * vdp1_get_cmd_color_pri(). - * - * [Parameters] - * color16: 16-bit color value - * textured: Nonzero if a textured polygon command, else zero - * CMDPMOD: Value of CMDPMOD field in VDP1 command - * [Return value] - * 32-bit color value - */ -static uint32_t vdp1_convert_color(uint16_t color16, int textured, - unsigned int CMDPMOD) -{ - uint32_t color32; - if (textured) { - color32 = 0xFFFFFF; - } else if (color16 == 0) { - color32 = adjust_color_16_32(0x0000, vdp1_rofs, vdp1_gofs, vdp1_bofs); - return color32 & 0x00FFFFFF; // Transparent regardless of CMDPMOD - } else if (color16 & 0x8000) { - color32 = adjust_color_16_32(color16, vdp1_rofs, vdp1_gofs, vdp1_bofs); - } else { - color32 = adjust_color_32_32(global_clut_32[color16 & 0x7FF], - vdp1_rofs, vdp1_gofs, vdp1_bofs); - } - - switch (CMDPMOD & 7) { - default: // Impossible, but avoid a "function may not return" warning - case 1: // Shadow - return 0x80000000; - case 4 ... 7: // Gouraud shading (handled separately) - case 0: // Replace - return 0xFF000000 | color32; - case 2: // 50% luminance - /* Clever, quick way to divide each component by 2 in one step - * (borrowed from vidsoft.c) */ - return 0xFF000000 | ((color32 & 0xFEFEFE) >> 1); - case 3: // 50% transparency - return 0x80000000 | color32; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_get_cmd_color: Return the 32-bit color value specified by a VDP1 - * line command. - * - * [Parameters] - * cmd: VDP1 command pointer - * [Return value] - * 32-bit color value - */ -static uint32_t vdp1_get_cmd_color(vdp1cmd_struct *cmd) -{ - return vdp1_convert_color(cmd->CMDCOLR, 0, cmd->CMDPMOD); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_get_cmd_color_pri: Return the 32-bit color value and priority - * specified by a VDP1 polygon command. - * - * [Parameters] - * cmd: VDP1 command pointer - * textured: Nonzero if the polygon is textured, else zero - * priority_ret: Pointer to variable to receive priority value - * [Return value] - * 32-bit color value - */ -static uint32_t vdp1_get_cmd_color_pri(vdp1cmd_struct *cmd, int textured, - int *priority_ret) -{ - uint16_t color16 = cmd->CMDCOLR; - if (cmd->CMDCOLR & 0x8000) { - *priority_ret = Vdp2Regs->PRISA & 7; - } else { - *priority_ret = 0; // Default if not set by SPCTL - int alpha_unused; // FIXME: is this used by non-sprite quads as well? - vdp1_process_sprite_color(color16, priority_ret, &alpha_unused); - } - return vdp1_convert_color(color16, textured, cmd->CMDPMOD); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_process_sprite_color: Return the color index mask, priority index, - * and alpha (color calculation) index selected by the given color register - * value and the VDP2 SPCTL register. - * - * [Parameters] - * color16: 16-bit color register value - * priority_ret: Pointer to variable to receive priority value - * [Return value] - * Mask to apply to CMDCOLR register - */ -static uint16_t vdp1_process_sprite_color(uint16_t color16, int *priority_ret, - int *alpha_ret) -{ - static const uint8_t priority_shift[16] = - { 14, 13, 14, 13, 13, 12, 12, 12, 7, 7, 6, 0, 7, 7, 6, 0 }; - static const uint8_t priority_mask[16] = - { 3, 7, 1, 3, 3, 7, 7, 7, 1, 1, 3, 0, 1, 1, 3, 0 }; - static const uint8_t alpha_shift[16] = - { 11, 11, 11, 11, 10, 11, 10, 9, 0, 6, 0, 6, 0, 6, 0, 6 }; - static const uint8_t alpha_mask[16] = - { 7, 3, 7, 3, 7, 1, 3, 7, 0, 1, 0, 3, 0, 1, 0, 3 }; - static const uint16_t color_mask[16] = - { 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x3FF, 0x7FF, 0x3FF, 0x1FF, - 0x7F, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF }; - - const unsigned int type = Vdp2Regs->SPCTL & 0xF; - *priority_ret = (color16 >> priority_shift[type]) & priority_mask[type]; - *alpha_ret = (color16 >> alpha_shift[type]) & alpha_mask[type]; - return color_mask[type]; -} - -/*************************************************************************/ - -/** - * vdp1_cache_sprite_texture: Cache the sprite texture designated by the - * given VDP1 command. - * - * [Parameters] - * cmd: VDP1 command pointer - * width: Sprite width (pixels; passed in to avoid recomputation) - * height: Sprite height (pixels; passed in to avoid recomputation) - * priority_ret: Pointer to variable to receive priority value - * alpha_ret: Pointer to variable to receive alpha value (0-31) - * [Return value] - * Cached texture key, or zero on error - */ -static uint32_t vdp1_cache_sprite_texture( - vdp1cmd_struct *cmd, int width, int height, int *priority_ret, - int *alpha_ret) -{ - uint16_t pixel_mask = 0xFFFF; - int pri_reg = 0, alpha_reg = 0; // Default value - - int is_indexed = 1; - uint16_t color16 = cmd->CMDCOLR; - const int pixfmt = cmd->CMDPMOD>>3 & 7; - if (pixfmt == 5) { - is_indexed = 0; - } else if (pixfmt == 1) { - /* Indirect T4 texture; see whether the first pixel references - * color RAM or uses raw RGB values. */ - const uint32_t addr = cmd->CMDSRCA << 3; - const uint8_t pixel = T1ReadByte(Vdp1Ram, addr) >> 4; - const uint32_t colortable = cmd->CMDCOLR << 3; - const uint16_t value = T1ReadWord(Vdp1Ram, colortable + pixel*2); - if (value & 0x8000) { - is_indexed = 0; - } else { - color16 = value; - } - } - if (is_indexed) { - pixel_mask = vdp1_process_sprite_color(color16, &pri_reg, &alpha_reg); - } - - *priority_ret = ((uint8_t *)&Vdp2Regs->PRISA)[pri_reg] & 0x7; - *alpha_ret = 0x1F - (((uint8_t *)&Vdp2Regs->CCRSA)[alpha_reg] & 0x1F); - - /* Cache the texture data and return the key. */ - - return texcache_cache_sprite(cmd, pixel_mask, width, height, - vdp1_is_persistent(cmd)); -} - -/*************************************************************************/ - -/** - * vdp1_queue_render: Queue a render operation from a VDP1 command. - * - * [Parameters] - * priority: Saturn display priority (0-7) - * texture_key: Texture key for sprites, zero for untextured operations - * primitive, - * vertex_type, - * count, - * indices, - * vertices: Parameters to pass to guDrawArray() - * [Return value] - * None - */ -static inline void vdp1_queue_render( - int priority, uint32_t texture_key, int primitive, - int vertex_type, int count, const void *indices, const void *vertices) -{ - /* Expand the queue if necessary. */ - if (UNLIKELY(vdp1_queue[priority].len >= vdp1_queue[priority].size)) { - const int newsize = vdp1_queue[priority].size + VDP1_QUEUE_EXPAND_SIZE; - VDP1RenderData * const newqueue = realloc(vdp1_queue[priority].queue, - newsize * sizeof(*newqueue)); - if (UNLIKELY(!newqueue)) { - DMSG("Failed to expand priority %d queue to %d entries", - priority, newsize); - return; - } - vdp1_queue[priority].queue = newqueue; - vdp1_queue[priority].size = newsize; - } - - /* Record the data passed in. */ - const int index = vdp1_queue[priority].len++; - VDP1RenderData * const entry = &vdp1_queue[priority].queue[index]; - entry->texture_key = texture_key; - entry->primitive = primitive; - entry->vertex_type = vertex_type; - entry->count = count; - entry->indices = indices; - entry->vertices = vertices; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_run_queue: Run the rendering queue for the given priority level. - * - * [Parameters] - * priority: Priority level to run - * [Return value] - * None - */ -static void vdp1_run_queue(int priority) -{ - int in_texture_mode; // Remember which mode we're in - VDP1RenderData *entry = vdp1_queue[priority].queue; - VDP1RenderData * const queue_top = entry + vdp1_queue[priority].len; - - if (vdp1_queue[priority].len == 0) { - return; // Nothing to do - } - - guShadeModel(GU_SMOOTH); - guAmbientColor(0xFFFFFFFF); - guTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - if (config_get_smooth_textures()) { - guTexFilter(GU_LINEAR, GU_LINEAR); - } - if (entry->texture_key) { - guEnable(GU_TEXTURE_2D); - in_texture_mode = 1; - } else { - guDisable(GU_TEXTURE_2D); - in_texture_mode = 0; - } - for (; entry < queue_top; entry++) { - if (entry->texture_key) { - texcache_load_sprite(entry->texture_key); - if (!in_texture_mode) { - guEnable(GU_TEXTURE_2D); - in_texture_mode = 1; - } - } else { - if (in_texture_mode) { - guDisable(GU_TEXTURE_2D); - in_texture_mode = 0; - } - } - guDrawArray(entry->primitive, entry->vertex_type, - entry->count, entry->indices, entry->vertices); - } - if (in_texture_mode) { - guDisable(GU_TEXTURE_2D); - } - if (config_get_smooth_textures()) { - guTexFilter(GU_NEAREST, GU_NEAREST); - } - guShadeModel(GU_FLAT); - - guCommit(); -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * vdp2_get_color_offset: Calculate the color offsets to use for the - * specified CLOFEN/CLOFSL bit. - * - * [Parameters] - * mask: 1 << bit number to check - * rofs_ret: Pointer to variable to store red offset in - * gofs_ret: Pointer to variable to store green offset in - * bofs_ret: Pointer to variable to store blue offset in - * [Return value] - * None - */ -static inline void vdp2_get_color_offsets(uint16_t mask, int32_t *rofs_ret, - int32_t *gofs_ret, int32_t *bofs_ret) -{ - if (Vdp2Regs->CLOFEN & mask) { // CoLor OFfset ENable - /* Offsets are 9-bit signed values */ - if (Vdp2Regs->CLOFSL & mask) { // CoLor OFfset SeLect - *rofs_ret = ((int32_t)Vdp2Regs->COBR << 23) >> 23; - *gofs_ret = ((int32_t)Vdp2Regs->COBG << 23) >> 23; - *bofs_ret = ((int32_t)Vdp2Regs->COBB << 23) >> 23; - } else { - *rofs_ret = ((int32_t)Vdp2Regs->COAR << 23) >> 23; - *gofs_ret = ((int32_t)Vdp2Regs->COAG << 23) >> 23; - *bofs_ret = ((int32_t)Vdp2Regs->COAB << 23) >> 23; - } - } else { - /* No color offset */ - *rofs_ret = *gofs_ret = *bofs_ret = 0; - } -} - -/*************************************************************************/ - -/** - * vdp2_draw_bg: Draw the screen background. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void vdp2_draw_bg(void) -{ - uint32_t address = ((Vdp2Regs->BKTAU & 7) << 16 | Vdp2Regs->BKTAL) << 1; - if (!(Vdp2Regs->VRSIZE & 0x8000)) { - address &= 0x7FFFF; - } - - int rofs, gofs, bofs; - vdp2_get_color_offsets(1<<6, &rofs, &gofs, &bofs); - - struct {uint32_t color; int16_t x, y, z, pad;} *vertices; - - if (Vdp2Regs->BKTAU & 0x8000) { - /* Distinct color for each line */ - int num_vertices, y; - if (disp_height > 272) { - /* For interlaced screens, we average the colors of each two - * adjacent lines */ - num_vertices = 2*(disp_height/2); - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * num_vertices); - for (y = 0; y+1 < disp_height; y += 2, address += 4) { - uint16_t rgb0 = T1ReadWord(Vdp2Ram, address); - uint32_t r0 = (rgb0 & 0x001F) << 3; - uint32_t g0 = (rgb0 & 0x03E0) >> 2; - uint32_t b0 = (rgb0 & 0x7C00) >> 7; - uint16_t rgb1 = T1ReadWord(Vdp2Ram, address); - uint32_t r1 = (rgb1 & 0x001F) << 3; - uint32_t g1 = (rgb1 & 0x03E0) >> 2; - uint32_t b1 = (rgb1 & 0x7C00) >> 7; - uint32_t color = bound(((r0+r1+1)/2) + rofs, 0, 255) << 0 - | bound(((g0+g1+1)/2) + gofs, 0, 255) << 8 - | bound(((b0+b1+1)/2) + bofs, 0, 255) << 16 - | 0xFF000000; - vertices[y+0].color = color; - vertices[y+0].x = 0; - vertices[y+0].y = y/2; - vertices[y+0].z = 0; - vertices[y+1].color = color; - vertices[y+1].x = disp_width >> disp_xscale; - vertices[y+1].y = y/2; - vertices[y+1].z = 0; - } - } else { - num_vertices = 2*disp_height; - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * num_vertices); - for (y = 0; y < disp_height; y++, address += 2) { - uint16_t rgb = T1ReadWord(Vdp2Ram, address); - uint32_t r = bound(((rgb & 0x001F) << 3) + rofs, 0, 255); - uint32_t g = bound(((rgb & 0x03E0) >> 2) + gofs, 0, 255); - uint32_t b = bound(((rgb & 0x7C00) >> 7) + bofs, 0, 255); - vertices[y*2+0].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[y*2+0].x = 0; - vertices[y*2+0].y = y; - vertices[y*2+0].z = 0; - vertices[y*2+1].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[y*2+1].x = disp_width >> disp_xscale; - vertices[y*2+1].y = y; - vertices[y*2+1].z = 0; - } - } - guDrawArray(GU_LINES, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - num_vertices, NULL, vertices); - guCommit(); - } else { - /* Single color for the whole screen */ - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 2); - uint16_t rgb = T1ReadWord(Vdp2Ram, address); - uint32_t r = bound(((rgb & 0x001F) << 3) + rofs, 0, 255); - uint32_t g = bound(((rgb & 0x03E0) >> 2) + gofs, 0, 255); - uint32_t b = bound(((rgb & 0x7C00) >> 7) + bofs, 0, 255); - vertices[0].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[0].x = 0; - vertices[0].y = 0; - vertices[0].z = 0; - vertices[1].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[1].x = disp_width >> disp_xscale; - vertices[1].y = disp_height >> disp_yscale; - vertices[1].z = 0; - guDrawArray(GU_SPRITES, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); - guCommit(); - } -} - -/*************************************************************************/ - -/** - * vdp2_draw_graphics: Draw a single VDP2 background graphics layer. - * - * [Parameters] - * layer: Background graphics layer (BG_* constant) - * [Return value] - * None - */ -static void vdp2_draw_graphics(int layer) -{ - vdp2draw_struct info; - clipping_struct clip[2]; - - /* Is this background layer enabled? */ - if (!(Vdp2Regs->BGON & Vdp2External.disptoggle & (1 << layer))) { - return; - } - if (layer == BG_RBG0 && !config_get_enable_rotate()) { - return; - } - - /* Check whether we should smooth the graphics. */ - const int smooth_hires = - (disp_width > 352 || disp_height > 272) && config_get_smooth_hires(); - - /* Find out whether it's a bitmap or not. */ - switch (layer) { - case BG_NBG0: info.isbitmap = Vdp2Regs->CHCTLA & 0x0002; break; - case BG_NBG1: info.isbitmap = Vdp2Regs->CHCTLA & 0x0200; break; - case BG_RBG0: info.isbitmap = Vdp2Regs->CHCTLB & 0x0200; break; - default: info.isbitmap = 0; break; - } - - /* Determine color-related data. */ - info.transparencyenable = !(Vdp2Regs->BGON & (0x100 << layer)); - /* FIXME: specialprimode is not actually supported by the map drawing - * functions */ - info.specialprimode = (Vdp2Regs->SFPRMD >> (2*layer)) & 3; - switch (layer) { - case BG_NBG0: - info.colornumber = (Vdp2Regs->CHCTLA & 0x0070) >> 4; - break; - case BG_NBG1: - info.colornumber = (Vdp2Regs->CHCTLA & 0x3000) >> 12; - break; - case BG_NBG2: - info.colornumber = (Vdp2Regs->CHCTLB & 0x0002) >> 1; - break; - case BG_NBG3: - info.colornumber = (Vdp2Regs->CHCTLB & 0x0020) >> 5; - break; - case BG_RBG0: - info.colornumber = (Vdp2Regs->CHCTLB & 0x7000) >> 12; - break; - } - if (Vdp2Regs->CCCTL & (1 << layer)) { - const uint8_t *ptr = (const uint8_t *)&Vdp2Regs->CCRNA; - info.alpha = ((~ptr[layer] & 0x1F) << 3) + 7; - } else { - info.alpha = 0xFF; - } - if (layer == BG_RBG0) { - info.coloroffset = (Vdp2Regs->CRAOFB & 7) << 8; - } else { - info.coloroffset = ((Vdp2Regs->CRAOFA >> (4*layer)) & 7) << 8; - } - vdp2_get_color_offsets(1 << layer, (int32_t *)&info.cor, - (int32_t *)&info.cog, (int32_t *)&info.cob); - - /* Extract rotation information for RBG0. */ - if (layer == BG_RBG0) { - switch (Vdp2Regs->RPMD & 3) { - case 0: - info.rotatenum = 0; - info.rotatemode = 0; - break; - case 1: - info.rotatenum = 1; - info.rotatemode = 0; - break; - case 2: - info.rotatenum = 0; - info.rotatemode = 1; - break; - case 3: - info.rotatenum = 0; - info.rotatemode = 2; - break; - } - } - - /* Determine tilemap/bitmap size and display offset. */ - if (info.isbitmap) { - if (layer == BG_RBG0) { - ReadBitmapSize(&info, Vdp2Regs->CHCTLB >> 10, 0x3); - info.charaddr = ((Vdp2Regs->MPOFR >> (4*info.rotatenum)) & 7) << 17; - info.paladdr = (Vdp2Regs->BMPNB & 0x7) << 4; - } else { - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> (2 + layer*8), 0x3); - info.charaddr = ((Vdp2Regs->MPOFN >> (4*layer)) & 7) << 17; - info.paladdr = ((Vdp2Regs->BMPNA >> (8*layer)) & 7) << 4; - } - info.flipfunction = 0; - info.specialfunction = 0; - switch (layer) { - case BG_NBG0: - info.x = - ((Vdp2Regs->SCXIN0 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN0 & 0x7FF) % info.cellh); - break; - case BG_NBG1: - info.x = - ((Vdp2Regs->SCXIN1 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN1 & 0x7FF) % info.cellh); - break; - case BG_RBG0: - /* Transformation is handled separately; nothing to do here. */ - break; - default: - DMSG("info.isbitmap set for invalid layer %d", layer); - return; - } - } else { - if (layer == BG_RBG0) { - info.mapwh = 4; - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> (8 + 4*info.rotatenum)); - } else { - info.mapwh = 2; - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> (2*layer)); - } - const int scx_mask = (512 * info.planew * info.mapwh) - 1; - const int scy_mask = (512 * info.planeh * info.mapwh) - 1; - switch (layer) { - case BG_NBG0: - info.x = - (Vdp2Regs->SCXIN0 & scx_mask); - info.y = - (Vdp2Regs->SCYIN0 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN0, Vdp2Regs->CHCTLA & 0x0001); - break; - case BG_NBG1: - info.x = - (Vdp2Regs->SCXIN1 & scx_mask); - info.y = - (Vdp2Regs->SCYIN1 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN1, Vdp2Regs->CHCTLA & 0x0100); - break; - case BG_NBG2: - info.x = - (Vdp2Regs->SCXN2 & scx_mask); - info.y = - (Vdp2Regs->SCYN2 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN2, Vdp2Regs->CHCTLB & 0x0001); - break; - case BG_NBG3: - info.x = - (Vdp2Regs->SCXN3 & scx_mask); - info.y = - (Vdp2Regs->SCYN3 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN3, Vdp2Regs->CHCTLB & 0x0010); - break; - case BG_RBG0: - ReadPatternData(&info, Vdp2Regs->PNCR, Vdp2Regs->CHCTLB & 0x0100); - break; - } - } - - /* Determine coordinate scaling. */ - // FIXME: scaled graphics may be distorted because integers are used - // for vertex coordinates - switch (layer) { - case BG_NBG0: - info.coordincx = 65536.0f / (Vdp2Regs->ZMXN0.all & 0x7FF00 ?: 65536); - info.coordincy = 65536.0f / (Vdp2Regs->ZMYN0.all & 0x7FF00 ?: 65536); - break; - case BG_NBG1: - info.coordincx = 65536.0f / (Vdp2Regs->ZMXN1.all & 0x7FF00 ?: 65536); - info.coordincy = 65536.0f / (Vdp2Regs->ZMYN1.all & 0x7FF00 ?: 65536); - break; - default: - info.coordincx = info.coordincy = 1; - break; - } - if (disp_xscale == 1) { - info.coordincx /= 2; - } - if (disp_yscale == 1) { - info.coordincy /= 2; - } - - /* Get clipping data. */ - info.wctl = ((uint8_t *)&Vdp2Regs->WCTLA)[layer]; - clip[0].xstart = 0; clip[0].xend = disp_width; - clip[0].ystart = 0; clip[0].yend = disp_height; - clip[1].xstart = 0; clip[1].xend = disp_width; - clip[1].ystart = 0; clip[1].yend = disp_height; - ReadWindowData(info.wctl, clip); - - /* Check for a zero-size clip window, which some games seem to use to - * temporarily disable a screen. */ - if (clip[0].xstart >= clip[0].xend - || clip[0].ystart >= clip[0].yend - || clip[1].xstart >= clip[1].xend - || clip[1].ystart >= clip[1].yend - ) { - return; - } - - info.priority = bg_priority[layer]; - switch (layer) { - case BG_NBG0: info.PlaneAddr = (void *)Vdp2NBG0PlaneAddr; break; - case BG_NBG1: info.PlaneAddr = (void *)Vdp2NBG1PlaneAddr; break; - case BG_NBG2: info.PlaneAddr = (void *)Vdp2NBG2PlaneAddr; break; - case BG_NBG3: info.PlaneAddr = (void *)Vdp2NBG3PlaneAddr; break; - case BG_RBG0: if (info.rotatenum == 0) { - info.PlaneAddr = (void *)Vdp2ParameterAPlaneAddr; - } else { - info.PlaneAddr = (void *)Vdp2ParameterBPlaneAddr; - } - break; - default: DMSG("No PlaneAddr for layer %d", layer); return; - } - info.patternpixelwh = 8 * info.patternwh; - info.draww = (int)((float)(disp_width >> disp_xscale) / info.coordincx); - info.drawh = (int)((float)(disp_height >> disp_yscale) / info.coordincy); - - /* Set up for rendering. */ - guEnable(GU_TEXTURE_2D); - guAmbientColor(info.alpha<<24 | 0xFFFFFF); - if (smooth_hires) { - guTexFilter(GU_LINEAR, GU_LINEAR); - } - - /* If a custom drawing function has been specified for this layer, call - * it first. */ - int custom_draw_succeeded = 0; - if (custom_draw_func[layer]) { - custom_draw_succeeded = (*custom_draw_func[layer])(&info, clip); - if (custom_draw_succeeded && layer == BG_RBG0) { - drew_slow_RBG0 = !RBG0_draw_func_is_fast; - } - } - - if (!custom_draw_succeeded) { - - /* Select a rendering function based on the tile layout and format. */ - void (*draw_map_func)(vdp2draw_struct *info, - const clipping_struct *clip); - if (layer == BG_RBG0) { - draw_map_func = &vdp2_draw_map_rotated; - } else if (info.isbitmap) { - switch (layer) { - case BG_NBG0: - if ((Vdp2Regs->SCRCTL & 7) == 7) { - DMSG("WARNING: line scrolling not supported"); - } - /* fall through */ - case BG_NBG1: - if (info.colornumber == 1 && !smooth_hires) { - draw_map_func = &vdp2_draw_bitmap_t8; - } else if (info.colornumber == 4 && !smooth_hires - && info.coordincx == 1 && info.coordincy == 1) { - draw_map_func = &vdp2_draw_bitmap_32; - } else { - draw_map_func = &vdp2_draw_bitmap; - } - break; - default: - DMSG("info.isbitmap set for invalid layer %d", layer); - return; - } - } else if (info.patternwh == 2) { - if (info.colornumber == 1 && !smooth_hires) { - draw_map_func = &vdp2_draw_map_16x16_t8; - } else { - draw_map_func = &vdp2_draw_map_16x16; - } - } else { - if (info.colornumber == 1 && !smooth_hires) { - draw_map_func = &vdp2_draw_map_8x8_t8; - } else { - draw_map_func = &vdp2_draw_map_8x8; - } - } - - /* Render the graphics. */ - (*draw_map_func)(&info, clip); - if (layer == BG_RBG0) { - drew_slow_RBG0 = 1; - } - - } // if (!custom_draw_succeeded) - - /* All done. */ - if (smooth_hires) { - guTexFilter(GU_NEAREST, GU_NEAREST); - } - guAmbientColor(0xFFFFFFFF); - guDisable(GU_TEXTURE_2D); - guCommit(); -} - -/*************************************************************************/ -/***** Utility routines exported to background graphics drawing code *****/ -/*************************************************************************/ - -/* Last block allocated with pspGuGetMemoryMerge() */ -static void *merge_last_ptr; -static uint32_t merge_last_size; - -/*-----------------------------------------------------------------------*/ - -/** - * pspGuGetMemoryMerge: Acquire a block of memory from the GE display - * list. Similar to sceGuGetMemory(), but if the most recent display list - * operation was also a pspGuGetMemoryMerge() call, merge the two blocks - * together to avoid long chains of jump instructions in the display list. - * - * [Parameters] - * size: Size of block to allocate, in bytes - * [Return value] - * Allocated block - */ -void *pspGuGetMemoryMerge(uint32_t size) -{ - /* Make sure size is 32-bit aligned. */ - size = (size + 3) & -4; - - /* Start off by allocating the block normally. Ideally, we'd check - * first whether the current list pointer is immediately past the last - * block allocated, but since there's apparently no interface for - * either getting the current pointer or deleting the last instruction, - * we're out of luck and can't save the 8 bytes taken by the jump, even - * if we end up not needing it. */ - void *ptr = guGetMemory(size); - - /* If the pointer we got back is equal to the end of the previously - * allocated block plus 8 bytes (2 GU instructions), we can merge. */ - if ((uint8_t *)ptr == (uint8_t *)merge_last_ptr + merge_last_size + 8) { - /* Make sure the instruction before the last block really is a - * jump instruction before we update it. */ - uint32_t *jump_ptr = (uint32_t *)merge_last_ptr - 1; - if (*jump_ptr >> 24 == 0x08) { - void *block_end = (uint8_t *)ptr + size; - *jump_ptr = 0x08<<24 | ((uintptr_t)block_end & 0xFFFFFF); - merge_last_size = (uint8_t *)block_end - (uint8_t *)merge_last_ptr; - return ptr; - } - } - - /* We couldn't merge, so reset the last-block-allocated variables and - * return the block we allocated above. */ - merge_last_ptr = ptr; - merge_last_size = size; - return ptr; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video.h b/yabause/src/psp/psp-video.h deleted file mode 100644 index a9629c5848..0000000000 --- a/yabause/src/psp/psp-video.h +++ /dev/null @@ -1,154 +0,0 @@ -/* src/psp/psp-video.h: PSP video interface module header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_VIDEO_H -#define PSP_VIDEO_H - -#include "../vdp1.h" // for VideoInterface_struct - -/*************************************************************************/ -/********* Module interface and global-use routine declarations **********/ -/*************************************************************************/ - -/* Module interface definition */ -extern VideoInterface_struct VIDPSP; - -/* Unique module ID (must be different from any in ../{vdp1,vid*}.h) */ -#define VIDCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -/** - * psp_video_infoline: Display an information line on the bottom of the - * screen. The text will be displayed for one frame only; call this - * function every frame to keep the text visible. - * - * [Parameters] - * color: Text color (0xAABBGGRR) - * text: Text string - * [Return value] - * None - */ -extern void psp_video_infoline(uint32_t color, const char *text); - -/*************************************************************************/ -/************ Internal utility data and routine declarations *************/ -/*************************************************************************/ - -/* Vertex data structure for GU drawing */ - -typedef struct VertexUVXYZ_ { - int16_t u, v; - int16_t x, y, z; -} VertexUVXYZ; - -/*************************************************************************/ - -/** - * global_clut_16, global_clut_32: Global color lookup table (from VDP2 - * color RAM), in 16- and 32-bit formats. Each array is indexed by the - * color index value used in sprites and tiles; when the VDP2 is in 32-bit - * color mode (Vdp2Internal.ColorMode == 2), indices 0x400-0x7FF are a - * copy of 0x000-0x3FF. In all cases, the alpha values are set to full - * (1 or 0xFF). - */ -extern uint16_t global_clut_16[0x800]; -extern uint32_t global_clut_32[0x800]; - -/*-----------------------------------------------------------------------*/ - -/** - * adjust_color_16_32: Adjust the components of a 16-bit color value, - * returning it as a 32-bit color value. - * - * [Parameters] - * color: 16-bit color value (A1B5G5R5) - * rofs: Red component offset - * gofs: Green component offset - * bofs: Blue component offset - * [Return value] - * Converted and djusted 32-bit color value - */ -static inline uint32_t adjust_color_16_32(uint16_t color, int32_t rofs, - int32_t gofs, int32_t bofs) -{ - int32_t r = color<<3 & 0xF8; - int32_t g = color>>2 & 0xF8; - int32_t b = color>>7 & 0xF8; - return bound(r+rofs, 0, 255) << 0 - | bound(g+gofs, 0, 255) << 8 - | bound(b+bofs, 0, 255) << 16 - | (color>>15 ? 0xFF000000 : 0); -} - -/*-----------------------------------------------------------------------*/ - -/** - * adjust_color_32_32: Adjust the components of a 32-bit color value. - * - * [Parameters] - * color: 32-bit color value (ABGR) - * rofs: Red component offset - * gofs: Green component offset - * bofs: Blue component offset - * [Return value] - * Adjusted 32-bit color value - */ -static inline uint32_t adjust_color_32_32(uint32_t color, int32_t rofs, - int32_t gofs, int32_t bofs) -{ - int32_t r = color>> 0 & 0xFF; - int32_t g = color>> 8 & 0xFF; - int32_t b = color>>16 & 0xFF; - return bound(r+rofs, 0, 255) << 0 - | bound(g+gofs, 0, 255) << 8 - | bound(b+bofs, 0, 255) << 16 - | (color & 0xFF000000); -} - -/*************************************************************************/ - -/** - * pspGuGetMemoryMerge: Acquire a block of memory from the GE display - * list. Similar to sceGuGetMemory(), but if the most recent display list - * operation was also a pspGuGetMemoryMerge() call, merge the two blocks - * together to avoid long chains of jump instructions in the display list. - * - * [Parameters] - * size: Size of block to allocate, in bytes - * [Return value] - * Allocated block - */ -void *pspGuGetMemoryMerge(uint32_t size); - -/*************************************************************************/ -/*************************************************************************/ - -#endif // PSP_VIDEO_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtl-internal.h b/yabause/src/psp/rtl-internal.h deleted file mode 100644 index f08bc6ccce..0000000000 --- a/yabause/src/psp/rtl-internal.h +++ /dev/null @@ -1,712 +0,0 @@ -/* src/psp/rtl-internal.h: Internal-use declarations for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef RTL_INTERNAL_H -#define RTL_INTERNAL_H - -/*************************************************************************/ -/************************* Configuration options *************************/ -/*************************************************************************/ - -/*============ General options ============*/ - -/** - * INSNS_EXPAND_SIZE: Specifies the number of instructions by which to - * expand a block's instruction array when the array is full. This value - * is also used for the initial size of the array. - */ -#define INSNS_EXPAND_SIZE 1000 - -/** - * UNITS_EXPAND_SIZE: Specifies the number of instructions by which to - * expand a block's instruction array when the array is full. This value - * is also used for the initial size of the array. - */ -#define UNITS_EXPAND_SIZE 100 - -/** - * REGS_EXPAND_SIZE: Specifies the number of register entries by which to - * expand a block's register array when the array is full. This value is - * also used for the initial size of the array. - */ -#define REGS_EXPAND_SIZE 1000 - -/** - * REGS_LIMIT: Specifies the maximum number of registers allowed for a - * single block. Must be no greater than 65535 (because this value must - * fit into a uint16_t). The actual number of available registers is one - * less than this value, since register 0 is never used. - */ -#define REGS_LIMIT 65535 - -/** - * LABELS_EXPAND_SIZE: Specifies the number of entries by which to expand - * a block's label-to-unit mapping array when the array is full. This - * value is also used for the initial size of the array. - */ -#define LABELS_EXPAND_SIZE 100 - -/** - * LABELS_LIMIT: Specifies the maximum number of labels allowed for a - * single block. Must be no greater than 65535 (because this value must - * fit into a uint16_t). The actual number of available labels is one less - * than this value, since label 0 is never used. - */ -#define LABELS_LIMIT 65535 - -/** - * NATIVE_EXPAND_SIZE: Specifies the block size (in bytes) by which to - * expand the native code buffer as necessary when translating. - */ -#define NATIVE_EXPAND_SIZE 8192 - -/*============ MIPS-specific options ============*/ - -/** - * MIPS_FRAME_SIZE: The stack frame size to use in generated native code, - * in bytes. This does not include space reserved for saving registers in - * the function prologue. - */ -#define MIPS_FRAME_SIZE 64 - -/** - * MIPS_OPTIMIZE_MERGE_CONSTANTS: When defined, RTL registers with - * identical constant values whose live ranges overlap will share the same - * hardware register. Hardware registers will also be reused if a value - * loaded for a previously-used constant is still available after the - * constant has died. - */ -#define MIPS_OPTIMIZE_MERGE_CONSTANTS - -/** - * MIPS_OPTIMIZE_IMMEDIATE: When defined, the translator will optimize a - * LOAD_IMM instruction followed by one of: - * ADD, SUB, AND, OR, XOR, SLL, SRL, SRA, SLTU, SLTS - * which uses the LOAD_IMM target as its second operand into the equivalent - * MIPS immediate instruction if the immediate operand is within range and - * is not used elsewhere. Similarly, LOAD_NATIVEADDR followed by a memory - * load or store operation will be optimized if possible to insert the low - * 16 bits of the address into the load/store instruction, allowing the - * base register to be loaded with a single MIPS LUI instruction. - */ -#define MIPS_OPTIMIZE_IMMEDIATE - -/** - * MIPS_OPTIMIZE_ABSOLUTE_CALL: When defined, the translator will optimize - * a LOAD_NATIVEADDR instruction followed by a CALL_NATIVE instruction into - * a MIPS JAL instruction to the address specified by the constant register. - * - * ==== PORTABILITY WARNING ==== - * - * This optimization is NOT guaranteed to be portable across different - * platforms! The MIPS JAL instruction only allows the low 28 bits of the - * target address to be specified, and takes the high bits from the current - * PC. We could theoretically check the target address against the address - * of the JAL instruction when we add it, but since the address of the - * native code block may change as it is expanded, we cannot guarantee at - * the time we add the JAL instruction that the target address is reachable. - * - * That said, on (at least current iterations of) the PSP, the upper bits - * of addresses for both code and data are always zero, so we can safely - * optimize jumps to constant addresses. - */ -#define MIPS_OPTIMIZE_ABSOLUTE_CALL - -/** - * MIPS_OPTIMIZE_DELAY_SLOT: When defined, the translator will move the - * instruction preceding a branch or jump instruction into the branch's - * delay slot, if possible. - */ -#define MIPS_OPTIMIZE_DELAY_SLOT - -/** - * MIPS_OPTIMIZE_BRANCHES: When defined, the translator will perform the - * following optimizations on branches: - * - * - A branch to another (unconditional) branch will be chained through to - * the final branch target, unless that target would be outside the range - * of a branch instruction. - * - * - When a branch has a NOP instruction in its delay slot, the instruction - * at the target address will be copied over the NOP, the branch will be - * changed to a Likely branch if it is conditional (e.g. BEQ becomes - * BEQL), and the branch target will be incremented by one instruction. - * (The optimization is not performed if the branch target is already at - * the positive branch offset limit.) - */ -#define MIPS_OPTIMIZE_BRANCHES - -/** - * MIPS_OPTIMIZE_SCHEDULING: When defined, the translator will attempt to - * reschedule load, multiply, and divide instructions to avoid stalls. - */ -#define MIPS_OPTIMIZE_SCHEDULING - -/** - * MIPS_OPTIMIZE_SEX: When defined, the translator will optimize SLL/SRA - * pairs to SEB or SEH when possible: - * - * LOAD_IMM rD,24 - * SLL rB,rA,rD - * LOAD_IMM rE,24 - * SRA rC,rB,rE --> seb $rC,$rA [assuming rB is otherwise unused] - * - * LOAD_IMM rD,16 - * SLL rB,rA,rD - * LOAD_IMM rE,16 - * SRA rC,rB,rE --> seh $rC,$rA [assuming rB is otherwise unused] - * - * SLLI/SRAI pairs are similarly optimized. - */ -#define MIPS_OPTIMIZE_SEX - -/** - * MIPS_OPTIMIZE_MIN_MAX: When defined, the translator will optimize - * SLTS/SELECT pairs to MIN or MAX when possible: - * - * SLTS rC, rA, rB - * SELECT rD, rA, rB, rC --> min $rD, $rA, $rB - * - * SLTS rC, rA, rB - * SELECT rD, rB, rA, rC --> max $rD, $rA, $rB - * - * (both assuming register rC is otherwise unused). - */ -#define MIPS_OPTIMIZE_MIN_MAX - -/*============ Debugging options ============*/ - -/** - * OPERAND_SANITY_CHECKS: If defined, causes rtl_add_insn() to check that - * register and label operands are within allowable ranges. - * - * This option is meaningless if CHECK_PRECONDITIONS is not defined. - */ -#define OPERAND_SANITY_CHECKS - -/** - * CHECK_PRECONDITIONS: If defined, causes functions to check that their - * preconditions are satisfied and return (with an error if appropriate) - * if not. This can add a significant amount of overhead. - */ -// #define CHECK_PRECONDITIONS - -/** - * RTL_TRACE_GENERATE: Trace the generation of RTL blocks and instructions. - */ -// #define RTL_TRACE_GENERATE - -/** - * RTL_TRACE_EXECUTE: Trace the execution of RTL instructions in - * rtl_execute_block(). - */ -// #define RTL_TRACE_EXECUTE - -/** - * RTL_TRACE_STEALTH_FOR_SH2: Enable SH-2 stealth tracing (see the - * documentation for TRACE_STEALTH in sh2.c). - */ -#define RTL_TRACE_STEALTH_FOR_SH2 - -/*************************************************************************/ -/*************************** Type declarations ***************************/ -/*************************************************************************/ - -#undef mips // Avoid namespace pollution from the compiler on MIPS machines - -/*-----------------------------------------------------------------------*/ - -/** - * RTLInsn: A single platform-neutral (more or less) operation. SH-2 - * instructions are translated into sequences of RTLInsns, which are then - * optimized and retranslated into MIPS instructions. - */ -typedef struct RTLInsn_ { - uint8_t opcode; // Operation code (RTLOpcode) - uint16_t dest; // Destination register - uint16_t src1, src2; // Source registers - union { - uint16_t dest2; // Second output register (for MULU_64, etc.) - uint16_t cond; // Condition register for SELECT - struct { - uint8_t start; // First (lowest) bit number for a bitfield - uint8_t count; // Number of bits for a bitfield - } bitfield; - int16_t offset; // Byte offset for load/store instructions - uint16_t label; // GOTO target label - uint16_t target; // CALL_NATIVE branch target register - uint32_t src_imm; // Source immediate value - uintptr_t src_addr; // Source native address value - }; -} RTLInsn; - -/*----------------------------------*/ - -/** - * RTLRegType: The type (source information) of a register used in an RTL - * block. - */ -typedef enum RTLRegType_ { - RTLREG_UNDEFINED = 0, // Not yet defined to anything - RTLREG_CONSTANT, // Constant value (RTLRegister.value) - RTLREG_PARAMETER, // Function parameter (.param_index) - RTLREG_MEMORY, // Memory reference - RTLREG_RESULT, // Result of an operation on other registers - RTLREG_RESULT_NOFOLD, // Result of an operation (not constant foldable) - RTLREG_UNKNOWN, // Source unknown (e.g. due to reassignment) -} RTLRegType; - -/** - * RTLRegister: Data about registers used in an RTL block. All registers - * are 32 bits wide. - */ -typedef struct RTLRegister_ RTLRegister; -struct RTLRegister_ { - /* Basic register information */ - uint8_t source; // Register source (RTLRegType) - uint8_t live; // Nonzero if this register has been referenced - // (this field is never cleared once set) - uint16_t live_link; // Next register in live list (sorted by birth) - uint32_t birth; // First RTL insn index when register is live - // (if SSA, insn index where it's assigned) - uint32_t death; // Last RTL insn index when register is live - - /* Unique pointer information. The "unique_pointer" field has the - * property that all registers with the same nonzero value for - * "unique_pointer" are native addresses which point to the same region - * of memory, and that region of memory will only be accessed through - * a register with the same "unique_pointer" value. */ - uint16_t unique_pointer; - - /* Register value information */ - union { - uintptr_t value; // Value of register for RTLREG_CONSTANT; - // also used during interpreted execution - unsigned int param_index;// Function parameter idx for RTLREG_PARAMETER - struct { - uint16_t addr_reg; // Register holding address for RTLREG_MEMORY - int16_t offset; // Access offset - uint8_t size; // Access size in bytes (1, 2, 4; or 8 if a - // pointer, regardless of actual size) - uint8_t is_signed; // Nonzero if a signed load, zero if unsigned - } memory; - struct { - uint8_t opcode; // Operation code for RTLREG_RESULT - uint8_t second_res:1; // "Second result" flag (high word of - // MUL[US]_64, remainder of DIVMOD[US]) - uint8_t is_imm:1; // Nonzero if a register-immediate operation - uint16_t src1; // Operand 1 - union { - struct { - uint16_t src2; // Op 2 for register-register operations - union { - uint16_t cond; // Condition register for SELECT - struct { - uint8_t start; // Start bit for bitfields - uint8_t count; // Bit count for bitfields - }; - }; - }; - uint32_t imm; // Operand 2 for register-immediate operations - }; - } result; - }; - - /* The following fields are for use by RTL-to-native translators: */ - uint32_t last_used; // Last insn index where this register was used - uint8_t native_allocated; // Nonzero if a native reg has been allocated - uint8_t native_reg; // Native register allocated for this register - uint8_t frame_allocated; // Nonzero if a frame slot has been allocated - uint8_t frame_slot; // Frame slot allocated for this register - int16_t stack_offset; // Stack offset of this register's frame slot - RTLRegister *next_merged; // Next register in merge chain, or NULL - union { - struct { - /* If nonzero, this field contains the opcode to retrieve the - * register's value from the MIPS HI or LO register (either - * MIPS_MFHI(0) or MIPS_MFLO(0)) */ - uint32_t is_in_hilo; - } mips; - }; -}; - -/*----------------------------------*/ - -/** - * RTLUnit: Information about an basic unit of code (a sequence of - * instructions with one entry point and one exit point). Note that a unit - * can be empty, denoted by last_insn < first_insn, and that last_insn can - * be negative, if first_insn is 0 and the unit is empty. - */ -typedef struct RTLUnit_ { - int32_t first_insn; // block->insns[] index of first insn in unit - int32_t last_insn; // block->insns[] index of last insn in unit - int16_t next_unit; // block->units[] index of next unit in code - // stream (may not be the sequentially next - // unit in the array due to optimization); - // -1 indicates the end of the code stream - int16_t prev_unit; // block->units[] index of previous unit in - // code stream - int16_t entries[8]; // block->units[] indices of dominating units; - // -1 indicates an unused slot. Holes in - // the list are not permitted; for more - // than 8 slots, add a dummy unit on top - // (rtlunit_*() functions handle all this) - int16_t exits[2]; // block->units[] indices of postdominating - // units. A terminating insn can go at - // most two places (conditional GOTO). - - /* These fields are provided as hints to RTL-to-native translators: */ - int16_t next_call_unit; // Next unit with a CALL_NATIVE insn (-1=none) - int16_t prev_call_unit; // Prev. unit with a CALL_NATIVE insn (-1=none) - - /* The following fields are used only by RTL-to-native translators: */ - union { - struct { - /* Register and stack frame state at the beginning of the unit */ - RTLRegister *reg_map[32]; // MIPS-to-RTL register map - RTLRegister *frame_map[MIPS_FRAME_SIZE/4]; // Stack frame reg map - } mips; - }; -} RTLUnit; - -/*----------------------------------*/ - -/** - * RTLBlock: State information used in translating a block of code. The - * RTLBlock type itself is defined in rtl.h. - */ -struct RTLBlock_ { - RTLInsn *insns; // Instruction array - int16_t *insn_unitmap; // Insn-to-unit mapping (used by interpreter) - uint32_t insns_size; // Size of instruction array (entries) - uint32_t num_insns; // Number of instructions actually in array - - RTLUnit *units; // Basic unit array - uint16_t units_size; // Size of unit array (entries) - uint16_t num_units; // Number of units actually in array - uint8_t have_unit; // Nonzero if there is a currently active unit - uint16_t cur_unit; // Current unit index if have_unit != 0 - - int16_t *label_unitmap; // Label-to-unit-index mapping (-1 = unset) - uint16_t labels_size; // Size of label-to-unit map array (entries) - uint16_t next_label; // Next label number to allocate - - RTLRegister *regs; // Register array - uint16_t regs_size; // Size of register array (entries) - uint16_t next_reg; // Next register number to allocate - uint16_t first_live_reg; // First register in live range list - uint16_t last_live_reg; // Last register in live range list - uint16_t unique_pointer_index; // Next value for RTLRegister.unique_pointer - - uint8_t finalized; // Nonzero if block has been finalized - - /* These fields are provided as hints to RTL-to-native translators: */ - int16_t first_call_unit; // First unit with a CALL_NATIVE insn (-1=none) - int16_t last_call_unit; // Last unit with a CALL_NATIVE insn (-1=none) - - /* The following fields are used only by optimization routines: */ - uint8_t *unit_seen; // Array of "seen" flags for all units - // (used by rtlopt_drop_dead_units()) - - /* The following fields are used only by RTL-to-native translators: */ - void *native_buffer; // Native code buffer - uint32_t native_bufsize; // Allocated size of native code buffer - uint32_t native_length; // Length of native code - uint32_t *label_offsets; // Array of native offsets for labels - union { - struct { - uint8_t need_save_ra; // Nonzero = need to save/restore $ra - uint8_t need_chain_at; // Nonzero = need chain-to-$at epilogue - uint8_t frame_used; // Nonzero = 1 or more frame slots used - uint32_t sreg_used; // Bitmask of $sN registers used - uint32_t total_frame_size; // Frame size incl. space for $sN/$ra - RTLRegister *reg_map[32]; // MIPS-to-RTL register map - uint32_t reg_free; // Bitmask of free MIPS registers - uint32_t hi_reg, lo_reg; // RTL registers cached in HI and LO - RTLRegister *frame_map[MIPS_FRAME_SIZE/4]; // Stack frame reg map - uint32_t frame_free[((MIPS_FRAME_SIZE/4)+31)/32]; // Free slot mask - uint32_t unit_start; // Offset of first insn in current unit - struct { - uint8_t is_frame; // 0 = MIPS reg, 1 = frame slot - uint8_t index; // Register or frame slot index - int16_t next; // Next entry index or -1 for EOL - } active_list[32 + MIPS_FRAME_SIZE/4]; - int first_active; // First active entry, or -1 if none - int16_t next_call_unit; // Current position in call_unit chain - uint32_t epilogue_offset; // Start offset of epilogue code - uint32_t chain_offset; // Start offset of chain epilogue code - // (only valid if need_chain_at!=0) - } mips; - }; - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - uint32_t sh2_regcache[23]; // Cached values of SH-2 registers - uint32_t sh2_regcache_mask; // Bitmask of cached registers -#endif -}; - -/*************************************************************************/ -/***************************** Miscellaneous *****************************/ -/*************************************************************************/ - -/* We use the PRECOND() macro from common.h for precondition checking; if - * CHECK_PRECONDITIONS is _not_ defined, then redefine PRECOND() here to do - * nothing. */ - -#ifndef CHECK_PRECONDITIONS -# undef PRECOND -# define PRECOND(condition,fail_action) /*nothing*/ -#endif - -/*************************************************************************/ -/**************** Library-internal function declarations *****************/ -/*************************************************************************/ - -/**** Instruction encoding function declarations ****/ - -/* Internal table used by rtlinsn_make() */ -extern int (* const makefunc_table[])(RTLBlock *, RTLInsn *, unsigned int, - uintptr_t, uint32_t, uint32_t); - -/** - * rtlinsn_make: Fill in an RTLInsn structure based on the opcode stored - * in the structure and the parameters passed to the function. - * - * [Parameters] - * block: RTLBlock containing instruction - * insn: RTLInsn structure to fill in (insn->opcode must be set by caller) - * dest: Destination register for instruction - * src1: First source register or immediate value for instruction - * src2: Second source register or immediate value for instruction - * other: Extra register for instruction - * [Return value] - * Nonzero on success, zero on error - */ -static inline int rtlinsn_make(RTLBlock *block, RTLInsn *insn, - unsigned int dest, uintptr_t src1, - uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(insn->opcode >= RTLOP__FIRST && insn->opcode <= RTLOP__LAST, - return 0); - - /* Keep this check out of PRECOND() to try and avoid crashes even when - * CHECK_PRECONDITIONS is disabled; also, invert the sense and call the - * table function first so the parameter registers or stack frame - * aren't spilled by the DMSG() call in debug mode. */ - if (LIKELY(makefunc_table[insn->opcode])) { - return (*makefunc_table[insn->opcode])(block, insn, - dest, src1, src2, other); - } - DMSG("BUG: missing function for opcode %u", insn->opcode); - return 0; -} - - -/*-----------------------------------------------------------------------*/ - -/**** Optimization function declarations ****/ - -/** - * rtlopt_fold_constants: Perform constant folding on the given RTL block, - * converting instructions that operate on constant operands into load- - * immediate instructions that load the result of the operation. If such - * an operand is not used by any other instruction, the instruction that - * loaded it is changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_fold_constants(RTLBlock *block); - -/** - * rtlopt_decondition: Perform "deconditioning" of conditional branches - * with constant conditions. For "GOTO_IF_Z (GOTO_IF_NZ) label, rN" where - * rN is type RTLREG_CONSTANT, the instruction is changed to GOTO if the - * value of rN is zero (nonzero) and changed to NOP otherwise. As with - * constant folding, if the condition register is not used anywhere else, - * the register is eliminated and the instruction that loaded it is - * changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_decondition(RTLBlock *block); - -/** - * rtlopt_drop_dead_units: Search an RTL block for basic units which are - * unreachable via any path from the initial unit and remove them from the - * code stream. All units dominated only by such dead units are - * recursively removed as well. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_drop_dead_units(RTLBlock *block); - -/** - * rtlopt_drop_dead_branches: Search an RTL block for branch instructions - * which branch to the next instruction in the code stream and replace them - * with NOPs. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_drop_dead_branches(RTLBlock *block); - -/*-----------------------------------------------------------------------*/ - -/**** Basic unit processing function declarations ****/ - -/** - * rtlunit_add: Add a new, empty basic unit to the given block - * at the end of the block->units[] array. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on failure - */ -extern int rtlunit_add(RTLBlock *block); - -/** - * rtlunit_add_edge: Add a new edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * to_index: Index of postdominating basic unit (in block->units[]) - * [Return value] - * Nonzero on success, zero on failure - */ -extern int rtlunit_add_edge(RTLBlock *block, unsigned int from_index, - unsigned int to_index); - -/** - * rtlunit_remove_edge: Remove an edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * exit_index: Index of exit edge to remove (in units[from_index].exits[]) - * [Return value] - * None - */ -extern void rtlunit_remove_edge(RTLBlock *block, const unsigned int from_index, - unsigned int exit_index); - -/** - * rtlunit_dump_all: Dump a list of all basic units in the block to - * stderr. Intended for debugging. - * - * [Parameters] - * block: RTL block - * tag: Tag to prepend to all lines, or NULL for none - * [Return value] - * None - */ -extern void rtlunit_dump_all(const RTLBlock * const block, const char * const tag); - -/*-----------------------------------------------------------------------*/ - -/**** Architecture-specific translation function declarations ****/ - -/** - * rtl_translate_block_XXX: Translate the given block into native code for - * a particular architecture. - * - * [Parameters] - * block: RTLBlock to translate - * code_ret: Pointer to variable to receive code buffer pointer - * size_ret: Pointer to variable to receive code buffer size (in bytes) - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * On error, *code_ret and *size_ret are not modified. - */ -extern int rtl_translate_block_mips(RTLBlock *block, void **code_ret, - uint32_t *size_ret); - -/*-----------------------------------------------------------------------*/ - -/**** Debugging-related functions ****/ - -#if defined(RTL_TRACE_GENERATE) || defined(RTL_TRACE_EXECUTE) - -/** - * rtl_decode_insn: Decode an RTL instruction into a human-readable - * string. - * - * [Parameters] - * block: RTLBlock containing instruction to decode - * index: Index of instruction to decode - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the instruction - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -extern const char *rtl_decode_insn(const RTLBlock *block, uint32_t index, int is_exec); - -/** - * rtl_describe_register: Generate a string describing the contents of the - * given RTL register. - * - * [Parameters] - * reg: Register to describe - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the register - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -extern const char *rtl_describe_register(const RTLRegister *reg, int is_exec); - -#endif // RTL_TRACE_GENERATE || RTL_TRACE_EXECUTE - -/*************************************************************************/ -/*************************************************************************/ - -#endif // RTL_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtl-mips.c b/yabause/src/psp/rtl-mips.c deleted file mode 100644 index c8025b456c..0000000000 --- a/yabause/src/psp/rtl-mips.c +++ /dev/null @@ -1,4819 +0,0 @@ -/* src/psp/rtl-mips.c: RTL->MIPS translator used in dynamic translation - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" -#include "rtl-mips.h" - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 -# include "sh2.h" -# include "sh2-internal.h" -#endif - -/*************************************************************************/ -/************************** Local declarations ***************************/ -/*************************************************************************/ - -/* Magic MIPS register index indicating that an RTL register is located in - * the stack frame and has no hardware register assigned */ -#define MIPS_noreg 32 - -/* List of caller-saved and callee-saved registers specified by the MIPS ABI. - * Note that we omit $at and $v1 from the caller-saved register list because - * we never assign them to RTL registers (they're only used to load values - * from the stack frame for use as instruction operands) */ -static const uint8_t caller_saved_regs[] = { - MIPS_v0, - MIPS_a0, MIPS_a1, MIPS_a2, MIPS_a3, - MIPS_t0, MIPS_t1, MIPS_t2, MIPS_t3, MIPS_t4, MIPS_t5, MIPS_t6, MIPS_t7, - MIPS_t8, MIPS_t9, -}; -static const uint8_t callee_saved_regs[] = { - MIPS_s0, MIPS_s1, MIPS_s2, MIPS_s3, MIPS_s4, MIPS_s5, MIPS_s6, - MIPS_s7, MIPS_s8, -}; - -/* Array of flags indicating which registers are caller-saved or callee-saved*/ -static const uint8_t reg_is_caller_saved[] = { - [MIPS_v1] = 1, - [MIPS_a0] = 1, [MIPS_a1] = 1, [MIPS_a2] = 1, [MIPS_a3] = 1, - [MIPS_t0] = 1, [MIPS_t1] = 1, [MIPS_t2] = 1, [MIPS_t3] = 1, - [MIPS_t4] = 1, [MIPS_t5] = 1, [MIPS_t6] = 1, [MIPS_t7] = 1, - [MIPS_t8] = 1, [MIPS_t9] = 1, -}; -static const uint8_t reg_is_callee_saved[] = { - [MIPS_s0] = 1, [MIPS_s1] = 1, [MIPS_s2] = 1, [MIPS_s3] = 1, - [MIPS_s4] = 1, [MIPS_s5] = 1, [MIPS_s6] = 1, [MIPS_s7] = 1, - [MIPS_s8] = 1, -}; - -/* Fake opcodes for branching to labels (to be resolved later) */ -#define __OP_BEQ_LABEL 074 // __OP_BEQ + 070 -#define __OP_BNE_LABEL 075 // __OP_BNE + 070 -#define MIPS_BEQ_LABEL(rs,rt,label) \ - __MIPS_INSN_IMM(BEQ_LABEL, (rs), (rt), (label)) -#define MIPS_BNE_LABEL(rs,rt,label) \ - __MIPS_INSN_IMM(BNE_LABEL, (rs), (rt), (label)) -#define MIPS_BEQZ_LABEL(reg,label) MIPS_BEQ_LABEL((reg), MIPS_zero, (label)) -#define MIPS_BNEZ_LABEL(reg,label) MIPS_BNE_LABEL((reg), MIPS_zero, (label)) -#define MIPS_B_LABEL(label) MIPS_BEQZ_LABEL(MIPS_zero, (label)) - -/* Fake opcode for jumping to the epilogue, returning a constant in $v0 */ -#define MIPS_B_EPILOGUE_RET_CONST __MIPS_SPECIAL(0, 0, 0, 1, JALR) - -/* Fake opcode for jumping to the epilogue, then chaining to the address - * in $at */ -#define MIPS_B_EPILOGUE_CHAIN_AT __MIPS_SPECIAL(0, 0, 0, 2, JALR) - -/*-----------------------------------------------------------------------*/ - -static int allocate_registers(RTLBlock * const block); -static inline int allocate_regs_unit(RTLBlock * const block, - const unsigned int unit_index); -static inline int allocate_regs_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index); -static void add_to_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index); -static void remove_from_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index); -static void clean_active_list(RTLBlock * const block, - const uint32_t clean_insn); -static int allocate_one_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index); -static int allocate_one_register_prefer(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index, - const unsigned int prefer_mips); -static int merge_constant_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index); -static int allocate_frame_slot(RTLBlock * const block, - const uint32_t insn_index, - const unsigned int reg_index); -#ifdef MIPS_OPTIMIZE_IMMEDIATE -static int optimize_immediate(RTLBlock * const block, - const uint32_t insn_index); -#endif -#ifdef RTL_TRACE_GENERATE -static void print_regmap(RTLBlock * const block); -#endif - -/*----------------------------------*/ - -static int translate_block(RTLBlock * const block); -static inline int translate_unit(RTLBlock * const block, - const unsigned int unit_index); -static inline unsigned int translate_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index); -static int append_alu_1op(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode); -static int append_alu_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode); -static int append_shift_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode); -static int append_mult_div(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode, const int accumulate, - const uint32_t insn_index); - -static int flush_for_call(RTLBlock * const block, const uint32_t insn_index); -static int reload_after_call(RTLBlock * const block, - const uint32_t insn_index); -static int flush_hilo(RTLBlock * const block, const uint32_t insn_index); - -#ifdef MIPS_OPTIMIZE_MIN_MAX -static int optimize_min_max(RTLBlock * const block, const uint32_t insn_index); -#endif - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 -static unsigned int sh2_stealth_trace_insn(RTLBlock * const block, - const uint32_t insn_index); -static unsigned int sh2_stealth_cache_reg(RTLBlock * const block, - const uint32_t insn_index); -static unsigned int sh2_stealth_trace_store(RTLBlock * const block, - const uint32_t insn_index); -#endif - -static int resolve_branches(RTLBlock * const block); - -/*----------------------------------*/ - -static inline int append_insn(RTLBlock * const block, const uint32_t insn); -static int expand_block(RTLBlock * const block); -static uint32_t last_insn(const RTLBlock * const block); -static uint32_t pop_insn(RTLBlock * const block); - -static int append_float(RTLBlock * const block, const uint32_t insn, - const int latency); -static int append_branch(RTLBlock * const block, const uint32_t insn); - -static int append_prologue(RTLBlock * const block); -static int append_epilogue(RTLBlock * const block); - -/*----------------------------------*/ - -#ifdef __GNUC__ -# define CONST_FUNC __attribute__((const)) -#else -# define CONST_FUNC /*nothing*/ -#endif - -static CONST_FUNC inline int insn_rs(const uint32_t opcode); -static CONST_FUNC inline int insn_rt(const uint32_t opcode); -static CONST_FUNC inline int insn_rd(const uint32_t opcode); -static CONST_FUNC inline int insn_imm(const uint32_t opcode); - -static CONST_FUNC inline int insn_is_load(const uint32_t opcode); -static CONST_FUNC inline int insn_is_store(const uint32_t opcode); -static CONST_FUNC inline int insn_is_jump(const uint32_t opcode); -static CONST_FUNC inline int insn_is_branch(const uint32_t opcode); -static CONST_FUNC inline int insn_is_imm(const uint32_t opcode); -static CONST_FUNC inline int insn_is_imm_alu(const uint32_t opcode); -static CONST_FUNC inline int insn_is_special(const uint32_t opcode); -static CONST_FUNC inline int insn_is_regimm(const uint32_t opcode); -static CONST_FUNC inline int insn_is_allegrex(const uint32_t opcode); - -static CONST_FUNC inline uint32_t insn_regs_used(const uint32_t opcode); -static CONST_FUNC inline uint32_t insn_regs_set(const uint32_t opcode); - -/*************************************************************************/ - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - -/* Array for caching unflushed SH-2 register values (this assumes - * singlethreaded execution, but since this is only for debugging anyway - * let's not worry too hard about it) */ - -static uint32_t sh2_regcache[23]; - -/*----------------------------------*/ - -/* Set up common code blocks as constant arrays so we don't bloat the code - * too badly */ - -/* Save all caller-saved MIPS registers and the current state block - * register values on the stack; the state block pointer is assumed to be - * in $at */ -static const uint32_t code_save_regs_state[] = { - /* Add stack space for saving registers */ - MIPS_ADDIU(MIPS_sp, MIPS_sp, -(4*(18+24))), - /* First save all MIPS caller-saved registers */ - MIPS_SW(MIPS_v0, 0, MIPS_sp), - MIPS_SW(MIPS_v1, 4, MIPS_sp), - MIPS_SW(MIPS_a0, 8, MIPS_sp), - MIPS_SW(MIPS_a1, 12, MIPS_sp), - MIPS_SW(MIPS_a2, 16, MIPS_sp), - MIPS_SW(MIPS_a3, 20, MIPS_sp), - MIPS_SW(MIPS_t0, 24, MIPS_sp), - MIPS_SW(MIPS_t1, 28, MIPS_sp), - MIPS_SW(MIPS_t2, 32, MIPS_sp), - MIPS_SW(MIPS_t3, 36, MIPS_sp), - MIPS_SW(MIPS_t4, 40, MIPS_sp), - MIPS_SW(MIPS_t5, 44, MIPS_sp), - MIPS_SW(MIPS_t6, 48, MIPS_sp), - MIPS_SW(MIPS_t7, 52, MIPS_sp), - MIPS_SW(MIPS_t8, 56, MIPS_sp), - MIPS_SW(MIPS_t9, 60, MIPS_sp), - MIPS_MFLO(MIPS_v1), - MIPS_SW(MIPS_v1, 64, MIPS_sp), - MIPS_MFHI(MIPS_v1), - MIPS_SW(MIPS_v1, 68, MIPS_sp), - /* Copy the current register values in the SH-2 state block (which may - * not be up to date) to the stack */ - MIPS_MOVE(MIPS_a0, MIPS_at), - MIPS_ADDIU(MIPS_a1, MIPS_sp, 4*18), - MIPS_ADDIU(MIPS_a2, MIPS_a0, 4*23), - MIPS_LW(MIPS_v1, 0, MIPS_a0), - MIPS_ADDIU(MIPS_a0, MIPS_a0, 4), - MIPS_ADDIU(MIPS_a1, MIPS_a1, 4), - MIPS_BNE(MIPS_a0, MIPS_a2, -4), - MIPS_SW(MIPS_v1, -4, MIPS_a1), - /* Copy the current cycle count to the stack (leaving a copy in $v1) - * and return */ - MIPS_LW(MIPS_v1, offsetof(SH2State,cycles), MIPS_at), - MIPS_JR(MIPS_ra), - MIPS_SW(MIPS_v1, 0, MIPS_a1), -}; - -/* Restore all caller-saved MIPS registers and the current state block - * register values from the stack; the state block pointer is assumed to be - * in $at */ -static const uint32_t code_restore_regs_state[] = { - /* Restore values to the SH-2 state block */ - MIPS_MOVE(MIPS_a0, MIPS_at), - MIPS_ADDIU(MIPS_a1, MIPS_sp, 4*18), - MIPS_ADDIU(MIPS_a2, MIPS_a0, 4*23), - MIPS_LW(MIPS_v1, 0, MIPS_a1), - MIPS_ADDIU(MIPS_a0, MIPS_a0, 4), - MIPS_ADDIU(MIPS_a1, MIPS_a1, 4), - MIPS_BNE(MIPS_a0, MIPS_a2, -4), - MIPS_SW(MIPS_v1, -4, MIPS_a0), - MIPS_LW(MIPS_v1, 0, MIPS_a1), - MIPS_SW(MIPS_v1, offsetof(SH2State,cycles), MIPS_at), - /* Restore all MIPS caller-saved registers */ - MIPS_LW(MIPS_v1, 64, MIPS_sp), - MIPS_MTLO(MIPS_v1), - MIPS_LW(MIPS_v1, 68, MIPS_sp), - MIPS_MTHI(MIPS_v1), - MIPS_LW(MIPS_v0, 0, MIPS_sp), - MIPS_LW(MIPS_v1, 4, MIPS_sp), - MIPS_LW(MIPS_a0, 8, MIPS_sp), - MIPS_LW(MIPS_a1, 12, MIPS_sp), - MIPS_LW(MIPS_a2, 16, MIPS_sp), - MIPS_LW(MIPS_a3, 20, MIPS_sp), - MIPS_LW(MIPS_t0, 24, MIPS_sp), - MIPS_LW(MIPS_t1, 28, MIPS_sp), - MIPS_LW(MIPS_t2, 32, MIPS_sp), - MIPS_LW(MIPS_t3, 36, MIPS_sp), - MIPS_LW(MIPS_t4, 40, MIPS_sp), - MIPS_LW(MIPS_t5, 44, MIPS_sp), - MIPS_LW(MIPS_t6, 48, MIPS_sp), - MIPS_LW(MIPS_t7, 52, MIPS_sp), - MIPS_LW(MIPS_t8, 56, MIPS_sp), - MIPS_LW(MIPS_t9, 60, MIPS_sp), - /* Restore the stack pointer and return */ - MIPS_JR(MIPS_ra), - MIPS_ADDIU(MIPS_sp, MIPS_sp, 4*(18+24)), -}; - -/* Save all caller-saved MIPS registers on the stack */ -static const uint32_t code_save_regs[] = { - /* Add stack space for saving registers */ - MIPS_ADDIU(MIPS_sp, MIPS_sp, -(4*16)), - MIPS_SW(MIPS_v0, 0, MIPS_sp), - MIPS_SW(MIPS_v1, 4, MIPS_sp), - MIPS_SW(MIPS_a0, 8, MIPS_sp), - MIPS_SW(MIPS_a1, 12, MIPS_sp), - MIPS_SW(MIPS_a2, 16, MIPS_sp), - MIPS_SW(MIPS_a3, 20, MIPS_sp), - MIPS_SW(MIPS_t0, 24, MIPS_sp), - MIPS_SW(MIPS_t1, 28, MIPS_sp), - MIPS_SW(MIPS_t2, 32, MIPS_sp), - MIPS_SW(MIPS_t3, 36, MIPS_sp), - MIPS_SW(MIPS_t4, 40, MIPS_sp), - MIPS_SW(MIPS_t5, 44, MIPS_sp), - MIPS_SW(MIPS_t6, 48, MIPS_sp), - MIPS_SW(MIPS_t7, 52, MIPS_sp), - MIPS_SW(MIPS_t8, 56, MIPS_sp), - MIPS_SW(MIPS_t9, 60, MIPS_sp), - MIPS_MFLO(MIPS_v1), - MIPS_SW(MIPS_v1, 64, MIPS_sp), - MIPS_MFHI(MIPS_v1), - MIPS_JR(MIPS_ra), - MIPS_SW(MIPS_v1, 68, MIPS_sp), -}; - -/* Restore all caller-saved MIPS registers from the stack */ -static const uint32_t code_restore_regs[] = { - MIPS_LW(MIPS_v1, 64, MIPS_sp), - MIPS_MTLO(MIPS_v1), - MIPS_LW(MIPS_v1, 68, MIPS_sp), - MIPS_MTHI(MIPS_v1), - MIPS_LW(MIPS_v0, 0, MIPS_sp), - MIPS_LW(MIPS_v1, 4, MIPS_sp), - MIPS_LW(MIPS_a0, 8, MIPS_sp), - MIPS_LW(MIPS_a1, 12, MIPS_sp), - MIPS_LW(MIPS_a2, 16, MIPS_sp), - MIPS_LW(MIPS_a3, 20, MIPS_sp), - MIPS_LW(MIPS_t0, 24, MIPS_sp), - MIPS_LW(MIPS_t1, 28, MIPS_sp), - MIPS_LW(MIPS_t2, 32, MIPS_sp), - MIPS_LW(MIPS_t3, 36, MIPS_sp), - MIPS_LW(MIPS_t4, 40, MIPS_sp), - MIPS_LW(MIPS_t5, 44, MIPS_sp), - MIPS_LW(MIPS_t6, 48, MIPS_sp), - MIPS_LW(MIPS_t7, 52, MIPS_sp), - MIPS_LW(MIPS_t8, 56, MIPS_sp), - MIPS_LW(MIPS_t9, 60, MIPS_sp), - MIPS_JR(MIPS_ra), - MIPS_ADDIU(MIPS_sp, MIPS_sp, 4*16), -}; - -#endif // RTL_TRACE_STEALTH_FOR_SH2 - -/*************************************************************************/ -/*********************** Main translation routine ************************/ -/*************************************************************************/ - -/** - * rtl_translate_block_mips: Translate the given block into MIPS code. - * - * [Parameters] - * block: RTLBlock to translate - * code_ret: Pointer to variable to receive code buffer pointer - * size_ret: Pointer to variable to receive code buffer size (in bytes) - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * On error, *code_ret and *size_ret are not modified. - */ -int rtl_translate_block_mips(RTLBlock *block, void **code_ret, - uint32_t *size_ret) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(code_ret != NULL, return 0); - PRECOND(size_ret != NULL, return 0); - - /* Handle manually-optimized cases specially for increased efficiency */ - if (block->num_insns == 4 - && block->insns[0].opcode == RTLOP_LOAD_PARAM - && block->insns[0].src_imm == 0 - && block->insns[1].opcode == RTLOP_LOAD_ADDR - && block->insns[2].opcode == RTLOP_CALL - && block->insns[2].src1 == block->insns[0].dest - && block->insns[2].target == block->insns[1].dest - && block->insns[3].opcode == RTLOP_RETURN - ) { - const unsigned int length = 16; - uint32_t *code = malloc(length); - if (!code) { - DMSG("No memory for native buffer (%u bytes)", length); - return 0; - } - if ((uintptr_t)code >> 28 == block->insns[1].src_addr >> 28) { - code[0] = MIPS_J((block->insns[1].src_addr & 0x0FFFFFFF) >> 2); - code[1] = MIPS_NOP(); - } else { - code[0] = MIPS_LUI(MIPS_at, block->insns[1].src_addr >> 16); - code[1] = MIPS_ORI(MIPS_at, MIPS_at, - block->insns[1].src_addr & 0xFFFF); - code[2] = MIPS_JR(MIPS_at); - code[3] = MIPS_NOP(); - } - *code_ret = code; - *size_ret = length; - return 1; - } - - /* Initialize translation-specific fields */ - block->native_buffer = NULL; - block->native_bufsize = 0; - block->native_length = 0; - block->label_offsets = NULL; - block->mips.need_save_ra = 0; - block->mips.need_chain_at = 0; - block->mips.frame_used = 0; - block->mips.sreg_used = 0; - - /* Check that the number of labels won't cause problems for our fake - * MIPS instructions */ - if (UNLIKELY(block->next_label > 1<<16)) { - DMSG("%p: Too many labels (%u, max %u)", block, (1<<16) - 1, - block->next_label - 1); - } - - /* Allocate the label map */ - if (block->next_label > 0) { // Should always be true, but just in case - block->label_offsets = - malloc(sizeof(*block->label_offsets) * block->next_label); - if (UNLIKELY(!block->label_offsets)) { - DMSG("No memory for block label offsets (%u bytes)", - sizeof(*block->label_offsets) * block->next_label); - goto fail; - } - memset(block->label_offsets, -1, - sizeof(*block->label_offsets) * block->next_label); - } - - /* Allocate an initial native code buffer for the block */ - block->native_bufsize = NATIVE_EXPAND_SIZE; - block->native_buffer = malloc(block->native_bufsize); - if (UNLIKELY(!block->native_buffer)) { - DMSG("No memory for native buffer (%u bytes)", block->native_bufsize); - goto fail; - } - - /* Allocate MIPS registers (and possibly stack frame locations) for all - * RTL registers, and perform other pre-translation scanning and - * optimization */ - if (UNLIKELY(!allocate_registers(block))) { - goto fail; - } -#ifdef RTL_TRACE_GENERATE - print_regmap(block); -#endif - - /* Translate the RTL instructions into MIPS code */ -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - block->sh2_regcache_mask = 0; -#endif - if (UNLIKELY(!translate_block(block))) { - goto fail; - } - - /* Free the branch label offset table */ - free(block->label_offsets); - block->label_offsets = NULL; - - /* Shrink the buffer down to the actual length before returning it */ - *code_ret = realloc(block->native_buffer, block->native_length); - if (UNLIKELY(!*code_ret)) { - DMSG("realloc() to a smaller size failed?!"); - *code_ret = block->native_buffer; - } - *size_ret = block->native_length; - - /* Make sure we don't accidentally free the native code buffer while - * the caller is using it */ - block->native_buffer = NULL; - block->native_bufsize = 0; - block->native_length = 0; - - /* Success */ - free(block->label_offsets); - block->label_offsets = NULL; - return 1; - - fail: - free(block->native_buffer); - free(block->label_offsets); - block->native_buffer = NULL; - block->native_bufsize = 0; - block->native_length = 0; - block->label_offsets = NULL; - return 0; -} - -/*************************************************************************/ -/************************** Register allocation **************************/ -/*************************************************************************/ - -/** - * allocate_registers: Allocate MIPS registers (and, if necessary, stack - * frame locations) for all RTL registers in the block. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_registers(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - int unit_index; - - /* - * The basic algorithm used for allocating registers is linear scan, as - * described by Poletto and Sarkar. However, since we do not have a - * sorted list of live intervals, we instead iterate through the - * instruction stream, allocating a hardware register (or frame slot) - * for each RTL register the first time it is encountered. - * - * Since live intervals calculated by the core RTL code do not take - * into account backward branches, the register allocation code checks - * each basic unit for entering edges from later units in the code - * stream, and if such a unit is found, updates the live intervals of - * all live registers to extend through the end of that unit (the - * latest unit in code stream order if there is more than one). - * - * The basic algorithm is tweaked as follows for the MIPS CPU: - * - * - Registers which are live over multiple basic units including a - * unit with a subroutine call are preferentially assigned callee- - * saved registers $s0-$s8, while registers which are only live - * within a single basic unit or which do not cross a subroutine - * call are preferentially assigned caller-saved registers $v1, - * $a0-$a3, and $t0-$t9. ($at and $v1 are reserved for loading - * values from the stack frame to be used as instruction - * operands.) However, constants are always assigned caller-saved - * registers, since it is often faster (and never slower) to - * reload them with addiu/ori/lui instructions than to save and - * restore another register on the stack. - * - * - Among caller-saved registers, preference is given to registers - * whose last use was longer ago. This assists instruction - * rescheduling by providing a larger live window for each - * hardware register. Callee-saved registers are allocated in - * numerical order regardless of last use to minimize the number - * of such registers which need to be saved and restored. - * - * - When spilling registers, the register with the shortest usage - * interval is spilled, rather than the one with the longest. - * (Spilling the longest interval first would cause the SH-2 state - * block pointer to be spilled, significantly impacting - * performance.) - * [FIXME: Currently, we always spill the new register.] - */ - - /* Clear the register map, stack frame map, and active register list */ - memset(block->mips.reg_map, 0, sizeof(block->mips.reg_map)); - block->mips.reg_free = ~0; - memset(block->mips.frame_map, 0, sizeof(block->mips.frame_map)); - memset(block->mips.frame_free, ~0, sizeof(block->mips.frame_free)); - block->mips.first_active = -1; - - /* Pick up the first unit with a CALL instruction, so we know where - * we'll need to use callee-saved registers */ - block->mips.next_call_unit = block->first_call_unit; - - /* Allocate registers for each basic unit in code stream order */ - for (unit_index = 0; unit_index >= 0; - unit_index = block->units[unit_index].next_unit - ) { - if (UNLIKELY(!allocate_regs_unit(block, unit_index))) { - return 0; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_regs_unit: Allocate MIPS registers for an RTL basic unit. - * - * [Parameters] - * block: RTL block - * unit: Index of basic unit - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_regs_unit(RTLBlock * const block, - const unsigned int unit_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - RTLUnit * const unit = &block->units[unit_index]; - - /* Copy the current register and stack frame map to the unit structure */ - - memcpy(unit->mips.reg_map, block->mips.reg_map, - sizeof(block->mips.reg_map)); - memcpy(unit->mips.frame_map, block->mips.frame_map, - sizeof(block->mips.frame_map)); - - /* Move to the next call unit if we reached the current one */ - - while (block->mips.next_call_unit >= 0 - && block->mips.next_call_unit <= unit_index - ) { - block->mips.next_call_unit = - block->units[block->mips.next_call_unit].next_call_unit; - } - - /* Scan through RTL instructions and allocate MIPS registers */ - - int32_t insn_index; // Signed so we catch last_insn==-1 properly - for (insn_index = unit->first_insn; insn_index <= unit->last_insn; - insn_index++ - ) { - if (UNLIKELY(!allocate_regs_insn(block, unit_index, insn_index))) { - return 0; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_regs_insn: Perform register allocation for registers used in a - * single RTL instruction. - * - * [Parameters] - * block: RTL block - * unit_index: Index of current RTL unit - * insn_index: Index of RTL instruction to allocate registers for - * [Return value] - * Nonzero on success, zero on error - */ -static inline int allocate_regs_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(unit_index < block->num_units, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - RTLInsn * const insn = &block->insns[insn_index]; - - retry: - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm & 0x80000000) { - /* If we have stealth trace NOPs, we'll be calling subroutines, - * so ensure $ra is saved */ - block->mips.need_save_ra = 1; - } -#endif - return 1; - - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_RETURN: - return 1; - - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - /* If this register is unused elsewhere, kill the instruction */ - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } -#ifdef MIPS_OPTIMIZE_IMMEDIATE - /* Try to optimize this and the following instruction into a single - * immediate instruction (but only if it's part of the same unit) */ - if (insn_index < block->units[unit_index].last_insn - && optimize_immediate(block, insn_index) - ) { - if (insn->opcode != RTLOP_LOAD_IMM - && insn->opcode != RTLOP_LOAD_ADDR - ) { - goto retry; // Instruction was altered - } - } -#endif - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (!block->regs[insn->dest].native_allocated - && merge_constant_register(block, unit_index, insn_index, - insn->dest) - ) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - - case RTLOP_LOAD_PARAM: - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - /* If it's a long-lived register, let allocate_one_register() - * select a callee-saved register; otherwise, try to allocate the - * appropriate parameter register to avoid an unnecessary MOVE */ - if (block->mips.next_call_unit >= 0 - && block->regs[insn->dest].death - >= block->units[block->mips.next_call_unit].first_insn - ) { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } else { - return allocate_one_register_prefer( - block, unit_index, insn_index, insn->dest, - MIPS_a0 + block->regs[insn->dest].param_index - ); - } - - case RTLOP_MOVE: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - case RTLOP_BFEXT: - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1))) { - return 0; - } - /* Source registers can be reused as destination registers */ - clean_active_list(block, insn_index+1); - if (insn->opcode == RTLOP_ANDI && insn->src_imm > 0xFFFF - && block->regs[insn->src1].native_reg != MIPS_noreg - ) { - /* This might be handled as "ins dest,$zero,...", so try to - * make the destination use the same register as the source */ - return allocate_one_register_prefer( - block, unit_index, insn_index, insn->dest, - block->regs[insn->src1].native_reg - ); - } else { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } - - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->src1) - && allocate_one_register(block, unit_index, insn_index, - insn->dest); - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - - case RTLOP_SELECT: { - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->cond].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->cond)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - /* We implement SELECT with a MOVE/MOVZ pair in the general case. - * If the target shares a hardware register with either of the - * source operands, we can drop the MOVE and use a single MOVZ or - * MOVN instead, so try to do that. */ - int desired_reg; - if (((desired_reg = block->regs[insn->src1].native_reg) != MIPS_noreg - && desired_reg != MIPS_zero - && (block->mips.reg_free & (1 << desired_reg))) - || ((desired_reg = block->regs[insn->src2].native_reg) != MIPS_noreg - && desired_reg != MIPS_zero - && (block->mips.reg_free & (1 << desired_reg))) - ) { - return allocate_one_register_prefer(block, unit_index, insn_index, - insn->dest, desired_reg); - } else { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } - } - - case RTLOP_BFINS: { - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - /* The INS instruction treats its destination (rt) as read-write, - * so try to allocate the destination in the same register as src1. - * If we fail, we'll have to MOVE(dest,src1) at translation time. */ - if (block->regs[insn->src1].native_reg == MIPS_noreg - || block->regs[insn->src1].native_reg == MIPS_zero - ) { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } else { - const int desired_reg = block->regs[insn->src1].native_reg; - return allocate_one_register_prefer(block, unit_index, insn_index, - insn->dest, desired_reg); - } - } - - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_MADDU: - case RTLOP_MADDS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - if (UNLIKELY((!insn->dest || block->regs[insn->dest].birth == block->regs[insn->dest].death) - && (!insn->dest2 || block->regs[insn->dest2].birth == block->regs[insn->dest2].death)) - ) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - block->regs[insn->dest2].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - return (!insn->dest - || allocate_one_register(block, unit_index, insn_index, - insn->dest)) - && (!insn->dest2 - || allocate_one_register(block, unit_index, insn_index, - insn->dest2)); - - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - block->regs[insn->src1].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->src1); - - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->src1) - && allocate_one_register(block, unit_index, insn_index, - insn->src2); - - case RTLOP_CALL: { - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->dest = 0; - /* Execute the call anyway, because it may have side effects */ - } - if (insn->src1) { - block->regs[insn->src1].last_used = insn_index; - } - if (insn->src2) { - block->regs[insn->src2].last_used = insn_index; - } - block->regs[insn->target].last_used = insn_index; - if (insn->dest) { - block->regs[insn->dest].last_used = insn_index; - } - clean_active_list(block, insn_index); - if ((insn->src1 - && UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->src1, MIPS_a0))) - || (insn->src2 - && UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->src2, MIPS_a1))) - || UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->target, MIPS_t9)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - /* Null out any free caller-saved registers because they'll have - * been clobbered by the call (otherwise we might try to reuse a - * constant value that's no longer valid) */ - unsigned int i; - for (i = 0; i < lenof(caller_saved_regs); i++) { - const unsigned int mips_reg = caller_saved_regs[i]; - if (block->mips.reg_free & (1 << mips_reg)) { - block->mips.reg_map[mips_reg] = NULL; - } - } - if (insn->dest - && UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->dest, MIPS_v0)) - ) { - return 0; - } - /* We'll need to save $ra now */ - block->mips.need_save_ra = 1; - return 1; - } // case RTLOP_CALL - - case RTLOP_RETURN_TO: - block->regs[insn->target].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->target); - - } // switch (insn->opcode) - - DMSG("%p/%u: Invalid RTL opcode %u", block, insn_index, insn->opcode); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * add_to_active_list: Add a register to the active list. - * - * [Parameters] - * block: RTL block - * is_frame: Nonzero if the register is in a frame slot, zero if in a - * hardware register - * index: MIPS register index or frame slot index - * [Return value] - * None - */ -static void add_to_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index) -{ - PRECOND(block != NULL, return); - - const unsigned int list_index = is_frame ? 32+index : index; - block->mips.active_list[list_index].is_frame = is_frame ? 1 : 0; - block->mips.active_list[list_index].index = index; - const uint32_t death = is_frame ? block->mips.frame_map[index]->death - : block->mips.reg_map[index]->death; - - int insert_at = -1; - int next = block->mips.first_active; - while (next >= 0 - && (block->mips.active_list[next].is_frame - ? block->mips.frame_map[block->mips.active_list[next].index]->death - : block->mips.reg_map[block->mips.active_list[next].index]->death) - < death - ) { - insert_at = next; - next = block->mips.active_list[next].next; - } - if (insert_at < 0) { - block->mips.first_active = list_index; - } else { - block->mips.active_list[insert_at].next = list_index; - } - block->mips.active_list[list_index].next = next; -} - -/*----------------------------------*/ - -/** - * remove_from_active_list: Explicitly remove a register from the active - * list. Used when merging constants or updating the death time of an - * active register. This function does NOT set the "free" bit for the - * freed register or frame slot. - * - * [Parameters] - * block: RTL block - * is_frame: Nonzero if the register is in a frame slot, zero if in a - * hardware register - * index: MIPS register index or frame slot index - * [Return value] - * None - */ -static void remove_from_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index) -{ - PRECOND(block != NULL, return); - - const unsigned int list_index = is_frame ? 32+index : index; - - int prev = -1; - int next = block->mips.first_active; - while (next >= 0 && next != list_index) { - prev = next; - next = block->mips.active_list[next].next; - } - if (next >= 0) { - next = block->mips.active_list[next].next; - if (prev < 0) { - block->mips.first_active = next; - } else { - block->mips.active_list[prev].next = next; - } - } -} - -/*----------------------------------*/ - -/** - * clean_active_list: Clean all dead registers from the active list. - * - * [Parameters] - * block: RTL block - * clean_insn: Instruction index for cleaning registers (any register - * with death < clean_insn is cleaned) - * [Return value] - * None - */ -static void clean_active_list(RTLBlock * const block, - const uint32_t clean_insn) -{ - PRECOND(block != NULL, return); - - int first_active = block->mips.first_active; - while (first_active >= 0 - && (block->mips.active_list[first_active].is_frame - ? block->mips.frame_map[block->mips.active_list[first_active].index]->death - : block->mips.reg_map[block->mips.active_list[first_active].index]->death) - < clean_insn - ) { - const unsigned int index = block->mips.active_list[first_active].index; - if (block->mips.active_list[first_active].is_frame) { - block->mips.frame_free[index/32] |= 1 << (index%32); - } else { - block->mips.reg_free |= 1 << index; - } - first_active = block->mips.active_list[first_active].next; - block->mips.first_active = first_active; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_one_register: Allocate a MIPS register for the given RTL - * register, if it does not have one allocated already, and update the - * current register map. - * - * [Parameters] - * block: RTL block - * unit_index: Index of current basic unit - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * This routine only maps into the available caller-saved registers, - * $3-$15 and $24-$25 ($v1, $a0-$a3, and $t0-$t9); the callee-saved - * registers ($s0-$s8) are only used when renaming. - */ -static int allocate_one_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(reg_index < block->next_reg, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - /* If it's already allocated, just return */ - if (reg->native_allocated) { - return 1; - } - - /* If it's a constant zero value, just use $zero */ - if (reg->source == RTLREG_CONSTANT && reg->value == 0) { - reg->native_allocated = 1; - reg->native_reg = MIPS_zero; - /* We don't mark it in the register map or add it to the active - * list since $zero can be shared */ - return 1; - } - - /* Macro to select a register if its last use is the oldest so far */ - #define SELECT_REG_BY_AGE(mips_reg) { \ - const int __mips_reg = (mips_reg); \ - if (block->mips.reg_free & (1 << __mips_reg)) { \ - if (!block->mips.reg_map[__mips_reg]) { \ - best_mips = __mips_reg; \ - break; \ - } else if (block->mips.reg_map[__mips_reg]->death < oldest) { \ - best_mips = __mips_reg; \ - oldest = block->mips.reg_map[__mips_reg]->death; \ - } \ - } \ - } - /* Macro to select a register unconditionally if it's free */ - #define SELECT_REG_BY_FREE(mips_reg) { \ - const int __mips_reg = (mips_reg); \ - if (block->mips.reg_free & (1 << __mips_reg)) { \ - best_mips = __mips_reg; \ - break; \ - } \ - } - - int best_mips = -1; - uint32_t oldest = insn_index; // Last use of best_$mips - unsigned int i; - if (reg->source != RTLREG_CONSTANT - && block->mips.next_call_unit >= 0 - && reg->death >= block->units[block->mips.next_call_unit].first_insn - ) { - /* Prefer a callee-saved register for non-constant, long-lived - * registers */ - for (i = 0; i < lenof(callee_saved_regs); i++) { - SELECT_REG_BY_FREE(callee_saved_regs[i]); - } - if (best_mips < 0) { - for (i = 0; i < lenof(caller_saved_regs); i++) { - SELECT_REG_BY_AGE(caller_saved_regs[i]); - } - } - } else { - /* Prefer a caller-saved register for short-lived registers */ - for (i = 0; i < lenof(caller_saved_regs); i++) { - SELECT_REG_BY_AGE(caller_saved_regs[i]); - } - if (best_mips < 0) { - for (i = 0; i < lenof(callee_saved_regs); i++) { - SELECT_REG_BY_FREE(callee_saved_regs[i]); - } - } - } - - #undef SELECT_REG_BY_AGE - #undef SELECT_REG_BY_FREE - - if (best_mips < 0) { - /* No free registers, so give it a frame slot instead */ - reg->native_allocated = 1; - reg->native_reg = MIPS_noreg; - return allocate_frame_slot(block, insn_index, reg_index); - } - - reg->native_allocated = 1; - reg->native_reg = best_mips; - block->mips.reg_map[best_mips] = &block->regs[reg_index]; - block->mips.reg_free &= ~(1 << best_mips); - if (reg_is_callee_saved[best_mips]) { - block->mips.sreg_used |= 1 << best_mips; - } - add_to_active_list(block, 0, best_mips); - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_one_register_prefer: Allocate a MIPS register for the given - * RTL register, like allocate_one_register(), but use MIPS register - * "prefer_mips" if possible. (If a MIPS register has already been - * allocated, the allocation is left unchanged.) - * - * [Parameters] - * block: RTL block - * unit_index: Index of current basic unit - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * prefer_mips: MIPS register to prefer - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_one_register_prefer(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index, - const unsigned int prefer_mips) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(reg_index < block->next_reg, return 0); - PRECOND(prefer_mips < 32, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - if (!reg->native_allocated && (block->mips.reg_free & (1<native_allocated = 1; - reg->native_reg = prefer_mips; - block->mips.reg_map[prefer_mips] = &block->regs[reg_index]; - block->mips.reg_free &= ~(1 << prefer_mips); - if (reg_is_callee_saved[prefer_mips]) { - block->mips.sreg_used |= 1 << prefer_mips; - } - add_to_active_list(block, 0, prefer_mips); - return 1; - } - - /* We couldn't get the preferred register, so just allocate as usual */ - return allocate_one_register(block, unit_index, insn_index, reg_index); -} - -/*-----------------------------------------------------------------------*/ - -/** - * merge_constant_register: Look for a MIPS hardware register holding the - * same constant value as the given RTL register; if found, assign that - * MIPS register to the given RTL register as well. - * - * When MIPS_OPTIMIZE_MERGE_CONSTANTS is disabled, this function will not - * search for generic constant registers, but will still assign $zero to - * RTL registers with the constant value 0. - * - * [Parameters] - * block: RTL block - * unit_index: Index of current basic unit - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * [Return value] - * Nonzero if the register was successfully merged with another, else zero - */ -static int merge_constant_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(unit_index < block->num_units, return 0); - PRECOND(reg_index < block->next_reg, return 0); - PRECOND(!block->regs[reg_index].native_allocated, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - /* If it's a constant zero value, just use $zero */ - if (reg->source == RTLREG_CONSTANT && reg->value == 0) { - reg->native_allocated = 1; - reg->native_reg = MIPS_zero; - /* We don't mark it in the register map or add it to the active - * list since $zero can be shared */ - return 1; - } - - /* If it's a constant that has the same value as another constant - * that's already been loaded (and if MIPS_OPTIMIZE_MERGE_CONSTANTS - * is enabled), reuse the same hardware register. But don't reuse a - * register that died in a previous basic unit, since it may be on a - * different code path */ -#ifdef MIPS_OPTIMIZE_MERGE_CONSTANTS - if (reg->source == RTLREG_CONSTANT) { - unsigned int mips_reg; - for (mips_reg = MIPS_v1; mips_reg <= MIPS_s8; mips_reg++) { - if (block->mips.reg_map[mips_reg] - && block->mips.reg_map[mips_reg]->death - >= block->units[unit_index].first_insn - && block->mips.reg_map[mips_reg]->source == RTLREG_CONSTANT - && block->mips.reg_map[mips_reg]->value == reg->value - ) { - /* Found a match--assign this MIPS register to the - * current RTL register, and ensure the MIPS register - * stays allocated until all merged registers are dead */ - reg->native_allocated = 1; - reg->native_reg = mips_reg; - if (reg->death < block->mips.reg_map[mips_reg]->death) { - reg->death = block->mips.reg_map[mips_reg]->death; - } - reg->next_merged = block->mips.reg_map[mips_reg]; - block->mips.reg_map[mips_reg] = &block->regs[reg_index]; - RTLRegister *merged_reg = reg; - while ((merged_reg = merged_reg->next_merged) != NULL) { - merged_reg->death = reg->death; - } - if (!(block->mips.reg_free & (1 << mips_reg))) { - /* The register's live interval has changed, so remove - * it from the active list (we'll re-add it below) */ - remove_from_active_list(block, 0, mips_reg); - } - block->mips.reg_free &= ~(1 << mips_reg); - add_to_active_list(block, 0, mips_reg); - return 1; - } - } - } -#endif - - /* Couldn't merge this register into another */ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_frame_slot: Allocate a frame slot for the given RTL register, - * if it does not have one allocated already. - * - * [Parameters] - * block: RTL block - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_frame_slot(RTLBlock * const block, - const uint32_t insn_index, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(reg_index < block->next_reg, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - if (reg->frame_allocated) { - return 1; - } - - const unsigned int num_slots = MIPS_FRAME_SIZE/4; - unsigned int slot; - for (slot = 0; slot < num_slots; slot++) { - if (block->mips.frame_free[slot/32] & (1 << (slot%32))) { - break; - } - } - if (slot >= num_slots) { - DMSG("%p/%u: No free frame slots for RTL register %u", - block, insn_index, reg_index); - return 0; - } - - reg->frame_allocated = 1; - reg->frame_slot = slot; - reg->stack_offset = slot * 4; - block->mips.frame_map[slot] = &block->regs[reg_index]; - block->mips.frame_free[slot/32] &= ~(1 << (slot%32)); - block->mips.frame_used = 1; - add_to_active_list(block, 1, slot); - return 1; -} - -/*-----------------------------------------------------------------------*/ - -#ifdef MIPS_OPTIMIZE_IMMEDIATE - -/** - * optimize_immediate: Attempt to optimize a sequence of LOAD_IMM or - * LOAD_ADDR followed by an instruction using the loaded constant into a - * sequence which uses fewer MIPS instructions. On success, the RTL - * instruction (and possibly following instructions) will be altered - * appropriately. - * - * The following optimizations are performed when r1 is not used beyond - * the second instruction and (for ALU instructions) the constant value is - * within range of the particular instruction: - * - * LOAD_IMM r1, constant; ALUOP r2, r3, r1 - * --> NOP; ALUOPI r2, r3, constant - * - * LOAD_ADDR r1, address; LOAD_{BU,BS,HU,HS,W} r2, offset(r1) - * --> LOAD_ADDR r1, %hi(address+offset); - * l{bu,b,hu,h,w} r2, %lo(address+offset)(r1) - * - * LOAD_ADDR r1, address; STORE_{B,H,W} offset(r1), r2 - * --> LOAD_ADDR r1, %hi(address+offset); - * s{b,h,w} r2, %lo(address+offset)(r1) - * - * where ALUOP is one of ADD, SUB, AND, OR, XOR, SLL, SRL, SRA, ROR, SLTU, - * or SLTS. - * - * [Parameters] - * block: RTL block being translated - * unit_index: Index of current basic unit - * insn_index: Index of RTL LOAD_IMM or LOAD_ADDR instruction - * [Return value] - * Nonzero if the given RTL instruction was successfully optimized, - * else zero - */ -static int optimize_immediate(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - PRECOND(block->insns[insn_index].opcode == RTLOP_LOAD_IMM - || block->insns[insn_index].opcode == RTLOP_LOAD_ADDR, - return 0); - PRECOND(block->insns[insn_index].dest != 0 - && block->insns[insn_index].dest < block->next_reg, return 0); - - RTLInsn *insn = &block->insns[insn_index]; - const uint32_t imm_index = insn[0].dest; - const uintptr_t value = block->regs[imm_index].value; - - if (block->regs[imm_index].death > insn_index+1) { - /* Register is used later, so we can't optimize the load out */ - return 0; - } - - switch ((RTLOpcode)insn[1].opcode) { - - case RTLOP_ADD: - if (value + 0x8000 <= 0xFFFF) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ADDI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ADDI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - - case RTLOP_SUB: - if (value + 0x7FFF <= 0xFFFF && insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ADDI; - insn[1].src_imm = -value; - return 1; - } - return 0; - - case RTLOP_AND: { - int is_insable = 0; // Can we turn it into "ins reg,$zero,..."? - if (value & 1) { - /* Must be 0b000...111 */ - is_insable = ((value & (value+1)) == 0); - } else { - /* Must be 0b111...000 */ - is_insable = ((~value & (~value+1)) == 0); - } - if (value <= 0xFFFF || is_insable) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ANDI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ANDI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - } // case RTLOP_AND - - case RTLOP_OR: - if (value <= 0xFFFF) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ORI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ORI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - - case RTLOP_XOR: - if (value <= 0xFFFF) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_XORI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_XORI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - - case RTLOP_SLL: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SLLI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SRL: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SRLI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SRA: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SRAI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_ROR: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_RORI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SLTU: - if (value + 0x8000 <= 0xFFFF && insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SLTUI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SLTS: - if (value + 0x8000 <= 0xFFFF && insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SLTSI; - insn[1].src_imm = value; - return 1; - } - return 0; - - /*----------------------------*/ - - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - if (insn[1].src1 == imm_index) { - const uint32_t address = value + insn[1].offset; - insn[0].src_imm = (address + 0x8000) & 0xFFFF0000; - block->regs[imm_index].value = insn[0].src_imm; - insn[1].offset = (int16_t)(address & 0xFFFF); - return 1; - } - return 0; - - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - if (insn[1].dest == imm_index) { - const uint32_t address = value + insn[1].offset; - insn[0].src_imm = (address + 0x8000) & 0xFFFF0000; - block->regs[imm_index].value = insn[0].src_imm; - insn[1].offset = (int16_t)(address & 0xFFFF); - return 1; - } - return 0; - - /*----------------------------*/ - - case RTLOP_NOP: - case RTLOP_MOVE: - case RTLOP_SELECT: - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_MADDU: - case RTLOP_MADDS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - case RTLOP_BFEXT: - case RTLOP_BFINS: - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - case RTLOP_LOAD_PARAM: - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - case RTLOP_CALL: - case RTLOP_RETURN: - case RTLOP_RETURN_TO: - return 0; - - } // switch (insn[1].opcode) - - DMSG("%p/%u: Invalid RTL opcode %u", block, insn_index, insn[1].opcode); - return 0; -} - -#endif // MIPS_OPTIMIZE_IMMEDIATE - -/*-----------------------------------------------------------------------*/ - -#ifdef RTL_TRACE_GENERATE - -/* Helper macro for print_regmap() to check the status of an instruction - * operand and update the line buffer and register map accordingly */ - -# define CHECK_REG(which) do { \ - const uint32_t __rtl_reg = insn->which; \ - if (__rtl_reg > 0 && __rtl_reg < block->next_reg \ - && block->regs[__rtl_reg].native_allocated \ - && block->regs[__rtl_reg].native_reg != MIPS_noreg \ - ) { \ - const uint32_t __mips_reg = block->regs[__rtl_reg].native_reg; \ - const unsigned int __column = columns[__mips_reg]; \ - if (!__column) { \ - break; \ - } \ - if (block->regs[__rtl_reg].birth == insn_index) { \ - block->mips.reg_map[__mips_reg] = &block->regs[__rtl_reg]; \ - unsigned int __value = __rtl_reg; \ - int __pos = 3; \ - do { \ - linebuf[__column+__pos] = '0' + (__value % 10); \ - __value /= 10; \ - __pos--; \ - } while (__value > 0 && __pos >= 0); \ - if (__pos >= 0) { \ - linebuf[__column+__pos] = 'r'; \ - } \ - print_line = 1; \ - } \ - } \ -} while (0) - -/*----------------------------------*/ - -/** - * print_regmap: Print the state of the RTL-to-MIPS register map over the - * course of the block. - * - * [Parameters] - * block: RTL block - * [Return value] - * None - */ -static void print_regmap(RTLBlock * const block) -{ - PRECOND(block != NULL, return); - - fprintf(stderr, "%p: MIPS register allocation:\n", block); - fprintf(stderr, " | v0 v1: a0 a1 a2 a3:" - " t0 t1 t2 t3: t4 t5 t6 t7: t8 t9\n"); - fprintf(stderr, "-----+--------+----------------+" - "----------------+----------------+--------\n"); - static const char template[75] = - " | : :" - " : : \n"; - static const unsigned int columns[32] = { - 0, 0, 6,10, 15,19,23,27, 32,36,40,44, 49,53,57,61, - 0, 0, 0, 0, 0, 0, 0, 0, 66,70, 0, 0, 0, 0, 0, 0, - }; - - char linebuf[75]; - memcpy(linebuf, template, sizeof(template)); - memset(block->mips.reg_map, 0, sizeof(block->mips.reg_map)); - - uint32_t insn_index; - for (insn_index = 0; insn_index < block->num_insns; insn_index++) { - const RTLInsn * const insn = &block->insns[insn_index]; - - /* Only print lines where registers are born or die */ - int print_line = 0; - - /* Fill in active registers first */ - unsigned int mips_reg; - for (mips_reg = MIPS_v0; mips_reg <= MIPS_t9; - mips_reg = (mips_reg==MIPS_t7 ? MIPS_t8 : mips_reg+1) - ) { - if (block->mips.reg_map[mips_reg] - && block->mips.reg_map[mips_reg]->death >= insn_index - ) { - unsigned int column = columns[mips_reg]; - if (column) { - if (block->mips.reg_map[mips_reg]->death == insn_index) { - block->mips.reg_map[mips_reg] = NULL; - linebuf[column+1] = '-'; - linebuf[column+2] = '-'; - linebuf[column+3] = '-'; - print_line = 1; - } else { - linebuf[column+2] = '|'; - } - } - } - } - - /* For simplicity, don't bother checking opcodes; just look at any - * register index that's in range and report it if it's become live */ - CHECK_REG(dest); - CHECK_REG(src1); - CHECK_REG(src2); - CHECK_REG(dest2); - - /* Print the line (with instruction index) if appropriate */ - if (print_line) { - unsigned int value = insn_index; - int pos = 4; - do { - linebuf[pos] = '0' + (value % 10); - value /= 10; - pos--; - } while (value > 0 && pos >= 0); - fwrite(linebuf, sizeof(linebuf), 1, stderr); - } - - /* Reset for the next line */ - memcpy(linebuf, template, sizeof(template)); - - } // for (insn_index) -} - -#undef CHECK_REG - -#endif // RTL_TRACE_GENERATE - -/*************************************************************************/ -/************************ Instruction translation ************************/ -/*************************************************************************/ - -/** - * APPEND: Append a MIPS instruction word to the native code buffer. - */ -#define APPEND(insn) do { \ - if (UNLIKELY(!append_insn(block, (insn)))) { \ - return 0; \ - } \ -} while (0) - -/** - * APPEND_FLOAT: Append a high-latency instruction (load, multiply or - * divide) to the native code buffer. If possible (and if rescheduling is - * enabled), the instruction is floated up by at most "latency" - * instructions to avoid a stall. - */ -#define APPEND_FLOAT(insn,latency) do { \ - if (UNLIKELY(!append_float(block, (insn), (latency)))) { \ - return 0; \ - } \ -} while (0) - -/** - * APPEND_BRANCH: Append a MIPS branch instruction to the native code buffer. - */ -#define APPEND_BRANCH(insn) do { \ - if (UNLIKELY(!append_branch(block, (insn)))) { \ - return 0; \ - } \ -} while (0) - -/** - * IS_SPILLED: Return nonzero if the given register (by index) is spilled, - * else zero. Assumes the variable "insn_index" is available and valid, - * and assumes that the register has been allocated a MIPS register. - * - * Under the current allocation scheme, simply returns nonzero iff the - * given register is live and does not have a hardware register allocated. - */ -#define IS_SPILLED(reg_index) \ - (block->regs[(reg_index)].birth < insn_index \ - && block->regs[(reg_index)].native_reg == MIPS_noreg) - -/** - * MAP_REGISTER: Look up the MIPS register mapped to the given RTL - * register and store it in a local variable. Pass one of the identifiers - * "dest", "src1", "src2", "dest2", or "target" as the "which" parameter; - * the MIPS register will be stored in the corresponding variable ("dest2" - * and "target" must be declared in any blocks that use them). If the RTL - * register does not have an assigned MIPS register, it is loaded into a - * temporary register. - * - * If the MIPS register must not collide with another register used by the - * same instruction, pass the RTL register index of that register as the - * "avoid" parameter (e.g. insn->src1 or insn->src2). If the register to - * be mapped is currently spilled and loading it would cause the "avoid" - * register to be spilled, it is loaded into $at and left spilled. If - * there is no register to avoid, pass 0 as the "avoid" parameter. - * - * The "reload" parameter indicates whether the register should be reloaded - * if it is not currently active. At the moment, this only applies to - * registers located on the stack. - */ -#define MAP_REGISTER(which,reload,avoid) do { \ - which = __MAP_REGISTER(block, insn->which, (reload), (avoid)); \ - if (UNLIKELY(which < 0)) { \ - return 0; \ - } \ -} while (0) -static int __MAP_REGISTER(RTLBlock * const block, const unsigned int reg_index, - const int reload, const uint32_t avoid_index) -{ - RTLRegister * const reg = &block->regs[reg_index]; - PRECOND(reg->native_allocated, return -1); - int mips_reg = reg->native_reg; - if (mips_reg == MIPS_noreg) { - mips_reg = MIPS_at; - if (block->mips.reg_map[mips_reg] == &block->regs[(avoid_index)]) { - mips_reg = MIPS_v1; - } - PRECOND(reg->frame_allocated, return -1); - if (reload - && UNLIKELY(!append_insn(block, MIPS_LW(mips_reg, reg->stack_offset, - MIPS_sp))) - ) { - return -1; - } - } - /* If it's in HI or LO, pull it out */ - if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | mips_reg<<11); - reg->mips.is_in_hilo = 0; - /* We don't clear the register from block->mips.{hi,lo}_reg, in - * case a subsequent madd/maddu instruction can make use of it */ - } - /* Update the register map unless we're using $zero */ - if (mips_reg != MIPS_zero) { - block->mips.reg_map[mips_reg] = reg; - } - /* Update the stack frame map if this register has a frame slot */ - if (reg->frame_allocated) { - block->mips.frame_map[reg->frame_slot] = reg; - } - return mips_reg; -} - -/** - * MAYBE_SAVE: Save the given register ("dest" or "dest2") to its frame - * slot if one is assigned. - */ -#define MAYBE_SAVE(reg) do { \ - RTLRegister * const regptr = &block->regs[insn->reg]; \ - if (regptr->frame_allocated) { \ - APPEND(MIPS_SW(reg, regptr->stack_offset, MIPS_sp)); \ - } \ -} while (0) - -/*************************************************************************/ - -/** - * translate_block: Perform the actual translation of an RTL block. - * - * [Parameters] - * block: RTL block to translate - * [Return value] - * Nonzero on success, zero on error - */ -static int translate_block(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - - int32_t i; - - /* Clear translation state */ - memset(block->mips.reg_map, 0, sizeof(block->mips.reg_map)); - block->mips.hi_reg = 0; - block->mips.lo_reg = 0; - memset(block->mips.frame_map, 0, sizeof(block->mips.frame_map)); - - /* Determine the total frame size, including space for saving and - * restoring callee-saved registers on entry/exit as well as for - * saving caller-saved registers around a CALL instruction */ - if (block->mips.need_save_ra || block->mips.frame_used) { - block->mips.total_frame_size = - MIPS_FRAME_SIZE + 4*16 // 16 caller-saved regs (not $at/$v1) - + 4; // $ra - } else { - block->mips.total_frame_size = 0; // No space needed for CALLs - } - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - block->mips.total_frame_size += 4; - } - } - block->mips.total_frame_size = - (block->mips.total_frame_size + 4) & -8; // Must be a multiple of 8 - - /* Start with the function prologue */ - if (UNLIKELY(!append_prologue(block))) { - return 0; - } - - /* Translate code a unit at a time */ - for (i = 0; i >= 0; i = block->units[i].next_unit) { - if (UNLIKELY(!translate_unit(block, i))) { - return 0; - } - } - - /* Append the function epilogue */ - if (UNLIKELY(!append_epilogue(block))) { - return 0; - } - - /* Resolve branches to labels */ - if (UNLIKELY(!resolve_branches(block))) { - return 0; - } - - /* Finished */ - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * translate_unit: Translate an RTL basic unit into MIPS code. - * - * [Parameters] - * block: RTL block being translated - * unit_index: Index of basic unit to translate - * [Return value] - * Nonzero on success, zero on error - */ -static inline int translate_unit(RTLBlock * const block, - const unsigned int unit_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(unit_index < block->num_units, return 0); - - RTLUnit * const unit = &block->units[unit_index]; - uint32_t i; - - /* Reset the current register map to that at the beginning of the unit - * as determined by flow analysis during register allocation */ - memcpy(block->mips.reg_map, unit->mips.reg_map, sizeof(unit->mips.reg_map)); - - /* Translate each RTL instruction in the unit */ - block->mips.unit_start = block->native_length; - i = unit->first_insn; - while ((int32_t)i <= unit->last_insn) { - const unsigned int num_processed = translate_insn(block, unit_index, i); - if (UNLIKELY(!num_processed)) { - return 0; - } - i += num_processed; - } - - /* Flush out any values cached in HI/LO for safety */ - if (UNLIKELY(!flush_hilo(block, unit->last_insn+1))) { - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * translate_insn: Translate a single RTL instruction into MIPS code. - * Optimization may result in multiple RTL instructions being parsed. - * - * [Parameters] - * block: RTL block being translated - * unit_index: Index of basic unit being translated - * insn_index: Index of RTL instruction to translate - * [Return value] - * Number of RTL instructions processed (nonzero) on success, zero on error - */ -static inline unsigned int translate_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - int dest, src1, src2; // MIPS register indices (mapped only when needed) - - block->mips.reg_map[MIPS_at] = NULL; // For MAP_REGISTER() - - /*------------------------------*/ - - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm >> 28 == 0x8 || insn->src_imm >> 28 == 0xA) { - return sh2_stealth_trace_insn(block, insn_index); - } else if (insn->src_imm >> 28 == 0xB) { - return sh2_stealth_cache_reg(block, insn_index); - } else if (insn->src_imm >> 28 == 0xC) { - return sh2_stealth_trace_store(block, insn_index); - } -#endif // RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm != 0) { - /* Debugging stuff from JIT_DEBUG_INSERT_PC (sh2.c) */ - const uint32_t addr = insn->src_imm; - APPEND(MIPS_LUI(MIPS_zero, addr>>16)); - APPEND(MIPS_ORI(MIPS_zero, MIPS_zero, addr & 0xFFFF)); - } - return 1; - - /*----------------------------*/ - - case RTLOP_MOVE: - if (block->regs[insn->src1].mips.is_in_hilo - && block->regs[insn->src1].death == insn_index - ) { - /* Handle this case specially--if we did it the usual way, - * we'd waste a cycle with MFHI/MFLO to src1 followed by a - * MOVE from src1 to dest. */ - MAP_REGISTER(dest, 0, 0); - APPEND(block->regs[insn->src1].mips.is_in_hilo | dest<<11); - block->regs[insn->src1].mips.is_in_hilo = 0; - } else { - MAP_REGISTER(src1, 1, 0); - /* Note: we have to map the output operand _after_ all the input - * operands, or else the output operand will get spilled if it - * shares a hardware register with an input operand. (This isn't - * actually true with the current allocation scheme, since we never - * share hardware registers between multiple live RTL registers, - * but it's applicable in general, and it doesn't hurt anything to - * do it this way.) */ - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MOVE(dest, src1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SELECT: { - int cond; - int spilled_v1 = 0; - if (block->regs[insn->src1].native_reg != MIPS_noreg) { - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(src2, 1, insn->cond); - MAP_REGISTER(cond, 1, insn->src2); - } else if (block->regs[insn->src2].native_reg != MIPS_noreg) { - MAP_REGISTER(src1, 1, insn->cond); - MAP_REGISTER(src2, 1, 0); - MAP_REGISTER(cond, 1, insn->src1); - } else if (block->regs[insn->cond].native_reg != MIPS_noreg) { - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(cond, 1, 0); - } else { - DMSG("%p/%u: WARNING: spilling $v1 to reload all 3 SELECT" - " operands", block, insn_index); - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_LW(MIPS_v1, - 8 + block->regs[insn->cond].stack_offset, MIPS_sp)); - cond = MIPS_v1; - spilled_v1 = 1; - } - MAP_REGISTER(dest, 0, 0); - if (dest == src1) { - APPEND(MIPS_MOVZ(dest, src2, cond)); - } else if (dest == src2) { - APPEND(MIPS_MOVN(dest, src1, cond)); - } else if (dest == cond) { - DMSG("%p/%u: WARNING: dest==cond ($%u) for SELECT, using slow" - " register swap", block, insn_index, dest); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(cond, 0, MIPS_sp)); - APPEND(MIPS_SW(src1, 4, MIPS_sp)); - APPEND(MIPS_MOVE(dest, src1)); - APPEND(MIPS_LW(src1, 0, MIPS_sp)); - APPEND(MIPS_MOVZ(dest, src2, src1)); - APPEND(MIPS_LW(src1, 4, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - } else { - APPEND(MIPS_MOVE(dest, src1)); - APPEND(MIPS_MOVZ(dest, src2, cond)); - } - if (spilled_v1) { - APPEND(MIPS_LW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_ADD: - return append_alu_reg(block, insn, MIPS_ADDU(0, 0, 0)); - - case RTLOP_SUB: - return append_alu_reg(block, insn, MIPS_SUBU(0, 0, 0)); - - case RTLOP_MULU: - return append_mult_div(block, insn, MIPS_MULTU(0, 0), 0, insn_index); - - case RTLOP_MULS: - return append_mult_div(block, insn, MIPS_MULT(0, 0), 0, insn_index); - - case RTLOP_MADDU: - return append_mult_div(block, insn, MIPS_MADDU(0, 0), 1, insn_index); - - case RTLOP_MADDS: - return append_mult_div(block, insn, MIPS_MADD(0, 0), 1, insn_index); - - case RTLOP_DIVMODU: - return append_mult_div(block, insn, MIPS_DIVU(0, 0), 0, insn_index); - - case RTLOP_DIVMODS: - return append_mult_div(block, insn, MIPS_DIV(0, 0), 0, insn_index); - - case RTLOP_AND: - return append_alu_reg(block, insn, MIPS_AND(0, 0, 0)); - - case RTLOP_OR: - return append_alu_reg(block, insn, MIPS_OR(0, 0, 0)); - - case RTLOP_XOR: - return append_alu_reg(block, insn, MIPS_XOR(0, 0, 0)); - - case RTLOP_NOT: - return append_alu_1op(block, insn, MIPS_NOR(0, 0, MIPS_zero)); - - case RTLOP_SLL: - return append_shift_reg(block, insn, MIPS_SLLV(0, 0, 0)); - - case RTLOP_SRL: - return append_shift_reg(block, insn, MIPS_SRLV(0, 0, 0)); - - case RTLOP_SRA: - return append_shift_reg(block, insn, MIPS_SRAV(0, 0, 0)); - - case RTLOP_ROR: - return append_shift_reg(block, insn, MIPS_RORV(0, 0, 0)); - - case RTLOP_CLZ: - return append_alu_1op(block, insn, MIPS_CLZ(0, 0)); - - case RTLOP_CLO: - return append_alu_1op(block, insn, MIPS_CLZ(0, 0)); - - case RTLOP_SLTU: - return append_alu_reg(block, insn, MIPS_SLTU(0, 0, 0)); - - case RTLOP_SLTS: -#ifdef MIPS_OPTIMIZE_MIN_MAX - { - const int num_insns = optimize_min_max(block, insn_index); - if (num_insns) { - return num_insns; - } - } -#endif - return append_alu_reg(block, insn, MIPS_SLT(0, 0, 0)); - - case RTLOP_BSWAPH: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_WSBH(dest, src1)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_BSWAPW: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_WSBW(dest, src1)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_HSWAPW: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_ROR(dest, src1, 16)); - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_ADDI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_ADDU(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_ANDI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ANDI(dest, src1, insn->src_imm & 0xFFFF)); - } else if (insn->src_imm == 0xFFFFFFFF) { - if (dest != src1) { - APPEND(MIPS_MOVE(dest, src1)); - } - } else if (((insn->src_imm & 1) - && !(insn->src_imm & (insn->src_imm+1))) - || (!(insn->src_imm & 1) - && !(~insn->src_imm & (~insn->src_imm+1))) - ) { - unsigned int start, count; - if (insn->src_imm & 1) { - count = __builtin_clz(insn->src_imm); - start = 32 - count; - } else { - count = 32 - __builtin_allegrex_clo(insn->src_imm); - start = 0; - } - if (dest != src1) { - APPEND(MIPS_MOVE(dest, src1)); - } - APPEND(MIPS_INS(dest, MIPS_zero, start, count)); - } else { - if (insn->src_imm >= 0xFFFF8000) { - APPEND(MIPS_ADDIU(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_AND(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_ORI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm >= 0xFFFF8000) { - APPEND(MIPS_ADDIU(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_OR(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_XORI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 0x10000) { - APPEND(MIPS_XORI(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm >= 0xFFFF8000) { - APPEND(MIPS_ADDIU(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_XOR(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SLLI: - MAP_REGISTER(src1, 1, 0); -#ifdef MIPS_OPTIMIZE_SEX - if ((insn->src_imm == 16 || insn->src_imm == 24) - && block->regs[insn->dest].death == insn_index+1 - && insn[1].opcode == RTLOP_SRAI - && insn[1].src1 == insn->dest - && insn[1].src_imm == insn->src_imm - ) { - insn++; - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm == 16) { - APPEND(MIPS_SEH(dest, src1)); - } else { - APPEND(MIPS_SEB(dest, src1)); - } - MAYBE_SAVE(dest); - return 2; - } -#endif - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 32) { - APPEND(MIPS_SLL(dest, src1, insn->src_imm)); - } else { - APPEND(MIPS_MOVE(dest, MIPS_zero)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SRLI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 32) { - APPEND(MIPS_SRL(dest, src1, insn->src_imm)); - } else { - APPEND(MIPS_MOVE(dest, MIPS_zero)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SRAI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 32) { - APPEND(MIPS_SRA(dest, src1, insn->src_imm)); - } else { - APPEND(MIPS_SRA(dest, src1, 31)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_RORI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_ROR(dest, src1, insn->src_imm & 31)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SLTUI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm + 0x8000 < 0x10000) { - APPEND(MIPS_SLTIU(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_SLTU(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SLTSI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm + 0x8000 < 0x10000) { - APPEND(MIPS_SLTI(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_SLT(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_BFEXT: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_EXT(dest, src1, - insn->bitfield.start, insn->bitfield.count)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_BFINS: - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(dest, 0, 0); - if (dest != src1) { - APPEND(MIPS_MOVE(dest, src1)); - } - MAP_REGISTER(src2, 1, insn->dest); - APPEND(MIPS_INS(dest, src2, - insn->bitfield.start, insn->bitfield.count)); - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_LOAD_IMM: { - const uint32_t value = insn->src_imm; - MAP_REGISTER(dest, 0, 0); - if (value + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(dest, MIPS_zero, value)); - } else if (value < 0x10000) { - APPEND(MIPS_ORI(dest, MIPS_zero, value)); - } else { - APPEND(MIPS_LUI(dest, value>>16)); - if (value & 0xFFFF) { - APPEND(MIPS_ORI(dest, dest, value & 0xFFFF)); - } - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_LOAD_ADDR: { - const uint32_t value = insn->src_addr; -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - if (block->regs[insn->dest].source == RTLREG_CONSTANT - && block->regs[insn->dest].birth == insn_index - && block->regs[insn->dest].death == insn_index+1 - && insn[1].opcode == RTLOP_CALL - && insn[1].target == insn->dest - ) { - /* Just skip the instruction; CALL will detect the constant and - * handle it properly */ - return 1; - } -#endif - MAP_REGISTER(dest, 0, 0); - if (value + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(dest, MIPS_zero, value)); - } else if (value < 0x10000) { - APPEND(MIPS_ORI(dest, MIPS_zero, value)); - } else { - APPEND(MIPS_LUI(dest, value>>16)); - if (value & 0xFFFF) { - APPEND(MIPS_ORI(dest, dest, value & 0xFFFF)); - } - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_LOAD_PARAM: { - const uint32_t param_index = insn->src_imm; - if (UNLIKELY(param_index > 8)) { - DMSG("Only 8 function parameters supported, index %u is invalid", - param_index); - return 0; - } - const unsigned int param_reg = MIPS_a0 + param_index; - MAP_REGISTER(dest, 0, 0); - if (dest != param_reg) { - APPEND(MIPS_MOVE(dest, param_reg)); - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_LOAD_BU: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LBU(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_BS: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LB(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_HU: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LHU(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_HS: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LH(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LW(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_STORE_B: - /* "dest" is actually a source operand here */ - MAP_REGISTER(src1, 1, insn->dest); - MAP_REGISTER(dest, 1, insn->src1); - APPEND(MIPS_SB(src1, insn->offset, dest)); - return 1; - - case RTLOP_STORE_H: - MAP_REGISTER(src1, 1, insn->dest); - MAP_REGISTER(dest, 1, insn->src1); - APPEND(MIPS_SH(src1, insn->offset, dest)); - return 1; - - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - MAP_REGISTER(src1, 1, insn->dest); - MAP_REGISTER(dest, 1, insn->src1); - APPEND(MIPS_SW(src1, insn->offset, dest)); - return 1; - - /*----------------------------*/ - - case RTLOP_LABEL: - block->label_offsets[insn->label] = block->native_length; - return 1; - - case RTLOP_GOTO: - /* A branch to the following unit is in effect a no-op, so just - * skip it entirely */ - if (block->label_unitmap[insn->label] == block->units[unit_index].next_unit) { - return 1; - } - /* Flush any cached values out of HI or LO */ - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - /* Fill in a fake opcode for now; this will be replaced later with - * a real branch instruction once the offset is known */ - APPEND_BRANCH(MIPS_B_LABEL(insn->label)); - return 1; - - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: { - if (block->label_unitmap[insn->label] == block->units[unit_index].next_unit) { - return 1; - } - MAP_REGISTER(src1, 1, 0); - /* Make sure it doesn't collide with anything we're about to - * reload, and move to $at if so */ - unsigned int target_unit = block->label_unitmap[insn->label]; - if (block->units[target_unit].first_insn < insn_index) { - RTLRegister * const target_reg = - block->units[target_unit].mips.reg_map[src1]; - if (target_reg && target_reg != &block->regs[insn->src1] - && target_reg->death >= insn_index - ) { - APPEND(MIPS_MOVE(MIPS_at, src1)); - src1 = MIPS_at; - } - } - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - if (insn->opcode == RTLOP_GOTO_IF_Z) { - APPEND_BRANCH(MIPS_BEQZ_LABEL(src1, insn->label)); - } else { - APPEND_BRANCH(MIPS_BNEZ_LABEL(src1, insn->label)); - } - return 1; - } // case RTLOP_GOTO_IF_{Z,NZ} - - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: { - if (block->label_unitmap[insn->label] == block->units[unit_index].next_unit) { - return 1; - } - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - unsigned int target_unit = block->label_unitmap[insn->label]; - if (block->units[target_unit].first_insn < insn_index) { - RTLRegister * const target_reg1 = - block->units[target_unit].mips.reg_map[src1]; - if (target_reg1 && target_reg1 != &block->regs[insn->src1] - && target_reg1->death >= insn_index - ) { - if (src2 == MIPS_at) { - APPEND(MIPS_MOVE(MIPS_v1, src1)); - src1 = MIPS_v1; - } else { - APPEND(MIPS_MOVE(MIPS_at, src1)); - src1 = MIPS_at; - } - } - RTLRegister * const target_reg2 = - block->units[target_unit].mips.reg_map[src2]; - if (target_reg2 && target_reg2 != &block->regs[insn->src2] - && target_reg2->death >= insn_index - ) { - if (src1 == MIPS_at) { - APPEND(MIPS_MOVE(MIPS_v1, src2)); - src2 = MIPS_v1; - } else { - APPEND(MIPS_MOVE(MIPS_at, src2)); - src2 = MIPS_at; - } - } - } - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - if (insn->opcode == RTLOP_GOTO_IF_E) { - APPEND_BRANCH(MIPS_BEQ_LABEL(src1, src2, insn->label)); - } else { - APPEND_BRANCH(MIPS_BNE_LABEL(src1, src2, insn->label)); - } - return 1; - } // case RTLOP_GOTO_IF_{E,NE} - - /*----------------------------*/ - - case RTLOP_CALL: { - - /* Map the argument registers, if any */ - src1 = src2 = 0; // Avoid a compiler warning (not actually needed) - if (insn->src1) { - MAP_REGISTER(src1, 1, insn->src2); - if (insn->src2) { - MAP_REGISTER(src2, 1, insn->src1); - } - } - - /* Flush any cached values out of HI or LO */ - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - - /* Flush all live caller-saved registers to the stack */ - if (UNLIKELY(!flush_for_call(block, insn_index))) { - return 0; - } - - /* Map the function address, if necessary */ - int target; -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - if (block->regs[insn->target].source == RTLREG_CONSTANT) { - target = -1; - } else { -#endif - /* Need to avoid collision with both src1 and src2; the - * MAP_REGISTER macro can't handle avoiding two registers at - * once, so we do it manually here, taking advantage of the - * registers reed up by flush_for_call(). This won't actually - * occur in practice as long as MIPS_OPTIMIZE_ABSOLUTE_CALL is - * enabled, since all the calls we make are to known addresses. */ - RTLRegister * const target_reg = &block->regs[insn->target]; - if (target_reg->native_reg == MIPS_noreg - && (src1 == MIPS_v1 || src2 == MIPS_v1) - ) { - PRECOND(target_reg->frame_allocated, return 0); - if (src1 == MIPS_v1) { // Impossible, but just for completeness - if (src2 == MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a2, src1)); - src1 = MIPS_a2; - } else { - APPEND(MIPS_MOVE(MIPS_a2, src1)); - src1 = MIPS_a2; - } - } else if (src2 == MIPS_v1) { - if (src1 == MIPS_a1) { - APPEND(MIPS_MOVE(MIPS_a2, src2)); - src2 = MIPS_a2; - } else { - APPEND(MIPS_MOVE(MIPS_a1, src2)); - src2 = MIPS_a1; - } - } - APPEND(MIPS_LW(MIPS_v1, target_reg->stack_offset, MIPS_sp)); - target = MIPS_v1; - } else { // No collision - MAP_REGISTER(target, 1, 0); - } -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - } -#endif - - /* Move any parameters to $a0-$a1 */ - if (insn->src1) { - if (insn->src2) { - if (src1 == MIPS_a1) { - if (src2 == MIPS_a0) { - /* Arguments are reversed, so use $at as a - * temporary to exchange them */ - APPEND(MIPS_MOVE(MIPS_at, MIPS_a1)); - src1 = MIPS_at; - } else { - APPEND(MIPS_MOVE(MIPS_a0, MIPS_a1)); - src1 = MIPS_a0; - } - } - if (src2 != MIPS_a1) { - APPEND(MIPS_MOVE(MIPS_a1, src2)); - } - } - if (src1 != MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a0, src1)); - } - } - - /* Actually call the routine */ -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - if (block->regs[insn->target].source == RTLREG_CONSTANT) { - const uint32_t address = block->regs[insn->target].value; - APPEND_BRANCH(MIPS_JAL((address & 0x0FFFFFFC) >> 2)); - } else { -#endif - APPEND_BRANCH(MIPS_JALR(MIPS_t9)); -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - } -#endif - - /* Copy the return value to the target register, if there is one */ - if (insn->dest) { - MAP_REGISTER(dest, 0, 0); - if (dest != MIPS_v0) { - APPEND(MIPS_MOVE(dest, MIPS_v0)); - } - MAYBE_SAVE(dest); - } - - /* Reload all flushed registers */ - if (UNLIKELY(!reload_after_call(block, insn_index))) { - return 0; - } - - return 1; - } // case RTLOP_CALL - - case RTLOP_RETURN: - if (insn_index == block->units[unit_index].last_insn - && block->units[unit_index].next_unit == -1 - ) { - /* This is the last instruction, so we can just fall through */ - } else { - APPEND_BRANCH(MIPS_B_EPILOGUE_RET_CONST); - } - return 1; - - case RTLOP_RETURN_TO: { - int target; - MAP_REGISTER(target, 1, 0); - if (target != MIPS_at) { - APPEND(MIPS_MOVE(MIPS_at, target)); - } - /* Don't forget to reload parameters. (Since we only use this for - * predicted static branches to other native code, we know that we - * can just pass the first parameter, i.e. the state block pointer, - * along; for a more general implementation, we'd treat this like - * CALL and take parameters.) */ - if (UNLIKELY(block->regs[1].source != RTLREG_PARAMETER) - || UNLIKELY(block->regs[1].param_index != 0) - ) { - DMSG("r1 is not state block, can't handle"); - return 0; - } - if (block->regs[1].native_reg != MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a0, block->regs[1].native_reg)); - } - APPEND_BRANCH(MIPS_B_EPILOGUE_CHAIN_AT); - block->mips.need_chain_at = 1; - return 1; - } // case RTLOP_RETURN_TO - - } // switch (insn->opcode) - - /*------------------------------*/ - - DMSG("%p/%u: Invalid RTL opcode %u", block, insn_index, insn->opcode); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * append_alu_1op: Append a 1-register-operand ALU instruction to the - * instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rd set to zero) - * [Return value] - * 1 on success, 0 on error - */ -static int append_alu_1op(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode) -{ - PRECOND(block != NULL, return 0); - - int src1, dest; - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(opcode | src1<<21 | dest<<11); - MAYBE_SAVE(dest); - return 1; -} - -/*----------------------------------*/ - -/** - * append_alu_reg: Append a 2-register-operand ALU instruction (other than - * a shift insturction) to the instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rt/rd set to zero) - * [Return value] - * 1 on success, 0 on error - */ -static int append_alu_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode) -{ - PRECOND(block != NULL, return 0); - - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - APPEND(opcode | src1<<21 | src2<<16 | dest<<11); - MAYBE_SAVE(dest); - return 1; -} - -/*----------------------------------*/ - -/** - * append_shift_reg: Append a variable-count shift instruction to the - * instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rt/rd set to zero) - * [Return value] - * 1 on success, 0 on error - */ -static int append_shift_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode) -{ - PRECOND(block != NULL, return 0); - - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - /* Register order is reversed from regular ALU insns: SLLV rd,rt,rs - * (as opposed to ADDU rd,rs,rt) */ - APPEND(opcode | src2<<21 | src1<<16 | dest<<11); - MAYBE_SAVE(dest); - return 1; -} - -/*----------------------------------*/ - -/** - * append_mult_div: Append a multiply or divide instruction to the - * instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rt set to zero) - * accumulate: Nonzero if this is an accumulating instruction (madd/maddu) - * insn_index: Index of instruction being translated - * [Return value] - * 1 on success, 0 on error - */ -static int append_mult_div(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode, const int accumulate, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - - if (accumulate) { - /* If the proper registers are already in HI and LO, we don't need - * to do anything here */ - if (block->mips.hi_reg != insn->dest2 - || block->mips.lo_reg != insn->dest - ) { - /* Need to reload HI and/or LO; don't bother with the case - * where one of the two is correctly loaded, since normally - * both will be preloaded properly */ - flush_hilo(block, insn_index); - int dest2; - MAP_REGISTER(dest2, 1, 0); - APPEND(MIPS_MTHI(dest2)); - int dest; - MAP_REGISTER(dest, 1, 0); - APPEND(MIPS_MTLO(dest)); - } - } else { - /* Make sure anything currently in HI/LO is flushed out before we - * overwrite them */ - flush_hilo(block, insn_index); - } - - int src1, src2; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - const int float_distance = ((opcode & 0x3E) == __SP_DIV) ? 35 : 6; - APPEND_FLOAT(opcode | src1<<21 | src2<<16, float_distance); - if (insn->dest) { - if (block->regs[insn->dest].frame_allocated) { - /* We have to save it to the stack, so it can't stay in LO */ - int dest; - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MFLO(dest)); - MAYBE_SAVE(dest); - } else { - /* Leave it in LO for now; we'll extract it when we need it */ - block->regs[insn->dest].mips.is_in_hilo = MIPS_MFLO(0); - block->mips.lo_reg = insn->dest; - } - } - if (insn->dest2) { - if (block->regs[insn->dest2].frame_allocated) { - int dest2; - MAP_REGISTER(dest2, 0, 0); - APPEND(MIPS_MFHI(dest2)); - MAYBE_SAVE(dest2); - } else { - block->regs[insn->dest2].mips.is_in_hilo = MIPS_MFHI(0); - block->mips.hi_reg = insn->dest2; - } - } - return 1; -} - -/*************************************************************************/ - -/** - * flush_for_call: Flush all caller-saved registers to the stack frame in - * preparation for a subroutine call. Registers which are born on or die - * with the current instruction are not saved; the destination register is - * also not saved (normally the destination register will be born with this - * instruction, but if the code is not SSA-form, it may already be live). - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of instruction being translated - * [Return value] - * Nonzero on success, zero on error - */ -static int flush_for_call(RTLBlock * const block, const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const uint32_t dest = block->insns[insn_index].dest; - - unsigned int push_offset = MIPS_FRAME_SIZE; - unsigned int i; - for (i = 0; i < lenof(caller_saved_regs); i++) { - const unsigned int mips_reg = caller_saved_regs[i]; - RTLRegister * const reg = block->mips.reg_map[mips_reg]; - if (reg - && reg->birth < insn_index - && reg->death > insn_index - && !(dest && reg == &block->regs[dest]) - && reg->source != RTLREG_CONSTANT - ) { - APPEND(MIPS_SW(mips_reg, push_offset, MIPS_sp)); - push_offset += 4; - } - } - - return 1; -} - -/*----------------------------------*/ - -/** - * reload_after_call: Reload necessary caller-saved registers after a - * subroutine call. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of instruction being translated - * [Return value] - * Nonzero on success, zero on error - */ -static int reload_after_call(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const uint32_t dest = block->insns[insn_index].dest; - - unsigned int pop_offset = MIPS_FRAME_SIZE; - unsigned int i; - for (i = 0; i < lenof(caller_saved_regs); i++) { - const unsigned int mips_reg = caller_saved_regs[i]; - RTLRegister * const reg = block->mips.reg_map[mips_reg]; - if (reg - && reg->birth < insn_index - && reg->death > insn_index - && !(dest && reg == &block->regs[dest]) - ) { - if (reg->source == RTLREG_CONSTANT) { - const uint32_t value = reg->value; - if (value + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(mips_reg, MIPS_zero, value)); - } else if (value < 0x10000) { - APPEND(MIPS_ORI(mips_reg, MIPS_zero, value)); - } else { - APPEND(MIPS_LUI(mips_reg, value>>16)); - if (value & 0xFFFF) { - APPEND(MIPS_ORI(mips_reg, mips_reg, value & 0xFFFF)); - } - } - } else { - APPEND(MIPS_LW(mips_reg, pop_offset, MIPS_sp)); - pop_offset += 4; - } - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * flush_hilo: Flush any values cached in the MIPS HI or LO registers to - * the appropriate general-purpose register. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction being translated (if between - * instructions, next instruction to be translated) - * [Return value] - * Nonzero on success, zero on error - */ -static int flush_hilo(RTLBlock * const block, const uint32_t insn_index) -{ - if (block->mips.hi_reg) { - RTLRegister * const reg = &block->regs[block->mips.hi_reg]; - /* If the register was already updated, its is_in_hilo field will - * be zero, so we don't need to update the register ourselves in - * that case; we just clear the register reference from hi_reg. - * Also make sure that we don't try to update a register that's - * already dead. */ - if (reg->mips.is_in_hilo && reg->death >= insn_index) { - PRECOND(reg->mips.is_in_hilo == MIPS_MFHI(0), return 0); - PRECOND(reg->native_allocated, return 0); - PRECOND(reg->native_reg != MIPS_noreg, return 0); - PRECOND(reg->native_reg != MIPS_zero, return 0); - APPEND(reg->mips.is_in_hilo | reg->native_reg<<11); - reg->mips.is_in_hilo = 0; - block->mips.reg_map[reg->native_reg] = reg; - } - block->mips.hi_reg = 0; - } - if (block->mips.lo_reg) { - RTLRegister * const reg = &block->regs[block->mips.lo_reg]; - if (reg->mips.is_in_hilo && reg->death >= insn_index) { - PRECOND(reg->mips.is_in_hilo == MIPS_MFLO(0), return 0); - PRECOND(reg->native_allocated, return 0); - PRECOND(reg->native_reg != MIPS_noreg, return 0); - PRECOND(reg->native_reg != MIPS_zero, return 0); - APPEND(reg->mips.is_in_hilo | reg->native_reg<<11); - reg->mips.is_in_hilo = 0; - block->mips.reg_map[reg->native_reg] = reg; - } - block->mips.lo_reg = 0; - } - return 1; -} - -/*************************************************************************/ - -#ifdef MIPS_OPTIMIZE_MIN_MAX - -/** - * optimize_min_max: Attempt to optimize an SLTS instruction followed by a - * SELECT instruction into a MIPS MIN or MAX instruction. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction to optimize (must be SLTS) - * [Return value] - * Number of RTL instructions processed (nonzero) if the given RTL - * instruction was successfully optimized into a MIPS MIN or MAX - * instruction, else zero - */ -static int optimize_min_max(RTLBlock * const block, const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - PRECOND(block->insns[insn_index].opcode == RTLOP_SLTS, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - - if (block->regs[insn->dest].death != insn_index+1 - || insn[1].opcode != RTLOP_SELECT - || insn[1].cond != insn->dest - ) { - return 0; - } else if (insn[1].src1 == insn->src1 && insn[1].src2 == insn->src2) { - insn++; - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MIN(dest, src1, src2)); - return 2; - } else if (insn[1].src1 == insn->src2 && insn[1].src2 == insn->src1) { - insn++; - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MAX(dest, src1, src2)); - return 2; - } else { - return 0; - } -} - -#endif // MIPS_OPTIMIZE_MIN_MAX - -/*************************************************************************/ - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - -/*----------------------------------*/ - -/** - * sh2_stealth_trace_insn: Add MIPS code to trace an instruction for SH-2 - * TRACE_STEALTH mode. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction to translate - * [Return value] - * Number of RTL instructions processed (nonzero) on success, zero on error - */ -static unsigned int sh2_stealth_trace_insn(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - if (block->regs[1].source != RTLREG_PARAMETER - || block->regs[1].param_index != 0 - ) { - DMSG("r1 is not state block, can't handle"); - return 0; - } - - const RTLInsn *insn = &block->insns[insn_index]; - unsigned int num_insns = 1; // Number of RTL instructions consumed - unsigned int cond_reg = 0; - unsigned int test_bit = 0; - uint32_t op = insn[num_insns++].src_imm; - if (op>>24 == 0x9F) { // Conditional execution - cond_reg = op & 0xFFFF; - test_bit = op>>16 & 1; - op = insn[num_insns++].src_imm; - } - uint32_t cached_cycles = op; - PRECOND(cached_cycles>>24 == 0x98, return 1); - cached_cycles &= 0xFFFF; - uint32_t cached_cycle_reg = insn[num_insns++].src_imm; - PRECOND(cached_cycles>>24 == 0x90, return 1); - cached_cycle_reg &= 0xFFFF; - - /* First save all registers; load the state block pointer into $at in - * the delay slot */ - APPEND(MIPS_JAL(((uintptr_t)code_save_regs_state & 0x0FFFFFFC) >> 2)); - if (IS_SPILLED(1)) { - APPEND(MIPS_LW(MIPS_at, block->regs[1].stack_offset, MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_at, block->regs[1].native_reg)); - } - - /* Update the state block with cached register values */ - uint32_t mask = block->sh2_regcache_mask; - if (mask) { - const uintptr_t cache_ptr = (uintptr_t)sh2_regcache; - APPEND(MIPS_LUI(MIPS_a0, cache_ptr >> 16)); - APPEND(MIPS_ORI(MIPS_a0, MIPS_a0, cache_ptr & 0xFFFF)); - } - unsigned int sh2_reg; - for (sh2_reg = 0; mask != 0; mask >>= 1, sh2_reg++) { - if (mask & 1) { - APPEND(MIPS_LW(MIPS_v1, 4*sh2_reg, MIPS_a0)); - APPEND(MIPS_SW(MIPS_v1, 4*sh2_reg, MIPS_at)); - } - } - - /* Update the state block's cached cycle count */ - if (cached_cycle_reg) { - RTLRegister * const reg = &block->regs[cached_cycle_reg]; - if (IS_SPILLED(cached_cycle_reg)) { - APPEND(MIPS_LW(MIPS_v1, 4*(18+24) + reg->stack_offset, MIPS_sp)); - } else if (reg->native_reg >= MIPS_v0 && reg->native_reg <= MIPS_t7) { - APPEND(MIPS_LW(MIPS_v1, 4*(reg->native_reg - MIPS_v0), MIPS_sp)); - } else if (reg->native_reg >= MIPS_t8 && reg->native_reg <= MIPS_t9) { - APPEND(MIPS_LW(MIPS_v1, - 4*(reg->native_reg - MIPS_t8 + 14), MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_v1, reg->native_reg)); - } - } - APPEND(MIPS_ADDI(MIPS_v1, MIPS_v1, cached_cycles)); - APPEND(MIPS_SW(MIPS_v1, offsetof(SH2State,cycles), MIPS_at)); - - /* Call the trace routine (if the instruction isn't nulled out) */ - if (cond_reg) { - if (IS_SPILLED(cond_reg)) { - APPEND(MIPS_LW(MIPS_v1, 4*(18+24) + block->regs[cond_reg].stack_offset, MIPS_sp)); - } else if (block->regs[cond_reg].native_reg >= MIPS_v0 - && block->regs[cond_reg].native_reg <= MIPS_t7) { - APPEND(MIPS_LW(MIPS_v1, 4*(block->regs[cond_reg].native_reg - MIPS_v0), MIPS_sp)); - } else if (block->regs[cond_reg].native_reg >= MIPS_t8 - && block->regs[cond_reg].native_reg <= MIPS_t9) { - APPEND(MIPS_LW(MIPS_v1, 4*(block->regs[cond_reg].native_reg - MIPS_t8 + 14), MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_v1, block->regs[cond_reg].native_reg)); - } - APPEND(MIPS_XORI(MIPS_v1, MIPS_v1, test_bit)); - APPEND(MIPS_BNEZ(MIPS_v1, 4)); - } - APPEND(MIPS_LUI(MIPS_a1, (insn->src_imm & 0x7FFF0000) >> 16)); - APPEND(MIPS_ORI(MIPS_a1, MIPS_a1, insn->src_imm & 0xFFFF)); - APPEND(MIPS_JAL(((uintptr_t)trace_insn_callback & 0x0FFFFFFC) >> 2)); - APPEND(MIPS_MOVE(MIPS_a0, MIPS_at)); - - /* Restore everything back the way it was */ - APPEND(MIPS_JAL(((uintptr_t)code_restore_regs_state & 0x0FFFFFFC) >> 2)); - if (IS_SPILLED(1)) { - APPEND(MIPS_LW(MIPS_at, - 4*(18+24) + block->regs[1].stack_offset, MIPS_sp)); - } else if (block->regs[1].native_reg >= MIPS_v0 - && block->regs[1].native_reg <= MIPS_t7) { - APPEND(MIPS_LW(MIPS_at, - 4*(block->regs[1].native_reg - MIPS_v0), MIPS_sp)); - } else if (block->regs[1].native_reg >= MIPS_t8 - && block->regs[1].native_reg <= MIPS_t9) { - APPEND(MIPS_LW(MIPS_at, - 4*(block->regs[1].native_reg - MIPS_t8 + 14), MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_at, block->regs[1].native_reg)); - } - - return num_insns; -} - -/*----------------------------------*/ - -/** - * sh2_stealth_cache_reg: Add MIPS code to cache a register value for - * SH-2 TRACE_STEALTH mode. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction to translate - * [Return value] - * Number of RTL instructions processed (nonzero) on success, zero on error - */ -static unsigned int sh2_stealth_cache_reg(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - unsigned int num_insns = 1; - uint32_t op = insn->src_imm; - uint32_t offset = 0; - - /* Get the offset if we have one */ - if (op & 0x08000000) { - PRECOND(op>>24 == 0xB8, return 1); - offset = (op & 0xFFFF) << 16; - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xBC, return 1); - offset |= op & 0xFFFF; - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xB0, return 1); - } - - unsigned int sh2_reg = (op >> 16) & 0xFF; - unsigned int rtl_reg = op & 0xFFFF; - - if (rtl_reg) { - /* Store a new value into the cache */ - - const RTLRegister * const reg = &block->regs[rtl_reg]; - unsigned int mips_reg; - if (reg->native_allocated - && reg == block->mips.reg_map[reg->native_reg] - ) { - if (IS_SPILLED(rtl_reg)) { - APPEND(MIPS_LW(MIPS_at, reg->stack_offset, MIPS_sp)); - mips_reg = MIPS_at; - } else if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | MIPS_at<<11); - mips_reg = MIPS_at; - } else if (reg->native_reg == MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_at, MIPS_a0)); - mips_reg = MIPS_at; - } else { - mips_reg = reg->native_reg; - } - } else { - /* Either the register is already dead and got clobbered, or it - * got eliminated perhaps because the corresponding SH-2 - * register was later overwritten. This is a pain if the - * dead/eliminated register is a result register, but what can - * we do... */ - switch (reg->source) { - - case RTLREG_CONSTANT: - APPEND(MIPS_LUI(MIPS_at, reg->value >> 16)); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, reg->value & 0xFFFF)); - break; - - case RTLREG_MEMORY: { - const RTLRegister * const addr_reg = - &block->regs[reg->memory.addr_reg]; - unsigned int base_reg; - if (addr_reg->native_allocated - && addr_reg==block->mips.reg_map[addr_reg->native_reg] - ) { - base_reg = addr_reg->native_reg; - } else if (addr_reg->source == RTLREG_CONSTANT) { - APPEND(MIPS_LUI(MIPS_at, addr_reg->value>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, addr_reg->value&0xFFFF)); - base_reg = MIPS_at; - } else { - DMSG("%p/%u: Address register r%u not available for r%u", - block, insn_index, reg->memory.addr_reg, rtl_reg); - break; - } - if (reg->memory.size == 1) { // 8 bits - if (reg->memory.is_signed) { - APPEND(MIPS_LB(MIPS_at, reg->memory.offset, base_reg)); - } else { - APPEND(MIPS_LBU(MIPS_at, reg->memory.offset, base_reg)); - } - } else if (reg->memory.size == 2) { // 16 bits - if (reg->memory.is_signed) { - APPEND(MIPS_LH(MIPS_at, reg->memory.offset, base_reg)); - } else { - APPEND(MIPS_LHU(MIPS_at, reg->memory.offset, base_reg)); - } - } else { // 32 bits - APPEND(MIPS_LW(MIPS_at, reg->memory.offset, base_reg)); - } - break; - } // case RTLREG_MEMORY - - case RTLREG_RESULT: - case RTLREG_RESULT_NOFOLD: { - static const uint32_t mips_opcodes[] = { - [RTLOP_ADD ] = MIPS_ADDU (MIPS_at, 0, 0), - [RTLOP_ADDI ] = MIPS_ADDU (MIPS_at, 0, 0), - [RTLOP_SUB ] = MIPS_SUBU (MIPS_at, 0, 0), - [RTLOP_MULU ] = MIPS_MULTU(0, 0), - [RTLOP_MULS ] = MIPS_MULT (0, 0), - [RTLOP_DIVMODU] = MIPS_DIVU (0, 0), - [RTLOP_DIVMODS] = MIPS_DIV (0, 0), - [RTLOP_AND ] = MIPS_AND (MIPS_at, 0, 0), - [RTLOP_ANDI ] = MIPS_AND (MIPS_at, 0, 0), - [RTLOP_OR ] = MIPS_OR (MIPS_at, 0, 0), - [RTLOP_ORI ] = MIPS_OR (MIPS_at, 0, 0), - [RTLOP_XOR ] = MIPS_XOR (MIPS_at, 0, 0), - [RTLOP_XORI ] = MIPS_XOR (MIPS_at, 0, 0), - [RTLOP_NOT ] = MIPS_NOR (MIPS_at, 0, MIPS_zero), - [RTLOP_SLL ] = MIPS_SLLV (MIPS_at, 0, 0), - [RTLOP_SLLI ] = MIPS_SLLV (MIPS_at, 0, 0), - [RTLOP_SRL ] = MIPS_SRLV (MIPS_at, 0, 0), - [RTLOP_SRLI ] = MIPS_SRLV (MIPS_at, 0, 0), - [RTLOP_SRA ] = MIPS_SRAV (MIPS_at, 0, 0), - [RTLOP_SRAI ] = MIPS_SRAV (MIPS_at, 0, 0), - [RTLOP_ROR ] = MIPS_RORV (MIPS_at, 0, 0), - [RTLOP_RORI ] = MIPS_RORV (MIPS_at, 0, 0), - [RTLOP_CLZ ] = MIPS_CLZ (MIPS_at, 0), - [RTLOP_CLO ] = MIPS_CLO (MIPS_at, 0), - [RTLOP_SLTU ] = MIPS_SLTU (MIPS_at, 0, 0), - [RTLOP_SLTUI ] = MIPS_SLTU (MIPS_at, 0, 0), - [RTLOP_SLTS ] = MIPS_SLT (MIPS_at, 0, 0), - [RTLOP_SLTSI ] = MIPS_SLT (MIPS_at, 0, 0), - [RTLOP_BSWAPH ] = MIPS_WSBH (MIPS_at, 0), - [RTLOP_BSWAPW ] = MIPS_WSBW (MIPS_at, 0), - [RTLOP_HSWAPW ] = MIPS_ROR (MIPS_at, 0, 16), - }; - const RTLRegister *src1_reg, *src2_reg; - src1_reg = &block->regs[reg->result.src1]; - src2_reg = &block->regs[reg->result.src2]; - switch (reg->result.opcode) { - - case RTLOP_MOVE: - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_MOVE(MIPS_at, src1_reg->native_reg)); - } - break; - - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: { - int rs; - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - APPEND(mips_opcodes[reg->result.opcode] | rs<<21); - break; - } - - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: { - int rt; - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - rt = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rt = MIPS_at; - } else { - rt = src1_reg->native_reg; - } - APPEND(mips_opcodes[reg->result.opcode] | rt<<16); - break; - } - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: { - unsigned int rs, rt; // src1/src2 MIPS registers - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_v1, src2_reg->stack_offset, MIPS_sp)); - rt = MIPS_v1; - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_v1<<11); - rt = MIPS_v1; - } else { - rt = src2_reg->native_reg; - } - if ((mips_opcodes[reg->result.opcode] & 0xFC00003F) < 010){ - /* For SLLV/SRLV/SRAV/RORV, rt is the source and - * rs is the shift amount */ - APPEND(mips_opcodes[reg->result.opcode] | rt<<21 | rs<<16); - } else { - APPEND(mips_opcodes[reg->result.opcode] | rs<<21 | rt<<16); - } - break; - } - - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: { - unsigned int rs, rt; // src1/src2 MIPS registers - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - rt = MIPS_v1; - APPEND(MIPS_LUI(rt, reg->result.imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(rt, rt, reg->result.imm & 0xFFFF)); - if ((mips_opcodes[reg->result.opcode] & 0xFC00003F) < 010){ - APPEND(mips_opcodes[reg->result.opcode] | rt<<21 | rs<<16); - } else { - APPEND(mips_opcodes[reg->result.opcode] | rs<<21 | rt<<16); - } - break; - } - - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: { - unsigned int rs, rt; - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_MFHI(MIPS_v1)); - APPEND(MIPS_SW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_MFLO(MIPS_v1)); - APPEND(MIPS_SW(MIPS_v1, 4, MIPS_sp)); - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_v1, src2_reg->stack_offset, MIPS_sp)); - rt = MIPS_v1; - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_v1<<11); - rt = MIPS_v1; - } else { - rt = src2_reg->native_reg; - } - APPEND(mips_opcodes[reg->result.opcode] | rs<<21 | rt<<16); - if (reg->result.second_res) { - APPEND(MIPS_MFHI(MIPS_at)); - } else { - APPEND(MIPS_MFLO(MIPS_at)); - } - APPEND(MIPS_LW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_MTHI(MIPS_v1)); - APPEND(MIPS_LW(MIPS_v1, 4, MIPS_sp)); - APPEND(MIPS_MTLO(MIPS_v1)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - break; - } - - case RTLOP_SELECT: { - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(MIPS_v0, 0, MIPS_sp)); - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_MOVE(MIPS_at, src1_reg->native_reg)); - } - int reg_src2, reg_cond; - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_v0, - src2_reg->stack_offset, MIPS_sp)); - reg_src2 = MIPS_v0; - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_v0<<11); - reg_src2 = MIPS_v0; - } else { - reg_src2 = src2_reg->native_reg; - } - if (IS_SPILLED(reg->result.cond)) { - APPEND(MIPS_LW(MIPS_v1, block->regs[reg->result.cond].stack_offset, MIPS_sp)); - reg_cond = MIPS_v1; - } else if (block->regs[reg->result.cond].mips.is_in_hilo) { - APPEND(block->regs[reg->result.cond].mips.is_in_hilo - | MIPS_at<<11); - } else { - reg_cond = block->regs[reg->result.cond].native_reg; - } - APPEND(MIPS_MOVZ(MIPS_at, reg_src2, reg_cond)); - APPEND(MIPS_LW(MIPS_v0, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - break; - } - - case RTLOP_BFEXT: - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - APPEND(MIPS_EXT(MIPS_at, MIPS_at, - insn->bitfield.start, - insn->bitfield.count)); - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_EXT(MIPS_at, src1_reg->native_reg, - insn->bitfield.start, - insn->bitfield.count)); - } - break; - - case RTLOP_BFINS: { - unsigned int rs; - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_at, - src2_reg->stack_offset, MIPS_sp)); - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_MOVE(MIPS_at, src2_reg->native_reg)); - } - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_v1, src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_v1; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_v1<<11); - rs = MIPS_v1; - } else { - rs = src1_reg->native_reg; - } - APPEND(MIPS_INS(MIPS_at, rs, insn->bitfield.start, - insn->bitfield.count)); - break; - } - - default: - DMSG("%p/%u: Don't know how to emulate result opcode %u" - " for r%u", block, insn_index, reg->result.opcode, - rtl_reg); -#ifdef PSP_DEBUG - return 0; // This is a bug, so abort -#else - break; -#endif - } - break; - } // case RTLREG_RESULT{,_NOFOLD} - - default: - DMSG("%p/%u: Don't know how to emulate register source %u" - " for r%u", block, insn_index, reg->source, rtl_reg); - /* Let it slide, because there's nothing we can do about it */ - break; - - } // switch (reg->source) - mips_reg = MIPS_at; - } // if live - - if (offset) { - if (offset+0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(MIPS_at, mips_reg, offset)); - } else { - if (offset < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, offset)); - } else { - APPEND(MIPS_LUI(MIPS_v1, offset >> 16)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, offset & 0xFFFF)); - } - APPEND(MIPS_ADDU(MIPS_at, mips_reg, MIPS_v1)); - } - mips_reg = MIPS_at; - } - - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(MIPS_a0, 0, MIPS_sp)); - if (sh2_reg & 0x80) { // Used for SR.T - const uintptr_t cache_ptr = (uintptr_t)&sh2_regcache[16]; - APPEND(MIPS_LUI(MIPS_a0, (cache_ptr + 0x8000) >> 16)); - if (!(block->sh2_regcache_mask & 1<<16)) { - if (block->regs[1].source != RTLREG_PARAMETER - || block->regs[1].param_index != 0 - ) { - DMSG("r1 is not state block, can't handle"); - return 0; - } - if (IS_SPILLED(1)) { - APPEND(MIPS_LW(MIPS_v1, - block->regs[1].stack_offset, MIPS_sp)); - APPEND(MIPS_LW(MIPS_v1, offsetof(SH2State,SR), MIPS_v1)); - } else { - APPEND(MIPS_LW(MIPS_v1, offsetof(SH2State,SR), - block->regs[1].native_reg)); - } - block->sh2_regcache_mask |= 1<<16; - } else { - APPEND(MIPS_LW(MIPS_v1, cache_ptr & 0xFFFF, MIPS_a0)); - } - APPEND(MIPS_INS(MIPS_v1, mips_reg, SR_T_SHIFT, 1)); - APPEND(MIPS_SW(MIPS_v1, cache_ptr & 0xFFFF, MIPS_a0)); - APPEND(MIPS_LW(MIPS_a0, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - } else { - const uintptr_t cache_ptr = (uintptr_t)&sh2_regcache[sh2_reg]; - APPEND(MIPS_LUI(MIPS_a0, (cache_ptr + 0x8000) >> 16)); - APPEND(MIPS_SW(mips_reg, cache_ptr & 0xFFFF, MIPS_a0)); - APPEND(MIPS_LW(MIPS_a0, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - block->sh2_regcache_mask |= 1<>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, offset & 0xFFFF)); - const uintptr_t cache_ptr = (uintptr_t)&sh2_regcache[sh2_reg]; - APPEND(MIPS_LUI(MIPS_v1, (cache_ptr + 0x8000) >> 16)); - APPEND(MIPS_SW(MIPS_at, cache_ptr & 0xFFFF, MIPS_v1)); - block->sh2_regcache_mask |= 1<sh2_regcache_mask &= ~(1<insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - unsigned int num_insns = 1; - - APPEND(MIPS_JAL(((uintptr_t)code_save_regs & 0x0FFFFFFC) >> 2)); - APPEND(MIPS_NOP()); - - uintptr_t funcptr; - switch (insn->src_imm & 0xFFFF) { - case 1: funcptr = (uintptr_t)trace_storeb_callback; break; - case 2: funcptr = (uintptr_t)trace_storew_callback; break; - case 4: funcptr = (uintptr_t)trace_storel_callback; break; - default: - DMSG("Invalid store trace type %u", insn->src_imm & 0xFF); - return 0; - } - - uint32_t op = insn[num_insns++].src_imm; - PRECOND(op>>28 == 0xD, return 1); - if (op & 0x08000000) { - PRECOND(op>>24 == 0xD8, return 0); - APPEND(MIPS_LUI(MIPS_a0, op & 0xFFFF)); - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xDC, return 0); - APPEND(MIPS_ORI(MIPS_a0, MIPS_a0, op & 0xFFFF)); - } else { - const uint32_t address_reg = op & 0xFFFF; - const RTLRegister *reg = &block->regs[address_reg]; - if (IS_SPILLED(address_reg)) { - APPEND(MIPS_LW(MIPS_a0, 4*18 + reg->stack_offset, MIPS_sp)); - } else if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | MIPS_a0<<11); - } else if (reg->native_reg != MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a0, reg->native_reg)); - } - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xD4, return 1); - APPEND(MIPS_LUI(MIPS_at, op & 0xFFFF)); - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xD6, return 1); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, op & 0xFFFF)); - APPEND(MIPS_ADD(MIPS_a0, MIPS_a0, MIPS_at)); - } - - op = insn[num_insns++].src_imm; - PRECOND(op>>28 == 0xE, return 1); - const uint32_t src_reg = op & 0xFFFF; - const RTLRegister *reg = &block->regs[src_reg]; - APPEND(MIPS_JAL((funcptr & 0x0FFFFFFC) >> 2)); - if (IS_SPILLED(src_reg)) { - APPEND(MIPS_LW(MIPS_a1, 4*18 + reg->stack_offset, MIPS_sp)); - } else if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | MIPS_a1<<11); - } else if (reg->native_reg == MIPS_a0) { - APPEND(MIPS_LW(MIPS_a1, 8, MIPS_sp)); - } else if (reg->native_reg != MIPS_a1) { - APPEND(MIPS_MOVE(MIPS_a1, reg->native_reg)); - } else { // Don't forget to fill the delay slot! - APPEND(MIPS_NOP()); - } - - APPEND(MIPS_JAL(((uintptr_t)code_restore_regs & 0x0FFFFFFC) >> 2)); - APPEND(MIPS_NOP()); - - return num_insns; -} - -/*----------------------------------*/ - -#endif // RTL_TRACE_STEALTH_FOR_SH2 - -/*************************************************************************/ - -/** - * resolve_branches: Resolve branches to RTL labels and jumps to the - * epilogue within MIPS code. If MIPS_OPTIMIZE_BRANCHES is defined, also - * perform optimizations on branches. - * - * [Parameters] - * block: RTL block to translate - * [Return value] - * Nonzero on success, zero on error - */ -static int resolve_branches(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - - uint32_t *native_ptr = (uint32_t *)block->native_buffer; - uint32_t * const native_top = - (uint32_t *)((uintptr_t)native_ptr + block->native_length); - const uint32_t * const epilogue_ptr = - (uint32_t *)((uintptr_t)native_ptr + block->mips.epilogue_offset); - const uint32_t * const chain_ptr = - (uint32_t *)((uintptr_t)native_ptr + block->mips.chain_offset); - - for (; native_ptr < native_top; native_ptr++) { - uint32_t opcode = *native_ptr; - - if (opcode>>27 == __OP_BEQ_LABEL>>1 /*covers both opcodes*/) { - const unsigned int label = opcode & ((1<<16) - 1); - const uint32_t delay_offset = - (uintptr_t)native_ptr - (uintptr_t)block->native_buffer + 4; - if (UNLIKELY((int32_t)block->label_offsets[label] < 0)) { - DMSG("%p: Label %u not defined at native offset %u", - block, label, delay_offset-4); - return 0; - } - int32_t disp = (block->label_offsets[label] - delay_offset); - if (disp < -0x8000<<2 || disp > 0x7FFF<<2) { - /* FIXME: Technically, we could resolve this by flipping - * the sense of the branch and inserting a jump - * instruction, but that would require another pass after - * the final buffer pointer was known to fill in absolute - * addresses; we could also do a BAL and calculate the - * target address manually. But in any case, the chance - * of hitting this is so slim that we don't worry about it - * for now. */ - DMSG("%p: Displacement to label %u (+0x%X) from +0x%X too" - " large, can't resolve", block, label, - block->label_offsets[label], delay_offset); - return 0; - } - *native_ptr = ((__OP_BEQ>>1) << 27) - | (opcode & 0x07FF0000) // Include the EQ/NE bit - | ((disp>>2) & 0xFFFF); - - } else if (opcode == MIPS_B_EPILOGUE_RET_CONST) { - const int32_t offset = epilogue_ptr - (native_ptr+1); - if (LIKELY(offset <= 0x7FFF)) { // Always positive - *native_ptr = MIPS_B(offset); - } else { - DMSG("WARNING: block too large, using nonportable J"); - const uint32_t j_addr = (uintptr_t)epilogue_ptr & 0x0FFFFFFC; - *native_ptr = MIPS_J(j_addr >> 2); - } - - } else if (opcode == MIPS_B_EPILOGUE_CHAIN_AT) { - const int32_t offset = chain_ptr - (native_ptr+1); - if (LIKELY(offset <= 0x7FFF)) { // Always positive - *native_ptr = MIPS_B(offset); - } else { - DMSG("WARNING: block too large, using nonportable J"); - const uint32_t j_addr = (uintptr_t)chain_ptr & 0x0FFFFFFC; - *native_ptr = MIPS_J(j_addr >> 2); - } - - } - -#ifdef MIPS_OPTIMIZE_BRANCHES - opcode = *native_ptr; // It may have been updated above - if (opcode>>28 == __OP_BEQ>>2 - || (opcode>>26 == __OP_REGIMM - && (insn_rt(opcode) & ~021) == __RI_BLTZ) - ) { - uint32_t likely_opcode; - if (opcode>>16 == MIPS_B(0)>>16) { - /* Unconditional branch, so no need for Likely bit */ - likely_opcode = opcode; - } else if (opcode>>28 == __OP_BEQ>>2) { - likely_opcode = opcode | (uint32_t)020<<26; - } else { // REGIMM insns - likely_opcode = opcode | (uint32_t)002<<16; - } - int32_t offset = (int16_t)(opcode & 0xFFFF); - const uint32_t *target = native_ptr + (1+offset); - unsigned int limit = 16; // Watch out for infinite loops - while ((*target>>16 == MIPS_B(0)>>16 - || *target>>16 == MIPS_B_LABEL(0)>>16 - || *target == MIPS_B_EPILOGUE_RET_CONST) - && (native_ptr[1] == MIPS_NOP() || target[1] == MIPS_NOP()) - && limit > 0 - ) { - limit--; - if (target[1] != MIPS_NOP()) { - native_ptr[1] = target[1]; // Must have been a NOP - opcode = likely_opcode; - } - int32_t new_offset; - if (*target == MIPS_B_EPILOGUE_RET_CONST) { - const uint32_t delay_pos = - (native_ptr+1) - (uint32_t *)block->native_buffer; - new_offset = block->mips.epilogue_offset/4 - delay_pos; - } else if (*target>>16 == MIPS_B_LABEL(0)>>16) { - const unsigned int label = *target & 0xFFFF; - if (UNLIKELY((int32_t)block->label_offsets[label] < 0)) { - /* Just skip out here; the Bxx_LABEL processing - * code will report the error */ - break; - } - const uint32_t delay_pos = - (native_ptr+1) - (uint32_t *)block->native_buffer; - new_offset = block->label_offsets[label]/4 - delay_pos; - } else { - new_offset = offset + (1 + (int16_t)(*target & 0xFFFF)); - } - if (new_offset < -0x8000 || new_offset > 0x7FFF) { - break; - } - offset = new_offset; - *native_ptr = (opcode & 0xFFFF0000) | (offset & 0xFFFF); - target = native_ptr + (1+offset); - } - if (*native_ptr>>16 == MIPS_B(0)>>16 - && (*target>>26 == MIPS_J(0) - || (*target & 0xFC00003F) == MIPS_JR(0)) - && (native_ptr[1] == MIPS_NOP() || target[1] == MIPS_NOP()) - ) { - /* Chain an unconditional branch through to a jump (but not - * JAL/JALR, since we'd get the wrong return address) */ - if (target[1] != MIPS_NOP()) { - native_ptr[1] = target[1]; - } - *native_ptr = *target; - } else if (offset != 0x7FFF - && native_ptr[1] == MIPS_NOP() - && !insn_is_jump(*target) - && !insn_is_branch(*target) - ) { - *native_ptr = - (likely_opcode & 0xFFFF0000) | ((offset+1) & 0xFFFF); - native_ptr[1] = *target; - } - } -#endif - - } // for (; native_ptr < native_top; native_ptr++) - - return 1; -} - -/*************************************************************************/ - -#undef MAP_REGISTER -#undef APPEND - -/*************************************************************************/ -/*********************** Low-level helper routines ***********************/ -/*************************************************************************/ - -/** - * append_insn: Append a MIPS instruction word to the given block. - * - * [Parameters] - * block: RTL block to append to - * insn: MIPS instruction word to append - * [Return value] - * Nonzero on success, zero on error - */ -static inline int append_insn(RTLBlock * const block, const uint32_t insn) -{ - PRECOND(block != NULL, return 0); - - if (UNLIKELY(block->native_length >= block->native_bufsize)) { - if (UNLIKELY(!expand_block(block))) { - return 0; - } - } - - *(uint32_t *)((uint8_t *)block->native_buffer + block->native_length) - = insn; - block->native_length += 4; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * expand_block: Expand the current native code buffer. - * - * [Parameters] - * block: RTL block to expand - * [Return value] - * Nonzero on success, zero on error - */ -static int expand_block(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - - block->native_bufsize = block->native_length + NATIVE_EXPAND_SIZE; - void *new_buffer = realloc(block->native_buffer, block->native_bufsize); - if (UNLIKELY(!new_buffer)) { - DMSG("No memory to expand native buffer to %u bytes", - block->native_bufsize); - return 0; - } - block->native_buffer = new_buffer; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * last_insn: Return the last 32-bit instruction word added to the given - * block. If the block is empty, returns MIPS_NOP(). - * - * [Parameters] - * block: RTL block - * [Return value] - * Last instruction word added - */ -static uint32_t last_insn(const RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->native_buffer != NULL, return 0); - - if (UNLIKELY(block->native_length == 0)) { - return MIPS_NOP(); - } - return *(uint32_t *)((uint8_t *)block->native_buffer - + (block->native_length - 4)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * pop_insn: Return the last 32-bit instruction word added to the given - * block, and remove that word from the end of the block. If the block is - * empty, returns MIPS_NOP() without modifying the block. - * - * [Parameters] - * block: RTL block - * [Return value] - * Last instruction word added - */ -static uint32_t pop_insn(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->native_buffer != NULL, return 0); - - if (UNLIKELY(block->native_length == 0)) { - return MIPS_NOP(); - } - block->native_length -= 4; - return *(uint32_t *)((uint8_t *)block->native_buffer - + block->native_length); -} - -/*************************************************************************/ - -/** - * append_float: Append a high-latency instruction (a load, multiply, or - * divide instruction) to the given block. If possible (and if - * MIPS_OPTIMIZE_SCHEDULING is enabled), float the instruction upwards to - * obtain a distance of at least "latency" instructions before the next - * instruction. Preceding instructions in the same dependency chain are - * also floated upwards to preserve correctness. - * - * [Parameters] - * block: RTL block to append to - * insn: Instruction word to append - * latency: Desired distance to next instruction - * [Return value] - * Nonzero on success, zero on error - */ -static int append_float(RTLBlock * const block, const uint32_t insn, - const int latency) -{ -#ifndef MIPS_OPTIMIZE_SCHEDULING - return append_insn(block, insn); -#else - - PRECOND(block != NULL, return 0); - PRECOND(insn_is_load(insn) - || (insn & 0xFC00003C) == __SP_MULT - || (insn & 0xFC00003E) == __SP_MADD - || (insn & 0xFC00003E) == __SP_MSUB, return 0); - - /* Does the dependency chain ending with the new instruction have a - * load or store instruction? If so, do we know where it points? */ - - int has_mem; - unsigned int unique_pointer; - uint32_t unique_pointer_birth; - if (insn_is_load(insn)) { // We're never called for stores - has_mem = 1; - PRECOND(block->mips.reg_map[insn_rs(insn)] != NULL, return 0); - unique_pointer = block->mips.reg_map[insn_rs(insn)]->unique_pointer; - unique_pointer_birth = block->mips.reg_map[insn_rs(insn)]->birth; - } else { - has_mem = 0; - unique_pointer = 0; - } - - /* First add the instruction to the block. */ - - if (UNLIKELY(!append_insn(block, insn))) { - return 0; - } - - /* Extract registers used and set by this instruction; we'll add to - * these sets all registers used by preceding instructions in the - * dependency chain. */ - - uint32_t regs_used = insn_regs_used(insn); - uint32_t regs_set = insn_regs_set(insn); - - /* Scan backwards, up to the beginning of the unit or preceding branch - * delay slot, to find instructions that can be placed below this one, - * and move them below the current instruction. */ - - uint32_t * const unit_start = (uint32_t *) - ((uint8_t *)block->native_buffer + block->mips.unit_start); - uint32_t *insn_ptr = (uint32_t *) - ((uint8_t *)block->native_buffer + (block->native_length - 4)); - uint32_t * const target = insn_ptr - (latency-1); - uint32_t *search; - - for (search = insn_ptr - 1; search >= unit_start; search--) { - - /* If the preceding instruction is a jump or branch, stop here. - * If this is the first instruction in the unit, the preceding - * instruction can't be a jump or branch (if it was, a delay slot - * instruction would have been added after it at the end of the - * unit). */ - - if (search > unit_start - && (insn_is_jump(search[-1]) || insn_is_branch(search[-1])) - ) { - break; - } - - /* An instruction is independent of a following sequence of - * instructions if that instruction: - * 1) Does not set a register used in the following sequence - * (i.e., the sequence does not depend on the result of the - * instruction). - * 2) Does not set a register set in the following sequence - * (i.e., the sequence does not reuse the instruction's - * result register). - * 3) Does not use a register set in the following sequence - * (i.e., the sequence does not clobber an operand of the - * instruction). - * We explicitly do not move load or store instructions across - * other load or store instructions, so as to maintain ordering of - * memory accesses (otherwise, we might try to load from an address - * before the store that updates it) and to avoid introducing a - * stall by shifting a previous load farther down the code stream. - * However, we _do_ float a load above a preceding store if we know - * that the store and load point to different addresses; i.e., if - * at least one of the registers is a unique pointer, and they do - * not reference the same unique address. */ - - const uint32_t this_used = insn_regs_used(*search); - const uint32_t this_set = insn_regs_set(*search); - int this_is_mem; - if (insn_is_load(*search)) { - this_is_mem = 1; - } else if (insn_is_store(*search)) { - // FIXME: We don't currently save unique pointer data with the - // generated MIPS instructions, so for now we assume that the - // current register is the only one pointing to this unique - // region. This works at the moment because the state block - // pointer is the only register we mark as a unique pointer, - // but could break in other cases. - if (unique_pointer == 0 || insn_rs(insn) != insn_rs(*search)) { - this_is_mem = 1; - } else { - PRECOND(block->mips.reg_map[insn_rs(*search)] != NULL, - return 0); - this_is_mem = (insn_imm(insn) == insn_imm(*search)); - } - } else { - this_is_mem = 0; - } - if ((this_set & (regs_used | regs_set)) != 0 - || (this_used & regs_set) != 0 - || (has_mem && this_is_mem) - ) { - /* Add this register's used and set registers to the dependency - * chain's cumulative set. */ - regs_used |= this_used; - regs_set |= this_set; - /* If it was a load or store instruction, record that fact. */ - if (insn_is_load(*search) || insn_is_store(*search)) { - has_mem = 1; - /* Register assignments may have changed, so we don't know - * for certain what the register pointed to at the time, so - * play it safe. */ - unique_pointer = 0; - } - } else { - /* Move this instruction immediately below the one we added. */ - const uint32_t move_insn = *search; - uint32_t *move_ptr; - for (move_ptr = search; move_ptr < insn_ptr; move_ptr++) { - *move_ptr = *(move_ptr + 1); - } - *move_ptr = move_insn; - /* The instruction we added has now moved one word up. */ - insn_ptr--; - /* If we've achieved the requested distance, stop. */ - if (insn_ptr <= target) { - break; - } - } - - } // for (search = insn_ptr - 1; search >= unit_start; search--) - - return 1; - -#endif // MIPS_OPTIMIZE_SCHEDULING -} - -/*-----------------------------------------------------------------------*/ - -/** - * append_branch: Append a branch instruction to the given block. If - * possible (and if MIPS_OPTIMIZE_DELAY_SLOT is enabled), place the current - * last instruction of the block into the branch's delay slot. - * - * [Parameters] - * block: RTL block to append to - * insn: Branch instruction word to append - * [Return value] - * Nonzero on success, zero on error - */ -static int append_branch(RTLBlock * const block, const uint32_t insn) -{ - PRECOND(block != NULL, return 0); - - uint32_t delay_slot = MIPS_NOP(); - -#ifdef MIPS_OPTIMIZE_DELAY_SLOT - if (block->native_length - 4 >= block->mips.unit_start) { - int can_swap_insns = 0; - const uint32_t prev1_insn = pop_insn(block); - uint32_t prev2_insn; - if (block->native_length - 4 >= block->mips.unit_start) { - prev2_insn = last_insn(block); - } else { - prev2_insn = MIPS_NOP(); - } - if (!insn_is_jump(prev2_insn) && !insn_is_branch(prev2_insn)) { - if (insn == MIPS_B_EPILOGUE_RET_CONST - || insn == MIPS_B_EPILOGUE_CHAIN_AT - || !(insn_regs_set(prev1_insn) & insn_regs_used(insn)) - ) { - can_swap_insns = 1; - } - } - if (can_swap_insns) { - delay_slot = prev1_insn; - } else { - if (UNLIKELY(!append_insn(block, prev1_insn))) { - // Just to be safe... - DMSG("Failed to re-append insn"); - return 0; - } - } - } -#endif - - return append_insn(block, insn) && append_insn(block, delay_slot); -} - -/*************************************************************************/ - -/** - * append_prologue: Append a function prologue to the given block. - * - * [Parameters] - * block: RTL block to append to - * [Return value] - * Nonzero on success, zero on error - */ -static int append_prologue(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - - /* Set up the stack frame (if we need one) */ - if (block->mips.total_frame_size) { - if (UNLIKELY(!append_insn(block, MIPS_ADDIU(MIPS_sp, MIPS_sp, -(block->mips.total_frame_size))))) { - DMSG("Failed to append prologue (stack frame)"); - return 0; - } - } - - /* Save $ra if necessary */ - if (block->mips.need_save_ra - && UNLIKELY(!append_insn(block, MIPS_SW(MIPS_ra, block->mips.total_frame_size - 4, MIPS_sp))) - ) { - DMSG("Failed to append prologue ($ra)"); - return 0; - } - - /* Save all callee-saved registers that we use */ - uint32_t offset = block->mips.total_frame_size - 8; - unsigned int i; - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - if (UNLIKELY(!append_insn(block, - MIPS_SW(mips_reg, offset, MIPS_sp)))) { - DMSG("Failed to append prologue ($%u)", mips_reg); - return 0; - } - offset -= 4; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * append_epilogue: Append a function epilogue to the given block. - * - * [Parameters] - * block: RTL block to append to - * [Return value] - * Nonzero on success, zero on error - */ -static int append_epilogue(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - - /* Save the offset to the epilogue code for branch resolution */ - block->mips.epilogue_offset = block->native_length; - - /* Restore the original values of saved registers ($ra and $sN) */ - if (block->mips.need_save_ra - && UNLIKELY(!append_insn(block, MIPS_LW(MIPS_ra, block->mips.total_frame_size - 4, MIPS_sp))) - ) { - DMSG("Failed to append epilogue ($ra)"); - return 0; - } - uint32_t offset = block->mips.total_frame_size - 8; - unsigned int i; - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - if (UNLIKELY(!append_insn(block, - MIPS_LW(mips_reg, offset, MIPS_sp)))) { - DMSG("Failed to append epilogue ($%u)", mips_reg); - return 0; - } - offset -= 4; - } - } - - /* Free the stack frame (if we allocated one) and return */ - uint32_t final_insn; - if (block->mips.total_frame_size) { - final_insn = - MIPS_ADDIU(MIPS_sp, MIPS_sp, block->mips.total_frame_size); - } else { - final_insn = MIPS_NOP(); - } - if (UNLIKELY(!append_insn(block, MIPS_JR(MIPS_ra))) - || UNLIKELY(!append_insn(block, final_insn)) - ) { - DMSG("Failed to append epilogue (return)"); - return 0; - } - - /* If we need a chain-to-$at epilogue as well, generate that */ - if (block->mips.need_chain_at) { - block->mips.chain_offset = block->native_length; - if (block->mips.need_save_ra - && UNLIKELY(!append_insn(block, MIPS_LW(MIPS_ra, block->mips.total_frame_size - 4, MIPS_sp))) - ) { - DMSG("Failed to append chain epilogue ($ra)"); - return 0; - } - offset = block->mips.total_frame_size - 8; - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - if (UNLIKELY(!append_insn(block, - MIPS_LW(mips_reg, offset, MIPS_sp)))) { - DMSG("Failed to append chain epilogue ($%u)", mips_reg); - return 0; - } - offset -= 4; - } - } - if (block->mips.total_frame_size) { - final_insn = - MIPS_ADDIU(MIPS_sp, MIPS_sp, block->mips.total_frame_size); - } else { - final_insn = MIPS_NOP(); - } - if (UNLIKELY(!append_insn(block, MIPS_JR(MIPS_at))) - || UNLIKELY(!append_insn(block, final_insn)) - ) { - DMSG("Failed to append chain epilogue (return)"); - return 0; - } - } // if (block->mips.need_chain_at) - - return 1; -} - -/*************************************************************************/ -/****************** MIPS opcode informational functions ******************/ -/*************************************************************************/ - -/** - * insn_rs, insn_rt, insn_rd: Return the register number specified in the - * rs, rt, or rd field of the given instruction, respectively. - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * rs, rt, or rd register number (0-31) - */ -static inline int insn_rs(const uint32_t opcode) -{ - return (opcode >> 21) & 0x1F; -} - -static inline int insn_rt(const uint32_t opcode) -{ - return (opcode >> 16) & 0x1F; -} - -static inline int insn_rd(const uint32_t opcode) -{ - return (opcode >> 11) & 0x1F; -} - -/*----------------------------------*/ - -/** - * insn_imm: Return the 16-bit immediate value specified in the given - * instruction. - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * 16-bit immediate value as a signed integer - */ -static inline int insn_imm(const uint32_t opcode) -{ - return (int)(int16_t)opcode; -} - -/*************************************************************************/ - -/** - * insn_is_*: Return whether the given instruction is of the type - * specified by the function name: - * insn_is_load -- a load instruction - * insn_is_store -- a store instruction - * insn_is_jump -- a JUMP class instruction (J or JAL) - * insn_is_branch -- an IMM/REGIMM class branch instruction (BEQ, etc.) - * insn_is_imm -- an IMM class instruction - * insn_is_imm_alu -- an IMM class ALU instruction (ADDI, etc.) - * insn_is_special -- a SPECIAL class instruction - * insn_is_regimm -- a REGIMM class instruction (BLTZ, etc.) - * insn_is_allegrex -- an Allegrex-specific instruction (INS, SEB, etc.) - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * Nonzero if the instruction is of the named type, else zero - */ -static inline int insn_is_load(const uint32_t opcode) -{ - return opcode>>29 == 4; // We don't use LL, so we don't check for it -} - -static inline int insn_is_store(const uint32_t opcode) -{ - return opcode>>29 == 5; // We don't use SC, so we don't check for it -} - -static inline int insn_is_jump(const uint32_t opcode) -{ - return opcode>>27 == __OP_J>>1 - || (insn_is_special(opcode) && (opcode & 0x3E) == __SP_JR); // JR/JALR -} - -static inline int insn_is_branch(const uint32_t opcode) -{ - return opcode>>28 == __OP_BEQ>>2 - || opcode>>28 == __OP_BEQL>>2 - || opcode>>27 == __OP_BEQ_LABEL>>1 - || insn_is_regimm(opcode); -} - -static inline int insn_is_imm(const uint32_t opcode) -{ - return (opcode>>26 >= __OP_BEQ && opcode>>26 <= __OP_BGTZL) - || (opcode>>27 == __OP_BEQ_LABEL>>1); -} - -static inline int insn_is_imm_alu(const uint32_t opcode) -{ - return opcode>>29 == 1; -} - -static inline int insn_is_special(const uint32_t opcode) -{ - return opcode>>26 == __OP_SPECIAL; -} - -static inline int insn_is_regimm(const uint32_t opcode) -{ - return opcode>>26 == __OP_REGIMM; -} - -static inline int insn_is_allegrex(const uint32_t opcode) -{ - return opcode>>26 == __OP_ALLEGREX; -} - -/*************************************************************************/ - -/** - * insn_regs_used: Return a bitmask of MIPS registers used by the given - * instruction (i.e. the instruction's source registers). $zero is never - * included in the set; bit 0 instead reflects the HI and LO registers. - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * Bitmask of registers used by the instruction - */ -static inline uint32_t insn_regs_used(const uint32_t opcode) -{ - uint32_t regs; - int hilo = 0; - - if (insn_is_load(opcode) || insn_is_regimm(opcode) - || insn_is_imm_alu(opcode) - ) { - regs = 1<>26 == __OP_JAL - || (insn_is_regimm(opcode) - && insn_rt(opcode)>>2 == __RI_BLTZAL>>2) - ) { - regs = 1<insns = NULL; - block->insn_unitmap = NULL; - block->insns_size = INSNS_EXPAND_SIZE; - block->num_insns = 0; - - block->units = NULL; - block->units_size = UNITS_EXPAND_SIZE; - block->num_units = 0; - block->have_unit = 0; - block->cur_unit = 0; - - block->label_unitmap = NULL; - block->labels_size = LABELS_EXPAND_SIZE; - block->next_label = 1; - - block->regs = NULL; - block->regs_size = REGS_EXPAND_SIZE; - block->next_reg = 1; - block->first_live_reg = 0; - block->last_live_reg = 0; - block->unique_pointer_index = 1; - - block->finalized = 0; - - block->first_call_unit = -1; - block->last_call_unit = -1; - - block->insns = malloc(sizeof(*block->insns) * block->insns_size); - if (!block->insns) { - DMSG("No memory for %d RTLInsns", block->insns_size); - goto fail; - } - - block->units = malloc(sizeof(*block->units) * block->units_size); - if (!block->units) { - DMSG("No memory for %d RTLUnits", block->units_size); - goto fail; - } - - block->regs = malloc(sizeof(*block->regs) * block->regs_size); - if (!block->regs) { - DMSG("No memory for %d RTLRegisters", block->regs_size); - goto fail; - } - memset(&block->regs[0], 0, sizeof(*block->regs)); - - block->label_unitmap = - malloc(sizeof(*block->label_unitmap) * block->labels_size); - if (!block->label_unitmap) { - DMSG("No memory for %d labels", block->labels_size); - goto fail; - } - block->label_unitmap[0] = -1; - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Created new block at %p\n", block); -#endif - return block; - - fail: - free(block->insns); - free(block->units); - free(block->regs); - free(block->label_unitmap); - free(block); - return NULL; -} - -/*************************************************************************/ - -/* rtl_add_insn() helpers -- these move function calls like realloc() out - * of rtl_add_insn() to help the compiler optimize the fast path, by - * avoiding register spillage when it's not necessary. Note that GCC (at - * least version 4.3) will inline these by default, but that actually slows - * down the fast path on at least MIPS due to spillage of the function - * parameter registers, so we force these to be generated as separate - * functions. */ -#ifdef __GNUC__ -__attribute__((noinline)) -#endif -static int rtl_add_insn_with_extend(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other); -#ifdef __GNUC__ -__attribute__((noinline)) -#endif -static int rtl_add_insn_with_new_unit(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other); - -/*----------------------------------*/ - -/** - * rtl_add_insn: Append an instruction to the given block. The meaning of - * each operand depends on the instruction. - * - * [Parameters] - * block: RTLBlock to append to - * opcode: Instruction opcode (RTLOP_*) - * dest: Destination register for instruction - * src1: First source register or immediate value for instruction - * src2: Second source register or immediate value for instruction - * other: Extra register for instruction - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_add_insn(RTLBlock *block, RTLOpcode opcode, uint32_t dest, - uintptr_t src1, uint32_t src2, uint32_t other) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(opcode >= RTLOP__FIRST && opcode <= RTLOP__LAST, return 0); - - /* Extend the instruction array if necessary */ - if (UNLIKELY(block->num_insns >= block->insns_size)) { - return rtl_add_insn_with_extend(block, opcode, - dest, src1, src2, other); - } - - /* Create a new basic unit if there's no active one */ - if (UNLIKELY(!block->have_unit)) { - return rtl_add_insn_with_new_unit(block, opcode, - dest, src1, src2, other); - } - - /* Fill in the instruction data */ - RTLInsn * const insn = &block->insns[block->num_insns]; - insn->opcode = opcode; - if (UNLIKELY(!rtlinsn_make(block, insn, dest, src1, src2, other))) { - return 0; - } - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%5u: %s\n", block, block->num_insns, - rtl_decode_insn(block, block->num_insns, 0)); -#endif - block->num_insns++; - return 1; -} - -/*----------------------------------*/ - -/** - * rtl_add_insn_with_extend: Extend the instruction array and then add a - * new instruction. Called by rtl_add_insn() when the instruction array is - * full upon entry. - */ -static int rtl_add_insn_with_extend(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other) -{ - uint32_t new_insns_size = block->num_insns + INSNS_EXPAND_SIZE; - RTLInsn *new_insns = realloc(block->insns, - sizeof(*block->insns) * new_insns_size); - if (UNLIKELY(!new_insns)) { - DMSG("No memory to expand block %p to %d insns", block, - new_insns_size); - return 0; - } - block->insns = new_insns; - block->insns_size = new_insns_size; - - /* Run back through rtl_add_insn() to handle the rest */ - return rtl_add_insn(block, opcode, dest, src1, src2, other); -} - -/*----------------------------------*/ - -/** - * rtl_add_insn_with_new_unit: Start a new basic unit and then add a new - * instruction. Called by rtl_add_insn() when there is no current basic - * unit upon entry. - */ -static int rtl_add_insn_with_new_unit(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other) -{ - if (UNLIKELY(!rtlunit_add(block))) { - return 0; - } - block->have_unit = 1; - block->cur_unit = block->num_units - 1; - block->units[block->cur_unit].first_insn = block->num_insns; - - /* Run back through rtl_add_insn() to handle the rest */ - return rtl_add_insn(block, opcode, dest, src1, src2, other); -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_alloc_register: Allocate a new register for use in the given block. - * The register's value is undefined until it has been used as the - * destination of an instruction. - * - * [Parameters] - * block: RTLBlock to allocate a register for - * [Return value] - * Register number (nonzero) on success, zero on error - */ -unsigned int rtl_alloc_register(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->regs != NULL, return 0); - - if (UNLIKELY(block->next_reg >= block->regs_size)) { - if (block->regs_size >= REGS_LIMIT) { - DMSG("Too many registers in block %p (limit %u)", - block, REGS_LIMIT); - return 0; - } - unsigned int new_regs_size; - /* Avoid 16-bit overflow (not that there are any modern machines - * where int is 16 bits, but let's follow the rules anyway) */ - if (block->regs_size > REGS_LIMIT - REGS_EXPAND_SIZE) { - new_regs_size = REGS_LIMIT; - } else { - new_regs_size = block->next_reg + REGS_EXPAND_SIZE; - } - RTLRegister * const new_regs = - realloc(block->regs, sizeof(*block->regs) * new_regs_size); - if (UNLIKELY(!new_regs)) { - DMSG("No memory to expand block %p to %d registers", - block, new_regs_size); - return 0; - } - block->regs = new_regs; - block->regs_size = new_regs_size; - } - - const unsigned int reg_index = block->next_reg++; - memset(&block->regs[reg_index], 0, sizeof(block->regs[reg_index])); - return reg_index; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_register_set_unique_pointer: Mark the given register as being a - * "unique pointer", which points to a region of memory which will never - * be accessed except through this register (or another register copied - * from it). This function must be called after adding the instruction - * which sets the register, and if the register's value is subsequently - * modified, its "unique pointer" status will be cancelled. - * - * [Parameters] - * block: RTLBlock containing register to mark - * regnum: Register number to mark - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_register_set_unique_pointer(RTLBlock *block, uint32_t regnum) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(regnum != 0 && regnum < block->next_reg, return 0); - - if (block->unique_pointer_index == 0) { // i.e. it wrapped around - DMSG("Unique pointer index overflow at register r%u", regnum); - return 0; - } - block->regs[regnum].unique_pointer = block->unique_pointer_index++; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_alloc_label: Allocate a new label for use in the given block. - * - * [Parameters] - * block: RTLBlock to allocate a label for - * [Return value] - * Label number (nonzero) on success, zero on error - */ -unsigned int rtl_alloc_label(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - if (UNLIKELY(block->next_label >= block->labels_size)) { - if (block->labels_size >= LABELS_LIMIT) { - DMSG("Too many labels in block %p (limit %u)", - block, LABELS_LIMIT); - return 0; - } - unsigned int new_labels_size; - if (block->labels_size > LABELS_LIMIT - LABELS_EXPAND_SIZE) { - new_labels_size = LABELS_LIMIT; - } else { - new_labels_size = block->next_label + LABELS_EXPAND_SIZE; - } - int16_t * const new_label_unitmap = - realloc(block->label_unitmap, - sizeof(*block->label_unitmap) * new_labels_size); - if (UNLIKELY(!new_label_unitmap)) { - DMSG("No memory to expand block %p to %d labels", block, - new_labels_size); - return 0; - } - block->label_unitmap = new_label_unitmap; - block->labels_size = new_labels_size; - } - - const unsigned int label = block->next_label++; - block->label_unitmap[label] = -1; - return label; -} - -/*************************************************************************/ - -/** - * rtl_finalize_block: Perform housekeeping at the end of the given - * block's translation. rtl_add_insn(), rtl_alloc_register(), and - * rtl_alloc_label() may not be called for a block after calling this - * function on the block. - * - * [Parameters] - * block: RTLBlock to finalize - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_finalize_block(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - /* Terminate the last unit (if there is one) */ - if (block->have_unit) { - block->units[block->cur_unit].last_insn = block->num_insns - 1; - block->have_unit = 0; - } - - /* Add execution graph edges for GOTO instructions */ - if (UNLIKELY(!add_unit_edges(block))) { - return 0; - } - - /* Update live ranges for registers used in loops */ - if (UNLIKELY(!update_live_ranges(block))) { - return 0; - } - - block->finalized = 1; -#ifdef RTL_TRACE_GENERATE - rtlunit_dump_all(block, NULL); - fprintf(stderr, "[RTL] Finalized block at %p\n", block); -#endif - return 1; -} - -/*************************************************************************/ - -/** - * rtl_optimize_block: Perform target-independent optimization on the - * given block. Before calling this function, rtl_finalize_block() must be - * called for the block. - * - * [Parameters] - * block: RTLBlock to optimize - * flags: RTLOPT_* flags indicating which optimizations to perform - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_optimize_block(RTLBlock *block, uint32_t flags) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - if (flags & RTLOPT_FOLD_CONSTANTS) { - if (UNLIKELY(!rtlopt_fold_constants(block))) { - DMSG("Constant folding failed"); - return 0; - } - } - - if (flags & RTLOPT_DECONDITION) { - if (UNLIKELY(!rtlopt_decondition(block))) { - DMSG("Deconditioning failed"); - return 0; - } - } - - if (flags & RTLOPT_DECONDITION) { - if (UNLIKELY(!rtlopt_drop_dead_units(block))) { - DMSG("Dead unit dropping failed"); - return 0; - } - } - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Optimized block at %p\n", block); - dump_block(block, "optimize"); -#endif - return 1; -} - -/*************************************************************************/ - -/** - * rtl_translate_block: Translate the given block into native machine code. - * - * [Parameters] - * block: RTLBlock to translate - * code_ret: Pointer to variable to receive code buffer pointer - * size_ret: Pointer to variable to receive code buffer size (in bytes) - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * On error, *code_ret and *size_ret are not modified. - */ -int rtl_translate_block(RTLBlock *block, void **code_ret, uint32_t *size_ret) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(code_ret != NULL, return 0); - PRECOND(size_ret != NULL, return 0); - - int retval; - -#if defined(PSP) - retval = rtl_translate_block_mips(block, code_ret, size_ret); -#else - DMSG("Native code generation is not implemented for this platform"); - retval = 0; -#endif - -#ifdef RTL_TRACE_GENERATE - if (retval) { - fprintf(stderr, "[RTL] Translated block at %p to native code at %p" - " (size %u)\n", block, *code_ret, *size_ret); - } else { - fprintf(stderr, "[RTL] FAILED to translate block at %p\n", block); - } -#endif - return retval; -} - -/*************************************************************************/ - -/** - * rtl_destroy_block: Destroy the given block, freeing any resources it - * used. - * - * [Parameters] - * block: RTLBlock to destroy (if NULL, this function does nothing) - * [Return value] - * None - */ -void rtl_destroy_block(RTLBlock *block) -{ - if (block) { -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Destroying block at %p\n", block); -#endif - free(block->insns); - free(block->insn_unitmap); - free(block->units); - free(block->regs); - free(block->label_unitmap); - free(block); - } -} - -/*************************************************************************/ -/*********************** Library-internal routines ***********************/ -/*************************************************************************/ - -#if defined(RTL_TRACE_GENERATE) || defined(RTL_TRACE_EXECUTE) - -/** - * rtl_decode_insn: Decode an RTL instruction into a human-readable - * string. - * - * [Parameters] - * block: RTLBlock containing instruction to decode - * index: Index of instruction to decode - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the instruction - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -const char *rtl_decode_insn(const RTLBlock *block, uint32_t index, int is_exec) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - /* We don't check the index because it'll be out of range when tracing - * code generation */ - - static const char * const opcode_names[] = { - [RTLOP_NOP ] = "NOP", - [RTLOP_MOVE ] = "MOVE", - [RTLOP_SELECT ] = "SELECT", - [RTLOP_ADD ] = "ADD", - [RTLOP_SUB ] = "SUB", - [RTLOP_MULU ] = "MULU", - [RTLOP_MULS ] = "MULS", - [RTLOP_MADDU ] = "MADDU", - [RTLOP_MADDS ] = "MADDS", - [RTLOP_DIVMODU ] = "DIVMODU", - [RTLOP_DIVMODS ] = "DIVMODS", - [RTLOP_AND ] = "AND", - [RTLOP_OR ] = "OR", - [RTLOP_XOR ] = "XOR", - [RTLOP_NOT ] = "NOT", - [RTLOP_SLL ] = "SLL", - [RTLOP_SRL ] = "SRL", - [RTLOP_SRA ] = "SRA", - [RTLOP_ROR ] = "ROR", - [RTLOP_CLZ ] = "CLZ", - [RTLOP_CLO ] = "CLO", - [RTLOP_SLTU ] = "SLTU", - [RTLOP_SLTS ] = "SLTS", - [RTLOP_BSWAPH ] = "BSWAPH", - [RTLOP_BSWAPW ] = "BSWAPW", - [RTLOP_HSWAPW ] = "HSWAPW", - [RTLOP_ADDI ] = "ADDI", - [RTLOP_ANDI ] = "ANDI", - [RTLOP_ORI ] = "ORI", - [RTLOP_XORI ] = "XORI", - [RTLOP_SLLI ] = "SLLI", - [RTLOP_SRLI ] = "SRLI", - [RTLOP_SRAI ] = "SRAI", - [RTLOP_RORI ] = "RORI", - [RTLOP_SLTUI ] = "SLTUI", - [RTLOP_SLTSI ] = "SLTSI", - [RTLOP_BFEXT ] = "BFEXT", - [RTLOP_BFINS ] = "BFINS", - [RTLOP_LOAD_IMM ] = "LOAD_IMM", - [RTLOP_LOAD_ADDR ] = "LOAD_ADDR", - [RTLOP_LOAD_PARAM ] = "LOAD_PARAM", - [RTLOP_LOAD_BS ] = "LOAD_BS", - [RTLOP_LOAD_BU ] = "LOAD_BU", - [RTLOP_LOAD_HS ] = "LOAD_HS", - [RTLOP_LOAD_HU ] = "LOAD_HU", - [RTLOP_LOAD_W ] = "LOAD_W", - [RTLOP_LOAD_PTR ] = "LOAD_PTR", - [RTLOP_STORE_B ] = "STORE_B", - [RTLOP_STORE_H ] = "STORE_H", - [RTLOP_STORE_W ] = "STORE_W", - [RTLOP_STORE_PTR ] = "STORE_PTR", - [RTLOP_LABEL ] = "LABEL", - [RTLOP_GOTO ] = "GOTO", - [RTLOP_GOTO_IF_Z ] = "GOTO_IF_Z", - [RTLOP_GOTO_IF_NZ ] = "GOTO_IF_NZ", - [RTLOP_GOTO_IF_E ] = "GOTO_IF_E", - [RTLOP_GOTO_IF_NE ] = "GOTO_IF_NE", - [RTLOP_CALL ] = "CALL", - [RTLOP_RETURN ] = "RETURN", - [RTLOP_RETURN_TO ] = "RETURN_TO", - }; - - static char buf[500]; - - const RTLInsn * const insn = &block->insns[index]; - const char * const name = opcode_names[insn->opcode]; - const unsigned int dest = insn->dest; - const unsigned int src1 = insn->src1; - const unsigned int src2 = insn->src2; - -#define APPEND_REG_DESC(regnum) \ - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "\n r%u: %s", \ - (regnum), rtl_describe_register(&block->regs[(regnum)], is_exec)); - - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: - if (insn->src_imm) { - snprintf(buf, sizeof(buf), "%-11s 0x%X", name, insn->src_imm); - } else { - snprintf(buf, sizeof(buf), "%s", name); - } - return buf; - - case RTLOP_MOVE: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u", name, dest, src1); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_SELECT: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, r%u", name, - dest, src1, src2, insn->cond); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - APPEND_REG_DESC(insn->cond); - return buf; - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u", name, dest, src1, - src2); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_ADDI: - case RTLOP_SLTSI: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, %d", name, dest, src1, - insn->src_imm); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, %u", name, dest, src1, - insn->src_imm); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, 0x%X", name, dest, src1, - insn->src_imm); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - if (dest == 0) { - if (insn->dest2 == 0) { - snprintf(buf, sizeof(buf), "%-11s ---, r%u, r%u, ---", name, - src1, src2); - } else { - snprintf(buf, sizeof(buf), "%-11s ---, r%u, r%u, r%u", name, - src1, src2, insn->dest2); - } - } else { - if (insn->dest2 == 0) { - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, ---", name, - dest, src1, src2); - } else { - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, r%u", name, - dest, src1, src2, insn->dest2); - } - } - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_MADDU: - case RTLOP_MADDS: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, r%u", name, - dest, src1, src2, insn->dest2); - APPEND_REG_DESC(dest); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - APPEND_REG_DESC(insn->dest2); - return buf; - - case RTLOP_BFEXT: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, %u, %u", name, dest, - src1, insn->bitfield.start, insn->bitfield.count); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_BFINS: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, %u, %u", name, dest, - src1, src2, insn->bitfield.start, insn->bitfield.count); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_LOAD_IMM: - if (insn->src_imm >= 0x10000 && insn->src_imm < 0xFFFF0000) { - snprintf(buf, sizeof(buf), "%-11s r%u, 0x%X", name, dest, - insn->src_imm); - } else { - snprintf(buf, sizeof(buf), "%-11s r%u, %d", name, dest, - (int32_t)insn->src_imm); - } - return buf; - - case RTLOP_LOAD_ADDR: - snprintf(buf, sizeof(buf), "%-11s r%u, 0x%lX", name, dest, - (unsigned long)insn->src_addr); - return buf; - - case RTLOP_LOAD_PARAM: - snprintf(buf, sizeof(buf), "%-11s r%u, params[%u]", name, dest, - insn->src_imm); - return buf; - - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - snprintf(buf, sizeof(buf), "%-11s r%u, %d(r%u)", name, dest, - insn->offset, src1); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - snprintf(buf, sizeof(buf), "%-11s %d(r%u), r%u", name, - insn->offset, dest, src1); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(dest); - return buf; - - case RTLOP_LABEL: - case RTLOP_GOTO: - snprintf(buf, sizeof(buf), "%-11s L%u", name, insn->label); - return buf; - - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - snprintf(buf, sizeof(buf), "%-11s L%u, r%u", name, insn->label, src1); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - snprintf(buf, sizeof(buf), "%-11s L%u, r%u, r%u", name, insn->label, - src1, src2); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_CALL: - if (insn->dest) { - int len = snprintf(buf, sizeof(buf), "%-11s r%u = r%u(", - name, dest, insn->target); - if (src1) { - len += snprintf(buf+len, sizeof(buf)-len, "r%u", src1); - if (src2) { - len += snprintf(buf+len, sizeof(buf)-len, ", r%u", src2); - } - } - snprintf(buf+len, sizeof(buf)-len, ")"); - } else { - int len = snprintf(buf, sizeof(buf), "%-11s r%u(", - name, insn->target); - if (src1) { - len += snprintf(buf+len, sizeof(buf)-len, "r%u", src1); - if (src2) { - len += snprintf(buf+len, sizeof(buf)-len, ", r%u", src2); - } - } - snprintf(buf+len, sizeof(buf)-len, ")"); - } - if (src1) { - APPEND_REG_DESC(src1); - if (src2) { - APPEND_REG_DESC(src2); - } - } - APPEND_REG_DESC(insn->target); - return buf; - - case RTLOP_RETURN: - snprintf(buf, sizeof(buf), "%-11s", name); - return buf; - - case RTLOP_RETURN_TO: - snprintf(buf, sizeof(buf), "%-11s r%u", name, insn->target); - APPEND_REG_DESC(insn->target); - return buf; - - } // switch (insn->opcode) - - snprintf(buf, sizeof(buf), "???"); - return buf; - -#undef APPEND_REG_DESC -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_describe_register: Generate a string describing the contents of the - * given RTL register. - * - * [Parameters] - * reg: Register to describe - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the register - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -const char *rtl_describe_register(const RTLRegister *reg, int is_exec) -{ - PRECOND(reg != NULL, return ""); - - static char buf[100]; - if (is_exec || reg->source == RTLREG_CONSTANT) { - if ((intptr_t)reg->value >= 0x10000 - || (intptr_t)reg->value < -0x10000 - ) { - snprintf(buf, sizeof(buf), "0x%lX", (unsigned long)reg->value); - } else { - snprintf(buf, sizeof(buf), "%d", (int32_t)reg->value); - } - } else if (reg->source == RTLREG_PARAMETER) { - snprintf(buf, sizeof(buf), "param[%u]", reg->param_index); - } else if (reg->source == RTLREG_MEMORY) { - snprintf(buf, sizeof(buf), "(%ssigned) @(%d,r%u).%s", - reg->memory.is_signed ? "" : "un", reg->memory.offset, - reg->memory.addr_reg, - reg->memory.size==1 ? "b" : - reg->memory.size==2 ? "w" : - reg->memory.size==4 ? "l" : "ptr"); - } else if (reg->source == RTLREG_RESULT - || reg->source == RTLREG_RESULT_NOFOLD) { - static const char * const operators[] = { - [RTLOP_ADD ] = "+", - [RTLOP_SUB ] = "-", - [RTLOP_AND ] = "&", - [RTLOP_OR ] = "|", - [RTLOP_XOR ] = "^", - [RTLOP_SLL ] = "<<", - [RTLOP_SRL ] = ">>", - [RTLOP_SRA ] = ">>", - [RTLOP_ROR ] = "ROR", - [RTLOP_CLZ ] = "CLZ", - [RTLOP_CLO ] = "CLO", - [RTLOP_SLTU ] = "<", - [RTLOP_SLTS ] = "<", - [RTLOP_BSWAPH] = "BSWAPH", - [RTLOP_BSWAPW] = "BSWAPW", - [RTLOP_HSWAPW] = "HSWAPW", - [RTLOP_ADDI ] = "+", - [RTLOP_ANDI ] = "&", - [RTLOP_ORI ] = "|", - [RTLOP_XORI ] = "^", - [RTLOP_SLLI ] = "<<", - [RTLOP_SRLI ] = ">>", - [RTLOP_SRAI ] = ">>", - [RTLOP_RORI ] = "ROR", - [RTLOP_SLTUI ] = "<", - [RTLOP_SLTSI ] = "<", - }; - // 0x01: immediate operand is signed, 0x02: display "(signed)" - static const uint8_t is_signed[] = { - [RTLOP_SRA ] = 2, - [RTLOP_SLTS ] = 2, - [RTLOP_ADDI ] = 1, - [RTLOP_SRAI ] = 2, - [RTLOP_SLTSI] = 3, - [RTLOP_SLTUI] = 1, - }; - switch (reg->result.opcode) { - case RTLOP_MOVE: - snprintf(buf, sizeof(buf), "r%u", reg->result.src1); - break; - case RTLOP_SELECT: - snprintf(buf, sizeof(buf), "r%u ? r%u : r%u", reg->result.cond, - reg->result.src1, reg->result.src2); - break; - case RTLOP_NOT: - snprintf(buf, sizeof(buf), "~r%u", reg->result.src1); - break; - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - snprintf(buf, sizeof(buf), "%s(r%u)", - operators[reg->result.opcode], reg->result.src1); - break; - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - snprintf(buf, sizeof(buf), "%sr%u %s r%u", - is_signed[reg->result.opcode] & 2 ? "(signed) " : "", - reg->result.src1, operators[reg->result.opcode], - reg->result.src2); - break; - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - snprintf(buf, sizeof(buf), "%sr%u %s ", - is_signed[reg->result.opcode] & 2 ? "(signed) " : "", - reg->result.src1, operators[reg->result.opcode]); - if ((is_signed[reg->result.opcode] & 1) - && (int32_t)reg->result.imm >= -0x8000 - && (int32_t)reg->result.imm <= 0xFFFF - ) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%d", - (int)reg->result.imm); - } else { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "0x%X", - (int)reg->result.imm); - } - break; - case RTLOP_MULU: - case RTLOP_MULS: - snprintf(buf, sizeof(buf), "%s%sr%u * r%u%s", - reg->result.opcode == RTLOP_MULS ? "(signed) " : "", - reg->result.second_res ? "(" : "", - reg->result.src1, reg->result.src2, - reg->result.second_res ? ") >> 32" : ""); - break; - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - snprintf(buf, sizeof(buf), "%sr%u %c r%u", - reg->result.opcode == RTLOP_DIVMODS ? "(signed) " : "", - reg->result.src1, reg->result.second_res ? '%' : '/', - reg->result.src2); - break; - case RTLOP_BFEXT: - snprintf(buf, sizeof(buf), "BFEXT(r%u, %u, %u)", - reg->result.src1, reg->result.start, reg->result.count); - break; - case RTLOP_BFINS: - snprintf(buf, sizeof(buf), "BFINS(r%u, r%u, %u, %u)", - reg->result.src1, reg->result.src2, - reg->result.start, reg->result.count); - break; - default: - snprintf(buf, sizeof(buf), "???"); - break; - } // switch (reg->result.opcode) - } else { - snprintf(buf, sizeof(buf), "???"); - } - return buf; -} - -#endif // RTL_TRACE_GENERATE || RTL_TRACE_EXECUTE - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * add_unit_edges: Add edges between basic units for GOTO instructions. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * Execution time is O(n) in the number of basic units. - */ -static int add_unit_edges(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - RTLUnit * const unit = &block->units[unit_index]; - if (unit->first_insn <= unit->last_insn) { - const RTLInsn * const insn = &block->insns[unit->last_insn]; - if (insn->opcode == RTLOP_GOTO - || insn->opcode == RTLOP_GOTO_IF_Z - || insn->opcode == RTLOP_GOTO_IF_NZ - || insn->opcode == RTLOP_GOTO_IF_E - || insn->opcode == RTLOP_GOTO_IF_NE - ) { - const unsigned int label = insn->label; - if (UNLIKELY(block->label_unitmap[label] < 0)) { - DMSG("%p/%u: GOTO to unknown label %u", block, - unit->last_insn, label); - return 0; - } else if (UNLIKELY(!rtlunit_add_edge(block, unit_index, block->label_unitmap[label]))) { - DMSG("%p: Failed to add edge %u->%u for %s L%u", block, - unit_index, block->label_unitmap[label], - insn->opcode == RTLOP_GOTO ? "GOTO" : - insn->opcode == RTLOP_GOTO_IF_Z ? "GOTO_IF_Z" : - insn->opcode == RTLOP_GOTO_IF_NZ ? "GOTO_IF_NZ" : - insn->opcode == RTLOP_GOTO_IF_E ? "GOTO_IF_E" : - "GOTO_IF_NE", - label); - return 0; - } - } - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * update_live_ranges: Update the live range of any register live at the - * beginning unit targeted by a backward branch so that the register is - * live through all branches that target the unit. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * Worst-case execution time is O(n*m) in the number of units (n) and - * the number of registers (m). However, the register scan is only - * required for units targeted by backward branches, and terminates at - * the first register born within or after the targeted unit. - */ -static int update_live_ranges(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - const RTLUnit * const unit = &block->units[unit_index]; - int latest_entry_unit = -1; - unsigned int i; - for (i = 0; i < lenof(unit->entries) && unit->entries[i] >= 0; i++) { - if (unit->entries[i] > latest_entry_unit) { - latest_entry_unit = unit->entries[i]; - } - } - if (latest_entry_unit >= unit_index - && block->units[latest_entry_unit].last_insn >= 0 // Just in case - ) { - const uint32_t birth_limit = unit->first_insn; - const uint32_t min_death = - block->units[latest_entry_unit].last_insn; - unsigned int reg; - for (reg = block->first_live_reg; - reg != 0 && block->regs[reg].birth < birth_limit; - reg = block->regs[reg].live_link - ) { - if (block->regs[reg].death >= birth_limit - && block->regs[reg].death < min_death - ) { - block->regs[reg].death = min_death; - } - } - } - } - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -#ifdef RTL_TRACE_GENERATE - -/** - * dump_block: Dump the contents of an RTL block to stderr. - * - * [Parameters] - * block: RTL block - * tag: Tag to prepend to all lines, or NULL for none - * [Return value] - * None - */ -static void dump_block(const RTLBlock * const block, const char * const tag) -{ - PRECOND(block != NULL, return); - - uint32_t insn_index; - for (insn_index = 0; insn_index < block->num_insns; insn_index++) { - fprintf(stderr, "[RTL] %s%s%s%p/%5u: %s\n", - tag ? "[" : "", tag ? tag : "", tag ? "] " : "", - block, insn_index, rtl_decode_insn(block, insn_index, 0)); - } - - rtlunit_dump_all(block, tag); -} - -#endif // RTL_TRACE_GENERATE - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtl.h b/yabause/src/psp/rtl.h deleted file mode 100644 index aed1d5fabb..0000000000 --- a/yabause/src/psp/rtl.h +++ /dev/null @@ -1,314 +0,0 @@ -/* src/psp/rtl.h: Declarations for register transfer language used in - dynamic translation - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef RTL_H -#define RTL_H - -/*************************************************************************/ - -/** - * RTLBlock: State information used in translating a block of code. - * Opaque to callers. - */ -typedef struct RTLBlock_ RTLBlock; - -/*-----------------------------------------------------------------------*/ - -/** - * RTLOpcode: Enumeration of operations, used as the value of the - * RTLInsn.op field. - */ -typedef enum RTLOpcode_ { - /* Zero is invalid */ - - /* No operation */ - RTLOP_NOP = 1, // [No operation -- note that a value can be given - // in src1 for debugging purposes] - - /* Register-register operations */ - RTLOP_MOVE, // dest = src1 - RTLOP_SELECT, // dest = other ? src1 : src2 - RTLOP_ADD, // dest = src1 + src2 - RTLOP_SUB, // dest = src1 - src2 - RTLOP_MULU, // (uint64_t){other,dest} = - // (unsigned)src1 * (unsigned)src2 - // [upper 32 bits of result stored in "other", - // lower 32 bits of result stored in "dest"; - // either dest or other may be zero = omitted] - RTLOP_MULS, // (int64_t){other,dest} = (signed)src1 * (signed)src2 - // [either dest or other may be zero = omitted] - RTLOP_MADDU, // (uint64_t){other,dest} += - // (unsigned)src1 * (unsigned)src2 - // [other/dest are both inputs and outputs; for - // optimal performance, they should be the same - // registers used as outputs of a MULU/MULS or - // previous MADDU/MADDS insn] - RTLOP_MADDS, // (int64_t){other,dest} += (signed)src1 * (signed)src2 - RTLOP_DIVMODU, // dest = (unsigned)src1 / (unsigned)src2; - // other = (unsigned)src1 % (unsigned)src2 - // [both undefined if src2 == 0] - // [either dest or other may be zero = omitted] - RTLOP_DIVMODS, // dest = (signed)src1 / (signed)src2; - // other = (signed)src1 % (signed)src2 - // [both undefined if src2 == 0] - // [either dest or other may be zero = omitted] - RTLOP_AND, // dest = src1 & src2 - RTLOP_OR, // dest = src1 | src2 - RTLOP_XOR, // dest = src1 ^ src2 - RTLOP_NOT, // dest = ~src1 - RTLOP_SLL, // dest = src1 << src2 [undefined when src2 >= 32] - RTLOP_SRL, // dest = (unsigned)src1 >> src2 - // [undefined when src2 >= 32] - RTLOP_SRA, // dest = (signed)src1 >> src2 - // [undefined when src2 >= 32] - RTLOP_ROR, // dest = src1 ROR (src2 % 32) [in 32 bits] - RTLOP_CLZ, // dest = [number of leading zeros in src1] - RTLOP_CLO, // dest = [number of leading ones in src1] - RTLOP_SLTU, // dest = (unsigned)src1 < (unsigned)src2 ? 1 : 0 - RTLOP_SLTS, // dest = (signed)src1 < (signed)src2 ? 1 : 0 - RTLOP_BSWAPH, // dest = [swap adjacent pairs of bytes in src1] - RTLOP_BSWAPW, // dest = [reverse order of sets of 4 bytes in src1] - RTLOP_HSWAPW, // dest = [swap adjacent pairs of halfword in src1] - - /* Register-immediate operations */ - RTLOP_ADDI, // dest = src1 + IMMEDIATE(src2) - RTLOP_ANDI, // dest = src1 & IMMEDIATE(src2) - RTLOP_ORI, // dest = src1 | IMMEDIATE(src2) - RTLOP_XORI, // dest = src1 ^ IMMEDIATE(src2) - RTLOP_SLLI, // dest = src1 << IMMEDIATE(src2) - RTLOP_SRLI, // dest = (unsigned)src1 >> IMMEDIATE(src2) - RTLOP_SRAI, // dest = (signed)src1 << IMMEDIATE(src2) - RTLOP_RORI, // dest = src1 ROR IMMEDIATE(src2) [in 32 bits] - RTLOP_SLTUI, // dest = (unsigned)src1 < (unsigned)IMMEDIATE(src2) - // ? 1 : 0 - RTLOP_SLTSI, // dest = (signed)src1 < (signed)IMMEDIATE(src2) - // ? 1 : 0 - - /* Bitfield operations ("start" and "count" are encoded in the "other" - * parameter as: other = start | count<<8) */ - RTLOP_BFEXT, // dest = (src1 >> start) & ((1<finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(state != NULL, return 0); - - /* Create the instruction-to-unit lookup table if it hasn't been - * created yet */ - if (UNLIKELY(!block->insn_unitmap)) { - if (UNLIKELY(!create_insn_unitmap(block))) { - DMSG("%p: Failed to create insn-to-unit lookup table", block); - return 0; - } - } - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - /* Clear the SH-2 register cache bitmask */ - block->sh2_regcache_mask = 0; -#endif - - /* Actually execute instructions */ - uint32_t insn_count = 0; - uint32_t index = 0; - while (index < block->num_insns) { - insn_count++; - if (!rtl_execute_insn(block, &index, state)) { - break; - } - } - return insn_count; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * create_insn_unitmap: Create a lookup table mapping instruction indices to - * unit indices, used by rtl_execute_block() to find the unit containing - * the first instruction to execute. - * - * [Parameters] - * block: RTLBlock to create table for - * [Return value] - * Nonzero on success, zero on error - */ -static int create_insn_unitmap(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - - block->insn_unitmap = - malloc(sizeof(*block->insn_unitmap) * block->num_insns); - if (UNLIKELY(!block->insn_unitmap)) { - DMSG("No memory for insn-to-unit lookup table (%lu bytes)", - (unsigned long)(sizeof(*block->insn_unitmap) * block->num_insns)); - return 0; - } - memset(block->insn_unitmap, -1, - sizeof(*block->insn_unitmap) * block->num_insns); - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - uint32_t insn_index; - for (insn_index = block->units[unit_index].first_insn; - (int32_t)insn_index <= block->units[unit_index].last_insn; - insn_index++ - ) { - block->insn_unitmap[insn_index] = unit_index; - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * rtl_execute_insn: Execute a single RTL instruction from the given - * block. - * - * [Parameters] - * block: RTLBlock to execute - * index_ptr: Pointer to variable holding index of instruction to - * execute; incremented on return to indicate the next - * instruction to execute - * state: SH-2 state block - * [Return value] - * Nonzero to continue execution, zero to terminate execution - */ -static inline int rtl_execute_insn(RTLBlock *block, uint32_t *index_ptr, - void *state) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(index_ptr != NULL, return 0); - PRECOND(*index_ptr < block->num_insns, return 0); - PRECOND(state != NULL, return 0); - -#ifdef RTL_TRACE_EXECUTE - fprintf(stderr, "%p/%u: %s\n", block, *index_ptr, - rtl_decode_insn(block, *index_ptr, 1)); -#endif - - const RTLInsn * const insn = &block->insns[*index_ptr]; - const RTLUnit * const unit = &block->units[block->insn_unitmap[*index_ptr]]; - if (*index_ptr < unit->last_insn) { - (*index_ptr)++; - } else { - int next_unit = unit->next_unit; - while (next_unit >= 0 && block->units[next_unit].first_insn - > block->units[next_unit].last_insn) { - next_unit = block->units[next_unit].next_unit; - } - if (next_unit >= 0) { - *index_ptr = block->units[next_unit].first_insn; - } else { - *index_ptr = block->num_insns; // Terminate execution - } - } - - RTLRegister * const dest = &block->regs[insn->dest]; - const RTLRegister * const src1 = &block->regs[insn->src1]; - const RTLRegister * const src2 = &block->regs[insn->src2]; - - /*------------------------------*/ - - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm >> 28 == 0x8 || insn->src_imm >> 28 == 0xA) { - /* Trace an instruction */ - - SH2State *sh2 = (SH2State *)state; - uint32_t *sh2_regs = (uint32_t *)&sh2; - uint32_t saveregs[23]; - memcpy(saveregs, sh2_regs, sizeof(saveregs)); - uint32_t mask = block->sh2_regcache_mask; - unsigned int sh2_reg; - for (sh2_reg = 0; mask != 0; mask >>= 1, sh2_reg++) { - if (mask & 1) { - sh2_regs[sh2_reg] = block->sh2_regcache[sh2_reg]; - } - } - uint32_t op = block->insns[(*index_ptr)++].src_imm; - unsigned int do_trace = 1; - if (op>>24 == 0x9F) { // Conditional execution - const unsigned int cond_reg = op & 0xFFFF; - const unsigned int test_bit = op>>16 & 1; - do_trace = (block->regs[cond_reg].value == test_bit); - op = block->insns[(*index_ptr)++].src_imm; - } - uint32_t cached_cycles = op; - PRECOND(cached_cycles>>24 == 0x98, return 1); - cached_cycles &= 0xFFFF; - uint32_t cached_cycle_reg = block->insns[(*index_ptr)++].src_imm; - PRECOND(cached_cycles>>24 == 0x90, return 1); - cached_cycle_reg &= 0xFFFF; - if (cached_cycle_reg) { - cached_cycles += block->regs[cached_cycle_reg].value; - } else { - cached_cycles += sh2->cycles; - } - const uint32_t old_cycles = sh2->cycles; - sh2->cycles = cached_cycles; - if (do_trace) { - (*trace_insn_callback)(sh2, insn->src_imm & 0x7FFFFFFF); - } - sh2->cycles = old_cycles; - memcpy(sh2_regs, saveregs, sizeof(saveregs)); - - } else if (insn->src_imm >> 28 == 0xB) { - /* Record a cached SH-2 register value */ - - uint32_t op = insn->src_imm; - uint32_t offset = 0; - if (op & 0x08000000) { - PRECOND(op>>24 == 0xB8, return 1); - offset = (op & 0xFFFF) << 16; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xBC, return 1); - offset |= op & 0xFFFF; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xB0, return 1); - } - unsigned int sh2_reg = (op >> 16) & 0xFF; - unsigned int rtl_reg = op & 0xFFFF; - if (rtl_reg) { - if (sh2_reg & 0x80) { // Used for SR.T - if (!(block->sh2_regcache_mask & 1<<16)) { - SH2State *sh2 = (SH2State *)state; - block->sh2_regcache[16] = sh2->SR & ~SR_T; - block->sh2_regcache_mask |= 1<<16; - } else { - block->sh2_regcache[16] &= ~SR_T; - } - block->sh2_regcache[16] |= block->regs[rtl_reg].value; - } else { - block->sh2_regcache[sh2_reg] = - block->regs[rtl_reg].value + offset; - block->sh2_regcache_mask |= 1<sh2_regcache[sh2_reg] = offset; - block->sh2_regcache_mask |= 1<sh2_regcache_mask &= ~(1<src_imm >> 28 == 0xC) { - /* Trace a store operation */ - - uint32_t op; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>28 == 0xD, return 1); - uint32_t address; - if (op & 0x08000000) { - PRECOND(op>>24 == 0xD8, return 1); - address = (op & 0xFFFF) << 16; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xDC, return 1); - address |= op & 0xFFFF; - } else { - address = block->regs[op & 0xFFFF].value; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xD4, return 1); - address += (op & 0xFFFF) << 16; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xD6, return 1); - address += op & 0xFFFF; - } - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>28 == 0xE, return 1); - const uint32_t src = block->regs[op & 0xFFFF].value; - switch (insn->src_imm & 0xFFFF) { - case 1: (*trace_storeb_callback)(address, src); break; - case 2: (*trace_storew_callback)(address, src); break; - case 4: (*trace_storel_callback)(address, src); break; - default: - DMSG("Invalid store trace type %u", insn->src_imm & 0xFF); - break; - } - - } -#endif // RTL_TRACE_STEALTH_FOR_SH2 - return 1; - - /*----------------------------*/ - - case RTLOP_MOVE: - dest->value = src1->value; - return 1; - - case RTLOP_SELECT: - dest->value = - block->regs[insn->cond].value ? src1->value : src2->value; - return 1; - - case RTLOP_ADD: - dest->value = src1->value + (intptr_t)(int32_t)src2->value; - return 1; - - case RTLOP_SUB: - dest->value = src1->value - (intptr_t)(int32_t)src2->value; - return 1; - - case RTLOP_MULU: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (uint32_t)(src1->value * src2->value); - dest2->value = (uint64_t)((uint64_t)(uint32_t)src1->value - * (uint64_t)(uint32_t)src2->value) >> 32; - return 1; - } - - case RTLOP_MULS: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (uint32_t)(src1->value * src2->value); - dest2->value = (int64_t)((int64_t)(int32_t)src1->value - * (int64_t)(int32_t)src2->value) >> 32; - return 1; - } - - case RTLOP_MADDU: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - uint64_t initial = (uint64_t)(uint32_t)dest2->value << 32 - | (uint64_t)(uint32_t)dest->value; - uint64_t product = (uint64_t)(uint32_t)src1->value - * (uint64_t)(uint32_t)src2->value; - uint64_t result = initial + product; - dest->value = (uint32_t)result; - dest2->value = (uint32_t)(result >> 32); - return 1; - } - - case RTLOP_MADDS: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - int64_t initial = (int64_t)(int32_t)dest2->value << 32 - | (int64_t)(uint32_t)dest->value; // unsigned! - int64_t product = (int64_t)(int32_t)src1->value - * (int64_t)(int32_t)src2->value; - int64_t result = initial + product; - dest->value = (uint32_t)result; - dest2->value = (uint32_t)(result >> 32); - return 1; - } - - case RTLOP_DIVMODU: - if (src2->value) { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (uint32_t)src1->value / (uint32_t)src2->value; - dest2->value = (uint32_t)src1->value % (uint32_t)src2->value; - } - return 1; - - case RTLOP_DIVMODS: - if (src2->value) { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (int32_t)src1->value / (int32_t)src2->value; - dest2->value = (int32_t)src1->value % (int32_t)src2->value; - } - return 1; - - case RTLOP_AND: - dest->value = src1->value & (intptr_t)(int32_t)src2->value; - return 1; - - case RTLOP_OR: - dest->value = src1->value | (uintptr_t)(uint32_t)src2->value; - return 1; - - case RTLOP_XOR: - dest->value = src1->value ^ (uintptr_t)(uint32_t)src2->value; - return 1; - - case RTLOP_NOT: - dest->value = (uint32_t)(~src1->value); - return 1; - - case RTLOP_SLL: - if (src2->value < 32) { - dest->value = (uint32_t)(src1->value << src2->value); - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRL: - if (src2->value < 32) { - dest->value = (uint32_t)src1->value >> src2->value; - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRA: - if (src2->value < 32) { - dest->value = (int32_t)src1->value >> src2->value; - } else { - dest->value = (int32_t)src1->value >> 31; - } - return 1; - - case RTLOP_ROR: - if ((src2->value & 31) != 0) { - dest->value = (uint32_t)src1->value >> (src2->value & 31) - | (uint32_t)src1->value << (32 - (src2->value & 31)); - } else { - dest->value = (uint32_t)src1->value; - } - return 1; - - case RTLOP_CLZ: { -#ifdef __GNUC__ - dest->value = __builtin_clz(src1->value); -#else - uint32_t temp = src1->value; - dest->value = 32; - while (temp) { - temp >>= 1; - dest->value--; - } -#endif - return 1; - } - - case RTLOP_CLO: { - uint32_t temp = src1->value; - dest->value = 0; - while ((int32_t)temp < 0) { - temp <<= 1; - dest->value++; - } - return 1; - } - - case RTLOP_SLTU: - dest->value = ((uint32_t)src1->value < (uint32_t)src2->value) ? 1 : 0; - return 1; - - case RTLOP_SLTS: - dest->value = ((int32_t)src1->value < (int32_t)src2->value) ? 1 : 0; - return 1; - - case RTLOP_BSWAPH: - dest->value = ((uint32_t)src1->value & 0xFF00FF00) >> 8 - | ((uint32_t)src1->value & 0x00FF00FF) << 8; - return 1; - - case RTLOP_BSWAPW: - dest->value = ((uint32_t)src1->value & 0xFF000000) >> 24 - | ((uint32_t)src1->value & 0x00FF0000) >> 8 - | ((uint32_t)src1->value & 0x0000FF00) << 8 - | ((uint32_t)src1->value & 0x000000FF) << 24; - return 1; - - case RTLOP_HSWAPW: - dest->value = ((uint32_t)src1->value & 0xFFFF0000) >> 16 - | ((uint32_t)src1->value & 0x0000FFFF) << 16; - return 1; - - /*----------------------------*/ - - case RTLOP_ADDI: - dest->value = src1->value + (intptr_t)(int32_t)insn->src_imm; - return 1; - - case RTLOP_ANDI: - dest->value = src1->value & (intptr_t)(int32_t)insn->src_imm; - return 1; - - case RTLOP_ORI: - dest->value = src1->value | (uintptr_t)(uint32_t)insn->src_imm; - return 1; - - case RTLOP_XORI: - dest->value = src1->value ^ (uintptr_t)(uint32_t)insn->src_imm; - return 1; - - case RTLOP_SLLI: - if (insn->src_imm < 32) { - dest->value = (uint32_t)(src1->value << insn->src_imm); - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRLI: - if (insn->src_imm < 32) { - dest->value = (uint32_t)src1->value >> insn->src_imm; - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRAI: - if (insn->src_imm < 32) { - dest->value = (int32_t)src1->value >> insn->src_imm; - } else { - dest->value = (int32_t)src1->value >> 31; - } - return 1; - - case RTLOP_RORI: - if ((insn->src_imm & 31) != 0) { - dest->value = (uint32_t)src1->value >> (insn->src_imm & 31) - | (uint32_t)src1->value << (32 - (insn->src_imm & 31)); - } else { - dest->value = (uint32_t)src1->value; - } - return 1; - - case RTLOP_SLTUI: - dest->value = ((uint32_t)src1->value < (uint32_t)insn->src_imm) ? 1 : 0; - return 1; - - case RTLOP_SLTSI: - dest->value = ((int32_t)src1->value < (int32_t)insn->src_imm) ? 1 : 0; - return 1; - - /*----------------------------*/ - - case RTLOP_BFEXT: - dest->value = ((uint32_t)src1->value >> insn->bitfield.start) - & ((1 << insn->bitfield.count) - 1); - return 1; - - case RTLOP_BFINS: - dest->value = ((uint32_t)src1->value - & ~(((1 << insn->bitfield.count) - 1) - << insn->bitfield.start)) - | (((uint32_t)src2->value - & ((1 << insn->bitfield.count) - 1)) - << insn->bitfield.start); - return 1; - - /*----------------------------*/ - - case RTLOP_LOAD_IMM: - dest->value = insn->src_imm; - return 1; - - case RTLOP_LOAD_ADDR: - dest->value = insn->src_addr; - return 1; - - case RTLOP_LOAD_PARAM: - if (insn->src_imm == 0) { - dest->value = (uintptr_t)state; - } else { - DMSG("LOAD_PARAM for undefined parameter %u", - (unsigned int)insn->src_imm); - dest->value = 0xDEADF00D; - } - return 1; - - case RTLOP_LOAD_BU: - dest->value = *(uint8_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_BS: - dest->value = *(int8_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_HU: - dest->value = *(uint16_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_HS: - dest->value = *(int16_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_W: - dest->value = *(uint32_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_PTR: - dest->value = *(uintptr_t *)(src1->value + insn->offset); - return 1; - - /*----------------------------*/ - - case RTLOP_STORE_B: - *(uint8_t *)(dest->value + insn->offset) = src1->value; - return 1; - - case RTLOP_STORE_H: - *(uint16_t *)(dest->value + insn->offset) = src1->value; - return 1; - - case RTLOP_STORE_W: - *(uint32_t *)(dest->value + insn->offset) = src1->value; - return 1; - - case RTLOP_STORE_PTR: - *(uintptr_t *)(dest->value + insn->offset) = src1->value; - return 1; - - /*----------------------------*/ - - case RTLOP_LABEL: - return 1; - - case RTLOP_GOTO: - do_goto: - if (insn->label < 1 || insn->label > block->next_label) { - DMSG("%p/%u: label %u out of range", - block, (int)(insn - block->insns), insn->label); - } else if (block->label_unitmap[insn->label] < 0) { - DMSG("%p/%u: label %u not defined", - block, (int)(insn - block->insns), insn->label); - } else { - *index_ptr = - block->units[block->label_unitmap[insn->label]].first_insn; - } - return 1; - - case RTLOP_GOTO_IF_Z: - if (src1->value == 0) { - goto do_goto; - } - return 1; - - case RTLOP_GOTO_IF_NZ: - if (src1->value != 0) { - goto do_goto; - } - return 1; - - case RTLOP_GOTO_IF_E: - if (src1->value == src2->value) { - goto do_goto; - } - return 1; - - case RTLOP_GOTO_IF_NE: - if (src1->value != src2->value) { - goto do_goto; - } - return 1; - - /*----------------------------*/ - - case RTLOP_CALL: { - /* The called function must take pointer-sized parameters and - * return a pointer-sized value. */ - const void *funcptr = (const void *)block->regs[insn->target].value; - if (insn->dest) { - if (insn->src1) { - if (insn->src2) { - FASTCALL uintptr_t (*func)(uintptr_t, uintptr_t) = funcptr; - dest->value = (*func)(src1->value, src2->value); - } else { - FASTCALL uintptr_t (*func)(uintptr_t) = funcptr; - dest->value = (*func)(src1->value); - } - } else { - FASTCALL uintptr_t (*func)(void) = funcptr; - dest->value = (*func)(); - } - } else { - if (insn->src1) { - if (insn->src2) { - FASTCALL void (*func)(uintptr_t, uintptr_t) = funcptr; - (*func)(src1->value, src2->value); - } else { - FASTCALL void (*func)(uintptr_t) = funcptr; - (*func)(src1->value); - } - } else { - FASTCALL void (*func)(void) = funcptr; - (*func)(); - } - } - return 1; - } - - /*----------------------------*/ - - case RTLOP_RETURN: - return 0; - - case RTLOP_RETURN_TO: { - RTLBlock *newblock = (RTLBlock *)block->regs[insn->target].value; - /* Assume we won't fill up the stack doing this... */ - rtl_execute_block(newblock, state); - return 0; - } - - } // switch (insn->opcode) - - /*------------------------------*/ - - DMSG("Block %p index %u: invalid opcode %u", block, *index_ptr, - insn->opcode); - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtlinsn.c b/yabause/src/psp/rtlinsn.c deleted file mode 100644 index e11dcfb9e4..0000000000 --- a/yabause/src/psp/rtlinsn.c +++ /dev/null @@ -1,935 +0,0 @@ -/* src/psp/rtlinsn.c: Instruction encoding routines for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This source file defines functions for encoding RTL instructions into - * the RTLInsn structure based on the type of instruction (2-operand ALU, - * memory load, and so on). These functions are not exported directly, but - * are instead called through a lookup table by rtlinsn_make(), an inline - * function defined in rtl-internal.h. - * - * Both the inlining of rtlinsn_make() and the requirement of preloading - * the opcode into insn->opcode (and then taking the RTLInsn pointer in - * place of the opcode parameter to rtl_add_insn()) are to help - * optimization of the fast path; for example, on MIPS architectures, - * rtl_add_insn() can directly call the encoding function in this file - * without having to pass through a call to rtlinsn_make() or reload the - * parameter registers ($a0-$t1). - */ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" - -/*************************************************************************/ -/************************** Local declarations ***************************/ -/*************************************************************************/ - -/* Encoding functions for specific opcode groups */ - -static int make_nop(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alu_1op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alu_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alui_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alu_2op_2dest(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_select(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_madd(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_bitfield(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load_imm(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load_addr(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load_param(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_store(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_label(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_goto(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_goto_cond(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_goto_cond2(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_call(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_return(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_return_to(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); - - -/* Encoding function table */ - -int (* const makefunc_table[])(RTLBlock *, RTLInsn *, unsigned int, - uintptr_t, uint32_t, unsigned int) = { - [RTLOP_NOP ] = make_nop, - [RTLOP_MOVE ] = make_alu_1op, - [RTLOP_SELECT ] = make_select, - [RTLOP_ADD ] = make_alu_2op, - [RTLOP_SUB ] = make_alu_2op, - [RTLOP_MULU ] = make_alu_2op_2dest, - [RTLOP_MULS ] = make_alu_2op_2dest, - [RTLOP_MADDU ] = make_madd, - [RTLOP_MADDS ] = make_madd, - [RTLOP_DIVMODU ] = make_alu_2op_2dest, - [RTLOP_DIVMODS ] = make_alu_2op_2dest, - [RTLOP_AND ] = make_alu_2op, - [RTLOP_OR ] = make_alu_2op, - [RTLOP_XOR ] = make_alu_2op, - [RTLOP_NOT ] = make_alu_1op, - [RTLOP_SLL ] = make_alu_2op, - [RTLOP_SRL ] = make_alu_2op, - [RTLOP_SRA ] = make_alu_2op, - [RTLOP_ROR ] = make_alu_2op, - [RTLOP_CLZ ] = make_alu_1op, - [RTLOP_CLO ] = make_alu_1op, - [RTLOP_SLTU ] = make_alu_2op, - [RTLOP_SLTS ] = make_alu_2op, - [RTLOP_BSWAPH ] = make_alu_1op, - [RTLOP_BSWAPW ] = make_alu_1op, - [RTLOP_HSWAPW ] = make_alu_1op, - [RTLOP_ADDI ] = make_alui_2op, - [RTLOP_ANDI ] = make_alui_2op, - [RTLOP_ORI ] = make_alui_2op, - [RTLOP_XORI ] = make_alui_2op, - [RTLOP_SLLI ] = make_alui_2op, - [RTLOP_SRLI ] = make_alui_2op, - [RTLOP_SRAI ] = make_alui_2op, - [RTLOP_RORI ] = make_alui_2op, - [RTLOP_SLTUI ] = make_alui_2op, - [RTLOP_SLTSI ] = make_alui_2op, - [RTLOP_BFEXT ] = make_bitfield, - [RTLOP_BFINS ] = make_bitfield, - [RTLOP_LOAD_IMM ] = make_load_imm, - [RTLOP_LOAD_ADDR ] = make_load_addr, - [RTLOP_LOAD_PARAM ] = make_load_param, - [RTLOP_LOAD_BS ] = make_load, - [RTLOP_LOAD_BU ] = make_load, - [RTLOP_LOAD_HS ] = make_load, - [RTLOP_LOAD_HU ] = make_load, - [RTLOP_LOAD_W ] = make_load, - [RTLOP_LOAD_PTR ] = make_load, - [RTLOP_STORE_B ] = make_store, - [RTLOP_STORE_H ] = make_store, - [RTLOP_STORE_W ] = make_store, - [RTLOP_STORE_PTR ] = make_store, - [RTLOP_LABEL ] = make_label, - [RTLOP_GOTO ] = make_goto, - [RTLOP_GOTO_IF_Z ] = make_goto_cond, - [RTLOP_GOTO_IF_NZ ] = make_goto_cond, - [RTLOP_GOTO_IF_E ] = make_goto_cond2, - [RTLOP_GOTO_IF_NE ] = make_goto_cond2, - [RTLOP_CALL ] = make_call, - [RTLOP_RETURN ] = make_return, - [RTLOP_RETURN_TO ] = make_return_to, -}; - -/*-----------------------------------------------------------------------*/ - -/* Macro to mark a given register live, updating birth/death fields too - * (requires block and insn_index to be separately defined) */ -#define MARK_LIVE(reg,index) do { \ - RTLRegister * const __reg = (reg); \ - const unsigned int __index = (index); \ - if (!__reg->live) { \ - __reg->live = 1; \ - __reg->birth = insn_index; \ - if (!block->last_live_reg) { \ - block->first_live_reg = __index; \ - } else { \ - block->regs[block->last_live_reg].live_link = __index; \ - } \ - block->last_live_reg = __index; \ - reg->live_link = 0; \ - } \ - __reg->death = insn_index; \ -} while (0) - -/*************************************************************************/ -/************************** Routine definitions **************************/ -/*************************************************************************/ - -/** - * make_nop: Encode a NOP instruction. - */ -static int make_nop(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(insn != NULL, return 0); - - insn->src_imm = src1; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alu_1op: Encode a 1-operand ALU instruction. - */ -static int make_alu_1op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); -#endif - - insn->dest = dest; - // FIXME: why does GCC waste time with an ANDI temp,arg,0xFFFF for - // stores like this src1 (but not with dest)? - insn->src1 = src1; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - if (insn->opcode == RTLOP_MOVE) { - destreg->unique_pointer = src1reg->unique_pointer; - } else { - destreg->unique_pointer = 0; - } - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = 0; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alu_2op: Encode a 2-operand ALU instruction. - */ -static int make_alu_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alui_2op: Encode a 2-operand register-immediate ALU instruction. - */ -static int make_alui_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src_imm = src2; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 1; - destreg->result.src1 = src1; - destreg->result.imm = src2; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alu_2op_2dest: Encode a 2-operand, 2-destination ALU instruction. - */ -static int make_alu_2op_2dest(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->dest2 = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const dest2reg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - if (dest != 0) { - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - MARK_LIVE(destreg, dest); - } - if (other != 0) { - dest2reg->source = dest2reg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - dest2reg->unique_pointer = 0; - dest2reg->result.opcode = insn->opcode; - dest2reg->result.second_res = 1; - dest2reg->result.is_imm = 0; - dest2reg->result.src1 = src1; - dest2reg->result.src2 = src2; - MARK_LIVE(dest2reg, other); - } - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_select: Encode a SELECT instruction. - */ -static int make_select(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->cond = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const condreg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - destreg->result.cond = other; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - MARK_LIVE(condreg, other); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_madd: Encode an MADDU or MADDS instruction. - */ -static int make_madd(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->dest2 = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const dest2reg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - destreg->source = RTLREG_UNKNOWN; // Always UNKNOWN, since we modify it - destreg->unique_pointer = 0; - MARK_LIVE(destreg, dest); - dest2reg->source = RTLREG_UNKNOWN; - dest2reg->unique_pointer = 0; - MARK_LIVE(dest2reg, other); - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_bitfield: Encode a bitfield instruction. - */ -static int make_bitfield(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); - const int start = other & 0xFF; - const int count = (other >> 8) & 0xFF; -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND((insn->opcode != RTLOP_BFINS || src2 != 0) && src2 < block->next_reg, return 0); - PRECOND(start < 32, return 0); - PRECOND(count <= 32 - start, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->bitfield.start = start; - insn->bitfield.count = count; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - destreg->result.start = start; - destreg->result.count = count; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - if (src2) { - MARK_LIVE(src2reg, src2); - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load_imm: Encode a LOAD_IMM instruction. - */ -static int make_load_imm(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src_imm = src1; - - RTLRegister * const destreg = &block->regs[dest]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_CONSTANT; - destreg->unique_pointer = 0; - destreg->value = src1; - MARK_LIVE(destreg, dest); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load_addr: Encode a LOAD_ADDR instruction. - */ -static int make_load_addr(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src_addr = src1; - - RTLRegister * const destreg = &block->regs[dest]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_CONSTANT; - destreg->unique_pointer = 0; - destreg->value = src1; - MARK_LIVE(destreg, dest); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load_param: Encode a LOAD_PARAM instruction. - */ -static int make_load_param(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src_imm = src1; - - RTLRegister * const destreg = &block->regs[dest]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_PARAMETER; - destreg->unique_pointer = 0; - destreg->param_index = src1; - MARK_LIVE(destreg, dest); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load: Encode a memory load instruction. - */ -static int make_load(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND((int)other >= -0x8000 && (int)other <= 0x7FFF, return 0); -#endif - - /* Lookup tables for destreg->memory.{size,is_signed} */ - static const uint8_t size_lookup[] = { - [RTLOP_LOAD_BU ] = 1, [RTLOP_LOAD_BS] = 1, - [RTLOP_LOAD_HU ] = 2, [RTLOP_LOAD_HS] = 2, - [RTLOP_LOAD_W ] = 4, - [RTLOP_LOAD_PTR] = sizeof(void *), - }; - static const uint8_t is_signed_lookup[] = { - [RTLOP_LOAD_BS] = 1, - [RTLOP_LOAD_HS] = 1, - }; - - insn->dest = dest; - insn->src1 = src1; - insn->offset = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_MEMORY; - destreg->unique_pointer = 0; - destreg->memory.addr_reg = src1; - destreg->memory.offset = other; - const unsigned int opcode = insn->opcode; - destreg->memory.size = size_lookup[opcode]; - destreg->memory.is_signed = is_signed_lookup[opcode]; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_store: Encode a memory store instruction. - */ -static int make_store(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND((int)other >= -0x8000 && (int)other <= 0x7FFF, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->offset = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_label: Encode a LABEL instruction. - */ -static int make_label(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->cur_unit >= 0 && block->cur_unit < block->num_units, - return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->label = other; - - /* If this is _not_ the first instruction in the current basic - * unit, end it and create a new basic unit starting here, since - * there could potentially be a branch to this location. */ - if (block->units[block->cur_unit].first_insn != block->num_insns) { - block->units[block->cur_unit].last_insn = block->num_insns - 1; - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p/%u: Failed to start a new basic unit", - block, block->num_insns); - return 0; - } - const uint32_t new_unit = block->num_units - 1; - if (UNLIKELY(!rtlunit_add_edge(block, block->cur_unit, new_unit))){ - DMSG("%p/%u: Failed to add edge %u->%u", block, - block->num_insns, block->cur_unit, new_unit); - return 0; - } - block->cur_unit = new_unit; - block->units[block->cur_unit].first_insn = block->num_insns; - } - - /* Save the label's unit number in the label-to-unit map */ - block->label_unitmap[insn->label] = block->cur_unit; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_goto: Encode a GOTO instruction. - */ -static int make_goto(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->label = other; - - /* Terminate the current basic unit after this instruction */ - block->units[block->cur_unit].last_insn = block->num_insns; - block->have_unit = 0; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_goto_cond: Encode a GOTO_IF_Z or GOTO_IF_NZ instruction. - */ -static int make_goto_cond(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->src1 = src1; - insn->label = other; - - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - MARK_LIVE(src1reg, src1); - - /* Terminate the current basic unit after this instruction, and - * start a new basic unit with an edge connecting from this one */ - block->units[block->cur_unit].last_insn = block->num_insns; - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p/%u: Failed to start a new basic unit", - block, block->num_insns); - return 0; - } - const unsigned int new_unit = block->num_units - 1; - if (UNLIKELY(!rtlunit_add_edge(block, block->cur_unit, new_unit))) { - DMSG("%p/%u: Failed to add edge %u->%u", block, block->num_insns, - block->cur_unit, new_unit); - return 0; - } - block->cur_unit = new_unit; - block->units[block->cur_unit].first_insn = block->num_insns + 1; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_goto_cond2: Encode a GOTO_IF_E or GOTO_IF_NE instruction. - */ -static int make_goto_cond2(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->src1 = src1; - insn->src2 = src2; - insn->label = other; - - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - const uint32_t insn_index = block->num_insns; - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - block->units[block->cur_unit].last_insn = block->num_insns; - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p/%u: Failed to start a new basic unit", - block, block->num_insns); - return 0; - } - const unsigned int new_unit = block->num_units - 1; - if (UNLIKELY(!rtlunit_add_edge(block, block->cur_unit, new_unit))) { - DMSG("%p/%u: Failed to add edge %u->%u", block, block->num_insns, - block->cur_unit, new_unit); - return 0; - } - block->cur_unit = new_unit; - block->units[block->cur_unit].first_insn = block->num_insns + 1; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_call: Encode a CALL instruction. - */ -static int make_call(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest < block->next_reg, return 0); - PRECOND(!(src1 == 0 && src2 != 0) && src1 < block->next_reg, return 0); - PRECOND(src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_reg, return 0); -#endif - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const targetreg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->target = other; - if (dest) { - destreg->source = RTLREG_UNKNOWN; - destreg->unique_pointer = 0; - MARK_LIVE(destreg, dest); - } - if (src1) { - MARK_LIVE(src1reg, src1); - } - if (src2) { - MARK_LIVE(src2reg, src2); - } - MARK_LIVE(targetreg, other); - - const int cur_unit = block->cur_unit; - if (block->first_call_unit < 0) { - block->first_call_unit = cur_unit; - } - if (block->last_call_unit < cur_unit) { - if (block->last_call_unit >= 0) { - block->units[block->last_call_unit].next_call_unit = cur_unit; - block->units[cur_unit].prev_call_unit = block->last_call_unit; - } else { - block->units[cur_unit].prev_call_unit = -1; - } - block->last_call_unit = cur_unit; - } - block->units[cur_unit].next_call_unit = -1; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_return: Encode a RETURN instruction. - */ -static int make_return(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); - - /* Terminate the current basic unit, like GOTO */ - block->units[block->cur_unit].last_insn = block->num_insns; - block->have_unit = 0; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_return_to: Encode a RETURN_TO instruction. - */ -static int make_return_to(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); - - RTLRegister * const targetreg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - insn->target = other; - MARK_LIVE(targetreg, other); - - /* Terminate the current basic unit, like GOTO */ - block->units[block->cur_unit].last_insn = block->num_insns; - block->have_unit = 0; - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtlopt.c b/yabause/src/psp/rtlopt.c deleted file mode 100644 index 1b17745fc8..0000000000 --- a/yabause/src/psp/rtlopt.c +++ /dev/null @@ -1,897 +0,0 @@ -/* src/psp/rtlopt.c: Optimization processing for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This source file contains code for the various transformations applied - * to RTL code to produce more optimized instruction streams. The - * currently implemented transformations are: - * - * Constant folding/propagation (rtlopt_fold_constants) - * ---------------------------------------------------- - * Replaces instructions that operate on constant operands with LOAD_IMM - * (load immediate) instructions that load the result of the operation - * directly into the target register, eliminating the operation itself and - * allowing the constant result to be propagated further. Source operands - * that are not used elsewhere are eliminated entirely, with the - * instructions that loaded them converted to NOPs. - * - * While most constant expressions will be resolved by the source - * translator at RTL generation time, this optimization step allows macros - * in particular to take faster paths when they are called with constant - * parameters. - * - * Deconditioning (rtlopt_decondition) - * ---------------------------------- - * Converts conditional jumps (GOTO_IF_Z, GOTO_IF_NZ, GOTO_IF_E, GOTO_IF_NE) - * whose test result is a constant to either unconditional jumps (GOTO) or - * NOPs, depending on the instruction and the result of the test. - * - * Dead unit removal (rtlopt_drop_dead_units) - * ------------------------------------------ - * Removes unreachable basic units from the RTL code stream. - * - * Useless branch removal (rtlopt_drop_dead_branches) - * -------------------------------------------------- - * Replaces branch instructions that branch to the next instruction in the - * code stream with NOPs. - */ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" - -/*************************************************************************/ -/************************** Local declarations ***************************/ -/*************************************************************************/ - -static inline int fold_one_register(RTLBlock * const block, - RTLRegister * const reg); -static void maybe_eliminate_folded_register(RTLBlock * const block, - RTLRegister * const reg, - const unsigned int reg_index); - -static void drop_dead_unit(RTLBlock * const block, - const unsigned int unit_index); - -/*************************************************************************/ -/*********************** Library-internal routines ***********************/ -/*************************************************************************/ - -/** - * rtlopt_fold_constants: Perform constant folding on the given RTL block, - * converting instructions that operate on constant operands into load- - * immediate instructions that load the result of the operation. If such - * an operand is not used by any other instruction, the instruction that - * loaded it is changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_fold_constants(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - unsigned int reg_index; - for (reg_index = 1; reg_index < block->next_reg; reg_index++) { - RTLRegister * const reg = &block->regs[reg_index]; - if (reg->live && reg->source == RTLREG_RESULT) { - fold_one_register(block, reg); - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * rtlopt_decondition: Perform "deconditioning" of conditional branches - * with constant conditions. For "GOTO_IF_Z (GOTO_IF_NZ) label, rN" where - * rN is type RTLREG_CONSTANT, the instruction is changed to GOTO if the - * value of rN is zero (nonzero) and changed to NOP otherwise; similarly - * for "GOTO_IF_E (GOTO_IF_NE) label, rX, rY". As with constant folding, - * if a condition register is not used anywhere else, the register is - * eliminated and the instruction that loaded it is changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_decondition(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - /* A conditional branch always ends an basic unit and has two targets, - * so we only need to check the last instruction of each unit with two - * exit edges. */ - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - RTLUnit * const unit = &block->units[unit_index]; - if (unit->exits[1] != -1) { - RTLInsn * const insn = &block->insns[unit->last_insn]; - const RTLOpcode opcode = insn->opcode; - - if (opcode == RTLOP_GOTO_IF_Z || opcode == RTLOP_GOTO_IF_NZ) { - const unsigned int reg_index = insn->src1; - RTLRegister * const condition_reg = &block->regs[reg_index]; - if (condition_reg->source == RTLREG_CONSTANT) { - const uintptr_t condition = condition_reg->value; - const int fallthrough_index = - (unit->exits[0] == unit_index+1) ? 0 : 1; - if ((opcode == RTLOP_GOTO_IF_Z && condition == 0) - || (opcode == RTLOP_GOTO_IF_NZ && condition != 0) - ) { - /* Branch always taken: convert to GOTO */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch always taken," - " convert to GOTO and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index]); -#endif - insn->opcode = RTLOP_GOTO; - rtlunit_remove_edge(block, unit_index, - fallthrough_index); - } else { - /* Branch never taken: convert to NOP */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch never taken," - " convert to NOP and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index ^ 1]); -#endif - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - rtlunit_remove_edge(block, unit_index, - fallthrough_index ^ 1); - } - if (condition_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, condition_reg, - reg_index); - } - } - - } else if (opcode == RTLOP_GOTO_IF_E || opcode == RTLOP_GOTO_IF_NE){ - const unsigned int src1_index = insn->src1; - const unsigned int src2_index = insn->src1; - RTLRegister * const src1_reg = &block->regs[src1_index]; - RTLRegister * const src2_reg = &block->regs[src2_index]; - if (src1_reg->source == RTLREG_CONSTANT - && src2_reg->source == RTLREG_CONSTANT - ) { - const uintptr_t condition = - src1_reg->value - src2_reg->value; - const int fallthrough_index = - (unit->exits[0] == unit_index+1) ? 0 : 1; - if ((opcode == RTLOP_GOTO_IF_Z && condition == 0) - || (opcode == RTLOP_GOTO_IF_NZ && condition != 0) - ) { - /* Branch always taken: convert to GOTO */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch always taken," - " convert to GOTO and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index]); -#endif - insn->opcode = RTLOP_GOTO; - rtlunit_remove_edge(block, unit_index, - fallthrough_index); - } else { - /* Branch never taken: convert to NOP */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch never taken," - " convert to NOP and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index ^ 1]); -#endif - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - rtlunit_remove_edge(block, unit_index, - fallthrough_index ^ 1); - } - if (src1_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src1_reg, - src1_index); - } - if (src2_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src2_reg, - src2_index); - } - } - - } - } // if (unit->exits[1] != -1) - } // for (unit_index = 0; unit_index < block->num_units; unit_index++) - - return 1; -} - -/*************************************************************************/ - -/** - * rtlopt_drop_dead_units: Search an RTL block for basic units which are - * unreachable via any path from the initial unit and remove them from the - * code stream. All units dominated only by such dead units are - * recursively removed as well. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_drop_dead_units(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - /* Allocate and clear a buffer for "seen" flags */ - block->unit_seen = calloc(block->num_units, sizeof(*block->unit_seen)); - if (UNLIKELY(!block->unit_seen)) { - DMSG("Failed to allocate units_seen (%u bytes)", block->num_units); - return 0; - } - - /* Check each unit in sequence (except the initial unit, which is never - * dead even if it has no entry edges) */ - unsigned int unit_index; - for (unit_index = 1; unit_index < block->num_units; unit_index++) { - if (block->units[unit_index].entries[0] < 0) { - drop_dead_unit(block, unit_index); - } - block->unit_seen[unit_index] = 1; - } - - /* Free the "seen" flag buffer before returning (since the core doesn't - * touch this field) */ - free(block->unit_seen); - block->unit_seen = NULL; // Just for safety - - return 1; -} - -/*************************************************************************/ - -/** - * rtlopt_drop_dead_branches: Search an RTL block for branch instructions - * which branch to the next instruction in the code stream and replace them - * with NOPs. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_drop_dead_branches(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - RTLUnit * const unit = &block->units[unit_index]; - if (unit->last_insn >= unit->first_insn) { - RTLInsn * const insn = &block->insns[unit->last_insn]; - const RTLOpcode opcode = insn->opcode; - if ((opcode == RTLOP_GOTO - || opcode == RTLOP_GOTO_IF_Z - || opcode == RTLOP_GOTO_IF_NZ - || opcode == RTLOP_GOTO_IF_E - || opcode == RTLOP_GOTO_IF_NE) - && block->label_unitmap[insn->label] == unit->next_unit - ) { -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Dropping branch to next insn\n", - block, unit->last_insn); -#endif - if (opcode == RTLOP_GOTO_IF_Z || opcode == RTLOP_GOTO_IF_NZ) { - RTLRegister *src1_reg = &block->regs[insn->src1]; - if (src1_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src1_reg, - insn->src1); - } - } else if (opcode == RTLOP_GOTO_IF_E || opcode == RTLOP_GOTO_IF_NE) { - RTLRegister *src1_reg = &block->regs[insn->src1]; - if (src1_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src1_reg, - insn->src1); - } - RTLRegister *src2_reg = &block->regs[insn->src2]; - if (src2_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src2_reg, - insn->src2); - } - } - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - } - } - } - - return 1; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * fold_one_register: Attempt to perform constant folding on a register. - * The register must be of type RTLREG_RESULT. - * - * [Parameters] - * block: RTL block - * reg: Register on which to perform constant folding - * [Return value] - * Nonzero if constant folding was performed, zero otherwise - * [Notes] - * This routine calls itself recursively, but it is declared inline - * anyway to optimize the outer loop in rtlopt_fold_constants(). - */ -static inline int fold_one_register(RTLBlock * const block, - RTLRegister * const reg) -{ - PRECOND(block != NULL, return 0); - PRECOND(reg != NULL, return 0); - PRECOND(reg->live, return 0); - PRECOND(reg->source == RTLREG_RESULT, return 0); - - /* Flag the register as not foldable for the moment (to avoid infinite - * recursion in case invalid code creates register dependency loops */ - - reg->source = RTLREG_RESULT_NOFOLD; - - /* See if the operands are constant, folding them if necessary */ - - RTLRegister * const src1 = &block->regs[reg->result.src1]; - RTLRegister * const src2 = &block->regs[reg->result.src2]; - if (src1->source != RTLREG_CONSTANT - && !(src1->source == RTLREG_RESULT - && fold_one_register(block, src1)) - ) { - return 0; // Operand 1 wasn't constant - } - if (!reg->result.is_imm - && reg->result.src2 != 0 // In case it's a 1-operand instruction - && src2->source != RTLREG_CONSTANT - && !(src2->source == RTLREG_RESULT - && fold_one_register(block, src2)) - ) { - return 0; // Operand 2 wasn't constant - } - if (reg->result.opcode == RTLOP_SELECT) { - RTLRegister * const cond = &block->regs[reg->result.cond]; - if (cond->source != RTLREG_CONSTANT - && !(cond->source == RTLREG_RESULT - && fold_one_register(block, cond)) - ) { - return 0; // Condition operand wasn't constant - } - } - - /* All operands are constants, so perform the operation now and convert - * the register to a constant */ - - uintptr_t result = 0; - switch (reg->result.opcode) { - - case RTLOP_MOVE: - result = src1->value; - break; - - case RTLOP_SELECT: - result = - block->regs[reg->result.cond].value ? src1->value : src2->value; - break; - - case RTLOP_ADD: - result = src1->value + (intptr_t)(int32_t)src2->value; - break; - - case RTLOP_SUB: - result = src1->value - (intptr_t)(int32_t)src2->value; - break; - - case RTLOP_MULU: - if (reg->result.second_res) { - result = ((uint64_t)src1->value * (uint64_t)src2->value) >> 32; - } else { - result = src1->value * src2->value; - } - break; - - case RTLOP_MULS: - if (reg->result.second_res) { - result = ((int64_t)(int32_t)src1->value - * (int64_t)(int32_t)src2->value) >> 32; - } else { - result = src1->value * src2->value; - } - break; - - case RTLOP_DIVMODU: - if (reg->result.second_res) { - result = src2->value ? src1->value % src2->value : 0; - } else { - result = src2->value ? src1->value / src2->value : 0; - } - break; - - case RTLOP_DIVMODS: - if (reg->result.second_res) { - result = src2->value ? (int32_t)src1->value % (int32_t)src2->value - : 0; - } else { - result = src2->value ? (int32_t)src1->value / (int32_t)src2->value - : 0; - } - break; - - case RTLOP_AND: - result = src1->value & (intptr_t)(int32_t)src2->value; - break; - - case RTLOP_OR: - result = src1->value | (uintptr_t)(uint32_t)src2->value; - break; - - case RTLOP_XOR: - result = src1->value ^ (uintptr_t)(uint32_t)src2->value; - break; - - case RTLOP_NOT: - result = ~src1->value; - break; - - case RTLOP_SLL: - result = src1->value << src2->value; - break; - - case RTLOP_SRL: - result = (uint32_t)src1->value >> src2->value; - break; - - case RTLOP_SRA: - result = (int32_t)src1->value >> src2->value; - break; - - case RTLOP_ROR: - if ((src2->value & 31) != 0) { - result = (uint32_t)src1->value >> (src2->value & 31) - | (uint32_t)src1->value << (32 - (src2->value & 31)); - } else { - result = (uint32_t)src1->value; - } - break; - - case RTLOP_CLZ: { -#ifdef __GNUC__ - result = __builtin_clz(src1->value); -#else - uint32_t temp = src1->value; - result = 32; - while (temp) { - temp >>= 1; - result--; - } -#endif // __GNUC__ - break; - } - - case RTLOP_CLO: { - uint32_t temp = src1->value; - result = 0; - while ((int32_t)temp < 0) { - temp <<= 1; - result++; - } - break; - } - - case RTLOP_SLTU: - result = ((uint32_t)src1->value < (uint32_t)src2->value) ? 1 : 0; - break; - - case RTLOP_SLTS: - result = ((int32_t)src1->value < (int32_t)src2->value) ? 1 : 0; - break; - - case RTLOP_BSWAPH: - result = ((uint32_t)src1->value & 0xFF00FF00) >> 8 - | ((uint32_t)src1->value & 0x00FF00FF) << 8; - break; - - case RTLOP_BSWAPW: - result = ((uint32_t)src1->value & 0xFF000000) >> 24 - | ((uint32_t)src1->value & 0x00FF0000) >> 8 - | ((uint32_t)src1->value & 0x0000FF00) << 8 - | ((uint32_t)src1->value & 0x000000FF) << 24; - break; - - case RTLOP_HSWAPW: - result = ((uint32_t)src1->value & 0xFFFF0000) >> 16 - | ((uint32_t)src1->value & 0x0000FFFF) << 16; - break; - - case RTLOP_ADDI: - result = src1->value + reg->result.imm; - break; - - case RTLOP_ANDI: - result = src1->value & reg->result.imm; - break; - - case RTLOP_ORI: - result = src1->value | reg->result.imm; - break; - - case RTLOP_XORI: - result = src1->value ^ reg->result.imm; - break; - - case RTLOP_SLLI: - result = src1->value << reg->result.imm; - break; - - case RTLOP_SRLI: - result = (uint32_t)src1->value >> reg->result.imm; - break; - - case RTLOP_SRAI: - result = (int32_t)src1->value >> reg->result.imm; - break; - - case RTLOP_RORI: - if ((reg->result.imm & 31) != 0) { - result = (uint32_t)src1->value >> (reg->result.imm & 31) - | (uint32_t)src1->value << (32 - (reg->result.imm & 31)); - } else { - result = (uint32_t)src1->value; - } - break; - - case RTLOP_SLTUI: - result = ((uint32_t)src1->value < (uint32_t)reg->result.imm) ? 1 : 0; - break; - - case RTLOP_SLTSI: - result = ((int32_t)src1->value < (int32_t)reg->result.imm) ? 1 : 0; - break; - - case RTLOP_BFEXT: - result = ((uint32_t)src1->value >> reg->result.start) - & ((1 << reg->result.count) - 1); - return 1; - - case RTLOP_BFINS: - result = ((uint32_t)src1->value - & ~(((1 << reg->result.count) - 1) << reg->result.start)) - | (((uint32_t)src2->value & ((1 << reg->result.count) - 1)) - << reg->result.start); - return 1; - - /* The remainder will never appear, but list them individually - * rather than using a default case so the compiler will warn us if - * we add a new opcode but don't include it here */ - case RTLOP_NOP: - case RTLOP_MADDU: - case RTLOP_MADDS: - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - case RTLOP_LOAD_PARAM: - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - case RTLOP_CALL: - case RTLOP_RETURN: - case RTLOP_RETURN_TO: - DMSG("impossible: opcode %u on RESULT register %u", - reg->result.opcode, (unsigned int)(reg - block->regs)); - return 0; - - } // switch (insn->opcode) - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Folded r%u to constant value 0x%lX at insn %u\n", - (unsigned int)(reg - block->regs), (unsigned long)result, - reg->birth); -#endif - - /* Update the instruction that set this register (use LOAD_ADDR in case - * the original value was an address) */ - - block->insns[reg->birth].opcode = RTLOP_LOAD_ADDR; - block->insns[reg->birth].src_addr = result; - - /* See whether the source register(s) are used anywhere else, and - * eliminate them if not */ - - if (src1->death == reg->birth) { - maybe_eliminate_folded_register(block, src1, reg->result.src1); - } - if ((!reg->result.is_imm && reg->result.src2 != 0) - && src2->death == reg->birth - ) { - maybe_eliminate_folded_register(block, src2, reg->result.src2); - } - - /* Constant folding was successful */ - - reg->source = RTLREG_CONSTANT; - reg->value = result; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * maybe_eliminate_folded_register: See whether the given register is no - * longer used after being eliminated from the instruction indexed by - * reg->death. If so, eliminate the register and change the instruction - * indexed by reg->birth to a NOP; otherwise, update reg->death to point to - * the last instruction that still uses the register. - * - * It is assumed that the register is only assigned once, at the - * instruction indexed by reg->birth. - * - * [Parameters] - * block: RTL block - * reg: Register to attempt to eliminate - * reg_index: Index of register in block->regs[] - * [Return value] - * None - */ -static void maybe_eliminate_folded_register(RTLBlock * const block, - RTLRegister * const reg, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return); - PRECOND(reg != NULL, return); - PRECOND(reg->live, return); - - uint32_t insn_index; - for (insn_index = reg->death-1; insn_index > reg->birth; insn_index--) { - const RTLInsn * const insn = &block->insns[insn_index]; - switch (insn->opcode) { - - case RTLOP_NOP: - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - case RTLOP_LOAD_PARAM: - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_RETURN: - break; - - case RTLOP_MOVE: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - case RTLOP_BFEXT: - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - if (insn->src1 == reg_index) { - still_used: -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] maybe_eliminate_folded_register: r%u" - " still used at insn %u\n", reg_index, insn_index); -#endif - reg->death = insn_index; - return; - } - break; - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - case RTLOP_BFINS: - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - if (insn->src1 == reg_index || insn->src2 == reg_index) { - goto still_used; - } - break; - - case RTLOP_MADDU: - case RTLOP_MADDS: - if (insn->src1 == reg_index || insn->src2 == reg_index - || insn->dest == reg_index || insn->dest2 == reg_index - ) { - goto still_used; - } - break; - - case RTLOP_SELECT: - if (insn->src1 == reg_index || insn->src2 == reg_index - || insn->cond == reg_index - ) { - goto still_used; - } - break; - - case RTLOP_CALL: - if (insn->src1 == reg_index || insn->src2 == reg_index - || insn->target == reg_index - ) { - goto still_used; - } - break; - - case RTLOP_RETURN_TO: - if (insn->target == reg_index) { - goto still_used; - } - break; - - } // switch (opcode) - } // for (insn_index) - - /* If we got this far, nothing else uses the register, so nuke it */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] maybe_eliminate_folded_register: r%u no longer" - " used, eliminating\n", reg_index); -#endif - block->insns[reg->birth].opcode = RTLOP_NOP; - block->insns[reg->birth].src_imm = 0; - reg->live = 0; -} - -/*************************************************************************/ - -/** - * drop_dead_unit: Drop a dead basic unit from an RTL block. Recursive - * helper function for rtlopt_drop_dead_units(). - * - * [Parameters] - * block: RTL block - * unit_index: Index of unit in block->units[] - * [Return value] - * None - */ -static void drop_dead_unit(RTLBlock * const block, - const unsigned int unit_index) -{ - PRECOND(block != NULL, return); - PRECOND(block->units != NULL, return); - PRECOND(block->unit_seen != NULL, return); - PRECOND(unit_index < block->num_units, return); - PRECOND(block->units[unit_index].entries[0] < 0, return); - PRECOND(block->units[unit_index].prev_unit >= 0, return); - - RTLUnit * const unit = &block->units[unit_index]; -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p: Dropping dead unit %u", block, unit_index); - if (unit->exits[0] < 0) { - fprintf(stderr, " (no exits)\n"); - } else if (unit->exits[1] < 0) { - fprintf(stderr, " (exits: %d)\n", unit->exits[0]); - } else { - fprintf(stderr, " (exits: %d, %d)\n", unit->exits[0], unit->exits[1]); - } -#endif - - block->units[unit->prev_unit].next_unit = unit->next_unit; - if (unit->next_unit >= 0) { - block->units[unit->next_unit].prev_unit = unit->prev_unit; - } - if (unit->prev_call_unit >= 0) { - block->units[unit->prev_call_unit].next_call_unit = - unit->next_call_unit; - } - if (unit->next_call_unit >= 0) { - block->units[unit->next_call_unit].prev_call_unit = - unit->prev_call_unit; - } - - while (unit->exits[0] >= 0) { - const unsigned int to_index = unit->exits[0]; - rtlunit_remove_edge(block, unit_index, 0); - if (block->unit_seen[to_index]) { - /* We already saw this unit and (presumably) skipped it because - * it wasn't dead. Check again now that we've removed this - * edge, and if it's now dead, recursively drop it. There's no - * danger of infinite recursion since any dead block has no - * edges entering into it by definition. */ - if (block->units[to_index].entries[0] < 0) { - drop_dead_unit(block, to_index); - } - } - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtlunit.c b/yabause/src/psp/rtlunit.c deleted file mode 100644 index 2eae2fc7be..0000000000 --- a/yabause/src/psp/rtlunit.c +++ /dev/null @@ -1,287 +0,0 @@ -/* src/psp/rtlunit.c: Basic unit processing for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This source file contains the logic used to divide a stream of RTL - * instructions into basic units (so-called "basic blocks"--we use the - * term "block" to refer to a sequence of source instructions translated - * into RTL as a group, so the term "units" is used here to differentiate). - * Each basic unit has exactly one entry point and one exit point, though - * there may be multiple paths into or out of the unit. As such, the unit - * can be optimized and translated to native code without the necessity of - * tracking every possible path for reaching each instruction. - */ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * rtlunit_add: Add a new, empty basic unit to the given block - * at the end of the block->units[] array. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on failure - */ -int rtlunit_add(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - - if (UNLIKELY(block->num_units >= block->units_size)) { - unsigned int new_units_size = block->num_units + UNITS_EXPAND_SIZE; - RTLUnit *new_units = realloc(block->units, - sizeof(*block->units) * new_units_size); - if (UNLIKELY(!new_units)) { - DMSG("No memory to expand block %p to %d units", block, - new_units_size); - return 0; - } - block->units = new_units; - block->units_size = new_units_size; - } - - const unsigned int index = block->num_units++; - if (index > 0) { - block->units[index-1].next_unit = index; - } - block->units[index].first_insn = 0; - block->units[index].last_insn = -1; - block->units[index].next_unit = -1; - block->units[index].prev_unit = index-1; - unsigned int i; - for (i = 0; i < lenof(block->units[index].entries); i++) { - block->units[index].entries[i] = -1; - } - for (i = 0; i < lenof(block->units[index].exits); i++) { - block->units[index].exits[i] = -1; - } - block->units[index].next_call_unit = -1; - block->units[index].prev_call_unit = -1; - - return 1; -} - -/*************************************************************************/ - -/** - * rtlunit_add_edge: Add a new edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * to_index: Index of postdominating basic unit (in block->units[]) - * [Return value] - * Nonzero on success, zero on failure - */ -int rtlunit_add_edge(RTLBlock *block, unsigned int from_index, - unsigned int to_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(from_index < block->num_units, return 0); - PRECOND(to_index < block->num_units, return 0); - - unsigned int i; - - /* Find an empty exit slot; also check whether this edge already exists, - * and return successfully (without adding a duplicate edge) if so. - * A unit can never have more than two exits, so bail if we try to add - * a third. */ - for (i = 0; i < lenof(block->units[from_index].exits); i++) { - if (block->units[from_index].exits[i] < 0) { - break; - } else if (block->units[from_index].exits[i] == to_index) { - return 1; - } - } - if (UNLIKELY(i >= lenof(block->units[from_index].exits))) { - DMSG("%p: Too many exits from unit %u", block, from_index); - } - block->units[from_index].exits[i] = to_index; - - /* If we overflow the entry list, add a dummy unit to take some of the - * entries out */ - for (i = 0; i < lenof(block->units[to_index].entries); i++) { - if (block->units[to_index].entries[i] < 0) { - break; - } - } - if (UNLIKELY(i >= lenof(block->units[to_index].entries))) { - /* No room in the entry list, so we need to create a dummy unit */ - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p: Failed to add dummy unit", block); - return 0; - } - const unsigned int dummy_unit = block->num_units - 1; - /* Move all the current edges over to the dummy unit */ - for (i = 0; i < lenof(block->units[to_index].entries); i++) { - const unsigned int other_unit = block->units[to_index].entries[i]; - unsigned int j; - for (j = 0; j < lenof(block->units[other_unit].exits); j++) { - if (block->units[other_unit].exits[j] == to_index) { - break; - } - } - if (UNLIKELY(j >= lenof(block->units[other_unit].exits))) { - DMSG("%p: Internal compiler error: edge to unit %u missing" - " from unit %u", block, to_index, other_unit); - return 0; - } - block->units[other_unit].exits[j] = dummy_unit; - block->units[dummy_unit].entries[i] = other_unit; - } - /* Link to the original unit */ - block->units[dummy_unit].exits[0] = to_index; - block->units[dummy_unit].exits[1] = -1; - block->units[to_index].entries[0] = dummy_unit; - /* The new entry will go into the second slot; clear out all - * other edges */ - for (i = lenof(block->units[to_index].entries) - 1; i > 1; i--) { - block->units[to_index].entries[i] = -1; - } - } - block->units[to_index].entries[i] = from_index; - - return 1; -} - -/*************************************************************************/ - -/** - * rtlunit_remove_edge: Remove an edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * exit_index: Index of exit edge to remove (in units[from_index].exits[]) - * [Return value] - * None - */ -void rtlunit_remove_edge(RTLBlock *block, const unsigned int from_index, - unsigned int exit_index) -{ - PRECOND(block != NULL, return); - PRECOND(block->units != NULL, return); - PRECOND(from_index < block->num_units, return); - PRECOND(exit_index < lenof(block->units[from_index].exits), return); - PRECOND(block->units[from_index].exits[exit_index] >= 0, return); - - RTLUnit * const from_unit = &block->units[from_index]; - const unsigned int to_index = from_unit->exits[exit_index]; - RTLUnit * const to_unit = &block->units[to_index]; - unsigned int entry_index; - - for (; exit_index < lenof(from_unit->exits) - 1; exit_index++) { - from_unit->exits[exit_index] = from_unit->exits[exit_index + 1]; - } - from_unit->exits[lenof(from_unit->exits) - 1] = -1; - - for (entry_index = 0; entry_index < lenof(to_unit->entries); - entry_index++ - ) { - if (to_unit->entries[entry_index] == from_index) { - break; - } - } - if (UNLIKELY(entry_index >= lenof(to_unit->entries))) { - DMSG("BUG: edge %u->%u missing from %u.entries!", - from_index, to_index, to_index); - return; - } - - for (; entry_index < lenof(to_unit->entries) - 1; entry_index++) { - to_unit->entries[entry_index] = to_unit->entries[entry_index + 1]; - } - to_unit->entries[lenof(to_unit->entries) - 1] = -1; -} - -/*************************************************************************/ - -/** - * rtlunit_dump_all: Dump a list of all basic units in the block to - * stderr. Intended for debugging. - * - * [Parameters] - * block: RTL block - * tag: Tag to prepend to all lines, or NULL for none - * [Return value] - * None - */ -void rtlunit_dump_all(const RTLBlock * const block, const char * const tag) -{ - PRECOND(block != NULL, return); - PRECOND(block->units != NULL, return); - - unsigned int i; - for (i = 0; i < block->num_units; i++) { - const RTLUnit * const unit = &block->units[i]; - fprintf(stderr, "[RTL] %s%s%sUnit %4u: ", - tag ? "[" : "", tag ? tag : "", tag ? "] " : "", i); - if (unit->entries[0] < 0) { - fprintf(stderr, ""); - } else { - unsigned int j; - for (j = 0; j < lenof(unit->entries) && unit->entries[j]>=0; j++) { - fprintf(stderr, "%s%u", j==0 ? "" : ",", unit->entries[j]); - } - } - if (unit->first_insn <= unit->last_insn) { - fprintf(stderr, " --> [%d,%d] --> ", - unit->first_insn, unit->last_insn); - } else { - fprintf(stderr, " --> [empty] --> "); - } - if (unit->exits[0] < 0) { - fprintf(stderr, ""); - } else { - unsigned int j; - for (j = 0; j < lenof(unit->exits) && unit->exits[j] >= 0; j++) { - fprintf(stderr, "%s%u", j==0 ? "" : ",", unit->exits[j]); - } - } - fprintf(stderr, "\n"); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/satopt-sh2.c b/yabause/src/psp/satopt-sh2.c deleted file mode 100644 index 5d123adb20..0000000000 --- a/yabause/src/psp/satopt-sh2.c +++ /dev/null @@ -1,4019 +0,0 @@ -/* src/psp/satopt-sh2.c: Saturn-specific SH-2 optimization routines - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "../core.h" -#include "../cs2.h" -#include "../memory.h" -#include "../scsp.h" -#include "../scu.h" -#include "../sh2core.h" -#include "../vdp1.h" -#include "../vdp2.h" -#include "../yabause.h" - -#include "sh2.h" -#include "sh2-internal.h" - -#include "misc.h" -#include "satopt-sh2.h" - -#ifdef JIT_DEBUG_TRACE -# include "../sh2d.h" -#endif - -/*************************************************************************/ - -/* Shorthand macros for memory access, both saving us from having to write - * out 0xFFFFF all over the place and allowing optimized memory access - * using constant offsets where possible (we assume small constant offsets - * don't fall outside the relevant memory region). Note that offsetted - * byte accesses to 16-bit-organized memory generally will not be optimized - * on little-endian systems, because the XOR has to be applied after adding - * the offset to the base; if the base is known to be 16-bit aligned, it - * may be faster to load a 16-bit word and mask or shift as appropriate. */ - -#define HRAM_PTR(base) ((uint8_t *)&HighWram[(base) & 0xFFFFF]) -#define HRAM_LOADB(base,offset) \ - T2ReadByte(HighWram, ((base) + (offset)) & 0xFFFFF) -#define HRAM_LOADW(base,offset) \ - T2ReadWord(HighWram, ((base) & 0xFFFFF) + (offset)) -#define HRAM_LOADL(base,offset) \ - T2ReadLong(HighWram, ((base) & 0xFFFFF) + (offset)) -#define HRAM_STOREB(base,offset,data) \ - T2WriteByte(HighWram, ((base) + (offset)) & 0xFFFFF, (data)) -#define HRAM_STOREW(base,offset,data) \ - T2WriteWord(HighWram, ((base) & 0xFFFFF) + (offset), (data)) -#define HRAM_STOREL(base,offset,data) \ - T2WriteLong(HighWram, ((base) & 0xFFFFF) + (offset), (data)) - -#define LRAM_PTR(base) ((uint8_t *)&LowWram[(base) & 0xFFFFF]) -#define LRAM_LOADB(base,offset) \ - T2ReadByte(LowWram, ((base) + (offset)) & 0xFFFFF) -#define LRAM_LOADW(base,offset) \ - T2ReadWord(LowWram, ((base) & 0xFFFFF) + (offset)) -#define LRAM_LOADL(base,offset) \ - T2ReadLong(LowWram, ((base) & 0xFFFFF) + (offset)) -#define LRAM_STOREB(base,offset,data) \ - T2WriteByte(LowWram, ((base) + (offset)) & 0xFFFFF, (data)) -#define LRAM_STOREW(base,offset,data) \ - T2WriteWord(LowWram, ((base) & 0xFFFFF) + (offset), (data)) -#define LRAM_STOREL(base,offset,data) \ - T2WriteLong(LowWram, ((base) & 0xFFFFF) + (offset), (data)) - -#define VDP1_PTR(base) ((uint8_t *)&Vdp1Ram[(base) & 0x7FFFF]) -#define VDP1_LOADB(base,offset) \ - T1ReadByte(Vdp1Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP1_LOADW(base,offset) \ - T1ReadWord(Vdp1Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP1_LOADL(base,offset) \ - T1ReadLong(Vdp1Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP1_STOREB(base,offset,data) \ - T1WriteByte(Vdp1Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP1_STOREW(base,offset,data) \ - T1WriteWord(Vdp1Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP1_STOREL(base,offset,data) \ - T1WriteLong(Vdp1Ram, ((base) & 0x7FFFF) + (offset), (data)) - -#define VDP2_PTR(base) ((uint8_t *)&Vdp2Ram[(base) & 0x7FFFF]) -#define VDP2_LOADB(base,offset) \ - T1ReadByte(Vdp2Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP2_LOADW(base,offset) \ - T1ReadWord(Vdp2Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP2_LOADL(base,offset) \ - T1ReadLong(Vdp2Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP2_STOREB(base,offset,data) \ - T1WriteByte(Vdp2Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP2_STOREW(base,offset,data) \ - T1WriteWord(Vdp2Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP2_STOREL(base,offset,data) \ - T1WriteLong(Vdp2Ram, ((base) & 0x7FFFF) + (offset), (data)) - -/* Use these macros instead of [BW]SWAP{16,32} when loading from or - * storing to work RAM or VDP memory, to avoid breaking things on - * big-endian systems. RAM_VDP_SWAPL is for copying longwords directly - * between work RAM and VDP memory, and is one operation faster on - * little-endian machines than VDP_SWAPL(RAM_SWAPL(x)). */ - -#ifdef WORDS_BIGENDIAN -# define RAM_SWAPL(x) (x) -# define VDP_SWAPW(x) (x) -# define VDP_SWAPL(x) (x) -# define RAM_VDP_SWAPL(x) (x) -#else -# define RAM_SWAPL(x) WSWAP32(x) -# define VDP_SWAPW(x) BSWAP16(x) -# define VDP_SWAPL(x) BSWAP32(x) -# define RAM_VDP_SWAPL(x) BSWAP16(x) // BSWAP32(WSWAP32(x)) == BSWAP16(x) -#endif - -/*************************************************************************/ -/********************** Optimization routine table ***********************/ -/*************************************************************************/ - -#ifdef ENABLE_JIT // Through end of file - -/*************************************************************************/ - -/* List of detection and translation routines for special-case blocks */ - -#ifdef PSP -# define ALIGN_OPTIMIZER __attribute__((aligned(64))) -#else -# define ALIGN_OPTIMIZER /*nothing*/ -#endif - -#define DECLARE_OPTIMIZER(name) \ - ALIGN_OPTIMIZER static FASTCALL void name(SH2State *state) - -#define DECLARE_OPTIMIZER_WITH_DETECT(name) \ - static int name##_detect(SH2State *state, uint32_t address, \ - const uint16_t *fetch); \ - DECLARE_OPTIMIZER(name) - -/*----------------------------------*/ - -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_000025AC); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_00002EFA); -DECLARE_OPTIMIZER (BIOS_00003BC6); -DECLARE_OPTIMIZER (BIOS_06001670); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_06010D22); -DECLARE_OPTIMIZER (BIOS_060115A4); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_060115B6); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_060115D4); -DECLARE_OPTIMIZER (BIOS_0602E364); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_0602E630); - -/*----------------------------------*/ - -DECLARE_OPTIMIZER_WITH_DETECT(Azel_0600614C); -DECLARE_OPTIMIZER (Azel_060061F0); -DECLARE_OPTIMIZER (Azel_0600C4DC); -DECLARE_OPTIMIZER (Azel_0600C59C); -DECLARE_OPTIMIZER_WITH_DETECT(Azel_0600C5B4); -DECLARE_OPTIMIZER (Azel_0600C5F8); -DECLARE_OPTIMIZER (Azel_0600C690); -DECLARE_OPTIMIZER_WITH_DETECT(Azel_06010F24); -DECLARE_OPTIMIZER (Azel_06014274); -DECLARE_OPTIMIZER (Azel_0601E330); -DECLARE_OPTIMIZER (Azel_0601E910); -DECLARE_OPTIMIZER (Azel_0601E95A); -DECLARE_OPTIMIZER (Azel_0601EC20); -DECLARE_OPTIMIZER (Azel_0601EC3C); -DECLARE_OPTIMIZER (Azel_0601EE60); -DECLARE_OPTIMIZER (Azel_0601EEE8); -DECLARE_OPTIMIZER (Azel_0601F240); -DECLARE_OPTIMIZER (Azel_0601F24C); -DECLARE_OPTIMIZER (Azel_0601F2D6); -DECLARE_OPTIMIZER (Azel_0601F2F2); -DECLARE_OPTIMIZER (Azel_0601F30E); -DECLARE_OPTIMIZER (Azel_0601F3F4); -DECLARE_OPTIMIZER (Azel_0601FB70); -DECLARE_OPTIMIZER (Azel_06022E18); -DECLARE_OPTIMIZER (Azel_06035530); -DECLARE_OPTIMIZER (Azel_06035552); -DECLARE_OPTIMIZER (Azel_0603556C); -DECLARE_OPTIMIZER (Azel_06035A8C); -DECLARE_OPTIMIZER (Azel_06035A9C); -DECLARE_OPTIMIZER (Azel_06035AA0); -DECLARE_OPTIMIZER (Azel_06035B14); -DECLARE_OPTIMIZER (Azel_06035C18); -DECLARE_OPTIMIZER (Azel_06035C3C); -DECLARE_OPTIMIZER (Azel_06035C60); -DECLARE_OPTIMIZER (Azel_06035C84); -DECLARE_OPTIMIZER (Azel_06035C90); -DECLARE_OPTIMIZER (Azel_06035C96); -DECLARE_OPTIMIZER (Azel_06035D24); -DECLARE_OPTIMIZER (Azel_06035D30); -DECLARE_OPTIMIZER (Azel_06035D36); -DECLARE_OPTIMIZER (Azel_06035DD4); -DECLARE_OPTIMIZER (Azel_06035DE0); -DECLARE_OPTIMIZER (Azel_06035DE6); -DECLARE_OPTIMIZER (Azel_06035E70); -DECLARE_OPTIMIZER (Azel_06035EA0); -DECLARE_OPTIMIZER (Azel_06035ED0); -DECLARE_OPTIMIZER (Azel_06035F00); -DECLARE_OPTIMIZER (Azel_06035F04); -DECLARE_OPTIMIZER (Azel_060360F0); -DECLARE_OPTIMIZER_WITH_DETECT(Azel_0603A22C); -DECLARE_OPTIMIZER (Azel_0603A242); -DECLARE_OPTIMIZER (Azel_0603ABE0); -DECLARE_OPTIMIZER (Azel_0603DD6E); - -/*----------------------------------*/ - -static const struct { - - /* Start address applicable to this translation. */ - uint32_t address; - - /* Routine that implements the SH-2 code. If NULL, no optimized - * translation is generated; instead, the hints specified in the - * .hint_* fields are applied to the current block. */ - FASTCALL void (*execute)(SH2State *state); - - /* Routine to detect whether to use this translation; returns the - * number of 16-bit words processed (nonzero) to use it, else zero. - * If NULL, the checksum is checked instead. */ - int (*detect)(SH2State *state, uint32_t address, const uint16_t *fetch); - - /* Checksum and block length (in instructions) if detect == NULL. */ - uint32_t sum; - unsigned int length; - - /* Nonzero if this function is foldable (i.e. does not modify any - * registers other than R0-R7, MACH/MACL, and PC). If not set, the - * function is never folded even if it is detected to be a candidate - * for folding. */ - uint8_t foldable; - - /* Bitmask indicating which general purpose registers should be hinted - * as having a constant value at block start. */ - uint16_t hint_constant_reg; - - /* Bitmask indicating which general purpose registers should be hinted - * as containing a data pointer at block start. */ - uint16_t hint_data_pointer_reg; - - /* Bitmask indicating which of the first 32 instructions in the block - * should be hinted as loading a data pointer. */ - uint32_t hint_data_pointer_load; - -} hand_tuned_table[] = { - - /******** BIOS startup animation ********/ - - {0x00001CFC, BIOS_000025AC, BIOS_000025AC_detect}, // 1.00 JP - {0x000025AC, BIOS_000025AC, BIOS_000025AC_detect}, // 1.01 JP / UE - {0x00002658, BIOS_00002EFA, BIOS_00002EFA_detect}, // 1.00 JP - {0x00002EFA, BIOS_00002EFA, BIOS_00002EFA_detect}, // 1.01 JP / UE - {0x00002D44, BIOS_00003BC6, .sum = 0x1A6ECE, .length = 70}, // 1.00 JP - {0x00003BC6, BIOS_00003BC6, .sum = 0x1A40C9, .length = 71}, // 1.01 JP / UE - {0x06001664, BIOS_06001670, .sum = 0x04A2D6, .length = 13}, // 1.00 JP - {0x06001670, BIOS_06001670, .sum = 0x04A2D6, .length = 13}, // 1.01 JP - {0x06001674, BIOS_06001670, .sum = 0x04A2D6, .length = 13}, // UE - {0x06010D22, BIOS_06010D22, BIOS_06010D22_detect}, // JP - {0x06010D36, BIOS_06010D22, BIOS_06010D22_detect}, // UE - {0x060115C0, BIOS_060115A4, .sum = 0x032D22, .length = 9}, // 1.00 JP - {0x060115A4, BIOS_060115A4, .sum = 0x032D22, .length = 9}, // 1.01 JP - {0x06011654, BIOS_060115A4, .sum = 0x032D22, .length = 9}, // UE - {0x060115D2, BIOS_060115B6, BIOS_060115B6_detect}, // 1.00 JP - {0x060115B6, BIOS_060115B6, BIOS_060115B6_detect}, // 1.01 JP - {0x06011666, BIOS_060115B6, BIOS_060115B6_detect}, // UE - {0x060115F0, BIOS_060115D4, BIOS_060115D4_detect}, // 1.00 JP - {0x060115D4, BIOS_060115D4, BIOS_060115D4_detect}, // 1.01 JP - {0x06011684, BIOS_060115D4, BIOS_060115D4_detect}, // UE - {0x0602DA80, NULL, .sum = 0x0A6FD6, .length = 31, // JP - .hint_data_pointer_load = 1<<20}, - {0x06039A80, NULL, .sum = 0x0A6FD6, .length = 31, // UE - .hint_data_pointer_load = 1<<20}, - {0x0602DABE, NULL, .sum = 0x016AF5, .length = 3, // JP - .hint_data_pointer_reg = 1<<12}, - {0x06039ABE, NULL, .sum = 0x016AF5, .length = 3, // UE - .hint_data_pointer_reg = 1<<12}, - {0x0602DAC4, NULL, .sum = 0x016AF5, .length = 3, // JP - .hint_data_pointer_reg = 1<<12}, - {0x06039AC4, NULL, .sum = 0x016AF5, .length = 3, // UE - .hint_data_pointer_reg = 1<<12}, - {0x0602DACA, NULL, .sum = 0x016AF6, .length = 3, // JP - .hint_data_pointer_reg = 1<<12}, - {0x06039ACA, NULL, .sum = 0x016AF6, .length = 3, // UE - .hint_data_pointer_reg = 1<<12}, - {0x0602DF10, NULL, .sum = 0x04634B, .length = 13, // 1.00 JP - .hint_data_pointer_load = 1<<2}, - {0x0602DF30, NULL, .sum = 0x04634B, .length = 13, // 1.01 JP - .hint_data_pointer_load = 1<<2}, - {0x06039F30, NULL, .sum = 0x04634B, .length = 13, // UE - .hint_data_pointer_load = 1<<2}, - {0x0602E364, BIOS_0602E364, .sum = 0x074A3C, .length = 20, // JP - .foldable = 1}, - {0x0603A364, BIOS_0602E364, .sum = 0x074A3C, .length = 20, // UE - .foldable = 1}, - {0x0602E3B0, NULL, .sum = 0x02AAF2, .length = 7, // JP - .hint_data_pointer_load = 1<<6}, - {0x0603A3B0, NULL, .sum = 0x02AAF2, .length = 7, // UE - .hint_data_pointer_load = 1<<6}, - {0x0602E410, NULL, .sum = 0x0298A3, .length = 5, // JP - .hint_data_pointer_load = 1<<4}, - {0x0603A410, NULL, .sum = 0x0298A3, .length = 5, // UE - .hint_data_pointer_load = 1<<4}, - {0x0602E4B8, NULL, .sum = 0x02984F, .length = 5, // JP - .hint_data_pointer_load = 1<<4}, - {0x0603A4B8, NULL, .sum = 0x02984F, .length = 5, // UE - .hint_data_pointer_load = 1<<4}, - {0x0602E560, NULL, .sum = 0x0297FB, .length = 5, // JP - .hint_data_pointer_load = 1<<4}, - {0x0603A560, NULL, .sum = 0x0297FB, .length = 5, // UE - .hint_data_pointer_load = 1<<4}, - {0x0602E38C, NULL, .sum = 0x04E94B, .length = 18, // JP - .hint_data_pointer_load = 1<<0 | 1<<7}, - {0x0603A38C, NULL, .sum = 0x07294B, .length = 18, // UE - .hint_data_pointer_load = 1<<0 | 1<<7}, - {0x0602E630, BIOS_0602E630, BIOS_0602E630_detect}, // JP - {0x0603A630, BIOS_0602E630, BIOS_0602E630_detect}, // UE - - /******** Azel: Panzer Dragoon RPG (JP) ********/ - - {0x0600614C, Azel_0600614C, Azel_0600614C_detect}, - {0x060061F0, Azel_060061F0, .sum = 0x2FB438, .length = 167, .foldable = 1}, - {0x0600C4DC, Azel_0600C4DC, .sum = 0x155D7C, .length = 64, .foldable = 1}, - {0x0600C59C, Azel_0600C59C, .sum = 0x0C1C5C, .length = 30}, - {0x0600C5B4, Azel_0600C5B4, Azel_0600C5B4_detect}, - {0x0600C5F8, Azel_0600C5F8, .sum = 0x085791, .length = 22, .foldable = 1}, - {0x0600C690, Azel_0600C690, .sum = 0x05E193, .length = 15, .foldable = 1}, - {0x06010F24, Azel_06010F24, Azel_06010F24_detect}, - {0x06010F52, Azel_06010F24, Azel_06010F24_detect}, - {0x06014274, Azel_06014274, .sum = 0x23F1EA, .length = 140, .foldable = 1}, - {0x0601E330, Azel_0601E330, .sum = 0x1F9402, .length = 68}, - {0x0601E910, Azel_0601E910, .sum = 0x0EDD5D, .length = 37}, - {0x0601E95A, Azel_0601E95A, .sum = 0x0EDD2D, .length = 37}, - {0x0601EC20, Azel_0601EC20, .sum = 0x05F967, .length = 14}, - {0x0601EC3C, Azel_0601EC3C, .sum = 0x05F97D, .length = 14}, - {0x0601EE60, Azel_0601EE60, .sum = 0x0958CD, .length = 39}, // MOV R0,R1 - {0x0601EE60, Azel_0601EE60, .sum = 0x0998AD, .length = 39}, // BRA 601F02C - {0x0601EEAE, NULL, .sum = 0x05CD03, .length = 17, - .hint_data_pointer_load = 1<<3}, - {0x0601EED6, NULL, .sum = 0x01C56B, .length = 7, - .hint_data_pointer_reg = 1<<0 | 1<<1}, - {0x0601EEE8, Azel_0601EEE8, .sum = 0x075BB7, .length = 20, .foldable = 1}, - {0x0601F120, NULL, .sum = 0x0988A3, .length = 24, - .hint_data_pointer_load = 1<<17}, - {0x0601F140, NULL, .sum = 0x02D776, .length = 8, - .hint_data_pointer_load = 1<<1}, - {0x0601F150, NULL, .sum = 0x034F6E, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601F15E, NULL, .sum = 0x034F70, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601F16C, NULL, .sum = 0x029E99, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601F190, NULL, .sum = 0x01C56B, .length = 7, - .hint_data_pointer_reg = 1<<0 | 1<<1}, - {0x0601F240, Azel_0601F240, .sum = 0x13322C, .length = 75}, - {0x0601F24C, Azel_0601F24C, .sum = 0x11E92D, .length = 69}, - {0x0601F2D6, Azel_0601F2D6, .sum = 0x05F6D3, .length = 14}, - {0x0601F2F2, Azel_0601F2F2, .sum = 0x05F6E9, .length = 14}, - {0x0601F30E, Azel_0601F30E, .sum = 0x250327, .length = 115}, - {0x0601F3F4, Azel_0601F3F4, .sum = 0x1A4DA5, .length = 84}, - {0x0601FB70, Azel_0601FB70, .sum = 0x095941, .length = 39}, // MOV R0,R1 - {0x0601FB70, Azel_0601FB70, .sum = 0x09995B, .length = 39}, // BRA 601FDB0 - {0x0601FBBE, NULL, .sum = 0x049C2B, .length = 14, - .hint_data_pointer_load = 1<<0}, - {0x0601FC3A, NULL, .sum = 0x060C32, .length = 18, - .hint_data_pointer_reg = 1<<4}, - {0x0601FC6C, Azel_0601EEE8, .sum = 0x075BB7, .length = 20, .foldable = 1}, - {0x0601FDB8, NULL, .sum = 0x091C0C, .length = 55, - .hint_data_pointer_reg = 1<<1}, - {0x0601FEA4, NULL, .sum = 0x084DF0, .length = 20, - .hint_data_pointer_load = 1<<17}, - {0x0601FEC4, NULL, .sum = 0x01822F, .length = 4, - .hint_data_pointer_load = 1<<1}, - {0x0601FECC, NULL, .sum = 0x034F73, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601FEDA, NULL, .sum = 0x034F75, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601FEE8, NULL, .sum = 0x029E9A, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x06021FA2, NULL, .sum = 0x2A12AF, .length = 136, - .hint_constant_reg = 1<<13}, - {0x06022E18, Azel_06022E18, .sum = 0x09ABCB, .length = 33, .foldable = 1}, - {0x06028EE8, NULL, .sum = 0x1F09D1, .length = 103, - .hint_constant_reg = 1<<10}, - {0x0602F834, NULL, .sum = 0x0676B0, .length = 16, - .hint_data_pointer_load = 1<<11}, - {0x06035530, Azel_06035530, .sum = 0x05ABFA, .length = 17, .foldable = 1}, - {0x06035552, Azel_06035552, .sum = 0x0358EB, .length = 13, .foldable = 1}, - {0x0603556C, Azel_0603556C, .sum = 0x0332E9, .length = 11, .foldable = 1}, - {0x06035A8C, Azel_06035A8C, .sum = 0x0A1ECF, .length = 36, .foldable = 1}, - {0x06035A9C, Azel_06035A9C, .sum = 0x065B51, .length = 28, .foldable = 1}, - {0x06035AA0, Azel_06035AA0, .sum = 0x052642, .length = 26, .foldable = 1}, - {0x06035B14, Azel_06035B14, .sum = 0x05CBE1, .length = 37, .foldable = 1}, - {0x06035C18, Azel_06035C18, .sum = 0x085E83, .length = 18, .foldable = 1}, - {0x06035C3C, Azel_06035C3C, .sum = 0x08595C, .length = 18, .foldable = 1}, - {0x06035C60, Azel_06035C60, .sum = 0x085DB6, .length = 18, .foldable = 1}, - {0x06035C84, Azel_06035C84, .sum = 0x0F24AE, .length = 80, .foldable = 1}, - {0x06035C90, Azel_06035C90, .sum = 0x0C95AD, .length = 74, .foldable = 1}, - {0x06035C96, Azel_06035C96, .sum = 0x0B1711, .length = 71, .foldable = 1}, - {0x06035D24, Azel_06035D24, .sum = 0x12CFBE, .length = 88, .foldable = 1}, - {0x06035D30, Azel_06035D30, .sum = 0x1040BD, .length = 82, .foldable = 1}, - {0x06035D36, Azel_06035D36, .sum = 0x0EC21D, .length = 79, .foldable = 1}, - {0x06035DD4, Azel_06035DD4, .sum = 0x0EAFA6, .length = 78, .foldable = 1}, - {0x06035DE0, Azel_06035DE0, .sum = 0x0C20A5, .length = 72, .foldable = 1}, - {0x06035DE6, Azel_06035DE6, .sum = 0x0AA20A, .length = 69, .foldable = 1}, - {0x06035E70, Azel_06035E70, .sum = 0x042E91, .length = 24, .foldable = 1}, - {0x06035EA0, Azel_06035EA0, .sum = 0x042E97, .length = 24, .foldable = 1}, - {0x06035ED0, Azel_06035ED0, .sum = 0x042E9D, .length = 24, .foldable = 1}, - {0x06035F00, Azel_06035F00, .sum = 0x04AC41, .length = 35, .foldable = 1}, - {0x06035F04, Azel_06035F04, .sum = 0x036FCE, .length = 33, .foldable = 1}, - {0x060360F0, Azel_060360F0, .sum = 0x00D021, .length = 4, .foldable = 1}, - {0x0603A22C, Azel_0603A22C, Azel_0603A22C_detect}, - {0x0603A242, Azel_0603A242, .sum = 0x11703E, .length = 49}, - {0x0603ABE0, Azel_0603ABE0, .sum = 0x0BABA4, .length = 35}, - {0x0603DD6E, Azel_0603DD6E, .sum = 0x0BB96E, .length = 31}, - {0x0605444C, NULL, .sum = 0x102906, .length = 56, - .hint_constant_reg = 1<<12}, - {0x06057450, NULL, .sum = 0x0D4F8B, .length = 37, - .hint_constant_reg = 1<<12}, - {0x06058910, NULL, .sum = 0x0F2F81, .length = 52, - .hint_constant_reg = 1<<12}, - {0x06059068, NULL, .sum = 0x42DE2F, .length = 196, - .hint_constant_reg = 1<<11}, - {0x0605906E, NULL, .sum = 0x40F2FD, .length = 193, - .hint_constant_reg = 1<<11}, - {0x060693AE, NULL, .sum = 0x452D32, .length = 237, - .hint_constant_reg = 1<<14}, - {0x0606B7E4, NULL, .sum = 0x5AFDCE, .length = 292, - .hint_constant_reg = 1<<10}, - {0x0606B898, NULL, .sum = 0x2FFF9D, .length = 155, - .hint_constant_reg = 1<<10 | 1<<12}, - {0x06080280, NULL, .sum = 0x22D6B8, .length = 134, - .hint_constant_reg = 1<<13}, - {0x0608DE80, NULL, .sum = 0x114129, .length = 53, - .hint_constant_reg = 1<<13}, - {0x060A03FE, NULL, .sum = 0x4D786E, .length = 246, - .hint_constant_reg = 1<<10 | 1<<14}, - -}; - -/*************************************************************************/ - -#endif // ENABLE_JIT - -/*************************************************************************/ -/************************** Interface function ***************************/ -/*************************************************************************/ - -/** - * saturn_optimize_sh2: Search for and return, if available, a native - * implementation of the SH-2 routine starting at the given address. - * If for_fold is nonzero, this function returns nonzero and NULL in - * *func_ret to indicate that the routine at the given address should not - * be folded. - * - * [Parameters] - * state: Processor state block pointer - * address: Address from which to translate - * fetch: Pointer corresponding to "address" from which opcodes can - * be fetched - * func_ret: Pointer to variable to receive address of native function - * implementing this routine if return value is nonzero - * for_fold: Nonzero if the callback is being called to look up a - * subroutine for folding, zero if being called for a - * full block translation - * [Return value] - * Length of translated block in instructions (nonzero) if a native - * function is returned, else zero - */ -unsigned int saturn_optimize_sh2(SH2State *state, uint32_t address, - const uint16_t *fetch, - SH2NativeFunctionPointer *func_ret, - int for_fold) -{ -#ifdef ENABLE_JIT - - unsigned int i; - for (i = 0; i < lenof(hand_tuned_table); i++) { - - if (hand_tuned_table[i].address != address) { - continue; - } - - unsigned int num_insns; - if (hand_tuned_table[i].detect) { - num_insns = hand_tuned_table[i].detect(state, address, fetch); - if (!num_insns) { - continue; - } - } else { - num_insns = hand_tuned_table[i].length; - const uint32_t sum = checksum_fast16(fetch, num_insns); - if (sum != hand_tuned_table[i].sum) { - continue; - } - } - - if (hand_tuned_table[i].execute == NULL) { - - if (for_fold) { - /* Tell the caller not to fold this function, because we - * want to apply our optimization hints (which we can't do - * while folding). */ - *func_ret = NULL; - return 1; - } - - uint32_t bitmask; - unsigned int bit; - - for (bitmask = hand_tuned_table[i].hint_constant_reg, bit = 0; - bitmask != 0; - bitmask &= ~(1< bf fetch[12] - && fetch[ 2] == 0xA008 // bra fetch[12] --> nop - && fetch[ 3] == 0x0009 // nop - && fetch[ 4] == 0x62D3 // mov r13, r2 - && fetch[ 5] == 0x32E7 // cmp/gt r14, r2 - && fetch[ 6] == 0x8F02 // bf/s fetch[10] --> bf/s fetch[-2] - && fetch[ 7] == 0x7D01 // add #1, r13 - && fetch[ 8] == 0xA008 // bra fetch[18] - && fetch[ 9] == 0xE000 // mov #0, r0 - && fetch[10] == 0xAFF2 // bra fetch[-2] - && fetch[11] == 0x0009 // nop - ? 12 : 0; -} - -static FASTCALL void BIOS_000025AC(SH2State *state) -{ - if (UNLIKELY(state->R[0])) { - state->SR &= ~SR_T; - state->PC += 2*12; - state->cycles += 5; - return; - } - - state->R[2] = state->R[13]; - state->SR &= ~SR_T; - state->SR |= (state->R[13] > state->R[14]) << SR_T_SHIFT; - if (UNLIKELY(state->R[13]++ > state->R[14])) { - state->R[0] = 0; - state->PC += 2*18; - state->cycles += 11; - return; - } - - if (LIKELY(state->R[13]+15 <= state->R[14])) { - state->R[13] += 15; - state->cycles += 15*76 + 15; - } else { - state->cycles += 15; - } - state->PR = state->PC; - state->PC = state->R[12]; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x2EFA: CD read loop */ - -static int BIOS_00002EFA_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[0] == 0x6503 // mov r0, r5 - && fetch[1] == 0x3CB3 // cmp/ge r11, r12 - && fetch[2] == 0x8D06 // bt/s fetch[10] - && fetch[3] == 0x64C3 // mov r12, r4 - // fetch[4] == 0x7401 // add #1, r4 -- these two are swapped - // fetch[5] == 0x6352 // mov.l @r5, r3 -- in some BIOS versions - && fetch[6] == 0x2E32 // mov.l r3, @r14 - && fetch[7] == 0x34B3 // cmp/ge r11, r4 - && fetch[8] == 0x8FFA // bf/s fetch[4] - && fetch[9] == 0x7E04 // add #4, r14 - ? 10 : 0; -} - -static FASTCALL void BIOS_00002EFA(SH2State *state) -{ - uint8_t *page_base; - - if (UNLIKELY(state->R[0] != 0x25818000) - || UNLIKELY(!(page_base = direct_pages[state->R[14]>>19])) - ) { - state->R[5] = state->R[0]; - state->PC += 2; - state->cycles += 1; - return; - } - - state->R[5] = state->R[0]; - state->SR |= SR_T; // Always ends up set from here down - - int32_t count = state->R[11]; - int32_t i = state->R[12]; - int32_t left = count - i; - if (UNLIKELY(left <= 0)) { - state->R[4] = i; - state->PC += 2*10; - state->cycles += 5; - return; - } - - uint8_t *ptr = page_base + state->R[14]; - state->R[4] = count; - state->R[14] += left*4; - state->PC += 2*10; - state->cycles += 7*left + (4-1); - - /* Call the copy routine last to avoid unnecessary register saves and - * restores. */ - Cs2RapidCopyT2(ptr, left); -} - -/*-----------------------------------------------------------------------*/ - -/* 0x3BC6: CD status read routine */ - -static FASTCALL void BIOS_00003BC6(SH2State *state) -{ - /* With the current CS2 implementation, this all amounts to a simple - * read of registers CR1-CR4, but let's not depend on that behavior. */ - - state->R[0] = -3; // Default return value (error) - - unsigned int try; - for (try = 0; try < 100; try++, state->cycles += 67) { - const unsigned int CR1 = Cs2ReadWord(0x90018); - const unsigned int CR2 = Cs2ReadWord(0x9001C); - const unsigned int CR3 = Cs2ReadWord(0x90020); - const unsigned int CR4 = Cs2ReadWord(0x90024); - HRAM_STOREW(state->R[4], 0, CR1); - HRAM_STOREW(state->R[4], 2, CR2); - HRAM_STOREW(state->R[4], 4, CR3); - HRAM_STOREW(state->R[4], 6, CR4); - - const unsigned int CR1_test = Cs2ReadWord(0x90018); - const unsigned int CR2_test = Cs2ReadWord(0x9001C); - const unsigned int CR3_test = Cs2ReadWord(0x90020); - const unsigned int CR4_test = Cs2ReadWord(0x90024); - if (CR1_test==CR1 && CR2_test==CR2 && CR3_test==CR3 && CR4_test==CR4) { - state->R[0] = 0; - state->cycles += 65; - break; - } - } - - state->PC = state->PR; - state->cycles += 15 + 12; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6001670: Sound RAM load loop (optimized to avoid slowdowns from ME - * cache issues, since it includes a read-back test) */ - -static FASTCALL void BIOS_06001670(SH2State *state) -{ - const uint32_t data = MappedMemoryReadLong(state->R[1]); - state->R[1] += 4; - MappedMemoryWriteLong(state->R[3], data); - state->R[3] += 4; - state->R[6]--; - if (state->R[6] != 0) { - state->cycles += 50; - } else { - state->PC = state->PR; - state->cycles += 52; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6010D22: 3-D intro animation idle loop */ - -static int BIOS_06010D22_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return (fetch[-2] & 0xF000) == 0xB000 // bsr 0x60101AC [only wastes time] - && fetch[-1] == 0xE41E // mov #30, r4 - && fetch[ 0] == 0xD011 // mov.l @(0x6010D68,pc), r0 - && fetch[ 1] == 0x6001 // mov.w @r0, r0 - && fetch[ 2] == 0x2008 // tst r0, r0 - && fetch[ 3] == 0x8BF9 // bf 0x6010D1E - ? 4 : 0; -} - -static FASTCALL void BIOS_06010D22(SH2State *state) -{ - const uint32_t address = HRAM_LOADL(state->PC & -4, 4 + 0x11*4); - state->R[0] = HRAM_LOADW(address, 0); - if (state->R[0]) { - state->SR &= ~SR_T; - state->cycles = state->cycle_limit; - } else { - state->SR |= SR_T; - state->PC += 8; - state->cycles += 4; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x60115A4, etc.: Routine with multiple JSRs and a looping recursive BSR - * (this helps cover the block switch overhead) */ - -static FASTCALL void BIOS_060115A4(SH2State *state) -{ - state->R[15] -= 12; - HRAM_STOREL(state->R[15], 8, state->R[14]); - HRAM_STOREL(state->R[15], 4, state->R[13]); - HRAM_STOREL(state->R[15], 0, state->PR); - state->R[14] = state->R[4]; - state->PR = state->PC + 9*2; - - state->PC = HRAM_LOADL((state->PC + 3*2) & -4, 4 + 0x24*4); - BIOS_0602E364(state); - - state->PC = HRAM_LOADL(state->R[14], 16); - state->cycles += 11; -} - -/*----------------------------------*/ - -static int BIOS_060115B6_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - const uint32_t jsr_address = HRAM_LOADL(state->PC & -4, 4 + 0x22*4); - return checksum_fast16(fetch, 5) == 0x3081A - && BIOS_0602E630_detect(state, jsr_address, - fetch + ((jsr_address - address) >> 1)) - ? 5 : 0; -} - -static FASTCALL void BIOS_060115B6(SH2State *state) -{ - state->R[4] = state->R[14]; - state->R[13] = 0; - state->PR = state->PC + 15*2; - state->PC = HRAM_LOADL(state->PC & -4, 4 + 0x22*4); - state->cycles += 7; - return BIOS_0602E630(state); -} - -/*----------------------------------*/ - -static int BIOS_060115D4_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return checksum_fast16(fetch-10, 21) == 0x8E03C ? 11 : 0; -} - -static FASTCALL void BIOS_060115D4(SH2State *state) -{ - const uint32_t R14_68_address = HRAM_LOADL(state->R[14], 68); - if (state->R[13] < HRAM_LOADL(R14_68_address, 0)) { - state->R[4] = HRAM_LOADL(R14_68_address, 4 + 4*state->R[13]); - state->R[13]++; - state->PC -= 24*2; // Recursive call to 0x60115A4 (PR is already set) - state->cycles += 19; - } else { - state->PR = HRAM_LOADL(state->R[15], 0); - state->R[13] = HRAM_LOADL(state->R[15], 4); - state->R[14] = HRAM_LOADL(state->R[15], 8); - state->R[15] += 12; - state->PC = HRAM_LOADL((state->PC + 8*2) & -4, 4 + 0x17*4); - state->cycles += 12; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x602E364: Short but difficult-to-optimize data initialization routine */ - -static FASTCALL void BIOS_0602E364(SH2State *state) -{ - const uint32_t r2 = HRAM_LOADL(state->PC & -4, 0*2 + 4 + 0xF*4); - const uint32_t r5 = HRAM_LOADL(state->PC & -4, 2*2 + 4 + 0xF*4); - const uint32_t r0 = HRAM_LOADL(state->PC & -4, 4*2 + 4 + 0xF*4); - const uint32_t r3 = HRAM_LOADW(r2, 0) + 1; - HRAM_STOREW(r2, 0, r3); - const uint32_t r6 = HRAM_LOADL(r0, 0); - const uint32_t r5_new = r5 + r3*48; - HRAM_STOREL(r0, 0, r5_new); - - /* Help out the optimizer by telling it we can load multiple values - * at once. */ - const uint32_t *src = (const uint32_t *)HRAM_PTR(r6); - uint32_t *dest = (uint32_t *)HRAM_PTR(r5_new); - unsigned int i; - for (i = 0; i < 12; i += 4) { - const uint32_t a = src[i+0]; - const uint32_t b = src[i+1]; - const uint32_t c = src[i+2]; - const uint32_t d = src[i+3]; - dest[i+0] = a; - dest[i+1] = b; - dest[i+2] = c; - dest[i+3] = d; - } - - state->PC = state->PR; - state->cycles += 87; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x602E630: Coordinate transformation */ - -static int BIOS_0602E630_is_UE; - -static int BIOS_0602E630_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - if (address == 0x602E630 && checksum_fast16(fetch,612) == 0xA87EE4) { - BIOS_0602E630_is_UE = 0; - return 612; - } - if (address == 0x603A630 && checksum_fast16(fetch,600) == 0xA9F4CC) { - BIOS_0602E630_is_UE = 1; - return 600; - } - return 0; -} - -static FASTCALL void BIOS_0602E630(SH2State *state) -{ - int32_t counter; - - int16_t * const R12_ptr = - (int16_t *)HRAM_PTR(HRAM_LOADL((state->PC + 11*2) & -4, 4 + 0x7B*4)); - int32_t * const R13_ptr = - (int32_t *)HRAM_PTR(HRAM_LOADL((state->PC + 12*2) & -4, 4 + 0x7B*4)); - - const uint32_t M_R7 = HRAM_LOADL((state->PC + 24*2) & -4, 4 + 0x76*4); - const int32_t * const M = (const int32_t *)HRAM_PTR(HRAM_LOADL(M_R7, 0)); - - const uint32_t R5 = HRAM_LOADL(state->R[4], 56) + 4; - counter = (int16_t)HRAM_LOADW(R5, -4); - state->cycles += 30; - - if (counter > 0) { - - /* 0x602E66E */ - - state->cycles += 19 + (counter * /*minimum of*/ 110); - -#ifdef PSP -# define DO_MULT(dest_all,dest_z,index) \ - int32_t dest_all, dest_z; \ - do { \ - int32_t temp_x, temp_y, temp_z; \ - asm(".set push; .set noreorder\n" \ - "lw %[temp_z], %[idx]*16+8(%[M])\n" \ - "lw %[temp_x], %[idx]*16+0(%[M])\n" \ - "lw %[temp_y], %[idx]*16+4(%[M])\n" \ - "ror %[temp_z], %[temp_z], 16\n" \ - "mult %[temp_z], %[in_z]\n" \ - "ror %[temp_x], %[temp_x], 16\n" \ - "ror %[temp_y], %[temp_y], 16\n" \ - "mfhi %[temp_z]\n" \ - "mflo %[dst_z]\n" \ - "madd %[temp_x], %[in_x]\n" \ - "sll %[temp_z], %[temp_z], 16\n" \ - "srl %[dst_z], %[dst_z], 16\n" \ - "lw %[temp_x], %[idx]*16+12(%[M])\n" \ - "madd %[temp_y], %[in_y]\n" \ - "or %[dst_z], %[dst_z], %[temp_z]\n" \ - "ror %[temp_z], %[temp_x], 16\n" \ - "mfhi %[temp_x]\n" \ - "mflo %[temp_y]\n" \ - "sll %[temp_x], %[temp_x], 16\n" \ - "srl %[temp_y], %[temp_y], 16\n" \ - "or %[dst_all], %[temp_x], %[temp_y]\n" \ - "addu %[dst_all], %[dst_all], %[temp_z]\n" \ - ".set pop" \ - : [dst_all] "=r" (dest_all), [dst_z] "=&r" (dest_z), \ - [temp_x] "=&r" (temp_x), [temp_y] "=&r" (temp_y), \ - [temp_z] "=&r" (temp_z) \ - : [M] "r" (M), [idx] "i" (index), [in_x] "r" (in_x), \ - [in_y] "r" (in_y), [in_z] "r" (in_z) \ - : "hi", "lo" \ - ); \ - } while (0) -#else // !PSP -# define GET_M(i) ((int64_t)(int32_t)RAM_SWAPL(M[(i)])) -# define DO_MULT(dest_all,dest_z,index) \ - const int32_t dest_z = ((int64_t)in_z * GET_M((index)*4+2)) >> 16; \ - int32_t dest_all = (((int64_t)in_x * GET_M((index)*4+0) \ - + (int64_t)in_y * GET_M((index)*4+1) \ - + (int64_t)in_z * GET_M((index)*4+2)) >> 16) \ - + GET_M((index)*4+3); -#endif - - const uint32_t testflag = HRAM_LOADL(state->R[4], 20); - const int32_t *in = (const int32_t *)HRAM_PTR(R5); - int32_t *out = R13_ptr; - int16_t *coord_out = R12_ptr; - - do { - const int32_t in_x = RAM_SWAPL(in[0]); - const int32_t in_y = RAM_SWAPL(in[1]); - const int32_t in_z = RAM_SWAPL(in[2]); - - DO_MULT(out_z, zz, 2); - if (out_z < 0 && testflag) { - out_z += out_z >> 3; - } - out[ 2] = RAM_SWAPL(out_z); - out[14] = RAM_SWAPL(out_z - (zz<<1)); - - DO_MULT(out_x, zx, 0); - out[ 0] = RAM_SWAPL(out_x); - out[12] = RAM_SWAPL(out_x - (zx<<1)); - - DO_MULT(out_y, zy, 1); - out[ 1] = RAM_SWAPL(out_y); - out[13] = RAM_SWAPL(out_y - (zy<<1)); - - /* The result gets truncated to 16 bits here, so we don't need - * to worry about the 32->24 bit precision loss with floats. - * (There are only a few pixels out of place during the entire - * animation as a result of rounding error.) */ - const float coord_mult = 192.0f / out_z; - *coord_out++ = (int16_t)ifloorf(out_x * coord_mult); - *coord_out++ = (int16_t)ifloorf(out_y * coord_mult); - - in += 3; - out += 3; - counter -= 2; - } while (counter > 0); - -#undef GET_M -#undef DO_MULT - - } // if (counter > 0) - - /* 0x602E840 */ - - /* Offset for second-half local data accesses */ - const int UE_PC_offset = (BIOS_0602E630_is_UE ? -12*2 : 0); - - const uint32_t R11 = HRAM_LOADL(state->R[4], 64); - counter = (int16_t)HRAM_LOADW(R11, 0); - state->cycles += 19; - - if (counter > 0) { - -#ifdef PSP -# define DOT3_16(v,x,y,z) __extension__({ \ - int32_t __temp1, __temp2, __result; \ - asm(".set push; .set noreorder\n" \ - "lw %[temp1], 0(%[V])\n" \ - "lw %[temp2], 4(%[V])\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "mult %[temp1], %[X]\n" \ - "lw %[temp1], 8(%[V])\n" \ - "ror %[temp2], %[temp2], 16\n" \ - "madd %[temp2], %[Y]\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "madd %[temp1], %[Z]\n" \ - "mflo %[result]\n" \ - "mfhi %[temp1]\n" \ - "sra %[result], %[result], 16\n" \ - "ins %[result], %[temp1], 16, 16\n" \ - ".set pop" \ - : [temp1] "=&r" (__temp1), [temp2] "=&r" (__temp2), \ - [result] "=r" (__result) \ - : [V] "r" (v), [X] "r" (x), [Y] "r" (y), [Z] "r" (z) \ - : "hi", "lo" \ - ); \ - __result; \ -}) -# define DOT3_32(v,x,y,z) __extension__({ \ - int32_t __temp1, __temp2, __result; \ - asm(".set push; .set noreorder\n" \ - "lw %[temp1], 0(%[V])\n" \ - "lw %[temp2], 4(%[V])\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "mult %[temp1], %[X]\n" \ - "lw %[temp1], 8(%[V])\n" \ - "ror %[temp2], %[temp2], 16\n" \ - "madd %[temp2], %[Y]\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "madd %[temp1], %[Z]\n" \ - "mfhi %[result]\n" \ - ".set pop" \ - : [temp1] "=&r" (__temp1), [temp2] "=&r" (__temp2), \ - [result] "=r" (__result) \ - : [V] "r" (v), [X] "r" (x), [Y] "r" (y), [Z] "r" (z) \ - : "hi", "lo" \ - ); \ - __result; \ -}) -#else // !PSP -# define DOT3_16(v,x,y,z) \ - (((int64_t)(int32_t)RAM_SWAPL((v)[0]) * (int64_t)(int32_t)(x) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[1]) * (int64_t)(int32_t)(y) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[2]) * (int64_t)(int32_t)(z)) >> 16) -# define DOT3_32(v,x,y,z) \ - (((int64_t)(int32_t)RAM_SWAPL((v)[0]) * (int64_t)(int32_t)(x) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[1]) * (int64_t)(int32_t)(y) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[2]) * (int64_t)(int32_t)(z)) >> 32) -#endif - - state->cycles += 68 + 95*(counter-2); - - /* 0x602E850 */ - - const int32_t *in = (const int32_t *)(HRAM_PTR(R11) + 28); - const int32_t *coord_in = &R13_ptr[12]; - const uint32_t out_address = - HRAM_LOADL((state->PC + 264*2 + UE_PC_offset) & -4, 4 + 0xA2*4); - int32_t *out = (int32_t *)HRAM_PTR(out_address); - int16_t *coord_out = &R12_ptr[8]; - - const uint16_t *R6_ptr = - (const uint16_t *)(HRAM_PTR(HRAM_LOADL(state->R[4], 60)) + 4); - const uint32_t flag_address = - HRAM_LOADL((state->PC + 348*2 + UE_PC_offset) & -4, 4 + 0x79*4); - int16_t *flag = (int16_t *)HRAM_PTR(flag_address); - - { - const int32_t M_2 = RAM_SWAPL(M[ 2]); - const int32_t M_6 = RAM_SWAPL(M[ 6]); - const int32_t M_10 = RAM_SWAPL(M[10]); - - out[0] = RAM_SWAPL(-M_2); - out[1] = RAM_SWAPL(-M_6); - out[2] = RAM_SWAPL(-M_10); - const int32_t *in0_0 = - (const int32_t *)((uintptr_t)R13_ptr + R6_ptr[3]); - R6_ptr += 10; - const int32_t test_0 = DOT3_32(in0_0, -M_2, -M_6, -M_10); - *flag++ = (test_0 < 0); - out += 3; - counter--; - - out[0] = RAM_SWAPL(M_2); - out[1] = RAM_SWAPL(M_6); - out[2] = RAM_SWAPL(M_10); - const int32_t *in0_1 = - (const int32_t *)((uintptr_t)R13_ptr + R6_ptr[3]); - R6_ptr += 10; - const int32_t test_1 = DOT3_32(in0_1, M_2, M_6, M_10); - *flag++ = (test_1 < 0); - out += 3; - counter--; - } - - do { - const int32_t in_x = RAM_SWAPL(in[0]); - const int32_t in_y = RAM_SWAPL(in[1]); - const int32_t in_z = RAM_SWAPL(in[2]); - - const int32_t out_x = DOT3_16(&M[0], in_x, in_y, in_z); - const int32_t out_y = DOT3_16(&M[4], in_x, in_y, in_z); - const int32_t out_z = DOT3_16(&M[8], in_x, in_y, in_z); - - out[0] = RAM_SWAPL(out_x); - out[1] = RAM_SWAPL(out_y); - out[2] = RAM_SWAPL(out_z); - - const float coord_mult = 192.0f / (int32_t)RAM_SWAPL(coord_in[2]); - *coord_out++ = - (int16_t)ifloorf((int32_t)RAM_SWAPL(coord_in[0]) * coord_mult); - *coord_out++ = - (int16_t)ifloorf((int32_t)RAM_SWAPL(coord_in[1]) * coord_mult); - coord_in += 3; - - const int32_t *in0 = - (const int32_t *)((uintptr_t)R13_ptr + R6_ptr[3]); - R6_ptr += 10; - const int32_t test = DOT3_32(in0, out_x, out_y, out_z); - *flag++ = (test < 0); - - in += 3; - out += 3; - counter--; - } while (counter > 0); - -#undef DOT3_16 -#undef DOT3_32 - - } // if (counter > 0) - - /* 0x602E914 */ - /* Note: At this point, all GPRs except R9, R12, R13, and R15 are dead */ - - const int16_t *flag = (const int16_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 572*2 + UE_PC_offset) & -4, 4 + 0x0F*4)); - const int32_t *R1_ptr = (const int32_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 378*2 + UE_PC_offset) & -4, 4 + 0x6C*4)); - const uint16_t *R6_ptr = (const uint16_t *)HRAM_PTR( - HRAM_LOADL(state->R[4], 60)); - const int32_t *R7_ptr = (const int32_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 371*2 + UE_PC_offset) & -4, 4 + 0x6D*4)); - const uint32_t R9 = HRAM_LOADL((state->PC + 9*2) & -4, 4 + 0x7A*4); - uint16_t *R10_ptr = (uint16_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 370*2 + UE_PC_offset) & -4, 4 + 0x73*4)); - - const int32_t limit = *R6_ptr; - R6_ptr += 2; - state->cycles += 13; - - for (counter = 0; counter < limit; counter++, R7_ptr += 3, R6_ptr += 10) { - - /* 0x602EAA8 */ - - if (!flag[counter]) { - state->cycles += 15; - continue; - } - - /* 0x602E924 */ - -#ifdef PSP - int32_t R2; - { - int32_t temp1, temp2, temp3; - asm(".set push; .set noreorder\n" - "lw %[temp1], 0(%[R7_ptr])\n" - "lw %[temp2], 0(%[R1_ptr])\n" - "lw %[temp3], 4(%[R7_ptr])\n" - "ror %[temp1], %[temp1], 16\n" - "ror %[temp2], %[temp2], 16\n" - "mult %[temp1], %[temp2]\n" - "lw %[temp1], 4(%[R1_ptr])\n" - "lw %[temp2], 8(%[R7_ptr])\n" - "ror %[temp3], %[temp3], 16\n" - "ror %[temp1], %[temp1], 16\n" - "madd %[temp3], %[temp1]\n" - "lw %[temp3], 8(%[R1_ptr])\n" - "ror %[temp2], %[temp2], 16\n" - "ror %[temp3], %[temp3], 16\n" - "madd %[temp2], %[temp3]\n" - "mflo %[temp1]\n" - "mfhi %[temp2]\n" - "sra %[temp1], %[temp1], 16\n" - "addiu %[temp2], %[temp2], 1\n" - "ins %[temp1], %[temp2], 16, 16\n" - "sra %[temp1], %[temp1], 10\n" - "max %[temp1], %[temp1], $zero\n" - "min %[R2], %[temp1], %[cst_127]\n" - ".set pop" - : [R2] "=r" (R2), [temp1] "=&r" (temp1), - [temp2] "=&r" (temp2), [temp3] "=&r" (temp3) - : [R7_ptr] "r" (R7_ptr), [R1_ptr] "r" (R1_ptr), - [cst_127] "r" (127) - : "hi", "lo" - ); - } -#else // !PSP - const int32_t mac = - ((int64_t) (int32_t)RAM_SWAPL(R7_ptr[0]) * (int32_t)RAM_SWAPL(R1_ptr[0]) - + (int64_t) (int32_t)RAM_SWAPL(R7_ptr[1]) * (int32_t)RAM_SWAPL(R1_ptr[1]) - + (int64_t) (int32_t)RAM_SWAPL(R7_ptr[2]) * (int32_t)RAM_SWAPL(R1_ptr[2]) - ) >> 16; - const int32_t R2_temp = (mac + 0x10000) >> 10; - const int32_t R2 = R2_temp < 0 ? 0 : R2_temp > 127 ? 127 : R2_temp; -#endif - const uint32_t R2_tableaddr = RAM_SWAPL(*(const uint32_t *)&R6_ptr[8]); - const uint16_t *R2_table = (const uint16_t *)HRAM_PTR(R2_tableaddr); - - const uint32_t R9_address = HRAM_LOADL(R9, 0); - HRAM_STOREL(R9, 0, R9_address + 48); - HRAM_STOREW(R9_address, 0, *R6_ptr); - HRAM_STOREW(R9_address, 42, R2_table[R2]); - - uint32_t * const R9_data32 = (uint32_t *)(HRAM_PTR(R9_address) + 4); - int32_t R3; - switch (R6_ptr[1] & 0xFF) { - case 0x00: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 0]; - R9_data32[1] = *(uint32_t *)&R12_ptr[ 2]; - R9_data32[2] = *(uint32_t *)&R12_ptr[ 4]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 6]; - R3 = RAM_SWAPL(R13_ptr[5]) + RAM_SWAPL(R13_ptr[11]); - break; - - case 0x30: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 8]; - R9_data32[1] = *(uint32_t *)&R12_ptr[14]; - R9_data32[2] = *(uint32_t *)&R12_ptr[12]; - R9_data32[3] = *(uint32_t *)&R12_ptr[10]; - R3 = RAM_SWAPL(R13_ptr[17]) + RAM_SWAPL(R13_ptr[23]); - break; - - case 0x60: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 0]; - R9_data32[1] = *(uint32_t *)&R12_ptr[ 8]; - R9_data32[2] = *(uint32_t *)&R12_ptr[10]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 2]; - R3 = RAM_SWAPL(R13_ptr[5]) + RAM_SWAPL(R13_ptr[14]); - break; - - case 0x90: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 4]; - R9_data32[1] = *(uint32_t *)&R12_ptr[12]; - R9_data32[2] = *(uint32_t *)&R12_ptr[14]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 6]; - R3 = RAM_SWAPL(R13_ptr[8]) + RAM_SWAPL(R13_ptr[23]); - break; - - case 0xC0: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 2]; - R9_data32[1] = *(uint32_t *)&R12_ptr[10]; - R9_data32[2] = *(uint32_t *)&R12_ptr[12]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 4]; - R3 = RAM_SWAPL(R13_ptr[5]) + RAM_SWAPL(R13_ptr[20]); - break; - - default: // case 0xF0 - R9_data32[0] = *(uint32_t *)&R12_ptr[ 0]; - R9_data32[1] = *(uint32_t *)&R12_ptr[ 6]; - R9_data32[2] = *(uint32_t *)&R12_ptr[14]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 8]; - R3 = RAM_SWAPL(R13_ptr[11]) + RAM_SWAPL(R13_ptr[14]); - break; - } - - if (!BIOS_0602E630_is_UE && R3 < -0x30000 && (R6_ptr[1] & 0xFF00)) { - R3 = -R3; - } - R3 >>= 1; - uint32_t *R3_buffer = (uint32_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 558*2 + UE_PC_offset) & -4, 4 + 0x17*4)); - R3_buffer[(*R10_ptr)++] = RAM_SWAPL(R3); - - state->cycles += 39 + /*approximately*/ 54; - } - - /* 0x602EAB8 */ - - state->PC = state->PR; - state->cycles += 10; -} - -/*************************************************************************/ - -/**** Azel: Panzer Dragoon RPG (JP) optimizations ****/ - -/*-----------------------------------------------------------------------*/ - -/* Common color calculation logic used by several routines */ - -static uint32_t Azel_color_calc(const int16_t *local_ptr, - const int16_t *r4_ptr, const int16_t *r5_ptr, - int32_t r, int32_t g, int32_t b) -{ - int32_t dot = r4_ptr[0] * local_ptr[0] - + r4_ptr[1] * local_ptr[1] - + r4_ptr[2] * local_ptr[2]; - if (dot > 0) { - dot >>= 16; - b += dot * r5_ptr[0]; - g += dot * r5_ptr[1]; - r += dot * r5_ptr[2]; - } - return (bound(b, 0, 0x1F00) & 0x1F00) << 2 - | (bound(g, 0, 0x1F00) & 0x1F00) >> 3 - | (bound(r, 0, 0x1F00) ) >> 8; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600614C: Idle loop with a JSR */ - -static int Azel_0600614C_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[-2] == 0x4B0B // jsr @r11 - && fetch[-1] == 0x0009 // nop - && fetch[ 0] == 0x60E2 // mov.l @r14, r0 - && fetch[ 1] == 0x2008 // tst r0, r0 - && fetch[ 2] == 0x8BFA // bf fetch[-2] - && state->R[14] == 0x604BC80 - ? 3 : 0; -} - -static FASTCALL void Azel_0600614C(SH2State *state) -{ - /* Help out the optimizer by loading these early. */ - const int32_t cycle_limit = state->cycle_limit; - const uint32_t test = *(uint32_t *)HRAM_PTR(0x604BC80); - const uint32_t r3 = 0x604B68C; // @(0x38,pc=0x600FCB0) -#if defined(__mips__) && !defined(WORDS_BIGENDIAN) - /* Similar to the "volatile" in the 0x600C59C optimizer, we force this - * to be loaded during the load delay slots of "test". */ - const uint32_t r3_HI = (r3 + 0x8000) & 0xF0000; - uint32_t r3_test; - asm("lbu %0, %1(%2)" - : "=r" (r3_test) - : "i" (((r3 & 0xFFFFF) ^ 1) - r3_HI), "r" (HighWram + r3_HI)); -#else - const uint32_t r3_test = HRAM_LOADB(r3, 0); -#endif - - /* For a comparison against zero, we don't need to swap bytes. */ - if (LIKELY(test)) { - - state->cycles = cycle_limit; - - /* 0x600FCB0 almost always returns straight to us, so we implement - * the first part of it here. */ - if (UNLIKELY(r3_test != 0)) { - state->PR = state->PC; - state->PC = 0x600FCB0 + 4*2; - state->R[3] = r3; - } - - } else { - - state->PC += 2*3; - state->cycles += 3; - - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x60061F0: RBG0 parameter generation for sky/ground backgrounds. We - * also store the slope set here in a video tweak parameter, so the code - * doesn't have to re-derive it from the coefficients (which may be mangled - * by the "shimmering" effect added to water). */ - -static FASTCALL void Azel_060061F0(SH2State *state) -{ - int32_t r4 = state->R[4]; - int32_t r5 = state->R[5]; - int32_t delta = state->R[6]; - uint32_t counter = state->R[7]; - const uint32_t out_address = HRAM_LOADL(state->R[15], 0); - int32_t *out = (int32_t *)HRAM_PTR(out_address); - - extern float psp_video_tweaks_Azel_RBG0_slope; - extern float psp_video_tweaks_Azel_RBG0_first_recip; - - if (r4 < 0) { - r4 = -r4; - r5 = -r5; - delta = -delta; - } - - if (r4 != 0) { - psp_video_tweaks_Azel_RBG0_slope = (float)-delta / (float)r4; - } - - const float r4_scaled = r4 * 65536.0f; - const int32_t r4_test = r4 >> 14; // See below for why we use this. - - if (delta == 0) { - /* No horizon scaling is taking place. Note that r5 should be - * checked against zero here (and in similar cases below), but - * we're a bit more conservative in order to avoid FPU overflow - * errors on conversion to integer; since only the low 24 bits of - * the 16.16 fixed point result are significant, this isn't a - * problem in practice--it will only come up in cases where the - * horizon line almost exactly coincides with a screen line. */ - if (r5 > r4_test) { - const int32_t quotient = ifloorf(r4_scaled / (float)r5); - state->PC = state->PR; - state->cycles += 72 + (counter * 5); - for (; counter != 0; counter--, out++) { - *out = RAM_SWAPL(quotient); - } - } else { - state->PC = state->PR; - state->cycles += 30 + (counter * 5); - for (; counter != 0; counter--, out++) { - *out = -1; - } - } - return; - } - - const int32_t r5_final = r5 - (delta * (counter-1)); - - if (delta > 0 ? (r5 <= r4_test) : (r5_final <= r4_test)) { - /* The entire background layer is outside the horizon area. */ - state->PC = state->PR; - state->cycles += (delta > 0 ? 40 : 43) + (counter * 5); - for (; counter != 0; counter--, out++) { - *out = -1; - } - return; - } - - if (delta > 0 && r5_final <= r4_test) { - /* The bottom of the background layer is outside the horizon area. */ - const uint32_t partial_count = - MIN(counter - ((r5 - r4_test) / delta) + 1, counter); - state->cycles += 88 + (partial_count * 5); - counter -= partial_count; - int32_t *out_temp = out + counter; - uint32_t i; - for (i = partial_count; i != 0; i--, out_temp++) { - *out_temp = -1; - } - } else if (delta < 0 && r5 <= r4_test) { - /* The top of the background layer is outside the horizon area. */ - const uint32_t partial_count = - MIN((r5 - r4_test) / delta + 1, counter); - state->cycles += 86 + (partial_count * 5); - r5 -= delta * partial_count; - counter -= partial_count; - uint32_t i; - for (i = partial_count; i != 0; i--, out++) { - *out = -1; - } - } else { - /* The entire background layer is within the horizon area. */ - state->cycles += (delta > 0 ? 39 : 42); - } - - state->PC = state->PR; - state->cycles += 15 + (counter * 32) + (counter%2 ? 10 : 0); - - if (r4 != 0) { - psp_video_tweaks_Azel_RBG0_first_recip = (float)r5 / (float)r4; - } - for (; counter != 0; counter--, out++) { - *out = RAM_SWAPL(ifloorf(r4_scaled / (float)r5)); - r5 -= delta; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600C4DC: Routine to register a function in the SSH2 call table. This - * could be optimized by the main code with a few hints if it had better - * flow analysis. */ - -static FASTCALL void Azel_0600C4DC(SH2State *state) -{ - const uint32_t base = 0x604B604; - const unsigned int index = HRAM_LOADW(base, 0); - const unsigned int next_index = (index + 1) & 7; - - if (HRAM_LOADL(base, 4 + next_index*16 + 0) != 0) { - MappedMemoryWriteByte(0xFFFFFE11, 0); - } - HRAM_STOREL(base, 4 + index*16 + 4, state->R[4]); - HRAM_STOREL(base, 4 + index*16 + 8, state->R[5]); - HRAM_STOREL(base, 4 + index*16 + 12, state->R[6]); - HRAM_STOREL(base, 4 + index*16 + 0, state->R[7]); - if (index == HRAM_LOADW(base, 2)) { - MappedMemoryWriteWord(0x21000000, 0); - } - HRAM_STOREW(base, 0, next_index); - - state->PC = state->PR; - state->cycles += 47; // Approximate -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600C59C, etc.: SSH2 main loop (idle + function call) */ - -static NOINLINE void Azel_0600C5A4(SH2State *state); -static ALWAYS_INLINE void Azel_0600C5C0( - SH2State *state, const uint32_t *r13_ptr, int extra_cycles); - -/*----------------------------------*/ - -static FASTCALL void Azel_0600C59C(SH2State *state) -{ - int32_t test = (int8_t)(((SH2_struct *)(state->userdata))->onchip.FTCSR); - - /* Again, help out the optimizer. This "volatile" actually speeds - * things up, because it forces the compiler to load this during the - * load delay slots of "test", rather than delaying the load so far - * that the subsequent store to state->cycles ends up stalling. - * (Granted, this is properly an optimizer bug that ought to be fixed - * in GCC. But since GCC's scheduler is so complex it might as well - * be random chaos, what else can we do?) */ - int32_t cycle_limit = -#ifdef __mips__ - *(volatile int32_t *)& -#endif - state->cycle_limit; - - if (LIKELY(test >= 0)) { - state->cycles = cycle_limit; - } else { - state->PR = 0x600C5B4; // Make sure PR is set before 0x600C5C0. - /* We deliberately chain to a separate NOINLINE routine here to - * minimize register saves and restores in the common case above, - * since even setting up and tearing down a stack frame adds a - * significant percentage to the execution time of this function. */ - return Azel_0600C5A4(state); - } -} - -/*----------------------------------*/ - -static NOINLINE void Azel_0600C5A4(SH2State *state) -{ - MappedMemoryWriteByte(0xFFFFFE11, 0); - const unsigned int index = HRAM_LOADW(state->R[13], 2); - const uint32_t *r13_ptr = (const uint32_t *)HRAM_PTR(state->R[13]); - return Azel_0600C5C0(state, &r13_ptr[1 + index*4], 7); -} - -/*----------------------------------*/ - -static int Azel_0600C5B4_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return checksum_fast16(fetch-6, 24) == 0x93C29 ? 24 : 0; -} - -static FASTCALL void Azel_0600C5B4(SH2State *state) -{ - const uint32_t r13 = state->R[13]; - uint32_t *r13_ptr = (uint32_t *)HRAM_PTR(r13); - unsigned int index = HRAM_LOADW(r13, 2); - r13_ptr[1 + index*4] = 0; - index = (index + 1) & 7; - HRAM_STOREW(r13, 2, index); - MappedMemoryWriteWord(0x21800000, 0); - return Azel_0600C5C0(state, &r13_ptr[1 + index*4], 6); -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_0600C5C0( - SH2State *state, const uint32_t *r13_ptr, int extra_cycles) -{ - const uint32_t func_address = RAM_SWAPL(r13_ptr[0]); - if (func_address) { - state->R[4] = RAM_SWAPL(r13_ptr[1]); - state->R[5] = RAM_SWAPL(r13_ptr[2]); - state->R[6] = RAM_SWAPL(r13_ptr[3]); - /* PR is known to be correct (0x600C5B4) here. */ - state->PC = func_address; - state->cycles += extra_cycles + 19; - } else { - state->PC = 0x600C59C; - state->cycles = state->cycle_limit; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600C5F8, 0x600C690: Cache flush routines (no-ops in emulation) */ - -static FASTCALL void Azel_0600C5F8(SH2State *state) -{ - state->R[0] = 0x604AEA8 + HRAM_LOADW(0x604B606, 0) * 48; - state->PC = state->PR; - state->cycles += 48; -} - -static FASTCALL void Azel_0600C690(SH2State *state) -{ - state->PC = state->PR; - state->cycles += 11 + (state->R[5] / 16) * 5; // Approximate -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6010F24/0x6010F52: Bitmap copy loop (for movies) */ - -static int Azel_06010F24_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[ 0] == 0x6693 // mov r9, r6 - && fetch[ 1] == 0x65D3 // mov r13, r5 - && fetch[ 2] == 0x4A0B // jsr @r10 [DMA copy routine] - && fetch[ 3] == 0x64E3 // mov r14, r4 - // fetch[ 4] == 0x53F1 // {mov.l @(4,r15), r3 [counter] | add r8, r14} - // fetch[ 5] == 0x3E8C // {add r8, r14 | mov.l @r15, r3 [counter]} - && fetch[ 6] == 0x73FF // add #-1, r3 - // fetch[ 7] == 0x2338 // {tst r3, r3 | mov.l r3, @r15} - // fetch[ 8] == 0x1F31 // {mov.l r3, @(4,r15) | tst r3, r3} - && fetch[ 9] == 0x8FF5 // bf/s fetch[0] - && fetch[10] == 0x3DCC // add r12, r13 - && state->R[13]>>20 == 0x25E - ? 11 : 0; -} - -static FASTCALL void Azel_06010F24(SH2State *state) -{ - const uint32_t src_addr = state->R[14]; - const uint32_t dest_addr = state->R[13]; - const uint32_t size = state->R[9]; - const uint32_t *src = (const uint32_t *)HRAM_PTR(src_addr); - uint32_t *dest = (uint32_t *)VDP2_PTR(dest_addr); - - uint32_t i; - for (i = 0; i < size; i += 16, src += 4, dest += 4) { - const uint32_t word0 = src[0]; - const uint32_t word1 = src[1]; - const uint32_t word2 = src[2]; - const uint32_t word3 = src[3]; - dest[0] = RAM_VDP_SWAPL(word0); - dest[1] = RAM_VDP_SWAPL(word1); - dest[2] = RAM_VDP_SWAPL(word2); - dest[3] = RAM_VDP_SWAPL(word3); - } - - state->R[14] = src_addr + state->R[8]; - state->R[13] = dest_addr + state->R[12]; - - /* Conveniently, the counter is always stored in R3 when we get here - * (it's first loaded when the loop is executed on the fall-in case) - * and the stack variables are never referenced once their respective - * loops complete, so we don't have to worry about which loop we're in. */ - unsigned int counter = state->R[3]; - counter--; - state->R[3] = counter; - - if (counter != 0) { - state->SR &= ~SR_T; - state->cycles += 290; - } else { - state->SR |= SR_T; - state->PC += 2*11; - state->cycles += 289; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6014274: Calculation routine (possibly for the line scroll table?) */ - -static FASTCALL void Azel_06014274(SH2State *state) -{ - const int32_t * const sin_table = (const int32_t *)LRAM_PTR(0x20216660); - - int32_t *r4_ptr = (int32_t *)HRAM_PTR(state->R[4]); - - int32_t r9 = RAM_SWAPL(r4_ptr[6]); - r4_ptr[6] = RAM_SWAPL(r9 + RAM_SWAPL(r4_ptr[1])); - const int32_t r10 = RAM_SWAPL(r4_ptr[7]); - r4_ptr[7] = RAM_SWAPL(r10 + RAM_SWAPL(r4_ptr[4])); - const int32_t r11 = 176; - const int32_t r5 = RAM_SWAPL(r4_ptr[2]); - const int32_t r6 = RAM_SWAPL(r4_ptr[5]); - const int32_t r7 = RAM_SWAPL(r4_ptr[3]); - r4_ptr = (int32_t *)HRAM_PTR(RAM_SWAPL(r4_ptr[0])); - - unsigned int counter; - for (counter = 224; counter != 0; counter--) { - const int32_t r0 = ((int64_t)r7 * sin_table[r9>>16 & 0xFFF]) >> 16; - /* We drop 2 bits of precision here so we can use a 32/32bit - * integer divide instruction; it shouldn't make a difference in - * the visible result. */ - const int32_t r12 = ((r7 + r0) >> 2) + 0x4000; - const int32_t quotient = 0x40000000 / r12; - r4_ptr[1] = RAM_SWAPL((RAM_SWAPL(r4_ptr[1]) + r6) & 0xFFFFFF); - r4_ptr[2] = RAM_SWAPL(quotient); - r4_ptr[0] = RAM_SWAPL((0x10000 - quotient) * r11 + r10); - r4_ptr += 3; - r9 += r5; - } - - state->PC = state->PR; - state->cycles += 86 + 222*48 + 58; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601E330: Input capture check */ - -static FASTCALL void Azel_0601E330(SH2State *state) -{ - int32_t test = (int8_t)(((SH2_struct *)(state->userdata))->onchip.FTCSR); - const uint32_t param = HRAM_LOADL(0x604AEA4, 0); - if (LIKELY(test >= 0)) { - state->R[5] = param; - state->R[6] = 0x604FCFC; - state->R[7] = 0x604BCB4; - state->PC = 0x601F1E4; - state->cycles += 21; - } else { - const uint32_t old_r4 = state->R[4]; - state->R[4] = param; - - /* 0x600C5D8 */ - const unsigned int index = HRAM_LOADW(0x604B604, 0); - state->R[5] = 0x604AEA8 + index*48; - state->PC = 0x6035AA0; - Azel_06035AA0(state); - - /* 0x601E3A6 */ - state->R[4] = old_r4; - state->R[5] = 0; - state->R[6] = 0; - state->R[7] = 0x601E314; - state->PC = 0x600C4DC; - state->cycles += 16 + 17 + 10; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601E910, etc.: Various varieties of vertex manipulation routines and - * their subfunctions */ - -static void Azel_0601E910_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)); -static void Azel_0601E9A4(SH2State *state, const uint32_t color_data, - int swapflag); -static int Azel_0601EB10(const int16_t *vertex_data, uint32_t color_data, - int base_r, int base_g, int base_b); - -static void Azel_0601EC20_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)); -static void Azel_0601EC58(SH2State *state, int swapflag); -static int Azel_0601ED58(const int16_t *vertex_data, - int base_r, int base_g, int base_b); -static int Azel_0601EDDC(const int16_t *vertex_data, - int base_r, int base_g, int base_b); - -static void Azel_0601F2D6_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)); -static void Azel_0601F49C(SH2State *state, int swapflag); -static int Azel_0601FA68(const int16_t *vertex_data, - int base_r, int base_g, int base_b); -static int Azel_0601FAEC(const int16_t *vertex_data, - int base_r, int base_g, int base_b); - -static int Azel_0601F58A(SH2State *state, uint32_t r11, uint32_t r13); -static int Azel_0601F5A6(SH2State *state, - const int16_t *r10_ptr, const int16_t *r11_ptr, - const int16_t *r12_ptr, const int16_t *r13_ptr); -static int Azel_0601F5D2(SH2State *state); - -static int Azel_0601F5EE(SH2State *state, uint32_t r11, uint32_t r13); - -static ALWAYS_INLINE int Azel_0601F762( - SH2State *state, const uint32_t * const r10_ptr, - const uint32_t * const r11_ptr, const uint32_t * const r12_ptr, - const uint32_t * const r13_ptr, uint32_t * const r14_ptr, - const uint32_t r4_0, const int swapflag); - -static int32_t Azel_0601F824(const int16_t *r6_ptr, uint32_t *r10_ptr, - uint32_t *r11_ptr, uint32_t *r12_ptr, - uint32_t *r13_ptr, uint32_t mask, - int (*clipfunc)(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr)); -static int Azel_0601F93A(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static int Azel_0601F948(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static ALWAYS_INLINE int Azel_0601F950(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_x, const int32_t x_lim, - int base_cycles); -static int Azel_0601F988(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static int Azel_0601F996(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static ALWAYS_INLINE int Azel_0601F99E(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_y, const int32_t y_lim, - int base_cycles); -static int Azel_0601F9D6(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); - -/*----------------------------------*/ - -static FASTCALL void Azel_0601E910(SH2State *state) -{ - return Azel_0601E910_common(state, Azel_0601F58A); -} - -static FASTCALL void Azel_0601E95A(SH2State *state) -{ - return Azel_0601E910_common(state, Azel_0601F5EE); -} - -static FASTCALL void Azel_0601EC20(SH2State *state) -{ - return Azel_0601EC20_common(state, Azel_0601F58A); -} - -static FASTCALL void Azel_0601EC3C(SH2State *state) -{ - return Azel_0601EC20_common(state, Azel_0601F5EE); -} - -static FASTCALL void Azel_0601F2D6(SH2State *state) -{ - return Azel_0601F2D6_common(state, Azel_0601F58A); -} - -static FASTCALL void Azel_0601F2F2(SH2State *state) -{ - return Azel_0601F2D6_common(state, Azel_0601F5EE); -} - -/*----------------------------------*/ - -static void Azel_0601E910_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)) -{ - const uint32_t saved_PR = state->PR; - - uint32_t color_data = HRAM_LOADL(state->R[15], 4); - uint32_t index = 0; - uint32_t r11 = LRAM_LOADL(state->R[4], 0); - uint32_t r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - while (r11 != r13) { - const int swapflag = (*clipfunc)(state, r11, r13); - const int clipped = (swapflag < 0); - if (LRAM_LOADL(color_data, 0) == index) { - if (clipped) { - state->cycles += 25; - } else { - Azel_0601E9A4(state, color_data + 4, swapflag); - state->cycles += 21; - } - color_data += 16; - } else { - if (clipped) { - state->cycles += 19; - } else { - Azel_0601F49C(state, swapflag); - state->cycles += 20; - } - } - index++; - r11 = LRAM_LOADL(state->R[4], 0); - r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - } - - state->PC = saved_PR; - state->cycles += 11; -} - -static void Azel_0601E9A4(SH2State *state, const uint32_t color_data, - int swapflag) -{ - static const uint16_t cycles_used[4][4] = - {{13,13,13,13},{312,319,321,319},{315,322,324,322},{309,317,319,317}}; - - const int16_t *quad_data = (const int16_t *)LRAM_PTR(state->R[4]); - const int quad_type = (quad_data[-6] >> 8) & 3; - uint32_t *gbr_ptr = (uint32_t *)HRAM_PTR(state->GBR); - - state->cycles += cycles_used[quad_type][swapflag]; - - gbr_ptr[0] = RAM_SWAPL(state->R[14] + 32); - - if (quad_type == 0) { - return; - } - - const uint32_t color_addr = RAM_SWAPL(gbr_ptr[4]); - int16_t *out = (int16_t *)VDP1_PTR(color_addr); - gbr_ptr[4] = RAM_SWAPL(color_addr + 8); - VDP1_STOREW(state->R[14], 28, color_addr >> 3); - - const int16_t *base_ptr = - (const int16_t *)(HRAM_PTR(0x601FCB0) + (state->R[1]>>7 & -8)); - const int base_r = base_ptr[0]; - const int base_g = base_ptr[1]; - const int base_b = base_ptr[2]; - int a, b, c, d; - - switch (quad_type) { - case 1: - a = Azel_0601EB10(quad_data, color_data+0, base_r, base_g, base_b); - b = Azel_0601EB10(quad_data, color_data+3, base_r, base_g, base_b); - c = Azel_0601EB10(quad_data, color_data+6, base_r, base_g, base_b); - d = Azel_0601EB10(quad_data, color_data+9, base_r, base_g, base_b); - state->R[4] += 8; - break; - - case 2: - a = Azel_0601EB10(quad_data+0, color_data+0, base_r, base_g, base_b); - b = Azel_0601EB10(quad_data+6, color_data+3, base_r, base_g, base_b); - c = Azel_0601EB10(quad_data+12,color_data+6, base_r, base_g, base_b); - d = Azel_0601EB10(quad_data+18,color_data+9, base_r, base_g, base_b); - state->R[4] += 48; - break; - - default: // case 3 - a = Azel_0601EB10(quad_data+0, color_data+0, base_r, base_g, base_b); - b = Azel_0601EB10(quad_data+3, color_data+3, base_r, base_g, base_b); - c = Azel_0601EB10(quad_data+6, color_data+6, base_r, base_g, base_b); - d = Azel_0601EB10(quad_data+9, color_data+9, base_r, base_g, base_b); - state->R[4] += 24; - break; - } // switch (quad_type) - - out[0 ^ swapflag] = VDP_SWAPW(a); - out[1 ^ swapflag] = VDP_SWAPW(b); - out[2 ^ swapflag] = VDP_SWAPW(c); - out[3 ^ swapflag] = VDP_SWAPW(d); -} - -static int Azel_0601EB10(const int16_t *vertex_data, uint32_t color_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601FC94), - vertex_data, - (const int16_t *)HRAM_PTR(0x601FCA8), - base_r + ((int8_t)LRAM_LOADB(color_data,2) << 8), - base_g + ((int8_t)LRAM_LOADB(color_data,1) << 8), - base_b + ((int8_t)LRAM_LOADB(color_data,0) << 8)); -} - -/*----------------------------------*/ - -static void Azel_0601EC20_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)) -{ - const uint32_t saved_PR = state->PR; - - uint32_t r11 = LRAM_LOADL(state->R[4], 0); - uint32_t r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - while (r11 != r13) { - const int swapflag = (*clipfunc)(state, r11, r13); - const int clipped = (swapflag < 0); - if (clipped) { - state->cycles += 12; - } else { - Azel_0601EC58(state, swapflag); - state->cycles += 13; - } - r11 = LRAM_LOADL(state->R[4], 0); - r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - } - - state->PC = saved_PR; - state->cycles += 11; -} - -static void Azel_0601EC58(SH2State *state, int swapflag) -{ - static const uint16_t cycles_used[4][4] = - {{10,10,10,10}, {98,98,98,98}, {285,291,293,291}, {266,272,274,272}}; - - const int16_t *quad_data = (const int16_t *)LRAM_PTR(state->R[4]); - const int quad_type = (quad_data[-6] >> 8) & 3; - uint32_t *gbr_ptr = (uint32_t *)HRAM_PTR(state->GBR); - - state->cycles += cycles_used[quad_type][swapflag]; - - gbr_ptr[0] = RAM_SWAPL(state->R[14] - 32); - - if (quad_type == 0) { - return; - } - - const uint32_t color_addr = RAM_SWAPL(gbr_ptr[4]); - int16_t *out = (int16_t *)VDP1_PTR(color_addr); - gbr_ptr[4] = RAM_SWAPL(color_addr - 8); - VDP1_STOREW(state->R[14], 28, color_addr >> 3); - - const int16_t *base_ptr = - (const int16_t *)(HRAM_PTR(0x601EF2C) + (state->R[1]>>7 & -8)); - const int base_r = base_ptr[0]; - const int base_g = base_ptr[1]; - const int base_b = base_ptr[2]; - int a, b, c, d; - - switch (quad_type) { - case 1: - a = b = c = d = Azel_0601ED58(quad_data, base_r, base_g, base_b); - state->R[4] += 8; - break; - - case 2: - a = Azel_0601EDDC(quad_data+ 0, base_r, base_g, base_b); - b = Azel_0601EDDC(quad_data+ 6, base_r, base_g, base_b); - c = Azel_0601EDDC(quad_data+12, base_r, base_g, base_b); - d = Azel_0601EDDC(quad_data+18, base_r, base_g, base_b); - state->R[4] += 48; - break; - - default: // case 3 - a = Azel_0601ED58(quad_data+0, base_r, base_g, base_b); - b = Azel_0601ED58(quad_data+3, base_r, base_g, base_b); - c = Azel_0601ED58(quad_data+6, base_r, base_g, base_b); - d = Azel_0601ED58(quad_data+9, base_r, base_g, base_b); - state->R[4] += 24; - break; - } // switch (quad_type) - - out[0 ^ swapflag] = VDP_SWAPW(a); - out[1 ^ swapflag] = VDP_SWAPW(b); - out[2 ^ swapflag] = VDP_SWAPW(c); - out[3 ^ swapflag] = VDP_SWAPW(d); -} - -static int Azel_0601ED58(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601EF10), - vertex_data, - (const int16_t *)HRAM_PTR(0x601EF24), - base_r, base_g, base_b); -} - -static int Azel_0601EDDC(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601EF10), - vertex_data, - (const int16_t *)HRAM_PTR(0x601EF24), - base_r + vertex_data[5], - base_g + vertex_data[4], - base_b + vertex_data[3]); -} - -/*----------------------------------*/ - -static void Azel_0601F2D6_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)) -{ - const uint32_t saved_PR = state->PR; - - uint32_t r11 = LRAM_LOADL(state->R[4], 0); - uint32_t r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - while (r11 != r13) { - const int swapflag = (*clipfunc)(state, r11, r13); - const int clipped = (swapflag < 0); - if (clipped) { - state->cycles += 12; - } else { - Azel_0601F49C(state, swapflag); - state->cycles += 13; - } - r11 = LRAM_LOADL(state->R[4], 0); - r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - } - - state->PC = saved_PR; - state->cycles += 11; -} - -static void Azel_0601F49C(SH2State *state, int swapflag) -{ - static const uint16_t cycles_used[4][4] = - {{10,10,10,10}, {98,98,98,98}, {285,291,293,291}, {266,272,274,272}}; - - const int16_t *quad_data = (const int16_t *)LRAM_PTR(state->R[4]); - const int quad_type = (quad_data[-6] >> 8) & 3; - uint32_t *gbr_ptr = (uint32_t *)HRAM_PTR(state->GBR); - - state->cycles += cycles_used[quad_type][swapflag]; - - gbr_ptr[0] = RAM_SWAPL(state->R[14] + 32); - - if (quad_type == 0) { - return; - } - - const uint32_t color_addr = RAM_SWAPL(gbr_ptr[4]); - int16_t *out = (int16_t *)VDP1_PTR(color_addr); - gbr_ptr[4] = RAM_SWAPL(color_addr + 8); - VDP1_STOREW(state->R[14], 28, color_addr >> 3); - - const int16_t *base_ptr = - (const int16_t *)(HRAM_PTR(0x601FCB0) + (state->R[1]>>7 & -8)); - const int base_r = base_ptr[0]; - const int base_g = base_ptr[1]; - const int base_b = base_ptr[2]; - int a, b, c, d; - - switch (quad_type) { - case 1: - a = b = c = d = Azel_0601FA68(quad_data, base_r, base_g, base_b); - state->R[4] += 8; - break; - - case 2: - a = Azel_0601FAEC(quad_data+ 0, base_r, base_g, base_b); - b = Azel_0601FAEC(quad_data+ 6, base_r, base_g, base_b); - c = Azel_0601FAEC(quad_data+12, base_r, base_g, base_b); - d = Azel_0601FAEC(quad_data+18, base_r, base_g, base_b); - state->R[4] += 48; - break; - - default: // case 3 - a = Azel_0601FA68(quad_data+0, base_r, base_g, base_b); - b = Azel_0601FA68(quad_data+3, base_r, base_g, base_b); - c = Azel_0601FA68(quad_data+6, base_r, base_g, base_b); - d = Azel_0601FA68(quad_data+9, base_r, base_g, base_b); - state->R[4] += 24; - break; - } // switch (quad_type) - - out[0 ^ swapflag] = VDP_SWAPW(a); - out[1 ^ swapflag] = VDP_SWAPW(b); - out[2 ^ swapflag] = VDP_SWAPW(c); - out[3 ^ swapflag] = VDP_SWAPW(d); -} - -static int Azel_0601FA68(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601FC94), - vertex_data, - (const int16_t *)HRAM_PTR(0x601FCA8), - base_r, base_g, base_b); -} - -static int Azel_0601FAEC(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601FC94), - vertex_data, - (const int16_t *)HRAM_PTR(0x601FCA8), - base_r + vertex_data[5], - base_g + vertex_data[4], - base_b + vertex_data[3]); -} - -/*----------------------------------*/ - -static int Azel_0601F58A(SH2State *state, uint32_t r11, uint32_t r13) -{ - r11 <<= 3; - r13 <<= 3; - const uint32_t r7 = state->R[7]; - const int16_t *r10_ptr = (const int16_t *)HRAM_PTR(r7 + (r11 >> 16)); - const int16_t *r11_ptr = (const int16_t *)HRAM_PTR(r7 + (r11 & 0xFFFF)); - const int16_t *r12_ptr = (const int16_t *)HRAM_PTR(r7 + (r13 >> 16)); - const int16_t *r13_ptr = (const int16_t *)HRAM_PTR(r7 + (r13 & 0xFFFF)); - return Azel_0601F5A6(state, r10_ptr, r11_ptr, r12_ptr, r13_ptr); -} - -static int Azel_0601F5A6(SH2State *state, - const int16_t *r10_ptr, const int16_t *r11_ptr, - const int16_t *r12_ptr, const int16_t *r13_ptr) -{ - const int32_t a = (r13_ptr[1] - r11_ptr[1]) * (r12_ptr[0] - r10_ptr[0]); - const int32_t b = (r12_ptr[1] - r10_ptr[1]) * (r13_ptr[0] - r11_ptr[0]); - if (b > a) { - state->cycles += 35; - return Azel_0601F5D2(state); - } - - const int swapflag = 0; - - state->R[14] = HRAM_LOADL(state->GBR, 0); - uint32_t *r14_ptr = (uint32_t *)VDP1_PTR(state->R[14]); - - r14_ptr[3] = RAM_VDP_SWAPL(*(const uint32_t *)r10_ptr); - r14_ptr[4] = RAM_VDP_SWAPL(*(const uint32_t *)r11_ptr); - r14_ptr[5] = RAM_VDP_SWAPL(*(const uint32_t *)r12_ptr); - r14_ptr[6] = RAM_VDP_SWAPL(*(const uint32_t *)r13_ptr); - - const uint32_t r4_0 = LRAM_LOADL(state->R[4], 0); - - state->cycles += 49; - return Azel_0601F762(state, - (const uint32_t *)r10_ptr, - (const uint32_t *)r11_ptr, - (const uint32_t *)r12_ptr, - (const uint32_t *)r13_ptr, - r14_ptr, r4_0, swapflag); -} - -static int Azel_0601F5D2(SH2State *state) -{ - static const uint8_t r4ofs_cycles[8] = { - 12, 20, 60, 36, // R4 offset (polygon data size) - 10, 12, 15, 15, // Cycle count - }; - const unsigned int quad_type = (LRAM_LOADW(state->R[4], 0) >> 8) & 0x3; - state->R[4] += r4ofs_cycles[quad_type]; - state->cycles += r4ofs_cycles[quad_type+4]; - return -1; -} - -/*----------------------------------*/ - -static int Azel_0601F5EE(SH2State *state, uint32_t r11, uint32_t r13) -{ - uint32_t cycles = state->cycles; - - r11 <<= 5; - r13 <<= 5; - const uint32_t r7 = state->R[7]; - uint32_t *r10_ptr = (uint32_t *)HRAM_PTR(r7 + (r11 >> 16)); - uint32_t *r11_ptr = (uint32_t *)HRAM_PTR(r7 + (r11 & 0xFFFF)); - uint32_t *r12_ptr = (uint32_t *)HRAM_PTR(r7 + (r13 >> 16)); - uint32_t *r13_ptr = (uint32_t *)HRAM_PTR(r7 + (r13 & 0xFFFF)); - - if (r10_ptr[6] & r11_ptr[6] & r12_ptr[6] & r13_ptr[6]) { - state->cycles = cycles + 27; - return Azel_0601F5D2(state); - } - if ((r10_ptr[6] | r11_ptr[6] | r12_ptr[6] | r13_ptr[6]) & RAM_SWAPL(0x20)) { - state->cycles = cycles + 33; - return Azel_0601F5D2(state); - } - if (!(r10_ptr[6] | r11_ptr[6] | r12_ptr[6] | r13_ptr[6])) { - state->cycles = cycles + 35 - 14; - return Azel_0601F5A6(state, - (const int16_t *)r10_ptr, - (const int16_t *)r11_ptr, - (const int16_t *)r12_ptr, - (const int16_t *)r13_ptr); - } - - r10_ptr[7] = r10_ptr[6]; - r11_ptr[7] = r11_ptr[6]; - r12_ptr[7] = r12_ptr[6]; - r13_ptr[7] = r13_ptr[6]; - r10_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r10_ptr)[0]); - r10_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r10_ptr)[1]); - r11_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r11_ptr)[0]); - r11_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r11_ptr)[1]); - r12_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r12_ptr)[0]); - r12_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r12_ptr)[1]); - r13_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r13_ptr)[0]); - r13_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r13_ptr)[1]); - - const int16_t * const r6_ptr = (const int16_t *)HRAM_PTR(state->R[6]); - int32_t result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x10, Azel_0601F9D6); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 61; - return Azel_0601F5D2(state); - } - - const int32_t r10_x = RAM_SWAPL(r10_ptr[4]); - const int32_t r11_x = RAM_SWAPL(r11_ptr[4]); - const int32_t r12_x = RAM_SWAPL(r12_ptr[4]); - const int32_t r13_x = RAM_SWAPL(r13_ptr[4]); - const int32_t r10_y = RAM_SWAPL(r10_ptr[5]); - const int32_t r11_y = RAM_SWAPL(r11_ptr[5]); - const int32_t r12_y = RAM_SWAPL(r12_ptr[5]); - const int32_t r13_y = RAM_SWAPL(r13_ptr[5]); - int32_t r0 = (r13_y - r11_y) * (r12_x - r10_x); - int32_t r2 = (r12_y - r10_y) * (r13_x - r11_x); - if (r2 > r0) { - state->cycles = cycles + 79; - return Azel_0601F5D2(state); - } - - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x1, Azel_0601F948); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 84; - return Azel_0601F5D2(state); - } - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x2, Azel_0601F93A); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 89; - return Azel_0601F5D2(state); - } - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x4, Azel_0601F996); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 94; - return Azel_0601F5D2(state); - } - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x8, Azel_0601F988); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 99; - return Azel_0601F5D2(state); - } - - int swapflag; - uint32_t r4_0 = LRAM_LOADL(state->R[4], 0); - if (r10_ptr[7]) { - if (r11_ptr[7]) { - if (r12_ptr[7]) { - if (r13_ptr[7]) { - swapflag = 0; - cycles += 116; - } else { - uint32_t *temp1, *temp2; - temp1 = r10_ptr; temp2 = r13_ptr; - r10_ptr = temp2; r13_ptr = temp1; - temp1 = r11_ptr; temp2 = r12_ptr; - r11_ptr = temp2; r12_ptr = temp1; - r4_0 ^= 0x20; - swapflag = 3; - cycles += 124; - } - } else { - uint32_t *temp1, *temp2; - temp1 = r10_ptr; temp2 = r12_ptr; - r10_ptr = temp2; r12_ptr = temp1; - temp1 = r11_ptr; temp2 = r13_ptr; - r11_ptr = temp2; r13_ptr = temp1; - r4_0 ^= 0x30; - swapflag = 2; - cycles += 123; - } - } else { - uint32_t *temp1, *temp2; - temp1 = r10_ptr; temp2 = r11_ptr; - r10_ptr = temp2; r11_ptr = temp1; - temp1 = r12_ptr; temp2 = r13_ptr; - r12_ptr = temp2; r13_ptr = temp1; - r4_0 ^= 0x10; - swapflag = 1; - cycles += 120; - } - } else { - swapflag = 0; - cycles += 105; - } - - state->R[14] = HRAM_LOADL(state->GBR, 0); - uint32_t *r14_ptr = (uint32_t *)VDP1_PTR(state->R[14]); - - const uint16_t *r10_ptr16 = (const uint16_t *)r10_ptr; - const uint16_t *r11_ptr16 = (const uint16_t *)r11_ptr; - const uint16_t *r12_ptr16 = (const uint16_t *)r12_ptr; - const uint16_t *r13_ptr16 = (const uint16_t *)r13_ptr; - r14_ptr[3] = VDP_SWAPL(r10_ptr16[9]<<16 | r10_ptr16[11]); - r14_ptr[4] = VDP_SWAPL(r11_ptr16[9]<<16 | r11_ptr16[11]); - r14_ptr[5] = VDP_SWAPL(r12_ptr16[9]<<16 | r12_ptr16[11]); - r14_ptr[6] = VDP_SWAPL(r13_ptr16[9]<<16 | r13_ptr16[11]); - - state->cycles = cycles + 24; - return Azel_0601F762(state, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - r14_ptr, r4_0, swapflag); -} - -/*----------------------------------*/ - -static ALWAYS_INLINE int Azel_0601F762( - SH2State *state, const uint32_t * const r10_ptr, - const uint32_t * const r11_ptr, const uint32_t * const r12_ptr, - const uint32_t * const r13_ptr, uint32_t * const r14_ptr, - const uint32_t r4_0, const int swapflag) -{ - const uint32_t r4_1 = LRAM_LOADL(state->R[4], 4); - const uint32_t r4_2 = LRAM_LOADL(state->R[4], 8); - state->R[4] += 12; - - *(uint16_t *)&r14_ptr[0] = VDP_SWAPW(r4_0 | 0x1000); - r14_ptr[1] = VDP_SWAPL(r4_1); - r14_ptr[2] = VDP_SWAPL(r4_2); - - int32_t r1 = RAM_SWAPL(r10_ptr[1]); - int32_t r2 = RAM_SWAPL(r11_ptr[1]); - int32_t r3 = RAM_SWAPL(r12_ptr[1]); - int32_t r5 = RAM_SWAPL(r13_ptr[1]); - const uint32_t out_addr = HRAM_LOADL(state->GBR, 32); - uint16_t *out_ptr = (uint16_t *)HRAM_PTR(out_addr); - const int32_t mult = HRAM_LOADL(state->R[6], 52); - - switch (r4_0 >> 28) { - case 0: - r1 = MAX(MAX(r1, r2), MAX(r3, r5)); - state->cycles += 21; - l_601F7F4: - r1 = ((int64_t)r1 * (int64_t)mult) >> 32; - if (r1 <= 0) { - r1 = 1; - } - out_ptr[2] = r1; - out_ptr[3] = (uint16_t)(state->R[14] >> 3); - state->cycles += 15; - break; - - default: // case 1 - r1 = MIN(MIN(r1, r2), MIN(r3, r5)); - state->cycles += 21; - goto l_601F7F4; - - case 2: - r2 -= r1; - r3 -= r1; - r5 -= r1; - r2 += r3 + r5; - r1 += r2 >> 2; - state->cycles += 18; - goto l_601F7F4; - - case 3: - r2 -= r1; - r3 -= r1; - r5 -= r1; - r2 += r3 + r5; - r1 += r2 >> 2; - r1 = ((int64_t)r1 * (int64_t)mult) >> 32; - if (r1 <= 0) { - r1 = 1; - } - out_ptr[2] = 0x7FFF; - out_ptr[3] = (uint16_t)(state->R[14] >> 3); - state->cycles += 25; - break; - } // switch (r4_0 >> 28) - - /* 0x601F810 */ - - HRAM_STOREL(state->GBR, 32, out_addr + 8); - HRAM_STOREL(state->GBR, 12, HRAM_LOADL(state->GBR, 12) + 1); - HRAM_STOREL(state->GBR, 28, HRAM_LOADL(state->GBR, 28) + 1); - state->R[1] = r1; - state->cycles += 8 + 11; - return swapflag; -} - -/*----------------------------------*/ - -static int32_t Azel_0601F824(const int16_t *r6_ptr, uint32_t *r10_ptr, - uint32_t *r11_ptr, uint32_t *r12_ptr, - uint32_t *r13_ptr, uint32_t mask, - int (*clipfunc)(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr)) -{ - int32_t cycles = 0; - - /* We save a bit of time by byte-swapping just this value and loading - * the values to check directly from native memory. */ - mask = RAM_SWAPL(mask); - const uint32_t r10_check = r10_ptr[7] & mask; - const uint32_t r11_check = r11_ptr[7] & mask; - const uint32_t r12_check = r12_ptr[7] & mask; - const uint32_t r13_check = r13_ptr[7] & mask; - - if (r13_check) { - if (r12_check) { - cycles += 10; - if (r11_check) { - if (r10_check) { - cycles += 20; - return 0x80000000 | cycles; - } else { - cycles += (*clipfunc)(r11_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r10_ptr, r6_ptr); - cycles += 27; - return cycles; - } - } else if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r11_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r11_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r11_ptr, r6_ptr); - cycles += 28; - return cycles; - } else { - cycles += (*clipfunc)(r13_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r11_ptr, r6_ptr); - cycles += 24; - return cycles; - } - } else if (r11_check) { - if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r12_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r12_ptr, r6_ptr); - cycles += (*clipfunc)(r11_ptr, r12_ptr, r6_ptr); - cycles += 28; - return cycles; - } else { - cycles += 17; - return 0x80000000 | cycles; - } - } else if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r11_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r12_ptr, r6_ptr); - cycles += 25; - return cycles; - } else { - const int32_t r1 = RAM_SWAPL(r12_ptr[1]); - const int32_t r2 = RAM_SWAPL(r10_ptr[1]); - cycles += (r1 > r2) ? 23 : 21; - cycles += (*clipfunc)(r13_ptr, (r1 > r2) ? r12_ptr : r10_ptr, - r6_ptr); - return cycles; - } - - } else if (r12_check) { - if (r11_check) { - if (r10_check) { - cycles += (*clipfunc)(r11_ptr, r13_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r13_ptr, r6_ptr); - cycles += (*clipfunc)(r10_ptr, r13_ptr, r6_ptr); - cycles += 28; - return cycles; - } else { - cycles += (*clipfunc)(r11_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r13_ptr, r6_ptr); - cycles += 24; - return cycles; - } - } else if (r10_check) { - cycles += 18; - return 0x80000000 | cycles; - } else { - const int32_t r1 = RAM_SWAPL(r13_ptr[1]); - const int32_t r2 = RAM_SWAPL(r11_ptr[1]); - cycles += (r1 > r2) ? 23 : 21; - cycles += (*clipfunc)(r12_ptr, (r1 > r2) ? r13_ptr : r11_ptr, - r6_ptr); - return cycles; - } - - } else if (r11_check) { - if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r13_ptr, r6_ptr); - cycles += (*clipfunc)(r11_ptr, r12_ptr, r6_ptr); - cycles += 25; - return cycles; - } else { - const int32_t r1 = RAM_SWAPL(r10_ptr[1]); - const int32_t r2 = RAM_SWAPL(r12_ptr[1]); - cycles += (r1 > r2) ? 23 : 21; - cycles += (*clipfunc)(r11_ptr, (r1 > r2) ? r10_ptr : r12_ptr, - r6_ptr); - return cycles; - } - - } else if (r10_check) { - const int32_t r1 = RAM_SWAPL(r11_ptr[1]); - const int32_t r2 = RAM_SWAPL(r13_ptr[1]); - cycles += (r1 > r2) ? 24 : 22; - cycles += (*clipfunc)(r10_ptr, (r1 > r2) ? r11_ptr : r13_ptr, r6_ptr); - return cycles; - - } else { - cycles += 15; - return cycles; - } -} - -/*----------------------------------*/ - -static int Azel_0601F93A(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_x = RAM_SWAPL(r8_ptr[4]); - const int32_t x_max = r6_ptr[3]; - if (r8_x <= x_max) { - return 8; - } - return Azel_0601F950(r8_ptr, r9_ptr, r6_ptr, r8_x, x_max, 6); -} - -static int Azel_0601F948(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_x = RAM_SWAPL(r8_ptr[4]); - const int32_t x_min = r6_ptr[2]; - if (r8_x >= x_min) { - return 10; - } - return Azel_0601F950(r8_ptr, r9_ptr, r6_ptr, r8_x, x_min, 4); -} - -static ALWAYS_INLINE int Azel_0601F950(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_x, const int32_t x_lim, - int base_cycles) -{ - r8_ptr[4] = RAM_SWAPL(x_lim); - const int32_t dx_lim = x_lim - r8_x; - const int32_t dx_r9 = RAM_SWAPL(r9_ptr[4]) - r8_x; - int32_t frac8; - if (UNLIKELY(dx_r9 == 0)) { - frac8 = (dx_lim >= 0) ? 0xFF : 0; - } else { - frac8 = bound((dx_lim << 8) / dx_r9, 0, 255); - } - const int32_t r8_y = RAM_SWAPL(r8_ptr[5]); - const int32_t r9_y = RAM_SWAPL(r9_ptr[5]); - const int32_t new_r8_y = (int16_t)(r8_y + (((r9_y - r8_y) * frac8) >> 8)); - r8_ptr[5] = RAM_SWAPL(new_r8_y); - - return 29 + base_cycles; -} - -/*----------------------------------*/ - -static int Azel_0601F988(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_y = RAM_SWAPL(r8_ptr[5]); - const int32_t y_max = r6_ptr[0]; - if (r8_y <= y_max) { - return 8; - } - return Azel_0601F99E(r8_ptr, r9_ptr, r6_ptr, r8_y, y_max, 6); -} - -static int Azel_0601F996(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_y = RAM_SWAPL(r8_ptr[5]); - const int32_t y_min = r6_ptr[1]; - if (r8_y >= y_min) { - return 10; - } - return Azel_0601F99E(r8_ptr, r9_ptr, r6_ptr, r8_y, y_min, 4); -} - -static ALWAYS_INLINE int Azel_0601F99E(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_y, const int32_t y_lim, - int base_cycles) -{ - r8_ptr[5] = RAM_SWAPL(y_lim); - const int32_t dy_lim = y_lim - r8_y; - const int32_t dy_r9 = RAM_SWAPL(r9_ptr[5]) - r8_y; - int32_t frac8; - if (UNLIKELY(dy_r9 == 0)) { - frac8 = (dy_lim >= 0) ? 0xFF : 0; - } else { - frac8 = bound((dy_lim << 8) / dy_r9, 0, 255); - } - const int32_t r8_x = RAM_SWAPL(r8_ptr[4]); - const int32_t r9_x = RAM_SWAPL(r9_ptr[4]); - const int32_t new_r8_x = (int16_t)(r8_x + (((r9_x - r8_x) * frac8) >> 8)); - r8_ptr[4] = RAM_SWAPL(new_r8_x); - - return 29 + base_cycles; -} - -/*----------------------------------*/ - -static int Azel_0601F9D6(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t *r6_ptr32 = (const int32_t *)r6_ptr; - int32_t r3 = RAM_SWAPL(r8_ptr[1]); - int32_t r0 = (RAM_SWAPL(r6_ptr32[4]) << 8) - r3; - int32_t r2 = RAM_SWAPL(r9_ptr[1]) - r3; - const float frac = (float)r0 / (float)r2; - r2 = RAM_SWAPL(r9_ptr[2]); - r0 = RAM_SWAPL(r8_ptr[2]); - r2 = r0 + (int32_t)((r2 - r0) * frac); - r3 = RAM_SWAPL(r9_ptr[3]); - r0 = RAM_SWAPL(r8_ptr[3]); - r3 = r0 + (int32_t)((r3 - r0) * frac); - const int32_t mult = RAM_SWAPL(r6_ptr32[12]); - r2 = ((int64_t)r2 * (int64_t)mult) >> 32; - r3 = ((int64_t)r3 * (int64_t)mult) >> 32; - r8_ptr[4] = RAM_SWAPL(r2); - r8_ptr[5] = RAM_SWAPL(r3); - - const uint32_t r1 = (r3 > r6_ptr[4]) << 3 - | (r3 < r6_ptr[5]) << 2 - | (r2 > r6_ptr[7]) << 1 - | (r2 < r6_ptr[6]) << 0; - r8_ptr[7] = RAM_SWAPL(r1); - - return 73; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601EE60: Coordinate transformation routine whose second instruction is - * modified from 0x601F1{20,40}; we detect the change here and hint - * 0x601EE62 as a data pointer to avoid having to repeatedly translate the - * block. Incidentally, 0x601F1{20,40} are themselves called from (among - * other places) 0x601F1{50,5E,6C}, which _push and pop_ the _instruction - * word_. Good grief... */ - -static FASTCALL void Azel_0601EE60(SH2State *state) -{ - const uint16_t insn = HRAM_LOADW(0x601EE62, 0); - if (insn>>12 == 0xA) { // BRA instruction - state->R[0] = 0x601EF10; - state->MACL = state->MACH = 0; - state->PC += 6 + ((int32_t)(insn<<20) >> 19); - state->cycles += 4; - } else { - if (insn != 0x6103) { - DMSG("WARNING: Wrong instruction at 0x601EE62 (%04X)", insn); - } - const int32_t *M_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - const int32_t in_x = HRAM_LOADL(0x601EF18, 0); - const int32_t in_y = HRAM_LOADL(0x601EF18, 4); - const int32_t in_z = HRAM_LOADL(0x601EF18, 8); - int16_t out_x = (RAM_SWAPL(M_ptr[ 0]) * in_x - + RAM_SWAPL(M_ptr[ 4]) * in_y - + RAM_SWAPL(M_ptr[ 8]) * in_z) >> 16; - int16_t out_y = (RAM_SWAPL(M_ptr[ 1]) * in_x - + RAM_SWAPL(M_ptr[ 5]) * in_y - + RAM_SWAPL(M_ptr[ 9]) * in_z) >> 16; - int16_t out_z = (RAM_SWAPL(M_ptr[ 2]) * in_x - + RAM_SWAPL(M_ptr[ 6]) * in_y - + RAM_SWAPL(M_ptr[10]) * in_z) >> 16; - HRAM_STOREW(0x601EF10, 0, out_x); - HRAM_STOREW(0x601EF10, 2, out_y); - HRAM_STOREW(0x601EF10, 4, out_z); - state->PC = state->PR; - state->cycles += 58; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601EEE8: Routine that writes a local data array in a loop; optimized - * to prevent JIT overwrite checks from flooding the blacklist array. An - * identical routine is located at 0x601FC6C; this code is used for both. */ - -static FASTCALL void Azel_0601EEE8(SH2State *state) -{ - const int r = (state->R[4]>> 0 & 0xFF) << 8; - const int g = (state->R[4]>> 8 & 0xFF) << 8; - const int b = (state->R[4]>>16 & 0xFF) << 8; - int16_t *out = (int16_t *)HRAM_PTR(((state->PC + 8*2) & -4) + 4 + 0xC*4); - int16_t *top = out + 32*4; - for (; out != top; out += 4) { - out[0] = r; - out[1] = g; - out[2] = b; - } - state->PC = state->PR; - state->cycles += 14 + 32*7; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601F240, 0x601F24C: Calculation function */ - -static ALWAYS_INLINE void Azel_0601F24E(SH2State *state, int32_t r2); - -/*----------------------------------*/ - -static FASTCALL void Azel_0601F240(SH2State *state) -{ - const int32_t r2 = LRAM_LOADL(state->R[4], 0); - state->cycles += 8; - return Azel_0601F24E(state, - ((int64_t)r2 * (int64_t)(int32_t)state->R[8]) >> 16); -} - -static FASTCALL void Azel_0601F24C(SH2State *state) -{ - const int32_t r2 = LRAM_LOADL(state->R[4], 0); - return Azel_0601F24E(state, r2); -} - -static ALWAYS_INLINE void Azel_0601F24E(SH2State *state, int32_t r2) -{ - uint32_t r0; - int32_t r8, r9; - int32_t r1 = HRAM_LOADL(state->R[5], 44); - int32_t r3 = HRAM_LOADL(state->R[6], 20); - if (r1 - r2 >= r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 12; - return; - } - int32_t r10 = HRAM_LOADL(state->R[6], 16); - if (r1 + r2 < r10) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 17; - return; - } - r0 = (r1 + r2 >= r3) << 5 - | (r1 - r2 < r10) << 4; - -#if defined(__mips__) - int32_t temp; - asm(".set push; .set noreorder\n" - "lw %[r8], 36(%[r6])\n" - "lw %[r9], 32(%[r6])\n" - "lw %[r3], 28(%[r5])\n" - "ror %[r8], %[r8], 16\n" - "mult %[r8], %[r1]\n" - "ror %[r9], %[r9], 16\n" - "ror %[r3], %[r3], 16\n" - "mflo %[r8]\n" - "mfhi %[temp]\n" - "mult %[r9], %[r2]\n" - "srl %[r8], %[r8], 16\n" - "ins %[r8], %[temp], 16, 16\n" - "mflo %[r9]\n" - "mfhi %[temp]\n" - "srl %[r9], %[r9], 16\n" - "ins %[r9], %[temp], 16, 16\n" - ".set pop" - : [r3] "=&r" (r3), [r8] "=&r" (r8), [r9] "=&r" (r9), - [temp] "=&r" (temp) - : [r5] "r" (HRAM_PTR(state->R[5])), [r6] "r" (HRAM_PTR(state->R[6])), - [r1] "r" (r1), [r2] "r" (r2) - ); -#else - r3 = HRAM_LOADL(state->R[5], 28); - r8 = HRAM_LOADL(state->R[6], 36); - r9 = HRAM_LOADL(state->R[6], 32); - r8 = ((int64_t)r8 * (int64_t)r1) >> 16; - r9 = ((int64_t)r9 * (int64_t)r2) >> 16; -#endif - if (r8 + r9 < r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 41; - return; - } - if (r8 + r9 < -r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 44; - return; - } - r0 |= (r8 - r9 < r3) << 3 - | (r8 - r9 < -r3) << 2; - -#if defined(__mips__) - asm(".set push; .set noreorder\n" - "lw %[r8], 44(%[r6])\n" - "lw %[r9], 40(%[r6])\n" - "lw %[r3], 12(%[r5])\n" - "ror %[r8], %[r8], 16\n" - "mult %[r8], %[r1]\n" - "ror %[r9], %[r9], 16\n" - "ror %[r3], %[r3], 16\n" - "mflo %[r8]\n" - "mfhi %[temp]\n" - "mult %[r9], %[r2]\n" - "srl %[r8], %[r8], 16\n" - "ins %[r8], %[temp], 16, 16\n" - "mflo %[r9]\n" - "mfhi %[temp]\n" - "srl %[r9], %[r9], 16\n" - "ins %[r9], %[temp], 16, 16\n" - ".set pop" - : [r3] "=&r" (r3), [r8] "=&r" (r8), [r9] "=&r" (r9), - [temp] "=&r" (temp) - : [r5] "r" (HRAM_PTR(state->R[5])), [r6] "r" (HRAM_PTR(state->R[6])), - [r1] "r" (r1), [r2] "r" (r2) - ); -#else - r3 = HRAM_LOADL(state->R[5], 12); - r8 = HRAM_LOADL(state->R[6], 44); - r9 = HRAM_LOADL(state->R[6], 40); - r8 = ((int64_t)r8 * (int64_t)r1) >> 16; - r9 = ((int64_t)r9 * (int64_t)r2) >> 16; -#endif - if (r8 + r9 < r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 69; - return; - } - if (r8 + r9 < -r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 72; - return; - } - r0 |= (r8 - r9 < r3) << 1 - | (r8 - r9 < -r3) << 0; - - state->R[0] = r0; - state->SR &= ~SR_T; - state->PC = state->PR; - state->cycles += 76; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601F30E: Coordinate transform routine */ - -static FASTCALL void Azel_0601F30E(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - const int32_t *r5_ptr = (const int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(state->R[6]); - - /* 0x601F38E */ - - const int32_t r6_x = RAM_SWAPL(r6_ptr[6]); - const int32_t M11 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[0])) >> 12; - const int32_t M12 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[1])) >> 12; - const int32_t M13 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[2])) >> 12; - const int32_t M14 = r6_x * (int32_t)RAM_SWAPL(r5_ptr[3]); - - const int32_t r6_y = -RAM_SWAPL(r6_ptr[7]); - const int32_t M21 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[4])) >> 12; - const int32_t M22 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[5])) >> 12; - const int32_t M23 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[6])) >> 12; - const int32_t M24 = r6_y * (int32_t)RAM_SWAPL(r5_ptr[7]); - - const int32_t M31 = (int32_t)RAM_SWAPL(r5_ptr[ 8]) >> 4; - const int32_t M32 = (int32_t)RAM_SWAPL(r5_ptr[ 9]) >> 4; - const int32_t M33 = (int32_t)RAM_SWAPL(r5_ptr[10]) >> 4; - const int32_t M34 = (int32_t)RAM_SWAPL(r5_ptr[11]) << 8; - - uint32_t counter = RAM_SWAPL(r4_ptr[1]); - const uint32_t in_address = RAM_SWAPL(r4_ptr[2]); - - state->cycles += 111; - - /* 0x601F314 */ - - state->cycles += 8 + 56*counter; - - const int16_t *in = in_address & 0x06000000 - ? (const int16_t *)HRAM_PTR(in_address) - : (const int16_t *)LRAM_PTR(in_address); - int16_t *out = (int16_t *)HRAM_PTR(state->R[7]); - - do { - const int32_t out_x = M11*in[0] + M12*in[1] + M13*in[2] + M14; - const int32_t out_y = M21*in[0] + M22*in[1] + M23*in[2] + M24; - const int32_t out_z = M31*in[0] + M32*in[1] + M33*in[2] + M34; - const float coord_mult = 256.0f / out_z; - out[0] = ifloorf(coord_mult * out_x); - out[1] = ifloorf(coord_mult * out_y); - *(int32_t *)&out[2] = RAM_SWAPL(out_z); - in += 3; - out += 4; - } while (--counter != 0); - - state->R[4] += 12; - state->PC = state->PR; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601F3F4: Coordinate transform routine with boundary checks */ - -static FASTCALL void Azel_0601F3F4(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - const int32_t *r5_ptr = (const int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(state->R[6]); - - /* 0x601F38E */ - - const int32_t r6_x = RAM_SWAPL(r6_ptr[6]); - const int32_t M11 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[0])) >> 12; - const int32_t M12 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[1])) >> 12; - const int32_t M13 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[2])) >> 12; - const int32_t M14 = r6_x * (int32_t)RAM_SWAPL(r5_ptr[3]); - - const int32_t r6_y = -RAM_SWAPL(r6_ptr[7]); - const int32_t M21 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[4])) >> 12; - const int32_t M22 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[5])) >> 12; - const int32_t M23 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[6])) >> 12; - const int32_t M24 = r6_y * (int32_t)RAM_SWAPL(r5_ptr[7]); - - const int32_t M31 = (int32_t)RAM_SWAPL(r5_ptr[ 8]) >> 4; - const int32_t M32 = (int32_t)RAM_SWAPL(r5_ptr[ 9]) >> 4; - const int32_t M33 = (int32_t)RAM_SWAPL(r5_ptr[10]) >> 4; - const int32_t M34 = (int32_t)RAM_SWAPL(r5_ptr[11]) << 8; - - uint32_t counter = RAM_SWAPL(r4_ptr[1]); - const uint32_t in_address = RAM_SWAPL(r4_ptr[2]); - - state->cycles += 111; - - /* 0x601F3FA */ - - state->cycles += 7 + 63*counter; - - const int16_t *in = in_address & 0x06000000 - ? (const int16_t *)HRAM_PTR(in_address) - : (const int16_t *)LRAM_PTR(in_address); - int16_t *out = (int16_t *)HRAM_PTR(state->R[7]); - - do { - const int32_t out_x = M11*in[0] + M12*in[1] + M13*in[2] + M14; - const int32_t out_y = M21*in[0] + M22*in[1] + M23*in[2] + M24; - const int32_t out_z = M31*in[0] + M32*in[1] + M33*in[2] + M34; - *(int32_t *)&out[2] = RAM_SWAPL(out_z); - *(int32_t *)&out[4] = RAM_SWAPL(out_x); - *(int32_t *)&out[6] = RAM_SWAPL(out_y); - uint32_t clip_flags = (out_z >= RAM_SWAPL(r6_ptr[5]) << 8) << 5 - | (out_z < RAM_SWAPL(r6_ptr[4]) << 8) << 4; - if (!(clip_flags & 0x10)) { - const float coord_mult = 256.0f / out_z; - out[0] = ifloorf(coord_mult * out_x); - out[1] = ifloorf(coord_mult * out_y); - clip_flags |= (out[1] > ((const int16_t *)r6_ptr)[4]) << 3 - | (out[1] < ((const int16_t *)r6_ptr)[5]) << 2 - | (out[0] > ((const int16_t *)r6_ptr)[7]) << 1 - | (out[0] < ((const int16_t *)r6_ptr)[6]) << 0; - state->cycles += 19; - } - *(uint32_t *)&out[12] = RAM_SWAPL(clip_flags); - in += 3; - out += 16; - } while (--counter != 0); - - state->R[4] += 12; - state->PC = state->PR; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601FB70: Entry to another self-modified routine like 0x601EE60 */ - -static FASTCALL void Azel_0601FB70(SH2State *state) -{ - const uint16_t insn = HRAM_LOADW(0x601FB72, 0); - if (insn>>12 == 0xA) { // BRA instruction - state->R[0] = 0x601FC94; - state->MACL = state->MACH = 0; - state->PC += 6 + ((int32_t)(insn<<20) >> 19); - state->cycles += 4; - } else { - if (insn != 0x6103) { - DMSG("WARNING: Wrong instruction at 0x601FB72 (%04X)", insn); - } - const int32_t *M_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - const int32_t in_x = HRAM_LOADL(0x601FC9C, 0); - const int32_t in_y = HRAM_LOADL(0x601FC9C, 4); - const int32_t in_z = HRAM_LOADL(0x601FC9C, 8); - int16_t out_x = (RAM_SWAPL(M_ptr[ 0]) * in_x - + RAM_SWAPL(M_ptr[ 4]) * in_y - + RAM_SWAPL(M_ptr[ 8]) * in_z) >> 16; - int16_t out_y = (RAM_SWAPL(M_ptr[ 1]) * in_x - + RAM_SWAPL(M_ptr[ 5]) * in_y - + RAM_SWAPL(M_ptr[ 9]) * in_z) >> 16; - int16_t out_z = (RAM_SWAPL(M_ptr[ 2]) * in_x - + RAM_SWAPL(M_ptr[ 6]) * in_y - + RAM_SWAPL(M_ptr[10]) * in_z) >> 16; - HRAM_STOREW(0x601FC94, 0, out_x); - HRAM_STOREW(0x601FC94, 2, out_y); - HRAM_STOREW(0x601FC94, 4, out_z); - state->PC = state->PR; - state->cycles += 58; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6022E18: Short but difficult-to-optimize routine */ - -static FASTCALL void Azel_06022E18(SH2State *state) -{ - uint32_t cycles = state->cycles; - - int32_t counter = HRAM_LOADL(state->R[4], 4); - if (counter > 0) { - HRAM_STOREL(state->R[4], 4, counter-1); - state->R[0] = HRAM_LOADL(state->R[4], 8); - state->PC = state->PR; - state->cycles = cycles + 9; - return; - } - - uint32_t index = HRAM_LOADL(state->R[4], 0); - int32_t r0 = (int16_t)LRAM_LOADW(state->R[5], index*2); - const uint32_t limit = state->R[6]; - if (index != 0) { - HRAM_STOREL(state->R[4], 4, (r0 & 15) - 1); - r0 &= -16; - cycles += 5; - } else { - HRAM_STOREL(state->R[4], 4, 0); - r0 <<= 4; - } - HRAM_STOREL(state->R[4], 8, r0); - index++; - if (index >= limit) { - index = 0; - cycles++; - } - HRAM_STOREL(state->R[4], 0, index); - state->R[0] = r0; - state->PC = state->PR; - state->cycles = cycles + 21; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6035xxx: Mathematical library routines */ - -static FASTCALL void Azel_06035530(SH2State *state) -{ - if (LIKELY(state->R[5] != 0)) { - state->R[0] = - ((int64_t)(int32_t)state->R[4] << 16) / (int32_t)state->R[5]; - state->cycles += 52; - } else { - state->R[0] = 0; - state->cycles += 7; - } - state->PC = state->PR; -} - -static FASTCALL void Azel_06035552(SH2State *state) -{ - if (LIKELY(state->R[6] != 0)) { - state->R[0] = - ((int64_t)(int32_t)state->R[4] * (int64_t)(int32_t)state->R[5]) - / (int32_t)state->R[6]; - } - state->cycles += 15; - state->PC = state->PR; -} - -static FASTCALL void Azel_0603556C(SH2State *state) -{ -#ifdef __mips__ // GCC's optimizer fails yet again... - - asm(".set push; .set noreorder\n" -# ifdef WORDS_BIGENDIAN // Just for completeness - "lh $v0, 18(%[state])\n" - "lh $v1, 22(%[state])\n" -# else - "lh $v0, 16(%[state])\n" - "lh $v1, 20(%[state])\n" -# endif - "lw $a1, 92(%[state])\n" - "lw $a2, 84(%[state])\n" - "mult $v0, $v1\n" - "lw $v1, 24(%[state])\n" - "addiu $a1, $a1, 15\n" - "sw $a1, 92(%[state])\n" - "sw $a2, 88(%[state])\n" - /* 1 cycle wasted */ - "mflo $v0\n" - "div $zero, $v0, $v1\n" // $zero needed to avoid the div-by-zero check - /* Up to 33 cycles wasted (sigh) */ - "lw $v0, 0(%[state])\n" - "bnezl $v1, 1f\n" - "mflo $v0\n" - "1:\n" - /* This is totally evil, but it works as long as GCC doesn't try to - * set up any stack frames on us, and it lets the routine fit in - * one cache line (barely). */ - "jr $ra\n" - "sw $v0, 0(%[state])\n" - ".set pop" - : "=m" (*state) - : [state] "r" (state) - : "v0", "v1", "a1", "a2", "hi", "lo" - ); - -#else // !__mips__ - - if (LIKELY(state->R[6] != 0)) { - state->R[0] = ((int16_t)state->R[4] * (int16_t)state->R[5]) - / (int32_t)state->R[6]; - } - state->cycles += 15; - state->PC = state->PR; - -#endif -} - -/*----------------------------------*/ - -static FASTCALL void Azel_06035A8C(SH2State *state) -{ - const uint32_t ptr = HRAM_LOADL(0x604AEA4, 0); - HRAM_STOREL(0x604AEA4, 0, ptr + 48); - state->R[4] = ptr; - state->R[5] = ptr + 48; - state->cycles += 9; - return Azel_06035AA0(state); -} - -static FASTCALL void Azel_06035A9C(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - state->cycles += 2; - return Azel_06035AA0(state); -} - -static FASTCALL void Azel_06035AA0(SH2State *state) -{ - const uint32_t *src = (const uint32_t *)HRAM_PTR(state->R[4]); - uint32_t *dest = (uint32_t *)HRAM_PTR(state->R[5]); - - const uint32_t *src_limit = &src[12]; - for (; src < src_limit; src += 4, dest += 4) { - const uint32_t word0 = src[0]; - const uint32_t word1 = src[1]; - const uint32_t word2 = src[2]; - const uint32_t word3 = src[3]; - dest[0] = word0; - dest[1] = word1; - dest[2] = word2; - dest[3] = word3; - } - - state->R[0] = state->R[5]; - state->PC = state->PR; - state->cycles += 27; -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_06035B14_F00_common( - SH2State *state, const int32_t *vector, const int32_t *matrix, - int32_t *out_x_ptr, int32_t *out_y_ptr, int32_t *out_z_ptr); - -static FASTCALL void Azel_06035B14(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - int32_t *r5_ptr = (int32_t *)HRAM_PTR(HRAM_LOADL(0x604AEA4, 0)); - - state->PC = state->PR; - state->cycles += 56; - return Azel_06035B14_F00_common(state, r4_ptr, r5_ptr, - &r5_ptr[3], &r5_ptr[7], &r5_ptr[11]); -} - -static FASTCALL void Azel_06035F00(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - int32_t *r5_ptr = (int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(HRAM_LOADL(0x604AEA4, 0)); - - state->PC = state->PR; - state->cycles += 54; - return Azel_06035B14_F00_common(state, r4_ptr, r6_ptr, - &r5_ptr[0], &r5_ptr[1], &r5_ptr[2]); -} - -static FASTCALL void Azel_06035F04(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - int32_t *r5_ptr = (int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(state->R[6]); - - state->PC = state->PR; - state->cycles += 52; - return Azel_06035B14_F00_common(state, r4_ptr, r6_ptr, - &r5_ptr[0], &r5_ptr[1], &r5_ptr[2]); -} - -static ALWAYS_INLINE void Azel_06035B14_F00_common( - SH2State *state, const int32_t *vector, const int32_t *matrix, - int32_t *out_x_ptr, int32_t *out_y_ptr, int32_t *out_z_ptr) -{ -#ifdef PSP - - int32_t v_0, v_1, v_2, M_0, M_1, M_2, M_3, hi, lo; - asm(".set push; .set noreorder\n" - - "lw %[v_0], 0(%[vector])\n" - "lw %[M_0], 0(%[matrix])\n" - "lw %[v_1], 4(%[vector])\n" - "ror %[v_0], %[v_0], 16\n" - "ror %[M_0], %[M_0], 16\n" - "mult %[v_0], %[M_0]\n" - "lw %[M_1], 4(%[matrix])\n" - "ror %[v_1], %[v_1], 16\n" - "ror %[M_1], %[M_1], 16\n" - "madd %[v_1], %[M_1]\n" - "lw %[v_2], 8(%[vector])\n" - "lw %[M_2], 8(%[matrix])\n" - "lw %[M_3], 12(%[matrix])\n" - "ror %[v_2], %[v_2], 16\n" - "ror %[M_2], %[M_2], 16\n" - "madd %[v_2], %[M_2]\n" - "lw %[M_0], 16(%[matrix])\n" - "lw %[M_1], 20(%[matrix])\n" - "lw %[M_2], 24(%[matrix])\n" - "ror %[M_3], %[M_3], 16\n" - "ror %[M_0], %[M_0], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - - "mult %[v_0], %[M_0]\n" - "ror %[M_1], %[M_1], 16\n" - "srl %[lo], %[lo], 16\n" - "ins %[lo], %[hi], 16, 16\n" - "madd %[v_1], %[M_1]\n" - "ror %[M_2], %[M_2], 16\n" - "addu %[lo], %[M_3], %[lo]\n" - "lw %[M_3], 28(%[matrix])\n" - "ror %[lo], %[lo], 16\n" - "sw %[lo], 0(%[out_x_ptr])\n" - "madd %[v_2], %[M_2]\n" - "lw %[M_0], 32(%[matrix])\n" - "lw %[M_1], 36(%[matrix])\n" - "lw %[M_2], 40(%[matrix])\n" - "ror %[M_3], %[M_3], 16\n" - "ror %[M_0], %[M_0], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - - "mult %[v_0], %[M_0]\n" - "ror %[M_1], %[M_1], 16\n" - "srl %[lo], %[lo], 16\n" - "ins %[lo], %[hi], 16, 16\n" - "madd %[v_1], %[M_1]\n" - "ror %[M_2], %[M_2], 16\n" - "addu %[lo], %[M_3], %[lo]\n" - "lw %[M_3], 44(%[matrix])\n" - "ror %[lo], %[lo], 16\n" - "sw %[lo], 0(%[out_y_ptr])\n" - "madd %[v_2], %[M_2]\n" - "ror %[M_3], %[M_3], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "srl %[lo], %[lo], 16\n" - "ins %[lo], %[hi], 16, 16\n" - "addu %[lo], %[M_3], %[lo]\n" - "ror %[lo], %[lo], 16\n" - "sw %[lo], 0(%[out_z_ptr])\n" - - ".set pop" - : "=m" (*out_x_ptr), "=m" (*out_y_ptr), "=m" (*out_z_ptr), - [v_0] "=&r" (v_0), [v_1] "=&r" (v_1), [v_2] "=&r" (v_2), - [M_0] "=&r" (M_0), [M_1] "=&r" (M_1), [M_2] "=&r" (M_2), - [M_3] "=&r" (M_3), [hi] "=&r" (hi), [lo] "=&r" (lo) - : [vector] "r" (vector), [matrix] "r" (matrix), - [out_x_ptr] "r" (out_x_ptr), [out_y_ptr] "r" (out_y_ptr), - [out_z_ptr] "r" (out_z_ptr) - : "hi", "lo" - ); - -#else // !PSP - - const int32_t temp0 = - ((int64_t)RAM_SWAPL(vector[0]) * (int64_t)RAM_SWAPL(matrix[0]) - + (int64_t)RAM_SWAPL(vector[1]) * (int64_t)RAM_SWAPL(matrix[1]) - + (int64_t)RAM_SWAPL(vector[2]) * (int64_t)RAM_SWAPL(matrix[2]) - ) >> 16; - *out_x_ptr = RAM_SWAPL(RAM_SWAPL(matrix[3]) + temp0); - - const int32_t temp1 = - ((int64_t)RAM_SWAPL(vector[0]) * (int64_t)RAM_SWAPL(matrix[4]) - + (int64_t)RAM_SWAPL(vector[1]) * (int64_t)RAM_SWAPL(matrix[5]) - + (int64_t)RAM_SWAPL(vector[2]) * (int64_t)RAM_SWAPL(matrix[6]) - ) >> 16; - *out_y_ptr = RAM_SWAPL(RAM_SWAPL(matrix[7]) + temp1); - - const int32_t temp2 = - ((int64_t)RAM_SWAPL(vector[0]) * (int64_t)RAM_SWAPL(matrix[8]) - + (int64_t)RAM_SWAPL(vector[1]) * (int64_t)RAM_SWAPL(matrix[9]) - + (int64_t)RAM_SWAPL(vector[2]) * (int64_t)RAM_SWAPL(matrix[10]) - ) >> 16; - *out_z_ptr = RAM_SWAPL(RAM_SWAPL(matrix[11]) + temp2); - -#endif // PSP -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_06035xxx_rotate_common( - int angle, int32_t *r5_ptr, unsigned int x_idx, unsigned int y_idx, - int invert); - -static FASTCALL void Azel_06035C18(SH2State *state) -{ - const int16_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int16_t *)HRAM_PTR(state->R[4]) - : (const int16_t *)LRAM_PTR(state->R[4]); - const uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - - if (r4_ptr[4] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[4] & 0xFFF, r5_ptr, 0, 1, 0); - } - if (r4_ptr[2] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[2] & 0xFFF, r5_ptr, 0, 2, 1); - } - if (r4_ptr[0] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[0] & 0xFFF, r5_ptr, 1, 2, 0); - } - - state->PC = state->PR; - state->cycles += 290; -} - -static FASTCALL void Azel_06035C3C(SH2State *state) -{ - const int16_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int16_t *)HRAM_PTR(state->R[4]) - : (const int16_t *)LRAM_PTR(state->R[4]); - const uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - - if (r4_ptr[2] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[2] & 0xFFF, r5_ptr, 0, 2, 1); - } - if (r4_ptr[0] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[0] & 0xFFF, r5_ptr, 1, 2, 0); - } - if (r4_ptr[4] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[4] & 0xFFF, r5_ptr, 0, 1, 0); - } - - state->PC = state->PR; - state->cycles += 290; -} - -static FASTCALL void Azel_06035C60(SH2State *state) -{ - const int16_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int16_t *)HRAM_PTR(state->R[4]) - : (const int16_t *)LRAM_PTR(state->R[4]); - const uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - - if (r4_ptr[2] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[4] & 0xFFF, r5_ptr, 0, 1, 0); - } - if (r4_ptr[1] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[2] & 0xFFF, r5_ptr, 0, 2, 1); - } - if (r4_ptr[0] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[0] & 0xFFF, r5_ptr, 1, 2, 0); - } - - state->PC = state->PR; - state->cycles += 290; -} - -static FASTCALL void Azel_06035C84(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035C96(state); -} - -static FASTCALL void Azel_06035C90(SH2State *state) -{ - state->R[4] >>= 16; - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035C96(state); -} - -static FASTCALL void Azel_06035C96(SH2State *state) -{ - const int32_t angle = state->R[4] & 0xFFF; - int32_t *r5_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - Azel_06035xxx_rotate_common(angle, r5_ptr, 1, 2, 0); - state->PC = state->PR; - state->cycles += 88; -} - -static FASTCALL void Azel_06035D24(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035D36(state); -} - -static FASTCALL void Azel_06035D30(SH2State *state) -{ - state->R[4] >>= 16; - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035D36(state); -} - -static FASTCALL void Azel_06035D36(SH2State *state) -{ - const int32_t angle = state->R[4] & 0xFFF; - int32_t *r5_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - Azel_06035xxx_rotate_common(angle, r5_ptr, 0, 2, 1); - state->PC = state->PR; - state->cycles += 96; -} - -static FASTCALL void Azel_06035DD4(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035DE6(state); -} - -static FASTCALL void Azel_06035DE0(SH2State *state) -{ - state->R[4] >>= 16; - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035DE6(state); -} - -static FASTCALL void Azel_06035DE6(SH2State *state) -{ - const int32_t angle = state->R[4] & 0xFFF; - int32_t *r5_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - Azel_06035xxx_rotate_common(angle, r5_ptr, 0, 1, 0); - state->PC = state->PR; - state->cycles += 87; -} - -static ALWAYS_INLINE void Azel_06035xxx_rotate_common( - int angle, int32_t *r5_ptr, unsigned int x_idx, unsigned int y_idx, - int invert) -{ - const int32_t *sin_table = (const int32_t *)LRAM_PTR(0x216660); - const int32_t *cos_table = (const int32_t *)LRAM_PTR(0x217660); - const int32_t sin_angle = invert ? -RAM_SWAPL(sin_table[angle]) - : +RAM_SWAPL(sin_table[angle]); - const int32_t cos_angle = RAM_SWAPL(cos_table[angle]); - int32_t new_x, new_y; - -#ifdef PSP - - int32_t old_x, old_y; - - asm(".set push; .set noreorder\n" - - "lw %[old_x], 0+%[x_ofs](%[r5_ptr])\n" - "lw %[old_y], 0+%[y_ofs](%[r5_ptr])\n" - "ror %[old_x], %[old_x], 16\n" - "mult %[old_x], %[cos_angle]\n" - "ror %[old_y], %[old_y], 16\n" - "madd %[old_y], %[sin_angle]\n" - "mfhi %[new_y]\n" - "mflo %[new_x]\n" - "mult %[old_x], %[nsin_angle]\n" - "lw %[old_x], 16+%[x_ofs](%[r5_ptr])\n" - /* We want ROR(HI<<16 | LO>>16, 16), but that's equivalent - * to (HI & 0xFFFF) | (LO & 0xFFFF0000), which we can do - * with a single INS instruction. */ - "ins %[new_x], %[new_y], 0, 16\n" - "sw %[new_x], 0+%[x_ofs](%[r5_ptr])\n" - "ror %[old_x], %[old_x], 16\n" - "madd %[old_y], %[cos_angle]\n" - "lw %[old_y], 16+%[y_ofs](%[r5_ptr])\n" - "ror %[old_y], %[old_y], 16\n" - "mfhi %[new_x]\n" - "mflo %[new_y]\n" - - "mult %[old_x], %[cos_angle]\n" - "ins %[new_y], %[new_x], 0, 16\n" - "sw %[new_y], 0+%[y_ofs](%[r5_ptr])\n" - "madd %[old_y], %[sin_angle]\n" - "mfhi %[new_y]\n" - "mflo %[new_x]\n" - "mult %[old_x], %[nsin_angle]\n" - "lw %[old_x], 32+%[x_ofs](%[r5_ptr])\n" - "ins %[new_x], %[new_y], 0, 16\n" - "sw %[new_x], 16+%[x_ofs](%[r5_ptr])\n" - "ror %[old_x], %[old_x], 16\n" - "madd %[old_y], %[cos_angle]\n" - "lw %[old_y], 32+%[y_ofs](%[r5_ptr])\n" - "ror %[old_y], %[old_y], 16\n" - "mfhi %[new_x]\n" - "mflo %[new_y]\n" - - "mult %[old_x], %[cos_angle]\n" - "ins %[new_y], %[new_x], 0, 16\n" - "sw %[new_y], 16+%[y_ofs](%[r5_ptr])\n" - "madd %[old_y], %[sin_angle]\n" - "mfhi %[new_y]\n" - "mflo %[new_x]\n" - "mult %[old_x], %[nsin_angle]\n" - "ins %[new_x], %[new_y], 0, 16\n" - "sw %[new_x], 32+%[x_ofs](%[r5_ptr])\n" - "madd %[old_y], %[cos_angle]\n" - "mfhi %[new_x]\n" - "mflo %[new_y]\n" - "ins %[new_y], %[new_x], 0, 16\n" - "sw %[new_y], 32+%[y_ofs](%[r5_ptr])\n" - - ".set pop" - : "=m" (r5_ptr[0*4 + x_idx]), "=m" (r5_ptr[0*4 + y_idx]), - "=m" (r5_ptr[1*4 + x_idx]), "=m" (r5_ptr[1*4 + y_idx]), - "=m" (r5_ptr[2*4 + x_idx]), "=m" (r5_ptr[2*4 + y_idx]), - [new_x] "=&r" (new_x), [new_y] "=&r" (new_y), - [old_x] "=&r" (old_x), [old_y] "=&r" (old_y) - : [sin_angle] "r" (sin_angle), [cos_angle] "r" (cos_angle), - [nsin_angle] "r" (-sin_angle), [r5_ptr] "r" (r5_ptr), - [x_ofs] "i" (x_idx*4), [y_ofs] "i" (y_idx*4) - : "hi", "lo" - ); - -#else // !PSP - - #define DOT2(x1,y1,x2,y2) \ - (((int64_t)(x1) * (int64_t)(x2) + (int64_t)(y1) * (int64_t)(y2)) >> 16) - #define ROTATE(index) \ - new_x = DOT2(RAM_SWAPL(r5_ptr[index*4 + x_idx]), \ - RAM_SWAPL(r5_ptr[index*4 + y_idx]), \ - cos_angle, sin_angle); \ - new_y = DOT2(RAM_SWAPL(r5_ptr[index*4 + x_idx]), \ - RAM_SWAPL(r5_ptr[index*4 + y_idx]), \ - -sin_angle, cos_angle); \ - r5_ptr[index*4 + x_idx] = RAM_SWAPL(new_x); \ - r5_ptr[index*4 + y_idx] = RAM_SWAPL(new_y) - - ROTATE(0); - ROTATE(1); - ROTATE(2); - - #undef DOT2 - #undef ROTATE - -#endif -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_06035Exx_scale_common( - int32_t scale, int32_t *r5_ptr); - -static FASTCALL void Azel_06035E70(SH2State *state) -{ - uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - Azel_06035Exx_scale_common(state->R[4], r5_ptr+0); - state->PC = state->PR; - state->cycles += 28; -} - -static FASTCALL void Azel_06035EA0(SH2State *state) -{ - uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - Azel_06035Exx_scale_common(state->R[4], r5_ptr+1); - state->PC = state->PR; - state->cycles += 28; -} - -static FASTCALL void Azel_06035ED0(SH2State *state) -{ - uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - Azel_06035Exx_scale_common(state->R[4], r5_ptr+2); - state->PC = state->PR; - state->cycles += 28; -} - -static ALWAYS_INLINE void Azel_06035Exx_scale_common( - int32_t scale, int32_t *r5_ptr) -{ -#ifdef PSP - - int32_t a, b, c, hi, lo; - - asm(".set push; .set noreorder\n" - - "lw %[a], 0(%[r5_ptr])\n" - "lw %[b], 16(%[r5_ptr])\n" - "lw %[c], 32(%[r5_ptr])\n" - "ror %[a], %[a], 16\n" - "mult %[a], %[scale]\n" - "ror %[b], %[b], 16\n" - "ror %[c], %[c], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "mult %[b], %[scale]\n" - // As with rotation, we take a shortcut for ROR(HI<<16 | LO>>16, 16). - "ins %[lo], %[hi], 0, 16\n" - "sw %[lo], 0(%[r5_ptr])\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "mult %[c], %[scale]\n" - "ins %[lo], %[hi], 0, 16\n" - "sw %[lo], 16(%[r5_ptr])\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "ins %[lo], %[hi], 0, 16\n" - "sw %[lo], 32(%[r5_ptr])\n" - - ".set pop" - : "=m" (r5_ptr[0]), "=m" (r5_ptr[4]), "=m" (r5_ptr[8]), - [a] "=&r" (a), [b] "=&r" (b), [c] "=&r" (c), - [hi] "=&r" (hi), [lo] "=&r" (lo) - : [scale] "r" (scale), [r5_ptr] "r" (r5_ptr) - : "hi", "lo" - ); - -#else // !PSP - - r5_ptr[0] = RAM_SWAPL(((int64_t)RAM_SWAPL(r5_ptr[0]) * scale) >> 16); - r5_ptr[4] = RAM_SWAPL(((int64_t)RAM_SWAPL(r5_ptr[4]) * scale) >> 16); - r5_ptr[8] = RAM_SWAPL(((int64_t)RAM_SWAPL(r5_ptr[8]) * scale) >> 16); - -#endif -} - -/*-----------------------------------------------------------------------*/ - -/* 0x60360F0: Delay routine (not automatically foldable due to the BF) */ - -static FASTCALL void Azel_060360F0(SH2State *state) -{ - state->PC = state->PR; - state->cycles += state->R[4]*4 + 1; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x603A22C: Wrapper for 0x603A242 that jumps in with a BRA */ - -static int Azel_0603A22C_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[0] == 0xA009 // bra 0x603A242 - && fetch[1] == 0xE700 // mov #0, r7 - ? 2 : 0; -} - -static FASTCALL void Azel_0603A22C(SH2State *state) -{ - state->R[7] = 0; - return Azel_0603A242(state); -} - -/*----------------------------------*/ - -/* 0x603A242: CD command execution routine */ - -static int Azel_0603A242_state = 0; -static int Azel_0603A242_cmd51_count = 0; // Count of sequential 0x51 commands - -static FASTCALL void Azel_0603A242(SH2State *state) -{ - if (Azel_0603A242_state == 0) { - const uint32_t r4 = state->R[4]; - uint16_t *ptr_6053278 = (uint16_t *)HRAM_PTR(0x6053278); - *ptr_6053278 |= Cs2ReadWord(0x90008); - if ((*ptr_6053278 & r4) != r4) { - state->R[0] = -1; - state->PC = state->PR; - state->cycles += 77; - return; - } - if (!(*ptr_6053278 & 1)) { - state->R[0] = -2; - state->PC = state->PR; - state->cycles += 82; - return; - } - - Cs2WriteWord(0x90008, ~(r4 | 1)); - *ptr_6053278 &= ~1; - const uint32_t r5 = state->R[5]; - uintptr_t r5_base = (uintptr_t)direct_pages[r5>>19]; - const uint16_t *r5_ptr = (const uint16_t *)(r5_base + r5); - Cs2WriteWord(0x90018, r5_ptr[0]); - Cs2WriteWord(0x9001C, r5_ptr[1]); - Cs2WriteWord(0x90020, r5_ptr[2]); - Cs2WriteWord(0x90024, r5_ptr[3]); - state->cycles += 88; - Azel_0603A242_state = 1; - if (r5_ptr[0]>>8 == 0x51) { - Azel_0603A242_cmd51_count++; - } else if (r5_ptr[0]>>8 != 0) { // Command 0x00 doesn't reset the count - Azel_0603A242_cmd51_count = 0; - } - return; - } - - if (Azel_0603A242_state == 1) { - uint32_t status = (uint16_t)Cs2ReadWord(0x90008); - if (status & 1) { - state->cycles += 23; - Azel_0603A242_state = 2; - } else { - /* Technically a timeout loop, but we assume no timeouts */ - state->cycles = state->cycle_limit; - } - return; - } - - if (Azel_0603A242_state == 2) { - const uint32_t r6 = state->R[6]; - uintptr_t r6_base = (uintptr_t)direct_pages[r6>>19]; - uint16_t *r6_ptr = (uint16_t *)(r6_base + r6); - const unsigned int CR1 = Cs2ReadWord(0x90018); - const unsigned int CR2 = Cs2ReadWord(0x9001C); - const unsigned int CR3 = Cs2ReadWord(0x90020); - const unsigned int CR4 = Cs2ReadWord(0x90024); - if (Azel_0603A242_cmd51_count >= 0 && CR4 == 0) { - /* We're probably waiting for a sector and it hasn't arrived - * yet, so consume enough cycles to get us to that next sector. - * But be careful we don't wait an extra sector if the current - * sector finished reading between executing the CS2 command - * and retrieving the delay period. */ - const unsigned int usec_left = Cs2GetTimeToNextSector(); - if (usec_left > 0 && usec_left < (1000000/(75*2))*9/10) { - uint32_t cycles_left = 0; - if (yabsys.CurSH2FreqType == CLKTYPE_26MHZ) { - cycles_left = (26847 * usec_left) / 1000; - } else { - cycles_left = (28637 * usec_left) / 1000; - } - state->cycles += cycles_left; - } - } - r6_ptr[0] = CR1; - r6_ptr[1] = CR2; - r6_ptr[2] = CR3; - r6_ptr[3] = CR4; - uint16_t *dest = (uint16_t *)HRAM_PTR(0x605329C); - *((uint8_t *)dest + 1) = CR1>>8; - if (state->R[7]) { - dest[2] = CR1<<8 | CR2>>8; - dest[3] = CR2<<8 | CR3>>8; - dest[4] = CR3 & 0xFF; - dest[5] = CR4; - } - state->R[0] = 0; -#if defined(TRACE) || defined(TRACE_STEALTH) || defined(TRACE_LITE) - state->R[1] = ~0xF0; - state->R[2] = 0; - state->R[3] = ~0xF0; - state->R[4] = state->R[15] - 12; - state->R[5] = 0x605329C; - state->SR &= ~SR_T; -#endif - state->PC = state->PR; - state->cycles += 121; - Azel_0603A242_state = 0; - return; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x603ABE0: The sole purpose of this routine seems to be to copy the - * first sample in a streaming audio ring buffer over the last sample. - * I don't know whether this is to work around an idiosyncrasy of the real - * SCSP or what, but it causes glitches when using the ME because we try - * to read the sample from an uncached address after writing it to a - * cached address. In any case, the function (as applied to audio data) - * is meaningless for emulation, so we null it out entirely. */ - -static FASTCALL void Azel_0603ABE0(SH2State *state) -{ - if ((MappedMemoryReadLong(state->R[4]+0xA0) & 0x1FF00000) == 0x05A00000) { - state->PC = state->PR; - state->cycles += 23; - return; - } - /* It's not touching sound RAM, so it must be doing something else. - * Let it run normally. */ - state->R[0] = 0xEF; - state->PC += 2; - state->cycles++; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x603DD6E: CD read routine (actually a generalized copy routine, but - * doesn't seem to be used for anything else) */ - -static FASTCALL void Azel_0603DD6E(SH2State *state) -{ - int32_t len = MappedMemoryReadLong(state->R[15]); - uint32_t dest = state->R[4]; - - if (UNLIKELY(state->R[5] != 1) - || UNLIKELY(state->R[6] != 0x25818000) - || UNLIKELY(state->R[7] != 0) - || UNLIKELY(len <= 0) - || UNLIKELY((len & 3) != 0) - ) { - state->SR &= ~SR_T; - state->SR |= (state->R[4] == 0) << SR_T_SHIFT; - state->PC += 2; - state->cycles += 1; - return; - } - - state->PC = state->PR; - state->cycles += 30 + len*2; - - const uint32_t dest_page = dest>>19; - uint8_t *dest_base; - - dest_base = direct_pages[dest_page]; - if (dest_base) { - Cs2RapidCopyT2(dest_base + dest, len/4); - sh2_write_notify(dest, len); - return; - } - - dest_base = byte_direct_pages[dest_page]; - if (dest_base) { - Cs2RapidCopyT1(dest_base + dest, len/4); - return; - } - - if ((dest & 0x1FF00000) == 0x05A00000) { - Cs2RapidCopyT2(SoundRam + (dest & 0x7FFFF), len/4); - M68KWriteNotify(dest & 0x7FFFF, len); - return; - } - - for (; len > 0; len -= 4, dest += 4) { - const uint32_t word = MappedMemoryReadLong(0x25818000); - MappedMemoryWriteLong(dest, word); - } -} - -/*************************************************************************/ - -#endif // ENABLE_JIT - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/satopt-sh2.h b/yabause/src/psp/satopt-sh2.h deleted file mode 100644 index 3969b1d315..0000000000 --- a/yabause/src/psp/satopt-sh2.h +++ /dev/null @@ -1,61 +0,0 @@ -/* src/psp/satopt-sh2.h: Saturn-specific SH-2 optimization header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_SATOPT_SH2_H -#define PSP_SATOPT_SH2_H - -/*************************************************************************/ - -/** - * saturn_optimize_sh2: Search for and return, if available, a native - * implementation of the SH-2 routine starting at the given address. - * - * [Parameters] - * state: Processor state block pointer - * address: Address from which to translate - * fetch: Pointer corresponding to "address" from which opcodes can - * be fetched - * func_ret: Pointer to variable to receive address of native function - * implementing this routine if return value is nonzero - * for_fold: Nonzero if the callback is being called to look up a - * subroutine for folding, zero if being called for a - * full block translation - * [Return value] - * Length of translated block in instructions (nonzero) if optimized - * code was generated, else zero - */ -extern unsigned int saturn_optimize_sh2(SH2State *state, uint32_t address, - const uint16_t *fetch, - SH2NativeFunctionPointer *func_ret, - int for_fold); - -/*************************************************************************/ - -#endif // PSP_SATOPT_SH2_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-core.i b/yabause/src/psp/sh2-core.i deleted file mode 100644 index be25488277..0000000000 --- a/yabause/src/psp/sh2-core.i +++ /dev/null @@ -1,4008 +0,0 @@ -/* src/psp/sh2-core.i: SH-2 instruction decoding core for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * This file is intended to be #included as part of a source file that - * processes SH-2 instructions. It defines the function: - * static inline unsigned int decode_insn(...) - * which decodes one instruction, performs actions to implement the - * instruction, and returns the instruction's opcode. The parameter list - * is set by the caller using - * #define DECODE_INSN_PARAMS ... - * and should be "void" (without quotes) if no parameters are used. The - * caller may also #define DECODE_INSN_INLINE to any inline-related - * keyword, including ALWAYS_INLINE or NOINLINE; if not defined, no such - * keyword will be used. - * - * The following identifiers must be either defined as macros or passed to - * decode_insn() as parameters: - * uint32_t initial_PC; // Address of the first instruction in the - * // current block, if OPTIMIZE_IDLE is defined - * uint32_t state_reg; // RTL register holding the state block pointer - * uint32_t cur_PC; // Address of the instruction to be decoded - * uint16_t *fetch; // Pointer to instruction to decode (or NULL if - * // direct access is not possible) - * - * Each instruction is decoded into a series of "micro-ops", which should - * be defined as macros before this file is included. See sh2.c or - * sh2-interpret.c for the micro-ops used. - * - * Note that while the decoder generally attempts to maintain SSA (static - * single assignment) form for all registers, optimization of state block - * fields into long-lived registers requires that every path through - * conditional code assign the same register to a given state block field. - * Since a proper SSA implementation could require many SELECT operations - * and temporary registers, leading to inefficient code (the optimization - * of which would be too time-consuming), we intentionally break SSA form - * in such cases, conditionally reassigning new values to state block - * mirror registers. Such cases are noted throughout the code. - */ - -/*************************************************************************/ - -/* Local convenience macros for defining and loading SH-2 registers */ - -#define GET_REG(name,reg,field,mask) \ - DECLARE_REG(name); \ - if ((REG_GETKNOWN((reg)) & (mask)) == (mask)) { \ - ALLOC_REG(name); \ - MOVEI(name, REG_GETVALUE((reg)) & (mask)); \ - } else { \ - LOAD_STATE_ALLOC(name, field); \ - } -#define GET_R0 GET_REG(R0, REG_R(0), R[0], 0xFFFFFFFF) -#define GET_R0_W GET_REG(R0, REG_R(0), R[0], 0xFFFF) -#define GET_R0_B GET_REG(R0, REG_R(0), R[0], 0xFF) -#define GET_R15 GET_REG(R15, REG_R(15), R[15], 0xFFFFFFFF) -#define GET_Rn GET_REG(Rn, REG_R(n), R[n], 0xFFFFFFFF) -#define GET_Rm GET_REG(Rm, REG_R(m), R[m], 0xFFFFFFFF) -#define GET_Rm_W GET_REG(Rm, REG_R(m), R[m], 0xFFFF) -#define GET_Rm_B GET_REG(Rm, REG_R(m), R[m], 0xFF) -#define GET_GBR GET_REG(GBR, REG_GBR, GBR, 0xFFFFFFFF) -/* These are generally unknown, so don't waste time on checking them */ -#define GET_SR FLUSH_STATE_SR_T(); \ - DECLARE_REG(SR); LOAD_STATE_ALLOC(SR, SR) -#define GET_SR_T DECLARE_REG(T); LOAD_STATE_SR_T (T) -#define GET_VBR DECLARE_REG(VBR); LOAD_STATE_ALLOC(VBR, VBR) -#define GET_MACH DECLARE_REG(MACH); LOAD_STATE_ALLOC(MACH, MACH) -#define GET_MACL DECLARE_REG(MACL); LOAD_STATE_ALLOC(MACL, MACL) -#define GET_PR DECLARE_REG(PR); LOAD_STATE_ALLOC(PR, PR) - -/* MACH/MACL may be overwritten in the same register by the MAC.[WL] insns, - * so STS MAC uses these macros to force creation of a new register */ -#define GET_MACH_COPY DEFINE_REG(MACH); LOAD_STATE_COPY(MACH, MACH) -#define GET_MACL_COPY DEFINE_REG(MACL); LOAD_STATE_COPY(MACL, MACL) - -/* Versions used by load/store macros to retain the cached offset */ -#define GET_REG_KEEPOFS(name,field) \ - DECLARE_REG(name); LOAD_STATE_ALLOC_KEEPOFS(name, field) -#define GET_R0_KEEPOFS GET_REG_KEEPOFS(R0, R[0]) -#define GET_R15_KEEPOFS GET_REG_KEEPOFS(R15, R[15]) -#define GET_Rn_KEEPOFS GET_REG_KEEPOFS(Rn, R[n]) -#define GET_Rm_KEEPOFS GET_REG_KEEPOFS(Rm, R[m]) -#define GET_GBR_KEEPOFS GET_REG_KEEPOFS(GBR, GBR) - -/* Local convenience macro for moving a value from one SH-2 register to - * another. If the source uses a fixed RTL register (e.g. due to loop - * optimization) but the destination does not, the destination will end up - * sharing the source register, causing the destination's value to - * improperly change when the source is modified. Pass the relevant SH-2 - * register name (R[m], GBR, etc.) as the macro parameter. */ - -#define COPY_FROM_Rn(dest) \ - DECLARE_REG(value); \ - if (!STATE_CACHE_FIXED_REG_WRITABLE(dest)) { \ - STATE_CACHE_CLEAR_FIXED_REG(dest); \ - } \ - if (STATE_CACHE_FIXED_REG(R[n]) && !STATE_CACHE_FIXED_REG(dest)) { \ - ALLOC_REG(value); \ - LOAD_STATE_COPY(value, R[n]); \ - } else { \ - LOAD_STATE_ALLOC(value, R[n]); \ - } \ - if (offsetof(SH2State,SR) == offsetof(SH2State,dest)) { \ - RESET_STATE_SR_T(); \ - } \ - STORE_STATE(dest, value) - -#define COPY_TO_Rn(src) \ - DECLARE_REG(value); \ - if (offsetof(SH2State,SR) == offsetof(SH2State,src)) { \ - FLUSH_STATE_SR_T(); \ - } \ - if (!STATE_CACHE_FIXED_REG_WRITABLE(R[n])) { \ - STATE_CACHE_CLEAR_FIXED_REG(R[n]); \ - } \ - if (STATE_CACHE_FIXED_REG(src) && !STATE_CACHE_FIXED_REG(R[n])) { \ - ALLOC_REG(value); \ - LOAD_STATE_COPY(value, src); \ - } else { \ - LOAD_STATE_ALLOC(value, src); \ - } \ - STORE_STATE(R[n], value) - -/* Local convenience macro for creating result registers to be stored in a - * state block field */ - -#define DEFINE_RESULT_REG(name,field) \ - DECLARE_REG(name); \ - do { \ - name = STATE_CACHE_FIXED_REG(field); \ - if (name && !STATE_CACHE_FIXED_REG_WRITABLE(field)) { \ - STATE_CACHE_CLEAR_FIXED_REG(field); \ - name = 0; \ - } \ - if (!name) { \ - ALLOC_REG(name); \ - } \ - } while (0) - -/* Local convenience macros for storing values to SH-2 registers */ - -#define SET_R0(reg) STORE_STATE(R[0], (reg)) -#define SET_R15(reg) STORE_STATE(R[15],(reg)) -#define SET_Rn(reg) STORE_STATE(R[n], (reg)) -#define SET_Rm(reg) STORE_STATE(R[m], (reg)) -#define SET_SR(reg) RESET_STATE_SR_T(); STORE_STATE(SR, (reg)) -#define SET_SR_T(reg) STORE_STATE_SR_T ((reg)) -#define SET_GBR(reg) STORE_STATE(GBR, (reg)) -#define SET_VBR(reg) STORE_STATE(VBR, (reg)) -#define SET_MACH(reg) STORE_STATE(MACH, (reg)) -#define SET_MACL(reg) STORE_STATE(MACL, (reg)) -#define SET_PR(reg) STORE_STATE(PR, (reg)) -#define SET_PC(reg) STORE_STATE(PC, (reg)) - -/* Set PC to a known value */ -#define SET_PC_KNOWN(value) STORE_STATE_PC((value)) - -/* Local convenience macros for adding constants to SH-2 registers */ - -#define ADDI_R0(imm) ADDI_STATE(R[0], (imm), R0) -#define ADDI_R15(imm) ADDI_STATE(R[15], (imm), R15) -#define ADDI_Rn(imm) ADDI_STATE(R[n], (imm), Rn) -#define ADDI_Rm(imm) ADDI_STATE(R[m], (imm), Rm) -#define ADDI_R0_NOREG(imm) ADDI_STATE_NOREG(R[0], (imm)) -#define ADDI_R15_NOREG(imm) ADDI_STATE_NOREG(R[15], (imm)) -#define ADDI_Rn_NOREG(imm) ADDI_STATE_NOREG(R[n], (imm)) -#define ADDI_Rm_NOREG(imm) ADDI_STATE_NOREG(R[m], (imm)) - -/* Local convenience macro for updating the cycle count */ - -#define ADD_CYCLES() do { \ - if (cur_cycles > 0) { \ - ADDI_STATE_NOREG(cycles, cur_cycles); \ - cur_cycles = 0; \ - } \ -} while (0) - -/*-----------------------------------------------------------------------*/ - -/* Local convenience macros for loading or storing values with various - * addressing modes */ - -/* Increment/decrement amounts */ -#define INCDEC_B 1 -#define INCDEC_W 2 -#define INCDEC_L 4 - -/*----------------------------------*/ - -#define LOAD_Rm(size,dest) LOAD_disp_Rm(size, dest, 0) - -#define LOAD_disp_Rm(size,dest,offset) \ - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(m)) + (offset)); \ - } else { \ - SH2_LOAD_REG_##size(dest, m, (offset), 0); \ - } - -/* Only treat R0 as an offset if it's "small" -- otherwise we might end up - * treating a small value in Rm as a pointer */ -#define LOAD_R0_Rm(size,dest) \ - if (REG_GETKNOWN(REG_R(0)) == 0xFFFFFFFF \ - && REG_GETVALUE(REG_R(0)) + 0x8000 < 0x10000 \ - ) { \ - SH2_LOAD_REG_##size(dest, m, REG_GETVALUE(REG_R(0)), 0); \ - } else { \ - GET_R0_KEEPOFS; \ - GET_Rm_KEEPOFS; \ - DEFINE_REG(address); \ - ADD(address, R0, Rm); \ - const int32_t offset = STATE_CACHE_OFFSET(R[0]) \ - + STATE_CACHE_OFFSET(R[m]); \ - DECLARE_REG(offset_addr); \ - if (offset) { \ - ALLOC_REG(offset_addr); \ - ADDI(offset_addr, address, offset); \ - } else { \ - offset_addr = address; \ - } \ - SH2_LOAD_##size(dest, offset_addr); \ - } - -#define LOAD_Rm_inc(size,dest) \ - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(m))); \ - ADDI_Rm_NOREG(INCDEC_##size); \ - REG_SETVALUE(REG_R(m), REG_GETVALUE(REG_R(m)) + INCDEC_##size); \ - } else { \ - SH2_LOAD_REG_##size(dest, m, 0, 1); \ - REG_SETKNOWN(REG_R(m), 0); \ - } - -#define LOAD_Rn(size,dest) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(n))); \ - } else { \ - SH2_LOAD_REG_##size(dest, n, 0, 0); \ - } - -#define LOAD_Rn_inc(size,dest) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(n))); \ - ADDI_Rn_NOREG(INCDEC_##size); \ - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) + INCDEC_##size); \ - } else { \ - SH2_LOAD_REG_##size(dest, n, 0, 1); \ - REG_SETKNOWN(REG_R(n), 0); \ - } - -#define LOAD_disp_GBR(size,dest,offset) \ - GET_GBR_KEEPOFS; \ - const int32_t final_offset = STATE_CACHE_OFFSET(GBR) + (offset); \ - DECLARE_REG(address); \ - if (final_offset) { \ - ALLOC_REG(address); \ - ADDI(address, GBR, final_offset); \ - } else { \ - address = GBR; \ - } \ - SH2_LOAD_##size(dest, address) - -#define LOAD_R0_GBR(size,dest) \ - DECLARE_REG(address); \ - GET_GBR_KEEPOFS; \ - if (REG_GETKNOWN(REG_R(0)) == 0xFFFFFFFF) { \ - const int32_t offset = STATE_CACHE_OFFSET(GBR) \ - + REG_GETVALUE(REG_R(0)); \ - if (offset) { \ - ALLOC_REG(address); \ - ADDI(address, GBR, offset); \ - } else { \ - address = GBR; \ - } \ - } else { \ - GET_R0_KEEPOFS; \ - DEFINE_REG(temp); \ - ADD(temp, R0, GBR); \ - const int32_t offset = STATE_CACHE_OFFSET(GBR) \ - + STATE_CACHE_OFFSET(R[0]); \ - if (offset) { \ - ALLOC_REG(address); \ - ADDI(address, temp, offset); \ - } else { \ - address = temp; \ - } \ - } \ - SH2_LOAD_##size(dest, address) - -/*----------------------------------*/ - -#define STORE_Rn(size,value) STORE_disp_Rn(size, value, 0) - -#define STORE_disp_Rn(size,value,offset) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - SH2_STORE_ABS_##size(REG_GETVALUE(REG_R(n)) + (offset), value, \ - PTR_ISLOCAL(n)); \ - } else { \ - SH2_STORE_REG_##size(n, value, offset, 0); \ - } - -#define STORE_dec_Rn(size,value) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - ADDI_Rn_NOREG(-INCDEC_##size); \ - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) - INCDEC_##size); \ - SH2_STORE_ABS_##size(REG_GETVALUE(REG_R(n)), value, \ - PTR_ISLOCAL(n)); \ - } else { \ - REG_SETKNOWN(REG_R(n), 0); \ - SH2_STORE_REG_##size(n, value, 0, 1); \ - } - -#define STORE_R0_Rn(size,value) \ - if (REG_GETKNOWN(REG_R(0)) == 0xFFFFFFFF \ - && REG_GETVALUE(REG_R(0)) + 0x8000 < 0x10000 \ - ) { \ - SH2_STORE_REG_##size(n, value, REG_GETVALUE(REG_R(0)), 0); \ - } else { \ - GET_R0_KEEPOFS; \ - GET_Rn_KEEPOFS; \ - DEFINE_REG(address); \ - ADD(address, R0, Rn); \ - const int32_t offset = STATE_CACHE_OFFSET(R[0]) \ - + STATE_CACHE_OFFSET(R[n]); \ - DECLARE_REG(offset_addr); \ - if (offset) { \ - ALLOC_REG(offset_addr); \ - ADDI(offset_addr, address, offset); \ - } else { \ - offset_addr = address; \ - } \ - SH2_STORE_##size(offset_addr, value); \ - } - -#define STORE_disp_Rm(size,value,offset) \ - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { \ - SH2_STORE_ABS_##size(REG_GETVALUE(REG_R(m)) + (offset), value, \ - PTR_ISLOCAL(n)); \ - } else { \ - SH2_STORE_REG_##size(m, value, offset, 0); \ - } - -#define STORE_disp_GBR(size,value,offset) \ - GET_GBR_KEEPOFS; \ - const int32_t final_offset = STATE_CACHE_OFFSET(GBR) + (offset); \ - DECLARE_REG(address); \ - if (final_offset) { \ - ALLOC_REG(address); \ - ADDI(address, GBR, final_offset); \ - } else { \ - address = GBR; \ - } \ - SH2_STORE_##size(address, value) - -/* @(R0,GBR) is only used in RMW instructions, so use the saved address */ -#define STORE_SAVED_R0_GBR(size,value) \ - SH2_STORE_##size(address, value) - -/*-----------------------------------------------------------------------*/ - -/* Local convenience macro to take a specified exception (immediate value), - * using the specified register as the return PC. */ - -#define TAKE_EXCEPTION(imm_index,PC_reg) do { \ - /* Push SR and PC */ \ - GET_R15_KEEPOFS; \ - GET_SR; \ - SH2_STORE_REG_L(15, SR, 0, 1); \ - SH2_STORE_REG_L(15, PC_reg, 0, 1); \ - if (REG_GETKNOWN(REG_R(15)) == 0xFFFFFFFF) { \ - REG_SETVALUE(REG_R(15), REG_GETVALUE(REG_R(15)) - 8); \ - } else { \ - REG_SETKNOWN(REG_R(15), 0); \ - } \ - /* Call the exception vector */ \ - DEFINE_REG(target); \ - SH2_LOAD_ABS_L(target, (imm_index) << 2); \ - SET_PC(target); \ - FLUSH_STATE_CACHE(); \ - JUMP(); \ -} while (0) - -/*-----------------------------------------------------------------------*/ - -#ifdef OPTIMIZE_SHIFT_SEQUENCES - -/* - * Local macro to retrieve the next opcode for use with shift optimization; - * the opcode is stored in the variable "next_opcode". If the next opcode - * in the instruction stream is a delayed branch which does not depend on - * the value of the register being shifted (Rn of the current instruction) - * or the T bit set by the shift (if a single-bit shift or rotate), then - * the instruction in the branch's delay slot is retrieved instead. If the - * next opcode cannot be retrieved, either because we've reached the end of - * the block or because we're interpreting, or if the instruction is not in - * directly-accessible memory, zero is stored in next_opcode. - */ - -# define GET_NEXT_OPCODE_FOR_SHIFT_CACHE \ - uint16_t next_opcode; \ - if (fetch && INSN_IS_AVAILABLE(1)) { \ - next_opcode = fetch[1]; \ - if (INSN_IS_AVAILABLE(2)) { \ - int use_delay = 0; \ - if ((next_opcode & 0xF0DF) == 0x0003 \ - || (next_opcode & 0xF0DF) == 0x400B) { \ - /* BSRF/BRAF Rn, JSR/JMP @Rn */ \ - use_delay = ((next_opcode>>8 & 0xF) != n); \ - } else if ((next_opcode & 0xFD00) == 0x8D00) { \ - /* BT/S, BF/S (allow only SHL[LR]#) */ \ - use_delay = ((opcode & 0xF00F) == 0x4008); \ - } else if ((next_opcode & 0xF0DF) == 0x000B \ - || (next_opcode & 0xE000) == 0xA000) { \ - /* RTS/RTE, BRA/BSR */ \ - use_delay = 1; \ - } \ - if (use_delay) { \ - next_opcode = fetch[2]; \ - } \ - } \ - } else { \ - next_opcode = 0; \ - } - -#endif // OPTIMIZE_SHIFT_SEQUENCES - -/*-----------------------------------------------------------------------*/ - -/* - * Debugging macro to print a line the first time an instruction is seen - * (enabled when DEBUG_DECODER_INSN_COVERAGE is defined by the including - * file). A full list of these can be generated with: - * - * grep -F 'DEBUG_PRINT_ONCE("' sh2-core.i | sed 's/^[^"]*"\([^"]*\).*$/\1/' - */ - -#ifdef DEBUG_DECODER_INSN_COVERAGE -# define DEBUG_PRINT_ONCE(insn) do { \ - static int seen = 0; \ - if (!seen) { \ - fprintf(stderr, "%s\n", insn); \ - seen = 1; \ - } \ -} while (0) -#else -# define DEBUG_PRINT_ONCE(insn) /*nothing*/ -#endif - -/*************************************************************************/ - -#ifndef DECODE_INSN_INLINE -# define DECODE_INSN_INLINE /*nothing*/ -#endif - -/** - * decode_insn: Decode a single SH-2 instruction. Implements - * translate_insn() using the shared decoder core. - * - * [Parameters] - * Defined by including file - * [Return value] - * Decoded SH-2 opcode, or value returned by micro-ops - */ -static DECODE_INSN_INLINE unsigned int decode_insn(DECODE_INSN_PARAMS) -{ - uint16_t opcode; - - /* Load the opcode to decode */ - - if (fetch) { - opcode = *fetch; - } else { - opcode = MappedMemoryReadWord(cur_PC); - } - - /* Perform any early processing required */ - - OPCODE_INIT(opcode); - - /* If tracing, trace the instruction (do this after OPCODE_INIT() so - * the JIT branch target label gets added before the trace call) */ - -#ifdef TRACE - DEFINE_REG(trace_PC); - MOVEI(trace_PC, cur_PC); - DEFINE_REG(trace_funcptr); - MOVEA(trace_funcptr, trace_insn_callback); - CALL_NORET(state_reg, trace_PC, trace_funcptr); -#endif - - /* Save and clear the delay flag (this needs to be done here, not at - * the end of the previous iteration, so (1) the translator knows not - * to interrupt the pair of instructions and (2) the delay flag can be - * accessed by OPCODE_INIT() if needed) */ - - const int in_delay = state->delay; - state->delay = 0; - - /* Clear the just-branched flag on every instruction, so - * fall-off-the-end is detected properly; we'll set it later if we - * branch after this instruction */ - - state->just_branched = 0; - - /* Record the number of cycles used by this instruction (any additional - * cycles necessary are added by the individual opcode handlers) */ - - int cur_cycles = 1; - - /**** The Big Honkin' Opcode Switch Begins Here ****/ - - /* Extract these early for convenience */ - const unsigned int n = opcode>>8 & 0xF; - const unsigned int m = opcode>>4 & 0xF; - - /* Note: Mnemonics listed here for some instructions differ slightly - * from the official Hitachi specs. Here, register Rn _always_ refers - * to the register specified by bits 8-11 of the opcode, and register - * Rm _always_ refers to the register specified by bits 4-7 of the - * opcode, regardless of the register's role (source or destination). */ - - switch (opcode>>12 & 0xF) { - - case 0x0: { - switch (opcode & 0xFF) { - - // $0xx2 - case 0x02: { // STC SR,Rn - DEBUG_PRINT_ONCE("STC SR,Rn"); - COPY_TO_Rn(SR); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - case 0x12: { // STC GBR,Rn - DEBUG_PRINT_ONCE("STC GBR,Rn"); - COPY_TO_Rn(GBR); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_GBR)); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_GBR)); - PTR_CLEAR(n); - break; - } - case 0x22: { // STC VBR,Rn - DEBUG_PRINT_ONCE("STC VBR,Rn"); - COPY_TO_Rn(VBR); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xx3 - case 0x03: { // BSRF Rn - DEBUG_PRINT_ONCE("BSRF Rn"); - DEFINE_RESULT_REG(ret_addr, PR); - MOVEI(ret_addr, cur_PC + 4); - SET_PR(ret_addr); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - DEFINE_REG(target); - ADD(target, ret_addr, Rn); - state->branch_target_reg = target; - } - state->delay = 1; - cur_cycles += 1; - break; - } - case 0x23: { // BRAF Rn - DEBUG_PRINT_ONCE("BRAF Rn"); -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if (fetch) { - unsigned int Rshift, count_max, Rcount, type; - const unsigned int num_insns = can_optimize_variable_shift( - fetch, cur_PC, &Rcount, &count_max, &Rshift, &type, NULL - ); - if (num_insns) { - state->varshift_target_PC = cur_PC + 2*num_insns; - state->varshift_type = type; - state->varshift_Rcount = Rcount; - state->varshift_max = count_max; - state->varshift_Rshift = Rshift; - } - } -#endif - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - DEFINE_REG(target); - ADDI(target, Rn, cur_PC + 4); - state->branch_target_reg = target; - } - state->delay = 1; - cur_cycles += 1; - break; - } - - // $0xx4 - case 0x04: case 0x14: case 0x24: case 0x34: - case 0x44: case 0x54: case 0x64: case 0x74: - case 0x84: case 0x94: case 0xA4: case 0xB4: - case 0xC4: case 0xD4: case 0xE4: case 0xF4: { // MOV.B Rm,@(R0,Rn) - DEBUG_PRINT_ONCE("MOV.B Rm,@(R0,Rn)"); - GET_Rm_B; - STORE_R0_Rn(B, Rm); - break; - } - - // $0xx5 - case 0x05: case 0x15: case 0x25: case 0x35: - case 0x45: case 0x55: case 0x65: case 0x75: - case 0x85: case 0x95: case 0xA5: case 0xB5: - case 0xC5: case 0xD5: case 0xE5: case 0xF5: { // MOV.W Rm,@(R0,Rn) - DEBUG_PRINT_ONCE("MOV.W Rm,@(R0,Rn)"); - GET_Rm_W; - STORE_R0_Rn(W, Rm); - break; - } - - // $0xx6 - case 0x06: case 0x16: case 0x26: case 0x36: - case 0x46: case 0x56: case 0x66: case 0x76: - case 0x86: case 0x96: case 0xA6: case 0xB6: - case 0xC6: case 0xD6: case 0xE6: case 0xF6: { // MOV.L Rm,@(R0,Rn) - DEBUG_PRINT_ONCE("MOV.L Rm,@(R0,Rn)"); - GET_Rm; - STORE_R0_Rn(L, Rm); - break; - } - - // $0xx7 - case 0x07: case 0x17: case 0x27: case 0x37: - case 0x47: case 0x57: case 0x67: case 0x77: - case 0x87: case 0x97: case 0xA7: case 0xB7: - case 0xC7: case 0xD7: case 0xE7: case 0xF7: { // MUL.L Rm,Rn - DEBUG_PRINT_ONCE("MUL.L Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, MACL); - MUL(result, Rn, Rm); - SET_MACL(result); - CLEAR_MAC_IS_ZERO(); - cur_cycles += 1; // Minimum number of cycles - break; - } - - // $0xx8 - case 0x08: { // CLRT - DEBUG_PRINT_ONCE("CLRT"); - DEFINE_REG(zero); - MOVEI(zero, 0); - SET_SR_T(zero); - break; - } - case 0x18: { // SETT - DEBUG_PRINT_ONCE("SETT"); - DEFINE_REG(one); - MOVEI(one, 1); - SET_SR_T(one); - break; - } - case 0x28: { // CLRMAC - DEBUG_PRINT_ONCE("CLRMAC"); - DEFINE_RESULT_REG(MACH, MACH); - MOVEI(MACH, 0); - SET_MACH(MACH); - DEFINE_RESULT_REG(MACL, MACL); - MOVEI(MACL, 0); - SET_MACL(MACL); - SET_MAC_IS_ZERO(); - break; - } - - // $0xx9 - case 0x09: { // NOP - DEBUG_PRINT_ONCE("NOP"); - /* No operation */ - break; - } - case 0x19: { // DIV0U - DEBUG_PRINT_ONCE("DIV0U"); - GET_SR; - DEFINE_RESULT_REG(new_SR, SR); - ANDI(new_SR, SR, ~(SR_T | SR_Q | SR_M)); - SET_SR(new_SR); -#ifdef OPTIMIZE_DIVISION - int Rlo = -1, Rhi = -1, Rdiv = -1; // Register numbers - int div_bits = 0; // Number of bits of division to perform - int skip_first_rotcl = 0; // Is the 1st ROTCL skipped? (see below) - /* Don't try to optimize if the DIV0U is sitting in a - * branch delay slot; also, only optimize when we can do - * direct fetching (otherwise our read-aheads might have side - * effects). */ - if (LIKELY(!in_delay) && fetch) { - if ((fetch[1] & 0xF00F) == 0x3004 - && (fetch[2] & 0xF0FF) == 0x4024 - ) { - /* If the value of Rlo is zero, the first ROTCL may be - * omitted (since neither Rlo or SR.T would change). */ -#ifdef __GNUC__ // Avoid a warning if known value optimization is disabled - __attribute__((unused)) -#endif - const int rotcl_Rn = fetch[2]>>8 & 0xF; - if (REG_GETKNOWN(REG_R(rotcl_Rn)) == 0xFFFFFFFF - && REG_GETVALUE(REG_R(rotcl_Rn)) == 0 - ) { - skip_first_rotcl = 1; - } - } - div_bits = can_optimize_div0u(fetch, cur_PC, skip_first_rotcl, - &Rhi, &Rlo, &Rdiv); - } - if (div_bits > 0) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Optimizing unsigned division at 0x%08X", (int)cur_PC); -# endif - /* Set up optimization flags/data */ - const int is_32bit = (REG_GETKNOWN(Rhi) == 0xFFFFFFFF - && REG_GETVALUE(Rhi) == 0); - const int safe_division = - (optimization_flags & SH2_OPTIMIZE_ASSUME_SAFE_DIVISION); - state->division_target_PC = cur_PC + div_bits*4; - if (!safe_division) { - /* Flush cached data since we jump out from inside the - * runtime conditional. */ - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - } else { - /* No need to flush data because we omit the - * unoptimized code entirely. */ - } - /* Load operands */ - DECLARE_REG(lo); - LOAD_STATE_ALLOC(lo, R[Rlo]); - DECLARE_REG(div); - LOAD_STATE_ALLOC(div, R[Rdiv]); - DECLARE_REG(hi); - LOAD_STATE_ALLOC(hi, R[Rhi]); - /* Define output registers (shared across all cases) */ - DEFINE_REG(quotient); - DEFINE_REG(remainder); - /* If the divide is less than 32 bits, save the low bits of - * the dividend. We don't shift the dividend right yet - * because we have to check Rhi first; the divide will - * still misbehave if Rhi >= div. */ - DECLARE_REG(lo_lowbits); - if (div_bits < 32) { - ALLOC_REG(lo_lowbits); - SLLI(lo_lowbits, lo, 32 - div_bits); - } else { // Not needed, but avoid a compiler warning - lo_lowbits = 0; - } - /* Allocate labels for use in non-optimized cases */ - CREATE_LABEL(div0u_not_safe); - CREATE_LABEL(div0u_not_32bit); - CREATE_LABEL(div0u_done); - if (!safe_division) { - GOTO_IF_Z(div0u_not_safe, div); - } - if (!is_32bit) { - GOTO_IF_NZ(div0u_not_32bit, hi); - } - /* Divide 32 bits by 32 bits, unsigned */ - if (div_bits < 32) { - /* Note: SSA violation */ - SRLI(lo, lo, 32 - div_bits); - } - DIVMODU(quotient, lo, div, remainder); - if (!is_32bit) { - GOTO_LABEL(div0u_done); - DEFINE_LABEL(div0u_not_32bit); - if (!safe_division) { - DEFINE_REG(test_safe); - SLTU(test_safe, hi, div); - GOTO_IF_Z(div0u_not_safe, test_safe); - } - if (div_bits < 32) { - /* Note: SSA violations */ - SRLI(lo, lo, 32 - div_bits); - BFINS(lo, lo, hi, div_bits, 32 - div_bits); - SRLI(hi, hi, 32 - div_bits); - } - /* - * Divide 64 bits by 32 bits, unsigned, when the - * quotient is known to fit in 32 bits. - * - * Here, we use the algorithm followed by GCC (among - * others), which is essentially to perform long - * division in base 2^16 with a normalized divisor, - * i.e. a divisor with the highest bit set. We divide - * the two-"digit" divisor into the upper three - * "digits" of the dividend, then append the final - * "digit" to the remainder and divide again. Since - * operands to a division instruction can only be 32 - * bits, i.e. 2 "digits", we process the divisor one - * "digit" at a time. - * - * To demonstrate, this is how it would work if a word - * consisted of two decimal digits (i.e. 0-99): - * _____ - * 59)5023 - * -50 Step 1: 50/5 = 10 (q1), 10*5 = 50 - * ---- - * 2 Step 2: Carry down the next digit - * Step 3: Is the remainder less than 10*9? - * +59 Step 3A: Yes, so add 59 and decrement q1 - * ---- (q1=9) - * 61 Step 3B: Is the remainder still less than 10*9? - * +59 Step 3C: Yes, so add 59 and decrement q1 again - * ---- (q1=8) (since the divisor is normalized, - * 120 we will never need to add it more - * than twice to avoid borrowing) - * -90 Step 4: Subtract 10*9 - * ---- - * 30 (Repeat steps 1-4) - * -30 Step 5: 30/5 = 6 (q0), 6*5 = 30 - * ---- - * 3 Step 6: Carry down the next (last) digit - * Step 7: Is the remainder less than 6*9? - * +59 Step 7A: Yes, so add 59 and decrement q0 - * ---- (q0=5) - * 62 Step 7B: Is the remainder still less than 6*9? - * Step 7C: No, so skip the add and decrement - * -54 Step 8: Subtract 6*9 - * ---- - * 8 Result: quotient 85, remainder 8 - */ - /* Normalize the divisor and dividend */ - DEFINE_REG(norm_shift); - CLZ(norm_shift, div); - DEFINE_REG(hi_norm_temp1); - SLL(hi_norm_temp1, hi, norm_shift); - DEFINE_REG(imm_32); - MOVEI(imm_32, 32); - DEFINE_REG(norm_invshift); - SUB(norm_invshift, imm_32, norm_shift); - DEFINE_REG(hi_norm_temp2); - SRL(hi_norm_temp2, lo, norm_invshift); - DEFINE_REG(hi_norm_temp3); - OR(hi_norm_temp3, hi_norm_temp1, hi_norm_temp2); - /* Need to SELECT here in case norm_shift==0, because - * shifting by 32 bits (norm_invshift) is undefined */ - DEFINE_REG(hi_norm); - SELECT(hi_norm, hi_norm_temp3, hi, norm_shift); - DEFINE_REG(lo_norm); - SLL(lo_norm, lo, norm_shift); - DEFINE_REG(div_norm); - SLL(div_norm, div, norm_shift); - /* Extract the upper and lower halfwords of the divisor */ - DEFINE_REG(div1); - SRLI(div1, div_norm, 16); - DEFINE_REG(div0); - ANDI(div0, div_norm, 0xFFFF); - /* Divide the upper 48 bits (steps 1-4) */ - DEFINE_REG(q1); - DEFINE_REG(mid_norm); - DIVMODU(q1, hi_norm, div1, mid_norm); // Step 1 - SLLI(mid_norm, mid_norm, 16); - DEFINE_REG(mid_norm_temp); - SRLI(mid_norm_temp, lo_norm, 16); - OR(mid_norm, mid_norm, mid_norm_temp); // Step 2 - DEFINE_REG(q1_div0); - MUL(q1_div0, q1, div0); - CREATE_LABEL(div0u_mid_done); - DEFINE_REG(mid_test1); - SLTU(mid_test1, mid_norm, q1_div0); // Step 3 - GOTO_IF_Z(div0u_mid_done, mid_test1); { - ADD(mid_norm, mid_norm, div_norm); // Step 3A - SUBI(q1, q1, 1); - /* If mid_norm < div_norm, then we overflowed and - * have a virtual 1 in bit position 32, so mid_norm - * must be greater than q1_div0 */ - DEFINE_REG(mid_test2a); - SLTU(mid_test2a, mid_norm, div_norm); // Step 3B - DEFINE_REG(mid_test2b); - SLTU(mid_test2b, mid_norm, q1_div0); - GOTO_IF_NZ(div0u_mid_done, mid_test2a); - GOTO_IF_Z(div0u_mid_done, mid_test2b); { - ADD(mid_norm, mid_norm, div_norm); // Step 3C - SUBI(q1, q1, 1); - } - } DEFINE_LABEL(div0u_mid_done); - SUB(mid_norm, mid_norm, q1_div0); // Step 4 - /* Divide the last 16 bits (steps 5-8) */ - DEFINE_REG(q0); - DEFINE_REG(rem_norm); - DIVMODU(q0, mid_norm, div1, rem_norm); // Step 5 - SLLI(rem_norm, rem_norm, 16); - DEFINE_REG(rem_norm_temp); - ANDI(rem_norm_temp, lo_norm, 0xFFFF); - OR(rem_norm, rem_norm, rem_norm_temp); // Step 6 - DEFINE_REG(q0_div0); - MUL(q0_div0, q0, div0); - CREATE_LABEL(div0u_lo_done); - DEFINE_REG(lo_test1); - SLTU(lo_test1, rem_norm, q0_div0); // Step 7 - GOTO_IF_Z(div0u_lo_done, lo_test1); { - ADD(rem_norm, rem_norm, div_norm); // Step 7A - SUBI(q0, q0, 1); - DEFINE_REG(lo_test2a); - SLTU(lo_test2a, rem_norm, div_norm); // Step 7B - DEFINE_REG(lo_test2b); - SLTU(lo_test2b, rem_norm, q0_div0); - GOTO_IF_NZ(div0u_lo_done, lo_test2a); - GOTO_IF_Z(div0u_lo_done, lo_test2b); { - ADD(rem_norm, rem_norm, div_norm); // Step 7C - SUBI(q0, q0, 1); - } - } DEFINE_LABEL(div0u_lo_done); - SUB(rem_norm, rem_norm, q0_div0); // Step 8 - /* Merge the two quotient halves */ - BFINS(quotient, q0, q1, 16, 16); - /* Un-normalize the remainder */ - SRL(remainder, rem_norm, norm_shift); - DEFINE_LABEL(div0u_done); - } // if (!is_32bit) - /* Process the division result */ - DEFINE_REG(new_T); - ANDI(new_T, quotient, 1); // Low bit to T flag - DEFINE_RESULT_REG(quo_out, R[Rlo]); - if (div_bits < 32) { - DEFINE_REG(quo_temp); - SRLI(quo_temp, quotient, 1); - OR(quo_out, quo_temp, lo_lowbits); - } else { - SRLI(quo_out, quotient, 1); - } - STORE_STATE(R[Rlo], quo_out); - REG_SETKNOWN(REG_R(Rlo), 0); - DEFINE_REG(temp0); - SUB(temp0, remainder, div); - DEFINE_REG(rem_out); - SELECT(rem_out, remainder, temp0, new_T); - STORE_STATE(R[Rhi], rem_out); - REG_SETKNOWN(REG_R(Rhi), 0); - DEFINE_REG(SR_temp); - OR(SR_temp, new_SR, new_T); - DEFINE_REG(new_Q); - XORI(new_Q, new_T, 1); - DEFINE_RESULT_REG(SR_out, SR); - BFINS(SR_out, SR_temp, new_Q, SR_Q_SHIFT, 1); - SET_SR(SR_out); - /* Skip over the step-by-step emulation */ - const unsigned int skipped_insns = - div_bits*2 - (skip_first_rotcl ? 1 : 0); - cur_cycles += skipped_insns; - if (!safe_division) { - ADD_CYCLES(); - SET_PC_KNOWN(cur_PC + (2 + skipped_insns*2)); - state->branch_target = cur_PC + (2 + skipped_insns*2); - FLUSH_STATE_CACHE(); - JUMP_STATIC(); - DEFINE_LABEL(div0u_not_safe); - } else { - INC_PC_BY(skipped_insns*2); - } - } // if (div_bits > 0) -#endif // OPTIMIZE_DIVISION - break; - } // DIV0U - case 0x29: { // MOVT Rn - DEBUG_PRINT_ONCE("MOVT Rn"); - GET_SR_T; - SET_Rn(T); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFE); - REG_SETVALUE(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxA - case 0x0A: { // STS MACH,Rn - DEBUG_PRINT_ONCE("STS MACH,Rn"); - if (STATE_CACHE_FIXED_REG_WRITABLE(R[n])) { - COPY_TO_Rn(MACH); - } else { - /* Make sure Rn gets a copy of the register so it's not - * altered by subsequent MAC instructions */ - GET_MACH_COPY; - SET_Rn(MACH); - } - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - case 0x1A: { // STS MACL,Rn - DEBUG_PRINT_ONCE("STS MACL,Rn"); - if (STATE_CACHE_FIXED_REG_WRITABLE(R[n])) { - COPY_TO_Rn(MACL); - } else { - GET_MACL_COPY; - SET_Rn(MACL); - } - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - case 0x2A: { // STS PR,Rn - DEBUG_PRINT_ONCE("STS PR,Rn"); - COPY_TO_Rn(PR); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxB - case 0x0B: { // RTS - DEBUG_PRINT_ONCE("RTS"); - /* We don't do anything if this is an RTS from a folded - * subroutine, since that's handled by our caller. */ - if (!state->folding_subroutine) { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_PR; - state->branch_target_reg = PR; - state->delay = 1; - } - cur_cycles += 1; - break; - } - case 0x1B: { // SLEEP - DEBUG_PRINT_ONCE("SLEEP"); - cur_cycles += 2; - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - DEFINE_REG(check_interrupts_funcptr); - MOVEA(check_interrupts_funcptr, check_interrupts); - DEFINE_REG(result); - CALL(result, state_reg, 0, check_interrupts_funcptr); - CREATE_LABEL(sleep_intr); - GOTO_IF_NZ(sleep_intr, result); { - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - STORE_STATE_B(asleep, imm_1); - DEFINE_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - STORE_STATE(cycles, cycle_limit); - } DEFINE_LABEL(sleep_intr); - RETURN(); - break; - } - case 0x2B: { // RTE - DEBUG_PRINT_ONCE("RTE"); - GET_R15_KEEPOFS; - DEFINE_REG(new_PC); - SH2_LOAD_REG_L(new_PC, 15, 0, 1); - DEFINE_REG(new_SR); - SH2_LOAD_REG_L(new_SR, 15, 0, 1); - if (REG_GETKNOWN(REG_R(15)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(15), REG_GETVALUE(REG_R(15)) + 8); - } else { - REG_SETKNOWN(REG_R(15), 0); - } - REG_SETKNOWN(REG_R(15), REG_GETKNOWN(REG_R(15)) & 7); - state->branch_type = SH2BRTYPE_RTE; - state->branch_target_reg = new_PC; - DEFINE_RESULT_REG(new_SR_3F3, SR); - ANDI(new_SR_3F3, new_SR, 0x3F3); - SET_SR(new_SR_3F3); - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - state->delay = 1; - cur_cycles += 3; - break; - } - - // $0xxC - case 0x0C: case 0x1C: case 0x2C: case 0x3C: - case 0x4C: case 0x5C: case 0x6C: case 0x7C: - case 0x8C: case 0x9C: case 0xAC: case 0xBC: - case 0xCC: case 0xDC: case 0xEC: case 0xFC: { // MOV.B @(R0,Rm),Rn - DEBUG_PRINT_ONCE("MOV.B @(R0,Rm),Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_R0_Rm(B, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxD - case 0x0D: case 0x1D: case 0x2D: case 0x3D: - case 0x4D: case 0x5D: case 0x6D: case 0x7D: - case 0x8D: case 0x9D: case 0xAD: case 0xBD: - case 0xCD: case 0xDD: case 0xED: case 0xFD: { // MOV.W @(R0,Rm),Rn - DEBUG_PRINT_ONCE("MOV.W @(R0,Rm),Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_R0_Rm(W, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxE - case 0x0E: case 0x1E: case 0x2E: case 0x3E: - case 0x4E: case 0x5E: case 0x6E: case 0x7E: - case 0x8E: case 0x9E: case 0xAE: case 0xBE: - case 0xCE: case 0xDE: case 0xEE: case 0xFE: { // MOV.L @(R0,Rm),Rn - DEBUG_PRINT_ONCE("MOV.L @(R0,Rm),Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_R0_Rm(L, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxF - case 0x0F: case 0x1F: case 0x2F: case 0x3F: - case 0x4F: case 0x5F: case 0x6F: case 0x7F: - case 0x8F: case 0x9F: case 0xAF: case 0xBF: - case 0xCF: case 0xDF: case 0xEF: case 0xFF: { // MAC.L @Rm+,@Rn+ - DEBUG_PRINT_ONCE("MAC.L @Rm+,@Rn+"); - - /* Load the values */ - DEFINE_REG(value_m); - LOAD_Rm_inc(L, value_m); - DEFINE_REG(value_n); - LOAD_Rn_inc(L, value_n); - - /* Do the actual multiplication and addition */ - if (MAC_IS_ZERO()) { - DEFINE_RESULT_REG(new_MACL, MACL); - DEFINE_RESULT_REG(new_MACH, MACH); - MULS_64(new_MACL, value_m, value_n, new_MACH); - SET_MACL(new_MACL); - SET_MACH(new_MACH); - } else { - GET_MACL; - GET_MACH; - MADDS_64(MACL, value_m, value_n, MACH); - SET_MACL(MACL); - SET_MACH(MACH); - } - - /* Perform saturation if the S flag of SR is set */ - if (!CAN_OMIT_MAC_S_CHECK) { - GET_SR; - DEFINE_REG(saturate); - ANDI(saturate, SR, SR_S); - CREATE_LABEL(macl_nosat); - GOTO_IF_Z(macl_nosat, saturate); { - GET_MACL; - GET_MACH; - DEFINE_REG(saturate_minus); - SLTSI(saturate_minus, MACH, -0x7FFF); - CREATE_LABEL(macl_sat_nominus); - GOTO_IF_Z(macl_sat_nominus, saturate_minus); { - DEFINE_REG(temp); - MOVEI(temp, -0x8000); - /* Note: SSA violations for state block optimization */ - MOVE(MACH, temp); - SET_MACH(MACH); - MOVEI(MACL, 0); - SET_MACL(MACL); - GOTO_LABEL(macl_nosat); - } DEFINE_LABEL(macl_sat_nominus); - DEFINE_REG(satplus_test); - SUBI(satplus_test, MACH, 0x8000); - DEFINE_REG(inv_saturate_plus); // Inverse value - SLTSI(inv_saturate_plus, satplus_test, 0); - GOTO_IF_NZ(macl_nosat, inv_saturate_plus); { - DEFINE_REG(temp1); - MOVEI(temp1, 0x7FFF); - /* Note: SSA violations for state block optimization */ - MOVE(MACH, temp1); - SET_MACH(MACH); - DEFINE_REG(temp2); - MOVEI(temp2, 0xFFFFFFFF); - MOVE(MACL, temp2); - SET_MACL(MACL); - } - } DEFINE_LABEL(macl_nosat); - } // if (!CAN_OMIT_MAC_S_CHECK) - - CLEAR_MAC_IS_ZERO(); - cur_cycles += 2; - break; - } // MAC.L - - default: - goto invalid; - } - break; - } // $0xxx - - case 0x1: { // MOV.L Rm,@(disp,Rn) - DEBUG_PRINT_ONCE("MOV.L Rm,@(disp,Rn)"); - const int disp = (opcode & 0xF) * 4; - GET_Rm; - STORE_disp_Rn(L, Rm, disp); - break; - } // $1xxx - - case 0x2: { - switch (opcode & 0xF) { - - case 0x0: { // MOV.B Rm,@Rn - DEBUG_PRINT_ONCE("MOV.B Rm,@Rn"); - GET_Rm_B; - STORE_Rn(B, Rm); - break; - } - - case 0x1: { // MOV.W Rm,@Rn - DEBUG_PRINT_ONCE("MOV.W Rm,@Rn"); - GET_Rm_W; - STORE_Rn(W, Rm); - break; - } - - case 0x2: { // MOV.L Rm,@Rn - DEBUG_PRINT_ONCE("MOV.L Rm,@Rn"); - GET_Rm; - STORE_Rn(L, Rm); - break; - } - - case 0x4: { // MOV.B Rm,@-Rn - DEBUG_PRINT_ONCE("MOV.B Rm,@-Rn"); - GET_Rm_B; - STORE_dec_Rn(B, Rm); - break; - } - - case 0x5: { // MOV.W Rm,@-Rn - DEBUG_PRINT_ONCE("MOV.W Rm,@-Rn"); - GET_Rm_W; - STORE_dec_Rn(W, Rm); - break; - } - - case 0x6: { // MOV.L Rm,@-Rn - DEBUG_PRINT_ONCE("MOV.L Rm,@-Rn"); - GET_Rm; - STORE_dec_Rn(L, Rm); - break; - } - - case 0x7: { // DIV0S Rm,Rn - DEBUG_PRINT_ONCE("DIV0S Rm,Rn"); - GET_Rm; - DEFINE_REG(new_M); - SRLI(new_M, Rm, 31); - GET_SR; - DEFINE_REG(SR_withM); - BFINS(SR_withM, SR, new_M, SR_M_SHIFT, 1); - GET_Rn; - DEFINE_REG(new_Q); - SRLI(new_Q, Rn, 31); - DEFINE_REG(SR_withQ); - BFINS(SR_withQ, SR_withM, new_Q, SR_Q_SHIFT, 1); - DEFINE_REG(new_T); - XOR(new_T, new_M, new_Q); - DEFINE_RESULT_REG(new_SR, SR); - BFINS(new_SR, SR_withQ, new_T, SR_T_SHIFT, 1); - SET_SR(new_SR); -#ifdef OPTIMIZE_DIVISION - int Rlo, Rhi = n, Rdiv = m; // Register numbers - const int can_optimize = !in_delay && fetch - && can_optimize_div0s(fetch+1, cur_PC+2, Rhi, &Rlo, Rdiv); - if (can_optimize) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Optimizing signed division at 0x%08X", (int)cur_PC); -# endif - const int safe_division = - (optimization_flags & SH2_OPTIMIZE_ASSUME_SAFE_DIVISION); - state->division_target_PC = cur_PC + 128; - if (!safe_division) { - /* Flush cached data since we jump out from inside the - * runtime conditional */ - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - } else { - /* No need to flush data because we omit the - * unoptimzied code entirely */ - } - /* Load operands */ - DECLARE_REG(lo); - LOAD_STATE_ALLOC(lo, R[Rlo]); - DECLARE_REG(div); - LOAD_STATE_ALLOC(div, R[Rdiv]); - DECLARE_REG(hi); - LOAD_STATE_ALLOC(hi, R[Rhi]); - /* Define output registers (shared across all cases) */ - DEFINE_REG(quotient); - DEFINE_REG(remainder); - /* Allocate a label for use in non-optimized cases */ - CREATE_LABEL(div0s_not_safe); - if (!safe_division) { - /* Make sure the divisor is nonzero (we don't handle - * division by zero here because we'd have to carry lo - * down too far) */ - GOTO_IF_Z(div0s_not_safe, div); - /* Check that the 64-bit value is within the range of - * a signed 32-bit integer. The Hitachi docs suggest - * that 64/32 (or 32/16) signed division isn't - * supported, so don't bother trying to optimize that - * case. Besides, 64/32 division is a pain when you - * only have 32-bit registers (see DIV0U). */ - DEFINE_REG(test_safe); - SRAI(test_safe, lo, 31); // Either 0 or -1 - GOTO_IF_NE(div0s_not_safe, hi, test_safe); - } - /* Divide 32 bits by 32 bits, unsigned */ - DIVMODS(quotient, lo, div, remainder); - /* Process the division result depending on the dividend sign*/ - DEFINE_REG(M_bit); - SRLI(M_bit, div, 31); // Get divisor sign bit (M) - DEFINE_REG(lo_sign); - SRLI(lo_sign, lo, 31); // Get dividend sign bit - /* Note: SSA violations for state block optimization */ - DEFINE_RESULT_REG(quo_out, R[Rlo]); - DEFINE_RESULT_REG(rem_out, R[Rhi]); - DEFINE_RESULT_REG(final_SR, SR); - CREATE_LABEL(div0s_final); - CREATE_LABEL(div0s_neg_dividend); - GOTO_IF_NZ(div0s_neg_dividend, lo_sign); { - /* Positive dividend */ - DEFINE_REG(quo_adj); - SUB(quo_adj, quotient, M_bit); // Adjust quotient - DEFINE_REG(new_T2); - ANDI(new_T2, quo_adj, 1); // Get value of T - DEFINE_REG(new_SR_T); - BFINS(new_SR_T, new_SR, new_T2, SR_T_SHIFT, 1); - SRAI(quo_out, quo_adj, 1); // Set quotient>>1 - DEFINE_REG(temp_Q2); - XOR(temp_Q2, new_T2, M_bit); // Get value of Q - DEFINE_REG(new_Q2); - XORI(new_Q2, temp_Q2, 1); - BFINS(final_SR, new_SR_T, new_Q2, SR_Q_SHIFT, 1); - SET_SR(final_SR); - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(neg_div); - SUB(neg_div, zero, div); // Get abs(divisor) - DEFINE_REG(abs_div); // (remember that M bit is - SELECT(abs_div, neg_div, div, M_bit); // divisor sign) - DEFINE_REG(rem_adj); - SUB(rem_adj, remainder, abs_div); // Adjust remainder - SELECT(rem_out, rem_adj, remainder, new_Q2); - GOTO_LABEL(div0s_final); - } DEFINE_LABEL(div0s_neg_dividend); { - /* Negative dividend */ - DEFINE_REG(M_adjtemp); - SLLI(M_adjtemp, M_bit, 1); // Adjust quotient - DEFINE_REG(M_adjtemp2); - SUBI(M_adjtemp2, M_adjtemp, 1); - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(M_adj); - SELECT(M_adj, M_adjtemp2, zero, remainder); - DEFINE_REG(qtemp); - ADD(qtemp, quotient, M_adj); - DEFINE_REG(quo_adj); - SUB(quo_adj, qtemp, M_bit); - DEFINE_REG(new_T2); - ANDI(new_T2, quo_adj, 1); // Get value of T - DEFINE_REG(new_SR_T); - BFINS(new_SR_T, new_SR, new_T2, SR_T_SHIFT, 1); - SRAI(quo_out, quo_adj, 1); // Set quotient>>1 - DEFINE_REG(temp_Q2); - XOR(temp_Q2, new_T2, M_bit); // Get value of Q - DEFINE_REG(new_Q2); - XORI(new_Q2, temp_Q2, 1); - BFINS(final_SR, new_SR_T, new_Q2, SR_Q_SHIFT, 1); - SET_SR(final_SR); - DEFINE_REG(neg_div); - SUB(neg_div, zero, div); // Get abs(divisor) - DEFINE_REG(abs_div); - SELECT(abs_div, neg_div, div, M_bit); - DEFINE_REG(rem_Q_temp); - SUB(rem_Q_temp, remainder, abs_div); - DEFINE_REG(rem_Q); // Remainder if Q - SELECT(rem_Q, remainder, rem_Q_temp, remainder); - DEFINE_REG(rem_nQ_temp); - ADD(rem_nQ_temp, remainder, abs_div); - DEFINE_REG(rem_nQ); // Remainder if !Q - SELECT(rem_nQ, rem_nQ_temp, remainder, remainder); - SELECT(rem_out, rem_Q, rem_nQ, new_Q2); - } DEFINE_LABEL(div0s_final); - STORE_STATE(R[Rlo], quo_out); - REG_SETKNOWN(REG_R(Rlo), 0); - STORE_STATE(R[Rhi], rem_out); - REG_SETKNOWN(REG_R(Rhi), 0); - /* Skip over the step-by-step emulation */ - cur_cycles += 64; // 1 cycle was already added - if (!safe_division) { - ADD_CYCLES(); - SET_PC_KNOWN(cur_PC + 130); - state->branch_target = cur_PC + 130; - FLUSH_STATE_CACHE(); - JUMP_STATIC(); - DEFINE_LABEL(div0s_not_safe); - } else { - INC_PC_BY(128); // Incremented by another 2 below - } - } // if (can_optimize) -#endif // OPTIMIZE_DIVISION - break; - } // DIV0S - - case 0x8: { // TST Rm,Rn - DEBUG_PRINT_ONCE("TST Rm,Rn"); - GET_Rn; - /* TST Rn,Rn is a common idiom for checking the zeroness of Rn */ - DEFINE_REG(new_T); - if (m == n) { - SEQZ(new_T, Rn); - } else { - GET_Rm; - DEFINE_REG(result); - AND(result, Rn, Rm); - SEQZ(new_T, result); - } - SET_SR_T(new_T); - break; - } - - case 0x9: { // AND Rm,Rn - DEBUG_PRINT_ONCE("AND Rm,Rn"); - if (m == n) { - break; // AND Rn,Rn is a no-op - } - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - AND(result, Rn, Rm); - SET_Rn(result); - /* A bit in the result of an AND operation is known iff (1) the - * bit is known in both operands or (2) the bit is known to be - * 0 in one operand. */ - REG_SETKNOWN(REG_R(n), - (REG_GETKNOWN(REG_R(m)) & REG_GETKNOWN(REG_R(n))) - | (REG_GETKNOWN(REG_R(m)) & ~REG_GETVALUE(REG_R(m))) - | (REG_GETKNOWN(REG_R(n)) & ~REG_GETVALUE(REG_R(n)))); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(m)) & REG_GETVALUE(REG_R(n))); - PTR_CLEAR(n); - break; - } - - case 0xA: { // XOR Rm,Rn - DEBUG_PRINT_ONCE("XOR Rm,Rn"); - if (m == n) { // XOR Rn,Rn is a common idiom for clearing Rn - DEFINE_RESULT_REG(result, R[n]); - MOVEI(result, 0); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - XOR(result, Rn, Rm); - SET_Rn(result); - /* A bit in the result of an XOR operation is known iff the - * bit is known in both operands. */ - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(m)) & REG_GETKNOWN(REG_R(n))); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(m)) ^ REG_GETVALUE(REG_R(n))); - } - PTR_CLEAR(n); - break; - } - - case 0xB: { // OR Rm,Rn - DEBUG_PRINT_ONCE("OR Rm,Rn"); - if (m == n) { - break; // OR Rn,Rn is a no-op - } - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - OR(result, Rn, Rm); - SET_Rn(result); - /* A bit in the result of an OR operation is known iff (1) the - * bit is known in both operands or (2) the bit is known to be - * 1 in one operand. */ - REG_SETKNOWN(REG_R(n), - (REG_GETKNOWN(REG_R(m)) & REG_GETKNOWN(REG_R(n))) - | (REG_GETKNOWN(REG_R(m)) & REG_GETVALUE(REG_R(m))) - | (REG_GETKNOWN(REG_R(n)) & REG_GETVALUE(REG_R(n)))); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(m)) | REG_GETVALUE(REG_R(n))); - PTR_CLEAR(n); - break; - } - - case 0xC: { // CMP/ST Rm,Rn - DEBUG_PRINT_ONCE("CMP/ST Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(temp); - XOR(temp, Rn, Rm); - DEFINE_REG(byte3); - BFEXT(byte3, temp, 24, 8); - DEFINE_REG(cmp3); - SEQZ(cmp3, byte3); - DEFINE_REG(byte2); - BFEXT(byte2, temp, 16, 8); - DEFINE_REG(cmp2); - SEQZ(cmp2, byte2); - DEFINE_REG(cmp23); - OR(cmp23, cmp2, cmp3); - DEFINE_REG(byte1); - BFEXT(byte1, temp, 8, 8); - DEFINE_REG(cmp1); - SEQZ(cmp1, byte1); - DEFINE_REG(byte0); - ANDI(byte0, temp, 0xFF); - DEFINE_REG(cmp0); - SEQZ(cmp0, byte0); - DEFINE_REG(cmp01); - OR(cmp01, cmp0, cmp1); - DEFINE_REG(new_T); - OR(new_T, cmp01, cmp23); - SET_SR_T(new_T); - break; - } - - case 0xD: { // XTRCT Rm,Rn - DEBUG_PRINT_ONCE("XTRCT Rm,Rn"); - GET_Rn; - DEFINE_REG(shift_Rn); - SRLI(shift_Rn, Rn, 16); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - BFINS(result, shift_Rn, Rm, 16, 16); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m)) << 16 - | REG_GETKNOWN(REG_R(n)) >> 16); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m)) << 16 - | REG_GETVALUE(REG_R(n)) >> 16); - PTR_CLEAR(n); - break; - } - - case 0xE: { // MULU.W Rm,Rn - DEBUG_PRINT_ONCE("MULU.W Rm,Rn"); - GET_Rn; - DEFINE_REG(ext_Rn); - ANDI(ext_Rn, Rn, 0xFFFF); - GET_Rm; - DEFINE_REG(ext_Rm); - ANDI(ext_Rm, Rm, 0xFFFF); - DEFINE_RESULT_REG(result, MACL); - MUL(result, ext_Rn, ext_Rm); - SET_MACL(result); - CLEAR_MAC_IS_ZERO(); - break; - } - - case 0xF: { // MULS.W Rm,Rn - DEBUG_PRINT_ONCE("MULS.W Rm,Rn"); - GET_Rn; - DEFINE_REG(temp_Rn); - SLLI(temp_Rn, Rn, 16); - DEFINE_REG(ext_Rn); - SRAI(ext_Rn, temp_Rn, 16); - GET_Rm; - DEFINE_REG(temp_Rm); - SLLI(temp_Rm, Rm, 16); - DEFINE_REG(ext_Rm); - SRAI(ext_Rm, temp_Rm, 16); - DEFINE_RESULT_REG(result, MACL); - MUL(result, ext_Rn, ext_Rm); - SET_MACL(result); - CLEAR_MAC_IS_ZERO(); - break; - } - - default: - goto invalid; - } - break; - } // $2xxx - - case 0x3: { - switch (opcode & 0xF) { - - case 0x0: { // CMP/EQ Rm,Rn - DEBUG_PRINT_ONCE("CMP/EQ Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(test); - XOR(test, Rn, Rm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0x2: { // CMP/HS Rm,Rn - DEBUG_PRINT_ONCE("CMP/HS Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(test); - SLTU(test, Rn, Rm); - DEFINE_REG(new_T); - XORI(new_T, test, 1); - SET_SR_T(new_T); - break; - } - - case 0x3: { // CMP/GE Rm,Rn - DEBUG_PRINT_ONCE("CMP/GE Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(test); - SLTS(test, Rn, Rm); - DEFINE_REG(new_T); - XORI(new_T, test, 1); - SET_SR_T(new_T); - break; - } - - case 0x4: { // DIV1 Rm,Rn - DEBUG_PRINT_ONCE("DIV1 Rm,Rn"); - GET_Rn; - DEFINE_REG(new_Q); - SRLI(new_Q, Rn, 31); - GET_SR; - DEFINE_REG(old_Q); - BFEXT(old_Q, SR, SR_Q_SHIFT, 1); - DEFINE_REG(old_T); - BFEXT(old_T, SR, SR_T_SHIFT, 1); - DEFINE_REG(temp_Rn); - SLLI(temp_Rn, Rn, 1); - DEFINE_REG(new_Rn); - OR(new_Rn, temp_Rn, old_T); - DEFINE_REG(M_bit); - BFEXT(M_bit, SR, SR_M_SHIFT, 1); - DEFINE_REG(M_xor_Q); - XOR(M_xor_Q, M_bit, old_Q); - GET_Rm; - DEFINE_REG(temp1); - /* Note: SSA violation for state block optimization */ - DEFINE_RESULT_REG(final_Rn, R[n]); - CREATE_LABEL(div1_MeqQ); - CREATE_LABEL(div1_continue); - GOTO_IF_Z(div1_MeqQ, M_xor_Q); { - ADD(final_Rn, new_Rn, Rm); - SLTU(temp1, final_Rn, new_Rn); - GOTO_LABEL(div1_continue); - } DEFINE_LABEL(div1_MeqQ); { - SUB(final_Rn, new_Rn, Rm); - SLTU(temp1, new_Rn, final_Rn); - } DEFINE_LABEL(div1_continue); - SET_Rn(final_Rn); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(temp2); - XOR(temp2, temp1, M_bit); - DEFINE_REG(final_Q); - XOR(final_Q, new_Q, temp2); - DEFINE_REG(SR_withQ); - BFINS(SR_withQ, SR, final_Q, SR_Q_SHIFT, 1); - DEFINE_REG(new_T); - XOR(new_T, final_Q, M_bit); - DEFINE_REG(final_T); - XORI(final_T, new_T, 1); - DEFINE_RESULT_REG(final_SR, SR); - BFINS(final_SR, SR_withQ, final_T, SR_T_SHIFT, 1); - SET_SR(final_SR); -#ifdef OPTIMIZE_DIVISION - if (cur_PC == state->division_target_PC) { - /* Flush cached state block fields here so they don't get - * picked up on the optimized path */ - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - state->division_target_PC = 0; - } -#endif - break; - } // DIV1 Rm,Rn - - case 0x5: { // DMULU.L Rm,Rn - DEBUG_PRINT_ONCE("DMULU.L Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(lo, MACL); - DEFINE_RESULT_REG(hi, MACH); - MULU_64(lo, Rn, Rm, hi); - SET_MACL(lo); - SET_MACH(hi); - CLEAR_MAC_IS_ZERO(); - cur_cycles += 1; // Minimum number of cycles - break; - } - - case 0x6: { // CMP/HI Rm,Rn - DEBUG_PRINT_ONCE("CMP/HI Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(new_T); - SLTU(new_T, Rm, Rn); - SET_SR_T(new_T); - break; - } - - case 0x7: { // CMP/GT Rm,Rn - DEBUG_PRINT_ONCE("CMP/GT Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(new_T); - SLTS(new_T, Rm, Rn); - SET_SR_T(new_T); - break; - } - - case 0x8: { // SUB Rm,Rn - DEBUG_PRINT_ONCE("SUB Rm,Rn"); - if (m == n) { // SUB Rn,Rn is an alternate way to clear Rn - DEFINE_RESULT_REG(result, R[n]); - MOVEI(result, 0); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - PTR_CLEAR(n); - } else if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { - /* Optimize subtraction a constants */ - const int32_t Rm_value = REG_GETVALUE(REG_R(m)); - ADDI_Rn_NOREG(-Rm_value); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) - Rm_value); - } else { - REG_SETKNOWN(REG_R(n), 0); - } - if (PTR_CHECK(m)) { - /* Subtracting a pointer from anything does not leave - * a valid pointer. */ - PTR_CLEAR(n); - } - } else { - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - SUB(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - } - break; - } - - case 0xA: { // SUBC Rm,Rn - DEBUG_PRINT_ONCE("SUBC Rm,Rn"); - GET_SR_T; - if (m == n) { // SUBC Rn,Rn sets Rn to -(SR.T), and is - // commonly used in signed division - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, zero, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - /* T is unchanged */ - } else { - GET_Rn; - GET_Rm; - DEFINE_REG(temp); - SUB(temp, Rn, Rm); - DEFINE_REG(borrow1); - SLTU(borrow1, Rn, temp); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(borrow2); - SLTU(borrow2, temp, result); - DEFINE_REG(new_T); - OR(new_T, borrow1, borrow2); - SET_SR_T(new_T); - } - break; - } - - case 0xB: { // SUBV Rm,Rn - DEBUG_PRINT_ONCE("SUBV Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - SUB(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(temp0); - XOR(temp0, Rn, Rm); - DEFINE_REG(temp1); - XOR(temp1, Rn, result); - DEFINE_REG(temp2); - AND(temp2, temp0, temp1); - DEFINE_REG(new_T); - SRLI(new_T, temp2, 31); - SET_SR_T(new_T); - break; - } - - case 0xC: { // ADD Rm,Rn - DEBUG_PRINT_ONCE("ADD Rm,Rn"); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { - /* Optimize addition of a constant */ - const int32_t Rm_value = REG_GETVALUE(REG_R(m)); - ADDI_Rn_NOREG(Rm_value); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) + Rm_value); - } else { - REG_SETKNOWN(REG_R(n), 0); - } - if (PTR_CHECK(m)) { - if (PTR_CHECK(n)) { - PTR_CLEAR(n); - } else { - PTR_COPY(m, n, 1); - } - } - } else if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - /* Treat this like MOV Rm,Rn; ADD old_Rn,Rn and optimize - * as above */ - const int32_t old_Rn_value = REG_GETVALUE(REG_R(n)); - const int old_PTR_CHECK = PTR_CHECK(n); - COPY_TO_Rn(R[m]); - PTR_COPY(m, n, 0); - ADDI_Rn_NOREG(old_Rn_value); - REG_SETKNOWN(REG_R(n), 0); - if (old_PTR_CHECK) { - /* We lost the old pointer data in the PTR_COPY() above, - * so just give up and mark it as not a pointer. - * Hopefully this case won't be too common. */ - PTR_CLEAR(n); - } - } else { // Neither operand is a known constant - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ADD(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - if (PTR_CHECK(m)) { - if (PTR_CHECK(n)) { - /* Adding a pointer to a pointer is invalid, so - * clear pointer info for the result register. */ - PTR_CLEAR(n); - } else { - /* ADD Rptr,Rn is equivalent to "MOV Rptr,Rn" - * followed by "ADD old_value_of_Rn,Rn", which we - * treat as a pointer result. */ - PTR_COPY(m, n, 1); - } - } - } - break; - } - - case 0xD: { // DMULS.L Rm,Rn - DEBUG_PRINT_ONCE("DMULS.L Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(lo, MACL); - DEFINE_RESULT_REG(hi, MACH); - MULS_64(lo, Rn, Rm, hi); - SET_MACL(lo); - SET_MACH(hi); - CLEAR_MAC_IS_ZERO(); - cur_cycles += 1; // Minimum number of cycles - break; - } - - case 0xE: { // ADDC Rm,Rn - DEBUG_PRINT_ONCE("ADDC Rm,Rn"); - GET_Rn; - GET_Rm; - GET_SR_T; - DEFINE_REG(temp); - ADD(temp, Rn, Rm); - DEFINE_REG(carry1); - SLTU(carry1, temp, Rn); - DEFINE_RESULT_REG(result, R[n]); - ADD(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(carry2); - SLTU(carry2, result, temp); - DEFINE_REG(new_T); - OR(new_T, carry1, carry2); - SET_SR_T(new_T); - break; - } - - case 0xF: { // ADDV Rm,Rn - DEBUG_PRINT_ONCE("ADDV Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ADD(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(temp0); - XOR(temp0, Rn, Rm); - DEFINE_REG(temp1); - XORI(temp1, temp0, 1); - DEFINE_REG(temp2); - XOR(temp2, Rn, result); - DEFINE_REG(temp3); - AND(temp3, temp1, temp2); - DEFINE_REG(new_T); - SRLI(new_T, temp3, 31); - SET_SR_T(new_T); - break; - } - - default: - goto invalid; - } - break; - } // $3xxx - - case 0x4: { - switch (opcode & 0xFF) { - - // $4xx0 - case 0x00: // SHLL Rn - case 0x20: { // SHAL Rn - DEBUG_PRINT_ONCE("SH[AL]L Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - /* - * If the next instruction is either SHLL or SHAL on the - * same register, we can cache the 1-bit shift from this - * instruction and combine it with the next instruction. - * (We can't do so with multi-bit shifts after a single-bit - * shift, because the multi-bit shifts don't set the T bit - * in SR.) If the next instruction is a delayed branch and - * does not reference the shifted register, we check the - * delay slot as well. - * - * If _this_ instruction is in a delay slot, we don't try - * to optimize at all because the next instruction executed - * may not be the next one in the code stream. Note that - * we check state->branch_type rather than state->delay - * because the latter is cleared at the top of this routine. - */ - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if ((next_opcode & 0xFFDF) == (opcode & 0xFFDF)) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(1); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + 1; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = 1; -#endif - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[n]); - if (shift_count > 32) { - /* Completely shifted out (including T bit) */ - MOVEI(new_T, 0); - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - BFEXT(new_T, Rn, 32 - shift_count, 1); - if (shift_count == 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - SLLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) << shift_count - | 0xFFFFFFFFU >> (32-shift_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) << shift_count); - } - } - SET_SR_T(new_T); - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLL/SHAL - case 0x10: { // DT Rn - DEBUG_PRINT_ONCE("DT Rn"); - GET_Rn; - DEFINE_RESULT_REG(result, R[n]); -#ifdef OPTIMIZE_DELAY - if (fetch && INSN_IS_AVAILABLE(1) && fetch[1]==0x8BFD){ - /* It's a DT/BF loop, so eat as many iterations as we can. - * At most, we consume enough iterations to push us over - * the cycle limit. */ -# ifdef JIT_DEBUG_VERBOSE - DMSG("Found DT/BF delay loop at 0x%08X", (int)cur_PC); -# endif - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF - && REG_GETVALUE(REG_R(n)) > 0 // Just in case - && REG_GETVALUE(REG_R(n)) <= OPTIMIZE_DELAY_OMIT_MAX - ) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("-- Known to be %u cycles, omitting loop", - REG_GETVALUE(REG_R(n))); -# endif - /* The iteration count is known and within the limit - * for omitting the loop code, so just clear the - * register and update the cycle count. */ - cur_cycles += REG_GETVALUE(REG_R(n)) * 4; - MOVEI(result, 0); - SET_Rn(result); - REG_SETVALUE(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(new_T); - MOVEI(new_T, 1); - SET_SR_T(new_T); - INC_PC_BY(2); // Skip over the BF - break; - } - /* Calculate the maximum number of loop iterations we can - * consume with the remaining cycles, but always execute - * at least one iteration. */ - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - /* cycle_limit generally won't be preloaded here, and we - * don't want to carry a previous use too far (so as not to - * create an unnecessarily long-lived register for what's - * essentially a constant value), so we don't bother trying - * to reuse any previous register with LOAD_STATE_ALLOC(). - * However, we _should_ make use of a fixed register if one - * is available. */ - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - DEFINE_REG(temp); - ADDI(temp, cycle_limit, 4-1); // Round the result up - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(cycles_left); - SUB(cycles_left, temp, cycles); - DEFINE_REG(max_loops_temp); - SRAI(max_loops_temp, cycles_left, 2); // 4 cycles per loop - DEFINE_REG(max_loops_test); - SLTS(max_loops_test, max_loops_temp, imm_1); - DEFINE_REG(max_loops); - SELECT(max_loops, imm_1, max_loops_temp, max_loops_test); - /* Don't consume more iterations than are actually - * available. */ - DEFINE_REG(test); - SLTU(test, Rn, max_loops); - DEFINE_REG(num_loops_temp); - SELECT(num_loops_temp, Rn, max_loops, test); - /* Protect against the case of Rn == 0. That should never - * happen in practice (it would take over 10 minutes to - * complete the loop), but since we're optimizing out - * hundreds of cycles here, we can afford a single extra - * instruction to be safe. */ - DEFINE_REG(num_loops); - SELECT(num_loops, num_loops_temp, max_loops, Rn); - SUB(result, Rn, num_loops); - /* Update the cycle counter; since the final loop will have - * its cycles added separately, we subtract one loop's - * worth of cycles before adding. */ - DEFINE_REG(used_cycles_temp); - SLLI(used_cycles_temp, num_loops, 2); - DEFINE_REG(used_cycles); - SUBI(used_cycles, used_cycles_temp, 4); - DEFINE_REG(final_cycles); - ADD(final_cycles, cycles, used_cycles); - STORE_STATE(cycles, final_cycles); - } else // Not optimizable -#endif // OPTIMIZE_DELAY - SUBI(result, Rn, 1); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(new_T); - SEQZ(new_T, result); - SET_SR_T(new_T); - break; - } // DT - - // $4xx1 - case 0x01: { // SHLR Rn - DEBUG_PRINT_ONCE("SHLR Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(1); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + 1; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = 1; -#endif - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[n]); - if (shift_count > 32) { - MOVEI(new_T, 0); - MOVE(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - BFEXT(new_T, Rn, shift_count - 1, 1); - if (shift_count == 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - SRLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> shift_count - | 0xFFFFFFFF << (32-shift_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) >> shift_count); - } - } - SET_SR_T(new_T); - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLR Rn - case 0x11: { // CMP/PZ Rn - DEBUG_PRINT_ONCE("CMP/PZ Rn"); - GET_Rn; - DEFINE_REG(temp); - SLTZ(temp, Rn); - DEFINE_REG(new_T); - XORI(new_T, temp, 1); - SET_SR_T(new_T); - break; - } - case 0x21: { // SHAR Rn - DEBUG_PRINT_ONCE("SHAR Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(1); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + 1; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = 1; -#endif - GET_Rn; - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[n]); - if (shift_count >= 32) { - SRAI(result, Rn, 31); - ANDI(new_T, result, 1); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), - (int32_t)REG_GETVALUE(REG_R(n)) >> 31); - } else { - BFEXT(new_T, Rn, shift_count - 1, 1); - SRAI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> shift_count - | 0xFFFFFFFF << (32-shift_count)); - REG_SETVALUE(REG_R(n), - (int32_t)REG_GETVALUE(REG_R(n))>>shift_count); - } - SET_SR_T(new_T); - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHAR Rn - - // $4xx2 - case 0x02: { // STS.L MACH,@-Rn - DEBUG_PRINT_ONCE("STS.L MACH,@-Rn"); - GET_MACH_COPY; - STORE_dec_Rn(L, MACH); - break; - } - case 0x12: { // STS.L MACL,@-Rn - DEBUG_PRINT_ONCE("STS.L MACL,@-Rn"); - GET_MACL_COPY; - STORE_dec_Rn(L, MACL); - break; - } - case 0x22: { // STS.L PR,@-Rn - DEBUG_PRINT_ONCE("STS.L PR,@-Rn"); - GET_PR; - STORE_dec_Rn(L, PR); - break; - } - - // $4xx3 - case 0x03: { // STC.L SR,@-Rn - DEBUG_PRINT_ONCE("STC.L SR,@-Rn"); - GET_SR; - STORE_dec_Rn(L, SR); - cur_cycles += 1; - break; - } - case 0x13: { // STC.L GBR,@-Rn - DEBUG_PRINT_ONCE("STC.L GBR,@-Rn"); - GET_GBR; - STORE_dec_Rn(L, GBR); - cur_cycles += 1; - break; - } - case 0x23: { // STC.L VBR,@-Rn - DEBUG_PRINT_ONCE("STC.L VBR,@-Rn"); - GET_VBR; - STORE_dec_Rn(L, VBR); - cur_cycles += 1; - break; - } - - // $4xx4 - case 0x04: { // ROTL Rn - DEBUG_PRINT_ONCE("ROTL Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - /* Don't worry about overflow; we only look at the - * lower 5 bits of the value */ - ADD_TO_SHIFT_CACHE(1); - break; - } - } - const unsigned int rotate_count = (CACHED_SHIFT_COUNT() + 1) & 31; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int rotate_count = 1; -#endif - GET_Rn; - DEFINE_REG(new_T); - BFEXT(new_T, Rn, (32 - rotate_count) & 31, 1); - SET_SR_T(new_T); - DEFINE_RESULT_REG(result, R[n]); - RORI(result, Rn, (32 - rotate_count) & 31); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) << rotate_count - | REG_GETKNOWN(REG_R(n)) >> (32 - rotate_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) << rotate_count - | REG_GETVALUE(REG_R(n)) >> (32 - rotate_count)); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } - case 0x24: { // ROTCL Rn - DEBUG_PRINT_ONCE("ROTCL Rn"); - GET_SR_T; - GET_Rn; - DEFINE_REG(new_T); - SRLI(new_T, Rn, 31); - SET_SR_T(new_T); - DEFINE_REG(temp); - SLLI(temp, Rn, 1); - DEFINE_RESULT_REG(result, R[n]); - OR(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(n)) << 1); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) << 1); - PTR_CLEAR(n); - break; - } - - // $4xx5 - case 0x05: { // ROTR Rn - DEBUG_PRINT_ONCE("ROTR Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - ADD_TO_SHIFT_CACHE(1); - break; - } - } - const unsigned int rotate_count = (CACHED_SHIFT_COUNT() + 1) & 31; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int rotate_count = 1; -#endif - GET_Rn; - DEFINE_REG(new_T); - BFEXT(new_T, Rn, (rotate_count + 31) & 31, 1); - SET_SR_T(new_T); - DEFINE_RESULT_REG(result, R[n]); - RORI(result, Rn, rotate_count); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> rotate_count - | REG_GETKNOWN(REG_R(n)) << (32 - rotate_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) >> rotate_count - | REG_GETVALUE(REG_R(n)) << (32 - rotate_count)); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } - case 0x15: { // CMP/PL Rn - DEBUG_PRINT_ONCE("CMP/PL Rn"); - GET_Rn; - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(new_T); - SLTS(new_T, zero, Rn); - SET_SR_T(new_T); - break; - } - case 0x25: { // ROTCR Rn - DEBUG_PRINT_ONCE("ROTCR Rn"); - GET_SR_T; - GET_Rn; - DEFINE_REG(new_T); - ANDI(new_T, Rn, 1); - SET_SR_T(new_T); - DEFINE_REG(temp); - SRLI(temp, Rn, 1); - DEFINE_RESULT_REG(result, R[n]); - BFINS(result, temp, T, 31, 1); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(n)) >> 1); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) >> 1); - PTR_CLEAR(n); - break; - } - - // $4xx6 - case 0x06: { // LDS.L @Rn+,MACH - DEBUG_PRINT_ONCE("LDS.L @Rn+,MACH"); - DEFINE_RESULT_REG(value, MACH); - LOAD_Rn_inc(L, value); - SET_MACH(value); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x16: { // LDS.L @Rn+,MACL - DEBUG_PRINT_ONCE("LDS.L @Rn+,MACL"); - DEFINE_RESULT_REG(value, MACL); - LOAD_Rn_inc(L, value); - SET_MACL(value); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x26: { // LDS.L @Rn+,PR - DEBUG_PRINT_ONCE("LDS.L @Rn+,PR"); - DEFINE_RESULT_REG(value, PR); - LOAD_Rn_inc(L, value); - SET_PR(value); - break; - } - - // $4xx7 - case 0x07: { // LDC.L @Rn+,SR - DEBUG_PRINT_ONCE("LDC.L @Rn+,SR"); - DEFINE_REG(value); - LOAD_Rn_inc(L, value); - DEFINE_RESULT_REG(new_SR, SR); - ANDI(new_SR, value, 0x3F3); - SET_SR(new_SR); - cur_cycles += 2; - state->need_interrupt_check = 1; - break; - } - case 0x17: { // LDC.L @Rn+,GBR - DEBUG_PRINT_ONCE("LDC.L @Rn+,GBR"); - DEFINE_RESULT_REG(value, GBR); - LOAD_Rn_inc(L, value); - SET_GBR(value); - REG_SETKNOWN(REG_GBR, 0); - cur_cycles += 2; - break; - } - case 0x27: { // LDC.L @Rn+,VBR - DEBUG_PRINT_ONCE("LDC.L @Rn+,VBR"); - DEFINE_RESULT_REG(value, VBR); - LOAD_Rn_inc(L, value); - SET_VBR(value); - cur_cycles += 2; - break; - } - - // $4xx8 - case 0x08: case 0x18: case 0x28: { - unsigned int this_count; - switch (opcode>>4 & 0xF) { - case 0x0: // SHLL2 Rn - DEBUG_PRINT_ONCE("SHLL2 Rn"); - this_count = 2; - break; - case 0x1: // SHLL8 Rn - DEBUG_PRINT_ONCE("SHLL8 Rn"); - this_count = 8; - break; - case 0x2: // SHLL16 Rn - DEBUG_PRINT_ONCE("SHLL16 Rn"); - this_count = 16; - break; - default: // Not needed, but avoid a compiler warning - this_count = 0; - break; - } -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - /* For multi-bit shifts, we can accept any size shift in - * the same direction on the next instruction. */ - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (((next_opcode & 0xFFCF) == (opcode & 0xFFCF) - && ((next_opcode>>4 & 0xF) != 3)) //Watch out for invalids - || (next_opcode & 0xFFDF) == (opcode & 0xFF07) - ) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(this_count); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + this_count; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = this_count; -#endif - DEFINE_RESULT_REG(result, R[n]); - if (shift_count >= 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - SLLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) << shift_count - | 0xFFFFFFFFU >> (32-shift_count)); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) << shift_count); - } - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLLx Rn - - // $4xx9 - case 0x09: case 0x19: case 0x29: { - unsigned int this_count; - switch (opcode>>4 & 0xF) { - case 0x0: // SHLR2 Rn - DEBUG_PRINT_ONCE("SHLR2 Rn"); - this_count = 2; - break; - case 0x1: // SHLR8 Rn - DEBUG_PRINT_ONCE("SHLR8 Rn"); - this_count = 8; - break; - case 0x2: // SHLR16 Rn - DEBUG_PRINT_ONCE("SHLR16 Rn"); - this_count = 16; - break; - default: // Not needed, but avoid a compiler warning - this_count = 0; - break; - } -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - /* We could theoretically cached SHLRn + SHAR by treating - * the SHAR as an SHLR instead (since the top bit will be - * zero following SHLRn), but since this would require - * extra logic for a case assumed to be extremely rare, - * we let it slide. */ - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (((next_opcode & 0xFFCF) == (opcode & 0xFFCF) - && ((next_opcode>>4 & 0xF) != 3)) //Watch out for invalids - || (next_opcode & 0xFFFF) == (opcode & 0xFF07) - ) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(this_count); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + this_count; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = this_count; -#endif - DEFINE_RESULT_REG(result, R[n]); - if (shift_count >= 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - SRLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> shift_count - | 0xFFFFFFFF << (32-shift_count)); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) >> shift_count); - } - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLRx Rn - - // $4xxA - case 0x0A: { // LDS Rn,MACH - DEBUG_PRINT_ONCE("LDS Rn,MACH"); - /* Make sure we load a _copy_ of Rn, so a subsequent overwrite - * of the register by a MADD instruction doesn't modify the - * value of Rn as well. */ - DEFINE_RESULT_REG(Rn, MACH); - LOAD_STATE_COPY(Rn, R[n]); - SET_MACH(Rn); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x1A: { // LDS Rn,MACL - DEBUG_PRINT_ONCE("LDS Rn,MACL"); - DEFINE_RESULT_REG(Rn, MACL); - LOAD_STATE_COPY(Rn, R[n]); - SET_MACL(Rn); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x2A: { // LDS Rn,PR - DEBUG_PRINT_ONCE("LDS Rn,PR"); - COPY_FROM_Rn(PR); - break; - } - - // $4xxB - case 0x0B: { // JSR @Rn - DEBUG_PRINT_ONCE("JSR @Rn"); - DEFINE_RESULT_REG(ret_addr, PR); - MOVEI(ret_addr, cur_PC + 4); - SET_PR(ret_addr); - if (BRANCH_IS_FOLDABLE_SUBROUTINE(cur_PC)) { - state->branch_type = SH2BRTYPE_FOLDED; - state->branch_target = BRANCH_FOLD_TARGET(cur_PC); - state->branch_fold_native = BRANCH_FOLD_NATIVE_FUNC(cur_PC); - } else if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - state->branch_target_reg = Rn; - } - state->delay = 1; - cur_cycles += 1; - break; - } - case 0x1B: { // TAS.B @Rn - DEBUG_PRINT_ONCE("TAS.B @Rn"); - DEFINE_REG(value); - LOAD_Rn(B, value); - DEFINE_REG(new_T); - SEQZ(new_T, value); - SET_SR_T(new_T); - DEFINE_REG(new_value); - ORI(new_value, value, 0x80); - STORE_Rn(B, new_value); - cur_cycles += 3; - break; - } - case 0x2B: { // JMP @Rn - DEBUG_PRINT_ONCE("JMP @Rn"); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - state->branch_target_reg = Rn; - } - state->delay = 1; - cur_cycles += 1; - break; - } - - // $4xxE - case 0x0E: { // LDC Rn,SR - DEBUG_PRINT_ONCE("LDC Rn,SR"); - GET_Rn; - DEFINE_RESULT_REG(new_SR, SR); - ANDI(new_SR, Rn, 0x3F3); - SET_SR(new_SR); - state->need_interrupt_check = 1; - break; - } - case 0x1E: { // LDC Rn,GBR - DEBUG_PRINT_ONCE("LDC Rn,GBR"); - COPY_FROM_Rn(GBR); - REG_SETKNOWN(REG_GBR, REG_GETKNOWN(REG_R(n))); - REG_SETVALUE(REG_GBR, REG_GETVALUE(REG_R(n))); - break; - } - case 0x2E: { // LDC Rn,VBR - DEBUG_PRINT_ONCE("LDC Rn,VBR"); - COPY_FROM_Rn(VBR); - break; - } - - // $4xxF - case 0x0F: case 0x1F: case 0x2F: case 0x3F: - case 0x4F: case 0x5F: case 0x6F: case 0x7F: - case 0x8F: case 0x9F: case 0xAF: case 0xBF: - case 0xCF: case 0xDF: case 0xEF: case 0xFF: { // MAC.W @Rm+,@Rn+ - DEBUG_PRINT_ONCE("MAC.W @Rm+,@Rn+"); - - /* Load the values */ - DEFINE_REG(value_m); - LOAD_Rm_inc(W, value_m); - DEFINE_REG(value_n); - LOAD_Rn_inc(W, value_n); - - /* If we're saturating, we may need the old value of MACH/MACL */ - DECLARE_REG(old_MACH); - DECLARE_REG(old_MACL); - if (!CAN_OMIT_MAC_S_CHECK) { - ALLOC_REG(old_MACH); - LOAD_STATE_COPY(old_MACH, MACH); - ALLOC_REG(old_MACL); - LOAD_STATE_COPY(old_MACL, MACL); - } else { // Not needed, but avoid a compiler warning - old_MACH = 0; - old_MACL = 0; - } - - /* Do the actual multiplication and addition */ - if (MAC_IS_ZERO()) { - DEFINE_RESULT_REG(new_MACL, MACL); - DEFINE_RESULT_REG(new_MACH, MACH); - MULS_64(new_MACL, value_m, value_n, new_MACH); - SET_MACL(new_MACL); - SET_MACH(new_MACH); - } else { - GET_MACL; - GET_MACH; - MADDS_64(MACL, value_m, value_n, MACH); - SET_MACL(MACL); - SET_MACH(MACH); - } - - /* Perform saturation if the S flag of SR is set */ - if (!CAN_OMIT_MAC_S_CHECK) { - GET_SR; - DEFINE_REG(saturate); - ANDI(saturate, SR, SR_S); - CREATE_LABEL(macw_nosat); - GOTO_IF_Z(macw_nosat, saturate); { - GET_MACL; - GET_MACH; - DEFINE_REG(value_m_sign); - SLTZ(value_m_sign, value_m); - DEFINE_REG(value_n_sign); - SLTZ(value_n_sign, value_n); - DEFINE_REG(sum_sign); - SLTZ(sum_sign, MACL); // sum < 0 - DEFINE_REG(product_sign); - XOR(product_sign, value_m_sign, value_n_sign); // product < 0 - DEFINE_REG(MACL_sign); - SLTZ(MACL_sign, old_MACL); // MACL < 0 - DEFINE_REG(temp0); - XOR(temp0, product_sign, MACL_sign); - DEFINE_REG(temp1); - XORI(temp1, temp0, 1); // (product<0) == (MACL<0) - DEFINE_REG(temp2); - XOR(temp2, sum_sign, product_sign); // (sum<0) != (product<0) - DEFINE_REG(overflow); - AND(overflow, temp2, temp1); // Nonzero if overflow - DEFINE_REG(overflow_bit); - MOVEI(overflow_bit, 0); - CREATE_LABEL(macw_no_overflow); - GOTO_IF_Z(macw_no_overflow, overflow); { - DEFINE_REG(sat_neg); - MOVEI(sat_neg, 0x80000000); - DEFINE_REG(sat_pos); - NOT(sat_pos, sat_neg); - DEFINE_REG(saturated); - SELECT(saturated, sat_neg, sat_pos, product_sign); - /* Note: SSA violations for state block optimization */ - MOVE(MACL, saturated); - SET_MACL(MACL); - MOVEI(overflow_bit, 1); - } DEFINE_LABEL(macw_no_overflow); - OR(MACH, old_MACH, overflow_bit); - SET_MACH(MACH); - } DEFINE_LABEL(macw_nosat); - } // if (!CAN_OMIT_MAC_S_CHECK) - - CLEAR_MAC_IS_ZERO(); - cur_cycles += 2; - break; - } // MAC.W - - default: - goto invalid; - } - break; - } // $4xxx - - case 0x5: { // MOV.L @(disp,Rm),Rn - DEBUG_PRINT_ONCE("MOV.L @(disp,Rm),Rn"); - const int disp = (opcode & 0xF) * 4; - DEFINE_RESULT_REG(value, R[n]); - LOAD_disp_Rm(L, value, disp); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF && PTR_ISLOCAL(m)) { - PTR_SET_SOURCE(n, REG_GETVALUE(REG_R(m)) + disp); - } - break; - } // $5xxx - - case 0x6: { - switch (opcode & 0xF) { - - case 0x0: { // MOV.B @Rm,Rn - DEBUG_PRINT_ONCE("MOV.B @Rm,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm(B, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x1: { // MOV.W @Rm,Rn - DEBUG_PRINT_ONCE("MOV.W @Rm,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm(W, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x2: { // MOV.L @Rm,Rn - DEBUG_PRINT_ONCE("MOV.L @Rm,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm(L, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF && PTR_ISLOCAL(m)) { - PTR_SET_SOURCE(n, REG_GETVALUE(REG_R(m))); - } - break; - } - - case 0x3: { // MOV Rm,Rn - DEBUG_PRINT_ONCE("MOV Rm,Rn"); - if (state->pending_select && !in_delay) { - state->pending_select = 0; - GET_Rm; - GET_Rn; - DEFINE_RESULT_REG(selected, R[n]); - if (state->select_sense) { - /* If select_sense is nonzero, the branch was a BT or BT/S, - * meaning we _skip_ the new value if SR.T is set. */ - SELECT(selected, Rn, Rm, state->branch_cond_reg); - } else { - SELECT(selected, Rm, Rn, state->branch_cond_reg); - } - SET_Rn(selected); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - } else { - COPY_TO_Rn(R[m]); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m))); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m))); - PTR_COPY(m, n, 0); - } - break; - } - - case 0x4: { // MOV.B @Rm+,Rn - DEBUG_PRINT_ONCE("MOV.B @Rm+,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm_inc(B, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x5: { // MOV.W @Rm+,Rn - DEBUG_PRINT_ONCE("MOV.W @Rm+,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm_inc(W, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x6: { // MOV.L @Rm+,Rn - DEBUG_PRINT_ONCE("MOV.L @Rm+,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm_inc(L, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF && PTR_ISLOCAL(m)) { - PTR_SET_SOURCE(n, REG_GETVALUE(REG_R(m)) - 4); - } - break; - } - - case 0x7: { // NOT Rm,Rn - DEBUG_PRINT_ONCE("NOT Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - NOT(result, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m))); - REG_SETVALUE(REG_R(n), ~REG_GETVALUE(REG_R(m))); - PTR_CLEAR(n); - break; - } - - case 0x8: { // SWAP.B Rm,Rn - DEBUG_PRINT_ONCE("SWAP.B Rm,Rn"); - GET_Rm; - /* BSWAPH swaps both low and high halfwords, but we want to - * keep the high halfword unchanged */ - DEFINE_REG(temp); - BSWAPH(temp, Rm); - DEFINE_RESULT_REG(result, R[n]); - BFINS(result, Rm, temp, 0, 16); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), (REG_GETKNOWN(REG_R(m)) & 0xFFFF0000) - | (REG_GETKNOWN(REG_R(m)) & 0x0000FF00) >> 8 - | (REG_GETKNOWN(REG_R(m)) & 0x000000FF) << 8); - REG_SETVALUE(REG_R(n), (REG_GETVALUE(REG_R(m)) & 0xFFFF0000) - | (REG_GETVALUE(REG_R(m)) & 0x0000FF00) >> 8 - | (REG_GETVALUE(REG_R(m)) & 0x000000FF) << 8); - PTR_CLEAR(n); - break; - } - - case 0x9: { // SWAP.W Rm,Rn - DEBUG_PRINT_ONCE("SWAP.W Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - HSWAPW(result, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), (REG_GETKNOWN(REG_R(m)) & 0xFFFF0000) >> 16 - | (REG_GETKNOWN(REG_R(m)) & 0x0000FFFF) << 16); - REG_SETVALUE(REG_R(n), (REG_GETVALUE(REG_R(m)) & 0xFFFF0000) >> 16 - | (REG_GETVALUE(REG_R(m)) & 0x0000FFFF) << 16); - PTR_CLEAR(n); - break; - } - - case 0xA: { // NEGC Rm,Rn - DEBUG_PRINT_ONCE("NEGC Rm,Rn"); - GET_SR_T; - GET_Rm; - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(borrow); - SLTU(borrow, zero, Rm); - DEFINE_REG(new_T); - OR(new_T, borrow, T); - SET_SR_T(new_T); - DEFINE_REG(temp); - SUB(temp, zero, Rm); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0xB: { // NEG Rm,Rn - DEBUG_PRINT_ONCE("NEG Rm,Rn"); - GET_Rm; - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, zero, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0xC: { // EXTU.B Rm,Rn - DEBUG_PRINT_ONCE("EXTU.B Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ANDI(result, Rm, 0xFF); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m)) | 0xFFFFFF00); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m)) & 0x000000FF); - PTR_CLEAR(n); - break; - } - - case 0xD: { // EXTU.W Rm,Rn - DEBUG_PRINT_ONCE("EXTU.W Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ANDI(result, Rm, 0xFFFF); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m)) | 0xFFFF0000); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m)) & 0x0000FFFF); - PTR_CLEAR(n); - break; - } - - case 0xE: { // EXTS.B Rm,Rn - DEBUG_PRINT_ONCE("EXTS.B Rm,Rn"); - GET_Rm; - DEFINE_REG(temp); - SLLI(temp, Rm, 24); - DEFINE_RESULT_REG(result, R[n]); - SRAI(result, temp, 24); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - (int32_t)(REG_GETKNOWN(REG_R(m)) << 24) >> 24); - REG_SETVALUE(REG_R(n), - (int32_t)(REG_GETVALUE(REG_R(m)) << 24) >> 24); - PTR_CLEAR(n); - break; - } - - case 0xF: { // EXTS.W Rm,Rn - DEBUG_PRINT_ONCE("EXTS.W Rm,Rn"); - GET_Rm; - DEFINE_REG(temp); - SLLI(temp, Rm, 16); - DEFINE_RESULT_REG(result, R[n]); - SRAI(result, temp, 16); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - (int32_t)(REG_GETKNOWN(REG_R(m)) << 16) >> 16); - REG_SETVALUE(REG_R(n), - (int32_t)(REG_GETVALUE(REG_R(m)) << 16) >> 16); - PTR_CLEAR(n); - break; - } - - default: // impossible, but included for consistency - goto invalid; - } - break; - } // $6xxx - - case 0x7: { // ADD #imm,Rn - DEBUG_PRINT_ONCE("ADD #imm,Rn"); - const int8_t imm = opcode & 0xFF; - if (state->pending_select && !in_delay) { - state->pending_select = 0; - GET_Rn; - DEFINE_REG(result); - ADDI(result, Rn, (int32_t)imm); - DEFINE_RESULT_REG(selected, R[n]); - if (state->select_sense) { - /* If select_sense is nonzero, the branch was a BT or BT/S, - * meaning we _skip_ the new value if SR.T is set. */ - SELECT(selected, Rn, result, state->branch_cond_reg); - } else { - SELECT(selected, result, Rn, state->branch_cond_reg); - } - SET_Rn(selected); - REG_SETKNOWN(REG_R(n), 0); - } else { - ADDI_Rn_NOREG((int32_t)imm); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) + (int32_t)imm); - } else { - REG_SETKNOWN(REG_R(n), 0); - } - } - break; - } // $7xxx - - case 0x8: { - switch (opcode>>8 & 0xF) { - - case 0x0: { // MOV.B R0,@(disp,Rm) - DEBUG_PRINT_ONCE("MOV.B R0,@(disp,Rm)"); - const int disp = opcode & 0xF; - GET_R0; - STORE_disp_Rm(B, R0, disp); - break; - } - - case 0x1: { // MOV.W R0,@(disp,Rm) - DEBUG_PRINT_ONCE("MOV.W R0,@(disp,Rm)"); - const int disp = (opcode & 0xF) * 2; - GET_R0; - STORE_disp_Rm(W, R0, disp); - break; - } - - case 0x4: { // MOV.B @(disp,Rm),R0 - DEBUG_PRINT_ONCE("MOV.B @(disp,Rm),R0"); - const int disp = opcode & 0xF; - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_Rm(B, value, disp); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x5: { // MOV.W @(disp,Rm),R0 - DEBUG_PRINT_ONCE("MOV.W @(disp,Rm),R0"); - const int disp = (opcode & 0xF) * 2; - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_Rm(W, value, disp); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x8: { // CMP/EQ #imm,R0 - DEBUG_PRINT_ONCE("CMP/EQ #imm,R0"); - const int8_t imm = opcode & 0xFF; - GET_R0; - DEFINE_REG(test); - SUBI(test, R0, (int32_t)imm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0x9: { // BT label - DEBUG_PRINT_ONCE("BT label"); - GET_SR_T; - if (BRANCH_FALLS_THROUGH(cur_PC) || BRANCH_IS_SELECT(cur_PC)) { - /* We don't need to branch in the native code, and we don't - * need to update PC (because a later instruction will do - * so), but we do need to update the cycle counter - * appropriately. */ - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, BRANCH_IS_SELECT(cur_PC) ? 1 : 2); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, inc_cycles, cycles, T); - STORE_STATE(cycles, new_cycles); - if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 1; - state->branch_cond_reg = T; - } - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BT; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 2; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - break; - } - - case 0xB: { // BF label - DEBUG_PRINT_ONCE("BF label"); - GET_SR_T; - if (BRANCH_FALLS_THROUGH(cur_PC) || BRANCH_IS_SELECT(cur_PC)) { - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, BRANCH_IS_SELECT(cur_PC) ? 1 : 2); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, cycles, inc_cycles, T); - STORE_STATE(cycles, new_cycles); - if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 0; - state->branch_cond_reg = T; - } - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BF; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 2; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - break; - } - - case 0xD: { // BT/S label - DEBUG_PRINT_ONCE("BT/S label"); - GET_SR_T; - /* For delayed SELECT branches, the cycle count ends up the - * same whether the branch is taken or not, so we can skip all - * the cycle stuff. */ - if (BRANCH_FALLS_THROUGH(cur_PC)) { - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, 1); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, inc_cycles, cycles, T); - STORE_STATE(cycles, new_cycles); - break; - } else if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 1; - state->branch_cond_reg = T; - state->delay = 1; - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BT_S; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 1; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - state->delay = 1; - /* Unlike the other delayed branch instructions, we don't add - * the extra cycle for conditional branches until we actually - * branch; this avoids having to add a variable number of - * cycles to the cycle counter and thus breaking compile-time - * accumulation of cycles with OPTIMIZE_CONSTANT_ADDS. */ - break; - } - - case 0xF: { // BF/S label - DEBUG_PRINT_ONCE("BF/S label"); - GET_SR_T; - if (BRANCH_FALLS_THROUGH(cur_PC)) { - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, 1); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, inc_cycles, cycles, T); - STORE_STATE(cycles, new_cycles); - break; - } else if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 0; - state->branch_cond_reg = T; - state->delay = 1; - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BF_S; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 1; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - state->delay = 1; - break; - } - - default: - goto invalid; - } - break; - } // $8xxx - - case 0x9: { // MOV.W @(disp,PC),Rn - DEBUG_PRINT_ONCE("MOV.W @(disp,PC),Rn"); - const int disp = (opcode & 0xFF) * 2; - const uint32_t address = cur_PC + 4 + disp; - DEFINE_RESULT_REG(value, R[n]); - SH2_LOAD_ABS_W(value, address); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } // $9xxx - - case 0xA: { // BRA label - DEBUG_PRINT_ONCE("BRA label"); - if (BRANCH_FALLS_THROUGH(cur_PC)) { - cur_cycles += 1; - break; - } - if (BRANCH_TARGETS_RTS(cur_PC)) { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_PR; - state->branch_target_reg = PR; - cur_cycles += 3; - } else { - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - const int disp = ((int32_t)(opcode & 0xFFF) << 20) >> 19; - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + disp; - } - state->delay = 1; - cur_cycles += 1; - break; - } // $Axxx - - case 0xB: { // BSR label - DEBUG_PRINT_ONCE("BSR label"); - const int disp = ((int32_t)(opcode & 0xFFF) << 20) >> 19; - DEFINE_RESULT_REG(ret_addr, PR); - MOVEI(ret_addr, cur_PC + 4); - SET_PR(ret_addr); - if (BRANCH_IS_FOLDABLE_SUBROUTINE(cur_PC)) { - state->branch_type = SH2BRTYPE_FOLDED; - state->branch_target = BRANCH_FOLD_TARGET(cur_PC); - state->branch_fold_native = BRANCH_FOLD_NATIVE_FUNC(cur_PC); - } else { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + disp; - } - state->delay = 1; - cur_cycles += 1; - break; - } // $Bxxx - - case 0xC: { - const unsigned int imm = opcode & 0xFF; - switch (opcode>>8 & 0xF) { - - case 0x0: { // MOV.B R0,@(disp,GBR) - DEBUG_PRINT_ONCE("MOV.B R0,@(disp,GBR)"); - GET_R0; - STORE_disp_GBR(B, R0, imm); - break; - } - - case 0x1: { // MOV.W R0,@(disp,GBR) - DEBUG_PRINT_ONCE("MOV.W R0,@(disp,GBR)"); - GET_R0; - STORE_disp_GBR(W, R0, imm*2); - break; - } - - case 0x2: { // MOV.L R0,@(disp,GBR) - DEBUG_PRINT_ONCE("MOV.L R0,@(disp,GBR)"); - GET_R0; - STORE_disp_GBR(L, R0, imm*4); - break; - } - - case 0x3: { // TRAPA #imm - DEBUG_PRINT_ONCE("TRAPA #imm"); - cur_cycles += 7; - DEFINE_REG(PC); - MOVEI(PC, cur_PC + 2); - TAKE_EXCEPTION(imm, PC); - break; - } - - case 0x4: { // MOV.B @(disp,GBR),R0 - DEBUG_PRINT_ONCE("MOV.B @(disp,GBR),R0"); - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_GBR(B, value, imm); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x5: { // MOV.W @(disp,GBR),R0 - DEBUG_PRINT_ONCE("MOV.W @(disp,GBR),R0"); - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_GBR(W, value, imm*2); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x6: { // MOV.L @(disp,GBR),R0 - DEBUG_PRINT_ONCE("MOV.L @(disp,GBR),R0"); - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_GBR(L, value, imm*4); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x7: { // MOVA @(disp,PC),R0 - DEBUG_PRINT_ONCE("MOVA @(disp,PC),R0"); - DEFINE_RESULT_REG(address, R[0]); - MOVEI(address, (cur_PC & ~3) + 4 + imm*4); - SET_R0(address); - REG_SETKNOWN(REG_R(0), 0xFFFFFFFF); - REG_SETVALUE(REG_R(0), (cur_PC & ~3) + 4 + imm*4); - /* Technically it's still a pointer, but the former value is - * gone (and we'll be using absolute loads/stores for this - * register anyway), so clear pointer status */ - PTR_CLEAR(0); - PTR_SETLOCAL(0); // Flag to pass to the load/store routines - break; - } - - case 0x8: { // TST #imm,R0 - DEBUG_PRINT_ONCE("TST #imm,R0"); - GET_R0; -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if (LIKELY(!in_delay) && fetch) { - unsigned int count_reg, count_mask, shift_reg, shift_type; - const uint8_t *cycles_array; - const unsigned int num_insns = can_optimize_variable_shift( - fetch, cur_PC, &count_reg, &count_mask, &shift_reg, - &shift_type, &cycles_array - ); - if (num_insns) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Optimizing variable shift at 0x%08X", (int)cur_PC); -# endif - DECLARE_REG(Rshift); - LOAD_STATE_ALLOC(Rshift, R[shift_reg]); - DEFINE_REG(count); - ANDI(count, R0, count_mask); // count_reg is always 0 - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[shift_reg]); - if (shift_type == 0) { - SRLI(new_T, Rshift, 31); - SLL(result, Rshift, count); - } else { - ANDI(new_T, Rshift, 1); - SRL(result, Rshift, count); - } - STORE_STATE(R[shift_reg], result); - /* SR.T is only set if the shift count is odd */ - GET_SR_T; - DEFINE_REG(test); - ANDI(test, count, 1); - DEFINE_REG(final_T); - SELECT(final_T, new_T, T, test); - SET_SR_T(final_T); - DEFINE_REG(cycles_array_base); - MOVEA(cycles_array_base, ADDR_HI(cycles_array)); - DEFINE_REG(cycles_array_ptr); - ADD(cycles_array_ptr, cycles_array_base, count); - cur_cycles--; // Avoid double-counting this instruction - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(cycles_to_add); - LOAD_BU(cycles_to_add, cycles_array_ptr, - ADDR_LO(cycles_array)); - DEFINE_RESULT_REG(new_cycles, cycles); - ADD(new_cycles, cycles, cycles_to_add); - STORE_STATE(cycles, new_cycles); - INC_PC_BY((num_insns - 1) * 2); - break; - } - } -#endif - DEFINE_REG(test); - ANDI(test, R0, imm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0x9: { // AND #imm,R0 - DEBUG_PRINT_ONCE("AND #imm,R0"); - GET_R0; - DEFINE_RESULT_REG(result, R[0]); - ANDI(result, R0, imm); - SET_R0(result); - REG_SETKNOWN(REG_R(0), REG_GETKNOWN(REG_R(0)) | ~imm); - REG_SETVALUE(REG_R(0), REG_GETVALUE(REG_R(0)) & imm); - break; - } - - case 0xA: { // XOR #imm,R0 - DEBUG_PRINT_ONCE("XOR #imm,R0"); - GET_R0; - DEFINE_RESULT_REG(result, R[0]); - XORI(result, R0, imm); - SET_R0(result); - REG_SETVALUE(REG_R(0), REG_GETVALUE(REG_R(0)) ^ imm); - break; - } - - case 0xB: { // OR #imm,R0 - DEBUG_PRINT_ONCE("OR #imm,R0"); - GET_R0; - DEFINE_RESULT_REG(result, R[0]); - ORI(result, R0, imm); - SET_R0(result); - REG_SETKNOWN(REG_R(0), REG_GETKNOWN(REG_R(0)) | imm); - REG_SETVALUE(REG_R(0), REG_GETVALUE(REG_R(0)) | imm); - break; - } - - case 0xC: { // TST.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("TST.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(test); - ANDI(test, value, imm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0xD: { // AND.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("AND.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(result); - ANDI(result, value, imm); - STORE_SAVED_R0_GBR(B, result); - cur_cycles += 2; - break; - } - - case 0xE: { // XOR.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("XOR.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(result); - XORI(result, value, imm); - STORE_SAVED_R0_GBR(B, result); - cur_cycles += 2; - break; - } - - case 0xF: { // OR.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("OR.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(result); - ORI(result, value, imm); - STORE_SAVED_R0_GBR(B, result); - cur_cycles += 2; - break; - } - - default: // impossible, but included for consistency - goto invalid; - } - break; - - } // $Cxxx - - case 0xD: { // MOV.L @(disp,PC),Rn - DEBUG_PRINT_ONCE("MOV.L @(disp,PC),Rn"); - const int disp = (opcode & 0xFF) * 4; - const uint32_t address = (cur_PC & ~3) + 4 + disp; - DEFINE_RESULT_REG(value, R[n]); - SH2_LOAD_ABS_L(value, address); - REG_SETKNOWN(REG_R(n), 0); - SET_Rn(value); - PTR_CLEAR(n); - PTR_SET_SOURCE(n, address); - break; - } // $Dxxx - - case 0xE: { // MOV #imm,Rn - DEBUG_PRINT_ONCE("MOV #imm,Rn"); - const int8_t imm = opcode & 0xFF; - if (state->pending_select && !in_delay) { - state->pending_select = 0; - GET_Rn; - DEFINE_REG(result); - MOVEI(result, (int32_t)imm); - DEFINE_RESULT_REG(selected, R[n]); - if (state->select_sense) { - /* If select_sense is nonzero, the branch was a BT or BT/S, - * meaning we _skip_ the new value if SR.T is set. */ - SELECT(selected, Rn, result, state->branch_cond_reg); - } else { - SELECT(selected, result, Rn, state->branch_cond_reg); - } - SET_Rn(selected); - REG_SETKNOWN(REG_R(n), 0); - } else { - DEFINE_RESULT_REG(result, R[n]); - MOVEI(result, (int32_t)imm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), (int32_t)imm); - } - PTR_CLEAR(n); - break; - } // $Exxx - - case 0xF: { - goto invalid; - } // $Fxxx - - } - - /**** The Big Honkin' Opcode Switch Ends Here ****/ - - /* Update the PC and cycle count */ - - INC_PC(); - ADD_CYCLES(); - - /* Handle any pending branches */ - - if (UNLIKELY(state->branch_type != SH2BRTYPE_NONE && !state->delay)) { - - int is_idle = 0; - -#ifdef OPTIMIZE_IDLE - if ((state->branch_type == SH2BRTYPE_STATIC - || ((state->branch_type == SH2BRTYPE_BT - || state->branch_type == SH2BRTYPE_BF - || state->branch_type == SH2BRTYPE_BT_S - || state->branch_type == SH2BRTYPE_BF_S) - && !state->branch_targets_rts)) - && state->branch_target >= initial_PC - && state->branch_target < cur_PC - && (cur_PC - state->branch_target) / 2 <= OPTIMIZE_IDLE_MAX_INSNS - && fetch - ) { - const int num_insns = (cur_PC - state->branch_target) / 2; - is_idle = can_optimize_idle((fetch+1) - num_insns, - state->branch_target, num_insns); -# ifdef JIT_DEBUG_VERBOSE - if (is_idle) { - DMSG("Found idle loop at 0x%08X (%d instructions)", - (int)state->branch_target, num_insns); - } -# endif - } -#endif - - switch (state->branch_type) { - - case SH2BRTYPE_NONE: // Avoid a compiler warning - break; - - case SH2BRTYPE_STATIC: { - if (is_idle) { - /* See delay loop handling in DT for why we don't use - * LOAD_STATE_ALLOC here. */ - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - STORE_STATE(cycles, cycle_limit); - } - if (state->loop_to_jsr) { - /* Clear the flag now, or else it'll get picked up if the - * subroutine call is a BSR or the target register is known */ - state->loop_to_jsr = 0; - const uint32_t target = state->branch_target; - RECURSIVE_DECODE(target, 0); - RECURSIVE_DECODE(target+2, 1); - /* The flush/jump will be performed by the subroutine call */ - } else { - SET_PC_KNOWN(state->branch_target); - FLUSH_STATE_CACHE(); - JUMP_STATIC(); - } - state->just_branched = 1; - break; - } - - case SH2BRTYPE_DYNAMIC: { -#ifdef OPTIMIZE_VARIABLE_SHIFTS - /* We still have to jump normally if the branch register is - * outside the shift sequence, so create a label for that */ - CREATE_LABEL(label_do_varshift); - int doing_varshift = 0; - DECLARE_REG(Rcount); - if (state->varshift_target_PC) { - doing_varshift = 1; - DEFINE_REG(test); - LOAD_STATE_ALLOC(Rcount, R[state->varshift_Rcount]); - SLTUI(test, Rcount, - (state->varshift_target_PC + 1) - cur_PC); - GOTO_IF_NZ(label_do_varshift, test); - SAVE_STATE_CACHE(); - } else { // Not needed, but avoid a compiler warning - Rcount = 0; - } -#endif - if (is_idle) { - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - STORE_STATE(cycles, cycle_limit); - } - SET_PC(state->branch_target_reg); - FLUSH_STATE_CACHE(); - JUMP(); -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if (doing_varshift) { - RESTORE_STATE_CACHE(); - DEFINE_LABEL(label_do_varshift); - /* A branch distance of zero means the maximum count */ - DEFINE_REG(count_2_max); - MOVEI(count_2_max, state->varshift_max * 2); - DEFINE_REG(count_2); - SUB(count_2, count_2_max, Rcount); - DEFINE_REG(count); - SRLI(count, count_2, 1); - DECLARE_REG(Rshift); - LOAD_STATE_ALLOC(Rshift, R[state->varshift_Rshift]); - DEFINE_RESULT_REG(new_Rshift, - R[state->varshift_Rshift]); - DEFINE_REG(new_T); - switch (state->varshift_type) { - case 0: { - DEFINE_REG(temp); - SUBI(temp, count, 1); - DEFINE_REG(temp2); - SLL(temp2, Rshift, temp); - SRLI(new_T, temp2, 31); - SLL(new_Rshift, Rshift, count); - break; - } - case 1: { - DEFINE_REG(temp); - SUBI(temp, count, 1); - DEFINE_REG(temp2); - SRL(temp2, Rshift, temp); - ANDI(new_T, temp2, 1); - SRL(new_Rshift, Rshift, count); - break; - } - case 2: { - DEFINE_REG(temp); - SUBI(temp, count, 1); - DEFINE_REG(temp2); - SRA(temp2, Rshift, temp); - ANDI(new_T, temp2, 1); - SRA(new_Rshift, Rshift, count); - break; - } - case 3: { - DEFINE_REG(imm_32); - MOVEI(imm_32, 32); - DEFINE_REG(right_count); - SUB(right_count, imm_32, count); - ROR(new_Rshift, Rshift, right_count); - ANDI(new_T, new_Rshift, 1); - break; - } - case 4: - ROR(new_Rshift, Rshift, count); - SRLI(new_T, new_Rshift, 31); - break; - default: - DMSG("Invalid shift type %u at 0x%X", - state->varshift_type, (unsigned int)cur_PC - 4); - MOVEI(new_T, 0); - break; - } - STORE_STATE(R[state->varshift_Rshift], new_Rshift); - GET_SR_T; - DEFINE_REG(final_T); - SELECT(final_T, new_T, T, count); - SET_SR_T(final_T); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_RESULT_REG(new_cycles, cycles); - ADD(new_cycles, cycles, count); - STORE_STATE(cycles, new_cycles); - INC_PC_BY(state->varshift_target_PC - cur_PC); - /* We fall through in this case, so don't set the - * just_branched flag */ - break; - } -#endif // OPTIMIZE_VARIABLE_SHIFTS - state->just_branched = 1; - break; - } // case SH2BRTYPE_DYNAMIC - - case SH2BRTYPE_RTE: { - SET_PC(state->branch_target_reg); - FLUSH_STATE_CACHE(); - DEFINE_REG(check_interrupts_funcptr); - MOVEA(check_interrupts_funcptr, check_interrupts); - CALL_NORET(state_reg, 0, check_interrupts_funcptr); - JUMP(); - break; - } // case SH2BRTYPE_RTE - - case SH2BRTYPE_BT: - case SH2BRTYPE_BF: - case SH2BRTYPE_BT_S: - case SH2BRTYPE_BF_S: { - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - DECLARE_REG(cycles); - LOAD_STATE_ALLOC_KEEPOFS(cycles, cycles); - if (STATE_CACHE_FIXED_REG(SR)) { - FLUSH_STATE_SR_T(); // Avoid needing to flush it twice - } - SAVE_STATE_CACHE(); - CREATE_LABEL(bt_bf_nobranch); - if (state->branch_type == SH2BRTYPE_BT - || state->branch_type == SH2BRTYPE_BT_S - ) { - GOTO_IF_Z(bt_bf_nobranch, state->branch_cond_reg); - } else { - GOTO_IF_NZ(bt_bf_nobranch, state->branch_cond_reg); - } - if (is_idle) { - STORE_STATE(cycles, cycle_limit); - } else { - DEFINE_RESULT_REG(new_cycles, cycles); - ADDI(new_cycles, cycles, - state->branch_cycles + STATE_CACHE_OFFSET(cycles)); - STORE_STATE(cycles, new_cycles); - } - if (state->branch_targets_rts) { - SET_PC(state->branch_target_reg); - FLUSH_STATE_CACHE(); - JUMP(); - } else if (state->loop_to_jsr) { - state->loop_to_jsr = 0; - const uint32_t target = state->branch_target; - RECURSIVE_DECODE(target, 0); - RECURSIVE_DECODE(target+2, 1); - } else { - SET_PC_KNOWN(state->branch_target); - WRITEBACK_STATE_CACHE(); // Avoid stores of fixed registers - JUMP_STATIC(); - } - DEFINE_LABEL(bt_bf_nobranch); - RESTORE_STATE_CACHE(); - /* We don't set state->just_branched here, because the code - * will fall through if the condition isn't met */ - break; - } // case SH2BRTYPE_B{T,F}{,_S} - - case SH2BRTYPE_FOLDED: { - /* Handle cleanup for this instruction first. */ - OPCODE_DONE(opcode); - /* Clear branch_type now (rather than at the end) so the - * recursive decode doesn't see it. */ - state->branch_type = SH2BRTYPE_NONE; - /* If it's a native implementation, just call it (but remember - * to update PC and flush the state block cache first). */ - if (state->branch_fold_native) { - SET_PC_KNOWN(state->branch_target); - FLUSH_STATE_CACHE(); - unsigned int i; - for (i = 0; i < 8; i++) { - PTR_CLEAR(i); - REG_SETKNOWN(REG_R(i), 0); - } - DEFINE_REG(funcptr_reg); - MOVEA(funcptr_reg, state->branch_fold_native); - CALL_NORET(state_reg, 0, funcptr_reg); - } else { - /* Fold in the contents of the called subroutine. We don't - * accept subroutines with branches in the first place, so - * we just recursively decode one instruction at a time - * until we reach RTS, then process the RTS manually, - * decode the delay slot, and start back up with the - * instruction after the BSR/JSR's delay slot. */ - state->folding_subroutine = 1; - uint32_t sub_PC = state->branch_target; - const uint16_t *sub_fetch = - BRANCH_FOLD_TARGET_FETCH(state->branch_target); - for (;;) { - uint16_t sub_opcode; - if (sub_fetch) { - sub_opcode = *sub_fetch++; - } else { - sub_opcode = MappedMemoryReadWord(sub_PC); - } - if (sub_opcode == 0x000B) { // RTS - break; - } - RECURSIVE_DECODE(sub_PC, 0); - sub_PC += 2; - } - RECURSIVE_DECODE(sub_PC, 0); - RECURSIVE_DECODE(sub_PC+2, 1); - state->folding_subroutine = 0; - DEFINE_REG(post_fold_PC); - MOVEI(post_fold_PC, cur_PC); - SET_PC(post_fold_PC); - } // if (state->branch_fold_native) - break; - } // case SH2BRTYPE_FOLDED - - } // switch (state->branch_type) - - state->branch_type = SH2BRTYPE_NONE; -#ifdef OPTIMIZE_VARIABLE_SHIFTS - state->varshift_target_PC = 0; -#endif - state->branch_targets_rts = 0; - state->loop_to_jsr = 0; - - } // if we need to branch - - /* Check for interrupts if necessary */ - - if (state->need_interrupt_check) { - state->need_interrupt_check = 0; - FLUSH_STATE_CACHE(); - DEFINE_REG(check_interrupts_funcptr); - MOVEA(check_interrupts_funcptr, check_interrupts); - DEFINE_REG(result); - CALL(result, state_reg, 0, check_interrupts_funcptr); - CREATE_LABEL(nointr); - GOTO_IF_Z(nointr, result); { - RETURN(); - } DEFINE_LABEL(nointr); - } - - /* Invalid opcode handler (jumped to on detection of an invalid opcode) */ - - if (0) { - invalid: - if (invalid_opcode_callback) { - (*invalid_opcode_callback)(state, cur_PC, opcode); - } - cur_cycles++; - DEFINE_REG(PC); - MOVEI(PC, cur_PC); - INC_PC(); // So we don't get stuck when translating - TAKE_EXCEPTION(state->delay ? 6 : 4, PC); - } - - /* All done; perform any cleanup requested and return the instruction's - * opcode to the caller. */ - - OPCODE_DONE(opcode); - return opcode; - -} // End of decode_insn() - -/*************************************************************************/ - -#undef GET_REG -#undef GET_R0 -#undef GET_R0_W -#undef GET_R0_B -#undef GET_R15 -#undef GET_Rn -#undef GET_Rm -#undef GET_Rm_W -#undef GET_Rm_B -#undef GET_SR -#undef GET_SR_T -#undef GET_GBR -#undef GET_VBR -#undef GET_MACH -#undef GET_MACL -#undef GET_PR -#undef GET_MACH_COPY -#undef GET_MACL_COPY -#undef GET_REG_KEEPOFS -#undef GET_R0_KEEPOFS -#undef GET_R15_KEEPOFS -#undef GET_Rn_KEEPOFS -#undef GET_Rm_KEEPOFS -#undef GET_GBR_KEEPOFS - -#undef COPY_FROM_Rn -#undef COPY_TO_Rn -#undef DEFINE_RESULT_REG - -#undef SET_R0 -#undef SET_R15 -#undef SET_Rn -#undef SET_Rm -#undef SET_SR -#undef SET_SR_T -#undef SET_GBR -#undef SET_VBR -#undef SET_MACH -#undef SET_MACL -#undef SET_PR -#undef SET_PC -#undef SET_PC_KNOWN - -#undef ADDI_R0 -#undef ADDI_R15 -#undef ADDI_Rn -#undef ADDI_Rm -#undef ADDI_R0_NOREG -#undef ADDI_R15_NOREG -#undef ADDI_Rn_NOREG -#undef ADDI_Rm_NOREG -#undef ADD_CYCLES - -#undef INCDEC_B -#undef INCDEC_W -#undef INCDEC_L -#undef LOAD_Rm -#undef LOAD_disp_Rm -#undef LOAD_R0_Rm -#undef LOAD_Rm_inc -#undef LOAD_Rn -#undef LOAD_Rn_inc -#undef LOAD_disp_GBR -#undef LOAD_R0_GBR -#undef STORE_Rn -#undef STORE_disp_Rn -#undef STORE_dec_Rn -#undef STORE_R0_Rn -#undef STORE_disp_Rm -#undef STORE_disp_GBR -#undef STORE_SAVED_R0_GBR - -#undef TAKE_EXCEPTION -#undef GET_NEXT_OPCODE_FOR_SHIFT_CACHE -#undef DEBUG_PRINT_ONCE - -/*************************************************************************/ - -/* - * Local variables: - * mode: c - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-internal.h b/yabause/src/psp/sh2-internal.h deleted file mode 100644 index 57e31a8fce..0000000000 --- a/yabause/src/psp/sh2-internal.h +++ /dev/null @@ -1,967 +0,0 @@ -/* src/psp/sh2-internal.h: SH-2 emulator internal definitions/declarations - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2_INTERNAL_H -#define SH2_INTERNAL_H - -#ifndef SH2_H -# include "sh2.h" -#endif - -/*************************************************************************/ -/************************* Configuration options *************************/ -/*************************************************************************/ - -/*============ Compilation environment settings ============*/ - -/** - * LOG2_SIZEOF_PTR: The base-2 log of the size of a pointer value (i.e. - * sizeof(void *) == 1 << LOG2_SIZEOF_PTR). - */ -#define LOG2_SIZEOF_PTR (sizeof(void *) == 8 ? 3 : 2) - -/*============ General options ============*/ - -/** - * INTERRUPT_STACK_SIZE: Sets the maximum number of interrupts that can - * be stacked. Any interrupts occurring when the stack is full will be - * lost. - */ -#ifndef INTERRUPT_STACK_SIZE -# define INTERRUPT_STACK_SIZE 50 -#endif - -/** - * ENABLE_JIT: When defined, enables the use of dynamic recompilation. - */ -#define ENABLE_JIT - -/** - * JIT_ACCURATE_ACCESS_TIMING: When defined, checks the current cycle - * count against the cycle limit before each load or store operation to - * ensure that external accesses occur at the proper times, as compared to - * interpreted execution. This does not apply to accesses which can be - * proven to be to internal RAM or ROM ($[02]0[026]xxxxx). - */ -// #define JIT_ACCURATE_ACCESS_TIMING - -/** - * JIT_ACCURATE_LDC_SR_TIMING: When defined, prevents interrupts from - * being accepted during the instruction following an LDC ...,SR - * instruction, just like a real SH-2 processor. When not defined, accepts - * interrupts immediately following an LDC ...,SR instruction, which may - * provide better performance depending on the code being executed. - */ -// #define JIT_ACCURATE_LDC_SR_TIMING - -/** - * JIT_ALLOW_DISTANT_BRANCHES: When defined, the translator will scan - * forward past an unconditional branch for branch targets later in the - * SH-2 code and attempt to include them in the same block. Otherwise, - * only a branch targeting the instruction immediately following the - * branch's delay slot (or targeting the delay slot itself) will be - * considered as part of the same block. - */ -#define JIT_ALLOW_DISTANT_BRANCHES - -/** - * JIT_TABLE_SIZE: Specifies the size of the dynamic translation (JIT) - * routine table. The larger the table, the more translated code can be - * retained in memory, but the greater the cost of stores that overwrite - * previously-translated code. This should always be a prime number. - */ -#ifndef JIT_TABLE_SIZE -# define JIT_TABLE_SIZE 4001 -#endif - -/** - * JIT_DATA_LIMIT_DEFAULT: Specifies the default for the maximum total - * size of translated code, in bytes of native code. When this limit is - * reached, the least recently created translations will be purged from - * memory to make room for new translations. This limit can be changed - * dynamically with sh2_set_jit_data_limit(). - */ -#ifndef JIT_DATA_LIMIT_DEFAULT -# define JIT_DATA_LIMIT_DEFAULT 20000000 -#endif - -/** - * JIT_BRANCH_PREDICTION_SLOTS: Specifies the number of dynamic branch - * prediction slots to use for each block of translated code. A larger - * value increases the number of different branch targets which can be - * predicted without having to search for the code in the global - * translation table, but slows down processing of code with varying - * branch targets. Each slot also uses up 16 * JIT_TABLE_SIZE bytes of - * memory in the translation table (on a 32-bit system). - * - * A value of zero disables branch prediction entirely (including optimized - * static branch prediction). - */ -#ifndef JIT_BRANCH_PREDICTION_SLOTS -# define JIT_BRANCH_PREDICTION_SLOTS 3 -#endif - -/** - * JIT_BRANCH_PREDICTION_FLOAT: When defined, causes successfully - * predicted dynamic branches to "float" up the predicted branch table, so - * they can be found more quickly the next time the block is executed. - * Whether this helps or hurts performance depends on the particular code - * being executed; blocks called from a single location many times followed - * by a different single location many times will benefit, while blocks - * which are alternately called by two or more locations will suffer. - * - * This option has no effect (obviously) if the value of - * JIT_BRANCH_PREDICTION_SLOTS is 0 or 1. - */ -#define JIT_BRANCH_PREDICTION_FLOAT - -/** - * JIT_BRANCH_PREDICT_STATIC: When defined, optimizes static branches and - * block termination code to minimize the overhead of jumping from one - * block to another. - * - * This option is ignored if the value of JIT_BRANCH_PREDICTION_SLOTS is 0. - */ -// #define JIT_BRANCH_PREDICT_STATIC - -/** - * JIT_INSNS_PER_BLOCK: Specifies the maximum number of SH-2 instructions - * (or 16-bit words of local data) to translate in a single block. A - * larger value allows larger blocks of code to be translated as a single - * unit, potentially increasing execution speed at the cost of longer - * translation delays. - */ -#ifndef JIT_INSNS_PER_BLOCK -# define JIT_INSNS_PER_BLOCK 512 -#endif - -/** - * JIT_MAX_INSN_GAP: Specifies the maximum number of 16-bit words to skip - * between SH-2 instructions or local data before terminating the block. - * A larger value allows common paths through a block to be translated as a - * single unit and helps detection of local data that does not immediately - * follow the last translated instruction, but may result in some segments - * of code being translated multiple times. - * - * Setting this option to 0 is not recommended when using the runtime- - * selectable OPTIMIZE_LOCAL_ACCESSES optimization, since doing so prevents - * recognition of all local data in blocks that end on a non-32-bit-aligned - * address. - */ -#ifndef JIT_MAX_INSN_GAP -# define JIT_MAX_INSN_GAP 256 -#endif - -/** - * JIT_BTCACHE_SIZE: Specifies the size of the branch target cache. - * A larger cache increases the amount of SH-2 code that can be translated - * as a single block, but increases the time required to translate branch - * instructions. - */ -#ifndef JIT_BTCACHE_SIZE -# define JIT_BTCACHE_SIZE 256 -#endif - -/** - * JIT_UNRES_BRANCH_SIZE: Specifies the size of the unresolved branch - * table. A larger table size increases the complexity of SH-2 code that - * can be translated as a single block, but increases the time required to - * translate all instructions. - */ -#ifndef JIT_UNRES_BRANCH_SIZE -# define JIT_UNRES_BRANCH_SIZE 32 -#endif - -/** - * JIT_PAGE_BITS: Specifies the page size used for checking whether a - * store operation affects a previously-translated block, in powers of two - * (e.g. a value of 8 means a page size of 256 bytes). A larger page size - * decreases the amount of memory needed for the page tables, but increases - * the chance of an ordinary data write triggering an expensive check of - * translated blocks. - */ -#ifndef JIT_PAGE_BITS -# define JIT_PAGE_BITS 8 -#endif - -/** - * JIT_BLACKLIST_SIZE: Specifies the size of the blacklist used for - * tracking regions of memory that should not be translated due to runtime - * modifications by nearby code. A smaller blacklist size increases the - * speed of handling writes to such regions as well as the speed of code - * translation, but also increases the chance of thrashing on the table, - * which can significantly degrade performance. - */ -#ifndef JIT_BLACKLIST_SIZE -# define JIT_BLACKLIST_SIZE 10 -#endif - -/** - * JIT_BLACKLIST_EXPIRE: Specifies the time after which a blacklist entry - * will expire if it has not been written to. The unit is calls to - * jit_exec(), so the optimal value will need to be found through - * experimentation. - */ -#ifndef JIT_BLACKLIST_EXPIRE -# define JIT_BLACKLIST_EXPIRE 1000000 -#endif - -/** - * JIT_PURGE_TABLE_SIZE: Specifies the size of the purge table, which - * holds addresses of SH-2 code blocks whose translations have been purged - * from memory due to failure of optimization preconditions. A larger - * table size slows down the translation of code blocks as well as the - * handling of a purge operation. - * - * This value is also used for the size of the "pending blacklist" table, - * used to track addresses which cause jit_clear_write() faults many times - * in rapid succession so that they can be blacklisted to avoid repeated - * retranslation of the affected blocks. (This latter table is essentially - * the equivalent of the purge table for data accesses.) - */ -#ifndef JIT_PURGE_TABLE_SIZE -# define JIT_PURGE_TABLE_SIZE 16 -#endif - -/** - * JIT_PURGE_THRESHOLD: Specifies the number of purges on a single block - * after which all optimizations which require precondition checks are - * disabled for that block. This prevents blocks which take varying - * parameters (pointers to different memory regions, for example) from - * requiring a retranslation on potentially every call. This value must - * be greater than 1 (a value of 1 may cause incorrect operation). - * - * This value is also used for the blacklisting threshold of the pending - * blacklist table. - */ -#ifndef JIT_PURGE_THRESHOLD -# define JIT_PURGE_THRESHOLD 3 -#endif - -/** - * JIT_PURGE_EXPIRE: Specifies the time after which a purge table entry - * will expire. The unit is calls to jit_exec(), so the optimal value will - * need to be found through experimentation. - * - * This value is also used for the expiration time of entries in the - * pending blacklist table. - */ -#ifndef JIT_PURGE_EXPIRE -# define JIT_PURGE_EXPIRE 100000 -#endif - -/*============ Code generation options ============*/ - -/** - * JIT_USE_RTL_REGIMM: When defined, causes the JIT core to use the RTL - * register-immediate instructions (RTLOP_ADDI, etc.); when not defined, - * the JIT core will instead load immediate operands into registers which - * are then used with the register-register form of the instruction. - * - * For MIPS, the register-immediate instructions are a significant win. - */ -#define JIT_USE_RTL_REGIMM - -/** - * JIT_USE_RTL_BITFIELDS: When defined, causes the JIT core to use the RTL - * bitfield manipulation instructions (RTLOP_BFINS and RTLOP_BFEXT) where - * convenient; when not defined, appropriate combinations of AND, OR, - * and shifts will be used instead. - * - * This is generally a win on any architecture supporting bitfield - * manipulation instructions, including the MIPS Allegrex (PSP) - * architecture. - */ -#define JIT_USE_RTL_BITFIELDS - -/*============ Optimization options ============*/ - -/** - * OPTIMIZE_IDLE: When defined, attempts to find "idle loops", i.e. loops - * which continue indefinitely until some external event occurs, and modify - * their behavior to increase processing speed. Specifically, when an idle - * loop finishes an iteration and branches back to the beginning of the - * loop, the virtual processor will consume all pending execution cycles - * immediately rather than continue executing the loop until the requested - * number of cycles have passed. - * - * This optimization will slightly change execution timing as compared to - * real hardware, since the number of cycles per loop is ignored when - * consuming pending cycles. - */ -#define OPTIMIZE_IDLE - -/** - * OPTIMIZE_IDLE_MAX_INSNS: When OPTIMIZE_IDLE is defined, specifies the - * maximum number of instructions to consider when looking at a single - * potential idle loop. - */ -#ifndef OPTIMIZE_IDLE_MAX_INSNS -# define OPTIMIZE_IDLE_MAX_INSNS 8 -#endif - -/** - * OPTIMIZE_DELAY: When defined, modifies the behavior of delay loops of - * the form - * label: DT Rn - * BF label - * to increase their execution speed. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_DELAY - -/** - * OPTIMIZE_DELAY_OMIT_MAX: Specifies the maximum number of iterations for - * omitting delay loops entirely from the translated code. - * - * When OPTIMIZE_DELAY is defined and a delay loop with a known number of - * iterations is found, if that known number of iterations is no greater - * than this value, the loop will be optimized out completely and replaced - * with code to consume the appropriate number of cycles (4 cycles per - * iteration) and clear the counter register to zero. - */ -#ifndef OPTIMIZE_DELAY_OMIT_MAX -# define OPTIMIZE_DELAY_OMIT_MAX 100 -#endif - -/** - * OPTIMIZE_DIVISION: When defined, attempts to find instruction sequences - * that perform division operations and replace them with native division - * instructions. This can achieve a speed increase of an order of - * magnitude or more with respect to the division operation. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_DIVISION - -/** - * OPTIMIZE_SHIFT_SEQUENCES: When defined, replaces sequences of similar - * shift instructions with a single native shift instruction of the total - * count. The following replacements are performed: - * - * - Zero or more SHLL{2,8,16} Rn followed by one or more SH[AL]L Rn - * ==> SLLI(Rn,Rn,count) and set T - * - One or more SHLL{2,8,16} Rn _not_ followed by SH[AL]L Rn - * ==> SLLI(Rn,Rn,count) - * - * - Zero or more SHLR{2,8,16} Rn followed by one or more SHLR Rn - * ==> SRLI(Rn,Rn,count) and set T - * - One or more SHLR{2,8,16} Rn _not_ followed by SHLR Rn - * ==> SRLI(Rn,Rn,count) - * - * - One or more SHAR Rn ==> SRAI(Rn,Rn,count) - * - * - One or more ROTL Rn ==> RORI(Rn,Rn,(32-count)) - * - * - One or more ROTR Rn ==> RORI(Rn,Rn,count) - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_SHIFT_SEQUENCES - -/** - * OPTIMIZE_VARIABLE_SHIFTS: When defined, replaces instruction sequences - * that perform variable-count shifts with shorter equivalent sequences of - * RTL instructions, potentially allowing multiple branch instructions to - * be eliminated. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * and since it may eliminate branches, it may alter trace output in - * TRACE_LITE mode as well. - */ -#define OPTIMIZE_VARIABLE_SHIFTS - -/** - * OPTIMIZE_KNOWN_VALUES: When defined, tracks which bits of which - * registers have known values and, when possible, performs calculations - * using those values at translation time rather than runtime. - * - * This optimization can cause the timing of cycle count checks to change, - * and therefore alters trace output in all trace modes. - */ -#define OPTIMIZE_KNOWN_VALUES - -/** - * OPTIMIZE_BRANCH_FALLTHRU: When defined, checks for branches which - * branch to the next instruction to be translated and converts them to - * native no-ops. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_BRANCH_FALLTHRU - -/** - * OPTIMIZE_BRANCH_THREAD: When defined, checks for conditional branches - * which branch to another conditional branch of the same sense and - * "threads" the branch through to the final target. This sort of branch - * chain can arise in long blocks of code due to the limited range of the - * conditional branch instructions (-128...+127 instructions). - * - * This optimization alters trace output in all trace modes. - */ -#define OPTIMIZE_BRANCH_THREAD - -/** - * OPTIMIZE_BRANCH_SELECT: When defined, checks for conditional branches - * whose only use is to choose between one of two values for a register, - * and converts such branches into native SELECT operations. - * - * This optimization alters trace output in TRACE mode. - */ -#define OPTIMIZE_BRANCH_SELECT - -/** - * OPTIMIZE_LOOP_TO_JSR: When defined, checks for backward branches that - * target a subroutine call (JSR, BSR, or BSRF) immediately preceding the - * beginning of the current block, and encodes the subroutine call along - * with its delay slot as part of the backward branch, avoiding the need - * to jump to a separate block just for the subroutine call. - * - * This optimization alters trace output in all trace modes. - */ -#define OPTIMIZE_LOOP_TO_JSR - -/** - * OPTIMIZE_STATE_BLOCK: When defined, attempts to minimize the number of - * state block accesses (loads and stores) by keeping live as long as - * possible each RTL register that holds a state block value. Values are - * flushed to memory when branching, and all cached values are cleared at - * branch targets. - */ -#define OPTIMIZE_STATE_BLOCK - -/** - * OPTIMIZE_CONSTANT_ADDS: When defined, accumulates constants added to or - * subtracted from a register, either immediate values in ADD #imm or - * offsets resulting from postincrement/predecrement memory accesses, and - * attempts to minimize the number of actual ADD instructions used to - * update the register in RTL code. - * - * This optimization relies on the following assumptions: - * - * - Offsets will not cause the final address to cross a page (2^19 byte) - * boundary. - * - * - Offsetted stores will not overwrite any code that a store to the - * non-offsetted address would not overwrite. - * - * If either of these assumptions are violated, the translated code will - * behave incorrectly and may crash the host program. - * - * Depends on OPTIMIZE_STATE_BLOCK; if OPTIMIZE_STATE_BLOCK is not defined, - * this optimization will not take place. - */ -#define OPTIMIZE_CONSTANT_ADDS - -/** - * OPTIMIZE_LOOP_REGISTERS: When defined, attempts to keep SH-2 registers - * and other state block fields used in a loop live in RTL registers for - * the duration of the loop, rather than reloading and flushing on each - * iteration. Registers which are only set within the loop (i.e., whose - * final value does not depend on the value of the register at the - * beginning of the loop) are not treated specially. - * - * Loops which include internal forward branches and other sufficiently - * complex loops will not be optimized. - * - * Depends on OPTIMIZE_STATE_BLOCK; if OPTIMIZE_STATE_BLOCK is not defined, - * this optimization will not take place. - */ -#define OPTIMIZE_LOOP_REGISTERS - -/** - * OPTIMIZE_LOOP_REGISTERS_MAX_REGS: Specifies the maximum number of RTL - * registers to keep live over a loop. Higher values minimize reload - * operations at the RTL generation level, but may increase reloads at the - * native code level due to register pressure. - */ -#ifndef OPTIMIZE_LOOP_REGISTERS_MAX_REGS -# define OPTIMIZE_LOOP_REGISTERS_MAX_REGS 12 -#endif - -/** - * OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD: Specifies the number of - * references to an unoptimizable pointer which will cause the block to be - * terminated immediately before the first access (thus providing another - * chance to optimize the pointer). A value of 1 will be treated as 2; a - * value of 0 disables this check entirely. - */ -#ifndef OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD -# define OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD 3 -#endif - -/** - * OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH: Specifies the maximum number of - * instructions in a subroutine (excluding the terminating RTS and its - * delay slot) for the subroutine to qualify as foldable for the - * SH2_OPTIMIZE_FOLD_SUBROUTINES optimization. - */ -#ifndef OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH -# define OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH 16 -#endif - -/** - * JIT_OPTIMIZE_FLAGS: Specifies the optimizations that should be - * performed on the generated RTL code. See RTLOPT_* in rtl.h for details - * on the available flags. - */ -#ifndef JIT_OPTIMIZE_FLAGS -# define JIT_OPTIMIZE_FLAGS 0 // Optimization doesn't currently win us much -#endif - -/*============ Debugging options ============*/ - -/** - * TRACE: When defined, all instructions and all store operations are - * traced using the functions passed to sh2_trace_insn_callback() and - * sh2_trace_store[bwl]_callback(). - */ -// #define TRACE - -/** - * TRACE_STEALTH: When defined, all instructions and all store operations - * are traced in a way that does not affect the behavior of the generated - * code. Where TRACE inserts RTL instructions to flush cached values and - * call the relevant trace functions (thus updating memory more often than - * usual and potentially hiding bugs), TRACE_STEALTH inserts specially- - * coded NOP instructions that inform the RTL interpreter and native code - * translators about cached values and direct it to call the tracing - * functions itself, thus not affecting the behavior of the RTL code. - * (This requires significantly more overhead than regular tracing with the - * TRACE option.) Note that it is also necessary to define - * RTL_TRACE_STEALTH_FOR_SH2 in rtl-internal.h to enable support for this - * option. - * - * Due to optimization (such as clobbering of dead registers), - * TRACE_STEALTH is likely to not work correctly with native code. - * - * TRACE takes precedent over TRACE_STEALTH; if TRACE is defined, then - * TRACE_STEALTH is ignored and tracing code is added directly to the RTL - * code stream. - */ -// #define TRACE_STEALTH - -/** - * TRACE_LITE: When defined, traces instructions at the rate of one per - * call to sh2_run(). This allows the progress of execution to be - * monitored without the significant overhead imposed by inserting trace - * calls for every instruction in the code stream. - * - * TRACE and TRACE_STEALTH take precedence over TRACE_LITE; if either of - * the former two are defined, TRACE_LITE is ignored rather than causing a - * duplicate trace to be output at the beginning of an sh2_run() call. - */ -// #define TRACE_LITE - -/** - * TRACE_LITE_VERBOSE: When defined and when TRACE_LITE is also enabled, - * additionally traces once per call to jit_exec() (except the first in - * each sh2_run() call, to avoid a double trace). - */ -// #define TRACE_LITE_VERBOSE - -/** - * DEBUG_DECODER_INSN_COVERAGE: When defined, a debug line is printed the - * first time the SH-2 decoder encounters each instruction (specifically, - * each opcode pattern handled by a distinct code block). This can be used - * to check the coverage of test runs. - */ -// #define DEBUG_DECODER_INSN_COVERAGE - -/** - * JIT_DEBUG: When defined, debug messages are output in cases that may - * indicate a problem in the translation or optimization of SH-2 code. - */ -// #define JIT_DEBUG - -/** - * JIT_DEBUG_VERBOSE: When defined, additional debug messages are output - * in certain cases considered useful in fine-tuning the translation and - * optimization. - */ -// #define JIT_DEBUG_VERBOSE - -/** - * JIT_DEBUG_TRACE: When defined, a trace line is printed for each SH-2 - * instruction translated. This option is independent of the other trace - * options. - */ -// #define JIT_DEBUG_TRACE - -/** - * JIT_DEBUG_INSERT_PC: When defined, causes the native code generator to - * insert dummy instructions at the beginning of the code for each SH-2 - * instruction, indicating the SH-2 PC for that instruction. The dummy - * instructions are of the form: - * (RTL) - * nop 0x12345678 - * (MIPS) - * lui $zero, 0x1234 - * ori $zero, $zero, 0x5678 - * for SH-2 PC 0x12345678. - */ -// #define JIT_DEBUG_INSERT_PC - -/** - * JIT_DEBUG_INTERPRET_RTL: When defined, causes the JIT core to execute - * RTL instruction sequences directly rather than translating them into - * MIPS machine code. - * - * This is currently forced on when not compiling on PSP since the only - * available RTL->native translator at the moment is the MIPS translator. - */ -// #define JIT_DEBUG_INTERPRET_RTL - -/** - * JIT_PROFILE: When defined, counts the number of times each code block - * is executed and the time spent in execution. Every JIT_PROFILE_INTERVAL - * SH-2 clock cycles, the first JIT_PROFILE_TOP callees in terms of - * execution time and number of calls are printed. - */ -// #define JIT_PROFILE -#ifndef JIT_PROFILE_INTERVAL -# define JIT_PROFILE_INTERVAL 50000000 -#endif -#ifndef JIT_PROFILE_TOP -# define JIT_PROFILE_TOP 10 -#endif - -/** - * PSP_TIME_TRANSLATION: When defined, calculates the average amount of - * time required to translate a single SH-2 instruction. Only works on the - * PSP. - */ -// #define PSP_TIME_TRANSLATION - -/*************************************************************************/ - -/* Perform sanity checks on configuration options */ - -#if JIT_BRANCH_PREDICTION_SLOTS <= 0 -# undef JIT_BRANCH_PREDICT_STATIC -#endif - -#if JIT_PURGE_THRESHOLD < 2 -# undef JIT_PURGE_THRESHOLD -# define JIT_PURGE_THRESHOLD 2 -#endif - -#ifndef OPTIMIZE_STATE_BLOCK -# undef OPTIMIZE_CONSTANT_ADDS -# undef OPTIMIZE_LOOP_REGISTERS -#endif - -#if !defined(TRACE) || !defined(OPTIMIZE_DIVISION) -# undef TRACE_OPTIMIZED_DIVISION -#endif - -#ifdef TRACE -# undef TRACE_STEALTH -# undef TRACE_LITE -#endif - -#ifdef TRACE_STEALTH -# undef TRACE_LITE -#endif - -#ifndef TRACE_LITE -# undef TRACE_LITE_VERBOSE -#endif - -#ifndef PSP -# define JIT_DEBUG_INTERPRET_RTL -# undef PSP_TIME_TRANSLATION -#endif - -/*************************************************************************/ -/************** Internal-use data and function declarations **************/ -/*************************************************************************/ - -/******** sh2.c ********/ - -/* Bitmask indicating which optional optimizations are enabled */ -extern uint32_t optimization_flags; - -/* Callback function for manual/special-case optimization */ -extern SH2OptimizeCallback *manual_optimization_callback; - -/* Callback function for native CPU cache flushing */ -extern SH2CacheFlushCallback *cache_flush_callback; - -/* Callback function for invalid instructions */ -extern SH2InvalidOpcodeCallback *invalid_opcode_callback; - -/* Callback functions for tracing */ -extern SH2TraceInsnCallback *trace_insn_callback; -extern SH2TraceAccessCallback *trace_storeb_callback; -extern SH2TraceAccessCallback *trace_storew_callback; -extern SH2TraceAccessCallback *trace_storel_callback; - -#ifdef ENABLE_JIT -/* Page tables (exported for use in sh2-optimize.c) */ -extern uint8_t *direct_pages[0x2000]; -extern uint8_t *fetch_pages[0x2000]; -extern uint8_t *byte_direct_pages[0x2000]; -extern uint8_t *direct_jit_pages[0x2000]; -#endif - -/** - * check_interrupts: Check whether there are any pending interrupts, and - * service the highest-priority one if so. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero if an interrupt was serviced, else zero - */ -extern FASTCALL int check_interrupts(SH2State *state); - -/******** sh2-interpret.c ********/ - -/** - * interpret_insn: Interpret and execute a single SH-2 instruction at the - * current PC. - * - * [Parameters] - * state: SH-2 processor state - * [Return value] - * None - */ -extern void interpret_insn(SH2State *state); - - -/******** sh2-opcodeinfo.c ********/ - -/** - * SH2_OPCODE_INFO_*: Flags used in the get_opcode_info() return value. - * "Rn" always refers to the register specified by bits 8-11 of the opcode, - * and "Rm" always refers to bits 4-7 of the opcode, regardless of the - * labeling used in the official Hitachi specs. - */ -#define SH2_OPCODE_INFO_USES_R0 (1<< 0) // Uses the value of R0 -#define SH2_OPCODE_INFO_USES_Rm (1<< 1) // Uses the value of Rm -#define SH2_OPCODE_INFO_USES_Rn (1<< 2) // Uses the value of Rn -#define SH2_OPCODE_INFO_USES_R15 (1<< 3) // Uses the value of R15 -#define SH2_OPCODE_INFO_SETS_R0 (1<< 4) // Sets the value of R0 - /* 1<< 5 is unused */ -#define SH2_OPCODE_INFO_SETS_Rn (1<< 6) // Sets the value of Rn -#define SH2_OPCODE_INFO_SETS_SR_T (1<< 7) // Sets the value of SR.T -#define SH2_OPCODE_INFO_ACCESSES_GBR (1<< 8) // Accesses memory through GBR -#define SH2_OPCODE_INFO_ACCESSES_Rm (1<< 9) // Accesses memory through Rm -#define SH2_OPCODE_INFO_ACCESSES_Rn (1<<10) // Accesses memory through Rn -#define SH2_OPCODE_INFO_ACCESSES_R15 (1<<11) // Accesses memory through R15 -#define SH2_OPCODE_INFO_ACCESSES_R0_GBR (1<<12) // Accesses memory thru R0+GBR -#define SH2_OPCODE_INFO_ACCESSES_R0_Rm (1<<13) // Accesses memory thru R0+Rm -#define SH2_OPCODE_INFO_ACCESSES_R0_Rn (1<<14) // Accesses memory thru R0+Rn -#define SH2_OPCODE_INFO_ACCESSES_PC (1<<15) // Accesses memory through PC -#define SH2_OPCODE_INFO_ACCESS_IS_STORE (1<<16) // Memory access is a store -#define SH2_OPCODE_INFO_ACCESS_IS_RMW (1<<17) // Read/modify/write operation -#define SH2_OPCODE_INFO_ACCESS_POSTINC (1<<18) // Postincrement access mode -#define SH2_OPCODE_INFO_ACCESS_PREDEC (1<<19) // Predecrement access mode -#define SH2_OPCODE_INFO_ACCESS_SIZE_B (1<<20) // Memory access is size 1 -#define SH2_OPCODE_INFO_ACCESS_SIZE_W (1<<21) // Memory access is size 2 -#define SH2_OPCODE_INFO_ACCESS_SIZE_L (1<<22) // Memory access is size 4 -#define SH2_OPCODE_INFO_ACCESS_SIZE_LL (1<<23) // Memory access is size 8 -#define SH2_OPCODE_INFO_ACCESS_DISP_4 (1<<24) // 4-bit displacement -#define SH2_OPCODE_INFO_ACCESS_DISP_8 (1<<25) // 8-bit displacement -#define SH2_OPCODE_INFO_BRANCH_UNCOND (1<<26) // Branches unconditionally -#define SH2_OPCODE_INFO_BRANCH_COND (1<<27) // Branches conditionally -#define SH2_OPCODE_INFO_BRANCH_DELAYED (1<<28) // Branches after a delay slot -#define SH2_OPCODE_INFO_VALID (1<<31) // Opcode is valid - -/** - * SH2_OPCODE_INFO_ACCESS_SIZE: Returns the size in bytes of an access - * performed by an instruction, given that instruction's get_opcode_info() - * value. - */ -#define SH2_OPCODE_INFO_ACCESS_SIZE(opcode_info) (((opcode_info) >> 20) & 0xF) - -/** - * init_opcode_info: Initialize the opcode_info[] table. Must be called - * before calling get_opcode_info(). - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void init_opcode_info(void); - -/** - * get_opcode_info: Return information about the given opcode. - * - * [Parameters] - * opcode: SH-2 opcode to obtain information about - * [Return value] - * - */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -extern int32_t get_opcode_info(uint16_t opcode); - -/******** sh2-optimize.c ********/ - -#ifdef OPTIMIZE_IDLE - -/** - * can_optimize_idle: Return whether the given sequence of instructions - * forms an "idle loop", in which the processor remains in a constant state - * (or repeating sequence of states) indefinitely until a certain external - * event occurs, such as an interrupt or a change in the value of a memory- - * mapped register. If an idle loop is detected, also return information - * allowing the loop to be translated into a faster sequence of native - * instructions. - * - * The sequence of instructions is assumed to end with a branch instruction - * to the beginning of the sequence (possibly including a delay slot). - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * count: Number of instructions to check - * [Return value] - * Nonzero if the given sequence of SH-2 instructions form an idle - * loop, else zero - */ -extern int can_optimize_idle(const uint16_t *insn_ptr, uint32_t PC, - unsigned int count); - -#endif // OPTIMIZE_IDLE - -#ifdef OPTIMIZE_DELAY - -/** - * can_optimize_delay: Return whether the given sequence of instructions - * forms a "delay loop", in which a counter register is repeatedly - * decremented with the DT instruction until it reaches zero. - * - * The sequence of instructions is assumed to end with a branch instruction - * to the beginning of the sequence (possibly including a delay slot). - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * count: Number of instructions to check - * counter_ret: Pointer to variable to receive counter register index - * if a delay loop (unmodified if not a delay loop) - * [Return value] - * Number of clock cycles taken by the loop (nonzero) if the given - * sequence of SH-2 instructions form a delay loop, else zero - */ -extern int can_optimize_delay(const uint16_t *insn_ptr, uint32_t PC, - unsigned int count, unsigned int *counter_ret); - -#endif // OPTIMIZE_DELAY - -#ifdef OPTIMIZE_DIVISION - -/** - * can_optimize_div0u: Return whether a sequence of instructions starting - * from a DIV0U instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to DIV0U instruction - * PC: PC of DIV0U instruction - * skip_first_rotcl: Nonzero if the first ROTCL instruction is known to - * be omitted (as may happen if the low word of - * the dividend is known to be zero) - * Rhi_ret: Pointer to variable to receive index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv_ret: Pointer to variable to receive index of divisor register - * [Return value] - * Number of bits of division performed by the instructions following - * the DIV0U instruction (1-32), or zero if the following instructions - * do not perform a division operation - */ -extern int can_optimize_div0u(const uint16_t *insn_ptr, uint32_t PC, - int skip_first_rotcl, - int *Rhi_ret, int *Rlo_ret, int *Rdiv_ret); - -/** - * can_optimize_div0s: Return whether a sequence of instructions starting - * from a DIV0S instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to instruction following DIV0S instruction - * PC: PC of instruction following DIV0S instruction - * Rhi: Index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv: Index of divisor register - * [Return value] - * Nonzero if the next 64 SH-2 instructions form a 32-bit division - * operation, else zero - */ -extern int can_optimize_div0s(const uint16_t *insn_ptr, uint32_t PC, - int Rhi, int *Rlo_ret, int Rdiv); - -#endif // OPTIMIZE_DIVISION - -#ifdef OPTIMIZE_VARIABLE_SHIFTS - -/** - * can_optimize_variable_shift: Return whether a sequence of instructions - * can be optimized to a native variable-count shift operation. - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * Rcount_ret: Pointer to variable to receive index of shift count register - * max_ret: Pointer to variable to receive maximum shift count - * Rshift_ret: Pointer to variable to receive index of target register - * type_ret: Pointer to variable to receive: - * 0 if a SHLL/SHAL sequence - * 1 if a SHLR sequence - * 2 if a SHAR sequence - * 3 if a ROTL sequence - * 4 if a ROTR sequence - * cycles_ret: Pointer to variable to receive pointer to an array of - * cycle counts indexed by shift count (unused for some - * types of sequences) - * [Return value] - * Number of instructions consumed (nonzero) if an optimizable sequence - * is found, else zero - */ -extern unsigned int can_optimize_variable_shift( - const uint16_t *insn_ptr, uint32_t PC, unsigned int *Rcount_ret, - unsigned int *max_ret, unsigned int *Rshift_ret, unsigned int *type_ret, - const uint8_t **cycles_ret); - -#endif // OPTIMIZE_VARIABLE_SHIFTS - -/*************************************************************************/ -/*************************************************************************/ - -#endif // SH2_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-interpret.c b/yabause/src/psp/sh2-interpret.c deleted file mode 100644 index 6866075100..0000000000 --- a/yabause/src/psp/sh2-interpret.c +++ /dev/null @@ -1,498 +0,0 @@ -/* src/psp/sh2-interpret.c: Instruction interpreter for SH-2 emulator - (mostly for debugging) - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "../sh2core.h" - -#include "sh2.h" -#include "sh2-internal.h" - -/*************************************************************************/ -/***************** SH-2 interpreted execution interface ******************/ -/*************************************************************************/ - -/* Declare a register identifier, but don't allocate a new register for it */ -#define DECLARE_REG(name) uintptr_t name - -/* Allocate a register for a declared identifier */ -#define ALLOC_REG(name) /*nothing*/ - -/* Define a new register (equivalent to DECLARE_REG followed by ALLOC_REG) */ -#define DEFINE_REG(name) uintptr_t name - -/* Register-register operations */ -#define MOVE(dest,src) ((dest) = (src)) -#define SELECT(dest,src1,src2,cond) ((dest) = (cond) ? (src1) : (src2)) -#define ADD(dest,src1,src2) ((dest) = (src1) + (intptr_t)(int32_t)(src2)) -#define SUB(dest,src1,src2) ((dest) = (src1) - (intptr_t)(int32_t)(src2)) -#define MUL(dest,src1,src2) ((dest) = (uint32_t)((src1) * (src2))) -#define MULU_64(dest,src1,src2,dest_hi) do { \ - (dest) = (uint32_t)((src1) * (src2)); \ - (dest_hi) = (uint64_t)((uint64_t)(uint32_t)(src1) \ - * (uint64_t)(uint32_t)(src2)) >> 32; \ -} while (0) -#define MULS_64(dest,src1,src2,dest_hi) do { \ - (dest) = (uint32_t)((src1) * (src2)); \ - (dest_hi) = (int64_t)((int64_t)(int32_t)(src1) \ - * (int64_t)(int32_t)(src2)) >> 32; \ -} while (0) -#define MADDU_64(dest,src1,src2,dest_hi) do { \ - uint64_t initial = (uint64_t)(uint32_t)(dest_hi) << 32 \ - | (uint64_t)(uint32_t)(dest); \ - uint64_t product = (uint64_t)(uint32_t)(src1) \ - * (uint64_t)(uint32_t)(src2); \ - uint64_t result = initial + product; \ - (dest) = (uint32_t)result; \ - (dest_hi) = (uint32_t)(result >> 32); \ -} while (0) -#define MADDS_64(dest,src1,src2,dest_hi) do { \ - uint64_t initial = (int64_t)(int32_t)(dest_hi) << 32 \ - | (int64_t)(uint32_t)(dest); \ - uint64_t product = (int64_t)(int32_t)(src1) \ - * (int64_t)(int32_t)(src2); \ - uint64_t result = initial + product; \ - (dest) = (uint32_t)result; \ - (dest_hi) = (uint32_t)(result >> 32); \ -} while (0) -#define DIVMODU(dest,src1,src2,rem) do { \ - if ((src2) != 0) { \ - (dest) = (uint32_t)(src1) / (uint32_t)(src2); \ - (rem) = (uint32_t)(src1) % (uint32_t)(src2); \ - } else { \ - /* Have to set these to avoid a compiler warning */ \ - (dest) = 0; \ - (rem) = 0; \ - } \ -} while (0) -#define DIVMODS(dest,src1,src2,rem) do { \ - if ((src2) != 0) { \ - (dest) = (int32_t)(src1) / (int32_t)(src2); \ - (rem) = (int32_t)(src1) % (int32_t)(src2); \ - } else { \ - /* Have to set these to avoid a compiler warning */ \ - (dest) = 0; \ - (rem) = 0; \ - } \ -} while (0) -#define AND(dest,src1,src2) ((dest) = (src1) & (intptr_t)(int32_t)(src2)) -#define OR(dest,src1,src2) ((dest) = (src1) | (uintptr_t)(uint32_t)(src2)) -#define XOR(dest,src1,src2) ((dest) = (src1) ^ (uintptr_t)(uint32_t)(src2)) -#define NOT(dest,src) ((dest) = (uint32_t)(~(src))) -#define SLL(dest,src1,src2) ((dest) = (uint32_t)((src1) << (src2))) -#define SRL(dest,src1,src2) ((dest) = (uint32_t)(src1) >> (src2)) -#define SRA(dest,src1,src2) ((dest) = (int32_t)(src1) >> (src2)) -#define ROR(dest,src1,src2) \ - ((dest) = (((src2) & 31) \ - ? (uint32_t)(src1) >> ((src2) & 31) \ - | (uint32_t)(src1) << (31-((src2) & 31)) \ - : (uint32_t)(src1))) -#ifdef __GNUC__ -# define CLZ(dest,src) ((dest) = __builtin_clz((src))) -#else -# define CLZ(dest,src) do { \ - uint32_t __temp = (src); \ - (dest) = 32; \ - while (__temp) { \ - __temp >>= 1; \ - (dest)--; \ - } \ -} while (0) -#endif // __GNUC__ -#define CLO(dest,src) do { \ - uint32_t __temp = (src); \ - (dest) = 0; \ - while ((int32_t)__temp < 0) {\ - __temp <<= 1; \ - (dest)++; \ - } \ -} while (0) -#define SLTU(dest,src1,src2) ((dest) = (uint32_t)(src1) < (uint32_t)(src2)) -#define SLTS(dest,src1,src2) ((dest) = (int32_t)(src1) < (int32_t)(src2)) -#define BSWAPH(dest,src) \ - ((dest) = ((uint32_t)(src) & 0xFF00FF00) >> 8 \ - | ((uint32_t)(src) & 0x00FF00FF) << 8) -#define BSWAPW(dest,src) \ - ((dest) = ((uint32_t)(src) & 0xFF000000) >> 24 \ - | ((uint32_t)(src) & 0x00FF0000) >> 8 \ - | ((uint32_t)(src) & 0x0000FF00) << 8 \ - | ((uint32_t)(src) & 0x000000FF) << 24) -#define HSWAPW(dest,src) \ - ((dest) = ((uint32_t)(src) & 0xFFFF0000) >> 16 \ - | ((uint32_t)(src) & 0x0000FFFF) << 16) - -/* Register-immediate operations */ -#define MOVEI(dest,imm) ((dest) = (imm)) -#define MOVEA(dest,addr) ((dest) = (uintptr_t)(addr)) -#define ADDI(dest,src,imm) ((dest) = (src) + (imm)) -#define SUBI(dest,src,imm) ((dest) = (src) - (imm)) -#define ANDI(dest,src,imm) ((dest) = (uint32_t)((src) & (imm))) -#define ORI(dest,src,imm) ((dest) = (uint32_t)((src) | (imm))) -#define XORI(dest,src,imm) ((dest) = (src) ^ (imm)) -#define SLLI(dest,src,imm) ((dest) = (uint32_t)((src) << (imm))) -#define SRLI(dest,src,imm) ((dest) = (uint32_t)(src) >> (imm)) -#define SRAI(dest,src,imm) ((dest) = (int32_t)(src) >> (imm)) -#define RORI(dest,src,imm) \ - ((dest) = (((imm) & 31) \ - ? (uint32_t)(src) >> ((imm) & 31) \ - | (uint32_t)(src) << (32-((imm) & 31)) \ - : (uint32_t)(src))) -#define SLTUI(dest,src,imm) ((dest) = (uint32_t)(src) < (uint32_t)(imm)) -#define SLTSI(dest,src,imm) ((dest) = (int32_t)(src) < (int32_t)(imm)) - -/* Bitfield operations */ -#define BFEXT(dest,src,start,count) \ - ((dest) = ((uint32_t)(src) >> (start)) & ((1 << (count)) - 1)) -#define BFINS(dest,src1,src2,start,count) \ - ((dest) = ((uint32_t)(src1) & ~(((1 << (count)) - 1) << (start))) \ - | (((uint32_t)(src2) & ((1 << (count)) - 1)) << (start))) - -/* Variants of SLT */ -#define SEQZ(dest,src) SLTUI((dest), (src), 1) -#define SLTZ(dest,src) SLTSI((dest), (src), 0) - -/* Load from or store to memory */ -#define LOAD_BU(dest,address,offset) \ - ((dest) = *(uint8_t *)((address)+(offset))) -#define LOAD_BS(dest,address,offset) \ - ((dest) = *(int8_t *)((address)+(offset))) -#define LOAD_HU(dest,address,offset) \ - ((dest) = *(uint16_t *)((address)+(offset))) -#define LOAD_HS(dest,address,offset) \ - ((dest) = *(int16_t *)((address)+(offset))) -#define LOAD_W(dest,address,offset) \ - ((dest) = *(uint32_t *)((address)+(offset))) -#define LOAD_PTR(dest,address,offset) \ - ((dest) = *(uintptr_t *)((address)+(offset))) -#define STORE_B(address,src,offset) \ - (*(uint8_t *)((address)+(offset)) = (src)) -#define STORE_H(address,src,offset) \ - (*(uint16_t *)((address)+(offset)) = (src)) -#define STORE_W(address,src,offset) \ - (*(uint32_t *)((address)+(offset)) = (src)) -#define STORE_PTR(address,src,offset) \ - (*(uintptr_t *)((address)+(offset)) = (src)) - -/* Load from, store to, or add constants to state block fields */ -#define LOAD_STATE(reg,field) ((reg) = state->field) -#define LOAD_STATE_PTR(reg,field) ((reg) = (uintptr_t)state->field) -#define LOAD_STATE_SR_T(reg) ((reg) = (state->SR & SR_T) >> SR_T_SHIFT) -#define STORE_STATE(field,reg) (state->field = (reg)) -#define STORE_STATE_PC(value) (state->PC = (value)) -#define STORE_STATE_B(field,reg) (state->field = (reg)) -#define STORE_STATE_PTR(field,reg) (state->field = (void *)(reg)) -#define STORE_STATE_SR_T(reg) (state->SR &= ~SR_T, \ - state->SR |= ((reg) & 1) << SR_T_SHIFT) -#define FLUSH_STATE_SR_T() /*nothing*/ -#define RESET_STATE_SR_T() /*nothing*/ -#define ADDI_STATE(field,imm,reg) (state->field = (reg) + (imm)) -#define ADDI_STATE_NOREG(field,imm) (state->field += (imm)) - -/* Load from a state block field, but don't change the state block cache */ -#define LOAD_STATE_COPY(name,field) LOAD_STATE(name,field) - -/* Allocate a new register and load it from the state block, or reuse an - * old register if appropriate */ -#define LOAD_STATE_ALLOC(name,field) ALLOC_REG(name); LOAD_STATE(name,field) - -/* Allocate a new register and load it from the state block, or reuse an - * old register (leaving any offset in the cache) if appropriate */ -#define LOAD_STATE_ALLOC_KEEPOFS(name,field) LOAD_STATE_ALLOC(name,field) - -/* Execute an SH-2 load or store operation (note that size desginations are - * SH-2 style B[yte]/W[ord]/L[ong] rather than RTL B[yte]/H[alfword]/W[ord], - * and all 8- and 16-bit loads are signed) */ - -#define SH2_LOAD_B(dest,address) \ - ((dest) = (int8_t)MappedMemoryReadByte((address))) -#define SH2_LOAD_W(dest,address) \ - ((dest) = (int16_t)MappedMemoryReadWord((address))) -#define SH2_LOAD_L(dest,address) \ - ((dest) = MappedMemoryReadLong((address))) - -#ifdef TRACE -# define LOG_STORE(address,src,type) ((*trace_store##type##_callback)((address), (src))) -#else -# define LOG_STORE(address,src,type) /*nothing*/ -#endif -#define SH2_STORE_B(address,src) do { \ - LOG_STORE((address), (src), b); \ - MappedMemoryWriteByte((address), (src)); \ -} while (0) -#define SH2_STORE_W(address,src) do { \ - LOG_STORE((address), (src), w); \ - MappedMemoryWriteWord((address), (src)); \ -} while (0) -#define SH2_STORE_L(address,src) do { \ - LOG_STORE((address), (src), l); \ - MappedMemoryWriteLong((address), (src)); \ -} while (0) - -/* Execute an SH-2 load or store to a known address */ -#define SH2_LOAD_ABS_B(dest,address) SH2_LOAD_B(dest,address) -#define SH2_LOAD_ABS_W(dest,address) SH2_LOAD_W(dest,address) -#define SH2_LOAD_ABS_L(dest,address) SH2_LOAD_L(dest,address) -#define SH2_STORE_ABS_B(address,src,islocal) SH2_STORE_B(address,src) -#define SH2_STORE_ABS_W(address,src,islocal) SH2_STORE_W(address,src) -#define SH2_STORE_ABS_L(address,src,islocal) SH2_STORE_L(address,src) - -/* Execute an SH-2 load or store through an SH-2 register */ -#define SH2_LOAD_REG_B(dest,sh2reg,offset,postinc) do { \ - SH2_LOAD_B(dest, state->R[sh2reg] + (offset)); \ - if (postinc) { \ - state->R[sh2reg] += 1; \ - } \ -} while (0) -#define SH2_LOAD_REG_W(dest,sh2reg,offset,postinc) do { \ - SH2_LOAD_W(dest, state->R[sh2reg] + (offset)); \ - if (postinc) { \ - state->R[sh2reg] += 2; \ - } \ -} while (0) -#define SH2_LOAD_REG_L(dest,sh2reg,offset,postinc) do { \ - SH2_LOAD_L(dest, state->R[sh2reg] + (offset)); \ - if (postinc) { \ - state->R[sh2reg] += 4; \ - } \ -} while (0) -#define SH2_STORE_REG_B(sh2reg,src,offset,predec) do { \ - if (predec) { \ - state->R[sh2reg] -= 1; \ - } \ - SH2_STORE_B(state->R[sh2reg] + (offset), src); \ -} while (0) -#define SH2_STORE_REG_W(sh2reg,src,offset,predec) do { \ - if (predec) { \ - state->R[sh2reg] -= 2; \ - } \ - SH2_STORE_W(state->R[sh2reg] + (offset), src); \ -} while (0) -#define SH2_STORE_REG_L(sh2reg,src,offset,predec) do { \ - if (predec) { \ - state->R[sh2reg] -= 4; \ - } \ - SH2_STORE_L(state->R[sh2reg] + (offset), src); \ -} while (0) - -/* Branches (within an SH-2 instruction's RTL code) */ -#define CREATE_LABEL(label) /*nothing*/ -#define DEFINE_LABEL(label) label: -#define GOTO_LABEL(label) goto label; -#define GOTO_IF_Z(label,reg) if ((reg) == 0) goto label; -#define GOTO_IF_NZ(label,reg) if ((reg) != 0) goto label; -#define GOTO_IF_E(label,reg1,reg2) if ((reg1) == (reg2)) goto label; -#define GOTO_IF_NE(label,reg1,reg2) if ((reg1) != (reg2)) goto label; - -/* Jumps (to other SH-2 instructions) */ -#define JUMP_STATIC() jumped = 1 -#define JUMP() jumped = 1 - -/* Call to a native subroutine */ -#define CALL(result,arg1,arg2,func) do { \ - FASTCALL uintptr_t (*__func)(uintptr_t,uintptr_t) = (void *)(uintptr_t)(func); \ - (result) = (*__func)((arg1), (arg2)); \ -} while (0) -#define CALL_NORET(arg1,arg2,func) do { \ - FASTCALL void (*__func)(uintptr_t,uintptr_t) = (void *)(uintptr_t)(func); \ - (*__func)((arg1), (arg2)); \ -} while (0) - -/* Return from the current block */ -#define RETURN() return 0 - -/*-----------------------------------------------------------------------*/ - -/* We don't have "registers", so alias state_reg directly to the pointer */ -#define state_reg ((uintptr_t)state) - -/* Access the state block directly for the PC */ -#define cur_PC (state->PC) - -/* No direct fetching */ -#define fetch ((uint16_t *)NULL) // uint16_t * to avoid compiler errors - -/* No pre- or post-decode processing needed */ -#define OPCODE_INIT(opcode) /*nothing*/ -#define OPCODE_DONE(opcode) /*nothing*/ - -/* cur_PC and REG_PC are the same thing, so only need to update one of them - * (but only do so for the default case if we didn't already set the PC via - * a jump) */ -#define INC_PC() do { \ - if (!jumped) { \ - cur_PC += 2; \ - } \ -} while (0) -#define INC_PC_BY(amount) (cur_PC += (amount)) - -/* Return whether the word at "offset" words from the current instruction - * is available for peephole optimization */ -#define INSN_IS_AVAILABLE(offset) 0 - -/* Return the "high" (pointer register) and "low" (load/store offset) parts - * of an address for generating optimal native load/store code */ -#define ADDR_HI(address) ((uintptr_t)address) -#define ADDR_LO(address) 0 - -/* Return whether the saturation check for MAC can be omitted */ -#define CAN_OMIT_MAC_S_CHECK 0 - -/* Get or set whether the MACL/MACH pair is known to be zero */ -#define MAC_IS_ZERO() 0 -#define SET_MAC_IS_ZERO() /*nothing*/ -#define CLEAR_MAC_IS_ZERO() /*nothing*/ - -/* Get, add to, or clear the cached shift count */ -#define CAN_CACHE_SHIFTS() 0 -#define CACHED_SHIFT_COUNT() 0 -#define ADD_TO_SHIFT_CACHE(n) /*nothing*/ -#define CLEAR_SHIFT_CACHE() /*nothing*/ - -/* Get or set register known bits and values */ -#define REG_GETKNOWN(reg) 0 -#define REG_GETVALUE(reg) 0 -#define REG_SETKNOWN(reg,value) /*nothing*/ -#define REG_SETVALUE(reg,value) /*nothing*/ - -/* Track pointer registers */ -#define PTR_ISLOCAL(reg) 0 -#define PTR_SETLOCAL(reg) /*nothing*/ -#define PTR_SET_SOURCE(reg,address) /*nothing*/ -#define PTR_CHECK(reg) 0 -#define PTR_COPY(reg,new,for_add) /*nothing*/ -#define PTR_CLEAR(reg) /*nothing*/ - -/* Save the current cache state */ -#define SAVE_STATE_CACHE() /*nothing*/ -/* Restore the saved cache state */ -#define RESTORE_STATE_CACHE() /*nothing*/ -/* Write back to the state block any cached, dirty state block values - * (but leave them dirty) */ -#define WRITEBACK_STATE_CACHE() /*nothing*/ -/* Flush all cached state block values */ -#define FLUSH_STATE_CACHE() /*nothing*/ -/* Return the cached offset for the given state block field, or 0 if none */ -#define STATE_CACHE_OFFSET(field) 0 -/* Return the fixed RTL register to use for the given state block field, - * or 0 if none */ -#define STATE_CACHE_FIXED_REG(field) 0 -/* Return whether the given state block field has a fixed RTL register that - * can be modified */ -#define STATE_CACHE_FIXED_REG_WRITABLE(field) 0 -/* Clear any fixed RTL register for the given state block field */ -#define STATE_CACHE_CLEAR_FIXED_REG(field) /*nothing*/ - -/* Check the status of a branch instruction */ -#define BRANCH_FALLS_THROUGH(addr) 0 -#define BRANCH_TARGETS_RTS(addr) 0 -#define BRANCH_IS_THREADED(addr) 0 -#define BRANCH_THREAD_TARGET(addr) 0 -#define BRANCH_THREAD_COUNT(addr) 0 -#define BRANCH_IS_SELECT(addr) 0 -#define BRANCH_IS_LOOP_TO_JSR(addr) 0 -#define BRANCH_IS_FOLDABLE_SUBROUTINE(addr) 0 -#define BRANCH_FOLD_TARGET(addr) 0 -#define BRANCH_FOLD_TARGET_FETCH(addr) NULL -#define BRANCH_FOLD_NATIVE_FUNC(addr) NULL - -/*************************************************************************/ - -/** - * decode_insn: Decode a single SH-2 instruction. Implements - * interpret_insn() using the shared decoder core. - * - * [Parameters] - * state: SH-2 processor state - * initial_PC: Equal to state->PC (used by OPTIMIZE_IDLE) - * jumped: Local register tracking whether a jump was performed - * [Return value] - * Decoded SH-2 opcode (not used) - */ -#define DECODE_INSN_INLINE NOINLINE -#define DECODE_INSN_PARAMS \ - SH2State *state, uint32_t initial_PC, int jumped -#define RECURSIVE_DECODE(address,is_last) do { \ - const uint32_t saved_PC = state->PC; \ - state->PC = (address); \ - interpret_insn(state); \ - state->PC = saved_PC; \ -} while (0) -#include "sh2-core.i" - -/*-----------------------------------------------------------------------*/ - -/** - * interpret_insn: Interpret and execute a single SH-2 instruction at the - * current PC. - * - * [Parameters] - * state: SH-2 processor state - * [Return value] - * None - */ -void interpret_insn(SH2State *state) -{ - /* Make sure we're not trying to execute from an odd address */ - if (UNLIKELY(state->PC & 1)) { - /* Push SR and PC */ - state->R[15] -= 4; - MappedMemoryWriteLong(state->R[15], state->SR); - state->R[15] -= 4; - MappedMemoryWriteLong(state->R[15], state->PC); - /* Jump to the instruction address error exception vector (9) */ - state->PC = MappedMemoryReadLong(9<<2); - } - - decode_insn(state, state->PC, 0); - - if (UNLIKELY(state->delay)) { - /* Don't treat the instruction after a not-taken conditional branch - * as a delay slot. (Note that when interpreting, the - * branch_cond_reg field holds the actual value of the condition.) */ - if (!(state->branch_type == SH2BRTYPE_BT_S && !state->branch_cond_reg) - && !(state->branch_type == SH2BRTYPE_BF_S && state->branch_cond_reg) - ) { - /* Make sure we interpret the delay slot immediately, so (1) we - * don't try to translate it as the beginning of a block and - * (2) we don't let any exceptions get in the way (SH7604 - * manual page 75, section 4.6.1: exceptions are not accepted - * when processing a delay slot). */ - decode_insn(state, state->PC, 0); - } - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-opcodeinfo.c b/yabause/src/psp/sh2-opcodeinfo.c deleted file mode 100644 index 61b497a544..0000000000 --- a/yabause/src/psp/sh2-opcodeinfo.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* src/psp/sh2-opcodeinfo.c: Information table for SH-2 opcodes - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "sh2.h" -#include "sh2-internal.h" - -/*************************************************************************/ -/************************ Opcode table definition ************************/ -/*************************************************************************/ - -/** - * opcode_info_low: Table of information bits for opcodes with the high - * bit clear; in all such instructions, the "n" field (bits 8-11) is an - * operand or part of an operand. Indexed by bits 0-7 and 12-14 of the - * opcode, i.e. ((opcode & 0x7000) >> 4 | (opcode & 0x00FF)). - */ -static int32_t opcode_info_low[0x800]; - -/** - * opcode_info_high: Table of information bits for opcodes in which the - * "n" field (bits 8-11) is part of the instruction code and the lower 8 - * bits are one or more operands. Indexed by bits 8-14 of the opcode. - */ -static int32_t opcode_info_high[0x80]; - -/*************************************************************************/ -/***************** Opcode table initialization routines ******************/ -/*************************************************************************/ - -/* Forward declarations */ - -static void init_0xxx(void); -static void init_1xxx(void); -static void init_2xxx(void); -static void init_3xxx(void); -static void init_4xxx(void); -static void init_5xxx(void); -static void init_6xxx(void); -static void init_7xxx(void); -static void init_8xxx(void); -static void init_9xxx(void); -static void init_Axxx(void); -static void init_Bxxx(void); -static void init_Cxxx(void); -static void init_Dxxx(void); -static void init_Exxx(void); - -/*************************************************************************/ - -/** - * init_opcode_info: Initialize the opcode_info[] table. Must be called - * before accessing the table. - * - * [Parameters] - * None - * [Return value] - * None - */ -void init_opcode_info(void) -{ - /* First clear the tables (rendering all opcodes invalid)... */ - memset(opcode_info_low, 0, sizeof(opcode_info_low)); - memset(opcode_info_high, 0, sizeof(opcode_info_high)); - - /* ... then fill in the tables by calling subroutines for each opcode - * group. */ - init_0xxx(); - init_1xxx(); - init_2xxx(); - init_3xxx(); - init_4xxx(); - init_5xxx(); - init_6xxx(); - init_7xxx(); - init_8xxx(); - init_9xxx(); - init_Axxx(); - init_Bxxx(); - init_Cxxx(); - init_Dxxx(); - init_Exxx(); - /* 0xFxxx is invalid */ -} - -/*************************************************************************/ - -/** - * init_xxxx: Initialize individual groups of opcodes. - * - * [Parameters] - * None - * [Return value] - * None - */ - -/*-----------------------------------------------------------------------*/ - -static void init_0xxx(void) -{ - unsigned int i; - - /* STC SR,Rn */ - opcode_info_low[0x002] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STC GBR,Rn */ - opcode_info_low[0x012] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STC VBR,Rn */ - opcode_info_low[0x022] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - - /* BSRF Rn */ - opcode_info_low[0x003] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - /* BRAF Rn */ - opcode_info_low[0x023] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* MOV.* Rm,@(R0,Rn) */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - } - - /* MUL.L Rm,Rn */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - } - - /* CLRT */ - opcode_info_low[0x008] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_SR_T; - /* SETT */ - opcode_info_low[0x018] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_SR_T; - /* CLRMAC */ - opcode_info_low[0x028] = SH2_OPCODE_INFO_VALID; - - /* NOP */ - opcode_info_low[0x009] = SH2_OPCODE_INFO_VALID; - /* DIV0U */ - opcode_info_low[0x019] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_SR_T; - /* MOVT Rn */ - opcode_info_low[0x029] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - - /* STS MACH,Rn */ - opcode_info_low[0x00A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STS MACL,Rn */ - opcode_info_low[0x01A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STS PR,Rn */ - opcode_info_low[0x02A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - - /* RTS */ - opcode_info_low[0x00B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - /* SLEEP */ - opcode_info_low[0x01B] = SH2_OPCODE_INFO_VALID; - /* RTE */ - opcode_info_low[0x02B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R15 - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_R15 - | SH2_OPCODE_INFO_ACCESS_SIZE_LL - | SH2_OPCODE_INFO_ACCESS_POSTINC - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* MOV.* @(R0,Rm),Rn */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - } - - /* MAC.L @Rm+,@Rn+ */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_1xxx(void) -{ - /* MOV.L Rm,@(disp,Rn) */ - unsigned int i; - for (i = 0x100; i <= 0x1FF; i++) { - opcode_info_low[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_4; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_2xxx(void) -{ - unsigned int i; - for (i = 0x200; i <= 0x2F0; i += 0x10) { - - /* MOV.* Rm,@Rn */ - opcode_info_low[i|0x0] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0x1] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0x2] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - - /* MOV.* Rm,@-Rn */ - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_PREDEC; - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_PREDEC; - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - - /* DIV0S Rm,Rn */ - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* TST Rm,Rn */ - opcode_info_low[i|0x8] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* AND Rm,Rn */ - opcode_info_low[i|0x9] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* XOR Rm,Rn */ - opcode_info_low[i|0xA] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* OR Rm,Rn */ - opcode_info_low[i|0xB] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* CMP/ST Rm,Rn */ - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* XTRCT Rm,Rn */ - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* MULU.W Rm,Rn */ - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - - /* MULS.W Rm,Rn */ - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_3xxx(void) -{ - unsigned int i; - for (i = 0x300; i <= 0x3F0; i += 0x10) { - - /* CMP/EQ Rm,Rn */ - opcode_info_low[i|0x0] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* CMP/HS Rm,Rn */ - opcode_info_low[i|0x2] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* CMP/GE Rm,Rn */ - opcode_info_low[i|0x3] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* DIV1 Rm,Rn */ - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* DMULU.L Rm,Rn */ - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - - /* CMP/HI Rm,Rn */ - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* CMP/GT Rm,Rn */ - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* SUB Rm,Rn */ - opcode_info_low[i|0x8] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* SUBC Rm,Rn */ - opcode_info_low[i|0xA] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* SUBV Rm,Rn */ - opcode_info_low[i|0xB] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* ADD Rm,Rn */ - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* DMULS.L Rm,Rn */ - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - - /* ADDC Rm,Rn */ - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* ADDV Rm,Rn */ - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_4xxx(void) -{ - /* SHLL Rn */ - opcode_info_low[0x400] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* DT Rn */ - opcode_info_low[0x410] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* SHAL Rn */ - opcode_info_low[0x420] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* SHLR Rn */ - opcode_info_low[0x401] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* CMP/PZ Rn */ - opcode_info_low[0x411] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* SHAR Rn */ - opcode_info_low[0x421] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* STS.L MACH,@-Rn */ - opcode_info_low[0x402] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STS.L MACL,@-Rn */ - opcode_info_low[0x412] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STS.L PR,@-Rn */ - opcode_info_low[0x422] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - - /* STC.L SR,@-Rn */ - opcode_info_low[0x403] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STC.L GBR,@-Rn */ - opcode_info_low[0x413] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STC.L VBR,@-Rn */ - opcode_info_low[0x423] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - - /* ROTL Rn */ - opcode_info_low[0x404] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* ROTCL Rn */ - opcode_info_low[0x424] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* ROTR Rn */ - opcode_info_low[0x405] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* CMP/PL Rn */ - opcode_info_low[0x415] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* ROTCR Rn */ - opcode_info_low[0x425] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* LDS.L @Rn+,MACH */ - opcode_info_low[0x406] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDS.L @Rn+,MACL */ - opcode_info_low[0x416] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDS.L @Rn+,PR */ - opcode_info_low[0x426] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - - /* LDC.L @Rn+,SR */ - opcode_info_low[0x407] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDC.L @Rn+,GBR */ - opcode_info_low[0x417] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDC.L @Rn+,VBR */ - opcode_info_low[0x427] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - - /* SHLL2 Rn */ - opcode_info_low[0x408] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLL8 Rn */ - opcode_info_low[0x418] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLL16 Rn */ - opcode_info_low[0x428] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* SHLR2 Rn */ - opcode_info_low[0x409] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLR8 Rn */ - opcode_info_low[0x419] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLR16 Rn */ - opcode_info_low[0x429] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* LDS Rn,MACH */ - opcode_info_low[0x40A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - /* LDS Rn,MACL */ - opcode_info_low[0x41A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - /* LDS Rn,PR */ - opcode_info_low[0x42A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - - /* JSR @Rn */ - opcode_info_low[0x40B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - /* TAS.B @Rn */ - opcode_info_low[0x41B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - /* JMP @Rn */ - opcode_info_low[0x42B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* LDC Rn,SR */ - opcode_info_low[0x40E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* LDC Rn,GBR */ - opcode_info_low[0x41E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - /* LDC Rn,VBR */ - opcode_info_low[0x42E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - - /* MAC.W @Rm+,@Rn+ */ - unsigned int i; - for (i = 0x400; i <= 0x4F0; i += 0x10) { - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_POSTINC; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_5xxx(void) -{ - /* MOV.L @(disp,Rm),Rn */ - unsigned int i; - for (i = 0x500; i <= 0x5FF; i++) { - opcode_info_low[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_4; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_6xxx(void) -{ - unsigned int i; - for (i = 0x600; i <= 0x6F0; i += 0x10) { - - /* MOV.* @Rm,Rn */ - opcode_info_low[i|0x0] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0x1] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0x2] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - - /* MOV Rm,Rn */ - opcode_info_low[i|0x3] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* MOV.* @Rm+,Rn */ - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_POSTINC; - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_POSTINC; - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - - /* NOT Rm,Rn */ - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* SWAP.* Rm,Rn */ - opcode_info_low[i|0x8] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - opcode_info_low[i|0x9] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* NEGC Rm,Rn */ - opcode_info_low[i|0xA] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* NEG Rm,Rn */ - opcode_info_low[i|0xB] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* EXTU.* Rm,Rn */ - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* EXTS.* Rm,Rn */ - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_7xxx(void) -{ - /* ADD #imm,Rn */ - unsigned int i; - for (i = 0x700; i <= 0x7FF; i++) { - opcode_info_low[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_8xxx(void) -{ - /* MOV.B R0,@(disp,Rm) */ - opcode_info_high[0x00] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* MOV.W R0,@(disp,Rm) */ - opcode_info_high[0x01] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* MOV.B @(disp,Rm),R0 */ - opcode_info_high[0x04] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* MOV.W @(disp,Rm),R0 */ - opcode_info_high[0x05] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* CMP/EQ #imm,R0 */ - opcode_info_high[0x08] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_SR_T; - - /* BT label */ - opcode_info_high[0x09] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND; - - /* BF label */ - opcode_info_high[0x0B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND; - - /* BT/S label */ - opcode_info_high[0x0D] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* BF/S label */ - opcode_info_high[0x0F] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND - | SH2_OPCODE_INFO_BRANCH_DELAYED; -} - -/*-----------------------------------------------------------------------*/ - -static void init_9xxx(void) -{ - /* MOV.W @(disp,PC),Rn */ - unsigned int i; - for (i = 0x10; i <= 0x1F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_PC - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_8; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Axxx(void) -{ - /* BRA label */ - unsigned int i; - for (i = 0x20; i <= 0x2F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Bxxx(void) -{ - /* BRA label */ - unsigned int i; - for (i = 0x30; i <= 0x3F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Cxxx(void) -{ - /* MOV.B R0,@(disp,GBR) */ - opcode_info_high[0x40] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.W R0,@(disp,GBR) */ - opcode_info_high[0x41] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.L R0,@(disp,GBR) */ - opcode_info_high[0x42] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* TRAPA #imm */ - opcode_info_high[0x43] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R15 - | SH2_OPCODE_INFO_ACCESSES_R15 - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_LL - | SH2_OPCODE_INFO_ACCESS_PREDEC - | SH2_OPCODE_INFO_BRANCH_UNCOND; - - /* MOV.B @(disp,GBR),R0 */ - opcode_info_high[0x44] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.W @(disp,GBR),R0 */ - opcode_info_high[0x45] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.L @(disp,GBR),R0 */ - opcode_info_high[0x46] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOVA @(disp,PC),R0 */ - opcode_info_high[0x47] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0; - - /* TST #imm,R0 */ - opcode_info_high[0x48] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_SR_T; - - /* AND #imm,R0 */ - opcode_info_high[0x49] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_R0; - - /* XOR #imm,R0 */ - opcode_info_high[0x4A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_R0; - - /* OR #imm,R0 */ - opcode_info_high[0x4B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_R0; - - /* TST.B #imm,@(R0,GBR) */ - opcode_info_high[0x4C] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - - /* AND.B #imm,@(R0,GBR) */ - opcode_info_high[0x4D] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - - /* XOR.B #imm,@(R0,GBR) */ - opcode_info_high[0x4E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - - /* OR.B #imm,@(R0,GBR) */ - opcode_info_high[0x4F] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; -} - -/*-----------------------------------------------------------------------*/ - -static void init_Dxxx(void) -{ - /* MOV.L @(disp,PC),Rn */ - unsigned int i; - for (i = 0x50; i <= 0x5F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_PC - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_8; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Exxx(void) -{ - /* MOV #imm,Rn */ - unsigned int i; - for (i = 0x60; i <= 0x6F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - } -} - -/*************************************************************************/ -/********************** Opcode table lookup routine **********************/ -/*************************************************************************/ - -/** - * get_opcode_info: Return information about the given opcode. - * - * [Parameters] - * opcode: SH-2 opcode to obtain information about - * [Return value] - * - */ -int32_t get_opcode_info(uint16_t opcode) -{ - if (opcode & 0x8000) { - return opcode_info_high[(opcode & 0x7F00) >> 8]; - } else { - return opcode_info_low[(opcode & 0x7000) >> 4 | (opcode & 0xFF)]; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-optimize.c b/yabause/src/psp/sh2-optimize.c deleted file mode 100644 index 5763fe6ae5..0000000000 --- a/yabause/src/psp/sh2-optimize.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* src/psp/sh2-optimize.c: Optimization routines for SH-2 emulator - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "../core.h" - -#include "rtl.h" -#include "sh2.h" -#include "sh2-internal.h" - -#ifdef JIT_DEBUG_TRACE -# include "../sh2d.h" -#endif - -/*************************************************************************/ -/****************************** Common data ******************************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_IDLE - -/* - * The table below is used by OPTIMIZE_IDLE to find the effects of a given - * SH-2 instruction on machine state. Instruction opcodes are listed - * hierarchically, starting with idle_table_main[], which is indexed by the - * top 4 bits of the opcode (bits 12-15). Each table entry is either a - * pointer to a subtable with a shift count indicating which 4 bits of the - * opcode are used to index the subtable, or an instruction definition - * indicating the effects of the given set of opcodes. - * - * Instruction definitions consist of "used" and "changed" bitmasks, - * indicating which registers are used (read) or changed (written) by the - * instruction, respectively. For example, the instruction ADD Rm,Rn uses - * both registers Rm and Rn and changes register Rn, so it is defined as: - * - * {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn} - * - * IDLE_Rm and IDLE_Rn in this example are pseudo-register flags, and are - * interpreted to mean the registers specified by the "m" and "n" fields of - * the opcode (bits 4-7 and 8-11 respectively). There are also individual - * flags for each of the individually-alterable fields in the SR register - * (T, S, Q, and M); the I field can only be altered by writing SR as a - * whole, and is not used directly by any instruction in any case. - * - * Instructions marked as IDLE_BAD in the "changed" field can never be part - * of an idle loop, either because the opcode group itself is invalid, or - * because the instruction modifies machine state in a fashion which is - * either nonrepeatable (such as postincrement or predecrement memory - * accesses) or not trivially repeatable (such as subroutine calls). - * - * The table also includes an "extra_cycles" field, used to indicate - * instructions which require more than one clock cycle to complete. This - * information is not currently used, but is stored in case it becomes - * useful in the future for computing the duration of a loop. - */ - -/*-----------------------------------------------------------------------*/ - -/* Bit values for register bitmasks */ -#define IDLE_R(n) (1U << (n)) -#define IDLE_SR_T (1U << 16) -#define IDLE_SR_S (1U << 17) -#define IDLE_SR_Q (1U << 18) -#define IDLE_SR_M (1U << 19) -#define IDLE_SR_MQT (IDLE_SR_T | IDLE_SR_Q | IDLE_SR_M) -#define IDLE_SR (IDLE_SR_T | IDLE_SR_S | IDLE_SR_Q | IDLE_SR_M) -#define IDLE_GBR (1U << 20) -#define IDLE_VBR (1U << 21) -#define IDLE_PR (1U << 22) -#define IDLE_MACL (1U << 23) -#define IDLE_MACH (1U << 24) -#define IDLE_MAC (IDLE_MACL | IDLE_MACH) - -/* Value used in IdleInfo.changed field to indicate an instruction which - * can never be part of an idle loop */ -#define IDLE_BAD (1U << 31) - -/* Virtual bits used for the Rn (bits 8-11) and Rm (bits 4-7) fields of - * the instruction; e.g. IDLE_Rn translates to IDLE_R(opcode>>8 & 0xF) */ -#define IDLE_Rn (1U << 30) -#define IDLE_Rm (1U << 29) - -/* Table data structure; fields "used" and "changed" are ignored if - * "subtable" is non-NULL */ -typedef struct IdleInfo_ IdleInfo; -struct IdleInfo_ { - uint32_t used; // Bitmask of registers used by the instruction - uint32_t changed; // Bitmask of registers changed by the instruction - uint8_t extra_cycles; // Clock cycles used by instruction minus 1 - uint8_t next_shift; // Bit position of subtable index (0, 4, or 8) - const IdleInfo *subtable; // NULL if no subtable for this opcode -}; - -/*-----------------------------------------------------------------------*/ - -/* Opcode table for $0xx2 opcodes */ -static const IdleInfo idle_table_0xx2[16] = { - {.used = IDLE_SR, .changed = IDLE_Rn}, // STC SR,Rn - {.used = IDLE_GBR, .changed = IDLE_Rn}, // STC GBR,Rn - {.used = IDLE_VBR, .changed = IDLE_Rn}, // STC VBR,Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xx3 opcodes */ -static const IdleInfo idle_table_0xx3[16] = { - {.changed = IDLE_BAD}, // BSRF Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rn, .changed = 0, .extra_cycles = 1}, // BRAF Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xx8 opcodes */ -static const IdleInfo idle_table_0xx8[16] = { - {.used = 0, .changed = IDLE_SR_T}, // CLRT - {.used = 0, .changed = IDLE_SR_T}, // SETT - {.used = 0, .changed = IDLE_MAC}, // CLRMAC - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xx9 opcodes */ -static const IdleInfo idle_table_0xx9[16] = { - {.used = 0, .changed = 0}, // NOP - {.used = 0, .changed = IDLE_SR_MQT}, // DIV0U - {.used = IDLE_SR_T, .changed = IDLE_Rn}, // MOVT Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -static const IdleInfo idle_table_0xxA[16] = { - {.used = IDLE_MACH, .changed = IDLE_Rn}, // STS MACH,Rn - {.used = IDLE_MACL, .changed = IDLE_Rn}, // STS MACL,Rn - {.used = IDLE_PR, .changed = IDLE_Rn}, // STS PR,Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xxx opcodes */ -static const IdleInfo idle_table_0xxx[16] = { - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.next_shift = 4, .subtable = idle_table_0xx2}, - {.next_shift = 4, .subtable = idle_table_0xx3}, - - {.changed = IDLE_BAD}, // MOV.B Rm,@(R0,Rn) - {.changed = IDLE_BAD}, // MOV.W Rm,@(R0,Rn) - {.changed = IDLE_BAD}, // MOV.L Rm,@(R0,Rn) - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MACL, .extra_cycles = 1}, // MUL.L Rm,Rn - - {.next_shift = 4, .subtable = idle_table_0xx8}, - {.next_shift = 4, .subtable = idle_table_0xx9}, - {.next_shift = 4, .subtable = idle_table_0xxA}, - {.changed = IDLE_BAD}, // RTS, SLEEP, RTE - - {.used = IDLE_R(0)|IDLE_Rm, .changed = IDLE_Rn}, // MOV.B @(R0,Rm),Rn - {.used = IDLE_R(0)|IDLE_Rm, .changed = IDLE_Rn}, // MOV.W @(R0,Rm),Rn - {.used = IDLE_R(0)|IDLE_Rm, .changed = IDLE_Rn}, // MOV.L @(R0,Rm),Rn - {.changed = IDLE_BAD}, // MAC.L @Rm+,@Rn+ -}; - -/*----------------------------------*/ - -/* Opcode table for $2xxx opcodes */ -static const IdleInfo idle_table_2xxx[16] = { - {.changed = IDLE_BAD}, // MOV.B Rm,@Rn - {.changed = IDLE_BAD}, // MOV.W Rm,@Rn - {.changed = IDLE_BAD}, // MOV.L Rm,@Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // MOV.B Rm,@-Rn - {.changed = IDLE_BAD}, // MOV.W Rm,@-Rn - {.changed = IDLE_BAD}, // MOV.L Rm,@-Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_MQT}, // DIV0S Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // TST Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // AND Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // XOR Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // OR Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/ST Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // XTRCT Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MACL}, // MULU.W Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MACL}, // MULS.W Rm,Rn -}; - -/*----------------------------------*/ - -/* Opcode table for $3xxx opcodes */ -static const IdleInfo idle_table_3xxx[16] = { - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/EQ Rm,Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/HS Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/GE Rm,Rn - - {.changed = IDLE_BAD}, // DIV1 Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MAC, .extra_cycles = 1}, // DMULU.L Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/HI Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/GT Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // SUB Rm,Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // SUBC Rm,Rn - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // SUBV Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // ADD Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MAC, .extra_cycles = 1}, // DMULS.L Rm,Rn - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ADDC Rm,Rn - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ADDV Rm,Rn -}; - -/*----------------------------------*/ - -/* Opcode table for $4xx0 opcodes */ -static const IdleInfo idle_table_4xx0[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHLL Rn - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // DT Rn - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHAL Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx1 opcodes */ -static const IdleInfo idle_table_4xx1[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHLR Rn - {.used = IDLE_Rn, .changed = IDLE_SR_T}, // CMP/PZ Rn - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHAR Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx4 opcodes */ -static const IdleInfo idle_table_4xx4[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // ROTL Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ROTCL Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx5 opcodes */ -static const IdleInfo idle_table_4xx5[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // ROTR Rn - {.used = IDLE_Rn, .changed = IDLE_SR_T}, // CMP/PL Rn - {.used = IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ROTCR Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx8 opcodes */ -static const IdleInfo idle_table_4xx8[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLL2 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLL8 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLL16 Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx9 opcodes */ -static const IdleInfo idle_table_4xx9[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLR2 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLR8 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLR16 Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxA opcodes */ -static const IdleInfo idle_table_4xxA[16] = { - {.used = IDLE_Rn, .changed = IDLE_MACH}, // LDS Rn,MACH - {.used = IDLE_Rn, .changed = IDLE_MACL}, // LDS Rn,MACL - {.used = IDLE_Rn, .changed = IDLE_PR}, // LDS Rn,PR - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxB opcodes */ -static const IdleInfo idle_table_4xxB[16] = { - {.changed = IDLE_BAD}, // JSR @Rn - {.changed = IDLE_BAD}, // TAS @Rn - {.used = 0, .changed = 0, .extra_cycles = 1}, // JMP @Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxE opcodes */ -static const IdleInfo idle_table_4xxE[16] = { - {.used = IDLE_Rn, .changed = IDLE_SR}, // LDC Rn,SR - {.used = IDLE_Rn, .changed = IDLE_GBR}, // LDC Rn,GBR - {.used = IDLE_Rn, .changed = IDLE_VBR}, // LDC Rn,VBR - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxx opcodes */ -static const IdleInfo idle_table_4xxx[16] = { - {.next_shift = 4, .subtable = idle_table_4xx0}, - {.next_shift = 4, .subtable = idle_table_4xx1}, - {.changed = IDLE_BAD}, // STSL ...,@-Rn - {.changed = IDLE_BAD}, // STCL ...,@-Rn - - {.next_shift = 4, .subtable = idle_table_4xx4}, - {.next_shift = 4, .subtable = idle_table_4xx5}, - {.changed = IDLE_BAD}, // LDSL @Rm+,... - {.changed = IDLE_BAD}, // LDCL @Rm+,... - - {.next_shift = 4, .subtable = idle_table_4xx8}, - {.next_shift = 4, .subtable = idle_table_4xx9}, - {.next_shift = 4, .subtable = idle_table_4xxA}, - {.next_shift = 4, .subtable = idle_table_4xxB}, - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.next_shift = 4, .subtable = idle_table_4xxE}, - {.changed = IDLE_BAD}, // MAC.W @Rm+,@Rn+ -}; - -/*----------------------------------*/ - -/* Opcode table for $6xxx opcodes */ -static const IdleInfo idle_table_6xxx[16] = { - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.B @Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.W @Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.L @Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV Rm,Rn - - {.used = IDLE_Rm, .changed = IDLE_Rm|IDLE_Rn}, // MOV.B @Rm+,Rn - {.used = IDLE_Rm, .changed = IDLE_Rm|IDLE_Rn}, // MOV.W @Rm+,Rn - {.used = IDLE_Rm, .changed = IDLE_Rm|IDLE_Rn}, // MOV.L @Rm+,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // NOT Rm,Rn - - {.used = IDLE_Rm, .changed = IDLE_Rn}, // SWAP.B Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // SWAP.W Rm,Rn - {.used = IDLE_Rm|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // NEGC Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // NEG Rm,Rn - - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTU.B Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTU.W Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTS.B Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTS.W Rm,Rn -}; - -/*----------------------------------*/ - -/* Opcode table for $8xxx opcodes */ -static const IdleInfo idle_table_8xxx[16] = { - {.changed = IDLE_BAD}, // MOV.B R0,@(disp,Rm) - {.changed = IDLE_BAD}, // MOV.W R0,@(disp,Rm) - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.used = IDLE_Rm, .changed = IDLE_R(0)}, // MOV.B @(disp,Rm),R0 - {.used = IDLE_Rm, .changed = IDLE_R(0)}, // MOV.W @(disp,Rm),R0 - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.used = IDLE_R(0), .changed = IDLE_SR_T}, // CMP/EQ #imm,R0 - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 2}, // BT label - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 2}, // BF label - - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 1}, // BT/S label - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 1}, // BF/S label -}; - -/*----------------------------------*/ - -/* Opcode table for $Cxxx opcodes */ -static const IdleInfo idle_table_Cxxx[16] = { - {.changed = IDLE_BAD}, // MOV.B R0,@(disp,GBR) - {.changed = IDLE_BAD}, // MOV.W R0,@(disp,GBR) - {.changed = IDLE_BAD}, // MOV.L R0,@(disp,GBR) - {.changed = IDLE_BAD}, // TRAPA #imm - - {.used = IDLE_GBR, .changed = IDLE_R(0)}, // MOV.B @(disp,GBR),R0 - {.used = IDLE_GBR, .changed = IDLE_R(0)}, // MOV.W @(disp,GBR),R0 - {.used = IDLE_GBR, .changed = IDLE_R(0)}, // MOV.L @(disp,GBR),R0 - {.used = 0, .changed = IDLE_R(0)}, // MOVA @(disp,PC),R0 - - {.used = IDLE_R(0), .changed = IDLE_SR_T}, // TST #imm,R0 - {.used = IDLE_R(0), .changed = IDLE_R(0)}, // AND #imm,R0 - {.used = IDLE_R(0), .changed = IDLE_R(0)}, // XOR #imm,R0 - {.used = IDLE_R(0), .changed = IDLE_R(0)}, // OR #imm,R0 - - {.used = IDLE_R(0)|IDLE_GBR, .changed = IDLE_SR_T}, // TST #imm,@(R0,GBR) - {.changed = IDLE_BAD}, // AND #imm,@(R0,GBR) - {.changed = IDLE_BAD}, // XOR #imm,@(R0,GBR) - {.changed = IDLE_BAD}, // OR #imm,@(R0,GBR) -}; - -/*----------------------------------*/ - -/* Main opcode table (for bits 12-15) */ -static const IdleInfo idle_table_main[16] = { - {.next_shift = 0, .subtable = idle_table_0xxx}, - {.changed = IDLE_BAD}, // MOV.L Rm,@(disp,Rn) - {.next_shift = 0, .subtable = idle_table_2xxx}, - {.next_shift = 0, .subtable = idle_table_3xxx}, - - {.next_shift = 0, .subtable = idle_table_4xxx}, - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.L @(disp,Rn),Rm - {.next_shift = 0, .subtable = idle_table_6xxx}, - {.changed = IDLE_BAD}, // ADD #imm,Rn - - {.next_shift = 8, .subtable = idle_table_8xxx}, - {.used = 0, .changed = IDLE_Rn}, // MOV.W @(disp,PC),Rn - {.used = 0, .changed = 0, .extra_cycles = 1}, // BRA label - {.changed = IDLE_BAD}, // BSR label - - {.next_shift = 8, .subtable = idle_table_Cxxx}, - {.used = 0, .changed = IDLE_Rn}, // MOV.L @(disp,PC),Rn - {.used = 0, .changed = IDLE_Rn}, // MOV #imm,Rn - {.changed = IDLE_BAD}, // invalid -}; - -/*-----------------------------------------------------------------------*/ - -#endif // OPTIMIZE_IDLE - -/*************************************************************************/ -/************************ Idle loop optimization *************************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_IDLE - -/* - * A loop is "idle" if a single execution of the entire loop, starting from - * the first instruction of the loop and ending immediately before the next - * time the first instruction is executed, has no net effect on the state - * of the system after the first iteration of the loop. Each individual - * instruction may alter system state (and in fact, the program counter - * will change with each instruction executed), but provided that the - * external system state remains constant, the final result of executing N - * loops must be identical to the result of executing N-1 loops for N - * greater than 1. - * - * For example, a loop consisting solely of a branch to the same - * instruction: - * 0x1000: bra 0x1000 - * 0x1002: nop - * would naturally qualify, as would a loop reading from the same memory - * location (here, waiting for a memory address to read as zero): - * 0x1000: mov.l @r0, r1 - * 0x1002: tst r1, r1 - * 0x1004: bf 0x1000 - * - * On the flip side, a loop with a counter: - * 0x1000: dt r0 - * 0x1002: bf 0x1000 - * would _not_ qualify, because the state of the system changes with each - * iteration of the loop (though this particular loop can be optimized - * separately through OPTIMIZE_DELAY). Likewise, a loop containing a store - * to memory: - * 0x1000: mov.l r2, @r3 - * 0x1002: mov.l @r0, r1 - * 0x1004: tst r1, r1 - * 0x1006: bt 0x1000 - * would not qualify, because a store operation is assumed to change system - * state even if the value stored is the same. (Even for ordinary memory, - * in a multiprocessor system like the Saturn memory can be accessed by - * agents other than the processor, and an identical store operation may - * have differing effects from one iteration to the next.) - * - * To determine whether a loop is idle, we check whether all operations - * performed in the loop depend on constant values; in other words, no - * instruction in the loop may modify a register which is used as a source - * for that or an earlier instruction. (The contents of memory are assumed - * to be constant for this purpose, and any side effects of load - * instructions are ignored.) One result of this is that any loop with an - * ALU-type operation other than CMP cannot be considered idle, except as - * discussed below, even in cases where the loop does not in fact have a - * net change in state: - * 0x1000: mov.l @r0+, r1 - * 0x1002: cmp/pl @r1 - * 0x1004: bt 0x100A - * 0x1006: bra 0x1000 - * 0x1008: add #-4, r0 - * 0x100A: ... - * While admittedly somewhat contrived, this example has no net effect on - * system state because R0 is decremented at the end of each loop; but - * because R0 is used both in a postincrement memory access and as the - * target of an ADD, its value cannot be considered a constant, so the - * loop is not treated as idle. (A more sophisticated algorithm could - * track such changes in value and determine their cumulative effect, but - * in most cases the simplistic algorithm we use is sufficient.) - * - * As an exception to the above, if a register is modified before it is - * used by another instruction, the register becomes a "don't care" for - * the remainder of the loop. Thus a loop like: - * 0x1000: mov.b @r0, r1 - * 0x1002: add r2, r1 - * 0x1004: tst r1, r1 - * 0x1006: bt 0x1000 - * qualifies as an idle loop despite the "add" instruction writing to - * the same register it reads from. - */ - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_idle: Return whether the given sequence of instructions - * forms an "idle loop", in which the processor remains in a constant state - * (or repeating sequence of states) indefinitely until a certain external - * event occurs, such as an interrupt or a change in the value of a memory- - * mapped register. If an idle loop is detected, also return information - * allowing the loop to be translated into a faster sequence of native - * instructions. - * - * The sequence of instructions is assumed to end with a branch instruction - * to the beginning of the sequence (possibly including a delay slot). - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * count: Number of instructions to check - * [Return value] - * Nonzero if the given sequence of SH-2 instructions form an idle - * loop, else zero - */ -int can_optimize_idle(const uint16_t *insn_ptr, uint32_t PC, - unsigned int count) -{ - uint32_t used_regs; // Which registers have been used so far? - uint32_t dont_care; // Which registers are "don't cares"? - int can_optimize = 1; - unsigned int i; - - /* We detect failure by matching the changed-registers bitmask against - * used_regs; set the initial value so that non-idleable instructions - * are automatically rejected */ - used_regs = IDLE_BAD; - /* Initially, no registers are don't cares */ - dont_care = 0; - - for (i = 0; can_optimize && i < count; i++) { - const uint16_t opcode = *insn_ptr++; - - /* Find the entry for this opcode */ - int shift = 12; - const IdleInfo *table = idle_table_main; - while (table[opcode>>shift & 0xF].subtable) { - int newshift = table[opcode>>shift & 0xF].next_shift; - table = table[opcode>>shift & 0xF].subtable; - shift = newshift; - } - - /* Replace virtual Rn/Rm bits with real registers from opcode */ - uint32_t used = table[opcode>>shift & 0xF].used; - uint32_t changed = table[opcode>>shift & 0xF].changed; - if (used & IDLE_Rn) { - used &= ~IDLE_Rn; - used |= IDLE_R(opcode>>8 & 0xF); - } - if (used & IDLE_Rm) { - used &= ~IDLE_Rm; - used |= IDLE_R(opcode>>4 & 0xF); - } - if (changed & IDLE_Rn) { - changed &= ~IDLE_Rn; - changed |= IDLE_R(opcode>>8 & 0xF); - } - if (changed & IDLE_Rm) { - changed &= ~IDLE_Rm; - changed |= IDLE_R(opcode>>4 & 0xF); - } - - /* Add any registers used by this instruction to used_regs */ - used_regs |= used; - - /* Add any not-yet-used registers modified by this instruction to - * dont_care */ - dont_care |= changed & ~used_regs; - - /* See whether we can still treat this as an idle loop */ - if (changed & ~dont_care & used_regs) { - can_optimize = 0; - } - } - - return can_optimize; -} - -/*-----------------------------------------------------------------------*/ - -#endif // OPTIMIZE_IDLE - -/*************************************************************************/ -/************************* Division optimization *************************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_DIVISION - -/* - * On the SH-2, unsigned 64bit/32bit division follows the sequence: - * DIV0U - * .arepeat 32 ;Repeat 32 times - * ROTCL Rlo - * DIV1 Rdiv,Rhi - * .aendr - * and finishes with the following state changes: - * M = 0 - * T = low bit of quotient - * Q = !T - * Rlo = high 31 bits of quotient in bits 0-30, with 0 in bit 31 - * Rhi = !Q ? remainder : (remainder - Rdiv) - * If the number of repetitions of ROTCL Rlo / DIV1 Rdiv,Rhi is less than - * 32, the result is equivalent to shifting the dividend right (32-N) bits - * where N is the repetition count, except that the low (32-N) bits of the - * dividend remain in the most-significant bits of Rlo. - * - * Signed 64bit/32bit division (where the dividend is a 32-bit signed value - * sign-extended to 64 bits) follows a sequence identical to unsigned - * division except for the first instruction: - * DIV0S Rdiv,Rhi - * .arepeat 32 ;Repeat 32 times - * ROTCL Rlo - * DIV1 Rdiv,Rhi - * .aendr - * and finishes with the following state changes: - * M = sign bit of divisor - * (if dividend >= 0) - * T = low bit of (quotient - M) - * Q = !(T ^ M) - * Rlo = high 31 bits of (quotient - M) in bits 0-30, - * sign-extended to 32 bits - * Rhi = !Q ? remainder : (remainder - abs(Rdiv)) - * (if dividend < 0) - * qtemp = quotient + (remainder ? (M ? 1 : -1) : 0) - * T = low bit of (qtemp - M) - * Q = !(T ^ M) - * Rlo = high 31 bits of (qtemp - M) in bits 0-30, - * sign-extended to 32 bits - * Rhi = !Q ? (remainder == 0 ? remainder : remainder + abs(Rdiv)) - * : (remainder != 0 ? remainder : remainder - abs(Rdiv)) - * - * In all cases, division by zero ends with: - * M = 0 - * T = 1 - * Q = 0 - * Rhi:Rlo = Rlo<<32 | x<<31 | (unsigned)(~Rhi)>>1 - * where x is 0 for unsigned division and the high bit of Rlo for signed - * division. - * - * Both of these sequences can thus be optimized significantly using native - * division instructions (at one point, a factor-of-18 reduction in - * execution speed was measured). - */ - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_div0u: Return whether a sequence of instructions starting - * from a DIV0U instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to DIV0U instruction - * PC: PC of DIV0U instruction - * skip_first_rotcl: Nonzero if the first ROTCL instruction is known to - * be omitted (as may happen if the low word of - * the dividend is known to be zero) - * Rhi_ret: Pointer to variable to receive index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv_ret: Pointer to variable to receive index of divisor register - * [Return value] - * Number of bits of division performed by the instructions following - * the DIV0U instruction (1-32), or zero if the following instructions - * do not perform a division operation - */ -int can_optimize_div0u(const uint16_t *insn_ptr, uint32_t PC, - int skip_first_rotcl, - int *Rhi_ret, int *Rlo_ret, int *Rdiv_ret) -{ - uint16_t opcode; // Opcode read from instruction stream - uint16_t rotcl_op = 0, div1_op = 0; // Expected opcodes - int nbits; // Number of bits divided so far - - if (!skip_first_rotcl) { - opcode = *++insn_ptr; - if ((opcode & 0xF0FF) != 0x4024) { // ROTCL Rlo -#ifdef JIT_DEBUG - DMSG("DIV0U optimization failed: PC+2 (0x%08X) is 0x%04X, not" - " ROTCL", PC+2, opcode); -#endif - return 0; - } - *Rlo_ret = opcode>>8 & 0xF; - rotcl_op = opcode; - } - - opcode = *++insn_ptr; - if ((opcode & 0xF00F) != 0x3004) { // DIV1 Rdiv,Rhi -#ifdef JIT_DEBUG - DMSG("DIV0U optimization failed: PC+%d (0x%08X) is 0x%04X, not DIV1", - skip_first_rotcl ? 2 : 4, PC + (skip_first_rotcl ? 2 : 4), - opcode); -#endif - return 0; - } - *Rhi_ret = opcode>>8 & 0xF; - *Rdiv_ret = opcode>>4 & 0xF; - div1_op = opcode; - - if (skip_first_rotcl) { - opcode = insn_ptr[1]; // Don't advance yet--we're just peeking - if ((opcode & 0xF0FF) != 0x4024) { -#ifdef JIT_DEBUG - DMSG("DIV0U optimization failed (with skip_first_rotcl):" - " PC+4 (0x%08X) is 0x%04X, not ROTCL", PC+4, opcode); -#endif - return 0; - } - *Rlo_ret = opcode>>8 & 0xF; - rotcl_op = opcode; - } - - for (nbits = 1; nbits < 32; nbits++) { - opcode = *++insn_ptr; - if (opcode != rotcl_op) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("DIV0U optimization stopped at %d bits: PC+%d (0x%08X) is" - " 0x%04X, not ROTCL R%d", - nbits, (skip_first_rotcl ? 0 : 2) + 4*nbits, - PC + ((skip_first_rotcl ? 0 : 2) + 4*nbits), opcode, - *Rlo_ret); -#endif - break; - } - - opcode = *++insn_ptr; - if (opcode != div1_op) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("DIV0U optimization stopped at %d bits: PC+%d (0x%08X) is" - " 0x%04X, not DIV1 R%d,R%d", - nbits, (skip_first_rotcl ? 2 : 4) + 4*nbits, - PC + ((skip_first_rotcl ? 2 : 4) + 4*nbits), opcode, - *Rdiv_ret, *Rhi_ret); -#endif - break; - } - } // for 32 bits - - return nbits; -} - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_div0s: Return whether a sequence of instructions starting - * from a DIV0S instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to instruction following DIV0S instruction - * PC: PC of instruction following DIV0S instruction - * Rhi: Index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv: Index of divisor register - * [Return value] - * Nonzero if the next 64 SH-2 instructions form a 32-bit division - * operation, else zero - */ -int can_optimize_div0s(const uint16_t *insn_ptr, uint32_t PC, - int Rhi, int *Rlo_ret, int Rdiv) -{ - uint16_t rotcl_op = 0, div1_op = 0x3004 | Rhi<<8 | Rdiv<<4; - int can_optimize = 1; - unsigned int i; - - for (i = 0; can_optimize && i < 64; i++) { - uint16_t nextop = *insn_ptr++; - - if (i%2 == 0) { // ROTCL Rlo - - if (i == 0) { - if ((nextop & 0xF0FF) == 0x4024) { - *Rlo_ret = nextop>>8 & 0xF; - rotcl_op = nextop; - } else { - /* Don't complain for the first instruction, since - * DIV0S seems to be put to uses other than division - * as well */ - can_optimize = 0; - } - } else { - if (UNLIKELY(nextop != rotcl_op)) { - DMSG("DIV0S optimization failed: PC+%d (0x%08X) is 0x%04X," - " not ROTCL R%d", 2 + 2*i, PC + 2*i, nextop, - *Rlo_ret); - can_optimize = 0; - } - } - - } else { // DIV1 Rdiv,Rhi - - if (UNLIKELY(nextop != div1_op)) { - DMSG("DIV0S optimization failed: PC+%d (0x%08X) is 0x%04X," - " not DIV1 R%d,R%d", 2 + 2*i, PC + 2*i, nextop, Rdiv, Rhi); - can_optimize = 0; - } - - } - } // for 64 instructions - - return can_optimize; -} - -#endif // OPTIMIZE_DIVISION - -/*************************************************************************/ -/********************** Variable shift optimization **********************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_VARIABLE_SHIFTS - -/* - * The SH-2's repertoire of shift instructions is fairly limited compared - * to modern processors. While the SH-2 has a few multi-bit shift - * instructions (SHLL2, SHLR8, and the like), it cannot shift a register - * by an arbitrary constant, instead requiring a sequence of fixed-sized - * shifts to accomplish the task. More importantly, the SH-2 also cannot - * shift by a variable count specified in another register, meaning that - * programs must use conditional tests or loops instead. Since modern - * processors do have variable-count shift instructions, such tests or - * loops can be significantly shortened, eliminating branches that can - * hurt optimizability of the code. - * - * Currently, the following variable shift/rotate sequences is recognized: - * - * - TST #1, R0 - * BT .+4 - * SHL[LR] Rshift - * TST #2, R0 - * BT .+4 - * SHL[LR]2 Rshift - * TST #4, R0 - * BT .+6 - * SHL[LR]2 Rshift - * SHL[LR]2 Rshift - * [TST #8, R0 - * BT .+4 - * SHL[LR]8 Rshift - * [TST #16, R0 - * BT .+4 - * SHL[LR]16 Rshift]] - * - * - BRAF Rcount_adjusted [Rcount_adjusted = (maximum shift - Rcount) * 2] - * (delay slot) - * SHLL Rshift [or SHAL, SHLR, SHAR, ROTL, ROTR] - * SHLL Rshift - * ... - */ - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_variable_shift: Return whether a sequence of instructions - * can be optimized to a native variable-count shift operation. - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * Rcount_ret: Pointer to variable to receive index of shift count register - * max_ret: Pointer to variable to receive maximum shift count - * Rshift_ret: Pointer to variable to receive index of target register - * type_ret: Pointer to variable to receive: - * 0 if a SHLL/SHAL sequence - * 1 if a SHLR sequence - * 2 if a SHAR sequence - * 3 if a ROTL sequence - * 4 if a ROTR sequence - * cycles_ret: Pointer to variable to receive pointer to an array of - * cycle counts indexed by shift count (unused for some - * types of sequences) - * [Return value] - * Number of instructions consumed (nonzero) if an optimizable sequence - * is found, else zero - */ -unsigned int can_optimize_variable_shift( - const uint16_t *insn_ptr, uint32_t PC, unsigned int *Rcount_ret, - unsigned int *max_ret, unsigned int *Rshift_ret, unsigned int *type_ret, - const uint8_t **cycles_ret) -{ - if (insn_ptr[0] == 0xC801 // TST #1, R0 - && insn_ptr[1] == 0x8900 // BT .+4 - && (insn_ptr[2] & 0xF0FE) == 0x4000 // SHL[LR] Rshift - && insn_ptr[3] == 0xC802 // TST #2, R0 - && insn_ptr[4] == 0x8900 // BT .+4 - && insn_ptr[5] == (insn_ptr[2] | 0x0008) // SHL[LR]2 Rshift - && insn_ptr[6] == 0xC804 // TST #4, R0 - && insn_ptr[7] == 0x8901 // BT .+6 - && insn_ptr[8] == (insn_ptr[2] | 0x0008) // SHL[LR]2 Rshift - && insn_ptr[9] == (insn_ptr[2] | 0x0008) // SHL[LR]2 Rshift - ) { - *Rcount_ret = 0; - *Rshift_ret = insn_ptr[2]>>8 & 0xF; - *type_ret = (insn_ptr[2] & 1) ? 1 : 0; - if (insn_ptr[10] == 0xC808 // TST #8, R0 - && insn_ptr[11] == 0x8900 // BT .+4 - && insn_ptr[12] == (insn_ptr[2] | 0x0018) // SHL[LR]8 Rshift - ) { - if (insn_ptr[13] == 0xC810 // TST #16, R0 - && insn_ptr[14] == 0x8900 // BT .+4 - && insn_ptr[15] == (insn_ptr[2] | 0x0028) // SHL[LR]16 Rshift - ) { - *max_ret = 31; - static const uint8_t cycles_array[32] = - {20,19,19,18,20,19,19,18,19,18,18,17,19,18,18,17, - 19,18,18,17,19,18,18,17,18,17,17,16,18,17,17,16}; - *cycles_ret = cycles_array; - return 16; - } else { - *max_ret = 15; - static const uint8_t cycles_array[16] = - {16,15,15,14,16,15,15,14,15,14,14,13,15,14,14,13}; - *cycles_ret = cycles_array; - return 13; - } - } else { - *max_ret = 7; - static const uint8_t cycles_array[8] = {12,11,11,10,12,11,11,10}; - *cycles_ret = cycles_array; - return 10; - } - } - - if ((insn_ptr[0] & 0xF0FF) == 0x0023 // BRAF Rcount_adjusted - && ((insn_ptr[2] & 0xF0DE) == 0x4000 // SH[LA][LR] Rshift - || (insn_ptr[2] & 0xF0FE) == 0x4004) // ROT[LR] Rshift - ) { - unsigned int num_insns = 3; - while (num_insns < 2+32 && insn_ptr[num_insns] == insn_ptr[2]) { - num_insns++; - } - *Rcount_ret = insn_ptr[0]>>8 & 0xF; - *Rshift_ret = insn_ptr[2]>>8 & 0xF; - *max_ret = num_insns - 2; - switch (insn_ptr[2] & 0xFF) { - case 0x00: *type_ret = 0; break; - case 0x20: *type_ret = 0; break; - case 0x01: *type_ret = 1; break; - case 0x21: *type_ret = 2; break; - case 0x04: *type_ret = 3; break; - case 0x05: *type_ret = 4; break; - } - return num_insns; - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -#endif // OPTIMIZE_VARIABLE_SHIFTS - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2.c b/yabause/src/psp/sh2.c deleted file mode 100644 index 2eafcf17ca..0000000000 --- a/yabause/src/psp/sh2.c +++ /dev/null @@ -1,7714 +0,0 @@ -/* src/psp/sh2.c: SH-2 emulator with dynamic translation support - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This SH-2 emulator is designed to execute SH-2 instructions by - * recompiling them into equivalent native machine code instructions, then - * executing that native code directly on the host CPU. - * - * The emulation loop (handled by sh2_run()) proceeds as follows: - * - * 1) If there is no current native block, sh2_run() calls jit_translate() - * to translate a block of SH-2 code beginning at the current PC. - * jit_translate() continues translating through the end of the block - * (determined heuristically) and returns the translated block to be - * executed. - * - * 3A) sh2_run() calls jit_exec(), which in turn calls the native code for - * the current, found, or created translated block. - * - * 3B) If translation failed for some reason, sh2_run() calls - * interpret_insn() to interpret and execute one instruction at the - * current PC, then starts over at step 1. If the failure occurred - * during RTL code generation (i.e., after the SH-2 block size was - * determined), the entire block is blacklisted to avoid repeatedly - * trying to translate the block at each subsequent address. - * - * 4) The translated code returns either when it reaches the end of the - * block, or when the number of cycles executed exceeds the requested - * cycle count. (For efficiency, cycle count checks are only performed - * before backward branches.) - * - * 5A) If the new PC at the end of the translated block is cached as the - * predicted branch target of the block, the current native block is - * set to that block. - * - * 5B) Otherwise, if a translated block exists for the new PC, it is cached - * as the predicted branch target and the current native block is set - * to that block. - * - * 5C) Otherwise, the current native block is cleared. - * - * During native code execution, if a write is made to a region of SH-2 - * memory containing translated blocks, all translated blocks containing - * that address are deleted by calling jit_clear_write(), so the modified - * code can be retranslated. - * - * If an external agent (such as DMA) modifies memory, sh2_write_notify() - * should be called to clear any translations in the affected area. In - * this case, the modified range is expanded to a multiple of - * 1< 0 - /* Predicted dynamic branch target(s) */ - BranchTargetInfo predicted[JIT_BRANCH_PREDICTION_SLOTS]; -#endif - -#ifdef JIT_BRANCH_PREDICT_STATIC - /* Predicted static branch target(s) */ - BranchTargetInfo *static_predict; // Dynamically-allocated array - uint32_t num_static_branches; // Number of entries in array -#endif - -#ifdef JIT_PROFILE - uint32_t call_count; // Number of calls made to this block - uint32_t cycle_count; // Number of SH-2 cycles spent in this block - uint64_t exec_time; // Time spent executing this block (when - // interpreting RTL, # of insns executed) -#endif -}; - -/* Hash function */ -#define JIT_HASH(addr) ((uint32_t)(addr) % JIT_TABLE_SIZE) - -/*-----------------------------------------------------------------------*/ - -/* Hash table of translated routines (shared between virtual processors) */ -static JitEntry jit_table[JIT_TABLE_SIZE]; // Record buffer -static JitEntry *jit_hashchain[JIT_TABLE_SIZE]; // Hash collision chains - -/* Head node for circular linked list of free entries */ -static JitEntry jit_freelist; - -/* Head node for circular linked list of active entries sorted by add - * timestamp; used to quickly find the oldest (least recently added) entry - * when we need to purge entries due to a full table or the data size limit */ -static JitEntry jit_lralist; - -/* Total size of translated data */ -static int32_t jit_total_data; // Signed to protect against underflow from bugs - -/* Size limit for translated data */ -static int32_t jit_data_limit = JIT_DATA_LIMIT_DEFAULT; - -/* Global timestamp for LRU expiration mechanism */ -static uint32_t jit_timestamp; - -/* Address from which data is being read */ -static uint32_t jit_PC; - -/* Flags indicating the status of each word in the current block - * (0: unknown, else a combination of WORD_INFO_* flags) */ -static uint8_t word_info[JIT_INSNS_PER_BLOCK]; -#define WORD_INFO_CODE (1<<0) // 1: this is a code word -#define WORD_INFO_FALLTHRU (1<<1) // 1: branch at this address jumps to the - // next translated instruction -#define WORD_INFO_BRA_RTS (1<<2) // 1: branch at this address jumps to a - // RTS/NOP pair -#define WORD_INFO_THREADED (1<<3) // 1: branch at this address jumps to - // another branch -#define WORD_INFO_SELECT (1<<4) // 1: branch at this address acts like - // a SELECT -#define WORD_INFO_LOOP_JSR (1<<5) // 1: branch at this address targets a - // JSR/BSR/BSRF + delay slot - // immediately preceding the block -#define WORD_INFO_FOLDABLE (1<<6) // 1: BSR/JSR at this address jumps to - // a foldable subroutine - -/* Branch target flag array (indicates which words in the current block - * are targeted by branches within the same block) */ -static uint32_t is_branch_target[(JIT_INSNS_PER_BLOCK+31)/32]; - -/* Subroutine call target array (used for subroutine folding) */ -static uint32_t subroutine_target[JIT_INSNS_PER_BLOCK]; - -/* Native implementation function pointers for folded subroutines */ -static SH2NativeFunctionPointer subroutine_native[JIT_INSNS_PER_BLOCK]; - -/* Threaded branch target array (indicates targets for branches marked with - * WORD_INFO_THREADED) */ -static uint32_t branch_thread_target[JIT_INSNS_PER_BLOCK]; - -/* Branch count for each threaded branch (for updating the cycle count) */ -static uint8_t branch_thread_count[JIT_INSNS_PER_BLOCK]; - -/* Branch target lookup table (indicates where in the native code each - * address is located) */ -static struct { - uint32_t sh2_address; // Address of SH-2 instruction - uint32_t rtl_label; // RTL label number corresponding to instruction -} btcache[JIT_BTCACHE_SIZE]; -static unsigned int btcache_index; // Where to store the next branch target - -/* Unresolved branch list (saves locations and targets of forward branches) */ -static struct { - uint32_t sh2_target; // Branch target (SH-2 address, 0 = unused entry) - uint32_t target_label; // RTL label number to be defined at branch target -} unres_branches[JIT_UNRES_BRANCH_SIZE]; - -/* JIT translation blacklist; note that ranges are always 16-bit aligned */ -static struct { - uint32_t start, end; // Zero in both fields indicates an empty entry - uint32_t timestamp; // jit_timestamp when region was last written to - uint32_t pad; // Pad entry size to 16 bytes -} blacklist[JIT_BLACKLIST_SIZE]; - -/* Table of addresses that may require blacklisting if they cause repeated - * faults (see jit_clear_write()); we use the purge table constants for - * this table because they are used for similar purposes */ -static struct { - uint32_t address; // Access address address (0 = unused) - uint32_t timestamp; // jit_timestamp when entry was added/updated - uint32_t count; // Number of jit_clear_write() faults on this block -} pending_blacklist[JIT_PURGE_TABLE_SIZE]; - -/* JIT purge table */ -static struct { - uint32_t address; // Block starting address (0 = unused) - uint32_t timestamp; // jit_timestamp when entry was added/updated - uint32_t count; // Number of purges on this block -} purge_table[JIT_PURGE_TABLE_SIZE]; - -/*----------------------------------*/ - -/* Should we ignore optimization hints? (Used when checking for - * optimizable subroutines to be folded.) */ -static uint8_t ignore_optimization_hints; - -/*----------------------------------*/ - -/* True if we can optimize out the MAC saturation check in this block - * (i.e. S was clear on entry and has not been modified) */ -static uint8_t can_optimize_mac_nosat; - -/* True if the current block contains any MAC instructions */ -static uint8_t block_contains_mac; - -/*----------------------------------*/ - -/* Bitmask of registers hinted as having constant values on block entry */ -static uint16_t is_constant_entry_reg; - -/*----------------------------------*/ - -#ifdef OPTIMIZE_KNOWN_VALUES - -/* Known state of registers (used for optimization when recompiling) */ -static uint32_t reg_knownbits[17];// 1 in a bit means that bit's value is known -static uint32_t reg_value[17]; // Value of known bits in each register -#define REG_R(n) (n) -#define REG_GBR 16 -/* PC is always constant when translating, and the remaining registers are - * generally unknown, so we don't waste time tracking them. */ - -#endif // OPTIMIZE_KNOWN_VALUES - -/*----------------------------------*/ - -/* Status of each register when viewed as a load/store address */ - -static struct { - - /* - * Status of the register: - * known == 0: Value is not a translation-time constant. - * known != 0: Value is within a known memory region. - * known > 0: Value has not significantly changed since the start - * of the block. - * known < 0: Value has been copied from another register - * pointing to a known memory region, or has been - * loaded from local data. - */ - int8_t known; - - /* - * Nonzero if this register is known to point to only data, and - * therefore the JIT overwrite checks can be skipped. - */ - uint8_t data_only; - - /* - * Type of memory pointed to by the register: - * 1: Arranged by 8-bit bytes. - * 2: Arranged by native 16-bit words. - */ - uint8_t type; - - /* - * For known == 0 && rtl_basereg != 0 && !data_only, nonzero if the - * direct_jit_pages[] entry for this pointer has already been checked, - * else zero. - */ - uint8_t checked_djp; - - /* - * Nonzero if the "check_offset" field is valid. - */ - uint8_t checked; - - /* - * Last offset at which a JIT check was performed. - */ - int16_t check_offset; - - /* - * RTL register containing the base pointer for direct memory access, - * to which the register's value is added to form a native address for - * loads and stores. - * - * For known == 0: - * - rtl_basereg==0 means the register has not yet been used as a - * pointer, or its value has changed since the last such use. - * - rtl_basereg!=0 means the register has already been used as a - * pointer. If the RTL register's value is nonzero, it is a - * native pointer through which accesses can be performed - * directly; if the value is zero, the access must go through - * the fallback functions. - * - * For known != 0: - * - rtl_basereg==0 means the access must go through the fallback - * functions. - * - rtl_basereg!=0 means the access can be performed directly; the - * RTL register holds the base address to be added to the register - * value. - */ - uint16_t rtl_basereg; - - /* - * RTL register containing a native pointer for direct memory access - * (equal to rtl_basereg plus the register's value), or zero if no - * such register has yet been created. Only used if known != 0. - */ - uint16_t rtl_ptrreg; - - /* - * Base pointer for JIT page bitmap. Only used for statically-known, - * 16-bit, non-data pointers (known > 0 && type == 2 && !data_only). - */ - uint8_t *djp_base; - - /* - * Source address if this register was loaded from local data. - */ - uint32_t source; - -} pointer_status[16]; - -/* Register holding the native address corresponding to the stack pointer - * (R15) when SH2_OPTIMIZE_STACK is defined */ -static uint16_t stack_pointer; - -/* Bitmask of general-purpose registers containing values which could be - * pointers (used at scanning time to determine which registers need to be - * checked against the constant memory region used in optimization) */ -static uint16_t pointer_regs; -/* Bitmask of registers which are actually used to access memory */ -static uint16_t pointer_used; - -/* Bitmask of general-purpose registers containing local data addresses */ -static uint16_t pointer_local; - -/* Bitmask of general-purpose registers hinted to contain data pointers */ -static uint16_t is_data_pointer_reg; - -/* Array of flags indicating instructions which load data pointers - * (optimization hint) */ -static uint32_t is_data_pointer_load[(JIT_INSNS_PER_BLOCK+31)/32]; - -/*----------------------------------*/ - -#ifdef OPTIMIZE_STATE_BLOCK - -/* Array indicating which SH-2 state block fields are cached in RTL - * registers; if the rtlreg field is nonzero, the field should be accessed - * through that RTL register rather than being loaded from the state block. - * Indexed by the word offset into SH2State, i.e. offsetof(SH2State,REG) / 4 - * The index for a given structure offset can be found by calling - * state_cache_index(offsetof(...)), which returns -1 if the given field - * cannot be cached. */ -static struct { - uint32_t rtlreg; // RTL register containing the SH-2 reg's current value - int16_t offset; // Accumulated offset from constant additions (always - // zero if !OPTIMIZE_CONSTANT_ADDS) - uint8_t fixed; // Nonzero if we should always use this RTL register - // for this state field (rather than allocating a - // new register for each operation) - uint8_t flush; // Nonzero if we should always flush this cache - // register to memory during cache writeback - // (rather than only when it's marked dirty) -} state_cache[25], - saved_state_cache[25]; // Saved cache state (used by SAVE_STATE_CACHE()) - -/* Flags indicating whether a state block field is dirty (needs to be - * flushed); each bit corresponds to a state_cache[] index */ -static uint32_t state_dirty, saved_state_dirty; - -/* Register containing current value of SR.T, or 0 if none */ -static uint32_t cached_SR_T, saved_cached_SR_T; - -/* Nonzero if SR.T is dirty */ -static uint8_t dirty_SR_T, saved_dirty_SR_T; - -/* Cached known value of state->PC (overrides state_cache if nonzero) */ -static uint32_t cached_PC, saved_cached_PC; - -/* Last value actually stored to state->PC */ -static uint32_t stored_PC, saved_stored_PC; - -/* Function to convert a state block offset to a state_cache[] index */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -static inline int state_cache_index(const uint32_t offset) { - if (offset < 25*4) { - return offset / 4; - } else { - return -1; - } -} - -/* Function to convert a state_cache[] index to a state block offset */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -static inline uint32_t state_cache_field(const int index) { - return index * 4; -} - -#endif // OPTIMIZE_STATE_BLOCK - -/*----------------------------------*/ - -#ifdef OPTIMIZE_LOOP_REGISTERS - -/* Is this block a loop that can be optimized? */ -static uint8_t can_optimize_loop; - -/* Bitmask of registers live in the loop (indexed by state cache index) */ -static uint32_t loop_live_registers; - -/* Bitmask of registers whose initial values are used in the loop, and which - * therefore must be loaded ahead of time (indexed by state cache index) */ -static uint32_t loop_load_registers; - -/* Bitmask of registers changed in the loop (indexed by state cache index) */ -static uint32_t loop_changed_registers; - -/* Bitmask of registers which contain invariant pointers, i.e. pointers - * which are unchanged (or only offset by predecrement/postincrement - * addressing or ADD #imm) throughout the body of a loop */ -static uint32_t loop_invariant_pointers; - -#endif // OPTIMIZE_LOOP_REGISTERS - -/*-----------------------------------------------------------------------*/ - -#endif // ENABLE_JIT - -/*************************************************************************/ - -/* Local function declarations */ - -#ifdef ENABLE_JIT // Through the function declarations - -static JitEntry *jit_find(uint32_t address); -static NOINLINE JitEntry *jit_find_noinline(uint32_t address); - -static NOINLINE JitEntry *jit_translate(SH2State *state, uint32_t address); - -#if defined(PSP) && !defined(JIT_DEBUG_INTERPRET_RTL) -__attribute__((unused)) // We use custom assembly in this case -#endif -static inline void jit_exec(SH2State *state, JitEntry *entry); - -static FASTCALL void jit_clear_write(SH2State *state, uint32_t address); -static void jit_clear_range(uint32_t address, uint32_t size); -static void jit_clear_all(void); -static void jit_blacklist_range(uint32_t start, uint32_t end); - -static FASTCALL void jit_mark_purged(uint32_t address); -static int jit_check_purged(uint32_t address); - -#if JIT_BRANCH_PREDICTION_SLOTS > 0 -static NOINLINE JitEntry *jit_predict_branch(BranchTargetInfo *predicted, - const uint32_t target); -#endif - -#ifdef JIT_PROFILE -static NOINLINE void jit_print_profile(void); -#endif - -static NOINLINE void clear_entry(JitEntry *entry); -static void clear_oldest_entry(void); - -static inline void flush_native_cache(void *start, uint32_t length); - -__attribute__((const)) static inline int timestamp_compare( - uint32_t reference, uint32_t a, uint32_t b); - -/*----------------------------------*/ - -static int translate_block(SH2State *state, JitEntry *entry); -static int setup_pointers(SH2State * const state, JitEntry * const entry, - const unsigned int state_reg, - const int skip_preconditions, - unsigned int * const invalidate_label_ptr); - -static int scan_block(SH2State *state, JitEntry *entry, uint32_t address); -static inline void optimize_pointers( - uint32_t start_address, uint32_t address, unsigned int opcode, - uint32_t opcode_info, uint8_t pointer_map[16]); -static inline void optimize_pointers_mac( - uint32_t address, unsigned int opcode, uint8_t pointer_map[16], - uint32_t last_clrmac, int *stop_ret, int *rollback_ret); -#ifdef OPTIMIZE_LOOP_REGISTERS -static inline void check_loop_registers( - unsigned int opcode, uint32_t opcode_info); -#endif -#ifdef OPTIMIZE_BRANCH_SELECT -static inline int optimize_branch_select( - uint32_t start_address, uint32_t address, const uint16_t *fetch, - unsigned int opcode, uint32_t target); -#endif -static int optimize_fold_subroutine( - SH2State *state, const uint32_t start_address, uint32_t address, - const uint32_t target, const uint16_t delay_slot, uint8_t pointer_map[16], - uint32_t local_constant[16], SH2NativeFunctionPointer *native_ret); - -static int translate_insn(SH2State *state, JitEntry *entry, - unsigned int state_reg, int recursing, int is_last); -#ifdef JIT_BRANCH_PREDICT_STATIC -static int add_static_branch_terminator(JitEntry *entry, - unsigned int state_reg, - uint32_t address, unsigned int index); -#endif -#if JIT_BRANCH_PREDICTION_SLOTS > 0 -static FASTCALL JitEntry *update_branch_target(BranchTargetInfo *bti, - uint32_t address); -#endif - -/*----------------------------------*/ - -static uint32_t btcache_lookup(uint32_t address); -static int record_unresolved_branch(const JitEntry *entry, uint32_t sh2_target, - unsigned int target_label); - -static int writeback_state_cache(const JitEntry *entry, unsigned int state_reg, - int flush_fixed); -static void clear_state_cache(int clear_fixed); - -#endif // ENABLE_JIT - -/*-----------------------------------------------------------------------*/ - -/* Dummy, do-nothing callback function used as a default trace callback - * so that the caller doesn't have to check for a NULL function pointer */ -static void dummy_callback(void) {} - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * sh2_init: Initialize the SH-2 core. Must be called before creating any - * virtual processors. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int sh2_init(void) -{ - /* Set up the opcode information tables */ - init_opcode_info(); - - /* Default to no optimizations; let the caller decide what to enable */ - optimization_flags = 0; - - /* Set the dummy callback function in the trace callback pointers */ - trace_insn_callback = (SH2TraceInsnCallback *)dummy_callback; - trace_storeb_callback = (SH2TraceAccessCallback *)dummy_callback; - trace_storew_callback = (SH2TraceAccessCallback *)dummy_callback; - trace_storel_callback = (SH2TraceAccessCallback *)dummy_callback; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_optimizations, sh2_get_optimizations: Set or retrieve the - * bitmask of currently-enabled optional optimizations, as defined by the - * SH2_OPTIMIZE_* constants. - * - * [Parameters] - * flags: Bitmask of optimizations to enable (sh2_set_optimizations() only) - * [Return value] - * Bitmask of enabled optimizations (sh2_get_optimizations() only) - */ -void sh2_set_optimizations(uint32_t flags) -{ - if (flags != optimization_flags) { -#ifdef ENABLE_JIT - jit_clear_all(); -#endif - optimization_flags = flags; - if (!(optimization_flags & SH2_OPTIMIZE_LOCAL_ACCESSES)) { - optimization_flags &= ~SH2_OPTIMIZE_LOCAL_POINTERS; - } - if (!(optimization_flags & SH2_OPTIMIZE_POINTERS)) { - optimization_flags &= ~SH2_OPTIMIZE_LOCAL_POINTERS; - optimization_flags &= ~SH2_OPTIMIZE_POINTERS_MAC; - } - } -} - -uint32_t sh2_get_optimizations(void) -{ - return optimization_flags; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_jit_data_limit: Set the limit on the total size of translated - * code, in bytes of native code (or bytes of RTL data when using the RTL - * interpreter). Does nothing if dynamic translation is disabled. - * - * [Parameters] - * limit: Total JIT data size limit - * [Return value] - * None - */ -void sh2_set_jit_data_limit(uint32_t limit) -{ -#ifdef ENABLE_JIT - jit_data_limit = limit; -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_manual_optimization_callback: Set a callback function to be - * called when beginning to analyze a new block of SH-2 code. If the - * function returns nonzero, it is assumed to have translated a block - * starting at the given address into an optimized RTL instruction stream, - * and the normal block analysis and translation is skipped. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_manual_optimization_callback(SH2OptimizeCallback *funcptr) -{ - manual_optimization_callback = funcptr; -} - -/*----------------------------------*/ - -/** - * sh2_set_cache_flush_callback: Set a callback function to be called when - * a range of addresses should be flushed from the native CPU's caches. - * This is called in preparation for executing a newly-translated block of - * code, so the given range must be flushed from both data and instruction - * caches. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_cache_flush_callback(SH2CacheFlushCallback *funcptr) -{ - cache_flush_callback = funcptr; -} - -/*----------------------------------*/ - -/** - * sh2_set_invalid_opcode_callback: Set a callback function to be called - * when the SH-2 decoder encounters an invalid instruction. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_invalid_opcode_callback(SH2InvalidOpcodeCallback *funcptr) -{ - invalid_opcode_callback = funcptr; -} - -/*----------------------------------*/ - -/** - * sh2_set_trace_insn_callback: Set a callback function to be used for - * tracing instructions as they are executed. The function is only called - * if tracing is enabled in the SH-2 core. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_trace_insn_callback(SH2TraceInsnCallback *funcptr) -{ - trace_insn_callback = - funcptr ? funcptr : (SH2TraceInsnCallback *)dummy_callback; -} - -/*----------------------------------*/ - -/** - * sh2_set_trace_store[bwl]_callback: Set a callback function to be used - * for tracing 1-, 2-, or 4-byte write accesses, respectively. The - * function is only called if tracing is enabled in the SH-2 core. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_trace_storeb_callback(SH2TraceAccessCallback *funcptr) -{ - trace_storeb_callback = - funcptr ? funcptr : (SH2TraceAccessCallback *)dummy_callback; -} - -void sh2_set_trace_storew_callback(SH2TraceAccessCallback *funcptr) -{ - trace_storew_callback = - funcptr ? funcptr : (SH2TraceAccessCallback *)dummy_callback; -} - -void sh2_set_trace_storel_callback(SH2TraceAccessCallback *funcptr) -{ - trace_storel_callback = - funcptr ? funcptr : (SH2TraceAccessCallback *)dummy_callback; -} - - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_alloc_direct_write_buffer: Allocate a buffer which can be passed - * as the write_buffer parameter to sh2_set_direct_access(). The buffer - * should be freed with free() when no longer needed, but no earlier than - * calling sh2_destroy() for all active virtual processors. - * - * [Parameters] - * size: Size of SH-2 address region to be marked as directly accessible - * [Return value] - * Buffer pointer, or NULL on error - */ -void *sh2_alloc_direct_write_buffer(uint32_t size) -{ - const uint32_t bufsize = - (size + ((1<> JIT_PAGE_BITS; - void *buffer = calloc(bufsize, 1); - if (UNLIKELY(!buffer)) { - DMSG("Failed to get 0x%X-byte buffer for 0x%X-byte region", - bufsize, size); - return NULL; - } - return buffer; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_direct_access: Mark a region of memory as being directly - * accessible. The data format of the memory region is assumed to be - * sequential 16-bit words in native order. - * - * As memory is internally divided into 512k (2^19) byte pages, both - * sh2_address and size must be aligned to a multiple of 2^19. - * - * Passing a NULL parameter for native_address causes the region to be - * marked as not directly accessible. - * - * [Parameters] - * sh2_address: Base address of region in SH-2 address space - * native_address: Pointer to memory block in native address space - * size: Size of memory block, in bytes - * readable: Nonzero if region is readable, zero if execute-only - * write_buffer: Buffer for checking writes to this region (allocated - * with sh2_alloc_direct_write_buffer()), or NULL to - * indicate that the region is read- or execute-only - * [Return value] - * None - */ -void sh2_set_direct_access(uint32_t sh2_address, void *native_address, - uint32_t size, int readable, void *write_buffer) -{ -#ifdef ENABLE_JIT - if (UNLIKELY(((sh2_address | size) & ((1<<19)-1)) != 0)) { - DMSG("sh2_address (0x%08X) and size (0x%X) must be aligned to a" - " 19-bit page", sh2_address, size); - return; - } - - const unsigned int first_page = sh2_address >> 19; - const unsigned int last_page = ((sh2_address + size) >> 19) - 1; - if (native_address) { - void * const target = - (void *)((uintptr_t)native_address - (first_page << 19)); - void * const jit_target = write_buffer - ? (void *)((uintptr_t)write_buffer - - (first_page << (19 - JIT_PAGE_BITS))) - : NULL; - unsigned int page; - for (page = first_page; page <= last_page; page++) { - fetch_pages[page] = target; - direct_pages[page] = readable ? target : NULL; - direct_jit_pages[page] = jit_target; - } - } else { - unsigned int page; - for (page = first_page; page <= last_page; page++) { - fetch_pages[page] = NULL; - direct_pages[page] = NULL; - direct_jit_pages[page] = NULL; - } - } -#endif // ENABLE_JIT -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_byte_direct_access: Mark a region of memory as being directly - * accessible in 8-bit units. - * - * As memory is internally divided into 512k (2^19) byte pages, both - * sh2_address and size must be aligned to a multiple of 2^19. - * - * Passing a NULL parameter for native_address causes the region to be - * marked as not directly accessible. - * - * [Parameters] - * sh2_address: Base address of region in SH-2 address space - * native_address: Pointer to memory block in native address space - * size: Size of memory block, in bytes - * [Return value] - * None - */ -void sh2_set_byte_direct_access(uint32_t sh2_address, void *native_address, - uint32_t size) -{ -#ifdef ENABLE_JIT - if (UNLIKELY(((sh2_address | size) & ((1<<19)-1)) != 0)) { - DMSG("sh2_address (0x%08X) and size (0x%X) must be aligned to a" - " 19-bit page", sh2_address, size); - return; - } - - const unsigned int first_page = sh2_address >> 19; - const unsigned int last_page = ((sh2_address + size) >> 19) - 1; - if (native_address) { - void * const target = - (void *)((uintptr_t)native_address - (first_page << 19)); - unsigned int page; - for (page = first_page; page <= last_page; page++) { - byte_direct_pages[page] = target; - } - } else { - unsigned int page; - for (page = first_page; page <= last_page; page++) { - byte_direct_pages[page] = NULL; - } - } -#endif // ENABLE_JIT -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_optimize_hint_data_pointer_load: Provide a hint to the optimizer - * that the load or ALU instruction at the given address loads a pointer to - * a 16-bit direct-access data region. If pointer optimization (the - * SH2_OPTIMIZE_POINTERS flag) is enabled, accesses through the register so - * loaded will automatically use direct access to SH-2 memory, and will - * bypass the code overwrite checks normally executed for store operations. - * If pointer optimization is disabled, this hint has no effect. - * - * The effect of calling this function from any context other than within - * the manual optimization callback, or of specifying an instruction other - * than MOVA which does not set the register specified by the Rn field of - * the opcode, is undefined. - * - * [Parameters] - * state: Processor state block pointer passed to callback function - * address: Address of load instruction to mark as loading a data pointer - * [Return value] - * None - */ -void sh2_optimize_hint_data_pointer_load(SH2State *state, uint32_t address) -{ - PRECOND(state != NULL, return); - PRECOND(state->translate_entry != NULL, return); - -#ifdef ENABLE_JIT - - if (ignore_optimization_hints) { - return; - } - if (!(optimization_flags & SH2_OPTIMIZE_POINTERS)) { - return; - } - - if (address >= state->translate_entry->sh2_start) { - const unsigned int insn_index = - (address - state->translate_entry->sh2_start) / 2; - if (insn_index < lenof(is_data_pointer_load) * 32) { - is_data_pointer_load[insn_index / 32] |= 1 << (insn_index % 32); - } - } - -#endif // ENABLE_JIT -} - -/*----------------------------------*/ - -/** - * sh2_optimize_hint_data_pointer_register: Provide a hint to the - * optimizer that the given general-purpose register (R0 through R15) - * contains a pointer to a direct-access data region at the start of the - * block, and the memory region pointed to will not change over the life - * of the block. If pointer optimization (the SH2_OPTIMIZE_POINTERS flag) - * is enabled, accesses through that register (as long as the register's - * value is unchanged) will automatically use direct access to SH-2 memory, - * and will bypass the code overwrite checks normally executed for store - * operations; furthermore, the register's value will not be verified for - * address validity at block start time, unlike dynamically-detected - * pointers which are verified each time the block is called. If pointer - * optimization is disabled, this hint has no effect. - * - * The effect of calling this function from any context other than within - * the manual optimization callback is undefined. - * - * [Parameters] - * state: Processor state block pointer passed to callback function - * regnum: General-purpose register to mark as containing a data pointer - * [Return value] - * None - */ -void sh2_optimize_hint_data_pointer_register(SH2State *state, - unsigned int regnum) -{ - PRECOND(state != NULL, return); - PRECOND(state->translate_entry != NULL, return); - PRECOND(regnum < 16, return); - -#ifdef ENABLE_JIT - - if (ignore_optimization_hints) { - return; - } - if (!(optimization_flags & SH2_OPTIMIZE_POINTERS)) { - return; - } - - is_data_pointer_reg |= 1 << regnum; - -#endif // ENABLE_JIT -} - -/*----------------------------------*/ - -/** - * sh2_optimize_hint_constant_register: Provide a hint to the optimizer - * that the given general-purpose register (R0 through R15) contains a - * value which will be constant at block entry for the life of the block. - * Instructions which use the register as a source operand may be optimized - * to use the constant value rather than loading the register, and if - * subroutine folding (the SH2_OPTIMIZE_FOLD_SUBROUTINES flag) is enabled, - * JSRs through that register will be considered for subroutine folding - * using the address contained in that register at translation time. - * - * The effect of calling this function from any context other than within - * the manual optimization callback is undefined. - * - * [Parameters] - * state: Processor state block pointer passed to callback function - * regnum: General-purpose register to mark as containing a data pointer - * [Return value] - * None - */ -void sh2_optimize_hint_constant_register(SH2State *state, unsigned int regnum) -{ - PRECOND(state != NULL, return); - PRECOND(state->translate_entry != NULL, return); - PRECOND(regnum < 16, return); - -#ifdef ENABLE_JIT - - if (ignore_optimization_hints) { - return; - } - - is_constant_entry_reg |= 1 << regnum; - -#endif // ENABLE_JIT -} - -/*************************************************************************/ - -/** - * sh2_create: Create a new virtual SH-2 processor. - * - * [Parameters] - * None - * [Return value] - * SH-2 processor state block (NULL on error) - */ -SH2State *sh2_create(void) -{ - SH2State *state; - - state = malloc(sizeof(*state)); - if (!state) { - DMSG("Out of memory allocating state block"); - goto error_return; - } - state->next = state_list; - state_list = state; - - /* Allocate interrupt stack */ - state->interrupt_stack = - malloc(sizeof(*state->interrupt_stack) * INTERRUPT_STACK_SIZE); - if (!state->interrupt_stack) { - DMSG("Out of memory allocating interrupt stack"); - goto error_free_state; - } - - return state; - - error_free_state: - free(state); - error_return: - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_destroy: Destroy a virtual SH-2 processor. - * - * [Parameters] - * state: SH-2 processor state block - * [Return value] - * None - */ -void sh2_destroy(SH2State *state) -{ - if (!state) { - return; - } - - SH2State **prev_ptr; - for (prev_ptr = &state_list; *prev_ptr; prev_ptr = &((*prev_ptr)->next)) { - if ((*prev_ptr) == state) { - break; - } - } - if (!*prev_ptr) { - DMSG("%p not found in state list", state); - return; - } - (*prev_ptr) = state->next; - - free(state->interrupt_stack); - free(state); -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_reset: Reset a virtual SH-2 processor. - * - * [Parameters] - * state: SH-2 processor state block - * [Return value] - * None - */ -void sh2_reset(SH2State *state) -{ - state->delay = 0; - state->asleep = 0; - state->need_interrupt_check = 0; - state->interrupt_stack_top = 0; - state->current_entry = NULL; - state->branch_type = SH2BRTYPE_NONE; - state->folding_subroutine = 0; - state->pending_select = 0; - state->just_branched = 0; - state->cached_shift_count = 0; - state->varshift_target_PC = 0; - state->division_target_PC = 0; - -#ifdef ENABLE_JIT - memset(blacklist, 0, sizeof(blacklist)); - memset(pending_blacklist, 0, sizeof(pending_blacklist)); - memset(purge_table, 0, sizeof(purge_table)); - jit_clear_all(); - jit_timestamp = 0; -#endif -} - -/*************************************************************************/ - -/** - * sh2_run: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * state: SH-2 processor state block - * cycles: Number of clock cycles to execute - * [Return value] - * None - */ -#ifdef PSP -__attribute__((aligned(64))) -#endif -void sh2_run(SH2State *state, uint32_t cycles) -{ - /* Update the JIT timestamp counter once per call */ - jit_timestamp++; - - /* Save this in the state block for use by translated code */ - state->cycle_limit = cycles; - - /* Check for interrupts before we start executing (this will wake up - * the processor if necessary) */ - if (UNLIKELY(check_interrupts(state))) { -#ifdef ENABLE_JIT - state->current_entry = jit_find(state->PC); -#endif - } - - /* If the processor is sleeping, consume all remaining cycles */ - if (UNLIKELY(state->asleep)) { - state->cycles = state->cycle_limit; - return; - } - - /* In TRACE_LITE (but not TRACE_LITE_VERBOSE) mode, trace a single - * instruction at the current PC before we start executing */ -#if defined(TRACE_LITE) && !defined(TRACE_LITE_VERBOSE) - (*trace_insn_callback)(state, state->PC); -#endif - - /* Load this for faster access during the loop */ - JitEntry *current_entry = state->current_entry; - - /* Loop until we've consumed the requested number of execution cycles. - * There's no need to check state->delay here, because it's handled - * either at translation time or by interpret_insn() call. */ - - const uint32_t cycle_limit = state->cycle_limit; - -#if !defined(ENABLE_JIT) - - while (state->cycles < cycle_limit) { - interpret_insn(state); - } - -#else // ENABLE_JIT - -# if defined(PSP) && !defined(JIT_DEBUG_INTERPRET_RTL) - - /* GCC's optimizer fails horribly on this loop, so we have no choice - * but to write it ourselves. */ - -# ifdef JIT_PROFILE - uint32_t start_cycles, start; // As in jit_exec() -# endif - - asm(".set push; .set noreorder\n" - - "lw $t0, %[cycles](%[state])\n" - "beqz %[current_entry], 5f\n" - "sltu $v0, $t0, %[cycle_limit]\n" - /* In the non-trace, non-profile case, this NOP aligns the top of - * the loop to a 64-byte (cache-line) boundary, so that the quick- - * predict critical path fits within a single cache line. This - * provides a noticeable (sometimes >5%) boost to performance. */ - "nop\n" - - // Loop top, quick restart point (jit_translate() call is at the end) - "1:\n" - "beqz $v0, 9f\n" - - // Resume point after block translation - "2:\n" -# ifdef TRACE_LITE_VERBOSE - "move $a0, %[state]\n" - "jalr %[trace_insn_callback]\n" - "lw $a1, %[PC](%[state])\n" -# endif - - // jit_exec(state, current_entry); -# ifdef JIT_PROFILE -# ifndef TRACE_LITE_VERBOSE - "nop\n" // Fill branch delay slot from above -# endif - "jal sceKernelGetSystemTimeLow\n" - "lw %[start_cycles], %[cycles](%[state])\n" - "move %[start], $v0\n" -# endif - - "lw $v0, %[native_code](%[current_entry])\n" - "li $v1, 1\n" - "sb $v1, %[running](%[current_entry])\n" - "jalr $v0\n" - "move $a0, %[state]\n" - -# ifdef JIT_PROFILE - "jal sceKernelGetSystemTimeLow\n" - "nop\n" - "lw $v1, %[cycles](%[state])\n" - "lw $a0, %[call_count](%[current_entry])\n" - "lw $a1, %[cycle_count](%[current_entry])\n" - "lw $a2, %[exec_time](%[current_entry])\n" - "lw $a3, %[exec_time]+4(%[current_entry])\n" - "addiu $a0, $a0, 1\n" - "subu $v1, $v1, %[start_cycles]\n" - "addu $a1, $a1, $v1\n" - "subu $v0, $v0, %[start]\n" - "addu $v0, $a2, $v0\n" - "sltu $v1, $v0, $a2\n" - "addu $a3, $a3, $v1\n" - "sw $a0, %[call_count](%[current_entry])\n" - "sw $a1, %[cycle_count](%[current_entry])\n" - "sw $v0, %[exec_time](%[current_entry])\n" - "sw $a3, %[exec_time]+4(%[current_entry])\n" -# endif - - // Preload data used below - "lbu $v0, %[must_clear](%[current_entry])\n" - "lw $t0, %[cycles](%[state])\n" -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - "lw $a1, %[PC](%[state])\n" - "lw $t1, %[predicted_target](%[current_entry])\n" -# endif - - // Clear current_entry->running and check must_clear - "bnez $v0, 8f\n" - "sb $zero, %[running](%[current_entry])\n" - -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - // Check for a quickly-predicted branch - "sltu $v0, $t0, %[cycle_limit]\n" - "beql $a1, $t1, 1b\n" - "lw %[current_entry], %[predicted_entry](%[current_entry])\n" - // Otherwise call jit_predict_branch() to get the next block - "jal %[jit_predict_branch]\n" - "addiu $a0, %[current_entry], %[predicted]\n" -# else - // Branch prediction is disabled, so just look up a block manually - "jal %[jit_find_noinline]\n" - "lw $a0, %[PC](%[state])\n" -# endif - // Loop back if we found a block, else translate it - "3:\n" - "lw $t0, %[cycles](%[state])\n" - "4:\n" - "move %[current_entry], $v0\n" - "bnez %[current_entry], 1b\n" - "sltu $v0, $t0, %[cycle_limit]\n" - - // Cycle check and jit_translate() call for not-found blocks - "5:\n" - "beqz $v0, 9f\n" - "move $a0, %[state]\n" - "6:\n" - "jal %[jit_translate]\n" - "lw $a1, %[PC](%[state])\n" - "bnez $v0, 2b\n" - "move %[current_entry], $v0\n" - - // interpret_insn() call for translation failure - "jal interpret_insn\n" - "move $a0, %[state]\n" - "jal %[jit_find_noinline]\n" - "lw $a0, %[PC](%[state])\n" - "b 4b\n" - "lw $t0, %[cycles](%[state])\n" - - // clear_entry() and jit_find_noinline() for purged blocks - "8:\n" - "jal %[clear_entry]\n" - "move $a0, %[current_entry]\n" - "jal %[jit_find_noinline]\n" - "lw $a0, %[PC](%[state])\n" - "b 4b\n" - "lw $t0, %[cycles](%[state])\n" - - // End of loop - "9:\n" - ".set pop" - : [current_entry] "=r" (current_entry), -# ifdef JIT_PROFILE - [start_cycles] "=&r" (start_cycles), - [start] "=&r" (start), -# endif - "=m" (*state) - : [state] "r" (state), [cycle_limit] "r" (cycle_limit), - "0" (current_entry), -# ifdef TRACE_LITE_VERBOSE - [trace_insn_callback] "r" (trace_insn_callback), -# endif - [PC] "i" (offsetof(SH2State,PC)), - [cycles] "i" (offsetof(SH2State,cycles)), - [native_code] "i" (offsetof(JitEntry,native_code)), - [running] "i" (offsetof(JitEntry,running)), - [must_clear] "i" (offsetof(JitEntry,must_clear)), -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - [predicted] "i" (offsetof(JitEntry,predicted)), - [predicted_target] "i" (offsetof(JitEntry,predicted[0].target)), - [predicted_entry] "i" (offsetof(JitEntry,predicted[0].entry)), -# endif -# ifdef JIT_PROFILE - [call_count] "i" (offsetof(JitEntry,call_count)), - [cycle_count] "i" (offsetof(JitEntry,cycle_count)), - [exec_time] "i" (offsetof(JitEntry,exec_time)), -# endif -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - [jit_predict_branch] "S" (jit_predict_branch), -# endif - [jit_translate] "S" (jit_translate), - [clear_entry] "S" (clear_entry), - [jit_find_noinline] "S" (jit_find_noinline) - : "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", - "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "ra" - ); - -# else // !(PSP && !JIT_DEBUG_INTERPRET_RTL) - - while (state->cycles < cycle_limit) { - - /* If we don't have a current native code block, translate from - * the current address */ - if (UNLIKELY(!current_entry)) { - current_entry = jit_translate(state, state->PC); - } - - /* If we (now) have a native code block, execute from it */ - if (LIKELY(current_entry)) { - quick_restart:; - -# ifdef TRACE_LITE_VERBOSE - (*trace_insn_callback)(state, state->PC); -# endif - jit_exec(state, current_entry); - -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - const uint32_t new_PC = state->PC; - BranchTargetInfo * const predicted = ¤t_entry->predicted[0]; - - if (UNLIKELY(current_entry->must_clear)) { - /* A purge was requested, so clear the just-executed entry */ - clear_entry(current_entry); - current_entry = jit_find_noinline(new_PC); - continue; - } - - /* Even if we're using multiple prediction slots, handle the - * first one specially for increased speed if it's a correct - * prediction; we make the safe (for all practical purposes) - * assumption that the target PC is not zero */ - if (new_PC == predicted->target) { - current_entry = predicted->entry; - if (LIKELY(state->cycles < cycle_limit)) { - goto quick_restart; - } - } else { - current_entry = jit_predict_branch(predicted, new_PC); - } -# else // branch prediction disabled - if (UNLIKELY(current_entry->must_clear)) { - clear_entry(current_entry); - } - current_entry = jit_find_noinline(state->PC); -# endif - - } else { // !current_entry - - /* We couldn't translate the code at this address, so interpret - * it instead */ - interpret_insn(state); - - } // if (current_entry) - - } // while (state->cycles < cycle_limit) - -# endif // PSP && !JIT_DEBUG_INTERPRET_RTL -#endif // ENABLE_JIT - - state->current_entry = current_entry; - -#if defined(ENABLE_JIT) && defined(JIT_PROFILE) - static int cycles_for_profile; - cycles_for_profile += state->cycle_limit; - if (cycles_for_profile >= JIT_PROFILE_INTERVAL) { - cycles_for_profile = 0; - jit_print_profile(); - } // if (cycles_for_profile >= JIT_PROFILE_INTERVAL) -#endif // ENABLE_JIT && JIT_PROFILE -} - -/*************************************************************************/ - -/** - * sh2_signal_interrupt: Signal an interrupt to a virtual SH-2 processor. - * The interrupt is ignored if another interrupt on the same vector has - * already been signalled. - * - * [Parameters] - * state: SH-2 processor state block - * vector: Interrupt vector (0-127) - * level: Interrupt level (0-15, or 16 for NMI) - * [Return value] - * None - */ -void sh2_signal_interrupt(SH2State *state, unsigned int vector, - unsigned int level) -{ - int i; - - if (UNLIKELY(state->interrupt_stack_top >= INTERRUPT_STACK_SIZE)) { - DMSG("WARNING: dropped interrupt <%u,%u> due to full stack", - vector, level); - DMSG("Interrupt stack:"); - for (i = state->interrupt_stack_top - 1; i >= 0; i--) { - DMSG(" <%3u,%2u>", state->interrupt_stack[i].vector, - state->interrupt_stack[i].level); - } - return; - } - - for (i = 0; i < state->interrupt_stack_top; i++) { - if (state->interrupt_stack[i].vector == vector) { - return; // This interrupt is already raised - } - } - - for (i = 0; i < state->interrupt_stack_top; i++) { - if (state->interrupt_stack[i].level > level) { - memmove(&state->interrupt_stack[i+1], &state->interrupt_stack[i], - sizeof(*state->interrupt_stack) - * (state->interrupt_stack_top - i)); - break; - } - } - state->interrupt_stack[i].level = level; - state->interrupt_stack[i].vector = vector; - state->interrupt_stack_top++; -} - -/*************************************************************************/ - -/** - * sh2_write_notify: Called when an external agent modifies memory. - * Used here to clear any JIT translations in the modified range. - * - * [Parameters] - * address: Beginning of address range to which data was written - * size: Size of address range to which data was written (in bytes) - * [Return value] - * None - */ -void sh2_write_notify(uint32_t address, uint32_t size) -{ -#ifdef ENABLE_JIT - jit_clear_range(address, size); -#endif -} - -/*************************************************************************/ -/******************** General-purpose local routines *********************/ -/*************************************************************************/ - -/** - * check_interrupts: Check whether there are any pending interrupts, and - * service the highest-priority one if so. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero if an interrupt was serviced, else zero - * [Notes] - * This routine is exported for use by sh2-interpret.c. - */ -FASTCALL int check_interrupts(SH2State *state) -{ - if (state->interrupt_stack_top > 0) { - const int level = - state->interrupt_stack[state->interrupt_stack_top-1].level; - if (level > ((state->SR & SR_I) >> SR_I_SHIFT)) { - const int vector = - state->interrupt_stack[state->interrupt_stack_top-1].vector; - state->R[15] -= 4; -#if defined(TRACE) || defined(TRACE_STEALTH) - (*trace_storel_callback)(state->R[15], state->SR); -#endif - MappedMemoryWriteLong(state->R[15], state->SR); - state->R[15] -= 4; -#if defined(TRACE) || defined(TRACE_STEALTH) - (*trace_storel_callback)(state->R[15], state->PC); -#endif - MappedMemoryWriteLong(state->R[15], state->PC); - state->SR &= ~SR_I; - state->SR |= level << SR_I_SHIFT; - state->PC = MappedMemoryReadLong(state->VBR + (vector << 2)); - state->asleep = 0; - state->interrupt_stack_top--; - return 1; - } - } - return 0; -} - -/*************************************************************************/ -/**************** Dynamic translation management routines ****************/ -/*************************************************************************/ - -#ifdef ENABLE_JIT // Through the end of the file - -/*************************************************************************/ - -/** - * jit_find, jit_find_noinline: Find the translated block for a given - * address, if any. jit_find_noinline() is explicitly marked NOINLINE to - * minimize register pressure when called from sh2_run(). - * - * [Parameters] - * address: Start address in SH-2 address space - * [Return value] - * Translated block, or NULL if no such block exists - */ -static JitEntry *jit_find(uint32_t address) -{ - const int hashval = JIT_HASH(address); - JitEntry *entry = jit_hashchain[hashval]; - while (entry) { - if (entry->sh2_start == address) { - return entry; - } - entry = entry->next; - } - return NULL; -} - -static NOINLINE JitEntry *jit_find_noinline(uint32_t address) -{ - return jit_find(address); -} - -/*************************************************************************/ - -/** - * jit_translate: Dynamically translate a block of instructions starting - * at the given address. If a translation already exists for the given - * address, it is cleared. - * - * [Parameters] - * state: SH-2 processor state block - * address: Start address in SH-2 address space - * [Return value] - * Translated block, or NULL on error - */ -static NOINLINE JitEntry *jit_translate(SH2State *state, uint32_t address) -{ - JitEntry *entry; - int index; - -#ifdef PSP_TIME_TRANSLATION - static uint32_t total, count; - const uint32_t a = sceKernelGetSystemTimeLow(); -#endif - - /* Update the timestamp on every call */ - jit_timestamp++; - - /* First check for untranslatable addresses */ - if (UNLIKELY(address == 0)) { - /* We use address 0 to indicate an unused entry, so we can't - * translate from address 0. But this should never happen except - * in pathological cases (or unhandled exceptions), so just punt - * and let the interpreter handle it. */ - return NULL; - } - if (UNLIKELY(address & 1)) { - /* Odd addresses are invalid, so we can't translate them in the - * first place. */ - return NULL; - } - if (UNLIKELY(!fetch_pages[address >> 19])) { - /* Don't try to translate anything from non-directly-accessible - * memory, since we can't track changes to such memory. */ - return NULL; - } - - /* Check whether the starting address is blacklisted */ - for (index = 0; index < lenof(blacklist); index++) { - uint32_t age = jit_timestamp - blacklist[index].timestamp; - if (age >= JIT_BLACKLIST_EXPIRE) { - /* Entry expired, so clear it */ - blacklist[index].start = blacklist[index].end = 0; - continue; - } - if (blacklist[index].start <= address - && address <= blacklist[index].end) { - return NULL; - } - } - - /* Clear out any existing translation; if we've reached the data size - * limit, also evict old entries until we're back under the limit */ - if ((entry = jit_find(address)) != NULL) { - clear_entry(entry); - } - if (UNLIKELY(jit_total_data >= jit_data_limit)) { -#ifdef JIT_DEBUG - DMSG("JIT data size over limit (%u >= %u), clearing entries", - jit_total_data, jit_data_limit); -#endif - while (jit_total_data >= jit_data_limit) { - clear_oldest_entry(); - } - } - - /* Obtain a free entry for this block */ - if (jit_freelist.next == &jit_freelist) { - /* No free entries, so clear the oldest one and use it */ -#ifdef JIT_DEBUG - DMSG("No free slots for code at 0x%08X, clearing oldest", address); -#endif - clear_oldest_entry(); - if (UNLIKELY(jit_freelist.next == &jit_freelist)) { // paranoia - DMSG("BUG: failed to update free list"); - return 0; - } - } - entry = jit_freelist.next; - jit_freelist.next = entry->next; - jit_freelist.next->prev = &jit_freelist; - - /* Store the entry pointer in the state block, for reference by other - * functions */ - state->translate_entry = entry; - - /* Initialize the new entry */ - entry->rtl = rtl_create_block(); - if (!entry->rtl) { - DMSG("No memory for code at 0x%08X", address); - goto fail; - } - const int hashval = JIT_HASH(address); - entry->next = jit_hashchain[hashval]; - if (entry->next) { - entry->next->prev = entry; - } - jit_hashchain[hashval] = entry; - entry->prev = NULL; - entry->lra_next = &jit_lralist; - entry->lra_prev = jit_lralist.lra_prev; - entry->lra_next->lra_prev = entry; - entry->lra_prev->lra_next = entry; - entry->pred_ref_head.next = &entry->pred_ref_head; - entry->pred_ref_head.prev = &entry->pred_ref_head; - entry->sh2_start = address; - entry->sh2_end = 0; - entry->native_code = NULL; - entry->native_length = 0; - entry->timestamp = jit_timestamp; - entry->running = 0; - entry->must_clear = 0; -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - for (index = 0; index < JIT_BRANCH_PREDICTION_SLOTS; index++) { - entry->predicted[index].target = 0; - entry->predicted[index].entry = NULL; - entry->predicted[index].next = NULL; - entry->predicted[index].prev = NULL; - } -#endif -#ifdef JIT_BRANCH_PREDICT_STATIC - entry->static_predict = NULL; - entry->num_static_branches = 0; -#endif -#ifdef JIT_PROFILE - entry->call_count = 0; - entry->cycle_count = 0; - entry->exec_time = 0; -#endif - - /* Perform the SH-2 -> RTL translation */ - if (UNLIKELY(!translate_block(state, entry))) { - DMSG("Failed to translate block at 0x%08X", address); - /* If we found a valid end address for the block, blacklist the - * entire block so we don't waste time trying to translate from - * every successive instruction. Otherwise, just blacklist the - * first address in case we come back here again. */ - if (entry->sh2_end) { - jit_blacklist_range(address, entry->sh2_end); - } else { - jit_blacklist_range(address, address+1); - } - goto clear_and_fail; - } - - /* Translate from RTL to native code */ -#ifndef JIT_DEBUG_INTERPRET_RTL - if (UNLIKELY(!rtl_translate_block(entry->rtl, &entry->native_code, - &entry->native_length))) { - DMSG("Failed to translate block at 0x%08X", entry->sh2_start); - goto clear_and_fail; - } - /* Make sure the new code isn't masked by cached data */ - flush_native_cache(entry->native_code, entry->native_length); - rtl_destroy_block(entry->rtl); - entry->rtl = NULL; -#endif - - /* Update JIT management data */ - uint8_t *jit_base = direct_jit_pages[entry->sh2_start >> 19]; - if (jit_base) { - for (index = entry->sh2_start >> JIT_PAGE_BITS; - index <= entry->sh2_end >> JIT_PAGE_BITS; - index++ - ) { - JIT_PAGE_SET(jit_base, index); - } - } -#ifdef JIT_DEBUG_INTERPRET_RTL - /* Guesstimate how much memory was used (including the insn-to-unit LUT - * later allocated by rtl_execute_block()); we assume average ratios of - * 5:8 insns:regs, and 1:8 insns:units (we don't bother with labels - * since they only require 2 bytes each and are generally less than 10% - * of insns). */ - entry->native_length = ((sizeof(RTLInsn)+2) - + sizeof(RTLRegister)*5/8 - + sizeof(RTLUnit)/8) * entry->rtl->insns_size - + sizeof(RTLBlock); -#endif - jit_total_data += entry->native_length; - -#ifdef PSP_TIME_TRANSLATION - const uint32_t b = sceKernelGetSystemTimeLow(); - total += b-a; - count += ((current_entry->sh2_end + 1) - current_entry->sh2_start) / 2; - DMSG("%u/%u = %.3f us/insn", total, count, (float)total/count); -#endif - - /* All done */ - state->translate_entry = NULL; - return entry; - - /* Error handling */ - clear_and_fail: - clear_entry(entry); - fail: - state->translate_entry = NULL; - return NULL; -} - -/*************************************************************************/ - -/** - * jit_clear_write: Clear any translation which includes the given - * address. Intended to be called from within translated code. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * [Return value] - * None - */ -static FASTCALL void jit_clear_write(SH2State *state, uint32_t address) -{ - int index; - - /* If it's a blacklisted address, we don't need to do anything (since - * the address couldn't have been translated); just update the entry's - * write timestamp and return */ - for (index = 0; index < lenof(blacklist); index++) { - if (blacklist[index].start <= address - && address <= blacklist[index].end) { - blacklist[index].timestamp = jit_timestamp; - return; - } - } - -#ifdef JIT_DEBUG - DMSG("WARNING: jit_clear_write(0x%08X) from PC %08X", address, state->PC); -#endif - - /* Clear any translations on the affected page */ - uint8_t * const jit_base = direct_jit_pages[address >> 19]; - const uint32_t page = address >> JIT_PAGE_BITS; - const uint32_t page_start = address & -(1 << JIT_PAGE_BITS); - const uint32_t page_end = page_start + ((1 << JIT_PAGE_BITS) - 1); - JIT_PAGE_CLEAR(jit_base, page); - int found_entry = 0; // Flag: Did we find a block on this page? - int do_blacklist = 0; // Flag: Blacklist this address? - for (index = 0; index < JIT_TABLE_SIZE; index++) { - if (jit_table[index].sh2_start == 0) { - continue; - } - if (jit_table[index].sh2_start <= page_end - && jit_table[index].sh2_end >= page_start - ) { - found_entry = 1; - if (UNLIKELY(jit_table[index].running)) { - jit_table[index].must_clear = 1; - do_blacklist = 1; - } else { - clear_entry(&jit_table[index]); - } - } - } - - /* If we fault on the same address multiple times in rapid succession, - * blacklist the address even if it wasn't in a running block. (We - * don't blacklist this case on the first fault because it could just - * be overwriting a block of memory with new code.) */ - if (found_entry && !do_blacklist) { - int empty = -1; - unsigned int oldest = 0; - for (index = 0; index < lenof(pending_blacklist); index++) { - if (pending_blacklist[index].address == address) { - if (jit_timestamp - pending_blacklist[index].timestamp - > JIT_PURGE_EXPIRE - ) { - pending_blacklist[index].count = 0; - } - break; - } else if (pending_blacklist[index].address != 0) { - if (pending_blacklist[index].timestamp - < pending_blacklist[oldest].timestamp - ) { - oldest = index; - } - } else if (empty < 0) { - empty = index; - } - } - if (index >= lenof(pending_blacklist)) { - if (empty >= 0) { - index = empty; - } else { - index = oldest; - } - pending_blacklist[index].address = address; - pending_blacklist[index].count = 0; - } - pending_blacklist[index].timestamp = jit_timestamp; - pending_blacklist[index].count++; - if (pending_blacklist[index].count >= JIT_PURGE_THRESHOLD) { -#ifdef JIT_DEBUG - DMSG("Blacklisting 0x%08X due to repeated faults",address); -#endif - do_blacklist = 1; - } - } - - /* Blacklist this address if appropriate. We always keep the blacklist - * entries 16-bit-aligned; since we don't pass the write size in, we - * assume the write is 32-bit-sized if on a 32-bit-aligned address, and - * 16-bit-sized otherwise. */ - if (do_blacklist) { - const uint32_t start = address & ~1; - const uint32_t end = (address & ~3) + 3; - jit_blacklist_range(start, end); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_clear_range: Clear any translation on any page touched by the given - * range of addresses. Intended to be called when an external agent - * modifies memory. - * - * [Parameters] - * address: Beginning of address range to which data was written - * size: Size of address range to which data was written (in bytes) - * [Return value] - * None - */ -static void jit_clear_range(uint32_t address, uint32_t size) -{ - const uint32_t first_page = address >> JIT_PAGE_BITS; - const uint32_t last_page = (address + size - 1) >> JIT_PAGE_BITS; - const uint32_t page_start = first_page << JIT_PAGE_BITS; - const uint32_t page_end = ((last_page+1) << JIT_PAGE_BITS) - 1; - - int page; - for (page = first_page; page <= last_page; page++) { - if (direct_jit_pages[page >> (19-JIT_PAGE_BITS)]) { - JIT_PAGE_CLEAR(direct_jit_pages[page >> (19-JIT_PAGE_BITS)], page); - } - } - - int index; - for (index = 0; index < JIT_TABLE_SIZE; index++) { - if (jit_table[index].sh2_start == 0) { - continue; - } - if (jit_table[index].sh2_start <= page_end - && jit_table[index].sh2_end >= page_start - ) { - clear_entry(&jit_table[index]); - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_clear_all: Clear all translations. Intended to be used when - * initializing/resetting the processor or when a change in optimization - * options invalidates existing translations. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void jit_clear_all(void) -{ - int index; - - /* Clear all JIT bitmaps */ - for (index = 0; index < lenof(direct_jit_pages); index++) { - if (direct_jit_pages[index]) { - uintptr_t address = (uintptr_t)direct_jit_pages[index]; - address += index << (19 - JIT_PAGE_BITS); - memset((void *)address, 0, (1<<19) >> JIT_PAGE_BITS); - } - } - - /* Clear all entry data (don't call clear_entry() to avoid wasting time - * updating management data for every single entry) */ - for (index = 0; index < JIT_TABLE_SIZE; index++) { - if (jit_table[index].sh2_start) { - free(jit_table[index].native_code); - jit_table[index].native_code = NULL; - rtl_destroy_block(jit_table[index].rtl); - jit_table[index].rtl = NULL; -#ifdef JIT_BRANCH_PREDICT_STATIC - free(jit_table[index].static_predict); - jit_table[index].static_predict = NULL; -#endif - jit_table[index].sh2_start = 0; - } - jit_table[index].timestamp = 0; - } - for (index = 0; index < JIT_TABLE_SIZE; index++) { - jit_hashchain[index] = NULL; - } - - /* Put every entry in the free list */ - jit_freelist.next = &jit_table[0]; - jit_table[0].prev = &jit_freelist; - for (index = 1; index < JIT_TABLE_SIZE; index++) { - jit_table[index-1].next = &jit_table[index]; - jit_table[index].prev = &jit_table[index-1]; - } - jit_table[JIT_TABLE_SIZE-1].next = &jit_freelist; - jit_freelist.prev = &jit_table[JIT_TABLE_SIZE-1]; - - /* Clear other management data */ - jit_lralist.lra_next = &jit_lralist; - jit_lralist.lra_prev = &jit_lralist; - jit_total_data = 0; - SH2State *state; - for (state = state_list; state; state = state->next) { - state->current_entry = NULL; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_blacklist_range: Add the specified range to the JIT blacklist. - * - * [Parameters] - * start: First byte in range to blacklist - * end: Last byte in range to blacklist - * [Return value] - * None - */ -static void jit_blacklist_range(uint32_t start, uint32_t end) -{ - unsigned int index; - - /* Merge this to the beginning or end of another entry if possible */ - for (index = 0; index < lenof(blacklist); index++) { - if (blacklist[index].start == end+1) { - blacklist[index].start = start; - /* See if there's another one we can join to this one */ - unsigned int index2; - for (index2 = 0; index2 < lenof(blacklist); index2++) { - if (start == blacklist[index2].end+1) { - blacklist[index].start = blacklist[index2].start; - blacklist[index2].start = blacklist[index2].end = 0; - break; - } - } - goto entry_added; - } else if (blacklist[index].end+1 == start) { - blacklist[index].end = end; - unsigned int index2; - for (index2 = 0; index2 < lenof(blacklist); index2++) { - if (end+1 == blacklist[index2].start) { - blacklist[index].end = blacklist[index2].end; - blacklist[index2].start = blacklist[index2].end = 0; - break; - } - } - goto entry_added; - } - } - - /* We didn't find an entry to merge this into, so allocate a new one */ - for (index = 0; index < lenof(blacklist); index++) { - if (!blacklist[index].start && !blacklist[index].end) { - break; - } - } - - /* If the table is full, purge the oldest entry */ - if (index >= lenof(blacklist)) { - unsigned int oldest = 0; - for (index = 1; index < lenof(blacklist); index++) { - if (timestamp_compare(jit_timestamp, - blacklist[index].timestamp, - blacklist[oldest].timestamp) < 0) { - oldest = index; - } - } -#ifdef JIT_DEBUG - DMSG("Blacklist full, purging entry %d (0x%X-0x%X)", - oldest, blacklist[oldest].start, blacklist[oldest].end); -#endif - index = oldest; - } - - /* Fill in the new entry */ - blacklist[index].start = start; - blacklist[index].end = end; - entry_added: - blacklist[index].timestamp = jit_timestamp; -} - -/*************************************************************************/ - -/** - * jit_mark_purged: Mark the given block as purged due to precondition - * failure. - * - * [Parameters] - * address: Block starting address - * [Return value] - * None - */ -static FASTCALL void jit_mark_purged(uint32_t address) -{ - unsigned int i; - unsigned int oldest = 0; // Oldest entry (which will be overwritten) - unsigned int oldest_age = 0; // Age of purge_table[oldest] - -#ifdef JIT_DEBUG - DMSG("WARNING: Purging block 0x%08X", address); -#endif - - for (i = 0; i < lenof(purge_table); i++) { - const uint32_t age = jit_timestamp - purge_table[i].timestamp; - if (!purge_table[i].address) { - /* Empty entry, so treat it as the oldest one for overwriting */ - oldest = i; - oldest_age = JIT_PURGE_EXPIRE; - } else if (age >= JIT_PURGE_EXPIRE) { - /* Entry has expired, so clear it out */ - purge_table[i].address = 0; - oldest = i; - oldest_age = JIT_PURGE_EXPIRE; - } else if (purge_table[i].address == address) { - /* If this block is already in the list (and not expired), - * increment its purge counter and stop immediately */ - purge_table[i].timestamp = jit_timestamp; - purge_table[i].count++; - return; - } else if (age > oldest_age) { - /* If this is the oldest entry in the table, we'll overwrite it */ - oldest = i; - oldest_age = age; - } - } - - /* We didn't find the entry in the table, so overwrite the oldest slot - * (which may be an empty slot) with this block's information */ - purge_table[oldest].address = address; - purge_table[oldest].timestamp = jit_timestamp; - purge_table[oldest].count = 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_check_purged: Check whether the given block has been purged often - * enough to require disabling optimizations with preconditions. - * - * [Parameters] - * address: Block starting address - * [Return value] - * Nonzero if relevant optimizations should be disabled, else zero - */ -static int jit_check_purged(uint32_t address) -{ - unsigned int i; - - for (i = 0; i < lenof(purge_table); i++) { - if (purge_table[i].address == address) { - const uint32_t age = jit_timestamp - purge_table[i].timestamp; - if (age >= JIT_PURGE_EXPIRE) { - purge_table[i].address = 0; - return 0; - } else { - return purge_table[i].count >= JIT_PURGE_THRESHOLD; - } - } - } - - return 0; -} - -/*************************************************************************/ - -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - -/** - * jit_predict_branch: Attempt to predict a branch to "target" using the - * prediction array "predicted", and update the prediction table as - * appropriate. Helper function for sh2_run(), called after the first - * prediction table entry has been checked. - * - * [Parameters] - * target: Target SH-2 address - * predicted: JitEntry.predicted array from current translated block - * [Return value] - * Translated block for target address, or NULL if none was found - */ -static NOINLINE JitEntry *jit_predict_branch(BranchTargetInfo *predicted, - const uint32_t target) -{ -# if JIT_BRANCH_PREDICTION_SLOTS > 1 - /* First see if it's in any slot other than the first */ - unsigned int i; - for (i = 1; i < JIT_BRANCH_PREDICTION_SLOTS; i++) { - if (predicted[i].target != 0 && target == predicted[i].target) { - JitEntry *result = predicted[i].entry; -# ifdef JIT_BRANCH_PREDICTION_FLOAT - /* Shift it up to the previous slot so we can find it faster next - * time. If we have any code that alternates between two branch - * targets, we're going to take a major performance hit... */ - BranchTargetInfo *this_next = predicted[i].next; - BranchTargetInfo *this_prev = predicted[i].prev; - uint32_t this_target = predicted[i].target; - JitEntry *this_entry = predicted[i].entry; - predicted[i].target = predicted[i-1].target; - predicted[i].entry = predicted[i-1].entry; - if (predicted[i].entry) { - predicted[i].next = predicted[i-1].next; - predicted[i].prev = predicted[i-1].prev; - predicted[i].next->prev = &predicted[i]; - predicted[i].prev->next = &predicted[i]; - } - predicted[i-1].next = this_next; - predicted[i-1].prev = this_prev; - predicted[i-1].target = this_target; - predicted[i-1].entry = this_entry; - this_next->prev = &predicted[i-1]; - this_prev->next = &predicted[i-1]; -# endif // JIT_BRANCH_PREDICTION_FLOAT - return result; - } - } - /* Update the first empty slot, or the last slot if none are empty */ - for (i = 0; i < JIT_BRANCH_PREDICTION_SLOTS-1; i++) { - if (predicted[i].target == 0) { - break; - } - } - return update_branch_target(&predicted[i], target); -# else // JIT_BRANCH_PREDICTION_SLOTS == 1 - return update_branch_target(predicted, target); -# endif -} - -#endif // JIT_BRANCH_PREDICTION_SLOTS > 0 - -/*************************************************************************/ - -#ifdef JIT_PROFILE - -/** - * jit_print_profile: Print profiling statistics for translated code. - * - * [Parameters] - * None - * [Return value] - * None - */ -static NOINLINE void jit_print_profile(void) -{ - int top[JIT_PROFILE_TOP]; - unsigned int i; - - printf("\n"); - - printf("================= Top callees by time: =================\n"); - memset(top, -1, sizeof(top)); - for (i = 0; i < lenof(jit_table); i++) { - if (!jit_table[i].sh2_start) { - continue; - } - unsigned int j; - for (j = 0; j < lenof(top); j++) { - if (top[j] < 0 - || jit_table[i].exec_time > jit_table[top[j]].exec_time - ) { - unsigned int k; - for (k = lenof(top)-1; k > j; k--) { - top[k] = top[k-1]; - } - top[j] = i; - break; - } - } - } - printf( -# ifdef JIT_DEBUG_INTERPRET_RTL - "RTL insns" -# else - "Exec time" -# endif - " SH2 cyc. Native/SH2 # calls Block addr\n"); - printf("--------- -------- ---------- ------- ----------\n"); - for (i = 0; i < lenof(top) && top[i] >= 0; i++) { - printf("%9lld %10d %12.3f %9d 0x%08X\n", - (unsigned long long)jit_table[top[i]].exec_time, - jit_table[top[i]].cycle_count, - (double)jit_table[top[i]].exec_time - / (double)jit_table[top[i]].cycle_count, - jit_table[top[i]].call_count, - jit_table[top[i]].sh2_start); - } - printf("========================================================\n"); - - - printf("============== Top callees by call count: ==============\n"); - memset(top, -1, sizeof(top)); - for (i = 0; i < lenof(jit_table); i++) { - if (!jit_table[i].sh2_start) { - continue; - } - unsigned int j; - for (j = 0; j < lenof(top); j++) { - if (top[j] < 0 - || jit_table[i].call_count > jit_table[top[j]].call_count - ) { - unsigned int k; - for (k = lenof(top)-1; k > j; k--) { - top[k] = top[k-1]; - } - top[j] = i; - break; - } - } - } - printf( -# ifdef JIT_DEBUG_INTERPRET_RTL - "RTL insns" -# else - "Exec time" -# endif - " SH2 cyc. Native/SH2 # calls Block addr\n"); - printf("--------- -------- ---------- ------- ----------\n"); - for (i = 0; i < lenof(top) && top[i] >= 0; i++) { - printf("%9lld %10d %12.3f %9d 0x%08X\n", - (unsigned long long)jit_table[top[i]].exec_time, - jit_table[top[i]].cycle_count, - (double)jit_table[top[i]].exec_time - / (double)jit_table[top[i]].cycle_count, - jit_table[top[i]].call_count, - jit_table[top[i]].sh2_start); - } - printf("========================================================\n"); - - for (i = 0; i < lenof(jit_table); i++) { - jit_table[i].call_count = 0; - jit_table[i].cycle_count = 0; - jit_table[i].exec_time = 0; - } - -} - -#endif // JIT_PROFILE - -/*************************************************************************/ -/***************** Dynamic translation utility routines ******************/ -/*************************************************************************/ - -/** - * clear_entry: Clear a specific entry from the JIT table, freeing the - * native code buffer and unlinking the entry from its references. - * - * [Parameters] - * entry: JitEntry structure pointer - * [Return value] - * None - */ -static NOINLINE void clear_entry(JitEntry *entry) -{ - PRECOND(entry != NULL, return); - - /* Make sure the non-active processor isn't trying to use this entry - * (if so, clear it out) */ - SH2State *state; - for (state = state_list; state; state = state->next) { - if (state->current_entry == entry) { - state->current_entry = NULL; - } - } - - /* Free the native code, if any */ - jit_total_data -= entry->native_length; - free(entry->native_code); - entry->native_code = NULL; - - /* Free the RTL block, if any */ - rtl_destroy_block(entry->rtl); - entry->rtl = NULL; - - /* Clear the entry from the predicted branch target of any entries - * referencing it */ - BranchTargetInfo *referrer, *next; - for (referrer = entry->pred_ref_head.next; - referrer != &entry->pred_ref_head; - referrer = next - ) { - next = referrer->next; - referrer->target = 0; - referrer->entry = NULL; - referrer->next = NULL; - referrer->prev = NULL; - } - entry->pred_ref_head.next = &entry->pred_ref_head; - entry->pred_ref_head.prev = &entry->pred_ref_head; - - /* Remove this entry from the reference list of any branch it predicts */ -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - unsigned int i; - for (i = 0; i < JIT_BRANCH_PREDICTION_SLOTS; i++) { - if (entry->predicted[i].entry) { - entry->predicted[i].next->prev = entry->predicted[i].prev; - entry->predicted[i].prev->next = entry->predicted[i].next; - } - } -#endif -#ifdef JIT_BRANCH_PREDICT_STATIC - for (i = 0; i < entry->num_static_branches; i++) { - if (entry->static_predict[i].entry) { - entry->static_predict[i].next->prev = entry->static_predict[i].prev; - entry->static_predict[i].prev->next = entry->static_predict[i].next; - } - } - free(entry->static_predict); - entry->static_predict = NULL; - jit_total_data -= - entry->num_static_branches * sizeof(*entry->static_predict); -#endif - - /* Clear the entry from the hash chain and LRA list */ - if (entry->next) { - entry->next->prev = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } else { - jit_hashchain[JIT_HASH(entry->sh2_start)] = entry->next; - } - entry->lra_next->lra_prev = entry->lra_prev; - entry->lra_prev->lra_next = entry->lra_next; - - /* Mark the entry as free */ - entry->sh2_start = 0; - - /* Insert the entry into the free list */ - entry->next = jit_freelist.next; - entry->prev = &jit_freelist; - entry->next->prev = entry; - jit_freelist.next = entry; -} - -/*-----------------------------------------------------------------------*/ - -/** - * clear_oldest_entry: Clear the oldest entry from the JIT table. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void clear_oldest_entry(void) -{ - JitEntry *oldest = jit_lralist.lra_next; - if (LIKELY(oldest != &jit_lralist)) { -#ifdef JIT_DEBUG - DMSG("Clearing oldest entry 0x%08X (age %u)", - oldest->sh2_start, jit_timestamp - oldest->timestamp); -#endif - clear_entry(oldest); - } else { -#ifdef JIT_DEBUG - DMSG("Tried to clear oldest entry from an empty table!"); -#endif - /* We don't call this function unless there's something we need to - * clear out, so if we come here, our internal tables may be - * corrupt. Reset everything to be safe. */ - jit_total_data = 0; - } -} - -/*************************************************************************/ - -/** - * flush_native_cache: Flush a range of addresses from the native CPU's - * caches. - * - * [Parameters] - * start: Pointer to start of range - * length: Length of range in bytes - * [Return value] - * None - */ -static inline void flush_native_cache(void *start, uint32_t length) -{ - if (cache_flush_callback) { - (*cache_flush_callback)(start, length); - } -} - -/*************************************************************************/ - -/** - * timestamp_compare: Compare two timestamps. - * - * [Parameters] - * a, b: Timestamps to compare - * reference: Reference timestamp by which the comparison is made - * [Return value] - * -1 if a < b (i.e. "a is older than b") - * 0 if a == b - * 1 if a > b - */ -__attribute__((const)) static inline int timestamp_compare( - uint32_t reference, uint32_t a, uint32_t b) -{ - const uint32_t age_a = reference - a; - const uint32_t age_b = reference - b; - return age_a > age_b ? -1 : - age_a < age_b ? 1 : 0; -} - -/*************************************************************************/ -/****************** Macros for SH-2 -> RTL translation *******************/ -/*************************************************************************/ - -/* Constants used in SH-2 memory access operations */ -#define SH2_ACCESS_TYPE_B 0 // 1-byte access (signed for loads) -#define SH2_ACCESS_TYPE_W 1 // 2-byte access (signed for loads) -#define SH2_ACCESS_TYPE_L 2 // 4-byte access - -/* Return the "high" (pointer register) and "low" (load/store offset) parts - * of an address for generating optimal native load/store code */ -#ifdef __mips__ -# define ADDR_HI(address) (((uintptr_t)(address) + 0x8000) & 0xFFFF0000) -# define ADDR_LO(address) ((int16_t)((uintptr_t)(address) & 0xFFFF)) -#else -# define ADDR_HI(address) ((uintptr_t)address) -# define ADDR_LO(address) 0 -#endif - -/*-----------------------------------------------------------------------*/ - -/* Basic macro to pass a failure (zero) return value up the call chain */ -#define ASSERT(expr) do { \ - if (UNLIKELY(!(expr))) { \ - return 0; \ - } \ -} while (0) - -/* Basic macro to append an RTL instruction, aborting on error */ -#define APPEND(opcode,dest,src1,src2,other) \ - ASSERT(rtl_add_insn(entry->rtl, RTLOP_##opcode, \ - (dest), (src1), (src2), (other))); - -/*-----------------------------------------------------------------------*/ - -/* Declare a register identifier, but don't allocate a new register for it */ -#define DECLARE_REG(name) uint32_t name - -/* Allocate a register for a declared identifier */ -#define ALLOC_REG(name) ASSERT(name = rtl_alloc_register(entry->rtl)) - -/* Define a new register (equivalent to DECLARE_REG followed by ALLOC_REG) */ -#define DEFINE_REG(name) \ - const uint32_t name = rtl_alloc_register(entry->rtl); \ - if (UNLIKELY(!name)) { \ - return 0; \ - } - -/*-----------------------------------------------------------------------*/ - -/* Register-register operations */ - -#define MOVE(dest,src) APPEND(MOVE, (dest), (src), 0, 0) -#define SELECT(dest,src1,src2,cond) \ - APPEND(SELECT, (dest), (src1), (src2), (cond)) -#define ADD(dest,src1,src2) APPEND(ADD, (dest), (src1), (src2), 0) -#define SUB(dest,src1,src2) APPEND(SUB, (dest), (src1), (src2), 0) -#define MUL(dest,src1,src2) APPEND(MULU, (dest), (src1), (src2), 0) -#define MULU_64(dest,src1,src2,dest_hi) \ - APPEND(MULU, (dest), (src1), (src2), (dest_hi)) -#define MULS_64(dest,src1,src2,dest_hi) \ - APPEND(MULS, (dest), (src1), (src2), (dest_hi)) -#define MADDU_64(dest,src1,src2,dest_hi) \ - APPEND(MADDU, (dest), (src1), (src2), (dest_hi)) -#define MADDS_64(dest,src1,src2,dest_hi) \ - APPEND(MADDS, (dest), (src1), (src2), (dest_hi)) -#define DIVMODU(dest,src1,src2,rem) \ - APPEND(DIVMODU, (dest), (src1), (src2), (rem)) -#define DIVMODS(dest,src1,src2,rem) \ - APPEND(DIVMODS, (dest), (src1), (src2), (rem)) -#define AND(dest,src1,src2) APPEND(AND, (dest), (src1), (src2), 0) -#define OR(dest,src1,src2) APPEND(OR, (dest), (src1), (src2), 0) -#define XOR(dest,src1,src2) APPEND(XOR, (dest), (src1), (src2), 0) -#define NOT(dest,src) APPEND(NOT, (dest), (src), 0, 0) -#define SLL(dest,src1,src2) APPEND(SLL, (dest), (src1), (src2), 0) -#define SRL(dest,src1,src2) APPEND(SRL, (dest), (src1), (src2), 0) -#define SRA(dest,src1,src2) APPEND(SRA, (dest), (src1), (src2), 0) -#define ROR(dest,src1,src2) APPEND(SRL, (dest), (src1), (src2), 0) -#define CLZ(dest,src) APPEND(CLZ, (dest), (src), 0, 0) -#define CLO(dest,src) APPEND(CLO, (dest), (src), 0, 0) -#define SLTU(dest,src1,src2) APPEND(SLTU, (dest), (src1), (src2), 0) -#define SLTS(dest,src1,src2) APPEND(SLTS, (dest), (src1), (src2), 0) -#define BSWAPH(dest,src) APPEND(BSWAPH, (dest), (src), 0, 0) -#define BSWAPW(dest,src) APPEND(BSWAPW, (dest), (src), 0, 0) -#define HSWAPW(dest,src) APPEND(HSWAPW, (dest), (src), 0, 0) - -/*----------------------------------*/ - -/* Register-immediate operations */ - -#define MOVEI(dest,imm) APPEND(LOAD_IMM, (dest), (imm), 0, 0) -#define MOVEA(dest,addr) APPEND(LOAD_ADDR, (dest), \ - (uintptr_t)(addr), 0, 0) -#ifdef JIT_USE_RTL_REGIMM -# define IMMOP(op,dest,src,imm) APPEND(op##I, (dest), (src), (imm), 0) -#else -# define IMMOP(op,dest,src,imm) do { DEFINE_REG(__immreg); \ - APPEND(LOAD_IMM, __immreg, (imm), 0, 0); \ - APPEND(op, (dest), (src), __immreg, 0); \ - } while (0) -#endif -#define ADDI(dest,src,imm) IMMOP(ADD, (dest), (src), (imm)) -#define SUBI(dest,src,imm) IMMOP(ADD, (dest), (src), -(imm)) -#define ANDI(dest,src,imm) IMMOP(AND, (dest), (src), (imm)) -#define ORI(dest,src,imm) IMMOP(OR, (dest), (src), (imm)) -#define XORI(dest,src,imm) IMMOP(XOR, (dest), (src), (imm)) -#define SLLI(dest,src,imm) IMMOP(SLL, (dest), (src), (imm)) -#define SRLI(dest,src,imm) IMMOP(SRL, (dest), (src), (imm)) -#define SRAI(dest,src,imm) IMMOP(SRA, (dest), (src), (imm)) -#define RORI(dest,src,imm) IMMOP(ROR, (dest), (src), (imm)) -#define SLTUI(dest,src,imm) IMMOP(SLTU, (dest), (src), (imm)) -#define SLTSI(dest,src,imm) IMMOP(SLTS, (dest), (src), (imm)) - -/*----------------------------------*/ - -/* Bitfield instructions */ - -#ifdef JIT_USE_RTL_BITFIELDS -# define BFOP(op,dest,src1,src2,start,count) \ - APPEND(BF##op, (dest), (src1), (src2), (start) | (count)<<8) -# define BFEXT(dest,src,start,count) \ - BFOP(EXT, (dest), (src), 0, (start), (count)) -# define BFINS(dest,src1,src2,start,count) \ - BFOP(INS, (dest), (src1), (src2), (start), (count)) -#else -# define BFEXT(dest,src,start,count) do { \ - const uint32_t __dest = (dest); \ - const uint32_t __src = (src); \ - const int __start = (start); \ - const int __count = (count); \ - if (__start == 0) { \ - if (__count == 32) { \ - MOVE(__dest, __src); \ - } else { \ - ANDI(__dest, __src, (1U<<__count) - 1); \ - } \ - } else if (__start + __count == 32) { \ - SRLI(__dest, __src, __start); \ - } else { \ - DEFINE_REG(__temp); \ - SRLI(__temp, __src, (start)); \ - ANDI(__dest, __temp, (1U<<__count) - 1); \ - } \ -} while (0) -# define BFINS(dest,src1,src2,start,count) do { \ - const uint32_t __dest = (dest); \ - const uint32_t __src1 = (src1); \ - const uint32_t __src2 = (src2); \ - const int __start = (start); \ - const int __count = (count); \ - if (__start == 0 && __count == 32) { \ - MOVE(__dest, __src2); \ - } else { \ - const uint32_t __mask = (1U<<__count) - 1; \ - DEFINE_REG(__out2); \ - if (__start == 0) { \ - ANDI(__out2, __src2, __mask); \ - } else { \ - DEFINE_REG(__temp); \ - ANDI(__temp, __src2, __mask); \ - SLLI(__out2, __temp, __start); \ - } \ - DEFINE_REG(__out1); \ - ANDI(__out1, __src1, ~(__mask << __start)); \ - OR(__dest, __out1, __out2); \ - } \ -} while (0) -#endif - -/*----------------------------------*/ - -/* Variants of SLT */ - -#define SEQZ(dest,src) SLTUI((dest), (src), 1) -#define SLTZ(dest,src) SLTSI((dest), (src), 0) - -/*----------------------------------*/ - -/* Load from or store to memory */ - -#define LOAD_BU(dest,address,offset) \ - APPEND(LOAD_BU, (dest), (address), 0, (offset)) -#define LOAD_BS(dest,address,offset) \ - APPEND(LOAD_BS, (dest), (address), 0, (offset)) -#define LOAD_HU(dest,address,offset) \ - APPEND(LOAD_HU, (dest), (address), 0, (offset)) -#define LOAD_HS(dest,address,offset) \ - APPEND(LOAD_HS, (dest), (address), 0, (offset)) -#define LOAD_W(dest,address,offset) \ - APPEND(LOAD_W, (dest), (address), 0, (offset)) -#define LOAD_PTR(dest,address,offset) \ - APPEND(LOAD_PTR, (dest), (address), 0, (offset)) -#define STORE_B(address,src,offset) \ - APPEND(STORE_B, (address), (src), 0, (offset)) -#define STORE_H(address,src,offset) \ - APPEND(STORE_H, (address), (src), 0, (offset)) -#define STORE_W(address,src,offset) \ - APPEND(STORE_W, (address), (src), 0, (offset)) -#define STORE_PTR(address,src,offset) \ - APPEND(STORE_PTR, (address), (src), 0, (offset)) - -/*----------------------------------*/ - -/* Load from, store to, or add constants to state block fields */ - -/* Loads */ - -#define LOAD_STATE(reg,field) \ - ASSERT(__LOAD_STATE(entry, state_reg, (reg), offsetof(SH2State,field))) -static inline int __LOAD_STATE(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t reg, const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0) { - if (state_cache[index].rtlreg) { - if (reg == state_cache[index].rtlreg) { - if (state_cache[index].offset) { - ADDI(state_cache[index].rtlreg, state_cache[index].rtlreg, - state_cache[index].offset); - if (index == 15 && stack_pointer) { - ADDI(stack_pointer, stack_pointer, - state_cache[index].offset); - } - state_cache[index].offset = 0; - } - } else { - if (state_cache[index].offset) { - ADDI(reg, state_cache[index].rtlreg, - state_cache[index].offset); - } else { - MOVE(reg, state_cache[index].rtlreg); - } - } - } else { - LOAD_W(reg, state_reg, offset); - } - if (!state_cache[index].fixed - && !(index == 15 && (optimization_flags & SH2_OPTIMIZE_STACK) - && state_cache[index].rtlreg != 0) - ) { - state_cache[index].rtlreg = reg; - state_cache[index].offset = 0; - } - if (index < 16) { - /* We changed the stored value, so we have to generate a new - * direct pointer on the next access. */ - pointer_status[index].rtl_ptrreg = 0; - } - return 1; - } -#endif - LOAD_W(reg, state_reg, offset); - return 1; -} - -/* Load from a state block field, but don't change the state block cache */ -#define LOAD_STATE_COPY(reg,field) \ - ASSERT(__LOAD_STATE_COPY(entry, state_reg, (reg), offsetof(SH2State,field))) -static inline int __LOAD_STATE_COPY(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t reg, const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0 && state_cache[index].rtlreg) { - PRECOND(reg != state_cache[index].rtlreg, return 0); - if (state_cache[index].offset) { - ADDI(reg, state_cache[index].rtlreg, state_cache[index].offset); - } else { - MOVE(reg, state_cache[index].rtlreg); - } - return 1; - } -#endif - LOAD_W(reg, state_reg, offset); - return 1; -} - -/* Allocate a new register and load it from the state block, or reuse an - * old register if appropriate and if the register is not offsetted. Note - * that a register obtained from this macro MUST NOT be reassigned, since - * it may be shared; if reassignment is necessary, use DEFINE_REG() and - * LOAD_STATE() instead. (The MAC.* instructions are exceptions to this - * rule, since all other users of MACH/MACL use LOAD_STATE_COPY() to avoid - * aliasing the register.) */ -#define LOAD_STATE_ALLOC(reg,field) \ - ASSERT(reg = __LOAD_STATE_ALLOC(entry, state_reg, \ - offsetof(SH2State,field))) -static inline uint32_t __LOAD_STATE_ALLOC(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0 && state_cache[index].rtlreg != 0) { - if (state_cache[index].offset == 0) { - return state_cache[index].rtlreg; - } else if (state_cache[index].fixed) { - ADDI(state_cache[index].rtlreg, state_cache[index].rtlreg, - state_cache[index].offset); - if (index == 15 && stack_pointer) { - ADDI(stack_pointer, stack_pointer, state_cache[index].offset); - } - state_cache[index].offset = 0; - return state_cache[index].rtlreg; - } - } -#endif - DEFINE_REG(reg); - ASSERT(__LOAD_STATE(entry, state_reg, reg, offset)); - return reg; -} - -/* Allocate a new register and load it from the state block, or reuse an - * old register (leaving any offset in the cache) if appropriate. As with - * LOAD_STATE_ALLOC(), a register obtained from this macro MUST NOT be - * reassigned. */ -#define LOAD_STATE_ALLOC_KEEPOFS(reg,field) \ - ASSERT(reg = __LOAD_STATE_ALLOC_KEEPOFS(entry, state_reg, \ - offsetof(SH2State,field))) -static inline uint32_t __LOAD_STATE_ALLOC_KEEPOFS(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0 && state_cache[index].rtlreg != 0) { - return state_cache[index].rtlreg; - } -#endif - DEFINE_REG(reg); - ASSERT(__LOAD_STATE(entry, state_reg, reg, offset)); - return reg; -} - -#define LOAD_STATE_PTR(reg,field) \ - LOAD_PTR((reg), state_reg, offsetof(SH2State,field)) - -#define LOAD_STATE_SR_T(reg) \ - ASSERT(reg = __LOAD_STATE_SR_T(entry, state_reg)) -static inline uint32_t __LOAD_STATE_SR_T(const JitEntry * const entry, - const uint32_t state_reg) -{ -#ifdef OPTIMIZE_STATE_BLOCK - if (cached_SR_T) { - return cached_SR_T; - } -#endif - DECLARE_REG(temp); - LOAD_STATE_ALLOC(temp, SR); - DEFINE_REG(reg); - ANDI(reg, temp, SR_T); -#ifdef OPTIMIZE_STATE_BLOCK - cached_SR_T = reg; -#endif - return reg; -} - -/* Stores */ - -#define STORE_STATE(field,reg) \ - ASSERT(__STORE_STATE(entry, state_reg, offsetof(SH2State,field), (reg))) -static inline int __STORE_STATE(const JitEntry * const entry, - const uint32_t state_reg, - const uint16_t offset, const uint32_t reg) -{ - if (offset == offsetof(SH2State,R[15]) - && (optimization_flags & SH2_OPTIMIZE_STACK) - ) { -#ifdef JIT_DEBUG_VERBOSE - if (pointer_status[15].known) { - DMSG("WARNING: Reassigning stack pointer in OPTIMIZE_STACK mode"); - } -#endif - DEFINE_REG(page); - SRLI(page, reg, 19); - DEFINE_REG(pageofs); - SLLI(pageofs, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, pageofs); - if (!pointer_status[15].known) { - DEFINE_REG(base); - pointer_status[15].known = 1; - pointer_status[15].type = 2; - pointer_status[15].data_only = 1; - pointer_status[15].rtl_basereg = base; - pointer_status[15].rtl_ptrreg = 0; // stack_pointer is used instead - DEFINE_REG(new_sp); - stack_pointer = new_sp; - } - PRECOND(pointer_status[15].rtl_basereg != 0, return 0); - LOAD_PTR(pointer_status[15].rtl_basereg, dp_ptr, - ADDR_LO(direct_pages)); - PRECOND(stack_pointer != 0, return 0); - ADD(stack_pointer, pointer_status[15].rtl_basereg, reg); - } -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0) { - if (state_cache[index].fixed) { - if (reg != state_cache[index].rtlreg) { - MOVE(state_cache[index].rtlreg, reg); - } - } else { - state_cache[index].rtlreg = reg; - } - if (index < 16) { - pointer_status[index].rtl_ptrreg = 0; - } - state_cache[index].offset = 0; - if (index == state_cache_index(offsetof(SH2State,PC))) { - cached_PC = 0; - stored_PC = 0; - } - state_dirty |= 1 << index; -# ifdef TRACE_STEALTH - if (index < 23) { - APPEND(NOP, 0, 0xB0000000 | index<<16 | state_cache[index].rtlreg, - 0, 0); - } -# endif - return 1; - } -#endif - STORE_W(state_reg, reg, offset); - return 1; -} - -#define STORE_STATE_PC(value) \ - ASSERT(__STORE_STATE_PC(entry, state_reg, (value))) -static inline int __STORE_STATE_PC(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t value) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index_PC = state_cache_index(offsetof(SH2State,PC)); - if (!state_cache[index_PC].fixed && value != 0) { - if (stored_PC == value) { - /* state->PC is already correct, so just clear the cache */ - if (state_cache[index_PC].rtlreg) { -# ifdef TRACE_STEALTH - APPEND(NOP, 0, 0xB0000000 | index_PC<<16, 0, 0); -# endif - } - cached_PC = 0; - state_cache[index_PC].rtlreg = 0; - state_dirty &= ~(1<> 16), 0, 0); - APPEND(NOP, 0, 0xBC000000 | index_PC<<16 | (value & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xB0000000 | index_PC<<16, 0, 0); -# endif - cached_PC = value; - state_dirty |= 1<= 0 - && (state_cache[index].rtlreg || !state_cache[index].fixed) - ) { - if (!state_cache[index].rtlreg) { - DEFINE_REG(rtlreg); - LOAD_W(rtlreg, state_reg, offset); - state_cache[index].rtlreg = rtlreg; - state_cache[index].offset = 0; - } - const int32_t new_offset = (int32_t)state_cache[index].offset + imm; - if ((uint32_t)(new_offset + 0x8000) < 0x10000) { - state_cache[index].offset = new_offset; - } else { - if (state_cache[index].fixed) { - ADDI(state_cache[index].rtlreg, state_cache[index].rtlreg, - new_offset); - } else { - DEFINE_REG(newreg); - ADDI(newreg, state_cache[index].rtlreg, new_offset); - state_cache[index].rtlreg = newreg; - if (index < 16) { - pointer_status[index].rtl_ptrreg = 0; - } - } - state_cache[index].offset = 0; - } - state_dirty |= 1 << index; -# ifdef TRACE_STEALTH - if (index < 23) { - uint32_t temp = state_cache[index].offset; - APPEND(NOP, 0, 0xB8000000 | index<<16 | (temp>>16 & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xBC000000 | index<<16 | (temp>> 0 & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xB0000000 | index<<16 | state_cache[index].rtlreg, - 0, 0); - } -# endif - return 1; - } -#endif - if (!cur_reg) { - ASSERT(cur_reg = __LOAD_STATE_ALLOC(entry, state_reg, offset)); - } - DEFINE_REG(result); - ADDI(result, cur_reg, imm); - STORE_W(state_reg, result, offset); - if (offset == offsetof(SH2State,R[15]) - && (optimization_flags & SH2_OPTIMIZE_STACK) - && stack_pointer - ) { - ADDI(stack_pointer, stack_pointer, imm); - } - return 1; -} - -/*----------------------------------*/ - -/* Execute an SH-2 load or store operation (note that size desginations are - * SH-2 style B[yte]/W[ord]/L[ong] rather than RTL B[yte]/H[alfword]/W[ord], - * and all 8- and 16-bit loads are signed) */ - -#define SH2_LOAD_B(dest,address) \ - do_load(entry, (dest), (address), SH2_ACCESS_TYPE_B) -#define SH2_LOAD_W(dest,address) \ - do_load(entry, (dest), (address), SH2_ACCESS_TYPE_W) -#define SH2_LOAD_L(dest,address) \ - do_load(entry, (dest), (address), SH2_ACCESS_TYPE_L) -#define SH2_STORE_B(address,src) \ - do_store(entry, (address), (src), SH2_ACCESS_TYPE_B, state_reg) -#define SH2_STORE_W(address,src) \ - do_store(entry, (address), (src), SH2_ACCESS_TYPE_W, state_reg) -#define SH2_STORE_L(address,src) \ - do_store(entry, (address), (src), SH2_ACCESS_TYPE_L, state_reg) - -/*----------------------------------*/ - -/* Execute an SH-2 load or store to a known address */ - -#define SH2_LOAD_ABS_B(dest,address) \ - do_load_abs(entry, (dest), (address), SH2_ACCESS_TYPE_B) -#define SH2_LOAD_ABS_W(dest,address) \ - do_load_abs(entry, (dest), (address), SH2_ACCESS_TYPE_W) -#define SH2_LOAD_ABS_L(dest,address) \ - do_load_abs(entry, (dest), (address), SH2_ACCESS_TYPE_L) -#define SH2_STORE_ABS_B(address,src,islocal) \ - do_store_abs(entry, (address), (src), SH2_ACCESS_TYPE_B, state_reg, \ - (islocal)) -#define SH2_STORE_ABS_W(address,src,islocal) \ - do_store_abs(entry, (address), (src), SH2_ACCESS_TYPE_W, state_reg, \ - (islocal)) -#define SH2_STORE_ABS_L(address,src,islocal) \ - do_store_abs(entry, (address), (src), SH2_ACCESS_TYPE_L, state_reg, \ - (islocal)) - -/*----------------------------------*/ - -/* Execute an SH-2 load or store through an SH-2 register */ - -#define SH2_LOAD_REG_B(dest,sh2reg,offset,postinc) \ - do_load_reg(entry, (dest), (sh2reg), (offset), SH2_ACCESS_TYPE_B, \ - (postinc), state, state_reg) -#define SH2_LOAD_REG_W(dest,sh2reg,offset,postinc) \ - do_load_reg(entry, (dest), (sh2reg), (offset), SH2_ACCESS_TYPE_W, \ - (postinc), state, state_reg) -#define SH2_LOAD_REG_L(dest,sh2reg,offset,postinc) \ - do_load_reg(entry, (dest), (sh2reg), (offset), SH2_ACCESS_TYPE_L, \ - (postinc), state, state_reg) -#define SH2_STORE_REG_B(sh2reg,src,offset,predec) \ - do_store_reg(entry, (sh2reg), (src), (offset), SH2_ACCESS_TYPE_B, \ - (predec), state, state_reg) -#define SH2_STORE_REG_W(sh2reg,src,offset,predec) \ - do_store_reg(entry, (sh2reg), (src), (offset), SH2_ACCESS_TYPE_W, \ - (predec), state, state_reg) -#define SH2_STORE_REG_L(sh2reg,src,offset,predec) \ - do_store_reg(entry, (sh2reg), (src), (offset), SH2_ACCESS_TYPE_L, \ - (predec), state, state_reg) - -/*----------------------------------*/ - -/* Branches (within an SH-2 instruction's RTL code) */ - -#define CREATE_LABEL(label) \ - const uint32_t label = rtl_alloc_label(entry->rtl); \ - if (UNLIKELY(!label)) { \ - return 0; \ - } -#define DEFINE_LABEL(label) APPEND(LABEL, 0, 0, 0, (label)) -#define GOTO_LABEL(label) APPEND(GOTO, 0, 0, 0, (label)) -#define GOTO_IF_Z(label,reg) APPEND(GOTO_IF_Z, 0, (reg), 0, (label)) -#define GOTO_IF_NZ(label,reg) APPEND(GOTO_IF_NZ, 0, (reg), 0, (label)) -#define GOTO_IF_E(label,reg1,reg2) \ - APPEND(GOTO_IF_E, 0, (reg1), (reg2), (label)) -#define GOTO_IF_NE(label,reg1,reg2) \ - APPEND(GOTO_IF_NE, 0, (reg1), (reg2), (label)) - -/*----------------------------------*/ - -/* Jumps (to other SH-2 instructions) */ - -#define JUMP_STATIC() \ - ASSERT(branch_static(state, entry, state_reg)) -#define JUMP() RETURN() - -/* Call to a native subroutine */ -#define CALL(result,arg1,arg2,func) \ - APPEND(CALL, (result), (arg1), (arg2), (func)) -#define CALL_NORET(arg1,arg2,func) \ - APPEND(CALL, 0, (arg1), (arg2), (func)) - -/* Return from the current block */ -#define RETURN() APPEND(RETURN, 0, 0, 0, 0) - -/* Chain to a different native routine */ -#define RETURN_TO(addr) APPEND(RETURN_TO, 0, 0, 0, addr) - -/*-----------------------------------------------------------------------*/ - -/* Use global variables for the PC and cycle count; the initial PC can be - * taken from the JitEntry structure */ -#define initial_PC (entry->sh2_start) -#define cur_PC jit_PC - -/* Pre- and post-decode processing is implemented by separate functions - * defined below */ -#define OPCODE_INIT(opcode) \ - ASSERT(opcode_init(state, entry, state_reg, (opcode), recursing)) -#define OPCODE_DONE(opcode) \ - ASSERT(opcode_done(state, entry, state_reg, (opcode), recursing)) - - -/* Need to update both jit_PC and state->PC */ -#define INC_PC() do { \ - jit_PC += 2; \ - STORE_STATE_PC(jit_PC); \ -} while (0) -#ifdef JIT_DEBUG_TRACE -/* Make sure we trace instructions even if eliminated by optimization */ -# define INC_PC_BY(amount) do { \ - const unsigned int __amount = (amount); \ - unsigned int __i; \ - for (__i = 0; __i < __amount; __i += 2) { \ - jit_PC += 2; \ - char tracebuf[100]; \ - const unsigned int __opcode = MappedMemoryReadWord(jit_PC); \ - SH2Disasm(jit_PC, __opcode, 0, tracebuf); \ - fprintf(stderr, "%08X: %04X %s\n", jit_PC, __opcode, tracebuf+12); \ - } \ - STORE_STATE_PC(jit_PC); \ -} while (0) -#else // !JIT_DEBUG_TRACE -# define INC_PC_BY(amount) do { \ - jit_PC += (amount); \ - STORE_STATE_PC(jit_PC); \ -} while (0) -#endif - -/* Return whether the word at "offset" words from the current instruction - * is available for peephole optimization */ -#define INSN_IS_AVAILABLE(offset) \ - (recursing ? !is_last : \ - jit_PC + (offset)*2 <= entry->sh2_end \ - && (word_info[(jit_PC - entry->sh2_start)/2 + (offset)] & WORD_INFO_CODE)\ - && !(is_branch_target[((jit_PC - entry->sh2_start) / 2 + (offset)) / 32] \ - & (1 << (((jit_PC - entry->sh2_start) / 2 + (offset)) % 32)))) - -/*----------------------------------*/ - -/* Return whether the saturation check for MAC can be omitted */ -#define CAN_OMIT_MAC_S_CHECK (can_optimize_mac_nosat) - -/* Get or set whether the MACL/MACH pair is known to be zero */ -#define MAC_IS_ZERO() (state->mac_is_zero) -#define SET_MAC_IS_ZERO() (state->mac_is_zero = 1) -#define CLEAR_MAC_IS_ZERO() (state->mac_is_zero = 0) - -/*----------------------------------*/ - -/* Get, add to, or clear the cached shift count */ -#define CAN_CACHE_SHIFTS() 1 -#define CACHED_SHIFT_COUNT() (state->cached_shift_count) -#define ADD_TO_SHIFT_CACHE(n) (state->cached_shift_count += (n)) -#define CLEAR_SHIFT_CACHE() (state->cached_shift_count = 0) - -/*----------------------------------*/ - -/* Get or set register known bits and values */ -#ifdef OPTIMIZE_KNOWN_VALUES -# define REG_GETKNOWN(reg) reg_knownbits[(reg)] -# define REG_GETVALUE(reg) reg_value[(reg)] -# define REG_SETKNOWN(reg,known) (reg_knownbits[(reg)] = (known)) -# define REG_SETVALUE(reg,value) (reg_value[(reg)] = (value)) -# define REG_RESETKNOWN() do { \ - unsigned int __i; \ - for (__i = 0; __i < lenof(reg_knownbits); __i++) { \ - reg_knownbits[__i] = 0; \ - } \ -} while (0) -#else -# define REG_GETKNOWN(reg) 0 -# define REG_GETVALUE(reg) 0 -# define REG_SETKNOWN(reg,value) /*nothing*/ -# define REG_SETVALUE(reg,value) /*nothing*/ -# define REG_RESETKNOWN() /*nothing*/ -#endif - -/*----------------------------------*/ - -/* Track pointer registers */ - -/* Check or set the local-pointer flag for a GPR (used to skip JIT overwrite - * checks in do_store_abs()); flag is cleared by PTR_CLEAR() */ -#define PTR_ISLOCAL(reg) (pointer_local & 1<<(reg)) -#define PTR_SETLOCAL(reg) do { \ - if (optimization_flags & SH2_OPTIMIZE_LOCAL_POINTERS) { \ - pointer_local |= 1<<(reg); \ - } \ -} while (0) - -/* Mark a GPR as having taken its value from the given local address */ -#define PTR_SET_SOURCE(reg,address) do { \ - if (optimization_flags & SH2_OPTIMIZE_LOCAL_POINTERS) { \ - pointer_status[(reg)].source = (address); \ - } \ -} while (0) - -/* Return whether the given register is a known pointer */ -#define PTR_CHECK(reg) (pointer_status[(reg)].known != 0 \ - || pointer_status[(reg)].rtl_basereg != 0) - -/* Copy pointer status for a MOVE Rm,Rn or ADD Rm,Rn instruction */ -#define PTR_COPY(reg,new,for_add) do { \ - const unsigned int __reg = (reg); \ - const unsigned int __new = (new); \ - pointer_status[__new] = pointer_status[__reg]; \ - if (pointer_status[__reg].known) { \ - pointer_status[__new].known = -1; \ - } \ - if (for_add) { \ - pointer_status[__new].rtl_ptrreg = 0; \ - } \ - if (PTR_ISLOCAL(__reg)) { \ - pointer_local |= 1<<__new; \ - } else { \ - pointer_local &= ~(1<<__new); \ - } \ -} while (0) - -/* Clear pointer status on a register modification */ -#define PTR_CLEAR(reg) do { \ - const unsigned int __reg = (reg); \ - if (__reg != 15 || !(optimization_flags & SH2_OPTIMIZE_STACK)) { \ - pointer_status[__reg].known = 0; \ - pointer_status[__reg].rtl_basereg = 0; \ - pointer_status[__reg].rtl_ptrreg = 0; \ - pointer_status[__reg].source = 0; \ - pointer_local &= ~(1<<__reg); \ - } \ -} while (0) - -/*----------------------------------*/ - -/* Processor state block caching */ - -/* Save the current cache state */ -#define SAVE_STATE_CACHE() do { \ - memcpy(saved_state_cache, state_cache, sizeof(state_cache));\ - saved_state_dirty = state_dirty; \ - saved_cached_SR_T = cached_SR_T; \ - saved_dirty_SR_T = dirty_SR_T; \ - saved_cached_PC = cached_PC; \ - saved_stored_PC = stored_PC; \ -} while (0) - -/* Restore the saved cache state */ -#define RESTORE_STATE_CACHE() do { \ - RESTORE_STATE_CACHE_APPEND_STEALTH_NOPS(); \ - memcpy(state_cache, saved_state_cache, sizeof(state_cache));\ - state_dirty = saved_state_dirty; \ - cached_SR_T = saved_cached_SR_T; \ - dirty_SR_T = saved_dirty_SR_T; \ - cached_PC = saved_cached_PC; \ - stored_PC = saved_stored_PC; \ -} while (0) -#ifdef TRACE_STEALTH -# define RESTORE_STATE_CACHE_APPEND_STEALTH_NOPS() do { \ - unsigned int __i; \ - for (__i = 0; __i < 23; __i++) { \ - if (__i == 22 && saved_cached_PC != 0) { \ - APPEND(NOP, 0, 0xB8160000 | (saved_cached_PC>>16 & 0xFFFF), 0, 0);\ - APPEND(NOP, 0, 0xBC160000 | (saved_cached_PC>> 0 & 0xFFFF), 0, 0);\ - APPEND(NOP, 0, 0xB0160000, 0, 0); \ - } else if ((saved_state_dirty & (1<<__i)) \ - && (!(state_dirty & (1<<__i)) \ - || saved_state_cache[__i].rtlreg != state_cache[__i].rtlreg \ - || saved_state_cache[__i].offset != state_cache[__i].offset) \ - ) { \ - uint32_t __temp = saved_state_cache[__i].offset; \ - if (__temp) { \ - APPEND(NOP, 0, 0xB8000000 | __i<<16 | (__temp>>16 & 0xFFFF), 0, 0); \ - APPEND(NOP, 0, 0xBC000000 | __i<<16 | (__temp>> 0 & 0xFFFF), 0, 0); \ - } \ - APPEND(NOP, 0, 0xB0000000 | __i<<16 | saved_state_cache[__i].rtlreg, 0, 0); \ - } else if (!(saved_state_dirty & (1<<__i)) && (state_dirty & (1<<__i))) { \ - APPEND(NOP, 0, 0xB0000000 | __i<<16, 0, 0); \ - } \ - } \ - if (saved_dirty_SR_T && (!dirty_SR_T || saved_cached_SR_T != cached_SR_T)) { \ - APPEND(NOP, 0, 0xB0900000 | saved_cached_SR_T, 0, 0); \ - } else if (!saved_dirty_SR_T && dirty_SR_T) { \ - APPEND(NOP, 0, 0xB0900000, 0, 0); \ - } \ -} while (0) -#else -# define RESTORE_STATE_CACHE_APPEND_STEALTH_NOPS() /*nothing*/ -#endif - -#ifndef OPTIMIZE_STATE_BLOCK -# undef SAVE_STATE_CACHE -# undef RESTORE_STATE_CACHE -# define SAVE_STATE_CACHE() /*nothing*/ -# define RESTORE_STATE_CACHE() /*nothing*/ -#endif - -/* Write back to the state block any cached, dirty state block values - * (but leave them dirty) */ -#define WRITEBACK_STATE_CACHE() \ - ASSERT(writeback_state_cache(entry, state_reg, 0)); - -/* Flush any cached state block values */ -#define FLUSH_STATE_CACHE() do { \ - ASSERT(writeback_state_cache(entry, state_reg, 1)); \ - clear_state_cache(0); \ -} while (0) - -/* Return the cached offset for the given state block field, or 0 if none */ -#ifdef OPTIMIZE_CONSTANT_ADDS -# define STATE_CACHE_OFFSET(field) \ - (state_cache_index(offsetof(SH2State,field)) >= 0 \ - ? state_cache[state_cache_index(offsetof(SH2State,field))].offset \ - : 0) -#else -# define STATE_CACHE_OFFSET(field) 0 -#endif - -/* Return the fixed RTL register to use for the given state block field, - * or 0 if none */ -#ifdef OPTIMIZE_STATE_BLOCK -# define STATE_CACHE_FIXED_REG(field) \ - (state_cache_index(offsetof(SH2State,field)) >= 0 \ - && state_cache[state_cache_index(offsetof(SH2State,field))].fixed \ - ? state_cache[state_cache_index(offsetof(SH2State,field))].rtlreg \ - : 0) -#else -# define STATE_CACHE_FIXED_REG(field) 0 -#endif - -/* Return whether the given state block field has a fixed RTL register that - * can be modified */ -#ifdef OPTIMIZE_STATE_BLOCK -# define STATE_CACHE_FIXED_REG_WRITABLE(field) \ - (state_cache_index(offsetof(SH2State,field)) >= 0 \ - ? state_cache[state_cache_index(offsetof(SH2State,field))].fixed \ - && state_cache[state_cache_index(offsetof(SH2State,field))].flush \ - : 0) -#else -# define STATE_CACHE_FIXED_REG_WRITABLE(field) 0 -#endif - -/* Clear any fixed RTL register for the given state block field */ -#ifdef OPTIMIZE_STATE_BLOCK -# define STATE_CACHE_CLEAR_FIXED_REG(field) do { \ - if (state_cache_index(offsetof(SH2State,field)) >= 0) { \ - state_cache[state_cache_index(offsetof(SH2State,field))].fixed = 0; \ - state_cache[state_cache_index(offsetof(SH2State,field))].flush = 0; \ - } \ -} while (0) -#else -# define STATE_CACHE_CLEAR_FIXED_REG(field) /*nothing*/ -#endif - -/*----------------------------------*/ - -/* Check the status of a branch instruction */ - -#define BRANCH_FALLS_THROUGH(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_FALLTHRU \ - : 0) -#define BRANCH_TARGETS_RTS(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_BRA_RTS \ - : 0) - -#define BRANCH_IS_THREADED(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_THREADED \ - : 0) - -#define BRANCH_THREAD_TARGET(addr) \ - (branch_thread_target[((addr) - entry->sh2_start) / 2]) - -#define BRANCH_THREAD_COUNT(addr) \ - (branch_thread_count[((addr) - entry->sh2_start) / 2]) - -#define BRANCH_IS_SELECT(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_SELECT \ - : 0) - -#define BRANCH_IS_LOOP_TO_JSR(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_LOOP_JSR \ - : 0) - -#define BRANCH_IS_FOLDABLE_SUBROUTINE(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_FOLDABLE \ - : 0) - -#define BRANCH_FOLD_TARGET(addr) \ - (subroutine_target[((addr) - entry->sh2_start) / 2]) - -#define BRANCH_FOLD_TARGET_FETCH(addr) \ - ((const uint16_t *)((uintptr_t)fetch_pages[(addr) >> 19] + (addr))) - -#define BRANCH_FOLD_NATIVE_FUNC(addr) \ - (subroutine_native[((addr) - entry->sh2_start) / 2]) - -/*************************************************************************/ -/************* Helper functions for SH-2 -> RTL translation **************/ -/*************************************************************************/ - -/** - * do_load_common: Generate code for an SH-2 memory load operation common - * to both generic loads and register loads from variable addresses. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * address: RTL register holding load address - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_*) - * page_ptr: RTL register holding base pointer for memory page or NULL - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load_common(const JitEntry *entry, uint32_t dest, - uint32_t address, int32_t offset, - unsigned int type, uint32_t page_ptr) -{ - CREATE_LABEL(label_fallback); - CREATE_LABEL(label_done); - - DEFINE_REG(final_ptr); // Move this up to help MIPS delay slot optimization - if (offset < -0x8000 || offset > 0x7FFF) { - /* Memory offsets must be within the range [-0x8000,0x7FFF], so if - * we fall outside that range, add the offset to the address - * separately */ - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - offset = 0; - ADD(final_ptr, page_ptr, offset_addr); - } else { - ADD(final_ptr, page_ptr, address); - } - - GOTO_IF_Z(label_fallback, page_ptr); { - /* We can access the data directly */ - // FIXME: all the code here assumes little-endian; this won't work - // if we port to a big-endian machine - switch (type) { - case SH2_ACCESS_TYPE_B: { - DEFINE_REG(real_ptr); - int32_t real_offset; - if (offset & 1) { - /* Can't use an immediate offset because we don't know - * whether the source address is odd, so we can't predict - * the effect of the XOR */ - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, final_ptr, offset); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - XORI(real_ptr, final_ptr, 1); - real_offset = offset; - } - LOAD_BS(dest, real_ptr, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - LOAD_HS(dest, final_ptr, offset); - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - LOAD_W(swapped, final_ptr, offset); - HSWAPW(dest, swapped); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - GOTO_LABEL(label_done); - - } DEFINE_LABEL(label_fallback); { - /* Not direct access, so call the fallback routine */ - DECLARE_REG(real_address); - if (offset) { - ALLOC_REG(real_address); - ADDI(real_address, address, offset); - } else { - real_address = address; - } - DEFINE_REG(fallback); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(fallback, MappedMemoryReadByte); - DEFINE_REG(retval); - CALL(retval, real_address, 0, fallback); - DEFINE_REG(tempdest); - SLLI(tempdest, retval, 24); - SRAI(dest, tempdest, 24); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(fallback, MappedMemoryReadWord); - DEFINE_REG(retval); - CALL(retval, real_address, 0, fallback); - DEFINE_REG(tempdest); - SLLI(tempdest, retval, 16); - SRAI(dest, tempdest, 16); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(fallback, MappedMemoryReadLong); - CALL(dest, real_address, 0, fallback); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } DEFINE_LABEL(label_done); - - return 1; -} - -/*----------------------------------*/ - -/** - * do_load: Generate code for an SH-2 memory load operation. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * address: RTL register holding load address - * type: Access type (SH2_ACCESS_TYPE_*) - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load(const JitEntry *entry, uint32_t dest, uint32_t address, - unsigned int type) -{ - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(temp); - SLLI(temp, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, temp); - DEFINE_REG(page_ptr); - LOAD_PTR(page_ptr, dp_ptr, ADDR_LO(direct_pages)); - - return do_load_common(entry, dest, address, 0, type, page_ptr); -} - -/*----------------------------------*/ - -/** - * do_load_abs: Generate optimized code for an SH-2 memory load operation - * from a known address. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * address: Load address (in SH-2 address space) - * type: Access type (SH2_ACCESS_TYPE_*) - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load_abs(const JitEntry *entry, uint32_t dest, uint32_t address, - unsigned int type) -{ - const uint32_t page = address >> 19; - - if (direct_pages[page]) { - - const uintptr_t real_address = - (uintptr_t)direct_pages[page] + address; - DEFINE_REG(addr_reg); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(addr_reg, ADDR_HI(real_address ^ 1)); - LOAD_BS(dest, addr_reg, ADDR_LO(real_address ^ 1)); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(addr_reg, ADDR_HI(real_address)); - LOAD_HS(dest, addr_reg, ADDR_LO(real_address)); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(addr_reg, ADDR_HI(real_address)); - DEFINE_REG(swapped); - LOAD_W(swapped, addr_reg, ADDR_LO(real_address)); - HSWAPW(dest, swapped); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } else { - - DEFINE_REG(addr_reg); - MOVEA(addr_reg, address); - DEFINE_REG(fallback); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(fallback, MappedMemoryReadByte); - DEFINE_REG(retval); - CALL(retval, addr_reg, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 24); - SRAI(dest, temp, 24); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(fallback, MappedMemoryReadWord); - DEFINE_REG(retval); - CALL(retval, addr_reg, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 16); - SRAI(dest, temp, 16); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(fallback, MappedMemoryReadLong); - CALL(dest, addr_reg, 0, fallback); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } - - return 1; -} - -/*----------------------------------*/ - -/** - * do_load_reg: Generate optimized code for an SH-2 memory load operation - * through an SH-2 register. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * sh2reg: SH-2 register holding load address (0-15) - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_*) - * postinc: Nonzero if a postincrement access, else zero - * state: SH-2 state block pointer - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load_reg(const JitEntry *entry, uint32_t dest, - unsigned int sh2reg, int32_t offset, unsigned int type, - int postinc, const SH2State *state, - uint32_t state_reg) -{ - const int postinc_size = - !postinc ? 0 : - type==SH2_ACCESS_TYPE_L ? 4 : type==SH2_ACCESS_TYPE_W ? 2 : 1; - -#ifdef OPTIMIZE_STATE_BLOCK - offset += state_cache[state_cache_index(offsetof(SH2State,R[sh2reg]))].offset; -#endif - - if (!pointer_status[sh2reg].known && pointer_status[sh2reg].source != 0) { - const uint32_t address = - MappedMemoryReadLong(pointer_status[sh2reg].source); - pointer_status[sh2reg].known = -1; // Only tentatively known - pointer_status[sh2reg].data_only = 0; - if ((address & 0xDFF00000) == 0x00200000 - || (address & 0xDE000000) == 0x06000000 - ) { - pointer_status[sh2reg].type = 2; - DEFINE_REG(basereg); - MOVEA(basereg, direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else if ((address & 0xDFF80000) == 0x05C00000 - || (address & 0xDFF00000) == 0x05E00000 - ) { - pointer_status[sh2reg].type = 1; - DEFINE_REG(basereg); - MOVEA(basereg, byte_direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else { - pointer_status[sh2reg].rtl_basereg = 0; - } - pointer_status[sh2reg].rtl_ptrreg = 0; - } - - if (pointer_status[sh2reg].known) { - - DECLARE_REG(address); - LOAD_STATE_ALLOC_KEEPOFS(address, R[sh2reg]); - - if (pointer_status[sh2reg].rtl_basereg) { - - DECLARE_REG(ptr); - if (sh2reg == 15 && stack_pointer) { - if (offset < -0x8000 || offset > 0x7FFF) { - ALLOC_REG(ptr); - ADDI(ptr, stack_pointer, offset); - offset = 0; - } else { - ptr = stack_pointer; - } - } else { - if (offset < -0x8000 || offset > 0x7FFF) { - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - offset = 0; - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, offset_addr); - } else if (pointer_status[sh2reg].rtl_ptrreg) { - ptr = pointer_status[sh2reg].rtl_ptrreg; - } else { - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, address); - pointer_status[sh2reg].rtl_ptrreg = ptr; - } - } - switch (type) { - case SH2_ACCESS_TYPE_B: { - DECLARE_REG(real_ptr); - int32_t real_offset; - if (sh2reg == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)){ - /* Assume the stack is 32-bit aligned, so we can apply - * the XOR directly to the offset */ - real_ptr = ptr; - real_offset = offset ^ 1; - } else if (pointer_status[sh2reg].type == 1) { - /* No need to modify address for byte-ordered memory */ - real_ptr = ptr; - real_offset = offset; - } else if (offset & 1) { - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, ptr, offset); - ALLOC_REG(real_ptr); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - ALLOC_REG(real_ptr); - XORI(real_ptr, ptr, 1); - real_offset = offset; - } - LOAD_BS(dest, real_ptr, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - if (pointer_status[sh2reg].type == 1) { - DEFINE_REG(swapped); - LOAD_HU(swapped, ptr, offset); - DEFINE_REG(temp); - BSWAPH(temp, swapped); - DEFINE_REG(temp2); - SLLI(temp2, temp, 16); - SRAI(dest, temp2, 16); - } else { - LOAD_HS(dest, ptr, offset); - } - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - LOAD_W(swapped, ptr, offset); - if (pointer_status[sh2reg].type == 1) { - BSWAPW(dest, swapped); - } else { - HSWAPW(dest, swapped); - } - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } else { // !pointer_status[sh2reg].rtl_basereg - - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - DEFINE_REG(fallback); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(fallback, MappedMemoryReadByte); - DEFINE_REG(retval); - CALL(retval, offset_addr, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 24); - SRAI(dest, temp, 24); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(fallback, MappedMemoryReadWord); - DEFINE_REG(retval); - CALL(retval, offset_addr, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 16); - SRAI(dest, temp, 16); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(fallback, MappedMemoryReadLong); - CALL(dest, offset_addr, 0, fallback); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } // if (pointer_status[sh2reg].rtl_basereg) - - } else { // !pointer_status[sh2reg].known - - DECLARE_REG(address); - LOAD_STATE_ALLOC_KEEPOFS(address, R[sh2reg]); - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - if (!pointer_status[sh2reg].rtl_basereg) { - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(basereg); - LOAD_PTR(basereg, dp_ptr, ADDR_LO(direct_pages)); - pointer_status[sh2reg].rtl_basereg = basereg; - pointer_status[sh2reg].rtl_ptrreg = 0; - pointer_status[sh2reg].checked_djp = 0; - } - ASSERT(do_load_common(entry, dest, address, offset, type, - pointer_status[sh2reg].rtl_basereg)); - } else { - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - ASSERT(do_load(entry, dest, offset_addr, type)); - } - - } - - if (postinc_size) { - ADDI_STATE_NOREG(R[sh2reg], postinc_size); - } - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * log_store: Helper function for do_store() and friends to log a store - * operation. Does nothing if no relevant tracing option is enabled. - * - * [Parameters] - * entry: Block being translated - * address: Register holding SH-2 store address, or store address itself - * src: Register holding value to store - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * is_abs: Nonzero if "address" is the actual store address - * [Return value] - * Nonzero on success, zero on error - */ -static inline int log_store(const JitEntry *entry, uint32_t address, - uint32_t src, int32_t offset, int type, int abs) -{ -#if defined(TRACE) - - static SH2TraceAccessCallback ** const logfunc_ptrs[] = { - [SH2_ACCESS_TYPE_B] = &trace_storeb_callback, - [SH2_ACCESS_TYPE_W] = &trace_storew_callback, - [SH2_ACCESS_TYPE_L] = &trace_storel_callback, - }; - DEFINE_REG(funcptr); - DECLARE_REG(addr_param); - if (abs) { - ALLOC_REG(addr_param); - MOVEI(addr_param, address + offset); - } else if (offset) { - ALLOC_REG(addr_param); - ADDI(addr_param, address, offset); - } else { - addr_param = address; - } - MOVEA(funcptr, *logfunc_ptrs[type]); - CALL_NORET(addr_param, src, funcptr); - -#elif defined(TRACE_STEALTH) - - static const unsigned int storecode[] = { - [SH2_ACCESS_TYPE_B] = 1, - [SH2_ACCESS_TYPE_W] = 2, - [SH2_ACCESS_TYPE_L] = 4, - }; - APPEND(NOP, 0, 0xC0000000 | storecode[type], 0, 0); - if (abs) { - address += offset; - APPEND(NOP, 0, 0xD8000000 | ((address >> 16) & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xDC000000 | (address & 0xFFFF), 0, 0); - } else { - APPEND(NOP, 0, 0xD0000000 | address, 0, 0); - APPEND(NOP, 0, 0xD4000000 | ((offset >> 16) & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xD6000000 | (offset & 0xFFFF), 0, 0); - } - APPEND(NOP, 0, 0xE0000000 | src, 0, 0); - -#endif - - return 1; -} - -/*----------------------------------*/ - -/** - * do_store_common: Generate code for an SH-2 memory store operation common - * to both generic loads and register loads from variable addresses. - * - * [Parameters] - * entry: Block being translated - * address: RTL register holding store address - * src: RTL register holding value to be stored - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * state_reg: RTL register holding state block pointer - * page_ptr: RTL register holding base pointer for memory page or NULL - * djppage_ptr: RTL register holding base pointer for JIT flag table, or - * zero to skip JIT write check - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store_common(const JitEntry *entry, uint32_t address, - uint32_t src, int32_t offset, unsigned int type, - uint32_t state_reg, uint32_t page_ptr, - uint32_t djppage_ptr) -{ - CREATE_LABEL(label_fallback); - CREATE_LABEL(label_done); - - DEFINE_REG(final_ptr); // Move this up to help MIPS delay slot optimization - int32_t final_offset; - if (offset < -0x8000 || offset > 0x7FFF) { - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - ADD(final_ptr, page_ptr, offset_addr); - final_offset = 0; - } else { - ADD(final_ptr, page_ptr, address); - final_offset = offset; - } - - GOTO_IF_Z(label_fallback, page_ptr); { - /* We can write data directly */ - - switch (type) { - case SH2_ACCESS_TYPE_B: { - DEFINE_REG(real_ptr); - int32_t real_offset; - if (final_offset & 1) { - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, final_ptr, final_offset); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - XORI(real_ptr, final_ptr, 1); - real_offset = final_offset; - } - STORE_B(real_ptr, src, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - STORE_H(final_ptr, src, final_offset); - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - HSWAPW(swapped, src); - STORE_W(final_ptr, swapped, final_offset); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - /* Check for modified translations and clear if needed */ - if (djppage_ptr) { - /* Look up the appropriate byte in the table */ - DEFINE_REG(byteofs); - SRLI(byteofs, address, JIT_PAGE_BITS); - DEFINE_REG(byteaddr); - ADD(byteaddr, djppage_ptr, byteofs); - DEFINE_REG(test); - LOAD_BU(test, byteaddr, 0); - /* Does the JIT page contain translations? */ - GOTO_IF_Z(label_done, test); { - /* Clear translations from the JIT page */ - DEFINE_REG(jcw_ptr); - MOVEA(jcw_ptr, jit_clear_write); - CALL_NORET(state_reg, address, jcw_ptr); - } DEFINE_LABEL(label_done); - } - - } DEFINE_LABEL(label_fallback); { - /* Not direct access, so call the fallback routine */ - - DECLARE_REG(real_address); - if (final_offset) { - ALLOC_REG(real_address); - ADDI(real_address, address, final_offset); - } else { - real_address = address; - } - void *funcptr; - switch (type) { - case SH2_ACCESS_TYPE_B: funcptr = MappedMemoryWriteByte; break; - case SH2_ACCESS_TYPE_W: funcptr = MappedMemoryWriteWord; break; - case SH2_ACCESS_TYPE_L: funcptr = MappedMemoryWriteLong; break; - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - DEFINE_REG(fallback); - MOVEA(fallback, funcptr); - CALL_NORET(real_address, src, fallback); - /* No need to check translations if not direct-access */ - - } DEFINE_LABEL(label_done); - - return 1; -} - -/*----------------------------------*/ - -/** - * do_store: Generate code for an SH-2 memory store operation. - * - * [Parameters] - * entry: Block being translated - * address: RTL register holding store address - * src: RTL register holding value to be stored - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store(const JitEntry *entry, uint32_t address, uint32_t src, - unsigned int type, uint32_t state_reg) -{ - CREATE_LABEL(label_fallback); - CREATE_LABEL(label_done); - - /* Log the store if appropriate */ - log_store(entry, address, src, 0, type, 0); - - /* Look up the direct access pointer */ - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(page_ptr_temp); - LOAD_PTR(page_ptr_temp, dp_ptr, ADDR_LO(direct_pages)); - /* Also check direct_jit_pages[] to make sure it's writable */ - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, table_offset); - DEFINE_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - /* Select to zero if the direct_jit_pages[] entry is zero */ - DEFINE_REG(page_ptr); - SELECT(page_ptr, page_ptr_temp, djppage_ptr, djppage_ptr); - - /* Actually perform the store */ - return do_store_common(entry, address, src, 0, type, state_reg, - page_ptr, djppage_ptr); -} - -/*----------------------------------*/ - -/** - * do_store_abs: Generate optimized code for an SH-2 memory store - * operation to a known address. - * - * [Parameters] - * entry: Block being translated - * address: Store address - * src: RTL register holding value to be stored - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * state_reg: RTL register holding state block pointer - * islocal: Nonzero if the address points to local data, else zero - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store_abs(const JitEntry *entry, uint32_t address, uint32_t src, - unsigned int type, uint32_t state_reg, int islocal) -{ - if (!(optimization_flags & SH2_OPTIMIZE_LOCAL_ACCESSES)) { - islocal = 0; // Prevent optimization - } - - log_store(entry, address, src, 0, type, 1); - - const uint32_t page = address >> 19; - - if ((address & 0x1FF00000) != 0 && direct_pages[page]) { - - const uintptr_t real_address = - (uintptr_t)direct_pages[page] + address; - DEFINE_REG(addr_reg); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(addr_reg, ADDR_HI(real_address ^ 1)); - STORE_B(addr_reg, src, ADDR_LO(real_address ^ 1)); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(addr_reg, ADDR_HI(real_address)); - STORE_H(addr_reg, src, ADDR_LO(real_address)); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(addr_reg, ADDR_HI(real_address)); - DEFINE_REG(swapped); - HSWAPW(swapped, src); - STORE_W(addr_reg, swapped, ADDR_LO(real_address)); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } -#ifdef JIT_DEBUG_VERBOSE - if (islocal) { - fprintf(stderr, "[OLA] %08X: store to local address 0x%08X\n", - jit_PC, address); - } -#endif - if (!islocal && direct_jit_pages[page]) { - CREATE_LABEL(label_done); - /* Look up the appropriate bit in the direct_jit_pages table */ - const uintptr_t byteaddr_val = (uintptr_t)direct_jit_pages[page] - + (address >> JIT_PAGE_BITS); - DEFINE_REG(byteaddr); - MOVEA(byteaddr, ADDR_HI(byteaddr_val)); - DEFINE_REG(test); - LOAD_BU(test, byteaddr, ADDR_LO(byteaddr_val)); - /* Does the JIT page contain translations? */ - GOTO_IF_Z(label_done, test); { - /* Clear translations from the JIT page */ - DEFINE_REG(sh2_addr_reg); - MOVEI(sh2_addr_reg, address); - DEFINE_REG(jcw_ptr); - MOVEA(jcw_ptr, jit_clear_write); - CALL_NORET(state_reg, sh2_addr_reg, jcw_ptr); - } DEFINE_LABEL(label_done); - } - - } else { - - void *funcptr; - switch (type) { - case SH2_ACCESS_TYPE_B: funcptr = MappedMemoryWriteByte; break; - case SH2_ACCESS_TYPE_W: funcptr = MappedMemoryWriteWord; break; - case SH2_ACCESS_TYPE_L: funcptr = MappedMemoryWriteLong; break; - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - DEFINE_REG(addr_reg); - MOVEI(addr_reg, address); - DEFINE_REG(fallback); - MOVEA(fallback, funcptr); - CALL_NORET(addr_reg, src, fallback); - - } - - return 1; -} - -/*----------------------------------*/ - -/** - * do_store_reg: Generate optimized code for an SH-2 memory store - * operation through an SH-2 register. - * - * [Parameters] - * entry: Block being translated - * sh2reg: SH-2 register holding store address - * src: RTL register holding value to be stored - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * predec: Nonzero if a predecrement access, else zero - * state: SH-2 state block pointer - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store_reg(const JitEntry *entry, unsigned int sh2reg, - uint32_t src, int32_t offset, unsigned int type, - int predec, const SH2State *state, uint32_t state_reg) -{ - /* Half of a JIT page, in bytes (used when deciding whether to perform - * a check for overwrites of translated code) */ - const int32_t half_jit_page = (1U << JIT_PAGE_BITS) / 2; - - const int predec_size = - !predec ? 0 : - type==SH2_ACCESS_TYPE_L ? 4 : - type==SH2_ACCESS_TYPE_W ? 2 : 1; - if (predec_size) { - ADDI_STATE_NOREG(R[sh2reg], -predec_size); - } - -#ifdef OPTIMIZE_STATE_BLOCK - offset += state_cache[state_cache_index(offsetof(SH2State,R[sh2reg]))].offset; -#endif - - if (!pointer_status[sh2reg].known && pointer_status[sh2reg].source != 0) { - const uint32_t address = - MappedMemoryReadLong(pointer_status[sh2reg].source); - pointer_status[sh2reg].known = -1; // Only tentatively known - pointer_status[sh2reg].data_only = 0; - pointer_status[sh2reg].checked = 0; - if ((address & 0xDFF00000) == 0x00200000 - || (address & 0xDE000000) == 0x06000000 - ) { - pointer_status[sh2reg].type = 2; - DEFINE_REG(basereg); - MOVEA(basereg, direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else if ((address & 0xDFF80000) == 0x05C00000 - || (address & 0xDFF00000) == 0x05E00000 - ) { - pointer_status[sh2reg].type = 1; - DEFINE_REG(basereg); - MOVEA(basereg, byte_direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else { - pointer_status[sh2reg].rtl_basereg = 0; - } - pointer_status[sh2reg].rtl_ptrreg = 0; - } - - DECLARE_REG(address); - LOAD_STATE_ALLOC_KEEPOFS(address, R[sh2reg]); - - if (pointer_status[sh2reg].known) { - - log_store(entry, address, src, offset, type, 0); - - if (pointer_status[sh2reg].rtl_basereg) { - - DECLARE_REG(ptr); - int32_t ptr_offset; - if (sh2reg == 15 && stack_pointer) { - if (offset < -0x8000 || offset > 0x7FFF) { - ALLOC_REG(ptr); - ADDI(ptr, stack_pointer, offset); - ptr_offset = 0; - } else { - ptr_offset = offset; - ptr = stack_pointer; - } - } else { - if (offset < -0x8000 || offset > 0x7FFF) { - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - ptr_offset = 0; - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, offset_addr); - } else { - ptr_offset = offset; - if (pointer_status[sh2reg].rtl_ptrreg) { - ptr = pointer_status[sh2reg].rtl_ptrreg; - } else { - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, address); - pointer_status[sh2reg].rtl_ptrreg = ptr; - } - } - } - switch (type) { - case SH2_ACCESS_TYPE_B: { - DECLARE_REG(real_ptr); - int32_t real_offset; - if (sh2reg == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)){ - real_ptr = ptr; - real_offset = ptr_offset ^ 1; - } else if (pointer_status[sh2reg].type == 1) { - real_ptr = ptr; - real_offset = ptr_offset; - } else if (offset & 1) { - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, ptr, ptr_offset); - ALLOC_REG(real_ptr); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - ALLOC_REG(real_ptr); - XORI(real_ptr, ptr, 1); - real_offset = ptr_offset; - } - STORE_B(real_ptr, src, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - if (pointer_status[sh2reg].type == 1) { - DEFINE_REG(swapped); - BSWAPH(swapped, src); - STORE_H(ptr, swapped, ptr_offset); - } else { - STORE_H(ptr, src, ptr_offset); - } - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - if (pointer_status[sh2reg].type == 1) { - BSWAPW(swapped, src); - } else { - HSWAPW(swapped, src); - } - STORE_W(ptr, swapped, ptr_offset); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - /* See if we need to check for overwrites of translated code */ - int need_jit_check = 1; - if (sh2reg == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)) { - need_jit_check = 0; - } else if (pointer_status[sh2reg].data_only) { - need_jit_check = 0; - } else if (pointer_status[sh2reg].type != 2) { - need_jit_check = 0; - } else if (pointer_status[sh2reg].checked - && offset - pointer_status[sh2reg].check_offset > -half_jit_page - && offset - pointer_status[sh2reg].check_offset < half_jit_page - ) { - need_jit_check = 0; - } - - if (need_jit_check) { - /* Obtain the address for checking. If the store offset is - * small, use an offset of zero for checking to save an - * instruction */ - DECLARE_REG(jit_address); - int32_t jit_offset; - if (offset > -half_jit_page && offset < half_jit_page) { - jit_address = address; - jit_offset = 0; - } else { - ALLOC_REG(jit_address); - ADDI(jit_address, address, offset); - jit_offset = offset; - } - /* Load the JIT bitmap address */ - CREATE_LABEL(label_done); - DEFINE_REG(djppage_ptr); - int djppage_ofs; - if (pointer_status[sh2reg].known > 0) { - MOVEA(djppage_ptr, - ADDR_HI(pointer_status[sh2reg].djp_base)); - djppage_ofs = ADDR_LO(pointer_status[sh2reg].djp_base); - } else { - DEFINE_REG(temp1); - SRLI(temp1, jit_address, 19); - DEFINE_REG(djp_offset); - SLLI(djp_offset, temp1, LOG2_SIZEOF_PTR); - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, djp_offset); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - GOTO_IF_Z(label_done, djppage_ptr); - djppage_ofs = 0; - } - /* Look up the appropriate bit in the table */ - DEFINE_REG(byteofs); - SRLI(byteofs, address, JIT_PAGE_BITS); - DEFINE_REG(byteaddr); - ADD(byteaddr, djppage_ptr, byteofs); - DEFINE_REG(test); - LOAD_BU(test, byteaddr, djppage_ofs); - /* Does the JIT page contain translations? */ - GOTO_IF_Z(label_done, test); { - /* Clear translations from the JIT page */ - DEFINE_REG(jcw_ptr); - MOVEA(jcw_ptr, jit_clear_write); - CALL_NORET(state_reg, address, jcw_ptr); - } DEFINE_LABEL(label_done); - /* Mark this register checked for translation overwrites */ - pointer_status[sh2reg].checked = 1; - pointer_status[sh2reg].check_offset = jit_offset; - } // if not an optimized stack access - - } else { // !pointer_status[sh2reg].rtl_basereg - - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - void *funcptr; - switch (type) { - case SH2_ACCESS_TYPE_B: funcptr = MappedMemoryWriteByte; break; - case SH2_ACCESS_TYPE_W: funcptr = MappedMemoryWriteWord; break; - case SH2_ACCESS_TYPE_L: funcptr = MappedMemoryWriteLong; break; - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - DEFINE_REG(fallback); - MOVEA(fallback, funcptr); - CALL_NORET(offset_addr, src, fallback); - - } // if (pointer_status[sh2reg].rtl_basereg) - - } else { // !pointer_status[sh2reg].known - - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - log_store(entry, address, src, offset, type, 0); - DECLARE_REG(djppage_ptr); - if (!pointer_status[sh2reg].rtl_basereg) { - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(page_ptr); - LOAD_PTR(page_ptr, dp_ptr, ADDR_LO(direct_pages)); - /* Also check direct_jit_pages[] to make sure it's writable */ - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - if (offset > -half_jit_page && offset < half_jit_page) { - /* Check at an offset of zero for efficiency */ - ADD(djp_ptr, djp_base, table_offset); - pointer_status[sh2reg].check_offset = 0; - } else { - DEFINE_REG(djp_address); - ADDI(djp_address, address, offset); - DEFINE_REG(djp_page); - SRLI(djp_page, djp_address, 19); - DEFINE_REG(djp_table_offset); - SLLI(djp_table_offset, djp_page, LOG2_SIZEOF_PTR); - ADD(djp_ptr, djp_base, djp_table_offset); - pointer_status[sh2reg].check_offset = offset; - } - ALLOC_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - pointer_status[sh2reg].checked = 1; - /* Select to zero if the direct_jit_pages[] entry is zero */ - DEFINE_REG(basereg); - SELECT(basereg, page_ptr, djppage_ptr, djppage_ptr); - pointer_status[sh2reg].rtl_basereg = basereg; - pointer_status[sh2reg].rtl_ptrreg = 0; - pointer_status[sh2reg].checked_djp = 1; - } else if (!pointer_status[sh2reg].checked_djp) { - /* This register was first used in a load, so we don't yet - * know whether it's writable; check the direct_jit_pages[] - * entry as above */ - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DECLARE_REG(basereg); - basereg = pointer_status[sh2reg].rtl_basereg; - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - if (offset > -half_jit_page && offset < half_jit_page) { - ADD(djp_ptr, djp_base, table_offset); - pointer_status[sh2reg].check_offset = 0; - } else { - DEFINE_REG(djp_address); - ADDI(djp_address, address, offset); - DEFINE_REG(djp_page); - SRLI(djp_page, djp_address, 19); - DEFINE_REG(djp_table_offset); - SLLI(djp_table_offset, djp_page, LOG2_SIZEOF_PTR); - ADD(djp_ptr, djp_base, djp_table_offset); - pointer_status[sh2reg].check_offset = offset; - } - ALLOC_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - pointer_status[sh2reg].checked = 1; - SELECT(basereg, basereg, djppage_ptr, djppage_ptr); - pointer_status[sh2reg].checked_djp = 1; - } else if (!pointer_status[sh2reg].checked - || offset - pointer_status[sh2reg].check_offset <= -half_jit_page - || offset - pointer_status[sh2reg].check_offset >= half_jit_page - ) { - /* Pointer has not been checked or the last check was at - * least half a JIT page away, so check for JIT overwrites */ - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_address); - ADDI(djp_address, address, offset); - DEFINE_REG(djp_page); - SRLI(djp_page, djp_address, 19); - DEFINE_REG(djp_table_offset); - SLLI(djp_table_offset, djp_page, LOG2_SIZEOF_PTR); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, djp_table_offset); - ALLOC_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - pointer_status[sh2reg].checked = 1; - pointer_status[sh2reg].check_offset = offset; - } else { - /* We recently checked for JIT overwrites here, so no need - * to do so again */ - djppage_ptr = 0; - } - ASSERT(do_store_common(entry, address, src, offset, type, state_reg, - pointer_status[sh2reg].rtl_basereg, - djppage_ptr)); - } else { - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - ASSERT(do_store(entry, offset_addr, src, type, state_reg)); - } - - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * check_cycles: Add RTL code to commit cycles cached in "cur_cycles", - * check whether we've hit the cycle limit, and terminate execution if so. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -#if defined(__GNUC__) && !defined(JIT_ACCURATE_ACCESS_TIMING) -__attribute__((unused)) -#endif -static int check_cycles(const JitEntry *entry, uint32_t state_reg) -{ - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DECLARE_REG(cycle_limit); - LOAD_STATE_ALLOC(cycle_limit, cycle_limit); - DEFINE_REG(test); - SLTS(test, cycles, cycle_limit); - CREATE_LABEL(no_interrupt); - GOTO_IF_NZ(no_interrupt, test); { - SAVE_STATE_CACHE(); - FLUSH_STATE_CACHE(); - RETURN(); - RESTORE_STATE_CACHE(); - } DEFINE_LABEL(no_interrupt); - - return 1; -} - -/*----------------------------------*/ - -/** - * check_cycles_and_goto: Add RTL code to commit cycles and check the - * cycle count, jumping to the specified label if the cycle count has not - * reached the limit and terminating execution otherwise. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * label: Target label for jump - * [Return value] - * Nonzero on success, zero on error - */ -static int check_cycles_and_goto(const JitEntry *entry, uint32_t state_reg, - uint32_t label) -{ - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DECLARE_REG(cycle_limit); - LOAD_STATE_ALLOC(cycle_limit, cycle_limit); - DEFINE_REG(test); - SLTS(test, cycles, cycle_limit); - GOTO_IF_NZ(label, test); - FLUSH_STATE_CACHE(); - RETURN(); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * branch_static: Generate code to branch to a static address. The - * address is assumed to be stored in state->branch_target. - * Implements the JUMP_STATIC() macro used by the decoding core. - * - * [Parameters] - * state: Processor state block - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on failure - */ -static int branch_static(SH2State *state, JitEntry *entry, uint32_t state_reg) -{ - if ((state->branch_target < jit_PC - && state->branch_target != entry->sh2_start) - || state->branch_target > entry->sh2_end - ) { - FLUSH_STATE_CACHE(); - RETURN(); - return 1; - } - - uint32_t target_label = btcache_lookup(state->branch_target); - if (!target_label) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Unresolved branch from %08X to %08X", jit_PC - 2, - (int)state->branch_target); -#endif - target_label = rtl_alloc_label(entry->rtl); - if (UNLIKELY(!target_label)) { -#ifdef JIT_DEBUG - DMSG("Failed to allocate label for unresolved branch at 0x%08X", - jit_PC); -#endif - FLUSH_STATE_CACHE(); - RETURN(); - return 1; - } - if (!record_unresolved_branch(entry, state->branch_target, - target_label)) { - return 0; - } - unsigned int index = (state->branch_target - entry->sh2_start) / 2; - is_branch_target[index/32] |= 1 << (index % 32); - } - - if (state->branch_target < jit_PC) { - check_cycles_and_goto(entry, state_reg, target_label); - } else { - APPEND(GOTO, 0, 0, 0, target_label); - } - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opcode_init: Perform pre-decode processing for an instruction. - * Implements the OPCODE_INIT() macro used by the decoding core. - * - * [Parameters] - * state: Processor state block - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * opcode: SH-2 opcode of instruction being decoded - * recursing: Nonzero if this is a recursive decode, else zero - * [Return value] - * Nonzero on success, zero on failure - */ -static int opcode_init(SH2State *state, JitEntry *entry, uint32_t state_reg, - unsigned int opcode, int recursing) -{ - unsigned int index; - - /* - * (1) If translation tracing is enabled, print a trace line for the - * instruction. - */ -#ifdef JIT_DEBUG_TRACE - char tracebuf[100]; - SH2Disasm(jit_PC, opcode, 0, tracebuf); - fprintf(stderr, "%08X: %04X %s\n", jit_PC, opcode, tracebuf+12); -#endif - - /* - * (2) In JIT_ACCURATE_ACCESS_TIMING mode, determine whether the - * instruction performs a load or store that might not be to - * ROM/RAM, and check the cycle count if so. (This is done before - * the branch target for optimization reasons, since a cycle check - * or unconditional interrupt/termination is always performed on a - * branch.) - */ -#if defined(JIT_ACCURATE_ACCESS_TIMING) - const unsigned int n = opcode>>8 & 0xF; - const unsigned int m = opcode>>4 & 0xF; - int is_pointer; - uint32_t knownbits = 0, value = 0; - if ((opcode & 0xF00E) == 0x0004 || (opcode & 0xF00F) == 0x0006) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(0)] & reg_knownbits[REG_R(n)]; - value = reg_value [REG_R(0)] & reg_value [REG_R(n)]; -# endif - } else if (opcode == 0x002B || (opcode & 0xFF00) == 0xC300) { - is_pointer = PTR_CHECK(15); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(15)]; - value = reg_value [REG_R(15)]; -# endif - } else if ((opcode & 0xF00E) == 0x000C || (opcode & 0xF00F) == 0x000E) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(0)] & reg_knownbits[REG_R(m)]; - value = reg_value [REG_R(0)] & reg_value [REG_R(m)]; -# endif - } else if ((opcode & 0xB00F) == 0x000F) { - is_pointer = PTR_CHECK(n) && PTR_CHECK(m); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(n)] & reg_knownbits[REG_R(m)]; - value = reg_value [REG_R(n)] & reg_value [REG_R(m)]; -# endif - } else if ((opcode & 0xF000) == 0x1000 - || (opcode & 0xF00A) == 0x2000 || (opcode & 0xF00B) == 0x2002 - || (opcode & 0xF00A) == 0x4002 || (opcode & 0xF0FF) == 0x401B) { - is_pointer = PTR_CHECK(n); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(n)]; - value = reg_value [REG_R(n)]; -# endif - } else if ((opcode & 0xF000) == 0x5000 - || (opcode & 0xF00A) == 0x6000 || (opcode & 0xF00B) == 0x6002 - || (opcode & 0xFA00) == 0x8000) { - is_pointer = PTR_CHECK(m); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(m)]; - value = reg_value [REG_R(m)]; -# endif - } else if ((opcode & 0xB000) == 0x9000) { - is_pointer = 0; - knownbits = 0xFFFFFFFF; - value = jit_PC; - } else if ((opcode & 0xFA00) == 0xC000 || (opcode & 0xFB00) == 0xC200) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_GBR]; - value = reg_value [REG_GBR]; -# endif - } else if ((opcode & 0xFC00) == 0xCC00) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_GBR] & reg_knownbits[REG_R(0)]; - value = reg_value [REG_GBR] & reg_value [REG_R(0)]; -# endif - } else { - is_pointer = 1; // i.e. no need to check - } - if (!is_pointer - && ((knownbits & 0xFFF00000) != 0xFFF00000 - || ((value & 0xDFF00000) != 0x00200000 // Don't bother with $Axxxxxxx - && (value & 0xDFF00000) != 0x06000000)) - ) { - /* Exceptions are not accepted when processing a delay slot (SH7604 - * manual page 75, section 4.6.1). For BT/S and BF/S, we have to - * check whether we would actually branch or not to know whether - * the following instruction is considered to be in a delay slot. */ - if (!state->delay) { - check_cycles(entry, state_reg); - } else { // It's a delayed-branch instruction - if (state->branch_type == SH2BRTYPE_BT_S - || state->branch_type == SH2BRTYPE_BF_S - ) { - CREATE_LABEL(no_branch); - if (state->branch_type == SH2BRTYPE_BT_S) { - GOTO_IF_NZ(no_branch, state->branch_cond_reg); - } else { - GOTO_IF_Z(no_branch, state->branch_cond_reg); - } - check_cycles(entry, state_reg); - DEFINE_LABEL(no_branch); - } - } - } -#endif // JIT_ACCURATE_ACCESS_TIMING - - /* - * (4) If this is not a recursive decode and the current address is the - * target of a static branch, reset all known register values and - * pointer base registers, flush the state block register cache, - * and commit pending cycles; then add a label to serve as the - * branch target. - */ - int cached_label = 0; - index = (jit_PC - initial_PC) / 2; - if (!recursing && (is_branch_target[index/32] & (1 << (index % 32)))) { - CLEAR_MAC_IS_ZERO(); -#ifdef JIT_DEBUG - if (UNLIKELY(CACHED_SHIFT_COUNT() != 0)) { - DMSG("0x%08X: WARNING: Shift count (%u) cached over a branch" - " target!", jit_PC, CACHED_SHIFT_COUNT()); - } -#endif - REG_RESETKNOWN(); - unsigned int reg; - for (reg = 0; reg < lenof(pointer_status); reg++) { - /* Known registers were checked at the start of the block, so - * there's no risk of them being undefined due to jumping over - * the code that loads them. However, if a register has been - * copied, the copy may have occurred on a different code - * branch, so mark it as unknown in that case. */ - if (pointer_status[reg].known <= 0) { - pointer_status[reg].known = 0; - pointer_status[reg].rtl_basereg = 0; - pointer_status[reg].source = 0; - } - /* Always reset this to avoid having too many long-lived - * registers (see setup_pointers()); we'll regenerate it as - * needed. */ - pointer_status[reg].rtl_ptrreg = 0; - } - pointer_local = 0; // Known registers never appear here - ASSERT(writeback_state_cache(entry, state_reg, 0)); - clear_state_cache(0); - btcache[btcache_index].sh2_address = jit_PC; - btcache[btcache_index].rtl_label = rtl_alloc_label(entry->rtl); - if (UNLIKELY(!btcache[btcache_index].rtl_label)) { - DMSG("Failed to generate label for branch target at 0x%08X", - jit_PC); - return 0; - } else { - DEFINE_LABEL(btcache[btcache_index].rtl_label); - btcache_index++; - if (UNLIKELY(btcache_index >= lenof(btcache))) { - btcache_index = 0; - } - cached_label = 1; - } - } - - /* - * (5) If this is not a recursive decode and there are any pending - * static branches to the current address, resolve them by defining - * the RTL label they branch to. (However, do _not_ define a label - * if this instruction is in a delay slot, because the RTL code - * implementing the branch will be appended after this instruction, - * which would cause incorrect behavior for other code branching to - * this instruction.) - */ - if (!recursing && !state->delay) { - for (index = 0; index < lenof(unres_branches); index++) { - if (unres_branches[index].sh2_target == jit_PC) { - const uint32_t label = unres_branches[index].target_label; - APPEND(LABEL, 0, 0, 0, label); - unres_branches[index].sh2_target = 0; - if (!cached_label) { - /* Probably won't need it, but cache anyway just in case */ - btcache[btcache_index].sh2_address = jit_PC; - btcache[btcache_index].rtl_label = label; - btcache_index++; - if (UNLIKELY(btcache_index >= lenof(btcache))) { - btcache_index = 0; - } - cached_label = 1; - } - } - } - } - - /* - * (6) If this is not a recursive decode and this instruction is hinted - * as loading a data pointer, set a flag so that we will generate - * RTL to load the base pointer after the instruction completes; - * otherwise, clear the flag. (Note that the hint flag will never - * be set if pointer optimization is disabled, so we don't need to - * check again here.) - */ - index = (jit_PC - initial_PC) / 2; - if (!recursing && (is_data_pointer_load[index/32] & (1 << (index % 32)))) { - state->make_Rn_data_pointer = 1; - } else { - state->make_Rn_data_pointer = 0; - } - - /* - * (7) If enabled, insert a dummy instruction indicating the current - * SH-2 PC. Do this after the label so the instruction isn't - * optimized away as part of a dead code block following a branch. - */ -#ifdef JIT_DEBUG_INSERT_PC - APPEND(NOP, 0, jit_PC, 0, 0); -#endif - - /* - * (8) If TRACE_STEALTH is enabled, insert coded NOPs to inform the - * RTL interpreter of cached values and direct it to trace the - * instruction. - */ -#ifdef TRACE_STEALTH - APPEND(NOP, 0, 0x80000000 | jit_PC, 0, 0); - if (state->pending_select && !state->delay) { - APPEND(NOP, 0, 0x9F000000 | (!state->select_sense) << 16 - | state->branch_cond_reg, 0, 0); - } -# ifdef OPTIMIZE_STATE_BLOCK - APPEND(NOP, 0, 0x98000000 | STATE_CACHE_OFFSET(cycles), 0, 0); - APPEND(NOP, 0, 0x90000000 | state_cache[state_cache_index(offsetof(SH2State,cycles))].rtlreg, 0, 0); -# else - APPEND(NOP, 0, 0x98000000, 0, 0); - APPEND(NOP, 0, 0x90000000, 0, 0); -# endif -#endif - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opcode_done: Perform post-decode processing for an instruction. - * Implements the OPCODE_DONE() macro used by the decoding core. - * - * [Parameters] - * state: Processor state block - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * opcode: SH-2 opcode of instruction being decoded - * recursing: Nonzero if this is a recursive decode, else zero - * [Return value] - * Nonzero on success, zero on failure - */ -static int opcode_done(SH2State *state, JitEntry *entry, uint32_t state_reg, - unsigned int opcode, int recursing) -{ - /* - * (1) If this instruction is hinted as loading a data pointer, - * generate RTL to set up a base pointer register for the SH-2 - * register identified by the Rn field of this instruction (or R0, - * if the instruction is MOVA @(disp,PC),R0). - */ - if (state->make_Rn_data_pointer) { - const unsigned int n = - ((opcode & 0xFF00) == 0xC700) ? 0 : opcode>>8 & 0xF; - - DECLARE_REG(Rn); - LOAD_STATE_ALLOC_KEEPOFS(Rn, R[n]); - DEFINE_REG(page); - SRLI(page, Rn, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(page_ptr); - LOAD_PTR(page_ptr, dp_ptr, ADDR_LO(direct_pages)); - pointer_status[n].known = -1; - pointer_status[n].type = 2; - pointer_status[n].data_only = 1; - pointer_status[n].rtl_basereg = page_ptr; - } - - /* - * (2) If tracing, write all cached SH-2 registers back to the state - * block so traces show the correct values at each instruction. - */ -#ifdef TRACE - ASSERT(writeback_state_cache(entry, state_reg, 1)); -#endif - - return 1; -} - -/*************************************************************************/ -/***************** SH-2 -> RTL translation main routines *****************/ -/*************************************************************************/ - -/** - * translate_block: Translate a block of SH-2 instructions beginning at - * the address in entry->sh2_start into RTL code. On success, the RTL - * block in entry->rtl is finalized. - * - * [Parameters] - * state: SH-2 processor state - * entry: Block being translated - * [Return value] - * Nonzero on success, zero on error - */ -static int translate_block(SH2State *state, JitEntry *entry) -{ - const uint16_t *fetch_base = - (const uint16_t *)fetch_pages[entry->sh2_start >> 19]; - PRECOND(fetch_base != NULL, return 0); - - unsigned int index; - - /* Clear out translation state. */ - - memset(is_branch_target, 0, sizeof(is_branch_target)); - for (index = 0; index < lenof(btcache); index++) { - btcache[index].sh2_address = 0; - } - btcache_index = 0; - for (index = 0; index < lenof(unres_branches); index++) { - unres_branches[index].sh2_target = 0; - } -#ifdef OPTIMIZE_KNOWN_VALUES - for (index = 0; index < lenof(reg_knownbits); index++) { - reg_knownbits[index] = 0; - reg_value[index] = 0; - } -#endif - ignore_optimization_hints = 0; - is_constant_entry_reg = 0; - memset(pointer_status, 0, sizeof(pointer_status)); - stack_pointer = 0; - pointer_local = 0; - is_data_pointer_reg = 0; - memset(is_data_pointer_load, 0, sizeof(is_data_pointer_load)); -#ifdef OPTIMIZE_STATE_BLOCK - clear_state_cache(1); // Should always be clear here, but just in case - stored_PC = entry->sh2_start; // So loops can skip the store if optimized -#endif - state->branch_type = SH2BRTYPE_NONE; - state->branch_target = 0; - state->branch_target_reg = 0; - state->branch_fold_native = 0; - state->branch_cond_reg = 0; - state->branch_cycles = 0; - state->branch_targets_rts = 0; - state->loop_to_jsr = 0; - state->folding_subroutine = 0; - state->pending_select = 0; - state->select_sense = 0; - state->just_branched = 0; - state->need_interrupt_check = 0; - state->mac_is_zero = 0; - state->cached_shift_count = 0; - state->varshift_target_PC = 0; - state->varshift_type = 0; - state->varshift_Rcount = 0; - state->varshift_max = 0; - state->varshift_Rshift = 0; - state->division_target_PC = 0; - state->div_data.Rquo = 0; - state->div_data.Rrem = 0; - state->div_data.quo = 0; - state->div_data.rem = 0; - state->div_data.SR = 0; - - /* If a manual optimization callback has been provided, check for a - * match at this address, and use the optimized translation if found. - * (This must be done after clearing state, because the callback may - * set optimization hints and return zero.) */ - - if (manual_optimization_callback) { - const uint16_t *fetch = - (const uint16_t *)((uintptr_t)fetch_base + entry->sh2_start); - SH2NativeFunctionPointer hand_tuned_function; - const unsigned int hand_tuned_len = - (*manual_optimization_callback)(state, entry->sh2_start, - fetch, &hand_tuned_function, 0); - if (hand_tuned_len > 0) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Using hand-tuned code for 0x%08X + %u insns", - entry->sh2_start, hand_tuned_len); -#endif - DEFINE_REG(state_reg); - APPEND(LOAD_PARAM, state_reg, 0, 0, 0); - DEFINE_REG(funcptr_reg); - MOVEA(funcptr_reg, hand_tuned_function); - CALL_NORET(state_reg, 0, funcptr_reg); - RETURN(); - ASSERT(rtl_finalize_block(entry->rtl)); - entry->sh2_end = entry->sh2_start + hand_tuned_len*2 - 1; - return 1; - } - } - - /* If any registers were marked as constant on entry, load their - * values into the known-constant array. */ - -#ifdef OPTIMIZE_KNOWN_VALUES - if (is_constant_entry_reg) { - for (index = 0; index < 16; index++) { - if (is_constant_entry_reg & (1<R[index]; - } - } - } -#endif - - /* Check whether saturation code can potentially be optimized out of - * MAC instructions. */ - - can_optimize_mac_nosat = (optimization_flags & SH2_OPTIMIZE_MAC_NOSAT) - && !(state->SR & SR_S); - - /* Mark which registers are currently valid pointers. Note that we - * currently can't detect ROM pointers, because the pointer analysis - * logic would treat "offset + unknown pointer" as "ROM pointer + - * unknown offset". */ - - pointer_regs = 0; - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - for (index = 0; index < 16; index++) { - if ((state->R[index] & 0xDFF00000) == 0x00200000 - || (state->R[index] & 0xDE000000) == 0x06000000 - || (state->R[index] & 0xDFF80000) == 0x05C00000 - || (state->R[index] & 0xDFF00000) == 0x05E00000 - ) { - pointer_regs |= 1 << index; - } - } - } - - /* Scan through the SH-2 code to find the end of the block and - * determine what parts of it are translatable code, and to perform - * pre-translation checks for various optimizations. */ - - unsigned int block_len = scan_block(state, entry, entry->sh2_start); - if (!block_len) { - DMSG("Failed to find any translatable instructions at 0x%08X", - entry->sh2_start); - return 0; - } - entry->sh2_end = entry->sh2_start + block_len*2 - 1; - - /* Preload the state block pointer (first function argument) into an - * RTL register, and mark it as a unique pointer. */ - - DEFINE_REG(state_reg); - APPEND(LOAD_PARAM, state_reg, 0, 0, 0); - ASSERT(rtl_register_set_unique_pointer(entry->rtl, state_reg)); - - /* If we have an optimizable loop, prepare RTL registers for all SH-2 - * registers live in the loop as well as the cycle count and limit, up - * to the maximum configured. */ - -#ifdef OPTIMIZE_LOOP_REGISTERS - if (can_optimize_loop) { - loop_live_registers |= - 1<sh2_start, loop_live_registers, - loop_load_registers, loop_changed_registers, - loop_invariant_pointers); -# endif - unsigned int regs_fixed = 0; - for (index = 0; index < lenof(state_cache); index++) { - if (loop_live_registers & 1<= OPTIMIZE_LOOP_REGISTERS_MAX_REGS) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Out of fixed registers (%u), skipping some", - regs_fixed); -# endif - break; - } - ALLOC_REG(state_cache[index].rtlreg); - state_cache[index].offset = 0; - state_cache[index].fixed = 1; - state_cache[index].flush = - (loop_changed_registers & 1<sh2_start); - - /* If the block contains MACs and the S flag is known not to change - * from block entry to the last MAC, add a check to ensure S is still - * clear at runtime and retranslate the block if not. */ - // FIXME: We assume that in a loop, if S is left clear through the - // last MAC in the loop, it won't be set before the end of the loop - // body. If anybody actually does that, they should be dragged out - // into the street and shot. - - if (!skip_preconditions && can_optimize_mac_nosat && block_contains_mac) { - if (!invalidate_label) { - ASSERT(invalidate_label = rtl_alloc_label(entry->rtl)); - } - DECLARE_REG(SR); - LOAD_STATE_ALLOC(SR, SR); - DEFINE_REG(S); - ANDI(S, SR, SR_S); - GOTO_IF_NZ(invalidate_label, S); - } - - /* If we're optimizing a loop, initialize pointer status and preload - * pointer base addresses before the block-top label. In this case, we - * ignore any pointers which are not loop invariants and look them up - * at runtime instead. */ - // FIXME: I wonder if we have to load the stack pointer dynamically? - // (e.g. if the same code is executed by both MSH2 and SSH2, and SSH2 - // uses $002xxxxx instead of $060xxxxx) - -#ifdef OPTIMIZE_LOOP_REGISTERS - if (can_optimize_loop) { - pointer_used &= loop_invariant_pointers; - ASSERT(setup_pointers(state, entry, state_reg, skip_preconditions, - &invalidate_label)); - } -#endif - - /* Add a label for the special case of branching back to the beginning - * of the block (backward branches normally terminate execution of the - * block). When we're not optimizing loops, this has to be added - * _before_ precondition checks on pointer values so changes in those - * values are properly detected when the code loops back. */ - - CREATE_LABEL(block_start_label); - DEFINE_LABEL(block_start_label); - btcache[btcache_index].sh2_address = entry->sh2_start; - btcache[btcache_index].rtl_label = block_start_label; - btcache_index++; - - /* If we're not optimizing a loop, initialize pointer status and - * preload pointer base addresses after the block-top label. */ - -#ifdef OPTIMIZE_LOOP_REGISTERS - if (!can_optimize_loop) -#endif - ASSERT(setup_pointers(state, entry, state_reg, skip_preconditions, - &invalidate_label)); - - /* Perform the actual translation of SH-2 instructions to RTL code. */ - -#ifdef JIT_DEBUG_VERBOSE - DMSG("Starting translation at %08X", entry->sh2_start); -#endif - jit_PC = entry->sh2_start; - uint32_t next_code_address = jit_PC; // For the fall-off-the-end case - while (jit_PC <= entry->sh2_end) { - index = (jit_PC - entry->sh2_start) / 2; - if (word_info[index] & WORD_INFO_CODE) { - if (UNLIKELY(!translate_insn(state, entry, state_reg, 0, 0))) { - DMSG("Failed to translate instruction at 0x%08X", - entry->sh2_start + index*2); - return 0; - } - next_code_address = jit_PC; - } else { - /* It's not code, so just skip the word */ - jit_PC += 2; - } - } -#ifdef JIT_DEBUG_VERBOSE - DMSG("Translation ended at %08X", jit_PC-2); -#endif - - /* If static branch prediction is enabled, count the number of static - * branches to be predicted and allocate memory for the prediction - * data. The memory used by this data will be included in the total - * data size of the translated block. Otherwise, just define a flag - * indicating whether we need to append a RETURN to terminate the - * block. */ - -#ifdef JIT_BRANCH_PREDICT_STATIC - entry->num_static_branches = state->just_branched ? 0 : 1; - for (index = 0; index < lenof(unres_branches); index++) { - if (unres_branches[index].sh2_target != 0) { - entry->num_static_branches++; - } - } - if (entry->num_static_branches > 0) { - const uint32_t static_predict_size = - entry->num_static_branches * sizeof(BranchTargetInfo); - entry->static_predict = calloc(static_predict_size, 1); - if (UNLIKELY(!entry->static_predict)) { - DMSG("No memory for %u static branch predictions", - entry->num_static_branches); - return 0; - } - jit_total_data += static_predict_size; - } - int branch_num = 0; -#else // !JIT_BRANCH_PREDICT_STATIC - int need_return = 0; -#endif - - /* Flush the state block cache and terminate the code if it can fall - * off the end of the block. */ - - if (!state->just_branched) { - ASSERT(writeback_state_cache(entry, state_reg, 1)); - clear_state_cache(0); -#ifdef JIT_BRANCH_PREDICT_STATIC - ASSERT(add_static_branch_terminator( - entry, state_reg, next_code_address, branch_num++)); -#else - need_return = 1; -#endif - } - - /* Add fallback termination code for unresolved static branches. */ - - for (index = 0; index < lenof(unres_branches); index++) { - if (unres_branches[index].sh2_target != 0) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("FAILED to resolve branch to %08X", - unres_branches[index].sh2_target); -#endif - DEFINE_LABEL(unres_branches[index].target_label); -#ifdef JIT_BRANCH_PREDICT_STATIC - ASSERT(add_static_branch_terminator( - entry, state_reg, unres_branches[index].sh2_target, - branch_num++)); -#else - need_return = 1; -#endif - } - } - - /* If static branch prediction is disabled, add a RETURN if needed for - * falling off the end of the block or terminating unresolved static - * branches. */ - -#ifndef JIT_BRANCH_PREDICT_STATIC - if (need_return) { - RETURN(); - } -#endif - - /* If necessary, add fallback code to invalidate the block if a - * precondition check fails. */ - - if (invalidate_label) { - DEFINE_LABEL(invalidate_label); - DEFINE_REG(imm_sh2_start); - MOVEI(imm_sh2_start, entry->sh2_start); - DEFINE_REG(addr_mark_purged); - MOVEA(addr_mark_purged, jit_mark_purged); - CALL_NORET(imm_sh2_start, 0, addr_mark_purged); - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - DEFINE_REG(addr_must_clear); - MOVEA(addr_must_clear, &entry->must_clear); - STORE_B(addr_must_clear, imm_1, 0); - RETURN(); - } - - /* Close out the translated block. */ - - if (UNLIKELY(!rtl_finalize_block(entry->rtl))) { - DMSG("Failed to finalize block at 0x%08X", entry->sh2_start); - return 0; - } - if (JIT_OPTIMIZE_FLAGS) { - if (UNLIKELY(!rtl_optimize_block(entry->rtl, JIT_OPTIMIZE_FLAGS))) { -#ifdef JIT_DEBUG - DMSG("Failed to optimize block at 0x%08X", entry->sh2_start); -#endif - /* Block is still usable, so keep going */ - } - } - - /* Clear everything from the cache, including any fixed registers. */ - - clear_state_cache(1); - - /* All done, return success. */ - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * setup_pointers: Initialize the pointer_status[] array and load any - * necessary pointer base registers. Helper function for translate_block(). - * - * [Parameters] - * state: SH-2 processor state - * entry: Block being translated - * skip_preconditions: Nonzero if preconditions should be skipped - * invalidate_label_ptr: Pointer to variable holding label index to - * jump to when the block should be invalidated - * [Return value] - * Nonzero on success, zero on error - */ -static int setup_pointers(SH2State * const state, JitEntry * const entry, - const unsigned int state_reg, - const int skip_preconditions, - unsigned int * const invalidate_label_ptr) -{ - unsigned int index; - - for (index = 0; index < lenof(pointer_status); index++) { - if ((pointer_used & 1<R[index]; - const unsigned int addr_shift = - ((reg_address & 0x0F000000) == 0x05000000) ? 19 : 20; - if (!(index == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)) - && !(is_data_pointer_reg & 1<rtl)); - } - DECLARE_REG(regval); - LOAD_STATE_ALLOC(regval, R[index]); - DEFINE_REG(highbits); - SRLI(highbits, regval, addr_shift); - DEFINE_REG(test); - XORI(test, highbits, reg_address >> addr_shift); - GOTO_IF_NZ(*invalidate_label_ptr, test); - } - pointer_status[index].type = - ((reg_address & 0x0F000000) == 0x05000000) ? 1 : 2; - DEFINE_REG(basereg); - if (pointer_status[index].type == 1) { - MOVEA(basereg, byte_direct_pages[reg_address>>19]); - } else { - MOVEA(basereg, direct_pages[reg_address>>19]); - } - pointer_status[index].rtl_basereg = basereg; - /* We don't immediately load a direct pointer in order to - * minimize the number of long-lived registers (one base - * register instead of lots of direct pointer registers); - * the direct pointer will be created as needed and - * discarded at branch points. */ - pointer_status[index].rtl_ptrreg = 0; - pointer_status[index].djp_base = - direct_jit_pages[reg_address>>19]; - if (index == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)) { - DECLARE_REG(regval); - LOAD_STATE_ALLOC(regval, R[index]); - DEFINE_REG(ptrreg); - ADD(ptrreg, basereg, regval); - stack_pointer = ptrreg; - } - } else { - /* Used as a pointer, but not pointing to a directly- - * accessible memory region, so we'll call the fallback - * functions for accesses through this register. But first - * make sure it really isn't pointing to a memory region - * that can contain code, or else we could overwrite an - * already-translated routine and not notice. */ - if (!*invalidate_label_ptr) { - ASSERT(*invalidate_label_ptr = - rtl_alloc_label(entry->rtl)); - } - DECLARE_REG(regval); - LOAD_STATE_ALLOC(regval, R[index]); - DEFINE_REG(page); - SRLI(page, regval, 19); - DEFINE_REG(page_ofs); - SLLI(page_ofs, page, LOG2_SIZEOF_PTR); - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, page_ofs); - DEFINE_REG(test); - LOAD_PTR(test, djp_ptr, ADDR_LO(direct_jit_pages)); - GOTO_IF_NZ(*invalidate_label_ptr, test); - pointer_status[index].rtl_basereg = 0; - pointer_status[index].rtl_ptrreg = 0; - } - } else { - pointer_status[index].known = 0; - pointer_status[index].rtl_basereg = 0; - pointer_status[index].rtl_ptrreg = 0; - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * scan_block: Scan through a block of SH-2 code, finding the length of - * the block, recording whether each word in the block is code or data, and - * recording all addresses targeted by branches in the is_branch_target[] - * array. - * - * [Parameters] - * state: Processor state block pointer - * entry: Translated block data structure - * address: Start of block in SH-2 address space - * [Return value] - * Length of block, in instructions - * [Side effects] - * - Fills in word_info[], is_branch_target[], branch_thread_target[], - * and branch_thread_count[] - * - Clears can_optimize_mac_nosat if an unoptimizable MAC is found - * - Sets or clears block_contains_mac appropriately - * - Sets pointer_used to the set of registers used as pointers - * - If OPTIMIZE_LOOP_REGISTERS is defined, sets can_optimize_loop, - * loop_live_registers, loop_load_registers, loop_changed_registers, - * and loop_invariant_pointers appropriately - */ -static int scan_block(SH2State *state, JitEntry *entry, uint32_t address) -{ - const uint32_t start_address = address; // Save the block's start address - - const uint16_t *fetch_base = (const uint16_t *)fetch_pages[address >> 19]; - PRECOND(fetch_base != NULL, return 0); - const uint16_t *fetch = - (const uint16_t *)((uintptr_t)fetch_base + address); - - unsigned int index; - - memset(word_info, 0, sizeof(word_info)); - - /* If we just encountered a branch instruction that branched to an - * address we haven't seen before, remember the branch and target - * addresses so we can mark the branch as fall-through if we don't - * translate anything in between. */ - unsigned int fallthru_target = 0; // Target word_info[] index (0 = none) - unsigned int fallthru_source = 0; // Location of branch (word_info[] index) - - /* Remember whether we've seen something write to SR (we don't clear - * the can-optimize flag unless we see a MAC instruction _after_ a - * write to SR, since the SR write could just be restoring it at the - * end of the subroutine) */ - int sr_was_changed = 0; - /* We haven't seen a MAC instruction yet */ - block_contains_mac = 0; - - /* Remember the last CLRMAC we saw, as well as relevant state - * information at the point of that CLRMAC, so we can roll back if we - * later find an unoptimizable MAC instruction. */ - int last_clrmac = -1; // Word index (negative = none seen) - uint32_t last_clrmac_pointer_used = 0; - uint8_t last_clrmac_comn = 0; // can_optimize_mac_nosat - uint8_t last_clrmac_bcm = 0; // block_contains_mac - - /* Map current register contents to registers at the block entry point, - * so we can track pointer values through MOV instructions. A value of - * 31 is inserted for registers which have been overwritten with other - * values (so we don't attempt to mark the original register indices as - * "used"); a value of 30 indicates that the register is known to be a - * pointer (either by being loaded with a MOVA instruction or from an - * optimization hint) but does not derive from a specific register. */ - uint8_t pointer_map[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; - /* Clear the current set of registers used as pointers. */ - pointer_used = 0; - - /* Track which registers have values loaded via MOV @(disp,PC) for - * subroutine folding. A value of 1 (an impossible target address) - * indicates that the register has not been so loaded. We assume that - * any PC-relative load subsequently used in a JSR is a constant. */ - uint32_t local_constant[16] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}; - for (index = 0; index < 16; index++) { - if (is_constant_entry_reg & (1<R[index]; - } - } - /* We also need to remember the state of each register at every branch - * target; if a particular instruction can be reached from multiple - * sources or does not fall through from the preceding instruction, the - * contents of registers will need to be updated appropriately. */ - static uint32_t local_constant_per_insn[JIT_INSNS_PER_BLOCK][16]; - int is_local_branch = 0; - unsigned int local_branch_target_index = 0; - int local_branch_is_new = 0; - -#ifdef OPTIMIZE_LOOP_REGISTERS - /* Initialize loop optimization tracking state; also keep track of - * whether we've seen a backward branch to the beginning of the block - * and the loop register state at the time of that branch. */ - can_optimize_loop = 1; - loop_live_registers = 0; - loop_load_registers = 0; - loop_changed_registers = 0; - loop_invariant_pointers = 0xFFFF; - int is_loop = 0; - int saw_branch_target = 0; - int at_loop_branch = 0; - uint32_t final_live_registers = 0; - uint32_t final_load_registers = 0; - uint32_t final_changed_registers = 0; - uint32_t final_invariant_pointers = 0; - - /* Remember which registers had been set before the first forward - * branch encountered in the loop. Any registers set by subsequent - * instructions will be added to the preload set even if their initial - * values are not used as source operands within the loop, so the - * corresponding RTL registers have the proper values even if the code - * jumps out from the middle of the loop. */ - uint32_t loop_noload_registers = 0; - int loop_noload_registers_set = 0; - int at_branch = 0; -#endif - - - /* Find the maximum length of this block: either JIT_INSNS_PER_BLOCK or - * the number of instruction words before the next blacklisted region, - * whichever is smaller. */ - - unsigned int max_len = JIT_INSNS_PER_BLOCK; - for (index = 0; index < lenof(blacklist); index++) { - if (blacklist[index].start >= start_address - && blacklist[index].start < (start_address + max_len*2) - ) { - max_len = (blacklist[index].start - start_address) / 2; - } - } - if (UNLIKELY(max_len < 2)) { - DMSG("No translatable block at 0x%X (max_len=%u)", - start_address, max_len); - return 0; - } - - int block_len = 0; - int end_block = 0; - int end_block_next = 0; // For use with LDC ...,SR - int delay = 0; - int at_uncond_branch = 0; - for (; !end_block || delay; address += 2, fetch++, block_len++) { - - /* Save whether or not this is a delay slot, then clear "delay". */ - - const int now_in_delay = delay; - delay = 0; - - /* Move the delayed block-end flag (set when an LDC ...,SR - * instruction is detected) to end_block; if it's set, we'll end - * the block after this instruction. */ - - end_block = end_block_next; - end_block_next = 0; - - /* Get the opcode. */ - - const unsigned int opcode = *fetch; - - /* Retrieve information about the opcode. */ - - const uint32_t opcode_info = get_opcode_info(opcode); - - /* Check whether the opcode is valid, and abort if not. Don't - * include the invalid instruction in the block; if we get there - * and it's still invalid, we'll interpret it (but who knows, maybe - * it'll be modified in the meantime). */ - - if (!(opcode_info & SH2_OPCODE_INFO_VALID)) { - goto abort_scan; - } - - /* Mark this word as code. */ - - word_info[block_len] = WORD_INFO_CODE; - - /* If we're not in a delay slot, check whether we just fell through - * from a branch, and clear the fall-through variables. */ - - int at_fallthru = 0; - const uint32_t saved_fallthru_source = fallthru_source; - const uint32_t saved_fallthru_target = fallthru_target; - if (!now_in_delay && fallthru_target) { - if (block_len == fallthru_target) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Continuing at %08X from fall-through branch at %08X", - address, start_address + fallthru_source*2); -#endif - /* We don't actually update the word_info[] table until we - * have successfully scanned this instruction. If we - * marked the branch as fall-through here but later decided - * to terminate the block for optimization reasons (e.g. - * unoptimizable pointers) before this instruction, the - * generated RTL would incorrectly set the PC to the - * instruction following the branch instead of the branch - * target. */ - at_fallthru = 1; - } - fallthru_target = fallthru_source = 0; - } - - /* If this is a branch target, update the local constant list used - * by subroutine folding. */ - - if (is_branch_target[block_len/32] & (1 << (block_len%32))) { - unsigned int reg; - for (reg = 0; reg < 16; reg++) { - local_constant[reg] = local_constant_per_insn[block_len][reg]; - } - } - - /* Check for MAC.[WL] optimizations. */ - - if (optimization_flags & SH2_OPTIMIZE_MAC_NOSAT) { - if ((opcode & 0xF0FF) == 0x4007 || (opcode & 0xF0FF) == 0x400E) { - sr_was_changed = 1; - } else if ((opcode & 0xB00F) == 0x000F) { - block_contains_mac = 1; - if (sr_was_changed) { - can_optimize_mac_nosat = 0; // Oh well, tough luck - } - } - } - - /* Record pointer accesses and register modifications for pointer - * optimization. */ - - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - - optimize_pointers(start_address, address, opcode, opcode_info, - pointer_map); - - /* If we're looking at a MAC instruction beyond the beginning - * of the block, and at least one of the source registers to - * the MAC is an unknown pointer, terminate the block before - * this instruction (or before a preceding CLRMAC if there was - * a recent one) so we can translate the MAC with maximum - * optimization. But don't check this if we're in a delay - * slot, since the delay slot isn't necessarily part of the - * following code stream (and interrupting a block between a - * branch and its delay slot will wreak havoc with processor - * state). */ - if ((optimization_flags & SH2_OPTIMIZE_POINTERS_MAC) - && block_len > 0 - && !now_in_delay - ) { - if ((opcode & 0xB00F) == 0x000F) { - int stop = 0, rollback = 0; - optimize_pointers_mac( - address, opcode, pointer_map, - last_clrmac<0 ? 0 : start_address + last_clrmac*2, - &stop, &rollback - ); - if (stop) { - if (rollback) { - block_len = last_clrmac; - pointer_used = last_clrmac_pointer_used; - can_optimize_mac_nosat = last_clrmac_comn; - block_contains_mac = last_clrmac_bcm; - } - goto abort_scan; - } - } else if (opcode == 0x0028) { - /* Remember this CLRMAC so we can terminate before it - * if we find a MAC with unoptimizable memory accesses */ - last_clrmac = block_len; - last_clrmac_pointer_used = pointer_used; - last_clrmac_comn = can_optimize_mac_nosat; - last_clrmac_bcm = block_contains_mac; - } - } // if ((opt_flags & SH2_OPTIMIZE_POINTERS_MAC) && etc.) - -#if OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD > 0 - /* If this instruction accesses through a non-optimizable - * pointer, and there are more accesses to the same pointer in - * subsequent instructions, terminate the block before this - * instruction. (Again, don't do this if we're in a delay - * slot.) */ - int pointer_reg = -1; - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rn) { - pointer_reg = opcode>>8 & 0xF; - } else if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - pointer_reg = opcode>>4 & 0xF; - } - /* First make sure this isn't an instruction that overwrites - * the same register it uses as a pointer. */ - if (((opcode_info & SH2_OPCODE_INFO_SETS_R0) && pointer_reg == 0) - || ((opcode_info & SH2_OPCODE_INFO_SETS_Rn) - && pointer_reg == (opcode>>8 & 0xF)) - ) { - pointer_reg = -1; - } - if (pointer_reg >= 0 - && pointer_map[pointer_reg] == 31 - && !now_in_delay - ) { - unsigned int accesses = 1; - int i; - for (i = 1; i < max_len - block_len; i++) { - const unsigned int opcode2 = fetch[i]; - const unsigned int n = opcode2>>8 & 0xF; - const unsigned int m = opcode2>>8 & 0xF; - const uint32_t info2 = get_opcode_info(opcode2); - int access_reg = -1; - if (info2 & SH2_OPCODE_INFO_ACCESSES_Rn) { - access_reg = n; - } else if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - access_reg = m; - } - if (access_reg == pointer_reg) { - accesses++; - if (accesses >= OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Breaking block from %08X at %08X due to" - " unoptimizable pointer in r%d\n", - start_address, address, pointer_reg); -# endif - goto abort_scan; - } - } - if (((info2 & SH2_OPCODE_INFO_SETS_R0) && pointer_reg == 0) - || ((info2 & SH2_OPCODE_INFO_SETS_Rn) && pointer_reg == n) - || (info2 & (SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_COND)) - ) { - /* The pointer register was overwritten, or a - * branch interrupted the block, so stop checking. - * (We stop even for conditional branches, so we - * don't break a block for the first access when - * that access is immediately followed by a check. */ - break; - } - } - } // if (pointer_reg >= 0 && etc.) -#endif // OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD > 0 - - } // if (optimization_flags & SH2_OPTIMIZE_POINTERS) - -#ifdef OPTIMIZE_LOOP_REGISTERS - - /* If this address is a branch target and we're within a loop, the - * loop is too complex to optimize. Of course, we won't know - * whether we're in a loop until we see a branch back to the top, - * so just track that we saw a branch target for now. */ - - if (is_branch_target[block_len/32] & (1 << (block_len%32))) { - saw_branch_target = 1; - } - - /* If this is a potential loop, check for changes to register state. */ - - if (can_optimize_loop) { - check_loop_registers(opcode, opcode_info); - } - -#endif // OPTIMIZE_LOOP_REGISTERS - - /* If the instruction is a static branch within the potential range - * of this block, record the target; also check for optimizations. */ - - if ((opcode & 0xF900) == 0x8900 // B[TF]{,_S} - || (opcode & 0xF000) == 0xA000 // BRA - ) { - int32_t disp; - if ((opcode & 0xF000) == 0xA000) { - disp = opcode & 0xFFF; - disp <<= 20; // Sign-extend - disp >>= 19; // And double - } else { - disp = opcode & 0xFF; - disp <<= 24; - disp >>= 23; - } - uint32_t target = (address + 4) + disp; - -#ifdef OPTIMIZE_BRANCH_THREAD - /* If this is a conditional branch, check whether the target is - * another conditional branch of the same sense, either without - * a delay slot or with a NOP in the delay slot; if so, then - * thread the branch through to the final target. But don't - * thread if this branch has a delay slot whose instruction - * modifies SR.T. */ - if ((opcode & 0xF900) == 0x8900 - && target >= start_address - && target <= start_address + max_len*2 - && (!(opcode & 0x0400) - || !(get_opcode_info(fetch[1]) & SH2_OPCODE_INFO_SETS_SR_T)) - ) { - branch_thread_count[block_len] = 0; - unsigned int target_insn0 = fetch[2+(disp/2)+0]; - unsigned int target_insn1 = fetch[2+(disp/2)+1]; - while ((target_insn0 & 0xFF00) == (opcode & 0xFB00) // B[TF] - || ((target_insn0 & 0xFF00) - == ((opcode & 0xFB00) | 0x0400) // B[TF]/S - && target_insn1 == 0x0009) // NOP - ) { - disp = ((int32_t)target_insn0 << 24) >> 23; - target = target + 4 + disp; -#ifdef JIT_DEBUG_VERBOSE - DMSG("Threading branch from 0x%08X through to 0x%08X", - address, target); -#endif - word_info[block_len] |= WORD_INFO_THREADED; - branch_thread_target[block_len] = target; - branch_thread_count[block_len]++; // Assume no overflow - disp = target - (address + 4); - if (target < start_address - || target >= start_address + max_len*2 - ) { - break; - } - target_insn0 = fetch[2+(disp/2)+0]; - target_insn1 = fetch[2+(disp/2)+1]; - } - } -#endif // OPTIMIZE_BRANCH_THREAD - -#ifdef OPTIMIZE_BRANCH_SELECT - /* If this is a conditional branch, check whether the branch - * acts like an RTL SELECT instruction. To be treated like a - * SELECT, the branch must skip exactly one instruction which - * is not targeted by any other branch and which supports being - * used as a SELECT source in the SH-2 decoder (sh2-core.i). */ - if (target < start_address + max_len*2) { - if (optimize_branch_select(start_address, address, fetch, - opcode, target)) { - goto skip_branch_target_check; - } - } -#endif // OPTIMIZE_BRANCH_SELECT - - /* If enabled, check whether this branch targets a RTS/NOP pair. - * We allow this check even if the target is out of range of - * the block, on the assumption that they are part of the same - * routine. */ - if (optimization_flags & SH2_OPTIMIZE_BRANCH_TO_RTS) { - unsigned int target_insn0 = fetch[2+(disp/2)+0]; - unsigned int target_insn1 = fetch[2+(disp/2)+1]; - if (target_insn0 == 0x000B // RTS - && target_insn1 == 0x0009 // NOP - ) { - word_info[block_len] |= WORD_INFO_BRA_RTS; - goto skip_branch_target_check; - } - } - -#ifdef OPTIMIZE_LOOP_REGISTERS - /* If this is a backward branch to the beginning of the block, - * mark the block as a loop and save loop state after the - * branch's delay slot (if any). But if we've seen a branch - * target before (or at) this instruction, then the loop is too - * complex to optimize, so clear the relevant flag. */ - if (target == start_address) { - if (saw_branch_target) { - can_optimize_loop = 0; - } else { - is_loop = 1; - at_loop_branch = 1; - } - } -#endif - -#ifdef OPTIMIZE_LOOP_TO_JSR - /* If this is a backward branch to two instructions before - * the beginning of the block, record whether the targeted - * instruction is a subroutine call (JSR, BSR, or BSRF). - * In this case, also mark the following instruction as a - * branch target, because we're effectively flipping the - * sense of the branch and skipping the call and delay slot - * on the opposite condition. (If we don't do this, side - * effects of the delay slot such as generating a native - * pointer register for an SH-2 pointer won't be forgotten in - * the fall-through case, causing the fall-through code to use - * uninitialized registers and potentially crash.) */ - if (target == start_address - 4) { - unsigned int target_insn = fetch[2+(disp/2)]; - if ((target_insn & 0xF0FF) == 0x400B // JSR @Rn - || (target_insn & 0xF000) == 0xB000 // BSR label - || (target_insn & 0xF0FF) == 0x0003 // BSRF Rn - ) { - word_info[block_len] |= WORD_INFO_LOOP_JSR; - uint32_t false_target; - if (opcode_info & SH2_OPCODE_INFO_BRANCH_DELAYED) { - false_target = address+2; - } else { - false_target = address+4; - } - const uint32_t target_index = - (false_target - start_address) / 2; - is_local_branch = 1; - local_branch_target_index = target_index; - const uint32_t flag = 1 << (target_index % 32); - local_branch_is_new = !(is_branch_target[index/32] & flag); - is_branch_target[target_index/32] |= flag; - /* We don't set the OPTIMIZE_BRANCH_FALLTHRU variables - * because the branch itself does _not_ fall through; - * this branch target handling is only a hack to avoid - * overoptimization. */ - } - } -#endif - - /* Only record the branch in the lookup table if it's a forward - * branch. We allow backward branches to the beginning of the - * block (index == 0), but we don't add them to the table - * because they're handled specially--we insert a label before - * any precondition checks instead of adding one when we - * translate the instruction itself. */ - if (target > address) { - const uint32_t target_index = (target - start_address) / 2; - if (target_index < lenof(is_branch_target)*32) { - is_local_branch = 1; - local_branch_target_index = target_index; - const uint32_t flag = 1 << (target_index % 32); - if (is_branch_target[target_index/32] & flag) { - /* There's already another branch targeting the - * same instruction. After processing any delay - * slot, we'll need to clear any constants from - * the target's local constant table which differ - * from the current known register values. */ - local_branch_is_new = 0; - } else { - /* This is the first time we've seen this target; - * remember it in case we can fall through. */ -#ifdef OPTIMIZE_BRANCH_FALLTHRU - fallthru_target = target_index; - fallthru_source = block_len; -#endif - local_branch_is_new = 1; - } - is_branch_target[target_index/32] |= flag; - } - } - skip_branch_target_check:; // From branch optimization above - } - - /* If this is a BSR or a JSR to a known target, see whether it can - * be folded into the current block. */ - - if (optimization_flags & SH2_OPTIMIZE_FOLD_SUBROUTINES) { - - /* First check for PC-relative loads so we can track JSR - * target addresses. */ - if ((opcode & 0xB000) == 0x9000) { - const unsigned int n = opcode>>8 & 0xF; - const unsigned int disp = opcode & 0xFF; - if (opcode & 0x4000) { // MOV.L - const unsigned int offset = (address&2 ? 1 : 2) + 2*disp; - local_constant[n] = fetch[offset]<<16 | fetch[offset+1]; - } else { // MOV.W - const unsigned int offset = 2 + disp; - local_constant[n] = fetch[offset]; - } - } else { - if (opcode_info & SH2_OPCODE_INFO_SETS_R0) { - local_constant[0] = 1; - } - if (opcode_info & SH2_OPCODE_INFO_SETS_Rn) { - local_constant[opcode>>8 & 0xF] = 1; - } - if (opcode_info & (SH2_OPCODE_INFO_ACCESS_POSTINC - | SH2_OPCODE_INFO_ACCESS_PREDEC)) { - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - local_constant[opcode>>4 & 0xF] = 1; - } - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rn) { - local_constant[opcode>>8 & 0xF] = 1; - } - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_R15) { - local_constant[15] = 1; - } - } - } - - /* Now see if this is an optimizable call. */ - uint32_t target = 1; // 1 = not a subroutine call or unknown target - if ((opcode & 0xF000) == 0xB000) { // BSR label - int32_t disp = opcode & 0xFFF; - disp <<= 20; // Sign-extend - disp >>= 19; // And double - target = (address + 4) + disp; - } else if ((opcode & 0xF0FF) == 0x400B) { // JSR @Rn - const unsigned int n = opcode>>8 & 0xF; - if (local_constant[n]) { - target = local_constant[n]; - } - } - if (target != 1 - && optimize_fold_subroutine(state, start_address, address, - target, fetch[1], - pointer_map, local_constant, - &subroutine_native[block_len]) - ) { - word_info[block_len] |= WORD_INFO_FOLDABLE; - subroutine_target[block_len] = target; -#ifdef OPTIMIZE_LOOP_REGISTERS - /* Subroutine folding and loop optimization don't currently - * play together well, so disable loop optimization if we - * fold a subroutine into the current block. (FIXME: this - * is a loss if the loop has already ended; better to just - * not fold and break the block instead in that case?) */ - is_loop = 0; - can_optimize_loop = 0; -#endif - } - - } // if (optimization_flags & SH2_OPTIMIZE_FOLD_SUBROUTINES) - - /* Check whether this is an instruction with a delay slot. */ - - delay = ((opcode_info & SH2_OPCODE_INFO_BRANCH_DELAYED) != 0); - - /* Check whether this is an unconditional branch or similar - * instruction; when we get past its delay slot (if applicable), - * we'll check whether to end the block. */ - - at_uncond_branch |= - (((opcode_info & SH2_OPCODE_INFO_BRANCH_UNCOND) - && !(word_info[block_len] & WORD_INFO_FOLDABLE)) - || opcode == 0x001B); // SLEEP - - /* If we have a pending local branch, update the local constant - * table as appropriate. */ - - if (is_local_branch && !delay) { - is_local_branch = 0; - unsigned int reg; - if (local_branch_is_new) { - for (reg = 0; reg < 16; reg++) { - local_constant_per_insn[local_branch_target_index][reg] - = local_constant[reg]; - } - } else { - for (reg = 0; reg < 16; reg++) { - if (local_constant_per_insn[local_branch_target_index][reg] != local_constant[reg]) { - local_constant_per_insn[local_branch_target_index][reg] = 1; - } - } - } - } - - /* If we have a pending branch and we're past its delay slot - * (if applicable), update loop optimization state. */ - -#ifdef OPTIMIZE_LOOP_REGISTERS - at_branch |= - at_uncond_branch || (opcode_info & SH2_OPCODE_INFO_BRANCH_COND); - if (at_branch && !delay) { - at_branch = 0; - if (at_loop_branch) { - final_live_registers = loop_live_registers; - final_load_registers = loop_load_registers; - final_changed_registers = loop_changed_registers; - unsigned int reg; - for (reg = 0; reg < 16; reg++) { - if (pointer_map[reg] != reg) { - loop_invariant_pointers &= ~(1 << reg); - } - } - final_invariant_pointers = loop_invariant_pointers; - at_loop_branch = 0; - } -# if !defined(TRACE) && !defined(TRACE_STEALTH) && !defined(TRACE_LITE) - /* If this is a branch back to the beginning of the loop from - * the middle, followed by more loop body code, then any - * registers first set below this branch will still have the - * proper value on exit from the loop, assuming an exception - * handler interrupting the loop doesn't try to alter or rely - * on the loop's state. But this will cause traces (including - * TRACE_LITE) to report invalid register contents if the - * early branch is taken and stops due to the cycle limit - * before the register has been set at least once, so if we're - * tracing, we make an exception to our "don't change behavior - * with TRACE_STEALTH/TRACE_LITE" rule and set the noload - * register set here. If we're _not_ tracing, we omit this - * "else" and let the noload registers continue to accumulate. */ - else -# endif - if (!loop_noload_registers_set) { - loop_noload_registers = loop_changed_registers; - loop_noload_registers_set = 1; - } - } // if (at_branch && !delay) -#endif // OPTIMIZE_LOOP_REGISTERS - - /* If this is an instruction that loads SR (LDC ...,SR), terminate - * the block after the next instruction (since the SH-2 ignores - * interrupts between LDC and the following instruction--SH7604 - * manual page 76, section 4.6.2) to allow any potentially unmasked - * interrupts to be recognized. While the other LD[CS]/ST[CS] - * instructions also ignore interrupts for the following - * instruction, we don't terminate the block for them anyway, so - * we don't worry about them here. */ - - if ((opcode & 0xF0FF) == 0x4007 || (opcode & 0xF0FF) == 0x400E) { -#ifdef JIT_ACCURATE_LDC_SR_TIMING - if (block_len+1 >= max_len) { - /* We'll hit the block size limit after this instruction, - * so terminate the block _before_ the LDC and include it - * in the next block. If the following instruction is in a - * blacklisted address, we'll end up interpreting the LDC, - * which is fine too. */ - goto abort_scan; - } else { - end_block_next = 1; - } -#else - end_block = 1; -#endif - } - - /* If this instruction is the target of a preceding fall-through - * branch, update the word_info[] and is_branch_target[] tables - * to reflect that. - * - * IMPORTANT: Once this code is executed, it is CRITICAL that this - * instruction be included in the scanned block, or incorrect code - * will result! See the earlier code that sets at_fallthru for an - * explanation. */ - - if (at_fallthru) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Marking branch at 0x%08X as fall-through", - start_address + saved_fallthru_source*2); -#endif - word_info[saved_fallthru_source] |= WORD_INFO_FALLTHRU; - /* Also clear the branch target flag so we don't set a label - * (which would break the basic unit and cause an optimization - * barrier). */ - const uint32_t flag = 1 << (saved_fallthru_target % 32); - is_branch_target[saved_fallthru_target/32] &= ~flag; - } - - /* If we have a pending unconditional branch and we're past its - * delay slot (if applicable), check whether there are any branch - * targets beyond this address which could be part of the same - * block (i.e. are within the instruction limit as well as - * JIT_MAX_INSN_GAP). If there are, we'll continue translating at - * the first such address; otherwise we'll end the block here. - * (In !JIT_ALLOW_DISTANT_BRANCHES mode, we always stop unless the - * next instruction is a branch target.) */ - - if (at_uncond_branch && !delay && !end_block) { - at_uncond_branch = 0; - index = block_len + 1; - - /* If variable shift optimization is enabled, allow a BRAF - * followed by one or more shift/rotate instructions to fall - * through to the instruction following the shift sequence. */ -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if ((fetch[-1] & 0xF0FF) == 0x0023) { // BRAF - unsigned int next_opcode = fetch[1]; - if ((next_opcode & 0xF0DE) == 0x4000 // SH[LA][LR] - || (next_opcode & 0xF0FE) == 0x4004 // ROT[LR] - ) { - const unsigned int shift_opcode = next_opcode; - do { - address += 2; - fetch++; - block_len++; - next_opcode = fetch[1]; - } while (next_opcode == shift_opcode); - } - } else -#endif - - if (!(is_branch_target[index/32] & (1 << (index % 32)))) { - end_block = 1; -#ifdef JIT_ALLOW_DISTANT_BRANCHES - /* See below for why the "-1" on max_len */ - const uint32_t gap_limit = block_len + JIT_MAX_INSN_GAP; - const uint32_t index_limit = (max_len-1 < gap_limit - ? max_len-1 : gap_limit); - const uint32_t address_limit = - start_address + (index_limit * 2); - const uint32_t first_valid = - (now_in_delay ? address : address+2); - index = (first_valid - start_address) / 2; - /* Search for a non-empty word, then find the first bit set - * in that word */ - uint32_t mask = 0xFFFFFFFF << (index % 32); - index /= 32; - for (; index < lenof(is_branch_target); index++) { - if (is_branch_target[index] & mask) { - break; - } - mask = 0xFFFFFFFF; - } - if (index < lenof(is_branch_target)) { - mask &= is_branch_target[index]; - index *= 32; - while (!(mask & 1)) { - mask >>= 1; - index++; - } - const uint32_t first_target = start_address + index*2; - if (first_target < address_limit) { - int skip_bytes = first_target - (address+2); - if (skip_bytes > 0) { - address += skip_bytes; - fetch += skip_bytes / 2; - block_len += skip_bytes / 2; - } - end_block = 0; - } - } -#endif - } // if next insn is not a branch target - } // if (at_uncond_branch && !delay && !end_block) - - /* Check whether we've hit the instruction limit. To avoid the - * potential for problems arising from an instruction with a delay - * slot crossing the limit, we stop one instruction early; if this - * instruction had a delay slot, the delay slot will still fall - * within the limit. (We could also explicitly check against - * (max_len+delay), but this way is both simpler and marginally - * faster.) However, if we're stopping after the following - * instruction due to an LDC SR, don't break early here. */ - - if (!end_block && !end_block_next && block_len+2 >= max_len) { -#ifdef JIT_DEBUG - DMSG("WARNING: Terminating block 0x%08X after 0x%08X due to" - " instruction limit (%d insns) or blacklist", - start_address, delay ? address+2 : address, max_len); -#endif - end_block = 1; - } - -#ifdef OPTIMIZE_VARIABLE_SHIFTS - - /* If this opcode begins a variable shift instruction sequence, - * skip the remaining instructions in the sequence. (Normally we - * don't alter scanning behavior for optimizations, but since - * variable shift sequences involve branches, we want to avoid - * marking the following instruction as a branch target--thus - * creating an optimization barrier--when the branches will be - * eliminated anyway.) However, we skip sequences starting with - * BRAF, since we handle them separately. */ - - if (!now_in_delay && (opcode & 0xF0FF) != 0x0023) { - unsigned int count_reg, count_max, shift_reg, type; - const uint8_t *cycles; - const unsigned int num_insns = - can_optimize_variable_shift(fetch, address, &count_reg, - &count_max, &shift_reg, &type, - &cycles); - if (num_insns) { - block_len += num_insns - 1; - fetch += num_insns - 1; - address += (num_insns - 1) * 2; - } - } - -#endif - - } // for (; !end_block || delay; address += 2, fetch++, block_len++) - - abort_scan: - - /* Record the final set of entry registers used as pointers. */ - - pointer_used &= 0xFFFF; - -#ifdef OPTIMIZE_LOOP_REGISTERS - /* If this block is a loop, update loop_*_registers with the values - * found at the end of the loop body, so we don't unnecessarily fix - * SH-2 registers that aren't used in the body of the loop; also add - * registers changed after any non-loop branch to the set of registers - * that must be preloaded. Otherwise, there's no point in attempting - * loop optimization, so clear the flag. */ - - if (is_loop) { - loop_live_registers = final_live_registers; - loop_load_registers = final_load_registers; - loop_changed_registers = final_changed_registers; - loop_invariant_pointers = final_invariant_pointers; - if (loop_noload_registers_set) { - loop_load_registers |= - (loop_changed_registers & ~loop_noload_registers); - } - } else { - can_optimize_loop = 0; - } -#endif - - /* All done! */ - return block_len; -} - -/*-----------------------------------------------------------------------*/ - -/** - * optimize_pointers: Check the current instruction to determine whether - * it accesses memory through a pointer register or modifies a register - * assumed to be a pointer. Helper function for scan_block(). - * - * [Parameters] - * start_address: Start address of block, or 1 for subroutine fold checks - * address: Address of current instruction - * opcode: Opcode of current instruction - * opcode_info: Information about current instruction - * pointer_map: pointer_map[] array pointer from scan_block() - * [Return value] - * None - */ -static inline void optimize_pointers( - uint32_t start_address, uint32_t address, unsigned int opcode, - uint32_t opcode_info, uint8_t pointer_map[16]) -{ - const unsigned int index = (address - start_address) / 2; - if (start_address != 1 - && (is_data_pointer_load[index/32] & (1 << (index % 32))) - ) { - - if ((opcode & 0xFF00) == 0xC700) { // MOVA - pointer_map[0] = 30; -#ifdef JIT_DEBUG_VERBOSE - DMSG("%08X marked as data pointer load for R0", address); -#endif - } else { - const unsigned int n = opcode>>8 & 0xF; - pointer_map[n] = 30; -#ifdef JIT_DEBUG - if (!(opcode_info & SH2_OPCODE_INFO_SETS_Rn)) { - DMSG("WARNING: %08X marked as data pointer load but does not" - " set Rn!", address); -# ifdef JIT_DEBUG_VERBOSE - } else { - DMSG("%08X marked as data pointer load for R%u", address, n); -# endif - } -#endif - } - - } else if ((opcode & 0xF00F) == 0x6003) { // MOV Rm,Rn - - const unsigned int n = opcode>>8 & 0xF; - const unsigned int m = opcode>>4 & 0xF; - pointer_map[n] = pointer_map[m]; - - } else if ((opcode & 0xFF00) == 0xC700) { // MOVA @(disp,PC),R0 - - pointer_map[0] = 30; - - } else if ((opcode & 0xF000) == 0x7000) { // ADD #imm,Rn - - /* This only modifies Rn by a small, fixed amount, so assume the - * pointer is still valid and don't clear pointer_map[n]. */ - - } else if ((opcode & 0xF00F) == 0x3008) { // SUB Rm,Rn - - const unsigned int m = opcode>>4 & 0xF; - const unsigned int n = opcode>>8 & 0xF; - if (pointer_map[m] == 31) { - /* If we're subtracting a non-pointer from a pointer, assume - * it's a pointer adjustment that leaves the pointer in Rn - * valid. (If Rn is already not a pointer, we don't need to - * do anything in the first place.) */ - } else { - pointer_map[n] = 31; - } - - } else if ((opcode & 0xF00F) == 0x300C) { // ADD Rm,Rn - - const unsigned int m = opcode>>4 & 0xF; - const unsigned int n = opcode>>8 & 0xF; - if (pointer_map[m] == 31) { - /* Like SUB Rm,Rn, we ignore ADD Rm,Rn where Rm is not a - * pointer on the assumption that it's a pointer adjustment. */ - } else if (pointer_map[n] == 31) { - /* Addition is commutative, unlike subtraction, so we could - * also have the case where Rm is a pointer and Rn is an - * adjustment, leaving a pointer value in Rn. Treat this case - * like MOV Rm,Rn where Rm is a pointer. */ - pointer_map[n] = pointer_map[m]; - } else { - pointer_map[n] = 31; - } - - } else { - - const unsigned int m = opcode>>4 & 0xF; - const unsigned int n = opcode>>8 & 0xF; - - if (opcode_info & SH2_OPCODE_INFO_SETS_R0) { - pointer_map[0] = 31; - } - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - pointer_used |= 1 << pointer_map[m]; - } else if (opcode_info & SH2_OPCODE_INFO_ACCESSES_R0_Rm) { - if (pointer_map[0] == 30 - || (pointer_map[0] != 31 && (pointer_regs & 1<>8 & 0xF; - const int m = opcode>>4 & 0xF; - if (pointer_map[n] == 31 - || (pointer_map[n] != 30 && !(pointer_regs & (1<>8 & 0xF; - const unsigned int Rm = opcode>>4 & 0xF; - /* And other register indices */ - const unsigned int R0 = 0; - const unsigned int R15 = 15; - const unsigned int SR = state_cache_index(offsetof(SH2State,SR)); - const unsigned int GBR = state_cache_index(offsetof(SH2State,GBR)); - const unsigned int VBR = state_cache_index(offsetof(SH2State,VBR)); - const unsigned int MACH= state_cache_index(offsetof(SH2State,MACH)); - const unsigned int MACL= state_cache_index(offsetof(SH2State,MACL)); - const unsigned int PR = state_cache_index(offsetof(SH2State,PR)); - #define SR_GBR_VBR(x) ((x)==0 ? SR : (x)==1 ? GBR : VBR) - #define MACH_MACL_PR(x) ((x)==0 ? MACH : (x)==1 ? MACL : PR) - - if ((opcode & 0xF00F) == 0x0002) { // STC ...,Rn - this_used = 1<> 9) & 3]; -# endif - const uint32_t skip_index = ((target-2) - start_address) / 2; - if (!(is_branch_target[skip_index/32] & (1<<(skip_index%32)))) { - const unsigned int skipped_insn = fetch[(opcode & 0x400) ? 2 : 1]; - if ((skipped_insn & 0xF00F) == 0x6003 // MOV Rm,Rn - || (skipped_insn & 0xF000) == 0x7000 // ADD #imm,Rn - || (skipped_insn & 0xF000) == 0xE000 // MOV #imm,Rn - ) { - word_info[(address - start_address) / 2] |= WORD_INFO_SELECT; -# ifdef JIT_DEBUG_VERBOSE - DMSG("Converted %s to SELECT at %08X", mnemonic, address); -# endif - return 1; -# ifdef JIT_DEBUG_VERBOSE - } else { - DMSG("Failed to convert %s to SELECT at %08X (skipped opcode" - " is %04X)", mnemonic, address, skipped_insn); -# endif - } -# ifdef JIT_DEBUG_VERBOSE - } else { - DMSG("Failed to convert %s to SELECT at %08X (skipped instruction" - " at %08X is a branch target)", mnemonic, address, target-2); -# endif - } - } - return 0; -} - -#endif // OPTIMIZE_BRANCH_SELECT - -/*-----------------------------------------------------------------------*/ - -/** - * optimize_fold_subroutine: Determine whether the code sequence starting - * at the SH-2 address "target" qualifies as a foldable subroutine. If so, - * update the pointer_map[] array with any changes as a result of the - * subroutine. - * - * [Parameters] - * state: Processor state block pointer - * start_address: Start address of block - * address: Address of subroutine call - * target: Target address of subroutine call - * delay_slot: Instruction word in delay slot of subroutine call - * pointer_map: pointer_map[] array pointer from scan_block() - * local_constant: local_constant[] array pointer from scan_block() - * native_ret: Pointer to variable to receive native implementation - * function address if the routine is to be folded - * using a native implementation, NULL if the routine - * is to be folded by translating instructions - * [Return value] - * Nonzero if subroutine is foldable, else zero - */ -static int optimize_fold_subroutine( - SH2State *state, const uint32_t start_address, uint32_t address, - const uint32_t target, const uint16_t delay_slot, uint8_t pointer_map[16], - uint32_t local_constant[16], SH2NativeFunctionPointer *native_ret) -{ - const uint16_t *fetch_base = (const uint16_t *)fetch_pages[target >> 19]; - if (fetch_base == NULL) { - return 0; // Unfetchable, therefore unoptimizable - } - const uint16_t *fetch = - (const uint16_t *)((uintptr_t)fetch_base + target); - const uint16_t * const start = fetch; - const uint16_t * const limit = - fetch + OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH + 2; - - /* First see if there's a native implementation which we can call. */ - - if (manual_optimization_callback) { - ignore_optimization_hints = 1; - const unsigned int hand_tuned_len = - (*manual_optimization_callback)(state, target, fetch, - native_ret, 1); - ignore_optimization_hints = 0; - if (hand_tuned_len > 0) { - if (*native_ret == NULL) { - return 0; // Folding was refused by the callback. - } -#ifdef JIT_DEBUG_VERBOSE - DMSG("Using hand-tuned code to fold subroutine at 0x%08X", target); -#endif - /* We assume all of R0-R7 have been destroyed. */ - unsigned int reg; - for (reg = 0; reg < 8; reg++) { - pointer_map[reg] = 31; - local_constant[reg] = 1; - } - return 1; - } - } - - /* Make a local copy of optimization state data, so we can revert if - * we discover that the subroutine can't be optimized. */ - - uint8_t saved_pointer_map[16]; - memcpy(saved_pointer_map, pointer_map, 16); - const uint16_t saved_pointer_used = pointer_used; - - /* Scan the delay slot, then each instruction in the subroutine. - * Branches (or similar instructions) are not permitted in delay - * slots, so we assume the instruction is a simple one. */ - - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - optimize_pointers(start_address, address+2, delay_slot, - get_opcode_info(delay_slot), pointer_map); - } - - for (address = target; - !(fetch >= start+2 && fetch[-2] == 0x000B); - address += 2, fetch++ - ) { - if (fetch > limit) { - goto fail; // Subroutine is too long - } - const uint16_t opcode = *fetch; - const uint32_t opcode_info = get_opcode_info(opcode); - if (opcode == 0x000B) { // RTS - /* Ignore; we'll catch it after the delay slot */ - } else if (opcode_info & (SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_COND)) { - goto fail; // Branches break optimization - } else if ((optimization_flags & SH2_OPTIMIZE_POINTERS_MAC) - && (opcode & 0xB00F) == 0x000F) { // MAC.[WL] - const int n = opcode>>8 & 0xF; - const int m = opcode>>4 & 0xF; - if (pointer_map[n] == 31 - || (pointer_map[n] != 30 && !(pointer_regs & (1<running = 1; - -#ifdef JIT_PROFILE - const uint32_t start_cycles = state->cycles; -#endif - -#ifdef JIT_DEBUG_INTERPRET_RTL - -# ifdef JIT_PROFILE - entry->exec_time += -# endif - rtl_execute_block(entry->rtl, state); - -#else // !JIT_DEBUG_INTERPRET_RTL - - const void (*native_code)(SH2State *state) = entry->native_code; - -# ifdef JIT_PROFILE - /* For systems that have an efficient way to measure execution time - * (such as a performance counter register), we could use that to - * update entry->exec_time. On the PSP, the MIPS Count register is - * only accessible in kernel mode, so we're stuck with using a syscall - * to a kernel routine that costs hundreds of cycles (where a short - * block of code may finish in as few as 10 cycles), and we can't even - * get a cycle-accurate count. Oh well... it's better than nothing. */ -# if defined(PSP) - const uint32_t start = sceKernelGetSystemTimeLow(); -# endif -# endif - (*native_code)(state); -# ifdef JIT_PROFILE -# if defined(PSP) - entry->exec_time += sceKernelGetSystemTimeLow() - start; -# else - entry->exec_time++; // Default is to just count each call as 1 time unit -# endif -# endif - -#endif // JIT_DEBUG_INTERPRET_RTL - -#ifdef JIT_PROFILE - entry->call_count++; - entry->cycle_count += state->cycles - start_cycles; -#endif - - entry->running = 0; -} - -/*************************************************************************/ - -/** - * decode_insn: Decode a single SH-2 instruction. Implements - * translate_insn() using the shared decoder core. - * - * [Parameters] - * fetch: Pointer to instruction to decode - * state: SH-2 processor state - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * recursing: Nonzero if this is a recursive decode, else zero - * is_last: Nonzero if this is the last instruction of a recursive - * decode, else zero - * [Return value] - * Decoded SH-2 opcode (nonzero) on success, zero on error - * [Notes] - * Since the opcode 0x0000 is invalid and scan_block() prevents invalid - * opcodes from being included in a block to be translated, the return - * value of this routine will always be nonzero on success. - */ - -#define DECODE_INSN_INLINE inline -#define DECODE_INSN_PARAMS \ - const uint16_t *fetch, SH2State *state, JitEntry *entry, \ - const unsigned int state_reg, const int recursing, const int is_last - -#ifdef TRACE -# define TRACE_WRITEBACK_FOR_RECURSIVE_DECODE \ - ASSERT(writeback_state_cache(entry, state_reg, 1)) -#else -# define TRACE_WRITEBACK_FOR_RECURSIVE_DECODE /*nothing*/ -#endif -#define RECURSIVE_DECODE(address,is_last) do { \ - const uint32_t saved_PC = jit_PC; \ - jit_PC = (address); \ - if (UNLIKELY(!translate_insn(state, entry, state_reg, 1, (is_last)))) { \ - return 0; \ - } \ - TRACE_WRITEBACK_FOR_RECURSIVE_DECODE; \ - jit_PC = saved_PC; \ -} while (0) - -#include "sh2-core.i" - -/*-----------------------------------------------------------------------*/ - -/** - * translate_insn: Translate a single SH-2 instruction at the current - * translation address into one or more equivalent RTL instructions. - * - * [Parameters] - * state: SH-2 processor state - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * recursing: Nonzero if this is a recursive decode (for inserting - * copies of instructions from other locations), else zero - * is_last: Nonzero if this is the last instruction in a recursively - * decoded sequence, else zero - * [Return value] - * Nonzero on success, zero on error - */ -static int translate_insn(SH2State *state, JitEntry *entry, - unsigned int state_reg, int recursing, int is_last) -{ - /* Get a fetch pointer for the current PC */ - const uint16_t *fetch_base = (const uint16_t *)fetch_pages[cur_PC >> 19]; - PRECOND(fetch_base != NULL, return 0); - const uint16_t *fetch = (const uint16_t *)((uintptr_t)fetch_base + cur_PC); - - /* Process the instruction */ - const unsigned int opcode = - decode_insn(fetch, state, entry, state_reg, recursing, is_last); - if (UNLIKELY(!opcode)) { - return 0; - } - - return 1; -} - -/*************************************************************************/ - -#ifdef JIT_BRANCH_PREDICT_STATIC - -/** - * add_static_branch_terminator: Add a terminator for a static branch when - * using static branch prediction. Code will be added to retrieve or look - * up the target address and branch to it if possible. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * address: Branch target address (in SH-2 address space) - * index: entry->static_predict[] index to use for static prediction - * [Return value] - * Nonzero on success, zero on failure - */ -static int add_static_branch_terminator(JitEntry *entry, - unsigned int state_reg, - uint32_t address, unsigned int index) -{ - CREATE_LABEL(label_not_predicted); - CREATE_LABEL(label_return); - - /* Load the address of the BranchTargetInfo we're using */ - DEFINE_REG(bti); - MOVEA(bti, &entry->static_predict[index]); - - /* Load relevant values early to mitigate load stalls (very MIPSy) */ - DEFINE_REG(predicted_entry); - LOAD_PTR(predicted_entry, bti, offsetof(BranchTargetInfo,entry)); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DECLARE_REG(cycle_limit); - LOAD_STATE_ALLOC(cycle_limit, cycle_limit); - DEFINE_REG(native_target); - LOAD_PTR(native_target, bti, offsetof(BranchTargetInfo,native_target)); - DEFINE_REG(can_continue); - SLTS(can_continue, cycles, cycle_limit); - - /* If we already have a prediction, jump to it (or return if we're out - * of cycles) */ - GOTO_IF_Z(label_not_predicted, predicted_entry); - STORE_STATE_PTR(current_entry, predicted_entry); - GOTO_IF_Z(label_return, can_continue); - RETURN_TO(native_target); - - /* Look up the translated block for this address, then return. For - * simplicity (and to keep code size down), we don't try too hard to - * optimize this case; we'll make up the time in future runs */ - DEFINE_LABEL(label_not_predicted); - DEFINE_REG(addr_reg); - MOVEI(addr_reg, address); - DEFINE_REG(ptr_update_branch_target); - MOVEA(ptr_update_branch_target, update_branch_target); - DEFINE_REG(new_entry); - CALL(new_entry, bti, addr_reg, ptr_update_branch_target); - STORE_STATE_PTR(current_entry, new_entry); - GOTO_IF_Z(label_return, new_entry); - DEFINE_REG(new_target); -#ifdef JIT_DEBUG_INTERPRET_RTL - LOAD_PTR(new_target, new_entry, offsetof(JitEntry,rtl)); -#else - LOAD_PTR(new_target, new_entry, offsetof(JitEntry,native_code)); -#endif - STORE_PTR(bti, new_target, offsetof(BranchTargetInfo,native_target)); - - DEFINE_LABEL(label_return); - RETURN(); - - clear_state_cache(0); - return 1; -} - -#endif // JIT_BRANCH_PREDICT_STATIC - -/*************************************************************************/ - -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - -/** - * update_branch_target: Find the translated block, if any, corresponding - * to the given address and update the given branch target structure with - * the found block. - * - * [Parameters] - * bti: BranchTargetInfo structure to update - * address: Branch target address - * [Return value] - * Translated block found, or NULL if none was found - */ -static FASTCALL JitEntry *update_branch_target(BranchTargetInfo *bti, - uint32_t address) -{ - JitEntry *new_entry = jit_find(address); - if (new_entry) { - if (bti->entry) { - bti->next->prev = bti->prev; - bti->prev->next = bti->next; - } - bti->target = address; - bti->entry = new_entry; - bti->next = new_entry->pred_ref_head.next; - bti->prev = &new_entry->pred_ref_head; - bti->next->prev = bti; - bti->prev->next = bti; - } - return new_entry; -} - -#endif // JIT_BRANCH_PREDICTION_SLOTS > 0 - -/*************************************************************************/ -/************************ Other utility routines *************************/ -/*************************************************************************/ - -/** - * btcache_lookup: Search the branch target cache for the given SH-2 - * address. - * - * [Parameters] - * address: SH-2 address to search for - * [Return value] - * Corresponding RTL label, or zero if the address could not be found - */ -static uint32_t btcache_lookup(uint32_t address) -{ - /* Search backwards from the current instruction so we can handle short - * loops quickly; note that btcache_index is now pointing to where the - * _next_ instruction will go */ - const int current = (btcache_index + (lenof(btcache)-1)) % lenof(btcache); - int index = current; - do { - if (btcache[index].sh2_address == address) { - return btcache[index].rtl_label; - } - index--; - if (UNLIKELY(index < 0)) { - index = lenof(btcache) - 1; - } - } while (index != current); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * record_unresolved_branch: Record the given branch target and native - * offset in an empty slot in the unresolved branch table. If there are - * no empty slots, purge the oldest (lowest native offset) entry. - * - * [Parameters] - * entry: Block being translated - * sh2_target: Branch target address in SH2 address space - * target_label: RTL label number to be defined at branch target - * [Return value] - * Nonzero on success, zero on error - */ -static int record_unresolved_branch(const JitEntry *entry, uint32_t sh2_target, - unsigned int target_label) -{ - PRECOND(entry != NULL, return 0); - - int oldest = 0; - int i; - for (i = 0; i < lenof(unres_branches); i++) { - if (unres_branches[i].sh2_target == 0) { - oldest = i; - break; - } else if (unres_branches[i].target_label - < unres_branches[oldest].target_label) { - oldest = i; - } - } - if (UNLIKELY(unres_branches[oldest].sh2_target != 0)) { -#ifdef JIT_DEBUG - DMSG("WARNING: Unresolved branch table full, dropping branch to PC" - " 0x%08X (RTL label %u)", unres_branches[oldest].sh2_target, - unres_branches[oldest].target_label); -#endif - /* Add a JUMP fallback for this entry in the middle of the code - * stream, since we have nowhere else to put it; use a temporary - * label to branch past it in the normal code flow */ - DEFINE_REG(temp_reg); - CREATE_LABEL(temp_label); - GOTO_LABEL(temp_label); - DEFINE_LABEL(unres_branches[oldest].target_label); - RETURN(); - DEFINE_LABEL(temp_label); - } - unres_branches[oldest].sh2_target = sh2_target; - unres_branches[oldest].target_label = target_label; - return 1; -} - -/*************************************************************************/ - -/** - * writeback_state_cache: Write all cached state block values to memory. - * Does nothing (and returns success) if OPTIMIZE_STATE_BLOCK is not - * defined. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * flush_fixed: Nonzero to flush dirty fixed-register fields to memory - * [Return value] - * Nonzero on success, zero on error - */ -static int writeback_state_cache(const JitEntry *entry, unsigned int state_reg, - int flush_fixed) -{ - PRECOND(entry != NULL, return 0); - -#ifdef OPTIMIZE_STATE_BLOCK - - if (dirty_SR_T) { - const int index_SR = state_cache_index(offsetof(SH2State,SR)); - DECLARE_REG(old_SR); - if (state_cache[index_SR].rtlreg) { - old_SR = state_cache[index_SR].rtlreg; - } else { - ALLOC_REG(old_SR); - LOAD_W(old_SR, state_reg, offsetof(SH2State,SR)); - } - DECLARE_REG(new_SR); - if (state_cache[index_SR].fixed) { - new_SR = old_SR; - } else { - ALLOC_REG(new_SR); - } - BFINS(new_SR, old_SR, cached_SR_T, SR_T_SHIFT, 1); - state_cache[index_SR].rtlreg = new_SR; - state_dirty |= 1 << index_SR; - dirty_SR_T = 0; - } - - unsigned int index; - for (index = 0; index < lenof(state_cache); index++) { - if ((state_dirty & (1 << index)) - || (flush_fixed && state_cache[index].flush) - ) { - DECLARE_REG(rtlreg); - if (index == state_cache_index(offsetof(SH2State,PC)) - && cached_PC != 0 - ) { - ALLOC_REG(rtlreg); - MOVEI(rtlreg, cached_PC); - cached_PC = 0; - state_cache[index].rtlreg = rtlreg; - state_cache[index].offset = 0; - } else if (state_cache[index].offset != 0) { - if (state_cache[index].fixed) { - rtlreg = state_cache[index].rtlreg; - } else { - ALLOC_REG(rtlreg); - } - ADDI(rtlreg, state_cache[index].rtlreg, - state_cache[index].offset); - state_cache[index].rtlreg = rtlreg; - if (index < 16) { - pointer_status[index].rtl_ptrreg = 0; - } - if (index == 15 && stack_pointer) { - ADDI(stack_pointer, stack_pointer, - state_cache[index].offset); - } - state_cache[index].offset = 0; - } else { - rtlreg = state_cache[index].rtlreg; - } - if (!state_cache[index].fixed || flush_fixed) { - STORE_W(state_reg, rtlreg, state_cache_field(index)); - state_dirty &= ~(1 << index); - if (index == state_cache_index(offsetof(SH2State,PC))) { - stored_PC = 0; - } -# ifdef TRACE_STEALTH - if (index < 23) { - APPEND(NOP, 0, 0xB0000000 | index<<16, 0, 0); - } -# endif - } - } - } - -#endif // OPTIMIZE_STATE_BLOCK - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * clear_state_cache: Clear all cached state block registers. Does - * nothing if OPTIMIZE_STATE_BLOCK is not defined. - * - * [Parameters] - * clear_fixed: Nonzero to clear fixed registers from the cache as well, - * zero to leave them in the cache - * [Return value] - * None - */ -static void clear_state_cache(int clear_fixed) -{ -#ifdef OPTIMIZE_STATE_BLOCK - if (clear_fixed) { -# ifdef JIT_DEBUG - if (UNLIKELY(state_dirty) || UNLIKELY(dirty_SR_T)) { - DMSG("WARNING: Clearing dirty state fields! (dirty=%08X SR_T=%d)", - state_dirty, dirty_SR_T); - } -# endif - memset(state_cache, 0, sizeof(state_cache)); - state_dirty = 0; - } else { - unsigned int index; -# ifdef JIT_DEBUG - uint32_t nonfixed = 0; - for (index = 0; index < lenof(state_cache); index++) { - if (!state_cache[index].fixed) { - nonfixed |= 1<>3 & 7) >= 5 ? 0 : (CMDCOLR&0x7FF)<<16) \ - | ((CMDPMOD>>3 & 15) << 27) | 0x80000000) -#define HASHKEY_TEXTURE_TILE(tilesize,address,pixfmt,color_base,color_ofs,transparent) \ - (tilesize>>4 | (address>>3 & ~1) \ - | (pixfmt >= 3 ? 0 : ((color_ofs|color_base)&0x7FF)<<16) \ - | (pixfmt<<27) | (transparent<<30)) -#define HASH_TEXTURE(key) ((key) % TEXCACHE_HASH_SIZE) - -/*************************************************************************/ - -/* Local routine declarations */ - -static TexInfo *alloc_texture(uint32_t key, uint32_t hash, int persistent); -static TexInfo *find_texture(uint32_t key, unsigned int *hash_ret); -static void load_texture(const TexInfo *tex); -static void *alloc_pixdata(uint32_t size); -static void *alloc_vram(uint32_t size); - -/* Force GCC to inline the texture/CLUT caching functions, to save the - * expense of register save/restore and optimize constant cases - * (particularly for tile loading). */ - -__attribute__((always_inline)) static inline int cache_sprite( - TexInfo *tex, uint16_t CMDSRCA, uint16_t CMDPMOD, uint16_t CMDCOLR, - uint16_t pixel_mask, unsigned int width, unsigned int height, int rofs, - int gofs, int bofs, int persistent); -__attribute__((always_inline)) static inline int cache_tile( - TexInfo *tex, uint32_t address, unsigned int width, unsigned int height, - unsigned int stride, int array, int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, int rofs, int gofs, int bofs, - int persistent); - -__attribute__((always_inline)) static inline int alloc_texture_pixels( - TexInfo *tex, unsigned int width, unsigned int height, unsigned int psm, - int persistent); - -__attribute__((always_inline)) static inline int gen_clut( - TexInfo *tex, unsigned int size, uint32_t color_base, uint8_t color_ofs, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int can_shadow, int persistent); -__attribute__((always_inline)) static inline int gen_clut_t4ind( - TexInfo *tex, const uint8_t *color_lut, uint16_t pixel_mask, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int persistent); - -__attribute__((always_inline)) static inline int cache_texture_t4( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride); -__attribute__((always_inline)) static inline int cache_texture_t8( - TexInfo *tex, const uint8_t *src, uint8_t pixmask, - unsigned int width, unsigned int height, unsigned int stride); -__attribute__((always_inline)) static inline int cache_texture_t16( - TexInfo *tex, const uint8_t *src, uint32_t color_base, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent); -__attribute__((always_inline)) static inline int cache_texture_16( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent); -__attribute__((always_inline)) static inline int cache_texture_32( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent); - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * texcache_reset: Reset the texture cache, including all persistent - * textures. - * - * [Parameters] - * None - * [Return value] - * None - */ -void texcache_reset(void) -{ - memset(tex_table_persistent, 0, sizeof(tex_table_persistent)); - memset(tex_table_transient, 0, sizeof(tex_table_transient)); - tex_buffer_nextfree_persistent = 0; - tex_buffer_nextfree_transient = lenof(tex_buffer) - 1; - pixdata_cache_next_alloc = 0; - - unsigned int i; - for (i = 0; i < lenof(clut_cache); i++) { - unsigned int j; - for (j = 0; j < lenof(clut_cache[i]); j++) { - clut_cache[i][j].size = 0; - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_clean: Clean all transient textures from the texture cache. - * Persistent textures are not affected. - * - * [Parameters] - * None - * [Return value] - * None - */ -void texcache_clean(void) -{ - memset(tex_table_transient, 0, sizeof(tex_table_transient)); - tex_buffer_nextfree_transient = lenof(tex_buffer) - 1; - - unsigned int i; - for (i = 0; i < lenof(clut_cache); i++) { - unsigned int j; - for (j = 0; j < lenof(clut_cache[i]); j++) { - clut_cache[i][j].size = 0; - } - } -} - -/*************************************************************************/ - -/** - * texcache_cache_sprite: Cache the given sprite texture if it has not - * been cached already. Returns a texture key for later use in loading the - * texture. The texture width must be a multiple of 8. - * - * [Parameters] - * cmd: VDP1 command structure - * pixel_mask: Mask to apply to paletted pixel data - * width, height: Size of texture (in pixels) - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this frame only - * [Return value] - * Texture key (zero on error) - */ -uint32_t texcache_cache_sprite(const vdp1cmd_struct *cmd, - uint16_t pixel_mask, - unsigned int width, unsigned int height, - int persistent) -{ - const uint32_t tex_key = - HASHKEY_TEXTURE_SPRITE(cmd->CMDSRCA, cmd->CMDPMOD, cmd->CMDCOLR); - uint32_t tex_hash; - TexInfo *tex = find_texture(tex_key, &tex_hash); - - if (tex) { - /* Already cached, so just generate a CLUT if needed and return the - * texture key. */ - if (tex->clut_dynamic) { - const int transparent = !(cmd->CMDPMOD & 0x40); - const int endcodes = !(cmd->CMDPMOD & 0x80); - const uint32_t color_base = (Vdp2Regs->CRAOFB & 0x0070) << 4; - switch (cmd->CMDPMOD>>3 & 7) { - case 0: - gen_clut(tex, 16, (color_base + cmd->CMDCOLR) & 0x7F0, - cmd->CMDCOLR & 0x00F, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0xF) & pixel_mask) == pixel_mask, 0); - break; - case 1: - gen_clut_t4ind(tex, Vdp1Ram + (cmd->CMDCOLR << 3), pixel_mask, - vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, 0); - break; - case 2: - gen_clut(tex, 64, (color_base + cmd->CMDCOLR) & 0x7C0, - cmd->CMDCOLR & 0x03F, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0x3F) & pixel_mask) == pixel_mask, 0); - break; - case 3: - gen_clut(tex, 128, - (color_base + cmd->CMDCOLR) & 0x780, - cmd->CMDCOLR & 0x07F, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0x7F) & pixel_mask) == pixel_mask, 0); - break; - case 4: - gen_clut(tex, 256, (color_base + cmd->CMDCOLR) & 0x700, - cmd->CMDCOLR & 0x0FF, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0xFF) & pixel_mask) == pixel_mask, 0); - break; - } - } - return tex_key; - } // if (tex) - - tex = alloc_texture(tex_key, tex_hash, persistent); - if (UNLIKELY(!tex)) { - DMSG("Texture buffer full, can't cache"); - return 0; - } - if (UNLIKELY(!cache_sprite(tex, cmd->CMDSRCA, cmd->CMDPMOD, cmd->CMDCOLR, - pixel_mask, width, height, - vdp1_rofs, vdp1_gofs, vdp1_bofs, persistent))) { - if (persistent) { - tex_table_persistent[tex_hash] = tex->next; - tex_buffer_nextfree_persistent--; - return texcache_cache_sprite(cmd, pixel_mask, width, height, 0); - } else { - return 0; - } - } - - return tex_key; -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_load_sprite: Load the sprite texture indicated by the given - * texture key. - * - * [Parameters] - * key: Texture key returned by texcache_cache_sprite - * [Return value] - * None - */ -void texcache_load_sprite(uint32_t key) -{ - TexInfo *tex = find_texture(key, NULL); - if (UNLIKELY(!tex)) { - DMSG("No texture found for key %08X", (int)key); - return; - } - - load_texture(tex); -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_load_tile: Load the specified 8x8 or 16x16 tile texture into - * the GE registers for drawing, first caching the texture if necessary. - * - * [Parameters] - * tilesize: Pixel size (width and height) of tile, either 8 or 16 - * address: Tile data address within VDP2 RAM - * pixfmt: Tile pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -void texcache_load_tile(int tilesize, uint32_t address, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bofs, int persistent) -{ - const uint32_t tex_key = - HASHKEY_TEXTURE_TILE(tilesize, address, pixfmt, color_base, - color_ofs, transparent); - uint32_t tex_hash; - TexInfo *tex = find_texture(tex_key, &tex_hash); - - if (tex) { - if (tex->clut_dynamic) { - if (pixfmt == 0) { - gen_clut(tex, 16, - (color_base + color_ofs) & 0x7F0, color_ofs & 0x00F, - rofs, gofs, bofs, transparent, 0, 0, 0); - } else { // pixfmt == 1 - gen_clut(tex, 256, - (color_base + color_ofs) & 0x700, color_ofs & 0x0FF, - rofs, gofs, bofs, transparent, 0, 0, 0); - } - } - } else { // !tex - tex = alloc_texture(tex_key, tex_hash, persistent); - if (UNLIKELY(!tex)) { - DMSG("Texture buffer full, can't cache"); - return; - } - int ok; - if (tilesize == 16) { - ok = cache_tile(tex, address, 16, 16, 8, 2, pixfmt, - transparent, color_base, color_ofs, - rofs, gofs, bofs, persistent); - } else { - ok = cache_tile(tex, address, 8, 8, 8, 1, pixfmt, - transparent, color_base, color_ofs, - rofs, gofs, bofs, persistent); - } - if (UNLIKELY(!ok)) { - if (persistent) { - tex_table_persistent[tex_hash] = tex->next; - tex_buffer_nextfree_persistent--; - return texcache_load_tile(tilesize, address, pixfmt, - transparent, color_base, color_ofs, - rofs, gofs, bofs, 0); - } else { - return; - } - } - } // if (tex) - - /* Load the texture data (and color table, if appropriate). */ - load_texture(tex); -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_load_bitmap: Load the specified bitmap texture into the GE - * registers for drawing, first caching the texture if necessary. The - * texture width must be a multiple of 8. - * - * [Parameters] - * address: Bitmap data address within VDP2 RAM - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * pixfmt: Bitmap pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -void texcache_load_bitmap(uint32_t address, unsigned int width, - unsigned int height, unsigned int stride, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bofs, int persistent) -{ - const uint32_t tex_key = - HASHKEY_TEXTURE_TILE(8, address, pixfmt, color_base, - color_ofs, transparent); - uint32_t tex_hash; - TexInfo *tex = find_texture(tex_key, &tex_hash); - - if (tex) { - if (tex->clut_dynamic) { - if (pixfmt == 0) { - gen_clut(tex, 16, - (color_base + color_ofs) & 0x7F0, color_ofs & 0x00F, - rofs, gofs, bofs, transparent, 0, 0, 0); - } else { // pixfmt == 1 - gen_clut(tex, 256, - (color_base + color_ofs) & 0x700, color_ofs & 0x0FF, - rofs, gofs, bofs, transparent, 0, 0, 0); - } - } - } else { // !tex - tex = alloc_texture(tex_key, tex_hash, persistent); - if (UNLIKELY(!tex)) { - DMSG("Texture buffer full, can't cache"); - return; - } - if (UNLIKELY(!cache_tile(tex, address, width, height, stride, 1, - pixfmt, transparent, color_base, color_ofs, - rofs, gofs, bofs, persistent))) { - if (persistent) { - tex_table_persistent[tex_hash] = tex->next; - tex_buffer_nextfree_persistent--; - return texcache_load_bitmap(address, width, height, stride, - pixfmt, transparent, color_base, - color_ofs, rofs, gofs, bofs, 0); - } else { - return; - } - } - } // if (!tex) - - /* Load the texture data (and color table, if appropriate). */ - load_texture(tex); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * alloc_texture: Allocate a new texture entry and insert it into the hash - * table. The entry's data fields (other than those for hash table - * management) are _not_ initialized. - * - * [Parameters] - * key: Hash key for texture - * hash: Hash index for texture (== HASH_TEXTURE(key), passed in - * separately so precomputed values can be reused) - * persistent: Nonzero if a persistent texture, zero if a transient texture - * [Return value] - * Allocated texture entry, or NULL on failure (table full) - */ -static TexInfo *alloc_texture(uint32_t key, uint32_t hash, int persistent) -{ - if (persistent) { - if (UNLIKELY(tex_buffer_nextfree_persistent > tex_buffer_nextfree_transient)) { - return NULL; - } - TexInfo *tex = &tex_buffer[tex_buffer_nextfree_persistent++]; - tex->next = tex_table_persistent[hash]; - tex_table_persistent[hash] = tex; - tex->key = key; - return tex; - } else { - if (UNLIKELY(tex_buffer_nextfree_transient < tex_buffer_nextfree_persistent)) { - return NULL; - } - TexInfo *tex = &tex_buffer[tex_buffer_nextfree_transient--]; - tex->next = tex_table_transient[hash]; - tex_table_transient[hash] = tex; - tex->key = key; - return tex; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * find_texture: Return the texture corresponding to the given texture - * key, or NULL if no such texture is cached. - * - * [Parameters] - * key: Texture hash key - * hash_ret: Pointer to variable to receive hash index, or NULL if unneeded - * [Return value] - * Cached texture, or NULL if none - */ -static TexInfo *find_texture(uint32_t key, unsigned int *hash_ret) -{ - const uint32_t hash = HASH_TEXTURE(key); - if (hash_ret) { - *hash_ret = hash; - } - - TexInfo *tex; - for (tex = tex_table_persistent[hash]; tex != NULL; tex = tex->next) { - if (tex->key == key) { - return tex; - } - } - for (tex = tex_table_transient[hash]; tex != NULL; tex = tex->next) { - if (tex->key == key) { - return tex; - } - } - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * load_texture: Load the given texture into the GE texture registers. - * - * [Parameters] - * tex: Texture to load - * [Return value] - * None - */ -static void load_texture(const TexInfo *tex) -{ - if (tex->clut_address) { - guClutMode(GU_PSM_8888, 0, tex->clut_size-1, 0); - guClutLoad(tex->clut_size/8, tex->clut_address); - } - guTexFlush(); - guTexMode(tex->pixfmt, 0, 0, /*swizzled*/ 1); - guTexImage(0, tex->width, tex->height, tex->stride, tex->vram_address); -} - -/*************************************************************************/ - -/** - * alloc_pixdata: Allocate memory from the persistent pixel data cache - * buffer, returning a pointer to the area in the uncached address region - * (0x4nnnnnnn). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -static void *alloc_pixdata(uint32_t size) -{ - if (UNLIKELY(pixdata_cache_next_alloc + size > sizeof(pixdata_cache))) { - return NULL; - } - void *ptr = &pixdata_cache[pixdata_cache_next_alloc]; - pixdata_cache_next_alloc += (size + 63) & -64; - return (void *)((uint32_t)ptr | 0x40000000); -} - -/*-----------------------------------------------------------------------*/ - -/** - * alloc_vram: Allocate memory from the spare VRAM area, returning a - * pointer to the area in the uncached address region (0x4nnnnnnn). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -static void *alloc_vram(uint32_t size) -{ - void *ptr = display_alloc_vram(size); - if (UNLIKELY(!ptr)) { - return NULL; - } - return (void *)((uint32_t)ptr | 0x40000000); -} - -/*************************************************************************/ - -/** - * cache_sprite: Cache a texture from sprite (VDP1) memory. Implements - * caching code for texcache_cache_sprite(). - * - * [Parameters] - * tex: TexInfo structure for caching texture - * CMDSRCA, CMDPMOD, CMDCOLR: Values of like-named fields in VDP1 command - * pixel_mask: Mask to apply to paletted pixel data - * width, height: Size of texture (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_sprite( - TexInfo *tex, uint16_t CMDSRCA, uint16_t CMDPMOD, uint16_t CMDCOLR, - uint16_t pixel_mask, unsigned int width, unsigned int height, int rofs, - int gofs, int bofs, int persistent) -{ - const uint32_t address = CMDSRCA << 3; - const int pixfmt = CMDPMOD>>3 & 7; - const int transparent = !(CMDPMOD & 0x40); - const int endcodes = !(CMDPMOD & 0x80); - uint32_t color_base = (Vdp2Regs->CRAOFB & 0x0070) << 4; - - if (UNLIKELY(address + (pixfmt<=1 ? width/2 : pixfmt<=4 ? width : width*2) * height > 0x80000)) { - DMSG("%dx%d texture at 0x%X extends past end of VDP1 RAM" - " and will be incorrectly drawn", width, height, address); - } - - const uint8_t *src = Vdp1Ram + address; - switch (pixfmt) { - case 0: - tex->clut_dynamic = persistent; - CMDCOLR &= pixel_mask; - return gen_clut(tex, 16, - (color_base + CMDCOLR) & 0x7F0, CMDCOLR & 0x00F, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0xF) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T4, persistent) - && cache_texture_t4(tex, src, width, height, width); - case 1: { - const int clut_persistent = - persistent && (int16_t)T1ReadWord(Vdp1Ram, CMDCOLR<<3) < 0; - tex->clut_dynamic = persistent && !clut_persistent; - return gen_clut_t4ind(tex, Vdp1Ram + (CMDCOLR << 3), pixel_mask, - rofs, gofs, bofs, transparent, endcodes, - clut_persistent) - && alloc_texture_pixels(tex, width, height, GU_PSM_T4, persistent) - && cache_texture_t4(tex, src, width, height, width); - } - case 2: - tex->clut_dynamic = persistent; - return gen_clut(tex, 64, - (color_base + CMDCOLR) & 0x7C0, CMDCOLR & 0x03F, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0x3F) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T8, persistent) - && cache_texture_t8(tex, src, 0x3F, width, height, width); - case 3: - tex->clut_dynamic = persistent; - return gen_clut(tex, 128, - (color_base + CMDCOLR) & 0x780, CMDCOLR & 0x07F, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0x7F) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T8, persistent) - && cache_texture_t8(tex, src, 0x7F, width, height, width); - case 4: - tex->clut_dynamic = persistent; - return gen_clut(tex, 256, - (color_base + CMDCOLR) & 0x700, CMDCOLR & 0x0FF, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0xFF) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T8, persistent) - && cache_texture_t8(tex, src, 0xFF, width, height, width); - default: - DMSG("unsupported pixel mode %d, assuming 16-bit", pixfmt); - /* Fall through to... */ - case 5: - tex->clut_dynamic = 0; - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, persistent) - && cache_texture_16(tex, src, width, height, width, - rofs, gofs, bofs, transparent); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_tile: Cache a texture from tile (VDP2) memory. Implements common - * code for texcache_load_tile() and texcache_load_bitmap(). - * - * [Parameters] - * tex: TexInfo structure for caching texture - * address: Bitmap data address within VDP2 RAM - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * array: Number of VDP2 cells across and down texture - * (2 for 16x16 tiles, 1 otherwise) - * pixfmt: Bitmap pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_tile( - TexInfo *tex, uint32_t address, unsigned int width, unsigned int height, - unsigned int stride, int array, int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, int rofs, int gofs, int bofs, - int persistent) -{ - if (UNLIKELY(address + (pixfmt==0 ? width/2 : pixfmt==1 ? width*1 : pixfmt<=3 ? width*2 : width*4) * height > 0x80000)) { - DMSG("%dx%d texture at 0x%X extends past end of VDP2 RAM" - " and will be incorrectly drawn", width, height, address); - } - - if (pixfmt == 0) { - tex->clut_dynamic = persistent; - if (!gen_clut(tex, 16, - (color_base + color_ofs) & 0x7F0, color_ofs & 0x00F, - rofs, gofs, bofs, transparent, 0, 0, 0)) { - return 0; - } - } else if (pixfmt == 1) { - tex->clut_dynamic = persistent; - if (!gen_clut(tex, 256, - (color_base + color_ofs) & 0x700, color_ofs & 0x0FF, - rofs, gofs, bofs, transparent, 0, 0, 0)) { - return 0; - } - } else { - tex->clut_dynamic = 0; - } - - const uint8_t *src = Vdp2Ram + address; - - if (array == 2) { - - switch (pixfmt) { - - case 0: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_T4, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - - /* Fake out the texture_cache_X() functions so they don't try - * to draw boundary pixels. */ - tex->width = tex->height = 8; - - unsigned int i; - for (i = 0; i < 4; i++, src += 32) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 4 : 0) - + (i/2 ? 128 : 0)); - if (!cache_texture_t4(tex, src, 8, 8, 8)) { - return 0; - } - } - - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 0 - - case 1: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_T8, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - unsigned int i; - for (i = 0; i < 4; i++, src += 64) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 8 : 0) - + (i/2 ? 128 : 0)); - if (!cache_texture_t8(tex, src, 0xFF, 8, 8, 8)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 1 - - case 2: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_8888, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - const uint32_t tilesize = (pixfmt < 4) ? 128 : 256; - unsigned int i; - for (i = 0; i < 4; i++, src += tilesize) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 32 : 0) - + (i/2 ? 512 : 0)); - if (!cache_texture_t16(tex, src, color_base, 8, 8, 8, - rofs, gofs, bofs, transparent)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 2 - - case 3: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_8888, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - const uint32_t tilesize = (pixfmt < 4) ? 128 : 256; - unsigned int i; - for (i = 0; i < 4; i++, src += tilesize) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 32 : 0) - + (i/2 ? 512 : 0)); - if (!cache_texture_16(tex, src, 8, 8, 8, - rofs, gofs, bofs, transparent)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 3 - - case 4: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_8888, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - const uint32_t tilesize = (pixfmt < 4) ? 128 : 256; - unsigned int i; - for (i = 0; i < 4; i++, src += tilesize) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 32 : 0) - + (i/2 ? 512 : 0)); - if (!cache_texture_32(tex, src, 8, 8, 8, - rofs, gofs, bofs, transparent)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 4 - - default: - DMSG("Invalid tile pixel format %d", pixfmt); - return 0; - - } // switch (pixfmt) - - } else { // array == 1 - - switch (pixfmt) { - case 0: - return alloc_texture_pixels(tex, width, height, GU_PSM_T4, - persistent) - && cache_texture_t4(tex, src, width, height, stride); - case 1: - return alloc_texture_pixels(tex, width, height, GU_PSM_T8, - persistent) - && cache_texture_t8(tex, src, 0xFF, width, height, stride); - case 2: - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, - persistent) - && cache_texture_t16(tex, src, color_base, width, height, - stride, rofs, gofs, bofs, transparent); - case 3: - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, - persistent) - && cache_texture_16(tex, src, width, height, stride, - rofs, gofs, bofs, transparent); - case 4: - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, - persistent) - && cache_texture_32(tex, src, width, height, stride, - rofs, gofs, bofs, transparent); - default: - DMSG("Invalid tile pixel format %d", pixfmt); - return 0; - } - - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * alloc_texture_pixels: Allocate memory for a texture's pixel data, and - * fill in the vram_address, width, height, stride, and pixfmt fields of - * the TexInfo structure. - * - * [Parameters] - * tex: TexInfo structure for texture - * width: Texture width in pixels - * height: Texture height in pixels - * psm: Native texture pixel format (GU_PSM_*) - * persistent: Nonzero if a persistent texture, zero if a transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int alloc_texture_pixels( - TexInfo *tex, unsigned int width, unsigned int height, unsigned int psm, - int persistent) -{ - /* Calculate the power-of-2 sizes we need for registering the texture - * with the GE. */ - unsigned int texwidth = 1 << (32 - __builtin_clz(width-1)); - unsigned int texheight = 1 << (32 - __builtin_clz(height-1)); - - /* If the texture width or height aren't powers of 2, we add an extra - * 1-pixel border on the right and bottom edges to avoid graphics - * glitches resulting from the GE trying to read one pixel beyond the - * edge of the texture data. */ - unsigned int outwidth = width + (width != texwidth ? 1 : 0); - unsigned int outheight = height + (height != texheight ? 1 : 0); - - unsigned int stride, linebytes; - if (psm == GU_PSM_T4) { - stride = (outwidth+31) & -32; - linebytes = stride/2; - } else if (psm == GU_PSM_T8) { - stride = (outwidth+15) & -16; - linebytes = stride; - } else { // Must be GU_PSM_8888, since we don't use any others - stride = (outwidth+3) & -4; - linebytes = stride*4; - } - - const unsigned int size = linebytes * ((outheight+7) & -8); - if (persistent) { - tex->vram_address = alloc_pixdata(size); - } else { - tex->vram_address = alloc_vram(size); - } - if (UNLIKELY(!tex->vram_address)) { - DMSG("%s buffer full, can't cache", - persistent ? "Persistent cache" : "DRAM"); - return 0; - } - - tex->width = texwidth; - tex->height = texheight; - tex->stride = stride; - tex->pixfmt = psm; - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * gen_clut: Generate a color lookup table for a 4-bit or 8-bit indexed - * texture. - * - * [Parameters] - * tex: TexInfo structure for color table - * size: Number of color entries to generate - * color_base: Base color index - * color_ofs: Color index offset ORed together with pixel - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if pixel value 0 should be transparent - * endcodes: Nonzero if pixel value 0b11...11 should be transparent - * can_shadow: Nonzero if pixel value 0b11...10 is a shadow pixel - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int gen_clut( - TexInfo *tex, unsigned int size, uint32_t color_base, uint8_t color_ofs, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int can_shadow, int persistent) -{ - tex->clut_size = size; - - if (!endcodes && !transparent && !can_shadow && !color_ofs - && !rofs && !gofs && !bofs - ) { - /* There are no changes to apply to the palette, so just use the - * global CLUT directly. */ - tex->clut_address = &global_clut_32[color_base + color_ofs]; - return 1; - } - - const uint32_t color_set = (rofs & 0x1FF) << 0 - | (gofs & 0x1FF) << 9 - | (bofs & 0x1FF) << 18 - | (transparent ? 1<<27 : 0) - | (endcodes ? 1<<28 : 0); - const unsigned int cache_slot = color_base >> 4; - unsigned int cache_entry; - for (cache_entry = 0; cache_entry < CLUT_ENTRIES; cache_entry++) { - if (clut_cache[cache_slot][cache_entry].size == 0) { - /* This entry is empty, so we'll generate a palette and store - * it here. */ - clut_cache[cache_slot][cache_entry].size = size; - clut_cache[cache_slot][cache_entry].color_ofs = color_ofs; - clut_cache[cache_slot][cache_entry].color_set = color_set; - break; - } else if (clut_cache[cache_slot][cache_entry].size == size - && clut_cache[cache_slot][cache_entry].color_ofs == color_ofs - && clut_cache[cache_slot][cache_entry].color_set == color_set){ - /* Found a match, so return it. */ - tex->clut_address = - clut_cache[cache_slot][cache_entry].clut_address; - return 1; - } - } - if (UNLIKELY(cache_entry >= CLUT_ENTRIES)) { - DMSG("Warning: no free entries for CLUT cache slot 0x%02X", cache_slot); - } - - if (persistent) { - tex->clut_address = alloc_pixdata(size*4); - } else { - tex->clut_address = alloc_vram(size*4); - } - if (UNLIKELY(!tex->clut_address)) { - DMSG("%s buffer full, can't cache CLUT", - persistent ? "Persistent cache" : "VRAM"); - return 0; - } - if (cache_entry < CLUT_ENTRIES) { - clut_cache[cache_slot][cache_entry].clut_address = tex->clut_address; - } - - uint32_t *dest = (uint32_t *)tex->clut_address; - int i; - - /* Apply the color offset values to transparent or shadow pixels as - * well; this prevents dark rims around interpolated textures when - * positive color offsets are applied. */ - const uint32_t transparent_rgb = (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - - if (transparent) { - *dest++ = 0x00<<24 | transparent_rgb; - i = 1; - } else { - i = 0; - } - - const uint32_t *clut_32 = &global_clut_32[color_base]; - if (rofs | gofs | bofs) { - for (; i < size; i++, dest++) { - uint32_t color = clut_32[i | color_ofs]; - *dest = adjust_color_32_32(color, rofs, gofs, bofs); - } - } else { - for (; i < size; i++, dest++) { - *dest = clut_32[i | color_ofs]; - } - } - - if (endcodes) { - dest[-1] = 0x00<<24 | transparent_rgb; - } - - if (can_shadow) { - dest[-1] = 0x80<<24 | transparent_rgb; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * gen_clut_t4ind: Generate a color lookup table for a 4-bit indirect - * indexed texture. - * - * [Parameters] - * tex: TexInfo structure for color table - * color_lut: Pointer to VDP1 color lookup table - * pixel_mask: Mask to apply to palette indices in lookup table - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if pixel value 0 should be transparent - * endcodes: Nonzero if pixel value 0b11...11 should be transparent - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int gen_clut_t4ind( - TexInfo *tex, const uint8_t *color_lut, uint16_t pixel_mask, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int persistent) -{ - tex->clut_size = 16; - - if (persistent) { - tex->clut_address = alloc_pixdata(16*4); - } else { - tex->clut_address = alloc_vram(16*4); - } - if (UNLIKELY(!tex->clut_address)) { - DMSG("%s buffer full, can't cache CLUT", - persistent ? "Persistent cache" : "VRAM"); - return 0; - } - - const uint16_t *src = (const uint16_t *)color_lut; - uint32_t *dest = (uint32_t *)tex->clut_address; - const uint32_t *clut_32 = global_clut_32; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_rgb = (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - const uint16_t *top; - if (endcodes) { - dest[15] = 0x00<<24 | transparent_rgb; - top = src + 15; - } else { - top = src + 16; - } - if (transparent) { - src++; - *dest++ = 0x00<<24 | transparent_rgb; - } - - for (; src < top; src++, dest++) { - uint16_t color16 = BSWAP16(*src); - if (color16 & 0x8000) { - *dest = adjust_color_16_32(color16, rofs, gofs, bofs); - } else { - color16 &= pixel_mask; - if (color16 == pixel_mask - 1) { - *dest = 0x80<<24 | transparent_rgb; - } else { - *dest = adjust_color_32_32(clut_32[color16], - rofs, gofs, bofs); - } - } - } - - } else { // No color offset - - const uint16_t *top; - if (endcodes) { - dest[15] = 0x00000000; - top = src + 15; - } else { - top = src + 16; - } - if (transparent) { - src++; - *dest++ = 0x00000000; - } - - for (; src < top; src++, dest++) { - uint16_t color16 = BSWAP16(*src); - if (color16 & 0x8000) { - *dest = 0xFF000000 | (color16 & 0x7C00) << 9 - | (color16 & 0x03E0) << 6 - | (color16 & 0x001F) << 3; - } else { - color16 &= pixel_mask; - if (color16 == pixel_mask - 1) { - *dest = 0x80000000; - } else { - *dest = clut_32[color16]; - } - } - } - - } - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * A note about the texture caching routines-- - * - * While the texture caching logic is divided into five separate caching - * routines (one for each pixel type: 4/8/16-bit indexed and 16/32-bit - * direct color), each with multiple branches conditioned on the texture - * parameters, all of them follow the same basic flow: - * - * for (each row of 16-byte-by-8-line swizzled blocks) { - * for (each swizzled block in the row) { - * for (each of 8 lines in the block) { - * read enough input pixels for 16 output bytes - * convert and store pixels into the output buffer - * } - * } - * if (width is not a power of 2) { - * copy rightmost column one pixel to the right - * } - * } - * if (height is not a power of 2) { - * copy bottommost row one pixel down - * } - * - * The reason for all the repetition is to help the compiler optimize - * specific common cases, particularly for tile caching in which case the - * size parameters are all a constant 8 or 16. - */ - -/*************************************************************************/ - -/** - * cache_texture_t4: Cache a 4-bit indexed texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_t4( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - /* Cache the value of this locally so we don't have to load it on - * every loop. */ - const unsigned int tex_stride = tex->stride; - - uint8_t *dest = (uint8_t *)tex->vram_address; - - if (tex_stride == 32) { - - if (width == 8) { - uint8_t *dest_top = dest + (height * 16); - for (; dest != dest_top; src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - } - } else if (width == 16) { - uint8_t *dest_top = dest + (height * 16); - for (; dest != dest_top; src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[1] = ((src_word1 & 0x0F0F0F0F) << 4) - | ((src_word1 >> 4) & 0x0F0F0F0F); - } - } else { - uint8_t *dest_top = dest + (height * 16); - for (; dest != dest_top; src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[1] = ((src_word1 & 0x0F0F0F0F) << 4) - | ((src_word1 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[2] = ((src_word2 & 0x0F0F0F0F) << 4) - | ((src_word2 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[3] = ((src_word3 & 0x0F0F0F0F) << 4) - | ((src_word3 >> 4) & 0x0F0F0F0F); - if (width != 32) { - dest[width/2] = dest[width/2-1] >> 4; // Copy last pixel - } - } - } - - if (outheight > height) { // Copy last line - ((uint32_t *)dest)[0] = ((uint32_t *)dest)[-4]; - ((uint32_t *)dest)[1] = ((uint32_t *)dest)[-3]; - ((uint32_t *)dest)[2] = ((uint32_t *)dest)[-2]; - ((uint32_t *)dest)[3] = ((uint32_t *)dest)[-1]; - } - - } else { // tex_stride > 32 - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*4 - tex_stride/2) { - uint8_t *dest_top = dest + tex_stride*4; - for (; dest != dest_top; src += 16) { - const uint8_t *line_src = src; - uint8_t *line_end = dest + 128; - for (; dest != line_end; line_src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)line_src)[0]; - const uint32_t src_word1 = ((const uint32_t *)line_src)[1]; - const uint32_t src_word2 = ((const uint32_t *)line_src)[2]; - const uint32_t src_word3 = ((const uint32_t *)line_src)[3]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[1] = ((src_word1 & 0x0F0F0F0F) << 4) - | ((src_word1 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[2] = ((src_word2 & 0x0F0F0F0F) << 4) - | ((src_word2 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[3] = ((src_word3 & 0x0F0F0F0F) << 4) - | ((src_word3 >> 4) & 0x0F0F0F0F); - } - } - if (outwidth > width) { - uint8_t *eol_ptr = dest - 128 + ((width/2) & 15); - const int eol_ofs = (width & 31) ? -1 : -128 + 15; - uint8_t *eol_top = eol_ptr + 128; - for (; eol_ptr != eol_top; eol_ptr += 16) { - *eol_ptr = eol_ptr[eol_ofs] >> 4; - } - } - } - - if (outheight > height) { - if ((height & 7) != 0) { - dest = dest - tex_stride*4 + (height & 7)*16; - src = dest - 16; - } else { - src = dest - tex_stride*4 + 7*16; - } - uint8_t *dest_top = dest + tex_stride*4; - for (; dest < dest_top; src += 128, dest += 128) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } - - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_t8: Cache an 8-bit indexed texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * pixmask: Pixel data mask - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_t8( - TexInfo *tex, const uint8_t *src, uint8_t pixmask, - unsigned int width, unsigned int height, unsigned int stride) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint8_t *dest = (uint8_t *)tex->vram_address; - - if (pixmask != 0xFF) { - - const uint32_t pixmask32 = pixmask * 0x01010101; - if (stride == 8) { - unsigned int y; - for (y = 0; y < height; y++, src += 8, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - ((uint32_t *)dest)[0] = src_word0 & pixmask32; - ((uint32_t *)dest)[1] = src_word1 & pixmask32; - } - } else if (stride == 16) { - uint8_t *dest_top = dest + (height * stride); - for (; dest != dest_top; dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0 & pixmask32; - ((uint32_t *)dest)[1] = src_word1 & pixmask32; - ((uint32_t *)dest)[2] = src_word2 & pixmask32; - ((uint32_t *)dest)[3] = src_word3 & pixmask32; - } - } else { // stride > 16 - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*8 - tex_stride) { - uint8_t *dest_top = dest + tex_stride*8; - for (; dest != dest_top; src += 16) { - const uint8_t *line_src = src; - uint8_t *line_end = dest + 128; - for (; dest != line_end; line_src += stride, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)line_src)[0]; - const uint32_t src_word1 = ((const uint32_t *)line_src)[1]; - const uint32_t src_word2 = ((const uint32_t *)line_src)[2]; - const uint32_t src_word3 = ((const uint32_t *)line_src)[3]; - ((uint32_t *)dest)[0] = src_word0 & pixmask32; - ((uint32_t *)dest)[1] = src_word1 & pixmask32; - ((uint32_t *)dest)[2] = src_word2 & pixmask32; - ((uint32_t *)dest)[3] = src_word3 & pixmask32; - } - } - if (outwidth > width) { - uint8_t *eol_ptr = dest - 128 + (width & 15); - const int eol_ofs = (width & 15) ? -1 : -128 + 15; - uint8_t *eol_top = eol_ptr + 128; - for (; eol_ptr != eol_top; eol_ptr += 16) { - *eol_ptr = eol_ptr[eol_ofs]; - } - } - } - } - - } else { // pixmask == 0xFF - - if (stride == 8) { - unsigned int y; - for (y = 0; y < height; y++, src += 8, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - } - } else if (stride == 16) { - uint8_t *dest_top = dest + (height * stride); - for (; dest != dest_top; dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } else { // stride > 16 - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*8 - tex_stride) { - uint8_t *dest_top = dest + tex_stride*8; - for (; dest != dest_top; src += 16) { - const uint8_t *line_src = src; - uint8_t *line_end = dest + 128; - for (; dest != line_end; line_src += stride, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)line_src)[0]; - const uint32_t src_word1 = ((const uint32_t *)line_src)[1]; - const uint32_t src_word2 = ((const uint32_t *)line_src)[2]; - const uint32_t src_word3 = ((const uint32_t *)line_src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } - if (outwidth > width) { - uint8_t *eol_ptr = dest - 128 + (width & 15); - const int eol_ofs = (width & 15) ? -1 : -128 + 15; - uint8_t *eol_top = eol_ptr + 128; - for (; eol_ptr != eol_top; eol_ptr += 16) { - *eol_ptr = eol_ptr[eol_ofs]; - } - } - } - } - - } // if (pixmask != 0xFF) - - if (outheight > height) { - if (tex_stride == 16) { - ((uint32_t *)dest)[0] = ((uint32_t *)dest)[-4]; - ((uint32_t *)dest)[1] = ((uint32_t *)dest)[-3]; - ((uint32_t *)dest)[2] = ((uint32_t *)dest)[-2]; - ((uint32_t *)dest)[3] = ((uint32_t *)dest)[-1]; - } else { - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*16; - src = dest - 16; - } else { - src = dest - tex_stride*8 + 7*16; - } - uint8_t *dest_top = dest + tex_stride*8; - for (; dest < dest_top; src += 128, dest += 128) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_t16: Cache a 16-bit indexed texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * color_base: Base color index - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if pixel value 0 should be transparent - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_t16( - TexInfo *tex, const uint8_t *src, uint32_t color_base, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint32_t *dest = (uint32_t *)tex->vram_address; - const uint32_t *clut_32 = &global_clut_32[color_base]; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_pixel = 0x00000000 - | (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const uint16_t *line_src = (const uint16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const uint16_t pixel0 = BSWAP16(line_src[0]); - const uint16_t pixel1 = BSWAP16(line_src[1]); - const uint16_t pixel2 = BSWAP16(line_src[2]); - const uint16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (transparent && !pixel0) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel0 & 0x7FF], - rofs, gofs, bofs); - dest[1] = (transparent && !pixel1) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel1 & 0x7FF], - rofs, gofs, bofs); - dest[2] = (transparent && !pixel2) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel2 & 0x7FF], - rofs, gofs, bofs); - dest[3] = (transparent && !pixel3) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel3 & 0x7FF], - rofs, gofs, bofs); - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else if (transparent) { - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const uint16_t *line_src = (const uint16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const uint16_t pixel0 = BSWAP16(line_src[0]); - const uint16_t pixel1 = BSWAP16(line_src[1]); - const uint16_t pixel2 = BSWAP16(line_src[2]); - const uint16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (pixel0 == 0) ? 0 : clut_32[pixel0 & 0x7FF]; - dest[1] = (pixel1 == 0) ? 0 : clut_32[pixel1 & 0x7FF]; - dest[2] = (pixel2 == 0) ? 0 : clut_32[pixel2 & 0x7FF]; - dest[3] = (pixel3 == 0) ? 0 : clut_32[pixel3 & 0x7FF]; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else { // !(rofs | gofs | bofs) && !transparent - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const uint16_t *line_src = (const uint16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const uint16_t pixel0 = BSWAP16(line_src[0]); - const uint16_t pixel1 = BSWAP16(line_src[1]); - const uint16_t pixel2 = BSWAP16(line_src[2]); - const uint16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = clut_32[pixel0 & 0x7FF]; - dest[1] = clut_32[pixel1 & 0x7FF]; - dest[2] = clut_32[pixel2 & 0x7FF]; - dest[3] = clut_32[pixel3 & 0x7FF]; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } // if (rofs | gofs | bofs) - - if (outheight > height) { - const uint32_t *src32; - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*4; - src32 = dest - 4; - } else { - src32 = dest - tex_stride*8 + 7*4; - } - uint32_t *dest_top = dest + tex_stride; - for (; dest < dest_top; src32 += 32, dest += 32) { - const uint32_t pixel0 = src32[0]; - const uint32_t pixel1 = src32[1]; - const uint32_t pixel2 = src32[2]; - const uint32_t pixel3 = src32[3]; - dest[0] = pixel0; - dest[1] = pixel1; - dest[2] = pixel2; - dest[3] = pixel3; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_16: Cache a 16-bit ARGB1555 texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if alpha-0 pixels should be transparent - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_16( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint32_t *dest = (uint32_t *)tex->vram_address; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_pixel = 0x00000000 - | (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - /* We load these as signed values to simplify checking the - * high (transparency) bit. */ - const int16_t *line_src = (const int16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int16_t pixel0 = BSWAP16(line_src[0]); - const int16_t pixel1 = BSWAP16(line_src[1]); - const int16_t pixel2 = BSWAP16(line_src[2]); - const int16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (transparent && !(pixel0<0)) ? transparent_pixel - : adjust_color_16_32(pixel0, rofs, gofs, bofs); - dest[1] = (transparent && !(pixel1<0)) ? transparent_pixel - : adjust_color_16_32(pixel1, rofs, gofs, bofs); - dest[2] = (transparent && !(pixel2<0)) ? transparent_pixel - : adjust_color_16_32(pixel2, rofs, gofs, bofs); - dest[3] = (transparent && !(pixel3<0)) ? transparent_pixel - : adjust_color_16_32(pixel3, rofs, gofs, bofs); - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else if (transparent) { - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const int16_t *line_src = (const int16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int16_t pixel0 = BSWAP16(line_src[0]); - const int16_t pixel1 = BSWAP16(line_src[1]); - const int16_t pixel2 = BSWAP16(line_src[2]); - const int16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (pixel0 >= 0) ? 0 - : 0xFF000000 | (pixel0 & 0x7C00) << 9 - | (pixel0 & 0x03E0) << 6 - | (pixel0 & 0x001F) << 3; - dest[1] = (pixel1 >= 0) ? 0 - : 0xFF000000 | (pixel1 & 0x7C00) << 9 - | (pixel1 & 0x03E0) << 6 - | (pixel1 & 0x001F) << 3; - dest[2] = (pixel2 >= 0) ? 0 - : 0xFF000000 | (pixel2 & 0x7C00) << 9 - | (pixel2 & 0x03E0) << 6 - | (pixel2 & 0x001F) << 3; - dest[3] = (pixel3 >= 0) ? 0 - : 0xFF000000 | (pixel3 & 0x7C00) << 9 - | (pixel3 & 0x03E0) << 6 - | (pixel3 & 0x001F) << 3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else { // !(rofs | gofs | bofs) && !transparent - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const int16_t *line_src = (const int16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int16_t pixel0 = BSWAP16(line_src[0]); - const int16_t pixel1 = BSWAP16(line_src[1]); - const int16_t pixel2 = BSWAP16(line_src[2]); - const int16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = 0xFF000000 | (pixel0 & 0x7C00) << 9 - | (pixel0 & 0x03E0) << 6 - | (pixel0 & 0x001F) << 3; - dest[1] = 0xFF000000 | (pixel1 & 0x7C00) << 9 - | (pixel1 & 0x03E0) << 6 - | (pixel1 & 0x001F) << 3; - dest[2] = 0xFF000000 | (pixel2 & 0x7C00) << 9 - | (pixel2 & 0x03E0) << 6 - | (pixel2 & 0x001F) << 3; - dest[3] = 0xFF000000 | (pixel3 & 0x7C00) << 9 - | (pixel3 & 0x03E0) << 6 - | (pixel3 & 0x001F) << 3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } // if (rofs | gofs | bofs) - - if (outheight > height) { - const uint32_t *src32; - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*4; - src32 = dest - 4; - } else { - src32 = dest - tex_stride*8 + 7*4; - } - uint32_t *dest_top = dest + tex_stride; - for (; dest < dest_top; src32 += 32, dest += 32) { - const uint32_t pixel0 = src32[0]; - const uint32_t pixel1 = src32[1]; - const uint32_t pixel2 = src32[2]; - const uint32_t pixel3 = src32[3]; - dest[0] = pixel0; - dest[1] = pixel1; - dest[2] = pixel2; - dest[3] = pixel3; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_32: Cache a 32-bit ARGB1888 texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if alpha-0 pixels should be transparent - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_32( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint32_t *dest = (uint32_t *)tex->vram_address; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_pixel = 0x00000000 - | (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*32 - width*4, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 16) { - const int32_t *line_src = (const int32_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int32_t pixel0 = BSWAP32(line_src[0]); - const int32_t pixel1 = BSWAP32(line_src[1]); - const int32_t pixel2 = BSWAP32(line_src[2]); - const int32_t pixel3 = BSWAP32(line_src[3]); - dest[0] = (transparent && !(pixel0<0)) ? transparent_pixel - : adjust_color_32_32(pixel0, rofs, gofs, bofs); - dest[1] = (transparent && !(pixel1<0)) ? transparent_pixel - : adjust_color_32_32(pixel1, rofs, gofs, bofs); - dest[2] = (transparent && !(pixel2<0)) ? transparent_pixel - : adjust_color_32_32(pixel2, rofs, gofs, bofs); - dest[3] = (transparent && !(pixel3<0)) ? transparent_pixel - : adjust_color_32_32(pixel3, rofs, gofs, bofs); - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else if (transparent) { - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*32 - width*4, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 16) { - const int32_t *line_src = (const int32_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int32_t pixel0 = BSWAP32(line_src[0]); - const int32_t pixel1 = BSWAP32(line_src[1]); - const int32_t pixel2 = BSWAP32(line_src[2]); - const int32_t pixel3 = BSWAP32(line_src[3]); - dest[0] = (pixel0 >= 0) ? 0 : 0xFF000000 | pixel0; - dest[1] = (pixel1 >= 0) ? 0 : 0xFF000000 | pixel1; - dest[2] = (pixel2 >= 0) ? 0 : 0xFF000000 | pixel2; - dest[3] = (pixel3 >= 0) ? 0 : 0xFF000000 | pixel3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else { // !(rofs | gofs | bofs) && !transparent - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*32 - width*4, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 16) { - const int32_t *line_src = (const int32_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int32_t pixel0 = BSWAP32(line_src[0]); - const int32_t pixel1 = BSWAP32(line_src[1]); - const int32_t pixel2 = BSWAP32(line_src[2]); - const int32_t pixel3 = BSWAP32(line_src[3]); - dest[0] = 0xFF000000 | pixel0; - dest[1] = 0xFF000000 | pixel1; - dest[2] = 0xFF000000 | pixel2; - dest[3] = 0xFF000000 | pixel3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } // if (rofs | gofs | bofs) - - if (outheight > height) { - const uint32_t *src32; - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*4; - src32 = dest - 4; - } else { - src32 = dest - tex_stride*8 + 7*4; - } - uint32_t *dest_top = dest + tex_stride; - for (; dest < dest_top; src32 += 32, dest += 32) { - const uint32_t pixel0 = src32[0]; - const uint32_t pixel1 = src32[1]; - const uint32_t pixel2 = src32[2]; - const uint32_t pixel3 = src32[3]; - dest[0] = pixel0; - dest[1] = pixel1; - dest[2] = pixel2; - dest[3] = pixel3; - } - } - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/texcache.h b/yabause/src/psp/texcache.h deleted file mode 100644 index c21bda8f37..0000000000 --- a/yabause/src/psp/texcache.h +++ /dev/null @@ -1,141 +0,0 @@ -/* src/psp/texcache.h: PSP texture cache management header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_TEXCACHE_H -#define PSP_TEXCACHE_H - -#include "../vdp1.h" - -/*************************************************************************/ - -/** - * texcache_reset: Reset the texture cache, including all persistent - * textures. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void texcache_reset(void); - -/** - * texcache_clean: Clean all transient textures from the texture cache. - * Persistent textures are not affected. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void texcache_clean(void); - -/** - * texcache_cache_sprite: Cache the given sprite texture if it has not - * been cached already. Returns a texture key for later use in loading the - * texture. The texture width must be a multiple of 8. - * - * [Parameters] - * cmd: VDP1 command structure - * pixel_mask: Mask to apply to paletted pixel data - * width, height: Size of texture (in pixels) - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this frame only - * [Return value] - * Texture key (zero on error) - */ -extern uint32_t texcache_cache_sprite(const vdp1cmd_struct *cmd, - uint16_t pixel_mask, - unsigned int width, unsigned int height, - int persistent); - -/** - * texcache_load_sprite: Load the sprite texture indicated by the given - * texture key. - * - * [Parameters] - * key: Texture key returned by texcache_cache_sprite - * [Return value] - * None - */ -extern void texcache_load_sprite(uint32_t key); - -/** - * texcache_load_tile: Load the specified 8x8 or 16x16 tile texture into - * the GE registers for drawing, first caching the texture if necessary. - * - * [Parameters] - * tilesize: Pixel size (width and height) of tile, either 8 or 16 - * address: Tile data address within VDP2 RAM - * pixfmt: Tile pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -extern void texcache_load_tile(int tilesize, uint32_t address, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bofs, int persistent); - -/** - * texcache_load_bitmap: Load the specified bitmap texture into the GE - * registers for drawing, first caching the texture if necessary. The - * texture width must be a multiple of 8. - * - * [Parameters] - * address: Bitmap data address within VDP2 RAM - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * pixfmt: Bitmap pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -extern void texcache_load_bitmap(uint32_t address, unsigned int width, - unsigned int height, unsigned int stride, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bof, int persistent); - -/*************************************************************************/ - -#endif // PSP_TEXCACHE_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/threads.c b/yabause/src/psp/threads.c deleted file mode 100644 index 71c7042121..0000000000 --- a/yabause/src/psp/threads.c +++ /dev/null @@ -1,227 +0,0 @@ -/* src/psp/threads.c: Yabause thread management routines - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" -#include "config.h" -#include "me.h" -#include "me-utility.h" -#include "sys.h" - -#include "../threads.h" - -/*************************************************************************/ - -/* Thread handle and setup data for each Yabause subthread */ -static struct { - int32_t handle; - const char * const name; - int priority; - uint32_t stack_size; -} thread_data[YAB_NUM_THREADS] = { - [YAB_THREAD_SCSP] = {.name = "YabauseScspThread", - .priority = THREADPRI_MAIN, - .stack_size = 16384}, // FIXME: could be smaller? -}; - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * YabThreadStart: Start a new thread for the given function. Only one - * thread will be started for each thread ID (YAB_THREAD_*). - * - * [Parameters] - * id: Yabause subthread ID (YAB_THREAD_*) - * func: Function to execute - * [Return value] - * Zero on success, negative on error - */ -int YabThreadStart(unsigned int id, void (*func)(void)) -{ - if (thread_data[id].handle) { - fprintf(stderr, "YabThreadStart: thread %u is already started!\n", id); - return -1; - } - - if (id == YAB_THREAD_SCSP) { // We run the SCSP on the ME - if (!me_available || !config_get_use_me()) { - DMSG("ME not available or disabled by user"); - return -1; - } - sceKernelDcacheWritebackAll(); -#ifdef PSP_DEBUG - meExceptionSetFatal(1); -#endif - int32_t res; - if ((res = meStart()) < 0) { - DMSG("meStart(): %s", psp_strerror(res)); - return -1; - } else if ((res = meWait()) < 0) { - DMSG("meWait(): %s", psp_strerror(res)); - return -1; - } else if ((res = meCall((void *)func, NULL)) < 0) { - DMSG("Failed to start thread %d (%s) on ME: %s", - id, thread_data[id].name, psp_strerror(res)); - return -1; - } - /* Attempting to suspend the PSP will currently cause a crash, - * so prevent suspending entirely. (This is documented in the - * README.PSP file.) */ - scePowerLock(0); - thread_data[id].handle = 1; // Anything nonzero will do - } else { - int32_t res = sys_start_thread(thread_data[id].name, func, - thread_data[id].priority, - thread_data[id].stack_size, 0, NULL); - if (res < 0) { - DMSG("Failed to start thread %d (%s): %s", - id, thread_data[id].name, psp_strerror(res)); - return -1; - } - thread_data[id].handle = res; - } - - return 0; -} - -/*************************************************************************/ - -/** - * YabThreadWait: Wait for the given ID's thread to terminate. Returns - * immediately if no thread has been started on the given ID. - * - * [Parameters] - * id: Yabause subthread ID (YAB_THREAD_*) - * [Return value] - * None - */ -void YabThreadWait(unsigned int id) -{ - if (!thread_data[id].handle) { - return; // Thread wasn't running in the first place - } - - if (id == YAB_THREAD_SCSP) { - sceKernelDcacheWritebackInvalidateAll(); - int32_t res; - if ((res = meWait()) < 0) { - DMSG("meWait(): %s", psp_strerror(res)); - } - } else { - int32_t res; - if ((res = sceKernelWaitThreadEnd(thread_data[id].handle, NULL)) < 0) { - DMSG("WaitThreadEnd(%d): %s", id, psp_strerror(res)); - } - if ((res = sceKernelDeleteThread(thread_data[id].handle)) < 0) { - DMSG("DeleteThread(%d): %s", id, psp_strerror(res)); - } - } - - thread_data[id].handle = 0; -} - -/*************************************************************************/ - -/** - * YabThreadYield: Yield CPU execution to another thread. - * - * [Parameters] - * None - * [Return value] - * None - */ -void YabThreadYield(void) -{ - if (meUtilityIsME()) { - /* On the ME, there's no other thread to yield to, but we do flush - * the cache to ensure the SC can see our updates. */ - meUtilityDcacheWritebackInvalidateAll(); - } else { -#ifdef PSP_DEBUG - if (thread_data[YAB_THREAD_SCSP].handle) { - /* ME is running, so check for ME exceptions */ - (void) mePoll(); - } -#endif - sceKernelDelayThread(0); - } -} - -/*************************************************************************/ - -/** - * YabThreadSleep: Put the current thread to sleep. - * - * [Parameters] - * None - * [Return value] - * None - */ -void YabThreadSleep(void) -{ - if (meUtilityIsME()) { - /* Used in place of YabThreadYield() when the SCSP thread has - * nothing to do; there's no real point in sleeping on the ME, but - * flush the data cache as in Yield(). */ - meUtilityDcacheWritebackInvalidateAll(); - } else { - sceKernelSleepThread(); - } -} - -/*************************************************************************/ - -/** - * YabThreadWake: Wake up the given thread if it is asleep. - * - * [Parameters] - * id: Yabause subthread ID (YAB_THREAD_*) - * [Return value] - * None - */ -void YabThreadWake(unsigned int id) -{ - if (!thread_data[id].handle) { - return; // Thread is not running - } - - if (id == YAB_THREAD_SCSP) { -#ifdef PSP_DEBUG - /* Check for ME exceptions */ - (void) mePoll(); -#endif - } else { - sceKernelWakeupThread(thread_data[id].handle); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/timing.c b/yabause/src/psp/timing.c deleted file mode 100644 index 270aded1f2..0000000000 --- a/yabause/src/psp/timing.c +++ /dev/null @@ -1,145 +0,0 @@ -/* src/psp/timing.c: Emulation timing logic for PSP - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "timing.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Length of a single frame in microseconds (32.32 fixed point). */ -#define FRAME_TIME (((1001000LL << 32) + 30) / 60) - -/* Minimum elapsed time since the beginning of the previous frame before - * we consider this the start of a new frame. This is slightly less than - * the actual frame length to account for slight discrepancies in hardware - * timing. */ -#define MIN_WAIT (FRAME_TIME * 9/10) - -/* Microsecond timestamp at the beginning of the previous frame - * (32.32 fixed point). */ -static int64_t last_frame_time; - -/* Flag indicating that the next frame should be synched to real time. - * This is set on the call to timing_init() and also each call to - * timing_sync(), and can be cleared during a frame by a call to - * timing_skip_next_sync(). If the flag is clear on entry to timing_sync(), - * the sync is skipped and the last frame time is incremented by FRAME_TIME - * regardless of the current time. This flag is typically cleared by - * psp-video.c during skipped output frames to let several emulated frames - * execute at once. */ -static int sync_next_frame; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * timing_init: Initialize the timing functionality at program start. - * Should be called as late as possible in the initialization sequence - * (as close to the start of emulation as possible). - * - * [Parameters] - * None - * [Return value] - * None - */ -void timing_init(void) -{ - sync_next_frame = 1; - sceDisplayWaitVblankStart(); - last_frame_time = (int64_t)sceKernelGetSystemTimeLow() << 32; -} - -/*-----------------------------------------------------------------------*/ - -/** - * timing_sync: Wait until at least one frame has passed since the - * beginning of the previous frame. However, if timing_skip_next_sync() - * was called after the previous call to timing_sync() or timing_init(), - * this function returns immediately, and the next timing_sync() call will - * wait one extra frame past the last synchronization point. (For example, - * calling timing_skip_next_sync() every second frame will cause the - * immediately subsequent timing_sync() to return immediately, and the - * timing_sync() after that to wait until two frames' time has passed since - * the call to timing_sync() preceding the timing_skip_next_sync() call.) - * - * [Parameters] - * None - * [Return value] - * None - */ -void timing_sync(void) -{ - if (sync_next_frame) { - int waited = 0; - int64_t now; - while (now = (int64_t)sceKernelGetSystemTimeLow() << 32, - now - last_frame_time < MIN_WAIT) - { - sceDisplayWaitVblankStart(); - waited = 1; - } - /* Keep the timer aligned as closely as possible to the actual - * vertical blank for smoother timing. */ - if (waited) { - last_frame_time = now; - } else { - do { - last_frame_time += FRAME_TIME; - } while (now - last_frame_time > FRAME_TIME/2); - } - } else { - last_frame_time += FRAME_TIME; - sync_next_frame = 1; - } -} - -/*************************************************************************/ - -/** - * timing_skip_next_sync: Called during a frame to indicate that the - * next call to timing_sync() should not perform a sync. See the - * timing_sync() documentation for details. - * - * [Parameters] - * None - * [Return value] - * None - */ -void timing_skip_next_sync(void) -{ - sync_next_frame = 0; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/timing.h b/yabause/src/psp/timing.h deleted file mode 100644 index f2df7bba76..0000000000 --- a/yabause/src/psp/timing.h +++ /dev/null @@ -1,80 +0,0 @@ -/* src/psp/timing.h: Header for emulation timing logic - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_TIMING_H -#define PSP_TIMING_H - -/*************************************************************************/ - -/** - * timing_init: Initialize the timing functionality at program start. - * Should be called as late as possible in the initialization sequence - * (as close to the start of emulation as possible). - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void timing_init(void); - -/** - * timing_sync: Wait until at least one frame has passed since the - * beginning of the previous frame. However, if timing_skip_next_sync() - * was called after the previous call to timing_sync() or timing_init(), - * this function returns immediately, and the next timing_sync() call will - * wait one extra frame past the last synchronization point. (For example, - * calling timing_skip_next_sync() every second frame will cause the - * immediately subsequent timing_sync() to return immediately, and the - * timing_sync() after that to wait until two frames' time has passed since - * the call to timing_sync() preceding the timing_skip_next_sync() call.) - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void timing_sync(void); - -/** - * timing_skip_next_sync: Called during a frame to indicate that the - * next call to timing_sync() should not perform a sync. See the - * timing_sync() documentation for details. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void timing_skip_next_sync(void); - -/*************************************************************************/ - -#endif // PSP_TIMING_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/yui.c b/yabause/src/psp/yui.c deleted file mode 100644 index b0eb5fc09f..0000000000 --- a/yabause/src/psp/yui.c +++ /dev/null @@ -1,147 +0,0 @@ -/* src/psp/yui.c: Yabause core interface routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidsoft.h" -#include "../yui.h" - -#include "display.h" -#include "menu.h" - -/*************************************************************************/ -/******************** Yabause core interface routines ********************/ -/*************************************************************************/ - -/** - * YuiErrorMsg: Report an error to the user. - * - * [Parameters] - * string: Error message string - * [Return value] - * None - */ -void YuiErrorMsg(const char *string) -{ - PRECOND(string != NULL, return); - -#ifdef PSP_DEBUG - fprintf(stderr, "%s", string); -#endif - - /* Drop any leading/trailing newlines, and convert internal newlines to - * spaces, before passing the message to the menu screen */ - while (*string == '\r' || *string == '\n') { - string++; - } - char buf[100]; - snprintf(buf, sizeof(buf), "%s", string); - int i; - for (i = strlen(buf)-1; i >= 0; i--) { - if (buf[i] == '\r' || buf[i] == '\n') { - buf[i] = 0; - } else { - break; - } - } - for (i = 0; buf[i]; i++) { - if (buf[i] == '\r' || buf[i] == '\n') { - buf[i] = ' '; - } - } - menu_set_error(buf); -} - -/*************************************************************************/ - -/** - * YuiSwapBuffers: Swap the front and back display buffers. Called by the - * software renderer. - * - * [Parameters] - * None - * [Return value] - * None - */ -void YuiSwapBuffers(void) -{ - if (!dispbuffer) { - return; - } - - /* Calculate display size (shrink interlaced/hi-res displays by half) */ - int width_in, height_in, width_out, height_out; - VIDCore->GetGlSize(&width_in, &height_in); - if (width_in <= DISPLAY_WIDTH) { - width_out = width_in; - } else { - width_out = width_in / 2; - } - if (height_in <= DISPLAY_HEIGHT) { - height_out = height_in; - } else { - height_out = height_in / 2; - } - int x = (DISPLAY_WIDTH - width_out) / 2; - int y = (DISPLAY_HEIGHT - height_out) / 2; - - /* Make sure all video buffer data is flushed to memory and cleared - * from the cache */ - sceKernelDcacheWritebackInvalidateRange(dispbuffer, - width_in * height_in * 4); - - /* Blit the data to the screen */ - display_begin_frame(); - if (width_out == width_in && height_out == height_in) { - display_blit(dispbuffer, width_in, height_in, width_in, x, y); - } else { - /* The PSP can't draw textures larger than 512x512, so if we're - * drawing a high-resolution buffer, split it in half. The height - * will never be greater than 512, so we don't need to check for a - * vertical split. */ - if (width_in > 512) { - const uint32_t *dispbuffer32 = (const uint32_t *)dispbuffer; - display_blit_scaled(dispbuffer32, width_in/2, height_in, - width_in, x, y, width_out/2, height_out); - dispbuffer32 += width_in/2; - x += width_out/2; - display_blit_scaled(dispbuffer32, width_in/2, height_in, - width_in, x, y, width_out/2, height_out); - } else { - display_blit_scaled(dispbuffer, width_in, height_in, width_in, - x, y, width_out, height_out); - } - } - display_end_frame(); - sceDisplayWaitVblankStart(); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-const.h b/yabause/src/q68/q68-const.h deleted file mode 100644 index 9de141f175..0000000000 --- a/yabause/src/q68/q68-const.h +++ /dev/null @@ -1,217 +0,0 @@ -/* src/q68/q68-const.h: Constants used in MC68000 emulation - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_CONST_H -#define Q68_CONST_H - -/*************************************************************************/ - -/* Configuration constants */ - -/* Maximum size in bytes of a 68k code block for translation */ -#ifndef Q68_JIT_MAX_BLOCK_SIZE -# define Q68_JIT_MAX_BLOCK_SIZE 4096 -#endif - -/* Size of pages used in checking for writes to already-translated code - * (1 page = 1<SR >> SR_I0_SHIFT) & 7) -#define SR_SET_I(state,val) ((state)->SR &= ~(7 << SR_I0_SHIFT), \ - (state)->SR |= ((val) & 7) << SR_I0_SHIFT) - -/*-----------------------------------------------------------------------*/ - -/* Exception numbers */ - -#define EX_INITIAL_SP 0 -#define EX_INITIAL_PC 1 -#define EX_BUS_ERROR 2 -#define EX_ADDRESS_ERROR 3 -#define EX_ILLEGAL_INSTRUCTION 4 -#define EX_DIVIDE_BY_ZERO 5 -#define EX_CHK 6 -#define EX_TRAPV 7 -#define EX_PRIVILEGE_VIOLATION 8 -#define EX_TRACE 9 -#define EX_LINE_1010 10 -#define EX_LINE_1111 11 - -#define EX_SPURIOUS_INTERRUPT 24 -#define EX_LEVEL_1_INTERRUPT 25 -#define EX_LEVEL_2_INTERRUPT 26 -#define EX_LEVEL_3_INTERRUPT 27 -#define EX_LEVEL_4_INTERRUPT 28 -#define EX_LEVEL_5_INTERRUPT 29 -#define EX_LEVEL_6_INTERRUPT 30 -#define EX_LEVEL_7_INTERRUPT 31 -#define EX_TRAP 32 // 16 vectors (EX_TRAP+0 .. EX_TRAP+15) - -/*-----------------------------------------------------------------------*/ - -/* Bits in the fault status word for bus/address error exceptions */ - -#define FAULT_STATUS_IN (1<<3) // Instruction/Not (0 = instruction, 1 = not) -#define FAULT_STATUS_IN_INSN (0) -#define FAULT_STATUS_IN_DATA (FAULT_STATUS_IN) - -#define FAULT_STATUS_RW (1<<4) // Read/Write (0 = write, 1 = read) -#define FAULT_STATUS_RW_READ (FAULT_STATUS_RW) -#define FAULT_STATUS_RW_WRITE (0) - -/*-----------------------------------------------------------------------*/ - -/* Condition codes for conditional instructions */ - -#define COND_T 0 -#define COND_F 1 -#define COND_HI 2 -#define COND_LS 3 -#define COND_CC 4 // also HS -#define COND_CS 5 // also LO -#define COND_NE 6 -#define COND_EQ 7 -#define COND_VC 8 -#define COND_VS 9 -#define COND_PL 10 -#define COND_MI 11 -#define COND_GE 12 -#define COND_LT 13 -#define COND_GT 14 -#define COND_LE 15 - -/*-----------------------------------------------------------------------*/ - -/* Size codes in opcode bits 6-7 */ - -#define SIZE_B 0 -#define SIZE_W 1 -#define SIZE_L 2 - -/* Macro to convert size codes to equivalent byte counts */ -#define SIZE_TO_BYTES(size) ((size) + 1 + ((size) == SIZE_L)) - -/*-----------------------------------------------------------------------*/ - -/* Effective address modes */ - -#define EA_DATA_REG 0 // Data Register Direct -#define EA_ADDRESS_REG 1 // Address Register Direct -#define EA_INDIRECT 2 // Address Register Indirect -#define EA_POSTINCREMENT 3 // Address Register Indirect with Postincrement -#define EA_PREDECREMENT 4 // Address Register Indirect with Predecrement -#define EA_DISPLACEMENT 5 // Address Register Indirect with Displacement -#define EA_INDEX 6 // Address Register Indirect with Index -#define EA_MISC 7 - -#define EA_MISC_ABSOLUTE_W 0 // Absolute Short -#define EA_MISC_ABSOLUTE_L 1 // Absolute Long -#define EA_MISC_PCREL 2 // Program Counter Indirect with Displacement -#define EA_MISC_PCREL_INDEX 3 // Program Counter Indirect with Index -#define EA_MISC_IMMEDIATE 4 // Immediate - -/* Macros to retrieve the mode and register number from an opcode */ -#define EA_MODE(opcode) ((opcode)>>3 & 7) -#define EA_REG(opcode) ((opcode)>>0 & 7) - -/*************************************************************************/ -/*************************************************************************/ - -#endif // Q68_CONST_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-core.c b/yabause/src/q68/q68-core.c deleted file mode 100644 index b3dc4a8bd7..0000000000 --- a/yabause/src/q68/q68-core.c +++ /dev/null @@ -1,2563 +0,0 @@ -/* src/q68/q68-core.c: Q68 execution core - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "q68.h" -#include "q68-const.h" -#include "q68-internal.h" - -/* Define this to export two tables of counters: - * uint32_t q68_ops[128]; // Corresponds to opcode_table[] - * uint32_t q68_4xxx_ops[32]; // Corresponds to opcode_4xxx_table[] - * Each entry will be incremented each time the corresponding function is - * called. */ -// #define COUNT_OPCODES - -/*************************************************************************/ - -/* - * The following table maps each 68000 instruction to its implementing - * function in this file: - * - * || Instruction | Func. || Instruction | Func. || Instruction | Func. || - * ++-------------+--------++-------------+--------++-------------+--------++ - * || ABCD | op_BCD || EOR | op_alu || NOT | op4alu || - * || ADD | op_alu || EORI | op_imm || OR | op_alu || - * || ADDA | op_alu || EORI to CCR | op_imm || ORI | op_imm || - * || ADDI | op_imm || EORI to SR | op_imm || ORI to CCR | op_imm || - * || ADDQ | opADSQ || EXG | op_EXG || ORI to SR | op_imm || - * || ADDX | opADSX || EXT | op_EXT || PEA | op_PEA || - * || AND | op_alu || ILLEGAL | op_TAS || RESET | op4E7x || - * || ANDI | op_imm || JMP | opjump || ROL | opshft || - * || ANDI to CCR | op_imm || JSR | opjump || ROR | opshft || - * || ANDI to SR | op_imm || LEA | op_LEA || ROXL | opshft || - * || ASL | opshft || LINK | opLINK || ROXR | opshft || - * || ASR | opshft || LSL | opshft || RTE | op4E7x || - * || Bcc | op_Bcc || LSR | opshft || RTR | op4E7x || - * || BCHG | op_bit || MOVE | opMOVE || RTS | op4E7x || - * || BCLR | op_bit || MOVEA | opMOVE || SBCD | op_BCD || - * || BRA | op_Bcc || MOVE to CCR | opMVSR || Scc | op_Scc || - * || BSET | op_bit || MOVE from SR| opMVSR || STOP | op4E7x || - * || BSR | op_Bcc || MOVE to SR | opMVSR || SUB | op_alu || - * || BTST | op_bit || MOVE USP | opMUSP || SUBA | op_alu || - * || CHK | op_CHK || MOVEM | (*1) || SUBI | op_imm || - * || CLR | op4alu || MOVEP | opMOVP || SUBQ | opADSQ || - * || CMP | op_alu || MOVEQ | opMOVQ || SUBX | opADSX || - * || CMPA | op_alu || MULS | op_MUL || SWAP | opSWAP || - * || CMPI | op_imm || MULU | op_MUL || TAS | op_TAS || - * || CMPM | opCMPM || NBCD | opNBCD || TRAP | opTRAP || - * || DBcc | opDBcc || NEG | op4alu || TRAPV | op4E7x || - * || DIVS | op_DIV || NEGX | op4alu || TST | op4alu || - * || DIVU | op_DIV || NOP | op4E7X || UNLK | opUNLK || - * - * (*1) MOVEM is implemented by two instructions, op_STM (MOVEM reglist,mem) - * and op_LDM (MOVEM mem,reglist). - * - * Cycle counts were taken from: - * http://linas.org/mirrors/www.nvg.ntnu.no/2002.09.16/amiga/MC680x0_Sections/mc68000timing.HTML - */ - -/*************************************************************************/ - -/* Forward declarations for helper functions and instruction implementations */ - -static void set_SR(Q68State *state, uint16_t value); -static inline void check_interrupt(Q68State *state); -static int take_exception(Q68State *state, uint8_t num); -static inline int op_ill(Q68State *state, uint32_t opcode); - -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type); -/* Note: Allowing these to be inlined actually slows down the code by ~0.5% - * (at least on x86). FIXME: how about PSP? */ -static NOINLINE uint32_t ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret); -static NOINLINE void ea_set(Q68State *state, uint32_t opcode, int size, - uint32_t data); - -static int op_imm(Q68State *state, uint32_t opcode); -static int op_bit(Q68State *state, uint32_t opcode); -static int opMOVE(Q68State *state, uint32_t opcode); -static int op4xxx(Q68State *state, uint32_t opcode); -static int op_CHK(Q68State *state, uint32_t opcode); -static int op_LEA(Q68State *state, uint32_t opcode); -static int opADSQ(Q68State *state, uint32_t opcode); -static int op_Scc(Q68State *state, uint32_t opcode); -static int opDBcc(Q68State *state, uint32_t opcode); -static int op_Bcc(Q68State *state, uint32_t opcode); -static int opMOVQ(Q68State *state, uint32_t opcode); -static int op_alu(Q68State *state, uint32_t opcode); -static int op_DIV(Q68State *state, uint32_t opcode); -static int opAxxx(Q68State *state, uint32_t opcode); -static int op_MUL(Q68State *state, uint32_t opcode); -static int opshft(Q68State *state, uint32_t opcode); -static int opFxxx(Q68State *state, uint32_t opcode); - -static int op4alu(Q68State *state, uint32_t opcode); -static int opMVSR(Q68State *state, uint32_t opcode); -static int opNBCD(Q68State *state, uint32_t opcode); -static int op_PEA(Q68State *state, uint32_t opcode); -static int opSWAP(Q68State *state, uint32_t opcode); -static int op_TAS(Q68State *state, uint32_t opcode); -static int op_EXT(Q68State *state, uint32_t opcode); -static int op_STM(Q68State *state, uint32_t opcode); -static int op_LDM(Q68State *state, uint32_t opcode); -static int opmisc(Q68State *state, uint32_t opcode); -static int opTRAP(Q68State *state, uint32_t opcode); -static int opLINK(Q68State *state, uint32_t opcode); -static int opUNLK(Q68State *state, uint32_t opcode); -static int opMUSP(Q68State *state, uint32_t opcode); -static int op4E7x(Q68State *state, uint32_t opcode); -static int opjump(Q68State *state, uint32_t opcode); - -static int opMOVP(Q68State *state, uint32_t opcode); -static int opADSX(Q68State *state, uint32_t opcode); -static int op_BCD(Q68State *state, uint32_t opcode); -static int opCMPM(Q68State *state, uint32_t opcode); -static int op_EXG(Q68State *state, uint32_t opcode); - -/*-----------------------------------------------------------------------*/ - -/* Main table of instruction implemenation functions; table index is bits - * 15-12 and 8-6 of the opcode (ABCD ...E FG.. .... -> 0ABC DEFG). */ -static OpcodeFunc * const opcode_table[128] = { - op_imm, op_imm, op_imm, op_imm, op_bit, op_bit, op_bit, op_bit, // 00 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 10 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 20 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 30 - - op4xxx, op4xxx, op4xxx, op4xxx, op_ill, op_ill, op_CHK, op_LEA, // 40 - opADSQ, opADSQ, opADSQ, op_Scc, opADSQ, opADSQ, opADSQ, op_Scc, // 50 - op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, // 60 - opMOVQ, opMOVQ, opMOVQ, opMOVQ, op_ill, op_ill, op_ill, op_ill, // 70 - - op_alu, op_alu, op_alu, op_DIV, op_alu, op_alu, op_alu, op_DIV, // 80 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // 90 - opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, // A0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // B0 - - op_alu, op_alu, op_alu, op_MUL, op_alu, op_alu, op_alu, op_MUL, // C0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // D0 - opshft, opshft, opshft, opshft, opshft, opshft, opshft, opshft, // E0 - opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, // F0 -}; - -/* Subtable for instructions in the $4xxx (miscellaneous) group; table index - * is bits 11-9 and 7-6 of the opcode (1000 ABC0 DE.. .... -> 000A BCDE). */ -static OpcodeFunc * const opcode_4xxx_table[32] = { - op4alu, op4alu, op4alu, opMVSR, // 40xx - op4alu, op4alu, op4alu, op_ill, // 42xx - op4alu, op4alu, op4alu, opMVSR, // 44xx - op4alu, op4alu, op4alu, opMVSR, // 46xx - opNBCD, op_PEA, op_STM, op_STM, // 48xx - op4alu, op4alu, op4alu, op_TAS, // 4Axx - op_ill, op_ill, op_LDM, op_LDM, // 4Cxx - op_ill, opmisc, opjump, opjump, // 4Exx -}; - -/* Sub-subtable for instructions in the $4E40-$4E7F range, used by opmisc(); - * index is bits 5-3 of the opcode. */ -static OpcodeFunc * const opcode_4E4x_table[8] = { - opTRAP, opTRAP, opLINK, opUNLK, - opMUSP, opMUSP, op4E7x, op_ill, -}; - -#ifdef COUNT_OPCODES -/* Counters for opcode groups. */ -uint32_t q68_ops[128], q68_4xxx_ops[32]; -#endif - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * q68_reset: Reset the virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_reset(Q68State *state) -{ - int i; - for (i = 0; i < 8; i++) { - state->D[i] = 0; - state->A[i] = 0; - } - state->PC = 0; - state->SR = SR_S; - SR_SET_I(state, 7); - state->USP = 0; - state->SSP = 0; - state->current_PC = 0; - state->ea_addr = 0; - state->exception = 0; - state->fault_addr = 0; - state->fault_opcode = 0; - state->fault_status = 0; - state->jit_running = NULL; -#ifdef Q68_USE_JIT - q68_jit_reset(state); -#endif -#ifdef Q68_TRACE - q68_trace_init(state); -#endif - - state->A[7] = READU32(state, 0x000000); - state->PC = READU32(state, 0x000004); - state->halted = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_run: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles executed (may be greater than "cycles") - */ -int q68_run(Q68State *state, int cycles) -{ - /* Check for pending interrupts */ - check_interrupt(state); - - /* Run the virtual processor */ - state->cycles = 0; - while (state->cycles < cycles) { - if (UNLIKELY(state->halted)) { - /* If we're halted, consume all remaining cycles */ - state->cycles = cycles; - break; - } - if (UNLIKELY(state->exception)) { - int exception = state->exception; - state->exception = 0; - state->cycles += take_exception(state, exception); - if (state->cycles >= cycles) { - break; - } - } -#ifdef Q68_USE_JIT - if (!state->jit_running) { - state->jit_running = q68_jit_find(state, state->PC); - if (UNLIKELY(!state->jit_running)) { - state->jit_running = q68_jit_translate(state, state->PC); - } - } - if (state->jit_running) { - q68_jit_run(state, cycles, &state->jit_running); - } else { -#endif -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (UNLIKELY(state->PC & 1)) { - state->fault_addr = state->PC; - state->fault_status = FAULT_STATUS_IN_INSN - | FAULT_STATUS_RW_READ; - state->cycles += take_exception(state, EX_ADDRESS_ERROR); - continue; - } -#endif -#ifdef Q68_TRACE - q68_trace(); -#endif - const unsigned int opcode = IFETCH(state); - state->current_PC = state->PC; -#ifndef Q68_DISABLE_ADDRESS_ERROR - state->fault_opcode = opcode; -#endif - const unsigned int index = (opcode>>9 & 0x78) | (opcode>>6 & 0x07); -#ifdef COUNT_OPCODES - q68_ops[index]++; -#endif - state->cycles += (*opcode_table[index])(state, opcode); -#ifdef Q68_USE_JIT - } -#endif - } // while (state->cycles < cycles && !state->halted) - -#ifdef Q68_TRACE - q68_trace_add_cycles(state->cycles); -#endif - - return state->cycles; -} - -/*************************************************************************/ -/************************** Instruction helpers **************************/ -/*************************************************************************/ - -/** - * set_SR: Set the processor's status register, performing any necessary - * additional actions (such as switching user/supervisor stacks). - * - * [Parameters] - * state: Processor state block - * value: New SR value - * [Return value] - * None - */ -static void set_SR(Q68State *state, uint16_t value) -{ - const uint16_t old_value = state->SR; - state->SR = value; - if ((old_value ^ value) & SR_S) { - if (value & SR_S) { // Switched to supervisor mode - state->USP = state->A[7]; - state->A[7] = state->SSP; - } else { // Switched to user mode - state->SSP = state->A[7]; - state->A[7] = state->USP; - } - } - check_interrupt(state); -} - -/*************************************************************************/ - -/** - * check_interrupt: Check whether an unmasked interrupt is pending, and - * raise the appropriate exception if so. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -static inline void check_interrupt(Q68State *state) -{ - const int irq = state->irq & 7; // Just to be safe - if (UNLIKELY(irq > SR_GET_I(state) - || irq == 7 // Level 7 is the non-maskable interrupt - )) { - if (state->halted != Q68_HALTED_DOUBLE_FAULT) { - state->irq = 0; - state->halted = 0; - state->exception = EX_LEVEL_1_INTERRUPT + (irq-1); - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * take_exception: Take an exception. - * - * [Parameters] - * state: Processor state block - * num: Exception number - * [Return value] - * Clock cycles used - */ -static int take_exception(Q68State *state, uint8_t num) -{ - static const int exception_cycles[256] = { - [EX_BUS_ERROR ] = 50, - [EX_ADDRESS_ERROR ] = 50, - [EX_ILLEGAL_INSTRUCTION ] = 34, - [EX_DIVIDE_BY_ZERO ] = 42, - [EX_CHK ] = 44, - [EX_TRAPV ] = 34, - [EX_PRIVILEGE_VIOLATION ] = 34, - [EX_TRACE ] = 34, - [EX_LINE_1010 ] = 34, // These two are assumed to be - [EX_LINE_1111 ] = 34, // equal to ILLEGAL_INSTRUCTION - [EX_SPURIOUS_INTERRUPT ] = 44, - [EX_LEVEL_1_INTERRUPT ] = 44, - [EX_LEVEL_2_INTERRUPT ] = 44, - [EX_LEVEL_3_INTERRUPT ] = 44, - [EX_LEVEL_4_INTERRUPT ] = 44, - [EX_LEVEL_5_INTERRUPT ] = 44, - [EX_LEVEL_6_INTERRUPT ] = 44, - [EX_LEVEL_7_INTERRUPT ] = 44, - [EX_TRAP+ 0 ] = 38, - [EX_TRAP+ 1 ] = 38, - [EX_TRAP+ 2 ] = 38, - [EX_TRAP+ 3 ] = 38, - [EX_TRAP+ 4 ] = 38, - [EX_TRAP+ 5 ] = 38, - [EX_TRAP+ 6 ] = 38, - [EX_TRAP+ 7 ] = 38, - [EX_TRAP+ 8 ] = 38, - [EX_TRAP+ 9 ] = 38, - [EX_TRAP+10 ] = 38, - [EX_TRAP+11 ] = 38, - [EX_TRAP+12 ] = 38, - [EX_TRAP+13 ] = 38, - [EX_TRAP+14 ] = 38, - [EX_TRAP+15 ] = 38, - }; - - /* Clear this out ahead of time in case we hit a double fault */ - state->jit_running = NULL; - - if (!(state->SR & SR_S)) { - state->USP = state->A[7]; - state->A[7] = state->SSP; - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->halted = Q68_HALTED_DOUBLE_FAULT; // Oops! - return 0; - } -#endif - PUSH32(state, state->PC); - PUSH16(state, state->SR); - if (num == EX_BUS_ERROR || num == EX_ADDRESS_ERROR) { - PUSH16(state, state->fault_opcode); - PUSH32(state, state->fault_addr); - PUSH16(state, state->fault_status); - } - state->SR |= SR_S; - if (num >= EX_LEVEL_1_INTERRUPT && num <= EX_LEVEL_7_INTERRUPT) { - SR_SET_I(state, (num - EX_LEVEL_1_INTERRUPT) + 1); - } - state->PC = READU32(state, num*4); -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->PC & 1) { - /* FIXME: Does a real 68000 double fault here or just take an - * address error exception? */ - state->halted = Q68_HALTED_DOUBLE_FAULT; - return 0; - } -#endif - return exception_cycles[num]; -} - -/*************************************************************************/ - -/** - * op_ill: Handle a generic illegal opcode. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * [Return value] - * Clock cycles used - */ -static inline int op_ill(Q68State *state, uint32_t opcode) -{ - state->exception = EX_ILLEGAL_INSTRUCTION; - return 0; -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * ea_resolve: Resolve the address for the memory-reference EA indicated - * by opcode[5:0], storing it in state->ea_addr. Behavior is undefined if - * the EA is a direct register reference. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * access_type: Access type (ACCESS_*) - * [Return value] - * Clock cycles used (negative indicates an illegal EA) - */ -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type) -{ - const unsigned int mode = EA_MODE(opcode); - const unsigned int reg = EA_REG(opcode); - const unsigned int bytes = SIZE_TO_BYTES(size); - - static const int base_cycles[8] = {0, 0, 4, 4, 6, 8, 10, 0}; - int cycles = base_cycles[mode] + (size==SIZE_L ? 4 : 0); - - switch (mode) { - case EA_INDIRECT: - state->ea_addr = state->A[reg]; - break; - case EA_POSTINCREMENT: - state->ea_addr = state->A[reg]; - state->A[reg] += bytes; - if (bytes == 1 && reg == 7) { // A7 must stay even - state->A[reg] += 1; - } - break; - case EA_PREDECREMENT: - if (access_type == ACCESS_WRITE) { - /* 2-cycle penalty not applied to write-only accesses - * (MOVE and MOVEM) */ - cycles -= 2; - } - state->A[reg] -= bytes; - if (bytes == 1 && reg == 7) { // A7 must stay even - state->A[reg] -= 1; - } - state->ea_addr = state->A[reg]; - break; - case EA_DISPLACEMENT: - state->ea_addr = state->A[reg] + (int16_t)IFETCH(state); - break; - case EA_INDEX: { - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int32_t index = (ext & 0x0800) ? (int32_t)state->DA[ireg] - : (int16_t)state->DA[ireg]; - const int32_t disp = (int32_t)((int8_t)ext); - state->ea_addr = state->A[reg] + index + disp; - break; - } - default: /* case EA_MISC */ - switch (reg) { - case EA_MISC_ABSOLUTE_W: - cycles += 8; - state->ea_addr = (int16_t)IFETCH(state); - break; - case EA_MISC_ABSOLUTE_L: - cycles += 12; - state->ea_addr = IFETCH(state) << 16; - state->ea_addr |= (uint16_t)IFETCH(state); - break; - case EA_MISC_PCREL: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 8; - state->ea_addr = state->current_PC + (int16_t)IFETCH(state); - } - break; - case EA_MISC_PCREL_INDEX: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 10; - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int32_t index = (ext & 0x0800) ? (int32_t)state->DA[ireg] - : (int16_t)state->DA[ireg]; - const int32_t disp = (int32_t)((int8_t)ext); - state->ea_addr = state->current_PC + index + disp; - } - break; - case EA_MISC_IMMEDIATE: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 4; - state->ea_addr = state->PC; - if (size == SIZE_B) { - state->ea_addr++; // Point at the lower byte - } - state->PC += (size==SIZE_L ? 4 : 2); - } - break; - default: - return -1; - } - } - return cycles; -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_get: Read an unsigned value from the EA indicated by opcode[5:0]. - * - * If the EA selector is invalid for the access size and mode, an illegal - * instruction exception is raised. If the EA is a memory reference, the - * size is word or long, and the address is odd, an address error - * exception is raised. In either case, the error is indicated by a - * negative value returned in *cycles_ret. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * is_rmw: Nonzero if the operand will be modified and written back - * cycles_ret: Pointer to variable to receive clock cycles used - * (negative indicates that an exception occurred) - * [Return value] - * Value read (undefined if an exception occurs) - */ -static uint32_t ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret) -{ - const unsigned int reg = EA_REG(opcode); - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - *cycles_ret = 0; - return size==SIZE_B ? (uint8_t) state->D[reg] : - size==SIZE_W ? (uint16_t)state->D[reg] : state->D[reg]; - case EA_ADDRESS_REG: - if (size == SIZE_B) { - /* An.b not permitted */ - state->exception = EX_ILLEGAL_INSTRUCTION; - *cycles_ret = -1; - return 0; - } else { - *cycles_ret = 0; - return size==SIZE_W ? (uint16_t)state->A[reg] : state->A[reg]; - } - default: { - *cycles_ret = ea_resolve(state, opcode, size, - is_rmw ? ACCESS_MODIFY : ACCESS_READ); - if (*cycles_ret < 0) { - state->exception = EX_ILLEGAL_INSTRUCTION; - return 0; - } - if (size == SIZE_B) { - return READU8(state, state->ea_addr); - } else { -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - *cycles_ret = -1; - return 0; - } -#endif - return size==SIZE_W ? READU16(state, state->ea_addr) - : READU32(state, state->ea_addr); - } - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_set: Update a value at the EA indicated by opcode[5:0]. If the - * EA is a memory reference, uses the previously resolved address in - * state->ea_addr rather than resolving the address again. Behavior is - * undefined if the previous ea_resolve() or ea_get() failed (or if no - * previous call was made). - * - * If the EA is a memory reference, the size is word or long, and the - * address is odd, an address error exception is raised instead. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * data: Value to store - * [Return value] - * None - */ -static void ea_set(Q68State *state, uint32_t opcode, int size, uint32_t data) -{ - const unsigned int reg = EA_REG(opcode); - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - switch (size) { - case SIZE_B: *(BYTE_OFS + (uint8_t *)&state->D[reg]) = data; break; - case SIZE_W: *(WORD_OFS + (uint16_t *)&state->D[reg]) = data; break; - default: state->D[reg] = data; break; - } - return; - case EA_ADDRESS_REG: - if (size == SIZE_W) { - state->A[reg] = (int16_t)data; // Sign-extended for address regs - } else { // must be SIZE_L - state->A[reg] = data; - } - return; - default: { - if (size == SIZE_B) { - WRITE8(state, state->ea_addr, data); - } else { -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return; - } else -#endif - if (size == SIZE_W) { - WRITE16(state, state->ea_addr, data); - } else { - WRITE32(state, state->ea_addr, data); - } - } - return; - } - } -} - -/*************************************************************************/ -/*********************** Major instruction groups ************************/ -/*************************************************************************/ - -/** - * op_imm: Immediate instructions (format 0000 xxx0 xxxx xxxx). - */ -static int op_imm(Q68State *state, uint32_t opcode) -{ - /* Check for bit-twiddling and illegal opcodes first */ - enum {OR = 0, AND, SUB, ADD, _BIT, EOR, CMP, _ILL} aluop; - aluop = opcode>>9 & 7; - if (aluop == _BIT) { - return op_bit(state, opcode); - } else if (aluop == _ILL) { - return op_ill(state, opcode); - } - - /* Get the instruction size */ - INSN_GET_SIZE; - if (size == 3) { - return op_ill(state, opcode); - } - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - - /* Fetch the immediate value */ - uint32_t imm = (uint16_t)IFETCH(state); - if (size == SIZE_B) { - imm &= 0xFF; - } else if (size == SIZE_L) { - imm = imm<<16 | (uint16_t)IFETCH(state); - } - - /* Fetch the EA operand (which may be SR or CCR) */ - int use_SR; - int cycles; - uint32_t ea_val; - if ((aluop==OR || aluop==AND || aluop==EOR) && (opcode & 0x3F) == 0x3C) { - /* xxxI #imm,SR (or CCR) use the otherwise-invalid form of an - * immediate value destination */ - if (size == SIZE_W && !(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - use_SR = 1; - cycles = 8; // Total instruction time is 20 cycles - switch (size) { - case SIZE_B: ea_val = state->SR & 0xFF; break; - case SIZE_W: ea_val = state->SR; break; - default: return op_ill(state, opcode); - } - } else { - use_SR = 0; - ea_val = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - } - - /* Perform the operation */ - uint32_t result; - if (aluop == ADD || aluop == SUB) { - INSN_CLEAR_XCC(); - } else { - INSN_CLEAR_CC(); - } - switch (aluop) { - case OR: result = ea_val | imm; - break; - case AND: result = ea_val & imm; - break; - case EOR: result = ea_val ^ imm; - break; - case CMP: if (size == SIZE_L) { // CMPI takes less time in most cases - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 8; - } else { - cycles -= 2; - } - } else { - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 4; - } - } - /* fall through to... */ - case SUB: { result = (ea_val - imm) & valuemask; - if (((imm ^ ea_val) & (result ^ ea_val)) >> shift) { - state->SR |= SR_V; - } - if ((int)((imm >> shift) - (ea_val >> shift) - + (result >> shift)) > 0) { - state->SR |= SR_C; - if (aluop != CMP) { - state->SR |= SR_X; - } - } - break; - } - default: // case ADD - result = (ea_val + imm) & valuemask; - if (((ea_val ^ result) & (imm ^ result)) >> shift) { - state->SR |= SR_V; - } - if ((int)((ea_val >> shift) + (imm >> shift) - - (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - break; - } - INSN_SETNZ_SHIFT(result); - - /* Update the EA operand (if not CMPI) */ - if (aluop != CMP) { - if (use_SR) { - if (size == SIZE_W) { - set_SR(state, result); - } else { - state->SR &= 0xFF00; - state->SR |= result; - } - } else { - ea_set(state, opcode, size, result); - } - } - - /* All done */ - return (size==SIZE_L ? 16 : 8) - + (EA_MODE(opcode) == EA_DATA_REG ? 0 : 4) + cycles; -} - -/*************************************************************************/ - -/** - * op_bit: Bit-twiddling instructions (formats 0000 rrr1 xxxx xxxx and - * 0000 1000 xxxx xxxx). - */ -static int op_bit(Q68State *state, uint32_t opcode) -{ - /* Check early for MOVEP (coded as BTST/BCHG/BCLR/BSET Dn,An) */ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - if (opcode & 0x0100) { - return opMOVP(state, opcode); - } else { - return op_ill(state, opcode); - } - } - - enum {BTST = 0, BCHG = 1, BCLR = 2, BSET = 3} op = opcode>>6 & 3; - int cycles; - - /* Get the bit number to operate on */ - unsigned int bitnum; - if (opcode & 0x0100) { - /* Bit number in register */ - INSN_GET_REG; - bitnum = state->D[reg]; - cycles = 0; - } else { - bitnum = IFETCH(state); - cycles = 4; - } - - /* EA operand is 32 bits when coming from a register, 8 when from memory */ - int size; - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - size = SIZE_L; - bitnum %= 32; - break; - default: - size = SIZE_B; - bitnum %= 8; - break; - } - int cycles_tmp; - uint32_t value = ea_get(state, opcode, size, 1, &cycles_tmp); - if (cycles_tmp < 0) { - return 0; - } - cycles += cycles_tmp; - if (size == SIZE_L && (op == BCLR || op == BTST)) { - cycles += 2; - } - - /* Perform the operation */ - if ((value >> bitnum) & 1) { - state->SR &= ~SR_Z; - } else { - state->SR |= SR_Z; - } - switch (op) { - case BTST: /* Nothing to do */ break; - case BCHG: value ^= 1 << bitnum; break; - case BCLR: value &= ~(1 << bitnum); break; - case BSET: value |= 1 << bitnum; break; - } - - /* Update EA operand (if not BTST) */ - if (op != BTST) { - ea_set(state, opcode, size, value); - } - - /* Return cycle count; note that the times for BCHG.L, BCLR.L, and - * BSET.L are maximums (though how they vary is undocumented) */ - return (op==BTST ? 4 : 8) + cycles; -} - -/*************************************************************************/ - -/** - * opMOVE: MOVE.[bwl] instruction (format {01,10,11}xx xxxx xxxx xxxx). - */ -static int opMOVE(Q68State *state, uint32_t opcode) -{ - const int size = (opcode>>12==1 ? SIZE_B : opcode>>12==2 ? SIZE_L : SIZE_W); - - int cycles_src; - const uint32_t data = ea_get(state, opcode, size, 0, &cycles_src); - if (cycles_src < 0) { - return 0; - } - - /* Rearrange the opcode bits so we can pass the destination EA to - * ea_resolve() */ - const uint32_t dummy_opcode = (opcode>>9 & 7) | (opcode>>3 & 0x38); - int cycles_dest; - if (EA_MODE(dummy_opcode) <= EA_ADDRESS_REG) { - cycles_dest = 0; - } else { - cycles_dest = ea_resolve(state, dummy_opcode, size, ACCESS_WRITE); - if (cycles_dest < 0) { - return op_ill(state, opcode); - } - } - - /* Update condition codes if the target is not an address register */ - if (EA_MODE(dummy_opcode) != EA_ADDRESS_REG) { - INSN_CLEAR_CC(); - INSN_SETNZ(size==SIZE_B ? (int8_t)data : - size==SIZE_W ? (int16_t)data : (int32_t)data); - } - - /* Update the destination EA and return */ - ea_set(state, dummy_opcode, size, data); - return 4 + cycles_src + cycles_dest; -} - -/*************************************************************************/ - -/** - * op4xxx: Miscellaneous instructions (format 0100 xxx0 xxxx xxxx). - */ -static int op4xxx(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>7 & 0x1C) | (opcode>>6 & 3); -#ifdef COUNT_OPCODES - q68_4xxx_ops[index]++; -#endif - return (*opcode_4xxx_table[index])(state, opcode); -} - -/*************************************************************************/ - -/** - * op_CHK: CHK instruction (format 0100 rrr1 10xx xxxx). - */ -static int op_CHK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - int size = SIZE_W; // Bit 7 == 0 indicates long mode on the 68020 - - int cycles; - int32_t upper; // Yes, it's signed - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - upper = ea_get(state, opcode, size, 0, &cycles); - if (cycles < 0) { - return 0; - } - if (size == SIZE_W) { - upper = (int32_t)(int16_t)upper; - } - - int32_t value; - if (size == SIZE_W) { - value = (int32_t)(int16_t)state->D[reg]; - } else { - value = (int32_t)state->D[reg]; - } - if (value < 0) { - state->SR |= SR_N; - state->exception = EX_CHK; - return cycles; - } else if (value > upper) { - state->SR &= ~SR_N; - state->exception = EX_CHK; - return cycles; - } - - return 10 + cycles; -} - -/*************************************************************************/ - -/** - * op_LEA: LEA instruction (format 0100 rrr1 11xx xxxx). - */ -static int op_LEA(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - - /* Register, predecrement, postincrement, immediate modes are illegal */ - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } - state->A[reg] = state->ea_addr; - return cycles; -} - -/*************************************************************************/ - -/** - * opADSQ: ADDQ and SUBQ instructions (format 0101 iiix xxxx xxxx). - */ -static int opADSQ(Q68State *state, uint32_t opcode) -{ - const int is_sub = opcode & 0x0100; - INSN_GET_COUNT; - INSN_GET_SIZE; - if (EA_MODE(opcode) == EA_ADDRESS_REG && size == 1) { - size = 2; // ADDQ.W #imm,An is equivalent to ADDQ.L #imm,An - } - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - int cycles; - uint32_t data = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - - uint32_t result; - if (is_sub) { - result = data - count; - } else { - result = data + count; - } - result &= valuemask; - if (EA_MODE(opcode) != EA_ADDRESS_REG) { - INSN_CLEAR_XCC(); - INSN_SETNZ_SHIFT(result); - if ((is_sub ? ~result & data : result & ~data) >> shift) { - state->SR |= SR_V; - } - if ((is_sub ? result & ~data : ~result & data) >> shift) { - state->SR |= SR_X | SR_C; - } - } - - ea_set(state, opcode, size, result); - return (size==SIZE_L || EA_MODE(opcode) == EA_ADDRESS_REG ? 8 : 4) - + (EA_MODE(opcode) >= EA_INDIRECT ? 4 : 0) + cycles; -} - -/*************************************************************************/ - -/** - * op_Scc: Scc instruction (format 0101 cccc 11xx xxxx). - */ -static int op_Scc(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - /* DBcc Dn,disp is coded as Scc An with an extension word */ - return opDBcc(state, opcode); - } - - INSN_GET_COND; - const int is_true = INSN_COND_TRUE(cond); - /* From the cycle counts, it looks like this is a standard read/write - * access rather than a write-only access */ - int cycles; - if (EA_MODE(opcode) == EA_DATA_REG) { - cycles = 0; - } else { - cycles = ea_resolve(state, opcode, SIZE_B, ACCESS_MODIFY); - if (cycles < 0) { - return op_ill(state, opcode); - } - } - ea_set(state, opcode, SIZE_B, is_true ? 0xFF : 0x00); - if (EA_MODE(opcode) == EA_DATA_REG) { - /* Scc Dn is a special case */ - return is_true ? 6 : 4; - } else { - return 8 + cycles; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_DBcc: DBcc instruction (format 0101 cccc 1100 1xxx). - */ -static int opDBcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - const int is_true = INSN_COND_TRUE(cond); - INSN_GET_REG0; - INSN_GET_IMM16; - if (is_true) { - return 12; - } else if (--(*(WORD_OFS + (int16_t *)&state->D[reg0])) == -1) { - return 14; - } else { - state->PC = state->current_PC + imm16; - return 10; - } -} - -/*************************************************************************/ - -/** - * op_Bcc: Conditional branch instructions (format 0110 cccc dddd dddd). - */ -static int op_Bcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - INSN_GET_DISP8; - int cycles = 0; - if (disp == 0) { - disp = (int16_t)IFETCH(state); - cycles = 4; - } - if (cond == COND_F) { - /* BF is really BSR */ -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - PUSH32(state, state->PC); - state->PC = state->current_PC + disp; - return 18; - } else if (INSN_COND_TRUE(cond)) { - state->PC = state->current_PC + disp; - return 10; - } else { - return 8 + cycles; - } -} - -/*************************************************************************/ - -/** - * opMOVQ: MOVEQ instruction (format 0111 rrr0 iiii iiii). - */ -static int opMOVQ(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_IMM8; - state->D[reg] = imm8; - INSN_CLEAR_CC(); - INSN_SETNZ(imm8); - return 4; -} - -/*************************************************************************/ - -/** - * op_alu: Non-immediate ALU instructions (format 1ooo rrrx xxxx xxxx for - * ooo = 000, 001, 011, 100, 101). - */ -static int op_alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - - /* Pass off special and invalid instructions early */ - if (size != 3) { - if ((opcode & 0xB130) == 0x9100) { - /* ADDX/SUBX are coded as ADD/SUB.* Dn, */ - return opADSX(state, opcode); - } - if ((opcode & 0xB1F0) == 0x8100) { - /* ABCD/SBCD are coded as AND/OR.b Dn, */ - return op_BCD(state, opcode); - } - if ((opcode & 0xF130) == 0xC100) { - /* EXG is coded as AND.[wl] Dn, */ - return op_EXG(state, opcode); - } - if ((opcode & 0xF130) == 0x8100) { - /* OR.[wl] Dn, is invalid on the 68000 (later PACK/UNPK) */ - return op_ill(state, opcode); - } - if ((opcode & 0xF138) == 0xB108 && (opcode>>6 & 3) != 3) { - /* CMPM is coded as EOR.* Dn, */ - return opCMPM(state, opcode); - } - } - - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - int ea_dest = opcode & 0x100; - int areg_dest = 0; // For ADDA/SUBA/CMPA - enum {OR, AND, EOR, CMP, SUB, ADD} aluop; - - /* Find the instruction for the opcode group */ - switch (opcode>>12) { - case 0x8: aluop = OR; break; - case 0x9: aluop = SUB; break; - case 0xB: aluop = (((opcode>>6)+1) & 7) <= 4 ? CMP : EOR; break; - case 0xC: aluop = AND; break; - default: aluop = ADD; break; // case 0xD - } - - /* Handle the special formats of ADDA/SUBA/CMPA */ - if ((aluop == ADD || aluop == SUB || aluop == CMP) && size == 3) { - size = ea_dest ? SIZE_L : SIZE_W; - ea_dest = 0; - areg_dest = 1; - } - - /* Retrieve the register and EA values */ - uint32_t reg_val = areg_dest ? state->A[reg] : (state->D[reg] & valuemask); - int cycles; - uint32_t ea_val = ea_get(state, opcode, size, ea_dest, &cycles); - if (cycles < 0) { - return 0; - } - if (size == SIZE_L || areg_dest) { - cycles += 4; - } - if (ea_dest) { - cycles += 4; - } else if ((aluop == CMP && areg_dest) - || (size == SIZE_L - && (EA_MODE(opcode) <= EA_ADDRESS_REG - || (EA_MODE(opcode) == EA_MISC - && EA_REG(opcode) == EA_MISC_IMMEDIATE)))) { - cycles -= 2; - } - - /* Perform the actual computation */ - uint32_t result; - if (!areg_dest || aluop == CMP) { - if (aluop == ADD || aluop == SUB) { - INSN_CLEAR_XCC(); - } else { - INSN_CLEAR_CC(); - } - } - switch (aluop) { - case OR: result = reg_val | ea_val; - break; - case AND: result = reg_val & ea_val; - break; - case EOR: result = reg_val ^ ea_val; - break; - case CMP: /* fall through to... */ - case SUB: { uint32_t src, dest; - if (areg_dest) { - /* CMPA/SUBA keep all 32 bits, and SUBA doesn't - * touch flags */ - src = ea_val; - dest = reg_val; - result = reg_val - ea_val; - if (aluop == SUB) { - break; - } - } else { - if (ea_dest) { - src = reg_val; - dest = ea_val; - } else { - src = ea_val; - dest = reg_val; - } - result = (dest - src) & valuemask; - } - if (((src ^ dest) & (result ^ dest)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) - (dest >> shift) - + (result >> shift)) > 0) { - state->SR |= SR_C; - if (aluop != CMP) { - state->SR |= SR_X; - } - } - break; - } - default: // case ADD - if (areg_dest) { - /* ADDA keeps all 32 bits and doesn't touch flags */ - result = reg_val + ea_val; - break; - } - result = (reg_val + ea_val) & valuemask; - if (((reg_val ^ result) & (ea_val ^ result)) >> shift) { - state->SR |= SR_V; - } - if ((int)((reg_val >> shift) + (ea_val >> shift) - - (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - break; - } // switch (aluop) - if (!areg_dest || aluop == CMP) { - INSN_SETNZ_SHIFT(result); - } - - /* Store the result in the proper place (if the instruction is not CMP) */ - if (aluop != CMP) { - if (ea_dest) { - ea_set(state, opcode, size, result); - } else if (areg_dest) { - state->A[reg] = result; - } else if (size == SIZE_B) { - *(BYTE_OFS + (uint8_t *)&state->D[reg]) = result; - } else if (size == SIZE_W) { - *(WORD_OFS + (uint16_t *)&state->D[reg]) = result; - } else { // size == SIZE_L - state->D[reg] = result; - } - } - - return 4 + cycles; -} - -/*************************************************************************/ - -/** - * op_DIV: DIVU and DIVS instructions (format 1000 rrrx 11xx xxxx). - */ -static int op_DIV(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - state->SR &= ~SR_C; // Always cleared, even on exception - - int cycles; - const uint16_t divisor = ea_get(state, opcode, SIZE_W, 0, &cycles); - if (cycles < 0) { - return 0; - } - if (divisor == 0) { - state->exception = EX_DIVIDE_BY_ZERO; - return cycles; - } - - int32_t quotient, remainder; - if (sign) { - quotient = (int32_t)state->D[reg] / (int16_t)divisor; - remainder = (int32_t)state->D[reg] % (int16_t)divisor; - if (quotient < -0x8000 || quotient > 0x7FFF) { - state->SR |= SR_V; - } else { - state->SR &= ~SR_V; - } - } else { - quotient = state->D[reg] / divisor; - remainder = state->D[reg] % divisor; - if (quotient & 0xFFFF0000) { - state->SR |= SR_V; - } else { - state->SR &= ~SR_V; - } - } - - if (!(state->SR & SR_V)) { - state->D[reg] = (quotient & 0xFFFF) | (remainder << 16); - if (quotient & 0x8000) { - state->SR |= SR_N; - } else { - state->SR &= ~SR_N; - } - if (quotient == 0) { - state->SR |= SR_Z; - } else { - state->SR &= ~SR_Z; - } - } - /* The 68000 docs say that the timing difference between best and - * worst cases is less than 10%, so we just return the worst case */ - return (sign ? 158 : 140) + cycles; -} - -/*************************************************************************/ - -/** - * opAxxx: $Axxx illegal instruction set (format 1010 xxxx xxxx xxxx). - */ -static int opAxxx(Q68State *state, uint32_t opcode) -{ - state->exception = EX_LINE_1010; - return 0; -} - -/*************************************************************************/ - -/** - * op_MUL: MULU and MULS instructions (format 1100 rrrx 11xx xxxx). - */ -static int op_MUL(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - int cycles; - const uint16_t data = ea_get(state, opcode, SIZE_W, 0, &cycles); - if (cycles < 0) { - return 0; - } - - if (sign) { - state->D[reg] = (int16_t)state->D[reg] * (int16_t)data; - } else { - state->D[reg] = (uint16_t)state->D[reg] * data; - } - INSN_CLEAR_CC(); - INSN_SETNZ(state->D[reg]); - - /* Precise timing varies with the effective address; the algorithm is - * implemented below for reference, but for typical usage it's probably - * not important to be exact */ -#ifdef MUL_PRECISE_TIMING // not normally defined - if (sign) { - uint32_t temp; - for (temp = (uint32_t)data << 1; temp != 0; temp >>= 1) { - if ((temp & 3) == 1 || (temp & 3) == 2) { - cycles += 2; - } - } - } else { - unsigned int temp; - for (temp = data; temp != 0; temp >>= 1) { - if (temp & 1) { - cycles += 2; - } - } - } - return 38 + cycles; -#else // !MUL_PRECISE_TIMING - return 54 + cycles; -#endif -} - -/*************************************************************************/ - -/** - * opshft: Shift and rotate instructions (format 1110 xxxx xxxx xxxx). - */ -static int opshft(Q68State *state, uint32_t opcode) -{ - const int is_left = opcode & 0x0100; - INSN_GET_SIZE; - INSN_GET_COUNT; - INSN_GET_REG0; - int is_memory; - int type; // Shift/rotate type (0=ASL/ASR, 1=LSL/LSR, ...) - uint32_t data; - int cycles; - - if (size == 3) { - /* Memory shift/rotate */ - is_memory = 1; - if ((opcode & 0x0800) || EA_MODE(opcode) <= EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - size = SIZE_W; - type = opcode>>9 & 3; - count = 1; - data = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - } else { - /* Register shift/rotate */ - is_memory = 0; - type = opcode>>3 & 3; - if (opcode & 0x0020) { - INSN_GET_REG; - count = state->D[reg] & 63; - } - data = size==SIZE_B ? (uint8_t) state->D[reg0] : - size==SIZE_W ? (uint16_t)state->D[reg0] : state->D[reg0]; - cycles = 0; - } - cycles += count*2; - - INSN_CLEAR_CC(); - if (count > 0) { - const int nbits = (size==SIZE_B ? 8 : size==SIZE_W ? 16 : 32); - switch (type) { - case 0: // ASL/ASR - state->SR &= ~SR_X; - if (is_left) { - int V = 0, C; - /* Have to shift bit by bit to detect overflow */ - for (; count > 0; count--) { - C = (data >> (nbits-1)) & 1; - data <<= 1; - V |= (C ^ (data >> (nbits-1))) & 1; - } - if (V) { - state->SR |= SR_V; - } - if (C) { - state->SR |= SR_X | SR_C; - } - } else { - if (size == SIZE_B) { // Sign extend if necessary - data = (int8_t)data; - } else if (size == SIZE_W) { - data = (int16_t)data; - } - if (count > nbits) { - count = 32; // Some systems break with a shift count >32 - } - data = (int32_t)data >> (count-1); - if (data & 1) { - state->SR |= SR_X | SR_C; - } - data = (int32_t)data >> 1; - } - break; - case 1: // LSL/LSR - state->SR &= ~SR_X; - if (count > nbits) { - data = 0; - } else if (is_left) { - data <<= count-1; - if ((data >> (nbits-1)) & 1) { - state->SR |= SR_X | SR_C; - } - data <<= 1; - } else { - data = (int32_t)data >> (count-1); - if (data & 1) { - state->SR |= SR_X | SR_C; - } - data = (int32_t)data >> 1; - } - break; - case 2: { // ROXL/ROXR - uint32_t X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~SR_X; - if (is_left) { - for (; count > 0; count--) { - const int new_X = (data >> (nbits-1)) & 1; - data = (data << 1) | X; - X = new_X; - } - } else { - for (; count > 0; count--) { - const int new_X = data & 1; - data = (data >> 1) | (X << (nbits-1)); - X = new_X; - } - } - if (X) { - state->SR |= SR_C | SR_X; - } - break; - } - default: { // (case 3) ROL/ROR - count %= nbits; - if (is_left) { - data = (data << count) | (data >> (nbits - count)); - if ((data >> (nbits-1)) & 1) { - state->SR |= SR_C; - } - data <<= 1; - } else { - data = (data >> count) | (data << (nbits - count)); - if (data & 1) { - state->SR |= SR_C; - } - data = (int32_t)data >> 1; - } - break; - } - } // switch (type) - } else { // count == 0 - if (type == 2 && (state->SR & SR_X)) { - state->SR |= SR_C; - } - } - INSN_SETNZ(size==SIZE_B ? (int8_t) data : - size==SIZE_W ? (int16_t)data : data); - - if (is_memory) { - ea_set(state, opcode, size, data); - } else { - switch (size) { - case SIZE_B: *(BYTE_OFS + (uint8_t *)&state->D[reg0]) = data; break; - case SIZE_W: *(WORD_OFS + (uint16_t *)&state->D[reg0]) = data; break; - default: state->D[reg0] = data; break; - } - } - return (size==SIZE_L ? 8 : 6) + cycles; -} - -/*************************************************************************/ - -/** - * opFxxx: $Fxxx illegal instruction set (format 1111 xxxx xxxx xxxx). - */ -static int opFxxx(Q68State *state, uint32_t opcode) -{ - state->exception = EX_LINE_1111; - return 0; -} - -/*************************************************************************/ -/*********************** $4xxx group instructions ************************/ -/*************************************************************************/ - -/** - * op4alu: Single-operand ALU instructions in the $4xxx opcode range - * (format 0100 ooo0 ssxx xxxx for ooo = 000, 001, 010, 011, 101). - */ -static int op4alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_SIZE; - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - enum {NEGX = 0, CLR = 1, NEG = 2, NOT = 3, TST = 5} aluop; - aluop = opcode>>9 & 7; - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Retrieve the EA value */ - int cycles; - uint32_t value = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - if (aluop != TST) { - if (EA_MODE(opcode) == EA_DATA_REG) { - if (size == SIZE_L) { - cycles += 2; - } - } else { - cycles += (size == SIZE_L) ? 8 : 4; - } - } - - /* Perform the actual computation */ - uint32_t result; - if (aluop == NEGX) { - state->SR &= ~(SR_N | SR_V | SR_C); // Z is never set, only cleared - } else { - INSN_CLEAR_CC(); - } - switch (aluop) { - case NEGX: { int X = (state->SR >> SR_X_SHIFT) & 1; - result = (0 - value - X) & valuemask; - if (result != 0) { - state->SR &= ~SR_Z; - } - goto NEG_common; - } - case NEG: result = (0 - value) & valuemask; - if (result == 0) { - state->SR |= SR_Z; - } else { - state->SR &= ~SR_Z; - } - NEG_common: - if (result >> shift) { - state->SR |= SR_N; - } - if ((value & result) >> shift) { - state->SR |= SR_V; - } - if ((value | result) != 0) { - state->SR |= SR_X | SR_C; - } else { - state->SR &= ~SR_X; - } - break; - case CLR: result = 0; - state->SR |= SR_Z; - break; - case NOT: result = ~value & valuemask; - INSN_SETNZ_SHIFT(result); - break; - default: // case TST - result = value; // Avoid a compiler warning - INSN_SETNZ_SHIFT(value); - break; - } // switch (aluop) - - /* Store the result in the proper place (if the instruction is not TST) */ - if (aluop != TST) { - ea_set(state, opcode, size, result); - } - - return 4 + cycles; -} - -/*************************************************************************/ - -/** - * opMVSR: MOVE to/from SR/CCR instructions (format 0100 0xx0 11xx xxxx). - */ -static int opMVSR(Q68State *state, uint32_t opcode) -{ - int is_CCR; - int ea_dest; - int cycles; - switch (opcode>>9 & 3) { - case 0: // MOVE SR, - is_CCR = 0; - ea_dest = 1; - cycles = (EA_MODE(opcode) == EA_DATA_REG) ? 6 : 8; - break; - case 1: // Undefined (MOVE CCR, on 68010) - return op_ill(state, opcode); - case 2: // MOVE ,CCR - is_CCR = 1; - ea_dest = 0; - cycles = 12; - break; - default: // MOVE ,SR (case 3) - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - is_CCR = 0; - ea_dest = 0; - cycles = 12; - break; - } - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Motorola docs say the address is read before being written, even - * for the SR, format; also, the access size is a word even for - * CCR operations. */ - int cycles_tmp; - uint16_t value = ea_get(state, opcode, SIZE_W, ea_dest, &cycles_tmp); - if (cycles_tmp < 0) { - return 0; - } - cycles += cycles_tmp; - - if (ea_dest) { - uint16_t value = state->SR; - if (is_CCR) { - value &= 0x00FF; - } - ea_set(state, opcode, SIZE_W, value); - } else { - if (!is_CCR) { - set_SR(state, value); - } - } - return cycles; -} - -/*************************************************************************/ - -/** - * opNBCD: NBCD instruction (format 0100 1000 00xx xxxx). - */ -static int opNBCD(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - int value = ea_get(state, opcode, SIZE_B, 1, &cycles); - if (cycles < 0) { - return 0; - } - - int result; - int X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~(SR_X | SR_C); // Z is never set, only cleared - /* Slightly convoluted to match what a real 68000 does (see SBCD) */ - int res_low = 0 - (value & 0x0F) - X; - int borrow = 0; - if (res_low < 0) { - res_low += 10; - borrow = 1<<4; - } - int res_high = 0 - (value & 0xF0) - borrow; - if (res_high < 0) { - res_high += 10<<4; - state->SR |= SR_X | SR_C; - } - result = res_high + res_low; - if (result < 0) { - state->SR |= SR_X | SR_C; - } - result &= 0xFF; - if (result != 0) { - state->SR &= ~SR_Z; - } - - ea_set(state, opcode, SIZE_B, result); - return (EA_MODE(opcode) == EA_DATA_REG ? 6 : 8) + cycles; -} - -/*************************************************************************/ - -/** - * op_PEA: PEA instruction (format 0100 1000 01xx xxxx). - */ -static int op_PEA(Q68State *state, uint32_t opcode) -{ - /* SWAP is coded as PEA Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return opSWAP(state, opcode); - } - - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - PUSH32(state, state->ea_addr); - return 8 + cycles; -} - -/*************************************************************************/ - -/** - * opSWAP: SWAP instruction (format 0100 1000 0100 0rrr). - */ -static int opSWAP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - state->D[reg0] = state->D[reg0]>>16 | state->D[reg0]<<16; - INSN_CLEAR_CC(); - INSN_SETNZ(state->D[reg0]); - return 4; -} - -/*************************************************************************/ - -/** - * op_TAS: TAS instruction (format 0100 1010 11xx xxxx). Also covers the - * ILLEGAL instruction (format 0100 1010 1111 1100). - */ -static int op_TAS(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - int8_t value = ea_get(state, opcode, SIZE_B, 1, &cycles); - if (cycles < 0) { - /* Note that the ILLEGAL instruction is coded as TAS #imm, so it - * will be rejected as unwriteable by ea_get() */ - return 0; - } - - INSN_CLEAR_CC(); - INSN_SETNZ(value); - ea_set(state, opcode, SIZE_B, value | 0x80); - return (EA_MODE(opcode) == EA_DATA_REG ? 4 : 10) + cycles; -} - -/*************************************************************************/ - -/** - * op_EXT: EXT instruction (format 0100 1000 1s00 0rrr). - */ -static int op_EXT(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - INSN_CLEAR_CC(); - if (opcode & 0x0040) { - int16_t value = (int16_t)state->D[reg0]; - state->D[reg0] = (int32_t)value; - INSN_SETNZ(value); - } else { - int8_t value = (int16_t)state->D[reg0]; - *(WORD_OFS + (int16_t *)&state->D[reg0]) = (int16_t)value; - INSN_SETNZ(value); - } - return 4; -} - -/*************************************************************************/ - -/** - * op_STM: MOVEM reglist, (i.e. STore Multiple) instruction (format - * 0100 1000 1sxx xxxx). - */ -static int op_STM(Q68State *state, uint32_t opcode) -{ - /* EXT.* is coded as MOVEM.* reglist,Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return op_EXT(state, opcode); - } - - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT // Not allowed for store - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_PREDECREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_WRITE); - if (cycles < 0) { - return op_ill(state, opcode); - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - - if (EA_MODE(opcode) == EA_PREDECREMENT) { - /* Register order is reversed in predecrement mode */ - int reg; - for (reg = 15; reg >= 0; reg--, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - state->ea_addr -= 2; - WRITE16(state, state->ea_addr, state->DA[reg]); - cycles += 4; - } else { - state->ea_addr -= 4; - WRITE32(state, state->ea_addr, state->DA[reg]); - cycles += 8; - } - } - } - state->A[EA_REG(opcode)] = state->ea_addr; - } else { - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - WRITE16(state, state->ea_addr, state->DA[reg]); - state->ea_addr += 2; - cycles += 4; - } else { - WRITE32(state, state->ea_addr, state->DA[reg]); - state->ea_addr += 4; - cycles += 8; - } - } - } - } - - return 4 + cycles; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_LDM: MOVEM ,reglist (i.e. LoaD Multiple) instruction (format - * 0100 1100 1sxx xxxx). - */ -static int op_LDM(Q68State *state, uint32_t opcode) -{ - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_PREDECREMENT // Not allowed for load - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - int16_t value = READS16(state, state->ea_addr); - if (reg < 8) { - *(WORD_OFS + (uint16_t *)&state->D[reg]) = value; - } else { - state->A[reg-8] = (int32_t)value; - } - state->ea_addr += 2; - cycles += 4; - } else { - state->DA[reg] = READU32(state, state->ea_addr); - state->ea_addr += 4; - cycles += 8; - } - } - } - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - state->A[EA_REG(opcode)] = state->ea_addr; - } - - return 8 + cycles; -} - -/*************************************************************************/ - -/** - * opmisc: $4xxx-group misc. instructions (format 0100 1110 01xx xxxx). - */ -static int opmisc(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>3 & 7); - return (*opcode_4E4x_table[index])(state, opcode); -} - -/*-----------------------------------------------------------------------*/ - -/** - * opTRAP: TRAP #n instruction (format 0100 1110 0100 nnnn). - */ -static int opTRAP(Q68State *state, uint32_t opcode) -{ - state->exception = EX_TRAP + (opcode & 0x000F); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opLINK: LINK instruction (format 0100 1110 0101 0rrr). - */ -static int opLINK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - int16_t disp = IFETCH(state); -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - PUSH32(state, state->A[reg0]); - state->A[reg0] = state->A[7]; - state->A[7] += disp; - return 16; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opUNLK: UNLK instruction (format 0100 1110 0101 1rrr). - */ -static int opUNLK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - /* FIXME: What happens if A7 is used as the register? I.e. does the - * postincrement happen before or after the value is written to - * the destination register? The Motorola docs could be read - * both ways, so going by the literal operation sequence here. */ - state->A[7] = state->A[reg0]; -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - state->A[reg0] = READU32(state, state->A[7]); - state->A[7] += 4; - return 12; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opMUSP: MOVE An,USP and MOVE USP,An instructions (format - * 0100 1110 0110 xrrr). - */ -static int opMUSP(Q68State *state, uint32_t opcode) -{ - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - - INSN_GET_REG0; - if (opcode & 0x0008) { - state->USP = state->A[reg0]; - } else { - state->A[reg0] = state->USP; - } - return 4; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op4E7x: Instructions with opcodes $4E70-$4E77 that don't fit anywhere - * else. - */ -static int op4E7x(Q68State *state, uint32_t opcode) -{ - switch (opcode & 7) { - case 0: // $4E70 RESET - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - return 132; - case 1: // $4E71 NOP - return 4; - case 2: // $4E72 STOP - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - state->halted = 1; - set_SR(state, IFETCH(state)); - return 4; - case 3: { // $4E73 RTE - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - uint16_t new_SR = POP16(state); - state->PC = POP32(state); - set_SR(state, new_SR); - return 20; - } - case 5: // $4E75 RTS -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - state->PC = POP32(state); - return 16; - case 6: // $4E76 TRAPV - if (state->SR & SR_V) { - state->exception = EX_TRAPV; - return 0; - } - return 4; - case 7: { // $4E77 RTR -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - state->SR &= 0xFF00; - state->SR |= POP16(state) & 0x00FF; - state->PC = POP32(state); - return 20; - } - default: // $4E74 RTD is 68010 only - return op_ill(state, opcode); - } -} - -/*************************************************************************/ - -/** - * opjump: JSR and JMP instructions (format 0100 1110 1xxx xxxx). - */ -static int opjump(Q68State *state, uint32_t opcode) -{ - int is_jsr = ~opcode & 0x0040; - - /* JMP is essentially identical to LEA PC, and has the same - * constraints. JSR is equivalent to MOVE.L PC,-(A7) followed by a - * JMP to the address. Both use a separate timing table, however. */ - - int cycles; - switch (EA_MODE(opcode)) { - case EA_INDIRECT: - cycles = 8; - break; - case EA_DISPLACEMENT: - cycles = 10; - break; - case EA_INDEX: - cycles = 14; - break; - case EA_MISC: - switch (EA_REG(opcode)) { - case EA_MISC_ABSOLUTE_W: - cycles = 10; - break; - case EA_MISC_ABSOLUTE_L: - cycles = 12; - break; - case EA_MISC_PCREL: - cycles = 10; - break; - case EA_MISC_PCREL_INDEX: - cycles = 14; - break; - default: - return op_ill(state, opcode); - } - break; - default: - return op_ill(state, opcode); - } - - ea_resolve(state, opcode, SIZE_W, ACCESS_READ); // cannot fail - if (is_jsr) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - cycles += 8; - PUSH32(state, state->PC); - } - state->PC = state->ea_addr; - return cycles; -} - -/*************************************************************************/ -/******************* Other miscellaneous instructions ********************/ -/*************************************************************************/ - -/** - * opMOVP: MOVEP instruction (0000 rrr1 xx00 1rrr). - */ -static int opMOVP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - int to_memory = opcode & 0x0080; - int is_long = opcode & 0x0040; - int16_t disp = IFETCH(state); - uint32_t addr = state->A[reg0] + disp; - - if (to_memory) { - uint32_t data = state->D[reg]; - if (is_long) { - WRITE8(state, addr+0, data>>24); - WRITE8(state, addr+2, data>>16); - WRITE8(state, addr+4, data>> 8); - WRITE8(state, addr+6, data>> 0); - } else { - WRITE8(state, addr+0, data>> 8); - WRITE8(state, addr+2, data>> 0); - } - } else { - uint32_t data; - if (is_long) { - data = READU8(state, addr+0) << 24; - data |= READU8(state, addr+2) << 16; - data |= READU8(state, addr+4) << 8; - data |= READU8(state, addr+6) << 0; - } else { - data = READU8(state, addr+0) << 8; - data |= READU8(state, addr+2) << 0; - } - state->D[reg] = data; - } - - return is_long ? 24 : 16; -} - -/*************************************************************************/ - -/** - * opADSX: ADDX/SUBX instructions (1x01 rrr1 ss00 xrrr). - */ -static int opADSX(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - uint32_t src = ea_get(state, src_ea, size, 0, &dummy); - uint32_t dest = ea_get(state, dest_ea, size, 1, &dummy); - - uint32_t result; - int X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~(SR_X | SR_N | SR_V | SR_C); // Z is never set, only cleared - if (is_add) { - result = (dest + src + X) & valuemask; - if (((src ^ result) & (dest ^ result)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) + (dest >> shift) - (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - } else { - result = (dest - src - X) & valuemask; - if (((src ^ dest) & (result ^ dest)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) - (dest >> shift) + (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - } - if (result >> shift) { - state->SR |= SR_N; - } - if (result != 0) { - state->SR &= ~SR_Z; - } - - ea_set(state, dest_ea, size, result); - return (is_memory ? (size==SIZE_L ? 30 : 18) : (size==SIZE_L ? 8 : 4)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_BCD: ABCD/SBCD instructions (1x00 rrr1 0000 xrrr). - */ -static int op_BCD(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - uint8_t src = ea_get(state, src_ea, SIZE_B, 0, &dummy); - uint8_t dest = ea_get(state, dest_ea, SIZE_B, 1, &dummy); - - int result; - int X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~(SR_X | SR_C); // Z is never set, only cleared - if (is_add) { - result = (dest & 0x0F) + (src & 0x0F) + X; - if (result >= 10) { - /* This seems to be correct w.r.t. a real 68000 and invalid data - * (e.g. 0x0F + 0x0F): it only checks for a carry of 1 */ - result += 6; - } - result += (dest & 0xF0) + (src & 0xF0); - if (result >= 10<<4) { - result -= 10<<4; - state->SR |= SR_X | SR_C; - } - } else { - /* Slightly convoluted to match what a real 68000 does */ - int res_low = (dest & 0x0F) - (src & 0x0F) - X; - int borrow = 0; - if (res_low < 0) { - res_low += 10; - borrow = 1<<4; - } - int res_high = (dest & 0xF0) - (src & 0xF0) - borrow; - if (res_high < 0) { - res_high += 10<<4; - state->SR |= SR_X | SR_C; - } - result = res_high + res_low; - if (result < 0) { - state->SR |= SR_X | SR_C; - } - } - result &= 0xFF; - if (result != 0) { - state->SR &= ~SR_Z; - } - - ea_set(state, dest_ea, SIZE_B, result); - return is_memory ? 18 : 6; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opCMPM: CMPM instructions (1011 rrr1 ss00 1rrr). - */ -static int opCMPM(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - - const uint16_t src_ea = EA_POSTINCREMENT<<3 | reg0; - const uint16_t dest_ea = EA_POSTINCREMENT<<3 | reg; - int dummy; - uint32_t src = ea_get(state, src_ea, size, 0, &dummy); - uint32_t dest = ea_get(state, dest_ea, size, 0, &dummy); - - uint32_t result = (dest - src) & valuemask; - INSN_CLEAR_XCC(); - INSN_SETNZ_SHIFT(result); - if (((src ^ dest) & (result ^ dest)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) - (dest >> shift) + (result >> shift)) > 0) { - state->SR |= SR_C; - } - - return size==SIZE_L ? 20 : 12; -} - -/*************************************************************************/ - -/** - * op_EXG: EXG instruction (1100 rrr1 xx00 1rrr). - */ -static int op_EXG(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int mode = opcode & 0xF8; - - if (mode == 0x40) { - const uint32_t tmp = state->D[reg]; - state->D[reg] = state->D[reg0]; - state->D[reg0] = tmp; - } else if (mode == 0x48) { - const uint32_t tmp = state->A[reg]; - state->A[reg] = state->A[reg0]; - state->A[reg0] = tmp; - } else if (mode == 0x88) { - const uint32_t tmp = state->D[reg]; - state->D[reg] = state->A[reg0]; - state->A[reg0] = tmp; - } else { - return op_ill(state, opcode); - } - return 6; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-disasm.c b/yabause/src/q68/q68-disasm.c deleted file mode 100644 index 9aab2ffcf4..0000000000 --- a/yabause/src/q68/q68-disasm.c +++ /dev/null @@ -1,836 +0,0 @@ -/* src/q68/q68-disasm.c: MC68000 disassembly routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "q68.h" -#include "q68-const.h" -#include "q68-internal.h" - -/*************************************************************************/ -/********************** 68k instruction disassembly **********************/ -/*************************************************************************/ - -/* Disassembly table. The first entry matching a given instruction is used. */ - -static const struct { - uint16_t mask, test; // Entry matches when (opcode & mask) == test - const char *format; // Instruction format -} instructions[] = { - - /* ALU immediate */ - - {0xFFFF, 0x003C, "ORI.B #,CCR"}, - {0xFFC0, 0x0000, "ORI.B #,"}, - {0xFFFF, 0x007C, "ORI.W #,SR"}, - {0xFFC0, 0x0040, "ORI.W #,"}, - {0xFFC0, 0x0080, "ORI.L #,"}, - {0xFFFF, 0x023C, "ANDI.B #,CCR"}, - {0xFFC0, 0x0200, "ANDI.B #,"}, - {0xFFFF, 0x027C, "ANDI.W #,SR"}, - {0xFFC0, 0x0240, "ANDI.W #,"}, - {0xFFC0, 0x0280, "ANDI.L #,"}, - {0xFFC0, 0x0400, "SUBI.B #,"}, - {0xFFC0, 0x0440, "SUBI.W #,"}, - {0xFFC0, 0x0480, "SUBI.L #,"}, - {0xFFC0, 0x0600, "ADDI.B #,"}, - {0xFFC0, 0x0640, "ADDI.W #,"}, - {0xFFC0, 0x0680, "ADDI.L #,"}, - {0xFFFF, 0x0A3C, "EORI.B #,CCR"}, - {0xFFC0, 0x0A00, "EORI.B #,"}, - {0xFFFF, 0x0A7C, "EORI.W #,SR"}, - {0xFFC0, 0x0A40, "EORI.W #,"}, - {0xFFC0, 0x0A80, "EORI.L #,"}, - {0xFFC0, 0x0C00, "CMPI.B #,"}, - {0xFFC0, 0x0C40, "CMPI.W #,"}, - {0xFFC0, 0x0C80, "CMPI.L #,"}, - - /* Bit twiddling and MOVEP */ - - {0xF1F8, 0x0108, "MOVEP.W (A),D"}, - {0xF1F8, 0x0148, "MOVEP.L (A),D"}, - {0xF1F8, 0x0188, "MOVEP.W D,(A)"}, - {0xF1F8, 0x01C8, "MOVEP.L D,(A)"}, - {0xFFC0, 0x0800, "BTST #,"}, - {0xFFC0, 0x0840, "BCHG #,"}, - {0xFFC0, 0x0880, "BCLR #,"}, - {0xFFC0, 0x08C0, "BSET #,"}, - {0xF1C0, 0x0100, "BTST D,"}, - {0xF1C0, 0x0140, "BCHG D,"}, - {0xF1C0, 0x0180, "BCLR D,"}, - {0xF1C0, 0x01C0, "BSET D,"}, - - /* MOVE */ - - {0xF1C0, 0x1040, "MOVEA.B ,A"}, - {0xF000, 0x1000, "MOVE.B ,"}, - {0xF1C0, 0x2040, "MOVEA.L ,A"}, - {0xF000, 0x2000, "MOVE.L ,"}, - {0xF1C0, 0x3040, "MOVEA.W ,A"}, - {0xF000, 0x3000, "MOVE.W ,"}, - - /* Miscellaneous */ - - {0xFFC0, 0x4000, "NEGX.B "}, - {0xFFC0, 0x4040, "NEGX.W "}, - {0xFFC0, 0x4080, "NEGX.L "}, - {0xFFC0, 0x40C0, "MOVE.W SR,"}, - - {0xFFC0, 0x4200, "CLR.B "}, - {0xFFC0, 0x4240, "CLR.W "}, - {0xFFC0, 0x4280, "CLR.L "}, - {0xFFC0, 0x42C0, "???"}, - - {0xFFC0, 0x4400, "NEG.B "}, - {0xFFC0, 0x4440, "NEG.W "}, - {0xFFC0, 0x4480, "NEG.L "}, - {0xFFC0, 0x44C0, "MOVE.W CCR,"}, - - {0xFFC0, 0x4600, "NOT.B "}, - {0xFFC0, 0x4640, "NOT.W "}, - {0xFFC0, 0x4680, "NOT.L "}, - {0xFFC0, 0x46C0, "MOVE.W ,SR"}, - - {0xFFF8, 0x4808, "???"}, - {0xFFC0, 0x4800, "NBCD.B "}, - {0xFFF8, 0x4840, "SWAP.W D"}, - {0xFFF8, 0x4848, "???"}, - {0xFFC0, 0x4840, "PEA.L "}, - {0xFFF8, 0x4880, "EXT.W D"}, - {0xFFF8, 0x48A0, "MOVEM.W ,-(A)"}, - {0xFFC0, 0x4880, "MOVEM.W ,"}, - {0xFFF8, 0x48C0, "EXT.L D"}, - {0xFFF8, 0x48E0, "MOVEM.L ,-(A)"}, - {0xFFC0, 0x48C0, "MOVEM.L ,"}, - - {0xFFC0, 0x4A00, "TST.B "}, - {0xFFC0, 0x4A40, "TST.W "}, - {0xFFC0, 0x4A80, "TST.L "}, - {0xFFFF, 0x4AFC, "ILLEGAL"}, - {0xFFC0, 0x4AC0, "TAS "}, - - {0xFFC0, 0x4C80, "MOVEM.W ,"}, - {0xFFC0, 0x4CC0, "MOVEM.L ,"}, - - {0xFFF0, 0x4E40, "TRAP #"}, - {0xFFF8, 0x4E50, "LINK #,A"}, - {0xFFF8, 0x4E58, "UNLK A"}, - {0xFFF8, 0x4E60, "MOVE USP,A"}, - {0xFFF8, 0x4E68, "MOVE A,USP"}, - {0xFFFF, 0x4E70, "RESET"}, - {0xFFFF, 0x4E71, "NOP"}, - {0xFFFF, 0x4E72, "STOP"}, - {0xFFFF, 0x4E73, "RTE"}, - {0xFFFF, 0x4E75, "RTS"}, - {0xFFFF, 0x4E76, "TRAPV"}, - {0xFFFF, 0x4E77, "RTR"}, - {0xFFC0, 0x4E80, "JSR "}, - {0xFFC0, 0x4EC0, "JMP "}, - - {0xF1C0, 0x4180, "CHK.W D,"}, - {0xF1C0, 0x41C0, "LEA.L ,A"}, - - /* ADDQ/SUBQ/Scc/DBcc */ - - {0xF1C0, 0x5000, "ADDQ.B #,"}, - {0xF1C0, 0x5040, "ADDQ.W #,"}, - {0xF1C0, 0x5080, "ADDQ.L #,"}, - {0xF1C0, 0x5100, "SUBQ.B #,"}, - {0xF1C0, 0x5140, "SUBQ.W #,"}, - {0xF1C0, 0x5180, "SUBQ.L #,"}, - {0xFFF8, 0x50C8, "DBT D,"}, - {0xFFC0, 0x50C0, "ST.B "}, - {0xFFF8, 0x51C8, "DBRA D,"}, - {0xFFC0, 0x51C0, "SF.B "}, - {0xFFF8, 0x52C8, "DBHI D,"}, - {0xFFC0, 0x52C0, "SHI.B "}, - {0xFFF8, 0x53C8, "DBLS D,"}, - {0xFFC0, 0x53C0, "SLS.B "}, - {0xFFF8, 0x54C8, "DBCC D,"}, - {0xFFC0, 0x54C0, "SCC.B "}, - {0xFFF8, 0x55C8, "DBCS D,"}, - {0xFFC0, 0x55C0, "SCS.B "}, - {0xFFF8, 0x56C8, "DBNE D,"}, - {0xFFC0, 0x56C0, "SNE.B "}, - {0xFFF8, 0x57C8, "DBEQ D,"}, - {0xFFC0, 0x57C0, "SEQ.B "}, - {0xFFF8, 0x58C8, "DBVC D,"}, - {0xFFC0, 0x58C0, "SVC.B "}, - {0xFFF8, 0x59C8, "DBVS D,"}, - {0xFFC0, 0x59C0, "SVS.B "}, - {0xFFF8, 0x5AC8, "DBPL D,"}, - {0xFFC0, 0x5AC0, "SPL.B "}, - {0xFFF8, 0x5BC8, "DBMI D,"}, - {0xFFC0, 0x5BC0, "SMI.B "}, - {0xFFF8, 0x5CC8, "DBLT D,"}, - {0xFFC0, 0x5CC0, "SLT.B "}, - {0xFFF8, 0x5DC8, "DBGE D,"}, - {0xFFC0, 0x5DC0, "SGE.B "}, - {0xFFF8, 0x5EC8, "DBLE D,"}, - {0xFFC0, 0x5EC0, "SLE.B "}, - {0xFFF8, 0x5FC8, "DBGT D,"}, - {0xFFC0, 0x5FC0, "SGT.B "}, - - /* BRA/BSR/Bcc */ - - {0xFFFF, 0x6000, "BRA.W "}, - {0xFF00, 0x6000, "BRA.S "}, - {0xFFFF, 0x6100, "BSR.W "}, - {0xFF00, 0x6100, "BSR.S "}, - {0xFFFF, 0x6200, "BHI.W "}, - {0xFF00, 0x6200, "BHI.S "}, - {0xFFFF, 0x6300, "BLS.W "}, - {0xFF00, 0x6300, "BLS.S "}, - {0xFFFF, 0x6400, "BCC.W "}, - {0xFF00, 0x6400, "BCC.S "}, - {0xFFFF, 0x6500, "BCS.W "}, - {0xFF00, 0x6500, "BCS.S "}, - {0xFFFF, 0x6600, "BNE.W "}, - {0xFF00, 0x6600, "BNE.S "}, - {0xFFFF, 0x6700, "BEQ.W "}, - {0xFF00, 0x6700, "BEQ.S "}, - {0xFFFF, 0x6800, "BVC.W "}, - {0xFF00, 0x6800, "BVC.S "}, - {0xFFFF, 0x6900, "BVS.W "}, - {0xFF00, 0x6900, "BVS.S "}, - {0xFFFF, 0x6A00, "BPL.W "}, - {0xFF00, 0x6A00, "BPL.S "}, - {0xFFFF, 0x6B00, "BMI.W "}, - {0xFF00, 0x6B00, "BMI.S "}, - {0xFFFF, 0x6C00, "BLT.W "}, - {0xFF00, 0x6C00, "BLT.S "}, - {0xFFFF, 0x6D00, "BGE.W "}, - {0xFF00, 0x6D00, "BGE.S "}, - {0xFFFF, 0x6E00, "BLE.W "}, - {0xFF00, 0x6E00, "BLE.S "}, - {0xFFFF, 0x6F00, "BGT.W "}, - {0xFF00, 0x6F00, "BGT.S "}, - - /* MOVEQ */ - - {0xF100, 0x7000, "MOVEQ #,D"}, - - /* ALU non-immediate,ABCD/SBCD etc. */ - - {0xF1F8, 0x8100, "SBCD.B D,D"}, - {0xF1F8, 0x8108, "SBCD.B -(A),-(A)"}, - {0xF1F0, 0x8140, "???"}, - {0xF1F0, 0x8180, "???"}, - {0xF1C0, 0x8000, "OR.B ,D"}, - {0xF1C0, 0x8040, "OR.W ,D"}, - {0xF1C0, 0x8080, "OR.L ,D"}, - {0xF1C0, 0x80C0, "DIVU ,D"}, - {0xF1C0, 0x8100, "OR.B D,"}, - {0xF1C0, 0x8140, "OR.W D,"}, - {0xF1C0, 0x8180, "OR.L D,"}, - {0xF1C0, 0x81C0, "DIVS ,D"}, - - {0xF1F8, 0x9100, "SUBX.B D,D"}, - {0xF1F8, 0x9108, "SUBX.B -(A),-(A)"}, - {0xF1F8, 0x9140, "SUBX.W D,D"}, - {0xF1F8, 0x9148, "SUBX.W -(A),-(A)"}, - {0xF1F8, 0x9180, "SUBX.L D,D"}, - {0xF1F8, 0x9188, "SUBX.L -(A),-(A)"}, - {0xF1C0, 0x9000, "SUB.B ,D"}, - {0xF1C0, 0x9040, "SUB.W ,D"}, - {0xF1C0, 0x9080, "SUB.L ,D"}, - {0xF1C0, 0x90C0, "SUBA.W ,A"}, - {0xF1C0, 0x9100, "SUB.B D,"}, - {0xF1C0, 0x9140, "SUB.W D,"}, - {0xF1C0, 0x9180, "SUB.L D,"}, - {0xF1C0, 0x91C0, "SUBA.L ,A"}, - - {0xF1F8, 0xB108, "CMPM.B -(A),-(A)"}, - {0xF1F8, 0xB148, "CMPM.W -(A),-(A)"}, - {0xF1F8, 0xB188, "CMPM.L -(A),-(A)"}, - {0xF1C0, 0xB000, "CMP.B ,D"}, - {0xF1C0, 0xB040, "CMP.W ,D"}, - {0xF1C0, 0xB080, "CMP.L ,D"}, - {0xF1C0, 0xB0C0, "CMPA.W ,A"}, - {0xF1C0, 0xB100, "CMP.B D,"}, - {0xF1C0, 0xB140, "CMP.W D,"}, - {0xF1C0, 0xB180, "CMP.L D,"}, - {0xF1C0, 0xB1C0, "CMPA.L ,A"}, - - {0xF1F8, 0xC100, "ABCD.B D,D"}, - {0xF1F8, 0xC108, "ABCD.B -(A),-(A)"}, - {0xF1F8, 0xC140, "EXG.L D,D"}, - {0xF1F8, 0xC148, "EXG.L A,A"}, - {0xF1F8, 0xC180, "???"}, - {0xF1F8, 0xC188, "EXG.L A,D"}, - {0xF1C0, 0xC000, "AND.B ,D"}, - {0xF1C0, 0xC040, "AND.W ,D"}, - {0xF1C0, 0xC080, "AND.L ,D"}, - {0xF1C0, 0xC0C0, "MULU ,D"}, - {0xF1C0, 0xC100, "AND.B D,"}, - {0xF1C0, 0xC140, "AND.W D,"}, - {0xF1C0, 0xC180, "AND.L D,"}, - {0xF1C0, 0xC1C0, "MULS ,D"}, - - {0xF1F8, 0xD100, "ADDX.B D,D"}, - {0xF1F8, 0xD108, "ADDX.B -(A),-(A)"}, - {0xF1F8, 0xD140, "ADDX.W D,D"}, - {0xF1F8, 0xD148, "ADDX.W -(A),-(A)"}, - {0xF1F8, 0xD180, "ADDX.L D,D"}, - {0xF1F8, 0xD188, "ADDX.L -(A),-(A)"}, - {0xF1C0, 0xD000, "ADD.B ,D"}, - {0xF1C0, 0xD040, "ADD.W ,D"}, - {0xF1C0, 0xD080, "ADD.L ,D"}, - {0xF1C0, 0xD0C0, "ADDA.W ,A"}, - {0xF1C0, 0xD100, "ADD.B D,"}, - {0xF1C0, 0xD140, "ADD.W D,"}, - {0xF1C0, 0xD180, "ADD.L D,"}, - {0xF1C0, 0xD1C0, "ADDA.L ,A"}, - - /* Shift/rotate instructions */ - - {0xF1F8, 0xE000, "ASR.B #,D"}, - {0xF1F8, 0xE008, "LSR.B #,D"}, - {0xF1F8, 0xE010, "ROXR.B #,D"}, - {0xF1F8, 0xE018, "ROR.B #,D"}, - {0xF1F8, 0xE020, "ASR.B D,D"}, - {0xF1F8, 0xE028, "LSR.B D,D"}, - {0xF1F8, 0xE030, "ROXR.B D,D"}, - {0xF1F8, 0xE038, "ROR.B D,D"}, - - {0xF1F8, 0xE040, "ASR.W #,D"}, - {0xF1F8, 0xE048, "LSR.W #,D"}, - {0xF1F8, 0xE050, "ROXR.W #,D"}, - {0xF1F8, 0xE058, "ROR.W #,D"}, - {0xF1F8, 0xE060, "ASR.W D,D"}, - {0xF1F8, 0xE068, "LSR.W D,D"}, - {0xF1F8, 0xE070, "ROXR.W D,D"}, - {0xF1F8, 0xE078, "ROR.W D,D"}, - - {0xF1F8, 0xE080, "ASR.L #,D"}, - {0xF1F8, 0xE088, "LSR.L #,D"}, - {0xF1F8, 0xE090, "ROXR.L #,D"}, - {0xF1F8, 0xE098, "ROR.L #,D"}, - {0xF1F8, 0xE0A0, "ASR.L D,D"}, - {0xF1F8, 0xE0A8, "LSR.L D,D"}, - {0xF1F8, 0xE0B0, "ROXR.L D,D"}, - {0xF1F8, 0xE0B8, "ROR.L D,D"}, - - {0xF1F8, 0xE100, "ASL.B #,D"}, - {0xF1F8, 0xE108, "LSL.B #,D"}, - {0xF1F8, 0xE110, "ROXL.B #,D"}, - {0xF1F8, 0xE118, "ROL.B #,D"}, - {0xF1F8, 0xE120, "ASL.B D,D"}, - {0xF1F8, 0xE128, "LSL.B D,D"}, - {0xF1F8, 0xE130, "ROXL.B D,D"}, - {0xF1F8, 0xE138, "ROL.B D,D"}, - - {0xF1F8, 0xE140, "ASL.W #,D"}, - {0xF1F8, 0xE148, "LSL.W #,D"}, - {0xF1F8, 0xE150, "ROXL.W #,D"}, - {0xF1F8, 0xE158, "ROL.W #,D"}, - {0xF1F8, 0xE160, "ASL.W D,D"}, - {0xF1F8, 0xE168, "LSL.W D,D"}, - {0xF1F8, 0xE170, "ROXL.W D,D"}, - {0xF1F8, 0xE178, "ROL.W D,D"}, - - {0xF1F8, 0xE180, "ASL.L #,D"}, - {0xF1F8, 0xE188, "LSL.L #,D"}, - {0xF1F8, 0xE190, "ROXL.L #,D"}, - {0xF1F8, 0xE198, "ROL.L #,D"}, - {0xF1F8, 0xE1A0, "ASL.L D,D"}, - {0xF1F8, 0xE1A8, "LSL.L D,D"}, - {0xF1F8, 0xE1B0, "ROXL.L D,D"}, - {0xF1F8, 0xE1B8, "ROL.L D,D"}, - - {0xFFC0, 0xE0C0, "ASR.W "}, - {0xFFC0, 0xE1C0, "ASL.W "}, - {0xFFC0, 0xE2C0, "LSR.W "}, - {0xFFC0, 0xE3C0, "LSL.W "}, - {0xFFC0, 0xE4C0, "ROXR.W "}, - {0xFFC0, 0xE5C0, "ROXL.W "}, - {0xFFC0, 0xE6C0, "ROR.W "}, - {0xFFC0, 0xE7C0, "ROL.W "}, -}; - -/*************************************************************************/ - -/** - * q68_disassemble: Disassembles the instruction at the given address. - * Returns "???" if the address or opcode is invalid. - * - * [Parameters] - * state: Processor state block - * address: Address of instruction to disassemble - * nwords_ret: Pointer to variable to receive length in words of the - * instruction (NULL permitted) - * [Return value] - * String containined disassembled instruction - * [Notes] - * The returned string is only valid until the next call to this function. - */ -const char *q68_disassemble(Q68State *state, uint32_t address, - int *nwords_ret) -{ - const uint32_t base_address = address; - static char outbuf[1000]; - - if (address % 2 != 0) { // Odd addresses are invalid - if (nwords_ret) { - *nwords_ret = 1; - } - return "???"; - } - - uint16_t opcode = READU16(state, address); - address += 2; - const char *format = NULL; - int i; - for (i = 0; i < lenof(instructions); i++) { - if ((opcode & instructions[i].mask) == instructions[i].test) { - format = instructions[i].format; - break; - } - } - if (!format) { - if (nwords_ret) { - *nwords_ret = 1; - } - return "???"; - } - - int outlen = 0; -#define APPEND_CHAR(ch) do { \ - if (outlen < sizeof(outbuf)-1) { \ - outbuf[outlen++] = (ch); \ - outbuf[outlen] = 0; \ - } \ -} while (0) -#define APPEND(fmt,...) do { \ - outlen += snprintf(&outbuf[outlen], sizeof(outbuf)-outlen, \ - fmt , ## __VA_ARGS__); \ - if (outlen > sizeof(outbuf)-1) { \ - outlen = sizeof(outbuf)-1; \ - } \ -} while (0) - - int inpos = 0; - while (format[inpos] != 0) { - if (format[inpos] == '<') { - char tagbuf[100]; - int end = inpos+1; - for (; format[end] != 0 && format[end] != '>'; end++) { - if (end - (inpos+1) >= sizeof(tagbuf)) { - break; - } - } - memcpy(tagbuf, &format[inpos+1], end - (inpos+1)); - tagbuf[end - (inpos+1)] = 0; - if (format[end] != 0) { - end++; - } - inpos = end; - if (strncmp(tagbuf,"ea",2) == 0) { - int mode, reg; - char size; // 'b', 'w', or 'l' - if (strncmp(tagbuf,"ea2",3) == 0) { // 2nd EA of MOVE insns - mode = opcode>>6 & 7; - reg = opcode>>9 & 7; - size = tagbuf[4]; - } else { - mode = opcode>>3 & 7; - reg = opcode>>0 & 7; - size = tagbuf[3]; - } - switch (mode) { - case 0: - APPEND("D%d", reg); - break; - case 1: - APPEND("A%d", reg); - break; - case 2: - APPEND("(A%d)", reg); - break; - case 3: - APPEND("(A%d)+", reg); - break; - case 4: - APPEND("-(A%d)", reg); - break; - case 5: { - int16_t disp = READS16(state, address); - address += 2; - APPEND("%d(A%d)", disp, reg); - break; - } - case 6: { - uint16_t ext = READU16(state, address); - address += 2; - const int iregtype = ext>>15; - const int ireg = ext>>12 & 7; - const int iregsize = ext>>11; - const int8_t disp = ext & 0xFF; - APPEND("%d(A%d,%c%d.%c)", disp, reg, - iregtype ? 'A' : 'D', ireg, iregsize ? 'l' : 'w'); - break; - } - case 7: - switch (reg) { - case 0: { - const uint16_t abs = READU16(state, address); - address += 2; - APPEND("($%X).w", abs); - break; - } - case 1: { - const uint32_t abs = READU32(state, address); - address += 4; - APPEND("($%X).l", abs); - break; - } - case 2: { - int16_t disp = READS16(state, address); - address += 2; - APPEND("$%X(PC)", (base_address+2) + disp); - break; - } - case 3: { - uint16_t ext = READU16(state, address); - address += 2; - const int iregtype = ext>>15; - const int ireg = ext>>12 & 7; - const int iregsize = ext>>11; - const int8_t disp = ext & 0xFF; - APPEND("$%X(PC,%c%d.%c)", (base_address+2) + disp, - iregtype ? 'A' : 'D', ireg, iregsize ? 'l' : 'w'); - break; - } - case 4: { - uint32_t imm; - if (size == 'l') { - imm = READU32(state, address); - address += 4; - } else { - imm = READU16(state, address); - address += 2; - } - APPEND("#%s%X", imm<10 ? "" : "$", imm); - break; - } - default: - APPEND("???"); - break; - } - } - } else if (strcmp(tagbuf,"reg") == 0) { - APPEND("%d", opcode>>9 & 7); - } else if (strcmp(tagbuf,"reg0") == 0) { - APPEND("%d", opcode>>0 & 7); - } else if (strcmp(tagbuf,"count") == 0) { - APPEND("%d", opcode>>9 & 7 ?: 8); - } else if (strcmp(tagbuf,"trap") == 0) { - APPEND("%d", opcode>>0 & 15); - } else if (strcmp(tagbuf,"quick8") == 0) { - APPEND("%d", (int8_t)(opcode & 0xFF)); - } else if (strncmp(tagbuf,"imm8",4) == 0) { - uint8_t imm8 = READU16(state, address); // Upper 8 bits ignored - imm8 &= 0xFF; - address += 2; - if (tagbuf[4] == 'd') { - APPEND("%d", imm8); - } else if (tagbuf[4] == 'x') { - APPEND("$%02X", imm8); - } else { - APPEND("%s%X", imm8<10 ? "" : "$", imm8); - } - } else if (strncmp(tagbuf,"imm16",5) == 0) { - uint16_t imm16 = READU16(state, address); - address += 2; - if (tagbuf[5] == 'd') { - APPEND("%d", imm16); - } else if (tagbuf[5] == 'x') { - APPEND("$%04X", imm16); - } else { - APPEND("%s%X", imm16<10 ? "" : "$", imm16); - } - } else if (strcmp(tagbuf,"pcrel8") == 0) { - int8_t disp8 = opcode & 0xFF; - APPEND("$%X", (base_address+2) + disp8); - } else if (strcmp(tagbuf,"pcrel16") == 0) { - int16_t disp16 = READS16(state, address); - address += 2; - APPEND("$%X", (base_address+2) + disp16); - } else if (strcmp(tagbuf,"reglist") == 0 - || strcmp(tagbuf,"tsilger") == 0) { - uint16_t reglist = READU16(state, address); - address += 2; - if (strcmp(tagbuf,"tsilger") == 0) { // "reglist" backwards - /* Predecrement-mode register list, so flip it around */ - uint16_t temp = reglist; - reglist = 0; - while (temp) { - reglist <<= 1; - if (temp & 1) { - reglist |= 1; - } - temp >>= 1; - } - } - char listbuf[3*16]; // Buffer for generating register list - unsigned int listlen = 0; // strlen(listbuf) - unsigned int last = 0; // State of the previous bit - unsigned int regnum = 0; // Current register number (0-15) - while (reglist) { - if (reglist & 1) { - if (last) { - if (listlen >= 3 && listbuf[listlen-3] == '-') { - listlen -= 2; - } else { - listbuf[listlen++] = '-'; - } - } else { - if (listlen > 0) { - listbuf[listlen++] = '/'; - } - } - listbuf[listlen++] = regnum<8 ? 'D' : 'A'; - listbuf[listlen++] = '0' + (regnum % 8); - } - last = reglist & 1; - regnum++; - reglist >>= 1; - } - listbuf[listlen] = 0; - APPEND("%s", listbuf); - } else { - APPEND("<%s>", tagbuf); - } - } else { - APPEND_CHAR(format[inpos]); - inpos++; - } - } - - if (nwords_ret) { - *nwords_ret = (address - base_address) / 2; - } - return outbuf; -} - -/*************************************************************************/ -/*********************** Execution tracing support ***********************/ -/*************************************************************************/ - -/* Processor state block to use in tracing */ -static Q68State *state; - -/* File pointer for trace output */ -static FILE *logfile; - -/* Cycle accumulator */ -static uint64_t total_cycles; - -/* Range of cycles to trace */ -static const uint64_t trace_start = 000000000ULL; // First cycle to trace -static const uint64_t trace_stop = 600000000ULL; // Last cycle to trace + 1 - -/*-----------------------------------------------------------------------*/ - -/** - * q68_trace_init: Initialize the tracing code. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_trace_init(Q68State *state_) -{ - state = state_; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_trace_add_cycles: Add the given number of cycles to the global - * accumulator. - * - * [Parameters] - * cycles: Number of cycles to add - * [Return value] - * None - */ -extern void q68_trace_add_cycles(int32_t cycles) -{ - total_cycles += cycles; -} - -/*-----------------------------------------------------------------------*/ - -#ifdef PSP -/** - * HEXIT: Helper routine for q68_trace() to print a value in hexadecimal. - * See q68_trace() for why we don't just use printf(). - */ -static inline void HEXIT(char * const ptr, uint32_t val, int ndigits) -{ - while (ndigits-- > 0) { - const int digit = val & 0xF; - val >>= 4; - ptr[ndigits] = (digit>9 ? digit+7+'0' : digit+'0'); - } -} -#endif - -/*----------------------------------*/ - -/** - * q68_trace: Output a trace for the instruction at the current PC. - * - * [Parameters] - * None - * [Return value] - * None - */ -void q68_trace(void) -{ - const uint64_t cycles = total_cycles + state->cycles; - - if (cycles < trace_start) { - - /* Before first instruction: do nothing */ - - } else if (cycles >= trace_stop) { - - /* After last instruction: close log file if it's open */ - if (logfile) { -#ifdef __linux__ - pclose(logfile); -#else - fclose(logfile); -#endif - logfile = NULL; - } - - } else { - - if (!logfile) { -#ifdef __linux__ - logfile = popen("gzip -3 >q68.log.gz", "w"); -#else - logfile = fopen("q68.log", "w"); -#endif - if (UNLIKELY(!logfile)) { - perror("Failed to open trace logfile"); - return; - } - setvbuf(logfile, NULL, _IOFBF, 65536); - } - - int nwords = 1, i; - const char *disassembled = q68_disassemble(state, state->PC, &nwords); - -#ifdef PSP // because the cleaner fprintf() version is just too slow - int dislen = strlen(disassembled); - static char buf1[] = - "......: .... .... .... .......................... SR=.... ..... [..........]\n"; - static char buf2[] = - " D: ........ ........ ........ ........ ........ ........ ........ ........\n" - " A: ........ ........ ........ ........ ........ ........ ........ ........\n"; - - if (nwords > 3) { // We can only fit 3 words on the line - nwords = 3; - } - HEXIT(&buf1[0], state->PC, 6); - for (i = 0; i < nwords; i++) { - HEXIT(&buf1[8+5*i], READU16(state, state->PC+2*i), 4); - } - if (i < 3) { - memset(&buf1[8+5*i], ' ', 4+5*(2-i)); - } - if (dislen > 26) { // Pathologically long text needs special handling - fprintf(logfile, "%.22s %-26s SR=%04X %c%c%c%c%c [%10lld]\n", - buf1, disassembled, (int)state->SR, - state->SR & SR_X ? 'X' : '.', state->SR & SR_N ? 'N' : '.', - state->SR & SR_Z ? 'Z' : '.', state->SR & SR_V ? 'V' : '.', - state->SR & SR_C ? 'C' : '.', (unsigned long long)cycles); - } else { - memcpy(&buf1[24], disassembled, dislen); - if (dislen < 26) { - memset(&buf1[24+dislen], ' ', 26-dislen); - } - HEXIT(&buf1[55], state->SR, 4); - buf1[60] = state->SR & SR_X ? 'X' : '.'; - buf1[61] = state->SR & SR_N ? 'N' : '.'; - buf1[62] = state->SR & SR_Z ? 'Z' : '.'; - buf1[63] = state->SR & SR_V ? 'V' : '.'; - buf1[64] = state->SR & SR_C ? 'C' : '.'; - snprintf(&buf1[68], sizeof(buf1)-68, "%10lld]\n", - (unsigned long long)cycles); - fwrite(buf1, 1, strlen(buf1), logfile); - } - for (i = 0; i < 8; i++) { - HEXIT(&buf2[ 7+9*i], state->D[i], 8); - HEXIT(&buf2[86+9*i], state->A[i], 8); - } - fwrite(buf2, 1, sizeof(buf2)-1, logfile); -#else // !PSP - char hexbuf[100]; - int hexlen = 0; - - if (nwords > 3) { // We can only fit 3 words on the line - nwords = 3; - } - for (i = 0; i < nwords && hexlen < sizeof(hexbuf)-5; i++) { - hexlen += snprintf(hexbuf+hexlen, sizeof(hexbuf)-hexlen, - "%s%04X", hexlen==0 ? "" : " ", - (int)READU16(state, state->PC+2*i)); - } - - fprintf(logfile, "%06X: %-14s %-26s SR=%04X %c%c%c%c%c [%10llu]\n" - " D: %08X %08X %08X %08X %08X %08X %08X %08X\n" - " A: %08X %08X %08X %08X %08X %08X %08X %08X\n", - (int)state->PC, hexbuf, disassembled, (int)state->SR, - state->SR & SR_X ? 'X' : '.', state->SR & SR_N ? 'N' : '.', - state->SR & SR_Z ? 'Z' : '.', state->SR & SR_V ? 'V' : '.', - state->SR & SR_C ? 'C' : '.', (unsigned long long)cycles, - (int)state->D[0], (int)state->D[1], (int)state->D[2], - (int)state->D[3], (int)state->D[4], (int)state->D[5], - (int)state->D[6], (int)state->D[7], - (int)state->A[0], (int)state->A[1], (int)state->A[2], - (int)state->A[3], (int)state->A[4], (int)state->A[5], - (int)state->A[6], (int)state->A[7] - ); -#endif // PSP - - } // current_cycles >= trace_start && current_cycles < trace_stop -} - -/*************************************************************************/ -/*************************************************************************/ - - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-internal.h b/yabause/src/q68/q68-internal.h deleted file mode 100644 index 48db390df7..0000000000 --- a/yabause/src/q68/q68-internal.h +++ /dev/null @@ -1,644 +0,0 @@ -/* src/q68/q68-internal.h: Internal declarations/definitions used by Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_INTERNAL_H -#define Q68_INTERNAL_H - -#ifndef Q68_CONST_H -# include "q68-const.h" -#endif - -/*************************************************************************/ -/******************** Defines controlling compilation ********************/ -/*************************************************************************/ - -/** - * Q68_USE_JIT: When defined, enables the use of dynamic translation. - * Defining this on a CPU without dynamic translation support will result - * in a compilation error. - * - * See q68-jit.h for additional settings specific to dynamic translation. - */ -// #define Q68_USE_JIT - -/** - * Q68_JIT_OPTIMIZE_FLAGS: When defined, allows the dynamic translator to - * skip setting the condition flags (XNZVC) after an instruction when it - * can prove that doing so will have no effect on program execution (e.g. - * because the following instruction overwrites the flags). This will - * cause an instruction-by-instruction execution trace to differ from an - * actual 68000, though the program behavior will remain unchanged - * (barring any bugs in the optimization). - */ -#define Q68_JIT_OPTIMIZE_FLAGS - -/** - * Q68_JIT_LOOSE_TIMING: When defined, allows the dynamic translator to - * take some leeway in checking execution timing, such that instructions - * may continue to be executed even after the cycle limit has been reached. - * This allows the translated code to execute more quickly, but will - * slightly alter the timing of responses to external events such as - * interrupts. - */ -#define Q68_JIT_LOOSE_TIMING - -/** - * Q68_OPTIMIZE_IDLE: When defined, optimizes certain idle loops to - * improve performance in JIT mode. Enabling this option slightly alters - * execution timing. - */ -#define Q68_OPTIMIZE_IDLE - -/** - * Q68_JIT_VERBOSE: When defined, outputs some status messages considered - * useful in debugging or optimizing the JIT core. - */ -// #define Q68_JIT_VERBOSE - -/** - * Q68_DISABLE_ADDRESS_ERROR: When defined, disables the generation of - * address error exceptions for unaligned word/longword accesses. The - * behavior for such an access will depend on how the host system handles - * unaligned accesses, and may include the host program itself crashing. - */ -// #define Q68_DISABLE_ADDRESS_ERROR - -/** - * Q68_TRACE: When defined, the execution of every instruction will be - * traced to the file "q68.log" in the current directory. (On Linux, the - * trace will be written in compressed form to "q68.log.gz".) - */ -// #define Q68_TRACE - -/*************************************************************************/ -/************************* Generic helper macros *************************/ -/*************************************************************************/ - -/* Offset of a byte and word within a native long */ -#ifdef WORDS_BIGENDIAN -# define BYTE_OFS 3 -# define WORD_OFS 1 -#else -# define BYTE_OFS 0 -# define WORD_OFS 0 -#endif - -/* Return the length of an array */ -#define lenof(a) (sizeof((a)) / sizeof(*(a))) - -/* Compiler attribute to mark functions as not to be inlined */ -#ifdef __GNUC__ -# define NOINLINE __attribute__((noinline)) -#else -# define NOINLINE /*nothing*/ -#endif - -/* Macro to tell the compiler that a certain condition is likely or - * unlikely to occur */ -#ifdef __GNUC__ -# define LIKELY(x) (__builtin_expect(!!(x), 1)) -# define UNLIKELY(x) (__builtin_expect(!!(x), 0)) -#else -# define LIKELY(x) (x) -# define UNLIKELY(x) (x) -#endif - -/* Debug/error message macro. DMSG("message",...) prints to stderr a line - * in the form: - * func_name(file:line): message - * printf()-style format tokens and arguments are allowed, and no newline - * is required at the end. The format string must be a literal string - * constant. */ -#define DMSG(msg,...) \ - fprintf(stderr, "%s(%s:%d): " msg "\n", __FUNCTION__, __FILE__, __LINE__ \ - , ## __VA_ARGS__) - -/*************************************************************************/ -/******************* Processor state block definition ********************/ -/*************************************************************************/ - -typedef struct Q68JitEntry_ Q68JitEntry; // For JIT code -typedef struct Q68JitBlacklist_ Q68JitBlacklist; // For JIT code - -struct Q68State_ { - - /**** Data directly reflecting the current CPU state ****/ - - /* Registers */ - union { - struct { - uint32_t D[8]; - uint32_t A[8]; - }; - uint32_t DA[16]; // For fast accessing (A0 = D8, A1 = D9, etc.) - }; - uint32_t PC; - uint32_t SR; - uint32_t USP, SSP; - - /* "Current PC" for this instruction (address of opcode + 2) */ - uint32_t current_PC; - - /* Effective address used by the current instruction */ - uint32_t ea_addr; - - /* Pending exception, to be taken after the current instruction has - * been processed (zero if none) */ - unsigned int exception; - /* Auxiliary exception data used for a bus error or address error */ - uint32_t fault_addr; - uint16_t fault_opcode; - uint16_t fault_status; - - /* Nonzero if virtual processor is halted (due to either a STOP - * instruction or a double fault); see Q68_HALTED_* */ - unsigned int halted; - - /* Current interrupt request level */ - unsigned int irq; - - /* Number of clock cycles executed so far */ - uint32_t cycles; - - /**** Environment settings ****/ - - /* Native memory allocation functions */ - void *(*malloc_func)(size_t size); - void *(*realloc_func)(void *ptr, size_t size); - void (*free_func)(void *ptr); - - /* 68k memory read/write functions */ - Q68ReadFunc *readb_func, *readw_func; - Q68WriteFunc *writeb_func, *writew_func; - - /* Native cache flushing function (for JIT) */ - void (*jit_flush)(void); - - /**** JIT-related data ****/ - - /* Currently executing JIT block (NULL = none) */ - Q68JitEntry *jit_running; - - /* Nonzero if JIT routine needs to abort because the underlying 68000 - * code was modified (e.g. by a self-modifying routine) */ - unsigned int jit_abort; - - /* Hash table of translated code segments, hashed by 68000 start address */ - Q68JitEntry *jit_table; // Record buffer - Q68JitEntry **jit_hashchain; // Hash collision chains - - /* Total size of translated data */ - int32_t jit_total_data; // Signed to protect against its going negative - - /* Internal timestamp used by JIT LRU logic */ - uint32_t jit_timestamp; - - /* List of self-modifying blocks not to be translated (zero in both - * address fields indicates a free entry) */ - struct { - uint32_t m68k_start; // Code start address in 68000 address space - uint32_t m68k_end; // Code end address in 68000 address space - uint32_t timestamp; // Time this entry was added - } jit_blacklist[Q68_JIT_BLACKLIST_SIZE]; - - /* Nonzero if the current PC is inside a blacklisted block */ - unsigned int jit_in_blist; - - /* When jit_in_blacklist != 0, indicates the relevant jit_blacklist[] - * array entry index */ - unsigned int jit_blist_num; - - /* Call stack for efficient handling of subroutine calls */ - unsigned int jit_callstack_top; // Index of next entry to write - struct { - uint32_t return_PC; // PC on return from subroutine (0 = free) - Q68JitEntry *return_entry; // JIT block containing native code - void *return_native; // Native address to jump to - } jit_callstack[Q68_JIT_CALLSTACK_SIZE]; - - /* Buffer for tracking translated code blocks */ - uint8_t jit_pages[1<<(24-(Q68_JIT_PAGE_BITS+3))]; - -}; - -/*-----------------------------------------------------------------------*/ - -/* Constants used in the Q68State.halted field */ - -enum { - Q68_HALTED_NONE = 0, // Processor is running normally - Q68_HALTED_STOP, // Processor halted because of a STOP instruction - Q68_HALTED_DOUBLE_FAULT, // Processor halted because of a double fault -}; - -/*-----------------------------------------------------------------------*/ - -/* Macros for accessing Q68State.jit_pages[] (page is assumed to be valid) */ - -#define JIT_PAGE_SET(state,page) \ - ((state)->jit_pages[(page)>>3] |= 1<<((page)&7)) -#define JIT_PAGE_CLEAR(state,page) \ - ((state)->jit_pages[(page)>>3] &= ~(1<<((page)&7))) -#define JIT_PAGE_TEST(state,page) \ - ((state)->jit_pages[(page)>>3] & 1<<((page)&7)) - -/*************************************************************************/ -/************************ JIT interface functions ************************/ -/*************************************************************************/ - -/** - * q68_jit_init: Allocate memory for JIT data. Must be called before any - * other JIT function. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero on success, zero on error - */ -extern int q68_jit_init(Q68State *state); - -/** - * q68_jit_reset: Reset the dynamic translation state, clearing out all - * previously stored data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_jit_reset(Q68State *state); - -/** - * q68_jit_cleanup: Destroy all JIT-related data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_jit_cleanup(Q68State *state); - -/** - * q68_jit_translate: Dynamically translate a block of instructions - * starting at the given address. If a translation already exists for the - * given address, it is cleared. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL on error - */ -extern Q68JitEntry *q68_jit_translate(Q68State *state, uint32_t address); - -/** - * q68_jit_find: Find the translated block for a given address, if any. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL if no such - * block exists - */ -extern Q68JitEntry *q68_jit_find(Q68State *state, uint32_t address); - -/** - * q68_jit_run: Run translated 68000 code. - * - * [Parameters] - * state: Processor state block - * cycle_limit: Clock cycle limit on execution (code will stop when - * state->cycles >= cycles) - * address_ptr: Pointer to translated block to execute; will be cleared - * to NULL on return if the end of the block was reached - * [Return value] - * None - */ -extern void q68_jit_run(Q68State *state, uint32_t cycle_limit, - Q68JitEntry **entry_ptr); - -/** - * q68_jit_clear: Clear any translation beginning at the given address. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * None - */ -extern void q68_jit_clear(Q68State *state, uint32_t address); - -/** - * q68_jit_clear_page: Clear any translation which occurs in the JIT page - * containing the given address. Intended for use on writes from external - * sources. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * [Return value] - * None - */ -extern void q68_jit_clear_page(Q68State *state, uint32_t address); - -/** - * q68_jit_clear_write: Clear any translation which includes the given - * address, and (if there is at least one such translation) blacklist the - * address from being translated. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * size: Size of data written - * [Return value] - * None - */ -extern void q68_jit_clear_write(Q68State *state, uint32_t address, uint32_t size); - -/*************************************************************************/ -/************************ Internal-use constants *************************/ -/*************************************************************************/ - -/* Effective address types for ea_type() */ -enum { - EA_xREG, // Data/address register - EA_MEM, // Memory reference - EA_IMM, // Immediate value -}; - -/* Effective address access types for ea_resolve() */ -enum { - ACCESS_READ = 0, - ACCESS_WRITE, - ACCESS_MODIFY, // For the read access of a read-write operation -}; - -/*************************************************************************/ -/*************** Opcode implementation function prototype ****************/ -/*************************************************************************/ - -/** - * OpcodeFunc: Type of a function implementing one or a group of - * instructions. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * [Return value] - * Clock cycles used - */ -typedef int OpcodeFunc(Q68State *state, uint32_t opcode); - -/*************************************************************************/ -/******************* Memory access functions (inline) ********************/ -/*************************************************************************/ - -/** - * READ[SU]{8,16,32}: Read a value from memory. - * - * [Parameters] - * state: Processor state block - * addr: Address to read or write - * [Return value] - * Value read - */ - -static inline int32_t READS8(Q68State *state, uint32_t addr) { - return (int8_t) state->readb_func(addr & 0xFFFFFF); -} -static inline uint32_t READU8(Q68State *state, uint32_t addr) { - return state->readb_func(addr & 0xFFFFFF); -} - -static inline int32_t READS16(Q68State *state, uint32_t addr) { - return (int16_t) state->readw_func(addr & 0xFFFFFF); -} -static inline uint32_t READU16(Q68State *state, uint32_t addr) { - return state->readw_func(addr & 0xFFFFFF); -} - -static inline int32_t READS32(Q68State *state, uint32_t addr) { - addr &= 0xFFFFFF; - int32_t value = (int32_t) state->readw_func(addr) << 16; - addr += 2; - addr &= 0xFFFFFF; - value |= state->readw_func(addr); - return value; -} -static inline uint32_t READU32(Q68State *state, uint32_t addr) { - addr &= 0xFFFFFF; - uint32_t value = state->readw_func(addr) << 16; - addr += 2; - addr &= 0xFFFFFF; - value |= state->readw_func(addr); - return value; -} - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE{8,16,32}: Write a value to memory. - * - * [Parameters] - * state: Processor state block - * addr: Address to read or write - * data: Value to write - * [Return value] - * None - */ - -static inline void WRITE8(Q68State *state, uint32_t addr, uint8_t data) { - addr &= 0xFFFFFF; -#ifdef Q68_USE_JIT - if (UNLIKELY(JIT_PAGE_TEST(state, addr >> Q68_JIT_PAGE_BITS))) { - q68_jit_clear_write(state, addr, 1); - } -#endif - state->writeb_func(addr, data); -} - -static inline void WRITE16(Q68State *state, uint32_t addr, uint16_t data) { - addr &= 0xFFFFFF; -#ifdef Q68_USE_JIT - if (UNLIKELY(JIT_PAGE_TEST(state, addr >> Q68_JIT_PAGE_BITS))) { - q68_jit_clear_write(state, addr, 2); - } -#endif - state->writew_func(addr, data); -} - -static inline void WRITE32(Q68State *state, uint32_t addr, uint32_t data) { - WRITE16(state, addr, data>>16); - WRITE16(state, addr+2, data); -} - -/*-----------------------------------------------------------------------*/ - -/** - * IFETCH: Retrieve and return the 16-bit word at the PC, incrementing the - * PC by 2. - * - * [Parameters] - * state: Processor state block - * [Return value] - * 16-bit value read - */ - -static inline uint32_t IFETCH(Q68State *state) { - uint32_t data = READU16(state, state->PC); - state->PC += 2; - return data; -} - -/*-----------------------------------------------------------------------*/ - -/** - * PUSH{16,32}, POP{16,32}: Push values onto or pop them off the stack. - * - * [Parameters] - * state: Processor state block - * data: Value to push (PUSH only) - * [Return value] - * Value popped (unsigned, POP only) - */ - -static inline void PUSH16(Q68State *state, uint16_t data) { - state->A[7] -= 2; - WRITE16(state, state->A[7], data); -} -static inline void PUSH32(Q68State *state, uint32_t data) { - state->A[7] -= 4; - WRITE32(state, state->A[7], data); -} - -static inline uint32_t POP16(Q68State *state) { - const uint32_t data = READU16(state, state->A[7]); - state->A[7] += 2; - return data; -} -static inline uint32_t POP32(Q68State *state) { - const uint32_t data = READU32(state, state->A[7]); - state->A[7] += 4; - return data; -} - -/*************************************************************************/ -/******************* Instruction implementation macros *******************/ -/*************************************************************************/ - -/* INSN_GET_REG: uint32_t reg = opcode[11:9] */ -#define INSN_GET_REG \ - uint32_t reg = (opcode>>9) & 7 - -/* INSN_GET_COUNT: uint32_t count = opcode[11:9] || 8 */ -#define INSN_GET_COUNT \ - uint32_t count = (opcode>>9) & 7 ?: 8 - -/* INSN_GET_COND: uint32_t cond = opcode[11:8] */ -#define INSN_GET_COND \ - uint32_t cond = (opcode>>8) & 15 - -/* INSN_GET_SIZE: uint32_t size = opcode[7:6] */ -#define INSN_GET_SIZE \ - uint32_t size = (opcode>>6) & 3 - -/* INSN_GET_REG0: uint32_t reg0 = opcode[2:0] */ -#define INSN_GET_REG0 \ - uint32_t reg0 = opcode & 7 - -/* INSN_GET_IMM8: const int32_t imm8 = SIGN_EXTEND(opcode[7:0]) */ -#define INSN_GET_IMM8 \ - const int32_t imm8 = (int32_t)(int8_t)opcode - -/* INSN_GET_IMM16: const int32_t imm16 = *++PC; */ -#define INSN_GET_IMM16 \ - const int32_t imm16 = (int16_t)IFETCH(state) - -/* INSN_GET_DISP8: int32_t disp = SIGN_EXTEND(opcode[7:0]) */ -#define INSN_GET_DISP8 \ - int32_t disp = (int32_t)(int8_t)opcode - -/*-----------------------------------------------------------------------*/ - -/* INSN_COND_TRUE: Evaluate whether the given condition code is satisfied. */ -#define INSN_COND_TRUE(cond) __extension__({ \ - const unsigned int __cond = (cond); \ - const unsigned int group = __cond >> 1; \ - const unsigned int onoff = __cond & 1; \ - (group==COND_LS>>1 ? (state->SR & SR_C) >> SR_C_SHIFT \ - | (state->SR & SR_Z) >> SR_Z_SHIFT : \ - group==COND_CS>>1 ? (state->SR & SR_C) >> SR_C_SHIFT : \ - group==COND_EQ>>1 ? (state->SR & SR_Z) >> SR_Z_SHIFT : \ - group==COND_VS>>1 ? (state->SR & SR_V) >> SR_V_SHIFT : \ - group==COND_MI>>1 ? (state->SR & SR_N) >> SR_N_SHIFT : \ - group==COND_LT>>1 ? (state->SR & SR_N) >> SR_N_SHIFT \ - ^ (state->SR & SR_V) >> SR_V_SHIFT : \ - group==COND_LE>>1 ? (state->SR & SR_Z) >> SR_Z_SHIFT \ - | ((state->SR & SR_N) >> SR_N_SHIFT \ - ^ (state->SR & SR_V) >> SR_V_SHIFT) : \ - 0 /* COND_T or COND_F */ \ - ) == onoff; \ -}) - -/*-----------------------------------------------------------------------*/ - -/* INSN_CLEAR_XCC, INSN_CLEAR_CC: Clear all condition codes, or all except - * the X flag. */ -#define INSN_CLEAR_XCC() (state->SR &= ~(SR_X|SR_N|SR_Z|SR_V|SR_C)) -#define INSN_CLEAR_CC() (state->SR &= ~( SR_N|SR_Z|SR_V|SR_C)) - - -/* INSN_SETNZ: Set the N and Z flags according to the given 32-bit result. - * Assumes the flags are currently cleared. */ -#define INSN_SETNZ(result) do { \ - const int32_t __result = (result); \ - if (__result < 0) { \ - state->SR |= SR_N; \ - } else if (__result == 0) { \ - state->SR |= SR_Z; \ - } \ -} while (0) - -/* INSN_SETNZ_SHIFT: Like INSN_SETNZ, but assumes the presence of a "shift" - * variable containing the number of bits of "result" less one. */ -#define INSN_SETNZ_SHIFT(result) do { \ - const int32_t __result = (result); \ - if (__result >> shift) { \ - state->SR |= SR_N; \ - } else if (__result == 0) { \ - state->SR |= SR_Z; \ - } \ -} while (0) - -/*************************************************************************/ -/*************************************************************************/ - -#endif // Q68_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit-psp.S b/yabause/src/q68/q68-jit-psp.S deleted file mode 100644 index b6a7204320..0000000000 --- a/yabause/src/q68/q68-jit-psp.S +++ /dev/null @@ -1,2876 +0,0 @@ -/* src/q68/q68-jit-psp.S: PSP dynamic translation implementation for Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "q68-const.h" - -.set noreorder -.set nomips16 - -#define s8 fp // since binutils doesn't seem to recognize $s8 on its own - -/*************************************************************************/ - -/* - * Register and stack usage is as follows: - * - * $v0 -- result; temporary used by macros; (on return) address to resume - * execution at, or NULL to terminate execution - * $v1 -- temporary - * $a0 -- temporary - * $a1 -- temporary - * $a2 -- temporary - * $a3 -- temporary - * $t0 -- temporary (not used by macros) - * $t1 -- temporary (not used by macros) - * $t2 -- temporary (not used by macros) - * $t3 -- temporary (not used by macros) - * $t4 -- temporary (not used by macros) - * $t5 -- not used - * $t6 -- not used - * $t7 -- operand 2 - * $t8 -- not used - * $t9 -- indirect function call pointer - * $s0 -- Q68State structure pointer - * $s1 -- cycles to execute - * $s2 -- cumulative cycle count - * $s3 -- operand 1; persistent temporary - * $s4 -- PC mirror register - * $s5 -- SR mirror register - * $s6 -- effective address (used instead of state->ea_addr); persistent - * temporary - * $s7 -- value of Q68State.jit_abort - * $s8 -- not used (not saved by JIT_CALL()) - * - * 0($sp) -- temporary (used by READ/WRITE macros to hold addresses) - * 4($sp) -- temporary (used by READ/WRITE macros to hold values) - * 8($sp) -- unused - * 12($sp) -- saved $ra - */ - -/*************************************************************************/ - -/* Label/size/parameter definition macros */ -#define DEFLABEL(name) .globl JIT_PSP_##name; \ - .type JIT_PSP_##name, @function; \ - JIT_PSP_##name: -#define DEFSIZE(name) .globl JIT_PSPSIZE_##name; \ - .type JIT_PSPSIZE_##name, @object; \ - JIT_PSPSIZE_##name: .int . - JIT_PSP_##name -#define DEFPARAM(name,param,label,offset) \ - .globl JIT_PSPPARAM_##name##_##param; \ - .type JIT_PSPPARAM_##name##_##param, @object; \ - JIT_PSPPARAM_##name##_##param: .int label - JIT_PSP_##name + (offset) - -/* Q68State structure offsets */ -Q68State_D = 0 -Q68State_A = 32 -Q68State_PC = 64 -Q68State_SR = 68 -Q68State_USP = 72 -Q68State_SSP = 76 -Q68State_current_PC = 80 -Q68State_ea_addr = 84 -Q68State_exception = 88 -Q68State_fault_addr = 92 -Q68State_fault_opcode = 96 -Q68State_fault_status = 98 -Q68State_halted = 100 -Q68State_irq = 104 -Q68State_cycles = 108 -Q68State_malloc_func = 112 -Q68State_realloc_func = 116 -Q68State_free_func = 120 -Q68State_readb_func = 124 -Q68State_readw_func = 128 -Q68State_writeb_func = 132 -Q68State_writew_func = 136 -Q68State_jit_flush = 140 -Q68State_jit_running = 144 -Q68State_jit_abort = 148 -Q68State_jit_table = 152 -Q68State_jit_hashchain = 156 -Q68State_jit_total_data = 160 -Q68State_jit_timestamp = 164 -Q68State_jit_blacklist = 168 -Q68State_jit_in_blist = Q68State_jit_blacklist + (12 * Q68_JIT_BLACKLIST_SIZE) -Q68State_jit_blist_num = Q68State_jit_in_blist + 4 -Q68State_jit_callstack_top = Q68State_jit_blist_num + 4 -Q68State_jit_callstack = Q68State_jit_callstack_top + 4 -Q68State_jit_pages = Q68State_jit_callstack + (12 * Q68_JIT_CALLSTACK_SIZE) - -/*************************************************************************/ - -/* Shorthand for referencing Q68State fields */ - -#define D0 Q68State_D+0*4($s0) -#define D1 Q68State_D+1*4($s0) -#define D2 Q68State_D+2*4($s0) -#define D3 Q68State_D+3*4($s0) -#define D4 Q68State_D+4*4($s0) -#define D5 Q68State_D+5*4($s0) -#define D6 Q68State_D+6*4($s0) -#define D7 Q68State_D+7*4($s0) - -#define A0 Q68State_A+0*4($s0) -#define A1 Q68State_A+1*4($s0) -#define A2 Q68State_A+2*4($s0) -#define A3 Q68State_A+3*4($s0) -#define A4 Q68State_A+4*4($s0) -#define A5 Q68State_A+5*4($s0) -#define A6 Q68State_A+6*4($s0) -#define A7 Q68State_A+7*4($s0) - -#define PC Q68State_PC($s0) -#define SR Q68State_SR($s0) -#define USP Q68State_USP($s0) -#define SSP Q68State_SSP($s0) - -/*************************************************************************/ - -/* LOAD_DELAY_NOP is used to indicate where a pipeline stall will occur - * due to a dependency on data loaded by a previous instruction. It - * doesn't actually expand to anything, but can be used as a hint for - * optimization. */ - -#define LOAD_DELAY_NOP /*nothing*/ - -/*************************************************************************/ -/************************** Convenience macros ***************************/ -/*************************************************************************/ - -/** - * seqz: seqz rd,rs is a clearer substitute for sltiu rd,rs,1 and sets rd - * to 1 if rs is zero, 0 otherwise. - */ -.macro seqz rd, rs - sltiu \rd, \rs, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * snez: sgtz rd,rs is a clearer substitute for sltu rd,zero,rs and sets - * rd to 1 if rs is positive, 0 otherwise. - */ -.macro snez rd, rs - sltu \rd, $zero, \rs -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * sgtz: sgtz rd,rs is a clearer substitute for slt rd,zero,rs and sets - * rd to 1 if rs is positive, 0 otherwise. - */ -.macro sgtz rd, rs - slt \rd, $zero, \rs -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * sltz: sltz rd,rs is a clearer substitute for slti rd,rs,0 and sets rd - * to 1 if rs is negative, 0 otherwise. - */ -.macro sltz rd, rs - slti \rd, \rs, 0 -.endm - -/*************************************************************************/ - -/** - * SETUP: Perform setup required before executing translated code. - */ -.macro SETUP - addiu $sp, $sp, -16 - lw $s5, Q68State_SR($s0) - lw $s4, Q68State_PC($s0) - sw $ra, 12($sp) - move $s7, $zero -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * TERMINATE: Terminate execution of the current block. The emulator will - * resume execution at the address in state->PC. - */ -.macro TERMINATE - lw $ra, 12($sp) - sw $s4, Q68State_PC($s0) - sw $s5, Q68State_SR($s0) - move $v0, $zero - jr $ra - addiu $sp, $sp, 16 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * TERMINATE_CONTINUE: Terminate execution of the current block, returning - * the address of the following native instruction. - */ -.macro TERMINATE_CONTINUE - sw $s4, Q68State_PC($s0) - jal TERMINATE_CONTINUE_get_pc - sw $s5, Q68State_SR($s0) - jr $ra - addiu $sp, $sp, 16 - SETUP -.endm - -/* Helper subroutine to get the PC */ -TERMINATE_CONTINUE_get_pc: - addiu $v0, $ra, 8 // Size of "jr ra; addiu $sp, $sp, 16" - jr $ra - lw $ra, 12($sp) // Preload the saved $ra to avoid a load stall - -/*************************************************************************/ - -/** - * READ{8,16,32}: Read a value from memory. The address to read from is - * taken from $s6; the value read is returned zero-extended in \return. - */ -.macro READ8 return - lw $t9, Q68State_readb_func($s0) - ext $a0, $s6, 0, 24 // Mask off top 8 bits - LOAD_DELAY_NOP - jalr $t9 - nop - andi \return, $v0, 0xFF -.endm - -.macro READ16 return - lw $t9, Q68State_readw_func($s0) - ext $a0, $s6, 0, 24 - LOAD_DELAY_NOP - jalr $t9 - nop - andi \return, $v0, 0xFFFF -.endm - -.macro READ32 return - lw $t9, Q68State_readw_func($s0) - ext $a0, $s6, 0, 24 - LOAD_DELAY_NOP - jalr $t9 // Read high word - sw $a0, 0($sp) - lw $a0, 0($sp) - sll $v0, $v0, 16 - lw $t9, Q68State_readw_func($s0) - sw $v0, 4($sp) - addiu $a0, $a0, 2 - jalr $t9 // Read low word - ext $a0, $a0, 0, 24 // Just in case we're reading from $FFFFFE - lw $v1, 4($sp) - andi $v0, $v0, 0xFFFF - LOAD_DELAY_NOP - or \return, $v0, $v1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE_CHECK_JIT: Check whether a write of size \nbytes (*bytes*, not - * bits) to the address in $s6 would clobber a page containing already- - * translated blocks, and clear those translations if so. All caller-saved - * registers are destroyed. - * - * Note that this macro uses local label 4. - */ -.macro WRITE_CHECK_JIT nbytes - srl $a0, $s6, Q68_JIT_PAGE_BITS+3 - addu $a0, $a0, $s0 - lbu $v0, Q68State_jit_pages($a0) - ext $a1, $s6, Q68_JIT_PAGE_BITS, 3 - li $v1, 1 - beqz $v0, 4f - sllv $v1, $v1, $a1 - and $v0, $v0, $v1 - beqz $v0, 4f - move $a1, $s6 - li $a2, \nbytes - jal q68_jit_clear_write - move $a0, $s0 - lw $s7, Q68State_jit_abort($s0) -4: -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE{8,16,32}: Write a value to memory. The address must be stored in - * $s6, and the value to write in $v0. Note that a 32-bit write spanning - * two JIT pages that clobbers the first word of a translated routine - * beginning on the second page will not be detected. - */ -.macro WRITE8 - sw $v0, 4($sp) - WRITE_CHECK_JIT 1 - lw $t9, Q68State_writeb_func($s0) - lw $a1, 4($sp) - LOAD_DELAY_NOP - jalr $t9 - ext $a0, $s6, 0, 24 -.endm - -.macro WRITE16 - sw $v0, 4($sp) - WRITE_CHECK_JIT 2 - lw $t9, Q68State_writew_func($s0) - lw $a1, 4($sp) - LOAD_DELAY_NOP - jalr $t9 - ext $a0, $s6, 0, 24 -.endm - -.macro WRITE32 - sw $v0, 4($sp) - WRITE_CHECK_JIT 4 - lw $t9, Q68State_writew_func($s0) - lw $a1, 4($sp) - ext $a0, $s6, 0, 24 - jalr $t9 // Write high word - srl $a1, $a1, 16 - lw $t9, Q68State_writew_func($s0) - lhu $a1, 4($sp) // Keep only the low 16 bits of the value - addiu $a0, $s6, 2 - jalr $t9 // Write low word - ext $a0, $a0, 0, 24 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * {PUSH,POP}{16,32}: Push or pop values onto or off of the stack. For - * POP, the value popped is zero-extended and returned in \return. - * - * For pushes, it is assumed that the push does not clobber any - * JIT-translated code. - */ -.macro PUSH16 value - lw $a0, A7 - lw $t9, Q68State_writew_func($s0) - move $a1, \value - addiu $a0, $a0, -2 - sw $a0, A7 - jalr $t9 - ext $a0, $a0, 0, 24 -.endm - -.macro PUSH32 value - lw $a0, A7 - lw $t9, Q68State_writew_func($s0) - sw \value, 4($sp) - addiu $a0, $a0, -4 - sw $a0, A7 - ext $a0, $a0, 0, 24 - jalr $t9 // Write high word - srl $a1, \value, 16 - lw $a0, A7 - lw $t9, Q68State_writew_func($s0) - lhu $a1, 4($sp) // Keep only the low 16 bits of \value - addiu $a0, $a0, 2 - jalr $t9 // Write low word - ext $a0, $a0, 0, 24 -.endm - -.macro POP16 return - lw $a0, A7 - lw $t9, Q68State_readw_func($s0) - LOAD_DELAY_NOP - addiu $v0, $a0, 2 - sw $v0, A7 - jalr $t9 - ext $a0, $a0, 0, 24 - andi \return, $v0, 0xFFFF -.endm - -.macro POP32 return - lw $a0, A7 - lw $t9, Q68State_readw_func($s0) - LOAD_DELAY_NOP - addiu $v0, $a0, 4 - sw $v0, A7 - jalr $t9 // Read high word - ext $a0, $a0, 0, 24 - lw $a0, A7 - sll $v0, $v0, 16 - lw $t9, Q68State_readw_func($s0) - sw $v0, 4($sp) - addiu $a0, $a0, -2 // Since it was already incremented by 4 - jalr $t9 // Read low word - ext $a0, $a0, 0, 24 - lw $v1, 4($sp) - andi $v0, $v0, 0xFFFF - LOAD_DELAY_NOP - or \return, $v0, $v1 -.endm - -/*************************************************************************/ - -/** - * SETCC_NZ_[BWL]: Set the N and Z condition codes according to \value. - */ -.macro SETCC_NZ_B value - ext $v1, \value, 7, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - andi $v1, \value, 0xFF - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -.endm - -.macro SETCC_NZ_W value - ext $v1, \value, 15, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - andi $v1, \value, 0xFFFF - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -.endm - -.macro SETCC_NZ_L value - ext $v1, \value, 31, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - seqz $v1, \value - ins $s5, $v1, SR_Z_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZ00_[BWL]: Set the N and Z condition codes according to \value, - * and clear the V and C condition codes. - */ -.macro SETCC_NZ00_B value - SETCC_NZ_B \value - ins $s5, $zero, 0, 2 -.endm - -.macro SETCC_NZ00_W value - SETCC_NZ_W \value - ins $s5, $zero, 0, 2 -.endm - -.macro SETCC_NZ00_L value - SETCC_NZ_L \value - ins $s5, $zero, 0, 2 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC_ADD: Set the condition codes for an ADD operation based on - * the values in the op1, op2, and result registers. - */ -.macro SETCC_XNZVC_ADD nbits - .if \nbits == 8 - SETCC_NZ_B $v0 - .else - .if \nbits == 16 - SETCC_NZ_W $v0 - .else - SETCC_NZ_L $v0 - .endif - .endif - xor $a0, $s3, $v0 - xor $a1, $t7, $v0 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - addu $a0, $a0, $a1 - subu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC_ADDX: Set the condition codes for an ADDX operation based - * on the values in the op1, op2, and result registers. - */ -.macro SETCC_XNZVC_ADDX nbits - // Z is only cleared (never set) by ADDX etc., so we can't use SETNZ - ext $v1, $v0, \nbits-1, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - .if \nbits < 32 - ext $v1, $v0, 0, \nbits - snez $v1, $v1 - .else - snez $v1, $v0 - .endif - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 - xor $a0, $s3, $v0 - xor $a1, $t7, $v0 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - addu $a0, $a0, $a1 - subu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZVC_SUB, SETCC_XNZVC_SUB: Set the condition codes for a SUB - * operation (excluding or including the X flag) based on the values in the - * op1, op2, and result registers. - */ -.macro SETCC_NZVC_SUB nbits - .if \nbits == 8 - SETCC_NZ_B $v0 - .else - .if \nbits == 16 - SETCC_NZ_W $v0 - .else - SETCC_NZ_L $v0 - .endif - .endif - xor $a0, $s3, $t7 - xor $a1, $v0, $t7 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - subu $a0, $a0, $a1 - addu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 -.endm - -.macro SETCC_XNZVC_SUB nbits - SETCC_NZVC_SUB \nbits - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC_SUBX: Set the condition codes for a SUBX operation based on - * the values in the op1, op2, and result registers. - */ -.macro SETCC_XNZVC_SUBX nbits - ext $v1, $v0, \nbits-1, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - .if \nbits < 32 - ext $v1, $v0, 0, \nbits - snez $v1, $v1 - .else - snez $v1, $v0 - .endif - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 - xor $a0, $s3, $t7 - xor $a1, $v0, $t7 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - subu $a0, $a0, $a1 - addu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*************************************************************************/ -/*************************** Local subroutines ***************************/ -/*************************************************************************/ - -/** - * UPDATE_SR: Set the status register according to the value in $v0. - */ -UPDATE_SR: - lw $a0, Q68State_irq($s0) // Load early for IRQ check below - xor $v1, $s5, $v0 - andi $v1, $v1, SR_S // Change in S bit? - beqz $v1, 1f - andi $s5, $v0, 0xFFFF // Zero-extend value into SR mirror register - andi $v1, $v0, SR_S // Which way did it change? - beqz $v1, 0f - lw $a0, A7 - lw $a1, SSP // Into supervisor mode - LOAD_DELAY_NOP - sw $a0, USP - j 1f - sw $a1, A7 -0: lw $a1, USP // Out of supervisor mode - sw $a0, SSP - LOAD_DELAY_NOP - sw $a1, A7 -1: andi $v1, $a0, 7 - slti $a1, $v1, 7 // Check for a pending NMI - beqz $a1, 2f - ext $v0, $v0, SR_I0_SHIFT, 3 - slt $v0, $v0, $v1 // Check for a pending unmasked interrupt - beqz $v0, 3f -2: addiu $a0, $v1, EX_LEVEL_1_INTERRUPT-1 // In a delay slot, but okay - sw $a0, Q68State_exception($s0) - sw $zero, Q68State_irq($s0) - TERMINATE -3: jr $ra - nop - -/*************************************************************************/ -/**************************** Meta-operations ****************************/ -/*************************************************************************/ - -/** - * PROLOGUE: Any prologue necessary at the beginning of the code stream. - */ -DEFLABEL(PROLOGUE) -_PROLOGUE_TOP: - /* Include various exceptional termination code here, so we can - * conditionally branch to it (meaning we can skip the branch in - * 1-2 cycles) instead of having to inverse-branch around an - * unconditional jump (costing 3-4 cycles). */ - b 0f - nop -_PROLOGUE_TERMINATE: // Generic termination (used for CHECK_ABORT) -1: TERMINATE -_PROLOGUE_EXCEPTION: // Exception raised (exception number in $a0) - b 1b - sw $a0, Q68State_exception($s0) -_PROLOGUE_ADDRESS_ERROR_EA: // EA address error (opcode in $a2, status in $a3) - li $v1, EX_ADDRESS_ERROR - sw $v1, Q68State_exception($s0) - sw $s6, Q68State_fault_addr($s0) - sh $a2, Q68State_fault_opcode($s0) - b 1b - sh $a3, Q68State_fault_status($s0) -_PROLOGUE_ADDRESS_ERROR_SP: // Stack address error (address in $a1, - // opcode in $a2, status in $a3) - li $a0, EX_ADDRESS_ERROR - sw $a0, Q68State_exception($s0) - sw $v1, Q68State_fault_addr($s0) - sh $a2, Q68State_fault_opcode($s0) - b 1b - sh $a3, Q68State_fault_status($s0) -0: // Actual setup starts here - SETUP -DEFSIZE(PROLOGUE) - - -/* Offset definitions used for branching to termination code; "branchofs" - * is the offset in _instructions_ (not bytes) from the beginning of the - * named fragment */ -#define DEFOFS(name,branchofs) \ - .globl JIT_PSPOFS_##name; \ - .type JIT_PSPOFS_##name, @object; \ - JIT_PSPOFS_##name: .int _PROLOGUE_##name - _PROLOGUE_TOP - 4*branchofs -DEFOFS(TERMINATE, 0) -DEFOFS(EXCEPTION, 0) -DEFOFS(ADDRESS_ERROR_EA, 2) -DEFOFS(ADDRESS_ERROR_SP, 4) - -/*-----------------------------------------------------------------------*/ - -/** - * EPILOGUE: Any epilogue necessary at the end of the code stream. - */ -DEFLABEL(EPILOGUE) - TERMINATE -DEFSIZE(EPILOGUE) - -/*************************************************************************/ - -/** - * TRACE: Trace the current instruction. - */ -DEFLABEL(TRACE) - lw $s3, Q68State_cycles($s0) - addu $t0, $s3, $s2 - sw $t0, Q68State_cycles($s0) - sw $s4, Q68State_PC($s0) - jal q68_trace - sw $s5, Q68State_SR($s0) - sw $s3, Q68State_cycles($s0) -DEFSIZE(TRACE) - -/*************************************************************************/ - -/** - * ADD_CYCLES: Add the specified number of clock cycles to the cycle count. - * - * [Parameters] - * cycles: Number of clock cycles to add - */ -DEFLABEL(ADD_CYCLES) - addiu $s2, $s2, 1 -9: -DEFSIZE(ADD_CYCLES) -DEFPARAM(ADD_CYCLES, cycles, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_CYCLES: Check whether the clock cycle limit has been reached, and - * interrupt execution if so. - */ -DEFLABEL(CHECK_CYCLES) - slt $v0, $s2, $s1 - bnez $v0, 2f - sw $s4, Q68State_PC($s0) // Can't have JAL in a delay slot - jal CHECK_CYCLES_get_pc // (got to keep up their reputation) - sw $s5, Q68State_SR($s0) -0: jr $ra - addiu $sp, $sp, 16 -1: SETUP -2: -DEFSIZE(CHECK_CYCLES) - -/* Helper subroutine to get the PC (as with TERMINATE_CONTINUE) */ -CHECK_CYCLES_get_pc: - addiu $v0, $ra, 1b-0b - jr $ra - lw $ra, 12($sp) // Preload the saved $ra to avoid a load stall - -/*************************************************************************/ - -/** - * ADVANCE_PC: Add the specified value to the current program counter. - * - * [Parameters] - * value: Amount to add - */ -DEFLABEL(ADVANCE_PC) - addiu $s4, $s4, 1 -9: -DEFSIZE(ADVANCE_PC) -DEFPARAM(ADVANCE_PC, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * ADVANCE_PC_CHECK_ABORT: Add the specified value to the current program - * counter, then check the jit_abort flag and abort if necessary. - * - * [Parameters] - * value: Amount to add - * disp_4: (JIT_PSPOFS_TERMINATE - native offset of this fragment) / 4 - */ -DEFLABEL(ADVANCE_PC_CHECK_ABORT) - bnez $s7, .+0x1234 -8: addiu $s4, $s4, 1 -9: -DEFSIZE(ADVANCE_PC_CHECK_ABORT) -DEFPARAM(ADVANCE_PC_CHECK_ABORT, value, 9b, -4) -DEFPARAM(ADVANCE_PC_CHECK_ABORT, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ABORT: Check the jit_abort flag and abort if necessary. - * - * [Parameters] - * disp_4: (JIT_PSPOFS_TERMINATE - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_ABORT) - bnez $s7, .+0x1234 -9: nop -DEFSIZE(CHECK_ABORT) -DEFPARAM(CHECK_ABORT, disp_4, 9b, -4) - -/*************************************************************************/ - -/** - * EXCEPTION: Raise the specified exception. - * - * [Parameters] - * num: Exception number - * disp_4: (JIT_PSPOFS_EXCEPTION - native offset of this fragment) / 4 - */ -DEFLABEL(EXCEPTION) - b .+0x1234 -8: addiu $a0, $zero, 1 -9: -DEFSIZE(EXCEPTION) -DEFPARAM(EXCEPTION, num, 9b, -4) -DEFPARAM(EXCEPTION, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_EA: Check whether the previously resolved effective - * address is word-aligned (bit 0 is clear), and raise an address error - * exception if not. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - * disp_4: (JIT_PSPOFS_ADDRESS_ERROR_EA - * - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_ALIGNED_EA) - andi $v1, $s6, 1 - ori $a2, $zero, 0x1234 -7: bnezl $v1, .+0x1234 -8: ori $a3, $zero, 0x1234 -9: -DEFSIZE(CHECK_ALIGNED_EA) -DEFPARAM(CHECK_ALIGNED_EA, opcode, 7b, -4) -DEFPARAM(CHECK_ALIGNED_EA, status, 9b, -4) -DEFPARAM(CHECK_ALIGNED_EA, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_SP: Check whether the current stack pointer (register A7) - * is word-aligned (bit 0 is clear), and raise an address error exception - * if not. Destroys $v1 and $a0-$a3. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - * disp_4: (JIT_PSPOFS_ADDRESS_ERROR_SP - * - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_ALIGNED_SP) - lw $a1, A7 - ori $a2, $zero, 0x1234 -7: LOAD_DELAY_NOP - andi $v1, $a1, 1 - bnez $v1, .+0x1234 -8: ori $a3, $zero, 0x1234 -9: -DEFSIZE(CHECK_ALIGNED_SP) -DEFPARAM(CHECK_ALIGNED_SP, opcode, 7b, -4) -DEFPARAM(CHECK_ALIGNED_SP, status, 9b, -4) -DEFPARAM(CHECK_ALIGNED_SP, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_SUPER: Check whether the processor is in supervisor mode, and - * raise a privilege violation exception if not. - * - * [Parameters] - * disp_4: (JIT_PSPOFS_EXCEPTION - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_SUPER) - andi $v0, $s5, SR_S - beqzl $v0, .+0x1234 -9: li $a0, EX_PRIVILEGE_VIOLATION -DEFSIZE(CHECK_SUPER) -DEFPARAM(CHECK_SUPER, disp_4, 9b, -4) - -/*************************************************************************/ -/********************* Effective address resolution **********************/ -/*************************************************************************/ - -/** - * RESOLVE_INDIRECT: Resolve an address register indirect reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - */ -DEFLABEL(RESOLVE_INDIRECT) - lw $s6, 1($s0) -9: -DEFSIZE(RESOLVE_INDIRECT) -DEFPARAM(RESOLVE_INDIRECT, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_POSTINC: Resolve an address register postincrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * size: Size in bytes of the reference - */ -DEFLABEL(RESOLVE_POSTINC) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $v0, $s6, 1 -8: sw $v0, 1($s0) -9: -DEFSIZE(RESOLVE_POSTINC) -DEFPARAM(RESOLVE_POSTINC, reg4, 7b, -4) -DEFPARAM(RESOLVE_POSTINC, size, 8b, -4) -DEFPARAM(RESOLVE_POSTINC, reg4_b, 9b, -4) // same as reg4 - -/* For byte-sized (A7)+, make sure A7 stays even */ -DEFLABEL(RESOLVE_POSTINC_A7_B) - lw $s6, A7 - LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 - addiu $v0, $s6, 1 - sw $v0, A7 -DEFSIZE(RESOLVE_POSTINC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_PREDEC: Resolve an address register predecrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * nsize: Size in bytes of the reference, negated - */ -DEFLABEL(RESOLVE_PREDEC) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, -1 -8: sw $s6, 1($s0) -9: -DEFSIZE(RESOLVE_PREDEC) -DEFPARAM(RESOLVE_PREDEC, reg4, 7b, -4) -DEFPARAM(RESOLVE_PREDEC, nsize, 8b, -4) -DEFPARAM(RESOLVE_PREDEC, reg4_b, 9b, -4) // same as reg4 - -/* For byte-sized -(A7), make sure A7 stays even */ -DEFLABEL(RESOLVE_PREDEC_A7_B) - lw $s6, 1($s0) - LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, -1 - addiu $v0, $s6, -1 - sw $v0, A7 -DEFSIZE(RESOLVE_PREDEC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_DISP: Resolve an address register indirect with displacement - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * disp: Displacement - */ -DEFLABEL(RESOLVE_DISP) - lw $s6, 1($s0) -8: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 -9: -DEFSIZE(RESOLVE_DISP) -DEFPARAM(RESOLVE_DISP, reg4, 8b, -4) -DEFPARAM(RESOLVE_DISP, disp, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_INDEX_[WL]: Resolve an address register indirect with index - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * ireg4: Index register number * 4 - * disp: Displacement - */ -DEFLABEL(RESOLVE_INDEX_W) - lw $s6, 1($s0) -7: lh $v0, 1($s0) -8: LOAD_DELAY_NOP - addi $s6, $s6, 1 -9: add $s6, $s6, $v0 -DEFSIZE(RESOLVE_INDEX_W) -DEFPARAM(RESOLVE_INDEX_W, reg4, 7b, -4) -DEFPARAM(RESOLVE_INDEX_W, ireg4, 8b, -4) -DEFPARAM(RESOLVE_INDEX_W, disp, 9b, -4) - -DEFLABEL(RESOLVE_INDEX_L) - lw $s6, 1($s0) -7: lw $v0, 1($s0) -8: LOAD_DELAY_NOP - addi $s6, $s6, 1 -9: add $s6, $s6, $v0 -DEFSIZE(RESOLVE_INDEX_L) -DEFPARAM(RESOLVE_INDEX_L, reg4, 7b, -4) -DEFPARAM(RESOLVE_INDEX_L, ireg4, 8b, -4) -DEFPARAM(RESOLVE_INDEX_L, disp, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABSOLUTE: Resolve an absolute short, absolute long, or - * PC-relative reference. - * - * [Parameters] - * addr_hi: Absolute address, high 16 bits - * addr_lo: Absolute address, low 16 bits - */ -DEFLABEL(RESOLVE_ABSOLUTE) - lui $s6, 0x1234 -8: ori $s6, $s6, 0x5678 -9: -DEFSIZE(RESOLVE_ABSOLUTE) -DEFPARAM(RESOLVE_ABSOLUTE, addr_hi, 8b, -4) -DEFPARAM(RESOLVE_ABSOLUTE, addr_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABS_INDEX_[WL]: Resolve a PC-relative with index reference. - * - * [Parameters] - * ireg4: Index register number * 4 - * addr_hi: Absolute address, high 16 bits - * addr_lo: Absolute address, low 16 bits - */ -DEFLABEL(RESOLVE_ABS_INDEX_W) - lh $v0, 1($s0) -7: lui $s6, 0x1234 -8: ori $s6, $s6, 0x5678 -9: addu $s6, $s6, $v0 -DEFSIZE(RESOLVE_ABS_INDEX_W) -DEFPARAM(RESOLVE_ABS_INDEX_W, ireg4, 7b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_W, addr_hi, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_W, addr_lo, 9b, -4) - -DEFLABEL(RESOLVE_ABS_INDEX_L) - lh $v0, 1($s0) -7: lui $s6, 0x1234 -8: ori $s6, $s6, 0x5678 -9: addu $s6, $s6, $v0 -DEFSIZE(RESOLVE_ABS_INDEX_L) -DEFPARAM(RESOLVE_ABS_INDEX_L, ireg4, 7b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_L, addr_hi, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_L, addr_lo, 9b, -4) - -/*************************************************************************/ -/*************************** Operand retrieval ***************************/ -/*************************************************************************/ - -/** - * GET_OP1_REGISTER: Get the current value of the given register as - * operand 1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(GET_OP1_REGISTER) - lw $s3, 1($s0) -9: -DEFSIZE(GET_OP1_REGISTER) -DEFPARAM(GET_OP1_REGISTER, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_EA_[BWL]: Get the value pointed to by the previously resolved - * effective address as operand 1. - */ -DEFLABEL(GET_OP1_EA_B) - READ8 $s3 -DEFSIZE(GET_OP1_EA_B) - -DEFLABEL(GET_OP1_EA_W) - READ16 $s3 -DEFSIZE(GET_OP1_EA_W) - -DEFLABEL(GET_OP1_EA_L) - READ32 $s3 -DEFSIZE(GET_OP1_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_IMMED_{16S,16U,16HI,32}: Get an immediate value as operand 1. - * - * [Parameters] - * value_hi: High 16 bits of immediate value - * value_lo: Low 16 bits of immediate value (signed for 16S, else unsigned) - */ -DEFLABEL(GET_OP1_IMMED_16S) - addiu $s3, $zero, 1 -9: -DEFSIZE(GET_OP1_IMMED_16S) -DEFPARAM(GET_OP1_IMMED_16S, value_lo, 9b, -4) - -DEFLABEL(GET_OP1_IMMED_16U) - ori $s3, $zero, 1 -9: -DEFSIZE(GET_OP1_IMMED_16U) -DEFPARAM(GET_OP1_IMMED_16U, value_lo, 9b, -4) - -DEFLABEL(GET_OP1_IMMED_16HI) - lui $s3, 1 -9: -DEFSIZE(GET_OP1_IMMED_16HI) -DEFPARAM(GET_OP1_IMMED_16HI, value_hi, 9b, -4) - -DEFLABEL(GET_OP1_IMMED_32) - lui $s3, 1 -8: ori $s3, $s3, 1 -9: -DEFSIZE(GET_OP1_IMMED_32) -DEFPARAM(GET_OP1_IMMED_32, value_hi, 8b, -4) -DEFPARAM(GET_OP1_IMMED_32, value_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_CCR: Get the current value of CCR as operand 1. - */ -DEFLABEL(GET_OP1_CCR) - andi $s3, $s5, 0xFF -DEFSIZE(GET_OP1_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_SR: Get the current value of SR as operand 1. - */ -DEFLABEL(GET_OP1_SR) - move $s3, $s5 -DEFSIZE(GET_OP1_SR) - -/*************************************************************************/ - -/** - * GET_OP2_*: Get the same things as above as operand 2. - */ -DEFLABEL(GET_OP2_REGISTER) - lw $t7, 1($s0) -9: -DEFSIZE(GET_OP2_REGISTER) -DEFPARAM(GET_OP2_REGISTER, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_EA_B) - READ8 $t7 -DEFSIZE(GET_OP2_EA_B) - -DEFLABEL(GET_OP2_EA_W) - READ16 $t7 -DEFSIZE(GET_OP2_EA_W) - -DEFLABEL(GET_OP2_EA_L) - READ32 $t7 -DEFSIZE(GET_OP2_EA_L) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_IMMED_16S) - addiu $t7, $zero, 1 -9: -DEFSIZE(GET_OP2_IMMED_16S) -DEFPARAM(GET_OP2_IMMED_16S, value_lo, 9b, -4) - -DEFLABEL(GET_OP2_IMMED_16U) - ori $t7, $zero, 1 -9: -DEFSIZE(GET_OP2_IMMED_16U) -DEFPARAM(GET_OP2_IMMED_16U, value_lo, 9b, -4) - -DEFLABEL(GET_OP2_IMMED_16HI) - lui $t7, 1 -9: -DEFSIZE(GET_OP2_IMMED_16HI) -DEFPARAM(GET_OP2_IMMED_16HI, value_hi, 9b, -4) - -DEFLABEL(GET_OP2_IMMED_32) - lui $t7, 1 -8: ori $t7, $t7, 1 -9: -DEFSIZE(GET_OP2_IMMED_32) -DEFPARAM(GET_OP2_IMMED_32, value_hi, 8b, -4) -DEFPARAM(GET_OP2_IMMED_32, value_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_CCR) - andi $t7, $s5, 0xFF -DEFSIZE(GET_OP2_CCR) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_SR) - move $t7, $s5 -DEFSIZE(GET_OP2_SR) - -/*************************************************************************/ -/**************************** Result storing *****************************/ -/*************************************************************************/ - -/** - * SET_REGISTER_[BWL]: Set the value of the given register to the result - * value. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(SET_REGISTER_B) - sb $v0, 1($s0) -9: -DEFSIZE(SET_REGISTER_B) -DEFPARAM(SET_REGISTER_B, reg4, 9b, -4) - -DEFLABEL(SET_REGISTER_W) - sh $v0, 1($s0) -9: -DEFSIZE(SET_REGISTER_W) -DEFPARAM(SET_REGISTER_W, reg4, 9b, -4) - -DEFLABEL(SET_REGISTER_L) - sw $v0, 1($s0) -9: -DEFSIZE(SET_REGISTER_L) -DEFPARAM(SET_REGISTER_L, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_AREG_W: Set the value of the given address register to the - * sign-extended result value. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(SET_AREG_W) - seh $v1, $v0 - sw $v1, 1($s0) -9: -DEFSIZE(SET_AREG_W) -DEFPARAM(SET_AREG_W, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_EA_[BWL]: Set the value pointed to by the previously resolved - * effective address to the result value. - */ -DEFLABEL(SET_EA_B) - WRITE8 -DEFSIZE(SET_EA_B) - -DEFLABEL(SET_EA_W) - WRITE16 -DEFSIZE(SET_EA_W) - -DEFLABEL(SET_EA_L) - WRITE32 -DEFSIZE(SET_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_CCR: Set the condition codes from the result value. - */ -DEFLABEL(SET_CCR) - ins $s5, $v0, 0, 8 -DEFSIZE(SET_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_SR: Set the status register from the result value. - */ -DEFLABEL(SET_SR) - jal UPDATE_SR - nop -DEFSIZE(SET_SR) - -/*************************************************************************/ -/*************************** Stack operations ****************************/ -/*************************************************************************/ - -/** - * PUSH_L: Push the 32-bit value of operand 1 onto the stack. - */ -DEFLABEL(PUSH_L) - PUSH32 $s3 -DEFSIZE(PUSH_L) - -/*-----------------------------------------------------------------------*/ - -/** - * POP_L: Pop a 32-bit value off the stack into the result register. - */ -DEFLABEL(POP_L) - POP32 $v0 -DEFSIZE(POP_L) - -/*************************************************************************/ -/************************ Condition code setting *************************/ -/*************************************************************************/ - -/** - * SETCC_ADD_[BWL]: Set the condition codes for the result of an ADD - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADD_B) - SETCC_XNZVC_ADD 8 -DEFSIZE(SETCC_ADD_B) - -DEFLABEL(SETCC_ADD_W) - SETCC_XNZVC_ADD 16 -DEFSIZE(SETCC_ADD_W) - -DEFLABEL(SETCC_ADD_L) - SETCC_XNZVC_ADD 32 -DEFSIZE(SETCC_ADD_L) - -/*************************************************************************/ - -/** - * SETCC_ADDX_[BWL]: Set the condition codes for the result of an ADDX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADDX_B) - SETCC_XNZVC_ADDX 8 -DEFSIZE(SETCC_ADDX_B) - -DEFLABEL(SETCC_ADDX_W) - SETCC_XNZVC_ADDX 16 -DEFSIZE(SETCC_ADDX_W) - -DEFLABEL(SETCC_ADDX_L) - SETCC_XNZVC_ADDX 32 -DEFSIZE(SETCC_ADDX_L) - -/*************************************************************************/ - -/** - * SETCC_SUB_[BWL]: Set the condition codes for the result of a SUB - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUB_B) - SETCC_XNZVC_SUB 8 -DEFSIZE(SETCC_SUB_B) - -DEFLABEL(SETCC_SUB_W) - SETCC_XNZVC_SUB 16 -DEFSIZE(SETCC_SUB_W) - -DEFLABEL(SETCC_SUB_L) - SETCC_XNZVC_SUB 32 -DEFSIZE(SETCC_SUB_L) - -/*************************************************************************/ - -/** - * SETCC_SUBX_[BWL]: Set the condition codes for the result of a SUBX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUBX_B) - SETCC_XNZVC_SUBX 8 -DEFSIZE(SETCC_SUBX_B) - -DEFLABEL(SETCC_SUBX_W) - SETCC_XNZVC_SUBX 16 -DEFSIZE(SETCC_SUBX_W) - -DEFLABEL(SETCC_SUBX_L) - SETCC_XNZVC_SUBX 32 -DEFSIZE(SETCC_SUBX_L) - -/*************************************************************************/ - -/** - * SETCC_CMP_[BWL]: Set the condition codes for the result of a CMP - * instruction stored in the result register. The X flag is unmodified. - */ -DEFLABEL(SETCC_CMP_B) - SETCC_NZVC_SUB 8 -DEFSIZE(SETCC_CMP_B) - -DEFLABEL(SETCC_CMP_W) - SETCC_NZVC_SUB 16 -DEFSIZE(SETCC_CMP_W) - -DEFLABEL(SETCC_CMP_L) - SETCC_NZVC_SUB 32 -DEFSIZE(SETCC_CMP_L) - -/*************************************************************************/ - -/** - * SETCC_LOGIC_[BWL]: Set the condition codes for the result of a logical - * instruction (MOVE, AND, OR, EOR) stored in the result register. The X - * flag is unmodified. - */ -DEFLABEL(SETCC_LOGIC_B) - SETCC_NZ00_B $v0 -DEFSIZE(SETCC_LOGIC_B) - -DEFLABEL(SETCC_LOGIC_W) - SETCC_NZ00_W $v0 -DEFSIZE(SETCC_LOGIC_W) - -DEFLABEL(SETCC_LOGIC_L) - SETCC_NZ00_L $v0 -DEFSIZE(SETCC_LOGIC_L) - -/*************************************************************************/ -/*************************** Condition testing ***************************/ -/*************************************************************************/ - -/** - * TEST_*: Check whether a condition is true (based on the current - * condition codes) and set $v1 based on the result (nonzero = true). - */ - -DEFLABEL(TEST_T) - li $v1, 1 -DEFSIZE(TEST_T) - -DEFLABEL(TEST_F) - li $v1, 0 -DEFSIZE(TEST_F) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_HI) - ext $v1, $s5, SR_Z_SHIFT, 1 - ext $a0, $s5, SR_C_SHIFT, 1 - or $v1, $v1, $a0 - xori $v1, $v1, 1 -DEFSIZE(TEST_HI) - -DEFLABEL(TEST_LS) - ext $v1, $s5, SR_Z_SHIFT, 1 - ext $a0, $s5, SR_C_SHIFT, 1 - or $v1, $v1, $a0 -DEFSIZE(TEST_LS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_CC) - ext $v1, $s5, SR_C_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_CC) - -DEFLABEL(TEST_CS) - ext $v1, $s5, SR_C_SHIFT, 1 -DEFSIZE(TEST_CS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_NE) - ext $v1, $s5, SR_Z_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_NE) - -DEFLABEL(TEST_EQ) - ext $v1, $s5, SR_Z_SHIFT, 1 -DEFSIZE(TEST_EQ) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_VC) - ext $v1, $s5, SR_V_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_VC) - -DEFLABEL(TEST_VS) - ext $v1, $s5, SR_V_SHIFT, 1 -DEFSIZE(TEST_VS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_PL) - ext $v1, $s5, SR_N_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_PL) - -DEFLABEL(TEST_MI) - ext $v1, $s5, SR_N_SHIFT, 1 -DEFSIZE(TEST_MI) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GE) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - xor $v1, $v1, $a0 - xori $v1, $v1, 1 -DEFSIZE(TEST_GE) - -DEFLABEL(TEST_LT) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - xor $v1, $v1, $a0 -DEFSIZE(TEST_LT) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GT) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - ext $a1, $s5, SR_Z_SHIFT, 1 - xor $v1, $v1, $a0 - or $v1, $v1, $a1 - xori $v1, $v1, 1 -DEFSIZE(TEST_GT) - -DEFLABEL(TEST_LE) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - ext $a1, $s5, SR_Z_SHIFT, 1 - xor $v1, $v1, $a0 - or $v1, $v1, $a1 -DEFSIZE(TEST_LE) - -/*************************************************************************/ -/**************************** ALU operations *****************************/ -/*************************************************************************/ - -/** - * MOVE_[BWL]: Evaluate op1, setting the result value for the MOVE - * instruction. - */ -DEFLABEL(MOVE_B) - move $v0, $s3 -DEFSIZE(MOVE_B) - -DEFLABEL(MOVE_W) - move $v0, $s3 -DEFSIZE(MOVE_W) - -DEFLABEL(MOVE_L) - move $v0, $s3 -DEFSIZE(MOVE_L) - -/*************************************************************************/ - -/** - * ADD_[BWL]: Evaluate op2 + op1. - */ -DEFLABEL(ADD_B) - addu $v0, $t7, $s3 -DEFSIZE(ADD_B) - -DEFLABEL(ADD_W) - addu $v0, $t7, $s3 -DEFSIZE(ADD_W) - -DEFLABEL(ADD_L) - addu $v0, $t7, $s3 -DEFSIZE(ADD_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDA_W: Sign-extend op1 to 32 bits, then evaluate op2 + op1. - */ -DEFLABEL(ADDA_W) - seh $v1, $s3 - addu $v0, $t7, $v1 -DEFSIZE(ADDA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDX_[BWL]: Evaluate op2 + op1 + X. - */ -DEFLABEL(ADDX_B) - ext $v1, $s5, SR_X_SHIFT, 1 - addu $v0, $t7, $s3 - addu $v0, $v0, $v1 -DEFSIZE(ADDX_B) - -DEFLABEL(ADDX_W) - ext $v1, $s5, SR_X_SHIFT, 1 - addu $v0, $t7, $s3 - addu $v0, $v0, $v1 -DEFSIZE(ADDX_W) - -DEFLABEL(ADDX_L) - ext $v1, $s5, SR_X_SHIFT, 1 - addu $v0, $t7, $s3 - addu $v0, $v0, $v1 -DEFSIZE(ADDX_L) - -/*************************************************************************/ - -/** - * SUB_[BWL]: Evaluate op2 - op1. - */ -DEFLABEL(SUB_B) - subu $v0, $t7, $s3 -DEFSIZE(SUB_B) - -DEFLABEL(SUB_W) - subu $v0, $t7, $s3 -DEFSIZE(SUB_W) - -DEFLABEL(SUB_L) - subu $v0, $t7, $s3 -DEFSIZE(SUB_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBA_W: Sign-extend op1 to 32 bits, then evaluate op2 - op1. - */ -DEFLABEL(SUBA_W) - seh $v1, $s3 - subu $v0, $t7, $v1 -DEFSIZE(SUBA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBX_[BWL]: Evaluate op2 - op1 - X. - */ -DEFLABEL(SUBX_B) - ext $v1, $s5, SR_X_SHIFT, 1 - subu $v0, $t7, $s3 - subu $v0, $v0, $v1 -DEFSIZE(SUBX_B) - -DEFLABEL(SUBX_W) - ext $v1, $s5, SR_X_SHIFT, 1 - subu $v0, $t7, $s3 - subu $v0, $v0, $v1 -DEFSIZE(SUBX_W) - -DEFLABEL(SUBX_L) - ext $v1, $s5, SR_X_SHIFT, 1 - subu $v0, $t7, $s3 - subu $v0, $v0, $v1 -DEFSIZE(SUBX_L) - -/*************************************************************************/ - -/** - * MUL[SU]_W: Evaluate op2 * op1 in signed or unsigned context. - */ -DEFLABEL(MULS_W) - seh $v0, $t7 - seh $v1, $s3 - mul $v0, $v1 - mflo $v0 -DEFSIZE(MULS_W) - -DEFLABEL(MULU_W) - andi $v0, $t7, 0xFFFF - andi $v1, $s3, 0xFFFF - multu $v0, $v1 - mflo $v0 -DEFSIZE(MULU_W) - -/*************************************************************************/ - -/** - * DIV[SU]_W: Evaluate op2 / op1 in signed or unsigned context, setting - * the condition codes appropriately. The quotient is stored in the low - * 16 bits, the remainder in the high 16 bits of the result value. On - * overflow, op2 is copied to the result. - */ -DEFLABEL(DIVS_W) - seh $v1, $s3 - /* MIPS doesn't raise an exception on divide-by-zero, so let the - * divider unit do its thing while we check for a zero divisor */ - div $t7, $v1 - bnez $v1, 0f - // The C flag is always cleared, so do it here in the delay slot - ins $s5, $zero, SR_C_SHIFT, 1 - li $a0, EX_DIVIDE_BY_ZERO - sw $a0, Q68State_exception($s0) - TERMINATE -0: mflo $v0 - mfhi $a3 - li $a0, 0x8000 // Overflow check - addu $a0, $v0, $a0 - srl $a0, $a0, 16 - beqz $a0, 1f - sll $a3, $a3, 16 - li $a0, 1 - ins $s5, $a0, SR_V_SHIFT, 1 - j 2f - move $v0, $t7 -1: andi $v0, $v0, 0xFFFF // Need to clear upper bits in case it's negative - SETCC_NZ_W $v0 - ins $s5, $zero, SR_V_SHIFT, 1 - or $v0, $v0, $a3 -2: -DEFSIZE(DIVS_W) - -DEFLABEL(DIVU_W) - andi $v1, $s3, 0xFFFF - divu $t7, $v1 - bnez $v1, 0f - ins $s5, $zero, SR_C_SHIFT, 1 - li $a0, EX_DIVIDE_BY_ZERO - sw $a0, Q68State_exception($s0) - TERMINATE -0: mflo $v0 - mfhi $a3 - srl $a0, $v0, 16 // Overflow check (easier for unsigned quotients) - beqz $a0, 1f - sll $a3, $a3, 16 - li $a0, 1 - ins $s5, $a0, SR_V_SHIFT, 1 - j 2f - move $v0, $t7 -1: SETCC_NZ_W $v0 - ins $s5, $zero, SR_V_SHIFT, 1 - or $v0, $v0, $a3 -2: -DEFSIZE(DIVU_W) - -/*************************************************************************/ - -/** - * AND_[BWL]: Evaluate op2 & op1. - */ -DEFLABEL(AND_B) - and $v0, $t7, $s3 -DEFSIZE(AND_B) - -DEFLABEL(AND_W) - and $v0, $t7, $s3 -DEFSIZE(AND_W) - -DEFLABEL(AND_L) - and $v0, $t7, $s3 -DEFSIZE(AND_L) - -/*************************************************************************/ - -/** - * OR_[BWL]: Evaluate op2 | op1. - */ -DEFLABEL(OR_B) - or $v0, $t7, $s3 -DEFSIZE(OR_B) - -DEFLABEL(OR_W) - or $v0, $t7, $s3 -DEFSIZE(OR_W) - -DEFLABEL(OR_L) - or $v0, $t7, $s3 -DEFSIZE(OR_L) - -/*************************************************************************/ - -/** - * EOR_[BWL]: Evaluate op2 ^ op1. - */ -DEFLABEL(EOR_B) - xor $v0, $t7, $s3 -DEFSIZE(EOR_B) - -DEFLABEL(EOR_W) - xor $v0, $t7, $s3 -DEFSIZE(EOR_W) - -DEFLABEL(EOR_L) - xor $v0, $t7, $s3 -DEFSIZE(EOR_L) - -/*************************************************************************/ - -/** - * EXT_[WL]: Sign-extend op1 from 8 to 16 or from 16 to 32 bits. - */ -DEFLABEL(EXT_W) - seb $v0, $s3 -DEFSIZE(EXT_W) - -DEFLABEL(EXT_L) - seh $v0, $s3 -DEFSIZE(EXT_L) - -/*************************************************************************/ - -/** - * SWAP: Swap the upper and lower 16-bit halves of op1, placing the result - * in the result register. - */ -DEFLABEL(SWAP) - srl $v0, $s3, 16 - ins $v0, $s3, 16, 16 -DEFSIZE(SWAP) - -/*************************************************************************/ -/**************************** BCD operations *****************************/ -/*************************************************************************/ - -/** - * ABCD: Evaluate op2 + op1 + X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(ABCD) - ext $t2, $s5, SR_X_SHIFT, 1 - andi $t0, $t7, 0xF - andi $t1, $s3, 0xF - addu $t3, $t0, $t1 - addu $t3, $t3, $t2 - sltiu $v1, $t3, 10 - beqzl $v1, 0f - addiu $t3, $t3, 6 // Skipped if no carry from the units place -0: andi $t0, $t7, 0xF0 - andi $t1, $s3, 0xF0 - addu $t2, $t0, $t1 - addu $v0, $t2, $t3 - sltiu $v1, $v0, 10<<4 - bnezl $v1, 1f - move $a3, $zero // Executed if no carry from the tens place - addiu $v0, $v0, -(10<<4) - li $a3, 1 -1: ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - andi $v1, $v0, 0xFF - snez $v1, $v1 - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 -DEFSIZE(ABCD) - -/*************************************************************************/ - -/** - * SBCD: Evaluate op2 - op1 - X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(SBCD) - ext $t2, $s5, SR_X_SHIFT, 1 - andi $t0, $t7, 0xF - andi $t1, $s3, 0xF - subu $t3, $t0, $t1 - subu $t3, $t3, $t2 - sltz $v1, $t3 - bnezl $v1, 0f - move $t2, $zero // Executed if no borrow from the units place - addiu $t3, $t3, 10 - li $t2, 1<<4 -0: andi $t0, $t7, 0xF0 - andi $t1, $s3, 0xF0 - subu $t4, $t0, $t1 - subu $t4, $t4, $t2 - sltz $v1, $t4 - bnezl $v1, 1f - move $a3, $zero // Executed if no carry from the tens place - addiu $v0, $v0, 10<<4 - li $a3, 1 -1: addu $v0, $t3, $t4 - sltz $v1, $v0 - or $a3, $a3, $v1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - andi $v1, $v0, 0xFF - snez $v1, $v1 - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 -DEFSIZE(SBCD) - -/*************************************************************************/ -/*********************** Bit-twiddling operations ************************/ -/*************************************************************************/ - -/** - * BTST_[BL]: Evaluate op2 & (1 << op1). The value (1 << op1), where the - * high bits of op1 have been masked to zero, is left in $t0 for use by a - * subsequent BCHG/BCLR/BSET operation. - */ -DEFLABEL(BTST_B) - andi $a0, $s3, 7 - li $t0, 1 - sllv $t0, $t0, $a0 - and $v1, $t7, $t0 - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -DEFSIZE(BTST_B) - -DEFLABEL(BTST_L) - andi $a0, $s3, 31 - li $t0, 1 - sllv $t0, $t0, $a0 - and $v1, $t7, $t0 - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -DEFSIZE(BTST_L) - -/*************************************************************************/ - -/** - * BCHG: Evaluate op2 ^ (1 << op1), where (1 << op1) has already been - * stored in $t0. - */ -DEFLABEL(BCHG) - xor $v0, $t7, $t0 -DEFSIZE(BCHG) - -/*-----------------------------------------------------------------------*/ - -/** - * BCLR: Evaluate op2 & ~(1 << op1), where (1 << op1) has already been - * stored in $t0. - */ -DEFLABEL(BCLR) - not $v1, $t0 - and $v0, $t7, $v1 -DEFSIZE(BCLR) - -/*-----------------------------------------------------------------------*/ - -/** - * BSET: Evaluate op2 | (1 << op1), where (1 << op1) has already been - * stored in $t0. - */ -DEFLABEL(BSET) - or $v0, $t7, $t0 -DEFSIZE(BSET) - -/*************************************************************************/ -/************************ Shift/rotate operations ************************/ -/*************************************************************************/ - -/** - * ASL_[BWL]: Evaluate (signed) op2 << op1. - */ -.macro DEF_ASL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 // Add 2 clock cycles per shift - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 1f - move $v0, $t7 - // Have to shift bit by bit to detect overflow -0: ext $a3, $v0, \nbits-1, 1 - ext $v1, $v0, \nbits-2, 1 - sll $v0, $v0, 1 - addiu $s3, $s3, -1 - xor $v1, $v1, $a3 - sll $v1, $v1, SR_V_SHIFT - bnez $s3, 0b - or $s5, $s5, $v1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 -1: -.endm - -DEFLABEL(ASL_B) - DEF_ASL 8 - SETCC_NZ_B $v0 -DEFSIZE(ASL_B) - -DEFLABEL(ASL_W) - DEF_ASL 16 - SETCC_NZ_W $v0 -DEFSIZE(ASL_W) - -DEFLABEL(ASL_L) - DEF_ASL 32 - SETCC_NZ_L $v0 -DEFSIZE(ASL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ASR_[BWL]: Evaluate (signed) op2 >> op1. - */ -.macro DEF_ASR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - sltiu $v1, $s3, \nbits - bnez $v1, 2f - nop -1: // count >= nbits - sra $v0, $t7, \nbits-1 - andi $a3, $v0, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - j 3f - ins $s5, $a3, SR_X_SHIFT, 1 -2: // count != 0 && count < nbits - addiu $v1, $s3, -1 - srav $v0, $t7, $v1 - andi $a3, $v0, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - sra $v0, $v0, 1 -3: // All cases -.endm - -DEFLABEL(ASR_B) - seb $t7 - DEF_ASR 8 - SETCC_NZ_B $v0 -DEFSIZE(ASR_B) - -DEFLABEL(ASR_W) - seh $t7 - DEF_ASR 16 - SETCC_NZ_W $v0 -DEFSIZE(ASR_W) - -DEFLABEL(ASR_L) - DEF_ASR 32 - SETCC_NZ_L $v0 -DEFSIZE(ASR_L) - -/*************************************************************************/ - -/** - * LSL_[BWL]: Evaluate (unsigned) op2 << op1. - */ -.macro DEF_LSL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - li $a0, \nbits - sltu $v1, $s3, $a0 - bnez $v1, 2f - sltu $v1, $a0, $s3 - bnez $v1, 1f - nop -0: // count == nbits - ins $s5, $t7, SR_C_SHIFT, 1 - ins $s5, $t7, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -1: // count > nbits - ins $s5, $zero, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -2: // count != 0 && count < nbits - addiu $v1, $s3, -1 - sllv $v0, $t7, $v1 - ext $a3, $v0, \nbits-1, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - sll $v0, $v0, 1 -3: // All cases -.endm - -DEFLABEL(LSL_B) - DEF_LSL 8 - SETCC_NZ_B $v0 -DEFSIZE(LSL_B) - -DEFLABEL(LSL_W) - DEF_LSL 16 - SETCC_NZ_W $v0 -DEFSIZE(LSL_W) - -DEFLABEL(LSL_L) - DEF_LSL 32 - SETCC_NZ_L $v0 -DEFSIZE(LSL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * LSR_[BWL]: Evaluate (unsigned) op2 >> op1. - */ -.macro DEF_LSR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - li $a0, \nbits - sltu $v1, $s3, $a0 - bnez $v1, 2f - sltu $v1, $a0, $s3 - bnez $v1, 1f - nop -0: // count == nbits - ext $a3, $t7, \nbits-1, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -1: // count > nbits - ins $s5, $zero, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -2: // count != 0 && count < nbits - addiu $v1, $s3, -1 - srlv $v0, $t7, $v1 - andi $a3, $v0, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - srl $v0, $v0, 1 -3: // All cases -.endm - -DEFLABEL(LSR_B) - andi $t7, $t7, 0xFF - DEF_LSR 8 - SETCC_NZ_B $v0 -DEFSIZE(LSR_B) - -DEFLABEL(LSR_W) - andi $t7, $t7, 0xFFFF - DEF_LSR 16 - SETCC_NZ_W $v0 -DEFSIZE(LSR_W) - -DEFLABEL(LSR_L) - DEF_LSR 32 - SETCC_NZ_L $v0 -DEFSIZE(LSR_L) - -/*************************************************************************/ - -/** - * ROXL_[BWL]: Evaluate op2 ROXL op1. - */ -.macro DEF_ROXL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ext $a3, $s5, SR_X_SHIFT, 1 - ins $s5, $a3, SR_C_SHIFT, 2 // Clear V while setting C - beqz $s3, 1f - move $v0, $t7 -0: sll $v1, $v0, 1 - ext $a0, $v0, \nbits-1, 1 - or $v0, $v1, $a3 - addiu $s3, $s3, -1 - bnez $s3, 0b - move $a3, $a0 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 -1: -.endm - -DEFLABEL(ROXL_B) - DEF_ROXL 8 - SETCC_NZ_B $v0 -DEFSIZE(ROXL_B) - -DEFLABEL(ROXL_W) - DEF_ROXL 16 - SETCC_NZ_W $v0 -DEFSIZE(ROXL_W) - -DEFLABEL(ROXL_L) - DEF_ROXL 32 - SETCC_NZ_L $v0 -DEFSIZE(ROXL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROXR_[BWL]: Evaluate op2 ROXR op1. - */ -.macro DEF_ROXR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ext $a3, $s5, SR_X_SHIFT, 1 - ins $s5, $a3, SR_C_SHIFT, 2 // Clear V while setting C - beqz $s3, 1f - move $v0, $t7 -0: srl $v1, $v0, 1 - ins $v1, $a3, \nbits-1, 1 - andi $a3, $v0, 1 - addiu $s3, $s3, -1 - bnez $s3, 0b - move $v0, $v1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 -1: -.endm - -DEFLABEL(ROXR_B) - DEF_ROXR 8 - SETCC_NZ_B $v0 -DEFSIZE(ROXR_B) - -DEFLABEL(ROXR_W) - DEF_ROXR 16 - SETCC_NZ_W $v0 -DEFSIZE(ROXR_W) - -DEFLABEL(ROXR_L) - DEF_ROXR 32 - SETCC_NZ_L $v0 -DEFSIZE(ROXR_L) - -/*************************************************************************/ - -/** - * ROL_[BWL]: Evaluate op2 ROL op1. - */ -.macro DEF_ROL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - andi $s3, $s3, \nbits-1 - bnez $s3, 2f -1: // count != 0 && count % nbits == 0 - andi $a3, $t7, 1 // Branch delay slot from above (this is safe) - j 3f - ins $s5, $a3, SR_C_SHIFT, 1 -2: // count % nbits != 0 - li $v1, \nbits - sub $v1, $v1, $s3 - sllv $a0, $t7, $s3 - srlv $t0, $t7, $v1 - or $v0, $a0, $t0 - andi $a3, $t7, 1 - ins $s5, $a3, SR_C_SHIFT, 1 -3: // All cases -.endm - -DEFLABEL(ROL_B) - andi $t7, $t7, 0xFF - DEF_ROL 8 - SETCC_NZ_B $v0 -DEFSIZE(ROL_B) - -DEFLABEL(ROL_W) - andi $t7, $t7, 0xFFFF - DEF_ROL 16 - SETCC_NZ_W $v0 -DEFSIZE(ROL_W) - -DEFLABEL(ROL_L) - DEF_ROL 32 - SETCC_NZ_L $v0 -DEFSIZE(ROL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROR_[BWL]: Evaluate op2 ROR op1. - */ -.macro DEF_ROR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - andi $s3, $s3, \nbits-1 - bnez $s3, 2f -1: // count != 0 && count % nbits == 0 - ext $a3, $t7, \nbits-1, 1 // Branch delay slot from above (safe) - j 3f - ins $s5, $a3, SR_C_SHIFT, 1 -2: // count % nbits != 0 - li $v1, \nbits - sub $v1, $v1, $s3 - srlv $a0, $t7, $s3 - sllv $t0, $t7, $v1 - or $v0, $a0, $t0 - ext $a3, $t7, \nbits-1, 1 - ins $s5, $a3, SR_C_SHIFT, 1 -3: // All cases -.endm - -DEFLABEL(ROR_B) - andi $t7, $t7, 0xFF - DEF_ROR 8 - SETCC_NZ_B $v0 -DEFSIZE(ROR_B) - -DEFLABEL(ROR_W) - andi $t7, $t7, 0xFFFF - DEF_ROR 16 - SETCC_NZ_W $v0 -DEFSIZE(ROR_W) - -DEFLABEL(ROR_L) - DEF_ROR 32 - SETCC_NZ_L $v0 -DEFSIZE(ROR_L) - -/*************************************************************************/ -/******************* Conditional and branch operations *******************/ -/*************************************************************************/ - -/** - * Scc: Set the lower 8 bits of the result value to 0xFF if the condition - * is true, 0x00 if false. - */ -DEFLABEL(Scc) - negu $v0, $v1 -DEFSIZE(Scc) - -/*-----------------------------------------------------------------------*/ - -/** - * ADD_CYCLES_Scc_Dn: Add the appropriate number of clock cycles for an - * Scc Dn instruction to the cycle count. - */ -DEFLABEL(ADD_CYCLES_Scc_Dn) - andi $v1, $v0, 2 - addiu $v1, $v1, 4 - addu $s2, $s2, $v1 -DEFSIZE(ADD_CYCLES_Scc_Dn) - -/*************************************************************************/ - -/** - * DBcc: Jump to the specified target address unless the condition is true - * or the lower 16 bits of the given data register, after being decremented, - * are equal to -1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target_hi: High 16 bits of target address - * target_lo: Low 16 bits of target address - */ -DEFLABEL(DBcc) - lhu $v0, 1($s0) -6: bnezl $v1, 0f - addiu $s2, $s2, 12 - addiu $v1, $v0, -1 - sh $v1, 1($s0) -7: beqzl $v0, 0f - addiu $s2, $s2, 14 - addiu $s2, $s2, 10 - lui $v0, 0x1234 -8: ori $s4, $v0, 0x5678 -9: TERMINATE -0: -DEFSIZE(DBcc) -DEFPARAM(DBcc, reg4, 6b, -4) -DEFPARAM(DBcc, reg4_b, 7b, -4) // same as reg4 -DEFPARAM(DBcc, target_hi, 8b, -4) -DEFPARAM(DBcc, target_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * DBcc_native: Implement DBcc using a jump within the native code. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target_hi: High 16 bits of target 68000 address - * target_lo: Low 16 bits of target 68000 address - * native_disp_4_4: (Native displacement from end of this fragment + 4) / 4 - */ -DEFLABEL(DBcc_native) - lhu $v0, 1($s0) -6: bnezl $v1, 0f - addiu $s2, $s2, 12 - addiu $v1, $v0, -1 - sh $v1, 1($s0) -7: beqzl $v0, 0f - addiu $s2, $s2, 14 - addiu $s2, $s2, 10 - lui $v0, 0x1234 -8: ori $s4, $v0, 0x5678 -9: b .+0x1234 -5: nop -0: -DEFSIZE(DBcc_native) -DEFPARAM(DBcc_native, reg4, 6b, -4) -DEFPARAM(DBcc_native, reg4_b, 7b, -4) // same as reg4 -DEFPARAM(DBcc_native, target_hi, 8b, -4) -DEFPARAM(DBcc_native, target_lo, 9b, -4) -DEFPARAM(DBcc_native, native_disp_4_4, 5b, -4) - -/*************************************************************************/ - -/** - * Bcc_common: Jump to the specified target address if the condition is - * true. Used for both interpreted jumps (by branching to TERMINATE) and - * native jumps. - * - * [Parameters] - * target_hi: High 16 bits of target 68000 address - * target_lo: Low 16 bits of target 68000 address - * disp_4: Native displacement / 4 (either JIT_PSPOFS_TERMINATE or - * target address minus address of "nop" following branch) - */ -DEFLABEL(Bcc_common) - beqz $v1, 0f - lui $v0, 0x1234 // In the delay slot, but not a problem -8: ori $s4, $v0, 0x5678 -9: addiu $s2, $s2, 10 - b .+0x1234 -5: nop -0: -DEFSIZE(Bcc_common) -DEFPARAM(Bcc_common, target_hi, 8b, -4) -DEFPARAM(Bcc_common, target_lo, 9b, -4) -DEFPARAM(Bcc_common, disp_4, 5b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * BSR: Push the address of the next instruction onto the stack, then jump - * to the specified target address. - * - * [Parameters] - * return_addr_hi: High 16 bits of return address to push onto the stack - * return_addr_lo: High 16 bits of return address to push onto the stack - * target_hi: High 16 bits of target address - * target_lo: Low 16 bits of target address - */ -DEFLABEL(BSR) - lui $v0, 0x1234 -6: ori $v0, $v0, 0x5678 -7: PUSH32 $v0 - lui $v0, 0x1234 -8: ori $s4, $v0, 0x5678 -9: ori $s2, $s2, 0x8000 // Indicate that this is a BSR/JSR termination - TERMINATE_CONTINUE -DEFSIZE(BSR) -DEFPARAM(BSR, return_addr_hi, 6b, -4) -DEFPARAM(BSR, return_addr_lo, 7b, -4) -DEFPARAM(BSR, target_hi, 8b, -4) -DEFPARAM(BSR, target_lo, 9b, -4) - -/*************************************************************************/ - -/** - * JMP: Jump to the previously resolved effective address. - */ -DEFLABEL(JMP) - move $s4, $s6 - TERMINATE -DEFSIZE(JMP) - -/*-----------------------------------------------------------------------*/ - -/** - * JSR: Push the address of the next instruction onto the stack, then jump - * to the previously resolved effective address. - * - * [Parameters] - * return_addr_hi: High 16 bits of return address to push onto the stack - * return_addr_lo: High 16 bits of return address to push onto the stack - */ -DEFLABEL(JSR) - lui $v0, 0x1234 -8: ori $v0, $v0, 0x5678 -9: PUSH32 $v0 - move $s4, $s6 - ori $s2, $s2, 0x8000 // Indicate that this is a BSR/JSR termination - TERMINATE_CONTINUE -DEFSIZE(JSR) -DEFPARAM(JSR, return_addr_hi, 8b, -4) -DEFPARAM(JSR, return_addr_lo, 9b, -4) - -/*************************************************************************/ -/*********************** MOVEM-related operations ************************/ -/*************************************************************************/ - -/** - * STORE_DEC_[WL]: Decrement state->ea_addr, then store the specified - * register to the resulting location. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_DEC_W) - lw $v0, 1($s0) -9: addiu $s6, $s6, -2 - LOAD_DELAY_NOP - WRITE16 -DEFSIZE(STORE_DEC_W) -DEFPARAM(STORE_DEC_W, reg4, 9b, -4) - -DEFLABEL(STORE_DEC_L) - lw $v0, 1($s0) -9: addiu $s6, $s6, -4 - LOAD_DELAY_NOP - WRITE32 -DEFSIZE(STORE_DEC_L) -DEFPARAM(STORE_DEC_L, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * STORE_INC_[WL]: Store the specified register to the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_INC_W) - lw $v0, 1($s0) -9: LOAD_DELAY_NOP - LOAD_DELAY_NOP - WRITE16 - addiu $s6, $s6, 2 -DEFSIZE(STORE_INC_W) -DEFPARAM(STORE_INC_W, reg4, 9b, -4) - -DEFLABEL(STORE_INC_L) - lw $v0, 1($s0) -9: LOAD_DELAY_NOP - LOAD_DELAY_NOP - WRITE32 - addiu $s6, $s6, 4 -DEFSIZE(STORE_INC_L) -DEFPARAM(STORE_INC_L, reg4, 9b, -4) - -/*************************************************************************/ - -/** - * LOAD_INC_[WL]: Load the specified register from the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(LOAD_INC_W) - READ16 $v0 - sh $v0, 1($s0) -9: addiu $s6, $s6, 2 -DEFSIZE(LOAD_INC_W) -DEFPARAM(LOAD_INC_W, reg4, 9b, -4) - -DEFLABEL(LOAD_INC_L) - READ32 $v0 - sw $v0, 1($s0) -9: addiu $s6, $s6, 4 -DEFSIZE(LOAD_INC_L) -DEFPARAM(LOAD_INC_L, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * LOADA_INC_W: Load the specified address register from the location - * indicated by state->ea_addr, sign-extending the 16-bit value to 32 bits, - * then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LOADA_INC_W) - READ16 $v0 - seh $v0, $v0 - sh $v0, 1($s0) -9: addiu $s6, $s6, 2 -DEFSIZE(LOADA_INC_W) -DEFPARAM(LOADA_INC_W, reg4, 9b, -4) - -/*************************************************************************/ - -/** - * MOVEM_WRITEBACK: Store the address in state->ea_addr to the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVEM_WRITEBACK) - sw $s6, 1($s0) -9: -DEFSIZE(MOVEM_WRITEBACK) -DEFPARAM(MOVEM_WRITEBACK, reg4, 9b, -4) - -/*************************************************************************/ -/*********************** Miscellaneous operations ************************/ -/*************************************************************************/ - -/** - * CHK_W: Raise a CHK exception if op1 < 0 or op1 > op2, treating both - * operands as signed 16-bit values. - */ -DEFLABEL(CHK_W) - seh $s3, $s3 - seh $t7, $t7 - bltzl $s3, 0f - ori $s5, $s5, SR_N - slt $v1, $t7, $s3 - beqz $v1, 1f - nop - ins $s5, $zero, SR_N_SHIFT, 1 -0: li $a0, EX_CHK - sw $a0, Q68State_exception($s0) - TERMINATE -1: -DEFSIZE(CHK_W) - -/*************************************************************************/ - -/** - * LEA: Store the previously resolved effective address in the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LEA) - sw $s6, 1($s0) -9: -DEFSIZE(LEA) -DEFPARAM(LEA, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * PEA: Push the previously resolved effective address onto the stack. - */ -DEFLABEL(PEA) - PUSH32 $s6 -DEFSIZE(PEA) - -/*************************************************************************/ - -/** - * TAS: Test the 8-bit value of op1, setting the condition codes - * appropriately, then calculate op1 | 0x80. - */ -DEFLABEL(TAS) - SETCC_NZ00_B $s3 - ori $v0, $s3, 0x80 -DEFSIZE(TAS) - -/*************************************************************************/ - -/** - * MOVE_FROM_USP: Copy the user stack pointer to the specified register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_FROM_USP) - lw $v0, USP - LOAD_DELAY_NOP - LOAD_DELAY_NOP - sw $v0, 1($s0) -9: -DEFSIZE(MOVE_FROM_USP) -DEFPARAM(MOVE_FROM_USP, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVE_TO_USP: Copy the specified register to the user stack pointer. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_TO_USP) - lw $v0, 1($s0) -9: LOAD_DELAY_NOP - LOAD_DELAY_NOP - sw $v0, USP -DEFSIZE(MOVE_TO_USP) -DEFPARAM(MOVE_TO_USP, reg4, 9b, -4) - -/*************************************************************************/ - -/** - * STOP: Halt the processor. - * - * [Parameters] - * newSR: Value to load into SR - */ -DEFLABEL(STOP) - li $v0, 1 - sw $v0, Q68State_halted($s0) - jal UPDATE_SR - ori $v0, $zero, 0x1234 -9: -DEFSIZE(STOP) -DEFPARAM(STOP, newSR, 9b, -4) - -/*************************************************************************/ - -/** - * TRAPV: Raise a TRAPV exception if the overflow flag is set. - */ -DEFLABEL(TRAPV) - ext $v1, $s5, SR_V_SHIFT, 1 - beqz $v1, 0f - li $a0, EX_TRAPV // In the delay slot, but that's okay - sw $a0, Q68State_exception($s0) - TERMINATE -0: -DEFSIZE(TRAPV) - -/*************************************************************************/ - -/** - * RTS: Pop the PC from the stack. - */ -DEFLABEL(RTS) - POP32 $s4 - ori $s2, $s2, 0xC000 // Indicate that this is an RTS/RTR termination - TERMINATE -DEFSIZE(RTS) - -/*-----------------------------------------------------------------------*/ - -/** - * RTR: Pop the condition codes and PC from the stack. - */ -DEFLABEL(RTR) - POP16 $v0 - ins $s5, $v0, 0, 8 - POP32 $s4 - ori $s2, $s2, 0xC000 // Indicate that this is an RTS/RTR termination - TERMINATE -DEFSIZE(RTR) - -/*-----------------------------------------------------------------------*/ - -/** - * RTE: Pop the status register and PC from the stack. - */ -DEFLABEL(RTE) - POP16 $s3 // Borrow op1, since POP32 will destroy temporary registers - POP32 $s4 - jal UPDATE_SR - move $v0, $s3 - TERMINATE -DEFSIZE(RTE) - -/*************************************************************************/ - -/** - * MOVEP_READ_[WL]: Read a value from memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. to receive data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_READ_W) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: READ8 $v0 // Byte 1 - addiu $s6, $s6, 2 - ins $s3, $v0, 8, 8 - READ8 $v0 // Byte 0 - ins $s3, $v0, 0, 8 - sh $s3, 1($s0) -9: -DEFSIZE(MOVEP_READ_W) -DEFPARAM(MOVEP_READ_W, areg4, 7b, -4) -DEFPARAM(MOVEP_READ_W, disp, 8b, -4) -DEFPARAM(MOVEP_READ_W, dreg4, 9b, -4) - -DEFLABEL(MOVEP_READ_L) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: READ8 $v0 // Byte 3 - addiu $s6, $s6, 2 - ins $s3, $v0, 24, 8 - READ8 $v0 // Byte 2 - addiu $s6, $s6, 2 - ins $s3, $v0, 16, 8 - READ8 $v0 // Byte 1 - addiu $s6, $s6, 2 - ins $s3, $v0, 8, 8 - READ8 $v0 // Byte 0 - ins $s3, $v0, 0, 8 - sh $s3, 1($s0) -9: -DEFSIZE(MOVEP_READ_L) -DEFPARAM(MOVEP_READ_L, areg4, 7b, -4) -DEFPARAM(MOVEP_READ_L, disp, 8b, -4) -DEFPARAM(MOVEP_READ_L, dreg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVEP_WRITE_[WL]: Write a value to memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. containing data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_WRITE_W) - lw $s6, 1($s0) -7: lw $s3, 1($s0) -9: LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: ext $v0, $s3, 8, 8 - WRITE8 // Byte 1 - addiu $s6, $s6, 2 - ext $v0, $s3, 0, 8 - WRITE8 // Byte 0 -DEFSIZE(MOVEP_WRITE_W) -DEFPARAM(MOVEP_WRITE_W, areg4, 7b, -4) -DEFPARAM(MOVEP_WRITE_W, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_W, dreg4, 9b, -4) - -DEFLABEL(MOVEP_WRITE_L) - lw $s6, 1($s0) -7: lw $s3, 1($s0) -9: LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: ext $v0, $s3, 24, 8 - WRITE8 // Byte 3 - addiu $s6, $s6, 2 - ext $v0, $s3, 16, 8 - WRITE8 // Byte 2 - addiu $s6, $s6, 2 - ext $v0, $s3, 8, 8 - WRITE8 // Byte 1 - addiu $s6, $s6, 2 - ext $v0, $s3, 0, 8 - WRITE8 // Byte 0 -DEFSIZE(MOVEP_WRITE_L) -DEFPARAM(MOVEP_WRITE_L, areg4, 7b, -4) -DEFPARAM(MOVEP_WRITE_L, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_L, dreg4, 9b, -4) - -/*************************************************************************/ - -/** - * EXG: Exchange the values of two registers. - * - * [Parameters] - * reg1_4: Register number * 4 of first register (0-60 = D0-A7) - * reg2_4: Register number * 4 of second register (0-60 = D0-A7) - */ -DEFLABEL(EXG) - addiu $a0, $s0, 1 -8: lw $v0, 0($a0) - addiu $a1, $s0, 1 -9: lw $v1, 0($a1) - sw $v0, 0($a1) - LOAD_DELAY_NOP - sw $v1, 0($a0) -DEFSIZE(EXG) -DEFPARAM(EXG, reg1_4, 8b, -1) -DEFPARAM(EXG, reg2_4, 9b, -1) - -/*************************************************************************/ -/*************************************************************************/ diff --git a/yabause/src/q68/q68-jit-psp.h b/yabause/src/q68/q68-jit-psp.h deleted file mode 100644 index be580cddbe..0000000000 --- a/yabause/src/q68/q68-jit-psp.h +++ /dev/null @@ -1,593 +0,0 @@ -/* src/q68/q68-jit-psp.h: PSP dynamic translation header for Q68 - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_JIT_PSP_H -#define Q68_JIT_PSP_H - -#include - -/*************************************************************************/ - -/** - * JIT_CALL: Run translated code from the given (native) address for the - * given number of cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * address_ptr: Pointer to address of native code to execute; must be - * updated on return with the next address to execute - * or NULL if the end of the block was reached - * [Return value] - * Number of clock cycles actually executed - */ -static inline int JIT_CALL(Q68State *state, int cycles, void **address_ptr) -{ - register Q68State *__state asm("s0") = state; - register int __cycles asm("s1") = cycles; - register int __cycles_out asm("s2"); - register void * __address asm("v0") = *address_ptr; - asm(".set push; .set noreorder\n" - "jalr %[address]\n" - "move $s2, $zero\n" - ".set pop" - : "=r" (__cycles), [address] "=r" (__address), "=r" (__cycles_out) - : "r" (__state), "0" (__cycles), "1" (__address) - : "at", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", - "t5", "t6", "t7", "t8", "t9", "s3", "s4", "s5", "s6", "s7", "ra", - "memory" - ); - *address_ptr = __address; - return __cycles_out; -} - -/*************************************************************************/ - -/** - * JIT_FIXUP_BRANCH: Modify a branch instruction at the given offset to - * jump to the given target. - * - * [Parameters] - * entry: Block being translated - * offset: Offset within entry->native_code of branch instruction - * (as returned in *branch_offset EMIT parameter) - * target: Target offset within entry->native_code - * [Return value] - * None - */ -static inline void JIT_FIXUP_BRANCH(Q68JitEntry *entry, uint32_t offset, - uint32_t target) -{ - int32_t disp_4 = (target - (offset + 4)) / 4; - if (disp_4 >= -32768 && disp_4 <= 32767) { - *(int16_t *)((uint8_t *)entry->native_code + offset) = disp_4; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * The remaining macros are all used to insert a specific operation into - * the native code stream. For simplicity, we define the actual code for - * each operation in a separate assembly file, and use memcpy() to copy - * from the assembled code to the output code stream. The GEN_EMIT macro - * below is used to generate each of the JIT_EMIT_* functions; each - * function JIT_EMIT_xxx copies JIT_PSPSIZE_xxx bytes from JIT_PSP_xxx to - * the code stream, expanding the code buffer if necessary. - */ - -/* Sub-macros: */ -#define GEN_NAMESIZE(name) \ - extern const uint8_t JIT_PSP_##name[]; \ - extern const uint32_t JIT_PSPSIZE_##name; -#define GEN_PARAM(name,param) \ - extern const uint32_t JIT_PSPPARAM_##name##_##param; -#define GEN_FUNC_TOP(name) \ - if (UNLIKELY(entry->native_size - entry->native_length \ - < JIT_PSPSIZE_##name)) { \ - if (!expand_buffer(entry)) { \ - return; \ - } \ - } \ - if (JIT_PSPSIZE_##name > 0) { \ - memcpy((uint8_t *)entry->native_code + entry->native_length, \ - JIT_PSP_##name, JIT_PSPSIZE_##name); \ - } -#define GEN_COPY_PARAM(name,type,param) \ - *(type *)((uint8_t *)entry->native_code + entry->native_length \ - + JIT_PSPPARAM_##name##_##param) = param; -#define GEN_FUNC_BOTTOM(name) \ - entry->native_length += JIT_PSPSIZE_##name; - - -#define GEN_EMIT(name) \ - GEN_NAMESIZE(name) \ - static void JIT_EMIT_##name(Q68JitEntry *entry) { \ - GEN_FUNC_TOP(name) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_1(name,type1,param1) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_2(name,type1,param1,type2,param2) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_3(name,type1,param1,type2,param2,type3,param3) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_4(name,type1,param1,type2,param2,type3,param3,type4,param4) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - GEN_PARAM(name,param4) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3, type4 param4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_COPY_PARAM(name, type4, param4) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_5(name,type1,param1,type2,param2,type3,param3,type4,param4,type5,param5) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - GEN_PARAM(name,param4) \ - GEN_PARAM(name,param5) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3, \ - type4 param4, type5 param5) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_COPY_PARAM(name, type4, param4) \ - GEN_COPY_PARAM(name, type5, param5) \ - GEN_FUNC_BOTTOM(name) \ - } - - -/* These versions include a hidden "disp_4" parameter, and pass the value of - * disp_4_formula for that parameter. */ - -#define GEN_EMIT_disp(name,disp_4_formula) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,disp_4) \ - static void __real_JIT_EMIT_##name(Q68JitEntry *entry, int16_t disp_4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, int16_t, disp_4) \ - GEN_FUNC_BOTTOM(name) \ - } \ - static void JIT_EMIT_##name(Q68JitEntry *entry) { \ - __real_JIT_EMIT_##name(entry, (disp_4_formula)); \ - } - -#define GEN_EMIT_1_disp(name,type1,param1,disp_4_formula) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,disp_4) \ - static void __real_JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - int16_t disp_4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, int16_t, disp_4) \ - GEN_FUNC_BOTTOM(name) \ - } \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1) { \ - __real_JIT_EMIT_##name(entry, param1, (disp_4_formula)); \ - } - -#define GEN_EMIT_2_disp(name,type1,param1,type2,param2,disp_4_formula) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,disp_4) \ - static void __real_JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, int16_t disp_4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, int16_t, disp_4) \ - GEN_FUNC_BOTTOM(name) \ - } \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2) { \ - __real_JIT_EMIT_##name(entry, param1, param2, (disp_4_formula)); \ - } - -/*-----------------------------------------------------------------------*/ - -/* Code prologue and epilogue */ -GEN_EMIT(PROLOGUE) -extern const int JIT_PSPOFS_TERMINATE; -extern const int JIT_PSPOFS_EXCEPTION; -extern const int JIT_PSPOFS_ADDRESS_ERROR_EA; -extern const int JIT_PSPOFS_ADDRESS_ERROR_SP; -GEN_EMIT(EPILOGUE) - -#ifdef Q68_TRACE -/* Trace the current instruction */ -GEN_EMIT(TRACE) -#endif - -/* Add the specified number of cycles to the cycle counter */ -GEN_EMIT_1(ADD_CYCLES, int16_t, cycles) - -/* Check the cycle limit and interrupt execution if necessary */ -GEN_EMIT(CHECK_CYCLES) - -/* Add the specified amount to the program counter and/or check whether - * to abort */ -GEN_EMIT_1(ADVANCE_PC, int16_t, value) -GEN_EMIT_1_disp(ADVANCE_PC_CHECK_ABORT, int16_t, value, - (JIT_PSPOFS_TERMINATE - (entry->native_length + 4)) / 4) -GEN_EMIT_disp(CHECK_ABORT, - (JIT_PSPOFS_TERMINATE - (entry->native_length + 4)) / 4) - -/* Exception raising */ -GEN_EMIT_1_disp(EXCEPTION, int16_t, num, - (JIT_PSPOFS_EXCEPTION - (entry->native_length + 4)) / 4) -GEN_EMIT_2_disp(CHECK_ALIGNED_EA, uint16_t, opcode, uint16_t, status, - (JIT_PSPOFS_ADDRESS_ERROR_EA - (entry->native_length + 4)) / 4) -GEN_EMIT_2_disp(CHECK_ALIGNED_SP, uint16_t, opcode, uint16_t, status, - (JIT_PSPOFS_ADDRESS_ERROR_SP - entry->native_length) / 4) -GEN_EMIT_disp(CHECK_SUPER, - (JIT_PSPOFS_EXCEPTION - (entry->native_length + 4)) / 4) - -/*-----------------------------------------------------------------------*/ - -/* Resolve an effective address */ -GEN_EMIT_1(RESOLVE_INDIRECT, int16_t, reg4) -GEN_EMIT_3(RESOLVE_POSTINC, int16_t, reg4, int16_t, size, int16_t, reg4_b) -#define JIT_EMIT_RESOLVE_POSTINC(entry,reg4,size) do { \ - int16_t __reg4 = (reg4); \ - JIT_EMIT_RESOLVE_POSTINC((entry), __reg4, (size), __reg4); \ -} while (0) -GEN_EMIT(RESOLVE_POSTINC_A7_B) -GEN_EMIT_3(RESOLVE_PREDEC, int16_t, reg4, int16_t, nsize, int16_t, reg4_b) -#define JIT_EMIT_RESOLVE_PREDEC(entry,reg4,size) do { \ - int16_t __reg4 = (reg4); \ - JIT_EMIT_RESOLVE_PREDEC((entry), __reg4, -(size), __reg4); \ -} while (0) -GEN_EMIT(RESOLVE_PREDEC_A7_B) -GEN_EMIT_2(RESOLVE_DISP, int16_t, reg4, int16_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_W, int16_t, reg4, int16_t, ireg4, int16_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_L, int16_t, reg4, int16_t, ireg4, int16_t, disp) -GEN_EMIT_2(RESOLVE_ABSOLUTE, uint16_t, addr_hi, uint16_t, addr_lo) -#define JIT_EMIT_RESOLVE_ABSOLUTE(entry,addr) do { \ - uint32_t __addr = (addr); \ - JIT_EMIT_RESOLVE_ABSOLUTE((entry), __addr>>16, __addr & 0xFFFF); \ -} while (0) -GEN_EMIT_3(RESOLVE_ABS_INDEX_W, int16_t, ireg4, uint16_t, addr_hi, - uint16_t, addr_lo) -#define JIT_EMIT_RESOLVE_ABS_INDEX_W(entry,addr,ireg4) do { \ - uint32_t __addr = (addr); \ - JIT_EMIT_RESOLVE_ABS_INDEX_W((entry), (ireg4), __addr>>16, \ - (addr) & 0xFFFF); \ -} while (0) -GEN_EMIT_3(RESOLVE_ABS_INDEX_L, int16_t, ireg4, uint16_t, addr_hi, - uint16_t, addr_lo) -#define JIT_EMIT_RESOLVE_ABS_INDEX_L(entry,addr,ireg4) do { \ - uint32_t __addr = (addr); \ - JIT_EMIT_RESOLVE_ABS_INDEX_L((entry), (ireg4), __addr>>16, \ - __addr & 0xFFFF); \ -} while (0) - -/* Retrieve various things as operand 1 */ -GEN_EMIT_1(GET_OP1_REGISTER, int16_t, reg4) -GEN_EMIT(GET_OP1_EA_B) -GEN_EMIT(GET_OP1_EA_W) -GEN_EMIT(GET_OP1_EA_L) -GEN_EMIT_1(GET_OP1_IMMED_16S, int16_t, value_lo) -GEN_EMIT_1(GET_OP1_IMMED_16U, uint16_t, value_lo) -GEN_EMIT_1(GET_OP1_IMMED_16HI, uint16_t, value_hi) -GEN_EMIT_2(GET_OP1_IMMED_32, uint16_t, value_hi, uint16_t, value_lo) -#define JIT_EMIT_GET_OP1_IMMEDIATE(entry,value) do { \ - Q68JitEntry * const __entry = (entry); \ - const int32_t __value = (value); \ - if (value >= -32768 && value <= 32767) { \ - JIT_EMIT_GET_OP1_IMMED_16S(__entry, __value); \ - } else if (value >= 0 && value <= 65535) { \ - JIT_EMIT_GET_OP1_IMMED_16U(__entry, __value); \ - } else if ((value & 0xFFFF) == 0) { \ - JIT_EMIT_GET_OP1_IMMED_16HI(__entry, __value>>16); \ - } else { \ - JIT_EMIT_GET_OP1_IMMED_32(__entry, __value>>16, __value & 0xFFFF); \ - } \ -} while (0) -GEN_EMIT(GET_OP1_CCR) -GEN_EMIT(GET_OP1_SR) - -/* Retrieve various things as operand 2 */ -GEN_EMIT_1(GET_OP2_REGISTER, int16_t, reg4) -GEN_EMIT(GET_OP2_EA_B) -GEN_EMIT(GET_OP2_EA_W) -GEN_EMIT(GET_OP2_EA_L) -GEN_EMIT_1(GET_OP2_IMMED_16S, int16_t, value_lo) -GEN_EMIT_1(GET_OP2_IMMED_16U, uint16_t, value_lo) -GEN_EMIT_1(GET_OP2_IMMED_16HI, uint16_t, value_hi) -GEN_EMIT_2(GET_OP2_IMMED_32, uint16_t, value_hi, uint16_t, value_lo) -#define JIT_EMIT_GET_OP2_IMMEDIATE(entry,value) do { \ - Q68JitEntry * const __entry = (entry); \ - const int32_t __value = (value); \ - if (value >= -32768 && value <= 32767) { \ - JIT_EMIT_GET_OP2_IMMED_16S(__entry, __value); \ - } else if (value >= 0 && value <= 65535) { \ - JIT_EMIT_GET_OP2_IMMED_16U(__entry, __value); \ - } else if ((value & 0xFFFF) == 0) { \ - JIT_EMIT_GET_OP2_IMMED_16HI(__entry, __value>>16); \ - } else { \ - JIT_EMIT_GET_OP2_IMMED_32(__entry, __value>>16, __value & 0xFFFF); \ - } \ -} while (0) -GEN_EMIT(GET_OP2_CCR) -GEN_EMIT(GET_OP2_SR) - -/* Update various things from result */ -GEN_EMIT_1(SET_REGISTER_B, int16_t, reg4) -GEN_EMIT_1(SET_REGISTER_W, int16_t, reg4) -GEN_EMIT_1(SET_REGISTER_L, int16_t, reg4) -GEN_EMIT_1(SET_AREG_W, int16_t, reg4) -GEN_EMIT(SET_EA_B) -GEN_EMIT(SET_EA_W) -GEN_EMIT(SET_EA_L) -GEN_EMIT(SET_CCR) -GEN_EMIT(SET_SR) - -/* Stack operations */ -GEN_EMIT(PUSH_L) -GEN_EMIT(POP_L) - -/* Condition code setting */ -GEN_EMIT(SETCC_ADD_B) -GEN_EMIT(SETCC_ADD_W) -GEN_EMIT(SETCC_ADD_L) -GEN_EMIT(SETCC_ADDX_B) -GEN_EMIT(SETCC_ADDX_W) -GEN_EMIT(SETCC_ADDX_L) -GEN_EMIT(SETCC_SUB_B) -GEN_EMIT(SETCC_SUB_W) -GEN_EMIT(SETCC_SUB_L) -GEN_EMIT(SETCC_SUBX_B) -GEN_EMIT(SETCC_SUBX_W) -GEN_EMIT(SETCC_SUBX_L) -GEN_EMIT(SETCC_CMP_B) -GEN_EMIT(SETCC_CMP_W) -GEN_EMIT(SETCC_CMP_L) -GEN_EMIT(SETCC_LOGIC_B) -GEN_EMIT(SETCC_LOGIC_W) -GEN_EMIT(SETCC_LOGIC_L) - -/* Condition testing */ -GEN_EMIT(TEST_T) -GEN_EMIT(TEST_F) -GEN_EMIT(TEST_HI) -GEN_EMIT(TEST_LS) -GEN_EMIT(TEST_CC) -GEN_EMIT(TEST_CS) -GEN_EMIT(TEST_NE) -GEN_EMIT(TEST_EQ) -GEN_EMIT(TEST_VC) -GEN_EMIT(TEST_VS) -GEN_EMIT(TEST_PL) -GEN_EMIT(TEST_MI) -GEN_EMIT(TEST_GE) -GEN_EMIT(TEST_LT) -GEN_EMIT(TEST_GT) -GEN_EMIT(TEST_LE) - -/* ALU operations */ -GEN_EMIT(MOVE_B) -GEN_EMIT(MOVE_W) -GEN_EMIT(MOVE_L) -GEN_EMIT(ADD_B) -GEN_EMIT(ADD_W) -GEN_EMIT(ADD_L) -GEN_EMIT(ADDA_W) -GEN_EMIT(ADDX_B) -GEN_EMIT(ADDX_W) -GEN_EMIT(ADDX_L) -GEN_EMIT(SUB_B) -GEN_EMIT(SUB_W) -GEN_EMIT(SUB_L) -GEN_EMIT(SUBA_W) -GEN_EMIT(SUBX_B) -GEN_EMIT(SUBX_W) -GEN_EMIT(SUBX_L) -GEN_EMIT(MULS_W) -GEN_EMIT(MULU_W) -GEN_EMIT(DIVS_W) -GEN_EMIT(DIVU_W) -GEN_EMIT(AND_B) -GEN_EMIT(AND_W) -GEN_EMIT(AND_L) -GEN_EMIT(OR_B) -GEN_EMIT(OR_W) -GEN_EMIT(OR_L) -GEN_EMIT(EOR_B) -GEN_EMIT(EOR_W) -GEN_EMIT(EOR_L) -GEN_EMIT(EXT_W) -GEN_EMIT(EXT_L) -GEN_EMIT(SWAP) - -/* BCD operations */ -GEN_EMIT(ABCD) -GEN_EMIT(SBCD) - -/* Bit-twiddling operations */ -GEN_EMIT(BTST_B) -GEN_EMIT(BTST_L) -GEN_EMIT(BCHG) -GEN_EMIT(BCLR) -GEN_EMIT(BSET) - -/* Shift/rotate operations */ -GEN_EMIT(ASL_B) -GEN_EMIT(ASL_W) -GEN_EMIT(ASL_L) -GEN_EMIT(ASR_B) -GEN_EMIT(ASR_W) -GEN_EMIT(ASR_L) -GEN_EMIT(LSL_B) -GEN_EMIT(LSL_W) -GEN_EMIT(LSL_L) -GEN_EMIT(LSR_B) -GEN_EMIT(LSR_W) -GEN_EMIT(LSR_L) -GEN_EMIT(ROXL_B) -GEN_EMIT(ROXL_W) -GEN_EMIT(ROXL_L) -GEN_EMIT(ROXR_B) -GEN_EMIT(ROXR_W) -GEN_EMIT(ROXR_L) -GEN_EMIT(ROL_B) -GEN_EMIT(ROL_W) -GEN_EMIT(ROL_L) -GEN_EMIT(ROR_B) -GEN_EMIT(ROR_W) -GEN_EMIT(ROR_L) - -/* Conditional and branch operations ("branch_offset" parameter receives - * the native offset of the branch to update when resolving, or -1 if not - * supported) */ -GEN_EMIT(Scc) -GEN_EMIT(ADD_CYCLES_Scc_Dn) -GEN_EMIT_4(DBcc, int16_t, reg4, int16_t, reg4_b, uint16_t, target_hi, - uint16_t, target_lo) -#define JIT_EMIT_DBcc(entry,reg4,target) do { \ - int16_t __reg4 = (reg4); \ - uint32_t __target = (target); \ - JIT_EMIT_DBcc((entry), __reg4, __reg4, __target>>16, __target & 0xFFFF); \ -} while (0) -GEN_EMIT_5(DBcc_native, int16_t, reg4, int16_t, reg4_b, uint16_t, target_hi, - uint16_t, target_lo, int16_t, native_disp_4_4) -#define JIT_EMIT_DBcc_native(entry,reg4,target,offset) do { \ - Q68JitEntry *__entry = (entry); \ - int16_t __reg4 = (reg4); \ - uint32_t __target = (target); \ - int32_t __fragment_end = __entry->native_length + JIT_PSPSIZE_DBcc_native; \ - JIT_EMIT_DBcc_native(__entry, __reg4, __reg4, \ - __target>>16, __target & 0xFFFF, \ - ((offset) - __fragment_end + 4) / 4); \ -} while (0) -GEN_EMIT_3(Bcc_common, uint16_t, target_hi, uint16_t, target_lo, int16_t, disp_4) -static void JIT_EMIT_Bcc(Q68JitEntry *entry, uint32_t target, - int32_t *branch_offset) { - *branch_offset = entry->native_length + JIT_PSPPARAM_Bcc_common_disp_4; - int32_t disp_4 = (JIT_PSPOFS_TERMINATE - (*branch_offset + 4)) / 4; - JIT_EMIT_Bcc_common(entry, target>>16, target & 0xFFFF, disp_4); -} -static void JIT_EMIT_Bcc_native(Q68JitEntry *entry, uint32_t target, - int32_t offset) { - uint32_t branch_offset = - entry->native_length + JIT_PSPPARAM_Bcc_common_disp_4; - int32_t disp_4 = (offset - (branch_offset + 4)) / 4; - /* Displacement is assumed to be within range (+/-128k) */ - JIT_EMIT_Bcc_common(entry, target>>16, target & 0xFFFF, disp_4); -} -GEN_EMIT_4(BSR, uint16_t, return_addr_hi, uint16_t, return_addr_lo, - uint16_t, target_hi, uint16_t, target_lo) -#define JIT_EMIT_BSR(entry,return_addr,target) do { \ - uint32_t __return_addr = (return_addr); \ - uint32_t __target = (target); \ - JIT_EMIT_BSR((entry), __return_addr>>16, __return_addr & 0xFFFF, \ - __target>>16, __target & 0xFFFF); \ -} while (0) -GEN_EMIT(JMP) -GEN_EMIT_2(JSR, uint16_t, return_addr_hi, uint16_t, return_addr_lo) -#define JIT_EMIT_JSR(entry,return_addr) do { \ - uint32_t __return_addr = (return_addr); \ - JIT_EMIT_JSR((entry), __return_addr>>16, __return_addr & 0xFFFF); \ -} while (0) - -/* MOVEM-related operations */ -GEN_EMIT_1(STORE_DEC_W, int16_t, reg4) -GEN_EMIT_1(STORE_DEC_L, int16_t, reg4) -GEN_EMIT_1(STORE_INC_W, int16_t, reg4) -GEN_EMIT_1(STORE_INC_L, int16_t, reg4) -GEN_EMIT_1(LOAD_INC_W, int16_t, reg4) -GEN_EMIT_1(LOAD_INC_L, int16_t, reg4) -GEN_EMIT_1(LOADA_INC_W, int16_t, reg4) -GEN_EMIT_1(MOVEM_WRITEBACK, int16_t, reg4) - -/* Miscellaneous operations */ -GEN_EMIT(CHK_W) -GEN_EMIT_1(LEA, int16_t, reg4) -GEN_EMIT(PEA) -GEN_EMIT(TAS) -GEN_EMIT_1(MOVE_FROM_USP, int16_t, reg4) -GEN_EMIT_1(MOVE_TO_USP, int16_t, reg4) -GEN_EMIT_1(STOP, uint16_t, newSR) -GEN_EMIT(TRAPV) -GEN_EMIT(RTS) -GEN_EMIT(RTR) -GEN_EMIT(RTE) -GEN_EMIT_3(MOVEP_READ_W, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_3(MOVEP_READ_L, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_W, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_L, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_2(EXG, int16_t, reg1_4, int16_t, reg2_4) - -/*************************************************************************/ - -#endif // Q68_JIT_PSP_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit-x86.S b/yabause/src/q68/q68-jit-x86.S deleted file mode 100644 index d6331dbf20..0000000000 --- a/yabause/src/q68/q68-jit-x86.S +++ /dev/null @@ -1,2800 +0,0 @@ -/* src/q68/q68-jit-x86.S: x86 (32/64-bit) dynamic translation implementation - for Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "q68-const.h" - -/*************************************************************************/ - -/* - * Register usage on x86 and x64 is as follows (for x86, read %rXX as %eXX): - * - * %rax -- result, temporary - * %rbx -- Q68State structure pointer - * %rcx -- temporary - * %rdx -- operand 2 - * %rsi -- cumulative cycle count - * %rdi -- operand 1, (on termination) pointer to next address to execute - * - * Additionally, the cycle limit is pushed onto the stack at the start of - * execution. - */ - -/*************************************************************************/ - -/* Define handy macros so we can use the same source on both x86 and x64 */ - -#ifdef CPU_X64 - -/* External routine calling macros (indirect calls only) */ -.macro CALL1 address, arg1 - push %rsi - push %rdi - mov \arg1, %rdi - call \address - pop %rdi - pop %rsi -.endm -.macro CALL2 address, arg1, arg2 - push %rsi - push %rdi - mov \arg1, %rdi - mov \arg2, %rsi - call \address - pop %rdi - pop %rsi -.endm - -/* Label/size/parameter definition macros */ -#define DEFLABEL(name) .globl JIT_X64_##name; JIT_X64_##name: -#define DEFSIZE(name) .globl JIT_X64SIZE_##name; \ - JIT_X64SIZE_##name: .int . - JIT_X64_##name -#define DEFPARAM(name,param,label,offset) \ - .globl JIT_X64PARAM_##name##_##param; \ - JIT_X64PARAM_##name##_##param: \ - .int label - JIT_X64_##name + (offset) - -/* Q68State structure offsets */ -Q68State_D = 0 -Q68State_A = 32 -Q68State_PC = 64 -Q68State_SR = 68 -Q68State_USP = 72 -Q68State_SSP = 76 -Q68State_current_PC = 80 -Q68State_ea_addr = 84 -Q68State_exception = 88 -Q68State_fault_addr = 92 -Q68State_fault_opcode = 96 -Q68State_fault_status = 98 -Q68State_halted = 100 -Q68State_irq = 104 -Q68State_cycles = 108 -Q68State_malloc_func = 112 -Q68State_realloc_func = 120 -Q68State_free_func = 128 -Q68State_readb_func = 136 -Q68State_readw_func = 144 -Q68State_writeb_func = 152 -Q68State_writew_func = 160 -Q68State_jit_flush = 168 -Q68State_jit_running = 176 -Q68State_jit_abort = 184 -Q68State_jit_table = 192 -Q68State_jit_hashchain = 200 -Q68State_jit_total_data = 208 -Q68State_jit_timestamp = 212 -Q68State_jit_blacklist = 216 -Q68State_jit_in_blist = Q68State_jit_blacklist + (12 * Q68_JIT_BLACKLIST_SIZE) -Q68State_jit_blist_num = Q68State_jit_in_blist + 4 -Q68State_jit_callstack_top = Q68State_jit_blist_num + 4 -Q68State_jit_callstack = (Q68State_jit_callstack_top + 7) & ~7 -Q68State_jit_pages = Q68State_jit_callstack + (24 * Q68_JIT_CALLSTACK_SIZE) - -#else // CPU_X86 - -/* Register name translation macros (we don't handle any 64-bit data except - * when protected by #ifdef CPU_X64, so this is safe) */ -#define rax eax -#define rbx ebx -#define rcx ecx -#define rdx edx -#define rsp esp -#define rbp ebp -#define rsi esi -#define rdi edi - -/* External routine calling macros (indirect calls only) */ -.macro CALL1 address, arg1 - push \arg1 - call \address - pop %rcx -.endm -.macro CALL2 address, arg1, arg2 - push \arg2 - push \arg1 - call \address - pop %rcx - pop %rcx -.endm - -/* Label/size/parameter definition macros */ -#define DEFLABEL(name) .globl JIT_X86_##name; JIT_X86_##name: -#define DEFSIZE(name) .globl JIT_X86SIZE_##name; \ - JIT_X86SIZE_##name: .int . - JIT_X86_##name -#define DEFPARAM(name,param,label,offset) \ - .globl JIT_X86PARAM_##name##_##param; \ - JIT_X86PARAM_##name##_##param: \ - .int label - JIT_X86_##name + (offset) - -/* Q68State structure offsets */ -Q68State_D = 0 -Q68State_A = 32 -Q68State_PC = 64 -Q68State_SR = 68 -Q68State_USP = 72 -Q68State_SSP = 76 -Q68State_current_PC = 80 -Q68State_ea_addr = 84 -Q68State_exception = 88 -Q68State_fault_addr = 92 -Q68State_fault_opcode = 96 -Q68State_fault_status = 98 -Q68State_halted = 100 -Q68State_irq = 104 -Q68State_cycles = 108 -Q68State_malloc_func = 112 -Q68State_realloc_func = 116 -Q68State_free_func = 120 -Q68State_readb_func = 124 -Q68State_readw_func = 128 -Q68State_writeb_func = 132 -Q68State_writew_func = 136 -Q68State_jit_flush = 140 -Q68State_jit_running = 144 -Q68State_jit_abort = 148 -Q68State_jit_table = 152 -Q68State_jit_hashchain = 156 -Q68State_jit_total_data = 160 -Q68State_jit_timestamp = 164 -Q68State_jit_blacklist = 168 -Q68State_jit_in_blist = Q68State_jit_blacklist + (12 * Q68_JIT_BLACKLIST_SIZE) -Q68State_jit_blist_num = Q68State_jit_in_blist + 4 -Q68State_jit_callstack_top = Q68State_jit_blist_num + 4 -Q68State_jit_callstack = Q68State_jit_callstack_top + 4 -Q68State_jit_pages = Q68State_jit_callstack + (12 * Q68_JIT_CALLSTACK_SIZE) - -#endif // X64/X86 - -/*************************************************************************/ - -/* Shorthand for referencing Q68State fields */ - -#define D0 Q68State_D+0*4(%rbx) -#define D1 Q68State_D+1*4(%rbx) -#define D2 Q68State_D+2*4(%rbx) -#define D3 Q68State_D+3*4(%rbx) -#define D4 Q68State_D+4*4(%rbx) -#define D5 Q68State_D+5*4(%rbx) -#define D6 Q68State_D+6*4(%rbx) -#define D7 Q68State_D+7*4(%rbx) - -#define A0 Q68State_A+0*4(%rbx) -#define A1 Q68State_A+1*4(%rbx) -#define A2 Q68State_A+2*4(%rbx) -#define A3 Q68State_A+3*4(%rbx) -#define A4 Q68State_A+4*4(%rbx) -#define A5 Q68State_A+5*4(%rbx) -#define A6 Q68State_A+6*4(%rbx) -#define A7 Q68State_A+7*4(%rbx) - -#define PC Q68State_PC(%rbx) -#define SR Q68State_SR(%rbx) -#define USP Q68State_USP(%rbx) -#define SSP Q68State_SSP(%rbx) - -/*************************************************************************/ -/************************** Convenience macros ***************************/ -/*************************************************************************/ - -/** - * READ{8,16,32}: Read a value from memory. The value read is returned - * zero-extended in %eax; the address parameter is destroyed. %rdx may not - * be used as a parameter. - */ -.macro READ8 address - and $0x00FFFFFF, \address - mov Q68State_readb_func(%rbx), %rdx - CALL1 *%rdx, \address - movzx %al, %eax -.endm - -.macro READ16 address - and $0x00FFFFFF, \address - mov Q68State_readw_func(%rbx), %rdx - CALL1 *%rdx, \address - movzx %ax, %eax -.endm - -.macro READ32 address - and $0x00FFFFFF, \address - mov Q68State_readw_func(%rbx), %rdx -#ifdef CPU_X64 - push %rdi - mov \address, %rdi - call *%rdx - push %rax - add $2, %rdi - and $0x00FFFFFF, %rdi - mov Q68State_readw_func(%rbx), %rdx - call *%rdx - pop %rcx - pop %rdi -#else - push \address - call *%rdx - xchg %rax, (%rsp) - addl $2, %rax - push %rax - mov Q68State_readw_func(%rbx), %rdx - call *%rdx - pop %rcx - pop %rcx -#endif - shl $16, %ecx - or %ecx, %eax -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE_CHECK_JIT: Check whether a write of size \nbytes (*bytes*, not - * bits) to \address would clobber a page containing already-translated - * blocks, and clear those translations if so. The value of \address is - * preserved, but all other caller-saved registers are destroyed. - * - * Note that this macro uses local label 4. - */ -.macro WRITE_CHECK_JIT address, nbytes - push \address - mov \address, %rdx - shr $Q68_JIT_PAGE_BITS+3, %rdx - mov \address, %rcx - shr $Q68_JIT_PAGE_BITS, %rcx - and $7, %cl - mov $1, %al - shl %cl, %al - test %al, Q68State_jit_pages(%rbx,%rdx,1) - jz 4f - /* Have to use an indirect call because the offset for the call - * instruction will change based on where this code is copied */ - mov (%rsp), \address -#ifdef CPU_X64 - mov $q68_jit_clear_write, %r8 - mov $\nbytes, %edx - CALL2 *%r8, %rbx, \address -#else - mov $q68_jit_clear_write, %edx - pushl $\nbytes - CALL2 *%edx, %ebx, \address - pop %ecx -#endif -4: pop \address -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE{8,16,32}: Write a value to memory. %rdx may not be used as a - * parameter; the address parameter is destroyed. - */ -.macro WRITE8 address, value - and $0x00FFFFFF, \address - push \value - WRITE_CHECK_JIT \address, 1 - pop \value - mov Q68State_writeb_func(%rbx), %rdx - CALL2 *%rdx, \address, \value -.endm - -.macro WRITE16 address, value - and $0x00FFFFFF, \address - push \value - WRITE_CHECK_JIT \address, 2 - pop \value - mov Q68State_writew_func(%rbx), %rdx - CALL2 *%rdx, \address, \value -.endm - -.macro WRITE32 address, value - push \value - push \address - shr $16, \value - WRITE16 \address, \value - pop \address - pop \value - add $2, \address - WRITE16 \address, \value -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * {PUSH,POP}{16,32}: Push or pop values onto or off of the stack. For - * POP, the value popped is zero-extended and returned in %rax; for PUSH, - * register %rax is destroyed before storing. %rdx may not be used as a - * parameter. - */ -.macro PUSH16 value - mov A7, %eax - sub $2, %eax - mov %eax, A7 - WRITE16 %rax, \value -.endm - -.macro PUSH32 value - mov A7, %eax - sub $4, %eax - mov %eax, A7 - WRITE32 %rax, \value -.endm - -.macro POP16 - mov A7, %eax - add $2, A7 - READ16 %rax -.endm - -.macro POP32 - mov A7, %eax - add $4, A7 - READ32 %rax -.endm - -/*************************************************************************/ - -/** - * LDC_FROM_X: Set the x86 carry flag (CF) based on the value of the - * 68000 extend flag (X). The byte register passed in \temp is destroyed. - */ -.macro LDC_FROM_X temp - mov SR, \temp - shr $5, \temp -.endm - -/*************************************************************************/ - -/** - * SETCC_NZ: Set the N and Z condition codes according to the x86 flag bits. - */ -.macro SETCC_NZ - sets %cl - setz %dl - andb $~(SR_N|SR_Z), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZ00: Set the N and Z condition codes according to the x86 flag - * bits, and clear the V and C condition codes. - */ -.macro SETCC_NZ00 - sets %cl - setz %dl - andb $~(SR_N|SR_Z|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZVC: Set the N, Z, V, and C condition codes according to the x86 - * flag bits. - */ -.macro SETCC_NZVC - sets %cl - setz %dl - seto %ch - setc %dh - andb $~(SR_N|SR_Z|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - shl $SR_V_SHIFT, %ch - //shl $SR_C_SHIFT, %dh // SR_C_SHIFT is zero, so skip the shift - or %ch, %cl - or %dh, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC: Set the N, Z, V, and C condition codes according to the - * x86 flag bits, and sets the X condition code equal to C. - */ -.macro SETCC_XNZVC - sets %cl - setz %dl - seto %ch - setc %dh - andb $~(SR_X|SR_N|SR_Z|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - shl $SR_V_SHIFT, %ch - //shl $SR_C_SHIFT, %dh // SR_C_SHIFT is zero, so skip the shift - or %ch, %cl - or %dh, %dl - shl $(SR_X_SHIFT - SR_C_SHIFT), %dh - or %dh, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNVC_Z: Set the N, V, and C condition codes according to the x86 - * flag bits; clears the Z condition code if the x86 Z flag is clear, and - * sets the X condition code equal to C. - */ -.macro SETCC_XNVC_Z - sets %cl - setnz %dl - seto %ch - setc %dh - andb $~(SR_X|SR_N|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - shl $SR_V_SHIFT, %ch - //shl $SR_C_SHIFT, %dh // SR_C_SHIFT is zero, so skip the shift - or %ch, %cl - or %dh, %cl - shl $(SR_X_SHIFT - SR_C_SHIFT), %dh - or %dh, %cl - or %cl, SR - not %dl - and %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * UPDATE_SR: Set the status register and condition codes according to - * the value in %ax. - * - * Note that this macro uses local labels 0, 1, 2, and 3. - */ -.macro UPDATE_SR value - movzwl %ax, %ecx - xor SR, %eax - mov %ecx, SR - test $SR_S, %eax // Change in S bit? - jz 1f - test $SR_S, %ecx // Which way did it change? - jz 0f - mov A7, %eax // Into supervisor mode - mov %eax, USP - mov SSP, %eax - mov %eax, A7 - jmp 1f -0: mov A7, %eax // Out of supervisor mode - mov %eax, SSP - mov USP, %eax - mov %eax, A7 -1: mov Q68State_irq(%rbx), %al - and $7, %al - cmp $7, %al - je 2f - and $7, %ch - cmp %al, %ch - jae 3f -2: movzx %al, %eax - add $EX_LEVEL_1_INTERRUPT-1, %eax - mov %eax, Q68State_exception(%rbx) - movl $0, Q68State_irq(%rbx) - TERMINATE -3: -.endm - -/*************************************************************************/ - -/** - * SETUP: Perform setup required before executing translated code. - */ -.macro SETUP - push %rsi - xor %esi, %esi -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * TERMINATE: Terminate execution of the current block. The emulator will - * resume execution at the address in state->PC. - */ -.macro TERMINATE - pop %rax - xor %rdi, %rdi - ret -.endm - -/*************************************************************************/ -/**************************** Meta-operations ****************************/ -/*************************************************************************/ - -/** - * PROLOGUE: Any prologue necessary at the beginning of the code stream. - */ -DEFLABEL(PROLOGUE) - SETUP -DEFSIZE(PROLOGUE) - -/*-----------------------------------------------------------------------*/ - -/** - * EPILOGUE: Any epilogue necessary at the end of the code stream. - */ -DEFLABEL(EPILOGUE) - TERMINATE -DEFSIZE(EPILOGUE) - -/*************************************************************************/ - -/** - * TRACE: Trace the current instruction. - */ -DEFLABEL(TRACE) - mov Q68State_cycles(%rbx), %eax - push %rax - add %esi, %eax - mov %eax, Q68State_cycles(%rbx) -#ifdef CPU_X64 - push %rsi - push %rdi -#endif - mov $q68_trace, %rdx - call *%rdx -#ifdef CPU_X64 - pop %rdi - pop %rsi -#endif - pop %rax - mov %eax, Q68State_cycles(%rbx) -DEFSIZE(TRACE) - -/*************************************************************************/ - -/** - * ADD_CYCLES: Add the specified number of clock cycles to the cycle count. - * - * [Parameters] - * cycles: Number of clock cycles to add - */ -DEFLABEL(ADD_CYCLES) - add $0x12345678, %esi -9: -DEFSIZE(ADD_CYCLES) -DEFPARAM(ADD_CYCLES, cycles, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_CYCLES: Check whether the clock cycle limit has been reached, and - * interrupt execution if so. - */ -DEFLABEL(CHECK_CYCLES) - cmp %esi, (%rsp) - ja 4f - pop %rax - call 1f -0: jmp 2f -1: mov (%rsp), %rdi - ret -2: add $3f-0b, %rdi - ret -3: SETUP -4: -DEFSIZE(CHECK_CYCLES) - -/*************************************************************************/ - -/** - * ADVANCE_PC: Add the specified value to the current program counter. - * - * [Parameters] - * value: Amount to add - */ -DEFLABEL(ADVANCE_PC) - addl $0x12345678, PC -9: -DEFSIZE(ADVANCE_PC) -DEFPARAM(ADVANCE_PC, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * ADVANCE_PC_CHECK_ABORT: Add the specified value to the current program - * counter, then check the jit_abort flag and abort if necessary. - * - * [Parameters] - * value: Amount to add - */ -DEFLABEL(ADVANCE_PC_CHECK_ABORT) - addl $0x12345678, PC -9: testb $1, Q68State_jit_abort(%rbx) - jz 0f - TERMINATE -0: -DEFSIZE(ADVANCE_PC_CHECK_ABORT) -DEFPARAM(ADVANCE_PC_CHECK_ABORT, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ABORT: Check the jit_abort flag and abort if necessary. - */ -DEFLABEL(CHECK_ABORT) - testb $1, Q68State_jit_abort(%rbx) - jz 0f - TERMINATE -0: -DEFSIZE(CHECK_ABORT) - -/*************************************************************************/ - -/** - * EXCEPTION: Raise the specified exception. - * - * [Parameters] - * num: Exception number - */ -DEFLABEL(EXCEPTION) - movl $0x12345678, Q68State_exception(%rbx) -9: TERMINATE -DEFSIZE(EXCEPTION) -DEFPARAM(EXCEPTION, num, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_EA: Check whether the previously resolved effective - * address is word-aligned (bit 0 is clear), and raise an address error - * exception if not. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - */ -DEFLABEL(CHECK_ALIGNED_EA) - testl $1, Q68State_ea_addr(%rbx) - jz 0f - movl $EX_ADDRESS_ERROR, Q68State_exception(%rbx) - mov Q68State_ea_addr(%rbx), %eax - mov %eax, Q68State_fault_addr(%rbx) - movw $0x1234, Q68State_fault_opcode(%rbx) -8: movw $0x1234, Q68State_fault_status(%rbx) -9: TERMINATE -0: -DEFSIZE(CHECK_ALIGNED_EA) -DEFPARAM(CHECK_ALIGNED_EA, opcode, 8b, -2) -DEFPARAM(CHECK_ALIGNED_EA, status, 9b, -2) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_SP: Check whether the current stack pointer (register A7) - * is word-aligned (bit 0 is clear), and raise an address error exception - * if not. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - */ -DEFLABEL(CHECK_ALIGNED_SP) - testl $1, A7 - jz 0f - movl $EX_ADDRESS_ERROR, Q68State_exception(%rbx) - mov A7, %eax - mov %eax, Q68State_fault_addr(%rbx) - movw $0x1234, Q68State_fault_opcode(%rbx) -8: movw $0x1234, Q68State_fault_status(%rbx) -9: TERMINATE -0: -DEFSIZE(CHECK_ALIGNED_SP) -DEFPARAM(CHECK_ALIGNED_SP, opcode, 8b, -2) -DEFPARAM(CHECK_ALIGNED_SP, status, 9b, -2) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_SUPER: Check whether the processor is in supervisor mode, and - * raise a privilege violation exception if not. - */ -DEFLABEL(CHECK_SUPER) - testl $SR_S, SR - jnz 0f - movl $EX_PRIVILEGE_VIOLATION, Q68State_exception(%rbx) - TERMINATE -0: -DEFSIZE(CHECK_SUPER) - -/*************************************************************************/ -/********************* Effective address resolution **********************/ -/*************************************************************************/ - -/** - * RESOLVE_INDIRECT: Resolve an address register indirect reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - */ -DEFLABEL(RESOLVE_INDIRECT) - mov 1(%rbx), %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_INDIRECT) -DEFPARAM(RESOLVE_INDIRECT, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_POSTINC: Resolve an address register postincrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * size: Size in bytes of the reference - */ -DEFLABEL(RESOLVE_POSTINC) - lea 1(%rbx), %rcx -8: mov (%rcx), %eax - add $1, (%rcx) -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_POSTINC) -DEFPARAM(RESOLVE_POSTINC, reg4, 8b, -1) -DEFPARAM(RESOLVE_POSTINC, size, 9b, -1) - -/* For byte-sized (A7)+, make sure A7 stays even */ -DEFLABEL(RESOLVE_POSTINC_A7_B) - mov A7, %ecx - lea 1(%ecx), %eax - add $2, A7 - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_POSTINC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_PREDEC: Resolve an address register predecrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * size: Size in bytes of the reference - */ -DEFLABEL(RESOLVE_PREDEC) - lea 1(%rbx), %rcx -8: sub $1, (%rcx) -9: mov (%rcx), %eax - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_PREDEC) -DEFPARAM(RESOLVE_PREDEC, reg4, 8b, -1) -DEFPARAM(RESOLVE_PREDEC, size, 9b, -1) - -/* For byte-sized -(A7), make sure A7 stays even */ -DEFLABEL(RESOLVE_PREDEC_A7_B) - mov A7, %ecx - lea -1(%ecx), %eax - sub $2, A7 - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_PREDEC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_DISP: Resolve an address register indirect with displacement - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * disp: Displacement - */ -DEFLABEL(RESOLVE_DISP) - mov 1(%rbx), %eax -8: add $0x12345678, %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_DISP) -DEFPARAM(RESOLVE_DISP, reg4, 8b, -1) -DEFPARAM(RESOLVE_DISP, disp, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_INDEX_[WL]: Resolve an address register indirect with index - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * ireg4: Index register number * 4 - * disp: Displacement - */ -DEFLABEL(RESOLVE_INDEX_W) - mov 1(%rbx), %eax -7: mov 1(%rbx), %ecx -8: movsx %cx, %ecx - lea 1(%eax, %ecx), %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_INDEX_W) -DEFPARAM(RESOLVE_INDEX_W, reg4, 7b, -1) -DEFPARAM(RESOLVE_INDEX_W, ireg4, 8b, -1) -DEFPARAM(RESOLVE_INDEX_W, disp, 9b, -1) - -DEFLABEL(RESOLVE_INDEX_L) - mov 1(%rbx), %eax -7: mov 1(%rbx), %ecx -8: lea 1(%eax, %ecx), %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_INDEX_L) -DEFPARAM(RESOLVE_INDEX_L, reg4, 7b, -1) -DEFPARAM(RESOLVE_INDEX_L, ireg4, 8b, -1) -DEFPARAM(RESOLVE_INDEX_L, disp, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABSOLUTE: Resolve an absolute short, absolute long, or - * PC-relative reference. - * - * [Parameters] - * addr: Absolute address - */ -DEFLABEL(RESOLVE_ABSOLUTE) - mov $0x12345678, %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_ABSOLUTE) -DEFPARAM(RESOLVE_ABSOLUTE, addr, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABS_INDEX_[WL]: Resolve a PC-relative with index reference. - * - * [Parameters] - * addr: Absolute address - * ireg4: Index register number * 4 - */ -DEFLABEL(RESOLVE_ABS_INDEX_W) - mov $0x12345678, %eax -8: movswl 1(%rbx), %ecx -9: add %ecx, %eax - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_ABS_INDEX_W) -DEFPARAM(RESOLVE_ABS_INDEX_W, addr, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_W, ireg4, 9b, -1) - -DEFLABEL(RESOLVE_ABS_INDEX_L) - mov $0x12345678, %eax -8: add 1(%rbx), %ecx -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_ABS_INDEX_L) -DEFPARAM(RESOLVE_ABS_INDEX_L, addr, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_L, ireg4, 9b, -1) - -/*************************************************************************/ -/*************************** Operand retrieval ***************************/ -/*************************************************************************/ - -/** - * GET_OP1_REGISTER: Get the current value of the given register as - * operand 1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(GET_OP1_REGISTER) - mov 1(%rbx), %edi -9: -DEFSIZE(GET_OP1_REGISTER) -DEFPARAM(GET_OP1_REGISTER, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_EA_[BWL]: Get the value pointed to by the previously resolved - * effective address as operand 1. - */ -DEFLABEL(GET_OP1_EA_B) - mov Q68State_ea_addr(%rbx), %eax - READ8 %rax - movzx %al, %edi -DEFSIZE(GET_OP1_EA_B) - -DEFLABEL(GET_OP1_EA_W) - mov Q68State_ea_addr(%rbx), %eax - READ16 %rax - movzx %ax, %edi -DEFSIZE(GET_OP1_EA_W) - -DEFLABEL(GET_OP1_EA_L) - mov Q68State_ea_addr(%rbx), %eax - READ32 %rax - mov %eax, %edi -DEFSIZE(GET_OP1_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_IMMEDIATE: Get an immediate value as operand 1. - * - * [Parameters] - * value: Immediate value - */ -DEFLABEL(GET_OP1_IMMEDIATE) - mov $0x12345678, %edi -9: -DEFSIZE(GET_OP1_IMMEDIATE) -DEFPARAM(GET_OP1_IMMEDIATE, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_CCR: Get the current value of CCR as operand 1. - */ -DEFLABEL(GET_OP1_CCR) - movzbl SR, %edi -DEFSIZE(GET_OP1_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_SR: Get the current value of SR as operand 1. - */ -DEFLABEL(GET_OP1_SR) - mov SR, %edi -DEFSIZE(GET_OP1_SR) - -/*************************************************************************/ - -/** - * GET_OP2_*: Get the same things as above as operand 2. - */ -DEFLABEL(GET_OP2_REGISTER) - mov 1(%rbx), %edx -9: -DEFSIZE(GET_OP2_REGISTER) -DEFPARAM(GET_OP2_REGISTER, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_EA_B) - mov Q68State_ea_addr(%rbx), %eax - READ8 %rax - movzx %al, %edx -DEFSIZE(GET_OP2_EA_B) - -DEFLABEL(GET_OP2_EA_W) - mov Q68State_ea_addr(%rbx), %eax - READ16 %rax - movzx %ax, %edx -DEFSIZE(GET_OP2_EA_W) - -DEFLABEL(GET_OP2_EA_L) - mov Q68State_ea_addr(%rbx), %eax - READ32 %rax - mov %eax, %edx -DEFSIZE(GET_OP2_EA_L) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_IMMEDIATE) - mov $0x12345678, %edx -9: -DEFSIZE(GET_OP2_IMMEDIATE) -DEFPARAM(GET_OP2_IMMEDIATE, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_CCR) - movzbl SR, %edx -DEFSIZE(GET_OP2_CCR) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_SR) - mov SR, %edx -DEFSIZE(GET_OP2_SR) - -/*************************************************************************/ -/**************************** Result storing *****************************/ -/*************************************************************************/ - -/** - * SET_REGISTER_[BWL]: Set the value of the given register to the result - * value. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(SET_REGISTER_B) - mov %al, 1(%rbx) -9: -DEFSIZE(SET_REGISTER_B) -DEFPARAM(SET_REGISTER_B, reg4, 9b, -1) - -DEFLABEL(SET_REGISTER_W) - mov %ax, 1(%rbx) -9: -DEFSIZE(SET_REGISTER_W) -DEFPARAM(SET_REGISTER_W, reg4, 9b, -1) - -DEFLABEL(SET_REGISTER_L) - mov %eax, 1(%rbx) -9: -DEFSIZE(SET_REGISTER_L) -DEFPARAM(SET_REGISTER_L, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_AREG_W: Set the value of the given address register to the - * sign-extended result value. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(SET_AREG_W) - cwde - mov %eax, 1(%rbx) -9: -DEFSIZE(SET_AREG_W) -DEFPARAM(SET_AREG_W, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_EA_[BWL]: Set the value pointed to by the previously resolved - * effective address to the result value. - */ -DEFLABEL(SET_EA_B) - mov Q68State_ea_addr(%rbx), %ecx - WRITE8 %rcx, %rax -DEFSIZE(SET_EA_B) - -DEFLABEL(SET_EA_W) - mov Q68State_ea_addr(%rbx), %ecx - WRITE16 %rcx, %rax -DEFSIZE(SET_EA_W) - -DEFLABEL(SET_EA_L) - mov Q68State_ea_addr(%rbx), %ecx - WRITE32 %rcx, %rax -DEFSIZE(SET_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_CCR: Set the condition codes from the result value. - */ -DEFLABEL(SET_CCR) - mov %al, SR // Update low byte only -DEFSIZE(SET_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_SR: Set the status register from the result value. - */ -DEFLABEL(SET_SR) - UPDATE_SR -DEFSIZE(SET_SR) - -/*************************************************************************/ -/*************************** Stack operations ****************************/ -/*************************************************************************/ - -/** - * PUSH_L: Push the 32-bit value of operand 1 onto the stack. - */ -DEFLABEL(PUSH_L) - PUSH32 %rdi -DEFSIZE(PUSH_L) - -/*-----------------------------------------------------------------------*/ - -/** - * POP_L: Pop a 32-bit value off the stack into the result register. - */ -DEFLABEL(POP_L) - POP32 -DEFSIZE(POP_L) - -/*************************************************************************/ -/************************ Condition code setting *************************/ -/*************************************************************************/ - -/** - * SETCC_ADD_[BWL]: Set the condition codes for the result of an ADD - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADD_B) - SETCC_XNZVC -DEFSIZE(SETCC_ADD_B) - -DEFLABEL(SETCC_ADD_W) - SETCC_XNZVC -DEFSIZE(SETCC_ADD_W) - -DEFLABEL(SETCC_ADD_L) - SETCC_XNZVC -DEFSIZE(SETCC_ADD_L) - -/*************************************************************************/ - -/** - * SETCC_ADDX_[BWL]: Set the condition codes for the result of an ADDX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADDX_B) - SETCC_XNVC_Z -DEFSIZE(SETCC_ADDX_B) - -DEFLABEL(SETCC_ADDX_W) - SETCC_XNVC_Z -DEFSIZE(SETCC_ADDX_W) - -DEFLABEL(SETCC_ADDX_L) - SETCC_XNVC_Z -DEFSIZE(SETCC_ADDX_L) - -/*************************************************************************/ - -/** - * SETCC_SUB_[BWL]: Set the condition codes for the result of a SUB - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUB_B) - SETCC_XNZVC -DEFSIZE(SETCC_SUB_B) - -DEFLABEL(SETCC_SUB_W) - SETCC_XNZVC -DEFSIZE(SETCC_SUB_W) - -DEFLABEL(SETCC_SUB_L) - SETCC_XNZVC -DEFSIZE(SETCC_SUB_L) - -/*************************************************************************/ - -/** - * SETCC_SUBX_[BWL]: Set the condition codes for the result of a SUBX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUBX_B) - SETCC_XNVC_Z -DEFSIZE(SETCC_SUBX_B) - -DEFLABEL(SETCC_SUBX_W) - SETCC_XNVC_Z -DEFSIZE(SETCC_SUBX_W) - -DEFLABEL(SETCC_SUBX_L) - SETCC_XNVC_Z -DEFSIZE(SETCC_SUBX_L) - -/*************************************************************************/ - -/** - * SETCC_CMP_[BWL]: Set the condition codes for the result of a CMP - * instruction stored in the result register. The X flag is unmodified. - */ -DEFLABEL(SETCC_CMP_B) - SETCC_NZVC -DEFSIZE(SETCC_CMP_B) - -DEFLABEL(SETCC_CMP_W) - SETCC_NZVC -DEFSIZE(SETCC_CMP_W) - -DEFLABEL(SETCC_CMP_L) - SETCC_NZVC -DEFSIZE(SETCC_CMP_L) - -/*************************************************************************/ - -/** - * SETCC_LOGIC_[BWL]: Set the condition codes for the result of a logical - * instruction (MOVE, AND, OR, EOR) stored in the result register. The X - * flag is unmodified. - */ -DEFLABEL(SETCC_LOGIC_B) - SETCC_NZ00 -DEFSIZE(SETCC_LOGIC_B) - -DEFLABEL(SETCC_LOGIC_W) - SETCC_NZ00 -DEFSIZE(SETCC_LOGIC_W) - -DEFLABEL(SETCC_LOGIC_L) - SETCC_NZ00 -DEFSIZE(SETCC_LOGIC_L) - -/*************************************************************************/ -/*************************** Condition testing ***************************/ -/*************************************************************************/ - -/** - * TEST_*: Check whether a condition is true (based on the current - * condition codes) and set %al based on the result (nonzero = true). - */ - -DEFLABEL(TEST_T) - mov $1, %al -DEFSIZE(TEST_T) - -DEFLABEL(TEST_F) - mov $0, %al -DEFSIZE(TEST_F) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_HI) - mov SR, %al - mov %al, %cl - shr $SR_Z_SHIFT, %cl - or %cl, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_HI) - -DEFLABEL(TEST_LS) - mov SR, %al - mov %al, %cl - shr $SR_Z_SHIFT, %cl - or %cl, %al - and $1, %al -DEFSIZE(TEST_LS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_CC) - mov SR, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_CC) - -DEFLABEL(TEST_CS) - mov SR, %al - and $1, %al -DEFSIZE(TEST_CS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_NE) - mov SR, %al - shr $SR_Z_SHIFT, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_NE) - -DEFLABEL(TEST_EQ) - mov SR, %al - shr $SR_Z_SHIFT, %al - and $1, %al -DEFSIZE(TEST_EQ) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_VC) - mov SR, %al - shr $SR_V_SHIFT, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_VC) - -DEFLABEL(TEST_VS) - mov SR, %al - shr $SR_V_SHIFT, %al - and $1, %al -DEFSIZE(TEST_VS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_PL) - mov SR, %al - shr $SR_N_SHIFT, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_PL) - -DEFLABEL(TEST_MI) - mov SR, %al - shr $SR_N_SHIFT, %al - and $1, %al -DEFSIZE(TEST_MI) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GE) - mov SR, %al - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %cl, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_GE) - -DEFLABEL(TEST_LT) - mov SR, %al - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %cl, %al - and $1, %al -DEFSIZE(TEST_LT) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GT) - mov SR, %al - push %rax - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %al, %cl - pop %rax - shr $SR_Z_SHIFT, %al - or %cl, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_GT) - -DEFLABEL(TEST_LE) - mov SR, %al - push %rax - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %al, %cl - pop %rax - shr $SR_Z_SHIFT, %al - or %cl, %al - and $1, %al -DEFSIZE(TEST_LE) - -/*************************************************************************/ -/**************************** ALU operations *****************************/ -/*************************************************************************/ - -/** - * MOVE_[BWL]: Evaluate op1, setting the result value for the MOVE - * instruction. - */ -DEFLABEL(MOVE_B) - mov %edi, %eax - test %al, %al -DEFSIZE(MOVE_B) - -DEFLABEL(MOVE_W) - mov %edi, %eax - test %ax, %ax -DEFSIZE(MOVE_W) - -DEFLABEL(MOVE_L) - mov %edi, %eax - test %eax, %eax -DEFSIZE(MOVE_L) - -/*************************************************************************/ - -/** - * ADD_[BWL]: Evaluate op2 + op1. - */ -DEFLABEL(ADD_B) - mov %edi, %eax - add %dl, %al -DEFSIZE(ADD_B) - -DEFLABEL(ADD_W) - mov %edi, %eax - add %dx, %ax -DEFSIZE(ADD_W) - -DEFLABEL(ADD_L) - mov %edi, %eax - add %edx, %eax -DEFSIZE(ADD_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDA_W: Sign-extend op1 to 32 bits, then evaluate op2 + op1. - */ -DEFLABEL(ADDA_W) - movsx %di, %edi - mov %edi, %eax - add %edx, %eax -DEFSIZE(ADDA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDX_[BWL]: Evaluate op2 + op1 + X. - */ -DEFLABEL(ADDX_B) - LDC_FROM_X %al - mov %edi, %eax - adc %dl, %al -DEFSIZE(ADDX_B) - -DEFLABEL(ADDX_W) - LDC_FROM_X %al - mov %edi, %eax - adc %dx, %ax -DEFSIZE(ADDX_W) - -DEFLABEL(ADDX_L) - LDC_FROM_X %al - mov %edi, %eax - adc %edx, %eax -DEFSIZE(ADDX_L) - -/*************************************************************************/ - -/** - * SUB_[BWL]: Evaluate op2 - op1. - */ -DEFLABEL(SUB_B) - mov %edi, %eax - xchg %edx, %eax - sub %dl, %al -DEFSIZE(SUB_B) - -DEFLABEL(SUB_W) - mov %edi, %eax - xchg %edx, %eax - sub %dx, %ax -DEFSIZE(SUB_W) - -DEFLABEL(SUB_L) - mov %edi, %eax - xchg %edx, %eax - sub %edx, %eax -DEFSIZE(SUB_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBA_W: Sign-extend op1 to 32 bits, then evaluate op2 - op1. - */ -DEFLABEL(SUBA_W) - movsx %di, %edi - mov %edi, %eax - xchg %edx, %eax - sub %edx, %eax -DEFSIZE(SUBA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBX_[BWL]: Evaluate op2 - op1 - X. - */ -DEFLABEL(SUBX_B) - LDC_FROM_X %al - mov %edi, %eax - xchg %edx, %eax - sbb %dl, %al -DEFSIZE(SUBX_B) - -DEFLABEL(SUBX_W) - LDC_FROM_X %al - mov %edi, %eax - xchg %edx, %eax - sbb %dx, %ax -DEFSIZE(SUBX_W) - -DEFLABEL(SUBX_L) - LDC_FROM_X %al - mov %edi, %eax - xchg %edx, %eax - sbb %edx, %eax -DEFSIZE(SUBX_L) - -/*************************************************************************/ - -/** - * MUL[SU]_W: Evaluate op2 * op1 in signed or unsigned context. - */ -DEFLABEL(MULS_W) - movsx %di, %eax - movsx %dx, %edx - imul %edx - test %eax, %eax -DEFSIZE(MULS_W) - -DEFLABEL(MULU_W) - movzx %di, %eax - movzx %dx, %edx - mul %edx - test %eax, %eax -DEFSIZE(MULU_W) - -/*************************************************************************/ - -/** - * DIV[SU]_W: Evaluate op2 / op1 in signed or unsigned context, setting - * the condition codes appropriately. The quotient is stored in the low - * 16 bits, the remainder in the high 16 bits of the result value. On - * overflow, op2 is copied to the result. - */ -DEFLABEL(DIVS_W) - andb $~SR_C, SR - test %di, %di - jnz 0f - movl $EX_DIVIDE_BY_ZERO, Q68State_exception(%rbx) - TERMINATE -0: push %rdx // Save op2 (register value) so we can restore it as the - // result on overflow - mov %edx, %eax - cdq - movsx %di, %edi - idiv %edi - lea 0x8000(%eax), %ecx - test $0xFFFF0000, %ecx - jz 1f - pop %rax - orb $SR_V, SR - jmp 2f -1: pop %rcx - shl $16, %edx - or %edx, %eax - test %ax, %ax - SETCC_NZ - andb $~SR_V, SR -2: -DEFSIZE(DIVS_W) - -DEFLABEL(DIVU_W) - andb $~SR_C, SR - test %di, %di - jnz 0f - movl $EX_DIVIDE_BY_ZERO, Q68State_exception(%rbx) - TERMINATE -0: push %rdx // Save op2 (register value) so we can restore it as the - // result on overflow - mov %edx, %eax - xor %edx, %edx - movsx %di, %edi - div %edi - test $0xFFFF0000, %eax - jz 1f - pop %rax - orb $SR_V, SR - jmp 2f -1: pop %rcx - shl $16, %edx - or %edx, %eax - test %ax, %ax - SETCC_NZ - andb $~SR_V, SR -2: -DEFSIZE(DIVU_W) - -/*************************************************************************/ - -/** - * AND_[BWL]: Evaluate op2 & op1. - */ -DEFLABEL(AND_B) - mov %edi, %eax - and %dl, %al -DEFSIZE(AND_B) - -DEFLABEL(AND_W) - mov %edi, %eax - and %dx, %ax -DEFSIZE(AND_W) - -DEFLABEL(AND_L) - mov %edi, %eax - and %edx, %eax -DEFSIZE(AND_L) - -/*************************************************************************/ - -/** - * OR_[BWL]: Evaluate op2 | op1. - */ -DEFLABEL(OR_B) - mov %edi, %eax - or %dl, %al -DEFSIZE(OR_B) - -DEFLABEL(OR_W) - mov %edi, %eax - or %dx, %ax -DEFSIZE(OR_W) - -DEFLABEL(OR_L) - mov %edi, %eax - or %edx, %eax -DEFSIZE(OR_L) - -/*************************************************************************/ - -/** - * EOR_[BWL]: Evaluate op2 ^ op1. - */ -DEFLABEL(EOR_B) - mov %edi, %eax - xor %dl, %al -DEFSIZE(EOR_B) - -DEFLABEL(EOR_W) - mov %edi, %eax - xor %dx, %ax -DEFSIZE(EOR_W) - -DEFLABEL(EOR_L) - mov %edi, %eax - xor %edx, %eax -DEFSIZE(EOR_L) - -/*************************************************************************/ - -/** - * EXT_[WL]: Sign-extend op1 from 8 to 16 or from 16 to 32 bits. - */ -DEFLABEL(EXT_W) - mov %edi, %eax - movsx %al, %ax - test %ax, %ax -DEFSIZE(EXT_W) - -DEFLABEL(EXT_L) - movsx %di, %eax - test %eax, %eax -DEFSIZE(EXT_L) - -/*************************************************************************/ - -/** - * SWAP: Swap the upper and lower 16-bit halves of op1, placing the result - * in the result register. - */ -DEFLABEL(SWAP) - mov %edi, %eax - rol $16, %eax - test %eax, %eax -DEFSIZE(SWAP) - -/*************************************************************************/ -/**************************** BCD operations *****************************/ -/*************************************************************************/ - -/** - * ABCD: Evaluate op2 + op1 + X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(ABCD) - mov %edi, %ecx - mov %edx, %eax - and $0x0F, %ecx - and $0x0F, %eax - add %ecx, %eax - mov SR, %ecx - shr $SR_X_SHIFT, %ecx - and $1, %ecx - add %ecx, %eax - cmp $10, %eax - jb 0f - add $6, %eax -0: and $0xF0, %edi - and $0xF0, %edx - add %edi, %edx - add %edx, %eax - xor %ecx, %ecx - cmp $10<<4, %eax - jb 1f - sub $10<<4, %eax - mov $1, %cl -1: mov %cl, %dl - //shl $SR_C_SHIFT, %cl // Shift count is 0, so omitted - shl $SR_X_SHIFT, %dl - or %cl, %dl - andb $~(SR_X|SR_C), SR - or %dl, SR - test %al, %al - setnz %cl - shl $SR_Z_SHIFT, %cl - not %cl - and %cl, SR -DEFSIZE(ABCD) - -/*************************************************************************/ - -/** - * SBCD: Evaluate op2 - op1 - X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(SBCD) - mov %edi, %ecx - mov %edx, %eax - and $0x0F, %ecx - and $0x0F, %eax - sub %ecx, %eax - mov SR, %ecx - shr $SR_X_SHIFT, %ecx - and $1, %ecx - sub %ecx, %eax - xor %ecx, %ecx - test %eax, %eax - jns 0f - add $10, %eax - add $16, %ecx -0: and $0xF0, %edi - and $0xF0, %edx - sub %ecx, %edx - xor %ecx, %ecx - sub %edi, %edx - jns 1f - add $10<<4, %eax - mov $1, %cl -1: add %edx, %eax - jns 2f - mov $1, %cl -2: mov %cl, %dl - //shl $SR_C_SHIFT, %cl // Shift count is 0, so omitted - shl $SR_X_SHIFT, %dl - or %cl, %dl - andb $~(SR_X|SR_C), SR - or %dl, SR - test %al, %al - setnz %cl - shl $SR_Z_SHIFT, %cl - not %cl - and %cl, SR -DEFSIZE(SBCD) - -/*************************************************************************/ -/*********************** Bit-twiddling operations ************************/ -/*************************************************************************/ - -/** - * BTST_[BL]: Evaluate op2 & (1 << op1). The value (1 << op1), where the - * high bits of op1 have been masked to zero, is left in %edi for use by a - * subsequent BCHG/BCLR/BSET operation. - */ -DEFLABEL(BTST_B) - mov %edi, %ecx - and $7, %ecx - mov $1, %edi - shl %cl, %edi - test %edi, %edx - setz %cl - shl $SR_Z_SHIFT, %cl - and $~SR_Z, SR - or %cl, SR -DEFSIZE(BTST_B) - -DEFLABEL(BTST_L) - mov %edi, %ecx - and $31, %ecx - mov $1, %edi - shl %cl, %edi - test %edi, %edx - setz %cl - shl $SR_Z_SHIFT, %cl - and $~SR_Z, SR - or %cl, SR -DEFSIZE(BTST_L) - -/*************************************************************************/ - -/** - * BCHG: Evaluate op2 ^ (1 << op1), where (1 << op1) has already been - * stored in %edi. - */ -DEFLABEL(BCHG) - mov %edx, %eax - xor %edi, %eax -DEFSIZE(BCHG) - -/*-----------------------------------------------------------------------*/ - -/** - * BCLR: Evaluate op2 & ~(1 << op1), where (1 << op1) has already been - * stored in %edi. - */ -DEFLABEL(BCLR) - mov %edx, %eax - not %edi - and %edi, %eax -DEFSIZE(BCLR) - -/*-----------------------------------------------------------------------*/ - -/** - * BSET: Evaluate op2 | (1 << op1), where (1 << op1) has already been - * stored in %edi. - */ -DEFLABEL(BSET) - mov %edx, %eax - or %edi, %eax -DEFSIZE(BSET) - -/*************************************************************************/ -/************************ Shift/rotate operations ************************/ -/*************************************************************************/ - -/** - * SETCC_XC_SHIFT: Set the X and C flags for a shift or rotate instruction. - * The value to set (0 or 1) is passed in %dl; %dh is destroyed. Assumes - * that the X and C flags have already been cleared. - */ -.macro SETCC_XC_SHIFT - mov %dl, %dh - shl $SR_X_SHIFT, %dh - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dh, %dl - or %dl, SR -.endm - -/*************************************************************************/ - -/** - * ASL_[BWL]: Evaluate (signed) op2 << op1. - */ -.macro DEF_ASL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 1f - andb $~SR_X, SR - // Have to shift bit by bit to detect overflow -0: sal $1, \reg - setc %dl - seto %dh - shl $SR_V_SHIFT, %dh - or %dh, SR - loop 0b - SETCC_XC_SHIFT -1: test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ASL_B) - DEF_ASL 8, %al -DEFSIZE(ASL_B) - -DEFLABEL(ASL_W) - DEF_ASL 16, %ax -DEFSIZE(ASL_W) - -DEFLABEL(ASL_L) - DEF_ASL 32, %eax -DEFSIZE(ASL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ASR_[BWL]: Evaluate (signed) op2 >> op1. - */ -.macro DEF_ASR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 4f - andb $~SR_X, SR - cmp $\nbits, %ecx - jb 2f -1: // count >= nbits - sar $\nbits-1, \reg - mov %al, %dl - and $1, %dl - jmp 3f -2: // 0 < count < nbits - sar %cl, \reg - setc %dl -3: // count != 0 - SETCC_XC_SHIFT -4: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ASR_B) - DEF_ASR 8, %al -DEFSIZE(ASR_B) - -DEFLABEL(ASR_W) - DEF_ASR 16, %ax -DEFSIZE(ASR_W) - -DEFLABEL(ASR_L) - DEF_ASR 32, %eax -DEFSIZE(ASR_L) - -/*************************************************************************/ - -/** - * LSL_[BWL]: Evaluate (unsigned) op2 << op1. - */ -.macro DEF_LSL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 4f - andb $~SR_X, SR - cmp $\nbits, %ecx - jb 2f - ja 1f -0: // count == nbits - and $1, %al - mov %al, %dl - xor \reg, \reg - jmp 3f -1: // count > nbits - xor \reg, \reg - jmp 4f -2: // 0 < count < nbits - sal %cl, \reg - setc %dl -3: // 0 < count <= nbits - SETCC_XC_SHIFT -4: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(LSL_B) - DEF_LSL 8, %al -DEFSIZE(LSL_B) - -DEFLABEL(LSL_W) - DEF_LSL 16, %ax -DEFSIZE(LSL_W) - -DEFLABEL(LSL_L) - DEF_LSL 32, %eax -DEFSIZE(LSL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * LSR_[BWL]: Evaluate (unsigned) op2 >> op1. - */ -.macro DEF_LSR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 4f - andb $~SR_X, SR - cmp $\nbits, %ecx - jb 2f - ja 1f -0: // count == nbits - shl $1, \reg - setc %dl - xor \reg, \reg - jmp 3f -1: // count > nbits - xor \reg, \reg - jmp 4f -2: // 0 < count < nbits - shr %cl, \reg - setc %dl -3: // 0 < count <= nbits - SETCC_XC_SHIFT -4: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(LSR_B) - DEF_LSR 8, %al -DEFSIZE(LSR_B) - -DEFLABEL(LSR_W) - DEF_LSR 16, %ax -DEFSIZE(LSR_W) - -DEFLABEL(LSR_L) - DEF_LSR 32, %eax -DEFSIZE(LSR_L) - -/*************************************************************************/ - -/** - * ROXL_[BWL]: Evaluate op2 ROXL op1. - */ -.macro DEF_ROXL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jnz 0f - mov SR, %dl - shr $SR_X_SHIFT, %dl - and $1, %dl - jmp 2f -0: LDC_FROM_X %dl -1: rcl \reg - loop 1b - setc %dl - andb $~SR_X, SR -2: SETCC_XC_SHIFT - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROXL_B) - DEF_ROXL 8, %al -DEFSIZE(ROXL_B) - -DEFLABEL(ROXL_W) - DEF_ROXL 16, %ax -DEFSIZE(ROXL_W) - -DEFLABEL(ROXL_L) - DEF_ROXL 32, %eax -DEFSIZE(ROXL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROXR_[BWL]: Evaluate op2 ROXR op1. - */ -.macro DEF_ROXR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jnz 0f - mov SR, %dl - shr $SR_X_SHIFT, %dl - and $1, %dl - jmp 2f -0: LDC_FROM_X %dl -1: rcr \reg - loop 1b - setc %dl - andb $~SR_X, SR -2: SETCC_XC_SHIFT - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROXR_B) - DEF_ROXR 8, %al -DEFSIZE(ROXR_B) - -DEFLABEL(ROXR_W) - DEF_ROXR 16, %ax -DEFSIZE(ROXR_W) - -DEFLABEL(ROXR_L) - DEF_ROXR 32, %eax -DEFSIZE(ROXR_L) - -/*************************************************************************/ - -/** - * ROL_[BWL]: Evaluate op2 ROL op1. - */ -.macro DEF_ROL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 3f - and $\nbits-1, %ecx - jnz 2f -1: // count != 0 && count % nbits == 0 - mov %al, %dl - and $1, %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR - jmp 3f -2: // count % nbits != 0 - rol %cl, \reg - setc %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR -3: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROL_B) - DEF_ROL 8, %al -DEFSIZE(ROL_B) - -DEFLABEL(ROL_W) - DEF_ROL 16, %ax -DEFSIZE(ROL_W) - -DEFLABEL(ROL_L) - DEF_ROL 32, %eax -DEFSIZE(ROL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROR_[BWL]: Evaluate op2 ROR op1. - */ -.macro DEF_ROR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 3f - and $\nbits-1, %ecx - jnz 2f -1: // count != 0 && count % nbits == 0 - mov %eax, %edx - shr $\nbits-1, %edx - and $1, %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR - jmp 3f -2: // count % nbits != 0 - ror %cl, \reg - setc %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR -3: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROR_B) - DEF_ROR 8, %al -DEFSIZE(ROR_B) - -DEFLABEL(ROR_W) - DEF_ROR 16, %ax -DEFSIZE(ROR_W) - -DEFLABEL(ROR_L) - DEF_ROR 32, %eax -DEFSIZE(ROR_L) - -/*************************************************************************/ -/******************* Conditional and branch operations *******************/ -/*************************************************************************/ - -/** - * Scc: Set the lower 8 bits of the result value to 0xFF if the condition - * is true, 0x00 if false. - */ -DEFLABEL(Scc) - neg %al -DEFSIZE(Scc) - -/*-----------------------------------------------------------------------*/ - -/** - * ADD_CYCLES_Scc_Dn: Add the appropriate number of clock cycles for an - * Scc Dn instruction to the cycle count. - */ -DEFLABEL(ADD_CYCLES_Scc_Dn) - movzx %al, %ecx - and $2, %ecx - add $4, %ecx - add %ecx, %esi -DEFSIZE(ADD_CYCLES_Scc_Dn) - -/*************************************************************************/ - -/** - * DBcc: Jump to the specified target address unless the condition is true - * or the lower 16 bits of the given data register, after being decremented, - * are equal to -1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target: Target address - */ -DEFLABEL(DBcc) - test %al, %al - jz 0f - add $12, %esi - jmp 2f -0: lea 1(%rbx), %rcx -8: subw $1, (%rcx) - mov (%rcx), %ax - cmp $-1, %ax - jne 1f - add $14, %esi - jmp 2f -1: add $10, %esi - mov $0x12345678, %eax -9: mov %eax, PC - TERMINATE -2: -DEFSIZE(DBcc) -DEFPARAM(DBcc, reg4, 8b, -1) -DEFPARAM(DBcc, target, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * DBcc_native: Implement DBcc using a jump within the native code. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target: Target 68000 address - * native_disp: Target native displacement from end of this fragment - */ -DEFLABEL(DBcc_native) - test %al, %al - jz 0f - add $12, %esi - jmp 2f -0: lea 1(%rbx), %rcx -8: subw $1, (%rcx) - mov (%rcx), %ax - cmp $-1, %ax - jne 1f - add $14, %esi - jmp 2f -1: add $10, %esi - mov $0x12345678, %eax -9: mov %eax, PC - jmp .+0x12345678 -2: -DEFSIZE(DBcc_native) -DEFPARAM(DBcc_native, reg4, 8b, -1) -DEFPARAM(DBcc_native, target, 9b, -4) -DEFPARAM(DBcc_native, native_disp, 2b, -4) - -/*************************************************************************/ - -/** - * Bcc: Jump to the specified target address if the condition is true. - * - * [Parameters] - * target: Target address - */ -DEFLABEL(Bcc) - test %al, %al - jz 0f - mov $0x12345678, %eax -9: mov %eax, PC - add $10, %esi - TERMINATE -0: -DEFSIZE(Bcc) -DEFPARAM(Bcc, target, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * Bcc_native: Implement Bcc using a jump within the native code. - * - * [Parameters] - * target: Target 68000 address - * native_disp: Target native displacement from end of this fragment - */ -DEFLABEL(Bcc_native) - test %al, %al - jz 0f - mov $0x12345678, %eax -9: mov %eax, PC - add $10, %esi - jmp .+0x12345678 -0: -DEFSIZE(Bcc_native) -DEFPARAM(Bcc_native, target, 9b, -4) -DEFPARAM(Bcc_native, native_disp, 0b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * BSR: Push the address of the next instruction onto the stack, then jump - * to the specified target address. - * - * [Parameters] - * return_addr: Return address to push onto the stack - * target: Target address - */ -DEFLABEL(BSR) - mov $0x12345678, %ecx -8: PUSH32 %rcx - mov $0x12345678, %eax -9: mov %eax, PC - TERMINATE -DEFSIZE(BSR) -DEFPARAM(BSR, return_addr, 8b, -4) -DEFPARAM(BSR, target, 9b, -4) - -/*************************************************************************/ - -/** - * JMP: Jump to the previously resolved effective address. - */ -DEFLABEL(JMP) - mov Q68State_ea_addr(%rbx), %eax - mov %eax, PC - TERMINATE -DEFSIZE(JMP) - -/*-----------------------------------------------------------------------*/ - -/** - * JSR: Push the address of the next instruction onto the stack, then jump - * to the previously resolved effective address. - * - * [Parameters] - * return_addr: Return address to push onto the stack - */ -DEFLABEL(JSR) - mov $0x12345678, %ecx -9: PUSH32 %rcx - mov Q68State_ea_addr(%rbx), %eax - mov %eax, PC - TERMINATE -DEFSIZE(JSR) -DEFPARAM(JSR, return_addr, 9b, -4) - -/*************************************************************************/ -/*********************** MOVEM-related operations ************************/ -/*************************************************************************/ - -/** - * STORE_DEC_[WL]: Decrement state->ea_addr, then store the specified - * register to the resulting location. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_DEC_W) - mov Q68State_ea_addr(%rbx), %ecx - sub $2, %ecx - mov %ecx, Q68State_ea_addr(%rbx) - mov 1(%rbx), %eax -9: WRITE16 %rcx, %rax -DEFSIZE(STORE_DEC_W) -DEFPARAM(STORE_DEC_W, reg4, 9b, -1) - -DEFLABEL(STORE_DEC_L) - mov Q68State_ea_addr(%rbx), %ecx - sub $4, %ecx - mov %ecx, Q68State_ea_addr(%rbx) - mov 1(%rbx), %eax -9: WRITE32 %rcx, %rax -DEFSIZE(STORE_DEC_L) -DEFPARAM(STORE_DEC_L, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * STORE_INC_[WL]: Store the specified register to the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_INC_W) - mov Q68State_ea_addr(%rbx), %ecx - mov 1(%rbx), %eax -9: WRITE16 %rcx, %rax - add $2, Q68State_ea_addr(%rbx) -DEFSIZE(STORE_INC_W) -DEFPARAM(STORE_INC_W, reg4, 9b, -1) - -DEFLABEL(STORE_INC_L) - mov Q68State_ea_addr(%rbx), %ecx - mov 1(%rbx), %eax -9: WRITE32 %rcx, %rax - add $4, Q68State_ea_addr(%rbx) -DEFSIZE(STORE_INC_L) -DEFPARAM(STORE_INC_L, reg4, 9b, -1) - -/*************************************************************************/ - -/** - * LOAD_INC_[WL]: Load the specified register from the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(LOAD_INC_W) - mov Q68State_ea_addr(%rbx), %ecx - READ16 %rcx - mov %ax, 1(%rbx) -9: add $2, Q68State_ea_addr(%rbx) -DEFSIZE(LOAD_INC_W) -DEFPARAM(LOAD_INC_W, reg4, 9b, -1) - -DEFLABEL(LOAD_INC_L) - mov Q68State_ea_addr(%rbx), %ecx - READ32 %rcx - mov %eax, 1(%rbx) -9: add $4, Q68State_ea_addr(%rbx) -DEFSIZE(LOAD_INC_L) -DEFPARAM(LOAD_INC_L, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * LOADA_INC_W: Load the specified address register from the location - * indicated by state->ea_addr, sign-extending the 16-bit value to 32 bits, - * then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LOADA_INC_W) - mov Q68State_ea_addr(%rbx), %ecx - READ16 %rcx - cwde - mov %eax, 1(%rbx) -9: add $2, Q68State_ea_addr(%rbx) -DEFSIZE(LOADA_INC_W) -DEFPARAM(LOADA_INC_W, reg4, 9b, -1) - -/*************************************************************************/ - -/** - * MOVEM_WRITEBACK: Store the address in state->ea_addr to the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVEM_WRITEBACK) - mov Q68State_ea_addr(%rbx), %ecx - mov %ecx, 1(%rbx) -9: -DEFSIZE(MOVEM_WRITEBACK) -DEFPARAM(MOVEM_WRITEBACK, reg4, 9b, -1) - -/*************************************************************************/ -/*********************** Miscellaneous operations ************************/ -/*************************************************************************/ - -/** - * CHK_W: Raise a CHK exception if op1 < 0 or op1 > op2, treating both - * operands as signed 16-bit values. - */ -DEFLABEL(CHK_W) - test %di, %di - jns 0f - orb $SR_N, SR - jmp 1f -0: cmp %dx, %di - jle 2f - andb $~SR_N, SR -1: movl $EX_CHK, Q68State_exception(%rbx) - TERMINATE -2: -DEFSIZE(CHK_W) - -/*************************************************************************/ - -/** - * LEA: Store the previously resolved effective address in the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LEA) - mov Q68State_ea_addr(%rbx), %eax - mov %eax, 1(%rbx) -9: -DEFSIZE(LEA) -DEFPARAM(LEA, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * PEA: Push the previously resolved effective address onto the stack. - */ -DEFLABEL(PEA) - mov Q68State_ea_addr(%rbx), %ecx - PUSH32 %rcx -DEFSIZE(PEA) - -/*************************************************************************/ - -/** - * TAS: Test the 8-bit value of op1, setting the condition codes - * appropriately, then calculate op1 | 0x80. - */ -DEFLABEL(TAS) - mov %edi, %eax - test %al, %al - SETCC_NZ00 - or $0x80, %al -DEFSIZE(TAS) - -/*************************************************************************/ - -/** - * MOVE_FROM_USP: Copy the user stack pointer to the specified register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_FROM_USP) - mov USP, %eax - mov %eax, 1(%rbx) -9: -DEFSIZE(MOVE_FROM_USP) -DEFPARAM(MOVE_FROM_USP, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVE_TO_USP: Copy the specified register to the user stack pointer. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_TO_USP) - mov 1(%rbx), %eax -9: mov %eax, USP -DEFSIZE(MOVE_TO_USP) -DEFPARAM(MOVE_TO_USP, reg4, 9b, -1) - -/*************************************************************************/ - -/** - * STOP: Halt the processor. - * - * [Parameters] - * newSR: Value to load into SR - */ -DEFLABEL(STOP) - movl $1, Q68State_halted(%rbx) - mov $0x1234, %ax -9: UPDATE_SR -DEFSIZE(STOP) -DEFPARAM(STOP, newSR, 9b, -2) - -/*************************************************************************/ - -/** - * TRAPV: Raise a TRAPV exception if the overflow flag is set. - */ -DEFLABEL(TRAPV) - testb $SR_V, SR - jz 0f - movl $EX_TRAPV, Q68State_exception(%rbx) - TERMINATE -0: -DEFSIZE(TRAPV) - -/*************************************************************************/ - -/** - * RTS: Pop the PC from the stack. - */ -DEFLABEL(RTS) - POP32 - mov %eax, PC - TERMINATE -DEFSIZE(RTS) - -/*-----------------------------------------------------------------------*/ - -/** - * RTR: Pop the condition codes and PC from the stack. - */ -DEFLABEL(RTR) - POP16 - mov %al, SR // Update low byte only - POP32 - mov %eax, PC - TERMINATE -DEFSIZE(RTR) - -/*-----------------------------------------------------------------------*/ - -/** - * RTE: Pop the status register and PC from the stack. - */ -DEFLABEL(RTE) - POP16 - push %rax - POP32 - mov %eax, PC - pop %rax - UPDATE_SR - TERMINATE -DEFSIZE(RTE) - -/*************************************************************************/ - -/** - * MOVEP_READ_[WL]: Read a value from memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. to receive data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_READ_W) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: push %rcx - READ8 %rcx // Byte 1 - movzx %al, %edi - shl $8, %edi - pop %rcx - add $2, %ecx - READ8 %rcx // Byte 0 - movzx %al, %eax - or %eax, %edi - mov %di, 1(%rbx) -9: -DEFSIZE(MOVEP_READ_W) -DEFPARAM(MOVEP_READ_W, areg4, 7b, -1) -DEFPARAM(MOVEP_READ_W, disp, 8b, -4) -DEFPARAM(MOVEP_READ_W, dreg4, 9b, -1) - -DEFLABEL(MOVEP_READ_L) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: push %rcx - READ8 %rcx // Byte 3 - movzx %al, %edi - shl $24, %edi - mov (%rsp), %ecx - add $2, %ecx - READ8 %rcx // Byte 2 - movzx %al, %eax - shl $16, %eax - or %eax, %edi - mov (%rsp), %ecx - add $4, %ecx - READ8 %rcx // Byte 1 - movzx %al, %eax - shl $8, %eax - or %eax, %edi - pop %rcx - add $6, %ecx - READ8 %rcx // Byte 0 - movzx %al, %eax - or %eax, %edi - mov %di, 1(%rbx) -9: -DEFSIZE(MOVEP_READ_L) -DEFPARAM(MOVEP_READ_L, areg4, 7b, -1) -DEFPARAM(MOVEP_READ_L, disp, 8b, -4) -DEFPARAM(MOVEP_READ_L, dreg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVEP_WRITE_[WL]: Write a value to memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. containing data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_WRITE_W) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: mov 1(%rbx), %eax -9: push %rcx - push %rax - shr $8, %eax - WRITE8 %rcx, %rax // Byte 1 - pop %rax - pop %rcx - add $2, %ecx - WRITE8 %rcx, %rax // Byte 0 -DEFSIZE(MOVEP_WRITE_W) -DEFPARAM(MOVEP_WRITE_W, areg4, 7b, -1) -DEFPARAM(MOVEP_WRITE_W, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_W, dreg4, 9b, -1) - -DEFLABEL(MOVEP_WRITE_L) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: mov 1(%rbx), %eax -9: push %rcx - push %rax - shr $24, %eax - WRITE8 %rcx, %rax // Byte 3 - pop %rax - mov (%rsp), %ecx - add $2, %ecx - push %rax - shr $16, %eax - WRITE8 %rcx, %rax // Byte 2 - pop %rax - mov (%rsp), %ecx - add $4, %ecx - push %rax - shr $8, %eax - WRITE8 %rcx, %rax // Byte 1 - pop %rax - pop %rcx - add $6, %ecx - WRITE8 %rcx, %rax // Byte 0 -DEFSIZE(MOVEP_WRITE_L) -DEFPARAM(MOVEP_WRITE_L, areg4, 7b, -1) -DEFPARAM(MOVEP_WRITE_L, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_L, dreg4, 9b, -1) - -/*************************************************************************/ - -/** - * EXG: Exchange the values of two registers. - * - * [Parameters] - * reg1_4: Register number * 4 of first register (0-60 = D0-A7) - * reg2_4: Register number * 4 of second register (0-60 = D0-A7) - */ -DEFLABEL(EXG) - lea 1(%rbx), %ecx -8: lea 1(%rbx), %edx -9: mov (%rcx), %eax - mov (%rdx), %edi - mov %eax, (%rdx) - mov %edi, (%rcx) -DEFSIZE(EXG) -DEFPARAM(EXG, reg1_4, 8b, -1) -DEFPARAM(EXG, reg2_4, 9b, -1) - -/*************************************************************************/ -/*************************************************************************/ diff --git a/yabause/src/q68/q68-jit-x86.h b/yabause/src/q68/q68-jit-x86.h deleted file mode 100644 index 1fef4589c2..0000000000 --- a/yabause/src/q68/q68-jit-x86.h +++ /dev/null @@ -1,453 +0,0 @@ -/* src/q68/q68-jit-x86.h: x86 (32/64-bit) dynamic translation header for Q68 - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_JIT_X86_H -#define Q68_JIT_X86_H - -/*************************************************************************/ - -/** - * JIT_CALL: Run translated code from the given (native) address for the - * given number of cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * address_ptr: Pointer to address of native code to execute; must be - * updated on return with the next address to execute - * or NULL if the end of the block was reached - * [Return value] - * Number of clock cycles actually executed - */ -static inline int JIT_CALL(Q68State *state, int cycles, void **address_ptr) -{ - asm( -#ifdef CPU_X64 - /* GCC doesn't know we're actually calling a function here, so make - * sure we don't accidentally overwrite the x64 redzone */ - "sub $128, %%rsp; call *%[address]; add $128, %%rsp" -#else - /* x86 doesn't have a redzone, so we can just do a direct call */ - "call *%[address]" -#endif - : [cycles] "=S" (cycles), [address] "=D" (*address_ptr) - : [state] "b" (state), "0" (cycles), "1" (*address_ptr) -#ifdef CPU_X64 - : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11" -#else - : "eax", "ecx", "edx" -#endif - , "memory" - ); - return cycles; -} - -/*************************************************************************/ - -/** - * JIT_FIXUP_BRANCH: Modify a branch instruction at the given offset to - * jump to the given target. - * - * [Parameters] - * entry: Block being translated - * offset: Offset within entry->native_code of branch instruction - * (as returned in *branch_offset EMIT parameter) - * target: Target offset within entry->native_code - * [Return value] - * None - */ -static inline void JIT_FIXUP_BRANCH(Q68JitEntry *entry, uint32_t offset, - uint32_t target) -{ - /* Not supported on x86/x64 */ -} - -/*************************************************************************/ - -/* - * The remaining macros are all used to insert a specific operation into - * the native code stream. For simplicity, we define the actual code for - * each operation in a separate assembly file, and use memcpy() to copy - * from the assembled code to the output code stream. The GEN_EMIT macro - * below is used to generate each of the JIT_EMIT_* functions; each - * function JIT_EMIT_xxx copies JIT_X86SIZE_xxx bytes from JIT_X86_xxx to - * the code stream, expanding the code buffer if necessary. - */ - -/* Sub-macros (platform-dependent): */ - -#ifdef CPU_X64 - -#define GEN_NAMESIZE(name) \ - extern const uint8_t JIT_X64_##name[]; \ - extern const uint32_t JIT_X64SIZE_##name; -#define GEN_PARAM(name,param) \ - extern const uint32_t JIT_X64PARAM_##name##_##param; -#define GEN_FUNC_TOP(name) \ - if (UNLIKELY(entry->native_size - entry->native_length \ - < JIT_X64SIZE_##name)) { \ - if (!expand_buffer(entry)) { \ - return; \ - } \ - } \ - if (JIT_X64SIZE_##name > 0) { \ - memcpy((uint8_t *)entry->native_code + entry->native_length, \ - JIT_X64_##name, JIT_X64SIZE_##name); \ - } -#define GEN_COPY_PARAM(name,type,param) \ - *(type *)((uint8_t *)entry->native_code + entry->native_length \ - + JIT_X64PARAM_##name##_##param) = param; -#define GEN_FUNC_BOTTOM(name) \ - entry->native_length += JIT_X64SIZE_##name; - -#else // CPU_X86 - -#define GEN_NAMESIZE(name) \ - extern const uint8_t JIT_X86_##name[]; \ - extern const uint32_t JIT_X86SIZE_##name; -#define GEN_PARAM(name,param) \ - extern const uint32_t JIT_X86PARAM_##name##_##param; -#define GEN_FUNC_TOP(name) \ - if (UNLIKELY(entry->native_size - entry->native_length \ - < JIT_X86SIZE_##name)) { \ - if (!expand_buffer(entry)) { \ - return; \ - } \ - } \ - if (JIT_X86SIZE_##name > 0) { \ - memcpy((uint8_t *)entry->native_code + entry->native_length, \ - JIT_X86_##name, JIT_X86SIZE_##name); \ - } -#define GEN_COPY_PARAM(name,type,param) \ - *(type *)((uint8_t *)entry->native_code + entry->native_length \ - + JIT_X86PARAM_##name##_##param) = param; -#define GEN_FUNC_BOTTOM(name) \ - entry->native_length += JIT_X86SIZE_##name; - -#endif // X64/X86 - -#define GEN_EMIT(name) \ - GEN_NAMESIZE(name) \ - static void JIT_EMIT_##name(Q68JitEntry *entry) { \ - GEN_FUNC_TOP(name) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_1(name,type1,param1) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_2(name,type1,param1,type2,param2) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_3(name,type1,param1,type2,param2,type3,param3) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_FUNC_BOTTOM(name) \ - } - -/*-----------------------------------------------------------------------*/ - -/* Code prologue and epilogue */ -GEN_EMIT(PROLOGUE) -GEN_EMIT(EPILOGUE) - -#ifdef Q68_TRACE -/* Trace the current instruction */ -GEN_EMIT(TRACE) -#endif - -/* Add the specified number of cycles to the cycle counter */ -GEN_EMIT_1(ADD_CYCLES, int32_t, cycles) - -/* Check the cycle limit and interrupt execution if necessary */ -GEN_EMIT(CHECK_CYCLES) - -/* Add the specified amount to the program counter and/or check whether - * to abort */ -GEN_EMIT_1(ADVANCE_PC, int32_t, value) -GEN_EMIT_1(ADVANCE_PC_CHECK_ABORT, int32_t, value) -GEN_EMIT(CHECK_ABORT) - -/* Exception raising */ -GEN_EMIT_1(EXCEPTION, uint32_t, num) -GEN_EMIT_2(CHECK_ALIGNED_EA, uint16_t, opcode, uint16_t, status) -GEN_EMIT_2(CHECK_ALIGNED_SP, uint16_t, opcode, uint16_t, status) -GEN_EMIT(CHECK_SUPER) - -/*-----------------------------------------------------------------------*/ - -/* Resolve an effective address */ -GEN_EMIT_1(RESOLVE_INDIRECT, uint8_t, reg4) -GEN_EMIT_2(RESOLVE_POSTINC, uint8_t, reg4, uint8_t, size) -GEN_EMIT(RESOLVE_POSTINC_A7_B) -GEN_EMIT_2(RESOLVE_PREDEC, uint8_t, reg4, uint8_t, size) -GEN_EMIT(RESOLVE_PREDEC_A7_B) -GEN_EMIT_2(RESOLVE_DISP, uint8_t, reg4, uint32_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_W, uint8_t, reg4, uint8_t, ireg4, uint8_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_L, uint8_t, reg4, uint8_t, ireg4, uint8_t, disp) -GEN_EMIT_1(RESOLVE_ABSOLUTE, uint32_t, addr) -GEN_EMIT_2(RESOLVE_ABS_INDEX_W, uint32_t, addr, uint8_t, ireg4) -GEN_EMIT_2(RESOLVE_ABS_INDEX_L, uint32_t, addr, uint8_t, ireg4) - -/* Retrieve various things as operand 1 */ -GEN_EMIT_1(GET_OP1_REGISTER, uint8_t, reg4) -GEN_EMIT(GET_OP1_EA_B) -GEN_EMIT(GET_OP1_EA_W) -GEN_EMIT(GET_OP1_EA_L) -GEN_EMIT_1(GET_OP1_IMMEDIATE, uint32_t, value) -GEN_EMIT(GET_OP1_CCR) -GEN_EMIT(GET_OP1_SR) - -/* Retrieve various things as operand 2 */ -GEN_EMIT_1(GET_OP2_REGISTER, uint8_t, reg4) -GEN_EMIT(GET_OP2_EA_B) -GEN_EMIT(GET_OP2_EA_W) -GEN_EMIT(GET_OP2_EA_L) -GEN_EMIT_1(GET_OP2_IMMEDIATE, uint32_t, value) -GEN_EMIT(GET_OP2_CCR) -GEN_EMIT(GET_OP2_SR) - -/* Update various things from result */ -GEN_EMIT_1(SET_REGISTER_B, uint8_t, reg4) -GEN_EMIT_1(SET_REGISTER_W, uint8_t, reg4) -GEN_EMIT_1(SET_REGISTER_L, uint8_t, reg4) -GEN_EMIT_1(SET_AREG_W, uint8_t, reg4) -GEN_EMIT(SET_EA_B) -GEN_EMIT(SET_EA_W) -GEN_EMIT(SET_EA_L) -GEN_EMIT(SET_CCR) -GEN_EMIT(SET_SR) - -/* Stack operations */ -GEN_EMIT(PUSH_L) -GEN_EMIT(POP_L) - -/* Condition code setting */ -GEN_EMIT(SETCC_ADD_B) -GEN_EMIT(SETCC_ADD_W) -GEN_EMIT(SETCC_ADD_L) -GEN_EMIT(SETCC_ADDX_B) -GEN_EMIT(SETCC_ADDX_W) -GEN_EMIT(SETCC_ADDX_L) -GEN_EMIT(SETCC_SUB_B) -GEN_EMIT(SETCC_SUB_W) -GEN_EMIT(SETCC_SUB_L) -GEN_EMIT(SETCC_SUBX_B) -GEN_EMIT(SETCC_SUBX_W) -GEN_EMIT(SETCC_SUBX_L) -GEN_EMIT(SETCC_CMP_B) -GEN_EMIT(SETCC_CMP_W) -GEN_EMIT(SETCC_CMP_L) -GEN_EMIT(SETCC_LOGIC_B) -GEN_EMIT(SETCC_LOGIC_W) -GEN_EMIT(SETCC_LOGIC_L) - -/* Condition testing */ -GEN_EMIT(TEST_T) -GEN_EMIT(TEST_F) -GEN_EMIT(TEST_HI) -GEN_EMIT(TEST_LS) -GEN_EMIT(TEST_CC) -GEN_EMIT(TEST_CS) -GEN_EMIT(TEST_NE) -GEN_EMIT(TEST_EQ) -GEN_EMIT(TEST_VC) -GEN_EMIT(TEST_VS) -GEN_EMIT(TEST_PL) -GEN_EMIT(TEST_MI) -GEN_EMIT(TEST_GE) -GEN_EMIT(TEST_LT) -GEN_EMIT(TEST_GT) -GEN_EMIT(TEST_LE) - -/* ALU operations */ -GEN_EMIT(MOVE_B) -GEN_EMIT(MOVE_W) -GEN_EMIT(MOVE_L) -GEN_EMIT(ADD_B) -GEN_EMIT(ADD_W) -GEN_EMIT(ADD_L) -GEN_EMIT(ADDA_W) -GEN_EMIT(ADDX_B) -GEN_EMIT(ADDX_W) -GEN_EMIT(ADDX_L) -GEN_EMIT(SUB_B) -GEN_EMIT(SUB_W) -GEN_EMIT(SUB_L) -GEN_EMIT(SUBA_W) -GEN_EMIT(SUBX_B) -GEN_EMIT(SUBX_W) -GEN_EMIT(SUBX_L) -GEN_EMIT(MULS_W) -GEN_EMIT(MULU_W) -GEN_EMIT(DIVS_W) -GEN_EMIT(DIVU_W) -GEN_EMIT(AND_B) -GEN_EMIT(AND_W) -GEN_EMIT(AND_L) -GEN_EMIT(OR_B) -GEN_EMIT(OR_W) -GEN_EMIT(OR_L) -GEN_EMIT(EOR_B) -GEN_EMIT(EOR_W) -GEN_EMIT(EOR_L) -GEN_EMIT(EXT_W) -GEN_EMIT(EXT_L) -GEN_EMIT(SWAP) - -/* BCD operations */ -GEN_EMIT(ABCD) -GEN_EMIT(SBCD) - -/* Bit-twiddling operations */ -GEN_EMIT(BTST_B) -GEN_EMIT(BTST_L) -GEN_EMIT(BCHG) -GEN_EMIT(BCLR) -GEN_EMIT(BSET) - -/* Shift/rotate operations */ -GEN_EMIT(ASL_B) -GEN_EMIT(ASL_W) -GEN_EMIT(ASL_L) -GEN_EMIT(ASR_B) -GEN_EMIT(ASR_W) -GEN_EMIT(ASR_L) -GEN_EMIT(LSL_B) -GEN_EMIT(LSL_W) -GEN_EMIT(LSL_L) -GEN_EMIT(LSR_B) -GEN_EMIT(LSR_W) -GEN_EMIT(LSR_L) -GEN_EMIT(ROXL_B) -GEN_EMIT(ROXL_W) -GEN_EMIT(ROXL_L) -GEN_EMIT(ROXR_B) -GEN_EMIT(ROXR_W) -GEN_EMIT(ROXR_L) -GEN_EMIT(ROL_B) -GEN_EMIT(ROL_W) -GEN_EMIT(ROL_L) -GEN_EMIT(ROR_B) -GEN_EMIT(ROR_W) -GEN_EMIT(ROR_L) - -/* Conditional and branch operations ("branch_offset" parameter receives - * the native offset of the branch to update when resolving, or -1 if not - * supported) */ -GEN_EMIT(Scc) -GEN_EMIT(ADD_CYCLES_Scc_Dn) -GEN_EMIT_2(DBcc, uint8_t, reg4, int32_t, target) -GEN_EMIT_3(DBcc_native, uint8_t, reg4, int32_t, target, int32_t, native_disp) -#ifdef CPU_X64 -# define SIZE_DBcc_native JIT_X64SIZE_DBcc_native -#else -# define SIZE_DBcc_native JIT_X86SIZE_DBcc_native -#endif -#define JIT_EMIT_DBcc_native(entry,reg4,target,offset) do { \ - Q68JitEntry *__entry = (entry); \ - int32_t __fragment_end = __entry->native_length + SIZE_DBcc_native; \ - JIT_EMIT_DBcc_native(__entry, (reg4), (target), \ - (offset) - __fragment_end); \ -} while (0) -GEN_EMIT_1(Bcc, int32_t, target) -#define JIT_EMIT_Bcc(entry,target,branch_offset) do { \ - JIT_EMIT_Bcc((entry), (target)); \ - *(branch_offset) = -1; \ -} while (0) -GEN_EMIT_2(Bcc_native, int32_t, target, int32_t, native_disp) -#ifdef CPU_X64 -# define SIZE_Bcc_native JIT_X64SIZE_Bcc_native -#else -# define SIZE_Bcc_native JIT_X86SIZE_Bcc_native -#endif -#define JIT_EMIT_Bcc_native(entry,target,native) do { \ - Q68JitEntry *__entry = (entry); \ - int32_t __fragment_end = __entry->native_length + SIZE_Bcc_native; \ - JIT_EMIT_Bcc_native(__entry, (target), (offset) - __fragment_end); \ -} while (0) -GEN_EMIT_2(BSR, uint32_t, return_addr, int32_t, target) -GEN_EMIT(JMP) -GEN_EMIT_1(JSR, uint32_t, return_addr) - -/* MOVEM-related operations */ -GEN_EMIT_1(STORE_DEC_W, uint8_t, reg4) -GEN_EMIT_1(STORE_DEC_L, uint8_t, reg4) -GEN_EMIT_1(STORE_INC_W, uint8_t, reg4) -GEN_EMIT_1(STORE_INC_L, uint8_t, reg4) -GEN_EMIT_1(LOAD_INC_W, uint8_t, reg4) -GEN_EMIT_1(LOAD_INC_L, uint8_t, reg4) -GEN_EMIT_1(LOADA_INC_W, uint8_t, reg4) -GEN_EMIT_1(MOVEM_WRITEBACK, uint8_t, reg4) - -/* Miscellaneous operations */ -GEN_EMIT(CHK_W) -GEN_EMIT_1(LEA, uint8_t, reg4) -GEN_EMIT(PEA) -GEN_EMIT(TAS) -GEN_EMIT_1(MOVE_FROM_USP, uint8_t, reg4) -GEN_EMIT_1(MOVE_TO_USP, uint8_t, reg4) -GEN_EMIT_1(STOP, uint16_t, newSR) -GEN_EMIT(TRAPV) -GEN_EMIT(RTS) -GEN_EMIT(RTR) -GEN_EMIT(RTE) -GEN_EMIT_3(MOVEP_READ_W, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_3(MOVEP_READ_L, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_W, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_L, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_2(EXG, uint8_t, reg1_4, uint8_t, reg2_4) - -/*************************************************************************/ - -#endif // Q68_JIT_X86_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit.c b/yabause/src/q68/q68-jit.c deleted file mode 100644 index a1c2348e3b..0000000000 --- a/yabause/src/q68/q68-jit.c +++ /dev/null @@ -1,3722 +0,0 @@ -/* src/q68/q68-jit.c: Dynamic translation support for Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include - -#include "q68.h" -#include "q68-const.h" -#include "q68-internal.h" -#include "q68-jit.h" - -/*************************************************************************/ - -/* - * Dynamic translation of 68000 instructions into native code is performed - * as follows: - * - * 1) The emulation core (q68-core.c) calls q68_jit_find() on the current - * PC to check whether there is a translated block starting at that - * address. - * - * 2) If no translated block exists, the emulation core calls - * q68_jit_translate() to translate a block beginning at the current - * PC. q68_jit_translate() continues translating through the end of - * the block of code (determined heuristically) and returns the - * translated block to be passed to q68_jit_run(). - * - * 3) If a translated block exists or was just created, the emulation core - * calls q68_jit_run() to begin execution of the translated code. - * - * 4) The translated code returns either when it reaches the end of the - * block, or when the number of cycles executed exceeds the requested - * cycle count. (For efficiency, cycle count checks are only performed - * before branching instructions: BRA, BSR, Bcc, DBcc, JMP, JSR, RTS, - * RTE, RTR, TRAP, STOP.) - * - * 5) If the translated code returns before the end of the block, the core - * continues to call q68_jit_run() until the end of the block is - * reached. - * - * 6) If a write is made to a region of memory containing one or more - * translated blocks, the core deletes the translations by calling - * q68_jit_clear_page() so the modified code can be retranslated. - * Writes originating in the translated code itself (i.e. self-modifying - * code) are handled by the native code calling q68_jit_clear_write() - * when detecting a write to a page containing translations. - * - * The amount of translated code which can be stored at one time is - * dependent upon two factors: the size of the hash table (set by the - * Q68_JIT_TABLE_SIZE define in q68-const.h) and the maximum translated - * data size (set by the Q68_JIT_DATA_LIMIT define). If either the hash - * table becomes full or the data size limit is reached, any subsequent - * translation will cause the oldest existing translation to be deleted, - * where "oldest" is defined as "last executed the greatest number of - * q68_jit_run() calls ago". Note that the data size limit is checked only - * when beginning a translation, so the total data size at the end of a - * translation may slightly exceed the specified limit. - * - * ======================================================================== - * - * Native code is generated through calls to JIT_EMIT_*() routines. - * Typically, these routines will copy a pre-assembled code fragment to the - * native code buffer, then patch that code fragment with values specific - * to the instruction being translated (such as register numbers or branch - * targets). The general sequence of operations emitted is as follows: - * - * JIT_EMIT_RESOLVE_* -- resolves an effective address to a 68000 - * memory location - * JIT_EMIT_GET_OP1_* -- loads the first operand for an instruction - * JIT_EMIT_GET_OP2_* -- loads the second operand for an instruction - * JIT_EMIT_TEST_* -- tests the state of condition codes - * JIT_EMIT_(insn) -- executes the instruction itself - * JIT_EMIT_SETCC_* -- updates the 68000 condition codes - * JIT_EMIT_SET_* -- stores the result of the instruction - * JIT_EMIT_ADD_CYCLES -- increments the count of clock cycles executed(*) - * JIT_EMIT_ADVANCE_PC -- increments the program counter register(*) - * - * (*) In some cases, particularly when the instruction may cause execution - * of the block to terminate, these operations will occur earlier in - * the sequence. The code generator takes responsibility for ensuring - * that such updates happen in the proper order. - * - * The code generator guarantees that the following invariants hold: - * - * - No operations which could result in a 68000 memory access will be - * generated between loading of the second operand (JIT_EMIT_GET_OP2_*) - * and execution of the instruction. - * - * - A JIT_EMIT_TEST_* operation will always be followed immediately by - * the instruction which uses the operation (such as JIT_EMIT_Scc). - * - * - A JIT_EMIT_SETCC_* operation will always immediately follow the - * operation which produced the result it is testing. - * - * The machine-dependent implementations must obey the following rules: - * - * - Each write to memory must be preceded by a check for translated code - * at the target address (by checking state->jit_pages[]) and a call to - * q68_jit_clear_write() if any translations are found. - * (Implementations may violate this rule in circumstances considered - * unlikely, at the risk of incorrect behavior if such circumstances - * actually occur; for example, the PSP implementation does not check - * for a longword write overlapping the end of a JIT page, and does not - * check writes from the MOVEM instruction.) - * - * - Any instruction which modifies the program counter (Bcc, etc.) must - * terminate execution of the native code block, _except for_ the - * following instructions: - * JMP, RTE, RTR, RTS - * - * - Any instruction which raises an exception must do so by storing the - * appropriate exception number in state->exception and terminating - * execution of the native code block. - * - * - It is the responsibility of the native code to check for a pending - * unmasked interrupt when modifying the status register. - * - * The BSR/JSR and RTS/RTR instructions may make use of a call stack - * provided by the JIT core to allow native code to quickly return to the - * point at which a subroutine call took place. The BSR and JSR - * implementations should, when they terminate execution, return a pointer - * to the following native code (as for termination in CHECK_CYCLES), and - * should set bit 15 of the cycle count returned from JIT_CALL(); - * q68_jit_run() will detect this as a subroutine call, and save the native - * code pointer returned before switching to the subroutine block. The RTS - * and RTR implementations should set bits 15 and 14 of the cycle count - * they return, which will cause q68_jit_run() to search the call stack - * from top to bottom for an entry matching the new 68000 PC; if one is - * found, the corresponding code will be immediately executed, bypassing - * the ordinary block search and execution process (steps 1 through 3 - * above). - * - * See the q68-jit-*.[hS] files for implementation details. - * - * ======================================================================== - * - * The JIT code generator includes a primitive optimization step (if the - * Q68_JIT_OPTIMIZE_FLAGS preprocessor symbol is defined) which omits the - * generation of code to set the 68000 condition flags (X, N, Z, V, and C) - * when unnecessary for correct execution. Specifically, the translator - * checks both the current and the following instruction to determine if - * there are any condition flags which are: - * - set by the current instruction, AND - * - used as input by the following instruction OR - * - NOT set by the following instruction - * If there are no such flags, then it is impossible for the flag values - * set by the current instruction to have any effect on program flow, so - * the native code to set the condition codes can be safely omitted. - * - * The above logic is contained in the cc_needed() routine (and its helper - * routine cc_info()). For each instruction that can set the condition - * flags, the translation routine first calls cc_needed() to determine - * whether the condition flags need to be set or not. If cc_needed() - * returns zero, then there are no flags whose output is required, and the - * relevant JIT_EMIT_SETCC_* operation will be skipped. - * - * In the interests of speed and code clarity, the helper routine cc_info() - * does not check the validity of the opcode passed to it; as a result, it - * may return invalid flag information for some invalid opcodes. If such - * an invalid opcode actually occurs in the instruction stream, the CCR - * register may therefore contain an incorrect value when control is - * transferred to the illegal instruction exception handler. In situations - * where this can cause undesired behavior, this optimization should be - * disabled. - * - * When Q68_JIT_OPTIMIZE_FLAGS is not defined, the definitions of - * cc_needed() and cc_info() are omitted, and cc_needed() is instead - * defined at the preprocessor level to return 1; this has the effect of - * always emitting code to set the condition flags. - */ - -/*************************************************************************/ - -/* For the PSP, we need to avoid local data here sharing a cache line with - * data in other files due to the lack of SC/ME cache coherency */ -#ifdef PSP -static __attribute__((aligned(64),used)) int dummy_top; -#endif - -/*----------------------------------*/ - -/* Entry into which translated code is currently being stored (set by - * q68_jit_translate(), used by opcode translation functions) */ -static Q68JitEntry *current_entry; - -/* Address from which data is being read */ -static uint32_t jit_PC; - -/* Flag indicating whether the PC was updated by an instruction (e.g. jumps) */ -static int PC_updated; - -/* Branch target lookup table (indicates where in the native code each - * address is located) */ -static struct { - uint32_t m68k_address; // Address of 68000 instruction - uint32_t native_offset; // Byte offset into current_entry->native_code -} btcache[Q68_JIT_BTCACHE_SIZE]; -static unsigned int btcache_index; // Where to store the next instruction - -/* Unresolved branch list (saves locations and targets of forward branches) */ -static struct { - uint32_t m68k_target; // Branch target (68000 address) - uint32_t native_offset; // Offset of native branch instruction to update -} unres_branches[Q68_JIT_UNRES_BRANCH_SIZE]; - -/*----------------------------------*/ - -#ifdef PSP // As above -static __attribute__((aligned(64),used)) int dummy_bottom; -#endif - -/*-----------------------------------------------------------------------*/ - -/* Redefine IFETCH to reference jit_PC */ - -static inline uint32_t jit_IFETCH(Q68State *state) { - uint32_t data = READU16(state, jit_PC); - jit_PC += 2; - return data; -} -#define IFETCH jit_IFETCH - -/*************************************************************************/ - -/* - * Forward declarations for helper functions and instruction implementations. - * These are set up identically to q68-core.c so that bugfixes or other - * changes to one can be easily ported to the other. - * - * Note that the return value of OpcodeFunc is taken to be the end-of-block - * flag as returned from q68_jit_translate(), not the number of clock cycles - * taken by the instruction. - */ - -static int translate_insn(Q68State *state, Q68JitEntry *entry); -static void clear_entry(Q68State *state, Q68JitEntry *entry); -static void clear_oldest_entry(Q68State *state); -static int expand_buffer(Q68JitEntry *entry); -static int32_t btcache_lookup(uint32_t address); -static void record_unresolved_branch(uint32_t m68k_target, - uint32_t native_offset); -static inline void JIT_EMIT_TEST_cc(int cond, Q68JitEntry *entry); -static void advance_PC(Q68State *state); -static int raise_exception(Q68State *state, uint8_t num); -static inline int op_ill(Q68State *state, uint32_t opcode); - -#ifdef Q68_JIT_OPTIMIZE_FLAGS -static unsigned int cc_needed(Q68State *state, uint16_t opcode); -# ifdef __GNUC__ -__attribute__((const)) -# endif -static unsigned int cc_info(uint16_t opcode); -#else -# define cc_needed(state,opcode) 1 -#endif - -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type); -static void ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret, int op_num); -static void ea_set(Q68State *state, uint32_t opcode, int size); - -static int op_imm(Q68State *state, uint32_t opcode); -static int op_bit(Q68State *state, uint32_t opcode); -static int opMOVE(Q68State *state, uint32_t opcode); -static int op4xxx(Q68State *state, uint32_t opcode); -static int op_CHK(Q68State *state, uint32_t opcode); -static int op_LEA(Q68State *state, uint32_t opcode); -static int opADSQ(Q68State *state, uint32_t opcode); -static int op_Scc(Q68State *state, uint32_t opcode); -static int opDBcc(Q68State *state, uint32_t opcode); -static int op_Bcc(Q68State *state, uint32_t opcode); -static int opMOVQ(Q68State *state, uint32_t opcode); -static int op_alu(Q68State *state, uint32_t opcode); -static int op_DIV(Q68State *state, uint32_t opcode); -static int opAxxx(Q68State *state, uint32_t opcode); -static int op_MUL(Q68State *state, uint32_t opcode); -static int opshft(Q68State *state, uint32_t opcode); -static int opFxxx(Q68State *state, uint32_t opcode); - -static int op4alu(Q68State *state, uint32_t opcode); -static int opMVSR(Q68State *state, uint32_t opcode); -static int opNBCD(Q68State *state, uint32_t opcode); -static int op_PEA(Q68State *state, uint32_t opcode); -static int opSWAP(Q68State *state, uint32_t opcode); -static int op_TAS(Q68State *state, uint32_t opcode); -static int op_EXT(Q68State *state, uint32_t opcode); -static int op_STM(Q68State *state, uint32_t opcode); -static int op_LDM(Q68State *state, uint32_t opcode); -static int opmisc(Q68State *state, uint32_t opcode); -static int opTRAP(Q68State *state, uint32_t opcode); -static int opLINK(Q68State *state, uint32_t opcode); -static int opUNLK(Q68State *state, uint32_t opcode); -static int opMUSP(Q68State *state, uint32_t opcode); -static int op4E7x(Q68State *state, uint32_t opcode); -static int opjump(Q68State *state, uint32_t opcode); - -static int opMOVP(Q68State *state, uint32_t opcode); -static int opADSX(Q68State *state, uint32_t opcode); -static int op_BCD(Q68State *state, uint32_t opcode); -static int opCMPM(Q68State *state, uint32_t opcode); -static int op_EXG(Q68State *state, uint32_t opcode); - -/*-----------------------------------------------------------------------*/ - -/* Main table of instruction implemenation functions; table index is bits - * 15-12 and 8-6 of the opcode (ABCD ...E FG.. .... -> 0ABC DEFG). */ -static OpcodeFunc * const opcode_table[128] = { - op_imm, op_imm, op_imm, op_imm, op_bit, op_bit, op_bit, op_bit, // 00 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 10 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 20 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 30 - - op4xxx, op4xxx, op4xxx, op4xxx, op_ill, op_ill, op_CHK, op_LEA, // 40 - opADSQ, opADSQ, opADSQ, op_Scc, opADSQ, opADSQ, opADSQ, op_Scc, // 50 - op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, // 60 - opMOVQ, opMOVQ, opMOVQ, opMOVQ, op_ill, op_ill, op_ill, op_ill, // 70 - - op_alu, op_alu, op_alu, op_DIV, op_alu, op_alu, op_alu, op_DIV, // 80 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // 90 - opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, // A0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // B0 - - op_alu, op_alu, op_alu, op_MUL, op_alu, op_alu, op_alu, op_MUL, // C0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // D0 - opshft, opshft, opshft, opshft, opshft, opshft, opshft, opshft, // E0 - opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, // F0 -}; - -/* Subtable for instructions in the $4xxx (miscellaneous) group; table index - * is bits 11-9 and 7-6 of the opcode (1000 ABC0 DE.. .... -> 000A BCDE). */ -static OpcodeFunc * const opcode_4xxx_table[32] = { - op4alu, op4alu, op4alu, opMVSR, // 40xx - op4alu, op4alu, op4alu, op_ill, // 42xx - op4alu, op4alu, op4alu, opMVSR, // 44xx - op4alu, op4alu, op4alu, opMVSR, // 46xx - opNBCD, op_PEA, op_STM, op_STM, // 48xx - op4alu, op4alu, op4alu, op_TAS, // 4Axx - op_ill, op_ill, op_LDM, op_LDM, // 4Cxx - op_ill, opmisc, opjump, opjump, // 4Exx -}; - -/* Sub-subtable for instructions in the $4E40-$4E7F range, used by opmisc(); - * index is bits 5-3 of the opcode. */ -static OpcodeFunc * const opcode_4E4x_table[8] = { - opTRAP, opTRAP, opLINK, opUNLK, - opMUSP, opMUSP, op4E7x, op_ill, -}; - -/*************************************************************************/ - -/* Include the header appropriate to the platform (make sure to do this - * after the local function declarations) */ - -#if defined(CPU_X86) || defined(CPU_X64) -# include "q68-jit-x86.h" -#elif defined(CPU_PSP) -# include "q68-jit-psp.h" -#else -# error Dynamic translation is not supported on this platform -#endif - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * q68_jit_init: Allocate memory for JIT data. Must be called before any - * other JIT function. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero on success, zero on error - */ -int q68_jit_init(Q68State *state) -{ - state->jit_table = - state->malloc_func(sizeof(*state->jit_table) * Q68_JIT_TABLE_SIZE); - if (!state->jit_table) { - DMSG("No memory for JIT table"); - goto error_return; - } - state->jit_hashchain = - state->malloc_func(sizeof(*state->jit_hashchain) * Q68_JIT_TABLE_SIZE); - if (!state->jit_hashchain) { - DMSG("No memory for JIT hash chain table"); - goto error_free_jit_table; - } - - /* Make sure all entries are marked as unused (so we don't try to free - * invalid pointers in q68_jit_reset()) */ - int i; - for (i = 0; i < Q68_JIT_TABLE_SIZE; i++) { - state->jit_table[i].m68k_start = 0; - } - - /* Make sure page table is clear (so writes before processor reset - * don't trigger JIT clearing */ - memset(state->jit_pages, 0, sizeof(state->jit_pages)); - - /* Default to no cache flush function */ - state->jit_flush = NULL; - -#ifdef Q68_DISABLE_ADDRESS_ERROR - /* Hack to avoid compiler warnings about unused functions */ - if (0) { - JIT_EMIT_CHECK_ALIGNED_EA(&state->jit_table[0], 0, 0); - JIT_EMIT_CHECK_ALIGNED_SP(&state->jit_table[0], 0, 0); - } -#endif - - return 1; - - error_free_jit_table: - state->free_func(state->jit_table); - state->jit_table = NULL; - error_return: - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_reset: Reset the dynamic translation state, clearing out all - * previously stored data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_jit_reset(Q68State *state) -{ - int index; - - state->jit_abort = 0; - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start) { - clear_entry(state, &state->jit_table[index]); - } - } - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - state->jit_hashchain[index] = NULL; - } - state->jit_total_data = 0; - state->jit_timestamp = 0; - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - state->jit_blacklist[index].m68k_start = 0; - state->jit_blacklist[index].m68k_end = 0; - } - state->jit_in_blist = 0; - state->jit_blist_num = 0; - state->jit_callstack_top = 0; - memset(state->jit_pages, 0, sizeof(state->jit_pages)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_cleanup: Destroy all JIT-related data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_jit_cleanup(Q68State *state) -{ - q68_jit_reset(state); - state->free_func(state->jit_hashchain); - state->jit_hashchain = NULL; - state->free_func(state->jit_table); - state->jit_table = NULL; -} - -/*************************************************************************/ - -/** - * q68_jit_translate: Dynamically translate a block of instructions - * starting at the given address. If a translation already exists for the - * given address, it is cleared. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL on error - */ -Q68JitEntry *q68_jit_translate(Q68State *state, uint32_t address) -{ - int index; - - if (address == 0) { - /* We use address 0 to indicate an unused entry, so we can't - * translate from address 0. But this should never happen except - * in pathological cases (or unhandled exceptions), so just punt - * and let the interpreter handle it */ - return NULL; - } - if (address & 1) { - /* Odd addresses are invalid, so we can't translate them in the - * first place */ - return NULL; - } - address &= 0xFFFFFF; - - /* Check whether we're trying to translate a blacklisted address. */ - - if (state->jit_in_blist) { - index = state->jit_blist_num; - /* See whether we've exited the blacklisted block */ - if (address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end - ) { - return NULL; - } - state->jit_in_blist = 0; - } // We might have entered another blacklisted block, so no "else" here - - if (!state->jit_in_blist) { - /* See if we're in a blacklisted block, and skip its translation - * if so */ - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end - ) { - uint32_t dt = state->jit_timestamp - - state->jit_blacklist[index].timestamp; - if (dt < Q68_JIT_BLACKLIST_TIMEOUT) { - state->jit_in_blist = 1; - state->jit_blist_num = index; - return NULL; - } else { - /* Entry expired, so clear it */ - state->jit_blacklist[index].m68k_start = 0; - state->jit_blacklist[index].m68k_end = 0; - } - } - } - } - - /* Clear out any existing translation, then search for an empty slot in - * the hash table. If we've reached the data size limit, first evict - * old entries until we're back under the limit. */ - q68_jit_clear(state, address); - while (state->jit_total_data >= Q68_JIT_DATA_LIMIT) { - clear_oldest_entry(state); - } - const int hashval = JIT_HASH(address); - index = hashval; - int oldest = index; - while (state->jit_table[index].m68k_start != 0) { - if (TIMESTAMP_COMPARE(state->jit_timestamp, - state->jit_table[index].timestamp, - state->jit_table[oldest].timestamp) < 0) { - oldest = index; - } - index++; - /* Using an if here is faster than taking the remainder with % */ - if (UNLIKELY(index >= Q68_JIT_TABLE_SIZE)) { - index = 0; - } - if (UNLIKELY(index == hashval)) { - /* Out of entries, so clear the oldest one and use it */ -#ifdef Q68_JIT_VERBOSE - DMSG("No free slots for code at $%06X, clearing oldest ($%06X)", - (int)address, (int)state->jit_table[oldest].m68k_start); -#endif - clear_entry(state, &state->jit_table[oldest]); - index = oldest; - } - } - current_entry = &state->jit_table[index]; - - /* Initialize the new entry */ - - current_entry->native_code = state->malloc_func(Q68_JIT_BLOCK_EXPAND_SIZE); - if (!current_entry->native_code) { - DMSG("No memory for code at $%06X", address); - current_entry = NULL; - return NULL; - } - current_entry->next = state->jit_hashchain[hashval]; - if (state->jit_hashchain[hashval]) { - state->jit_hashchain[hashval]->prev = current_entry; - } - state->jit_hashchain[hashval] = current_entry; - current_entry->prev = NULL; - current_entry->state = state; - current_entry->m68k_start = address; - current_entry->native_size = Q68_JIT_BLOCK_EXPAND_SIZE; - current_entry->native_length = 0; - current_entry->exec_address = NULL; - current_entry->timestamp = state->jit_timestamp; - current_entry->must_clear = 0; - JIT_EMIT_PROLOGUE(current_entry); - - /* Clear out the branch target cache and unresolved branch list */ - for (index = 0; index < lenof(btcache); index++) { - btcache[index].m68k_address = 0; - } - btcache_index = 0; - for (index = 0; index < lenof(unres_branches); index++) { - unres_branches[index].m68k_target = 0; - } - - /* Translate a block of 68000 code */ - - jit_PC = address; - const uint32_t limit = address + Q68_JIT_MAX_BLOCK_SIZE; - int done = 0; - while (!done && jit_PC < limit) { - /* Make sure we haven't entered a blacklisted block */ - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (UNLIKELY(address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end) - ) { - const uint32_t age = state->jit_timestamp - - state->jit_blacklist[index].timestamp; - if (age < Q68_JIT_BLACKLIST_TIMEOUT) { - done = 1; - break; - } else { - /* Entry expired, so clear it */ - state->jit_blacklist[index].m68k_start = 0; - state->jit_blacklist[index].m68k_end = 0; - } - } - } - if (LIKELY(!done)) { - done = translate_insn(state, current_entry); - } - } - - /* Close out the translated block */ - - JIT_EMIT_EPILOGUE(current_entry); - current_entry->m68k_end = jit_PC - 1; - for (index = current_entry->m68k_start >> Q68_JIT_PAGE_BITS; - index <= current_entry->m68k_end >> Q68_JIT_PAGE_BITS; - index++ - ) { - JIT_PAGE_SET(state, index); - } - void *newptr = state->realloc_func(current_entry->native_code, - current_entry->native_length); - if (newptr) { - current_entry->native_code = newptr; - current_entry->native_size = current_entry->native_length; - } - state->jit_total_data += current_entry->native_size; - /* Prepare the block for execution so it can be immediately passed to - * q68_jit_run() (see q68_jit_find() for why we do it here) */ - current_entry->exec_address = current_entry->native_code; - - Q68JitEntry *retval = current_entry; - current_entry = NULL; - if (state->jit_flush) { - state->jit_flush(); - } - return retval; -} - -/*************************************************************************/ - -/** - * q68_jit_find: Find the translated block for a given address, if any. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL if no such - * block exists - */ -Q68JitEntry *q68_jit_find(Q68State *state, uint32_t address) -{ - const int hashval = JIT_HASH(address); - Q68JitEntry *entry = state->jit_hashchain[hashval]; - while (entry) { - if (entry->m68k_start == address) { - /* Prepare the block for execution. We set exec_address here - * both to avoid overhead in q68_jit_run(), and because - * exec_address could be non-NULL if (for example) the native - * code stopped due to reaching the cycle limit and the core - * then serviced an interrupt. */ - entry->exec_address = entry->native_code; - return entry; - } - entry = entry->next; - } - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_run: Run translated 68000 code. - * - * [Parameters] - * state: Processor state block - * cycle_limit: Clock cycle limit on execution (code will stop when - * state->cycles >= cycles) - * address_ptr: Pointer to translated block to execute; will be cleared - * to NULL on return if the end of the block was reached - * [Return value] - * None - */ -void q68_jit_run(Q68State *state, uint32_t cycle_limit, - Q68JitEntry **entry_ptr) -{ - Q68JitEntry *entry = *entry_ptr; - - again: - entry->timestamp = state->jit_timestamp; - state->jit_timestamp++; - entry->running = 1; - int cycles = JIT_CALL(state, cycle_limit - state->cycles, - &entry->exec_address); - entry->running = 0; - state->jit_abort = 0; - state->cycles += cycles & 0x3FFF; - - if (UNLIKELY(entry->must_clear)) { - clear_entry(state, entry); - entry = NULL; - } else if (cycles & 0x8000) { // BSR/JSR/RTS/RTR - if (cycles & 0x4000) { // RTS/RTR - entry = NULL; - unsigned int top = state->jit_callstack_top; - unsigned int i; - for (i = Q68_JIT_CALLSTACK_SIZE; i > 0; i--) { - top = (top + Q68_JIT_CALLSTACK_SIZE-1) % Q68_JIT_CALLSTACK_SIZE; - if (state->jit_callstack[top].return_PC == state->PC) { - entry = state->jit_callstack[top].return_entry; - entry->exec_address = - state->jit_callstack[top].return_native; - state->jit_callstack_top = top; - if (state->cycles < cycle_limit) { - goto again; - } else { - break; - } - } - } - } else { // BSR/JSR - const unsigned int top = state->jit_callstack_top; - const uint32_t return_PC = READU32(state, state->A[7]); - state->jit_callstack[top].return_PC = return_PC; - state->jit_callstack[top].return_entry = entry; - state->jit_callstack[top].return_native = entry->exec_address; - state->jit_callstack_top = (top+1) % Q68_JIT_CALLSTACK_SIZE; - entry = NULL; - } - } else if (!entry->exec_address) { - entry = NULL; - } - - /* If we finished a block, we still have cycles to go, there's no - * exception pending, and there's already a translated block at the - * next PC, jump right to it so we don't incur the extra overhead of - * returning to the caller */ - if (!entry && state->cycles < cycle_limit && !state->exception) { - entry = q68_jit_find(state, state->PC); - if (entry) { - goto again; - } - } - - *entry_ptr = entry; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_clear: Clear any translation beginning at the given address. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * None - */ -void q68_jit_clear(Q68State *state, uint32_t address) -{ - const int hashval = JIT_HASH(address); - Q68JitEntry *entry = state->jit_hashchain[hashval]; - while (entry) { - if (entry->m68k_start == address) { - clear_entry(state, entry); - return; - } - entry = entry->next; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_clear_page: Clear any translation which occurs in the JIT page - * containing the given address. Intended for use on writes from external - * sources. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * [Return value] - * None - */ -void q68_jit_clear_page(Q68State *state, uint32_t address) -{ - const uint32_t page = address >> Q68_JIT_PAGE_BITS; -#ifdef Q68_JIT_VERBOSE - DMSG("WARNING: jit_clear_page($%06X)", page << Q68_JIT_PAGE_BITS); -#endif - - int index; - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start != 0 - && state->jit_table[index].m68k_start >> Q68_JIT_PAGE_BITS <= page - && state->jit_table[index].m68k_end >> Q68_JIT_PAGE_BITS >= page - ) { - if (UNLIKELY(state->jit_table[index].running)) { - state->jit_table[index].must_clear = 1; - state->jit_abort = 1; - } else { - clear_entry(state, &state->jit_table[index]); - } - } - } - - JIT_PAGE_CLEAR(state, page); -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_clear_write: Clear any translation which includes the given - * address, and (if there is at least one such translation) blacklist the - * address from being translated. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * size: Size of data written - * [Return value] - * None - */ -void q68_jit_clear_write(Q68State *state, uint32_t address, uint32_t size) -{ - int index; - - /* If the address is in a blacklisted block, we don't need to do - * anything (but update the timestamp to extend its timeout) */ - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end - ) { - state->jit_blacklist[index].timestamp = state->jit_timestamp; - return; - } - } - - /* Clear the translations-exist flag now; we'll set it later if we - * find a translation on the page that we don't clear */ - const uint32_t page = address >> Q68_JIT_PAGE_BITS; - const uint32_t page_start = page << Q68_JIT_PAGE_BITS; - const uint32_t page_end = ((page+1) << Q68_JIT_PAGE_BITS) - 1; - JIT_PAGE_CLEAR(state, page); - - /* Clear any translations affected by the address, and determine - * the range to be blacklisted. We default to assuming the address is - * the last byte/word of the longest possible instruction (10 bytes: - * MOVE.L #$12345678, ($12345678).l), but do not extend backwards past - * the beginning of a block. */ - int found = 0; - uint32_t start = address + size, end = address + (size-1); -#ifdef Q68_JIT_VERBOSE - DMSG("WARNING: jit_clear_write($%06X,%d)", (int)address, (int)size); -#endif - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start == 0) { - continue; - } - if (state->jit_table[index].m68k_start < address + size - && state->jit_table[index].m68k_end >= address) { - found = 1; - if (start > state->jit_table[index].m68k_start) { - /* Use the earliest start address of those we see */ - start = state->jit_table[index].m68k_start; - } - if (UNLIKELY(state->jit_table[index].running)) { - state->jit_table[index].must_clear = 1; - state->jit_abort = 1; - } else { - clear_entry(state, &state->jit_table[index]); - } - } else if (state->jit_table[index].m68k_start <= page_start - && state->jit_table[index].m68k_end >= page_end) { - /* No need to clear this one, so set the page bit again */ - JIT_PAGE_SET(state, page); - } - } - if (!found || start < (address & ~1) - 8) { - start = (address & ~1) - 8; - } - - /* Add the blacklist entry */ -#ifdef Q68_JIT_VERBOSE - DMSG("Blacklisting $%06X...$%06X", (int)start, (int)end); -#endif - /* First see if this overlaps with another entry */ - found = 0; - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (state->jit_blacklist[index].m68k_start <= end - && state->jit_blacklist[index].m68k_end >= start) { -#ifdef Q68_JIT_VERBOSE - DMSG("(Merging with $%06X...%06X)", - (int)state->jit_blacklist[index].m68k_start, - (int)state->jit_blacklist[index].m68k_end); -#endif - if (start > state->jit_blacklist[index].m68k_start) { - start = state->jit_blacklist[index].m68k_start; - } - if (end < state->jit_blacklist[index].m68k_end) { - end = state->jit_blacklist[index].m68k_end; - } - found = 1; - break; - } - } - /* Otherwise, add this as a new entry; if there are no free slots, - * evict the oldest entry */ - if (!found) { - int oldest = 0; - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (state->jit_blacklist[index].m68k_start == 0) { - found = 1; - break; - } else if (TIMESTAMP_COMPARE(state->jit_timestamp, - state->jit_blacklist[index].timestamp, - state->jit_blacklist[oldest].timestamp) < 0) { - oldest = index; - } - } - if (!found) { - index = oldest; - } - } - state->jit_blacklist[index].m68k_start = start; - state->jit_blacklist[index].m68k_end = end; - state->jit_blacklist[index].timestamp = state->jit_timestamp; -} - -/*************************************************************************/ -/************************ Local helper functions *************************/ -/*************************************************************************/ - -/** - * translate_insn: Translate a single 68000 instruction. - * - * [Parameters] - * state: Processor state block - * entry: Q68JitEntry structure pointer - * [Return value] - * Nonzero if the instruction marks the end of the block, else zero - */ -static int translate_insn(Q68State *state, Q68JitEntry *entry) -{ - /* See if there are any branches to this address we can update */ - int i; - for (i = 0; i < lenof(unres_branches); i++) { - if (unres_branches[i].m68k_target == jit_PC) { - JIT_FIXUP_BRANCH(entry, unres_branches[i].native_offset, - current_entry->native_length); - unres_branches[i].m68k_target = 0; - } - } - - /* Update the branch target cache with this address */ - btcache[btcache_index].m68k_address = jit_PC; - btcache[btcache_index].native_offset = current_entry->native_length; - btcache_index = (btcache_index + 1) % lenof(btcache); - - /* Fetch the next instruction */ - const unsigned int opcode = IFETCH(state); - state->current_PC = jit_PC; - - /* Emit a cycle count check if appropriate */ -#ifdef Q68_JIT_LOOSE_TIMING - if ((opcode & 0xFF00) == 0x6100 // Bcc - || (opcode & 0xF0F8) == 0x50C8 // DBcc - || (opcode & 0xFFF0) == 0x4E40 // TRAP - || (opcode & 0xFF80) == 0x4E80 // JSR/JMP - || opcode == 0x4E72 // STOP - || opcode == 0x4E73 // RTE - || opcode == 0x4E75 // RTS - || opcode == 0x4E77 // RTR -# ifdef Q68_M68K_TESTER // Define when linking with m68k-tester - || opcode == 0x7100 // m68k-tester abort opcode -# endif - ) { -#endif - JIT_EMIT_CHECK_CYCLES(current_entry); -#ifdef Q68_JIT_LOOSE_TIMING - } -#endif - - /* Add a trace call if we're tracing */ -#ifdef Q68_TRACE - JIT_EMIT_TRACE(current_entry); -#endif - - /* Translate the instruction itself and update the 68000 PC */ - PC_updated = 0; - const unsigned int index = (opcode>>9 & 0x78) | (opcode>>6 & 0x07); - int done = (*opcode_table[index])(state, opcode); - /* Only update the PC if the function didn't do so itself (see e.g. - * op_imm() to SR), but check the jit_abort flag unless we're - * terminating anyway */ - if (!done) { - if (!PC_updated) { - const int32_t advance = jit_PC - (state->current_PC - 2); - JIT_EMIT_ADVANCE_PC_CHECK_ABORT(current_entry, advance); - } else { - JIT_EMIT_CHECK_ABORT(current_entry); - } - } else { - if (!PC_updated) { - advance_PC(state); - } - } - - return done; -} - -/*************************************************************************/ - -/** - * clear_entry: Clear a specific entry from the JIT table, freeing the - * native code buffer and unlinking the entry from its references. - * - * [Parameters] - * state: Processor state block - * entry: Q68JitEntry structure pointer - * [Return value] - * None - */ -static void clear_entry(Q68State *state, Q68JitEntry *entry) -{ - /* Clear the entry out of the call stack first */ - int i; - for (i = 0; i < Q68_JIT_CALLSTACK_SIZE; i++) { - if (state->jit_callstack[i].return_entry == entry) { - state->jit_callstack[i].return_PC = 0; - } - } - - /* Free the native code */ - state->jit_total_data -= entry->native_size; - state->free_func(entry->native_code); - entry->native_code = NULL; - - /* Clear the entry from the table and hash chain */ - if (entry->next) { - entry->next->prev = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } else { - state->jit_hashchain[JIT_HASH(entry->m68k_start)] = entry->next; - } - - /* Mark the entry as free */ - entry->m68k_start = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * clear_oldest_entry: Clear the oldest entry from the JIT table. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -static void clear_oldest_entry(Q68State *state) -{ - int oldest = -1; - int index; - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start == 0) { - continue; - } - if (oldest < 0 - || TIMESTAMP_COMPARE(state->jit_timestamp, - state->jit_table[index].timestamp, - state->jit_table[oldest].timestamp) < 0) { - oldest = index; - } - } - if (LIKELY(oldest >= 0)) { - clear_entry(state, &state->jit_table[oldest]); - } else { - DMSG("Tried to clear oldest entry from an empty table!"); - /* Set the total size to zero, just in case something weird happened */ - state->jit_total_data = 0; - } -} - -/*************************************************************************/ - -/** - * expand_buffer: Expands the native code buffer in the given JIT entry by - * Q68_JIT_BLOCK_EXPAND_SIZE. - * - * [Parameters] - * entry: Q68JitEntry structure pointer - * [Return value] - * Nonzero on success, zero on failure (out of memory) - */ -static int expand_buffer(Q68JitEntry *entry) -{ - const uint32_t newsize = entry->native_size + Q68_JIT_BLOCK_EXPAND_SIZE; - void *newptr = entry->state->realloc_func(entry->native_code, newsize); - if (!newptr) { - DMSG("Out of memory"); - return 0; - } - entry->native_code = newptr; - entry->native_size = newsize; - return 1; -} - -/*************************************************************************/ - -/** - * btcache_lookup: Search the branch target cache for the given 68000 - * address. - * - * [Parameters] - * address: 68000 address to search for - * [Return value] - * Corresponding byte offset into current_entry->native_code, or -1 if - * the address could not be found - */ -static int32_t btcache_lookup(uint32_t address) -{ - /* Search backwards from the current instruction so we can handle short - * loops quickly; note that btcache_index is now pointing to where the - * _next_ instruction will go */ - const int current = (btcache_index + (lenof(btcache)-1)) % lenof(btcache); - int index = current; - do { - if (btcache[index].m68k_address == address) { - return btcache[index].native_offset; - } - index = (index + (lenof(btcache)-1)) % lenof(btcache); - } while (index != current); - return -1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * record_unresolved_branch: Record the given branch target and native - * offset in an empty slot in the unresolved branch table. If there are - * no empty slots, purge the oldest (lowest native offset) entry. - * - * [Parameters] - * m68k_target: Branch target address in 68000 address space - * native_offset: Offset of branch to update in native code - * [Return value] - * None - */ -static void record_unresolved_branch(uint32_t m68k_target, - uint32_t native_offset) -{ - int oldest = 0; - int i; - for (i = 0; i < lenof(unres_branches); i++) { - if (unres_branches[i].m68k_target == 0) { - oldest = i; - break; - } else if (unres_branches[i].native_offset - < unres_branches[oldest].native_offset) { - oldest = i; - } - } - unres_branches[oldest].m68k_target = m68k_target; - unres_branches[oldest].native_offset = native_offset; -} - -/*************************************************************************/ - -/** - * JIT_EMIT_TEST_cc: Emit the appropriate TEST_* operation depending on - * the specified condition. - * - * [Parameters] - * cond: Condition code - * entry: Q68JitEntry structure pointer - */ -static inline void JIT_EMIT_TEST_cc(int cond, Q68JitEntry *entry) -{ - switch ((cond)) { - case COND_T: JIT_EMIT_TEST_T (entry); break; - case COND_F: JIT_EMIT_TEST_F (entry); break; - case COND_HI: JIT_EMIT_TEST_HI(entry); break; - case COND_LS: JIT_EMIT_TEST_LS(entry); break; - case COND_CC: JIT_EMIT_TEST_CC(entry); break; - case COND_CS: JIT_EMIT_TEST_CS(entry); break; - case COND_NE: JIT_EMIT_TEST_NE(entry); break; - case COND_EQ: JIT_EMIT_TEST_EQ(entry); break; - case COND_VC: JIT_EMIT_TEST_VC(entry); break; - case COND_VS: JIT_EMIT_TEST_VS(entry); break; - case COND_PL: JIT_EMIT_TEST_PL(entry); break; - case COND_MI: JIT_EMIT_TEST_MI(entry); break; - case COND_GE: JIT_EMIT_TEST_GE(entry); break; - case COND_LT: JIT_EMIT_TEST_LT(entry); break; - case COND_GT: JIT_EMIT_TEST_GT(entry); break; - case COND_LE: JIT_EMIT_TEST_LE(entry); break; - } -} - -/*************************************************************************/ - -/** - * advance_PC: Emit JIT code to advance the PC to the location indicated - * by jit_PC, and set the PC_updated flag so that the PC is not advanced - * again after the current instruction has been processed. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -static void advance_PC(Q68State *state) -{ - JIT_EMIT_ADVANCE_PC(current_entry, jit_PC - (state->current_PC - 2)); - PC_updated = 1; -} - -/*************************************************************************/ - -/** - * raise_exception: Emit JIT code to raise an exception. - * - * [Parameters] - * state: Processor state block - * num: Exception number - * [Return value] - * Nonzero (end translated block) - */ -static int raise_exception(Q68State *state, uint8_t num) -{ - JIT_EMIT_EXCEPTION(current_entry, num); - return 1; -} - -/*************************************************************************/ - -/** - * op_ill: Emit JIT code to handle a generic illegal opcode. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * [Return value] - * Nonzero (end translated block) - */ -static inline int op_ill(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_ILLEGAL_INSTRUCTION); -} - -/*************************************************************************/ -/*************************************************************************/ - -#ifdef Q68_JIT_OPTIMIZE_FLAGS - -/** - * cc_needed: Return whether any condition code outputs are required from - * the current instruction, based on the instruction located at jit_PC. - * - * This routine assumes that the current and following instructions are - * valid ones; certain illegal forms of instructions may be incorrectly - * treated as valid and thus cause an incorrect result. - * - * [Parameters] - * state: Processor state block - * opcode: Opcode of the instruction currently being processed - * [Return value] - * Nonzero if condition code outputs are required, zero otherwise - */ -static unsigned int cc_needed(Q68State *state, uint16_t opcode) -{ - const uint16_t next_opcode = READU16(state, jit_PC); - const unsigned int this_output = cc_info(opcode) & 0x1F; - const unsigned int next_input = (cc_info(next_opcode) >> 8) & 0x1F; - const unsigned int next_output = cc_info(next_opcode) & 0x1F; - /* A condition code output from this instruction is known to be - * unneeded if the following instruction (1) does not use that - * condition code as input and (2) also outputs to the same condition - * code. We want to know whether there are any condition codes in the - * current instruction's output set for which these conditions are - * _not_ fulfilled. */ - return this_output & ~(~next_input & next_output); -} - -/*************************************************************************/ - -/** - * cc_info: Return a bitmask of which condition codes are used and which - * are modified by the given opcode. - * - * [Parameters] - * opcode: Opcode to check - * [Return value] - * Bits 12-8: Which of XNZVC are used as input by the given opcode - * Bits 4-0: Which of XNZVC are modified by the given opcode - */ -static unsigned int cc_info(uint16_t opcode) -{ - const unsigned int INPUT_XNZVC = 0x1F00; - const unsigned int INPUT_XZ = 0x1400; - const unsigned int INPUT_X = 0x1000; - const unsigned int INPUT_N = 0x0800; - const unsigned int INPUT_V = 0x0200; - const unsigned int INPUT_NONE = 0x0000; - const unsigned int OUTPUT_XNZVC = 0x001F; - const unsigned int OUTPUT_XZC = 0x0015; - const unsigned int OUTPUT_NZVC = 0x000F; - const unsigned int OUTPUT_N = 0x0008; - const unsigned int OUTPUT_Z = 0x0004; - const unsigned int OUTPUT_NONE = 0x0000; - static const unsigned int cond_inputs[] = { - [COND_T ] = 0x0000, - [COND_F ] = 0x0000, - [COND_HI] = 0x0500, - [COND_LS] = 0x0500, - [COND_CC] = 0x0100, - [COND_CS] = 0x0100, - [COND_NE] = 0x0400, - [COND_EQ] = 0x0400, - [COND_VC] = 0x0200, - [COND_VS] = 0x0200, - [COND_PL] = 0x0800, - [COND_MI] = 0x0800, - [COND_GE] = 0x0A00, - [COND_LT] = 0x0A00, - [COND_GT] = 0x0E00, - [COND_LE] = 0x0E00, - }; - - switch (opcode>>12) { - - case 0x0: - if (opcode & 0x100) { - if ((opcode>>3 & 7) == 1) { // MOVEP - return INPUT_NONE | OUTPUT_NONE; - } else { // BTST, etc. (dynamic) - return INPUT_NONE | OUTPUT_Z; - } - } else if ((opcode>>6 & 3) == 3) { // Illegal (size==3) - return 0; - } else { - switch (opcode>>9 & 7) { - case 0: // ORI - if ((opcode & 0xBF) == 0x3C) { // ORI to CCR/SR - return INPUT_XNZVC | OUTPUT_XNZVC; - } else { - return INPUT_NONE | OUTPUT_NZVC; - } - case 1: // ANDI - if ((opcode & 0xBF) == 0x3C) { // ANDI to CCR/SR - return INPUT_XNZVC | OUTPUT_XNZVC; - } else { - return INPUT_NONE | OUTPUT_NZVC; - } - case 2: // SUBI - return INPUT_NONE | OUTPUT_XNZVC; - case 3: // ADDI - return INPUT_NONE | OUTPUT_XNZVC; - case 4: // BTST, etc. (static) - return INPUT_NONE | OUTPUT_Z; - case 5: // EORI - if ((opcode & 0xBF) == 0x3C) { // EORI to CCR/SR - return INPUT_XNZVC | OUTPUT_XNZVC; - } else { - return INPUT_NONE | OUTPUT_NZVC; - } - case 6: // CMPI - return INPUT_NONE | OUTPUT_NZVC; - case 7: // Illegal - return 0; - } - } - - case 0x1: - case 0x2: - case 0x3: - if ((opcode>>6 & 7) == 1) { // MOVEA.[LW] - return INPUT_NONE | OUTPUT_NONE; - } else { // MOVE.[BLW] - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0x4: - if (opcode & 0x0100) { - switch (opcode>>6 & 3) { - case 0: // Illegal - case 1: // Illegal - return 0; - case 2: // CHK - /* N is unmodified if no exception occurs, so treat as input */ - return INPUT_N | OUTPUT_N; - case 3: // LEA - return INPUT_NONE | OUTPUT_NONE; - } - } else { - switch (opcode & 0x0EC0) { - case 0x0000: // NEGX.B - case 0x0040: // NEGX.W - case 0x0080: // NEGX.L - return INPUT_XZ | OUTPUT_XNZVC; - case 0x00C0: // MOVE from SR - return INPUT_XNZVC | OUTPUT_NONE; - case 0x0200: // CLR.B - case 0x0240: // CLR.W - case 0x0280: // CLR.L - return INPUT_NONE | OUTPUT_NZVC; - case 0x02C0: // Illegal - return 0; - case 0x0400: // NEG.B - case 0x0440: // NEG.W - case 0x0480: // NEG.L - return INPUT_NONE | OUTPUT_XNZVC; - case 0x04C0: // MOVE to CCR - return INPUT_NONE | OUTPUT_XNZVC; - case 0x0600: // NOT.B - case 0x0640: // NOT.W - case 0x0680: // NOT.L - return INPUT_NONE | OUTPUT_NZVC; - case 0x06C0: // MOVE to SR - return INPUT_NONE | OUTPUT_XNZVC; - case 0x0800: // NBCD - return INPUT_XZ | OUTPUT_XZC; - case 0x0840: // PEA - if ((opcode>>3 & 7) == 0) { // SWAP.L - return INPUT_NONE | OUTPUT_NZVC; - } else { - return INPUT_NONE | OUTPUT_NONE; - } - case 0x0880: // MOVEM.W reglist, - case 0x08C0: // MOVEM.L reglist, - if ((opcode>>3 & 7) == 0) { // EXT.* - return INPUT_NONE | OUTPUT_NZVC; - } else { - return INPUT_NONE | OUTPUT_NONE; - } - case 0x0A00: // TST.B - case 0x0A40: // TST.W - case 0x0A80: // TST.L - case 0x0AC0: // TAS - return INPUT_NONE | OUTPUT_NZVC; - case 0x0C00: // TST.B - return 0; - case 0x0C40: // Miscellaneous - switch (opcode>>3 & 7) { - case 0: // TRAP #0-7 - case 1: // TRAP #8-15 - case 2: // LINK - case 3: // UNLK - case 4: // MOVE from USP - case 5: // MOVE to USP - return INPUT_NONE | OUTPUT_NONE; - case 6: // Miscellaneous - switch (opcode & 7) { - case 0: // RESET - case 1: // NOP - return INPUT_NONE | OUTPUT_NONE; - case 2: // STOP - case 3: // RTE - return INPUT_NONE | OUTPUT_XNZVC; - case 4: // Illegal - return 0; - case 5: // RTS - return INPUT_NONE | OUTPUT_NONE; - case 6: // TRAPV - return INPUT_V | OUTPUT_NONE; - case 7: // RTR - return INPUT_NONE | OUTPUT_XNZVC; - } - case 7: // Illegal - return 0; - } - case 0x0C80: // MOVEM.W ,reglist - case 0x0CC0: // MOVEM.L ,reglist - return INPUT_NONE | OUTPUT_NONE; - case 0x0E00: // Illegal - case 0x0E40: // Illegal - return 0; - case 0x0E80: // JSR - case 0x0EC0: // JMP - return INPUT_NONE | OUTPUT_NONE; - } - } - - case 0x5: - if ((opcode>>6 & 3) == 3) { // Scc/DBcc - return cond_inputs[opcode>>8 & 0xF] | OUTPUT_NONE; - } else { // ADDQ/SUBQ - if ((opcode>>3 & 7) == 1) { // Address register target - return INPUT_NONE | OUTPUT_NONE; - } else { // Other target - return INPUT_NONE | OUTPUT_XNZVC; - } - } - - case 0x6: - /* Bcc/BSR */ - return cond_inputs[opcode>>8 & 0xF] | OUTPUT_NONE; - - case 0x7: - if (opcode & 0x0100) { // Illegal - return 0; - } else { // MOVEQ - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0x8: - if ((opcode>>6 & 3) == 3) { // MULS/MULU - return INPUT_NONE | OUTPUT_NZVC; - } else if ((opcode & 0x01F0) == 0x0100) { // SBCD - return INPUT_XZ | OUTPUT_XZC; - } else { // OR - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0x9: - if ((opcode>>6 & 3) == 3) { // SUBA - return INPUT_NONE | OUTPUT_NONE; - } else if ((opcode & 0x0130) == 0x0100) { // SUBX - return INPUT_XZ | OUTPUT_XNZVC; - } else { // SUB - return INPUT_NONE | OUTPUT_XNZVC; - } - - case 0xA: - /* Nothing here */ - return 0; - - case 0xB: - /* CMP/CMPA/CMPM/EOR */ - return INPUT_NONE | OUTPUT_NZVC; - - case 0xC: - if ((opcode>>6 & 3) == 3) { // DIVS/DIVD - return INPUT_NONE | OUTPUT_NZVC; - } else if ((opcode & 0x01F0) == 0x0100) { // ABCD - return INPUT_XZ | OUTPUT_XZC; - } else if ((opcode & 0x0130) == 0x0100) { // EXG - return INPUT_NONE | OUTPUT_NONE; - } else { // AND - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0xD: - if ((opcode>>6 & 3) == 3) { // ADDA - return INPUT_NONE | OUTPUT_NONE; - } else if ((opcode & 0x0130) == 0x0100) { // ADDX - return INPUT_XZ | OUTPUT_XNZVC; - } else { // ADD - return INPUT_NONE | OUTPUT_XNZVC; - } - - case 0xE: - /* Shift/rotate */ - return INPUT_X | OUTPUT_XNZVC; - - case 0xF: - /* Nothing here */ - return 0; - - } // switch (opcode>>12) - - return 0; // Should be unreachable, but just for safety -} - -#endif // Q68_JIT_OPTIMIZE_FLAGS - -/*************************************************************************/ -/*************************************************************************/ - -/** - * ea_resolve: Emit JIT code to resolve the address for the - * memory-reference EA indicated by opcode[5:0] and store it in - * state->ea_addr. Behavior is undefined if the EA is a direct register - * reference. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * access_type: Access type (ACCESS_*) - * [Return value] - * Clock cycles used (negative indicates an illegal EA) - */ -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type) -{ - const unsigned int mode = EA_MODE(opcode); - const unsigned int reg = EA_REG(opcode); - const unsigned int bytes = SIZE_TO_BYTES(size); - - static const int base_cycles[8] = {0, 0, 4, 4, 6, 8, 10, 0}; - int cycles = base_cycles[mode] + (size==SIZE_L ? 4 : 0); - - switch (mode) { - case EA_INDIRECT: - JIT_EMIT_RESOLVE_INDIRECT(current_entry, (8+reg)*4); - break; - case EA_POSTINCREMENT: - if (bytes == 1 && reg == 7) { // A7 must stay even - JIT_EMIT_RESOLVE_POSTINC_A7_B(current_entry); - } else { - JIT_EMIT_RESOLVE_POSTINC(current_entry, (8+reg)*4, bytes); - } - break; - case EA_PREDECREMENT: - if (access_type == ACCESS_WRITE) { - /* 2-cycle penalty not applied to write-only accesses - * (MOVE and MOVEM) */ - cycles -= 2; - } - if (bytes == 1 && reg == 7) { // A7 must stay even - JIT_EMIT_RESOLVE_PREDEC_A7_B(current_entry); - } else { - JIT_EMIT_RESOLVE_PREDEC(current_entry, (8+reg)*4, bytes); - } - break; - case EA_DISPLACEMENT: - JIT_EMIT_RESOLVE_DISP(current_entry, (8+reg)*4, (int16_t)IFETCH(state)); - break; - case EA_INDEX: { - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int8_t disp = (int8_t)ext; - if (ext & 0x0800) { - JIT_EMIT_RESOLVE_INDEX_L(current_entry, (8+reg)*4, ireg*4, disp); - } else { - JIT_EMIT_RESOLVE_INDEX_W(current_entry, (8+reg)*4, ireg*4, disp); - } - break; - } - default: /* case EA_MISC */ - switch (reg) { - case EA_MISC_ABSOLUTE_W: - cycles += 8; - JIT_EMIT_RESOLVE_ABSOLUTE(current_entry, (int16_t)IFETCH(state)); - break; - case EA_MISC_ABSOLUTE_L: { - cycles += 12; - uint32_t addr = IFETCH(state) << 16; - addr |= (uint16_t)IFETCH(state); - JIT_EMIT_RESOLVE_ABSOLUTE(current_entry, addr); - break; - } - case EA_MISC_PCREL: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 8; - JIT_EMIT_RESOLVE_ABSOLUTE( - current_entry, state->current_PC + (int16_t)IFETCH(state) - ); - } - break; - case EA_MISC_PCREL_INDEX: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 10; - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int32_t disp = (int32_t)((int8_t)ext); - if (ext & 0x0800) { - JIT_EMIT_RESOLVE_ABS_INDEX_L( - current_entry, state->current_PC + disp, ireg*4 - ); - } else { - JIT_EMIT_RESOLVE_ABS_INDEX_W( - current_entry, state->current_PC + disp, ireg*4 - ); - } - } - break; - default: - return -1; - } - } - return cycles; -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_get: Emit JIT code to read an unsigned value from the EA indicated - * by opcode[5:0] and use it as either the first or the second operand to - * an operation, as specified by the op_num parameter. - * - * If the EA selector is invalid for the access size and mode, an illegal - * instruction exception is raised, and the error is indicated by a - * negative value returned in *cycles_ret. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * is_rmw: Nonzero if the operand will be modified and written back - * cycles_ret: Pointer to variable to receive clock cycles used - * (negative indicates an illegal EA) - * op_num: Which operand to read the value into (1 or 2) - * [Return value] - * None - */ -static void ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret, int op_num) -{ - switch (EA_MODE(opcode)) { - - case EA_DATA_REG: - *cycles_ret = 0; - if (op_num == 1) { - JIT_EMIT_GET_OP1_REGISTER(current_entry, EA_REG(opcode) * 4); - } else { - JIT_EMIT_GET_OP2_REGISTER(current_entry, EA_REG(opcode) * 4); - } - break; - - case EA_ADDRESS_REG: - *cycles_ret = 0; - if (size == SIZE_B) { - /* An.b not permitted */ - raise_exception(state, EX_ILLEGAL_INSTRUCTION); - *cycles_ret = -1; - return; - } else { - if (op_num == 1) { - JIT_EMIT_GET_OP1_REGISTER(current_entry, - (8 + EA_REG(opcode)) * 4); - } else { - JIT_EMIT_GET_OP2_REGISTER(current_entry, - (8 + EA_REG(opcode)) * 4); - } - } - break; - - case EA_MISC: - if (EA_REG(opcode) == EA_MISC_IMMEDIATE) { - if (is_rmw) { - raise_exception(state, EX_ILLEGAL_INSTRUCTION); - *cycles_ret = -1; - return; - } else { - *cycles_ret = (size==SIZE_L ? 8 : 4); - uint32_t val; - val = IFETCH(state); - if (size == SIZE_B) { - val &= 0xFF; - } else if (size == SIZE_L) { - val <<= 16; - val |= (uint16_t)IFETCH(state); - } - if (op_num == 1) { - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, val); - } else { - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, val); - } - } - break; - } - /* else fall through */ - - default: - *cycles_ret = ea_resolve(state, opcode, size, - is_rmw ? ACCESS_MODIFY : ACCESS_READ); - if (*cycles_ret < 0) { - raise_exception(state, EX_ILLEGAL_INSTRUCTION); - return; - } - if (size == SIZE_B) { - if (op_num == 1) { - JIT_EMIT_GET_OP1_EA_B(current_entry); - } else { - JIT_EMIT_GET_OP2_EA_B(current_entry); - } - } else if (size == SIZE_W) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ - ); -#endif - if (op_num == 1) { - JIT_EMIT_GET_OP1_EA_W(current_entry); - } else { - JIT_EMIT_GET_OP2_EA_W(current_entry); - } - } else { // size == SIZE_L -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ - ); -#endif - if (op_num == 1) { - JIT_EMIT_GET_OP1_EA_L(current_entry); - } else { - JIT_EMIT_GET_OP2_EA_L(current_entry); - } - } - break; - - } // switch (EA_MODE(opcode)) -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_set: Emit JIT code to update a value at the EA indicated by - * opcode[5:0]. If the EA is a memory reference, uses the previously - * resolved address in state->ea_addr rather than resolving the address - * again. Behavior is undefined if the previous ea_resolve() or ea_get() - * failed (or if no previous call was made). - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * [Return value] - * None - */ -static void ea_set(Q68State *state, uint32_t opcode, int size) -{ - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - if (size == SIZE_B) { - JIT_EMIT_SET_REGISTER_B(current_entry, EA_REG(opcode) * 4); - } else if (size == SIZE_W) { - JIT_EMIT_SET_REGISTER_W(current_entry, EA_REG(opcode) * 4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, EA_REG(opcode) * 4); - } - return; - case EA_ADDRESS_REG: - if (size == SIZE_W) { - JIT_EMIT_SET_AREG_W(current_entry, (8 + EA_REG(opcode)) * 4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, (8 + EA_REG(opcode)) * 4); - } - return; - default: { - if (size == SIZE_B) { - JIT_EMIT_SET_EA_B(current_entry); - } else if (size == SIZE_W) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE - ); -#endif - JIT_EMIT_SET_EA_W(current_entry); - } else { // size == SIZE_L -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE - ); -#endif - JIT_EMIT_SET_EA_L(current_entry); - } - return; - } - } -} - -/*************************************************************************/ -/*********************** Major instruction groups ************************/ -/*************************************************************************/ - -/** - * op_imm: Immediate instructions (format 0000 xxx0 xxxx xxxx). - */ -static int op_imm(Q68State *state, uint32_t opcode) -{ - /* Check for bit-twiddling and illegal opcodes first */ - enum {OR = 0, AND, SUB, ADD, _BIT, EOR, CMP, _ILL} aluop; - aluop = opcode>>9 & 7; - if (aluop == _BIT) { - return op_bit(state, opcode); - } else if (aluop == _ILL) { - return op_ill(state, opcode); - } - - /* Get the instruction size */ - INSN_GET_SIZE; - if (size == 3) { - return op_ill(state, opcode); - } - - /* Fetch the immediate value */ - int cycles_dummy; - ea_get(state, EA_MISC<<3 | EA_MISC_IMMEDIATE, size, 0, &cycles_dummy, 1); - - /* Fetch the EA operand (which may be SR or CCR) */ - int use_SR; - int cycles; - if ((aluop==OR || aluop==AND || aluop==EOR) && (opcode & 0x3F) == 0x3C) { - /* xxxI #imm,SR (or CCR) use the otherwise-invalid form of an - * immediate value destination */ - use_SR = 1; - cycles = 8; // Total instruction time is 20 cycles - switch (size) { - case SIZE_B: - JIT_EMIT_GET_OP2_CCR(current_entry); - break; - case SIZE_W: - JIT_EMIT_CHECK_SUPER(current_entry); - JIT_EMIT_GET_OP2_SR(current_entry); - break; - default: - return op_ill(state, opcode); - } - } else { - use_SR = 0; - ea_get(state, opcode, size, 1, &cycles, 2); - if (cycles < 0) { - return 1; - } - } - - /* Check whether we need to output condition codes */ - const int do_cc = cc_needed(state, opcode); - - /* Perform the operation */ - switch (aluop) { - case OR: if (size == SIZE_B) { - JIT_EMIT_OR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_OR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_OR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case AND: if (size == SIZE_B) { - JIT_EMIT_AND_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_AND_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_AND_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case EOR: if (size == SIZE_B) { - JIT_EMIT_EOR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_EOR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_EOR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case CMP: if (size == SIZE_L) { // CMPI takes less time in most cases - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 8; - } else { - cycles -= 2; - } - } else { - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 4; - } - } - if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_L(current_entry); - } - break; - case SUB: if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - break; - default: // case ADD - if (size == SIZE_B) { - JIT_EMIT_ADD_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADD_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADD_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_L(current_entry); - } - break; - } - - /* Update the cycle counter (and PC) before writing the result, in case - * a change to SR triggers an interrupt */ - cycles += (size==SIZE_L ? 16 : 8); - cycles += (EA_MODE(opcode) == EA_DATA_REG ? 0 : 4); - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - advance_PC(state); - - /* Update the EA operand (if not CMPI) */ - if (aluop != CMP) { - if (use_SR) { - if (size == SIZE_B) { - JIT_EMIT_SET_CCR(current_entry); - } else { - JIT_EMIT_SET_SR(current_entry); - } - } else { - ea_set(state, opcode, size); - } - } - - /* All done */ - return 0; -} - -/*************************************************************************/ - -/** - * op_bit: Bit-twiddling instructions (formats 0000 rrr1 xxxx xxxx and - * 0000 1000 xxxx xxxx). - */ -static int op_bit(Q68State *state, uint32_t opcode) -{ - /* Check early for MOVEP (coded as BTST/BCHG/BCLR/BSET Dn,An) */ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - if (opcode & 0x0100) { - return opMOVP(state, opcode); - } else { - return op_ill(state, opcode); - } - } - - enum {BTST = 0, BCHG = 1, BCLR = 2, BSET = 3} op = opcode>>6 & 3; - int cycles; - - /* Get the bit number to operate on */ - if (opcode & 0x0100) { - /* Bit number in register */ - INSN_GET_REG; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - cycles = 0; - } else { - unsigned int bitnum = IFETCH(state); - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, bitnum); - cycles = 4; - } - - /* EA operand is 32 bits when coming from a register, 8 when from memory */ - int size = (EA_MODE(opcode)==EA_DATA_REG ? SIZE_L : SIZE_B); - int cycles_tmp; - ea_get(state, opcode, size, 1, &cycles_tmp, 2); - if (cycles_tmp < 0) { - return 1; - } - cycles += cycles_tmp; - if (size == SIZE_L && (op == BCLR || op == BTST)) { - cycles += 2; - } - - /* Perform the operation: first test the bit, then (for non-BTST cases) - * twiddle it as appropriate. All size-related checking is performed - * in BTST, so the remaining operations are unsized. */ - if (size == SIZE_B) { - JIT_EMIT_BTST_B(current_entry); - } else { // size == SIZE_L - JIT_EMIT_BTST_L(current_entry); - } - switch (op) { - default: break; // case BTST: nothing to do - case BCHG: JIT_EMIT_BCHG(current_entry); break; - case BCLR: JIT_EMIT_BCLR(current_entry); break; - case BSET: JIT_EMIT_BSET(current_entry); break; - } - - /* Update EA operand (but not for BTST) */ - if (op != BTST) { - ea_set(state, opcode, size); - } - - /* Update cycle counter; note that the times for BCHG.L, BCLR.L, and - * BSET.L are maximums (though how they vary is undocumented) */ - JIT_EMIT_ADD_CYCLES(current_entry, (op==BTST ? 4 : 8) + cycles); - - return 0; -} - -/*************************************************************************/ - -/** - * opMOVE: MOVE.[bwl] instruction (format {01,10,11}xx xxxx xxxx xxxx). - */ -static int opMOVE(Q68State *state, uint32_t opcode) -{ - const int size = (opcode>>12==1 ? SIZE_B : opcode>>12==2 ? SIZE_L : SIZE_W); - - int cycles_src; - ea_get(state, opcode, size, 0, &cycles_src, 1); - if (cycles_src < 0) { - return 1; - } - - /* Rearrange the opcode bits so we can pass the destination EA to - * ea_resolve() */ - const uint32_t dummy_opcode = (opcode>>9 & 7) | (opcode>>3 & 0x38); - int cycles_dest; - if (EA_MODE(dummy_opcode) <= EA_ADDRESS_REG) { - cycles_dest = 0; - } else { - cycles_dest = ea_resolve(state, dummy_opcode, size, ACCESS_WRITE); - if (cycles_dest < 0) { - return op_ill(state, opcode); - } - } - - /* Copy the operand to the result and set flags (if needed) */ - const int do_cc = cc_needed(state, opcode); - if (EA_MODE(dummy_opcode) == EA_ADDRESS_REG) { - if (size == SIZE_W) { - JIT_EMIT_EXT_L(current_entry); - } else { // size == SIZE_L - JIT_EMIT_MOVE_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_MOVE_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_MOVE_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_MOVE_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - } - - /* Update the destination EA and cycle count */ - ea_set(state, dummy_opcode, size); - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles_src + cycles_dest); - - return 0; -} - -/*************************************************************************/ - -/** - * op4xxx: Miscellaneous instructions (format 0100 xxx0 xxxx xxxx). - */ -static int op4xxx(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>7 & 0x1C) | (opcode>>6 & 3); - return (*opcode_4xxx_table[index])(state, opcode); -} - -/*************************************************************************/ - -/** - * op_CHK: CHK instruction (format 0100 rrr1 10xx xxxx). - */ -static int op_CHK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - - int cycles; - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - ea_get(state, opcode, SIZE_W, 0, &cycles, 2); - if (cycles < 0) { - return 1; - } - - JIT_EMIT_ADD_CYCLES(current_entry, 10 + cycles); - /* The JIT code takes care of adding the extra 34 cycles of exception - * processing if necessary */ - JIT_EMIT_CHK_W(current_entry); - return 0; -} - -/*************************************************************************/ - -/** - * op_LEA: LEA instruction (format 0100 rrr1 11xx xxxx). - */ -static int op_LEA(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - - /* Register, predecrement, postincrement, immediate modes are illegal */ - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } - - JIT_EMIT_LEA(current_entry, (8+reg)*4); - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opADSQ: ADDQ and SUBQ instructions (format 0101 iiix xxxx xxxx). - */ -static int opADSQ(Q68State *state, uint32_t opcode) -{ - const int is_sub = opcode & 0x0100; - INSN_GET_COUNT; - INSN_GET_SIZE; - if (EA_MODE(opcode) == EA_ADDRESS_REG && size == 1) { - size = 2; // ADDQ.W #imm,An is equivalent to ADDQ.L #imm,An - } - - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, count); - - int cycles; - ea_get(state, opcode, size, 1, &cycles, 2); - if (cycles < 0) { - return 1; - } - - const int do_cc = cc_needed(state, opcode); - if (is_sub) { - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - JIT_EMIT_SUB_L(current_entry); - } else { - if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - } - } else { - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - JIT_EMIT_ADD_L(current_entry); - } else { - if (size == SIZE_B) { - JIT_EMIT_ADD_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADD_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADD_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_L(current_entry); - } - } - } - - ea_set(state, opcode, size); - - cycles += (size==SIZE_L || EA_MODE(opcode) == EA_ADDRESS_REG ? 8 : 4); - cycles += (EA_MODE(opcode) >= EA_INDIRECT ? 4 : 0); - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_Scc: Scc instruction (format 0101 cccc 11xx xxxx). - */ -static int op_Scc(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - /* DBcc Dn,disp is coded as Scc An with an extension word */ - return opDBcc(state, opcode); - } - - INSN_GET_COND; - /* From the cycle counts, it looks like this is a standard read/write - * access rather than a write-only access */ - int cycles; - if (EA_MODE(opcode) == EA_DATA_REG) { - cycles = 0; - } else { - cycles = ea_resolve(state, opcode, SIZE_B, ACCESS_MODIFY); - if (cycles < 0) { - return op_ill(state, opcode); - } - } - JIT_EMIT_TEST_cc(cond, current_entry); - JIT_EMIT_Scc(current_entry); - if (EA_MODE(opcode) == EA_DATA_REG) { - /* Scc Dn is a special case */ - JIT_EMIT_ADD_CYCLES_Scc_Dn(current_entry); - } else { - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - } - ea_set(state, opcode, SIZE_B); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_DBcc: DBcc instruction (format 0101 cccc 1100 1xxx). - */ -static int opDBcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - INSN_GET_REG0; - INSN_GET_IMM16; - uint32_t target = state->current_PC + imm16; - int32_t offset = btcache_lookup(target); - JIT_EMIT_TEST_cc(cond, current_entry); - if (offset >= 0) { - JIT_EMIT_DBcc_native(current_entry, reg0*4, target, offset); - } else { - JIT_EMIT_DBcc(current_entry, reg0*4, target); - } - return 0; -} - -/*************************************************************************/ - -/** - * op_Bcc: Conditional branch instructions (format 0110 cccc dddd dddd). - */ -static int op_Bcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - INSN_GET_DISP8; - int cycles = 0; - if (disp == 0) { - disp = (int16_t)IFETCH(state); - cycles = 4; - } - uint32_t target = state->current_PC + disp; - if (cond == COND_F) { - /* BF is really BSR */ -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 18); - advance_PC(state); - JIT_EMIT_BSR(current_entry, jit_PC, target); - return 0; - } else { - int32_t offset; -#ifdef Q68_OPTIMIZE_IDLE - /* FIXME: Temporary hack to improve PSP performance */ - if (target == 0x1066 - && ((cond == COND_EQ && state->current_PC - 2 == 0x001092) - || (cond == COND_PL && state->current_PC - 2 == 0x0010B4)) - ) { - /* BIOS intro animation */ - JIT_EMIT_ADD_CYCLES(current_entry, - 468); // Length of one loop when idle - } else if (target == 0x10BC - && ((cond == COND_PL && state->current_PC - 2 == 0x001122) - || (cond == COND_T && state->current_PC - 2 == 0x00116A)) - ) { - /* Azel: Panzer Dragoon RPG (JP) */ - JIT_EMIT_ADD_CYCLES(current_entry, - 178*4); // Assuming a cycle_limit of 768 - } -#endif - if (target < state->current_PC) { - offset = btcache_lookup(target); - } else { - offset = -1; // Forward jumps can't be in the cache - } - JIT_EMIT_TEST_cc(cond, current_entry); - if (offset >= 0) { - JIT_EMIT_Bcc_native(current_entry, target, offset); - } else { - int32_t branch_offset; - JIT_EMIT_Bcc(current_entry, target, &branch_offset); - if (target >= state->current_PC && branch_offset >= 0) { - record_unresolved_branch(target, branch_offset); - } - } - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - return 0; - } -} - -/*************************************************************************/ - -/** - * opMOVQ: MOVEQ instruction (format 0111 rrr0 iiii iiii). - */ -static int opMOVQ(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_IMM8; - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, imm8); - const int do_cc = cc_needed(state, opcode); - JIT_EMIT_MOVE_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*************************************************************************/ - -/** - * op_alu: Non-immediate ALU instructions (format 1ooo rrrx xxxx xxxx for - * ooo = 000, 001, 011, 100, 101). - */ -static int op_alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - - /* Pass off special and invalid instructions early */ - if (size != 3) { - if ((opcode & 0xB130) == 0x9100) { - /* ADDX/SUBX are coded as ADD/SUB.* Dn, */ - return opADSX(state, opcode); - } - if ((opcode & 0xB1F0) == 0x8100) { - /* ABCD/SBCD are coded as AND/OR.b Dn, */ - return op_BCD(state, opcode); - } - if ((opcode & 0xF130) == 0xC100) { - /* EXG is coded as AND.[wl] Dn, */ - return op_EXG(state, opcode); - } - if ((opcode & 0xF130) == 0x8100) { - /* OR.[wl] Dn, is invalid on the 68000 (later PACK/UNPK) */ - return op_ill(state, opcode); - } - if ((opcode & 0xF138) == 0xB108 && (opcode>>6 & 3) != 3) { - /* CMPM is coded as EOR.* Dn, */ - return opCMPM(state, opcode); - } - } - - int ea_dest = opcode & 0x100; - int areg_dest = 0; // For ADDA/SUBA/CMPA - enum {OR, AND, EOR, CMP, SUB, ADD} aluop; - - /* Find the instruction for the opcode group */ - switch (opcode>>12) { - case 0x8: aluop = OR; break; - case 0x9: aluop = SUB; break; - case 0xB: aluop = (((opcode>>6)+1) & 7) <= 4 ? CMP : EOR; break; - case 0xC: aluop = AND; break; - default: aluop = ADD; break; // case 0xD - } - - /* Handle the special formats of ADDA/SUBA/CMPA */ - if ((aluop == ADD || aluop == SUB || aluop == CMP) && size == 3) { - size = ea_dest ? SIZE_L : SIZE_W; - ea_dest = 0; - areg_dest = 1; - } - - /* Retrieve the register and EA values; make sure to load operand 1 - * first, since operand 2 may be destroyed by memory operations */ - int cycles; - if (ea_dest) { - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - ea_get(state, opcode, size, ea_dest, &cycles, 2); - } else { - ea_get(state, opcode, size, ea_dest, &cycles, 1); - if (areg_dest) { - JIT_EMIT_GET_OP2_REGISTER(current_entry, (8+reg)*4); - } else { - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg*4); - } - } - if (cycles < 0) { - return 1; - } - if (size == SIZE_L || areg_dest) { - cycles += 4; - } - if (ea_dest) { - cycles += 4; - } else if ((aluop == CMP && areg_dest) - || (size == SIZE_L - && (EA_MODE(opcode) <= EA_ADDRESS_REG - || (EA_MODE(opcode) == EA_MISC - && EA_REG(opcode) == EA_MISC_IMMEDIATE)))) { - cycles -= 2; - } - - /* Perform the actual computation */ - const int do_cc = cc_needed(state, opcode); - switch (aluop) { - case OR: if (size == SIZE_B) { - JIT_EMIT_OR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_OR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_OR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case AND: if (size == SIZE_B) { - JIT_EMIT_AND_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_AND_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_AND_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case EOR: if (size == SIZE_B) { - JIT_EMIT_EOR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_EOR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_EOR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case CMP: if (areg_dest && size == SIZE_W) { - JIT_EMIT_SUBA_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_L(current_entry); - } - break; - case SUB: if (areg_dest && size == SIZE_W) { - JIT_EMIT_SUBA_W(current_entry); - } else if (areg_dest && size == SIZE_L) { - JIT_EMIT_SUB_L(current_entry); - } else if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - break; - default: // case ADD - if (areg_dest && size == SIZE_W) { - JIT_EMIT_ADDA_W(current_entry); - } else if (areg_dest && size == SIZE_L) { - JIT_EMIT_ADD_L(current_entry); - } else if (size == SIZE_B) { - JIT_EMIT_ADD_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADD_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADD_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_L(current_entry); - } - break; - } // switch (aluop) - - /* Store the result in the proper place (if the instruction is not CMP) */ - if (aluop != CMP) { - if (ea_dest) { - ea_set(state, opcode, size); - } else if (areg_dest) { - JIT_EMIT_SET_REGISTER_L(current_entry, (8+reg)*4); - } else if (size == SIZE_B) { - JIT_EMIT_SET_REGISTER_B(current_entry, reg*4); - } else if (size == SIZE_W) { - JIT_EMIT_SET_REGISTER_W(current_entry, reg*4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - } - } - - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_DIV: DIVU and DIVS instructions (format 1000 rrrx 11xx xxxx). - */ -static int op_DIV(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - int cycles; - ea_get(state, opcode, SIZE_W, 0, &cycles, 1); - if (cycles < 0) { - return 1; - } - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg*4); - /* Add the EA cycles now, in case a divide-by-zero exception occurs */ - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - - if (sign) { - JIT_EMIT_DIVS_W(current_entry); - } else { - JIT_EMIT_DIVU_W(current_entry); - } - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - - /* The 68000 docs say that the timing difference between best and - * worst cases is less than 10%, so we just return the worst case */ - JIT_EMIT_ADD_CYCLES(current_entry, sign ? 158 : 140); - return 0; -} - -/*************************************************************************/ - -/** - * opAxxx: $Axxx illegal instruction set (format 1010 xxxx xxxx xxxx). - */ -static int opAxxx(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_LINE_1010); -} - -/*************************************************************************/ - -/** - * op_MUL: MULU and MULS instructions (format 1100 rrrx 11xx xxxx). - */ -static int op_MUL(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - int cycles; - ea_get(state, opcode, SIZE_W, 0, &cycles, 1); - if (cycles < 0) { - return 1; - } - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg*4); - - const int do_cc = cc_needed(state, opcode); - if (sign) { - JIT_EMIT_MULS_W(current_entry); - } else { - JIT_EMIT_MULU_W(current_entry); - } - /* 16*16 -> 32 multiplication can't produce carry or overflow, so we - * can treat it like a logical operation for setting condition codes */ - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - - JIT_EMIT_ADD_CYCLES(current_entry, 54 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opshft: Shift and rotate instructions (format 1110 xxxx xxxx xxxx). - */ -static int opshft(Q68State *state, uint32_t opcode) -{ - const int is_left = opcode & 0x0100; - INSN_GET_SIZE; - INSN_GET_COUNT; - INSN_GET_REG0; - int is_memory; - int type; // Shift/rotate type (0=ASL/ASR, 1=LSL/LSR, ...) - int cycles; - - if (size == 3) { - /* Memory shift/rotate */ - is_memory = 1; - if ((opcode & 0x0800) || EA_MODE(opcode) <= EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - size = SIZE_W; - type = opcode>>9 & 3; - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, 1); - ea_get(state, opcode, size, 1, &cycles, 2); - if (cycles < 0) { - return 1; - } - } else { - /* Register shift/rotate */ - is_memory = 0; - type = opcode>>3 & 3; - if (opcode & 0x0020) { - INSN_GET_REG; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - } else { - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, count); - } - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg0*4); - cycles = 0; - } - - switch (type) { - case 0: // ASL/ASR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_ASL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ASL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ASL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_ASR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ASR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ASR_L(current_entry); - } - } - break; - case 1: // LSL/LSR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_LSL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_LSL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_LSL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_LSR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_LSR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_LSR_L(current_entry); - } - } - break; - case 2: // ROXL/ROXR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_ROXL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROXL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROXL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_ROXR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROXR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROXR_L(current_entry); - } - } - break; - case 3: // ROL/ROR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_ROL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_ROR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROR_L(current_entry); - } - } - break; - } // switch (type) - - if (is_memory) { - ea_set(state, opcode, size); - } else if (size == SIZE_B) { - JIT_EMIT_SET_REGISTER_B(current_entry, reg0*4); - } else if (size == SIZE_W) { - JIT_EMIT_SET_REGISTER_W(current_entry, reg0*4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, reg0*4); - } - - /* Cycles based on count are added in the shift/rotate processing */ - JIT_EMIT_ADD_CYCLES(current_entry, (size==SIZE_L ? 8 : 6) + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opFxxx: $Fxxx illegal instruction set (format 1111 xxxx xxxx xxxx). - */ -static int opFxxx(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_LINE_1111); -} - -/*************************************************************************/ -/*********************** $4xxx group instructions ************************/ -/*************************************************************************/ - -/** - * op4alu: Single-operand ALU instructions in the $4xxx opcode range - * (format 0100 ooo0 ssxx xxxx for ooo = 000, 001, 010, 011, 101). - */ -static int op4alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_SIZE; - enum {NEGX = 0, CLR = 1, NEG = 2, NOT = 3, TST = 5} aluop; - aluop = opcode>>9 & 7; - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Retrieve the EA value */ - int cycles; - ea_get(state, opcode, size, 1, &cycles, 1); - if (cycles < 0) { - return 1; - } - if (aluop != TST) { - if (EA_MODE(opcode) == EA_DATA_REG) { - if (size == SIZE_L) { - cycles += 2; - } - } else { - cycles += (size == SIZE_L) ? 8 : 4; - } - } - - /* Perform the actual computation */ - /* For simplicity, use the 2-argument operations with 0 or ~0 as the - * second operand: - * -n = 0 - n - * 0 = 0 & n - * ~n = ~0 ^ n - * n = 0 | n - */ - JIT_EMIT_GET_OP2_IMMEDIATE(current_entry, aluop==NOT ? ~(uint32_t)0 : 0); - const int do_cc = cc_needed(state, opcode); - switch (aluop) { - case NEGX:if (size == SIZE_B) { - JIT_EMIT_SUBX_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUBX_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUBX_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_L(current_entry); - } - break; - case NEG: if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - break; - case CLR: if (size == SIZE_B) { - JIT_EMIT_AND_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_AND_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_AND_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case NOT: if (size == SIZE_B) { - JIT_EMIT_EOR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_EOR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_EOR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - default: // case TST - if (size == SIZE_B) { - JIT_EMIT_OR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_OR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_OR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - } // switch (aluop) - - /* Store the result in the proper place (if the instruction is not TST) */ - if (aluop != TST) { - ea_set(state, opcode, size); - } - - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opMVSR: MOVE to/from SR/CCR instructions (format 0100 0xx0 11xx xxxx). - */ -static int opMVSR(Q68State *state, uint32_t opcode) -{ - int is_CCR; - int ea_dest; - int cycles; - switch (opcode>>9 & 3) { - case 0: // MOVE SR, - is_CCR = 0; - ea_dest = 1; - cycles = (EA_MODE(opcode) == EA_DATA_REG) ? 6 : 8; - break; - case 1: // Undefined (MOVE CCR, on 68010) - return op_ill(state, opcode); - case 2: // MOVE ,CCR - is_CCR = 1; - ea_dest = 0; - cycles = 12; - break; - default: // MOVE ,SR (case 3) - JIT_EMIT_CHECK_SUPER(current_entry); - is_CCR = 0; - ea_dest = 0; - cycles = 12; - break; - } - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Motorola docs say the address is read before being written, even - * for the SR, format; also, the access size is a word even for - * CCR operations. */ - int cycles_tmp; - ea_get(state, opcode, SIZE_W, ea_dest, &cycles_tmp, 1); - if (cycles_tmp < 0) { - return 1; - } - cycles += cycles_tmp; - - /* Update the cycle counter (and PC) before writing the result, in case - * a change to SR triggers an interrupt */ - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - advance_PC(state); - - if (ea_dest) { - if (is_CCR) { - JIT_EMIT_GET_OP1_CCR(current_entry); - } else { - JIT_EMIT_GET_OP1_SR(current_entry); - } - JIT_EMIT_MOVE_W(current_entry); - ea_set(state, opcode, SIZE_W); - } else { - JIT_EMIT_MOVE_W(current_entry); - /* No need to set condition codes--we're about to overwrite them */ - if (is_CCR) { - JIT_EMIT_SET_CCR(current_entry); - } else { - JIT_EMIT_SET_SR(current_entry); - } - } - - return 0; -} - -/*************************************************************************/ - -/** - * opNBCD: NBCD instruction (format 0100 1000 00xx xxxx). - */ -static int opNBCD(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - ea_get(state, opcode, SIZE_B, 1, &cycles, 1); - if (cycles < 0) { - return 1; - } - - /* Treat it as something like SBCD ,#0 for simplicity */ - JIT_EMIT_GET_OP2_IMMEDIATE(current_entry, 0); - JIT_EMIT_SBCD(current_entry); - - ea_set(state, opcode, SIZE_B); - JIT_EMIT_ADD_CYCLES(current_entry, - (EA_MODE(opcode) == EA_DATA_REG ? 6 : 8) + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_PEA: PEA instruction (format 0100 1000 01xx xxxx). - */ -static int op_PEA(Q68State *state, uint32_t opcode) -{ - /* SWAP is coded as PEA Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return opSWAP(state, opcode); - } - - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } - -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_PEA(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opSWAP: SWAP instruction (format 0100 1000 0100 0rrr). - */ -static int opSWAP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg0*4); - const int do_cc = cc_needed(state, opcode); - JIT_EMIT_SWAP(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg0*4); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*************************************************************************/ - -/** - * op_TAS: TAS instruction (format 0100 1010 11xx xxxx). Also covers the - * ILLEGAL instruction (format 0100 1010 1111 1100). - */ -static int op_TAS(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - ea_get(state, opcode, SIZE_B, 1, &cycles, 1); - if (cycles < 0) { - /* Note that the ILLEGAL instruction is coded as TAS #imm, so it - * will be rejected as unwriteable by ea_get() */ - return 1; - } - JIT_EMIT_TAS(current_entry); - ea_set(state, opcode, SIZE_B); - JIT_EMIT_ADD_CYCLES(current_entry, - (EA_MODE(opcode) == EA_DATA_REG ? 4 : 10) + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_EXT: EXT instruction (format 0100 1000 1s00 0rrr). - */ -static int op_EXT(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg0*4); - const int do_cc = cc_needed(state, opcode); - if (opcode & 0x0040) { - JIT_EMIT_EXT_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg0*4); - } else { - JIT_EMIT_EXT_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - JIT_EMIT_SET_REGISTER_W(current_entry, reg0*4); - } - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*************************************************************************/ - -/** - * op_STM: MOVEM reglist, (i.e. STore Multiple) instruction (format - * 0100 1000 1sxx xxxx). - */ -static int op_STM(Q68State *state, uint32_t opcode) -{ - /* EXT.* is coded as MOVEM.* reglist,Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return op_EXT(state, opcode); - } - - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT // Not allowed for store - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_PREDECREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_WRITE); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (regmask != 0) { // FIXME: does a real 68000 choke even if regmask==0? -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - } - - if (EA_MODE(opcode) == EA_PREDECREMENT) { - /* Register order is reversed in predecrement mode */ - int reg; - for (reg = 15; reg >= 0; reg--, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - JIT_EMIT_STORE_DEC_W(current_entry, reg*4); - cycles += 4; - } else { - JIT_EMIT_STORE_DEC_L(current_entry, reg*4); - cycles += 8; - } - } - } - JIT_EMIT_MOVEM_WRITEBACK(current_entry, (8 + EA_REG(opcode)) * 4); - } else { - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - JIT_EMIT_STORE_INC_W(current_entry, reg*4); - cycles += 4; - } else { - JIT_EMIT_STORE_INC_L(current_entry, reg*4); - cycles += 8; - } - } - } - } - - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_LDM: MOVEM ,reglist (i.e. LoaD Multiple) instruction (format - * 0100 1100 1sxx xxxx). - */ -static int op_LDM(Q68State *state, uint32_t opcode) -{ - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_PREDECREMENT // Not allowed for load - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (regmask != 0) { // FIXME: does a real 68000 choke even if regmask==0? -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - } - - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - if (reg < 8) { - JIT_EMIT_LOAD_INC_W(current_entry, reg*4); - } else { - JIT_EMIT_LOADA_INC_W(current_entry, reg*4); - } - cycles += 4; - } else { - JIT_EMIT_LOAD_INC_L(current_entry, reg*4); - cycles += 8; - } - } - } - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - JIT_EMIT_MOVEM_WRITEBACK(current_entry, (8 + EA_REG(opcode)) * 4); - } - - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opmisc: $4xxx-group misc. instructions (format 0100 1110 01xx xxxx). - */ -static int opmisc(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>3 & 7); - return (*opcode_4E4x_table[index])(state, opcode); -} - -/*-----------------------------------------------------------------------*/ - -/** - * opTRAP: TRAP #n instruction (format 0100 1110 0100 nnnn). - */ -static int opTRAP(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_TRAP + (opcode & 0x000F)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * opLINK: LINK instruction (format 0100 1110 0101 0rrr). - */ -static int opLINK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - int16_t disp = IFETCH(state); -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_GET_OP1_REGISTER(current_entry, (8+reg0)*4); - JIT_EMIT_PUSH_L(current_entry); - JIT_EMIT_GET_OP1_REGISTER(current_entry, (8+7)*4); - JIT_EMIT_MOVE_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+reg0)*4); - JIT_EMIT_GET_OP2_IMMEDIATE(current_entry, disp); - JIT_EMIT_ADD_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+7)*4); - JIT_EMIT_ADD_CYCLES(current_entry, 16); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opUNLK: UNLK instruction (format 0100 1110 0101 1rrr). - */ -static int opUNLK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - JIT_EMIT_GET_OP1_REGISTER(current_entry, (8+reg0)*4); - JIT_EMIT_MOVE_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+7)*4); -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_POP_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+reg0)*4); - JIT_EMIT_ADD_CYCLES(current_entry, 12); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opMUSP: MOVE An,USP and MOVE USP,An instructions (format - * 0100 1110 0110 xrrr). - */ -static int opMUSP(Q68State *state, uint32_t opcode) -{ - JIT_EMIT_CHECK_SUPER(current_entry); - INSN_GET_REG0; - if (opcode & 0x0008) { - JIT_EMIT_MOVE_TO_USP(current_entry, reg0*4); - } else { - JIT_EMIT_MOVE_FROM_USP(current_entry, reg0*4); - } - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op4E7x: Instructions with opcodes $4E70-$4E77 that don't fit anywhere - * else. - */ -static int op4E7x(Q68State *state, uint32_t opcode) -{ - switch (opcode & 7) { - case 0: // $4E70 RESET - JIT_EMIT_CHECK_SUPER(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 132); - return 0; - case 1: // $4E71 NOP - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; - case 2: // $4E72 STOP - JIT_EMIT_CHECK_SUPER(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - advance_PC(state); - JIT_EMIT_STOP(current_entry, IFETCH(state)); - return 1; - case 3: { // $4E73 RTE - JIT_EMIT_CHECK_SUPER(current_entry); -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 20); - JIT_EMIT_RTE(current_entry); - PC_updated = 1; - return 1; - } - case 5: // $4E75 RTS -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 16); - JIT_EMIT_RTS(current_entry); - PC_updated = 1; - return 1; - case 6: // $4E76 TRAPV - JIT_EMIT_TRAPV(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; - case 7: { // $4E77 RTR -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 20); - JIT_EMIT_RTR(current_entry); - PC_updated = 1; - return 1; - } - default: // $4E74 RTD is 68010 only - return op_ill(state, opcode); - } -} - -/*************************************************************************/ - -/** - * opjump: JSR and JMP instructions (format 0100 1110 1xxx xxxx). - */ -static int opjump(Q68State *state, uint32_t opcode) -{ - int is_jsr = ~opcode & 0x0040; - - /* JMP is essentially identical to LEA PC, and has the same - * constraints. JSR is equivalent to MOVE.L PC,-(A7) followed by a - * JMP to the address. Both use a separate timing table, however. */ - - int cycles; - switch (EA_MODE(opcode)) { - case EA_INDIRECT: - cycles = 8; - break; - case EA_DISPLACEMENT: - cycles = 10; - break; - case EA_INDEX: - cycles = 14; - break; - case EA_MISC: - switch (EA_REG(opcode)) { - case EA_MISC_ABSOLUTE_W: - cycles = 10; - break; - case EA_MISC_ABSOLUTE_L: - cycles = 12; - break; - case EA_MISC_PCREL: - cycles = 10; - break; - case EA_MISC_PCREL_INDEX: - cycles = 14; - break; - default: - return op_ill(state, opcode); - } - break; - default: - return op_ill(state, opcode); - } - if (is_jsr) { - cycles += 8; - } - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - advance_PC(state); - - ea_resolve(state, opcode, SIZE_W, ACCESS_READ); // cannot fail - if (is_jsr) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_JSR(current_entry, jit_PC); - return 0; - } else { - JIT_EMIT_JMP(current_entry); - return 1; - } -} - -/*************************************************************************/ -/******************* Other miscellaneous instructions ********************/ -/*************************************************************************/ - -/** - * opMOVP: MOVEP instruction (0000 rrr1 xx00 1rrr). - */ -static int opMOVP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - int to_memory = opcode & 0x0080; - int is_long = opcode & 0x0040; - int16_t disp = IFETCH(state); - - if (to_memory) { - if (is_long) { - JIT_EMIT_MOVEP_WRITE_L(current_entry, reg0*4, disp, reg*4); - } else { - JIT_EMIT_MOVEP_WRITE_W(current_entry, reg0*4, disp, reg*4); - } - } else { - if (is_long) { - JIT_EMIT_MOVEP_READ_L(current_entry, reg0*4, disp, reg*4); - } else { - JIT_EMIT_MOVEP_READ_W(current_entry, reg0*4, disp, reg*4); - } - } - - JIT_EMIT_ADD_CYCLES(current_entry, is_long ? 24 : 16); - return 0; -} - -/*************************************************************************/ - -/** - * opADSX: ADDX/SUBX instructions (1x01 rrr1 ss00 xrrr). - */ -static int opADSX(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - ea_get(state, src_ea, size, 0, &dummy, 1); - ea_get(state, dest_ea, size, 1, &dummy, 2); - - const int do_cc = cc_needed(state, opcode); - if (is_add) { - if (size == SIZE_B) { - JIT_EMIT_ADDX_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADDX_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADDX_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADDX_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADDX_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADDX_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_SUBX_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUBX_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUBX_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_L(current_entry); - } - } - - ea_set(state, dest_ea, size); - JIT_EMIT_ADD_CYCLES(current_entry, (is_memory ? (size==SIZE_L ? 30 : 18) - : (size==SIZE_L ? 8 : 4))); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_BCD: ABCD/SBCD instructions (1x00 rrr1 0000 xrrr). - */ -static int op_BCD(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - ea_get(state, src_ea, SIZE_B, 0, &dummy, 1); - ea_get(state, dest_ea, SIZE_B, 1, &dummy, 2); - - if (is_add) { - JIT_EMIT_ABCD(current_entry); - } else { - JIT_EMIT_SBCD(current_entry); - } - - ea_set(state, dest_ea, SIZE_B); - JIT_EMIT_ADD_CYCLES(current_entry, is_memory ? 18 : 6); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opCMPM: CMPM instructions (1011 rrr1 ss00 1rrr). - */ -static int opCMPM(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - - const uint16_t src_ea = EA_POSTINCREMENT<<3 | reg0; - const uint16_t dest_ea = EA_POSTINCREMENT<<3 | reg; - int dummy; - ea_get(state, src_ea, size, 0, &dummy, 1); - ea_get(state, dest_ea, size, 0, &dummy, 2); - - const int do_cc = cc_needed(state, opcode); // Just for consistency - if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_L(current_entry); - } - - JIT_EMIT_ADD_CYCLES(current_entry, SIZE_L ? 20 : 12); - return 0; -} - -/*************************************************************************/ - -/** - * op_EXG: EXG instruction (1100 rrr1 xx00 1rrr). - */ -static int op_EXG(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int mode = opcode & 0xF8; - - if (mode == 0x40) { - JIT_EMIT_EXG(current_entry, reg*4, reg0*4); - } else if (mode == 0x48) { - JIT_EMIT_EXG(current_entry, (8+reg)*4, (8+reg0)*4); - } else if (mode == 0x88) { - JIT_EMIT_EXG(current_entry, reg*4, (8+reg0)*4); - } else { - return op_ill(state, opcode); - } - JIT_EMIT_ADD_CYCLES(current_entry, 6); - return 0; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit.h b/yabause/src/q68/q68-jit.h deleted file mode 100644 index e57885bf3f..0000000000 --- a/yabause/src/q68/q68-jit.h +++ /dev/null @@ -1,81 +0,0 @@ -/* src/q68/q68-jit.h: Dynamic translation header for Q68 - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_JIT_H -#define Q68_JIT_H - -/*************************************************************************/ - -/* Info structure for translated code blocks */ -struct Q68JitEntry_ { - Q68JitEntry *next, *prev; // Hash table collision chain pointers - Q68State *state; // Associated processor state block - uint32_t m68k_start; // Code start address in 68000 address space - // (zero indicates a free entry) - uint32_t m68k_end; // Code end address in 68000 address space - OpcodeFunc *native_code; // Pointer to native code - uint32_t native_length; // Length of native code (bytes) - uint32_t native_size; // Size of native code buffer (bytes) - void *exec_address; // Next execution address (NULL if not started) - uint32_t timestamp; // Time this entry was added - uint8_t running; // Nonzero if entry is currently running - uint8_t must_clear; // Nonzero if entry must be cleared on completion -}; - -/* Hash function */ -#define JIT_HASH(addr) ((uint32_t)(addr) % Q68_JIT_TABLE_SIZE) - -/*************************************************************************/ - -/** - * TIMESTAMP_COMPARE: Compare two timestamps. - * - * [Parameters] - * a, b: Timestamps to compare - * reference: Reference timestamp by which the comparison is made - * [Return value] - * -1 if a < b (i.e. "a is older than b") - * 0 if a == b - * 1 if a > b - */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -static inline int TIMESTAMP_COMPARE(uint32_t reference, uint32_t a, uint32_t b) -{ - const uint32_t age_a = reference - a; - const uint32_t age_b = reference - b; - return age_a > age_b ? -1 : - age_a < age_b ? 1 : 0; -} - -/*************************************************************************/ - -#endif // Q68_JIT_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68.c b/yabause/src/q68/q68.c deleted file mode 100644 index 53125b8160..0000000000 --- a/yabause/src/q68/q68.c +++ /dev/null @@ -1,324 +0,0 @@ -/* src/q68/q68.c: Quick-and-dirty MC68000 emulator with dynamic - translation support - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "q68.h" -#include "q68-internal.h" - -/*************************************************************************/ - -/* - * The source code for Q68 is divided into the following files: - * - * q68.c (this file) -- Main interface function definitions - * q68.h -------------- Interface definition (users should include this header) - * q68-const.h -------- 68000-related constants (status register bits, etc.) - * q68-core.c --------- Processor execution core - * q68-disasm.c ------- 68000 instruction disassembly and tracing support - * (for debugging) - * q68-internal.h ----- General definitions and declarations for internal use - * q68-jit.c ---------- Dynamic ("just-in-time") translation support - * q68-jit.h ---------- Declarations used only by the JIT code - * q68-jit-psp.[hS] --- JIT implementation for the PSP's Allegrex processor - * q68-jit-x86.[hS] --- JIT implementation for the Intel x86 architecture - * (both 32-bit and 64-bit environments supported) - */ - -/*************************************************************************/ -/*************************************************************************/ - -/** - * q68_create: Create a new virtual processor. The virtual processor is - * created uninitialized; before starting the processor, the caller must - * set the IRQ level and read/write callbacks, then call q68_reset(). - * - * [Parameters] - * None - * [Return value] - * Processor state block on success, NULL on error - */ -Q68State *q68_create(void) -{ - return q68_create_ex(malloc, realloc, free); -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_create_ex: Create a new virtual processor, using the specified - * functions for all memory allocation. - * - * [Parameters] - * malloc_func: Function for allocating a memory block - * realloc_func: Function for adjusting the size of a memory block - * free_func: Function for freeing a memory block - * [Return value] - * Processor state block on success, NULL on error - */ -Q68State *q68_create_ex(void *(*malloc_func)(size_t size), - void *(*realloc_func)(void *ptr, size_t size), - void (*free_func)(void *ptr)) -{ - Q68State *state; - - state = (*malloc_func)(sizeof(*state)); - if (!state) { - return NULL; - } - state->malloc_func = malloc_func; - state->realloc_func = realloc_func; - state->free_func = free_func; - -#ifdef Q68_USE_JIT - if (!q68_jit_init(state)) { - state->free_func(state); - return NULL; - } -#endif - - state->halted = Q68_HALTED_DOUBLE_FAULT; // Let's initialize this, at least - return state; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_destroy: Free all resources used by a virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_destroy(Q68State *state) -{ -#ifdef Q68_USE_JIT - q68_jit_cleanup(state); -#endif - state->free_func(state); -} - -/*************************************************************************/ - -/** - * q68_set_irq: Set the interrupt request (IRQ) input to the processor. - * - * [Parameters] - * state: Processor state block - * irq: IRQ level (0-7) - * [Return value] - * None - */ -void q68_set_irq(Q68State *state, int irq) -{ - state->irq = irq & 7; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_set_{readb,readw,writeb,writew}_func: Set the read/write callback - * functions called by the virtual processor on memory accesses. - * - * For the read functions, only the lower 8 (readb) or 16 (readw) bits of - * the return value are used; the function does not need to sign-extend or - * zero-extend the value. Similarly, the value passed to the write - * functions will only have the low 8 (writeb) or 16 (writew) bits valid, - * and the function should ignore the upper bits of the value. - * - * For the word access functions (readw and writew), the address is - * guaranteed to be even, so the function does not need to check for this - * itself. (However, see the Q68_DISABLE_ADDRESS_ERROR configuration - * option in q68-internal.h.) - * - * [Parameters] - * state: Processor state block - * func: Callback function to set - * [Return value] - * None - */ -void q68_set_readb_func(Q68State *state, Q68ReadFunc func) -{ - state->readb_func = func; -} - -void q68_set_readw_func(Q68State *state, Q68ReadFunc func) -{ - state->readw_func = func; -} - -void q68_set_writeb_func(Q68State *state, Q68WriteFunc func) -{ - state->writeb_func = func; -} - -void q68_set_writew_func(Q68State *state, Q68WriteFunc func) -{ - state->writew_func = func; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_set_jit_flush_func: Set a function to be used to flush the native - * CPU's caches after a block of 68k code has been translated into native - * code. If not set, no cache flushing is performed. This function has no - * effect if dynamic translation is not enabled. - * - * [Parameters] - * state: Processor state block - * flush_func: Function for flushing the native CPU's caches (NULL if none) - * [Return value] - * None - */ -void q68_set_jit_flush_func(Q68State *state, void (*flush_func)(void)) -{ - state->jit_flush = flush_func; -} - -/*************************************************************************/ - -/** - * q68_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of the - * specified register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_get_dreg() and q68_get_areg() only) - * [Return value] - * Register value - */ -uint32_t q68_get_dreg(const Q68State *state, int num) -{ - return state->D[num]; -} - -uint32_t q68_get_areg(const Q68State *state, int num) -{ - return state->A[num]; -} - -uint32_t q68_get_pc(const Q68State *state) -{ - return state->PC; -} - -uint16_t q68_get_sr(const Q68State *state) -{ - return state->SR; -} - -uint32_t q68_get_usp(const Q68State *state) -{ - return state->USP; -} - -uint32_t q68_get_ssp(const Q68State *state) -{ - return state->SSP; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_set_dreg() and q68_set_areg() only) - * value: Value to set - * [Return value] - * None - */ -void q68_set_dreg(Q68State *state, int num, uint32_t value) -{ - state->D[num] = value; -} - -void q68_set_areg(Q68State *state, int num, uint32_t value) -{ - state->A[num] = value; -} - -void q68_set_pc(Q68State *state, uint32_t value) -{ - state->PC = value; -} - -void q68_set_sr(Q68State *state, uint16_t value) -{ - state->SR = value; -} - -void q68_set_usp(Q68State *state, uint32_t value) -{ - state->USP = value; -} - -void q68_set_ssp(Q68State *state, uint32_t value) -{ - state->SSP = value; -} - -/*************************************************************************/ - -/** - * q68_touch_memory: Clear any cached translations covering the given - * address range. Users should call this function whenever 68000-accessible - * memory is modified by an external agent. - * - * [Parameters] - * state: Processor state block - * address: 68000 address of modified data - * size: Size of modified data (in bytes) - * [Return value] - * None - */ -void q68_touch_memory(Q68State *state, uint32_t address, uint32_t size) -{ -#ifdef Q68_USE_JIT - const uint32_t first_page = address >> Q68_JIT_PAGE_BITS; - const uint32_t last_page = (address + (size-1)) >> Q68_JIT_PAGE_BITS; - uint32_t page; - for (page = first_page; page <= last_page; page++) { - if (UNLIKELY(JIT_PAGE_TEST(state, page))) { - q68_jit_clear_page(state, page << Q68_JIT_PAGE_BITS); - } - } -#endif -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68.h b/yabause/src/q68/q68.h deleted file mode 100644 index fa4af2c254..0000000000 --- a/yabause/src/q68/q68.h +++ /dev/null @@ -1,295 +0,0 @@ -/* src/q68/q68.h: Q68 main header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause 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. - - Yabause 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 Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_H -#define Q68_H - -#include -#include - -/*************************************************************************/ -/****************** Exported definitions and data types ******************/ -/*************************************************************************/ - -/* Memory read/write function types. The size of the operation is not - * specified here, but is rather determined by which callback the function - * is assigned to. */ - -/** - * Q68ReadFunc: Read data from memory. - * - * [Parameters] - * address: Address to read from - * [Return value] - * Value read (zero-extended to 32 bits) - */ -typedef uint32_t Q68ReadFunc(uint32_t address); - -/** - * Q68WriteFunc: Write data to memory. - * - * [Parameters] - * address: Address to write to - * data: Value to write - * [Return value] - * None - */ -typedef void Q68WriteFunc(uint32_t address, uint32_t data); - -/*************************************************************************/ - -/* Virtual processor state (opaque) */ - -typedef struct Q68State_ Q68State; - -/*************************************************************************/ -/************************** Emulator interface ***************************/ -/*************************************************************************/ - -/** - * q68_create: Create a new virtual processor. The virtual processor is - * created uninitialized; before starting the processor, the caller must - * set the IRQ level and read/write callbacks, then call q68_reset(). - * - * [Parameters] - * None - * [Return value] - * Processor state block on success, NULL on error - */ -extern Q68State *q68_create(void); - -/** - * q68_create_ex: Create a new virtual processor, using the specified - * functions for all memory allocation. - * - * [Parameters] - * malloc_func: Function for allocating a memory block - * realloc_func: Function for adjusting the size of a memory block - * free_func: Function for freeing a memory block - * [Return value] - * Processor state block on success, NULL on error - */ -extern Q68State *q68_create_ex(void *(*malloc_func)(size_t size), - void *(*realloc_func)(void *ptr, size_t size), - void (*free_func)(void *ptr)); - -/** - * q68_destroy: Free all resources used by a virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_destroy(Q68State *state); - -/*----------------------------------*/ - -/** - * q68_set_irq: Set the interrupt request (IRQ) input to the processor. - * - * [Parameters] - * state: Processor state block - * irq: IRQ level (0-7) - * [Return value] - * None - */ -extern void q68_set_irq(Q68State *state, int irq); - -/** - * q68_set_{readb,readw,writeb,writew}_func: Set the read/write callback - * functions called by the virtual processor on memory accesses. - * - * For the read functions, only the lower 8 (readb) or 16 (readw) bits of - * the return value are used; the function does not need to sign-extend or - * zero-extend the value. Similarly, the value passed to the write - * functions will only have the low 8 (writeb) or 16 (writew) bits valid, - * and the function should ignore the upper bits of the value. - * - * For the word access functions (readw and writew), the address is - * guaranteed to be even, so the function does not need to check for this - * itself. (However, see the Q68_DISABLE_ADDRESS_ERROR configuration - * option in q68-internal.h.) - * - * [Parameters] - * state: Processor state block - * func: Callback function to set - * [Return value] - * None - */ -extern void q68_set_readb_func(Q68State *state, Q68ReadFunc func); -extern void q68_set_readw_func(Q68State *state, Q68ReadFunc func); -extern void q68_set_writeb_func(Q68State *state, Q68WriteFunc func); -extern void q68_set_writew_func(Q68State *state, Q68WriteFunc func); - -/** - * q68_set_jit_flush_func: Set a function to be used to flush the native - * CPU's caches after a block of 68k code has been translated into native - * code. If not set, no cache flushing is performed. This function has no - * effect if dynamic translation is not enabled. - * - * [Parameters] - * state: Processor state block - * flush_func: Function for flushing the native CPU's caches (NULL if none) - * [Return value] - * None - */ -extern void q68_set_jit_flush_func(Q68State *state, void (*flush_func)(void)); - -/*----------------------------------*/ - -/** - * q68_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of the - * specified register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_get_dreg() and q68_get_areg() only) - * [Return value] - * Register value - */ -extern uint32_t q68_get_dreg(const Q68State *state, int num); -extern uint32_t q68_get_areg(const Q68State *state, int num); -extern uint32_t q68_get_pc(const Q68State *state); -extern uint16_t q68_get_sr(const Q68State *state); -extern uint32_t q68_get_usp(const Q68State *state); -extern uint32_t q68_get_ssp(const Q68State *state); - -/** - * q68_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_set_dreg() and q68_set_areg() only) - * value: Value to set - * [Return value] - * None - */ -extern void q68_set_dreg(Q68State *state, int num, uint32_t value); -extern void q68_set_areg(Q68State *state, int num, uint32_t value); -extern void q68_set_pc(Q68State *state, uint32_t value); -extern void q68_set_sr(Q68State *state, uint16_t value); -extern void q68_set_usp(Q68State *state, uint32_t value); -extern void q68_set_ssp(Q68State *state, uint32_t value); - -/*----------------------------------*/ - -/** - * q68_touch_memory: Clear any cached translations covering the given - * address range. Users should call this function whenever 68000-accessible - * memory is modified by an external agent. - * - * [Parameters] - * state: Processor state block - * address: 68000 address of modified data - * size: Size of modified data (in bytes) - * [Return value] - * None - */ -extern void q68_touch_memory(Q68State *state, uint32_t address, uint32_t size); - -/*-----------------------------------------------------------------------*/ - -/** - * q68_reset: Reset the virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_reset(Q68State *state); - -/** - * q68_run: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles executed (may be greater than "cycles") - */ -extern int q68_run(Q68State *state, int cycles); - -/*-----------------------------------------------------------------------*/ - -/** - * q68_disassemble: Disassemble the instruction at the given address. - * Returns "???" if the address or opcode is invalid. - * - * [Parameters] - * state: Processor state block - * address: Address of instruction to disassemble - * [Return value] - * String containined disassembled instruction - * [Notes] - * The returned string is only valid until the next call to this function. - */ -extern const char *q68_disassemble(Q68State *state, uint32_t address, - int *nwords_ret); - -/*----------------------------------*/ - -/** - * q68_trace_init: Initialize the tracing code. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_trace_init(Q68State *state_); - -/** - * q68_trace_add_cycles: Add the given number of cycles to the global - * accumulator. - * - * [Parameters] - * cycles: Number of cycles to add - * [Return value] - * None - */ -extern void q68_trace_add_cycles(int32_t cycles); - -/** - * q68_trace: Output a trace for the instruction at the current PC. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void q68_trace(void); - -/*************************************************************************/ -/*************************************************************************/ - -#endif // Q68_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/qt/Arguments.cpp b/yabause/src/qt/Arguments.cpp deleted file mode 100644 index f92a757ea2..0000000000 --- a/yabause/src/qt/Arguments.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "Arguments.h" -#include "VolatileSettings.h" -#include "QtYabause.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace Arguments -{ - - void autoframeskip(const QString& param); - void autoload(const QString& param); - void autostart(const QString& param); - void binary(const QString& param); - void bios(const QString& param); - void cdrom(const QString& param); - void fullscreen(const QString& param); - void help(const QString& param); - void iso(const QString& param); - void nobios(const QString& param); - void nosound(const QString& param); - void version(const QString& param); - - struct Option - { - const char * shortname; - const char * longname; - const char * parameter; - const char * description; - unsigned short priority; - void (*callback)(const QString& param); - }; - - static Option LAST_OPTION = { NULL, NULL, NULL, NULL, 0 }; - - static Option availableOptions[] = - { - { NULL, "--autoframeskip=", "0|1", "Enable or disable auto frame skipping / limiting.", 2, autoframeskip }, - { NULL, "--autoload=", "", "Automatically start emulation and load a save state.",1, autoload }, - { "-a", "--autostart", NULL, "Automatically start emulation.", 1, autostart }, - { NULL, "--binary=", "[:ADDRESS]", "Use a binary file.", 1, binary }, - { "-b", "--bios=", "", "Choose a bios file.", 3, bios }, - { "-c", "--cdrom=", "", "Choose the cdrom device.", 4, cdrom }, - { "-f", "--fullscreen", NULL, "Start the emulator in fullscreen.", 5, fullscreen }, - { "-h", "--help", NULL, "Show this help and exit.", 0, help }, - { "-i", "--iso=", "", "Choose a dump file.", 4, iso }, - { "-nb", "--no-bios", NULL, "Use the emulated bios", 3, nobios }, - { "-ns", "--no-sound", NULL, "Turns sound off.", 6, nosound }, - { "-v", "--version", NULL, "Show version and exit.", 0, version }, - LAST_OPTION - }; - - void parse() - { - QVector