Ejemplo n.º 1
0
void __IoInit() {
	INFO_LOG(HLE, "Starting up I/O...");

	MemoryStick_SetFatState(PSP_FAT_MEMORYSTICK_STATE_ASSIGNED);

#ifdef _WIN32

	char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR], file[_MAX_FNAME], ext[_MAX_EXT];
	char memstickpath[_MAX_PATH];
	char flashpath[_MAX_PATH];

	GetModuleFileName(NULL,path_buffer,sizeof(path_buffer));

	char *winpos = strstr(path_buffer, "Windows");
	if (winpos)
	*winpos = 0;
	strcat(path_buffer, "dummy.txt");

	_splitpath_s(path_buffer, drive, dir, file, ext );

	// Mount a couple of filesystems
	sprintf(memstickpath, "%s%sMemStick\\", drive, dir);
	sprintf(flashpath, "%s%sFlash\\", drive, dir);

#else
	// TODO
	std::string memstickpath = g_Config.memCardDirectory;
	std::string flashpath = g_Config.flashDirectory;
#endif

	DirectoryFileSystem *memstick;
	DirectoryFileSystem *flash;

	memstick = new DirectoryFileSystem(&pspFileSystem, memstickpath);
	flash = new DirectoryFileSystem(&pspFileSystem, flashpath);
	pspFileSystem.Mount("ms0:", memstick);
	pspFileSystem.Mount("fatms0:", memstick);
	pspFileSystem.Mount("fatms:", memstick);
	pspFileSystem.Mount("flash0:", flash);
	pspFileSystem.Mount("flash1:", flash);
	
	__KernelListenThreadEnd(&TellFsThreadEnded);
}
Ejemplo n.º 2
0
u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 outPtr, int outLen) {
	if (strcmp(name, "emulator:")) {
		DEBUG_LOG(HLE,"sceIoDevctl(\"%s\", %08x, %08x, %i, %08x, %i)", name, cmd, argAddr, argLen, outPtr, outLen);
	}

	// UMD checks
	switch (cmd) {
	case 0x01F20001:  // Get Disc Type.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0x10, outPtr);  // Game disc
			return 0;
		} else {
			return -1;
		}
		break;
	case 0x01F20002:  // Get current LBA.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0, outPtr);  // Game disc
			return 0;
		} else {
			return -1;
		}
		break;
	case 0x01F100A3:  // Seek
		return 0;
	}

	// This should really send it on to a FileSystem implementation instead.

	if (!strcmp(name, "mscmhc0:") || !strcmp(name, "ms0:"))
	{
		switch (cmd)
		{
		// does one of these set a callback as well? (see coded arms)
		case 0x02015804:	// Register callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK, cbId, MemoryStick_State());
					return 0;
				} else {
					return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
				}
			}
			break;

		case 0x02025805:	// Unregister callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick callback %i", cbId);
					return 0;
				} else {
					return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
				}
			}
			break;

		case 0x02025801:	// Memstick Driver status?
			if (Memory::IsValidAddress(outPtr) && outLen >= 4) {
				Memory::Write_U32(4, outPtr);  // JPSCP: The right return value is 4 for some reason
				return 0;
			} else {
				return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
			}

		case 0x02025806:	// Memory stick inserted?
			if (Memory::IsValidAddress(outPtr) && outLen >= 4) {
				Memory::Write_U32(1, outPtr);
				return 0;
			} else {
				return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
			}

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			if (Memory::IsValidAddress(argAddr) && argLen >= 4) {  // "Should" be outPtr but isn't
				u32 pointer = Memory::Read_U32(argAddr);
				u32 sectorSize = 0x200;
				u32 memStickSectorSize = 32 * 1024;
				u32 sectorCount = memStickSectorSize / sectorSize;
				u64 freeSize = 1 * 1024 * 1024 * 1024;
				DeviceSize deviceSize;
				deviceSize.maxClusters = (u32)((freeSize  * 95 / 100) / (sectorSize * sectorCount));
				deviceSize.freeClusters = deviceSize.maxClusters;
				deviceSize.maxSectors = deviceSize.maxClusters;
				deviceSize.sectorSize = sectorSize;
				deviceSize.sectorCount = sectorCount;
				Memory::WriteStruct(pointer, &deviceSize);
				DEBUG_LOG(HLE, "Returned memstick size: maxSectors=%i", deviceSize.maxSectors);
				return 0;
			} else {
				ERROR_LOG(HLE, "memstick size query: bad params");
				return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
			}
		}
	}

	if (!strcmp(name, "fatms0:"))
	{
		switch (cmd) {
		case 0x02415821:  // MScmRegisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick FAT callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId, MemoryStick_FatState());
					return 0;
				} else {
					return -1;
				}
			}
			break;
		case 0x02415822: // MScmUnregisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick FAT callback %i", cbId);
					return 0;
				} else {
					return -1;
				}
			}

		case 0x02415823:  // Set FAT as enabled
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				MemoryStick_SetFatState((MemStickFatState)Memory::Read_U32(argAddr));
				return 0;
			} else {
				ERROR_LOG(HLE, "Failed 0x02415823 fat");
				return -1;
			}
			break;

		case 0x02425823:  // Check if FAT enabled
			if (Memory::IsValidAddress(outPtr) && outLen == 4) {
				Memory::Write_U32(MemoryStick_FatState(), outPtr);
				return 0;
			} else {
				ERROR_LOG(HLE, "Failed 0x02425823 fat");
				return -1;
			}
			break;

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			{
				if (Memory::IsValidAddress(argAddr) && argLen >= 4) {  // NOTE: not outPtr
					u32 pointer = Memory::Read_U32(argAddr);
					u32 sectorSize = 0x200;
					u32 memStickSectorSize = 32 * 1024;
					u32 sectorCount = memStickSectorSize / sectorSize;
					u64 freeSize = 1 * 1024 * 1024 * 1024;
					DeviceSize deviceSize;
					deviceSize.maxClusters = (u32)((freeSize  * 95 / 100) / (sectorSize * sectorCount));
					deviceSize.freeClusters = deviceSize.maxClusters;
					deviceSize.maxSectors = deviceSize.maxClusters;
					deviceSize.sectorSize = sectorSize;
					deviceSize.sectorCount = sectorCount;
					Memory::WriteStruct(pointer, &deviceSize);
					return 0;
				} else {
					return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
				}
			}
		}
	}

	if (!strcmp(name, "kemulator:") || !strcmp(name, "emulator:"))
	{
		// Emulator special tricks!
		switch (cmd)
		{
		case 1:	// EMULATOR_DEVCTL__GET_HAS_DISPLAY
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(0, outPtr);	 // TODO: Make a headless mode for running tests!
			return 0;
		case 2:	// EMULATOR_DEVCTL__SEND_OUTPUT
			{
				std::string data(Memory::GetCharPointer(argAddr), argLen);
				if (PSP_CoreParameter().printfEmuLog)
				{
					host->SendDebugOutput(data.c_str());
				}
				else
				{
					DEBUG_LOG(HLE, "%s", data.c_str());
				}
				return 0;
			}
		case 3:	// EMULATOR_DEVCTL__IS_EMULATOR
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(1, outPtr);
			return 0;
		case 4: // EMULATOR_DEVCTL__VERIFY_STATE
			// Note that this is async, and makes sure the save state matches up.
			SaveState::Verify();
			// TODO: Maybe save/load to a file just to be sure?
			return 0;
		}

		ERROR_LOG(HLE, "sceIoDevCtl: UNKNOWN PARAMETERS");

		return 0;
	}

	//089c6d1c weird branch
	/*
	089c6bdc ]: HLE: sceKernelCreateCallback(name= MemoryStick Detection ,entry= 089c7484 ) (z_un_089c6bc4)
	089c6c18 ]: HLE: sceIoDevctl("mscmhc0:", 02015804, 09ffb9c0, 4, 00000000, 0) (z_un_089c6bc4)
	089c6c40 ]: HLE: sceKernelCreateCallback(name= MemoryStick Assignment ,entry= 089c7534 ) (z_un_089c6bc4)
	089c6c78 ]: HLE: sceIoDevctl("fatms0:", 02415821, 09ffb9c4, 4, 00000000, 0) (z_un_089c6bc4)
	089c6cac ]: HLE: sceIoDevctl("mscmhc0:", 02025806, 00000000, 0, 09ffb9c8, 4) (z_un_089c6bc4)
	*/
	return SCE_KERNEL_ERROR_UNSUP;
}
Ejemplo n.º 3
0
void sceIoDevctl() //(const char *name, int cmd, void *arg, size_t arglen, void *buf, size_t *buflen); 
{
	const char *name = Memory::GetCharPointer(PARAM(0));
	int cmd = PARAM(1);
	u32 argAddr = PARAM(2);
	int argLen = PARAM(3);
	u32 outPtr = PARAM(4);
	int outLen = PARAM(5);

	if (strcmp(name, "emulator:")) {
		DEBUG_LOG(HLE,"sceIoDevctl(\"%s\", %08x, %08x, %i, %08x, %i)", name, cmd,argAddr,argLen,outPtr,outLen);
	}

	// UMD checks
	switch (cmd) {
	case 0x01F20001:  // Get Disc Type.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0x10, outPtr);  // Game disc
			RETURN(0); return;
		} else {
			RETURN(-1); return;
		}
		break;
	case 0x01F20002:  // Get current LBA.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0, outPtr);  // Game disc
			RETURN(0); return;
		} else {
			RETURN(-1); return;
		}
		break;
	case 0x01F100A3:  // Seek
		RETURN(0); return;
		break;
	}
	
	// This should really send it on to a FileSystem implementation instead.

	if (!strcmp(name, "mscmhc0:") || !strcmp(name, "ms0:"))
	{
		switch (cmd)
		{
		// does one of these set a callback as well? (see coded arms)
		case 0x02015804:	// Register callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK, cbId, MemoryStick_State());
					RETURN(0);
				} else {
					RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
				}
				return;
			}
			break;

		case 0x02025805:	// Unregister callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick callback %i", cbId);
					RETURN(0);
				} else {
					RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
				}
				return;
			}
			break;

		case 0x02025806:	// Memory stick inserted?
		case 0x02025801:	// Memstick Driver status?
			if (Memory::IsValidAddress(outPtr)) {
				Memory::Write_U32(1, outPtr);
				RETURN(0);
			} else {
				RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
			}
			return;

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			if (Memory::IsValidAddress(argAddr)) {  // "Should" be outPtr but isn't
				u32 pointer = Memory::Read_U32(argAddr);

				u64 totalSize = (u32)2 * 1024 * 1024 * 1024;
				u64 freeSize	= 1 * 1024 * 1024 * 1024;
				DeviceSize deviceSize;
				deviceSize.maxSectors				= 512;
				deviceSize.sectorSize				= 0x200;
				deviceSize.sectorsPerCluster = 0x08;
				deviceSize.totalClusters		 = (u32)((totalSize * 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
				deviceSize.freeClusters			= (u32)((freeSize	* 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
				Memory::WriteStruct(pointer, &deviceSize);
				RETURN(0);
			} else {
				RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
			}
			return;
		}
	}

	if (!strcmp(name, "fatms0:"))
	{
		switch (cmd) {
		case 0x02415821:  // MScmRegisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick FAT callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId, MemoryStick_FatState());
					RETURN(0);
				} else {
					RETURN(-1);
				}
				return;
			}
			break;
		case 0x02415822: // MScmUnregisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick FAT callback %i", cbId);
					RETURN(0);
				} else {
					RETURN(-1);
				}
				return;
			}

		case 0x02415823:  // Set FAT as enabled
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				MemoryStick_SetFatState((MemStickFatState)Memory::Read_U32(argAddr));
				RETURN(0);
			} else {
				ERROR_LOG(HLE, "Failed 0x02415823 fat");
				RETURN(-1);
			}
			break;

		case 0x02425823:  // Check if FAT enabled
			if (Memory::IsValidAddress(outPtr) && outLen == 4) {
				Memory::Write_U32(MemoryStick_FatState(), outPtr);
				RETURN(0);
			} else {
				ERROR_LOG(HLE, "Failed 0x02425823 fat");
				RETURN(-1);
			}
			break;

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			{
				if (Memory::IsValidAddress(argAddr)) {  // "Should" be outPtr but isn't
					u32 pointer = Memory::Read_U32(argAddr);

					u64 totalSize = (u32)2 * 1024 * 1024 * 1024;
					u64 freeSize	= 1 * 1024 * 1024 * 1024;
					DeviceSize deviceSize;
					deviceSize.maxSectors				= 512;
					deviceSize.sectorSize				= 0x200;
					deviceSize.sectorsPerCluster = 0x08;
					deviceSize.totalClusters		 = (u32)((totalSize * 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
					deviceSize.freeClusters			= (u32)((freeSize	* 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
					Memory::WriteStruct(pointer, &deviceSize);
					RETURN(0);
				} else {
					RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
				}
				return;
			}
		}
	}


	if (!strcmp(name, "kemulator:") || !strcmp(name, "emulator:"))
	{
		// Emulator special tricks!
		switch (cmd)
		{
		case 1:	// EMULATOR_DEVCTL__GET_HAS_DISPLAY
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(0, outPtr);	 // TODO: Make a headless mode for running tests!
			RETURN(0);
			return;
		case 2:	// EMULATOR_DEVCTL__SEND_OUTPUT
			{
				std::string data(Memory::GetCharPointer(argAddr), argLen);
				if (PSP_CoreParameter().printfEmuLog)
				{
					printf("%s", data.c_str());
#ifdef _WIN32
					OutputDebugString(data.c_str());
#endif
					// Also collect the debug output
					emuDebugOutput += data;
				}
				else
				{
					DEBUG_LOG(HLE, "%s", data.c_str());
				}
				RETURN(0);
				return;
			}
		case 3:	// EMULATOR_DEVCTL__IS_EMULATOR
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(1, outPtr);	 // TODO: Make a headless mode for running tests!
			RETURN(0);
			return;
		}

		ERROR_LOG(HLE, "sceIoDevCtl: UNKNOWN PARAMETERS");
		
		RETURN(0);
		return;
	}

	//089c6d1c weird branch
	/*
	089c6bdc ]: HLE: sceKernelCreateCallback(name= MemoryStick Detection ,entry= 089c7484 ) (z_un_089c6bc4)
	089c6c18 ]: HLE: sceIoDevctl("mscmhc0:", 02015804, 09ffb9c0, 4, 00000000, 0) (z_un_089c6bc4)
	089c6c40 ]: HLE: sceKernelCreateCallback(name= MemoryStick Assignment ,entry= 089c7534 ) (z_un_089c6bc4)
	089c6c78 ]: HLE: sceIoDevctl("fatms0:", 02415821, 09ffb9c4, 4, 00000000, 0) (z_un_089c6bc4)
	089c6cac ]: HLE: sceIoDevctl("mscmhc0:", 02025806, 00000000, 0, 09ffb9c8, 4) (z_un_089c6bc4)
	*/
	RETURN(SCE_KERNEL_ERROR_UNSUP);
}