~ndiddy/a65

eea8250745c79c47d614c691622d2b200994ea38 — Nathan Misner a month ago 213237d
added the ability to generate export files from a build
5 files changed, 91 insertions(+), 10 deletions(-)

M .gitignore
M a65.c
M a65.h
M a65util.c
M a65util.h
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		*/