home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
languages
/
northc_384
/
disass
/
disass.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-30
|
19KB
|
595 lines
/* (c) 1990 Martin Combs */
#include <stdio.h>
#define maxfile 20000
long i, ii, iold;
long *lp;
unsigned int hibyte, lobyte, lonib, L76, mode, reg, reg1, size;
short *wp;
char p[maxfile], instS[40], opS[20], op1S[40], op2S[20], ascS[20];
char objS[40];
char reg1S[4];
char spaceS[10]=" ";
char spS[27][12];
char *ccS[16]={ "t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs",
"pl", "mi", "ge", "lt", "gt", "le" };
char *shiftS[8]= { "asr", "asl", "lsr", "lsl",
"roxr", "roxl", "ror", "rol"};
/* activate function test() for trouble shooting */
/*
test()
{ printf("\nsize=%d\thibyte=%d\tlobyte=%d\treg=%d\n",size,hibyte,lobyte,reg);
printf("lonib=%d\tmode=%d\tL76=%d\n",lonib,mode,L76);
printf("opS=%s\top1S=%s\top2S=%s\n",opS,op1S,op2S);
}
*/
tab()
{ int len;
for (len=0;len<27;len++)
{ if (!len) strcpy(spS[len],"\t\t\t");
else if (len < 9) sprintf(spS[len],"%s\t\t",spaceS+len);
else if (len < 17) sprintf(spS[len],"%s\t",spaceS+len-8);
else if (len<25) sprintf(spS[len],"%s",spaceS+len-16);
else spS[len][0]='\0';
}
}
binst()
{ switch (L76)
{ case 0: strcpy(instS,"btst"); break;
case 1: strcpy(instS,"bchg"); break;
case 2: strcpy(instS,"bclr"); break;
case 3: strcpy(instS,"bset");
}
}
sizef()
{ switch (L76)
{ case 0: strcat(instS,".b"); size=0; break;
case 1: strcat(instS,".w"); size=1; break;
case 2: strcat(instS,".l"); size=2;
}
}
sizeff()
{ sizef(); eff();
}
eff()
{ mode = (lobyte&56) >> 3; reg = lobyte & 7; eff1();
}
eff1()
{ switch (mode)
{ case 0: opS[0]='d'; opS[1]=reg+48; opS[2]='\0'; break;
case 1: opS[0]='a'; opS[1]=reg+48; opS[2]='\0'; break;
case 2: opS[0]='('; opS[1]='a'; opS[2]=reg+48;
opS[4]=')'; opS[3]='\0'; break;
case 3: opS[0]='('; opS[1]='a'; opS[2]=reg+48;
opS[3]=')'; opS[4]='+';opS[5]='\0'; break;
case 4: opS[0]='-'; opS[1]='('; opS[2]='a'; opS[3]=reg+48;
opS[4]=')'; opS[5]='\0'; break;
case 5: i+=2; wp=(short *)&p[i]; sprintf(opS,"%d(a%d)",*wp,reg); break;
case 6: i+=2; sprintf(opS,"%d(a%d,",p[i+1],reg); ariwi2(); break;
case 7: grabbag();
}
}
ariwi2()
{ char regS[4];
if (p[i]&128) strcat(opS,"a"); else strcat(opS,"d");
regS[1]='\0';
regS[0]=48 + ((p[i] & 112) >> 4);
strcat(opS,regS);
if (p[i]&8) strcat(opS,".l)"); else strcat(opS,".w)");
}
grabbag()
{ switch (reg)
{ case 0: i+=2; wp=(short *)&p[i]; sprintf(opS,"%d",*wp); break;
case 1: i+=4; lp=(long *)&p[i-2]; sprintf(opS,"%ld",*lp); break;
case 2: i+=2; wp=(short *)&p[i]; sprintf(opS,"%d(pc)",*wp); break;
case 3: i+=2; sprintf(opS,"%d(pc,",p[i+1]); ariwi2(); break;
default: switch (size)
{ case 0: i+=2; sprintf(opS,"#%d",p[i+1]); break;
case 1: i+=2; wp=(short *)&p[i];
sprintf(opS,"#%d",*wp); break;
case 2: i+=4; lp=(long *)&p[i-2];
sprintf(opS,"#%ld",*lp); break;
}
}
}
movep()
{ if (lobyte & 64) strcpy(instS,"movep.l"); else strcpy(instS,"movep.w");
dreg(); reg=lobyte & 7; i+=2;
wp=(short *)&p[i];
if (lobyte & 128) {strcpy(op1S,reg1S);sprintf(op2S,"%d(a%d)",*wp,reg);}
else { strcpy(op2S,reg1S); sprintf(op1S,"%d(a%d)",*wp,reg); }
}
dreg()
{ reg1S[0]='d';
reg1=(hibyte & 14) >> 1;
reg1S[1]=reg1+48;
}
areg()
{ reg1S[0]='a';
reg1=(hibyte & 14) >> 1;
reg1S[1]=reg1+48;
}
op0000()
{
if (hibyte&1) op0000xxx1(); else op0000xxx0();
}
op0000xxx0()
{ if (hibyte==8)
{ binst(); i+=2; sprintf(op1S,"#%d",p[i+1]&31);
eff(); strcpy(op2S,opS); return; }
if (hibyte==14) { strcpy(instS,"moves"); i+=2;
if (p[i]&128) opS[0]='a'; else opS[0]='d';
opS[1] = 48 + ((p[i] & 112) >> 4);
opS[2] = '\0';
wp=(short *)&p[i];
if ((*wp)&2048)
{ strcpy(op1S,opS); sizeff(); strcpy(op2S,opS); }
else {strcpy(op2S,opS); sizeff(); strcpy(op1S,opS); }
return;
}
switch (hibyte)
{ case 0: strcpy(instS,"ori"); break;
case 2: strcpy(instS,"andi"); break;
case 4: strcpy(instS,"subi"); break;
case 6: strcpy(instS,"addi"); break;
case 10: strcpy(instS,"eori"); break;
case 12: strcpy(instS,"cmpi");
}
switch (L76)
{ case 0: sprintf(op1S,"#%d",p[i+3]&255); break;
case 1: wp=(short *)&p[i+2]; sprintf(op1S,"#%d",*wp); break;
case 2: i+=2; lp=(long *)&p[i]; sprintf(op1S,"#%ld",*lp);
}
i+=2; sizeff();
if (mode==7 && reg==4) { i-=2; if (!L76) { strcpy(op2S,"ccr"); return; }
else { strcpy(op2S,"sr"); return; }
} /* end if (mode==7 etc */
strcpy(op2S,opS);
}
op0000xxx1()
{ if ((lobyte & 56)==8) { movep();return;}
binst();
dreg();
strcpy(op1S,reg1S);
eff();
strcpy(op2S,opS);
}
op0001()
{ strcpy(instS,"move.b"); size=0; move();
}
op0010()
{ size=2; move();
}
op0011()
{ size=1; move();
}
move()
{ unsigned int inst;
inst=hibyte*256+lobyte;
if (size) { strcpy(instS,"move");
if ((inst & 448)==64) strcat(instS,"a");
if (size==2) strcat(instS,".l");
else strcat(instS,".w");
}
eff(); strcpy(op1S,opS); mode=(inst & 448)>>6; reg=(inst & 3584) >> 9;
eff1(); strcpy(op2S,opS);
}
op0100()
{ if (hibyte & 1) op0100xxx1(); else op0100xxx0();
}
op0100xxx0()
{ int flag=1, lb240;
switch (lonib)
{ case 0: if (L76==3) { strcpy(instS,"move"); strcpy(op1S,"sr");
eff(); strcpy(op2S,opS); }
else {strcpy(instS,"negx"); sizeff(); strcpy(op1S,opS); }
break;
case 2: if (L76==3) {strcpy(instS,"move"); strcpy(op1S,"ccr");
eff(); strcpy(op2S,opS); }
else { strcpy(instS,"clr"); sizeff(); strcpy(op1S,opS);}
break;
case 4: if (L76==3) { strcpy(instS,"move"); eff(), strcpy(op1S,opS);
strcpy(op2S,"ccr"); }
else { strcpy(instS,"neg"); sizeff(); strcpy(op1S,opS); }
break;
case 6: if (L76==3) {strcpy(instS,"move"); eff(); strcpy(op1S,opS);
strcpy(op2S,"sr"); }
else {strcpy(instS,"not"); sizeff(); strcpy(op1S,opS);}
break;
case 8: op01001000(); break;
case 10: op01001010(); break;
case 12: movem(); break;
default: flag=0;
}
if (flag) return;
lb240=lobyte & 240;
switch (lb240)
{ case 64: strcpy(instS,"trap"); sprintf(op1S,"#%d",lobyte&15); break;
case 80: op1S[0]='a'; op1S[1]=48+(lobyte&7); op1S[2]='\0';
if (lobyte & 8) strcpy(instS,"unlk");
else { strcpy(instS,"link"); i+=2;
wp=(short *)&p[i]; sprintf(op2S,"#%d",*wp); }
break;
case 96: strcpy(instS,"move");
opS[0]='a'; opS[1]=48+(lobyte&7); opS[2]='\0';
if (lobyte & 8) { strcpy(op1S,"usp"); strcpy(op2S,opS); }
else { strcpy(op1S,opS); strcpy(op2S,"usp"); }
break;
default: flag=1;
}
if (!flag) return;
switch (lobyte)
{ case 112: strcpy(instS,"reset"); break;
case 113: strcpy(instS,"nop"); break;
case 114: strcpy(instS,"stop"); wp=(short *)&p[i+2];
sprintf(op1S,"#%d",*wp); i+=2; break;
case 115: strcpy(instS,"rte"); break;
case 116: strcpy(instS,"rtd"); i+=2; wp=(short *)&p[i];
sprintf(op1S,"#%d",*wp);break;
case 117: strcpy(instS,"rts"); break;
case 118: strcpy(instS,"trapv"); break;
case 119: strcpy(instS,"rtr"); break;
case 122: strcpy(instS,"movec"); i+=2; movec();
strcpy(op2S,opS); break;
case 123: strcpy(instS,"movec"); i+=2; movec(); strcpy(op2S,op1S);
strcpy(op1S,opS); break;
default: flag=0;
}
if (flag) return;
if (L76==2) { strcpy(instS,"jsr"); eff(); strcpy(op1S,opS); return; }
if (L76==3) { strcpy(instS,"jmp"); eff(); strcpy(op1S,opS); }
}
movec()
{ int contreg;
if (p[i]&128) opS[0]='a'; else opS[0]='d';
opS[1]=48 + ((p[i] & 112) >> 4);
opS[2]='\0';
wp=(short *)&p[i]; contreg=(*wp)&4095;
switch (contreg)
{ case 0: strcpy(op1S,"sfc"); break;
case 1: strcpy(op1S,"dfc"); break;
case 2048: strcpy(op1S,"usp"); break;
case 2049: strcpy(op1S,"vbr"); break;
}
}
op0100xxx1()
{ if (L76==2) { strcpy(instS,"chk"); dreg(); }
if (L76==3) { strcpy(instS,"lea"); areg(); }
eff(); strcpy(op1S,opS); strcpy(op2S,reg1S); return;
}
op01001000()
{ if (!L76) {strcpy(instS,"nbcd"); eff(); strcpy(op1S,opS); return; }
if ((L76==1) && (!(lobyte & 56))) strcpy(instS,"swap");
else strcpy(instS,"pea");
if (L76==1) { eff(); strcpy(op1S,opS); return; }
if (!(lobyte&56)) { strcpy(instS,"ext");
if (L76==2) strcat(instS,".w");
else if (L76==3) strcat(instS,".l");
op1S[0]='d'; op1S[1]=48+(lobyte&7);
op1S[2]='\0'; return; }
movem();
}
op01001010()
{ if (lobyte==252) { strcpy(instS,"illegal"); return; }
if (L76==3) { strcpy(instS,"tas"); eff(); strcpy(op1S,opS); return; }
strcpy(instS,"tst"); sizeff(); strcpy(op1S,opS);
}
movem()
{ char rdS[20], raS[20], registerlistS[20];
register j;
int bm, bm1=0;
if (lobyte & 64) strcpy(instS,"movem.l"); else strcpy(instS,"movem.w");
eff();
i+=2; wp=(short *)&p[i]; bm=*wp;
registerlistS[0]='d'; registerlistS[1]='\0';
if (mode==4)
{ for (j=0; j<16; j++) if (bm & 1<<j) bm1= bm1 | 1<<(15-j);
bm=bm1; }
rdS[1]='\0';
for (j=0;j<8;j++)
if (bm & 1<<j) { rdS[0]=48 + j; strcat(registerlistS,rdS); }
if (strlen(registerlistS) < 2) registerlistS[0]='\0';
rdS[0]='a'; rdS[1]='\0';
raS[1]='\0';
for (j=8;j<16;j++)
if (bm & 1<<j) { raS[0]=40+j; strcat(rdS,raS); }
if (strlen(rdS) > 2) strcat(registerlistS,rdS);
if (lonib==8) { strcpy(op1S,registerlistS); strcpy(op2S,opS); }
else { strcpy(op1S,opS); strcpy(op2S,registerlistS); }
}
op0101()
{ int quick;
if (L76==3) { strcpy(instS,ccS[lonib]);
if ((lobyte&56)==8) { dbcc(); return; }
else { strcpy(opS,"s"); strcat(opS,instS); strcpy(instS,opS);
eff(); strcpy(op1S,opS); return; }
}
if (lonib & 1) strcpy(instS,"subq"); else strcpy(instS,"addq");
sizeff(); strcpy(op2S,opS);
quick=(lonib & 14) >> 1;
if (!quick) quick=8;
op1S[0]='#'; op1S[1]=48+quick; op1S[2]='\0';
}
dbcc()
{ if (lonib==1) strcpy(instS,"dbra");
else { strcpy(opS,"db"); strcat(opS,instS); strcpy(instS,opS); }
op1S[0]='d'; op1S[1]=48 + (lobyte & 7); op1S[2]='\0';
i+=2; figurelabel(); sprintf(op2S,"%d",*wp);
strcat(op2S,opS);
}
op0110()
{ if (!lonib) strcpy(instS,"bra");
else if (lonib==1) strcpy(instS,"bsr");
else { strcpy(instS,"b"); strcat(instS,ccS[lonib]);}
if (!lobyte) { i+=2; strcat(instS,".w"); figurelabel();
sprintf(op1S,"%d%s",*wp,opS); return; }
strcat(instS,".s");
sprintf(op1S,"%d (%ld)",p[i+1],iold + 2 + p[i+1]);
}
figurelabel()
{ wp=(short *)&p[i];
sprintf(opS," (%ld)",iold + 2 + *wp);
}
op0111()
{ strcpy(instS,"moveq"); sprintf(op1S,"#%d",p[i+1]);
dreg(); strcpy(op2S,reg1S);
}
op1000()
{ if (L76==3) { if (hibyte & 1) strcpy(instS,"divs");
else strcpy(instS,"divu");
size=1; dreg(); eff(); strcpy(op1S,opS);
strcpy(op2S, reg1S); return; }
if (hibyte & 1) { if (!(lobyte & 48)) { strcpy(instS,"sbcd"); dreg();
if (lobyte & 8) { sprintf(op1S,"-(a%d)",lobyte & 7);
sprintf(op2S,"-(a%d)",reg1); }
else { sprintf(op1S,"d%d",lobyte & 7);
strcpy(op2S,reg1S); }
}
else { strcpy(instS,"or"); dreg(); sizeff();
strcpy(op1S,reg1S); strcpy(op2S,opS); }
}
else { strcpy(instS,"or"); dreg(); sizeff();
strcpy(op1S,opS); strcpy(op2S,reg1S); }
}
op1001()
{ if (L76==3) { if (lonib & 1) { strcpy(instS,"suba.l"); size=2; }
else {strcpy(instS,"suba.w"); size=1; }
areg(); eff(); strcpy(op1S,opS); strcpy(op2S,reg1S); return; }
if (!(lonib & 1)) { strcpy(instS,"sub"); dreg(); sizeff();
strcpy(op1S,opS); strcpy(op2S,reg1S); }
if (lonib & 1) { if (!(lobyte & 48)) { strcpy(instS,"subx");
sizef(); dreg();
if (lobyte & 8) { sprintf(op1S,"-(a%d)",lobyte & 7);
sprintf(op2S,"-(a%d)",reg1); }
else { sprintf(op1S,"d%d",lobyte & 7);
strcpy(op2S,reg1S); }
}
else { strcpy(instS,"sub"); sizeff(); dreg();
strcpy(op1S,reg1S); strcpy(op2S,opS); }
}
}
op1011()
{ if (L76==3) { strcpy(instS,"cmpa");
if (lonib & 1) { size=2; strcat(instS,".l"); }
else { size=1; strcat(instS,".w"); }
areg(); eff(); strcpy(op1S,opS); strcpy(op2S,reg1S); return; }
if (lonib & 1) { mode=(lobyte & 56) >> 3;
if (mode==1) { strcpy(instS,"cmpm"); sizeff(); dreg();
sprintf(op1S,"(%s)+",opS);
sprintf(op2S,"(a%d)+",reg1); }
else { strcpy(instS,"eor"); sizeff(); dreg();
strcpy(op1S,reg1S); strcpy(op2S,opS); }
}
else { strcpy(instS,"cmp"); sizeff(); dreg();
strcpy(op1S,opS); strcpy(op2S,reg1S); }
}
op1100()
{ if (L76==3) {
if (lonib & 1) strcpy(instS,"muls"); else strcpy(instS,"mulu");
size=1; dreg(); eff(); strcpy(op1S,opS); strcpy(op2S,reg1S); return; }
if (!(lonib & 1)) { strcpy(instS,"and"); dreg(); sizeff();
strcpy(op1S,opS); strcpy(op2S,reg1S); return; }
if (!(lobyte & 48)) {
if (!L76) { strcpy(instS,"abcd"); dreg(); eff();
if (mode==1) { sprintf(op1S,"-(%s)",opS);
sprintf(op2S,"-(a%d)",reg1); return; }
else { strcpy(op1S,opS); strcpy(op2S,reg1S); return; }
}
strcpy(instS,"exg"); eff(); dreg();
if (L76==2) { strcpy(op1S,reg1S); strcpy(op2S,opS); return; }
if (mode==1) { strcpy(op1S,opS); sprintf(op2S,"a%d",reg1); }
else { strcpy(op1S,opS); strcpy(op2S,reg1S); }
return;
}
strcpy(instS,"and"); dreg(); sizeff();
strcpy(op1S,reg1S); strcpy(op2S,opS);
}
op1101()
{ if (L76==3) { strcpy(instS,"adda");
if (lonib & 1) { size=2; strcat(instS,".l"); }
else { size=1; strcat(instS,".w"); }
areg(); eff(); strcpy(op1S,opS); strcpy(op2S,reg1S); return;
}
if (!(lonib & 1)) { strcpy(instS,"add"); dreg(); sizeff();
strcpy(op1S,opS); strcpy(op2S,reg1S); return; }
if (lobyte & 48) {strcpy(instS,"add"); sizeff(); dreg();
strcpy(op1S,reg1S); strcpy(op2S,opS); return; }
strcpy(instS,"addx"); sizeff(); dreg();
if (mode==1) { sprintf(op1S,"-(%s)",opS); sprintf(op2S,"-(a%d)",reg1); }
else { strcpy(op1S,opS); strcpy(op2S,reg1S); }
}
op1110()
{ int sh;
if (L76==3) { sprintf(instS,"%s.w",shiftS[lonib]); eff();
strcpy(op1S,opS); return; }
dreg(); sprintf(op2S,"d%d",lobyte & 7);
sh= ((lobyte & 24) >> 2) + (lonib & 1);
strcpy(instS,shiftS[sh]);
sizef();
if (lobyte & 32) { strcpy(op1S,reg1S); return; }
if (!reg1) reg1=8;
sprintf(op1S,"#%d",reg1);
}
genasc()
{ int asc, k=0;
for (ii=iold; ii<i; ii++)
{ asc=p[ii];
if ((asc>31) && (asc<127)) ascS[k++]=asc; else ascS[k++]=166;
}
ascS[k]='\0';
}
genobj()
{ int hinib, lonib, k=0;
for (ii=iold; ii<i; ii++)
{ hinib=p[ii]&255; lonib=hinib & 15; hinib=hinib >> 4;
if (lonib<10) lonib=48+lonib; else lonib=55+lonib;
if (hinib<10) hinib=48+hinib; else hinib=55+hinib;
objS[k++]=hinib; objS[k++]=lonib; objS[k++]=' ';
}
objS[k]='\0';
}
main(argc, argv)
int argc;
char **argv;
{ register long maxi=0, line=0;
register char ch;
FILE *fromfile, *tofile;
unsigned int hinib;
char *fromname, *toname, outname[40];
if (argc < 2 || argc > 3)
{
printf("Useage: disass fromfile <tofile>\n");
printf("If tofile omitted, output will be directed to monitor.\n");
printf("If tofile specified, .asm will be appended to tofile.\n");
printf("\nWarning!! Output file may be about 13 times as big as \n");
printf("input file. Make sure you have enough memory.\n");
printf("Maximum input file size set for 20,000 bytes.\n");
printf("For maximum speed, send output to ram:.\n");
exit(4);
}
fromfile = fopen(argv[1], "r");
if (fromfile == NULL )
{
printf("Can't open: %s\n", argv[1]);
exit(4);
}
if (argc==3)
{ sprintf(outname,"%s.asm",argv[2]);
tofile = fopen(outname, "w");
if (tofile == NULL )
{ printf("Can't open: %s\n", argv[2]);
exit(4); }
printf("%s opened\n",argv[2]);
fprintf(tofile,"PC\tINST\tOPERANDS\t\tASCII\t HEX\n");
}
printf("Reading %s\n",argv[1]);
ch=fgetc(fromfile);
while (!feof(fromfile) && maxi<maxfile)
{
p[maxi++]=ch;
ch=fgetc(fromfile);
}
printf("number of bytes loaded %ld\n\n",maxi);
fclose( fromfile); printf("Input file %s closed.\n\n",argv[1]);
do
{ printf("Enter a starting PC (program counter) between 0 and %ld ",maxi-2);
fflush(stdout);
scanf("%ld",&i); }
while (i<0 || i>maxi-2);
if (i%2) i--; /* only even PC allowed */
if (argc==2) printf("\nPC\tINST\tOPERANDS\t\tASCII\t HEX\n");
tab();
while (i<maxi)
{ /* main loop */
iold=i;
hibyte=p[i]&255; lobyte=p[i+1]&255;
L76=lobyte>>6&15;
hinib=hibyte>>4; lonib=hibyte&15;
instS[0]='\0'; op1S[0]='\0'; op2S[0]='\0'; /* initialize strings */
switch (hinib)
{ case 0: op0000(); break;
case 1: op0001(); break;
case 2: op0010(); break;
case 3: op0011(); break;
case 4: op0100(); break;
case 5: op0101(); break;
case 6: op0110(); break;
case 7: op0111(); break;
case 8: op1000(); break;
case 9: op1001(); break;
/* no case 10 or 15 */
case 11: op1011() ; break;
case 12: op1100() ; break;
case 13: op1101() ; break;
case 14: op1110() ; break;
default: strcpy(instS,"INVALID");
} /* end of switch */
if (strlen(op1S)) if (strlen(op2S))
{ strcpy(opS,","); strcat(opS,op2S); strcat(op1S,opS); }
if (argc==2)
{ i+=2;
printf("%5ld\t%s\t%s%s",iold,instS,op1S,spS[strlen(op1S)]);
genasc();
genobj();
if (i-iold>6) printf("%s %s\n",ascS,objS);
else printf("%s\t%s\n",ascS,objS);
}
else
{ if (!(++line % 100)) printf("%ld\r",line);
i+=2;
fprintf(tofile,"%5ld\t%s\t%s%s",iold,instS,op1S,spS[strlen(op1S)]);
genasc();
genobj();
if (i-iold>6) fprintf(tofile,"%s %s\n",ascS,objS);
else fprintf(tofile,"%s\t%s\n",ascS,objS);
}
} /* end of main while loop */
if (argc==3)
{ fclose( tofile );
printf("\nFinished. Output file %s closed.\n",outname); }
exit(0);
}