char mapdn(); char *alloc(); /* * 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. */ main(argc,argv) int argc; char **argv; { char *i; char *tp; int k; FILE *fopen(); int j = 0; void do_op(),f_record(); /* added for ANSI C compat ver TER_2.0 6/18/89 */ printf("Assembler release TER_2.0 version 2.09\n"); printf("(c) Motorola (free ware)\n"); if(argc < 2){ printf("Usage: %s [files]\n",argv[j]); exit(1); } if ( strcmp( argv[1],"-o") == 0) { initialize(argv[2]); argc = argc-2; argv = argv+2; } Argv = argv; for (N_files = 0, j = 1; j < argc; j++) { if (*argv[j] != '-') { N_files++; continue; } tp = argv[j]; tp++; if ((*tp <= 'Z') && (*tp >= 'A')) { (*tp) += 32; } if (strcmp(tp,"l")==0) { Lflag = 1; } else if (strcmp(tp,"nol")==0) { Lflag = 0; } else if (strcmp(tp,"c")==0) { Cflag = 1; } else if (strcmp(tp,"noc")==0) { Cflag = 0; } else if (strcmp(tp,"s")==0) { Sflag = 1; } else if (strcmp(tp,"cre")==0) { CREflag = 1; } else if (strcmp(tp,"crlf")==0) /* test for crlf option */ { CRflag = 1; /* add to S record */ } /* ver TER_1.1 June 3, 1989 */ else if (strcmp(tp,"nnf")==0) /* test for nnf option */ { nfFlag=0; /* nfFlag=1 means number INCLUDE separately. ver TER_2.0 6/17/89 */ } else if (strcmp(tp,"p50")==0) /* page every 50 lines */ { Pflag50 = 1; /* ver (TER) 2.01 19 Jun 89 */ } } root = NULL; Line_num = 0; /* reset line number */ for (Ccnt = 0; Ccnt <= N_files; Ccnt++) { for (k = 0, Cfn = 1; ; Cfn++) { if ((*argv[Cfn] != '-') && (k++ <= Ccnt)) { break; } } if((Fd = fopen(argv[Cfn],"r")) == NULL) { printf("as: can't open %s\n",argv[Cfn]); } else { make_pass(); fclose(Fd); } if( Err_count == 0 ) { Pass++; re_init(); Line_num = 0; FdCount=0; /* Resets INCLUDE file nesting ver TER_2.0 6/17/89 */ while(++Ccnt <= N_files) { for (k = 0, Cfn = 1; ; Cfn++) { if ((*argv[Cfn] != '-') && (k++ <= Ccnt)) { break; } } if((Fd = fopen(argv[Cfn],"r")) != NULL) { make_pass(); fclose(Fd); } } printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */ printf ("Error count = %d\n",Err_count); /* rel TER_2.0 */ if (Sflag == 1) { printf ("\f"); stable (root); } if (CREflag == 1) { printf ("\f"); cross (root); } if (CRflag == 1) { fprintf(Objfil,"S9030000FC%c\n",CR); /* ver TER_1.1 print w */ } else { fprintf(Objfil,"S9030000FC\n"); /* at least give a decent ending */ } fclose(Objfil); /* close file correctly ver TER_1.1 */ } else /* just note errors, TER_2.0 */ { printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */ printf ("Error count = %d\n",Err_count); } } 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 */ } initialize(file1) char *file1; { FILE *fopen(); int i = 0; #ifdef DEBUG printf("Initializing\n"); #endif Err_count = 0; Pc = 0; Pass = 1; Lflag = 0; Cflag = 0; Ctotal = 0; Sflag = 0; CREflag = 0; N_page = 0; Line[MAXBUF-1] = NEWLINE; if( (Objfil = fopen(file1,"w")) == NULL) { fatal("Can't create object file"); } fwdinit(); /* forward ref init */ localinit(); /* target machine specific init. */ } re_init() { #ifdef DEBUG printf("Reinitializing\n"); #endif Pc = 0; E_total = 0; P_total = 0; Ctotal = 0; N_page = 0; fwdreinit(); } make_pass() { #ifdef IBM char *fgets(); /* the original line */ #else char *FGETS(); /* use own FGETS which is rewrite of lib function */ /* such that it discards 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 June 3, 1989 */ /* rev TER_1.1 */ 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 */ parse_line() { 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 != ';')) /* ver TER_2.0 */ *ptrto++ = *ptrfrm++; /* kill comments */ *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 */ process() { 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(s, n, 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 */ char *s; int n; register FILE *iop; { 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