home *** CD-ROM | disk | FTP | other *** search
- /* As6502 main routine: assm1.c */
-
- #include "stdio.h"
- #include "ctype.h"
- #include "assm.d1"
- #include "assm.d2"
- #include <time.h>
-
- #define CPMEOF EOF
-
- /* Version 5.0 ported to the Amiga 3/1/87 by Joel Swank */
-
- /* Version 5.0 is a major revision by Joel Swank. It adds the following
- * features: '.PAGE' pseudo with optional title; automatic paging and
- * -p flag to specify page length; A sorted symbol cross reference;
- * -t flag to specify the symbol table size; -w flag to specify the width
- * of a listing line. The -m option causes the object file to be formatted
- * as a standard MOS Technology object file. Also added error checking
- * and error messages to the argument parsing routine.
- */
-
- /*
- * Two changes to version 1.4 have been made to "port" as6502 to CP/M(tm).
- * A "tolower()" function call was add to the command line processing
- * code to (re)map the command line arguments to lower case (CP/M
- * converts all command line arguments to upper case). The readline()
- * function has code added to "ignore" the '\r' character (CP/M includes
- * the \r character along with \n).
- *
- * Also, the ability to process multiple files on the command line has been
- * added. Now one can do, for example:
- *
- * as6502 -nisvo header.file source.file data.file ...
- *
- * George V. Wilder
- * IX 1A-360 x1937
- * ihuxp!gvw1
- */
- /* Had to take out tolower call to work on 4.2bsd. Joel Swank 5/9/85 */
- /* Added USAGE message in place of Invalid count message JS 12/2/86 */
-
-
- int badflag;
- int act;
- char **avt;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *malloc();
- int cnt;
- int i;
- int ac;
- char **av;
- long l;
- size = STABSZ;
- pagesize = PAGESIZE;
- linesize = LINESIZE;
- getargs(argc, argv); /* parse the command line arguments */
- if (badflag > 0) exit(1);
- if (act == 0) {
- fprintf(stderr, "USAGE: as6502 -[milnosv] [-p -t -w] file ...\n");
- exit(1);
- }
- symtab = malloc(size);
- if (symtab == 0) {
- fprintf(stderr,"Symbol table allocation failed - specify a smaller size\n");
- exit(2); }
- time(&l);
- date = ctime(&l);
- date[24] = '\0';
- pagect = 0;
- paglin = pagesize;
- titlesize = linesize-36;
- for (i=0 ; i<100; i++) titlbuf[i] = ' ';
- titlbuf[titlesize] = '\0';
- for (i=0 ; i<linesize-58; i++) syspc[i] = ' ';
- syspc[i] = '\0';
- ac = act;
- av = avt;
- pass = FIRST_PASS;
- errcnt = loccnt = slnum = 0;
- fprintf(stderr,"Initialization complete\n");
- while (pass != DONE) {
- initialize(ac, av, act);
- fprintf(stderr,"PASS %d %s\n",pass+1,*av);
- if(pass == LAST_PASS && ac == act)
- errcnt = loccnt = slnum = 0;
- /* lower level routines can terminate assembly by setting
- pass = DONE ('symbol table full' does this) */
- while (readline() != -1 && pass != DONE)
- assemble(); /* rest of assembler executes from here */
- if (errcnt != 0) {
- pass = DONE;
- fprintf(stderr, "Terminated with error counter = %d\n", errcnt);
- }
- switch (pass) {
- case FIRST_PASS:
- --ac;
- ++av;
- if(ac == 0) {
- pass = LAST_PASS;
- if (lflag == 0)
- lflag++;
- ac = act;
- av = avt;
- }
- break;
- case LAST_PASS:
- --ac;
- ++av;
- if(ac == 0) {
- pass = DONE;
- if (sflag != 0)
- stprnt();
- }
- }
- wrapup();
- if ((dflag != 0) && (pass == LAST_PASS)) {
- fprintf(stdout, "nxt_free = %d\n", nxt_free);
- cnt = 0;
- }
- }
- fclose(stdout);
- free(symtab);
- return(0);
- }
-
- /*****************************************************************************/
-
- /* parse the command args and save data */
-
- getargs(argc,argv)
- int argc;
- char *argv[];
- {
- int i;
- char c;
- int sz;
- while (--argc > 0 && (*++argv)[0] == '-') {
- for (i = 1; (c = (*argv)[i]) != '\0'; i++) {
- switch (c) {
- case 'd': /* debug flag */
- dflag++;
- break;
- case 'i': /* ignore .nlst flag */
- iflag++;
- break;
- case 'l': /* disable listing flag */
- lflag--;
- break;
- case 'n': /* normal/split address mode */
- nflag++;
- break;
- case 'o': /* object output flag */
- oflag++;
- break;
- case 'm': /* MOS Tech. object format */
- mflag++;
- oflag++; /* -m implies -o */
- break;
- case 's': /* list symbol table flag */
- sflag++;
- break;
- case 'v': /* print assembler version */
- fprintf(stderr,
- "as6502 - Amiga version 5.0 - 3/1/87 - JHV [gvw,jhs]\n");
- break;
- case 't': /* input symbol table size */
- {
- if ((*argv)[++i] == '\0') {
- ++argv;
- argc--;
- sz = atoi(*argv);
- } else sz = atoi(&(*argv)[i]);
- if (sz>1000) size=sz;
- else {
- fprintf(stderr,
- "Invalid Symbol table size - minimum is 1000\n");
- badflag++; }
- goto outofloop;
- }
- case 'p': /* input lines per page */
- {
- if ((*argv)[++i] == '\0') {
- ++argv;
- argc--;
- sz = atoi(*argv);
- } else sz = atoi(&(*argv)[i]);
- if (sz>10 || sz == 0) pagesize=sz;
- else {
- fprintf(stderr,
- "Invalid Pagesize - minimum is 10\n");
- badflag++; }
- goto outofloop;
- }
- case 'w': /* input characters per line */
- {
- if ((*argv)[++i] == '\0') {
- ++argv;
- argc--;
- sz = atoi(*argv);
- } else sz = atoi(&(*argv)[i]);
- if (sz >= 80 && sz < 133) linesize=sz;
- else {
- fprintf(stderr,
- "Invalid Linesize - min is 80, max is 133\n");
- badflag++; }
- goto outofloop;
- }
- default:
- fprintf(stderr,"Unknown flag '%c'\n",c);
- badflag++;
- } /* end switch */
- } /* end for */
- outofloop: ;
- }
- act=argc; /* return values to main */
- avt=argv;
- }
- /*****************************************************************************/
-
- /* initialize opens files */
-
- initialize(ac, av, argc)
- int ac;
- char *av[];
- int argc;
- {
-
- if ((iptr = fopen(*av, "r")) == NULL) {
- fprintf(stderr, "Open error for file '%s'.\n", *av);
- exit(1);
- }
- if ((pass == LAST_PASS) && (oflag != 0) && ac == argc) {
- if ((optr = fopen("6502.out", "w")) == NULL) {
- fprintf(stderr, "Create error for object file 6502.out.\n");
- exit(1);
- }
- }
- }
-
- /* readline reads and formats an input line */
-
- int field[] =
- {
- SFIELD,
- SFIELD + 8,
- SFIELD + 14,
- SFIELD + 23,
- SFIELD + 43,
- SFIELD + 75
- };
-
- readline()
- {
- int i; /* pointer into prlnbuf */
- int j; /* pointer to current field start */
- int ch; /* current character */
- int cmnt; /* comment line flag */
- int spcnt; /* consecutive space counter */
- int string; /* ASCII string flag */
- int temp1; /* temp used for line number conversion */
-
- temp1 = ++slnum;
- clrlin();
- i = 3;
- while (temp1 != 0) { /* put source line number into prlnbuf */
- prlnbuf[i--] = temp1 % 10 + '0';
- temp1 /= 10;
- }
- i = SFIELD;
- cmnt = spcnt = string = 0;
- j = 1;
- while ((ch = getc(iptr)) != '\n') {
- if(ch == '\r')
- continue;
- prlnbuf[i++] = ch;
- if ((ch == ' ') && (string == 0)) {
- if (spcnt != 0)
- --i;
- else if (cmnt == 0) {
- ++spcnt;
- if (i < field[j])
- i = field[j];
- if (++j > 3) {
- spcnt = 0;
- ++cmnt;
- }
- }
- }
- else if (ch == '\t') {
- prlnbuf[i - 1] = ' ';
- spcnt = 0;
- if (cmnt == 0) {
- if (i < field[j])
- i = field[j];
- if (++j > 3)
- ++cmnt;
- }
- else i = (i + 8) & 0x78;
- }
- else if ((ch == ';') && (string == 0)) {
- spcnt = 0;
- if (i == SFIELD + 1)
- ++cmnt;
- else if (prlnbuf[i - 2] != '\'') {
- ++cmnt;
- prlnbuf[i-1] = ' ';
- if (i < field[3])
- i = field[3];
- prlnbuf[i++] = ';';
- }
- }
- else if (ch == EOF || ch == CPMEOF)
- return(-1);
- else {
- if ((ch == '"') && (cmnt == 0))
- string = string ^ 1;
- spcnt = 0;
- if (i >= LAST_CH_POS - 1)
- --i;
- }
- }
- prlnbuf[i] = 0;
- return(0);
- }
-
- /*
- * wrapup() closes the source, object and stdout files
- */
-
- wrapup()
- {
-
- fclose(iptr); /* close source file */
- if (pass == DONE) {
- if ((oflag != 0) && (optr !=0)) {
- if (mflag != 0) fin_obj();
- else fputc('\n', optr);
- fclose(optr);
- }
- }
- return;
- }
-
- /* symbol table print
- */
-
- stprnt()
- {
- int i; /* print line position */
- int ptr; /* symbol table position */
- int j; /* integer conversion variable */
- int k; /* printf buffer pointer */
- int refct; /* counter for references */
- char buf[6];
- paglin = pagesize;
- ptr = 0;
- clrlin();
- while (ptr < nxt_free)
- {
- for (i=1; i <= symtab[ptr]; i++) prlnbuf[i] = symtab[ptr+i];
- ptr += i+1; i=23; /* value at pos 23 */
- j = symtab[ptr++] & 0xff;
- j += (symtab[ptr++] << 8);
- hexcon(4,j);
- if (nflag == 0) {
- i--;
- prlnbuf[i++] = hex[3];
- prlnbuf[i++] = hex[4];
- prlnbuf[i++] = ':';
- prlnbuf[i++] = hex[1];
- prlnbuf[i++] = hex[2]; }
- else for (k=1; k<5; k++) prlnbuf[i++] = hex[k];
- j = symtab[ptr++] & 0xff;
- j += (symtab[ptr++] << 8);
- sprintf(buf,"%d",j);
- k=0;i=30; /* line defined at pos 30 */
- while (buf[k] != '\0') prlnbuf[i++] = buf[k++];
- k=0;i=37; /* count of references */
- refct = symtab[ptr++] & 0xff;
- sprintf(buf,"(%d)",refct);
- while (buf[k] != '\0') prlnbuf[i++] = buf[k++];
- i++; /* and all the references */
- while (refct > 0)
- {
- j = symtab[ptr++] & 0xff;
- j += (symtab[ptr++] << 8);
- sprintf(buf,"%d",j);
- k=0;
- while (buf[k] != '\0') prlnbuf[i++] = buf[k++];
- i++;
- refct--;
- if ( i > linesize-5 && refct > 0) {
- prlnbuf[i] = '\0';
- prsyline(); i=37; }
- }
- prlnbuf[i] = '\0';
- prsyline();
- }
-
- }
- /* prsyline prints the contents of prlnbuf */
-
- prsyline()
- {
- if (paglin == pagesize) prsymhead();
- prlnbuf[linesize] = '\0';
- fprintf(stdout, "%s\n", prlnbuf);
- paglin++ ;
- clrlin();
- }
-
- /****************************************************************************/
-
- /* prsymhead prints the page heading */
-
- prsymhead()
- {
- if (pagesize == 0) return;
- pagect++ ;
- fprintf(stdout, "\f\nAmiga 6502 assembler : Symbol Cross Reference - %s PAGE %d\n",syspc,pagect);
- fprintf(stdout, "Symbol Value Defined References\n\n");
- paglin = 0;
- }
-
- /* clear the print buffer */
-
- clrlin()
- {
- int i;
- for (i = 0; i < LAST_CH_POS; i++)
- prlnbuf[i] = ' ';
- }
-