DataHoarder
835c84c944
Some checks reported errors
continuous-integration/drone/push Build was killed
* Stack redesigned to have a Stack pointer and Frame pointer, and restoration of such for ease of access * Can now directly add parameters to RET for setting RRET * PUT, GET (and immediate versions) ops have been added to interact with stack offsets without pushing/popping * New PUSH op to push values onto stack, and PushGroup optimized multiple value set * FastCall now uses optimized PushGroup and minimizes amount of PUSH calls
125 lines
4.8 KiB
C++
125 lines
4.8 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <cstring>
|
|
#include "Parser.h"
|
|
#include "Assembler.h"
|
|
#include "instructions/virtual/Stack.h"
|
|
#include "EmbeddedResource.h"
|
|
|
|
#define xstr(s) __str(s)
|
|
#define __str(s) #s
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc == 2 && strcmp(argv[1], "version") == 0){
|
|
std::cout << xstr(RRCC_VERSION) << "\n";
|
|
return 0;
|
|
} else if (argc < 3) {
|
|
std::cout << "rrc-as " << xstr(RRCC_VERSION) << "\n";
|
|
std::cout << "Usage: " << argv[0] << " code.asm [code2.asm ...] output.bin\n";
|
|
return 1;
|
|
}
|
|
|
|
try {
|
|
|
|
Linker linker;
|
|
|
|
std::vector<EmbeddedResource> embeddedResources = {
|
|
LOAD_RESOURCE(asm_registers_asm),
|
|
LOAD_RESOURCE(asm_config_asm),
|
|
LOAD_RESOURCE(asm_api_asm),
|
|
LOAD_RESOURCE(asm_stdlib_asm)
|
|
};
|
|
|
|
Instruction::Instruction::addDefaultOperators();
|
|
|
|
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)});
|
|
linker.addVariable("rrcc_FRAME_POINTER", {Token(Token::Type::RegisterLocation,
|
|
std::to_string(Instruction::Stack::frameOffsetRegisterAddress),
|
|
Instruction::Stack::frameOffsetRegisterAddress)});
|
|
for (uint32_t i = Instruction::Stack::stackRegisterEnd; i <= Instruction::Stack::stackRegisterStart; ++i){
|
|
linker.addReservation(i, "rrc_STACK_RESERVED_" + std::to_string(i));
|
|
}
|
|
|
|
for (auto &r : embeddedResources) {
|
|
std::vector<uint8_t> bytes(r.begin(), r.end());
|
|
Parser parser(bytes, linker.getVariables(), linker.getReservations());
|
|
parser.parse();
|
|
linker.addFromParser(parser);
|
|
}
|
|
|
|
for (int inputIndex = 1; inputIndex < (argc - 1); ++inputIndex) {
|
|
try {
|
|
std::cout << "Parsing file " << argv[inputIndex] << "\n";
|
|
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);
|
|
}
|
|
Parser parser(bytes, linker.getVariables(), linker.getReservations());
|
|
parser.parse();
|
|
linker.addFromParser(parser);
|
|
} else {
|
|
throw std::runtime_error("Could not open " + std::string(argv[inputIndex]));
|
|
}
|
|
}catch (const std::exception& e){
|
|
std::cerr << "Exception: " << e.what() << " on input file " << argv[inputIndex] << "\n";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//Load base init
|
|
auto res = LOAD_RESOURCE(asm_init_asm);
|
|
std::vector<uint8_t> bytes(res.begin(), res.end());
|
|
Parser parser(bytes, linker.getVariables(), linker.getReservations());
|
|
parser.parse();
|
|
linker.addFromParser(parser);
|
|
|
|
Assembler assembler(linker);
|
|
|
|
std::cout << "Assembly start\n";
|
|
|
|
Assembler::ImageConfig config;
|
|
|
|
config.header.baseAddress = linker.getIntegerConstant("rrcc_BASE_ADDRESS", 0x080000, false);
|
|
config.header.spiTransferMode = linker.getIntegerConstant("rrcc_SPI_TRANSFER_MODE", 0, false);
|
|
config.header.spiTransferSpeed = linker.getIntegerConstant("rrcc_SPI_TRANSFER_SPEED", 7, false);
|
|
config.buildVersion = linker.getIntegerConstant("rrcc_IMAGE_VERSION", 0, false);
|
|
|
|
std::stringstream s;
|
|
s << "Image generated with rrc-as " << xstr(RRCC_VERSION) << ". EEPROM Image Version: 0x" << std::hex << std::setw(4) << std::setfill('0') << config.buildVersion;
|
|
config.buildSignature = s.str();
|
|
|
|
auto entrypointName = linker.getTextConstant("rrcc_ENTRYPOINT", "", true);
|
|
|
|
assembler.assemble(entrypointName, config);
|
|
|
|
std::cout << "Assembly done\n";
|
|
|
|
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";
|
|
return 1;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|