All pastes #1422659 Raw Edit

Mine

public cpp v1 · immutable
#1422659 ·published 2009-05-14 13:52 UTC
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;}