Exemplo n.º 1
0
void r4300i_LL (void)
{
    uint32_t Address =  GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;
    uintptr_t ll = 0;
    if ((Address & 3) != 0)
    {
        ADDRESS_ERROR_EXCEPTION(Address,1);
    }

    if (Opcode.rt == 0)
    {
        return;
    }

    if (!r4300i_LW_VAddr(Address,&GPR[Opcode.rt].UW[0]))
    {
        //if (ShowTLBMisses) {
        DisplayError("LW TLB: %X",Address);
        //}
        TLB_READ_EXCEPTION(Address);
    }
    else
    {
        GPR[Opcode.rt].DW = GPR[Opcode.rt].W[0];
    }
    LLBit = 1;
    LLAddr = Address;
    ll = LLAddr;
    TranslateVaddr(&ll);
    LLAddr = ll;

}
Exemplo n.º 2
0
void ExecuteInterpreterOpCode (usf_state_t * state) {


	if (*state->WaitMode) state->Timers->Timer = -1;

	if (!r4300i_LW_VAddr(state, state->PROGRAM_COUNTER, &state->Opcode.u.Hex)) {
		DoTLBMiss(state, state->NextInstruction == JUMP,state->PROGRAM_COUNTER);
		state->NextInstruction = NORMAL;
		return;
	}
    
#ifdef DEBUG_INFO
    {
        char opcode[256];
        char arguments[256];
        r4300_decode_op(state->Opcode.u.Hex, opcode, arguments, state->PROGRAM_COUNTER);
        fprintf(state->debug_log, "%08x: %-16s %s\n", state->PROGRAM_COUNTER, opcode, arguments);
    }
#endif

	COUNT_REGISTER += 2;
	state->Timers->Timer -= 2;

	RANDOM_REGISTER -= 1;
	if ((int32_t)RANDOM_REGISTER < (int32_t)WIRED_REGISTER) {
		RANDOM_REGISTER = 31;
	}

	R4300i_Opcode[ state->Opcode.u.b.op ](state);

	if (state->GPR[0].DW != 0) {
		state->GPR[0].DW = 0;
	}

	switch (state->NextInstruction) {
	case NORMAL:
		state->PROGRAM_COUNTER += 4;
		break;
	case DELAY_SLOT:
		state->NextInstruction = JUMP;
		state->PROGRAM_COUNTER += 4;
		break;
	case JUMP:
		if (
#ifdef DEBUG_INFO
            0 &&
#endif
            state->cpu_hle_entry_count &&
			DoCPUHLE(state, state->JumpToLocation)) {
            state->PROGRAM_COUNTER = state->GPR[31].UW[0];
            state->NextInstruction = NORMAL;
        }
		else {
			state->PROGRAM_COUNTER = state->JumpToLocation;
			state->NextInstruction = NORMAL;
		}
		if ((int32_t)state->Timers->Timer < 0) { TimerDone(state); }
		if (state->CPU_Action->DoSomething) { DoSomething(state); }
	}
}
void _fastcall r4300i_LWC1 (void) {
	DWORD Address =  GPR[Opcode.base].UW[0] + (DWORD)((short)Opcode.offset);
	TEST_COP1_USABLE_EXCEPTION
	if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); }
	if (!r4300i_LW_VAddr(Address,&*(DWORD *)FPRFloatLocation[Opcode.ft])) {
		if (ShowTLBMisses) {
			DisplayError("LWC1 TLB: %X",Address);
		}
		TLB_READ_EXCEPTION(Address);
	}
}
void _fastcall r4300i_LWU (void) {
	DWORD Address =  GPR[Opcode.base].UW[0] + (short)Opcode.offset;	
	if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); }
	if (Opcode.rt == 0) { return; }

	if (!r4300i_LW_VAddr(Address,&GPR[Opcode.rt].UW[0])) {
		if (ShowTLBMisses) {
			DisplayError("LWU TLB: %X",Address);
		}
		TLB_READ_EXCEPTION(Address);
	} else {
		GPR[Opcode.rt].UDW = GPR[Opcode.rt].UW[0];
	}
}
void _fastcall r4300i_LWR (void) {
	DWORD Offset, Address, Value;
	
	Address = GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	Offset  = Address & 3;

	if (!r4300i_LW_VAddr((Address & ~3),&Value)) {
		DisplayError("LDL TLB: %X",Address);
		return;
	}
	
	GPR[Opcode.rt].DW = (int)(GPR[Opcode.rt].W[0] & LWR_MASK[Offset]);
	GPR[Opcode.rt].DW += (int)(Value >> LWR_SHIFT[Offset]);
}
Exemplo n.º 6
0
void  r4300i_LWL (void) {
	u32 Offset, Address, Value;

	Address = GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	Offset  = Address & 3;

	if (!r4300i_LW_VAddr((Address & ~3),&Value)) {
		//DisplayError("LDL TLB: %X",Address);
		return;
	}

	GPR[Opcode.rt].DW = (int)(GPR[Opcode.rt].W[0] & LWL_MASK[Offset]);
	GPR[Opcode.rt].DW += (int)(Value << LWL_SHIFT[Offset]);
}
Exemplo n.º 7
0
void r4300i_LWR (void)
{
    uint32_t Offset, Address, Value;

    Address = GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;
    Offset  = Address & 3;

    if (!r4300i_LW_VAddr((Address & ~3),&Value))
    {
        return;
    }

    GPR[Opcode.rt].DW = (int32_t)(GPR[Opcode.rt].W[0] & LWR_MASK[Offset]);
    GPR[Opcode.rt].DW += (int32_t)(Value >> LWR_SHIFT[Offset]);
}
Exemplo n.º 8
0
void _fastcall r4300i_LWL (void) {
	DWORD Offset, Address, Value;
	
	Address = GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	Offset  = Address & 3;

	if (!r4300i_LW_VAddr((Address & ~3),&Value)) {
#ifndef EXTERNAL_RELEASE
		DisplayError("LDL TLB: %X",Address);
#endif
		return;
	}
	
	GPR[Opcode.rt].DW = (int)(GPR[Opcode.rt].W[0] & LWL_MASK[Offset]);
	GPR[Opcode.rt].DW += (int)(Value << LWL_SHIFT[Offset]);
}
Exemplo n.º 9
0
void r4300i_LWC1 (void)
{
    uint32_t Address =  GPR[Opcode.base].UW[0] + (uint32_t)((int16_t)Opcode.offset);
    TEST_COP1_USABLE_EXCEPTION
    if ((Address & 3) != 0)
    {
        ADDRESS_ERROR_EXCEPTION(Address,1);
    }
    if (!r4300i_LW_VAddr(Address,&*(uint32_t *)FPRFloatLocation[Opcode.ft]))
    {
        //if (ShowTLBMisses) {
        DisplayError("LWC1 TLB: %X",Address);
        //}
        TLB_READ_EXCEPTION(Address);
    }
}
Exemplo n.º 10
0
void _fastcall r4300i_SWR (void) {
	DWORD Offset, Address, Value;
	
	Address = GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	Offset  = Address & 3;

	if (!r4300i_LW_VAddr((Address & ~3),&Value)) {
		DisplayError("SWL TLB: %X",Address);
		return;
	}
	
	Value &= SWR_MASK[Offset];
	Value += GPR[Opcode.rt].UW[0] << SWR_SHIFT[Offset];

	if (!r4300i_SW_VAddr((Address & ~0x03),Value)) {
		DisplayError("SWL TLB: %X",Address);
	}
}
Exemplo n.º 11
0
void  r4300i_LL (void) {
	u32 Address =  GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); }

	if (Opcode.rt == 0) { return; }

	if (!r4300i_LW_VAddr(Address,&GPR[Opcode.rt].UW[0])) {
		if (ShowTLBMisses) {
			//DisplayError("LW TLB: %X",Address);
		}
		TLB_READ_EXCEPTION(Address);
	} else {
		GPR[Opcode.rt].DW = GPR[Opcode.rt].W[0];
	}
	LLBit = 1;
	LLAddr = Address;
	TranslateVaddr(&LLAddr);
}
Exemplo n.º 12
0
void  r4300i_SWL (void) {
	s32 Offset;
	u32 Address, Value;

	Address = GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	Offset  = Address & 3;

	if (!r4300i_LW_VAddr((Address & ~3),&Value)) {
		//DisplayError("SWL TLB: %X",Address);
		return;
	}

	Value &= SWL_MASK[Offset];
	Value += GPR[Opcode.rt].UW[0] >> SWL_SHIFT[Offset];

	if (!r4300i_SW_VAddr((Address & ~0x03),Value)) {
		//DisplayError("SWL TLB: %X",Address);
	}
}
Exemplo n.º 13
0
void r4300i_SWR (void)
{
    uint32_t Offset, Address, Value;

    Address = GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;
    Offset  = Address & 3;

    if (!r4300i_LW_VAddr((Address & ~3),&Value))
    {
        return;
    }

    Value &= SWR_MASK[Offset];
    Value += GPR[Opcode.rt].UW[0] << SWR_SHIFT[Offset];

    if (!r4300i_SW_VAddr((Address & ~0x03),Value))
    {
    }
}
Exemplo n.º 14
0
void ExecuteInterpreterOpCode (usf_state_t * state) {


	if (*state->WaitMode) state->Timers->Timer = -1;

	if (!r4300i_LW_VAddr(state, state->PROGRAM_COUNTER, &state->Opcode.u.Hex)) {
		DoTLBMiss(state, state->NextInstruction == JUMP,state->PROGRAM_COUNTER);
		state->NextInstruction = NORMAL;
		return;
	}

	COUNT_REGISTER += 2;
	state->Timers->Timer -= 2;

	RANDOM_REGISTER -= 1;
	if ((int32_t)RANDOM_REGISTER < (int32_t)WIRED_REGISTER) {
		RANDOM_REGISTER = 31;
	}

	R4300i_Opcode[ state->Opcode.u.b.op ](state);

	if (state->GPR[0].DW != 0) {
		state->GPR[0].DW = 0;
	}

	switch (state->NextInstruction) {
	case NORMAL:
		state->PROGRAM_COUNTER += 4;
		break;
	case DELAY_SLOT:
		state->NextInstruction = JUMP;
		state->PROGRAM_COUNTER += 4;
		break;
	case JUMP:
		state->PROGRAM_COUNTER  = state->JumpToLocation;
		state->NextInstruction = NORMAL;
		if ((int32_t)state->Timers->Timer < 0) {  TimerDone(state); }
		if (state->CPU_Action->DoSomething) { DoSomething(state); }

	}
}
Exemplo n.º 15
0
void _fastcall r4300i_LW (void) {
	DWORD Address =  GPR[Opcode.base].UW[0] + (short)Opcode.offset;	
	if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); }

