From 33b53e7605aceaacc8b2b3f1d2083f5118240ce8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 11 Mar 2019 22:47:58 -0400 Subject: [PATCH] Settles upon disassembly as the route in, and begins work in that direction. --- Processors/68000/68000.hpp | 1 + .../Implementation/68000Implementation.hpp | 2 + .../68000/Implementation/68000Storage.cpp | 99 +++++++++++++++++++ .../68000/Implementation/68000Storage.hpp | 6 ++ 4 files changed, 108 insertions(+) diff --git a/Processors/68000/68000.hpp b/Processors/68000/68000.hpp index 872e86b68..66418bf9a 100644 --- a/Processors/68000/68000.hpp +++ b/Processors/68000/68000.hpp @@ -10,6 +10,7 @@ #define MC68000_h #include +#include #include #include diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 393f53d80..9e51b13bc 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -25,6 +25,8 @@ template void Processor: } } + // TODO: synchronous bus. + // Perform the microcycle. bus_handler_.perform_bus_operation(active_program_->microcycle, is_supervisor_); diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 356ec4a0a..9a8db17a0 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -11,8 +11,16 @@ using namespace CPU::MC68000; ProcessorStorage::ProcessorStorage() { + // Create the reset program. reset_program_ = assemble_program("n- n- n- n- n- nn nF nf nV nv np np"); + // TODO: install access patterns. + + // Install operations. + for(int c = 0; c < 65536; ++c) { + install_instruction(c); + } + // Set initial state. Largely TODO. active_program_ = reset_program_.data(); effective_address_ = 0; @@ -110,3 +118,94 @@ std::vector ProcessorStorage::assemble_program(const cha return steps; } + +/* + install_instruction acts, in effect, in the manner of a disassembler. So this class is + formulated to run through all potential 65536 instuction encodings and attempt to + disassemble each, rather than going in the opposite direction. + + This has two benefits: + + (i) which addressing modes go with which instructions falls out automatically; + (ii) it is a lot easier during the manual verification stage of development to work + from known instructions to their disassembly rather than vice versa; especially + (iii) given that there are plentiful disassemblers against which to test work in progress. +*/ +void ProcessorStorage::install_instruction(int instruction) { + enum class Operation { + ABCD, ADD, ADDA, ADDI, ADDQ, ADDX, AND, ANDI, + ASL, ASLrmw, ASR, ASRrmw, Bcc, + + TODO + }; + + struct PatternMapping { + uint16_t mask, value; + Operation operation; + }; + + /* + Credit here is due to 'wrm' (https://github.com/wrm-za I assume) for his public + domain 68000 disassembler, from which the table below was largely sourced. + Manual legwork has been extended to check this table against the M68000 + Programmer's Reference Manual, currently available at + https://www.nxp.com/files-static/archives/doc/ref_manual/M68000PRM.pdf + */ + const std::vector mappings = { + {0xf1f0, 0xc100, Operation::ABCD}, {0xf000, 0xd000, Operation::ADD}, + {0xf0c0, 0xd0c0, Operation::ADDA}, {0xff00, 0x0600, Operation::ADDI}, + {0xf100, 0x5000, Operation::ADDQ}, {0xf130, 0xd100, Operation::ADDX}, + {0xf000, 0xc000, Operation::AND}, {0xff00, 0x0200, Operation::ANDI}, + {0xf118, 0xe100, Operation::ASL}, {0xffc0, 0xe1c0, Operation::ASLrmw}, + {0xf118, 0xe000, Operation::ASR}, {0xffc0, 0xe0c0, Operation::ASRrmw}, + {0xf000, 0x6000, Operation::Bcc}, {0xf1c0, 0x0140, Operation::TODO}, + {0xffc0, 0x0840, Operation::TODO}, {0xf1c0, 0x0180, Operation::TODO}, + {0xffc0, 0x0880, Operation::TODO}, {0xf1c0, 0x01c0, Operation::TODO}, + {0xffc0, 0x08c0, Operation::TODO}, {0xf1c0, 0x0100, Operation::TODO}, + {0xffc0, 0x0800, Operation::TODO}, {0xf1c0, 0x4180, Operation::TODO}, + {0xff00, 0x4200, Operation::TODO}, {0xf100, 0xb000, Operation::TODO}, + {0xf0c0, 0xb0c0, Operation::TODO}, {0xff00, 0x0c00, Operation::TODO}, + {0xf138, 0xb108, Operation::TODO}, {0xf0f8, 0x50c8, Operation::TODO}, + {0xf1c0, 0x81c0, Operation::TODO}, {0xf1c0, 0x80c0, Operation::TODO}, + {0xf100, 0xb100, Operation::TODO}, {0xff00, 0x0a00, Operation::TODO}, + {0xf100, 0xc100, Operation::TODO}, {0xffb8, 0x4880, Operation::TODO}, + {0xffc0, 0x4ec0, Operation::TODO}, {0xffc0, 0x4e80, Operation::TODO}, + {0xf1c0, 0x41c0, Operation::TODO}, {0xfff8, 0x4e50, Operation::TODO}, + {0xf118, 0xe108, Operation::TODO}, {0xffc0, 0xe3c0, Operation::TODO}, + {0xf118, 0xe008, Operation::TODO}, {0xffc0, 0xe2c0, Operation::TODO}, + {0xc000, 0x0000, Operation::TODO}, {0xffc0, 0x44c0, Operation::TODO}, + {0xffc0, 0x46c0, Operation::TODO}, {0xffc0, 0x40c0, Operation::TODO}, + {0xfff0, 0x4e60, Operation::TODO}, {0xc1c0, 0x0040, Operation::TODO}, + {0xfb80, 0x4880, Operation::TODO}, {0xf138, 0x0108, Operation::TODO}, + {0xf100, 0x7000, Operation::TODO}, {0xf1c0, 0xc1c0, Operation::TODO}, + {0xf1c0, 0xc0c0, Operation::TODO}, {0xffc0, 0x4800, Operation::TODO}, + {0xff00, 0x4400, Operation::TODO}, {0xff00, 0x4000, Operation::TODO}, + {0xffff, 0x4e71, Operation::TODO}, {0xff00, 0x4600, Operation::TODO}, + {0xf000, 0x8000, Operation::TODO}, {0xff00, 0x0000, Operation::TODO}, + {0xffc0, 0x4840, Operation::TODO}, {0xffff, 0x4e70, Operation::TODO}, + {0xf118, 0xe118, Operation::TODO}, {0xffc0, 0xe7c0, Operation::TODO}, + {0xf118, 0xe018, Operation::TODO}, {0xffc0, 0xe6c0, Operation::TODO}, + {0xf118, 0xe110, Operation::TODO}, {0xffc0, 0xe5c0, Operation::TODO}, + {0xf118, 0xe010, Operation::TODO}, {0xffc0, 0xe4c0, Operation::TODO}, + {0xffff, 0x4e73, Operation::TODO}, {0xffff, 0x4e77, Operation::TODO}, + {0xffff, 0x4e75, Operation::TODO}, {0xf1f0, 0x8100, Operation::TODO}, + {0xf0c0, 0x50c0, Operation::TODO}, {0xffff, 0x4e72, Operation::TODO}, + {0xf000, 0x9000, Operation::TODO}, {0xf0c0, 0x90c0, Operation::TODO}, + {0xff00, 0x0400, Operation::TODO}, {0xf100, 0x5100, Operation::TODO}, + {0xf130, 0x9100, Operation::TODO}, {0xfff8, 0x4840, Operation::TODO}, + {0xffc0, 0x4ac0, Operation::TODO}, {0xfff0, 0x4e40, Operation::TODO}, + {0xffff, 0x4e76, Operation::TODO}, {0xff00, 0x4a00, Operation::TODO}, + {0xfff8, 0x4e58, Operation::TODO} + }; + + // Perform a linear search of the mappings above for this instruction. + for(const auto &mapping: mappings) { + if((instruction & mapping.mask) == mapping.value) { + if(mapping.operation == Operation::TODO) { + std::cout << std::hex << std::setw(4) << std::setfill('0'); + std::cout << "Yet to implement, instruction matching: x & " << mapping.mask << " == " << mapping.value << std::endl; + } + break; + } + } +} diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index ac90504cb..d7829c36e 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -104,6 +104,12 @@ class ProcessorStorage { data from those. */ std::vector assemble_program(const char *access_pattern); + + /*! + Disassembles the instruction @c instruction and inserts it into the + appropriate lookup tables. + */ + void install_instruction(int instruction); }; #endif /* MC68000Storage_h */