Compare commits

..

No commits in common. "091a5e3bf574550497315d6f316d0fe523a01b9e" and "7d04e3eb3c24468be7d17640503243478e9a9822" have entirely different histories.

13 changed files with 677 additions and 473 deletions

569
.idea/workspace.xml Normal file
View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="CMakePresetLoader">{
&quot;useNewFormat&quot;: true
}</component>
<component name="CMakeReloadState">
<option name="reloaded" value="true" />
</component>
<component name="CMakeRunConfigurationManager">
<generated>
<config projectName="NESEmulator" targetName="NESEmulator" />
<config projectName="NESEmulator" targetName="DEBUG" />
<config projectName="NESEmulator" targetName="ROM" />
<config projectName="NESEmulator" targetName="Mappers" />
<config projectName="NESEmulator" targetName="PPU" />
<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=&quot;conan_provider.cmake&quot;" />
</configurations>
</component>
<component name="ChangeListManager">
<list default="true" id="0c3b231e-0637-4ac1-8964-c60fc9e9e691" name="Changes" comment="gitignore">
<change afterPath="$PROJECT_DIR$/debugger/program_view.c" afterDir="false" />
<change afterPath="$PROJECT_DIR$/debugger/program_view.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/cpu/op.c" beforeDir="false" afterPath="$PROJECT_DIR$/cpu/op.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/cpu/op.h" beforeDir="false" afterPath="$PROJECT_DIR$/cpu/op.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/debugger/CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/CMakeLists.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/debugger/debugger.c" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/debugger.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/debugger/memory_view.c" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/memory_view.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/debugger/memory_view.h" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/memory_view.h" 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="ProblemsViewState">
<option name="selectedTabId" value="CurrentFile" />
</component>
<component name="ProjectApplicationVersion">
<option name="ide" value="CLion" />
<option name="majorVersion" value="2023" />
<option name="minorVersion" value="2.2" />
</component>
<component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;&quot;,
&quot;associatedIndex&quot;: 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">{
&quot;keyToString&quot;: {
&quot;ASKED_ADD_EXTERNAL_FILES&quot;: &quot;true&quot;,
&quot;CMake Application.NESEmulator (Term).executor&quot;: &quot;Run&quot;,
&quot;CMake Application.NESEmulator.executor&quot;: &quot;Run&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.cidr.known.project.marker&quot;: &quot;true&quot;,
&quot;RunOnceActivity.readMode.enableVisualFormatting&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;cf.first.check.clang-format&quot;: &quot;false&quot;,
&quot;cidr.known.project.marker&quot;: &quot;true&quot;,
&quot;com.jfrog.conanplugin.addconansupport&quot;: &quot;true&quot;,
&quot;com.jfrog.conanplugin.automanage.cmake.advanced.settings&quot;: &quot;true&quot;,
&quot;com.jfrog.conanplugin.conanexecutable&quot;: &quot;conan&quot;,
&quot;com.jfrog.conanplugin.hasbeensetup&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;master&quot;,
&quot;last_opened_file_path&quot;: &quot;/home/william/Dev/ETS/LOG710/Lab2/CMakeLists.txt&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;configurable.group.editor&quot;,
&quot;structure.view.defaults.are.configured&quot;: &quot;true&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/include" />
<recent name="$PROJECT_DIR$/rom" />
<recent name="$PROJECT_DIR$/cpu" />
<recent name="$PROJECT_DIR$/include/cpu" />
<recent name="$PROJECT_DIR$" />
</key>
</component>
<component name="RunManager" selected="CMake Application.NESEmulator">
<configuration default="true" type="PythonConfigurationType" factoryName="Python">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="Tox" factoryName="Tox">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Autodetect">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Doctests">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="" />
<option name="CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="FOLDER_NAME" value="" />
<option name="TEST_TYPE" value="TEST_SCRIPT" />
<option name="PATTERN" value="" />
<option name="USE_PATTERN" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Nosetests">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_regexPattern" value="&quot;&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Twisted Trial">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Unittests">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="py.test">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_keywords" value="&quot;&quot;" />
<option name="_new_parameters" value="&quot;&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration name="NESEmulator" type="CMakeListConfigurationType" factoryName="CMakeListConfigurationFactory" temporary="true">
<method v="2" />
</configuration>
<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="DEBUG" 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="DEBUG" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="Mappers" 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="Mappers" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="NESEmulator (GDB Server)" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="-- /usr/bin/gdbserver localhost:1234 $CMakeCurrentBuildDir$/NESEmulator" 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_PATH="/usr/bin/gnome-terminal">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="NESEmulator (Term)" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="-- $CMakeCurrentBuildDir$/NESEmulator" 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_PATH="/usr/bin/gnome-terminal">
<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="true" 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>
<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>
<configuration name="PPU" 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="PPU" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="ROM" 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="ROM" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration default="true" type="PythonConfigurationType" factoryName="Python">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="Tox" factoryName="Tox">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Autodetect">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Doctests">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="" />
<option name="CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="FOLDER_NAME" value="" />
<option name="TEST_TYPE" value="TEST_SCRIPT" />
<option name="PATTERN" value="" />
<option name="USE_PATTERN" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Nosetests">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_regexPattern" value="&quot;&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Twisted Trial">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Unittests">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="py.test">
<module name="nesemu" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_keywords" value="&quot;&quot;" />
<option name="_new_parameters" value="&quot;&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<list>
<item itemvalue="CMake Debug.NESEmulator" />
<item itemvalue="CMake Application.CPU" />
<item itemvalue="CMake Application.DEBUG" />
<item itemvalue="CMake Application.Mappers" />
<item itemvalue="CMake Application.NESEmulator (GDB Server)" />
<item itemvalue="CMake Application.NESEmulator (Term)" />
<item itemvalue="CMake Application.NESEmulator" />
<item itemvalue="CMake Application.PPU" />
<item itemvalue="CMake Application.ROM" />
</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" />
<workItem from="1696705497743" duration="219000" />
<workItem from="1696705726453" duration="4200000" />
<workItem from="1696811216438" duration="1141000" />
<workItem from="1697310877679" duration="207000" />
<workItem from="1697340607326" duration="3636000" />
<workItem from="1697386768217" duration="19159000" />
<workItem from="1697491210595" duration="714000" />
<workItem from="1698343311430" duration="84000" />
<workItem from="1700970472703" duration="9613000" />
<workItem from="1701463001105" duration="2058000" />
<workItem from="1701558929054" duration="14565000" />
<workItem from="1703367277258" duration="1000" />
<workItem from="1703810207562" duration="27667000" />
<workItem from="1703912983973" duration="23543000" />
<workItem from="1704429138262" duration="2629000" />
<workItem from="1704484992884" duration="2000" />
<workItem from="1704501418104" duration="8204000" />
<workItem from="1704569084127" duration="8903000" />
<workItem from="1704582152049" duration="7863000" />
<workItem from="1704660072645" duration="19497000" />
<workItem from="1704934699461" duration="5989000" />
<workItem from="1705006965034" duration="2000" />
</task>
<task id="LOCAL-00001" summary="Cpu opcodes implementation">
<option name="closed" value="true" />
<created>1701018709236</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1701018709236</updated>
</task>
<task id="LOCAL-00002" summary="Gitignore">
<option name="closed" value="true" />
<created>1701463073548</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1701463073548</updated>
</task>
<task id="LOCAL-00003" summary="Added logging for operand decoding">
<option name="closed" value="true" />
<created>1703369431911</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1703369431911</updated>
</task>
<task id="LOCAL-00004" summary="Things">
<option name="closed" value="true" />
<created>1704569231622</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1704569231622</updated>
</task>
<task id="LOCAL-00005" summary="Memory debugger">
<option name="closed" value="true" />
<created>1704662439962</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1704662439962</updated>
</task>
<task id="LOCAL-00006" summary="Finished read-only memory debugger">
<option name="closed" value="true" />
<created>1704829582042</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1704829582042</updated>
</task>
<task id="LOCAL-00007" summary="gitignore">
<option name="closed" value="true" />
<created>1704903354414</created>
<option name="number" value="00007" />
<option name="presentableId" value="LOCAL-00007" />
<option name="project" value="LOCAL" />
<updated>1704903354414</updated>
</task>
<option name="localTasksCounter" value="8" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VCPKGProject">
<isAutomaticCheckingOnLaunch value="false" />
<isAutomaticFoundErrors value="true" />
<isAutomaticReloadCMake value="true" />
</component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="Cpu opcodes implementation" />
<MESSAGE value="Gitignore" />
<MESSAGE value="Added logging for operand decoding" />
<MESSAGE value="Things" />
<MESSAGE value="Memory debugger" />
<MESSAGE value="Finished read-only memory debugger" />
<MESSAGE value="gitignore" />
<option name="LAST_COMMIT_MESSAGE" value="gitignore" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
<url>file://$PROJECT_DIR$/system.c</url>
<line>51</line>
<option name="timeStamp" value="8" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

View File

@ -3,11 +3,7 @@ add_library(DEBUG
memory_view.c
dialog.c
program_view.c
program_view.h
cursor.c
cursor.h
window.c
window.h)
program_view.h)
find_package(Curses)

