Tidy instruction prefixing in the 6809, such that executed/ing instruction events fire correctly.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-08-24 10:49:13 +01:00
parent a43b1109bc
commit 57928602d5
2 changed files with 31 additions and 42 deletions

View File

@ -119,9 +119,9 @@ namespace EightBit {
// Execution helpers // Execution helpers
int executeUnprefixed(uint8_t opcode); void executeUnprefixed(uint8_t opcode);
int execute10(uint8_t opcode); void execute10(uint8_t opcode);
int execute11(uint8_t opcode); void execute11(uint8_t opcode);
// Register selection for "indexed" // Register selection for "indexed"
register16_t& RR(int which); register16_t& RR(int which);

View File

@ -2,6 +2,7 @@
#include "mc6809.h" #include "mc6809.h"
#include <algorithm> #include <algorithm>
#include <cassert>
EightBit::mc6809::mc6809(Bus& bus) EightBit::mc6809::mc6809(Bus& bus)
: BigEndianProcessor(bus) {} : BigEndianProcessor(bus) {}
@ -14,39 +15,46 @@ int EightBit::mc6809::step() {
resetCycles(); resetCycles();
auto returned = 0; auto returned = 0;
if (LIKELY(powered())) { if (LIKELY(powered())) {
m_prefix10 = m_prefix11 = false;
ExecutingInstruction.fire(*this); ExecutingInstruction.fire(*this);
returned = execute(fetchByte()); return execute(fetchByte());
ExecutedInstruction.fire(*this); ExecutedInstruction.fire(*this);
} }
return returned; return cycles();
} }
void EightBit::mc6809::reset() { void EightBit::mc6809::reset() {
Processor::reset(); Processor::reset();
DP() = 0; // Reestablish zero page DP() = 0; // Reestablish zero page
CC() |= (IF & FF); // Disable interrupts CC() |= (IF & FF); // Disable interrupts
m_prefix10 = m_prefix11 = false;
jump(getWordPaged(0xff, RESETvector)); jump(getWordPaged(0xff, RESETvector));
} }
int EightBit::mc6809::execute(uint8_t opcode) { int EightBit::mc6809::execute(uint8_t opcode) {
const bool prefixed = m_prefix10 || m_prefix11;
if (LIKELY(!prefixed)) {
executeUnprefixed(opcode);
} else {
if (m_prefix10) if (m_prefix10)
return execute10(opcode); execute10(opcode);
else if (m_prefix11) else if (m_prefix11)
return execute11(opcode); execute11(opcode);
return executeUnprefixed(opcode); else
UNREACHABLE;
}
assert(cycles() > 0);
return cycles();
} }
int EightBit::mc6809::executeUnprefixed(uint8_t opcode) { void EightBit::mc6809::executeUnprefixed(uint8_t opcode) {
ASSUME(!m_prefix10); assert(!(m_prefix10 || m_prefix11));
ASSUME(!m_prefix11); assert(cycles() == 0);
ASSUME(cycles() == 0);
switch (opcode) { switch (opcode) {
case 0x10: m_prefix10 = true; break; case 0x10: m_prefix10 = true; execute(fetchByte()); break;
case 0x11: m_prefix11 = true; break; case 0x11: m_prefix11 = true; execute(fetchByte()); break;
// ABX // ABX
case 0x3a: addCycles(3); X() += B(); break; // ABX (inherent) case 0x3a: addCycles(3); X() += B(); break; // ABX (inherent)
@ -406,20 +414,12 @@ int EightBit::mc6809::executeUnprefixed(uint8_t opcode) {
default: default:
UNREACHABLE; UNREACHABLE;
} }
if (m_prefix10 || m_prefix11)
ASSUME(cycles() == 0);
else
ASSUME(cycles() > 0);
return cycles();
} }
int EightBit::mc6809::execute10(uint8_t opcode) { void EightBit::mc6809::execute10(uint8_t opcode) {
ASSUME(m_prefix10); assert(m_prefix10 && !m_prefix11);
ASSUME(!m_prefix11); assert(cycles() == 0);
ASSUME(cycles() == 0);
switch (opcode) { switch (opcode) {
@ -485,18 +485,12 @@ int EightBit::mc6809::execute10(uint8_t opcode) {
default: default:
UNREACHABLE; UNREACHABLE;
} }
m_prefix10 = false;
ASSUME(cycles() > 0);
return cycles();
} }
int EightBit::mc6809::execute11(uint8_t opcode) { void EightBit::mc6809::execute11(uint8_t opcode) {
ASSUME(m_prefix10); assert(!m_prefix10 && m_prefix11);
ASSUME(!m_prefix11); assert(cycles() == 0);
ASSUME(cycles() == 0);
switch (opcode) { switch (opcode) {
@ -520,11 +514,6 @@ int EightBit::mc6809::execute11(uint8_t opcode) {
default: default:
UNREACHABLE; UNREACHABLE;
} }
m_prefix11 = false;
ASSUME(cycles() > 0);
return cycles();
} }
// //