From 53836cabe3ecb4efcda698b98b50499c80e380ad Mon Sep 17 00:00:00 2001 From: g1n Date: Thu, 14 Oct 2021 11:30:45 +0300 Subject: [PATCH] Initial commit --- README.org | 15 +++++++ src/.gitignore | 1 + src/6502.c | 14 ++++++ src/6502.h | 9 ++++ src/Makefile | 18 ++++++++ src/main.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/test.asm | 3 ++ tests/test.bin | 1 + 8 files changed, 176 insertions(+) create mode 100644 README.org create mode 100644 src/.gitignore create mode 100644 src/6502.c create mode 100644 src/6502.h create mode 100644 src/Makefile create mode 100644 src/main.c create mode 100644 tests/test.asm create mode 100644 tests/test.bin diff --git a/README.org b/README.org new file mode 100644 index 0000000..b8a9bc3 --- /dev/null +++ b/README.org @@ -0,0 +1,15 @@ +#+TITLE: GRU assembler + +GRU gasm - yet another assembler + +** Supported platforms + + - 6502 + +** How to build + - cd src + - make + - now you should see `gasm` executable + +** How to use + - run your executable with asm file as argument and with -o flag for output filename diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..380f918 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +gasm diff --git a/src/6502.c b/src/6502.c new file mode 100644 index 0000000..eff29a2 --- /dev/null +++ b/src/6502.c @@ -0,0 +1,14 @@ +#include +#include "6502.h" + +void inx(FILE *outfile) { + fwrite(INX, 1, 1, outfile); +} + +void iny(FILE *outfile) { + fwrite(INY, 1, 1, outfile); +} + +void nop(FILE *outfile) { + fwrite(NOP, 1, 1, outfile); +} diff --git a/src/6502.h b/src/6502.h new file mode 100644 index 0000000..edf1f67 --- /dev/null +++ b/src/6502.h @@ -0,0 +1,9 @@ +#define INX "\xE8" +#define INY "\xC8" + +#define NOP "\xEA" + +void inx(FILE *outfile); +void iny(FILE *outfile); + +void nop(FILE *outfile); diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..d518cee --- /dev/null +++ b/src/Makefile @@ -0,0 +1,18 @@ +CC = gcc +CFLAGS= -O2 -Wall -Wextra +LIBS = +LFLAGS= + +SRCFILES= main.c 6502.c +OBJFILES= gasm + +.PHONY: all clean + +all: main + +main: + $(CC) $(CFLAGS) $(SRCFILES) -o $(OBJFILES) +test: + ./gasm ../tests/test.asm ../tests/test.bin + xxd ../tests/test.bin + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..965235a --- /dev/null +++ b/src/main.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include "6502.h" + +char *format; +char lexed_buf[512][128][128]; +void lexer(FILE* infile) { // FIXME + char str[100]; + int line_index = 0; + while (fgets(str, 100, infile) != NULL){ + int word_index = 0; + int char_index = 0; // FIXME + for (size_t i = 0; i <= strlen(str); i++) { + if (str[i] != ' ' && str[i] != '\n') { + lexed_buf[line_index][word_index][char_index] = str[i]; + char_index++; + } else if (str[i] == ' ') { + word_index++; + } else if (str[i] == '\n') { + line_index++; + } + } + } +} + +void parser(char lexed_buf[512][128][128], FILE *outfile) { // outfile is needed to add it as argument to command functions + // TODO + for (int i = 0; i <= 512; i++) { + // Parsing lines + for (int j = 0; j <= 128; j++) { + if (lexed_buf[i][j] == NULL) + break; + else if (lexed_buf[i][j][0] == '\0') + break; + if (!strcmp(lexed_buf[i][j], "NOP")) { + nop(outfile); + } else if (!strcmp(lexed_buf[i][j], "INX")) { + inx(outfile); + } else if (!strcmp(lexed_buf[i][j], "INY")) { + iny(outfile); + } else { + printf("Unrecognized command: %s\n", lexed_buf[i][j]); + break; + } + } + } + return; +} + +void usage() { + printf("%s - GRU Assembler\n", "gasm"); + printf("Usage: %s [OPTIONS] [--] filename \n", "gasm"); + printf(" %s -v\n", "gasm"); + printf("Options:\n"); + printf("\n"); + printf(" --help display this message\n"); + printf(" -o outfile write output to file\n"); + // TODO: add more flags +} + +int main(int argc, char *argv[]){ + char *infilename = NULL; + char *outfilename = NULL; + if (argc == 1) { + usage(); + return 0; + } else if (argc >= 2) { + for (int i = 1; i <= argc; i++) { + if (argv[i][0] == '-') { + char *arg = argv[i]; + argv[i]++; + if(argv[i][0] == '-') + argv[i]++; + if (!strcmp(argv[i], "o")) { + outfilename = argv[i+1]; + i+=2; // To skip next argument + } else if (!strcmp(argv[i], "help")) { + usage(); + return 0; + } else { + printf("Unknown argument: %s\n", arg); + return 1; + } + } else { + infilename = argv[i]; + } + } + } + if (infilename == NULL) { + printf("No input file\n"); + } else if (outfilename == NULL) { + printf("No out file\n"); + } + FILE *infile = fopen(infilename, "r"); + FILE *outfile = fopen(outfilename, "w"); + + if (infile == NULL) { + printf("Failed to open input file\n"); + return 1; + } + if (outfile == NULL) { + printf("Failed to open out file\n"); + return 1; + } + + lexer(infile); + + parser(lexed_buf, outfile); + + fclose(infile); + fclose(outfile); + + return 0; +} diff --git a/tests/test.asm b/tests/test.asm new file mode 100644 index 0000000..f155b7a --- /dev/null +++ b/tests/test.asm @@ -0,0 +1,3 @@ +NOP +INX +INY diff --git a/tests/test.bin b/tests/test.bin new file mode 100644 index 0000000..f681f96 --- /dev/null +++ b/tests/test.bin @@ -0,0 +1 @@ +يوب \ No newline at end of file