rendered paste body#include "cpu.h"CPU::CPU(){ reg[R0] = 0x00000000; reg[R1] = 0x00000000; reg[R2] = 0x00000000; reg[R3] = 0x00000000; reg[R4] = 0x00000000; reg[R5] = 0x00000000; reg[R6] = 0x00000000; reg[R7] = 0x00000000; reg[R8] = 0x00000000; reg[R9] = 0x00000000; reg[R10] = 0x00000000; reg[R11] = 0x00000000; reg[R12] = 0x00000000; reg[R13] = 0x00000000; reg[R14] = 0x00000000; reg[R15] = 0x00000000; reg[R16] = 0x00000000; reg[R17] = 0x00000000; reg[R18] = 0x00000000; reg[R19] = 0x00000000; reg[R20] = 0x00000000; reg[R21] = 0x00000000; reg[R22] = 0x00000000; reg[R23] = 0x00000000; reg[R24] = 0x00000000; reg[R25] = 0x00000000; reg[R26] = 0x00000000; reg[R27] = 0x00000000; reg[R28] = 0x00000000; reg[R29] = 0x00000000; reg[R30] = 0x00000000; reg[R31] = 0x00000000; reg[R32] = 0x00000000; reg[Rmar] = 0x00000000; reg[Rmdr] = 0x00000000; reg[Rpc1] = 0x00000000; reg[Rpc4] = 0x00000000; reg[Rmd] = 0x00000000; reg[Rpsw] = 0x00000000; reg[Rpc] = 0x00000000; pipe = IF_PHASE1;}CPU::~CPU(){ pthread_mutex_destroy(&mutexIF); pthread_mutex_destroy(&mutexRF); pthread_mutex_destroy(&mutexMEM); pthread_mutex_destroy(&mutexWB);}void CPU::start(char *filename){ firm.ReadFirmware(filename,rom); ReadHeader(); CopyRom2Mem(); Run();}void CPU::ReadHeader(void){ ReadPos(&pointer2header,rom,SIZE_OF_ROM-4); _DEBUG("\nPointer to header: %X \n",pointer2header); ReadPos(&Hrom.date,rom,pointer2header-0xCF00000); _DEBUG("Date: %X \n",Hrom.date); ReadPos(&Hrom.pLT,rom,pointer2header-0xCF00000+0x4); _DEBUG("Pointer to loader table: %X \n",Hrom.pLT); ReadPos(&Hrom.lenLT,rom,pointer2header-0xCF00000+0x8); _DEBUG("Max. entries of loader table: %X \n",Hrom.lenLT); ReadPos(&Hrom.SP,rom,pointer2header-0xCF00000+0xC); reg[R29] = Hrom.SP; reg[Rpc] = Hrom.pLT;}void CPU::ReadPos(DWORD* ptr,unsigned char* org,DWORD pos){ *ptr = 0x1000000*(org[pos]&0xff) + 0x10000*(org[pos+1]&0xff)+ 0x100*(org[pos+2]&0xff) + (org[pos+3]&0xff);}void CPU::Run(void){ pthread_create( &threadpipe, NULL,&ProcessPipe, this);}extern "C" void * Execute(void *arg){ CPU* obj = static_cast<CPU*>(arg); //type_of_instruction tmptype; //tmptype = obj->types.front(); DWORD dwOpCode = obj->func.front(); obj->func.pop(); bool m_bUseISA2Opcodes = true; DWORD byOpCode = (dwOpCode >> 27); DWORD byRegSrc = (dwOpCode >> 22) & 0x1f; DWORD byRegDest = (dwOpCode >> 17) & 0x1f; DWORD byOffset = (dwOpCode & ( (1<<17) -1 ) ); DWORD byCompFunction = (byOffset) & 0xfff; DWORD byReg3 = (byOffset>>12) & 0x1f; long lIndex; long lJumpOffset17; if ( byOffset & (1<<16) ) { lIndex=-(0x10000-(byOffset&0xffff)); lJumpOffset17 = -((byOffset&0xffff)); } else { lIndex=(byOffset&0xffff); lJumpOffset17 = (byOffset&0xffff); } switch (byOpCode) { case 0x10: // LD { obj->ld(byOffset,byRegDest,byRegSrc); } break; case 0x12: // ST { obj->st(byRegDest,byRegSrc,byOffset); } break; case 0x14: if (m_bUseISA2Opcodes) { // LBU obj->lbu(byRegSrc,byRegDest,byOffset); } else { // LDF obj->ldf(byOffset,byRegSrc,byRegDest); } break; case 0x16: if (m_bUseISA2Opcodes) { // SS obj->ss(byOffset,byRegSrc,byRegDest); } else { // STF obj->stf(byOffset,byRegSrc,byRegDest); } break; case 0x11: if (m_bUseISA2Opcodes) { // LSU obj->lsu(byRegSrc,byRegDest,byOffset); } else { // LDT obj->ldt(byOffset,byRegSrc,byRegDest); } break; case 0x13: if (m_bUseISA2Opcodes) { // SB obj->sb(byOffset,byRegSrc,byRegDest); } else { // STT obj->stt(byOffset,byRegSrc,byRegDest); } break; case 0x15: if (m_bUseISA2Opcodes) { // LB obj->lb(byRegSrc,byRegDest,byOffset); } else { // MOVFRC obj->movfrc(byRegSrc,byRegDest,byReg3); } break; case 0x17: if (m_bUseISA2Opcodes) { //LS obj->ls(byRegSrc,byRegDest,byOffset); } else { //MOVTOC obj->movtoc(byRegSrc,byRegDest,byReg3); } break; case 0x1: // BEQ / BEQSQ { if ( byOffset & (1 << 16) ) { obj->beqsq(byRegSrc,byRegDest,byOffset); } else { obj->beq(byRegSrc,byRegDest,byOffset); } } break; case 0x7:// BGE / BGESQ { if ( byOffset & (1 << 16) ) { obj->bgesq(byRegSrc,byRegDest,byOffset); } else { obj->bge(byRegSrc,byRegDest,byOffset); } } break; case 0x2:// BHS / BHSSQ { if ( byOffset & (1 << 16) ) { obj->bhssq(byRegSrc,byRegDest,byOffset); } else { obj->bhs(byRegSrc,byRegDest,byOffset); } } break; case 0x6:// BLO / BLOSQ { if ( byOffset & (1 << 16) ) { obj->blosq(byRegSrc,byRegDest,byOffset); } else { obj->blo(byRegSrc,byRegDest,byOffset); } } break; case 0x3:// BLT / BLTSQ { if ( byOffset & (1 << 16) ) { obj->bltsq(byRegSrc,byRegDest,byOffset); } else { obj->blt(byRegSrc,byRegDest,byOffset); } } break; case 0x5:// BNE / BNESQ { if ( byOffset & (1 << 16) ) { obj->bnesq(byRegSrc,byRegDest,byOffset); } else { obj->bne(byRegSrc,byRegDest,byOffset); } } break; //****************************** case 0xc: // NOP/ADD/SUB/SUBNC/BIC/NOT/CLR/OR/XOR/MOV { if ( 25 == byOffset && 0 == byRegSrc && 0==byRegDest) { obj->nop(); } else { if ( byCompFunction == 0x19) { obj->add(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0x66) { obj->sub(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0x26) { obj->subnc(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0x23) { obj->andX(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0xb) { obj->bic(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0xf) { obj->notX(byRegSrc,byReg3); } if ( byCompFunction == 0x3b) { obj->orX(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0x1b) { obj->xorX(byRegSrc, byRegDest,byReg3); } if ( byCompFunction == 0x19) { obj->mov(byRegSrc, byRegDest); } if ( byCompFunction == 0x156) { //obj->abs(byRegSrc, byRegDest,byReg3); } } } break; case 0x8: // DSTEP/MSTART/MSTEP { switch (byCompFunction) { case 0x166: obj->dstep(byRegSrc,byRegDest,byReg3); break; case 0xe6: obj->mstart(byRegSrc,byRegDest); break; case 0x99: obj->mstep(byRegSrc,byRegDest,byReg3); break; default: break; } } break; case 0x9: // SH/ASR/ROTLB/ROTLCB { byReg3=(byOffset>>12); if ( ( ( byOffset >> 7) & 0x1f ) == 4) { obj->sh(byRegSrc,byRegDest,byReg3,byOffset); } else if ( ( ( byOffset >> 7) & 0x1f ) == 2) { obj->asr(byRegSrc,byRegDest,byOffset); } else if ( byCompFunction == 0xc0) { if (!m_bUseISA2Opcodes) { obj->rtlb(byRegSrc,byRegDest,byReg3); } else { } } else if ( byCompFunction == 0x80) { if (!m_bUseISA2Opcodes) { obj->rtlcb(byRegSrc,byRegDest,byReg3); } else { obj->sh(byRegSrc,byRegDest,byReg3,byOffset); } } else if ( byCompFunction == 0x180) { obj->asr(byRegSrc,byRegDest,byOffset); } else { } } break; //************************************************************ case 0x1c: // ADDI { obj->addi(byRegSrc,byRegDest,lIndex); } break; case 0x18: //JSPCI { obj->jspci(byRegSrc,byRegDest,byOffset); } break; case 0x1d: // JPC { obj->jpc(); } break; case 0x1f: // JPCRS { obj->jpcrs(); } break; case 0x1b: //MOVFRS { obj->movfrs(byRegSrc,byRegDest); } break; case 0x1a: // MOVTOS { obj->movtos(byRegSrc,byRegDest); } break; case 0x1e: // TRAP { } break; case 0x19: if (m_bUseISA2Opcodes) { obj->andi(byRegSrc,lIndex,byRegDest); } break; default: break; }}extern "C" void * ProcessPipe(void *arg){ CPU* obj = static_cast<CPU*>(arg); unsigned long long start, end, ammount; start = obj->t.rdtsc(); pthread_mutex_init(&obj->mutexIF,NULL); pthread_mutex_init(&obj->mutexRF,NULL); pthread_mutex_init(&obj->mutexMEM,NULL); pthread_mutex_init(&obj->mutexWB,NULL); while(1) { ammount=0; start = obj->t.rdtsc(); //while(ammount<(1/FREQ)) //{ // end = obj->t.rdtsc(); // ammount = end - start; //} if (obj->reg[Rpc]==0x0CFD5994) { //obj->PrintFromToDWORD(0x0,0x0cffffff); exit(0); } if (obj->reg[Rpc]>=obj->Hrom.pLT && obj->reg[Rpc]<obj->Hrom.pLT+(obj->Hrom.lenLT*0x10)) { switch(obj->memory[obj->reg[Rpc]]*0x1000000+obj->memory[obj->reg[Rpc]+1]*0x10000+obj->memory[obj->reg[Rpc]+2]*0x100+obj->memory[obj->reg[Rpc]+3]) { case 0x1: obj->macro1( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7], obj->memory[obj->reg[Rpc]+8]*0x1000000+ obj->memory[obj->reg[Rpc]+9]*0x10000+ obj->memory[obj->reg[Rpc]+10]*0x100+ obj->memory[obj->reg[Rpc]+11], obj->memory[obj->reg[Rpc]+12]*0x1000000+ obj->memory[obj->reg[Rpc]+13]*0x10000+ obj->memory[obj->reg[Rpc]+14]*0x100+ obj->memory[obj->reg[Rpc]+15]); obj->reg[Rpc]+=0x10; break; case 0x2: obj->macro2( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7], obj->memory[obj->reg[Rpc]+8]*0x1000000+ obj->memory[obj->reg[Rpc]+9]*0x10000+ obj->memory[obj->reg[Rpc]+10]*0x100+ obj->memory[obj->reg[Rpc]+11]); obj->reg[Rpc]+=0x10; break; case 0x3: obj->macro3( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0x4: obj->macro4( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); break; case 0x5: obj->macro5( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0x6: obj->macro6( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0x7: obj->macro7( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0x8: obj->macro8( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0x9: obj->macro9( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0xA: obj->macroA( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0xB: obj->macroB( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0xC: obj->macroC( obj->memory[obj->reg[Rpc]+4]*0x1000000+ obj->memory[obj->reg[Rpc]+5]*0x10000+ obj->memory[obj->reg[Rpc]+6]*0x100+ obj->memory[obj->reg[Rpc]+7]); obj->reg[Rpc]+=0x10; break; case 0xD: obj->macroD(); obj->reg[Rpc]+=0x10; break; } } else { type_of_instruction tmptype; switch(obj->pipe) { case IF_PHASE1: obj->actual = obj->memory[obj->reg[Rpc]]*0x1000000+obj->memory[obj->reg[Rpc]+1]*0x10000+obj->memory[obj->reg[Rpc]+2]*0x100+obj->memory[obj->reg[Rpc]+3]; obj->actual2 = obj->memory[obj->reg[Rpc]+4]*0x1000000+obj->memory[obj->reg[Rpc]+5]*0x10000+obj->memory[obj->reg[Rpc]+6]*0x100+obj->memory[obj->reg[Rpc]+7]; obj->actual3 = obj->memory[obj->reg[Rpc]+8]*0x1000000+obj->memory[obj->reg[Rpc]+9]*0x10000+obj->memory[obj->reg[Rpc]+10]*0x100+obj->memory[obj->reg[Rpc]+11]; tmptype = obj->DecodeOpcode(obj->actual); obj->func.push(obj->actual); printf("PC_EXE %X : %8X\n",obj->reg[Rpc],obj->reg[R29]); obj->reg[Rpc]+=4; if (tmptype==_jump || tmptype==_branch || tmptype==_branchsq) { //printf("BRanch or jump!!\n"); obj->func.push(obj->actual2); obj->reg[Rpc]+=4; obj->func.push(obj->actual3); obj->reg[Rpc]+=4; } obj->pipe = IF_PHASE2; break; case IF_PHASE2: obj->pipe = RF_PHASE1; break; case RF_PHASE1: //Execute(obj); obj->pipe = RF_PHASE2; break; case RF_PHASE2: obj->pipe = ALU_PHASE1; break; case ALU_PHASE1: Execute(obj); obj->pipe = ALU_PHASE2; break; case ALU_PHASE2: obj->pipe = MEM_PHASE1; break; case MEM_PHASE1: //Execute(obj); obj->pipe = MEM_PHASE2; break; case MEM_PHASE2: obj->pipe = WB_PHASE1; break; case WB_PHASE1: //Execute(obj); obj->pipe = WB_PHASE2; break; case WB_PHASE2: obj->pipe = IF_PHASE1; break; } } }}void CPU::CopyRom2Mem(void){ for(long l=0x0cf00000;l<=(0x0cf00000+SIZE_OF_ROM);l++) { memory[l]=rom[l-0x0cf00000]; }} //memoryvoid CPU::ld(DWORD offset,DWORD Rdest,DWORD Rsrc){ signed long off = offset & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); reg[Rdest] = getDWORDAT(off2 + reg[Rsrc]); printf("%8X - ld : r%i=mem[%8X] (r%i=%8X)\n",reg[Rpc],Rdest,off2 + reg[Rsrc],Rdest,reg[Rdest]); printf("--------------------> %8X %8X %8X \n",reg[R4],Rdest,reg[Rdest]);}void CPU::st(DWORD Rsrc2,DWORD Rsrc1,DWORD offset){ signed short off = offset & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); setDWORDAT(reg[Rsrc2],off2 + reg[Rsrc1]); printf("%8X - st : mem[%8X]=r%i (mem[%8X]=%8X)\n",reg[Rpc],off2 + reg[Rsrc1],Rsrc2,off2 + reg[Rsrc1],reg[Rsrc2]); //printf("PC>AAAAAAAAAAAAA %X : %X : %X \n",Rsrc1,off2,(off2*4 + reg[Rsrc1])); //PrintFromToDWORD((off2 + reg[Rsrc1])*4,(off2 + reg[Rsrc1])*4+1); //exit(0);}void CPU::ldf(DWORD offset,DWORD Rsrc,DWORD Rfdest){ signed short off = offset & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); reg[Rfdest] = getDWORDAT((off2 + reg[Rsrc])*4); }void CPU::stf(DWORD offset,DWORD Rsrc1,DWORD Rfsrc2){ signed short off = offset & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); setDWORDAT(reg[Rfsrc2],(off2 + reg[Rsrc1])*4); }void CPU::ldt(DWORD offset,DWORD Rsrc1,DWORD Rdest){ signed short off = offset & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); reg[Rdest] = getDWORDAT((off2 + reg[Rsrc1])*4); }void CPU::stt(DWORD offset,DWORD Rsrc1,DWORD Rsrc2){ signed short off = offset & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); setDWORDAT(reg[Rsrc2],(off2 + reg[Rsrc1])*4); }void CPU::movfrc(DWORD Rcpu,DWORD Rdest,DWORD Rsrc1){ signed short tmp = reg[Rcpu]; reg[Rmar] = tmp + reg[Rsrc1]; reg[Rdest] = reg[Rmdr]; }void CPU::movtoc(DWORD Rcpu,DWORD Rsrc2,DWORD Rsrc1){ signed short tmp = reg[Rcpu]; reg[Rmar] = tmp + reg[Rsrc1]; reg[Rmdr] = reg[Rsrc2]; }void CPU::aluc(DWORD Rcpu,DWORD Rsrc1){ signed short tmp = reg[Rcpu]; reg[Rmar] = tmp + reg[Rsrc1]; }void CPU::movtos(DWORD Rsrc,DWORD Rdest){ signed short tmp = reg[Rsrc]; reg[Rdest] = tmp; }void CPU::ls(DWORD Rsrc,DWORD Rdest,DWORD address){ signed short tmp = address & 0x0001ffff; signed long off2; off2 = CalculateValue17(tmp); reg[Rdest] = (signed) getDWORDAT((reg[Rsrc] + off2)*4); }void CPU::lsu(DWORD Rsrc,DWORD Rdest,DWORD address){ signed short tmp = address & 0x0001ffff; signed long off2; off2 = CalculateValue17(tmp); reg[Rdest] = (unsigned) getDWORDAT((reg[Rsrc] + off2)*4); }void CPU::lb(DWORD Rsrc,DWORD Rdest,DWORD address){ signed short tmp = address & 0x0001ffff; signed long off2; off2 = CalculateValue17(tmp); DWORD tmp2 = (reg[Rsrc] + off2) & 0x000000ff; reg[Rdest] = (signed) getDWORDAT(tmp2*4); }void CPU::lbu(DWORD Rsrc,DWORD Rdest,DWORD address){ signed short tmp = address & 0x0001ffff; signed long off2; off2 = CalculateValue17(tmp); DWORD tmp2 = (reg[Rsrc] + off2) & 0x000000ff; reg[Rdest] = (unsigned) getDWORDAT(tmp2*4); printf("lbu : r%i=%X\n",Rdest,reg[Rdest]); }void CPU::ss(DWORD offset,DWORD Rsrc1,DWORD Rsrc2){ signed short off = offset & 0x0001ffff; DWORD tmp2 = (reg[Rsrc2]) & 0x0000ffff; signed long off2; off2 = CalculateValue17(off); setDWORDAT(tmp2,(off2 + reg[Rsrc1])*4); }void CPU::sb(DWORD offset,DWORD Rsrc1,DWORD Rsrc2){ signed short off = offset & 0x0001ffff; DWORD tmp2 = (reg[Rsrc2]) & 0x000000ff; signed long off2; off2 = CalculateValue17(off); setDWORDAT(tmp2,(off2 + reg[Rsrc1])*4);} //branchvoid CPU::beq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ DWORD off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); Execute(this); Execute(this); //printf("------------->> %8X \n",reg[Rpc] + off2*4); if (reg[Rsrc1]==reg[Rsrc2]) { reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } }void CPU::beqsq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); if (reg[Rsrc1]==reg[Rsrc2]) { Execute(this); Execute(this); reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } else { func.pop(); func.pop(); } }void CPU::bge(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); Execute(this); Execute(this); if (reg[Rsrc1]>=reg[Rsrc2]) { reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } }void CPU::bgesq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); if (reg[Rsrc1]>=reg[Rsrc2]) { Execute(this); Execute(this); reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } else { func.pop(); func.pop(); }}void CPU::bhs(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); Execute(this); Execute(this); if (reg[Rsrc1]>=reg[Rsrc2]) { reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } }void CPU::bhssq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); if (reg[Rsrc1]>=reg[Rsrc2]) { Execute(this); Execute(this); reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } else { func.pop(); func.pop(); }}void CPU::blo(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); Execute(this); Execute(this); if (reg[Rsrc1]<reg[Rsrc2]) { reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } }void CPU::blosq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); if (reg[Rsrc1]<reg[Rsrc2]) { Execute(this); Execute(this); reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } else { func.pop(); func.pop(); }}void CPU::blt(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); Execute(this); Execute(this); if (reg[Rsrc1]<reg[Rsrc2]) { reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } }void CPU::bltsq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); if (reg[Rsrc1]<reg[Rsrc2]) { Execute(this); Execute(this); reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } else { func.pop(); func.pop(); }}void CPU::bne(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); Execute(this); Execute(this); if (reg[Rsrc1]!=reg[Rsrc2]) { reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; }}void CPU::bnesq(DWORD Rsrc1, DWORD Rsrc2, DWORD address){ signed short off = address & 0x0000ffff; signed long off2; off2 = CalculateValue16(off); if (reg[Rsrc1]!=reg[Rsrc2]) { Execute(this); Execute(this); reg[Rpc] = reg[Rpc] + off2*4; //reg[Rpc]+=8; } else { func.pop(); func.pop(); }} //computevoid CPU::add(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Rdest] = reg[Rsrc1] + reg[Rsrc2]; printf("%8X - add : r%i=r%i + r%i (r%i=%8X)\n",reg[Rpc],Rdest,Rsrc1,Rsrc2,Rdest,reg[Rdest]);}void CPU::mstart(DWORD Rsrc2,DWORD Rdest){ if ((reg[Rmd] & 0x80000000)==1) { reg[Rdest] = 0 - reg[Rsrc2]; reg[Rmd] = reg[Rmd] << 1; } else { reg[Rdest] = 0; reg[Rmd] = reg[Rmd] << 1; } }void CPU::mstep(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ if ((reg[Rmd] & 0x80000000)==1) { reg[Rdest] = (reg[Rsrc1]<<1) + reg[Rsrc2]; reg[Rmd] = reg[Rmd] << 1; } else { reg[Rdest] = (reg[Rsrc1]<<1); reg[Rmd] = reg[Rmd] << 1; } }void CPU::dstep(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Ralusrc1] = (reg[Rsrc1]<<1) + (reg[Rmd] & 0x80000000); reg[Ralusrc2] = reg[Rsrc2]; if ((reg[Raluout] & 0x80000000)==1) { reg[Rdest] = reg[Raluout]; reg[Rmd] = reg[Rmd] << 1; } else { reg[Rdest] = reg[Raluout]; reg[Rmd] = (reg[Rmd] << 1) + 1; } }void CPU::sub(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Rdest] = reg[Rsrc1] - reg[Rsrc2]; }void CPU::subnc(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Rdest] = reg[Rsrc1] + ~(reg[Rsrc2]); }void CPU::andX(DWORD Rsrc1, DWORD Rdest, DWORD Rsrc2){ reg[Rsrc1] = reg[Rsrc2] & reg[Rdest]; printf("%8X - and : r%i=r%i && r%i\n",reg[Rpc],Rsrc1,Rsrc2,Rdest); }void CPU::andi(DWORD Rsrc1, DWORD Rdest, DWORD Rsrc2){ reg[Rsrc1] = reg[Rsrc2] & reg[Rdest]; printf("%8X - andi : r%i=r%i && %i\n",reg[Rpc],Rsrc1,Rsrc2,Rdest); }void CPU::bic(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Rdest] = ~(reg[Rsrc1]) & reg[Rsrc2]; }void CPU::notX(DWORD Rsrc1, DWORD Rdest){ reg[Rdest] = ~(reg[Rsrc1]); }void CPU::orX(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Rdest] = reg[Rsrc1] | reg[Rsrc2]; }void CPU::xorX(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ reg[Rdest] = reg[Rsrc1] ^ reg[Rsrc2]; }void CPU::mov(DWORD Rsrc1, DWORD Rdest){ reg[Rdest] = reg[Rsrc1]; }void CPU::asr(DWORD Rsrc1, DWORD Rdest, DWORD ammount){ int Amount=DecodeShiftAmount(ammount&0x7f); DWORD res = Amount; DWORD res2 = res & 3; DWORD res3 = res >> 2; DWORD res4; if (res2==0) { res4 = 1; } if (res2==1) { res4 = 2; } if (res2==2) { res4 = 4; } if (res2==3) { res4 = 8; } res3 = (res3 * 16) + res4; reg[Rdest] = reg[Rsrc1] >> res3; }//#######################void CPU::rtlb(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ DWORD res = reg[Rsrc2] & 0xc0000000; res = res >> 30; while(res--) { } }//#######################void CPU::rtlcb(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest){ DWORD res = reg[Rsrc2] & 0xc0000000; res = res >> 30; res = ~(res); while(res--) { } }void CPU::sh(DWORD Rsrc1, DWORD Rsrc2, DWORD Rdest,DWORD ammount){ int Amount=DecodeShiftAmount(ammount&0x7f); DWORD dwReg1 = (DWORD)reg[Rsrc1]; dwReg1 >>=Amount; DWORD dwReg2 = (DWORD)reg[Rsrc2]; dwReg2 <<=Amount; dwReg2 |= dwReg1; reg[Rdest] = dwReg2; printf("sh : r%X=%X\n",Rdest,dwReg2);}void CPU::nop(void){ add(0x0000000000000000,0x0000000000000000,0x0000000000000000); } //compute immediatevoid CPU::addi(DWORD Rsrc1, DWORD Rdest, DWORD immed){ signed short off = immed & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); reg[Rdest] = off2 + reg[Rsrc1]; printf("R29 is %8X\n",reg[R29]); printf("%8X - addi : r%i=r%i + %X (r%i=%8X)\n",reg[Rpc],Rdest,Rsrc1,off2,Rdest,reg[Rdest]); printf("R29 is %8X\n",reg[R29]);}void CPU::jpc(void){ reg[Rpc] = reg[Rpc4]; }void CPU::jpcrs(void){ reg[Rpsw] = reg[Rpswother]; reg[Rpc] = reg[Rpc4]; }void CPU::jspci(DWORD Rsrc1, DWORD Rdest, DWORD immed){ signed long off = immed & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); Execute(this); Execute(this); if (Rdest!=0x0) reg[Rdest] = reg[Rpc]/4; printf("jump %8X\n",(off2 + reg[Rsrc1])*4); reg[Rpc] = (off2 + reg[Rsrc1])*4; }void CPU::movfrs(DWORD Rspecial, DWORD Rdest){ reg[Rdest] = reg[Rspecial];}void CPU::movi(DWORD Rdest, DWORD immed){ signed short off = immed & 0x0001ffff; signed long off2; off2 = CalculateValue17(off); reg[Rdest] = off2; printf("movi : r%X=%X\n",Rdest,off2);}//#######################void CPU::trap(BYTE vector){}//####################### LOLvoid CPU::hsc(void){} //othersvoid CPU::macro1(DWORD A,DWORD B,DWORD C){ for(long l=A;l<=A+C;l++) { memory[B] = memory[l]; B++; }}void CPU::macro2(DWORD A,DWORD B){ for(long l=A;l<=A+B;l++) { memory[l]=0x0; }}void CPU::macro3(DWORD A){ reg[Rpc]=A;}void CPU::macro4(DWORD A){ reg[Rpc]+=0x10; reg[R31]=(reg[Rpc])/4; reg[Rpc]=0x0CFA6D18;}void CPU::macro5(DWORD A){ reg[R24]=A;}void CPU::macro6(DWORD A){ reg[R25]=A;}void CPU::macro7(DWORD A){ reg[R23]=A;}void CPU::macro8(DWORD A){ reg[R4]=A;}void CPU::macro9(DWORD A){ reg[R5]=A;}void CPU::macroA(DWORD A){ reg[R29]=A;}void CPU::macroB(DWORD A){ reg[R29]=A;}void CPU::macroC(DWORD A){ reg[R19]=A;}void CPU::macroD(void){ //sleep}void CPU::returnX(void){ reg[Rpc] = reg[Rpc4];}DWORD CPU::getDWORDAT(DWORD address){ DWORD tmp; tmp = 0x1000000*(memory[address]&0xff) + 0x10000*(memory[address+1]&0xff)+ 0x100*(memory[address+2]&0xff) + (memory[address+3]&0xff); return tmp;}void CPU::setDWORDAT(DWORD value, DWORD address){ memory[address] = (BYTE)((value>>24)&0xff); memory[address+1] = (BYTE)((value>>16)&0xff); memory[address+2] = (BYTE)((value>>8)&0xff); memory[address+3] = (BYTE)((value)&0xff); DWORD tmp; tmp = 0x1000000*(memory[address]&0xff) + 0x10000*(memory[address+1]&0xff)+ 0x100*(memory[address+2]&0xff) + (memory[address+3]&0xff); printf("\nStored at %8X value %8X!\n",address,tmp);}signed long CPU::CalculateValue17(DWORD X){int t = X & 0x00010000;if (t == 0x10000){ X = ((~X)+1) & (0x1ffff); X = (-1)*X;}else{ X = +X;}return ((signed long)X);}signed long CPU::CalculateValue16(DWORD X){int t = X & 0x00008000;if (t == 0x1000){ X = ((~X)+1) & (0xffff); X = (-1)*X;}else{ X = +X;}return ((signed long)X);}unsigned long CPU::ZeroExtend8to32(unsigned char val8){ return((unsigned long)val8);}unsigned long CPU::SignExtend8to32(unsigned char val8){ unsigned long retval; if (val8 & 0x80) retval = ((unsigned long)val8) | 0xFFFFFF00; else retval = (unsigned long)val8; return(retval);}unsigned long CPU::ZeroExtend16to32(unsigned short val16){ return((unsigned long)val16);}unsigned long CPU::SignExtend16to32(unsigned short val16){ unsigned long retval; if (val16 & 0xF000) retval = ((unsigned long)val16) | 0xFFFF0000; else retval = (unsigned long)val16; return(retval);}type_of_instruction CPU::DecodeOpcode(DWORD dw){ DWORD byOpCode = (dw >> 27); DWORD byOffset = (dw & ( (1<<17) -1 ) ); DWORD byRegSrc = (dw >> 22) & 0x1f; DWORD byRegDest = (dw >> 17) & 0x1f; DWORD byCompFunction = (byOffset) & 0xfff; DWORD byReg3 = (byOffset>>12) & 0x1f; bool m_bUseISA2Opcodes = false; switch (byOpCode) { case 0x10: // LD { type = _memoryWB; } break; case 0x12: // ST { type = _memoryMEM; } break; case 0x14: if (m_bUseISA2Opcodes) { // LBU type = _memoryWB; } else { // LDF type = _memoryWB; } break; case 0x16: if (m_bUseISA2Opcodes) { // SS type = _memoryMEM; } else { // STF type = _memoryMEM; } break; case 0x11: if (m_bUseISA2Opcodes) { // LSU type = _memoryWB; } else { // LDT type = _memoryWB; } break; case 0x13: if (m_bUseISA2Opcodes) { // SB type = _memoryMEM; } else { // STT type = _memoryMEM; } break; case 0x15: if (m_bUseISA2Opcodes) { // LB type = _memoryWB; } else { // MOVFRC type = _memoryWB; } break; case 0x17: if (m_bUseISA2Opcodes) { //LS type = _memoryWB; } else { //MOVTOC type = _memoryMEM; } break; case 0x1: // BEQ / BEQSQ { if ( byOffset & (1 << 16) ) { type = _branchsq; } else { type = _branch; } } break; case 0x7:// BGE / BGESQ { if ( byOffset & (1 << 16) ) { type = _branchsq; } else { type = _branch; } } break; case 0x2:// BHS / BHSSQ { if ( byOffset & (1 << 16) ) { type = _branchsq; } else { type = _branch; } } break; case 0x6:// BLO / BLOSQ { if ( byOffset & (1 << 16) ) { type = _branchsq; } else { type = _branch; } } break; case 0x3:// BLT / BLTSQ { if ( byOffset & (1 << 16) ) { type = _branchsq; } else { type = _branch; } } break; case 0x5:// BNE / BNESQ { if ( byOffset & (1 << 16) ) { type = _branchsq; } else { type = _branch; } } break; //****************************** case 0xc: // NOP/ADD/SUB/SUBNC/BIC/NOT/CLR/OR/XOR/MOV { if ( 25 == byOffset && 0 == byRegSrc && 0==byRegDest) { type = _compute; } else { if ( byCompFunction == 0x19) { type = _compute; } if ( byCompFunction == 0x66) { type = _compute; } if ( byCompFunction == 0x26) { type = _compute; } if ( byCompFunction == 0x23) { type = _compute; } if ( byCompFunction == 0xb) { type = _compute; } if ( byCompFunction == 0xf) { type = _compute; } if ( byCompFunction == 0x3b) { type = _compute; } if ( byCompFunction == 0x1b) { type = _compute; } if ( byCompFunction == 0x19) { type = _compute; } if ( byCompFunction == 0x156) { //obj->abs(byRegSrc, byRegDest,byReg3); } } } break; case 0x8: // DSTEP/MSTART/MSTEP { switch (byCompFunction) { case 0x166: type = _dstep; break; case 0xe6: type = _compute; break; case 0x99: type = _mstep; break; default: break; } } break; case 0x9: // SH/ASR/ROTLB/ROTLCB { byReg3=(byOffset>>12); if ( ( ( byOffset >> 7) & 0x1f ) == 4) { type = _compute; } else if ( ( ( byOffset >> 7) & 0x1f ) == 2) { type = _compute; } else if ( byCompFunction == 0xc0) { if (!m_bUseISA2Opcodes) { type = _compute; } else { } } else if ( byCompFunction == 0x80) { if (!m_bUseISA2Opcodes) { type = _compute; } else { type = _compute; } } else if ( byCompFunction == 0x180) { type = _compute; } else { } } break; //************************************************************ case 0x1c: // ADDI { type = _computeimmediate; } break; case 0x18: //JSPCI { type = _jump; } break; case 0x1d: // JPC { type = _computeimmediate; } break; case 0x1f: // JPCRS { type = _computeimmediate; } break; case 0x1b: //MOVFRS { type = _special; } break; case 0x1a: // MOVTOS { type = _special; } break; case 0x1e: // TRAP { type = _computeimmediate; } break; case 0x19: if (m_bUseISA2Opcodes) { type = _computeimmediate; } break; default: break; } return type;}void CPU::PrintFromToDWORD(DWORD from,DWORD to){ for(DWORD i=from;i<=to;i+=4) { printf("%X: %8X\n",i,getDWORDAT(i)); }}BYTE CPU::DecodeShiftAmount(WORD wShiftAmount){ BYTE bShiftAmount= ((wShiftAmount >> 4) & 0x7); bShiftAmount <<=2; switch (wShiftAmount & 0xf) { case 1: break; case 2: bShiftAmount |=1 ; break; case 4: bShiftAmount |= 2; break; case 8: bShiftAmount |= 3; break; } return 32-bShiftAmount;}