- Added Linker and multiple file assembly support.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Added asm/registers.asm and asm/api.asm with some used registers on the platform - Added embedded resources into build
This commit is contained in:
parent
a824385ec4
commit
d9094e7d83
|
@ -3,6 +3,26 @@ project(rrcc)
|
|||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
# Compilation step for static resources
|
||||
FUNCTION(ADD_RESOURCES out_var)
|
||||
SET(result)
|
||||
FOREACH(in_f ${ARGN})
|
||||
FILE(RELATIVE_PATH src_f ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${in_f})
|
||||
SET(out_f "${PROJECT_BINARY_DIR}/${in_f}.o")
|
||||
get_filename_component(out_d ${out_f} DIRECTORY)
|
||||
FILE(MAKE_DIRECTORY ${out_d})
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${out_f}
|
||||
COMMAND ld --relocatable --format binary --output ${out_f} ${src_f}
|
||||
DEPENDS ${in_f}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Embedding object ${src_f} into ${out_f}"
|
||||
VERBATIM
|
||||
)
|
||||
LIST(APPEND result ${out_f})
|
||||
ENDFOREACH()
|
||||
SET(${out_var} "${result}" PARENT_SCOPE)
|
||||
ENDFUNCTION()
|
||||
|
||||
set(SOURCE_FILES
|
||||
|
||||
src/instructions/AddressOffset.h
|
||||
|
@ -28,6 +48,11 @@ set(SOURCE_FILES
|
|||
src/Token.cpp src/Token.h
|
||||
src/Declaration.cpp src/Declaration.h
|
||||
src/Function.cpp src/Function.h
|
||||
src/Assembler.cpp src/Assembler.h)
|
||||
src/Assembler.cpp src/Assembler.h src/Linker.cpp src/Linker.h src/EmbeddedResource.h)
|
||||
|
||||
add_executable(rrc-as src/rrcas.cpp ${SOURCE_FILES})
|
||||
ADD_RESOURCES(embeddedResources
|
||||
asm/registers.asm
|
||||
asm/api.asm
|
||||
)
|
||||
|
||||
add_executable(rrc-as src/rrcas.cpp ${SOURCE_FILES} ${embeddedResources})
|
|
@ -19,4 +19,10 @@ NOTE: **This is a Work In Progress project**
|
|||
Assembler, kind-of 2-Pass. Quite loose token syntax defined in [Token.h](src/Token.h)
|
||||
|
||||
### Usage
|
||||
* `$ ./rrc-as code.asm output.bin`
|
||||
* `$ ./rrc-as code.asm [code2.asm ...] output.bin`
|
||||
* Multiple asm files can be specified. They are interpreted from first in arguments to last.
|
||||
* You can call functions across files, as they will be linked together.
|
||||
* Directive resolution occurs at parsing time, so while you can override values it does not affect previously parsed files.
|
||||
* Directives like `.constant` are passed to the next files.
|
||||
* These files will be automatically included in front every time:
|
||||
* *[asm/registers.asm](asm/registers.asm)*
|
51
asm/api.asm
Normal file
51
asm/api.asm
Normal file
|
@ -0,0 +1,51 @@
|
|||
; Definition of registers found on FM10000 official images for comunication back with driver/manager
|
||||
; Based on Intel datasheet and BSD-3 code.
|
||||
|
||||
|
||||
.constant api_SPI_LOCK_STATE, %0x800
|
||||
.constant api_PCIE_SBUS_LOCK_STATE, %0x801
|
||||
.constant api_SOFT_RESET_LOCK_STATE, %0x802
|
||||
|
||||
.constant api_RECOVERY_STATUS_VECTOR, %0x803
|
||||
|
||||
.constant api_PEP_MAC_BASE, %0x80a
|
||||
.constant api_CUSTOM_MAC_BASE, %0x864
|
||||
|
||||
.constant api_BSM_STATUS, %0x990
|
||||
.constant api_EEPROM_IMAGE_VERSION, %0x991
|
||||
.constant api_MASTER_FW_VERSION, %0x992
|
||||
.constant api_SERDES_FW_VERSION, %0x993
|
||||
.constant api_SERDES_STATUS_1, %0x994
|
||||
.constant api_SERDES_STATUS_2, %0x995
|
||||
.constant api_SERDES_STATUS_3, %0x996
|
||||
.constant api_SERDES_STATUS_4, %0x997
|
||||
.constant api_PCIE_MASTER_STATUS, %0x998
|
||||
.constant api_PCIE_SERDES_STATUS, %0x999
|
||||
|
||||
.constant api_DE_COLD_RESET_STATUS, %0x9ae
|
||||
.constant api_SBUS_RESET_STATUS, %0x9af
|
||||
.constant api_MEMORY_REPAIR_STATUS, %0x9b0
|
||||
.constant api_MEMORY_INIT_STATUS, %0x9b1
|
||||
.constant api_PCIE_PCS_DIS_STATUS, %0x9b2
|
||||
.constant api_PCIE_MASTER_FW_DL_STATUS, %0x9b3
|
||||
.constant api_PCIE_FW_CHECK_STATUS, %0x9b4
|
||||
.constant api_PCIE_SERDES_FW_DL_STATUS, %0x9b5
|
||||
.constant api_PCIE_SERDES_INIT_STATUS, %0x9b6
|
||||
.constant api_PCIE_PCS_EN_STATUS, %0x9b7
|
||||
.constant api_PCIE_DE_WARM_RESET_STATUS, %0x9b8
|
||||
.constant api_PCIE_ISR_STATUS_0, %0x9b9
|
||||
.constant api_PCIE_ISR_STATUS_1, %0x9ba
|
||||
.constant api_PCIE_ISR_STATUS_2, %0x9bb
|
||||
.constant api_PCIE_ISR_STATUS_3, %0x9bc
|
||||
.constant api_PCIE_ISR_STATUS_4, %0x9bd
|
||||
.constant api_PCIE_ISR_STATUS_5, %0x9be
|
||||
.constant api_PCIE_ISR_STATUS_6, %0x9bf
|
||||
.constant api_PCIE_ISR_STATUS_7, %0x9c0
|
||||
.constant api_PCIE_ISR_STATUS_8, %0x9c1
|
||||
.constant api_SERDES_OOR_STATUS_PASS_1, %0x9c2
|
||||
.constant api_SERDES_OOR_STATUS_PASS_2, %0x9c3
|
||||
.constant api_SW_LOCK_ERR_STATUS, %0x9c4
|
||||
.constant api_PCIE_EN_REFCLK_STATUS, %0x9c5
|
||||
.constant api_RE_RESET_MASK_STATUS_1, %0x9c6
|
||||
.constant api_RE_RESET_MASK_STATUS_2, %0x9c7
|
||||
.constant api_RE_RESET_ERR_STATUS, %0x9c8
|
83
asm/registers.asm
Normal file
83
asm/registers.asm
Normal file
|
@ -0,0 +1,83 @@
|
|||
; Definition of registers found on FM10000 ASIP
|
||||
; Based on Intel datasheet and BSD-3 code.
|
||||
|
||||
.constant FATAL_CODE, %0x0
|
||||
.constant LAST_FATAL_CODE, %0x1
|
||||
|
||||
.constant SOFT_RESET, %0x3
|
||||
.constant DEVICE_CFG, %0x4
|
||||
.constant RESET_CFG, %0x5
|
||||
.constant WATCHDOG_CFG, %0x6
|
||||
|
||||
.constant MGMT_SCRATCH_0, %0x8
|
||||
.constant MGMT_SCRATCH_1, %0x9
|
||||
|
||||
.constant VITAL_PRODUCT_DATA, %0x304
|
||||
|
||||
.constant GLOBAL_INTERRUPT_DETECT, %0x400
|
||||
|
||||
.constant INTERRUPT_MASK_BSM, %0x442
|
||||
|
||||
.constant CHIP_VERSION, %0x452
|
||||
|
||||
.constant BSM_SCRATCH_START, %0x800
|
||||
.constant BSM_SCRATCH_END, %0xBFF
|
||||
|
||||
.constant BSM_ARGS, %0x000C01
|
||||
|
||||
.constant BSM_ADDR_OFFSET_0, %0x000C04
|
||||
.constant BSM_ADDR_OFFSET_1, %0x000C05
|
||||
.constant BSM_ADDR_OFFSET_2, %0x000C06
|
||||
.constant BSM_ADDR_OFFSET_3, %0x000C07
|
||||
|
||||
.constant BSM_COUNTER_0, %0x000C08
|
||||
.constant BSM_COUNTER_1, %0x000C09
|
||||
|
||||
.constant BIST_CTRL_0, %0x000C10
|
||||
.constant BIST_CTRL_1, %0x000C11
|
||||
|
||||
.constant REI_CTRL, %0x000C12
|
||||
.constant REI_STAT, %0x000C13
|
||||
|
||||
.constant GPIO_CFG, %0x000C15
|
||||
.constant GPIO_DATA, %0x000C16
|
||||
.constant GPIO_IP, %0x000C17
|
||||
.constant GPIO_IM, %0x000C18
|
||||
.constant PLL_PCIE_CTRL, %0x2241
|
||||
.constant PLL_PCIE_STAT, %0x2242
|
||||
.constant SBUS_PCIE_CFG, %0x2243
|
||||
.constant SBUS_PCIE_COMMAND, %0x2244
|
||||
.constant SBUS_PCIE_REQUEST, %0x2245
|
||||
.constant SBUS_PCIE_RESPONSE, %0x2246
|
||||
.constant SBUS_PCIE_SPICO_IN, %0x2247
|
||||
.constant SBUS_PCIE_SPICO_OUT, %0x2248
|
||||
.constant SBUS_PCIE_IP, %0x2249
|
||||
.constant SBUS_PCIE_IM, %0x224a
|
||||
|
||||
.constant PCIE_XPLL_CTRL, %0x3000
|
||||
.constant PCIE_CLK_CTRL, %0x3001
|
||||
.constant PCIE_CLK_CTRL_2, %0x3002
|
||||
.constant PCIE_CLKMON_RATIO_CFG, %0x3003
|
||||
.constant PCIE_CLKMON_TOLERANCE_CFG, %0x3004
|
||||
.constant PCIE_CLKMON_DEADLINES_CFG, %0x3005
|
||||
.constant PCIE_CLK_STAT, %0x3006
|
||||
.constant PCIE_CLK_IP, %0x3007
|
||||
.constant PCIE_CLK_IM, %0x3008
|
||||
.constant PCIE_WARM_RESET_DELAY, %0x3009
|
||||
|
||||
.constant PORTS_MGMT_BASE_ADDRESS, %0xE8000
|
||||
.constant PLL_EPL_CTRL, %0xE8000
|
||||
.constant PLL_EPL_STAT, %0xE8001
|
||||
.constant PLL_FABRIC_CTRL, %0xE8002
|
||||
.constant PLL_FABRIC_STAT, %0xE8003
|
||||
.constant PLL_FABRIC_LOCK, %0xE8004
|
||||
.constant SBUS_EPL_CFG, %0xE8005
|
||||
.constant SBUS_EPL_COMMAND, %0xE8006
|
||||
.constant SBUS_EPL_REQUEST, %0xE8007
|
||||
.constant SBUS_EPL_RESPONSE, %0xE8008
|
||||
.constant SBUS_EPL_SPICO_IN, %0xE8009
|
||||
.constant SBUS_EPL_SPICO_OUT, %0xE800a
|
||||
.constant SBUS_EPL_IP, %0xE800b
|
||||
.constant SBUS_EPL_IM, %0xE800c
|
||||
|
||||
.constant PM_CLKOBS_CTRL, %0xE8012
|
|
@ -43,7 +43,7 @@ void Assembler::assemble(uint32_t baseAddress, uint32_t imageSize) {
|
|||
|
||||
|
||||
if (placementMode == FunctionPlacementMode::PlaceAll) {
|
||||
for (auto &f : parser.getTree()) {
|
||||
for (auto &f : linker.getTree()) {
|
||||
if (freeOffsetLocation == baseAddress && f.label != "entrypoint") {
|
||||
throw std::runtime_error("entrypoint not at start");
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ uint32_t Assembler::placeFunction(uint32_t base, const Function &function) {
|
|||
}
|
||||
|
||||
const Function *Assembler::getFunctionByLabel(const std::string &l) {
|
||||
for (auto &f : parser.getTree()) {
|
||||
for (auto &f : linker.getTree()) {
|
||||
if (f.label == l) {
|
||||
return &f;
|
||||
}
|
||||
|
|
|
@ -27,13 +27,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Parser.h"
|
||||
#include "Linker.h"
|
||||
#include "instructions/Instruction.h"
|
||||
|
||||
class Assembler {
|
||||
private:
|
||||
const Parser &parser;
|
||||
const Linker &linker;
|
||||
bool padEndFunction = true;
|
||||
std::vector<uint8_t> bytes;
|
||||
std::unordered_map<std::string, uint32_t> knownRegisters;
|
||||
|
@ -45,7 +44,7 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
Assembler(const Parser &parser) : parser(parser) {
|
||||
Assembler(const Linker &linker) : linker(linker) {
|
||||
|
||||
}
|
||||
|
||||
|
|
54
src/EmbeddedResource.h
Normal file
54
src/EmbeddedResource.h
Normal file
|
@ -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 <cstddef>
|
||||
|
||||
class EmbeddedResource {
|
||||
public:
|
||||
EmbeddedResource(const char *start, const char *end) : mData(start),
|
||||
mSize(end - start) {}
|
||||
|
||||
const char *const &data() const { return mData; }
|
||||
|
||||
const size_t &size() const { return mSize; }
|
||||
|
||||
const char *begin() const { return mData; }
|
||||
|
||||
const char *end() const { return mData + mSize; }
|
||||
|
||||
private:
|
||||
const char *mData;
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
#define LOAD_RESOURCE(x) ([]() { \
|
||||
extern const char _binary_##x##_start, _binary_##x##_end; \
|
||||
return EmbeddedResource(&_binary_##x##_start, &_binary_##x##_end); \
|
||||
})()
|
||||
|
51
src/Linker.cpp
Normal file
51
src/Linker.cpp
Normal file
|
@ -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 "Linker.h"
|
||||
|
||||
void Linker::addFromParser(const Parser &p) {
|
||||
for (auto &fn : p.getTree()) {
|
||||
addFunction(fn);
|
||||
}
|
||||
for (auto &v : p.getVariables()) {
|
||||
variables[v.first] = v.second;
|
||||
}
|
||||
}
|
||||
|
||||
void Linker::addFunction(const Function &f) {
|
||||
for (auto &fn : functions) {
|
||||
if (fn.label == f.label) {
|
||||
fn = f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
functions.push_back(f);
|
||||
}
|
||||
|
||||
void Linker::addVariable(const std::string &k, const std::vector<Token> &v) {
|
||||
variables[k] = v;
|
||||
}
|
54
src/Linker.h
Normal file
54
src/Linker.h
Normal file
|
@ -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 "Parser.h"
|
||||
|
||||
class Linker {
|
||||
std::vector<Function> functions;
|
||||
std::unordered_map<std::string, std::vector<Token>> variables;
|
||||
public:
|
||||
Linker() {
|
||||
|
||||
}
|
||||
|
||||
void addFunction(const Function &f);
|
||||
|
||||
void addVariable(const std::string &k, const std::vector<Token> &v);
|
||||
|
||||
void addFromParser(const Parser &p);
|
||||
|
||||
const std::vector<Function> &getTree() const {
|
||||
return functions;
|
||||
}
|
||||
|
||||
const auto &getVariables() const {
|
||||
return variables;
|
||||
}
|
||||
|
||||
};
|
|
@ -30,7 +30,6 @@
|
|||
void Parser::parse() {
|
||||
offset = 0;
|
||||
functions.clear();
|
||||
variables.clear();
|
||||
|
||||
std::string currentValue;
|
||||
uint8_t c;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
@ -94,8 +95,13 @@ class Parser {
|
|||
static bool isAlphaNumeric(const std::string &v);
|
||||
|
||||
public:
|
||||
Parser(const std::vector<uint8_t> &bytes, std::unordered_map<std::string, std::vector<Token>> variables) : bytes(
|
||||
bytes), variables(std::move(variables)) {
|
||||
|
||||
}
|
||||
|
||||
Parser(const std::vector<uint8_t> &bytes) : bytes(bytes) {
|
||||
parse();
|
||||
|
||||
}
|
||||
|
||||
void parse();
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
//End of Token: \n\t[space],;
|
||||
};
|
||||
|
||||
Token(const Token &) = default;
|
||||
|
||||
Token(Type type, std::string valueString, uint32_t valueImmediate = 0) : type(type), valueImmediate(valueImmediate),
|
||||
valueString(std::move(valueString)) {
|
||||
|
||||
|
|
|
@ -3,40 +3,65 @@
|
|||
#include <vector>
|
||||
#include "Parser.h"
|
||||
#include "Assembler.h"
|
||||
#include "instructions/virtual/Stack.h"
|
||||
#include "EmbeddedResource.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 3) {
|
||||
std::cout << "Usage: " << argv[0] << " code.asm output.bin\n";
|
||||
std::cout << "Usage: " << argv[0] << " code.asm [code2.asm ...] output.bin\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
std::ifstream image(argv[1]);
|
||||
if (image.is_open()) {
|
||||
std::vector<uint8_t> bytes;
|
||||
int c;
|
||||
while (!image.eof() && (c = image.get()) != EOF) {
|
||||
bytes.push_back(c);
|
||||
}
|
||||
Linker linker;
|
||||
|
||||
std::vector<EmbeddedResource> embeddedResources = {
|
||||
LOAD_RESOURCE(asm_registers_asm),
|
||||
LOAD_RESOURCE(asm_api_asm)
|
||||
};
|
||||
|
||||
Parser parser(bytes);
|
||||
linker.addVariable("rrcc_STACK_START",
|
||||
{Token(Token::Type::RegisterLocation, std::to_string(Instruction::Stack::stackRegisterStart),
|
||||
Instruction::Stack::stackRegisterStart)});
|
||||
linker.addVariable("rrcc_STACK_POINTER", {Token(Token::Type::RegisterLocation,
|
||||
std::to_string(Instruction::Stack::stackOffsetRegisterAddress),
|
||||
Instruction::Stack::stackOffsetRegisterAddress)});
|
||||
|
||||
for (auto &r : embeddedResources) {
|
||||
std::vector<uint8_t> bytes(r.begin(), r.end());
|
||||
Parser parser(bytes, linker.getVariables());
|
||||
parser.parse();
|
||||
linker.addFromParser(parser);
|
||||
}
|
||||
|
||||
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);
|
||||
for (int inputIndex = 1; inputIndex < (argc - 1); ++inputIndex) {
|
||||
std::ifstream image(argv[inputIndex]);
|
||||
if (image.is_open()) {
|
||||
std::vector<uint8_t> bytes;
|
||||
int c;
|
||||
while (!image.eof() && (c = image.get()) != EOF) {
|
||||
bytes.push_back(c);
|
||||
}
|
||||
patchedImage.close();
|
||||
Parser parser(bytes, linker.getVariables());
|
||||
parser.parse();
|
||||
linker.addFromParser(parser);
|
||||
} else {
|
||||
throw std::runtime_error("Could not open " + std::string(argv[inputIndex]));
|
||||
}
|
||||
}
|
||||
|
||||
Assembler assembler(linker);
|
||||
assembler.assemble();
|
||||
|
||||
std::ofstream patchedImage(argv[argc - 1]);
|
||||
|
||||
if (patchedImage.is_open()) {
|
||||
auto &result = assembler.getImage();
|
||||
for (auto c : result) {
|
||||
patchedImage.put(c);
|
||||
}
|
||||
patchedImage.close();
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Exception: " << e.what() << "\n";
|
||||
|
|
Loading…
Reference in a new issue