Пример #1
0
void __KernelMemoryInit()
{
	kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd()-PSP_GetKernelMemoryBase());
	userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd()-PSP_GetUserMemoryBase());
	INFO_LOG(HLE, "Kernel and user memory pools initialized");

	vplWaitTimer = CoreTiming::RegisterEvent("VplTimeout", __KernelVplTimeout);
}
Пример #2
0
void JitBlockCache::FinalizeBlock(int block_num, bool block_link) {
    JitBlock &b = blocks_[block_num];

    b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
    MIPSOpcode opcode = GetEmuHackOpForBlock(block_num);
    Memory::Write_Opcode_JIT(b.originalAddress, opcode);

    AddBlockMap(block_num);

    u32 latestExit = 0;
    if (block_link) {
        for (int i = 0; i < MAX_JIT_BLOCK_EXITS; i++) {
            if (b.exitAddress[i] != INVALID_EXIT) {
                links_to_.insert(std::make_pair(b.exitAddress[i], block_num));
                latestExit = std::max(latestExit, b.exitAddress[i]);
            }
        }

        LinkBlock(block_num);
        LinkBlockExits(block_num);
    }

    if (Memory::IsScratchpadAddress(b.originalAddress)) {
        ExpandRange(blockMemRanges_[JITBLOCK_RANGE_SCRATCH], b.originalAddress, latestExit);
    }
    const u32 halfUserMemory = (PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase()) / 2;
    if (b.originalAddress < PSP_GetUserMemoryBase() + halfUserMemory) {
        ExpandRange(blockMemRanges_[JITBLOCK_RANGE_RAMBOTTOM], b.originalAddress, latestExit);
    }
    if (latestExit > PSP_GetUserMemoryBase() + halfUserMemory) {
        ExpandRange(blockMemRanges_[JITBLOCK_RANGE_RAMTOP], b.originalAddress, latestExit);
    }

#if defined USE_OPROFILE && USE_OPROFILE
    char buf[100];
    sprintf(buf, "EmuCode%x", b.originalAddress);
    const u8* blockStart = blocks_[block_num].checkedEntry;
    op_write_native_code(agent, buf, (uint64_t)blockStart, blockStart, b.normalEntry + b.codeSize - b.checkedEntry);
#endif

#ifdef USE_VTUNE
    sprintf(b.blockName, "EmuCode_0x%08x", b.originalAddress);

    iJIT_Method_Load jmethod = {0};
    jmethod.method_id = iJIT_GetNewMethodID();
    jmethod.class_file_name = "";
    jmethod.source_file_name = __FILE__;
    jmethod.method_load_address = (void*)blocks_[block_num].checkedEntry;
    jmethod.method_size = b.normalEntry + b.codeSize - b.checkedEntry;
    jmethod.line_number_size = 0;
    jmethod.method_name = b.blockName;
    iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
#endif
}
Пример #3
0
void __KernelMemoryInit()
{
	kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd()-PSP_GetKernelMemoryBase());
	userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd()-PSP_GetUserMemoryBase());
	INFO_LOG(HLE, "Kernel and user memory pools initialized");

	vplWaitTimer = CoreTiming::RegisterEvent("VplTimeout", __KernelVplTimeout);

	flags_ = 0;
	sdkVersion_ = 0;
	compilerVersion_ = 0;
	memset(tlsUsedIndexes, 0, sizeof(tlsUsedIndexes));
}
Пример #4
0
void DumpMemoryWindow::changeMode(HWND hwnd, Mode newMode)
{
	char buffer[128];
	selectedMode = newMode;
	
	SendMessage(GetDlgItem(hwnd,IDC_DUMP_USERMEMORY),BM_SETCHECK,selectedMode == MODE_RAM ? BST_CHECKED : BST_UNCHECKED,0);
	SendMessage(GetDlgItem(hwnd,IDC_DUMP_VRAM),BM_SETCHECK,selectedMode == MODE_VRAM ? BST_CHECKED : BST_UNCHECKED,0);
	SendMessage(GetDlgItem(hwnd,IDC_DUMP_SCRATCHPAD),BM_SETCHECK,selectedMode == MODE_SCRATCHPAD ? BST_CHECKED : BST_UNCHECKED,0);
	SendMessage(GetDlgItem(hwnd,IDC_DUMP_CUSTOMRANGE),BM_SETCHECK,selectedMode == MODE_CUSTOM ? BST_CHECKED : BST_UNCHECKED,0);

	if (selectedMode == MODE_CUSTOM)
	{
		EnableWindow(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),TRUE);
		EnableWindow(GetDlgItem(hwnd,IDC_DUMP_SIZE),TRUE);

		if (filenameChosen == false)
			SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),"Custom.dump");
	} else {
		u32 start, size;
		const char* defaultFileName;

		switch (selectedMode)
		{
		case MODE_RAM:
			start = PSP_GetUserMemoryBase();
			size = PSP_GetUserMemoryEnd()-start;
			defaultFileName = "RAM.dump";
			break;
		case MODE_VRAM:
			start = PSP_GetVidMemBase();
			size = PSP_GetVidMemEnd()-start;
			defaultFileName = "VRAM.dump";
			break;
		case MODE_SCRATCHPAD:
			start = PSP_GetScratchpadMemoryBase();
			size = PSP_GetScratchpadMemoryEnd()-start;
			defaultFileName = "Scratchpad.dump";
			break;
		}
		
		sprintf(buffer,"0x%08X",start);
		SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),buffer);
		EnableWindow(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),FALSE);

		sprintf(buffer,"0x%08X",size);
		SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_SIZE),buffer);
		EnableWindow(GetDlgItem(hwnd,IDC_DUMP_SIZE),FALSE);
		
		if (filenameChosen == false)
			SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),defaultFileName);
	}
}
Пример #5
0
jint Java_com_ruin_psp_PSP_readRAMU32(JNIEnv *env, jclass clazz, jint address) {
  u32 start = PSP_GetUserMemoryBase() + (u32)address;
  u32 size = 32;

  auto memLock = Memory::Lock();
  if (!PSP_IsInited())
    return 0;

  if (!checkStart(start, size))
    return 0;

  return (jint) Memory::Read_U32(start);
}
Пример #6
0
static inline u32 SampleNearest(int level, unsigned int u, unsigned int v)
{
	GETextureFormat texfmt = gstate.getTextureFormat();
	u32 texaddr = (gstate.texaddr[level] & 0xFFFFF0) | ((gstate.texbufwidth[level] << 8) & 0x0F000000);
	u8* srcptr = (u8*)Memory::GetPointer(texaddr); // TODO: not sure if this is the right place to load from...?

	// Special rules for kernel textures (PPGe), TODO: Verify!
	int texbufwidth = (texaddr < PSP_GetUserMemoryBase()) ? gstate.texbufwidth[level] & 0x1FFF : gstate.texbufwidth[level] & 0x7FF;

	// TODO: Should probably check if textures are aligned properly...

	if (texfmt == GE_TFMT_4444) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
		return DecodeRGBA4444(*(u16*)srcptr);
	} else if (texfmt == GE_TFMT_5551) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
		return DecodeRGBA5551(*(u16*)srcptr);
	} else if (texfmt == GE_TFMT_5650) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
		return DecodeRGB565(*(u16*)srcptr);
	} else if (texfmt == GE_TFMT_8888) {
		srcptr += GetPixelDataOffset(32, texbufwidth*8, u, v);
		return DecodeRGBA8888(*(u32*)srcptr);
	} else if (texfmt == GE_TFMT_CLUT32) {
		srcptr += GetPixelDataOffset(32, texbufwidth*8, u, v);

		u32 val = srcptr[0] + (srcptr[1] << 8) + (srcptr[2] << 16) + (srcptr[3] << 24);

		return LookupColor(GetClutIndex(val), level);
	} else if (texfmt == GE_TFMT_CLUT16) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);

		u16 val = srcptr[0] + (srcptr[1] << 8);

		return LookupColor(GetClutIndex(val), level);
	} else if (texfmt == GE_TFMT_CLUT8) {
		srcptr += GetPixelDataOffset(8, texbufwidth*8, u, v);

		u8 val = *srcptr;

		return LookupColor(GetClutIndex(val), level);
	} else if (texfmt == GE_TFMT_CLUT4) {
		srcptr += GetPixelDataOffset(4, texbufwidth*8, u, v);

		u8 val = (u & 1) ? (srcptr[0] >> 4) : (srcptr[0] & 0xF);

		return LookupColor(GetClutIndex(val), level);
	} else {
Пример #7
0
jfloat Java_com_ruin_psp_PSP_readRAMU32Float (JNIEnv *env, jclass clazz, jint address) {
  u32 start = PSP_GetUserMemoryBase() + (u32)address;
  u32 size = 32;

  auto memLock = Memory::Lock();
  if (!PSP_IsInited())
    return 0;

  if (!checkStart(start, size))
    return 0;

  u32 dat = Memory::Read_U32(start);
  float f;
  memcpy(&f, &dat, sizeof(f));

  return (jfloat) f;
}
Пример #8
0
double ExecCPUTest() {
	int blockTicks = 1000000;
	int total = 0;
	double st = real_time_now();
	do {
		for (int j = 0; j < 1000; ++j) {
			currentMIPS->pc = PSP_GetUserMemoryBase();
			coreState = CORE_RUNNING;

			while (coreState == CORE_RUNNING) {
				mipsr4k.RunLoopUntil(blockTicks);
			}
			++total;
		}
	}
	while (real_time_now() - st < 0.5);
	double elapsed = real_time_now() - st;

	return total / elapsed;
}
Пример #9
0
jbyteArray Java_com_ruin_psp_PSP_readRam(JNIEnv *env, jclass clazz, jint address, jint size) {
  u32 start = PSP_GetUserMemoryBase() + (u32)address;

  auto memLock = Memory::Lock();
  if (!PSP_IsInited())
    return 0;

  if (!checkStart(start, size))
    return 0;

  u8 *ptr = Memory::GetPointer(start);

  jbyte arr[size];

  memcpy(&arr, ptr, sizeof(arr));

  jbyteArray ret = env->NewByteArray(size);
  env->SetByteArrayRegion(ret, 0, size, arr);
  return ret;
}
Пример #10
0
bool TestJit() {
	SetupJitHarness();

	currentMIPS->pc = PSP_GetUserMemoryBase();
	u32 *p = (u32 *)Memory::GetPointer(currentMIPS->pc);

	// TODO: Smarter way of seeding in the code sequence.
	static const char *lines[] = {
		//"vcrsp.t C000, C100, C200",
		//"vdot.q C000, C100, C200",
		//"vmmul.q M000, M100, M200",
		"lui r1, 0x8910",
		"vmmul.q M000, M100, M200",
		"sv.q C000, 0(r1)",
		"sv.q C000, 16(r1)",
		"sv.q C000, 32(r1)",
		"sv.q C000, 48(r1)",
		/*
		"abs.s f1, f1",
		"cvt.w.s f1, f1",
		"cvt.w.s f3, f1",
		"cvt.w.s f0, f2",
		"cvt.w.s f5, f1",
		"cvt.w.s f6, f5",
		*/
	};

	bool compileSuccess = true;
	u32 addr = currentMIPS->pc;
	DebugInterface *dbg = currentDebugMIPS;
	for (int i = 0; i < 100; ++i) {
		/*
		// VFPU ops aren't supported by MIPSAsm yet.
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8);
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15);
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8);
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8);
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8);
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8);
		*p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8);
		*/
		for (size_t j = 0; j < ARRAY_SIZE(lines); ++j) {
			p++;
			if (!MIPSAsm::MipsAssembleOpcode(lines[j], currentDebugMIPS, addr)) {
				printf("ERROR: %ls\n", MIPSAsm::GetAssembleError().c_str());
				compileSuccess = false;
			}
			addr += 4;
		}
	}

	*p++ = MIPS_MAKE_SYSCALL("UnitTestFakeSyscalls", "UnitTestTerminator");
	*p++ = MIPS_MAKE_BREAK(1);

	// Dogfood.
	addr = currentMIPS->pc;
	for (size_t j = 0; j < ARRAY_SIZE(lines); ++j) {
		char line[512];
		MIPSDisAsm(Memory::Read_Instruction(addr), addr, line, true);
		addr += 4;
		printf("%s\n", line);
	}

	printf("\n");

	double jit_speed = 0.0, interp_speed = 0.0;
	if (compileSuccess) {
		interp_speed = ExecCPUTest();
		mipsr4k.UpdateCore(CPUCore::JIT);
		jit_speed = ExecCPUTest();

		// Disassemble
		JitBlockCache *cache = MIPSComp::jit->GetBlockCache();
		JitBlock *block = cache->GetBlock(0);  // Should only be one block.
#if defined(ARM)
		std::vector<std::string> lines = DisassembleArm2(block->normalEntry, block->codeSize);
#elif defined(ARM64)
		std::vector<std::string> lines = DisassembleArm64(block->normalEntry, block->codeSize);
#else
		std::vector<std::string> lines = DisassembleX86(block->normalEntry, block->codeSize);
#endif
		// Cut off at 25 due to the repetition above. Might need tweaking for large instructions.
		const int cutoff = 25;
		for (int i = 0; i < std::min((int)lines.size(), cutoff); i++) {
			printf("%s\n", lines[i].c_str());
		}
		if (lines.size() > cutoff)
			printf("...\n");
		printf("Jit was %fx faster than interp.\n\n", jit_speed / interp_speed);
	}

	printf("\n");

	DestroyJitHarness();

	return jit_speed >= interp_speed;
}