2012-11-01 15:19:01 +00:00
|
|
|
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
2012-11-04 22:01:49 +00:00
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
|
|
|
#include "HLE.h"
|
|
|
|
#include "../MIPS/MIPS.h"
|
|
|
|
#include "../System.h"
|
|
|
|
#include "../CoreParameter.h"
|
|
|
|
#include "sceGe.h"
|
2012-11-06 14:46:21 +00:00
|
|
|
#include "sceKernelThread.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
#include "sceKernelInterrupt.h"
|
2012-11-06 16:05:27 +00:00
|
|
|
#include "../GPU/GPUState.h"
|
|
|
|
#include "../GPU/GPUInterface.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
// TODO: This doesn't really belong here
|
|
|
|
static int state;
|
|
|
|
|
|
|
|
|
|
|
|
void __GeInit()
|
|
|
|
{
|
|
|
|
state = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __GeShutdown()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// The GE is implemented wrong - it should be parallel to the CPU execution instead of
|
|
|
|
// synchronous.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
u32 sceGeEdramGetAddr()
|
|
|
|
{
|
|
|
|
u32 retVal = 0x04000000;
|
|
|
|
DEBUG_LOG(HLE,"%08x = sceGeEdramGetAddr",retVal);
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 sceGeEdramGetSize()
|
|
|
|
{
|
|
|
|
u32 retVal = 0x00200000;
|
|
|
|
DEBUG_LOG(HLE,"%08x = sceGeEdramGetSize()",retVal);
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, u32 callbackId, u32 optParamAddr)
|
|
|
|
{
|
2012-11-07 14:44:48 +00:00
|
|
|
DEBUG_LOG(HLE,"sceGeListEnQueue(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
|
|
|
|
listAddress,stallAddress,callbackId,optParamAddr);
|
|
|
|
//if (!stallAddress)
|
|
|
|
// stallAddress = listAddress;
|
2012-11-06 16:05:27 +00:00
|
|
|
u32 listID = gpu->EnqueueList(listAddress, stallAddress);
|
2012-11-01 15:19:01 +00:00
|
|
|
// HACKY
|
|
|
|
if (listID)
|
|
|
|
state = SCE_GE_LIST_STALLING;
|
|
|
|
else
|
|
|
|
state = SCE_GE_LIST_COMPLETED;
|
|
|
|
|
|
|
|
DEBUG_LOG(HLE,"List enqueued.");
|
|
|
|
//return display list ID
|
|
|
|
return listID;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, u32 callbackId, u32 optParamAddr)
|
|
|
|
{
|
2012-11-07 14:44:48 +00:00
|
|
|
if (!stallAddress)
|
|
|
|
stallAddress = listAddress;
|
2012-11-06 16:05:27 +00:00
|
|
|
u32 listID = gpu->EnqueueList(listAddress,stallAddress);
|
2012-11-01 15:19:01 +00:00
|
|
|
// HACKY
|
|
|
|
if (listID)
|
|
|
|
state = SCE_GE_LIST_STALLING;
|
|
|
|
else
|
|
|
|
state = SCE_GE_LIST_COMPLETED;
|
|
|
|
|
|
|
|
DEBUG_LOG(HLE,"%i=sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
|
|
|
|
listID, listAddress,stallAddress,callbackId,optParamAddr);
|
|
|
|
DEBUG_LOG(HLE,"List enqueued.");
|
|
|
|
//return display list ID
|
|
|
|
return listID;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceGeListUpdateStallAddr(u32 displayListID, u32 stallAddress)
|
|
|
|
{
|
|
|
|
DEBUG_LOG(HLE,"sceGeListUpdateStallAddr(dlid=%i,stalladdr=%08x)",
|
|
|
|
displayListID,stallAddress);
|
|
|
|
|
2012-11-06 16:05:27 +00:00
|
|
|
gpu->UpdateStall(displayListID, stallAddress);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sceGeListSync(u32 displayListID, u32 mode) //0 : wait for completion 1:check and return
|
|
|
|
{
|
|
|
|
DEBUG_LOG(HLE,"sceGeListSync(dlid=%08x, mode=%08x)", displayListID,mode);
|
|
|
|
}
|
|
|
|
|
2012-11-10 23:08:46 +00:00
|
|
|
u32 sceGeDrawSync(u32 mode)
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
//wait/check entire drawing state
|
2012-11-06 14:46:21 +00:00
|
|
|
DEBUG_LOG(HLE,"FAKE sceGeDrawSync(mode=%d) (0=wait for completion)",mode);
|
2012-11-06 17:14:09 +00:00
|
|
|
gpu->DrawSync(mode);
|
|
|
|
return 0;
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
2012-11-05 09:05:09 +00:00
|
|
|
void sceGeBreak()
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2012-11-05 09:05:09 +00:00
|
|
|
u32 mode = PARAM(0); //0 : current dlist 1: all drawing
|
2012-11-01 15:19:01 +00:00
|
|
|
ERROR_LOG(HLE,"UNIMPL sceGeBreak(mode=%d)",mode);
|
|
|
|
}
|
|
|
|
|
2012-11-05 09:05:09 +00:00
|
|
|
void sceGeContinue()
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
ERROR_LOG(HLE,"UNIMPL sceGeContinue");
|
2012-11-05 09:05:09 +00:00
|
|
|
// no arguments
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 sceGeSetCallback(u32 structAddr)
|
|
|
|
{
|
2012-11-06 19:56:19 +00:00
|
|
|
DEBUG_LOG(HLE,"sceGeSetCallback(struct=%08x)", structAddr);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
PspGeCallbackData ge_callback_data;
|
|
|
|
Memory::ReadStruct(structAddr, &ge_callback_data);
|
|
|
|
|
2012-11-09 12:40:09 +00:00
|
|
|
if (ge_callback_data.finish_func) {
|
2012-11-01 15:19:01 +00:00
|
|
|
sceKernelRegisterSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH, ge_callback_data.finish_func, ge_callback_data.finish_arg);
|
2012-11-09 12:40:09 +00:00
|
|
|
sceKernelEnableSubIntr(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH);
|
|
|
|
}
|
|
|
|
if (ge_callback_data.signal_func) {
|
2012-11-01 15:19:01 +00:00
|
|
|
sceKernelRegisterSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL, ge_callback_data.signal_func, ge_callback_data.signal_arg);
|
2012-11-09 12:40:09 +00:00
|
|
|
sceKernelEnableSubIntr(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL);
|
|
|
|
}
|
2012-11-04 10:54:45 +00:00
|
|
|
|
|
|
|
// TODO: This should return a callback ID
|
2012-11-01 15:19:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceGeUnsetCallback(u32 cbID)
|
|
|
|
{
|
2012-11-07 18:10:52 +00:00
|
|
|
DEBUG_LOG(HLE,"sceGeUnsetCallback(cbid=%08x)", cbID);
|
|
|
|
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH);
|
|
|
|
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sceGeSaveContext()
|
|
|
|
{
|
|
|
|
ERROR_LOG(HLE,"UNIMPL sceGeSaveContext()");
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceGeRestoreContext()
|
|
|
|
{
|
|
|
|
ERROR_LOG(HLE,"UNIMPL sceGeRestoreContext()");
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceGeGetMtx()
|
|
|
|
{
|
|
|
|
ERROR_LOG(HLE,"UNIMPL sceGeGetMtx()");
|
|
|
|
}
|
|
|
|
|
2012-11-05 09:05:09 +00:00
|
|
|
void sceGeEdramSetAddrTranslation()
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2012-11-05 09:05:09 +00:00
|
|
|
int new_size = PARAM(0);
|
2012-11-01 15:19:01 +00:00
|
|
|
INFO_LOG(HLE,"sceGeEdramSetAddrTranslation(%i)", new_size);
|
|
|
|
static int EDRamWidth;
|
|
|
|
int last = EDRamWidth;
|
|
|
|
EDRamWidth = new_size;
|
2012-11-05 09:05:09 +00:00
|
|
|
RETURN(last);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const HLEFunction sceGe_user[] =
|
|
|
|
{
|
2012-11-05 09:05:09 +00:00
|
|
|
{0xE47E40E4,&WrapU_V<sceGeEdramGetAddr>, "sceGeEdramGetAddr"},
|
|
|
|
{0xAB49E76A,&WrapU_UUUU<sceGeListEnQueue>, "sceGeListEnQueue"},
|
|
|
|
{0x1C0D95A6,&WrapU_UUUU<sceGeListEnQueueHead>, "sceGeListEnQueueHead"},
|
|
|
|
{0xE0D68148,&WrapV_UU<sceGeListUpdateStallAddr>, "sceGeListUpdateStallAddr"},
|
|
|
|
{0x03444EB4,&WrapV_UU<sceGeListSync>, "sceGeListSync"},
|
|
|
|
{0xB287BD61,&WrapU_U<sceGeDrawSync>, "sceGeDrawSync"},
|
|
|
|
{0xB448EC0D,sceGeBreak, "sceGeBreak"},
|
|
|
|
{0x4C06E472,sceGeContinue, "sceGeContinue"},
|
|
|
|
{0xA4FC06A4,&WrapU_U<sceGeSetCallback>, "sceGeSetCallback"},
|
|
|
|
{0x05DB22CE,&WrapV_U<sceGeUnsetCallback>, "sceGeUnsetCallback"},
|
|
|
|
{0x1F6752AD,&WrapU_V<sceGeEdramGetSize>, "sceGeEdramGetSize"},
|
|
|
|
{0xB77905EA,&sceGeEdramSetAddrTranslation,"sceGeEdramSetAddrTranslation"},
|
2012-11-01 15:19:01 +00:00
|
|
|
{0xDC93CFEF,0,"sceGeGetCmd"},
|
2012-11-05 09:05:09 +00:00
|
|
|
{0x57C8945B,&sceGeGetMtx,"sceGeGetMtx"},
|
2012-11-01 15:19:01 +00:00
|
|
|
{0x438A385A,0,"sceGeSaveContext"},
|
|
|
|
{0x0BF608FB,0,"sceGeRestoreContext"},
|
|
|
|
{0x5FB86AB0,0,"sceGeListDeQueue"},
|
|
|
|
};
|
|
|
|
|
|
|
|
void Register_sceGe_user()
|
|
|
|
{
|
|
|
|
RegisterModule("sceGe_user", ARRAY_SIZE(sceGe_user), sceGe_user);
|
|
|
|
}
|