1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-19 23:29:05 +00:00

The operations table is now per-instance.

This commit is contained in:
Thomas Harte 2018-08-06 20:47:14 -04:00
parent 76a73c835c
commit 633af4d404
4 changed files with 165 additions and 156 deletions

View File

@ -33,6 +33,15 @@ enum Register {
S
};
/*
The list of 6502 variants supported by this implementation.
*/
enum Personality {
P6502, // the original 6502, replete with various undocumented instructions
P65C02, // the 65C02; an extended 6502 with a few extra instructions and addressing modes for existing instructions
P65SC02, // like the 65C02, but lacking bit instructions
};
/*
Flags as defined on the 6502; can be used to decode the result of @c get_value_of_register(Flags) or to form a value for
the corresponding set.
@ -110,6 +119,8 @@ class BusHandler {
*/
class ProcessorBase: public ProcessorStorage {
public:
ProcessorBase(Personality personality) : ProcessorStorage(personality) {}
/*!
Gets the value of a register.
@ -180,12 +191,6 @@ class ProcessorBase: public ProcessorStorage {
bool is_jammed();
};
enum Personality {
P6502, // the original 6502, replete with various undocumented instructions
P65C02, // the 65C02; an extended 6502 with a few extra instructions and addressing modes for existing instructions
P65SC02, // like the 65C02, but lacking bit instructions
};
/*!
@abstact Template providing emulation of a 6502 processor.
@ -199,7 +204,7 @@ template <typename T, bool uses_ready_line> class Processor: public ProcessorBas
/*!
Constructs an instance of the 6502 that will use @c bus_handler for all bus communications.
*/
Processor(Personality personality, T &bus_handler) : bus_handler_(bus_handler) {}
Processor(Personality personality, T &bus_handler) : ProcessorBase(personality), bus_handler_(bus_handler) {}
/*!
Runs the 6502 for a supplied number of cycles.

View File

@ -97,7 +97,7 @@ if(number_of_cycles <= Cycles(0)) break;
break;
case OperationDecodeOperation:
scheduled_program_counter_ = operations[operation_];
scheduled_program_counter_ = operations_[operation_];
continue;
case OperationMoveToNextProgram:
@ -160,7 +160,7 @@ if(number_of_cycles <= Cycles(0)) break;
case CycleScheduleJam: {
is_jammed_ = true;
scheduled_program_counter_ = operations[CPU::MOS6502::JamOpcode];
scheduled_program_counter_ = operations_[CPU::MOS6502::JamOpcode];
} continue;
// MARK: - Bitwise

View File

@ -8,6 +8,8 @@
#include "../6502.hpp"
#include <cstring>
using namespace CPU::MOS6502;
#define Program(...) {__VA_ARGS__, OperationMoveToNextProgram}
@ -67,7 +69,14 @@ using namespace CPU::MOS6502;
#define JAM {CycleFetchOperand, CycleScheduleJam}
const ProcessorStorage::MicroOp ProcessorStorage::operations[256][10] = {
ProcessorStorage::ProcessorStorage(Personality) {
// only the interrupt flag is defined upon reset but get_flags isn't going to
// mask the other flags so we need to do that, at least
carry_flag_ &= Flag::Carry;
decimal_flag_ &= Flag::Decimal;
overflow_flag_ &= Flag::Overflow;
const ProcessorStorage::MicroOp operations_6502[256][10] = {
/* 0x00 BRK */ Program(CycleIncPCPushPCH, CyclePushPCL, OperationBRKPickVector, OperationSetOperandFromFlagsWithBRKSet, CyclePushOperand, OperationSetI, CycleReadVectorLow, CycleReadVectorHigh),
/* 0x01 ORA x, ind */ IndexedIndirectRead(OperationORA),
/* 0x02 JAM */ JAM, /* 0x03 ASO x, ind */ IndexedIndirectReadModifyWrite(OperationASO),
@ -203,7 +212,10 @@ const ProcessorStorage::MicroOp ProcessorStorage::operations[256][10] = {
/* 0xfa NOP # */ ImpliedNop(), /* 0xfb INS abs, y */ AbsoluteYReadModifyWrite(OperationINS),
/* 0xfc NOP abs, x */ AbsoluteXNop(), /* 0xfd SBC abs, x */ AbsoluteXRead(OperationSBC),
/* 0xfe INC abs, x */ AbsoluteXReadModifyWrite(OperationINC), /* 0xff INS abs, x */ AbsoluteXReadModifyWrite(OperationINS),
};
};
memcpy(operations_, operations_6502, sizeof(operations_));
}
#undef Program
#undef Absolute
@ -243,11 +255,3 @@ const ProcessorStorage::MicroOp ProcessorStorage::operations[256][10] = {
#undef IndirectIndexedReadModify
#undef Immediate
#undef Implied
ProcessorStorage::ProcessorStorage() {
// only the interrupt flag is defined upon reset but get_flags isn't going to
// mask the other flags so we need to do that, at least
carry_flag_ &= Flag::Carry;
decimal_flag_ &= Flag::Decimal;
overflow_flag_ &= Flag::Overflow;
}

View File

@ -15,7 +15,7 @@
*/
class ProcessorStorage {
protected:
ProcessorStorage();
ProcessorStorage(Personality);
/*
This emulation functions by decomposing instructions into micro programs, consisting of the micro operations
@ -62,7 +62,7 @@ class ProcessorStorage {
CycleScheduleJam
};
static const MicroOp operations[256][10];
MicroOp operations_[256][10];
const MicroOp *scheduled_program_counter_ = nullptr;