CPU
This commit is contained in:
parent
31f0c2f937
commit
15af3f0c75
|
@ -0,0 +1 @@
|
|||
NESEmulator
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/nes.iml" filepath="$PROJECT_DIR$/.idea/nes.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,164 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="CMakePresetLoader">{
|
||||
"useNewFormat": true
|
||||
}</component>
|
||||
<component name="CMakeReloadState">
|
||||
<option name="reloaded" value="true" />
|
||||
</component>
|
||||
<component name="CMakeRunConfigurationManager">
|
||||
<generated>
|
||||
<config projectName="NESEmulator" targetName="NESEmulator" />
|
||||
<config projectName="NESEmulator" targetName="CPU" />
|
||||
</generated>
|
||||
</component>
|
||||
<component name="CMakeSettings">
|
||||
<configurations>
|
||||
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="conan_provider.cmake"" />
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="0c3b231e-0637-4ac1-8964-c60fc9e9e691" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/nes.iml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/conan_provider.cmake" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/conandata.yml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/conanfile.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cpu/CMakeLists.txt" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cpu/mem.c" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cpu/op.c" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/include/cpu/cpu.h" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/include/cpu/mem.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Makefile" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/obj/cpu.o" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/obj/main.o" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cpu/cpu.c" beforeDir="false" afterPath="$PROJECT_DIR$/cpu/cpu.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cpu/cpu.h" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cpu/op.c" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cpu/op.h" beforeDir="false" afterPath="$PROJECT_DIR$/include/cpu/op.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/main.c" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ClangdSettings">
|
||||
<option name="formatViaClangd" value="false" />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="CMakeBuildProfile:Debug" />
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="CMakeLists.txt" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectApplicationVersion">
|
||||
<option name="ide" value="CLion" />
|
||||
<option name="majorVersion" value="2023" />
|
||||
<option name="minorVersion" value="2.2" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"customColor": "",
|
||||
"associatedIndex": 7
|
||||
}</component>
|
||||
<component name="ProjectId" id="2W5yx3U4hkbEJBqDsLukxSBRGfR" />
|
||||
<component name="ProjectLevelVcsManager">
|
||||
<ConfirmationsSetting value="2" id="Add" />
|
||||
</component>
|
||||
<component name="ProjectViewState">
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.cidr.known.project.marker": "true",
|
||||
"cf.first.check.clang-format": "false",
|
||||
"cidr.known.project.marker": "true",
|
||||
"com.jfrog.conanplugin.addconansupport": "true",
|
||||
"com.jfrog.conanplugin.automanage.cmake.advanced.settings": "true",
|
||||
"com.jfrog.conanplugin.conanexecutable": "conan",
|
||||
"com.jfrog.conanplugin.hasbeensetup": "true",
|
||||
"git-widget-placeholder": "master",
|
||||
"last_opened_file_path": "/d/p/nes/CMakeLists.txt",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$/include/cpu" />
|
||||
<recent name="$PROJECT_DIR$/cpu" />
|
||||
<recent name="$PROJECT_DIR$" />
|
||||
<recent name="$PROJECT_DIR$/src" />
|
||||
<recent name="$PROJECT_DIR$/include" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager" selected="CMake Application.NESEmulator">
|
||||
<configuration name="NESEmulator" type="CMakeListConfigurationType" factoryName="CMakeListConfigurationFactory" temporary="true">
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="CPU" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="NESEmulator" TARGET_NAME="CPU" CONFIG_NAME="Debug">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="NESEmulator" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="NESEmulator" TARGET_NAME="NESEmulator" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="NESEmulator" RUN_TARGET_NAME="NESEmulator">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<list>
|
||||
<item itemvalue="CMake Application.NESEmulator" />
|
||||
<item itemvalue="CMake Application.CPU" />
|
||||
<item itemvalue="CMake Debug.NESEmulator" />
|
||||
</list>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="CMake Debug.NESEmulator" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="0c3b231e-0637-4ac1-8964-c60fc9e9e691" name="Changes" comment="" />
|
||||
<created>1696036979238</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1696036979238</updated>
|
||||
<workItem from="1696036981362" duration="4054000" />
|
||||
<workItem from="1696127133169" duration="3618000" />
|
||||
<workItem from="1696203038713" duration="1394000" />
|
||||
<workItem from="1696539868309" duration="1000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="VCPKGProject">
|
||||
<isAutomaticEditVcpkgJson value="false" />
|
||||
<isAutomaticCheckingOnLaunch value="false" />
|
||||
<isAutomaticFoundErrors value="true" />
|
||||
<isAutomaticFoundErrors value="true" />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,14 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
project(NESEmulator VERSION 0.1)
|
||||
|
||||
add_subdirectory(cpu)
|
||||
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/cpu")
|
||||
|
||||
add_executable(NESEmulator main.c)
|
||||
|
||||
find_package(log.c)
|
||||
|
||||
target_link_libraries(NESEmulator CPU log.c::log.c)
|
||||
target_include_directories(NESEmulator PUBLIC
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
${EXTRA_INCLUDES})
|
30
Makefile
30
Makefile
|
@ -1,30 +0,0 @@
|
|||
CC = gcc
|
||||
BIN = ./bin
|
||||
OBJ = ./obj
|
||||
SRC = ./src
|
||||
|
||||
SRCS = $(wildcard $(SRC)/*.c)
|
||||
OBJS = $(patsubst $(SRC)/%.c,$(OBJ)/%.o,$(SRCS))
|
||||
EXE = $(BIN)/emu
|
||||
|
||||
CFLAGS = -Wall
|
||||
LDLIBS = -lm
|
||||
|
||||
.PHONY: all run clean
|
||||
|
||||
all: $(EXE)
|
||||
|
||||
$(EXE): $(OBJS) | $(BIN)
|
||||
$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)
|
||||
|
||||
$(OBJ)/%.o: $(SRC)/%.c | $(OBJ)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BIN) $(OBJ):
|
||||
mkdir $@
|
||||
|
||||
run: $(EXE)
|
||||
$<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ) $(BIN)
|
|
@ -0,0 +1,548 @@
|
|||
# This file is managed by Conan, contents will be overwritten.
|
||||
# To keep your changes, remove these comment lines, but the plugin won't be able to modify your requirements
|
||||
|
||||
set(CONAN_MINIMUM_VERSION 2.0.5)
|
||||
|
||||
|
||||
function(detect_os OS OS_API_LEVEL OS_SDK OS_SUBSYSTEM OS_VERSION)
|
||||
# it could be cross compilation
|
||||
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
|
||||
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
set(${OS} Macos PARENT_SCOPE)
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "QNX")
|
||||
set(${OS} Neutrino PARENT_SCOPE)
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "CYGWIN")
|
||||
set(${OS} Windows PARENT_SCOPE)
|
||||
set(${OS_SUBSYSTEM} cygwin PARENT_SCOPE)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "^MSYS")
|
||||
set(${OS} Windows PARENT_SCOPE)
|
||||
set(${OS_SUBSYSTEM} msys2 PARENT_SCOPE)
|
||||
else()
|
||||
set(${OS} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
||||
endif()
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
|
||||
string(REGEX MATCH "[0-9]+" _OS_API_LEVEL ${ANDROID_PLATFORM})
|
||||
message(STATUS "CMake-Conan: android_platform=${ANDROID_PLATFORM}")
|
||||
set(${OS_API_LEVEL} ${_OS_API_LEVEL} PARENT_SCOPE)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
|
||||
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
|
||||
# generators, but just has the original input string for Xcode.
|
||||
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
|
||||
set(_OS_SDK ${CMAKE_OSX_SYSROOT})
|
||||
else()
|
||||
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
|
||||
set(apple_platform_suffix simulator)
|
||||
else()
|
||||
set(apple_platform_suffix os)
|
||||
endif()
|
||||
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
|
||||
set(_OS_SDK "appletv${apple_platform_suffix}")
|
||||
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
|
||||
set(_OS_SDK "iphone${apple_platform_suffix}")
|
||||
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
|
||||
set(_OS_SDK "watch${apple_platform_suffix}")
|
||||
endif()
|
||||
endif()
|
||||
if(DEFINED _OS_SDK)
|
||||
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
|
||||
set(${OS_SDK} ${_OS_SDK} PARENT_SCOPE)
|
||||
endif()
|
||||
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
set(${OS_VERSION} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_arch ARCH)
|
||||
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
|
||||
# Therefore this code only finds one. If the recipes support multiple architectures, the
|
||||
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
|
||||
if(DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
|
||||
list(LENGTH apple_arch_list apple_arch_count)
|
||||
if(apple_arch_count GREATER 1)
|
||||
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|arm64" OR CMAKE_OSX_ARCHITECTURES MATCHES arm64)
|
||||
set(_ARCH armv8)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "armv7-a|armv7l" OR CMAKE_OSX_ARCHITECTURES MATCHES armv7)
|
||||
set(_ARCH armv7)
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES armv7s)
|
||||
set(_ARCH armv7s)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686" OR CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
||||
set(_ARCH x86)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|amd64|x86_64" OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
|
||||
set(_ARCH x86_64)
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: cmake_system_processor=${_ARCH}")
|
||||
set(${ARCH} ${_ARCH} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_cxx_standard CXX_STANDARD)
|
||||
set(${CXX_STANDARD} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
|
||||
if(CMAKE_CXX_EXTENSIONS)
|
||||
set(${CXX_STANDARD} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(detect_gnu_libstdcxx)
|
||||
# _CONAN_IS_GNU_LIBSTDCXX true if GNU libstdc++
|
||||
check_cxx_source_compiles("
|
||||
#include <cstddef>
|
||||
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
|
||||
static_assert(false);
|
||||
#endif
|
||||
int main(){}" _CONAN_IS_GNU_LIBSTDCXX)
|
||||
|
||||
# _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI true if C++11 ABI
|
||||
check_cxx_source_compiles("
|
||||
#include <string>
|
||||
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
|
||||
int main () {}" _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI)
|
||||
|
||||
set(_CONAN_GNU_LIBSTDCXX_SUFFIX "")
|
||||
if(_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI)
|
||||
set(_CONAN_GNU_LIBSTDCXX_SUFFIX "11")
|
||||
endif()
|
||||
unset (_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI)
|
||||
endmacro()
|
||||
|
||||
macro(detect_libcxx)
|
||||
# _CONAN_IS_LIBCXX true if LLVM libc++
|
||||
check_cxx_source_compiles("
|
||||
#include <cstddef>
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
static_assert(false);
|
||||
#endif
|
||||
int main(){}" _CONAN_IS_LIBCXX)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(detect_lib_cxx OS LIB_CXX)
|
||||
if(${OS} STREQUAL "Android")
|
||||
message(STATUS "CMake-Conan: android_stl=${ANDROID_STL}")
|
||||
set(${LIB_CXX} ${ANDROID_STL} PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
detect_gnu_libstdcxx()
|
||||
set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
||||
set(${LIB_CXX} "libc++" PARENT_SCOPE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
# Check for libc++
|
||||
detect_libcxx()
|
||||
if(_CONAN_IS_LIBCXX)
|
||||
set(${LIB_CXX} "libc++" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check for libstdc++
|
||||
detect_gnu_libstdcxx()
|
||||
if(_CONAN_IS_GNU_LIBSTDCXX)
|
||||
set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO: it would be an error if we reach this point
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
# Do nothing - compiler.runtime and compiler.runtime_type
|
||||
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
|
||||
return()
|
||||
else()
|
||||
# TODO: unable to determine, ask user to provide a full profile file instead
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_compiler COMPILER COMPILER_VERSION COMPILER_RUNTIME COMPILER_RUNTIME_TYPE)
|
||||
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
||||
set(_COMPILER ${CMAKE_CXX_COMPILER_ID})
|
||||
set(_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION})
|
||||
else()
|
||||
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
||||
message(FATAL_ERROR "C or C++ compiler not defined")
|
||||
endif()
|
||||
set(_COMPILER ${CMAKE_C_COMPILER_ID})
|
||||
set(_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION})
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: CMake compiler=${_COMPILER}")
|
||||
message(STATUS "CMake-Conan: CMake compiler version=${_COMPILER_VERSION}")
|
||||
|
||||
if(_COMPILER MATCHES MSVC)
|
||||
set(_COMPILER "msvc")
|
||||
string(SUBSTRING ${MSVC_VERSION} 0 3 _COMPILER_VERSION)
|
||||
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
|
||||
if(CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
set(_KNOWN_MSVC_RUNTIME_VALUES "")
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
|
||||
|
||||
# only accept the 6 possible values, otherwise we don't don't know to map this
|
||||
if(NOT CMAKE_MSVC_RUNTIME_LIBRARY IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
|
||||
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${CMAKE_MSVC_RUNTIME_LIBRARY} to Conan settings")
|
||||
endif()
|
||||
|
||||
# Runtime is "dynamic" in all cases if it ends in DLL
|
||||
if(CMAKE_MSVC_RUNTIME_LIBRARY MATCHES ".*DLL$")
|
||||
set(_COMPILER_RUNTIME "dynamic")
|
||||
else()
|
||||
set(_COMPILER_RUNTIME "static")
|
||||
endif()
|
||||
|
||||
# Only define compiler.runtime_type when explicitly requested
|
||||
# If a generator expression is used, let Conan handle it conditional on build_type
|
||||
get_property(_IS_MULTI_CONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(NOT CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "<CONFIG:Debug>:Debug>")
|
||||
if(CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "Debug")
|
||||
set(_COMPILER_RUNTIME_TYPE "Debug")
|
||||
else()
|
||||
set(_COMPILER_RUNTIME_TYPE "Release")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
unset(_KNOWN_MSVC_RUNTIME_VALUES)
|
||||
unset(_IS_MULTI_CONFIG_GENERATOR)
|
||||
endif()
|
||||
elseif(_COMPILER MATCHES AppleClang)
|
||||
set(_COMPILER "apple-clang")
|
||||
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
||||
list(GET VERSION_LIST 0 _COMPILER_VERSION)
|
||||
elseif(_COMPILER MATCHES Clang)
|
||||
set(_COMPILER "clang")
|
||||
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
||||
list(GET VERSION_LIST 0 _COMPILER_VERSION)
|
||||
elseif(_COMPILER MATCHES GNU)
|
||||
set(_COMPILER "gcc")
|
||||
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
||||
list(GET VERSION_LIST 0 _COMPILER_VERSION)
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: [settings] compiler=${_COMPILER}")
|
||||
message(STATUS "CMake-Conan: [settings] compiler.version=${_COMPILER_VERSION}")
|
||||
if (_COMPILER_RUNTIME)
|
||||
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_COMPILER_RUNTIME}")
|
||||
endif()
|
||||
if (_COMPILER_RUNTIME_TYPE)
|
||||
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}")
|
||||
endif()
|
||||
|
||||
set(${COMPILER} ${_COMPILER} PARENT_SCOPE)
|
||||
set(${COMPILER_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
|
||||
set(${COMPILER_RUNTIME} ${_COMPILER_RUNTIME} PARENT_SCOPE)
|
||||
set(${COMPILER_RUNTIME_TYPE} ${_COMPILER_RUNTIME_TYPE} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(detect_build_type BUILD_TYPE)
|
||||
get_property(_MULTICONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(NOT _MULTICONFIG_GENERATOR)
|
||||
# Only set when we know we are in a single-configuration generator
|
||||
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
|
||||
set(${BUILD_TYPE} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(append_compiler_executables_configuration)
|
||||
set(_conan_c_compiler "")
|
||||
set(_conan_cpp_compiler "")
|
||||
if(CMAKE_C_COMPILER)
|
||||
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\",")
|
||||
else()
|
||||
message(WARNING "CMake-Conan: The C compiler is not defined. "
|
||||
"Please define CMAKE_C_COMPILER or enable the C language.")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER)
|
||||
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
|
||||
else()
|
||||
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
|
||||
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
|
||||
endif()
|
||||
|
||||
string(APPEND PROFILE "tools.build:compiler_executables={${_conan_c_compiler}${_conan_cpp_compiler}}\n")
|
||||
unset(_conan_c_compiler)
|
||||
unset(_conan_cpp_compiler)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(detect_host_profile output_file)
|
||||
detect_os(MYOS MYOS_API_LEVEL MYOS_SDK MYOS_SUBSYSTEM MYOS_VERSION)
|
||||
detect_arch(MYARCH)
|
||||
detect_compiler(MYCOMPILER MYCOMPILER_VERSION MYCOMPILER_RUNTIME MYCOMPILER_RUNTIME_TYPE)
|
||||
detect_cxx_standard(MYCXX_STANDARD)
|
||||
detect_lib_cxx(MYOS MYLIB_CXX)
|
||||
detect_build_type(MYBUILD_TYPE)
|
||||
|
||||
set(PROFILE "")
|
||||
string(APPEND PROFILE "[settings]\n")
|
||||
if(MYARCH)
|
||||
string(APPEND PROFILE arch=${MYARCH} "\n")
|
||||
endif()
|
||||
if(MYOS)
|
||||
string(APPEND PROFILE os=${MYOS} "\n")
|
||||
endif()
|
||||
if(MYOS_API_LEVEL)
|
||||
string(APPEND PROFILE os.api_level=${MYOS_API_LEVEL} "\n")
|
||||
endif()
|
||||
if(MYOS_VERSION)
|
||||
string(APPEND PROFILE os.version=${MYOS_VERSION} "\n")
|
||||
endif()
|
||||
if(MYOS_SDK)
|
||||
string(APPEND PROFILE os.sdk=${MYOS_SDK} "\n")
|
||||
endif()
|
||||
if(MYOS_SUBSYSTEM)
|
||||
string(APPEND PROFILE os.subsystem=${MYOS_SUBSYSTEM} "\n")
|
||||
endif()
|
||||
if(MYCOMPILER)
|
||||
string(APPEND PROFILE compiler=${MYCOMPILER} "\n")
|
||||
endif()
|
||||
if(MYCOMPILER_VERSION)
|
||||
string(APPEND PROFILE compiler.version=${MYCOMPILER_VERSION} "\n")
|
||||
endif()
|
||||
if(MYCOMPILER_RUNTIME)
|
||||
string(APPEND PROFILE compiler.runtime=${MYCOMPILER_RUNTIME} "\n")
|
||||
endif()
|
||||
if(MYCOMPILER_RUNTIME_TYPE)
|
||||
string(APPEND PROFILE compiler.runtime_type=${MYCOMPILER_RUNTIME_TYPE} "\n")
|
||||
endif()
|
||||
if(MYCXX_STANDARD)
|
||||
string(APPEND PROFILE compiler.cppstd=${MYCXX_STANDARD} "\n")
|
||||
endif()
|
||||
if(MYLIB_CXX)
|
||||
string(APPEND PROFILE compiler.libcxx=${MYLIB_CXX} "\n")
|
||||
endif()
|
||||
if(MYBUILD_TYPE)
|
||||
string(APPEND PROFILE "build_type=${MYBUILD_TYPE}\n")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED output_file)
|
||||
set(_FN "${CMAKE_BINARY_DIR}/profile")
|
||||
else()
|
||||
set(_FN ${output_file})
|
||||
endif()
|
||||
|
||||
string(APPEND PROFILE "[conf]\n")
|
||||
string(APPEND PROFILE "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
|
||||
|
||||
# propagate compilers via profile
|
||||
append_compiler_executables_configuration()
|
||||
|
||||
if(${MYOS} STREQUAL "Android")
|
||||
string(APPEND PROFILE "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: Creating profile ${_FN}")
|
||||
file(WRITE ${_FN} ${PROFILE})
|
||||
message(STATUS "CMake-Conan: Profile: \n${PROFILE}")
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_profile_detect_default)
|
||||
message(STATUS "CMake-Conan: Checking if a default profile exists")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} profile path default
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
ECHO_OUTPUT_VARIABLE
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(NOT ${return_code} EQUAL "0")
|
||||
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} profile detect
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
ECHO_OUTPUT_VARIABLE
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_install)
|
||||
cmake_parse_arguments(ARGS CONAN_ARGS ${ARGN})
|
||||
set(CONAN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/conan)
|
||||
# Invoke "conan install" with the provided arguments
|
||||
set(CONAN_ARGS ${CONAN_ARGS} -of=${CONAN_OUTPUT_FOLDER})
|
||||
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN}")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN} --format=json
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(NOT "${return_code}" STREQUAL "0")
|
||||
message(FATAL_ERROR "Conan install failed='${return_code}'")
|
||||
else()
|
||||
# the files are generated in a folder that depends on the layout used, if
|
||||
# one is specified, but we don't know a priori where this is.
|
||||
# TODO: this can be made more robust if Conan can provide this in the json output
|
||||
string(JSON CONAN_GENERATORS_FOLDER GET ${conan_stdout} graph nodes 0 generators_folder)
|
||||
# message("conan stdout: ${conan_stdout}")
|
||||
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${CONAN_GENERATORS_FOLDER}")
|
||||
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${CONAN_GENERATORS_FOLDER}")
|
||||
# reconfigure on conanfile changes
|
||||
string(JSON CONANFILE GET ${conan_stdout} graph nodes 0 label)
|
||||
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${CONANFILE}")
|
||||
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${CONANFILE}")
|
||||
# success
|
||||
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_get_version conan_command conan_current_version)
|
||||
execute_process(
|
||||
COMMAND ${conan_command} --version
|
||||
OUTPUT_VARIABLE conan_output
|
||||
RESULT_VARIABLE conan_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(conan_result)
|
||||
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
|
||||
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_version_check)
|
||||
set(options )
|
||||
set(oneValueArgs MINIMUM CURRENT)
|
||||
set(multiValueArgs )
|
||||
cmake_parse_arguments(CONAN_VERSION_CHECK
|
||||
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT CONAN_VERSION_CHECK_MINIMUM)
|
||||
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
|
||||
endif()
|
||||
if(NOT CONAN_VERSION_CHECK_CURRENT)
|
||||
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
|
||||
endif()
|
||||
|
||||
if(CONAN_VERSION_CHECK_CURRENT VERSION_LESS CONAN_VERSION_CHECK_MINIMUM)
|
||||
message(FATAL_ERROR "CMake-Conan: Conan version must be ${CONAN_VERSION_CHECK_MINIMUM} or later")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(construct_profile_argument argument_variable profile_list)
|
||||
set(${argument_variable} "")
|
||||
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
|
||||
set(_arg_flag "--profile:host=")
|
||||
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
|
||||
set(_arg_flag "--profile:build=")
|
||||
endif()
|
||||
|
||||
set(_profile_list "${${profile_list}}")
|
||||
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
|
||||
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
|
||||
set(${argument_variable} ${_profile_list})
|
||||
|
||||
unset(_arg_flag)
|
||||
unset(_profile_list)
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_provide_dependency method package_name)
|
||||
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
|
||||
get_property(CONAN_INSTALL_SUCCESS GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
|
||||
if(NOT CONAN_INSTALL_SUCCESS)
|
||||
find_program(CONAN_COMMAND "conan" REQUIRED)
|
||||
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
|
||||
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
|
||||
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
|
||||
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
|
||||
conan_profile_detect_default()
|
||||
endif()
|
||||
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
|
||||
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
|
||||
endif()
|
||||
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
|
||||
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
|
||||
get_property(_MULTICONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(NOT _MULTICONFIG_GENERATOR)
|
||||
message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}")
|
||||
conan_install(${_host_profile_flags} ${_build_profile_flags} --build=missing -g CMakeDeps)
|
||||
else()
|
||||
message(STATUS "CMake-Conan: Installing both Debug and Release")
|
||||
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release --build=missing -g CMakeDeps)
|
||||
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug --build=missing -g CMakeDeps)
|
||||
endif()
|
||||
unset(_MULTICONFIG_GENERATOR)
|
||||
else()
|
||||
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
|
||||
endif()
|
||||
|
||||
get_property(CONAN_GENERATORS_FOLDER GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
|
||||
|
||||
# Ensure that we consider Conan-provided packages ahead of any other,
|
||||
# irrespective of other settings that modify the search order or search paths
|
||||
# This follows the guidelines from the find_package documentation
|
||||
# (https://cmake.org/cmake/help/latest/command/find_package.html):
|
||||
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
|
||||
# find_package (<PackageName>)
|
||||
|
||||
# Filter out `REQUIRED` from the argument list, as the first call may fail
|
||||
set(_find_args "${ARGN}")
|
||||
list(REMOVE_ITEM _find_args "REQUIRED")
|
||||
if(NOT "MODULE" IN_LIST _find_args)
|
||||
find_package(${package_name} ${_find_args} BYPASS_PROVIDER PATHS "${CONAN_GENERATORS_FOLDER}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
endif()
|
||||
|
||||
# Invoke find_package a second time - if the first call succeeded,
|
||||
# this will simply reuse the result. If not, fall back to CMake default search
|
||||
# behaviour, also allowing modules to be searched.
|
||||
set(_cmake_module_path_orig "${CMAKE_MODULE_PATH}")
|
||||
list(PREPEND CMAKE_MODULE_PATH "${CONAN_GENERATORS_FOLDER}")
|
||||
if(NOT ${package_name}_FOUND)
|
||||
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH "${_cmake_module_path_orig}")
|
||||
unset(_find_args)
|
||||
unset(_cmake_module_path_orig)
|
||||
unset(_host_profile_flags)
|
||||
unset(_build_profile_flags)
|
||||
endmacro()
|
||||
|
||||
|
||||
cmake_language(
|
||||
SET_DEPENDENCY_PROVIDER conan_provide_dependency
|
||||
SUPPORTED_METHODS FIND_PACKAGE
|
||||
)
|
||||
|
||||
macro(conan_provide_dependency_check)
|
||||
set(_CONAN_PROVIDE_DEPENDENCY_INVOKED FALSE)
|
||||
get_property(_CONAN_PROVIDE_DEPENDENCY_INVOKED GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
|
||||
if(NOT _CONAN_PROVIDE_DEPENDENCY_INVOKED)
|
||||
message(WARNING "Conan is correctly configured as dependency provider, "
|
||||
"but Conan has not been invoked. Please add at least one "
|
||||
"call to `find_package()`.")
|
||||
if(DEFINED CONAN_COMMAND)
|
||||
# supress warning in case `CONAN_COMMAND` was specified but unused.
|
||||
set(_CONAN_COMMAND ${CONAN_COMMAND})
|
||||
unset(_CONAN_COMMAND)
|
||||
endif()
|
||||
endif()
|
||||
unset(_CONAN_PROVIDE_DEPENDENCY_INVOKED)
|
||||
endmacro()
|
||||
|
||||
# Add a deferred call at the end of processing the top-level directory
|
||||
# to check if the dependency provider was invoked at all.
|
||||
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
|
||||
|
||||
# Configurable variables for Conan profiles
|
||||
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
|
||||
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
|
|
@ -0,0 +1,5 @@
|
|||
# This file is managed by Conan, contents will be overwritten.
|
||||
# To keep your changes, remove these comment lines, but the plugin won't be able to modify your requirements
|
||||
|
||||
requirements:
|
||||
- "log.c/cci.20200620"
|
|
@ -0,0 +1,23 @@
|
|||
# This file is managed by Conan, contents will be overwritten.
|
||||
# To keep your changes, remove these comment lines, but the plugin won't be able to modify your requirements
|
||||
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import cmake_layout, CMakeToolchain
|
||||
|
||||
class ConanApplication(ConanFile):
|
||||
package_type = "application"
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
generators = "CMakeDeps"
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.user_presets_path = False
|
||||
tc.generate()
|
||||
|
||||
def requirements(self):
|
||||
requirements = self.conan_data.get('requirements', [])
|
||||
for requirement in requirements:
|
||||
self.requires(requirement)
|
|
@ -0,0 +1,4 @@
|
|||
add_library(CPU
|
||||
cpu.c
|
||||
op.c
|
||||
mem.c)
|
|
@ -18,16 +18,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define test(x) \
|
||||
print_##x(x)
|
||||
#include "../include/cpu/op.h"
|
||||
|
||||
long cpu_clock = 0;
|
||||
|
||||
void cpu_step_to(long cycle) {
|
||||
cpu_clock = cycle;
|
||||
printf("Clock: %ld", cpu_clock);
|
||||
|
||||
test(f);
|
||||
// test("b");
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by william on 30/09/23.
|
||||
//
|
||||
|
||||
#include "../include/cpu/mem.h"
|
||||
#include "../include/cpu/op.h"
|
||||
|
||||
#include "../include/cpu/cpu.h"
|
||||
|
||||
unsigned short get_memory_address(addr_mode_t addr_mode, unsigned short operand) {
|
||||
if (addr_mode == ADDR_MODE_ABSOLUTE) {
|
||||
cpu_add_cycles(4);
|
||||
return operand;
|
||||
} else if (addr_mode == ADDR_MODE_ABSOLUTE_INDEXED_X) {
|
||||
unsigned char x = cpu_get_registers()->x;
|
||||
cpu_add_cycles(4);
|
||||
return operand + x;
|
||||
} else if (addr_mode == ADDR_MODE_ABSOLUTE_INDEXED_Y) {
|
||||
unsigned char y = cpu_get_registers()->y;
|
||||
cpu_add_cycles(4);
|
||||
return operand + y;
|
||||
} else if (addr_mode == ADDR_MODE_INDEXED_INDIRECT) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,530 @@
|
|||
#include "../include/cpu/op.h"
|
||||
|
||||
// Reference: https://www.nesdev.org/wiki/CPU_unofficial_opcodes
|
||||
|
||||
#define IS_OP_CODE_MODE(op, op_code, addr_mode) \
|
||||
case op_code: \
|
||||
op_ ## op(ADDR_MODE_ ## addr_mode); \
|
||||
break;
|
||||
|
||||
#define IS_OP_CODE(op, op_code) \
|
||||
IS_OP_CODE_MODE(op, op_code, IMPLICIT)
|
||||
|
||||
#define IS_ALU_OP_CODE_(op, offset, addr_mode) \
|
||||
IS_OP_CODE_MODE(op, OP_CODE_BASE_ ## op + offset, addr_mode)
|
||||
|
||||
#define IS_ALU_OP_CODE(op) \
|
||||
IS_ALU_OP_CODE_(op, 0x01, INDEXED_INDIRECT) \
|
||||
IS_ALU_OP_CODE_(op, 0x05, ZERO_PAGE) \
|
||||
IS_ALU_OP_CODE_(op, 0x09, IMMEDIATE) \
|
||||
IS_ALU_OP_CODE_(op, 0x0d, ABSOLUTE) \
|
||||
IS_ALU_OP_CODE_(op, 0x11, INDIRECT_INDEXED) \
|
||||
IS_ALU_OP_CODE_(op, 0x15, ZERO_PAGE_INDEXED_X) \
|
||||
IS_ALU_OP_CODE_(op, 0x19, ABSOLUTE_INDEXED_Y) \
|
||||
IS_ALU_OP_CODE_(op, 0x1d, ABSOLUTE_INDEXED_X)
|
||||
|
||||
#define IS_ALU_OP_CODE_NO_IMMEDIATE(op) \
|
||||
IS_ALU_OP_CODE_(op, 0x01, INDEXED_INDIRECT) \
|
||||
IS_ALU_OP_CODE_(op, 0x05, ZERO_PAGE) \
|
||||
IS_ALU_OP_CODE_(op, 0x0d, ABSOLUTE) \
|
||||
IS_ALU_OP_CODE_(op, 0x11, INDIRECT_INDEXED) \
|
||||
IS_ALU_OP_CODE_(op, 0x15, ZERO_PAGE_INDEXED_X) \
|
||||
IS_ALU_OP_CODE_(op, 0x19, ABSOLUTE_INDEXED_Y) \
|
||||
IS_ALU_OP_CODE_(op, 0x1d, ABSOLUTE_INDEXED_X)
|
||||
|
||||
#define IS_RMW_OP_CODE_(op, line, offset, addr_mode) \
|
||||
IS_OP_CODE_MODE(op, OP_CODE_BASE_ ## line + offset, addr_mode)
|
||||
|
||||
#define IS_RMW_OP_CODE(op, line) \
|
||||
IS_RMW_OP_CODE_(op, line, 0x06, ZERO_PAGE) \
|
||||
IS_RMW_OP_CODE_(op, line, 0x0a, IMPLICIT) \
|
||||
IS_RMW_OP_CODE_(op, line, 0x0e, ABSOLUTE) \
|
||||
IS_RMW_OP_CODE_(op, line, 0x16, ZERO_PAGE_INDEXED_X) \
|
||||
IS_RMW_OP_CODE_(op, line, 0x1e, ABSOLUTE_INDEXED_X)
|
||||
|
||||
#define IS_UNOFFICIAL_OP_CODE_(op, line, offset, addr_mode) \
|
||||
IS_OP_CODE_MODE(op, OP_CODE_BASE_ ## line + offset, addr_mode)
|
||||
|
||||
#define IS_UNOFFICIAL_OP_CODE(op, line) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x03, INDEXED_INDIRECT) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x07, ZERO_PAGE) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x0f, ABSOLUTE) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x13, INDIRECT_INDEXED) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x17, ZERO_PAGE_INDEXED_X) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x1b, ABSOLUTE_INDEXED_Y) \
|
||||
IS_UNOFFICIAL_OP_CODE_(op, line, 0x1f, ABSOLUTE_INDEXED_X)
|
||||
|
||||
void op_ADC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
/* === CTRL === */
|
||||
void op_BRK(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BPL(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BIT(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BMI(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BVC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BVS(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BCC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BCS(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BNE(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_BEQ(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_PHP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CLC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_JSR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_PLP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SEC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_RTI(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_PHA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_JMP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CLI(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_RTS(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_PLA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SEI(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_STY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_DEY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TYA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_LDY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TAY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CLV(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CPY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_INY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CLD(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CPX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_INX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SED(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
/* === ALU === */
|
||||
void op_ORA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_AND(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_EOR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ADC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_STA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_LDA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CMP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SBC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_NOP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
/* RMW */
|
||||
void op_ASL(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ROL(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_LSR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ROR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_STX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TXA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TXS(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SHX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_LDX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TAX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TSX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_DEC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_DEX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_INC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
// Unofficial
|
||||
void op_STP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SHY(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SLO(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_RLA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SRE(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_RRA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SAX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_LAX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_DCP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ISC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ANC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ALR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ARR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_XAA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_AXS(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_AHX(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_TAS(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void process_op_code(int op) {
|
||||
switch (op) {
|
||||
// CTRL
|
||||
IS_OP_CODE(BRK, 0x00)
|
||||
IS_OP_CODE(PHP, 0x08)
|
||||
IS_OP_CODE(CLC, 0x18)
|
||||
IS_OP_CODE(PLP, 0x28)
|
||||
IS_OP_CODE(SEC, 0x38)
|
||||
IS_OP_CODE(RTI, 0x40)
|
||||
IS_OP_CODE(PHA, 0x48)
|
||||
IS_OP_CODE(CLI, 0x58)
|
||||
IS_OP_CODE(RTS, 0x60)
|
||||
IS_OP_CODE(PLA, 0x68)
|
||||
IS_OP_CODE(SEI, 0x78)
|
||||
IS_OP_CODE(DEY, 0x88)
|
||||
IS_OP_CODE(TYA, 0x98)
|
||||
IS_OP_CODE(TAY, 0xa8)
|
||||
IS_OP_CODE(CLV, 0xb8)
|
||||
IS_OP_CODE(INY, 0xc8)
|
||||
IS_OP_CODE(CLD, 0xd8)
|
||||
IS_OP_CODE(INX, 0xe8)
|
||||
IS_OP_CODE(SED, 0xf8)
|
||||
|
||||
IS_OP_CODE_MODE(JSR, 0x20, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(BIT, 0x24, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(BIT, 0x2c, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(JMP, 0x4c, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(JMP, 0x6c, ABSOLUTE_JUMP)
|
||||
IS_OP_CODE_MODE(STY, 0x84, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(STY, 0x8c, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(STY, 0x94, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(SHY, 0x9c, ABSOLUTE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(LDY, 0xa0, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(LDY, 0xa4, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(LDY, 0xac, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(LDY, 0xb4, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(LDY, 0xbc, ABSOLUTE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(CPY, 0xc0, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(CPY, 0xc4, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(CPY, 0xcc, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(CPX, 0xe0, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(CPX, 0xe4, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(CPX, 0xec, ABSOLUTE)
|
||||
|
||||
IS_OP_CODE_MODE(BPL, 0x10, RELATIVE)
|
||||
IS_OP_CODE_MODE(BMI, 0x30, RELATIVE)
|
||||
IS_OP_CODE_MODE(BVC, 0x50, RELATIVE)
|
||||
IS_OP_CODE_MODE(BVS, 0x70, RELATIVE)
|
||||
IS_OP_CODE_MODE(BCC, 0x90, RELATIVE)
|
||||
IS_OP_CODE_MODE(BCS, 0xb0, RELATIVE)
|
||||
IS_OP_CODE_MODE(BNE, 0xd0, RELATIVE)
|
||||
IS_OP_CODE_MODE(BEQ, 0xf0, RELATIVE)
|
||||
|
||||
IS_OP_CODE_MODE(NOP, 0x04, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(NOP, 0x0c, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(NOP, 0x14, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x1c, ABSOLUTE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x34, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x3c, ABSOLUTE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x44, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(NOP, 0x54, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x5c, ABSOLUTE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x64, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(NOP, 0x74, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x7c, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0x80, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(NOP, 0xd4, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0xdc, ABSOLUTE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0xf4, ZERO_PAGE_INDEXED_X)
|
||||
IS_OP_CODE_MODE(NOP, 0xfc, ABSOLUTE_INDEXED_X)
|
||||
|
||||
// ALU
|
||||
IS_ALU_OP_CODE(ORA)
|
||||
IS_ALU_OP_CODE(AND)
|
||||
IS_ALU_OP_CODE(EOR)
|
||||
IS_ALU_OP_CODE(ADC)
|
||||
IS_ALU_OP_CODE_NO_IMMEDIATE(STA)
|
||||
IS_ALU_OP_CODE(LDA)
|
||||
IS_ALU_OP_CODE(CMP)
|
||||
IS_ALU_OP_CODE(SBC)
|
||||
|
||||
// RMW
|
||||
IS_RMW_OP_CODE(ASL, ORA)
|
||||
IS_RMW_OP_CODE(ROL, AND)
|
||||
IS_RMW_OP_CODE(LSR, EOR)
|
||||
IS_RMW_OP_CODE(ROR, ADC)
|
||||
|
||||
IS_OP_CODE(STP, 0x02)
|
||||
IS_OP_CODE(STP, 0x12)
|
||||
IS_OP_CODE(NOP, 0x1a)
|
||||
IS_OP_CODE(STP, 0x22)
|
||||
IS_OP_CODE(STP, 0x32)
|
||||
IS_OP_CODE(NOP, 0x3a)
|
||||
IS_OP_CODE(STP, 0x42)
|
||||
IS_OP_CODE(STP, 0x52)
|
||||
IS_OP_CODE(NOP, 0x5a)
|
||||
IS_OP_CODE(STP, 0x62)
|
||||
IS_OP_CODE(STP, 0x72)
|
||||
IS_OP_CODE(NOP, 0x7a)
|
||||
|
||||
IS_OP_CODE_MODE(NOP, 0x82, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(STX, 0x86, ZERO_PAGE)
|
||||
IS_OP_CODE(TXA, 0x8a)
|
||||
IS_OP_CODE_MODE(STX, 0x8e, ABSOLUTE)
|
||||
IS_OP_CODE(STP, 0x92)
|
||||
IS_OP_CODE_MODE(STX, 0x96, ZERO_PAGE_INDEXED_Y)
|
||||
IS_OP_CODE(TSX, 0x9a)
|
||||
IS_OP_CODE_MODE(SHX, 0x9e, ABSOLUTE_INDEXED_Y)
|
||||
|
||||
IS_OP_CODE_MODE(LDX, 0xa2, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(LDX, 0xa6, ZERO_PAGE)
|
||||
IS_OP_CODE(TAX, 0xaa)
|
||||
IS_OP_CODE_MODE(LDX, 0xae, ABSOLUTE)
|
||||
IS_OP_CODE(STP, 0xb2)
|
||||
IS_OP_CODE_MODE(LDX, 0xb6, ZERO_PAGE_INDEXED_Y)
|
||||
IS_OP_CODE(TSX, 0xba)
|
||||
IS_OP_CODE_MODE(LDX, 0xbe, ABSOLUTE_INDEXED_Y)
|
||||
|
||||
IS_OP_CODE_MODE(NOP, 0xc2, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(DEC, 0xc6, ZERO_PAGE)
|
||||
IS_OP_CODE(DEX, 0xca)
|
||||
IS_OP_CODE_MODE(DEC, 0xce, ABSOLUTE)
|
||||
IS_OP_CODE(STP, 0xd2)
|
||||
IS_OP_CODE_MODE(DEC, 0xd6, ZERO_PAGE_INDEXED_Y)
|
||||
IS_OP_CODE(NOP, 0xda)
|
||||
IS_OP_CODE_MODE(DEC, 0xde, ABSOLUTE_INDEXED_Y)
|
||||
|
||||
IS_OP_CODE_MODE(NOP, 0xe2, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(INC, 0xe6, ZERO_PAGE)
|
||||
IS_OP_CODE(NOP, 0xea) // The official NOP
|
||||
IS_OP_CODE_MODE(INC, 0xee, ABSOLUTE)
|
||||
IS_OP_CODE(STP, 0xf2)
|
||||
IS_OP_CODE_MODE(INC, 0xf6, ZERO_PAGE_INDEXED_Y)
|
||||
IS_OP_CODE(NOP, 0xfa)
|
||||
IS_OP_CODE_MODE(INC, 0xfe, ABSOLUTE_INDEXED_X)
|
||||
|
||||
// Unofficial
|
||||
IS_UNOFFICIAL_OP_CODE(SLO, ORA)
|
||||
IS_UNOFFICIAL_OP_CODE(RLA, AND)
|
||||
IS_UNOFFICIAL_OP_CODE(SRE, EOR)
|
||||
IS_UNOFFICIAL_OP_CODE(RRA, ADC)
|
||||
IS_UNOFFICIAL_OP_CODE(DCP, CMP)
|
||||
IS_UNOFFICIAL_OP_CODE(ISC, SBC)
|
||||
|
||||
IS_OP_CODE_MODE(ANC, 0x0b, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(ANC, 0x2b, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(ALR, 0x4b, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(ARR, 0x6b, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(AXS, 0xcb, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(SBC, 0xeb, IMMEDIATE)
|
||||
|
||||
IS_OP_CODE_MODE(SAX, 0x83, INDEXED_INDIRECT)
|
||||
IS_OP_CODE_MODE(SAX, 0x87, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(XAA, 0x8b, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(SAX, 0x8f, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(AHX, 0x93, INDIRECT_INDEXED)
|
||||
IS_OP_CODE_MODE(SAX, 0x97, ZERO_PAGE_INDEXED_Y)
|
||||
IS_OP_CODE_MODE(TAS, 0x9b, ABSOLUTE_INDEXED_Y)
|
||||
IS_OP_CODE_MODE(AHX, 0x9f, ABSOLUTE_INDEXED_Y)
|
||||
|
||||
IS_OP_CODE_MODE(LAX, 0xa3, INDEXED_INDIRECT)
|
||||
IS_OP_CODE_MODE(LAX, 0xa7, ZERO_PAGE)
|
||||
IS_OP_CODE_MODE(LAX, 0xab, IMMEDIATE)
|
||||
IS_OP_CODE_MODE(LAX, 0xaf, ABSOLUTE)
|
||||
IS_OP_CODE_MODE(LAX, 0xb3, INDIRECT_INDEXED)
|
||||
IS_OP_CODE_MODE(LAX, 0xb7, ZERO_PAGE_INDEXED_Y)
|
||||
IS_OP_CODE_MODE(LAX, 0xbb, ABSOLUTE_INDEXED_Y)
|
||||
IS_OP_CODE_MODE(LAX, 0xbf, ABSOLUTE_INDEXED_Y)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: cpu.h
|
||||
*
|
||||
* Description: 6502 CPU emulator headers
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 2023-09-21 10:12:33 PM
|
||||
* Revision: none
|
||||
* Compiler: gcc
|
||||
*
|
||||
* Author: William Nolin,
|
||||
* Organization:
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef EMU_CPU_H
|
||||
#define EMU_CPU_H
|
||||
|
||||
// Reference: https://www.nesdev.org/wiki/Status_flags
|
||||
#define CPU_STATUS_CARRY_MASK = 0x01;
|
||||
#define CPU_STATUS_ZERO_MASK = 0x02;
|
||||
#define CPU_STATUS_INTERRUPT_DISABLE_MASK = 0x04;
|
||||
#define CPU_STATUS_DECIMAL_MASK = 0x08;
|
||||
#define CPU_STATUS_B_MASK = 0x10;
|
||||
#define CPU_STATUS_I_MASK = 0x20;
|
||||
#define CPU_STATUS_OVERFLOW_MASK = 0x40;
|
||||
#define CPU_STATUS_NEGATIVE_MASK = 0x80;
|
||||
|
||||
// Reference: https://www.nesdev.org/obelisk-6502-guide/registers.html
|
||||
typedef struct {
|
||||
unsigned short program_counter;
|
||||
unsigned char stack_pointer;
|
||||
unsigned char accumulator;
|
||||
unsigned char x;
|
||||
unsigned char y;
|
||||
unsigned char status;
|
||||
} cpu_registers_t;
|
||||
|
||||
/**
|
||||
* @brief Set clock
|
||||
*/
|
||||
void cpu_step_to(int cycle);
|
||||
|
||||
void cpu_add_cycles(int count);
|
||||
|
||||
cpu_registers_t* cpu_get_registers();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
//
|
||||
// Created by william on 30/09/23.
|
||||
//
|
||||
|
||||
#ifndef NESEMULATOR_MEM_H
|
||||
#define NESEMULATOR_MEM_H
|
||||
|
||||
#endif //NESEMULATOR_MEM_H
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
// The number associated with each op code is the matching line of the ALU op code.
|
||||
// Based on the table here: https://www.nesdev.org/wiki/CPU_unofficial_opcodes
|
||||
enum op_code {
|
||||
OP_CODE_ORA = 0x00,
|
||||
OP_CODE_AND = 0x20,
|
||||
OP_CODE_EOR = 0x40,
|
||||
OP_CODE_ADC = 0x60,
|
||||
OP_CODE_STA = 0x80,
|
||||
OP_CODE_LDA = 0xa0,
|
||||
OP_CODE_CMP = 0xc0,
|
||||
OP_CODE_SBC = 0xe0
|
||||
enum op_code_base {
|
||||
OP_CODE_BASE_ORA = 0x00,
|
||||
OP_CODE_BASE_AND = 0x20,
|
||||
OP_CODE_BASE_EOR = 0x40,
|
||||
OP_CODE_BASE_ADC = 0x60,
|
||||
OP_CODE_BASE_STA = 0x80,
|
||||
OP_CODE_BASE_LDA = 0xa0,
|
||||
OP_CODE_BASE_CMP = 0xc0,
|
||||
OP_CODE_BASE_SBC = 0xe0
|
||||
};
|
||||
|
||||
typedef enum {
|
|
@ -15,23 +15,14 @@
|
|||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include <log.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cpu/cpu.h"
|
||||
|
||||
long master_clock = 0;
|
||||
|
||||
void step() {
|
||||
master_clock += 1;
|
||||
cpu_step_to(master_clock);
|
||||
|
||||
return;
|
||||
}
|
||||
#include "config.h"
|
||||
#include "include/cpu/cpu.h"
|
||||
|
||||
int main() {
|
||||
while (1) {
|
||||
step();
|
||||
}
|
||||
cpu_step_to(0);
|
||||
|
||||
return -1;
|
||||
}
|
BIN
obj/main.o
BIN
obj/main.o
Binary file not shown.
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: cpu.h
|
||||
*
|
||||
* Description: 6502 CPU emulator headers
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 2023-09-21 10:12:33 PM
|
||||
* Revision: none
|
||||
* Compiler: gcc
|
||||
*
|
||||
* Author: William Nolin,
|
||||
* Organization:
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef EMU_CPU_H
|
||||
#define EMU_CPU_H
|
||||
|
||||
/**
|
||||
* @brief Set clock
|
||||
*/
|
||||
void cpu_step_to(int cycle);
|
||||
|
||||
#endif
|
83
src/cpu/op.c
83
src/cpu/op.c
|
@ -1,83 +0,0 @@
|
|||
#include "op.h"
|
||||
|
||||
// Reference: https://www.nesdev.org/wiki/CPU_unofficial_opcodes
|
||||
|
||||
#define IS_OP_CODE_MODE(op, op_code, addr_mode) \
|
||||
case op_code: \
|
||||
op_ ## op(ADDR_MODE_ ## addr_mode); \
|
||||
break;
|
||||
|
||||
#define IS_OP_CODE(op, op_code) \
|
||||
IS_OP_CODE_MODE(op, op_code, IMPLICIT)
|
||||
|
||||
#define IS_ALU_OP_CODE_(op, offset, addr_mode) \
|
||||
IS_OP_CODE_MODE(op, OP_CODE_ ## op + offset, addr_mode)
|
||||
|
||||
#define IS_ALU_OP_CODE(op) \
|
||||
IS_ALU_OP_CODE_(op, 0x01, INDEXED_INDIRECT) \
|
||||
IS_ALU_OP_CODE_(op, 0x05, ZERO_PAGE) \
|
||||
IS_ALU_OP_CODE_(op, 0x09, IMMEDIATE) \
|
||||
IS_ALU_OP_CODE_(op, 0x0d, ABSOLUTE) \
|
||||
IS_ALU_OP_CODE_(op, 0x11, INDIRECT_INDEXED) \
|
||||
IS_ALU_OP_CODE_(op, 0x15, ZERO_PAGE_INDEXED_X) \
|
||||
IS_ALU_OP_CODE_(op, 0x19, ABSOLUTE_INDEXED_Y) \
|
||||
IS_ALU_OP_CODE_(op, 0x1d, ABSOLUTE_INDEXED_X)
|
||||
|
||||
#define IS_ALU_OP_CODE_NO_IMMEDIATE(op) \
|
||||
IS_ALU_OP_CODE_(op, 0x01, INDEXED_INDIRECT) \
|
||||
IS_ALU_OP_CODE_(op, 0x05, ZERO_PAGE) \
|
||||
IS_ALU_OP_CODE_(op, 0x0d, ABSOLUTE) \
|
||||
IS_ALU_OP_CODE_(op, 0x11, INDIRECT_INDEXED) \
|
||||
IS_ALU_OP_CODE_(op, 0x15, ZERO_PAGE_INDEXED_X) \
|
||||
IS_ALU_OP_CODE_(op, 0x19, ABSOLUTE_INDEXED_Y) \
|
||||
IS_ALU_OP_CODE_(op, 0x1d, ABSOLUTE_INDEXED_X)
|
||||
|
||||
void op_ORA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_AND(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_EOR(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_ADC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_STA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_LDA(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_CMP(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void op_SBC(addr_mode_t addr_mode) {
|
||||
|
||||
}
|
||||
|
||||
void process_op_code(int op) {
|
||||
switch (op) {
|
||||
// CTRL
|
||||
IS_OP_CODE(BRK, 0x00)
|
||||
IS_OP_CODE_MODE(NOP, 0x04, ZERO_PAGE)
|
||||
|
||||
// ALU
|
||||
IS_ALU_OP_CODE(ORA)
|
||||
IS_ALU_OP_CODE(AND)
|
||||
IS_ALU_OP_CODE(EOR)
|
||||
IS_ALU_OP_CODE(ADC)
|
||||
IS_ALU_OP_CODE_NO_IMMEDIATE(STA)
|
||||
IS_ALU_OP_CODE(LDA)
|
||||
IS_ALU_OP_CODE(CMP)
|
||||
IS_ALU_OP_CODE(SBC)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue