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

Makes first efforts towards disassembly.

This commit is contained in:
Thomas Harte 2021-01-26 19:52:30 -05:00
parent cc90935abd
commit 56111c75ae
5 changed files with 127 additions and 23 deletions

View File

@ -9,6 +9,8 @@
#ifndef CachingExecutor_hpp
#define CachingExecutor_hpp
#include "Sizes.hpp"
#include <array>
#include <cstdint>
#include <limits>
@ -19,29 +21,6 @@
namespace InstructionSet {
/*!
Maps to the smallest of the following integers that can contain max_value:
* uint8_t;
* uint16_t;
* uint32_t; or
* uint64_t.
*/
template <uint64_t max_value> struct MinIntTypeValue {
using type =
std::conditional_t<
max_value <= std::numeric_limits<uint8_t>::max(), uint8_t,
std::conditional_t<
max_value <= std::numeric_limits<uint16_t>::max(), uint16_t,
std::conditional_t<
max_value <= std::numeric_limits<uint32_t>::max(), uint32_t,
uint64_t
>
>
>;
};
/*!
A caching executor makes use of an instruction set-specific executor to cache 'performers' (i.e. function pointers)
that result from decoding.

View File

@ -0,0 +1,80 @@
//
// Disassembler.hpp
// Clock Signal
//
// Created by Thomas Harte on 26/01/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef Disassembler_hpp
#define Disassembler_hpp
#include "Sizes.hpp"
#include <list>
#include <map>
#include <set>
namespace InstructionSet {
template <
/// Indicates the Parser for this platform.
template<typename, bool> class ParserType,
/// Indicates the greatest value the program counter might take.
uint64_t max_address,
/// Provides the type of Instruction to expect.
typename InstructionType,
/// Provides the storage size used for memory.
typename MemoryWord,
/// Provides the addressing range of memory.
typename AddressType
> class Disassembler {
public:
using ProgramCounterType = typename MinIntTypeValue<max_address>::type;
static_assert(!std::is_same_v<ProgramCounterType, void>);
/*!
Adds the result of disassembling @c memory which is @c length @c MemoryWords long from @c start_address
to the current net total of instructions and recorded memory accesses.
*/
void disassemble(const MemoryWord *memory, ProgramCounterType location, ProgramCounterType length, ProgramCounterType start_address) {
// TODO: possibly, move some of this stuff to instruction-set specific disassemblers, analogous to
// the Executor's ownership of the Parser. That would allow handling of stateful parsing.
ParserType<decltype(*this), true> parser;
pending_entry_points_.push_back(start_address);
entry_points_.insert(start_address);
while(!pending_entry_points_.empty()) {
const auto next_entry_point = pending_entry_points_.front();
pending_entry_points_.pop_front();
parser.parse(*this, memory - location, next_entry_point, length + location);
}
}
void announce_overflow(ProgramCounterType) {}
void announce_instruction(ProgramCounterType address, InstructionType instruction) {
instructions_[address] = instruction;
}
void add_entry(ProgramCounterType address) {
if(entry_points_.find(address) == entry_points_.end()) {
pending_entry_points_.push_back(address);
entry_points_.insert(address);
}
}
void add_access(AddressType address, AccessType access_type) {
// TODO.
(void)address;
(void)access_type;
}
private:
std::map<ProgramCounterType, InstructionType> instructions_;
std::set<ProgramCounterType> entry_points_;
std::list<ProgramCounterType> pending_entry_points_;
};
}
#endif /* Disassembler_h */

34
InstructionSets/Sizes.hpp Normal file
View File

@ -0,0 +1,34 @@
//
// Sizes.hpp
// Clock Signal
//
// Created by Thomas Harte on 26/01/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef Sizes_h
#define Sizes_h
/*!
Maps to the smallest of the following integers that can contain max_value:
* uint8_t;
* uint16_t;
* uint32_t; or
* uint64_t.
*/
template <uint64_t max_value> struct MinIntTypeValue {
using type =
std::conditional_t<
max_value <= std::numeric_limits<uint8_t>::max(), uint8_t,
std::conditional_t<
max_value <= std::numeric_limits<uint16_t>::max(), uint16_t,
std::conditional_t<
max_value <= std::numeric_limits<uint32_t>::max(), uint32_t,
uint64_t
>
>
>;
};
#endif /* Sizes_h */

View File

@ -11,6 +11,10 @@
#include <cassert>
#include <cstdio>
// TEST.
#include "../../../InstructionSets/M50740/Parser.hpp"
#include "../../../InstructionSets/Disassembler.hpp"
using namespace Apple::IIgs::ADB;
GLU::GLU() : executor_(*this) {}
@ -217,6 +221,9 @@ uint8_t GLU::read_microcontroller_address(uint16_t address) {
void GLU::set_microcontroller_rom(const std::vector<uint8_t> &rom) {
executor_.set_rom(rom);
InstructionSet::Disassembler<InstructionSet::M50740::Parser, 0x1fff, InstructionSet::M50740::Instruction, uint8_t, uint16_t> disassembler;
disassembler.disassemble(rom.data(), 0x1000, uint16_t(rom.size()), 0x1000);
}
void GLU::run_for(Cycles cycles) {

View File

@ -1914,6 +1914,8 @@
4BE34437238389E10058E78F /* AtariSTVideoTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AtariSTVideoTests.mm; sourceTree = "<group>"; };
4BE76CF822641ED300ACD6FA /* QLTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QLTests.mm; sourceTree = "<group>"; };
4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = "<group>"; };
4BE8EB5425C0E9D40040BC40 /* Disassembler.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Disassembler.hpp; sourceTree = "<group>"; };
4BE8EB5525C0EA490040BC40 /* Sizes.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sizes.hpp; sourceTree = "<group>"; };
4BE90FFC22D5864800FB464D /* MacintoshVideoTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MacintoshVideoTests.mm; sourceTree = "<group>"; };
4BE9A6B01EDE293000CBCB47 /* zexdoc.com */ = {isa = PBXFileReference; lastKnownFileType = file; name = zexdoc.com; path = Zexall/zexdoc.com; sourceTree = "<group>"; };
4BEA525D1DF33323007E74F2 /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tape.cpp; path = Electron/Tape.cpp; sourceTree = "<group>"; };
@ -4352,6 +4354,8 @@
children = (
4BEDA42925B3C26B000C2DBD /* AccessType.hpp */,
4BEDA45425B5ECAB000C2DBD /* CachingExecutor.hpp */,
4BE8EB5425C0E9D40040BC40 /* Disassembler.hpp */,
4BE8EB5525C0EA490040BC40 /* Sizes.hpp */,
4BEDA3B625B25563000C2DBD /* README.md */,
4BEDA40925B2844B000C2DBD /* M50740 */,
4BEDA3B325B25563000C2DBD /* PowerPC */,