示例#1
0
void CRegTable::SetValue(int row, int col, const wxString& strNewVal)
{
  if (row < 32)
  {
    if (col == 1)
    {
      u32 new_val = 0;
      if (TryParseGPR(strNewVal, m_formatRegs[row], &new_val))
        GPR(row) = new_val;
    }
    else if (col == 3)
    {
      unsigned long long new_val = 0;
      if (TryParseFPR(strNewVal, m_formatFRegs[row][0], &new_val))
        riPS0(row) = new_val;
    }
    else if (col == 4)
    {
      unsigned long long new_val = 0;
      if (TryParseFPR(strNewVal, m_formatFRegs[row][1], &new_val))
        riPS1(row) = new_val;
    }
  }
  else
  {
    if ((static_cast<size_t>(row - 32) < NUM_SPECIALS) && col == 1)
    {
      u32 new_val = 0;
      if (TryParse("0x" + WxStrToStr(strNewVal), &new_val))
        SetSpecialRegValue(row - 32, new_val);
    }
  }
}
示例#2
0
wxString CRegTable::GetValue(int row, int col)
{
	if (row < 32)
	{
		switch (col)
		{
		case 0: return StrToWxStr(GetGPRName(row));
		case 1: return wxString::Format("%08x", GPR(row));
		case 2: return StrToWxStr(GetFPRName(row));
		case 3: return wxString::Format("%016llx", riPS0(row));
		case 4: return wxString::Format("%016llx", riPS1(row));
		default: return wxEmptyString;
		}
	}
	else
	{
		if (row - 32 < NUM_SPECIALS)
		{
			switch (col)
			{
			case 0: return StrToWxStr(special_reg_names[row - 32]);
			case 1: return wxString::Format("%08x", GetSpecialRegValue(row - 32));
			default: return wxEmptyString;
			}
		}
	}
	return wxEmptyString;
}
示例#3
0
void CRegTable::UpdateCachedRegs()
{
	for (int i = 0; i < 32; ++i)
	{
		m_CachedRegHasChanged[i] = (m_CachedRegs[i] != GPR(i));
		m_CachedRegs[i] = GPR(i);

		m_CachedFRegHasChanged[i][0] = (m_CachedFRegs[i][0] != riPS0(i));
		m_CachedFRegs[i][0] = riPS0(i);
		m_CachedFRegHasChanged[i][1] = (m_CachedFRegs[i][1] != riPS1(i));
		m_CachedFRegs[i][1] = riPS1(i);
	}
	for (int i = 0; i < NUM_SPECIALS; ++i)
	{
		m_CachedSpecialRegHasChanged[i] = (m_CachedSpecialRegs[i] != GetSpecialRegValue(i));
		m_CachedSpecialRegs[i] = GetSpecialRegValue(i);
	}
}
void Interpreter::lfs(UGeckoInstruction _inst)
{
	u32 uTemp = PowerPC::Read_U32(Helper_Get_EA(_inst));
	if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
	{
		u64 value = ConvertToDouble(uTemp);
		riPS0(_inst.FD) = value;
		riPS1(_inst.FD) = value;
	}
}
示例#5
0
wxString CRegTable::FormatFPR(int reg_index, int reg_part)
{
  if (m_formatFRegs[reg_index][reg_part] == FormatSpecifier::Double)
  {
    double reg = (reg_part == 0) ? rPS0(reg_index) : rPS1(reg_index);
    return wxString::Format(GetFormatString(m_formatFRegs[reg_index][reg_part]), reg);
  }
  u64 reg = (reg_part == 0) ? riPS0(reg_index) : riPS1(reg_index);
  return wxString::Format(GetFormatString(m_formatFRegs[reg_index][reg_part]), reg);
}
void Interpreter::lfsux(UGeckoInstruction _inst)
{
	u32 uAddress = Helper_Get_EA_UX(_inst);
	u32 uTemp = PowerPC::Read_U32(uAddress);
	if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
	{
		u64 value = ConvertToDouble(uTemp);
		riPS0(_inst.FD) = value;
		riPS1(_inst.FD) = value;
		rGPR[_inst.RA] = uAddress;
	}
}
示例#7
0
void RunCodeHandler()
{
	if (!SConfig::GetInstance().bEnableCheats)
		return;

	// NOTE: Need to release the lock because of GUI deadlocks with PanicAlert in HostWrite_*
	{
		std::lock_guard<std::mutex> codes_lock(s_active_codes_lock);
		if (s_code_handler_installed != Installation::Installed)
		{
			// Don't spam retry if the install failed. The corrupt / missing disk file is not likely to be
			// fixed within 1 frame of the last error.
			if (s_active_codes.empty() || s_code_handler_installed == Installation::Failed)
				return;
			s_code_handler_installed = InstallCodeHandlerLocked();

			// A warning was already issued for the install failing
			if (s_code_handler_installed != Installation::Installed)
				return;
		}
	}

	// We always do this to avoid problems with the stack since we're branching in random locations.
	// Even with function call return hooks (PC == LR), hand coded assembler won't necessarily
	// follow the ABI. [Volatile FPR, GPR, CR may not be volatile]
	// The codehandler will STMW all of the GPR registers, but we need to fix the Stack's Red
	// Zone, the LR, PC (return address) and the volatile floating point registers.
	// Build a function call stack frame.
	u32 SFP = GPR(1);                     // Stack Frame Pointer
	GPR(1) -= 256;                        // Stack's Red Zone
	GPR(1) -= 16 + 2 * 14 * sizeof(u64);  // Our stack frame (HLE_Misc::GeckoReturnTrampoline)
	GPR(1) -= 8;                          // Fake stack frame for codehandler
	GPR(1) &= 0xFFFFFFF0;                 // Align stack to 16bytes
	u32 SP = GPR(1);                      // Stack Pointer
	PowerPC::HostWrite_U32(SP + 8, SP);
	// SP + 4 is reserved for the codehandler to save LR to the stack.
	PowerPC::HostWrite_U32(SFP, SP + 8);  // Real stack frame
	PowerPC::HostWrite_U32(PC, SP + 12);
	PowerPC::HostWrite_U32(LR, SP + 16);
	PowerPC::HostWrite_U32(PowerPC::CompactCR(), SP + 20);
	// Registers FPR0->13 are volatile
	for (int i = 0; i < 14; ++i)
	{
		PowerPC::HostWrite_U64(riPS0(i), SP + 24 + 2 * i * sizeof(u64));
		PowerPC::HostWrite_U64(riPS1(i), SP + 24 + (2 * i + 1) * sizeof(u64));
	}
	DEBUG_LOG(ACTIONREPLAY, "GeckoCodes: Initiating phantom branch-and-link. "
		"PC = 0x%08X, SP = 0x%08X, SFP = 0x%08X",
		PC, SP, SFP);
	LR = HLE_TRAMPOLINE_ADDRESS;
	PC = NPC = ENTRY_POINT;
}
示例#8
0
void CRegTable::SetValue(int row, int col, const wxString& strNewVal)
{
	u32 newVal = 0;
	if (TryParse(std::string(strNewVal.mb_str()), &newVal))
	{
		if (row < 32) {
			if (col == 1)
				GPR(row) = newVal;
			else if (col == 3)
				riPS0(row) = newVal;
			else if (col == 4)
				riPS1(row) = newVal;
		} else {
			if ((row - 32 < NUM_SPECIALS) && (col == 1)) {
				SetSpecialRegValue(row - 32, newVal);
			}
		}
	}
}
void Interpreter::lfsx(UGeckoInstruction inst)
{
  const u32 address = Helper_Get_EA_X(inst);

  if ((address & 0b11) != 0)
  {
    GenerateAlignmentException(address);
    return;
  }

  const u32 temp = PowerPC::Read_U32(address);

  if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
  {
    const u64 value = ConvertToDouble(temp);
    riPS0(inst.FD) = value;
    riPS1(inst.FD) = value;
  }
}
示例#10
0
static wxString GetValueByRowCol(int row, int col)
{
	if (row < 32)
	{
		switch (col)
		{
		case 0: return StrToWxStr(GekkoDisassembler::GetGPRName(row));
		case 1: return wxString::Format("%08x", GPR(row));
		case 2: return StrToWxStr(GekkoDisassembler::GetFPRName(row));
		case 3: return wxString::Format("%016llx", riPS0(row));
		case 4: return wxString::Format("%016llx", riPS1(row));
		case 5:
		{
			if (row < 4)
				return wxString::Format("DBAT%01d", row);

			if (row < 8)
				return wxString::Format("IBAT%01d", row - 4);

			if (row < 12)
				return wxString::Format("DBAT%01d", row - 4);

			if (row < 16)
				return wxString::Format("IBAT%01d", row - 8);

			break;
		}
		case 6:
		{
			if (row < 4)
				return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_DBAT0U + row * 2] << 32 | PowerPC::ppcState.spr[SPR_DBAT0L + row * 2]);

			if (row < 8)
				return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_IBAT0U + (row - 4) * 2] << 32 | PowerPC::ppcState.spr[SPR_IBAT0L + (row - 4) * 2]);

			if (row < 12)
				return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_DBAT4U + (row - 12) * 2] << 32 | PowerPC::ppcState.spr[SPR_DBAT4L + (row - 12) * 2]);

			if (row < 16)
				return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_IBAT4U + (row - 16) * 2] << 32 | PowerPC::ppcState.spr[SPR_IBAT4L + (row - 16) * 2]);

			break;
		}
		case 7:
		{
			if (row < 16)
				return wxString::Format("SR%02d", row);

			break;
		}
		case 8:
		{
			if (row < 16)
				return wxString::Format("%08x", PowerPC::ppcState.sr[row]);

			break;
		}
		default: return wxEmptyString;
		}
	}
	else
	{
		if (row - 32 < NUM_SPECIALS)
		{
			switch (col)
			{
			case 0: return StrToWxStr(special_reg_names[row - 32]);
			case 1: return wxString::Format("%08x", GetSpecialRegValue(row - 32));
			default: return wxEmptyString;
			}
		}
	}
	return wxEmptyString;
}
示例#11
0
void RegisterWidget::PopulateTable()
{
  for (int i = 0; i < 32; i++)
  {
    // General purpose registers (int)
    AddRegister(i, 0, RegisterType::gpr, "r" + std::to_string(i), [i] { return GPR(i); },
                [i](u64 value) { GPR(i) = value; });

    // Floating point registers (double)
    AddRegister(i, 2, RegisterType::fpr, "f" + std::to_string(i), [i] { return riPS0(i); },
                [i](u64 value) { riPS0(i) = value; });

    AddRegister(i, 4, RegisterType::fpr, "", [i] { return riPS1(i); },
                [i](u64 value) { riPS1(i) = value; });
  }

  for (int i = 0; i < 8; i++)
  {
    // IBAT registers
    AddRegister(i, 5, RegisterType::ibat, "IBAT" + std::to_string(i),
                [i] {
                  return (static_cast<u64>(PowerPC::ppcState.spr[SPR_IBAT0U + i * 2]) << 32) +
                         PowerPC::ppcState.spr[SPR_IBAT0L + i * 2];
                },
                nullptr);
    // DBAT registers
    AddRegister(i + 8, 5, RegisterType::dbat, "DBAT" + std::to_string(i),
                [i] {
                  return (static_cast<u64>(PowerPC::ppcState.spr[SPR_DBAT0U + i * 2]) << 32) +
                         PowerPC::ppcState.spr[SPR_DBAT0L + i * 2];
                },
                nullptr);
    // Graphics quantization registers
    AddRegister(i + 16, 7, RegisterType::gqr, "GQR" + std::to_string(i),
                [i] { return PowerPC::ppcState.spr[SPR_GQR0 + i]; }, nullptr);
  }

  for (int i = 0; i < 16; i++)
  {
    // SR registers
    AddRegister(i, 7, RegisterType::sr, "SR" + std::to_string(i),
                [i] { return PowerPC::ppcState.sr[i]; },
                [i](u64 value) { PowerPC::ppcState.sr[i] = value; });
  }

  // Special registers
  // TB
  AddRegister(16, 5, RegisterType::tb, "TB",
              [] {
                return static_cast<u64>(PowerPC::ppcState.spr[SPR_TU]) << 32 |
                       PowerPC::ppcState.spr[SPR_TL];
              },
              nullptr);

  // PC
  AddRegister(17, 5, RegisterType::pc, "PC", [] { return PowerPC::ppcState.pc; },
              [](u64 value) { PowerPC::ppcState.pc = value; });

  // LR
  AddRegister(18, 5, RegisterType::lr, "LR", [] { return PowerPC::ppcState.spr[SPR_LR]; },
              [](u64 value) { PowerPC::ppcState.spr[SPR_LR] = value; });

  // CTR
  AddRegister(19, 5, RegisterType::ctr, "CTR", [] { return PowerPC::ppcState.spr[SPR_CTR]; },
              [](u64 value) { PowerPC::ppcState.spr[SPR_CTR] = value; });

  // CR
  AddRegister(20, 5, RegisterType::cr, "CR", [] { return GetCR(); },
              [](u64 value) { SetCR(value); });

  // XER
  AddRegister(21, 5, RegisterType::xer, "XER", [] { return GetXER().Hex; },
              [](u64 value) { SetXER(UReg_XER(value)); });

  // FPSCR
  AddRegister(22, 5, RegisterType::fpscr, "FPSCR", [] { return PowerPC::ppcState.fpscr; },
              [](u64 value) { PowerPC::ppcState.fpscr = value; });

  // MSR
  AddRegister(23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr; },
              [](u64 value) { PowerPC::ppcState.msr = value; });

  // SRR 0-1
  AddRegister(24, 5, RegisterType::srr, "SRR0", [] { return PowerPC::ppcState.spr[SPR_SRR0]; },
              [](u64 value) { PowerPC::ppcState.spr[SPR_SRR0] = value; });
  AddRegister(25, 5, RegisterType::srr, "SRR1", [] { return PowerPC::ppcState.spr[SPR_SRR1]; },
              [](u64 value) { PowerPC::ppcState.spr[SPR_SRR1] = value; });

  // Exceptions
  AddRegister(26, 5, RegisterType::exceptions, "Exceptions",
              [] { return PowerPC::ppcState.Exceptions; },
              [](u64 value) { PowerPC::ppcState.Exceptions = value; });

  // Int Mask
  AddRegister(27, 5, RegisterType::int_mask, "Int Mask",
              [] { return ProcessorInterface::GetMask(); }, nullptr);

  // Int Cause
  AddRegister(28, 5, RegisterType::int_cause, "Int Cause",
              [] { return ProcessorInterface::GetCause(); }, nullptr);

  // DSISR
  AddRegister(29, 5, RegisterType::dsisr, "DSISR", [] { return PowerPC::ppcState.spr[SPR_DSISR]; },
              [](u64 value) { PowerPC::ppcState.spr[SPR_DSISR] = value; });
  // DAR
  AddRegister(30, 5, RegisterType::dar, "DAR", [] { return PowerPC::ppcState.spr[SPR_DAR]; },
              [](u64 value) { PowerPC::ppcState.spr[SPR_DAR] = value; });

  // Hash Mask
  AddRegister(
      31, 5, RegisterType::pt_hashmask, "Hash Mask",
      [] { return (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base; },
      nullptr);

  emit RequestTableUpdate();
  m_table->resizeColumnsToContents();
}