1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Adds access type declaration.

This commit is contained in:
Thomas Harte 2021-01-16 20:04:01 -05:00
parent 3dc36b704a
commit 3b2d65fa16
4 changed files with 99 additions and 53 deletions

View File

@ -0,0 +1,24 @@
//
// AccessType.h
// Clock Signal
//
// Created by Thomas Harte on 1/16/21.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef AccessType_h
#define AccessType_h
namespace InstructionSet {
enum class AccessType {
None,
Read,
Write,
ReadModifyWrite
};
}
#endif /* AccessType_h */

View File

@ -10,6 +10,7 @@
#define InstructionSets_M50740_Instruction_h
#include <cstdint>
#include "../AccessType.hpp"
namespace InstructionSet {
namespace M50740 {
@ -37,7 +38,7 @@ enum class AddressingMode {
Bit4ZeroPageRelative, Bit5ZeroPageRelative, Bit6ZeroPageRelative, Bit7ZeroPageRelative,
};
inline int size(AddressingMode mode) {
constexpr int size(AddressingMode mode) {
// This is coupled to the AddressingMode list above; be careful!
constexpr int sizes[] = {
0, 0, 0,
@ -86,18 +87,25 @@ enum class Operation: uint8_t {
LDA, LDX, LDY,
TST,
// Write operations.
LDM,
STA, STX, STY,
// Read-modify-write operations.
ASL, LSR,
CLB, SEB,
COM,
DEC, INC,
ROL, ROR, RRF,
// Write operations.
LDM,
STA, STX, STY,
};
constexpr AccessType access_type(Operation operation) {
if(operation < Operation::ADC) return AccessType::None;
if(operation < Operation::LDM) return AccessType::Read;
if(operation < Operation::LDM) return AccessType::Write;
return AccessType::ReadModifyWrite;
}
struct Instruction {
Operation operation = Operation::Invalid;
AddressingMode addressing_mode = AddressingMode::Implied;

View File

@ -11,11 +11,12 @@
#include <cstdint>
#include "Decoder.hpp"
#include "../AccessType.hpp"
namespace InstructionSet {
namespace M50740 {
template<typename Target> struct Parser {
template<typename Target, bool include_entries_and_accesses> struct Parser {
void parse(Target &target, const uint8_t *storage, uint16_t start, uint16_t closing_bound) {
Decoder decoder;
@ -31,58 +32,69 @@ template<typename Target> struct Parser {
// Pass on the instruction.
target.announce_instruction(start, next.second);
// Check for end of stream and potential new entry points.
switch(next.second.operation) {
// Terminating instructions.
case Operation::RTS: case Operation::RTI: case Operation::BRK:
return;
if constexpr(!include_entries_and_accesses) {
// Do a simplified test: is this a terminating operation?
switch(next.second.operation) {
case Operation::RTS: case Operation::RTI: case Operation::BRK:
case Operation::JMP: case Operation::BRA:
return;
// Terminating operations with implied additional entry point.
case Operation::JMP:
target.add_entry(storage[start + 1] | (storage[start + 2] << 8));
return;
case Operation::BRA:
target.add_entry(start + 2 + int8_t(storage[start + 1]));
return;
default: break;
}
} else {
// Check for end of stream and potential new entry points.
switch(next.second.operation) {
// Terminating instructions.
case Operation::RTS: case Operation::RTI: case Operation::BRK:
return;
// Instructions that suggest another entry point but don't terminate parsing.
case Operation::BBS: case Operation::BBC:
case Operation::BCC: case Operation::BCS:
case Operation::BVC: case Operation::BVS:
case Operation::BMI: case Operation::BPL:
case Operation::BNE: case Operation::BEQ:
target.add_entry(start + 2 + int8_t(storage[start + 1]));
break;
case Operation::JSR:
target.add_entry(storage[start + 1] | (storage[start + 2] << 8));
break;
// Terminating operations with implied additional entry point.
case Operation::JMP:
target.add_entry(storage[start + 1] | (storage[start + 2] << 8));
return;
case Operation::BRA:
target.add_entry(start + 2 + int8_t(storage[start + 1]));
return;
default: break;
}
// Instructions that suggest another entry point but don't terminate parsing.
case Operation::BBS: case Operation::BBC:
case Operation::BCC: case Operation::BCS:
case Operation::BVC: case Operation::BVS:
case Operation::BMI: case Operation::BPL:
case Operation::BNE: case Operation::BEQ:
target.add_entry(start + 2 + int8_t(storage[start + 1]));
break;
case Operation::JSR:
target.add_entry(storage[start + 1] | (storage[start + 2] << 8));
break;
// Provide any fixed address accesses.
switch(next.second.addressing_mode) {
case AddressingMode::Absolute:
target.add_access(storage[start + 1] | (storage[start + 2] << 8));
break;
case AddressingMode::ZeroPage:
case AddressingMode::Bit0ZeroPage: case AddressingMode::Bit1ZeroPage:
case AddressingMode::Bit2ZeroPage: case AddressingMode::Bit3ZeroPage:
case AddressingMode::Bit4ZeroPage: case AddressingMode::Bit5ZeroPage:
case AddressingMode::Bit6ZeroPage: case AddressingMode::Bit7ZeroPage:
target.add_access(storage[start + 1]);
break;
case AddressingMode::SpecialPage:
target.add_access(storage[start + 1] | 0x1f00);
break;
case AddressingMode::ImmediateZeroPage:
target.add_access(storage[start + 2]);
break;
case AddressingMode::Bit0AccumulatorRelative:
target.add_access(start + 2 + int8_t(storage[start + 1]));
break;
default: break;
}
default: break;
// Provide any fixed address accesses.
switch(next.second.addressing_mode) {
case AddressingMode::Absolute:
target.add_access(storage[start + 1] | (storage[start + 2] << 8), access_type(next.second.operation));
break;
case AddressingMode::ZeroPage:
case AddressingMode::Bit0ZeroPage: case AddressingMode::Bit1ZeroPage:
case AddressingMode::Bit2ZeroPage: case AddressingMode::Bit3ZeroPage:
case AddressingMode::Bit4ZeroPage: case AddressingMode::Bit5ZeroPage:
case AddressingMode::Bit6ZeroPage: case AddressingMode::Bit7ZeroPage:
target.add_access(storage[start + 1], access_type(next.second.operation));
break;
case AddressingMode::SpecialPage:
target.add_access(storage[start + 1] | 0x1f00, access_type(next.second.operation));
break;
case AddressingMode::ImmediateZeroPage:
target.add_access(storage[start + 2], access_type(next.second.operation));
break;
case AddressingMode::Bit0AccumulatorRelative:
target.add_access(start + 2 + int8_t(storage[start + 1]), access_type(next.second.operation));
break;
default: break;
}
}
// Advance.

View File

@ -1941,6 +1941,7 @@
4BEDA40B25B2844B000C2DBD /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = "<group>"; };
4BEDA41725B2845D000C2DBD /* Instruction.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Instruction.hpp; sourceTree = "<group>"; };
4BEDA41D25B388E4000C2DBD /* Parser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Parser.hpp; sourceTree = "<group>"; };
4BEDA42925B3C26B000C2DBD /* AccessType.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AccessType.hpp; sourceTree = "<group>"; };
4BEE0A6A1D72496600532C7B /* Cartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cartridge.cpp; sourceTree = "<group>"; };
4BEE0A6B1D72496600532C7B /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
4BEE0A6D1D72496600532C7B /* PRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRG.cpp; sourceTree = "<group>"; };
@ -4359,6 +4360,7 @@
4BEDA3B225B25563000C2DBD /* InstructionSets */ = {
isa = PBXGroup;
children = (
4BEDA42925B3C26B000C2DBD /* AccessType.hpp */,
4BEDA3B625B25563000C2DBD /* README.md */,
4BEDA40925B2844B000C2DBD /* M50740 */,
4BEDA3B325B25563000C2DBD /* PowerPC */,