From 95fac5dc139eda01d3c66429f4559e7dad680ffa Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 9 Oct 2024 14:27:35 -0400 Subject: [PATCH 1/4] Begin macro elimination. --- InstructionSets/M50740/Executor.cpp | 39 +++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index 4c7a9cc22..48d1d12a5 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -380,8 +380,18 @@ template void Executor::pe // a write is valid [if required]. unsigned int address; -#define next8() memory_[(program_counter_ + 1) & 0x1fff] -#define next16() uint16_t(memory_[(program_counter_ + 1) & 0x1fff] | (memory_[(program_counter_ + 2) & 0x1fff] << 8)) + const auto next8 = [&]() -> uint8_t& { + return memory_[(program_counter_ + 1) & 0x1fff]; + }; + const auto next16 = [&] { + return uint16_t(memory_[(program_counter_ + 1) & 0x1fff] | (memory_[(program_counter_ + 2) & 0x1fff] << 8)); + }; + const auto bcc = [&](auto condition) { + if(condition) { + set_program_counter(uint16_t(address)); + subtract_duration(2); + } + }; // Underlying assumption below: the instruction stream will never // overlap with IO ports. @@ -487,8 +497,6 @@ template void Executor::pe assert(false); } -#undef next16 -#undef next8 program_counter_ += 1 + size(addressing_mode); // Check for a branch; those don't go through the memory accesses below. @@ -505,16 +513,14 @@ template void Executor::pe set_program_counter(uint16_t(address)); } return; -#define Bcc(c) if(c) { set_program_counter(uint16_t(address)); subtract_duration(2); } return - case Operation::BPL: Bcc(!(negative_result_&0x80)); - case Operation::BMI: Bcc(negative_result_&0x80); - case Operation::BEQ: Bcc(!zero_result_); - case Operation::BNE: Bcc(zero_result_); - case Operation::BCS: Bcc(carry_flag_); - case Operation::BCC: Bcc(!carry_flag_); - case Operation::BVS: Bcc(overflow_result_ & 0x80); - case Operation::BVC: Bcc(!(overflow_result_ & 0x80)); -#undef Bcc + case Operation::BPL: bcc(!(negative_result_&0x80)); return; + case Operation::BMI: bcc(negative_result_&0x80); return; + case Operation::BEQ: bcc(!zero_result_); return; + case Operation::BNE: bcc(zero_result_); return; + case Operation::BCS: bcc(carry_flag_); return; + case Operation::BCC: bcc(!carry_flag_); return; + case Operation::BVS: bcc(overflow_result_ & 0x80); return; + case Operation::BVC: bcc(!(overflow_result_ & 0x80)); return; default: break; } @@ -538,8 +544,10 @@ template void Executor::pe } template void Executor::perform(uint8_t *operand [[maybe_unused]]) { + const auto set_nz = [&](uint8_t result) { + negative_result_ = zero_result_ = result; + }; -#define set_nz(a) negative_result_ = zero_result_ = (a) switch(operation) { case Operation::LDA: if(index_mode_) { @@ -781,7 +789,6 @@ template void Executor::perform(uint8_t *operand [[maybe_u logger.error().append("Unimplemented operation: %d", operation); assert(false); } -#undef set_nz } inline void Executor::subtract_duration(int duration) { From 48387285211aaf3989bb19685b0e926a4e4d703b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 9 Oct 2024 21:04:32 -0400 Subject: [PATCH 2/4] Eliminate `nibble` macros. --- InstructionSets/M50740/Executor.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index 48d1d12a5..944b8280d 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -724,16 +724,15 @@ template void Executor::perform(uint8_t *operand [[maybe_u uint16_t partials = 0; int result = carry_flag_; -#define nibble(mask, limit, adjustment, carry) \ - result += (a & mask) + (*operand & mask); \ - partials += result & mask; \ - if(result >= limit) result = ((result + (adjustment)) & (carry - 1)) + carry; + const auto nibble = [&](uint16_t mask, uint16_t limit, uint16_t adjustment, uint16_t carry) { + result += (a & mask) + (*operand & mask); + partials += result & mask; + if(result >= limit) result = ((result + (adjustment)) & (carry - 1)) + carry; + }; nibble(0x000f, 0x000a, 0x0006, 0x00010); nibble(0x00f0, 0x00a0, 0x0060, 0x00100); -#undef nibble - overflow_result_ = uint8_t((partials ^ a) & (partials ^ *operand)); set_nz(uint8_t(result)); carry_flag_ = (result >> 8) & 1; @@ -742,17 +741,16 @@ template void Executor::perform(uint8_t *operand [[maybe_u unsigned int borrow = carry_flag_ ^ 1; const uint16_t decimal_result = uint16_t(a - *operand - borrow); -#define nibble(mask, adjustment, carry) \ - result += (a & mask) - (*operand & mask) - borrow; \ - if(result > mask) result -= adjustment; \ - borrow = (result > mask) ? carry : 0; \ - result &= (carry - 1); + const auto nibble = [&](uint16_t mask, uint16_t adjustment, uint16_t carry) { + result += (a & mask) - (*operand & mask) - borrow; + if(result > mask) result -= adjustment; + borrow = (result > mask) ? carry : 0; + result &= (carry - 1); + }; nibble(0x000f, 0x0006, 0x00010); nibble(0x00f0, 0x0060, 0x00100); -#undef nibble - overflow_result_ = uint8_t((decimal_result ^ a) & (~decimal_result ^ *operand)); set_nz(uint8_t(result)); carry_flag_ = ((borrow >> 8)&1)^1; From f136151064fc2a37a77d2e2a26e00647e96f779f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 9 Oct 2024 21:46:30 -0400 Subject: [PATCH 3/4] Transcribe op_X macros. --- InstructionSets/M50740/Executor.cpp | 39 ++++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index 944b8280d..2f006c1b1 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -547,6 +547,11 @@ template void Executor::perform(uint8_t *operand [[maybe_u const auto set_nz = [&](uint8_t result) { negative_result_ = zero_result_ = result; }; + const auto op_cmp = [&](uint8_t x) { + const uint16_t temp16 = x - *operand; + set_nz(uint8_t(temp16)); + carry_flag_ = (~temp16 >> 8)&1; + }; switch(operation) { case Operation::LDA: @@ -688,22 +693,27 @@ template void Executor::perform(uint8_t *operand [[maybe_u op(a_); \ } -#define op_ora(x) set_nz(x |= *operand) -#define op_and(x) set_nz(x &= *operand) -#define op_eor(x) set_nz(x ^= *operand) - case Operation::ORA: index(op_ora); break; - case Operation::AND: index(op_and); break; - case Operation::EOR: index(op_eor); break; -#undef op_eor -#undef op_and -#undef op_ora + case Operation::ORA: { + const auto op_ora = [&](uint8_t x) { + set_nz(x |= *operand); + }; + index(op_ora); + } break; + case Operation::AND: { + const auto op_and = [&](uint8_t x) { + set_nz(x &= *operand); + }; + index(op_and); + } break; + case Operation::EOR: { + const auto op_eor = [&](uint8_t x) { + set_nz(x ^= *operand); + }; + index(op_eor); + } break; + #undef index -#define op_cmp(x) { \ - const uint16_t temp16 = x - *operand; \ - set_nz(uint8_t(temp16)); \ - carry_flag_ = (~temp16 >> 8)&1; \ - } case Operation::CMP: if(index_mode_) { op_cmp(read(x_)); @@ -713,7 +723,6 @@ template void Executor::perform(uint8_t *operand [[maybe_u break; case Operation::CPX: op_cmp(x_); break; case Operation::CPY: op_cmp(y_); break; -#undef op_cmp case Operation::SBC: case Operation::ADC: { From 49012a21c8570ac882c658595c37a96bda557959 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 9 Oct 2024 21:50:03 -0400 Subject: [PATCH 4/4] Convert `index` macro. --- InstructionSets/M50740/Executor.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index 2f006c1b1..ee3bbff33 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -553,6 +553,16 @@ template void Executor::perform(uint8_t *operand [[maybe_u carry_flag_ = (~temp16 >> 8)&1; }; + const auto index = [&](auto op) { + if(index_mode_) { + uint8_t t = read(x_); + op(t); + write(x_, t); + } else { + op(a_); + } + }; + switch(operation) { case Operation::LDA: if(index_mode_) { @@ -684,36 +694,25 @@ template void Executor::perform(uint8_t *operand [[maybe_u Operations affected by the index mode flag: ADC, AND, CMP, EOR, LDA, ORA, and SBC. */ -#define index(op) \ - if(index_mode_) { \ - uint8_t t = read(x_); \ - op(t); \ - write(x_, t); \ - } else { \ - op(a_); \ - } - case Operation::ORA: { - const auto op_ora = [&](uint8_t x) { + const auto op_ora = [&](uint8_t &x) { set_nz(x |= *operand); }; index(op_ora); } break; case Operation::AND: { - const auto op_and = [&](uint8_t x) { + const auto op_and = [&](uint8_t &x) { set_nz(x &= *operand); }; index(op_and); } break; case Operation::EOR: { - const auto op_eor = [&](uint8_t x) { + const auto op_eor = [&](uint8_t &x) { set_nz(x ^= *operand); }; index(op_eor); } break; -#undef index - case Operation::CMP: if(index_mode_) { op_cmp(read(x_));