home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 3
/
goldfish_volume_3.bin
/
files
/
dev
/
cross
/
tms32010
/
x320.c
< prev
Wrap
C/C++ Source or Header
|
1992-09-02
|
16KB
|
680 lines
/* TMS320 Cross Assembler release 1.0 */
#include <libraries/dosextens.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* mnemonic table definition */
char *mntable[]= {
"ABS", "ADD", "ADDH", "ADDS", "AND", "AORG","APAC",
"B", "BANZ", "BGEZ", "BGZ", "BIOZ","BLEZ",
"BLZ", "BNZ", "BV", "BZ", "CALA", "CALL", "DATA",
"DINT", "DMOV", "EINT", "END", "EQU", "IN", "LAC",
"LACK", "LAR", "LARK", "LARP", "LDP", "LDPK", "LST",
"LT", "LTA", "LTD", "MAR", "MPY", "MPYK",
"NOP", "OR", "OUT", "PAC", "POP", "PUSH",
"RET", "ROVM", "SACH", "SACL", "SAR", "SOVM",
"SPAC", "SST", "SUB", "SUBC", "SUBH", "SUBS",
"TBLR", "TBLW", "XOR", "ZAC", "ZALH", "ZALS"
};
/* instruction type table definition */
unsigned char tytable[]= {
0, 9, 5, 5, 5, 14, 0, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 0, 10, 11, 0, 5,
0, 15, 13, 8, 9, 2, 6, 3, 1, 5, 1, 5,
5, 5, 5, 5, 5, 4, 0, 5, 8, 0,
0, 0, 0, 0, 7, 5, 6, 0, 0, 5,
9, 5, 5, 5, 5, 5, 5, 0, 5, 5
};
/* opcode table definition */
unsigned short optable[]= {
0x7F88, 0x0000, 0x6000, 0x6100, 0x7900, 0, 0x7F8F,
0xF900, 0xF400, 0xFD00, 0xFC00, 0xF600, 0xFB00,
0xFA00, 0xFE00, 0xF500, 0xFF00, 0x7F8C, 0xF800, 0,
0x7F81, 0x6900, 0x7F82, 0, 0, 0x4000, 0x2000, 0x7E00,
0x3800, 0x7000, 0x6880, 0x6F00, 0x6E00, 0x7B00,
0x6A00, 0x6C00, 0x6B00, 0x6800, 0x6D00, 0x8000,
0x7F80, 0x7A00, 0x4800, 0x7F8E, 0x7F9D, 0x7F9C,
0x7F8D, 0x7F8A, 0x5800, 0x5000, 0x3000, 0x7F8B,
0x7F90, 0x7C00, 0x1000, 0x6400, 0x6200, 0x6300,
0x6700, 0x7D00, 0x7800, 0x7F89, 0x6500, 0x6600
};
/* Predefined labels definition */
char *pdlab[]= {
"AR0", "AR1", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7"
};
unsigned long pdadd[]= {
0, 1, 0, 1, 2, 3, 4, 5, 6, 7
};
/* opcode info structure definition */
struct OpInfo {
unsigned char Type;
unsigned short OpCode;
};
/* label table structure definition */
struct LabTab {
char Label[10];
unsigned long Address;
};
/* functions declaration */
void Copyright(void);
char *getword(char *);
void incpc(void);
long getnum(char *);
char *getop(char *);
/* constants declaration */
#define MAXBUF 128
#define LINEBUF 256
#define TABLEN 64
#define MAXLAB 256
#define PDLABS 10
/* variables declaration */
struct OpInfo *opinfo;
struct LabTab labtab[MAXLAB];
char filein[MAXBUF], fileout[MAXBUF], linebuf[LINEBUF], auxbuf[LINEBUF];
char *labptr[MAXLAB], *pointer;
unsigned short indx;
FILE *fi, *fo;
unsigned long PC;
long value;
int Ops;
main(argc, argv)
int argc;
char *argv[];
{
char c;
int i=1, j, lineno;
struct LabTab auxlab;
long word;
BOOL xref=FALSE, link=FALSE;
Copyright();
if(argc==1) {
badusage: printf("Usage: %s [-xL] filename [filename]\n",argv[0]);
puts("\tx: generates cross reference listing to stdout.");
puts("\tL: calls L320 after assembly, linking to hex.");
exit(1);
}
if(*argv[i]=='-') {
for(j=0;j<strlen(argv[i]++);j++)
switch(*argv[i]) {
case 'L':
link=TRUE;
break;
case 'x':
xref=TRUE;
break;
default:
goto badusage;
}
i++;
argc--;
}
if(!(--argc))
goto badusage;
strcpy(filein,argv[i]);
strcpy(fileout,filein);
if(--argc)
strcpy(fileout,argv[++i]);
strcat(fileout,".obj");
if(!(fi=fopen(filein,"r"))) {
printf("Can't open file %s for input\n",filein);
exit(1);
}
if(!(fo=fopen(fileout,"w"))) {
printf("Can't open file %s for output\n",fileout);
fclose(fi);
exit(1);
}
/* Predefined labels storage */
for(indx=0;indx<PDLABS;indx++) {
strcpy(labtab[indx].Label,pdlab[indx]);
labtab[indx].Address=pdadd[indx];
}
/* Start first pass */
PC=0;
lineno=0;
while(fgets(linebuf,sizeof(linebuf),fi)) {
pointer=linebuf;
lineno++;
auxbuf[0]=0;
strtok(linebuf,";"); /* strip out comments */
if(!(isseppp(linebuf[0]))) { /* label found */
strcpy(auxbuf,linebuf);
for(i=0;(i<(LINEBUF-1))&&(!(issep(linebuf[i])));i++,pointer++);
auxbuf[i]=0;
if(!(i=stlabel(auxbuf))) {
printf("*** LABEL ALREADY DEFINED *** at line %d :%s\nLabel: %s\n",lineno,linebuf,auxbuf);
goto error;
}
if(i==-1) {
printf("*** OUT OF SYMBOL SPACE *** at line %d :%s\nLabel: %s\n",lineno,linebuf,auxbuf);
goto error;
}
}
if(pointer=getword(pointer)) {
if((i=findopc(pointer))==-1) { /* not an opcode */
synterr: printf("*** SYNTAX ERROR *** at line %d :%s\nUnknown mnemonic: %s\n",lineno,linebuf,pointer);
goto error;
}
switch(opinfo->Type) {
case 14: /* handle AORG directive */
if(Ops!=1)
goto synterr2;
if(!(eval(pointer,NULL)))
goto synterr2;
PC=(unsigned long) value;
break;
case 13: /* resolve EQU directive */
if(Ops!=1)
goto synterr2;
if(!eval(pointer,NULL))
printf("*** UNKNOWN LABEL *** at line %d :%s\nLabel: %s\n",lineno,linebuf,pointer);
labtab[indx-1].Address=value;
break;
case 11: /* handle multioperand DATA directive */
if(!Ops)
goto synterr2;
PC+=Ops; /* increment PC */
break;
}
incpc();
}
}
if(xref) {
puts("\nCross Reference Listing:");
puts("-----------------------\n");
for(i=0;i<indx;i++)
printf("\tLabel: %s, address: 0x%04X\n",labtab[i].Label,labtab[i].Address);
puts("");
}
/* Start second pass */
rewind(fi);
PC=0;
lineno=0;
while(fgets(linebuf,sizeof(linebuf),fi)) {
pointer=linebuf;
lineno++;
strtok(linebuf,";"); /* strip out comments */
if(!(isseppp(linebuf[0]))) /* skip labels */
for(i=0;(i<(LINEBUF-1))&&(!(issep(linebuf[i])));i++,pointer++);
if(pointer=getword(pointer)) {
if((i=findopc(pointer))==-1) { /* not an opcode */
goto synterr;
}
switch(opinfo->Type) {
case 14:
if(Ops!=1)
goto synterr2;
if(!(eval(pointer,NULL))) {
synterr2: printf("*** SYNTAX ERROR *** at line %d :%s\nBad operand: %s\n",lineno,linebuf,pointer);
goto error;
}
PC=(unsigned long) value;
break;
case 0:
if(Ops)
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode);
break;
case 1:
if(Ops!=1)
goto synterr2;
if(!eval(pointer,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|value);
break;
case 2:
if(Ops!=1)
goto synterr2;
if(!eval(pointer,NULL))
goto synterr2;
if((value>255)||(value<-127))
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|value);
break;
case 3:
if(Ops!=2)
goto synterr2;
if(!evalops(pointer,NULL)) /* 1st operand */
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=opinfo->OpCode|(value<<8);
if(!evalops(NULL,NULL)) /* 2nd operand */
goto synterr2;
if((value>255)||(value<-127))
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC,word|value);
break;
case 4:
if(Ops!=1)
goto synterr2;
if(!eval(pointer,NULL))
goto synterr2;
if((value>8191)||(value<-4095))
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|value);
break;
case 5:
if((!Ops)||(Ops>2))
goto synterr2;
if((i=evalops(pointer,TRUE))==-1) { /* get first operand and */
word=value; /* check for indirect addressing */
if(Ops==2) { /* check for new AR */
if(!evalops(NULL,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=word&0xfff7|value;
}
}
else { /* first operand is direct addressing */
if (Ops!=1)
goto synterr2;
if(!i)
goto synterr2;
if((value>127)||(value<0))
goto synterr2;
word=value;
}
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
break;
case 6:
if((Ops<2)||(Ops>3))
goto synterr2;
if(!evalops(pointer,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=value<<8;
if((i=evalops(NULL,TRUE))==-1) {
word=word|value;
if(Ops==3) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=word&0xfff7|value;
}
}
else {
if (Ops!=2)
goto synterr2;
if(!i)
goto synterr2;
if((value>127)||(value<0))
goto synterr2;
word=word|value;
}
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
break;
case 7:
if((!Ops)||(Ops>3))
goto synterr2;
if((i=evalops(pointer,TRUE))==-1) {
word=value;
if(Ops>1) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value)&&(value!=1)&&(value!=4))
goto synterr2;
word=word|(value<<8);
if(Ops==3) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=word&0xfff7|value;
}
}
}
else {
if (Ops!=2)
goto synterr2;
if(!i)
goto synterr2;
if((value>127)||(value<0))
goto synterr2;
word=value;
if(!evalops(NULL,NULL))
goto synterr2;
if((value)&&(value!=1)&&(value!=4))
goto synterr2;
word=word|(value<<8);
}
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
break;
case 8:
if((!Ops)||(Ops>3))
goto synterr2;
if((i=evalops(pointer,TRUE))==-1) {
word=value;
if(Ops>1) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value<0)||(value>7))
goto synterr2;
word=word|(value<<8);
if(Ops==3) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=word&0xfff7|value;
}
}
}
else {
if (Ops!=2)
goto synterr2;
if(!i)
goto synterr2;
if((value>127)||(value<0))
goto synterr2;
word=value;
if(!evalops(NULL,NULL))
goto synterr2;
if((value<0)||(value>7))
goto synterr2;
word=word|(value<<8);
}
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
break;
case 9:
if((!Ops)||(Ops>3))
goto synterr2;
if((i=evalops(pointer,TRUE))==-1) {
word=value;
if(Ops>1) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value<0)||(value>15))
goto synterr2;
word=word|(value<<8);
if(Ops==3) {
if(!evalops(NULL,NULL))
goto synterr2;
if((value>1)||(value<0))
goto synterr2;
word=word&0xfff7|value;
}
}
}
else {
if (Ops!=2)
goto synterr2;
if(!i)
goto synterr2;
if((value>127)||(value<0))
goto synterr2;
word=value;
if(!evalops(NULL,NULL))
goto synterr2;
if((value<0)||(value>15))
goto synterr2;
word=word|(value<<8);
}
fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
break;
case 10:
if(Ops!=1)
goto synterr2;
if(!eval(pointer,NULL))
goto synterr2;
if((value>4095)||(value<0))
goto synterr2;
fprintf(fo,"%04X\n%04X\n%04X\n%04X\n",PC,opinfo->OpCode,PC+1,value);
break;
case 11:
if(!Ops)
goto synterr2;
if(!evalops(pointer,NULL))
goto synterr2;
if((value>65535)||(value<-32767))
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC++,value);
while (--Ops) { /* handle multiple operands */
if(!evalops(NULL,NULL))
goto synterr2;
if((value>65535)||(value<-32767))
goto synterr2;
fprintf(fo,"%04X\n%04X\n",PC++,value);
}
break;
case 13:
break;
case 15:
goto end;
break;
default:
puts("*** Oh, Oh, the soft is dead...");
goto error;
}
incpc();
}
}
end: fclose(fi);
fclose(fo);
if(link) {
sprintf(linebuf,"L320 %s\n",fileout);
Execute(linebuf,0,0);
}
exit(0);
error: fclose(fi);
fclose(fo);
exit(1);
}
void Copyright(void)
{
puts("TMS32010 Cross Assembler (C)1994 by SRC");
}
issep(char c)
{
return((c==' ')||(c=='\t'));
}
issepp(char c)
{
return((c==' ')||(c=='\t')||(c==';'));
}
isseppp(char c)
{
return((c==' ')||(c=='\t')||(c==';')||(c=='\n'));
}
char *getword(char *ptr) /* get a word from a line */
{
char word[LINEBUF];
int i;
for(;(*ptr!=0)&&(issep(*ptr));ptr++); /* skip leading blanks */
if((*ptr==0)||(isseppp(*ptr))) /* handle EOL */
return(0);
strcpy(word,ptr); /* get word */
for(i=0;(*ptr!=0)&&(!(isseppp(*ptr)));i++,ptr++); /* find lenght */
word[i]=0;
return(word);
}
findword(word, tab, n) /* find a word in an array, tab is an array */
/* of vectors pointing to each entry in the table */
char *word, *tab[]; /* the array is sorted lower to higher */
int n;
{
int low,high,mid,cond; /* (C) Kernighan & Ritchie */
low=0;
high=n-1;
while(low<=high) {
mid=(low+high)/2;
if((cond=strcmp(word,tab[mid]))<0)
high=mid-1;
else if(cond>0)
low=mid+1;
else return(mid);
}
return(-1);
}
findopc(char *word) /* find an opcode in the opcode table */
{
int pos=0;
char *opc;
opc=strdup(word);
if(!(isupper(opc[0]))) /* if lower case, get upper */
for(pos=0;pos<strlen(opc);pos++)
opc[pos]=toupper(opc[pos]);
if((pos=findword(opc,mntable,TABLEN))==-1) /* search... */
return(-1);
opinfo->Type=tytable[pos]; /* if found, fill structure */
opinfo->OpCode=optable[pos];
pointer=getop(word); /* advance pointer to point to ops */
Ops=getopinf(pointer);
return(pos);
}
void incpc(void) /* increment PC according to instruction */
{
if(opinfo->Type<11) /* standard opcode */
PC++;
if(opinfo->Type==10) /* Two word instruction */
PC++;
}
long getnum(char *ptr)
{
int base=0; /* support C notation */
long add;
char **eptr;
if(ptr[0]=='>') { /* support Texas hex notation */
base=16;
ptr++;
}
add=strtol(ptr,eptr,base);
if(*eptr==ptr) /* syntax error (labels not supported) */
return(-1);
return(add);
}
char *getop(char *inst)
{
char *ptr;
strcpy(auxbuf,linebuf);
ptr=strstr(auxbuf,inst); /* point to instruction */
ptr+=(strlen(inst)+1); /* point to operands */
ptr[strlen(ptr)-1]=0;
return(ptr);
}
stlabel(char *label) /* store label in label table */
{
if(findlabel(label)!=-1) /* check if already defined */
return(0);
if(indx==MAXLAB) /* check for room */
return(-1);
strcpy(labtab[indx].Label,label);
labtab[indx++].Address=PC;
return(1);
}
findlabel(char *label)
{
int i;
for(i=0;i<indx;i++)
if(!strcmp(labtab[i].Label,label)) /* label found */
return(i);
return(-1);
}
eval (char *ptr,BOOL type)
{
int i=0;
ptr=getword(ptr);
if((strlen(ptr)==1)&&(*ptr=='$')) { /* allow "?" label */
value=PC;
return(1);
}
if (type &&((*ptr)=='*')) { /* handle indirect addressing */
i=strlen(ptr++);
if(i==1) {
value=0x88;
return(-1);
}
if(i==2) {
if(*ptr=='+') { /* handle postincrement */
value=0xa8;
return(-1);
}
else if(*ptr=='-') { /* handle postdecrement */
value=0x98;
return(-1);
}
else return(0);
}
}
if((value=findlabel(ptr))!=-1) { /* is it a label ? */
value=labtab[value].Address;
return(1);
}
if((value=getnum(ptr))!=-1) /* evaluate operand */
return(1);
return(0);
}
evalops(char *ptr,BOOL type)
{
if(ptr)
strtok(ptr,","); /* get first operand */
else
pointer=strtok(NULL,","); /* get next operand */
return(eval(pointer,type));
}
getopinf(char *ptr)
{
int n=1;
for(;(*ptr!=0)&&(issep(*ptr));ptr++); /* skip blanks */
if(!strlen(ptr))
return(0);
for(;*ptr!=0;ptr++)
if(*ptr==',')
n++;
return(n);
}