GSP: Implement SetBufferSwap.

This commit is contained in:
Tony Wasserka 2014-07-25 11:23:28 +02:00
parent e832bbe554
commit 590c206ac8
2 changed files with 47 additions and 1 deletions

View File

@ -105,6 +105,40 @@ void ReadHWRegs(Service::Interface* self) {
} }
} }
void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
u32 base_address = 0x400000;
if (info.active_fb == 0) {
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_left1), 4, &info.address_left);
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_right1), 4, &info.address_right);
} else {
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_left2), 4, &info.address_left);
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_right2), 4, &info.address_right);
}
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].stride), 4, &info.stride);
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].color_format), 4, &info.format);
WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].active_fb), 4, &info.shown_fb);
}
/**
* GSP_GPU::SetBufferSwap service function
*
* Updates GPU display framebuffer configuration using the specified parameters.
*
* Inputs:
* 1 : Screen ID (0 = top screen, 1 = bottom screen)
* 2-7 : FrameBufferInfo structure
* Outputs:
* 1: Result code
*/
void SetBufferSwap(Service::Interface* self) {
u32* cmd_buff = Service::GetCommandBuffer();
u32 screen_id = cmd_buff[1];
FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2];
SetBufferSwap(screen_id, *fb_info);
cmd_buff[1] = 0; // No error
}
/** /**
* GSP_GPU::RegisterInterruptRelayQueue service function * GSP_GPU::RegisterInterruptRelayQueue service function
* Inputs: * Inputs:
@ -283,7 +317,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00020084, nullptr, "WriteHWRegsWithMask"}, {0x00020084, nullptr, "WriteHWRegsWithMask"},
{0x00030082, nullptr, "WriteHWRegRepeat"}, {0x00030082, nullptr, "WriteHWRegRepeat"},
{0x00040080, ReadHWRegs, "ReadHWRegs"}, {0x00040080, ReadHWRegs, "ReadHWRegs"},
{0x00050200, nullptr, "SetBufferSwap"}, {0x00050200, SetBufferSwap, "SetBufferSwap"},
{0x00060082, nullptr, "SetCommandList"}, {0x00060082, nullptr, "SetCommandList"},
{0x000700C2, nullptr, "RequestDma"}, {0x000700C2, nullptr, "RequestDma"},
{0x00080082, nullptr, "FlushDataCache"}, {0x00080082, nullptr, "FlushDataCache"},

View File

@ -64,6 +64,18 @@ struct InterruptRelayQueue {
static_assert(sizeof(InterruptRelayQueue) == 0x40, static_assert(sizeof(InterruptRelayQueue) == 0x40,
"InterruptRelayQueue struct has incorrect size"); "InterruptRelayQueue struct has incorrect size");
struct FrameBufferInfo {
BitField<0, 1, u32> active_fb; // 0 = first, 1 = second
u32 address_left;
u32 address_right;
u32 stride; // maps to 0x1EF00X90 ?
u32 format; // maps to 0x1EF00X70 ?
u32 shown_fb; // maps to 0x1EF00X78 ?
u32 unknown;
};
static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size");
/// GSP command /// GSP command
struct Command { struct Command {
BitField<0, 8, CommandId> id; BitField<0, 8, CommandId> id;