#if (!defined(EXTERNAL_RELEASE))
	Log_LW(PROGRAM_COUNTER,Address);
#endif
	if (Opcode.rt == 0) { return; }

	if (!r4300i_LW_VAddr(Address,&GPR[Opcode.rt].UW[0])) {
		if (ShowTLBMisses) {
			DisplayError("LW TLB: %X",Address);
		}
		TLB_READ_EXCEPTION(Address);
	} else {
		GPR[Opcode.rt].DW = GPR[Opcode.rt].W[0];
		//TranslateVaddr(&Address);
		//if (Address == 0x00090AA0) {
		//	LogMessage("%X: Read %X from %X",PROGRAM_COUNTER,GPR[Opcode.rt].UW[0],GPR[Opcode.base].UW[0] + (short)Opcode.offset);
		//}
	}
}
Exemplo n.º 16
0
void _fastcall r4300i_SWL (void) {
	DWORD Offset, Address, Value;
	
	Address = GPR[Opcode.base].UW[0] + (short)Opcode.offset;
	Offset  = Address & 3;

	if (!r4300i_LW_VAddr((Address & ~3),&Value)) {
#ifndef EXTERNAL_RELEASE
		DisplayError("SWL TLB: %X",Address);
#endif
		return;
	}
	
	Value &= SWL_MASK[Offset];
	Value += GPR[Opcode.rt].UW[0] >> SWL_SHIFT[Offset];

	if (!r4300i_SW_VAddr((Address & ~0x03),Value)) {
#ifndef EXTERNAL_RELEASE
		DisplayError("SWL TLB: %X",Address);
#endif
	}
}
Exemplo n.º 17
0
void r4300i_LW (void)
{
    uint32_t Address =  GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;

    if (Opcode.rt == 0)
    {
        return;
    }


    if (!r4300i_LW_VAddr(Address,&GPR[Opcode.rt].UW[0]))
    {
        //if (ShowTLBMisses) {
        printf("LW TLB: %X",Address);
        //}
        TLB_READ_EXCEPTION(Address);
    }
    else
    {
        GPR[Opcode.rt].DW = GPR[Opcode.rt].W[0];
    }
}
Exemplo n.º 18
0
void r4300i_LWU (void)
{
    uint32_t Address =  GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;
    if ((Address & 3) != 0)
    {
        ADDRESS_ERROR_EXCEPTION(Address,1);
    }
    if (Opcode.rt == 0)
    {
        return;
    }

    if (!r4300i_LW_VAddr(Address,&GPR[Opcode.rt].UW[0]))
    {
        //if (ShowTLBMisses) {
        DisplayError("LWU TLB: %X",Address);
        //}
        TLB_READ_EXCEPTION(Address);
    }
    else
    {
        GPR[Opcode.rt].UDW = GPR[Opcode.rt].UW[0];
    }
}
Exemplo n.º 19
0
int32_t DelaySlotEffectsJump (usf_state_t * state, uint32_t JumpPC) {
	OPCODE Command;

	if (!r4300i_LW_VAddr(state, JumpPC, &Command.u.Hex)) { return 1; }

	switch (Command.u.b.op) {
	case R4300i_SPECIAL:
		switch (Command.u.e.funct) {
		case R4300i_SPECIAL_JR:	return DelaySlotEffectsCompare(state,JumpPC,Command.u.b.rs,0);
		case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(state,JumpPC,Command.u.b.rs,31);
		}
		break;
	case R4300i_REGIMM:
		switch (Command.u.b.rt) {
		case R4300i_REGIMM_BLTZ:
		case R4300i_REGIMM_BGEZ:
		case R4300i_REGIMM_BLTZL:
		case R4300i_REGIMM_BGEZL:
		case R4300i_REGIMM_BLTZAL:
		case R4300i_REGIMM_BGEZAL:
			return DelaySlotEffectsCompare(state,JumpPC,Command.u.b.rs,0);
		}
		break;
	case R4300i_JAL:
	case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(state,JumpPC,31,0); break;
	case R4300i_J: return 0;
	case R4300i_BEQ:
	case R4300i_BNE:
	case R4300i_BLEZ:
	case R4300i_BGTZ:
		return DelaySlotEffectsCompare(state,JumpPC,Command.u.b.rs,Command.u.b.rt);
	case R4300i_CP1:
		switch (Command.u.f.fmt) {
		case R4300i_COP1_BC:
			switch (Command.u.f.ft) {
			case R4300i_COP1_BC_BCF:
			case R4300i_COP1_BC_BCT:
			case R4300i_COP1_BC_BCFL:
			case R4300i_COP1_BC_BCTL:
				{
					int32_t EffectDelaySlot;
					OPCODE NewCommand;

					if (!r4300i_LW_VAddr(state, JumpPC + 4, &NewCommand.u.Hex)) { return 1; }

					EffectDelaySlot = 0;
					if (NewCommand.u.b.op == R4300i_CP1) {
						if (NewCommand.u.f.fmt == R4300i_COP1_S && (NewCommand.u.e.funct & 0x30) == 0x30 ) {
							EffectDelaySlot = 1;
						}
						if (NewCommand.u.f.fmt == R4300i_COP1_D && (NewCommand.u.e.funct & 0x30) == 0x30 ) {
							EffectDelaySlot = 1;
						}
					}
					return EffectDelaySlot;
				}
				break;
			}
			break;
		}
		break;
	case R4300i_BEQL:
	case R4300i_BNEL:
	case R4300i_BLEZL:
	case R4300i_BGTZL:
		return DelaySlotEffectsCompare(state,JumpPC,Command.u.b.rs,Command.u.b.rt);
	}
	return 1;
}
Exemplo n.º 20
0
int32_t DelaySlotEffectsCompare (usf_state_t * state, uint32_t PC, uint32_t Reg1, uint32_t Reg2) {
	OPCODE Command;

	if (!r4300i_LW_VAddr(state, PC + 4, (uint32_t*)&Command.u.Hex)) {
		return 1;
	}

	switch (Command.u.b.op) {
	case R4300i_SPECIAL:
		switch (Command.u.e.funct) {
		case R4300i_SPECIAL_SLL:
		case R4300i_SPECIAL_SRL:
		case R4300i_SPECIAL_SRA:
		case R4300i_SPECIAL_SLLV:
		case R4300i_SPECIAL_SRLV:
		case R4300i_SPECIAL_SRAV:
		case R4300i_SPECIAL_MFHI:
		case R4300i_SPECIAL_MTHI:
		case R4300i_SPECIAL_MFLO:
		case R4300i_SPECIAL_MTLO:
		case R4300i_SPECIAL_DSLLV:
		case R4300i_SPECIAL_DSRLV:
		case R4300i_SPECIAL_DSRAV:
		case R4300i_SPECIAL_ADD:
		case R4300i_SPECIAL_ADDU:
		case R4300i_SPECIAL_SUB:
		case R4300i_SPECIAL_SUBU:
		case R4300i_SPECIAL_AND:
		case R4300i_SPECIAL_OR:
		case R4300i_SPECIAL_XOR:
		case R4300i_SPECIAL_NOR:
		case R4300i_SPECIAL_SLT:
		case R4300i_SPECIAL_SLTU:
		case R4300i_SPECIAL_DADD:
		case R4300i_SPECIAL_DADDU:
		case R4300i_SPECIAL_DSUB:
		case R4300i_SPECIAL_DSUBU:
		case R4300i_SPECIAL_DSLL:
		case R4300i_SPECIAL_DSRL:
		case R4300i_SPECIAL_DSRA:
		case R4300i_SPECIAL_DSLL32:
		case R4300i_SPECIAL_DSRL32:
		case R4300i_SPECIAL_DSRA32:
			if (Command.u.e.rd == 0) { return 0; }
			if (Command.u.e.rd == Reg1) { return 1; }
			if (Command.u.e.rd == Reg2) { return 1; }
			break;
		case R4300i_SPECIAL_MULT:
		case R4300i_SPECIAL_MULTU:
		case R4300i_SPECIAL_DIV:
		case R4300i_SPECIAL_DIVU:
		case R4300i_SPECIAL_DMULT:
		case R4300i_SPECIAL_DMULTU:
		case R4300i_SPECIAL_DDIV:
		case R4300i_SPECIAL_DDIVU:
			break;
		default:
			return 1;
		}
		break;
	case R4300i_CP0:
		switch (Command.u.b.rs) {
		case R4300i_COP0_MT: break;
		case R4300i_COP0_MF:
			if (Command.u.b.rt == 0) { return 0; }
			if (Command.u.b.rt == Reg1) { return 1; }
			if (Command.u.b.rt == Reg2) { return 1; }
			break;
		default:
			if ( (Command.u.b.rs & 0x10 ) != 0 ) {
				switch( state->Opcode.u.e.funct ) {
				case R4300i_COP0_CO_TLBR: break;
				case R4300i_COP0_CO_TLBWI: break;
				case R4300i_COP0_CO_TLBWR: break;
				case R4300i_COP0_CO_TLBP: break;
				default:
					return 1;
				}
				return 1;
			}
		}
		break;
	case R4300i_CP1:
		switch (Command.u.f.fmt) {
		case R4300i_COP1_MF:
			if (Command.u.b.rt == 0) { return 0; }
			if (Command.u.b.rt == Reg1) { return 1; }
			if (Command.u.b.rt == Reg2) { return 1; }
			break;
		case R4300i_COP1_CF: break;
		case R4300i_COP1_MT: break;
		case R4300i_COP1_CT: break;
		case R4300i_COP1_S: break;
		case R4300i_COP1_D: break;
		case R4300i_COP1_W: break;
		case R4300i_COP1_L: break;
			return 1;
		}
		break;
	case R4300i_ANDI:
	case R4300i_ORI:
	case R4300i_XORI:
	case R4300i_LUI:
	case R4300i_ADDI:
	case R4300i_ADDIU:
	case R4300i_SLTI:
	case R4300i_SLTIU:
	case R4300i_DADDI:
	case R4300i_DADDIU:
	case R4300i_LB:
	case R4300i_LH:
	case R4300i_LW:
	case R4300i_LWL:
	case R4300i_LWR:
	case R4300i_LDL:
	case R4300i_LDR:
	case R4300i_LBU:
	case R4300i_LHU:
	case R4300i_LD:
	case R4300i_LWC1:
	case R4300i_LDC1:
		if (Command.u.b.rt == 0) { return 0; }
		if (Command.u.b.rt == Reg1) { return 1; }
		if (Command.u.b.rt == Reg2) { return 1; }
		break;
	case R4300i_CACHE: break;
	case R4300i_SB: break;
	case R4300i_SH: break;
	case R4300i_SW: break;
	case R4300i_SWR: break;
	case R4300i_SWL: break;
	case R4300i_SWC1: break;
	case R4300i_SDC1: break;
	case R4300i_SD: break;
	default:

		return 1;
	}
	return 0;
}