Example #1
0
std::string DSPDebugInterface::GetRawMemoryString(int memory, unsigned int address)
{
  if (DSPCore_GetState() == State::Stopped)
    return "";

  switch (memory)
  {
  case 0:  // IMEM
    switch (address >> 12)
    {
    case 0:
    case 0x8:
      return StringFromFormat("%04x", dsp_imem_read(address));
    default:
      return "--IMEM--";
    }

  case 1:  // DMEM
    switch (address >> 12)
    {
    case 0:
    case 1:
      return StringFromFormat("%04x (DMEM)", dsp_dmem_read(address));
    case 0xf:
      return StringFromFormat("%04x (MMIO)", g_dsp.ifx_regs[address & 0xFF]);
    default:
      return "--DMEM--";
    }
  }

  return "";
}
Example #2
0
void DSPDebugInterface::GetRawMemoryString(int memory, unsigned int address, char *dest, int max_size)
{
    if (DSPCore_GetState() == DSPCORE_STOP)
    {
        dest[0] = 0;
        return;
    }

    switch (memory)
    {
    case 0:  // IMEM
        switch (address >> 12)
        {
        case 0:
        case 0x8:
            sprintf(dest, "%04x", dsp_imem_read(address));
            break;
        default:
            sprintf(dest, "--IMEM--");
            break;
        }
        break;
    case 1:  // DMEM
        switch (address >> 12)
        {
        case 0:
        case 1:
            sprintf(dest, "%04x (DMEM)", dsp_dmem_read(address));
            break;
        case 0xf:
            sprintf(dest, "%04x (MMIO)", g_dsp.ifx_regs[address & 0xFF]);
            break;
        default:
            sprintf(dest, "--DMEM--");
            break;
        }
        break;
    }
}
Example #3
0
static void AnalyzeRange(int start_addr, int end_addr)
{
	// First we run an extremely simplified version of a disassembler to find
	// where all instructions start.

	// This may not be 100% accurate in case of jump tables!
	// It could get desynced, which would be bad. We'll see if that's an issue.
	u16 last_arithmetic = 0;
	for (int addr = start_addr; addr < end_addr;)
	{
		UDSPInstruction inst = dsp_imem_read(addr);
		const DSPOPCTemplate *opcode = GetOpTemplate(inst);
		if (!opcode)
		{
			addr++;
			continue;
		}
		code_flags[addr] |= CODE_START_OF_INST;
		// Look for loops.
		if ((inst & 0xffe0) == 0x0060 || (inst & 0xff00) == 0x1100)
		{
			// BLOOP, BLOOPI
			u16 loop_end = dsp_imem_read(addr + 1);
			code_flags[addr] |= CODE_LOOP_START;
			code_flags[loop_end] |= CODE_LOOP_END;
		}
		else if ((inst & 0xffe0) == 0x0040 || (inst & 0xff00) == 0x1000)
		{
			// LOOP, LOOPI
			code_flags[addr] |= CODE_LOOP_START;
			code_flags[addr + 1] |= CODE_LOOP_END;
		}

		// Mark the last arithmetic/multiplier instruction before a branch.
		// We must update the SR reg at these instructions
		if (opcode->updates_sr)
		{
			last_arithmetic = addr;
		}

		if (opcode->branch && !opcode->uncond_branch)
		{
			code_flags[last_arithmetic] |= CODE_UPDATE_SR;
		}

		// If an instruction potentially raises exceptions, mark the following
		// instruction as needing to check for exceptions
		if (opcode->opcode == 0x00c0 ||
			opcode->opcode == 0x1800 ||
			opcode->opcode == 0x1880 ||
			opcode->opcode == 0x1900 ||
			opcode->opcode == 0x1980 ||
			opcode->opcode == 0x2000 ||
			opcode->extended
			)
		code_flags[addr + opcode->size] |= CODE_CHECK_INT;

		addr += opcode->size;
	}

	// Next, we'll scan for potential idle skips.
	for (int s = 0; s < NUM_IDLE_SIGS; s++)
	{
		for (int addr = start_addr; addr < end_addr; addr++)
		{
			bool found = false;
			for (int i = 0; i < MAX_IDLE_SIG_SIZE + 1; i++)
			{
				if (idle_skip_sigs[s][i] == 0)
					found = true;
				if (idle_skip_sigs[s][i] == 0xFFFF)
					continue;
				if (idle_skip_sigs[s][i] != dsp_imem_read(addr + i))
					break;
			}
			if (found)
			{
				INFO_LOG(DSPLLE, "Idle skip location found at %02x (sigNum:%d)", addr, s+1);
				code_flags[addr] |= CODE_IDLE_SKIP;
			}
		}
	}
	INFO_LOG(DSPLLE, "Finished analysis.");
}