home *** CD-ROM | disk | FTP | other *** search
- /*
- MIPS disassembler
- =================
-
- Written by BERO
- */
-
- #include "fpse.h"
-
- static char *regname[32] = {
- "zero","at","v0","v1","a0","a1","a2","a3",
- "t0","t1","t2","t3","t4","t5","t6","t7",
- "s0","s1","s2","s3","s4","s5","s6","s7",
- "t8","t9","k0","k1","gp","sp","fp","ra"
- };
-
- static char *cop0regname[32] = {
- /* from mips 4400 manual
- "Index","Random","EntryLo0","EntryLo1","Context","PageMask","Wired","$7",
- "BadVAddr","Count","EntryHi","Compare","Status","Cause","EPC","PRId",
- "Config","LLAddr","WatchLo","WatchHi","XContext","$21","$22","$23",
- "$24","$25","ECC","CacheErr","TagLo","TagHi","ErrorEPC","$31"
- */
- "INDEX","RAND","TLBL","BPC","CTXT","BDA","TAR","DCIC",
- "BADV","BDAM","TLBH","BPCM","SR","CAUSE","EPC","PRID",
- "ERREG","$17","$18","$19","$20","$21","$22","$23",
- "$24","$25","$26","$27","$28","$29","$30","$31"
- };
-
- static char *cop2cregname[32] = {
- "R11R12","R13R21","R22R23","R31R32","R33","TRX","TRY","TRZ",
- "L11L12","L13L21","L22L23","L31L32","L33","RBK","GBK","BBK",
- "LR1LR2","LR3LG1","LG2LG3","LB1LB2","LB3","RFC","GFC","BFC",
- "OFX","OFY","H","DQA","DQB","ZSF3","ZSF4","FLAG"
- };
-
- static char *cop2regname[32] = {
- "VXY0","VZ0","VXY1","VZ1","VXY2","VZ2","RGB","OTZ",
- "IR0","IR1","IR2","IR3","SXY0","SXY1","SXY2","SXYP",
- "SZ0","SZ1","SZ2","SZ3","RGB0","RGB1","RGB2","RES1",
- "MAC0","MAC1","MAC2","MAC3","IRGB","ORGB","LZCS","LZCR"
- };
-
- static char *cregname[32] = {
- "$0","$1","$2","$3","$4","$5","$6","$7",
- "$8","$9","$10","$11","$12","$13","$14","$15",
- "$16","$17","$18","$19","$20","$21","$22","$23",
- "$24","$25","$26","$27","$28","$29","$30","$31"
- };
-
- static char *nemonic[64] = {
- "special","bcond","j","jal","beq","bne","blez","bgtz",
- "addi","addiu","slti","sltiu","andi","ori","xori","lui",
- "cop0","cop1","cop2","cop3","","","","",
- "","","","","","","","",
- "lb","lh","lwl","lw","lbu","lhu","lwr","",
- "sb","sh","swl","sw","","","swr","",
- "lwc0","lwc1","lwc2","lwc3","","","","",
- "swc0","swc1","swc2","swc3","","","",""
- };
-
- static char *special[64] = {
- "sll","","srl","sra","sllv","","srlv","srav",
- "jr","jalr","","","syscall","break","","",
- "mfhi","mthi","mflo","mtlo","","","","",
- "mult","multu","div","divu","","","","",
- "add","addu","sub","subu","and","or","xor","nor",
- "","","slt","sltu","","","","",
- "","","","","","","","",
- "","","","","","","",""
- };
-
- static char *bcond[32] = {
- "bltz","bgez","","","","","","",
- "","","","","","","","",
- "bltzal","bgezal","","","","","","",
- "","","","","","","",""
- };
-
- static char *cop[16] = {
- "mfc","","cfc","","mtc","","ctc","",
- "bc","","","","bc","","",""
- };
-
- static char *cop0[32] = {
- "","tlbr","tlbwi","","","","tlbwr","",
- "tlbp","","","","","","","",
- "rfe","","","","","","","",
- "","","","","","","",""
- };
-
- #define MASK(from,n) (((1<<(n))-1)<<(from))
- #define CHECK(a)
-
- #define rdna regname[rdno]
- #define rtna regname[rtno]
- #define rsna regname[rsno]
-
- int dumpreg = 1;
- int rlist[4] = { 0,0,0,0 };
-
- #ifndef MAKEDIS
- void watch(int num)
- {
- int i;
-
- if (num < 0) {
- for(i=0;i<32;i++)
- printf("%-4s = %08x ",regname[i],(int)reg.r[i]);
- printf("\n");
- } else printf("%-4s = %08x\n",regname[num],(int)reg.r[num]);
- }
-
- void watchcop(int num)
- {
- int i;
-
- switch (num) {
- case 2:
- for(i=0;i<32;i++)
- printf("%-4s = %08x ",cop2cregname[i],(int)reg.ccr2[i]);
- break;
- case 3:
- for(i=0;i<32;i++)
- printf("%-4s = %08x ",cop2regname[i],(int)reg.cpr2[i]);
- break;
- }
- printf("\n");
- }
-
- static int reduce(int n)
- {
- int x,y;
-
- for (x=0;x<n;)
- {
- if (rlist[x]==0 || rlist[x+1]==rlist[x]) {
- for (y=x;y<n;y++) rlist[y] = rlist[y+1];
- n--;
- } else x++;
- }
- return n;
- }
- #endif
-
- #ifdef MAKEDIS
- #define DUMPREG(r1,r2,r3)
- #else
- #define DUMPREG(r1,r2,r3) if (dumpreg) { \
- int nreg; \
- rlist[0] = r1; \
- rlist[1] = r2; \
- rlist[2] = r3; \
- nreg = reduce(3); \
- while (nreg--) \
- sprintf(buf,"%s %s=%08x",buf, \
- regname[rlist[nreg]], \
- (int)reg.r[rlist[nreg]]); \
- }
- #endif
-
- void disasm(char *buf, UINT32 code, UINT32 addr)
- {
- int op,func; // ,rs,rt,rd,immS;
-
- if (!code) {
- strcpy(buf,"nop");
- return;
- }
-
- op = code>>26;
- /* rs = (code>>21)&31;
- rt = (code>>16)&31;
- rd = (code>>11)&31;
- immS = (short)code;
- */
- switch(op){
- case SPECIAL:
- func = code&63;
- switch(func){
- case SLL:
- case SRL:
- case SRA:
- CHECK(rsno) /* err */
- sprintf(buf,"%-5s %s,%s,%d\t",
- special[func],rdna,rtna,(int)((code>>6)&31));
- DUMPREG(rdno,rtno,0)
- break;
- case SLLV:
- case SRLV:
- case SRAV:
- CHECK(code & MASK(6,5)) /* err */
- sprintf(buf,"%-5s %s,%s,%s\t",special[func],rdna,rtna,rsna);
- DUMPREG(rdno,rtno,rsno)
- break;
- case JR:
- CHECK(code & MASK(6,15)) /* err */
- sprintf(buf,"%-5s %s\t\t",special[func],rsna);
- DUMPREG(rsno,0,0)
- break;
- case JALR:
- CHECK(code & (MASK(6,5)|MASK(16,5))) /* err */
- sprintf(buf,"%-5s %s,%s\t",special[func],rsna,rdna);
- DUMPREG(rdno,rsno,0)
- break;
- case SYSCALL:
- case BREAK:
- sprintf(buf,"%-5s %08x",special[func],(int)((code>>6)&0xfffff));
- break;
- case MFHI:
- case MFLO:
- CHECK(code & (MASK(6,5)|MASK(16,10))) /* err */
- sprintf(buf,"%-5s %s\t",special[func],rdna);
- DUMPREG(rdno,0,0)
- break;
- case MTHI:
- case MTLO:
- CHECK(code & MASK(6,15)) /* err */
- sprintf(buf,"%-5s %s\t",special[func],rsna);
- DUMPREG(rsno,0,0)
- break;
- case MULT:
- case MULTU:
- case DIV:
- case DIVU:
- CHECK(code & MASK(6,10)) /* error */
- sprintf(buf,"%-5s %s,%s\t",special[func],rsna,rtna);
- DUMPREG(rsno,rtno,0)
- break;
- case ADD:
- case ADDU:
- case SUB:
- case SUBU:
- case AND:
- case OR:
- case XOR:
- case NOR:
- case SLT:
- case SLTU:
- CHECK(code & MASK(6,5)) /* err */
- sprintf(buf,"%-5s %s,%s,%s\t",special[func],rdna,rsna,rtna);
- DUMPREG(rdno,rtno,rsno)
- break;
- default:
- strcpy(buf,"unknown special");
- break;
- }
- break;
- case BCOND:
- sprintf(buf,"%-5s %s,%08x\t",bcond[rtno],rsna,(int)(addr+(immS+1)*4));
- DUMPREG(rsno,0,0)
- break;
- case J:
- case JAL:
- sprintf(buf,"%-5s %08x",nemonic[op],(int)((addr&0xf0000000)|(code&0x3ffffff)*4));
- break;
- case BEQ:
- case BNE:
- sprintf(buf,"%-5s %s,%s,%08x\t",nemonic[op],rsna,rtna,(int)(addr+(immS+1)*4));
- DUMPREG(rsno,rtno,0)
- break;
- case BLEZ:
- case BGTZ:
- CHECK(rtno) /* err */
- sprintf(buf,"%-5s %s,%08x\t",nemonic[op],rsna,(int)(addr+(immS+1)*4));
- DUMPREG(rsno,0,0)
- break;
- case ADDI:
- case ADDIU:
- case SLTI:
- case SLTIU:
- case ANDI:
- case ORI:
- case XORI:
- case LUI:
- sprintf(buf,"%-5s %s,%s,%d\t# %04x",nemonic[op],rtna,rsna,(int)immS,(int)(code&0xffff));
- DUMPREG(rsno,0,0)
- break;
- case COP0:
- if (rsno&0x10) {
- CHECK(code && MASK(5,20)) /* err */
- sprintf(buf,"%s",cop0[code&31]);
- } else {
- CHECK(code & MASK(0,11)) /* err */
- switch(rsno) {
- case MFC:
- case MTC:
- sprintf(buf,"%s0 %s,%s",cop[rsno],rtna,cop0regname[rdno]);
- break;
- case CFC:
- case CTC:
- sprintf(buf,"%s0 %s,%s",cop[rsno],rtna,cregname[rdno]);
- break;
- }
- }
- break;
- case COP2:
- if (rsno&0x10) {
- sprintf(buf,"cop%d %08x",op&3,(int)(code&0x1ffffff));
- } else {
- CHECK(code & MASK(0,11)) /* err */
- switch(rsno) {
- case MFC:
- case MTC:
- sprintf(buf,"%s2 %s,%s",cop[rsno],rtna,cop2regname[rdno]);
- break;
- case CFC:
- case CTC:
- sprintf(buf,"%s2 %s,%s",cop[rsno],rtna,cop2cregname[rdno]);
- break;
- }
- }
- break;
- case LB:
- case LH:
- case LWL:
- case LW:
- case LBU:
- case LHU:
- case LWR:
- case SB:
- case SH:
- case SWL:
- case SW:
- case SWR:
- sprintf(buf,"%-5s %s,%d(%s)\t",nemonic[op],rtna,immS,rsna);
- DUMPREG(rsno,0,0)
- break;
- case LWC0:
- case SWC0:
- sprintf(buf,"%-5s %s,%d(%s)",nemonic[op],cop0regname[rtno],(int)immS,rsna);
- break;
- case SWC2:
- case LWC2:
- sprintf(buf,"%-5s %s,%d(%s)",nemonic[op],cop2regname[rtno],(int)immS,rsna);
- break;
- case LWC1:
- case LWC3:
- case SWC1:
- case SWC3:
- sprintf(buf,"%-5s %s,%d(%s)",nemonic[op],cregname[rtno],(int)immS,rsna);
- break;
- default:
- strcpy(buf,"unknown");
- break;
- }
- }
-
- #ifdef MAKEDIS
-
- int main(int argc,char *argv[])
- {
- FILE *fp;
- char *buf,*mem;
- UINT32 addr,startaddr,fsize;
- int i;
- // char inputbuf[256];
-
- EXE_HEADER *head;
- char strbuf[256];
-
- fp = fopen(argv[1],"rb");
- fseek(fp,0,SEEK_END);
- fsize = ftell(fp);
- fseek(fp,0,SEEK_SET);
- buf = malloc(fsize);
- fread(buf,1,fsize,fp);
- fclose(fp);
-
- head = (void*)buf;
- mem = buf;
- if (memcmp(head->id,"PS-X EXE",8)==0) {
- startaddr = head->t_addr;
- mem+=2048;
- } else {
- if (argc > 2) sscanf(argv[2],"%x",(int *)(&startaddr));
- else startaddr = 0xbfc00000;
- }
-
- mem-=startaddr;
- addr = startaddr;
-
- for (i=0;i<fsize/4;i++)
- {
- UINT32 code = *(UINT32 *)(mem+addr);
- disasm(strbuf,code,addr);
- printf("%08x %08x %s\n",(int)addr,(int)code,strbuf);
- addr+=4;
- }
- /*
- while(1) {
- for(i=0;i<16;i++) {
- u_long code = *(u_long*)(mem+addr);
- disasm(strbuf,code,addr);
- printf("%08x %08x %s\n",addr,code,strbuf);
- addr+=4;
- }
- printf(">");
- gets(inputbuf);
- if (strcmp(inputbuf,"q")==0) break;
- switch(inputbuf[0]){
- case 'a': { char *endp; addr=strtoul(inputbuf+1,&endp,16); }
- }
- }
- */
- return 0;
- }
- #endif