diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/test.yml similarity index 81% rename from .gitea/workflows/build.yml rename to .gitea/workflows/test.yml index cbc8480..cf4cb0b 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/test.yml @@ -1,4 +1,4 @@ -name: Build +name: Test on: push @@ -12,3 +12,5 @@ jobs: run: cmake -S emulator -B emulator/build - name: Build run: cmake --build emulator/build + - name: Test + ctest emulator/build diff --git a/emulator/CMakeLists.txt b/emulator/CMakeLists.txt index abcebcd..bef228e 100644 --- a/emulator/CMakeLists.txt +++ b/emulator/CMakeLists.txt @@ -1,5 +1,14 @@ cmake_minimum_required(VERSION 3.20) -project(foot-emu) +project(foot-emulator) -add_executable(foot-emu main.cpp foot-emulator.cpp foot-emulator.h) +add_library(foot-emulator src/foot-emulator.cpp include/foot-emulator.h) +target_include_directories(foot-emulator PUBLIC include) + +add_executable(foot-emulator-cli src/main.cpp) +target_link_libraries(foot-emulator-cli PUBLIC foot-emulator) + +if(PROJECT_IS_TOP_LEVEL) + enable_testing() + add_subdirectory(tests) +endif() diff --git a/emulator/foot-emulator.h b/emulator/include/foot-emulator.h similarity index 97% rename from emulator/foot-emulator.h rename to emulator/include/foot-emulator.h index b97a5a3..e1c2373 100644 --- a/emulator/foot-emulator.h +++ b/emulator/include/foot-emulator.h @@ -59,6 +59,9 @@ public: uint16_t& memory_at(uint16_t address); uint16_t& decode_operand(Operand operand); + uint16_t& register_at(uint8_t index); + + void run_instruction(); private: std::array memory; @@ -76,7 +79,6 @@ private: uint16_t mapped_base; void read_instruction(); - void run_instruction(); void CNST(); void CMPR(); diff --git a/emulator/foot-emulator.cpp b/emulator/src/foot-emulator.cpp similarity index 98% rename from emulator/foot-emulator.cpp rename to emulator/src/foot-emulator.cpp index 773307d..8858e65 100644 --- a/emulator/foot-emulator.cpp +++ b/emulator/src/foot-emulator.cpp @@ -91,12 +91,9 @@ uint16_t& Emulator::decode_operand(Operand operand) } } -void Emulator::read_instruction() +uint16_t& Emulator::register_at(uint8_t index) { - uint16_t low = memory[registers[PC]++]; - uint16_t high = memory[registers[PC]++]; - - instruction = (uint32_t(high) << 16) | uint32_t(low); + return registers[index]; } void Emulator::run_instruction() @@ -197,6 +194,14 @@ void Emulator::run_instruction() if (rep) { registers[LC] = loop_count; } } +void Emulator::read_instruction() +{ + uint16_t low = memory[registers[PC]++]; + uint16_t high = memory[registers[PC]++]; + + instruction = (uint32_t(high) << 16) | uint32_t(low); +} + void Emulator::CNST() { decode_operand((instruction & 0x00FF0000) >> 16) = instruction & 0x0000FFFF; diff --git a/emulator/main.cpp b/emulator/src/main.cpp similarity index 100% rename from emulator/main.cpp rename to emulator/src/main.cpp diff --git a/emulator/tests/CMakeLists.txt b/emulator/tests/CMakeLists.txt new file mode 100644 index 0000000..dc68f0e --- /dev/null +++ b/emulator/tests/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.20) + +include(CTest) + +function(test name) + add_executable(foot-emulator-test-${name} ${name}.cpp test-common.h) + target_link_libraries(foot-emulator-test-${name} PUBLIC foot-emulator) + add_test(NAME ${name} COMMAND foot-emulator-test-${name}) +endfunction() + +test(cnst-instruction) diff --git a/emulator/tests/cnst-instruction.cpp b/emulator/tests/cnst-instruction.cpp new file mode 100644 index 0000000..c68abac --- /dev/null +++ b/emulator/tests/cnst-instruction.cpp @@ -0,0 +1,27 @@ +#include +#include "test-common.h" + +int main(int argc, char** argv) +{ + // CNST + // dst - 0, Direct + // imm - 0xFFFF + { + foot::Emulator emu = run_instruction(0x0020FFFF); + if (emu.register_at(0) != 0xFFFF) { return 1; } + } + + // CNST + // dst - 0, Direct + // imm - 0xFFFF + // + // CNST + // dst - 0, Indirect + // imm = 0x7777 + { + foot::Emulator emu = run_instructions({ 0x0020FFFF, 0x00807777 }); + if (emu.memory_at(0xFFFF) != 0x7777) { return 1; } + } + + return 0; +} diff --git a/emulator/tests/test-common.h b/emulator/tests/test-common.h new file mode 100644 index 0000000..2cdf7a7 --- /dev/null +++ b/emulator/tests/test-common.h @@ -0,0 +1,29 @@ +#include + +inline foot::Emulator run_instruction(uint32_t instruction) +{ + foot::Emulator emu; + emu.memory_at(0) = instruction & 0xFFFF; + emu.memory_at(1) = (instruction >> 16) & 0xFFFF; + + emu.run_instruction(); + + return emu; +} + +inline foot::Emulator run_instructions(const std::vector& instructions) +{ + foot::Emulator emu; + for (int i = 0; i < instructions.size(); i++) + { + emu.memory_at(i * 2) = instructions[i] & 0xFFFF; + emu.memory_at(i * 2 + 1) = (instructions[i] >> 16) & 0xFFFF; + } + + for (int i = 0; i < instructions.size(); i++) + { + emu.run_instruction(); + } + + return emu; +}