home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- /* #include <kernel.h> */
-
- #include "mselect.h" /*external selection of microprocessor symbol table*/
- #include "proto.h"
- #include "as.h"
- #include "structs.h"
- #include "glovars.h"
-
- void stable(struct nlist * ptr);
- void cross(struct nlist * point);
-
- /*
- * as --- cross assembler main program
- *
- * Note: Compile with define DEBUG for function module debug statements. Compile
- * with define DEBUG2 for version 2 debug statements only. Compile with
- * define IBM to use original, non- Amiga, non-MAC, non-UNIX fgets()
- * function. Amiga version will accept IBM generated source code but not the
- * other way around. Note added version (TER) 2.01 19 June 1989.
- */
-
- int
- main(int argc, char **argv)
- {
- char **np;
- char *i;
- int j = 0;
-
- fprintf(stderr, "Assembler release TER_2.0 version 2.09 - (c) Motorola (free ware)\n");
- fprintf(stderr, "Archimedes porting April 1993 Maurizio Ferrari - version 2.00\n");
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s [files] [-options]\n", argv[j]);
- fprintf(stderr, "Example: %s FILE1.ASM FILE2.ASM -o <Obj_name> -x -list <List_name> -cyc -p50 -crlf -nnf\n", argv[j]);
- exit(1);
- }
- Argv = argv;
- while ((*argv[j] != '-') && (j < argc)) {
- #ifdef DEBUG
- printf("%s\n", argv[j]);
- #endif
- j++;
- }
- N_files = j - 1;
- Lflag = 0;
- Cflag = 0;
- Sflag = 0;
- CREflag = 0;
- if (j < argc) {
- while (j < argc) {
- for (i = argv[j]; *i != 0; i++)
- if ((*i <= 'Z') && (*i >= 'A'))
- *i = *i + 32;
- if (strcmp(argv[j], "-list") == 0) {
- Lflag = 1;
- } else if (strcmp(argv[j], "-cyc") == 0)
- {Cflag = 1;}
- else if (strcmp(argv[j], "-sym") == 0)
- {Sflag = 1;}
- else if (strcmp(argv[j], "-x") == 0)
- {CREflag = 1;}
- else if (strcmp(argv[j], "-crlf") == 0) /* test for crlf option */
- {CRflag = 1;} /* add <CR><LF> to S record */
- /* ver TER_1.1 June 3, 1989 */
- else if (strcmp(argv[j], "-nnf") == 0) /* test for nnf option */
- {nfFlag = 0;} /* nfFlag=1 means number
- * INCLUDE separately. ver
- * TER_2.0 6/17/89 */
- else if (strcmp(argv[j], "-p") == 0) /* page every 50 lines */
- {Pflag50 = 1;
- PageLen = atoi(argv[++j]);} /* ver (TER) 2.01 19 Jun 89 */
- else if (strcmp(argv[j], "-o") == 0) {
- ObjFilePos = ++j;
- } else if (*argv[j]) {
- fprintf(stderr, "\nUnrecognized option '%s' on command line\n", argv[j]);
- fprintf(stderr, "Valid options are:");
- fprintf(stderr, " -list -cyc -sym -x -crlf -nnf -p <pages> -o <Obj name>\n\n");
- exit(1);
- }
- j++;
- }
- }
- if (ObjFilePos == 0)
- fatal("\nmust specify output file");
- /* errorInit(throwback,SourceFileName); */
- fwdinit(); /* forward ref init */
- initialize();
- root = NULL;
- Cfn = 0;
- np = argv;
- Line_num = 0; /* reset line number */
- Local_Line_num = 0; /* reset line number */
- while (++Cfn <= N_files)
- if ((Fd = fopen(*++np, "r")) == NULL) {
- fprintf(stderr, "as: can't open %s\n", *np);
- } else {
- errorInit(1, *np);
- make_pass();
- fclose(Fd);
- errorFinish();
- Local_Line_num = 0; /* reset line number */
- }
- if (Err_count == 0) {
- Pass++;
- re_init();
- Cfn = 0;
- np = argv;
- Line_num = 0;
- Local_Line_num = 0;
- FdCount = 0; /* Resets INCLUDE file nesting ver TER_2.0
- * 6/17/89 */
- while (++Cfn <= N_files)
- if ((Fd = fopen(*++np, "r")) != NULL) {
- fprintf(stderr, "\nAssembling %s\n", *np);
- errorInit(1, *np);
- make_pass();
- fclose(Fd);
- errorFinish();
- Local_Line_num = 0; /* reset Line_num for
- * throwback */
- }
- fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
- fprintf(stderr, "Error count = %d\n\n", Err_count); /* rel TER_2.0 */
- if (Sflag == 1) {
- fprintf(stderr, "Writing Symbols file\n");
- stable(root);
- fclose (Mapfil);
- }
- if (CREflag == 1) {
- fprintf(stderr, "Writing Xref file\n");
- cross(root);
- fclose (Xfil);
- }
- if (CRflag == 1)
- fprintf(Objfil, "S9030000FC%c\n", CR); /* ver TER_1.1 print w
- * <CR> */
- else
- fprintf(Objfil, "S9030000FC\n"); /* at least give a
- * decent ending */
- fclose(Objfil); /* close file correctly ver TER_1.1 */
- fclose(Listfil); /* close file */
- } else { /* just note errors, TER_2.0 */
- fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
- fprintf(stderr, "Error count = %d\n\n", Err_count);
- fclose(Listfil); /* close file */
- }
- fwd_done();
- errorFinish();
- exit(Err_count); /* neat for UNIX cuz can test return value in
- * script but on other systems like Amiga,
- * mostly just makes further script
- * statements fail if >10, else nothing.
- * Therefore, printed out byte count and
- * error level. ver (TER) 2.02 19 Jun 89 */
- }
-
- void
- initialize(void)
- {
- char c;
- char *leafname, *maproot, *xroot, *lroot;/*input file leaf and output names*/
- int i = 0;
-
- #ifdef DEBUG
- printf("Initializing\n");
- #endif
- Err_count = 0;
- Pc = 0;
- Pass = 1;
- Ctotal = 0;
- N_page = 0;
- Line[MAXBUF - 1] = NEWLINE;
- if (strlen(Argv[ObjFilePos]) > FILENAME_MAX)
- fatal("obj_file name too long ");
- Obj_name = (char *) malloc(strlen(Argv[ObjFilePos]));
- lroot = (char *) malloc(strlen(Argv[1]));
- maproot = (char *) malloc(strlen(Argv[1]));
- xroot = (char *) malloc(strlen(Argv[1]));
- if (Obj_name == NULL)
- fatal("Cannot allocate space for obj name");
- if (lroot == NULL)
- fatal("Cannot allocate space for list file name");
- if (maproot == NULL)
- fatal("Cannot allocate space for map file name");
- if (xroot == NULL)
- fatal("Cannot allocate space for xref file name");
- #ifdef DEBUG
- printf("%d, %d\n", strlen(Argv[ObjFilePos]), sizeof(char));
- printf("Oun =%s-\n", Obj_name);
-
- #endif
- do { /* copy -o <file name> into Obj_name */
- c = Obj_name[i] = Argv[ObjFilePos][i];
- i++;
- } while (c && (i < FILENAME_MAX));
-
- #ifdef DEBUG
- printf("Fwd =%s\n", Fwd_name);
- printf("Obj =%s\n", Obj_name);
- #endif
- Obj_name[--i] = EOS;
- printf ("S19 Obj file: %s\n", Obj_name);
- if ((Objfil = fopen(Obj_name, "w")) == NULL) {
- fatal("Can't create object file");
- }
-
- leafname = strrchr (Argv[1], '.');
- if (leafname == NULL)
- {fatal ("cannot decipher leafname: empty ?");}
-
- i=strlen(Argv[1]);
- do {
- i--;
- } while (Argv[1][i-1] != '.');
- do {
- i--;
- } while (Argv[1][i-1] != '.');
- if (Lflag)
- { strncpy(lroot, Argv[1], i-1);
- lroot[i-1] = EOS;
- lroot=strcat(lroot, ".l");
- lroot=strcat(lroot, leafname);
- printf ("Listing file: %s\n", lroot);
- if ((Listfil = fopen(lroot, "w")) == NULL) {
- fatal("Panic! Can't create listing file");
- }
- }
- if (Sflag)
- { strncpy(maproot, Argv[1], i-1);
- maproot[i-1] = EOS;
- maproot=strcat(maproot, ".m");
- maproot=strcat(maproot, leafname);
- printf ("Symbols file: %s\n", maproot);
- if ((Mapfil = fopen(maproot, "w")) == NULL) {
- fatal("Panic! Can't create symbols map file. Does 'm' dir exist?");
- }
- }
- if (CREflag)
- { strncpy(xroot, Argv[1], i-1);
- xroot[i-1] = EOS;
- xroot=strcat(xroot, ".x");
- xroot=strcat(xroot, leafname);
- printf ("Xref file : %s\n", xroot);
- if ((Xfil = fopen(xroot, "w")) == NULL) {
- fatal("Panic! Can't create xref file. Does 'x' dir exist?");
- }
- }
-
- localinit(); /* target machine specific init. */
- }
-
- void
- re_init(void)
- {
- #ifdef DEBUG
- printf("Reinitializing\n");
- #endif
- Pc = 0;
- E_total = 0;
- P_total = 0;
- Ctotal = 0;
- N_page = 0;
- fwdreinit();
- }
-
- void
- make_pass(void)
- {
- /*
- * #ifdef IBM char *fgets();
- *//* the original line */
- /* #else */
- /* char *FGETS(); *//* use own FGETS which is rewrite of lib function */
- /* such that it discards <CR> so can read code */
- /* generated on IBM */
- /* June 3, 1989 rev TER_1.1 */
- /* #endif */
-
- #ifdef DEBUG
- printf("Pass %d\n", Pass);
- #endif
- while (FGETS(Line, MAXBUF - 1, Fd) != (char *) NULL) { /* changed to FGETS */
- /* which does not pass on <CR> June 3, 1989 */
- /* rev TER_1.1 */
- Line_num++;
- Local_Line_num++;
- P_force = 0; /* No force unless bytes emitted */
- N_page = 0;
- if (parse_line())
- process();
- if (Pass == 2 && Lflag && !N_page)
- print_line();
- P_total = 0; /* reset byte count */
- Cycles = 0; /* and per instruction cycle count */
- }
- f_record();
- }
-
-
- /*
- * parse_line --- split input line into label, op and operand
- */
- int
- parse_line(void)
- {
- register char *ptrfrm = Line;
- register char *ptrto = Label;
- /* char *skip_white(); */
-
- if (*ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';')
- /* added check for ';' ver TER_1.1 */
- /* June 3, 1989 */
- return (0); /* a comment line */
-
- while (delim(*ptrfrm) == NO) /* parsing Label */
- *ptrto++ = *ptrfrm++;
- if (*--ptrto != ':')
- ptrto++; /* allow trailing : */
- *ptrto = EOS;
-
- ptrfrm = skip_white(ptrfrm);
- if (*ptrfrm == ';') { /* intercept comment after label, ver TER_2.0 */
- *Op = *Operand = EOS; /* comment, no Opcode or Operand */
- return (1);
- }
- ptrto = Op;
-
- while (delim(*ptrfrm) == NO) /* parsing Opcode */
- *ptrto++ = mapdn(*ptrfrm++);
- *ptrto = EOS;
-
- ptrfrm = skip_white(ptrfrm);
- if (*ptrfrm == ';') { /* intercept comment, ver TER_2.0 */
- *Operand = EOS; /* comment, no Operand */
- return (1);
- }
- ptrto = Operand;
- while ((*ptrfrm != NEWLINE) && ((*ptrfrm != ';')||(*Op != 'fcc'))) /* ver TER_2.0 */
- *ptrto++ = *ptrfrm++; /* kill comments */ /* buggy: if FCC ';'
- * error reported
- * removed 27/6/93 */
- *ptrto = EOS;
-
- #ifdef DEBUG
- printf("Label-%s-\n", Label);
- printf("Op----%s-\n", Op);
- printf("Operand-%s-\n", Operand);
- #endif
- return (1);
- }
-
- /*
- * process --- determine mnemonic class and act on it
- */
- void
- process(void)
- {
- register struct oper *i;
- /* struct oper *mne_look(); */
-
- Old_pc = Pc; /* setup `old' program counter */
- Optr = Operand; /* point to beginning of operand field */
-
- if (*Op == EOS) { /* no mnemonic */
- if (*Label != EOS)
- install(Label, Pc);
- } else if ((i = mne_look(Op)) == NULL)
- error("Unrecognized Mnemonic");
- else if (i->class == PSEUDO)
- do_pseudo(i->opcode);
- else {
- if (*Label)
- install(Label, Pc);
- if (Cflag)
- Cycles = i->cycles;
- do_op(i->opcode, i->class);
- if (Cflag)
- Ctotal += Cycles;
- }
- }
-
- #ifndef IBM
- char *
- FGETS(char *s, int n, register FILE * iop)
- { /* get at most n chars from iop */
- /* Added rev TER_1.1 June 3, 1989 */
- /* Adapted from Kernighan & Ritchie */
- /*
- * An fgets() that is IBM proof. Not needed if this IS an IBM
- */
- register int c;
- register char *cs;
-
- cs = s;
- while (--n > 0 && (c = getc(iop)) != EOF) { /* read chars if not
- * file end */
- if ((*cs = c) != CR)
- cs++; /* incr buffer pointer if not CR */
- /* If CR, leave to be written over */
- if (c == '\n')
- break;
- }
- *cs = '\0'; /* replace NEWLINE with NULL as in standard
- * fgets() */
- return ((c == EOF && cs == s) ? NULL : s); /* return NULL if this
- * is EOF */
- }
- #endif
-