home *** CD-ROM | disk | FTP | other *** search
- /* (c) 1990 Martin Combs */
- /* Edited by Steve Hawtin to use as part of the dump program
-
- This file defines the function
-
- void
- disass(length,fptr)
- int length;
- FILE *fptr;
-
- this function will read the next "length" elements of the file using the
- function my_fread() and will create a disassembly listing using the
- function my_printf() to print the data out.
- */
-
- #include <stdio.h>
- #include <ctype.h>
-
- typedef void (*voidfun)();
-
- #ifdef NEED_MAIN
- #define maxfile 20000
-
- #endif
-
- long i, iold;
- long *lp;
- unsigned int hibyte, lobyte, lonib, L76, mode, reg, reg1, size;
- short *wp;
- char *p;
- char instS[40], opS[20], op1S[40], op2S[20], ascS[20];
- char objS[40];
- char reg1S[4];
- 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"
- };
-
- 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:
- sprintf(opS,"d%d",reg);
- break;
- case 1:
- sprintf(opS,"a%d",reg);
- break;
- case 2:
- sprintf(opS,"(a%d)",reg);
- break;
- case 3:
- sprintf(opS,"(a%d)+",reg);
- break;
- case 4:
- sprintf(opS,"-(a%d)",reg);
- 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[6];
-
- sprintf(regS,"%c%d.%c)",(p[i]&128)?'a':'d',((p[i] & 0x70) >> 4),
- (p[i]&8)?'l':'w');
- strcat(opS,regS);
- }
-
- 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,"#$%x",p[i+1]); break;
- case 1: i+=2; wp=(short *)&p[i];
- sprintf(opS,"#$%x",*wp); break;
- case 2: i+=4; lp=(long *)&p[i-2];
- sprintf(opS,"#$%lx",*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;
- }
-
- 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);
- }
-
- 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;
- }
- }
-
- movem()
- {char rdS[20], registerlistS[30];
- register j;
- int bm, bm1=0;
- int state = 0;
-
- if (lobyte & 64)
- strcpy(instS,"movem.l");
- else
- strcpy(instS,"movem.w");
- eff();
- i+=2;
- wp=(short *)&p[i];
- bm=*wp;
-
- registerlistS[0] = '\0';
-
- /* Scan the bits to see which registers we have */
- for(j=0;j<16;++j)
- {/* Look at this bit */
- if(state==0 && (bm & 1<<(15-j)))
- {/* We have a register */
- sprintf(rdS,registerlistS[0]=='\0'?"%c%d":"/%c%d",
- j>=8?'a':'d',j%8);
- strcat(registerlistS,rdS);
- state = 1;
- }
- else if (state == 1)
- {if((bm & 1<<(15-j))==0)
- state = 0;
- else if (j==7 || j==15 || (bm & 1<<(14-j))==0)
- {/* So this is the last of a set */
- sprintf(rdS,"-%c%d",j>=8?'a':'d',j%8);
- strcat(registerlistS,rdS);
- state = 0;
- }
- }
- }
- if (lonib==8)
- {strcpy(op1S,registerlistS);
- strcpy(op2S,opS);
- }
- else
- {strcpy(op1S,opS);
- strcpy(op2S,registerlistS);
- }
- }
-
- 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);
- }
-
- figurelabel()
- { wp=(short *)&p[i];
- sprintf(opS," ($%lx)",iold + 2 + *wp);
- }
-
- genasc()
- {int asc, ii, k=0;
- for (ii=iold; ii<i; ii++)
- {asc=p[ii];
- if (isprint(asc) && !(asc & 0x80))
- ascS[k++]=asc;
- else
- ascS[k++]='.';
- }
- ascS[k]='\0';
- }
-
- genobj()
- {/* Print out the object code as hex numbers */
- int ii;
- char pr[4];
-
- objS[0] = '\0';
- for (ii=0; (ii+iold)<i; ii++)
- {
- sprintf(pr,"%02x",p[ii+iold] & 0xff);
- strcat(objS,pr);
- if(ii%2)
- strcat(objS," ");
- }
- }
-
- void
- opinvalid()
- {
- strcpy(instS,"INVALID");
- }
-
- void
- op0000xxx0()
- { if (hibyte==8)
- { binst(); i+=2; sprintf(op1S,"#$%x",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,"#$%x",p[i+3]&255); break;
- case 1: wp=(short *)&p[i+2]; sprintf(op1S,"#$%x",*wp); break;
- case 2: i+=2; lp=(long *)&p[i]; sprintf(op1S,"#$%lx",*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);
- }
-
- void
- op0000xxx1()
- { if ((lobyte & 56)==8) { movep();return;}
- binst();
- dreg();
- strcpy(op1S,reg1S);
- eff();
- strcpy(op2S,opS);
- }
-
- void
- op0000()
- {
- if (hibyte&1) op0000xxx1(); else op0000xxx0();
- }
-
- void
- op0001()
- { strcpy(instS,"move.b"); size=0; move();
- }
-
- void
- op0010()
- { size=2; move();
- }
-
- void
- op0011()
- { size=1; move();
- }
-
- void
- 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();
- }
-
- void
- 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);
- }
-
- void
- op0100xxx0()
- {
- 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);
- }
- return;
- case 2:
- if (L76==3)
- {strcpy(instS,"move");
- strcpy(op1S,"ccr");
- eff();
- strcpy(op2S,opS);
- }
- else
- {strcpy(instS,"clr");
- sizeff();
- strcpy(op1S,opS);
- }
- return;
- case 4:
- if (L76==3)
- {strcpy(instS,"move");
- eff();
- strcpy(op1S,opS);
- strcpy(op2S,"ccr");
- }
- else
- {strcpy(instS,"neg");
- sizeff();
- strcpy(op1S,opS);
- }
- return;
- case 6:
- if (L76==3)
- {strcpy(instS,"move");
- eff();
- strcpy(op1S,opS);
- strcpy(op2S,"sr");
- }
- else
- {strcpy(instS,"not");
- sizeff();
- strcpy(op1S,opS);
- }
- return;
- case 8:
- op01001000();
- return;
- case 10:
- op01001010();
- return;
- case 12:
- movem();
- return;
- }
- switch (lobyte & 0xF0)
- {case 64:
- strcpy(instS,"trap");
- sprintf(op1S,"#$%x",lobyte&15);
- return;
- case 80:
- sprintf(op1S,"a%d",lobyte & 7);
- if (lobyte & 8)
- strcpy(instS,"unlk");
- else
- {strcpy(instS,"link");
- i+=2;
- wp=(short *)&p[i];
- sprintf(op2S,"#$%x",*wp);
- }
- return;
- case 96:
- strcpy(instS,"move");
- sprintf(opS,"a%d",lobyte & 7);
- if (lobyte & 8)
- {strcpy(op1S,"usp");
- strcpy(op2S,opS);
- }
- else
- {strcpy(op1S,opS);
- strcpy(op2S,"usp");
- }
- return;
- }
- switch (lobyte)
- {case 112:
- strcpy(instS,"reset");
- return;
- case 113: strcpy(instS,"nop");
- return;
- case 114: strcpy(instS,"stop"); wp=(short *)&p[i+2];
- sprintf(op1S,"#$%x",*wp); i+=2;
- return;
- case 115: strcpy(instS,"rte"); break;
- return;
- case 116: strcpy(instS,"rtd"); i+=2; wp=(short *)&p[i];
- sprintf(op1S,"#$%x",*wp);
- return;
- case 117: strcpy(instS,"rts");
- return;
- case 118: strcpy(instS,"trapv");
- return;
- case 119: strcpy(instS,"rtr");
- return;
- case 122: strcpy(instS,"movec"); i+=2; movec();
- strcpy(op2S,opS);
- return;
- case 123: strcpy(instS,"movec"); i+=2; movec(); strcpy(op2S,op1S);
- strcpy(op1S,opS);
- return;
- }
- if (L76==2)
- {strcpy(instS,"jsr");
- eff();
- strcpy(op1S,opS);
- }
- else if (L76==3)
- {strcpy(instS,"jmp");
- eff();
- strcpy(op1S,opS);
- }
- else
- opinvalid();
- }
-
- void
- op0100xxx1()
- {if (L76==2)
- {strcpy(instS,"chk");
- dreg();
- }
- else if (L76==3)
- {strcpy(instS,"lea");
- areg();
- }
- else
- opinvalid();
- eff();
- strcpy(op1S,opS);
- strcpy(op2S,reg1S);
- }
-
- void
- op0100()
- { if (hibyte & 1) op0100xxx1(); else op0100xxx0();
- }
-
- void
- 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';
- }
-
- void
- 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,"%-5d ($%lx)",p[i+1],iold + 2 + p[i+1]);
- }
-
- void
- op0111()
- {strcpy(instS,"moveq");
- sprintf(op1S,"#%d",p[i+1]);
- dreg();
- strcpy(op2S,reg1S);
- }
-
- void
- 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); }
- }
-
- void
- 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); }
- }
- }
-
- void
- 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); }
- }
-
- void
- 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);
- }
-
- void
- 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); }
- }
-
- void
- 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,"#$%x",reg1);
- }
-
- voidfun opxxxx[16] =
- {op0000,op0001,op0010,op0011,
- op0100,op0101,op0110,op0111,
- op1000,op1001,opinvalid,op1011,
- op1100,op1101,op1110,opinvalid
- };
-
- void
- disass(length,fptr)
- int length;
- FILE *fptr;
- {
- unsigned int hinib;
-
- i = 0;
- p = calloc(length,sizeof(long));
- if(p==NULL)
- {my_printf("malloc failed\n");
- exit(20);
- }
- my_fread(p,length*sizeof(long),fptr);
-
- while (i<length*sizeof(long))
- { /* main loop */
- iold=i;
- hibyte=p[i]&255;
- lobyte=p[i+1]&255;
- L76=lobyte>>6&15;
- hinib=hibyte>>4;
- lonib=hibyte&15;
- /* initialize strings */
- instS[0]='\0';
- op1S[0]='\0';
- op2S[0]='\0';
- /* Call the function selected by the hi nibble */
- (*opxxxx[hinib])();
- /* If there were two ops then concatenate them */
- if (strlen(op1S))
- if (strlen(op2S))
- {strcpy(opS,",");
- strcat(opS,op2S);
- strcat(op1S,opS);
- }
- i+=2;
- my_printf(" %4lx: %-7s %-24s",iold,instS,op1S);
- genasc();
- genobj();
- my_printf("%-16s %s\n",objS,ascS);
- }
- /* Now free the storage we loaded the code into */
- free(p);
- }
-
- #ifdef NEED_MAIN
- 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);
- }
-
- disass();
-
- if (argc==3)
- { fclose( tofile );
- printf("\nFinished. Output file %s closed.\n",outname); }
- exit(0);
- }
- #endif
-