View File

@ -1,78 +0,0 @@
//
// Created by william on 1/12/24.
//
#include <assert.h>
#include "cursor.h"
void cursor_init(Cursor *cursor, WINDOW *window, int max_x, int max_y) {
cursor->window = window;
cursor->min_x = 1;
cursor->min_y = 1;
cursor->max_x = max_x;
cursor->max_y = max_y;
cursor->multiplier_x = 1;
cursor->multiplier_y = 1;
cursor->width = 1;
cursor->pos_x = 0;
cursor->pos_y = 0;
cursor->enabled = false;
}
void cursor_set_at(Cursor *cursor, int at) {
int win_x = cursor->min_x + cursor->pos_x * cursor->multiplier_x;
int win_y = cursor->min_y + cursor->pos_y * cursor->multiplier_y;
mvwchgat(cursor->window, win_y, win_x, cursor->width, at, 0, NULL);
}
void cursor_enable(Cursor *cursor) {
cursor_set_at(cursor, CURSOR_AT_ENABLED);
cursor->enabled = true;
}
void cursor_disable(Cursor *cursor) {
cursor_set_at(cursor, CURSOR_AT_DISABLED);
cursor->enabled = false;
}
void cursor_set_pos(Cursor *cursor, int x, int y) {
assert(x >= 0);
assert(y >= 0);
bool enabled = cursor->enabled;
if (enabled) {
// Remove the cursor from its old position
cursor_disable(cursor);
}
cursor->pos_x = x;
cursor->pos_y = y;
if (enabled) {
// Display the cursor in the new position
cursor_enable(cursor);
}
}
int cursor_limit(int value, int limit) {
if (value < 0) {
return 0;
}
if (value > limit) {
return limit;
}
return value;
}
void cursor_move(Cursor *cursor, int offset_x, int offset_y) {
int x = cursor->pos_x + offset_x;
x = cursor_limit(x, cursor->max_x);
int y = cursor->pos_y + offset_y;
y = cursor_limit(y, cursor->max_y);
cursor_set_pos(cursor, x, y);
}

