From 59dbf69c1e97e098c1adcb913a92d7b3f9b665ec Mon Sep 17 00:00:00 2001 From: WeebDataHoarder <57538841+weebdatahoarder@users.noreply.github.com> Date: Thu, 31 Dec 2020 22:06:52 +0100 Subject: [PATCH] WIP: Initial commit, working basic assembler --- .drone.jsonnet | 52 +++++ .gitignore | 2 + CMakeLists.txt | 31 +++ COPYING | 24 +++ src/Assembler.cpp | 28 +++ src/Assembler.h | 195 +++++++++++++++++ src/Declaration.cpp | 28 +++ src/Declaration.h | 42 ++++ src/Function.cpp | 28 +++ src/Function.h | 41 ++++ src/Parser.cpp | 217 +++++++++++++++++++ src/Parser.h | 102 +++++++++ src/Token.cpp | 28 +++ src/Token.h | 78 +++++++ src/instructions/AddressOffset.h | 35 ++++ src/instructions/Branch.cpp | 56 +++++ src/instructions/Branch.h | 56 +++++ src/instructions/Calc.cpp | 52 +++++ src/instructions/Calc.h | 70 +++++++ src/instructions/CalcImm.cpp | 51 +++++ src/instructions/CalcImm.h | 59 ++++++ src/instructions/Copy.cpp | 47 +++++ src/instructions/Copy.h | 57 +++++ src/instructions/End.cpp | 40 ++++ src/instructions/End.h | 49 +++++ src/instructions/Init.cpp | 56 +++++ src/instructions/Init.h | 57 +++++ src/instructions/Instruction.cpp | 350 +++++++++++++++++++++++++++++++ src/instructions/Instruction.h | 80 +++++++ src/instructions/Jump.cpp | 41 ++++ src/instructions/Jump.h | 51 +++++ src/instructions/Load.cpp | 53 +++++ src/instructions/Load.h | 58 +++++ src/instructions/Loop.cpp | 40 ++++ src/instructions/Loop.h | 52 +++++ src/instructions/Poll.cpp | 64 ++++++ src/instructions/Poll.h | 61 ++++++ src/instructions/Return.cpp | 40 ++++ src/instructions/Return.h | 51 +++++ src/instructions/Set.cpp | 50 +++++ src/instructions/Set.h | 54 +++++ src/instructions/Wait.cpp | 41 ++++ src/instructions/Wait.h | 53 +++++ src/instructions/Write.cpp | 47 +++++ src/instructions/Write.h | 54 +++++ src/rrcas.cpp | 75 +++++++ 46 files changed, 2896 insertions(+) create mode 100644 .drone.jsonnet create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 src/Assembler.cpp create mode 100644 src/Assembler.h create mode 100644 src/Declaration.cpp create mode 100644 src/Declaration.h create mode 100644 src/Function.cpp create mode 100644 src/Function.h create mode 100644 src/Parser.cpp create mode 100644 src/Parser.h create mode 100644 src/Token.cpp create mode 100644 src/Token.h create mode 100644 src/instructions/AddressOffset.h create mode 100644 src/instructions/Branch.cpp create mode 100644 src/instructions/Branch.h create mode 100644 src/instructions/Calc.cpp create mode 100644 src/instructions/Calc.h create mode 100644 src/instructions/CalcImm.cpp create mode 100644 src/instructions/CalcImm.h create mode 100644 src/instructions/Copy.cpp create mode 100644 src/instructions/Copy.h create mode 100644 src/instructions/End.cpp create mode 100644 src/instructions/End.h create mode 100644 src/instructions/Init.cpp create mode 100644 src/instructions/Init.h create mode 100644 src/instructions/Instruction.cpp create mode 100644 src/instructions/Instruction.h create mode 100644 src/instructions/Jump.cpp create mode 100644 src/instructions/Jump.h create mode 100644 src/instructions/Load.cpp create mode 100644 src/instructions/Load.h create mode 100644 src/instructions/Loop.cpp create mode 100644 src/instructions/Loop.h create mode 100644 src/instructions/Poll.cpp create mode 100644 src/instructions/Poll.h create mode 100644 src/instructions/Return.cpp create mode 100644 src/instructions/Return.h create mode 100644 src/instructions/Set.cpp create mode 100644 src/instructions/Set.h create mode 100644 src/instructions/Wait.cpp create mode 100644 src/instructions/Wait.h create mode 100644 src/instructions/Write.cpp create mode 100644 src/instructions/Write.h create mode 100644 src/rrcas.cpp diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 0000000..5ce085c --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,52 @@ +local Pipeline(image, version, arch, depinstall, extra) = { + kind: "pipeline", + type: "docker", + name: image+"-"+version+"-"+arch, + platform: { + os: "linux", + arch: arch + }, + steps: [ + { + name: "build", + image: image+":"+version, + commands: [ + depinstall+" cmake make gcc g++ "+extra, + "mkdir build" + "cd build", + "cmake ..", + "make -j $(nproc)", + ] + } + ] +}; + +local AptPipeline(image, version, arch, extra="") = Pipeline(image, version, arch, "apt update && DEBIAN_FRONTEND=noninteractive apt install -y", extra); + +local PacManPipeline(image, version, arch, extra="") = Pipeline(image, version, arch, "pacman -Syy && pacman --noconfirm -S", extra); + +local ApkPipeline(image, version, arch, extra="") = Pipeline(image, version, arch, "apk add --update gcc musl-dev", extra); + +local YumPipeline(image, version, arch, extra="") = Pipeline(image, version, arch, "yum install -y", extra); + +local XbpsPipeline(image, version, arch, extra="") = Pipeline(image, version, arch, "xbps-install -Sy", extra); + +[ + AptPipeline("ubuntu", "20.04", "amd64"), + AptPipeline("ubuntu", "20.04", "arm64"), + + AptPipeline("debian", "buster", "amd64"), + AptPipeline("debian", "buster", "arm64"), + + + YumPipeline("fedora", "latest", "amd64"), + YumPipeline("fedora", "latest", "arm64"), + + PacManPipeline("archlinux", "latest", "amd64"), + + ApkPipeline("alpine", "latest", "amd64"), + ApkPipeline("alpine", "latest", "arm64"), + + + XbpsPipeline("voidlinux/voidlinux", "latest", "amd64"), +] \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c10195 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/cmake-build* +/.idea \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e13058b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.16) +project(rrcc) + +set(CMAKE_CXX_STANDARD 14) + +set(SOURCE_FILES + + src/instructions/AddressOffset.h + src/instructions/Instruction.cpp src/instructions/Instruction.h + src/instructions/Write.cpp src/instructions/Write.h + src/instructions/Copy.cpp src/instructions/Copy.h + src/instructions/Load.cpp src/instructions/Load.h + src/instructions/Init.cpp src/instructions/Init.h + src/instructions/Calc.cpp src/instructions/Calc.h + src/instructions/CalcImm.cpp src/instructions/CalcImm.h + src/instructions/Branch.cpp src/instructions/Branch.h + src/instructions/Poll.cpp src/instructions/Poll.h + src/instructions/Loop.cpp src/instructions/Loop.h + src/instructions/Jump.cpp src/instructions/Jump.h + src/instructions/Return.cpp src/instructions/Return.h + src/instructions/Set.cpp src/instructions/Set.h + src/instructions/Wait.cpp src/instructions/Wait.h + src/instructions/End.cpp src/instructions/End.h + + src/Parser.cpp src/Parser.h + src/Token.cpp src/Token.h + src/Declaration.cpp src/Declaration.h + src/Function.cpp src/Function.h + src/Assembler.cpp src/Assembler.h) + +add_executable(rrc-as src/rrcas.cpp ${SOURCE_FILES}) \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..0cb14df --- /dev/null +++ b/COPYING @@ -0,0 +1,24 @@ +Copyright (c) 2020, rrcc FM10K-Documentation Contributors + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/src/Assembler.cpp b/src/Assembler.cpp new file mode 100644 index 0000000..3f86d91 --- /dev/null +++ b/src/Assembler.cpp @@ -0,0 +1,28 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Assembler.h" diff --git a/src/Assembler.h b/src/Assembler.h new file mode 100644 index 0000000..10d9445 --- /dev/null +++ b/src/Assembler.h @@ -0,0 +1,195 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + + +#include "Parser.h" +#include "instructions/Instruction.h" + +class Assembler { +private: + const Parser &parser; + std::vector bytes; + std::unordered_map knownRegisters; + std::unordered_map> entries; + + uint32_t placeFunction(uint32_t base, const Function &function) { + std::unordered_map addr; + + auto declarations = function.declarations; //Copy is necessary + + uint32_t offset = base; + + //Resolve local labels + for (auto &d : declarations) { + if (!d.label.empty()) { + addr[d.label] = offset; + } + + bool hasOperator = false; + for (auto &t : d.tokens) { + if (t.getType() == Token::Type::Operator) { + hasOperator = true; + break; + } + } + + if (!hasOperator) { + continue;; + } + + auto instr = Instruction::Instruction::getCommandForDeclaration(d); + if (instr == nullptr) { + throw std::runtime_error("Unknown or invalid declaration"); + } + + auto b = instr->toBytes(); + offset += b.size(); + } + + offset = base; + + bool needsReLabeling = false; + + for (auto &d : declarations) { + for (auto &t : d.tokens) { + if (t.getType() == Token::Type::CodeLabel) { + if (t.getTextValue().at(0) == '.') { + if (addr.find(t.getTextValue()) != addr.end()) { + t.valueImmediate = addr.at(t.getTextValue()); + } else { + throw std::runtime_error("Could not find local label " + t.getTextValue()); + } + } else if (entries.find(t.getTextValue()) != entries.end()) { + t.valueImmediate = entries.at(t.getTextValue()).first; + } else { + needsReLabeling = true; + } + } else if (t.getType() == Token::Type::RegisterName) { + if (knownRegisters.find(t.getTextValue()) != knownRegisters.end()) { + t.valueImmediate = knownRegisters.at(t.getTextValue()); + } else { + throw std::runtime_error("Could not find named register " + t.getTextValue()); + } + } + } + } + + for (auto &d : declarations) { + auto instr = Instruction::Instruction::getCommandForDeclaration(d); + if (instr == nullptr) { + throw std::runtime_error("Unknown or invalid declaration"); + } + + if (!d.label.empty()) { + addr[d.label] = offset; + } + + auto data = instr->toBytes(); + + if (offset + data.size() > +bytes.size()) { + throw std::runtime_error("Instruction encoding exceeds image size"); + } + + std::copy(data.begin(), data.end(), bytes.begin() + offset); + offset += data.size(); + } + + entries[function.label] = {base, needsReLabeling}; + + return offset + 4; //Free bytes between functions + } + + const Function *getFunctionByLabel(const std::string &l) { + for (auto &f : parser.getTree()) { + if (f.label == l) { + return &f; + } + } + + return nullptr; + } + +public: + + Assembler(const Parser &parser) : parser(parser) { + + } + + //Default max size 1 MiB + void assemble(uint32_t baseAddress = 0x08000, uint32_t imageSize = 0x100000) { + entries.clear(); + bytes.clear(); + bytes.resize(imageSize - 1, (uint8_t) Instruction::Instruction::CommandOp::END); + + uint32_t freeOffsetLocation = baseAddress; + + auto entrypoint = getFunctionByLabel("entrypoint"); + if (entrypoint == nullptr) { + throw std::runtime_error("Entrypoint function not found"); + } + + freeOffsetLocation = placeFunction(freeOffsetLocation, *entrypoint); + + while (true) { + bool changed = false; + for (auto &fEntry : entries) { + if (fEntry.second.second) { + auto f = getFunctionByLabel(fEntry.first); + for (auto &d : f->declarations) { + for (auto &t : d.tokens) { + if (t.getType() == Token::Type::CodeLabel && t.getTextValue().at(0) != '.') { + if (entries.find(t.getTextValue()) == entries.end()) { + changed = true; + auto fUsed = getFunctionByLabel(t.getTextValue()); + if (fUsed == nullptr) { + throw std::runtime_error( + t.getTextValue() + " function not found, in use by " + fEntry.first); + } + + freeOffsetLocation = placeFunction(freeOffsetLocation, *fUsed); + } + } + } + } + + placeFunction(fEntry.second.first, *f); + } + } + + if (!changed) { + break; + } + } + + } + + const auto &getImage() const { + return bytes; + } +}; diff --git a/src/Declaration.cpp b/src/Declaration.cpp new file mode 100644 index 0000000..a8a31b6 --- /dev/null +++ b/src/Declaration.cpp @@ -0,0 +1,28 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Declaration.h" diff --git a/src/Declaration.h b/src/Declaration.h new file mode 100644 index 0000000..20afef1 --- /dev/null +++ b/src/Declaration.h @@ -0,0 +1,42 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + + +#include +#include "Token.h" + +class Declaration { +public: + Declaration() { + + } + + std::string label; + std::vector tokens; +}; diff --git a/src/Function.cpp b/src/Function.cpp new file mode 100644 index 0000000..bdcf224 --- /dev/null +++ b/src/Function.cpp @@ -0,0 +1,28 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Function.h" diff --git a/src/Function.h b/src/Function.h new file mode 100644 index 0000000..ebd4460 --- /dev/null +++ b/src/Function.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include +#include "Declaration.h" + +class Function { +public: + Function() { + + } + + std::string label; + std::vector declarations; +}; diff --git a/src/Parser.cpp b/src/Parser.cpp new file mode 100644 index 0000000..6bf35b2 --- /dev/null +++ b/src/Parser.cpp @@ -0,0 +1,217 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Parser.h" + +void Parser::parse() { + offset = 0; + functions.clear(); + + std::string currentValue; + uint8_t c; + currentValue.reserve(16); + + std::vector>> states = { + /* 0 */ {{Token::Type::Label, 1}}, + + /* 1 */ + {{Token::Type::LocalLabel, 2}, {Token::Type::Operator, 3}}, + /* 2 */ + {{Token::Type::LocalLabel, 2}, {Token::Type::Operator, 3}, {Token::Type::Label, 1}}, + + /* 3 */ + {{Token::Type::CodeLocation, 3}, {Token::Type::CodeLabel, 3}, {Token::Type::RegisterLocation, 3}, {Token::Type::RegisterName, 3}, {Token::Type::Immediate, 3}, {Token::Type::Label, 1}}, + }; + + size_t currentStateIndex = 0; + const size_t resetStateIndex = 2; + bool isComment = false; + + Function currentFunction; + Declaration currentDeclaration; + + while (true) { + c = getByte(); + if (c == '\n' || c == '\0' || (!isComment && (c == ' ' || c == '\t' || c == ',' || c == ';'))) { + //End token + + //TODO: identify Token + if (!currentValue.empty()) { + bool foundToken = false; + for (auto &t : states[currentStateIndex]) { + switch (t.first) { + case Token::Type::Label: + if (isLabel(currentValue)) { + if (!currentFunction.label.empty()) { + functions.emplace_back(std::move(currentFunction)); + currentFunction = Function(); + } + currentFunction.label = currentValue.substr(0, currentValue.size() - 1); + + foundToken = true; + } + break; + case Token::Type::LocalLabel: + if (isLocalLabel(currentValue)) { + currentDeclaration.label = currentValue.substr(0, currentValue.size() - 1); + foundToken = true; + } + break; + case Token::Type::Operator: + if (isOperator(currentValue)) { + currentDeclaration.tokens.emplace_back(Token(t.first, currentValue)); + foundToken = true; + } + break; + case Token::Type::RegisterName: + if (isRegisterName(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos))); + foundToken = true; + } + break; + case Token::Type::RegisterLocation: + if (isRegisterLocation(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos), + std::stoi(currentValue.substr(1, std::string::npos), nullptr, 0))); + foundToken = true; + } + break; + case Token::Type::CodeLabel: + if (isCodeLabel(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos))); + foundToken = true; + } + break; + case Token::Type::CodeLocation: + if (isCodeLocation(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos), + std::stoi(currentValue.substr(1, std::string::npos), nullptr, 0))); + foundToken = true; + } + break; + case Token::Type::Immediate: + if (isImmediate(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue, std::stoi(currentValue, nullptr, 0))); + foundToken = true; + } + break; + } + + if (foundToken) { + currentValue.clear(); + currentStateIndex = t.second; + break; + } + + } + + if (!foundToken) { + //TODO: ERROR + throw std::runtime_error("Could not find new Token state"); + } + } + + if (c == '\n' || c == '\0') { + isComment = false; + if (resetStateIndex < currentStateIndex) { + currentStateIndex = resetStateIndex; + } + + if (!currentDeclaration.tokens.empty()) { + currentFunction.declarations.emplace_back(std::move(currentDeclaration)); + currentDeclaration = Declaration(); + } + + if (c == '\0') { + functions.emplace_back(std::move(currentFunction)); + break; + } + } + if (c == ';') { + isComment = true; + } + } else if (!isComment) { + currentValue += c; + } + } +} + +bool Parser::isIteratorAllowedValues(std::string::const_iterator it, std::string::const_iterator end, + const std::vector &values) { + while (it != end) { + if (!isAllowedValues(*it, values)) { + return false; + } + it++; + } + return true; +} + +bool Parser::isAllowedValues(uint8_t c, const std::vector &values) { + return std::find(values.begin(), values.end(), c) != values.end(); +} + +bool Parser::isOperator(const std::string &v) { + return isIteratorAllowedValues(v.begin(), v.end(), getOperatorValues()); +} + +bool Parser::isRegisterName(const std::string &v) { + return v.size() >= 2 && v.at(0) == '%' && isIteratorAllowedValues(v.begin() + 1, v.end(), getAlphanumericValues()); +} + +bool Parser::isRegisterLocation(const std::string &v) { + return v.size() >= 2 && v.at(0) == '%' && isIteratorAllowedValues(v.begin() + 1, v.end(), getNumericValues()); +} + +bool Parser::isCodeLabel(const std::string &v) { + return v.size() >= 2 && v.at(0) == '@' && + ((v.at(1) == '.' && isIteratorAllowedValues(v.begin() + 2, v.end(), getAlphanumericValues())) || + isIteratorAllowedValues(v.begin() + 1, v.end(), getAlphanumericValues())); +} + +bool Parser::isCodeLocation(const std::string &v) { + return v.size() >= 2 && v.at(0) == '@' && isIteratorAllowedValues(v.begin() + 1, v.end(), getNumericValues()); +} + +bool Parser::isImmediate(const std::string &v) { + return isIteratorAllowedValues(v.begin(), v.end(), getNumericValues()); +} + +bool Parser::isLocalLabel(const std::string &v) { + return v.size() >= 3 && v.at(0) == '.' && isAllowedValues(v.at(1), getAlphaValues()) && v.at(v.size() - 1) == ':' && + isIteratorAllowedValues(v.begin() + 2, v.end() - 1, getAlphanumericValues()); +} + +bool Parser::isLabel(const std::string &v) { + return v.size() >= 2 && isAllowedValues(v.at(0), getAlphaValues()) && v.at(v.size() - 1) == ':' && + isIteratorAllowedValues(v.begin() + 1, v.end() - 1, getAlphanumericValues()); +} diff --git a/src/Parser.h b/src/Parser.h new file mode 100644 index 0000000..0ba1084 --- /dev/null +++ b/src/Parser.h @@ -0,0 +1,102 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + + +#include +#include +#include +#include "Function.h" + +class Parser { + size_t offset; + const std::vector &bytes; + std::vector functions; + + + uint8_t getByte() { + return bytes.size() <= offset ? 0 : bytes.at(offset++); + } + + static std::vector getAlphaValues() { + return {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', + 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_',}; + } + + static std::vector getAlphanumericValues() { + return {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', + 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9'}; + } + + static std::vector getOperatorValues() { + return {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', + 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '~', '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9'}; + } + + static std::vector getNumericValues() { + return {'x', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', + 'E', 'F'}; + } + + static bool isIteratorAllowedValues(std::string::const_iterator it, std::string::const_iterator end, + const std::vector &values); + + static bool isAllowedValues(uint8_t c, const std::vector &values); + + static bool isOperator(const std::string &v); + + static bool isRegisterName(const std::string &v); + + static bool isRegisterLocation(const std::string &v); + + static bool isCodeLabel(const std::string &v); + + static bool isCodeLocation(const std::string &v); + + static bool isImmediate(const std::string &v); + + static bool isLocalLabel(const std::string &v); + + static bool isLabel(const std::string &v); + +public: + Parser(const std::vector &bytes) : bytes(bytes) { + parse(); + } + + void parse(); + + const std::vector &getTree() const { + return functions; + } +}; diff --git a/src/Token.cpp b/src/Token.cpp new file mode 100644 index 0000000..6729ccc --- /dev/null +++ b/src/Token.cpp @@ -0,0 +1,28 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Token.h" diff --git a/src/Token.h b/src/Token.h new file mode 100644 index 0000000..dce34c8 --- /dev/null +++ b/src/Token.h @@ -0,0 +1,78 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +class Token { +public: + + enum class Type { + // (LocalLabel:) Operator(.Flags) (RegisterLabel,RegisterLocation,CodeLabel,CodeLocation,Immediate) + Label, // {label}: can't start with a number. Can contain a-zA-Z0-9_. Example: label: + LocalLabel, // .{label} + + Operator, // Operator string. Can contain {a-zA-Z0-9_~} + + RegisterName, // %{label}, example: %MGMT_SCRATCH_0 + RegisterLocation, // %{32-bit unsigned integer} , example: %0, %1234, %0x1234 + + CodeLabel, // @{label} or @{.label}, example: @__test, @.loop + CodeLocation, // @{32-bit unsigned integer} , example: @0, @1234, @0x1234 + + Immediate, // {32-bit unsigned integer} , example: 0, 1234, 0x1234 + + // A comment is ;{....} anything that starts with ; . Reads until \n + + //End of Token: \n\t[space],; + }; + + Token(Type type, std::string valueString, uint32_t valueImmediate = 0) : type(type), valueImmediate(valueImmediate), + valueString(std::move(valueString)) { + + } + + Type type; + uint32_t valueImmediate; + std::string valueString; + + Type getType() const { + return type; + } + + const std::string &getTextValue() const { + return valueString; + } + + uint32_t getNumericValue() const { + return valueImmediate; + } +}; \ No newline at end of file diff --git a/src/instructions/AddressOffset.h b/src/instructions/AddressOffset.h new file mode 100644 index 0000000..d2059f5 --- /dev/null +++ b/src/instructions/AddressOffset.h @@ -0,0 +1,35 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +namespace Instruction { + typedef struct { + uint32_t address: 24; + uint8_t offset: 2; + } AddressWithOffset; +} \ No newline at end of file diff --git a/src/instructions/Branch.cpp b/src/instructions/Branch.cpp new file mode 100644 index 0000000..6e5af1f --- /dev/null +++ b/src/instructions/Branch.cpp @@ -0,0 +1,56 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Branch.h" + +std::vector Instruction::Branch::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | (equality << 2) | address.offset); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + bytes.emplace_back((value >> 24) & 0xFF); + bytes.emplace_back((value >> 16) & 0xFF); + bytes.emplace_back((value >> 8) & 0xFF); + bytes.emplace_back(value & 0xFF); + + bytes.emplace_back((mask >> 24) & 0xFF); + bytes.emplace_back((mask >> 16) & 0xFF); + bytes.emplace_back((mask >> 8) & 0xFF); + bytes.emplace_back(mask & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((jumpAddress >> 16) & 0xFF); + bytes.emplace_back((jumpAddress >> 8) & 0xFF); + bytes.emplace_back(jumpAddress & 0xFF); + + return bytes; +} \ No newline at end of file diff --git a/src/instructions/Branch.h b/src/instructions/Branch.h new file mode 100644 index 0000000..1b5fba1 --- /dev/null +++ b/src/instructions/Branch.h @@ -0,0 +1,56 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Branch : public Instruction { + public: + + Branch() { + + } + + Branch(const AddressWithOffset &address, uint8_t equality, uint32_t value, uint32_t mask, uint32_t jumpAddress) + : equality(equality), address(address), value(value), mask(mask), jumpAddress(jumpAddress) {} + + CommandOp getCommand() const override { + return CommandOp::BRANCH; + }; + + std::vector toBytes() const override; + + + AddressWithOffset address; + uint8_t equality; + uint32_t value; + uint32_t mask; + uint32_t jumpAddress; + }; +} \ No newline at end of file diff --git a/src/instructions/Calc.cpp b/src/instructions/Calc.cpp new file mode 100644 index 0000000..fd8a49c --- /dev/null +++ b/src/instructions/Calc.cpp @@ -0,0 +1,52 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Calc.h" + +std::vector Instruction::Calc::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | ((uint8_t) operation << 2) | addressOffset); + + bytes.emplace_back((addressDestination >> 16) & 0xFF); + bytes.emplace_back((addressDestination >> 8) & 0xFF); + bytes.emplace_back(addressDestination & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((addressSource >> 16) & 0xFF); + bytes.emplace_back((addressSource >> 8) & 0xFF); + bytes.emplace_back(addressSource & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((addressTarget >> 16) & 0xFF); + bytes.emplace_back((addressTarget >> 8) & 0xFF); + bytes.emplace_back(addressTarget & 0xFF); + + return bytes; +} diff --git a/src/instructions/Calc.h b/src/instructions/Calc.h new file mode 100644 index 0000000..b75fa21 --- /dev/null +++ b/src/instructions/Calc.h @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Calc : public Instruction { + public: + + enum class Operation : uint8_t { + AND = 0, + OR = 1, + ADD = 2, + SUB = 3, + LSHIFT = 4, + RSHIFT = 5, + ARSHIFT = 6, + UNDEFINED = 7 + }; + + Calc() { + + } + + Calc(Operation operation, uint8_t addressOffset, uint32_t addressDestination, uint32_t addressSource, + uint32_t addressTarget) : operation(operation), addressOffset(addressOffset), + addressDestination(addressDestination), addressSource(addressSource), + addressTarget(addressTarget) {} + + CommandOp getCommand() const override { + return CommandOp::CALC; + }; + + + std::vector toBytes() const override; + + + Operation operation; + uint8_t addressOffset; + uint32_t addressDestination; + uint32_t addressSource; + uint32_t addressTarget; + }; +} \ No newline at end of file diff --git a/src/instructions/CalcImm.cpp b/src/instructions/CalcImm.cpp new file mode 100644 index 0000000..9bb0e0a --- /dev/null +++ b/src/instructions/CalcImm.cpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "CalcImm.h" + +std::vector Instruction::CalcImm::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | ((uint8_t) operation << 2) | addressOffset); + + bytes.emplace_back((addressDestination >> 16) & 0xFF); + bytes.emplace_back((addressDestination >> 8) & 0xFF); + bytes.emplace_back(addressDestination & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((addressSource >> 16) & 0xFF); + bytes.emplace_back((addressSource >> 8) & 0xFF); + bytes.emplace_back(addressSource & 0xFF); + + bytes.emplace_back((value >> 24) & 0xFF); + bytes.emplace_back((value >> 16) & 0xFF); + bytes.emplace_back((value >> 8) & 0xFF); + bytes.emplace_back(value & 0xFF); + + return bytes; +} diff --git a/src/instructions/CalcImm.h b/src/instructions/CalcImm.h new file mode 100644 index 0000000..e619bcc --- /dev/null +++ b/src/instructions/CalcImm.h @@ -0,0 +1,59 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" +#include "Calc.h" + +namespace Instruction { + class CalcImm : public Instruction { + public: + + CalcImm() { + + } + + CalcImm(Calc::Operation operation, uint8_t addressOffset, uint32_t addressDestination, uint32_t addressSource, + uint32_t value) : operation(operation), addressOffset(addressOffset), + addressDestination(addressDestination), addressSource(addressSource), value(value) {} + + CommandOp getCommand() const override { + return CommandOp::CALC_IMM; + }; + + + std::vector toBytes() const override; + + + Calc::Operation operation; + uint8_t addressOffset; + uint32_t addressDestination; + uint32_t addressSource; + uint32_t value; + }; +} \ No newline at end of file diff --git a/src/instructions/Copy.cpp b/src/instructions/Copy.cpp new file mode 100644 index 0000000..afdf1d4 --- /dev/null +++ b/src/instructions/Copy.cpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Copy.h" + + +std::vector Instruction::Copy::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | ((count - 1) << 4) | (addressBB.offset << 2) | addressAA.offset); + + bytes.emplace_back((addressAA.address >> 16) & 0xFF); + bytes.emplace_back((addressAA.address >> 8) & 0xFF); + bytes.emplace_back(addressAA.address & 0xFF); + + bytes.emplace_back(0); + + bytes.emplace_back((addressBB.address >> 16) & 0xFF); + bytes.emplace_back((addressBB.address >> 8) & 0xFF); + bytes.emplace_back(addressBB.address & 0xFF); + + return bytes; +} diff --git a/src/instructions/Copy.h b/src/instructions/Copy.h new file mode 100644 index 0000000..1a3b861 --- /dev/null +++ b/src/instructions/Copy.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Copy : public Instruction { + public: + Copy() { + + } + + Copy(const AddressWithOffset &addressAa, const AddressWithOffset &addressBb, uint8_t count) : count(count), + addressAA( + addressAa), + addressBB( + addressBb) {} + + CommandOp getCommand() const override { + return CommandOp::COPY; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset addressAA; + AddressWithOffset addressBB; + uint8_t count; + }; +} \ No newline at end of file diff --git a/src/instructions/End.cpp b/src/instructions/End.cpp new file mode 100644 index 0000000..21be4f7 --- /dev/null +++ b/src/instructions/End.cpp @@ -0,0 +1,40 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "End.h" + +std::vector Instruction::End::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand()); + + bytes.emplace_back((reserved >> 16) & 0xFF); + bytes.emplace_back((reserved >> 8) & 0xFF); + bytes.emplace_back(reserved & 0xFF); + + return bytes; +} diff --git a/src/instructions/End.h b/src/instructions/End.h new file mode 100644 index 0000000..bb02885 --- /dev/null +++ b/src/instructions/End.h @@ -0,0 +1,49 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class End : public Instruction { + public: + End() { + + } + + CommandOp getCommand() const override { + return CommandOp::END; + }; + + + std::vector toBytes() const override; + + + uint32_t reserved = 0; + }; +} \ No newline at end of file diff --git a/src/instructions/Init.cpp b/src/instructions/Init.cpp new file mode 100644 index 0000000..ee0e3ae --- /dev/null +++ b/src/instructions/Init.cpp @@ -0,0 +1,56 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Init.h" + +std::vector Instruction::Init::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | (increment << 2) | address.offset); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((count >> 16) & 0xFF); + bytes.emplace_back((count >> 8) & 0xFF); + bytes.emplace_back(count & 0xFF); + + bytes.emplace_back((data >> 24) & 0xFF); + bytes.emplace_back((data >> 16) & 0xFF); + bytes.emplace_back((data >> 8) & 0xFF); + bytes.emplace_back(data & 0xFF); + + bytes.emplace_back((data_add >> 24) & 0xFF); + bytes.emplace_back((data_add >> 16) & 0xFF); + bytes.emplace_back((data_add >> 8) & 0xFF); + bytes.emplace_back(data_add & 0xFF); + + return bytes; +} diff --git a/src/instructions/Init.h b/src/instructions/Init.h new file mode 100644 index 0000000..d5d01a7 --- /dev/null +++ b/src/instructions/Init.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Init : public Instruction { + public: + Init() { + + } + + Init(const AddressWithOffset &address, uint8_t increment, uint32_t count, uint32_t data, uint32_t dataAdd) + : address(address), increment(increment), count(count), data(data), data_add(dataAdd) {} + + + CommandOp getCommand() const override { + return CommandOp::INIT; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset address; + uint8_t increment; + uint32_t count; + uint32_t data; + uint32_t data_add; + }; +} \ No newline at end of file diff --git a/src/instructions/Instruction.cpp b/src/instructions/Instruction.cpp new file mode 100644 index 0000000..165dc5e --- /dev/null +++ b/src/instructions/Instruction.cpp @@ -0,0 +1,350 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Instruction.h" + +#include "Write.h" +#include "Copy.h" +#include "Load.h" +#include "Init.h" +#include "Calc.h" +#include "CalcImm.h" +#include "Branch.h" +#include "Poll.h" +#include "Loop.h" +#include "Jump.h" +#include "Return.h" +#include "Set.h" +#include "Wait.h" +#include "End.h" + +#include "../Declaration.h" + +namespace Instruction { + + std::unique_ptr Instruction::getCommandForDeclaration(const Declaration &declaration) { + size_t offset = 0; + for (auto &t : declaration.tokens) { + if (t.getType() == Token::Type::Operator) { + break; + } + ++offset; + } + + if (offset == declaration.tokens.size()) { + return nullptr; + } + + offset++; + + uint32_t paramCount = declaration.tokens.size() - offset; + + std::string operatorValue = declaration.tokens.at(offset - 1).getTextValue(); + + uint8_t addressOffset = 0; + uint8_t addressOffset2 = 0; + + + if ( + ((operatorValue == "WRITE") || (operatorValue == "WRITE~1" && (addressOffset = 1)) || + (operatorValue == "WRITE~2" && (addressOffset = 2)) || + (operatorValue == "WRITE~3" && (addressOffset = 3))) + && paramCount >= 2 + ) { + std::vector data; + for (auto it = declaration.tokens.begin() + offset + 1; it != declaration.tokens.end(); ++it) { + data.emplace_back(it->getNumericValue()); + } + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, data); + } else if ( + ((operatorValue == "COPY") || + (operatorValue == "COPY~01" && (addressOffset2 = 1)) || + (operatorValue == "COPY~02" && (addressOffset2 = 2)) || + (operatorValue == "COPY~03" && (addressOffset2 = 3)) || + (operatorValue == "COPY~10" && (addressOffset = 1)) || + (operatorValue == "COPY~11" && (addressOffset = 1) && (addressOffset2 = 1)) || + (operatorValue == "COPY~12" && (addressOffset = 1) && (addressOffset2 = 2)) || + (operatorValue == "COPY~13" && (addressOffset = 1) && (addressOffset2 = 3)) || + (operatorValue == "COPY~20" && (addressOffset = 2)) || + (operatorValue == "COPY~21" && (addressOffset = 2) && (addressOffset2 = 1)) || + (operatorValue == "COPY~22" && (addressOffset = 2) && (addressOffset2 = 2)) || + (operatorValue == "COPY~23" && (addressOffset = 2) && (addressOffset2 = 3)) || + (operatorValue == "COPY~30" && (addressOffset = 3)) || + (operatorValue == "COPY~31" && (addressOffset = 3) && (addressOffset2 = 1)) || + (operatorValue == "COPY~32" && (addressOffset = 3) && (addressOffset2 = 2)) || + (operatorValue == "COPY~33" && (addressOffset = 3) && (addressOffset2 = 3)) + ) + && paramCount >= 2 + ) { + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, + AddressWithOffset{declaration.tokens.at(offset + 1).getNumericValue(), addressOffset2}, + declaration.tokens.at(offset + 3).getNumericValue()); + } else if ( + ((operatorValue == "LOAD") || (operatorValue == "LOAD~1" && (addressOffset = 1)) || + (operatorValue == "LOAD~2" && (addressOffset = 2)) || + (operatorValue == "LOAD~3" && (addressOffset = 3))) + && paramCount >= 2 + ) { + std::vector data; + for (auto it = declaration.tokens.begin() + offset + 1; it != declaration.tokens.end(); ++it) { + data.emplace_back(it->getNumericValue()); + } + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, 1, data); + } else if ( + ((operatorValue == "LOAD_DIRECT") || (operatorValue == "LOAD_DIRECT~1" && (addressOffset = 1)) || + (operatorValue == "LOAD_DIRECT~2" && (addressOffset = 2)) || + (operatorValue == "LOAD_DIRECT~3" && (addressOffset = 3))) + && paramCount >= 2 + ) { + std::vector data; + for (auto it = declaration.tokens.begin() + offset + 1; it != declaration.tokens.end(); ++it) { + data.emplace_back(it->getNumericValue()); + } + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, 0, data); + } + + //TODO INIT + + else if ( + ((operatorValue == "AND") || (operatorValue == "AND~1" && (addressOffset = 1)) || + (operatorValue == "AND~2" && (addressOffset = 2)) || (operatorValue == "AND~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::AND, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::AND, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "OR") || (operatorValue == "OR~1" && (addressOffset = 1)) || + (operatorValue == "OR~2" && (addressOffset = 2)) || (operatorValue == "OR~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::OR, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::OR, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "ADD") || (operatorValue == "ADD~1" && (addressOffset = 1)) || + (operatorValue == "ADD~2" && (addressOffset = 2)) || (operatorValue == "ADD~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::ADD, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::ADD, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "SUB") || (operatorValue == "SUB~1" && (addressOffset = 1)) || + (operatorValue == "SUB~2" && (addressOffset = 2)) || (operatorValue == "SUB~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::SUB, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::SUB, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "LSHIFT") || (operatorValue == "LSHIFT~1" && (addressOffset = 1)) || + (operatorValue == "LSHIFT~2" && (addressOffset = 2)) || + (operatorValue == "LSHIFT~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::LSHIFT, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::LSHIFT, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "RSHIFT") || (operatorValue == "RSHIFT~1" && (addressOffset = 1)) || + (operatorValue == "RSHIFT~2" && (addressOffset = 2)) || + (operatorValue == "RSHIFT~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::RSHIFT, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::RSHIFT, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "ARSHIFT") || (operatorValue == "ARSHIFT~1" && (addressOffset = 1)) || + (operatorValue == "ARSHIFT~2" && (addressOffset = 2)) || + (operatorValue == "ARSHIFT~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + if (declaration.tokens.at(offset + 2).getType() == Token::Type::Immediate) { + return std::make_unique(Calc::Operation::ARSHIFT, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else { + return std::make_unique(Calc::Operation::ARSHIFT, addressOffset, + declaration.tokens.at(offset).getNumericValue(), + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } + } else if ( + ((operatorValue == "BEQ") || (operatorValue == "BEQ~1" && (addressOffset = 1)) || + (operatorValue == "BEQ~2" && (addressOffset = 2)) || (operatorValue == "BEQ~3" && (addressOffset = 3))) + && paramCount >= 4 + ) { + + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, 1, + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue(), + declaration.tokens.at(offset + 3).getNumericValue()); + } else if ( + ((operatorValue == "BNE") || (operatorValue == "BNE~1" && (addressOffset = 1)) || + (operatorValue == "BNE~2" && (addressOffset = 2)) || (operatorValue == "BNE~3" && (addressOffset = 3))) + && paramCount >= 4 + ) { + + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, 0, + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue(), + declaration.tokens.at(offset + 3).getNumericValue()); + } else if ( + ((operatorValue == "PEQ") || (operatorValue == "PEQ~1" && (addressOffset = 1)) || + (operatorValue == "PEQ~2" && (addressOffset = 2)) || (operatorValue == "PEQ~3" && (addressOffset = 3))) + && paramCount >= 6 + ) { + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, 1, + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue(), + declaration.tokens.at(offset + 3).getNumericValue(), + declaration.tokens.at(offset + 4).getNumericValue(), + declaration.tokens.at(offset + 5).getNumericValue()); + } else if ( + ((operatorValue == "PNE") || (operatorValue == "PNE~1" && (addressOffset = 1)) || + (operatorValue == "PNE~2" && (addressOffset = 2)) || (operatorValue == "PNE~3" && (addressOffset = 3))) + && paramCount >= 6 + ) { + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, 1, + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue(), + declaration.tokens.at(offset + 3).getNumericValue(), + declaration.tokens.at(offset + 4).getNumericValue(), + declaration.tokens.at(offset + 5).getNumericValue()); + } else if ( + ((operatorValue == "LOOP") || (operatorValue == "LOOP~1" && (addressOffset = 1)) || + (operatorValue == "LOOP~2" && (addressOffset = 2)) || + (operatorValue == "LOOP~3" && (addressOffset = 3))) + && paramCount >= 1 + ) { + return std::make_unique( + 0, + declaration.tokens.at(offset).getNumericValue()); + } else if ( + ((operatorValue == "LOOPB") || (operatorValue == "LOOPB~1" && (addressOffset = 1)) || + (operatorValue == "LOOPB~2" && (addressOffset = 2)) || + (operatorValue == "LOOPB~3" && (addressOffset = 3))) + && paramCount >= 1 + ) { + return std::make_unique( + 1, + declaration.tokens.at(offset).getNumericValue()); + } else if ( + ((operatorValue == "CALL") || (operatorValue == "CALL~1" && (addressOffset = 1)) || + (operatorValue == "CALL~2" && (addressOffset = 2)) || + (operatorValue == "CALL~3" && (addressOffset = 3))) + && paramCount >= 1 + ) { + + + if (declaration.tokens.at(offset).getType() == Token::Type::CodeLocation || + declaration.tokens.at(offset).getType() == Token::Type::CodeLabel) { + return std::make_unique( + declaration.tokens.at(offset).getNumericValue()); + } else { + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}); + } + } else if ( + ((operatorValue == "SET") || (operatorValue == "SET~1" && (addressOffset = 1)) || + (operatorValue == "SET~2" && (addressOffset = 2)) || (operatorValue == "SET~3" && (addressOffset = 3))) + && paramCount >= 3 + ) { + + return std::make_unique( + AddressWithOffset{declaration.tokens.at(offset).getNumericValue(), addressOffset}, + declaration.tokens.at(offset + 1).getNumericValue(), + declaration.tokens.at(offset + 2).getNumericValue()); + } else if (operatorValue == "WAIT" && paramCount >= 1) { + return std::make_unique(declaration.tokens.at(offset).getNumericValue()); + } else if (operatorValue == "END") { + return std::make_unique(); + } + + return nullptr; + } +} + diff --git a/src/instructions/Instruction.h b/src/instructions/Instruction.h new file mode 100644 index 0000000..d308476 --- /dev/null +++ b/src/instructions/Instruction.h @@ -0,0 +1,80 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include + +#include "AddressOffset.h" + +class Declaration; + +namespace Instruction { + + class Instruction { + protected: + uint32_t _address{}; + uint32_t _endAddress{}; + public: + + enum class CommandOp : uint8_t { + WRITE = 0b00000000, + COPY = 0b01000000, + LOAD = 0b11000000, + INIT = 0b11001000, + CALC = 0b10000000, + CALC_IMM = 0b10100000, + BRANCH = 0b11010000, + POLL = 0b11011000, + LOOP = 0b11100000, + JUMP = 0b11101000, + RETURN = 0b11110000, + SET = 0b11111000, + WAIT = 0xFE, + END = 0xFF + }; + + static std::unique_ptr getCommandForDeclaration(const Declaration &declaration); + + virtual std::vector toBytes() const = 0; + + virtual CommandOp getCommand() const = 0; + + uint32_t getAddress() const { + return _address; + } + + uint32_t getEndAddress() const { + return _endAddress; + } + + }; +}; diff --git a/src/instructions/Jump.cpp b/src/instructions/Jump.cpp new file mode 100644 index 0000000..06ce96b --- /dev/null +++ b/src/instructions/Jump.cpp @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Jump.h" + +std::vector Instruction::Jump::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand()); + + bytes.emplace_back((jumpAddress >> 16) & 0xFF); + bytes.emplace_back((jumpAddress >> 8) & 0xFF); + bytes.emplace_back(jumpAddress & 0xFF); + + return bytes; +} + diff --git a/src/instructions/Jump.h b/src/instructions/Jump.h new file mode 100644 index 0000000..91c8afe --- /dev/null +++ b/src/instructions/Jump.h @@ -0,0 +1,51 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Jump : public Instruction { + public: + Jump() { + + } + + Jump(uint32_t jumpAddress) : jumpAddress(jumpAddress) {} + + CommandOp getCommand() const override { + return CommandOp::JUMP; + }; + + + std::vector toBytes() const override; + + + uint32_t jumpAddress; + }; +} \ No newline at end of file diff --git a/src/instructions/Load.cpp b/src/instructions/Load.cpp new file mode 100644 index 0000000..9860afe --- /dev/null +++ b/src/instructions/Load.cpp @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Load.h" + +std::vector Instruction::Load::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | (increment << 2) | address.offset); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((data.size() >> 16) & 0xFF); + bytes.emplace_back((data.size() >> 8) & 0xFF); + bytes.emplace_back(data.size() & 0xFF); + + for (auto d : data) { + bytes.emplace_back((d >> 24) & 0xFF); + bytes.emplace_back((d >> 16) & 0xFF); + bytes.emplace_back((d >> 8) & 0xFF); + bytes.emplace_back(d & 0xFF); + } + + return bytes; +} diff --git a/src/instructions/Load.h b/src/instructions/Load.h new file mode 100644 index 0000000..d6ed452 --- /dev/null +++ b/src/instructions/Load.h @@ -0,0 +1,58 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include + +#include "Instruction.h" + +namespace Instruction { + class Load : public Instruction { + public: + Load() { + + } + + Load(const AddressWithOffset &address, uint8_t increment, std::vector data) : address(address), + increment( + increment), + data(std::move(data)) {} + + CommandOp getCommand() const override { + return CommandOp::LOAD; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset address; + uint8_t increment; + std::vector data; + }; +} \ No newline at end of file diff --git a/src/instructions/Loop.cpp b/src/instructions/Loop.cpp new file mode 100644 index 0000000..1d7ccd5 --- /dev/null +++ b/src/instructions/Loop.cpp @@ -0,0 +1,40 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Loop.h" + +std::vector Instruction::Loop::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | counter); + + bytes.emplace_back((jumpAddress >> 16) & 0xFF); + bytes.emplace_back((jumpAddress >> 8) & 0xFF); + bytes.emplace_back(jumpAddress & 0xFF); + + return bytes; +} diff --git a/src/instructions/Loop.h b/src/instructions/Loop.h new file mode 100644 index 0000000..e39428d --- /dev/null +++ b/src/instructions/Loop.h @@ -0,0 +1,52 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Loop : public Instruction { + public: + Loop() { + + } + + Loop(uint8_t counter, uint32_t jumpAddress) : counter(counter), jumpAddress(jumpAddress) {} + + CommandOp getCommand() const override { + return CommandOp::LOOP; + }; + + + std::vector toBytes() const override; + + + uint8_t counter; + uint32_t jumpAddress; + }; +} \ No newline at end of file diff --git a/src/instructions/Poll.cpp b/src/instructions/Poll.cpp new file mode 100644 index 0000000..492756d --- /dev/null +++ b/src/instructions/Poll.cpp @@ -0,0 +1,64 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Poll.h" + +std::vector Instruction::Poll::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | (equality << 2) | address.offset); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + bytes.emplace_back((value >> 24) & 0xFF); + bytes.emplace_back((value >> 16) & 0xFF); + bytes.emplace_back((value >> 8) & 0xFF); + bytes.emplace_back(value & 0xFF); + + bytes.emplace_back((mask >> 24) & 0xFF); + bytes.emplace_back((mask >> 16) & 0xFF); + bytes.emplace_back((mask >> 8) & 0xFF); + bytes.emplace_back(mask & 0xFF); + + + bytes.emplace_back((maxRetry >> 8) & 0xFF); + bytes.emplace_back(maxRetry & 0xFF); + + + bytes.emplace_back((retryInterval >> 8) & 0xFF); + bytes.emplace_back(retryInterval & 0xFF); + + bytes.emplace_back(0x00); + + bytes.emplace_back((jumpAddress >> 16) & 0xFF); + bytes.emplace_back((jumpAddress >> 8) & 0xFF); + bytes.emplace_back(jumpAddress & 0xFF); + + return bytes; +} diff --git a/src/instructions/Poll.h b/src/instructions/Poll.h new file mode 100644 index 0000000..f7bec07 --- /dev/null +++ b/src/instructions/Poll.h @@ -0,0 +1,61 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Poll : public Instruction { + public: + Poll() { + + } + + Poll(const AddressWithOffset &address, uint8_t equality, uint32_t value, uint32_t mask, uint16_t maxRetry, + uint16_t retryInterval, uint32_t jumpAddress) : address(address), equality(equality), value(value), + mask(mask), maxRetry(maxRetry), + retryInterval(retryInterval), jumpAddress(jumpAddress) {} + + + CommandOp getCommand() const override { + return CommandOp::POLL; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset address; + uint8_t equality; + uint32_t value; + uint32_t mask; + uint16_t maxRetry; + uint16_t retryInterval; + uint32_t jumpAddress; + }; +} \ No newline at end of file diff --git a/src/instructions/Return.cpp b/src/instructions/Return.cpp new file mode 100644 index 0000000..3925313 --- /dev/null +++ b/src/instructions/Return.cpp @@ -0,0 +1,40 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Return.h" + +std::vector Instruction::Return::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | address.offset); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + return bytes; +} \ No newline at end of file diff --git a/src/instructions/Return.h b/src/instructions/Return.h new file mode 100644 index 0000000..ecbbe75 --- /dev/null +++ b/src/instructions/Return.h @@ -0,0 +1,51 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Return : public Instruction { + public: + Return() { + + } + + Return(const AddressWithOffset &address) : address(address) {} + + CommandOp getCommand() const override { + return CommandOp::RETURN; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset address; + }; +} \ No newline at end of file diff --git a/src/instructions/Set.cpp b/src/instructions/Set.cpp new file mode 100644 index 0000000..e157069 --- /dev/null +++ b/src/instructions/Set.cpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Set.h" + +std::vector Instruction::Set::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | address.offset); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + bytes.emplace_back((value >> 24) & 0xFF); + bytes.emplace_back((value >> 16) & 0xFF); + bytes.emplace_back((value >> 8) & 0xFF); + bytes.emplace_back(value & 0xFF); + + bytes.emplace_back((mask >> 24) & 0xFF); + bytes.emplace_back((mask >> 16) & 0xFF); + bytes.emplace_back((mask >> 8) & 0xFF); + bytes.emplace_back(mask & 0xFF); + + return bytes; +} diff --git a/src/instructions/Set.h b/src/instructions/Set.h new file mode 100644 index 0000000..ec19196 --- /dev/null +++ b/src/instructions/Set.h @@ -0,0 +1,54 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Set : public Instruction { + public: + Set() { + + } + + Set(const AddressWithOffset &address, uint32_t value, uint32_t mask) : address(address), value(value), + mask(mask) {} + + CommandOp getCommand() const override { + return CommandOp::SET; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset address; + uint32_t value; + uint32_t mask; + }; +} \ No newline at end of file diff --git a/src/instructions/Wait.cpp b/src/instructions/Wait.cpp new file mode 100644 index 0000000..5b83c9c --- /dev/null +++ b/src/instructions/Wait.cpp @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Wait.h" + +std::vector Instruction::Wait::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand()); + + bytes.emplace_back((time >> 16) & 0xFF); + bytes.emplace_back((time >> 8) & 0xFF); + bytes.emplace_back(time & 0xFF); + + return bytes; +} + diff --git a/src/instructions/Wait.h b/src/instructions/Wait.h new file mode 100644 index 0000000..1dffe6e --- /dev/null +++ b/src/instructions/Wait.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include "Instruction.h" + +namespace Instruction { + class Wait : public Instruction { + public: + Wait() { + + } + + Wait(uint32_t time) : time(time) { + + } + + CommandOp getCommand() const override { + return CommandOp::WAIT; + }; + + + std::vector toBytes() const override; + + + uint32_t time; + }; +} \ No newline at end of file diff --git a/src/instructions/Write.cpp b/src/instructions/Write.cpp new file mode 100644 index 0000000..33e1942 --- /dev/null +++ b/src/instructions/Write.cpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "Write.h" + +std::vector Instruction::Write::toBytes() const { + std::vector bytes; + + bytes.emplace_back((uint8_t) getCommand() | ((data.size() - 1) << 2) | address.address); + + bytes.emplace_back((address.address >> 16) & 0xFF); + bytes.emplace_back((address.address >> 8) & 0xFF); + bytes.emplace_back(address.address & 0xFF); + + for (auto d : data) { + bytes.emplace_back((d >> 24) & 0xFF); + bytes.emplace_back((d >> 16) & 0xFF); + bytes.emplace_back((d >> 8) & 0xFF); + bytes.emplace_back(d & 0xFF); + } + + return bytes; +} diff --git a/src/instructions/Write.h b/src/instructions/Write.h new file mode 100644 index 0000000..40ad27e --- /dev/null +++ b/src/instructions/Write.h @@ -0,0 +1,54 @@ +/***************************************************************************** + * Copyright (c) 2020, rrcc FM10K-Documentation Contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#pragma once + +#include + +#include "Instruction.h" + +namespace Instruction { + class Write : public Instruction { + public: + Write() { + + } + + Write(const AddressWithOffset &address, std::vector data) : address(address), data(std::move(data)) {} + + CommandOp getCommand() const override { + return CommandOp::WRITE; + }; + + + std::vector toBytes() const override; + + + AddressWithOffset address; + std::vector data; + }; +} \ No newline at end of file diff --git a/src/rrcas.cpp b/src/rrcas.cpp new file mode 100644 index 0000000..75866c4 --- /dev/null +++ b/src/rrcas.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include "Parser.h" +#include "Assembler.h" + +int main(int argc, char *argv[]) { + if (argc < 3) { + std::cout << "Usage: " << argv[0] << " code.asm output.bin\n"; + return 1; + } + + try { + + std::ifstream image(argv[1]); + if (image.is_open()) { + std::vector bytes; + int c; + while (!image.eof() && (c = image.get()) != EOF) { + bytes.push_back(c); + } + + + Parser parser(bytes); + /*for (auto& f : parser.getTree()){ + std::cout << f.label << ":\n"; + for (auto& d : f.declarations){ + if(!d.label.empty()){ + std::cout << " " << d.label << ":\n"; + } + std::cout << " "; + for (auto& t : d.tokens){ + switch (t.getType()) { + case Token::Type::Operator: + std::cout << t.getTextValue() << " "; + break; + case Token::Type::RegisterName: + case Token::Type::RegisterLocation: + case Token::Type::CodeLabel: + case Token::Type::CodeLocation: + case Token::Type::Immediate: + std::cout << t.getTextValue() << ", "; + break; + + case Token::Type::LocalLabel: + case Token::Type::Label: + break; + } + + } + std::cout << "\n"; + } + }*/ + + Assembler assembler(parser); + assembler.assemble(); + + std::ofstream patchedImage(argv[2]); + + if (patchedImage.is_open()) { + auto &result = assembler.getImage(); + for (auto c : result) { + patchedImage.put(c); + } + patchedImage.close(); + } + + } + } catch (const std::exception &e) { + std::cerr << e.what() << "\n"; + } + + + return 0; +}