M .gitignore => .gitignore +1 -0
@@ 12,6 12,7 @@ variables.asm
# build artifacts
*.o
*.d
+*.exp
a65
*.swp
M a65.c => a65.c +22 -1
@@ 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();
M a65.h => a65.h +4 -0
@@ 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,
M a65util.c => a65util.c +47 -9
@@ 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;
M a65util.h => a65util.h +17 -0
@@ 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 */