diff --git a/Processors/Z80/Implementation/Z80Implementation.hpp b/Processors/Z80/Implementation/Z80Implementation.hpp index 12fb1ed70..7c39d0d65 100644 --- a/Processors/Z80/Implementation/Z80Implementation.hpp +++ b/Processors/Z80/Implementation/Z80Implementation.hpp @@ -18,23 +18,40 @@ template < class T, bool uses_bus_request, bool uses_wait_line> void Processor ::run_for(const HalfCycles cycles) { -#define advance_operation() \ - pc_increment_ = 1; \ - if(last_request_status_) { \ - halt_mask_ = 0xff; \ - if(last_request_status_ & (Interrupt::PowerOn | Interrupt::Reset)) { \ - request_status_ &= ~Interrupt::PowerOn; \ - scheduled_program_counter_ = reset_program_.data(); \ - } else if(last_request_status_ & Interrupt::NMI) { \ - request_status_ &= ~Interrupt::NMI; \ - scheduled_program_counter_ = nmi_program_.data(); \ - } else if(last_request_status_ & Interrupt::IRQ) { \ - scheduled_program_counter_ = irq_program_[interrupt_mode_].data(); \ - } \ - } else { \ - current_instruction_page_ = &base_page_; \ - scheduled_program_counter_ = base_page_.fetch_decode_execute_data; \ - } + + /// Schedules the next concrete block of work for the CPU, whatever that may be: + /// performing the reset, NMI or IRQ sequences, or fetching a new instruction. + const auto advance_operation = [&] { + pc_increment_ = 1; + if(last_request_status_) { + halt_mask_ = 0xff; + if(last_request_status_ & (Interrupt::PowerOn | Interrupt::Reset)) { + request_status_ &= ~Interrupt::PowerOn; + scheduled_program_counter_ = reset_program_.data(); + } else if(last_request_status_ & Interrupt::NMI) { + request_status_ &= ~Interrupt::NMI; + scheduled_program_counter_ = nmi_program_.data(); + } else if(last_request_status_ & Interrupt::IRQ) { + scheduled_program_counter_ = irq_program_[interrupt_mode_].data(); + } + } else { + current_instruction_page_ = &base_page_; + scheduled_program_counter_ = base_page_.fetch_decode_execute_data; + } + }; + + /// Indicates that the ALU was used in this operation; this affects flag output in future SCF and CCFs. + const auto set_did_compute_flags = [&] { + flag_adjustment_history_ |= 1; + }; + + /// Computes parity for @c v, leaving it bit 2 of parity_overflow_result_; the other bits are undefined. + const auto set_parity = [&](uint8_t v) { + parity_overflow_result_ = uint8_t(v^1); + parity_overflow_result_ ^= parity_overflow_result_ >> 4; + parity_overflow_result_ ^= parity_overflow_result_ << 2; + parity_overflow_result_ ^= parity_overflow_result_ >> 1; + }; number_of_cycles_ += cycles; if(!scheduled_program_counter_) { @@ -42,7 +59,6 @@ template < class T, } while(1) { - do_bus_acknowledge: while(uses_bus_request && bus_request_line_) { static PartialMachineCycle bus_acknowledge_cycle = {PartialMachineCycle::BusAcknowledge, HalfCycles(2), nullptr, nullptr, false}; @@ -56,15 +72,6 @@ template < class T, const MicroOp *const operation = scheduled_program_counter_; scheduled_program_counter_++; -#define set_did_compute_flags() \ - flag_adjustment_history_ |= 1; - -#define set_parity(v) \ - parity_overflow_result_ = uint8_t(v^1);\ - parity_overflow_result_ ^= parity_overflow_result_ >> 4;\ - parity_overflow_result_ ^= parity_overflow_result_ << 2;\ - parity_overflow_result_ ^= parity_overflow_result_ >> 1; - switch(operation->type) { case MicroOp::BusOperation: if(number_of_cycles_ < operation->machine_cycle.length) { @@ -449,12 +456,9 @@ template < class T, // MARK: - Exchange -#define swap(a, b) temp = a.full; a.full = b.full; b.full = temp; - - case MicroOp::ExDEHL: { - uint16_t temp; - swap(de_, hl_); - } break; + case MicroOp::ExDEHL: + std::swap(de_, hl_); + break; case MicroOp::ExAFAFDash: { const uint8_t a = a_; @@ -465,14 +469,11 @@ template < class T, af_dash_.halves.low = f; } break; - case MicroOp::EXX: { - uint16_t temp; - swap(de_, de_dash_); - swap(bc_, bc_dash_); - swap(hl_, hl_dash_); - } break; - -#undef swap + case MicroOp::EXX: + std::swap(de_, de_dash_); + std::swap(bc_, bc_dash_); + std::swap(hl_, hl_dash_); + break; // MARK: - Repetition @@ -890,7 +891,6 @@ template < class T, case MicroOp::IndexedPlaceHolder: return; } -#undef set_parity } } @@ -926,8 +926,6 @@ template < class T, return wait_line_; } -#define isTerminal(n) (n == MicroOp::MoveToNextProgram || n == MicroOp::DecodeOperation) - template < class T, bool uses_bus_request, bool uses_wait_line> void Processor @@ -938,7 +936,7 @@ template < class T, // Count number of micro-ops required. for(int c = 0; c < 256; c++) { std::size_t length = 0; - while(!isTerminal(table[c][length].type)) length++; + while(!is_terminal(table[c][length].type)) length++; length++; lengths[c] = length; number_of_micro_ops += length; @@ -995,7 +993,7 @@ template < class T, bool uses_wait_line> void Processor ::copy_program(const MicroOp *source, std::vector &destination) { std::size_t length = 0; - while(!isTerminal(source[length].type)) length++; + while(!is_terminal(source[length].type)) length++; std::size_t pointer = 0; while(true) { // TODO: This test is duplicated from assemble_page; can a better factoring be found? @@ -1006,13 +1004,11 @@ template < class T, } destination.emplace_back(source[pointer]); - if(isTerminal(source[pointer].type)) break; + if(is_terminal(source[pointer].type)) break; pointer++; } } -#undef isTerminal - bool ProcessorBase::get_halt_line() const { return halt_mask_ == 0x00; } diff --git a/Processors/Z80/Implementation/Z80Storage.hpp b/Processors/Z80/Implementation/Z80Storage.hpp index b88bf2a84..aaf07e8c9 100644 --- a/Processors/Z80/Implementation/Z80Storage.hpp +++ b/Processors/Z80/Implementation/Z80Storage.hpp @@ -115,6 +115,9 @@ class ProcessorStorage { void *destination = nullptr; PartialMachineCycle machine_cycle{}; }; + static constexpr bool is_terminal(MicroOp::Type type) { + return type == MicroOp::MoveToNextProgram || type == MicroOp::DecodeOperation; + } struct InstructionPage { std::vector instructions; diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index b5a453640..a1271ab32 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -9,6 +9,7 @@ #ifndef Z80_hpp #define Z80_hpp +#include #include #include #include