From 0fafbf50924366ecdd48b6bfeac04577ff81ae51 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 21 Jan 2021 19:08:38 -0500 Subject: [PATCH] Completes M50740 instruction set. --- InstructionSets/CachingExecutor.hpp | 7 +++++++ InstructionSets/M50740/Executor.cpp | 21 +++++++++++++++++---- InstructionSets/M50740/Executor.hpp | 1 + 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/InstructionSets/CachingExecutor.hpp b/InstructionSets/CachingExecutor.hpp index ada7dffd7..c5fc80753 100644 --- a/InstructionSets/CachingExecutor.hpp +++ b/InstructionSets/CachingExecutor.hpp @@ -118,6 +118,13 @@ template < // } } + /*! + Indicates whether the processor is currently 'stopped', i.e. whether all attempts to run + should produce no activity. Some processors have such a state when waiting for + interrupts or for a reset. + */ + void set_is_stopped(bool) {} + /*! Executes up to the next branch. */ diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index a9e1d6de1..def6927e6 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -116,6 +116,15 @@ uint8_t Executor::flags() { carry_flag_; } +template inline void Executor::perform_interrupt() { + // BRK has an unused operand. + ++program_counter_; + push(uint8_t(program_counter_ >> 8)); + push(uint8_t(program_counter_ & 0xff)); + push(flags() | (is_brk ? 0x10 : 0x00)); + set_program_counter(uint16_t(memory_[0x1ff4] | (memory_[0x1ff5] << 8))); +} + template void Executor::perform() { // Deal with all modes that don't access memory up here; // those that access memory will go through a slightly longer @@ -336,6 +345,14 @@ template void Executor::perform(uint8_t *operand [[maybe_u // after exiting from here. } break; + case Operation::BRK: + perform_interrupt(); + --program_counter_; // To undo the unavoidable increment + // after exiting from here. + break; + + case Operation::STP: set_is_stopped(true); break; + case Operation::COM: set_nz(*operand ^= 0xff); break; case Operation::FST: case Operation::SLW: case Operation::NOP: @@ -347,10 +364,6 @@ template void Executor::perform(uint8_t *operand [[maybe_u case Operation::PLA: set_nz(a_ = pull()); break; case Operation::PLP: set_flags(pull()); break; - // TODO: - // - // BRK, STP - case Operation::ASL: carry_flag_ = *operand >> 7; *operand <<= 1; diff --git a/InstructionSets/M50740/Executor.hpp b/InstructionSets/M50740/Executor.hpp index 1ab978fdd..744c4da43 100644 --- a/InstructionSets/M50740/Executor.hpp +++ b/InstructionSets/M50740/Executor.hpp @@ -132,6 +132,7 @@ class Executor: public CachingExecutor { inline uint8_t pull(); inline void set_flags(uint8_t); inline uint8_t flags(); + template inline void perform_interrupt(); }; }