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:
parent
76a73c835c
commit
633af4d404
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user