From f87fe92bc8c4f1f9e78dc1cb5fd0809966181b9c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 23 Sep 2020 22:14:42 -0400 Subject: [PATCH] Begins a meandering road towards the 65816. --- .../Clock Signal.xcodeproj/project.pbxproj | 26 ++ Processors/65816/65816.hpp | 32 ++ .../65816/Implementation/65816Storage.cpp | 317 ++++++++++++++++++ .../65816/Implementation/65816Storage.hpp | 65 ++++ 4 files changed, 440 insertions(+) create mode 100644 Processors/65816/65816.hpp create mode 100644 Processors/65816/Implementation/65816Storage.cpp create mode 100644 Processors/65816/Implementation/65816Storage.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index b86a62c7d..94d7fb34e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -861,6 +861,8 @@ 4BF437EE209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; }; 4BF437EF209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; }; 4BF8D4C82516E27A00BBE21B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BB8617024E22F4900A00E03 /* Accelerate.framework */; }; + 4BF8D4D5251C11DD00BBE21B /* 65816Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D4D4251C11DD00BBE21B /* 65816Storage.cpp */; }; + 4BF8D4D6251C11DD00BBE21B /* 65816Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D4D4251C11DD00BBE21B /* 65816Storage.cpp */; }; 4BFCA1241ECBDCB400AC40C1 /* AllRAMProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFCA1211ECBDCAF00AC40C1 /* AllRAMProcessor.cpp */; }; 4BFCA1271ECBE33200AC40C1 /* TestMachineZ80.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BFCA1261ECBE33200AC40C1 /* TestMachineZ80.mm */; }; 4BFCA1291ECBE7A700AC40C1 /* zexall.com in Resources */ = {isa = PBXBuildFile; fileRef = 4BFCA1281ECBE7A700AC40C1 /* zexall.com */; }; @@ -1788,6 +1790,9 @@ 4BF4A2D91F534DB300B171F4 /* TargetPlatforms.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TargetPlatforms.hpp; sourceTree = ""; }; 4BF52672218E752E00313227 /* ScanTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScanTarget.hpp; path = ../../Outputs/ScanTarget.hpp; sourceTree = ""; }; 4BF6606A1F281573002CB053 /* ClockReceiver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ClockReceiver.hpp; sourceTree = ""; }; + 4BF8D4CD251C0C9C00BBE21B /* 65816.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 65816.hpp; sourceTree = ""; }; + 4BF8D4D3251C0D9F00BBE21B /* 65816Storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 65816Storage.hpp; sourceTree = ""; }; + 4BF8D4D4251C11DD00BBE21B /* 65816Storage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = 65816Storage.cpp; sourceTree = ""; }; 4BFCA1211ECBDCAF00AC40C1 /* AllRAMProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllRAMProcessor.cpp; sourceTree = ""; }; 4BFCA1221ECBDCAF00AC40C1 /* AllRAMProcessor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AllRAMProcessor.hpp; sourceTree = ""; }; 4BFCA1251ECBE33200AC40C1 /* TestMachineZ80.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachineZ80.h; sourceTree = ""; }; @@ -3485,6 +3490,7 @@ 4BFCA1221ECBDCAF00AC40C1 /* AllRAMProcessor.hpp */, 4B2C455C1EC9442600FC74DD /* RegisterSizes.hpp */, 4B1414561B58879D00E04248 /* 6502 */, + 4BF8D4CC251C0C9C00BBE21B /* 65816 */, 4BFF1D332233778C00838EA1 /* 68000 */, 4B77069E1EC9045B0053B588 /* Z80 */, ); @@ -3892,6 +3898,24 @@ path = ../../ClockReceiver; sourceTree = ""; }; + 4BF8D4CC251C0C9C00BBE21B /* 65816 */ = { + isa = PBXGroup; + children = ( + 4BF8D4CD251C0C9C00BBE21B /* 65816.hpp */, + 4BF8D4D2251C0D9F00BBE21B /* Implementation */, + ); + path = 65816; + sourceTree = ""; + }; + 4BF8D4D2251C0D9F00BBE21B /* Implementation */ = { + isa = PBXGroup; + children = ( + 4BF8D4D3251C0D9F00BBE21B /* 65816Storage.hpp */, + 4BF8D4D4251C11DD00BBE21B /* 65816Storage.cpp */, + ); + path = Implementation; + sourceTree = ""; + }; 4BFDD7891F7F2DB4008579B9 /* Utility */ = { isa = PBXGroup; children = ( @@ -4489,6 +4513,7 @@ 4B9BE401203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */, 4B055AA61FAE85EF0060FFFF /* Parser.cpp in Sources */, 4B055AE91FAE9B990060FFFF /* 6502Base.cpp in Sources */, + 4BF8D4D6251C11DD00BBE21B /* 65816Storage.cpp in Sources */, 4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */, 4B89453F201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B89453D201967B4007DE474 /* StaticAnalyser.cpp in Sources */, @@ -4771,6 +4796,7 @@ 4B55DD8320DF06680043F2E5 /* MachinePicker.swift in Sources */, 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */, 4B89453E201967B4007DE474 /* StaticAnalyser.cpp in Sources */, + 4BF8D4D5251C11DD00BBE21B /* 65816Storage.cpp in Sources */, 4B0ACC2823775819008902D0 /* DMAController.cpp in Sources */, 4BC131702346DE5000E4FF3D /* StaticAnalyser.cpp in Sources */, 4B37EE821D7345A6006A09A4 /* BinaryDump.cpp in Sources */, diff --git a/Processors/65816/65816.hpp b/Processors/65816/65816.hpp new file mode 100644 index 000000000..acb76ccf3 --- /dev/null +++ b/Processors/65816/65816.hpp @@ -0,0 +1,32 @@ +// +// 65816.hpp +// Clock Signal +// +// Created by Thomas Harte on 23/09/2020. +// Copyright © 2020 Thomas Harte. All rights reserved. +// + +#ifndef WDC65816_hpp +#define WDC65816_hpp + +#include +#include + +namespace CPU { +namespace WDC65816 { + +enum class Personality { + WDC65816, + WDC65802 +}; + +#include "Implementation/65816Storage.hpp" + +template class Processor: public ProcessorStorage { + +}; + +} +} + +#endif /* WDC65816_hpp */ diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp new file mode 100644 index 000000000..f3cde1803 --- /dev/null +++ b/Processors/65816/Implementation/65816Storage.cpp @@ -0,0 +1,317 @@ +// +// 65816Storage.cpp +// Clock Signal +// +// Created by Thomas Harte on 23/09/2020. +// Copyright © 2020 Thomas Harte. All rights reserved. +// + +#include +#include + +#include "65816Storage.hpp" + +ProcessorStorage::ProcessorStorage() { + // 1a. Absolute a [read and write]. + const auto absolute_read = + install_ops({ + CycleFetchIncrementPC, // OpCode. + CycleFetchIncrementPC, // AAL. + CycleFetchIncrementPC, // AAH. + OperationConstructAbsolute, // (copy AAL and AAH fetch to address) + CycleFetchIncrementData, // Data low. + OperationSkipIf8, // (don't do the next fetch if in emulation mode) + CycleFetchIncrementData, // Data high. + OperationPerform, // (whatever the operation is) + OperationMoveToNextProgram + }); + + const auto absolute_write = + install_ops({ + CycleFetchIncrementPC, // OpCode. + CycleFetchIncrementPC, // AAL. + CycleFetchIncrementPC, // AAH. + OperationConstructAbsolute, // (copy AAL and AAH fetch to address) + OperationPerform, // (whatever the operation is) + CycleStoreIncrementData, // Data low. + OperationSkipIf8, // (don't do the next fetch if in emulation mode) + CycleStoreIncrementData, // Data high. + OperationMoveToNextProgram + }); + + // Install the instructions. +#define op set_instruction + /* 0x00 BRK s */ + /* 0x01 ORA (d, x) */ + /* 0x02 COP s */ + /* 0x03 ORA d, s */ + /* 0x04 TSB d */ + /* 0x05 ORA d */ + /* 0x06 ASL d */ + /* 0x07 ORA [d] */ + /* 0x08 PHP s */ + /* 0x09 ORA # */ + /* 0x0a ASL a */ + /* 0x0b PHD s */ + /* 0x0c TSB a */ + /* 0x0d ORA a */ op(0x0d, absolute_read, ORA); + /* 0x0e ASL a */ + /* 0x0f ORA al */ + + /* 0x10 BPL r */ + /* 0x11 ORA (d), y */ + /* 0x12 ORA (d) */ + /* 0x13 ORA (d, s), y */ + /* 0x14 TRB d */ + /* 0x15 ORA d,x */ + /* 0x16 ASL d, x */ + /* 0x17 ORA [d], y */ + /* 0x18 CLC i */ + /* 0x19 ORA a, y */ + /* 0x1a INC A */ + /* 0x1b TCS i */ + /* 0x1c TRB a */ + /* 0x1d ORA a, x */ + /* 0x1e ASL a, x */ + /* 0x1f ORA al, x */ + + /* 0x20 JSR a */ + /* 0x21 ORA (d), y */ + /* 0x22 AND (d, x) */ + /* 0x23 JSL al */ + /* 0x24 BIT d */ + /* 0x25 AND d */ + /* 0x26 ROL d */ + /* 0x27 AND [d] */ + /* 0x28 PLP s */ + /* 0x29 AND # */ + /* 0x2a ROL A */ + /* 0x2b PLD s */ + /* 0x2c BIT a */ op(0x2c, absolute_read, BIT); + /* 0x2d AND a */ op(0x2d, absolute_read, AND); + /* 0x2e ROL a */ + /* 0x2f AND al */ + + /* 0x30 BMI R */ + /* 0x31 AND (d), y */ + /* 0x32 AND (d) */ + /* 0x33 AND (d, s), y */ + /* 0x34 BIT d, x */ + /* 0x35 AND d, x */ + /* 0x36 TOL d, x */ + /* 0x37 AND [d], y */ + /* 0x38 SEC i */ + /* 0x39 AND a, y */ + /* 0x3a DEC A */ + /* 0x3b TSC i */ + /* 0x3c BIT a, x */ + /* 0x3d AND a, x */ + /* 0x3e TLD a, x */ + /* 0x3f AND al, x */ + + /* 0x40 RTI s */ + /* 0x41 EOR (d, x) */ + /* 0x42 WDM i */ + /* 0x43 EOR d, s */ + /* 0x44 MVP xyc */ + /* 0x45 EOR d */ + /* 0x46 LSR d */ + /* 0x47 EOR [d] */ + /* 0x48 PHA s */ + /* 0x49 EOR # */ + /* 0x4a LSR A */ + /* 0x4b PHK s */ + /* 0x4c JMP a */ + /* 0x4d EOR a */ op(0x4d, absolute_read, EOR); + /* 0x4e LSR a */ + /* 0x4f EOR Al */ + + /* 0x50 BVC r */ + /* 0x51 EOR (d), y */ + /* 0x52 EOR (d) */ + /* 0x53 EOR (d, s), y */ + /* 0x54 MVN xyc */ + /* 0x55 EOR d, x */ + /* 0x56 LSR d, x */ + /* 0x57 EOR [d],y */ + /* 0x58 CLI i */ + /* 0x59 EOR a, y */ + /* 0x5a PHY s */ + /* 0x5b TCD i */ + /* 0x5c JMP al */ + /* 0x5d EOR a, x */ + /* 0x5e LSR a, x */ + /* 0x5f EOR al, x */ + + /* 0x60 RTS s */ + /* 0x61 ADC (d, x) */ + /* 0x62 PER s */ + /* 0x63 ADC d, s */ + /* 0x64 STZ d */ + /* 0x65 ADC d */ + /* 0x66 ROR d */ + /* 0x67 ADC [d] */ + /* 0x68 PLA s */ + /* 0x69 ADC # */ + /* 0x6a ROR A */ + /* 0x6b RTL s */ + /* 0x6c JMP (a) */ + /* 0x6d ADC a */ op(0x6d, absolute_read, ADC); + /* 0x6e ROR a */ + /* 0x6f ADC al */ + + /* 0x70 BVS r */ + /* 0x71 ADC (d), y */ + /* 0x72 ADC (d) */ + /* 0x73 ADC (d, s), y */ + /* 0x74 STZ d, x */ + /* 0x75 ADC d, x */ + /* 0x76 ROR d, x */ + /* 0x77 ADC [d], y */ + /* 0x78 SEI i */ + /* 0x79 ADC a, y */ + /* 0x7a PLY s */ + /* 0x7b TDC i */ + /* 0x7c JMP (a, x) */ + /* 0x7d ADC a, x */ + /* 0x7e ROR a, x */ + /* 0x7f ADC al, x */ + + /* 0x80 BRA r */ + /* 0x81 STA (d, x) */ + /* 0x82 BRL rl */ + /* 0x83 STA d, s */ + /* 0x84 STY d */ + /* 0x85 STA d */ + /* 0x86 STX d */ + /* 0x87 STA [d] */ + /* 0x88 DEY i */ + /* 0x89 BIT # */ + /* 0x8a TXA i */ + /* 0x8b PHB s */ + /* 0x8c STY a */ op(0x8c, absolute_write, STY); + /* 0x8d STA a */ op(0x8d, absolute_write, STA); + /* 0x8e STX a */ op(0x8e, absolute_write, STX); + /* 0x8f STA al */ + + /* 0x90 BCC r */ + /* 0x91 STA (d), y */ + /* 0x92 STA (d) */ + /* 0x93 STA (d, x), y */ + /* 0x94 STY d, x */ + /* 0x95 STA d, x */ + /* 0x96 STX d, y */ + /* 0x97 STA [d], y */ + /* 0x98 TYA i */ + /* 0x99 STA a, y */ + /* 0x9a TXS i */ + /* 0x9b TXY i */ + /* 0x9c STZ a */ op(0x9c, absolute_write, STZ); + /* 0x9d STA a, x */ + /* 0x9e STZ a, x */ + /* 0x9f STA al, x */ + + /* 0xa0 LDY # */ + /* 0xa1 LDA (d, x) */ + /* 0xa2 LDX # */ + /* 0xa3 LDA d, s */ + /* 0xa4 LDY d */ + /* 0xa5 LDA d */ + /* 0xa6 LDX d */ + /* 0xa7 LDA [d] */ + /* 0xa8 TAY i */ + /* 0xa9 LDA # */ + /* 0xaa TAX i */ + /* 0xab PLB s */ + /* 0xac LDY a */ op(0xac, absolute_read, LDY); + /* 0xad LDA a */ op(0xad, absolute_read, LDA); + /* 0xae LDX a */ op(0xae, absolute_read, LDX); + /* 0xaf LDA al */ + + /* 0xb0 BCS r */ + /* 0xb1 LDA (d), y */ + /* 0xb2 LDA (d) */ + /* 0xb3 LDA (d, s), y */ + /* 0xb4 LDY d, x */ + /* 0xb5 LDA d, x */ + /* 0xb6 LDX d, y */ + /* 0xb7 LDA [d], y */ + /* 0xb8 CLV i */ + /* 0xb9 LDA a, y */ + /* 0xba TSX i */ + /* 0xbb TYX i */ + /* 0xbc LDY a, x */ + /* 0xbd LDA a, x */ + /* 0xbe LDX a, y */ + /* 0xbf LDA al, x */ + + /* 0xc0 CPY # */ + /* 0xc1 CMP (d, x) */ + /* 0xc2 REP # */ + /* 0xc3 CMP d, s */ + /* 0xc4 CPY d */ + /* 0xc5 CMP d */ + /* 0xc6 DEC d */ + /* 0xc7 CMP [d] */ + /* 0xc8 INY i */ + /* 0xc9 CMP # */ + /* 0xca DEX i */ + /* 0xcb WAI i */ + /* 0xcc CPY a */ op(0xcd, absolute_read, CPY); + /* 0xcd CMP a */ op(0xcd, absolute_read, CMP); + /* 0xce DEC a */ + /* 0xcf CMP al */ + + /* 0xd0 BNE r */ + /* 0xd1 CMP (d), y */ + /* 0xd2 CMP (d) */ + /* 0xd3 CMP (d, s), y */ + /* 0xd4 PEI s */ + /* 0xd5 CMP d, x */ + /* 0xd6 DEC d, x */ + /* 0xd7 CMP [d], y */ + /* 0xd8 CLD i */ + /* 0xd9 CMP a, y */ + /* 0xda PHX s */ + /* 0xdb STP i */ + /* 0xdc JMP (a) */ + /* 0xdd CMP a, x */ + /* 0xde DEC a, x */ + /* 0xdf CMP al, x */ + + /* 0xe0 CPX # */ + /* 0xe1 SBC (d, x) */ + /* 0xe2 SEP # */ + /* 0xe3 SBC d, s */ + /* 0xe4 CPX d */ + /* 0xe5 SBC d */ + /* 0xe6 INC d */ + /* 0xe7 SBC [d] */ + /* 0xe8 INX i */ + /* 0xe9 SBC # */ + /* 0xea NOP i */ + /* 0xeb XBA i */ + /* 0xec CPX a */ op(0xec, absolute_read, CPX); + /* 0xed SBC a */ op(0xed, absolute_read, SBC); + /* 0xee INC a */ + /* 0xef SBC al */ + + /* 0xf0 BEQ r */ + /* 0xf1 SBC (d), y */ + /* 0xf2 SBC (d) */ + /* 0xf3 SBC (d, s), y */ + /* 0xf4 PEA s */ + /* 0xf5 SBC d, x */ + /* 0xf6 INC d, x */ + /* 0xf7 SBC [d], y */ + /* 0xf8 SED i */ + /* 0xf9 SBC a, y */ + /* 0xfa PLX s */ + /* 0xfb XCE i */ + /* 0xfc JSR (a, x) */ + /* 0xfd SBC a, x */ + /* 0xfe INC a, x */ + /* 0xff SBC al, x */ + +#undef op +} diff --git a/Processors/65816/Implementation/65816Storage.hpp b/Processors/65816/Implementation/65816Storage.hpp new file mode 100644 index 000000000..8ecef7ae6 --- /dev/null +++ b/Processors/65816/Implementation/65816Storage.hpp @@ -0,0 +1,65 @@ +// +// 65816Implementation.hpp +// Clock Signal +// +// Created by Thomas Harte on 23/09/2020. +// Copyright © 2020 Thomas Harte. All rights reserved. +// + +#ifndef WDC65816Implementation_h +#define WDC65816Implementation_h + +class ProcessorStorage { + public: + ProcessorStorage(); + + enum MicroOp: uint8_t { + /// Fetches a byte from the program counter to the instruction buffer and increments the program counter. + CycleFetchIncrementPC, + /// Fetches a byte from the data address to the data buffer and increments the data address. + CycleFetchIncrementData, + /// Stores a byte to the data address from the data buffer and increments the data address. + CycleStoreIncrementData, + + /// Skips the next micro-op if in emulation mode. + OperationSkipIf8, + + /// Sets the data address by copying the final two bytes of the instruction buffer. + OperationConstructAbsolute, + + /// Performs whatever operation goes with this program. + OperationPerform, + + /// Complete this set of micr-ops. + OperationMoveToNextProgram + }; + + enum Operation: uint8_t { + ADC, AND, BIT, CMP, CPX, CPY, EOR, LDA, LDX, LDY, ORA, SBC, + + STA, STX, STY, STZ, + }; + + struct Instruction { + size_t program_offset; + Operation operation; + }; + Instruction instructions[256]; + + private: + std::vector micro_ops_; + + size_t install_ops(std::initializer_list ops) { + // Just copy into place and return the index at which copying began. + const size_t index = micro_ops_.size(); + micro_ops_.insert(micro_ops_.end(), ops.begin(), ops.end()); + return index; + } + + void set_instruction(uint8_t opcode, size_t micro_ops, Operation operation) { + instructions[opcode].program_offset = micro_ops; + instructions[opcode].operation = operation; + } +}; + +#endif /* WDC65816Implementation_h */