Exemplo n.º 1
0
void CMemoryWindow::OnSearch(wxCommandEvent& event)
{
	wxBusyCursor hourglass_cursor;
	u8* ram_ptr = nullptr;
	u32 ram_size = 0;
	// NOTE: We're assuming the base address is zero.
	switch (memview->GetMemoryType())
	{
	case 0:
	default:
		if (Memory::m_pRAM)
		{
			ram_ptr = Memory::m_pRAM;
			ram_size = Memory::REALRAM_SIZE;
		}
		break;
	case 1:
	{
		u8* aram = DSP::GetARAMPtr();
		if (aram)
		{
			ram_ptr = aram;
			ram_size = DSP::ARAM_SIZE;
		}
	}
	break;
	}
	if (!ram_ptr)
	{
		m_search_result_msg->SetLabel(_("Memory Not Ready"));
		return;
	}

	std::vector<u8> search_bytes;
	wxString search_val = valbox->GetValue();

	if (m_rb_hex->GetValue())
	{
		search_val.Trim(true).Trim(false);
		// If there's a trailing nybble, stick a zero in front to make it a byte
		if (search_val.size() & 1)
			search_val.insert(0, 1, '0');
		search_bytes.reserve(search_val.size() / 2);

		wxString conversion_buffer(2, ' ');
		for (std::size_t i = 0; i < search_val.size(); i += 2)
		{
			unsigned long byte = 0;
			conversion_buffer[0] = search_val[i];
			conversion_buffer[1] = search_val[i + 1];
			if (!conversion_buffer.ToULong(&byte, 16))
			{
				m_search_result_msg->SetLabel(_("Not Valid Hex"));
				return;
			}
			search_bytes.push_back(static_cast<u8>(byte));
		}
	}
	else
	{
		const auto& bytes = search_val.ToUTF8();
		search_bytes.assign(bytes.data(), bytes.data() + bytes.length());
	}
	search_val.Clear();

	// For completeness
	if (search_bytes.size() > ram_size)
	{
		m_search_result_msg->SetLabel(_("Value Too Large"));
		return;
	}

	if (search_bytes.empty())
	{
		m_search_result_msg->SetLabel(_("No Value Given"));
		return;
	}

	// Search starting from specified address if there is one.
	u32 addr = 0;  // Base address
	{
		wxString addr_val = addrbox->GetValue();
		addr_val.Trim(true).Trim(false);
		if (!addr_val.empty())
		{
			unsigned long addr_ul = 0;
			if (addr_val.ToULong(&addr_ul, 16))
			{
				addr = static_cast<u32>(addr_ul);
				// Don't find the result we're already looking at
				if (m_continue_search && addr == m_last_search_address)
					addr += 1;
			}
		}
	}

	// If the current address doesn't leave enough bytes to search then we're done.
	if (addr >= ram_size - search_bytes.size())
	{
		m_search_result_msg->SetLabel(_("Address Out of Range"));
		return;
	}

	u8* end = &ram_ptr[ram_size - search_bytes.size() + 1];
	u8* ptr = &ram_ptr[addr];
	while (true)
	{
		ptr = std::find(ptr, end, search_bytes[0]);
		if (ptr == end)
		{
			m_search_result_msg->SetLabel(_("No Match"));
			break;
		}

		if (std::equal(search_bytes.begin(), search_bytes.end(), ptr))
		{
			m_search_result_msg->SetLabel(_("Match Found"));
			u32 offset = static_cast<u32>(ptr - ram_ptr);
			// NOTE: SetValue() generates a synthetic wxEVT_TEXT
			addrbox->SetValue(wxString::Format("%08x", offset));
			m_last_search_address = offset;
			m_continue_search = true;
			break;
		}

		++ptr;
	}
}
Exemplo n.º 2
0
void CMemoryWindow::Search(SearchType search_type)
{
  u8* ram_ptr = nullptr;
  std::size_t ram_size = 0;
  u32 base_address = 0;
  switch (m_memory_view->GetMemoryType())
  {
  case 0:
  default:
    if (Memory::m_pRAM)
    {
      ram_ptr = Memory::m_pRAM;
      ram_size = Memory::REALRAM_SIZE;
      base_address = 0x80000000;
    }
    break;
  case 1:
  {
    u8* aram = DSP::GetARAMPtr();
    if (aram)
    {
      ram_ptr = aram;
      ram_size = DSP::ARAM_SIZE;
      base_address = 0x0c005000;
    }
  }
  break;
  }
  if (!ram_ptr)
  {
    m_search_result_msg->SetLabel(_("Memory Not Ready"));
    return;
  }

  std::vector<u8> search_bytes;
  wxString search_val = m_value_text_ctrl->GetValue();

  if (m_rb_hex->GetValue())
  {
    search_val.Trim(true).Trim(false);
    // If there's a trailing nybble, stick a zero in front to make it a byte
    if (search_val.size() & 1)
      search_val.insert(0, 1, '0');
    search_bytes.reserve(search_val.size() / 2);

    wxString conversion_buffer(2, ' ');
    for (std::size_t i = 0; i < search_val.size(); i += 2)
    {
      unsigned long byte = 0;
      conversion_buffer[0] = search_val[i];
      conversion_buffer[1] = search_val[i + 1];
      if (!conversion_buffer.ToULong(&byte, 16))
      {
        m_search_result_msg->SetLabel(_("Not Valid Hex"));
        return;
      }
      search_bytes.push_back(static_cast<u8>(byte));
    }
  }
  else
  {
    const auto& bytes = search_val.ToUTF8();
    search_bytes.assign(bytes.data(), bytes.data() + bytes.length());
  }
  search_val.Clear();

  // For completeness
  if (search_bytes.size() > ram_size)
  {
    m_search_result_msg->SetLabel(_("Value Too Large"));
    return;
  }

  if (search_bytes.empty())
  {
    m_search_result_msg->SetLabel(_("No Value Given"));
    return;
  }

  // Search starting from specified address if there is one.
  u32 addr = 0;  // Physical address
  {
    wxString addr_val = m_address_search_ctrl->GetValue();
    addr_val.Trim(true).Trim(false);
    if (!addr_val.empty())
    {
      unsigned long addr_ul = 0;
      if (addr_val.ToULong(&addr_ul, 16))
      {
        addr = static_cast<u32>(addr_ul);
        // Get physical address
        if (addr >= base_address)
          addr -= base_address;
        // Don't find the result we're already looking at
        if (m_continue_search && addr == m_last_search_address &&
          search_type == SearchType::FindNext)
        {
          addr += 1;
        }
      }
    }
  }

  // If the current address doesn't leave enough bytes to search then we're done.
  if (addr >= ram_size - search_bytes.size())
  {
    m_search_result_msg->SetLabel(_("Address Out of Range"));
    return;
  }

  const u8* ptr;
  const u8* end;
  if (search_type == SearchType::FindNext)
  {
    const u8* begin = &ram_ptr[addr];
    end = &ram_ptr[ram_size - search_bytes.size() + 1];
    ptr = std::search(begin, end, search_bytes.begin(), search_bytes.end());
  }
  else
  {
    const u8* begin = ram_ptr;
    end = &ram_ptr[addr + search_bytes.size() - 1];
    ptr = std::find_end(begin, end, search_bytes.begin(), search_bytes.end());
  }

  if (ptr != end)
  {
    m_search_result_msg->SetLabel(_("Match Found"));
    u32 offset = static_cast<u32>(ptr - ram_ptr);
    // NOTE: SetValue() generates a synthetic wxEVT_TEXT
    m_address_search_ctrl->SetValue(wxString::Format("%08x", base_address + offset));
    m_last_search_address = offset;
    m_continue_search = true;
    return;
  }

  m_search_result_msg->SetLabel(_("No Match"));
}