A portable 6502 assembler written in C++
I wanted to make a 6502 IDE for the M5Stack Cardputer (an ESP32 based computer), but I couldn’t find an assembler that didn’t rely on the underlying operating system (which the Cardputer doesn’t have) so I’m making my own! I’m hoping to have a 6502 assembler contained in a single file (well, two files including the .h) while using minimal standard libraries (hopefully only stdio for sprintf, stdlib for malloc, and regex)
To test:
test/
make main
./main
To use in your own project: (DON’T DO IT YET, THIS ISN’T FINISHED)src/6502pasm.h
and src/6502pasm.cpp
into your projectAssembler()
classThis is the class that contains the assembler. It has:
std::vector<std::string> input_lines
: A list of lines, each line has only one thing:
.org $0800
)cool_label:
)lda #$05
);
is ignored)std::vector<unsigned char> output_bytes
: A list of bytes as the assembled codestd::vector<Label> labels
: A list of labels that were foundstd::vector<Macro> macros
: A list of macros that were foundint assemble()
: Assembles the input_lines
into the output_bytes
. Returns 0 if successful, 1 if not.#include "6502pasm.h"
int main() {
Assembler assembler = Assembler();
// Loads some simple stuff into input_lines
assembler.input_lines.push_back(std::string(".org $0800"));
assembler.input_lines.push_back(std::string(".macro addr $05"));
assembler.input_lines.push_back(std::string("main:"));
assembler.input_lines.push_back(std::string(" lda #$2e ; comment"));
assembler.input_lines.push_back(std::string(" LDX $04 ; capital mnemonic"));
assembler.input_lines.push_back(std::string(" ldy %addr ; macro"));
assembler.input_lines.push_back(std::string(" jmp main ; uses a label"));
// Assemble it
assembler.assemble();
// Output it
printf("Output hex (%d bytes):\n",assembler.output_bytes.size());
for (int i=0;i<assembler.output_bytes.size();i++) {
if (i%8==0)
printf(" %02x: ",i);
printf("%02x ",assembler.output_bytes[i]);
if (i%8==7)
printf("\n");
}
printf("\n");
printf("Labels (%d labels):\n",assembler.labels.size());
for (Label l : assembler.labels) {
printf(" %s @ 0x%04x\n",l.name.c_str(),l.location);
}
printf("Macros (%d macros):\n",assembler.macros.size());
for (Macro m : assembler.macros) {
printf(" %s = '%s'\n",m.name.c_str(),m.text.c_str());
}
return 0;
}
You can also look at test/main.cpp