#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
char mapdn();
|
char mapdn();
|
char *alloc();
|
char *alloc();
|
/*
|
/*
|
* as --- cross assembler main program
|
* as --- cross assembler main program
|
|
|
Note: Compile with define DEBUG for function module debug
|
Note: Compile with define DEBUG for function module debug
|
statements. Compile with define DEBUG2 for version 2 debug
|
statements. Compile with define DEBUG2 for version 2 debug
|
statements only. Compile with define IBM to use original, non-
|
statements only. Compile with define IBM to use original, non-
|
Amiga, non-MAC, non-UNIX fgets() function. Amiga version will
|
Amiga, non-MAC, non-UNIX fgets() function. Amiga version will
|
accept IBM generated source code but not the other way around.
|
accept IBM generated source code but not the other way around.
|
Note added version (TER) 2.01 19 June 1989.
|
Note added version (TER) 2.01 19 June 1989.
|
|
|
Additional modifications to cleanup output listing made by
|
Additional modifications to cleanup output listing made by
|
Donald W. Coates 1/5/92. Version changed to 2.10
|
Donald W. Coates 1/5/92. Version changed to 2.10
|
*/
|
*/
|
main(argc,argv)
|
main(argc,argv)
|
int argc;
|
int argc;
|
char **argv;
|
char **argv;
|
{
|
{
|
char **np;
|
char **np;
|
char *i;
|
char *i;
|
FILE *fopen();
|
FILE *fopen();
|
int j = 0;
|
int j = 0;
|
|
|
printf("Assembler release DWC_2.0 version 2.11\n");
|
printf("Assembler release DWC_2.0 version 2.11\n");
|
printf("May 6, 2004 (c) Motorola (free ware)\n");
|
printf("May 6, 2004 (c) Motorola (free ware)\n");
|
|
|
if(argc < 2){
|
if(argc < 2){
|
printf("Usage: %s [files]\n",argv[j]);
|
printf("Usage: %s [files]\n",argv[j]);
|
exit(1);
|
exit(1);
|
}
|
}
|
Argv = argv;
|
Argv = argv;
|
initialize();
|
initialize();
|
while ((j<argc) && (*argv[j] != '-'))
|
while ((j<argc) && (*argv[j] != '-'))
|
j++;
|
j++;
|
N_files = j-1;
|
N_files = j-1;
|
if (j < argc )
|
if (j < argc )
|
{
|
{
|
argv[j]++;
|
argv[j]++;
|
while (j<argc)
|
while (j<argc)
|
{
|
{
|
for (i = argv[j]; *i != 0; i++)
|
for (i = argv[j]; *i != 0; i++)
|
if ((*i <= 'Z') && (*i >= 'A'))
|
if ((*i <= 'Z') && (*i >= 'A'))
|
*i = *i + 32;
|
*i = *i + 32;
|
if (strcmp(argv[j],"l")==0)
|
if (strcmp(argv[j],"l")==0)
|
Lflag = 1;
|
Lflag = 1;
|
else if (strcmp(argv[j],"nol")==0)
|
else if (strcmp(argv[j],"nol")==0)
|
Lflag = 0;
|
Lflag = 0;
|
else if (strcmp(argv[j],"c")==0)
|
else if (strcmp(argv[j],"c")==0)
|
Cflag = 1;
|
Cflag = 1;
|
else if (strcmp(argv[j],"noc")==0)
|
else if (strcmp(argv[j],"noc")==0)
|
Cflag = 0;
|
Cflag = 0;
|
else if (strcmp(argv[j],"s")==0)
|
else if (strcmp(argv[j],"s")==0)
|
Sflag = 1;
|
Sflag = 1;
|
else if (strcmp(argv[j],"cre")==0)
|
else if (strcmp(argv[j],"cre")==0)
|
CREflag = 1;
|
CREflag = 1;
|
else if (strcmp(argv[j],"crlf")==0) /* test for crlf option */
|
else if (strcmp(argv[j],"crlf")==0) /* test for crlf option */
|
CRflag = 1; /* add <CR><LF> to S record */
|
CRflag = 1; /* add <CR><LF> to S record */
|
/* ver TER_1.1 June 3, 1989 */
|
/* ver TER_1.1 June 3, 1989 */
|
else if (strcmp(argv[j],"nnf")==0) /* test for nnf option */
|
else if (strcmp(argv[j],"nnf")==0) /* test for nnf option */
|
nfFlag=0; /* nfFlag=1 means number INCLUDE */
|
nfFlag=0; /* nfFlag=1 means number INCLUDE */
|
/* separately. ver TER_2.0 6/17/89 */
|
/* separately. ver TER_2.0 6/17/89 */
|
else if (strcmp(argv[j],"p50")==0){ /* page every 50 lines */
|
else if (strcmp(argv[j],"p50")==0){ /* page every 50 lines */
|
Pflag50 = 1; /* ver (TER) 2.01 19 Jun 89 */
|
Pflag50 = 1; /* ver (TER) 2.01 19 Jun 89 */
|
Pflag75 = 0;
|
Pflag75 = 0;
|
} /* separately. ver TER_2.0 6/17/89 */
|
} /* separately. ver TER_2.0 6/17/89 */
|
else if (strcmp(argv[j],"p75")==0){ /* page every 75 lines */
|
else if (strcmp(argv[j],"p75")==0){ /* page every 75 lines */
|
Pflag50 = 0; /* ver (DWC) 2.10 8 Oct 2001 */
|
Pflag50 = 0; /* ver (DWC) 2.10 8 Oct 2001 */
|
Pflag75 = 1;
|
Pflag75 = 1;
|
}
|
}
|
j++;
|
j++;
|
}
|
}
|
}
|
}
|
root = NULL;
|
root = NULL;
|
|
|
Cfn = 0;
|
Cfn = 0;
|
np = argv;
|
np = argv;
|
Line_num = 0; /* reset line number */
|
Line_num = 0; /* reset line number */
|
while( ++Cfn <= N_files )
|
while( ++Cfn <= N_files )
|
if((Fd = fopen(*++np,"r")) == NULL)
|
if((Fd = fopen(*++np,"r")) == NULL)
|
printf("as: can't open %s\n",*np);
|
printf("as: can't open %s\n",*np);
|
else{
|
else{
|
make_pass();
|
make_pass();
|
fclose(Fd);
|
fclose(Fd);
|
}
|
}
|
if( Err_count == 0 ){
|
if( Err_count == 0 ){
|
Pass++;
|
Pass++;
|
re_init();
|
re_init();
|
Cfn = 0;
|
Cfn = 0;
|
np = argv;
|
np = argv;
|
Line_num = 0;
|
Line_num = 0;
|
FdCount=0; /* Resets INCLUDE file nesting ver TER_2.0 6/17/89 */
|
FdCount=0; /* Resets INCLUDE file nesting ver TER_2.0 6/17/89 */
|
while( ++Cfn <= N_files)
|
while( ++Cfn <= N_files)
|
if((Fd = fopen(*++np,"r")) != NULL)
|
if((Fd = fopen(*++np,"r")) != NULL)
|
{
|
{
|
make_pass();
|
make_pass();
|
fclose(Fd);
|
fclose(Fd);
|
}
|
}
|
printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */
|
printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */
|
printf ("Error count = %d\n",Err_count); /* rel TER_2.0 */
|
printf ("Error count = %d\n",Err_count); /* rel TER_2.0 */
|
if (Sflag == 1)
|
if (Sflag == 1)
|
{
|
{
|
printf ("\n\f\n");
|
printf ("\n\f\n");
|
stable (root);
|
stable (root);
|
}
|
}
|
if (CREflag == 1)
|
if (CREflag == 1)
|
{
|
{
|
printf ("\n\f\n");
|
printf ("\n\f\n");
|
cross (root);
|
cross (root);
|
}
|
}
|
if (CRflag == 1)
|
if (CRflag == 1)
|
fprintf(Objfil,"S9030000FC%c\n",CR); /* ver TER_1.1 print w <CR> */
|
fprintf(Objfil,"S9030000FC%c\n",CR); /* ver TER_1.1 print w <CR> */
|
else
|
else
|
fprintf(Objfil,"S9030000FC\n"); /* at least give a decent ending */
|
fprintf(Objfil,"S9030000FC\n"); /* at least give a decent ending */
|
fclose(Objfil); /* close file correctly ver TER_1.1 */
|
fclose(Objfil); /* close file correctly ver TER_1.1 */
|
}
|
}
|
else /* just note errors, TER_2.0 */
|
else /* just note errors, TER_2.0 */
|
{
|
{
|
printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */
|
printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */
|
printf ("Error count = %d\n",Err_count);
|
printf ("Error count = %d\n",Err_count);
|
}
|
}
|
fwd_done();
|
fwd_done();
|
exit(Err_count); /* neat for UNIX cuz can test return value in script
|
exit(Err_count); /* neat for UNIX cuz can test return value in script
|
but on other systems like Amiga, mostly just makes
|
but on other systems like Amiga, mostly just makes
|
further script statements fail if >10, else
|
further script statements fail if >10, else
|
nothing. Therefore, printed out byte count
|
nothing. Therefore, printed out byte count
|
and error level. ver (TER) 2.02 19 Jun 89 */
|
and error level. ver (TER) 2.02 19 Jun 89 */
|
}
|
}
|
|
|
initialize()
|
initialize()
|
{
|
{
|
FILE *fopen();
|
FILE *fopen();
|
int i = 0;
|
int i = 0;
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Initializing\n");
|
printf("Initializing\n");
|
#endif
|
#endif
|
Err_count = 0;
|
Err_count = 0;
|
Pc = 0;
|
Pc = 0;
|
Pass = 1;
|
Pass = 1;
|
Lflag = 0;
|
Lflag = 0;
|
Cflag = 0;
|
Cflag = 0;
|
Ctotal = 0;
|
Ctotal = 0;
|
Sflag = 0;
|
Sflag = 0;
|
CREflag = 0;
|
CREflag = 0;
|
N_page = 0;
|
N_page = 0;
|
Line[MAXBUF-1] = NEWLINE;
|
Line[MAXBUF-1] = NEWLINE;
|
|
|
strcpy(Obj_name,Argv[1]); /* copy first file name into array */
|
strcpy(Obj_name,Argv[1]); /* copy first file name into array */
|
do {
|
do {
|
if (Obj_name[i]=='.')
|
if (Obj_name[i]=='.')
|
Obj_name[i]=0;
|
Obj_name[i]=0;
|
}
|
}
|
while (Obj_name[i++] != 0);
|
while (Obj_name[i++] != 0);
|
strcat(Obj_name,".s19"); /* append .out to file name. */
|
strcat(Obj_name,".s19"); /* append .out to file name. */
|
if( (Objfil = fopen(Obj_name,"w")) == NULL)
|
if( (Objfil = fopen(Obj_name,"w")) == NULL)
|
fatal("Can't create object file");
|
fatal("Can't create object file");
|
fwdinit(); /* forward ref init */
|
fwdinit(); /* forward ref init */
|
localinit(); /* target machine specific init. */
|
localinit(); /* target machine specific init. */
|
}
|
}
|
|
|
re_init()
|
re_init()
|
{
|
{
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Reinitializing\n");
|
printf("Reinitializing\n");
|
#endif
|
#endif
|
Pc = 0;
|
Pc = 0;
|
E_total = 0;
|
E_total = 0;
|
P_total = 0;
|
P_total = 0;
|
Ctotal = 0;
|
Ctotal = 0;
|
N_page = 0;
|
N_page = 0;
|
fwdreinit();
|
fwdreinit();
|
}
|
}
|
|
|
make_pass()
|
make_pass()
|
{
|
{
|
#ifdef IBM
|
#ifdef IBM
|
char *fgets(); /* the original line */
|
char *fgets(); /* the original line */
|
#else
|
#else
|
char *FGETS(); /* use own FGETS which is rewrite of lib function */
|
char *FGETS(); /* use own FGETS which is rewrite of lib function */
|
/* such that it discards <CR> so can read code */
|
/* such that it discards <CR> so can read code */
|
/* generated on IBM */
|
/* generated on IBM */
|
/* June 3, 1989 rev TER_1.1 */
|
/* June 3, 1989 rev TER_1.1 */
|
#endif
|
#endif
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Pass %d\n",Pass);
|
printf("Pass %d\n",Pass);
|
#endif
|
#endif
|
|
|
#ifndef IBM
|
#ifndef IBM
|
while( FGETS(Line,MAXBUF-1,Fd) != (char *)NULL ){ /* changed to FGETS */
|
while( FGETS(Line,MAXBUF-1,Fd) != (char *)NULL ){ /* changed to FGETS */
|
/* which does not pass on <CR> June 3, 1989 */
|
/* which does not pass on <CR> June 3, 1989 */
|
/* rev TER_1.1 */
|
/* rev TER_1.1 */
|
#else
|
#else
|
while( fgets(Line,MAXBUF,Fd) != (char *)NULL ){
|
while( fgets(Line,MAXBUF,Fd) != (char *)NULL ){
|
|
|
#endif
|
#endif
|
|
|
Line_num++;
|
Line_num++;
|
P_force = 0; /* No force unless bytes emitted */
|
P_force = 0; /* No force unless bytes emitted */
|
N_page = 0;
|
N_page = 0;
|
if(parse_line())
|
if(parse_line())
|
process();
|
process();
|
if(Pass == 2 && Lflag && !N_page)
|
if(Pass == 2 && Lflag && !N_page)
|
print_line();
|
print_line();
|
P_total = 0; /* reset byte count */
|
P_total = 0; /* reset byte count */
|
Cycles = 0; /* and per instruction cycle count */
|
Cycles = 0; /* and per instruction cycle count */
|
}
|
}
|
f_record();
|
f_record();
|
}
|
}
|
|
|
|
|
/*
|
/*
|
* parse_line --- split input line into label, op and operand
|
* parse_line --- split input line into label, op and operand
|
*/
|
*/
|
parse_line()
|
parse_line()
|
{
|
{
|
register char *ptrfrm = Line;
|
register char *ptrfrm = Line;
|
register char *ptrto = Label;
|
register char *ptrto = Label;
|
char *skip_white();
|
char *skip_white();
|
|
|
if( *ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';' )
|
if( *ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';' )
|
/* added check for ';' ver TER_1.1 */
|
/* added check for ';' ver TER_1.1 */
|
/* June 3, 1989 */
|
/* June 3, 1989 */
|
return(0); /* a comment line */
|
return(0); /* a comment line */
|
|
|
while( delim(*ptrfrm)== NO ) /* parsing Label */
|
while( delim(*ptrfrm)== NO ) /* parsing Label */
|
*ptrto++ = *ptrfrm++;
|
*ptrto++ = *ptrfrm++;
|
if(*--ptrto != ':')ptrto++; /* allow trailing : */
|
if(*--ptrto != ':')ptrto++; /* allow trailing : */
|
*ptrto = EOS;
|
*ptrto = EOS;
|
|
|
ptrfrm = skip_white(ptrfrm);
|
ptrfrm = skip_white(ptrfrm);
|
if (*ptrfrm == ';') { /* intercept comment after label, ver TER_2.0 */
|
if (*ptrfrm == ';') { /* intercept comment after label, ver TER_2.0 */
|
*Op = *Operand = EOS; /* comment, no Opcode or Operand */
|
*Op = *Operand = EOS; /* comment, no Opcode or Operand */
|
return(1); }
|
return(1); }
|
ptrto = Op;
|
ptrto = Op;
|
|
|
while( delim(*ptrfrm) == NO) /* parsing Opcode */
|
while( delim(*ptrfrm) == NO) /* parsing Opcode */
|
*ptrto++ = mapdn(*ptrfrm++);
|
*ptrto++ = mapdn(*ptrfrm++);
|
*ptrto = EOS;
|
*ptrto = EOS;
|
|
|
ptrfrm = skip_white(ptrfrm);
|
ptrfrm = skip_white(ptrfrm);
|
if (*ptrfrm == ';') { /* intercept comment, ver TER_2.0 */
|
if (*ptrfrm == ';') { /* intercept comment, ver TER_2.0 */
|
*Operand = EOS; /* comment, no Operand */
|
*Operand = EOS; /* comment, no Operand */
|
return(1); }
|
return(1); }
|
|
|
ptrto = Operand;
|
ptrto = Operand;
|
while( (*ptrfrm != NEWLINE) && (*ptrfrm != ';')) /* ver TER_2.0 */
|
while( (*ptrfrm != NEWLINE) && (*ptrfrm != ';')) /* ver TER_2.0 */
|
*ptrto++ = *ptrfrm++; /* kill comments */
|
*ptrto++ = *ptrfrm++; /* kill comments */
|
*ptrto = EOS;
|
*ptrto = EOS;
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Label-%s-\n",Label);
|
printf("Label-%s-\n",Label);
|
printf("Op----%s-\n",Op);
|
printf("Op----%s-\n",Op);
|
printf("Operand-%s-\n",Operand);
|
printf("Operand-%s-\n",Operand);
|
#endif
|
#endif
|
return(1);
|
return(1);
|
}
|
}
|
|
|
/*
|
/*
|
* process --- determine mnemonic class and act on it
|
* process --- determine mnemonic class and act on it
|
*/
|
*/
|
process()
|
process()
|
{
|
{
|
register struct oper *i;
|
register struct oper *i;
|
struct oper *mne_look();
|
struct oper *mne_look();
|
|
|
Old_pc = Pc; /* setup `old' program counter */
|
Old_pc = Pc; /* setup `old' program counter */
|
Optr = Operand; /* point to beginning of operand field */
|
Optr = Operand; /* point to beginning of operand field */
|
|
|
if(*Op==EOS){ /* no mnemonic */
|
if(*Op==EOS){ /* no mnemonic */
|
if(*Label != EOS)
|
if(*Label != EOS)
|
install(Label,Pc);
|
install(Label,Pc);
|
}
|
}
|
else if( (i = mne_look(Op))== NULL)
|
else if( (i = mne_look(Op))== NULL)
|
error("Unrecognized Mnemonic");
|
printf("Unrecognized Mnemonic '%s'\n",Op);
|
else if( i->class == PSEUDO )
|
else if( i->class == PSEUDO )
|
do_pseudo(i->opcode);
|
do_pseudo(i->opcode);
|
else{
|
else{
|
if( *Label )install(Label,Pc);
|
if( *Label )install(Label,Pc);
|
if(Cflag)Cycles = i->cycles;
|
if(Cflag)Cycles = i->cycles;
|
do_op(i->opcode,i->class);
|
do_op(i->opcode,i->class);
|
if(Cflag)Ctotal += Cycles;
|
if(Cflag)Ctotal += Cycles;
|
}
|
}
|
}
|
}
|
|
|
#ifndef IBM
|
#ifndef IBM
|
char *FGETS(s, n, iop) /* get at most n chars from iop */
|
char *FGETS(s, n, iop) /* get at most n chars from iop */
|
/* Added rev TER_1.1 June 3, 1989 */
|
/* Added rev TER_1.1 June 3, 1989 */
|
/* Adapted from Kernighan & Ritchie */
|
/* Adapted from Kernighan & Ritchie */
|
/* An fgets() that is IBM proof. Not needed if
|
/* An fgets() that is IBM proof. Not needed if
|
this IS an IBM */
|
this IS an IBM */
|
|
|
char *s;
|
char *s;
|
int n;
|
int n;
|
register FILE *iop;
|
register FILE *iop;
|
{
|
{
|
register int c;
|
register int c;
|
register char *cs;
|
register char *cs;
|
|
|
cs=s;
|
cs=s;
|
while (--n > 0 && (c = getc(iop)) != EOF) /* read chars if not file end */
|
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 ((*cs = c) != CR) cs++; /* incr buffer pointer if not CR */
|
/* If CR, leave to be written over */
|
/* If CR, leave to be written over */
|
if (c == '\n')
|
if (c == '\n')
|
break;
|
break;
|
}
|
}
|
*cs = '\0'; /* replace NEWLINE with NULL as in standard fgets() */
|
*cs = '\0'; /* replace NEWLINE with NULL as in standard fgets() */
|
return((c == EOF && cs == s) ? NULL : s); /* return NULL if this is EOF */
|
return((c == EOF && cs == s) ? NULL : s); /* return NULL if this is EOF */
|
}
|
}
|
#endif
|
#endif
|
|
|