From eea8250745c79c47d614c691622d2b200994ea38 Mon Sep 17 00:00:00 2001 From: Nathan Misner Date: Thu, 2 Feb 2023 11:34:04 -0500 Subject: [PATCH] added the ability to generate export files from a build --- .gitignore | 1 + a65.c | 23 +++++++++++++++++++++- a65.h | 4 ++++ a65util.c | 56 +++++++++++++++++++++++++++++++++++++++++++++--------- a65util.h | 17 +++++++++++++++++ 5 files changed, 91 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index bd00de6..2a6009d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ variables.asm # build artifacts *.o *.d +*.exp a65 *.swp diff --git a/a65.c b/a65.c index fffc39a..122b971 100644 --- a/a65.c +++ b/a65.c @@ -77,6 +77,14 @@ int main(int argc, char **argv) { while (--argc > 0) { if (**++argv == '-') { switch (toupper(*++*argv)) { + case 'E': + if (!*++ * argv) { + if (!--argc) { warning(NOEXP); break; } + else ++argv; + } + eopen(*argv); + break; + case 'L': if (!*++*argv) { if (!--argc) { warning(NOLST); break; } @@ -130,7 +138,7 @@ int main(int argc, char **argv) { } } - fclose(filestk[0].fp); lclose(); bclose(); + fclose(filestk[0].fp); eclose(); lclose(); bclose(); if (errors) printf("%d Error(s)\n",errors); else printf("No Errors\n"); @@ -416,6 +424,19 @@ static void pseudo_op() { else error('L'); break; + case EXP: /* label export */ + do_label(); + if (pass == 2) { + if ((lex()->attr & TYPE) == VAL) { + if ((l = find_symbol(token.sval))) { + eputs(l); + } + else error('V'); + } + } + + break; + case IF: if (++ifsp == IFDEPTH) fatal_error(IFOFLOW); address = expr(); diff --git a/a65.h b/a65.h index 324e573..f387c16 100644 --- a/a65.h +++ b/a65.h @@ -48,12 +48,14 @@ all modules of the cross-assembler. #define ASMOPEN "Source File Did Not Open" #define ASMREAD "Error Reading Source File" +#define EXPOPEN "Export File Did Not Open" #define DSKFULL "Disk or Directory Full" #define FLOFLOW "File Stack Overflow" #define HEXOPEN "Object File Did Not Open" #define IFOFLOW "If Stack Overflow" #define LSTOPEN "Listing File Did Not Open" #define NOASM "No Source File Specified" +#define NOEXP "No Export File Specified" #define SYMBOLS "Too Many Symbols" /* The warning messages generated by the assembler: */ @@ -62,6 +64,7 @@ all modules of the cross-assembler. #define NOHEX "-o Option Ignored -- No File Name" #define NOLST "-l Option Ignored -- No File Name" #define TWOASM "Extra Source File Ignored" +#define TWOEXP "Extra Export File Ignored" #define TWOHEX "Extra Object File Ignored" #define TWOLST "Extra Listing File Ignored" @@ -90,6 +93,7 @@ typedef enum { END, ENDI, EQU, + EXP, IF, INCB, INCL, diff --git a/a65util.c b/a65util.c index 27c29f4..286c8e9 100644 --- a/a65util.c +++ b/a65util.c @@ -118,6 +118,7 @@ OPCODE *find_code(char *nam) { { PSEUDO + ISIF, ENDI, "ENDI" }, { TWOOP, 0x41, "EOR" }, { PSEUDO, EQU, "EQU" }, + { PSEUDO, EXP, "EXP" }, { PSEUDO + ISIF, IF, "IF" }, { INCOP, 0xe6, "INC" }, { PSEUDO, INCB, "INCB" }, @@ -216,16 +217,53 @@ static int ustrcmp(char *s, char *t) { return i; } +/* export file pointer */ +static FILE *export = NULL; + +/* Export file open routine. If an export file is already open, a */ +/* warning occurs. If the export file doesn't open correctly, a */ +/* fatal error occurs. If no export file is open, all calls to */ +/* eputs() and eclose() will produce fatal errors. */ + +void eopen(char *nam) { + if (export) warning(TWOEXP); + else if (!(export = fopen(nam, "w"))) fatal_error(EXPOPEN); + else { + fprintf(export, "; Autogenerated export file - do not modify!\n\n"); + if (ferror(export)) fatal_error(DSKFULL); + } +} + +/* Export file line output routine. This routine writes the value */ +/* of a single symbol to the currently open export file. If the export */ +/* file is not open, or the disk is full, a fatal error occurs. */ + +void eputs(SYMBOL *sym) { + if (export) { + fprintf(export, "%s\tequ\t$%X\n", sym->sname, sym->valu); + if (ferror(export)) fatal_error(DSKFULL); + } + else fatal_error(NOEXP); +} + +/* Export file close routine. */ +void eclose() { + if (export) { + fclose(export); + } +} + + /* Buffer storage for line listing routine. This allows the listing */ -/* output routines to do all operations without the main routine */ -/* having to fool with it. */ +/* output routines to do all operations without the main routine */ +/* having to fool with it. */ static FILE *list = NULL; /* Listing file open routine. If a listing file is already open, a */ -/* warning occurs. If the listing file doesn't open correctly, a */ -/* fatal error occurs. If no listing file is open, all calls to */ -/* lputs() and lclose() have no effect. */ +/* warning occurs. If the listing file doesn't open correctly, a */ +/* fatal error occurs. If no listing file is open, all calls to */ +/* lputs() and lclose() have no effect. */ void lopen(char *nam) { if (list) warning(TWOLST); @@ -233,10 +271,10 @@ void lopen(char *nam) { return; } -/* Listing file line output routine. This routine processes the */ +/* Listing file line output routine. This routine processes the */ /* source line saved by popc() and the output of the line assembler in */ -/* buffer obj into a line of the listing. If the disk fills up, a */ -/* fatal error occurs. */ +/* buffer obj into a line of the listing. If the disk fills up, a */ +/* fatal error occurs. */ void lputs() { SCRATCH int i, j; @@ -264,7 +302,7 @@ void lputs() { /* Listing file close routine. The symbol table is appended to the */ /* listing in alphabetic order by symbol name, and the listing file is */ -/* closed. If the disk fills up, a fatal error occurs. */ +/* closed. If the disk fills up, a fatal error occurs. */ static int col = 0; diff --git a/a65util.h b/a65util.h index c02c26d..01ebcc9 100644 --- a/a65util.h +++ b/a65util.h @@ -69,6 +69,23 @@ OPCODE *find_code(char *nam); OPCODE *find_operator(char *nam); +/* Export file open routine. If an export file is already open, a */ +/* warning occurs. If the export file doesn't open correctly, a */ +/* fatal error occurs. If no export file is open, all calls to */ +/* eputs() and eclose() will produce fatal errors. */ +void eopen(char *nam); + + +/* Export file line output routine. This routine writes the value */ +/* of a single symbol to the currently open export file. If the export */ +/* file is not open, or the disk is full, a fatal error occurs. */ +void eputs(SYMBOL *sym); + + +/* Export file close routine. */ +void eclose(); + + /* Listing file open routine. If a listing file is already open, a */ /* warning occurs. If the listing file doesn't open correctly, a */ /* fatal error occurs. If no listing file is open, all calls to */ -- 2.38.4