/* As6502 main routine: assm1.c */ #include "stdio.h" #include "ctype.h" #include "assm.d1" #include "assm.d2" #include #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 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] = ' '; }