Definition at line 255 of file st20.c.
References AAA, b, BBB, CCC, CLEAR_OP, DROP, ERR_CNT, ERR_ILL_OP, GET_OP, JUMP, L_SYS_DISASM, L_SYS_ST20, LOG_OP, MOSTNEG, POP, POP64, cLineBuff::Printf(), PRINTF, PUSH, PUSHPOP, PUTLB, RB, ReadByte(), ReadShort(), RW, WriteByte(), and WW.
Referenced by cTPSDecrypt::Handle80008003().
{
int operand;
bool v=verbose;
CLEAR_OP();
while(Iptr!=0) {
int a, op1=RB(Iptr++);
if(v) LogOpOper(op1,operand);
GET_OP();
switch(op1>>4) {
case 0x0:
#ifdef SAVE_DEBUG
POP(); POP(); POP();
#endif
JUMP(operand);
CLEAR_OP();
break;
case 0x1:
PUSH(Wptr+(operand*4));
CLEAR_OP();
break;
case 0x2:
operand<<=4;
break;
case 0x3:
AAA=RW(AAA+(operand*4));
CLEAR_OP();
break;
case 0x4:
PUSH(operand);
CLEAR_OP();
break;
case 0x5:
PUSHPOP(+,operand*4);
CLEAR_OP();
break;
case 0x6:
operand=(~operand)<<4;
break;
case 0x7:
PUSH(RW(Wptr+(operand*4)));
CLEAR_OP();
break;
case 0x8:
PUSHPOP(+,operand);
CLEAR_OP();
break;
case 0x9:
Wptr-=16;
WW(Wptr,Iptr); WW(Wptr+4,POP()); WW(Wptr+8,POP()); WW(Wptr+12,POP());
PUSH(Iptr);
JUMP(operand);
CLEAR_OP();
break;
case 0xA:
if(AAA) DROP(1); else JUMP(operand);
CLEAR_OP();
break;
case 0xB:
Wptr+=operand*4;
CLEAR_OP();
break;
case 0xC:
AAA=(operand==AAA ? 1 : 0);
CLEAR_OP();
break;
case 0xD:
WW(Wptr+(operand*4),POP());
CLEAR_OP();
break;
case 0xE:
a=POP(); WW(a+(operand*4),POP());
CLEAR_OP();
break;
case 0xF:
switch(operand) {
case 0x00: LOG_OP("rev"); a=AAA; AAA=BBB; BBB=a; break;
case 0x01: LOG_OP("lb"); AAA=RB(AAA); break;
case 0x02: LOG_OP("bsub"); PUSHPOP(+,POP()); break;
case 0x04: LOG_OP("diff"); PUSHPOP(-,POP()); break;
case 0x05: LOG_OP("add"); PUSHPOP(+,POP()); break;
case 0x06: LOG_OP("gcall"); a=AAA; AAA=Iptr; Iptr=a; break;
case 0x08: LOG_OP("prod"); PUSHPOP(*,POP()); break;
case 0x09: LOG_OP("gt"); a=POP(); AAA=(AAA>a); break;
case 0x0A: LOG_OP("wsub"); a=POP(); AAA=a+(AAA*4); break;
case 0x0C: LOG_OP("sub"); PUSHPOP(-,POP()); break;
case 0x1B: LOG_OP("ldpi"); PUSHPOP(+,Iptr); break;
case 0x20: LOG_OP("ret"); Iptr=RW(Wptr); Wptr=Wptr+16; break;
case 0x2C: LOG_OP("div"); PUSHPOP(/,POP()); break;
case 0x32: LOG_OP("not"); AAA=~AAA; break;
case 0x33: LOG_OP("xor"); PUSHPOP(^,POP()); break;
case 0x34: LOG_OP("bcnt"); PUSHPOP(*,4); break;
case 0x3B: LOG_OP("sb"); a=POP(); WriteByte(a,POP()); break;
case 0x3F: LOG_OP("wcnt"); a=POP(); PUSH(a&3); PUSH((unsigned int)a>>2); break;
case 0x40: LOG_OP("shr"); a=POP(); AAA=(unsigned int)AAA>>a; break;
case 0x41: LOG_OP("shl"); a=POP(); AAA=(unsigned int)AAA<<a; break;
case 0x42: LOG_OP("mint"); PUSH(MOSTNEG); break;
case 0x46: LOG_OP("and"); PUSHPOP(&,POP()); break;
case 0x4A: LOG_OP("move"); { a=POP(); int b=POP(); int c=POP(); while(a--) WriteByte(b++,ReadByte(c++)); } break;
case 0x4B: LOG_OP("or"); PUSHPOP(|,POP()); break;
case 0x53: LOG_OP("mul"); PUSHPOP(*,POP()); break;
case 0x5A: LOG_OP("dup"); PUSH(AAA); break;
case 0x5F: LOG_OP("gtu"); a=POP(); AAA=((unsigned int)AAA>(unsigned int)a); break;
case 0x1D: LOG_OP("xdble"); CCC=BBB; BBB=(AAA>=0 ? 0:-1); break;
case 0x1A: LOG_OP("ldiv"); { a=POP(); unsigned long long ll=POP64(); PUSH(ll%(unsigned int)a); PUSH(ll/(unsigned int)a); } break;
case 0x1F: LOG_OP("rem"); PUSHPOP(%,POP()); break;
case 0x35: LOG_OP("lshr"); { a=POP(); unsigned long long ll=POP64()>>a; PUSH((ll>>32)&0xFFFFFFFF); PUSH(ll&0xFFFFFFFF); } break;
case 0xCA: LOG_OP("ls"); AAA=ReadShort(AAA); break;
case 0xCD: LOG_OP("gintdis"); break;
case 0xCE: LOG_OP("gintenb"); break;
case -0x40: LOG_OP("nop"); break;
default:
if(verbose) PUTLB(L_SYS_DISASM,loglb);
PRINTF(L_SYS_ST20,"unknown opcode %X",operand);
return ERR_ILL_OP;
}
CLEAR_OP();
break;
}
if(v && operand==0) {
loglb->Printf("%08X %08X %08X W:%08X",AAA,BBB,CCC,Wptr);
PUTLB(L_SYS_DISASM,loglb);
}
if(--count<=0 && operand==0) {
PRINTF(L_SYS_ST20,"instruction counter exceeded");
return ERR_CNT;
}
}
return 0;
}