View File

@ -1,74 +0,0 @@
//
// Created by william on 1/12/24.
//
#ifndef NESEMULATOR_CURSOR_H
#define NESEMULATOR_CURSOR_H
#include <curses.h>
#define CURSOR_OFFSET_UP (-1)
#define CURSOR_OFFSET_DOWN 1
#define CURSOR_OFFSET_LEFT (-1)
#define CURSOR_OFFSET_RIGHT 1
#define CURSOR_AT_ENABLED A_REVERSE
#define CURSOR_AT_DISABLED A_NORMAL
typedef struct cursor {
WINDOW *window;
int min_x;
int min_y;
int max_x;
int max_y;
int multiplier_x;
int multiplier_y;
int width;
int pos_x;
int pos_y;
bool enabled;
} Cursor;
/**
* Initializes a cursor with default values.
*
* @param cursor A reference to the cursor to initialize
* @param window The window the cursor is in
*/
void cursor_init(Cursor *cursor, WINDOW *window, int max_x, int max_y);
/**
* Enables a cursor, making it visible in its window.
*
* @param cursor The cursor
*/
void cursor_enable(Cursor *cursor);
/**
* Disables a cursor, removing it from the display.
*
* @param cursor The cursor
*/
void cursor_disable(Cursor *cursor);
/**
* Sets the position of the cursor.
* The positions are from left to right (horizontal) and top to bottom (vertical).
*
* @param cursor The cursor
* @param x The new horizontal position
* @param y The new vertical position
*/
void cursor_set_pos(Cursor *cursor, int x, int y);
/**
* Moves the position of the cursor by an offset. This function ensures that the cursor is kept in the window bounds.
* A negative offset moves the cursor position towards the 0 direction (left or top).
* A position offset moves it in the opposite direction (right or bottom).
*
* @param cursor The cursor
* @param offset_x The horizontal offset
* @param offset_y The vertical offset
*/
void cursor_move(Cursor *cursor, int offset_x, int offset_y);
#endif //NESEMULATOR_CURSOR_H

