mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
Introduces 6502Selector, for picking either a 6502 or a 65816 based on a single template parameter.
This commit is contained in:
parent
6635876e7e
commit
ef1a514785
@ -424,8 +424,8 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
!tape_player_.get_tape()->is_at_end()) {
|
!tape_player_.get_tape()->is_at_end()) {
|
||||||
|
|
||||||
uint8_t next_byte = tape_player_.get_next_byte(!ram_[tape_speed_address_]);
|
uint8_t next_byte = tape_player_.get_next_byte(!ram_[tape_speed_address_]);
|
||||||
m6502_.set_value_of_register(CPU::MOS6502::A, next_byte);
|
m6502_.set_value_of_register(CPU::MOS6502Esque::A, next_byte);
|
||||||
m6502_.set_value_of_register(CPU::MOS6502::Flags, next_byte ? 0 : CPU::MOS6502::Flag::Zero);
|
m6502_.set_value_of_register(CPU::MOS6502Esque::Flags, next_byte ? 0 : CPU::MOS6502::Flag::Zero);
|
||||||
*value = 0x60; // i.e. RTS
|
*value = 0x60; // i.e. RTS
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -210,6 +210,9 @@
|
|||||||
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
|
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
|
||||||
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
|
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
|
||||||
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
|
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
|
||||||
|
4B4DEBED2522C03F004583AC /* 65816Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DEBEC2522C03F004583AC /* 65816Base.cpp */; };
|
||||||
|
4B4DEBEE2522C03F004583AC /* 65816Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DEBEC2522C03F004583AC /* 65816Base.cpp */; };
|
||||||
|
4B4DEBEF2522C03F004583AC /* 65816Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DEBEC2522C03F004583AC /* 65816Base.cpp */; };
|
||||||
4B50AF80242817F40099BBD7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B50AF7F242817F40099BBD7 /* QuartzCore.framework */; };
|
4B50AF80242817F40099BBD7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B50AF7F242817F40099BBD7 /* QuartzCore.framework */; };
|
||||||
4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; };
|
4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; };
|
||||||
4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; };
|
4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; };
|
||||||
@ -1119,6 +1122,7 @@
|
|||||||
4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = "<group>"; };
|
4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = "<group>"; };
|
||||||
4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = "<group>"; };
|
4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = "<group>"; };
|
||||||
4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = "<group>"; };
|
4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = "<group>"; };
|
||||||
|
4B4DEBEC2522C03F004583AC /* 65816Base.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = 65816Base.cpp; path = ../../Processors/65816/Implementation/65816Base.cpp; sourceTree = "<group>"; };
|
||||||
4B4F2B7024DF99D4000DA6B0 /* CSScanTarget+CppScanTarget.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CSScanTarget+CppScanTarget.h"; sourceTree = "<group>"; };
|
4B4F2B7024DF99D4000DA6B0 /* CSScanTarget+CppScanTarget.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CSScanTarget+CppScanTarget.h"; sourceTree = "<group>"; };
|
||||||
4B50AF7F242817F40099BBD7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
4B50AF7F242817F40099BBD7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||||
4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = "<group>"; };
|
4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = "<group>"; };
|
||||||
@ -1344,6 +1348,7 @@
|
|||||||
4BAF2B4D2004580C00480230 /* DMK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMK.hpp; sourceTree = "<group>"; };
|
4BAF2B4D2004580C00480230 /* DMK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMK.hpp; sourceTree = "<group>"; };
|
||||||
4BB023FF25212888009F8D90 /* 65816Implementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = 65816Implementation.hpp; path = ../../Processors/65816/Implementation/65816Implementation.hpp; sourceTree = "<group>"; };
|
4BB023FF25212888009F8D90 /* 65816Implementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = 65816Implementation.hpp; path = ../../Processors/65816/Implementation/65816Implementation.hpp; sourceTree = "<group>"; };
|
||||||
4BB0240425229C6E009F8D90 /* 6502Esque.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = 6502Esque.hpp; sourceTree = "<group>"; };
|
4BB0240425229C6E009F8D90 /* 6502Esque.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = 6502Esque.hpp; sourceTree = "<group>"; };
|
||||||
|
4BB024092522B7BE009F8D90 /* 6502Selector.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = 6502Selector.hpp; sourceTree = "<group>"; };
|
||||||
4BB06B211F316A3F00600C7A /* ForceInline.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ForceInline.hpp; sourceTree = "<group>"; };
|
4BB06B211F316A3F00600C7A /* ForceInline.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ForceInline.hpp; sourceTree = "<group>"; };
|
||||||
4BB0A6592044FD3000FB3688 /* SN76489.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SN76489.cpp; sourceTree = "<group>"; };
|
4BB0A6592044FD3000FB3688 /* SN76489.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SN76489.cpp; sourceTree = "<group>"; };
|
||||||
4BB0A65A2044FD3000FB3688 /* SN76489.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SN76489.hpp; sourceTree = "<group>"; };
|
4BB0A65A2044FD3000FB3688 /* SN76489.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SN76489.hpp; sourceTree = "<group>"; };
|
||||||
@ -3332,6 +3337,7 @@
|
|||||||
4BB73E951B587A5100552FC2 = {
|
4BB73E951B587A5100552FC2 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4B4DEBEC2522C03F004583AC /* 65816Base.cpp */,
|
||||||
4BB023FF25212888009F8D90 /* 65816Implementation.hpp */,
|
4BB023FF25212888009F8D90 /* 65816Implementation.hpp */,
|
||||||
4B51F70820A521D700AFA2C1 /* Activity */,
|
4B51F70820A521D700AFA2C1 /* Activity */,
|
||||||
4B8944E2201967B4007DE474 /* Analyser */,
|
4B8944E2201967B4007DE474 /* Analyser */,
|
||||||
@ -3491,6 +3497,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4BFCA1211ECBDCAF00AC40C1 /* AllRAMProcessor.cpp */,
|
4BFCA1211ECBDCAF00AC40C1 /* AllRAMProcessor.cpp */,
|
||||||
4BB0240425229C6E009F8D90 /* 6502Esque.hpp */,
|
4BB0240425229C6E009F8D90 /* 6502Esque.hpp */,
|
||||||
|
4BB024092522B7BE009F8D90 /* 6502Selector.hpp */,
|
||||||
4BFCA1221ECBDCAF00AC40C1 /* AllRAMProcessor.hpp */,
|
4BFCA1221ECBDCAF00AC40C1 /* AllRAMProcessor.hpp */,
|
||||||
4B2C455C1EC9442600FC74DD /* RegisterSizes.hpp */,
|
4B2C455C1EC9442600FC74DD /* RegisterSizes.hpp */,
|
||||||
4B1414561B58879D00E04248 /* 6502 */,
|
4B1414561B58879D00E04248 /* 6502 */,
|
||||||
@ -4496,6 +4503,7 @@
|
|||||||
4BDACBED22FFA5D20045EF7E /* ncr5380.cpp in Sources */,
|
4BDACBED22FFA5D20045EF7E /* ncr5380.cpp in Sources */,
|
||||||
4BC131772346DE9100E4FF3D /* StaticAnalyser.cpp in Sources */,
|
4BC131772346DE9100E4FF3D /* StaticAnalyser.cpp in Sources */,
|
||||||
4B055ACF1FAE9B030060FFFF /* SoundGenerator.cpp in Sources */,
|
4B055ACF1FAE9B030060FFFF /* SoundGenerator.cpp in Sources */,
|
||||||
|
4B4DEBEF2522C03F004583AC /* 65816Base.cpp in Sources */,
|
||||||
4B894519201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
|
4B894519201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
|
||||||
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */,
|
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */,
|
||||||
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
|
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
|
||||||
@ -4778,6 +4786,7 @@
|
|||||||
4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */,
|
4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */,
|
||||||
4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */,
|
4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */,
|
||||||
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
|
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
|
||||||
|
4B4DEBED2522C03F004583AC /* 65816Base.cpp in Sources */,
|
||||||
4B894524201967B4007DE474 /* Tape.cpp in Sources */,
|
4B894524201967B4007DE474 /* Tape.cpp in Sources */,
|
||||||
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */,
|
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */,
|
||||||
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */,
|
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */,
|
||||||
@ -4925,6 +4934,7 @@
|
|||||||
4B778F4123A5F19A0000D260 /* MemoryPacker.cpp in Sources */,
|
4B778F4123A5F19A0000D260 /* MemoryPacker.cpp in Sources */,
|
||||||
4B778F4423A5F1BE0000D260 /* CommodoreGCR.cpp in Sources */,
|
4B778F4423A5F1BE0000D260 /* CommodoreGCR.cpp in Sources */,
|
||||||
4B778EF923A5EB740000D260 /* MSA.cpp in Sources */,
|
4B778EF923A5EB740000D260 /* MSA.cpp in Sources */,
|
||||||
|
4B4DEBEE2522C03F004583AC /* 65816Base.cpp in Sources */,
|
||||||
4B778F2323A5EDE40000D260 /* Tape.cpp in Sources */,
|
4B778F2323A5EDE40000D260 /* Tape.cpp in Sources */,
|
||||||
4B778F4F23A5F21C0000D260 /* StaticAnalyser.cpp in Sources */,
|
4B778F4F23A5F21C0000D260 /* StaticAnalyser.cpp in Sources */,
|
||||||
4B778EEF23A5D6680000D260 /* AsyncTaskQueue.cpp in Sources */,
|
4B778EEF23A5D6680000D260 /* AsyncTaskQueue.cpp in Sources */,
|
||||||
|
@ -42,14 +42,13 @@ static CPU::MOS6502::Register registerForRegister(CSTestMachine6502Register reg)
|
|||||||
if(self) {
|
if(self) {
|
||||||
switch(processor) {
|
switch(processor) {
|
||||||
case CSTestMachine6502Processor6502:
|
case CSTestMachine6502Processor6502:
|
||||||
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502::Personality::P6502);
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::T6502);
|
||||||
break;
|
break;
|
||||||
case CSTestMachine6502Processor65C02:
|
case CSTestMachine6502Processor65C02:
|
||||||
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502::Personality::PWDC65C02);
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::TWDC65C02);
|
||||||
break;
|
break;
|
||||||
default:
|
case CSTestMachine6502Processor65816:
|
||||||
assert(false); // TODO
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::TWDC65816);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,19 +22,7 @@ namespace MOS6502 {
|
|||||||
|
|
||||||
using BusOperation = CPU::MOS6502Esque::BusOperation;
|
using BusOperation = CPU::MOS6502Esque::BusOperation;
|
||||||
using BusHandler = CPU::MOS6502Esque::BusHandler<uint16_t>;
|
using BusHandler = CPU::MOS6502Esque::BusHandler<uint16_t>;
|
||||||
|
using Register = CPU::MOS6502Esque::Register;
|
||||||
/*
|
|
||||||
The list of registers that can be accessed via @c set_value_of_register and @c set_value_of_register.
|
|
||||||
*/
|
|
||||||
enum Register {
|
|
||||||
LastOperationAddress,
|
|
||||||
ProgramCounter,
|
|
||||||
StackPointer,
|
|
||||||
Flags,
|
|
||||||
A,
|
|
||||||
X,
|
|
||||||
Y
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The list of 6502 variants supported by this implementation.
|
The list of 6502 variants supported by this implementation.
|
||||||
|
@ -15,7 +15,9 @@ using namespace CPU::MOS6502;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <Personality personality> class ConcreteAllRAMProcessor: public AllRAMProcessor, public BusHandler {
|
using Type = CPU::MOS6502Esque::Type;
|
||||||
|
|
||||||
|
template <Type type> class ConcreteAllRAMProcessor: public AllRAMProcessor, public BusHandler {
|
||||||
public:
|
public:
|
||||||
ConcreteAllRAMProcessor() :
|
ConcreteAllRAMProcessor() :
|
||||||
mos6502_(*this) {
|
mos6502_(*this) {
|
||||||
@ -63,20 +65,21 @@ template <Personality personality> class ConcreteAllRAMProcessor: public AllRAMP
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPU::MOS6502::Processor<personality, ConcreteAllRAMProcessor, false> mos6502_;
|
CPU::MOS6502Esque::Processor<type, ConcreteAllRAMProcessor, false> mos6502_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AllRAMProcessor *AllRAMProcessor::Processor(Personality personality) {
|
AllRAMProcessor *AllRAMProcessor::Processor(Type type) {
|
||||||
#define Bind(p) case p: return new ConcreteAllRAMProcessor<p>();
|
#define Bind(p) case p: return new ConcreteAllRAMProcessor<p>();
|
||||||
switch(personality) {
|
switch(type) {
|
||||||
default:
|
default:
|
||||||
Bind(Personality::P6502)
|
Bind(Type::T6502)
|
||||||
Bind(Personality::PNES6502)
|
Bind(Type::TNES6502)
|
||||||
Bind(Personality::PSynertek65C02)
|
Bind(Type::TSynertek65C02)
|
||||||
Bind(Personality::PWDC65C02)
|
Bind(Type::TWDC65C02)
|
||||||
Bind(Personality::PRockwell65C02)
|
Bind(Type::TRockwell65C02)
|
||||||
|
Bind(Type::TWDC65816)
|
||||||
}
|
}
|
||||||
#undef Bind
|
#undef Bind
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#ifndef MOS6502AllRAM_cpp
|
#ifndef MOS6502AllRAM_cpp
|
||||||
#define MOS6502AllRAM_cpp
|
#define MOS6502AllRAM_cpp
|
||||||
|
|
||||||
#include "../6502.hpp"
|
#include "../../6502Selector.hpp"
|
||||||
#include "../../AllRAMProcessor.hpp"
|
#include "../../AllRAMProcessor.hpp"
|
||||||
|
|
||||||
namespace CPU {
|
namespace CPU {
|
||||||
@ -17,9 +17,8 @@ namespace MOS6502 {
|
|||||||
|
|
||||||
class AllRAMProcessor:
|
class AllRAMProcessor:
|
||||||
public ::CPU::AllRAMProcessor {
|
public ::CPU::AllRAMProcessor {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static AllRAMProcessor *Processor(Personality personality);
|
static AllRAMProcessor *Processor(CPU::MOS6502Esque::Type type);
|
||||||
virtual ~AllRAMProcessor() {}
|
virtual ~AllRAMProcessor() {}
|
||||||
|
|
||||||
virtual void run_for(const Cycles cycles) = 0;
|
virtual void run_for(const Cycles cycles) = 0;
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
#include "../6502.hpp"
|
#include "../6502.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
using namespace CPU::MOS6502;
|
using namespace CPU::MOS6502;
|
||||||
|
|
||||||
const uint8_t CPU::MOS6502::JamOpcode = 0xf2;
|
const uint8_t CPU::MOS6502::JamOpcode = 0xf2;
|
||||||
|
@ -22,6 +22,19 @@
|
|||||||
namespace CPU {
|
namespace CPU {
|
||||||
namespace MOS6502Esque {
|
namespace MOS6502Esque {
|
||||||
|
|
||||||
|
/*
|
||||||
|
The list of registers that can be accessed via @c set_value_of_register and @c set_value_of_register.
|
||||||
|
*/
|
||||||
|
enum Register {
|
||||||
|
LastOperationAddress,
|
||||||
|
ProgramCounter,
|
||||||
|
StackPointer,
|
||||||
|
Flags,
|
||||||
|
A,
|
||||||
|
X,
|
||||||
|
Y
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Bus handlers will be given the task of performing bus operations, allowing them to provide whatever interface they like
|
Bus handlers will be given the task of performing bus operations, allowing them to provide whatever interface they like
|
||||||
between a 6502 and the rest of the system. @c BusOperation lists the types of bus operation that may be requested.
|
between a 6502 and the rest of the system. @c BusOperation lists the types of bus operation that may be requested.
|
||||||
|
46
Processors/6502Selector.hpp
Normal file
46
Processors/6502Selector.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// 6502Selector.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 28/09/2020.
|
||||||
|
// Copyright © 2020 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef _502Selector_h
|
||||||
|
#define _502Selector_h
|
||||||
|
|
||||||
|
#include "6502/6502.hpp"
|
||||||
|
#include "65816/65816.hpp"
|
||||||
|
|
||||||
|
namespace CPU {
|
||||||
|
namespace MOS6502Esque {
|
||||||
|
|
||||||
|
enum class Type {
|
||||||
|
TNES6502, // the NES's 6502, which is like a 6502 but lacks decimal mode (though it retains the decimal flag)
|
||||||
|
T6502, // the original [NMOS] 6502, replete with various undocumented instructions
|
||||||
|
TSynertek65C02, // a 6502 extended with BRA, P[H/L][X/Y], STZ, TRB, TSB and the (zp) addressing mode and a few other additions
|
||||||
|
TRockwell65C02, // like the Synertek, but with BBR, BBS, RMB and SMB
|
||||||
|
TWDC65C02, // like the Rockwell, but with STP and WAI
|
||||||
|
TWDC65816, // the slightly 16-bit follow-up to the 6502
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Machines that can use either a 6502 or a 65816 can use CPU::MOS6502Esque::Processor in order to select the proper
|
||||||
|
class in much the same way that a raw user of CPU::MOS6502::Processor would set the personality. Just provide one
|
||||||
|
of the type enums as above as the appropriate template parameter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <Type processor_type, typename BusHandler, bool uses_ready_line> class Processor:
|
||||||
|
public CPU::MOS6502::Processor<CPU::MOS6502::Personality(processor_type), BusHandler, uses_ready_line> {
|
||||||
|
using CPU::MOS6502::Processor<CPU::MOS6502::Personality(processor_type), BusHandler, uses_ready_line>::Processor;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename BusHandler, bool uses_ready_line> class Processor<Type::TWDC65816, BusHandler, uses_ready_line>:
|
||||||
|
public CPU::WDC65816::Processor<BusHandler> {
|
||||||
|
using CPU::WDC65816::Processor<BusHandler>::Processor;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _502Selector_h */
|
@ -14,16 +14,30 @@
|
|||||||
|
|
||||||
#include "../RegisterSizes.hpp"
|
#include "../RegisterSizes.hpp"
|
||||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||||
|
#include "../6502Esque.hpp"
|
||||||
|
|
||||||
namespace CPU {
|
namespace CPU {
|
||||||
namespace WDC65816 {
|
namespace WDC65816 {
|
||||||
|
|
||||||
|
using BusOperation = CPU::MOS6502Esque::BusOperation;
|
||||||
|
using Register = CPU::MOS6502Esque::Register;
|
||||||
|
|
||||||
#include "Implementation/65816Storage.hpp"
|
#include "Implementation/65816Storage.hpp"
|
||||||
|
|
||||||
template <typename BusHandler> class Processor: private ProcessorStorage {
|
class ProcessorBase: protected ProcessorStorage {
|
||||||
|
public:
|
||||||
|
inline void set_power_on(bool);
|
||||||
|
inline void set_irq_line(bool);
|
||||||
|
inline void set_nmi_line(bool);
|
||||||
|
void set_value_of_register(Register r, uint16_t value);
|
||||||
|
|
||||||
|
inline bool is_jammed() const;
|
||||||
|
uint16_t get_value_of_register(Register r) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename BusHandler> class Processor: public ProcessorBase {
|
||||||
public:
|
public:
|
||||||
Processor(BusHandler &bus_handler) : bus_handler_(bus_handler) {}
|
Processor(BusHandler &bus_handler) : bus_handler_(bus_handler) {}
|
||||||
|
|
||||||
void run_for(const Cycles cycles);
|
void run_for(const Cycles cycles);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
36
Processors/65816/Implementation/65816Base.cpp
Normal file
36
Processors/65816/Implementation/65816Base.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// 65816Base.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 28/09/2020.
|
||||||
|
// Copyright © 2020 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../65816.hpp"
|
||||||
|
|
||||||
|
using namespace CPU::WDC65816;
|
||||||
|
|
||||||
|
uint16_t ProcessorBase::get_value_of_register(Register r) const {
|
||||||
|
switch (r) {
|
||||||
|
// case Register::ProgramCounter: return pc_.full;
|
||||||
|
// case Register::LastOperationAddress: return last_operation_pc_.full;
|
||||||
|
// case Register::StackPointer: return s_;
|
||||||
|
// case Register::Flags: return get_flags();
|
||||||
|
// case Register::A: return a_;
|
||||||
|
// case Register::X: return x_;
|
||||||
|
// case Register::Y: return y_;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessorBase::set_value_of_register(Register r, uint16_t value) {
|
||||||
|
switch (r) {
|
||||||
|
// case Register::ProgramCounter: pc_.full = value; break;
|
||||||
|
// case Register::StackPointer: s_ = uint8_t(value); break;
|
||||||
|
// case Register::Flags: set_flags(uint8_t(value)); break;
|
||||||
|
// case Register::A: a_ = uint8_t(value); break;
|
||||||
|
// case Register::X: x_ = uint8_t(value); break;
|
||||||
|
// case Register::Y: y_ = uint8_t(value); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
// The exception program will determine the appropriate way to respond
|
// The exception program will determine the appropriate way to respond
|
||||||
// based on the pending exception if one exists; otherwise just do a
|
// based on the pending exception if one exists; otherwise just do a
|
||||||
// standard fetch-decode-execute.
|
// standard fetch-decode-execute.
|
||||||
next_op_ = µ_ops_[&instructions[pending_exceptions_ ? size_t(OperationSlot::Exception) : size_t(OperationSlot::FetchDecodeExecute)].program_offset];
|
next_op_ = µ_ops_[instructions[pending_exceptions_ ? size_t(OperationSlot::Exception) : size_t(OperationSlot::FetchDecodeExecute)].program_offset];
|
||||||
|
|
||||||
// TODO: reset instruction buffer.
|
// TODO: reset instruction buffer.
|
||||||
continue;
|
continue;
|
||||||
@ -27,3 +27,8 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessorBase::set_power_on(bool) {}
|
||||||
|
void ProcessorBase::set_irq_line(bool) {}
|
||||||
|
void ProcessorBase::set_nmi_line(bool) {}
|
||||||
|
bool ProcessorBase::is_jammed() const { return false; }
|
||||||
|
@ -185,10 +185,14 @@ struct ProcessorStorage {
|
|||||||
FetchDecodeExecute
|
FetchDecodeExecute
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_power_on_state() {
|
void set_power_on(bool power_on) {
|
||||||
// Set next_op_ to start the exception program.
|
if(power_on) {
|
||||||
next_op_ = µ_ops_[instructions[size_t(OperationSlot::Exception)].program_offset];
|
// Set next_op_ to start the exception program.
|
||||||
pending_exceptions_ = PowerOn;
|
next_op_ = µ_ops_[instructions[size_t(OperationSlot::Exception)].program_offset];
|
||||||
|
pending_exceptions_ = PowerOn;
|
||||||
|
} else {
|
||||||
|
pending_exceptions_ &= ~PowerOn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registers.
|
// Registers.
|
||||||
|
Loading…
Reference in New Issue
Block a user