View File

@ -25,13 +25,13 @@ void create_window() {
}
void start_debugger(System *system) {
InteractWindow windows[2];
InteractWindow *current_window;
MemoryView m_view;
ProgramView p_view;
create_window();
memory_view_init(&windows[0], system->ram, 0, 0);
program_view_init(&windows[1], system->ram, MEMORY_VIEW_WIDTH, 0);
memory_view_init(&m_view, system->ram, 0, 0);
program_view_init(&p_view, MEMORY_VIEW_WIDTH, 0);
update_panels();
doupdate();
@ -39,19 +39,19 @@ void start_debugger(System *system) {
int keycode;
while ((keycode = getch()) != CTRL_KEY_EXIT) {
if (keycode == KEY_UP) {
current_window->handle_cursor_move(current_window, 0, CURSOR_OFFSET_UP);
memory_view_move_cursor(&m_view, 0, MEMORY_VIEW_DIRECTION_DOWN);
}
if (keycode == KEY_DOWN) {
current_window->handle_cursor_move(current_window, 0, CURSOR_OFFSET_DOWN);
memory_view_move_cursor(&m_view, 0, MEMORY_VIEW_DIRECTION_UP);
}
if (keycode == KEY_LEFT) {
current_window->handle_cursor_move(current_window, CURSOR_OFFSET_LEFT, 0);
memory_view_move_cursor(&m_view, MEMORY_VIEW_DIRECTION_LEFT, 0);
}
if (keycode == KEY_RIGHT) {
current_window->handle_cursor_move(current_window, CURSOR_OFFSET_RIGHT, 0);
memory_view_move_cursor(&m_view, MEMORY_VIEW_DIRECTION_RIGHT, 0);
}
if (keycode == CTRL_KEY_G) {
@ -63,7 +63,7 @@ void start_debugger(System *system) {
if (!cancelled) {
memory_view_goto(&m_view, input);
memory_view_cursor_set_addr(&m_view, input);
memory_view_set_cursor_addr(&m_view, input);
}
}
@ -71,8 +71,5 @@ void start_debugger(System *system) {
doupdate();
}
window_inter_deinit(&windows[0]);
window_inter_deinit(&windows[1]);
endwin();
}

View File

@ -2,11 +2,11 @@
// Created by william on 1/6/24.
//
#include "../include/system.h"
#ifndef NESEMULATOR_DEBUGGER_H
#define NESEMULATOR_DEBUGGER_H
#include "../include/system.h"
void start_debugger(System *system);
#endif //NESEMULATOR_DEBUGGER_H

View File

@ -1,47 +1,58 @@
#include <curses.h>
#include <panel.h>
#include <assert.h>
#include <stdlib.h>
#include "memory_view.h"
//
// Created by william on 6/1/24.
// Created by william on 1/6/24.
//
void memory_view_write_line(MemoryView *view, int line, address base_address, byte *data) {
window_inter_print(view->window, 0, line + 1, "[%04x]", base_address);
void memory_view_highlight_cursor(MemoryView *view) {
int win_x = 8 + view->cursor_x * 3;
int win_y = 2 + view->cursor_y;
mvwchgat(view->panel->win, win_y, win_x, 2, A_REVERSE, 0, NULL);
}
void memory_view_set_cursor_pos(MemoryView *view, int x, int y) {
assert(x >= 0);
assert(x <= 0xf);
assert(y >= 0);
assert(y <= 0xf);
int old_win_x = 8 + view->cursor_x * 3;
int old_win_y = 2 + view->cursor_y;
mvwchgat(view->panel->win, old_win_y, old_win_x, 2, A_NORMAL, 0, NULL);
view->cursor_x = (char) x;
view->cursor_y = (char) y;
memory_view_highlight_cursor(view);
}
void memory_view_write_line(WINDOW *window, int line, address base_address, byte *data) {
mvwprintw(window, line + 2, 1, "[%04x]", base_address);
for (int i = 0; i <= MEMORY_VIEW_LINE_BYTE_COUNT; i++) {
window_inter_print(view->window, 7 + i * 3, line + 1, "%02x", data[i]);
mvwprintw(window, line + 2, 8 + i * 3, "%02x", data[i]);
}
}
void memory_view_cursor_init(MemoryView *view) {
Cursor *cursor = &view->window->cursor;
window_inter_cursor_init(view->window, 0xf, 0xf);
cursor->min_x = 8;
cursor->min_y = 2;
cursor->multiplier_x = 3;
cursor->width = 2;
void memory_view_init(MemoryView *view, ram ram, int x, int y) {
WINDOW *window = newwin(MEMORY_VIEW_HEIGHT, MEMORY_VIEW_WIDTH, y, x);
box(window, 0, 0);
cursor_enable(cursor);
}
mvwprintw(window, 0, 1, " MEMORY VIEW ");
mvwprintw(window, 1, 1, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
void memory_view_handle_key_down(InteractWindow *window, int keycode) {
}
void memory_view_init(InteractWindow *interact, ram ram, int x, int y) {
MemoryView *view = malloc(sizeof(MemoryView));
view->window = interact;
view->panel = new_panel(window);
view->ram = ram;
view->base_address = 0x0000;
interact->view = view;
interact->handle_cursor_move = &memory_view_cursor_move;
interact->handle_key_down = &memory_view_handle_key_down;
window_inter_init(interact, x, y, MEMORY_VIEW_WIDTH, MEMORY_VIEW_HEIGHT, "MEMORY VIEW");
window_inter_print(interact, 0, 0, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
view->cursor_x = 0;
view->cursor_y = 0;
memory_view_print(view);
memory_view_cursor_init(view);
memory_view_set_cursor_pos(view, 0, 0);
}
void memory_view_print(MemoryView *view) {
@ -49,7 +60,7 @@ void memory_view_print(MemoryView *view) {
address line_address = view->base_address + line * (MEMORY_VIEW_LINE_BYTE_COUNT + 1);
byte *data = &view->ram[line_address];
memory_view_write_line(view, line, line_address, data);
memory_view_write_line(view->panel->win, line, line_address, data);
}
}
@ -66,14 +77,14 @@ void memory_view_goto(MemoryView *view, address target) {
memory_view_print(view);
}
void memory_view_scroll(MemoryView *view, int direction) {
assert(direction == CURSOR_OFFSET_DOWN || direction == CURSOR_OFFSET_UP);
void memory_view_scroll(MemoryView *view, char direction) {
assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP);
int offset = 0;
if (direction == CURSOR_OFFSET_UP && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) {
if (direction == MEMORY_VIEW_DIRECTION_DOWN && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) {
offset -= MEMORY_VIEW_LINE_BYTE_COUNT + 1;
}
if (direction == CURSOR_OFFSET_DOWN && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) {
if (direction == MEMORY_VIEW_DIRECTION_UP && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) {
offset += MEMORY_VIEW_LINE_BYTE_COUNT + 1;
}
@ -81,23 +92,28 @@ void memory_view_scroll(MemoryView *view, int direction) {
memory_view_goto(view, target);
}
void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical) {
MemoryView *view = (MemoryView *) window->view;
if (vertical == CURSOR_OFFSET_DOWN && view->window->cursor.pos_y == 0xf ||
vertical == CURSOR_OFFSET_UP && view->window->cursor.pos_y == 0) {
// Scroll the view
memory_view_scroll(view, vertical);
void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical) {
if (horizontal == MEMORY_VIEW_DIRECTION_UP && view->cursor_x == 0xf ||
horizontal == MEMORY_VIEW_DIRECTION_DOWN && view->cursor_x == 0) {
return;
}
// We are not on any edge, move the cursor
cursor_move(&view->window->cursor, horizontal, vertical);
if (vertical == MEMORY_VIEW_DIRECTION_RIGHT && view->cursor_y == 0xf ||
vertical == MEMORY_VIEW_DIRECTION_LEFT && view->cursor_y == 0) {
memory_view_scroll(view, vertical);
memory_view_highlight_cursor(view);
return;
}
int target_x = view->cursor_x + horizontal;
int target_y = view->cursor_y + vertical;
memory_view_set_cursor_pos(view, target_x, target_y);
}
void memory_view_cursor_set_addr(MemoryView *view, address target) {
void memory_view_set_cursor_addr(MemoryView *view, address target) {
int view_byte = target - view->base_address;
int x = view_byte & 0x0f;
int y = (view_byte & 0xf0) >> 4;
cursor_set_pos(&view->window->cursor, x, y);
memory_view_set_cursor_pos(view, x, y);
}

View File

@ -1,5 +1,5 @@
//
// Created by william on 6/1/24.
// Created by william on 1/6/24.
//
#ifndef NESEMULATOR_MEMORY_VIEW_H
@ -7,8 +7,6 @@
#include <panel.h>
#include "../include/types.h"
#include "cursor.h"
#include "window.h"
#define MEMORY_VIEW_HEIGHT 19
#define MEMORY_VIEW_WIDTH 56
@ -16,10 +14,17 @@
#define MEMORY_VIEW_LINE_BYTE_COUNT 0xf
#define MEMORY_VIEW_BYTE_COUNT 0xff
#define MEMORY_VIEW_DIRECTION_UP 1
#define MEMORY_VIEW_DIRECTION_DOWN (-1)
#define MEMORY_VIEW_DIRECTION_RIGHT 1
#define MEMORY_VIEW_DIRECTION_LEFT (-1)
typedef struct memory_view {
InteractWindow *window;
PANEL *panel;
byte *ram;
address base_address;
char cursor_x;
char cursor_y;
} MemoryView;
/**
@ -29,7 +34,7 @@ typedef struct memory_view {
* @param view A pointer to the view to initialize
* @param ram A pointer to the RAM
*/
void memory_view_init(InteractWindow *interact, ram ram, int x, int y);
void memory_view_init(MemoryView *view, ram ram, int x, int y);
/**
* Prints the RAM content from the viewer base address.
@ -52,7 +57,7 @@ void memory_view_goto(MemoryView *view, address target);
* @param view
* @param direction The scroll direction
*/
void memory_view_scroll(MemoryView *view, int direction);
void memory_view_scroll(MemoryView *view, char direction);
/**
* Moves the cursor up, down, right or left.
@ -61,7 +66,7 @@ void memory_view_scroll(MemoryView *view, int direction);
* @param horizontal
* @param vertical
*/
void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical);
void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical);
/**
* Moves the cursor to a specific memory address.
@ -70,6 +75,6 @@ void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertica
* @param view
* @param target
*/
void memory_view_cursor_set_addr(MemoryView *view, address target);
void memory_view_set_cursor_addr(MemoryView *view, address target);
#endif //NESEMULATOR_MEMORY_VIEW_H

View File

@ -2,118 +2,42 @@
// Created by william on 10/01/24.
//
#include <stdlib.h>
#include "program_view.h"
#include "../cpu/op.h"
void decode_operands(DebugOperand *operands, const byte *ram, address start_addr) {
void decode_operands(byte *ram, address start_addr) {
int pc = start_addr;
for (int i = 0; i < 10; i++) {
DebugOperand operand;
byte op_code = ram[pc];
operand.addr = pc;
operand.op_code = op_code;
operand.addr_mode = get_op_addr_mode(op_code);
pc += 1;
if (operand.addr_mode == ADDR_MODE_ACCUMULATOR || operand.addr_mode == ADDR_MODE_IMPLICIT) {
operand.type = OPERAND_TYPE_ACCUMULATOR;
operand.value = 0;
} else if (operand.addr_mode == ADDR_MODE_IMMEDIATE) {
operand.type = OPERAND_TYPE_IMMEDIATE;
operand.value = ram[pc];
pc += 1;
} else if (operand.addr_mode == ADDR_MODE_RELATIVE) {
operand.type = OPERAND_TYPE_ADDRESS;
operand.value = ram[pc];
pc += 1;
} else {
operand.type = OPERAND_TYPE_ADDRESS;
operand.value = ram[pc];
operand.value += ram[pc + 1] << 8;
pc += 2;
}
operands[i] = operand;
}
}
char *get_addr_mode_format_str(AddressingMode addr_mode) {
switch (addr_mode) {
case ADDR_MODE_ABSOLUTE:
return "$%04x";
case ADDR_MODE_ABSOLUTE_INDEXED_X:
return "$%04x,x";
case ADDR_MODE_ABSOLUTE_INDEXED_Y:
return "$%04x,y";
case ADDR_MODE_ACCUMULATOR:
return "A";
case ADDR_MODE_IMMEDIATE:
return "#$%02x";
case ADDR_MODE_IMPLICIT:
return "";
case ADDR_MODE_INDIRECT_X:
return "($%04x,x)";
case ADDR_MODE_INDIRECT_JUMP:
return "($%04x)";
case ADDR_MODE_INDIRECT_Y:
return "($%04x),y";
case ADDR_MODE_RELATIVE:
return "$%04x";
case ADDR_MODE_ZERO_PAGE:
return "$%02x,y";
case ADDR_MODE_ZERO_PAGE_INDEXED_X:
return "$%02x,x";
case ADDR_MODE_ZERO_PAGE_INDEXED_Y:
return "$%02x,y";
void program_view_write_line(WINDOW *window, int line, address addr) {
mvwprintw(window, line + 1, 1, "%04x:", addr);
mvwprintw(window, line + 1, 7, "%s", "BRK");
}
void program_view_print(ProgramView *view) {
for (int line = 0; line <= 0xf; line++) {
address addr = 0x8000 + line;
program_view_write_line(view->panel->win, line, addr);
}
}
void program_view_write_line(ProgramView *view, int line, DebugOperand *operand) {
char *op_name = get_op_code_name(operand->op_code);
void program_view_init(ProgramView *view, ram ram, int x, int y) {
WINDOW *window = newwin(PROGRAM_VIEW_HEIGHT, PROGRAM_VIEW_WIDTH, y, x);
box(window, 0, 0);
window_inter_print(view->window, 0, line, "%04x:", operand->addr);
window_inter_print(view->window, 6, line, "%s", op_name);
mvwprintw(window, 0, 1, " PROGRAM VIEW ");
char *format = get_addr_mode_format_str(operand->addr_mode);
window_inter_print(view->window, 10, line, format, operand->value);
}
void program_view_print(ProgramView *view, DebugOperand *operands) {
for (int line = 0; line < 10; line++) {
program_view_write_line(view, line, &operands[line]);
}
}
void program_view_cursor_init(ProgramView *view) {
window_inter_cursor_init(view->window, 0, 10);
view->window->cursor.width = PROGRAM_VIEW_WIDTH - 2;
cursor_enable(&view->window->cursor);
}
void program_view_handle_cursor_move(InteractWindow *window, int horizontal, int vertical) {
cursor_move(&window->cursor, horizontal, vertical);
}
void program_view_handle_key_down(InteractWindow *window, int keycode) {
}
void program_view_init(InteractWindow *interact, ram ram, int x, int y) {
ProgramView *view = malloc(sizeof(ProgramView));
view->window = interact;
view->panel = new_panel(window);
view->ram = ram;
interact->view = view;
interact->handle_cursor_move = &program_view_handle_cursor_move;
interact->handle_key_down = &program_view_handle_key_down;
window_inter_init(interact, x, y, PROGRAM_VIEW_WIDTH, PROGRAM_VIEW_HEIGHT, "PROGRAM VIEW");
DebugOperand operands[10];
decode_operands(&operands[0], ram, 0xc004);
program_view_print(view, &operands[0]);
program_view_cursor_init(view);
program_view_print(view);
}

View File

@ -2,32 +2,27 @@
// Created by william on 10/01/24.
//
#ifndef NESEMULATOR_PROGRAM_VIEW_H
#define NESEMULATOR_PROGRAM_VIEW_H
#include <panel.h>
#include "../include/types.h"
#include "../cpu/decoding.h"
#include "cursor.h"
#include "window.h"
#ifndef NESEMULATOR_PROGRAM_VIEW_H
#define NESEMULATOR_PROGRAM_VIEW_H
#define PROGRAM_VIEW_HEIGHT 19
#define PROGRAM_VIEW_WIDTH 42
typedef struct program_view {
InteractWindow *window;
PANEL *panel;
byte *ram;
address base_address;
} ProgramView;
typedef struct debug_operand {
address addr;
byte op_code;
AddressingMode addr_mode;
enum OperandType type;
word value;
} DebugOperand;
void program_view_init(InteractWindow *interact, ram ram, int x, int y);
void program_view_init(ProgramView *view, ram ram, int x, int y);
#endif //NESEMULATOR_PROGRAM_VIEW_H

View File

@ -1,61 +0,0 @@
//
// Created by william on 1/12/24.
//
#include <assert.h>
#include <stdlib.h>
#include "window.h"
void window_init(Window *window, int x, int y, int width, int height, char *title) {
assert(x >= 0);
assert(y >= 0);
assert(width > 0);
assert(height > 0);
WINDOW *curse_win = newwin(height, width, y, x);
box(curse_win, 0, 0);
mvwprintw(curse_win, 0, 1, " %s ", title);
window->panel = new_panel(curse_win);
window->width = width;
window->height = height;
}
void window_inter_init(InteractWindow *window, int x, int y, int width, int height, char *title) {
window_init(&window->window, x, y, width, height, title);
}
void window_print_va(Window *window, int x, int y, const char *fmt, va_list args) {
assert(x >= 0);
assert(x < window->width - 1);
assert(y >= 0);
assert(y < window->height - 1);
wmove(window->panel->win, y + 1, x + 1);
vw_printw(window->panel->win, fmt, args);
}
void window_inter_cursor_init(InteractWindow *window, int max_x, int max_y) {
cursor_init(&window->cursor, window->window.panel->win, max_x, max_y);
}
void window_print(Window *window, int x, int y, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
window_print_va(window, x, y, fmt, args);
va_end(args);
}
void window_inter_print(InteractWindow *window, int x, int y, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
window_print_va(&window->window, x, y, fmt, args);
va_end(args);
}
void window_inter_deinit(InteractWindow *window) {
assert(window->view != NULL);
free(window->view);
}

View File

@ -1,84 +0,0 @@
//
// Created by william on 1/12/24.
//
#ifndef NESEMULATOR_WINDOW_H
#define NESEMULATOR_WINDOW_H
#include <panel.h>
#include "cursor.h"
typedef struct window {
PANEL *panel;
int width;
int height;
} Window;
typedef struct interact_window {
Window window;
Cursor cursor;
void *view;
void (*handle_cursor_move)(struct interact_window *window, int horizontal, int vertical);
void (*handle_key_down)(struct interact_window *window, int keycode);
} InteractWindow;
/**
* Initializes a window with a position, size and title.
*
* @param window The window to initialize
* @param x The horizontal position (left to right)
* @param y The vertical position (top to bottom)
* @param width The window width
* @param height The window height
* @param title The window title
*/
void window_init(Window *window, int x, int y, int width, int height, char *title);
/**
* Initializes an interactable window with a position, size and title.
*
* @param window The window to initialize
* @param x The horizontal position (left to right)
* @param y The vertical position (top to bottom)
* @param width The window width
* @param height The window height
* @param title The window title
*/
void window_inter_init(InteractWindow *window, int x, int y, int width, int height, char *title);
/**
* Initializes the cursor of an interactable window.
*
* @param window The window
* @param max_x The cursor's maximum horizontal position
* @param max_y The cursor's maximum vertical position
*/
void window_inter_cursor_init(InteractWindow *window, int max_x, int max_y);
/**
* Prints text on a window.
*
* @param window The window
* @param x The horizontal position (left to right)
* @param y The vertical position (top to bottom)
* @param fmt A format string
* @param ... The format string arguments
*/
void window_print(Window *window, int x, int y, const char *fmt, ...);
/**
* Prints text on an interactable window.
*
* @param window The window
* @param x The horizontal position (left to right)
* @param y The vertical position (top to bottom)
* @param fmt A format string
* @param ... The format string arguments
*/
void window_inter_print(InteractWindow *window, int x, int y, const char *fmt, ...);
void window_inter_deinit(InteractWindow *window);
#endif //NESEMULATOR_WINDOW_H

View File

@ -1,4 +1,3 @@
BreakPoint: startAddr=00000014 endAddr=00000000 flags=ER--X- condition="" desc=""
BreakPoint: startAddr=00000023 endAddr=00000000 flags=ER--X- condition="" desc=""
BreakPoint: startAddr=00000000 endAddr=00000000 flags=EC--X- condition="" desc=""
Bookmark: addr=C10F desc=""