summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/skyeye_common/arm_regformat.h2
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp20
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h4
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp75
-rw-r--r--src/core/hle/service/soc_u.cpp18
-rw-r--r--src/core/hw/gpu.cpp79
-rw-r--r--src/core/loader/ncch.cpp1
7 files changed, 114 insertions, 85 deletions
diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h
index a92effbb4..d1c721809 100644
--- a/src/core/arm/skyeye_common/arm_regformat.h
+++ b/src/core/arm/skyeye_common/arm_regformat.h
@@ -59,6 +59,8 @@ enum {
VFP_FPSID,
VFP_FPSCR,
VFP_FPEXC,
+ VFP_FPINST,
+ VFP_FPINST2,
VFP_MVFR0,
VFP_MVFR1,
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index bbe11f690..1ffc1f9af 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -27,30 +27,20 @@
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
-unsigned VFPInit(ARMul_State* state)
+void VFPInit(ARMul_State* state)
{
state->VFP[VFP_FPSID] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |
VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION;
state->VFP[VFP_FPEXC] = 0;
state->VFP[VFP_FPSCR] = 0;
+ // ARM11 MPCore instruction register reset values.
+ state->VFP[VFP_FPINST] = 0xEE000A00;
+ state->VFP[VFP_FPINST2] = 0;
+
// ARM11 MPCore feature register values.
state->VFP[VFP_MVFR0] = 0x11111111;
state->VFP[VFP_MVFR1] = 0;
-
- return 0;
-}
-
-void VMSR(ARMul_State* state, ARMword reg, ARMword Rt)
-{
- if (reg == 1)
- {
- state->VFP[VFP_FPSCR] = state->Reg[Rt];
- }
- else if (reg == 8)
- {
- state->VFP[VFP_FPEXC] = state->Reg[Rt];
- }
}
void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value)
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index acefae9bb..80ca93ccd 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.h
+++ b/src/core/arm/skyeye_common/vfp/vfp.h
@@ -26,7 +26,7 @@
#define CHECK_VFP_ENABLED
#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
-unsigned VFPInit(ARMul_State* state);
+void VFPInit(ARMul_State* state);
s32 vfp_get_float(ARMul_State* state, u32 reg);
void vfp_put_float(ARMul_State* state, s32 val, u32 reg);
@@ -36,10 +36,8 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc
u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
-void VMSR(ARMul_State* state, ARMword reg, ARMword Rt);
void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value);
void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2);
void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2);
void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm);
void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword imm);
-
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 67fe63aa4..8efcbab1c 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -995,7 +995,7 @@ VMOVBRS_INST:
#ifdef VFP_INTERPRETER_STRUCT
struct vmsr_inst {
unsigned int reg;
- unsigned int Rd;
+ unsigned int Rt;
};
#endif
#ifdef VFP_INTERPRETER_TRANS
@@ -1009,7 +1009,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
inst_base->br = NON_BRANCH;
inst_cream->reg = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rt = BITS(inst, 12, 15);
return inst_base;
}
@@ -1017,15 +1017,30 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
#ifdef VFP_INTERPRETER_IMPL
VMSR_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
/* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
and in privileged mode */
/* Exceptions must be checked, according to v7 ref manual */
CHECK_VFP_ENABLED;
- vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
+ vmsr_inst* const inst_cream = (vmsr_inst*)inst_base->component;
+
+ unsigned int reg = inst_cream->reg;
+ unsigned int rt = inst_cream->Rt;
- VMSR(cpu, inst_cream->reg, inst_cream->Rd);
+ if (reg == 1)
+ {
+ cpu->VFP[VFP_FPSCR] = cpu->Reg[rt];
+ }
+ else if (InAPrivilegedMode(cpu))
+ {
+ if (reg == 8)
+ cpu->VFP[VFP_FPEXC] = cpu->Reg[rt];
+ else if (reg == 9)
+ cpu->VFP[VFP_FPINST] = cpu->Reg[rt];
+ else if (reg == 10)
+ cpu->VFP[VFP_FPINST2] = cpu->Reg[rt];
+ }
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(vmsr_inst));
@@ -1111,19 +1126,22 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
#ifdef VFP_INTERPRETER_IMPL
VMRS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
/* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
and in privileged mode */
/* Exceptions must be checked, according to v7 ref manual */
CHECK_VFP_ENABLED;
- vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
+ vmrs_inst* const inst_cream = (vmrs_inst*)inst_base->component;
- if (inst_cream->reg == 1) /* FPSCR */
+ unsigned int reg = inst_cream->reg;
+ unsigned int rt = inst_cream->Rt;
+
+ if (reg == 1) // FPSCR
{
- if (inst_cream->Rt != 15)
+ if (rt != 15)
{
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPSCR];
+ cpu->Reg[rt] = cpu->VFP[VFP_FPSCR];
}
else
{
@@ -1133,25 +1151,26 @@ VMRS_INST:
cpu->VFlag = (cpu->VFP[VFP_FPSCR] >> 28) & 1;
}
}
- else
+ else if (reg == 0)
{
- switch (inst_cream->reg)
- {
- case 0:
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPSID];
- break;
- case 6:
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_MVFR1];
- break;
- case 7:
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_MVFR0];
- break;
- case 8:
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_FPEXC];
- break;
- default:
- break;
- }
+ cpu->Reg[rt] = cpu->VFP[VFP_FPSID];
+ }
+ else if (reg == 6)
+ {
+ cpu->Reg[rt] = cpu->VFP[VFP_MVFR1];
+ }
+ else if (reg == 7)
+ {
+ cpu->Reg[rt] = cpu->VFP[VFP_MVFR0];
+ }
+ else if (InAPrivilegedMode(cpu))
+ {
+ if (reg == 8)
+ cpu->Reg[rt] = cpu->VFP[VFP_FPEXC];
+ else if (reg == 9)
+ cpu->Reg[rt] = cpu->VFP[VFP_FPINST];
+ else if (reg == 10)
+ cpu->Reg[rt] = cpu->VFP[VFP_FPINST2];
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 5b2a643d8..d0e166fdf 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -335,6 +335,7 @@ static void Socket(Service::Interface* self) {
if ((s32)socket_handle == SOCKET_ERROR_VALUE)
result = TranslateError(GET_ERRNO);
+ cmd_buffer[0] = IPC::MakeHeader(2, 2, 0);
cmd_buffer[1] = result;
cmd_buffer[2] = socket_handle;
}
@@ -358,8 +359,9 @@ static void Bind(Service::Interface* self) {
if (res != 0)
result = TranslateError(GET_ERRNO);
- cmd_buffer[2] = res;
+ cmd_buffer[0] = IPC::MakeHeader(5, 2, 0);
cmd_buffer[1] = result;
+ cmd_buffer[2] = res;
}
static void Fcntl(Service::Interface* self) {
@@ -441,8 +443,9 @@ static void Listen(Service::Interface* self) {
if (ret != 0)
result = TranslateError(GET_ERRNO);
- cmd_buffer[2] = ret;
+ cmd_buffer[0] = IPC::MakeHeader(3, 2, 0);
cmd_buffer[1] = result;
+ cmd_buffer[2] = ret;
}
static void Accept(Service::Interface* self) {
@@ -467,8 +470,10 @@ static void Accept(Service::Interface* self) {
Memory::WriteBlock(cmd_buffer[0x104 >> 2], (const u8*)&ctr_addr, max_addr_len);
}
- cmd_buffer[2] = ret;
+ cmd_buffer[0] = IPC::MakeHeader(4, 2, 2);
cmd_buffer[1] = result;
+ cmd_buffer[2] = ret;
+ cmd_buffer[3] = IPC::StaticBufferDesc(static_cast<u32>(max_addr_len), 0);
}
static void GetHostId(Service::Interface* self) {
@@ -676,8 +681,10 @@ static void Connect(Service::Interface* self) {
int result = 0;
if (ret != 0)
result = TranslateError(GET_ERRNO);
- cmd_buffer[2] = ret;
+
+ cmd_buffer[0] = IPC::MakeHeader(6, 2, 0);
cmd_buffer[1] = result;
+ cmd_buffer[2] = ret;
}
static void InitializeSockets(Service::Interface* self) {
@@ -688,7 +695,8 @@ static void InitializeSockets(Service::Interface* self) {
#endif
u32* cmd_buffer = Kernel::GetCommandBuffer();
- cmd_buffer[1] = 0;
+ cmd_buffer[0] = IPC::MakeHeader(1, 1, 0);
+ cmd_buffer[1] = RESULT_SUCCESS.raw;
}
static void ShutdownSockets(Service::Interface* self) {
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 901519a8b..a1789f9c7 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -56,6 +56,29 @@ inline void Read(T &var, const u32 raw_addr) {
var = g_regs[addr / 4];
}
+static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
+ switch (input_format) {
+ case Regs::PixelFormat::RGBA8:
+ return Color::DecodeRGBA8(src_pixel);
+
+ case Regs::PixelFormat::RGB8:
+ return Color::DecodeRGB8(src_pixel);
+
+ case Regs::PixelFormat::RGB565:
+ return Color::DecodeRGB565(src_pixel);
+
+ case Regs::PixelFormat::RGB5A1:
+ return Color::DecodeRGB5A1(src_pixel);
+
+ case Regs::PixelFormat::RGBA4:
+ return Color::DecodeRGBA4(src_pixel);
+
+ default:
+ LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", input_format);
+ return {0, 0, 0, 0};
+ }
+}
+
template <typename T>
inline void Write(u32 addr, const T data) {
addr -= HW::VADDR_GPU;
@@ -128,11 +151,18 @@ inline void Write(u32 addr, const T data) {
break;
}
- unsigned horizontal_scale = (config.scaling != config.NoScale) ? 2 : 1;
- unsigned vertical_scale = (config.scaling == config.ScaleXY) ? 2 : 1;
+ if (config.output_tiled &&
+ (config.scaling == config.ScaleXY || config.scaling == config.ScaleX)) {
+ LOG_CRITICAL(HW_GPU, "Scaling is only implemented on tiled input");
+ UNIMPLEMENTED();
+ break;
+ }
- u32 output_width = config.output_width / horizontal_scale;
- u32 output_height = config.output_height / vertical_scale;
+ bool horizontal_scale = config.scaling != config.NoScale;
+ bool vertical_scale = config.scaling == config.ScaleXY;
+
+ u32 output_width = config.output_width >> horizontal_scale;
+ u32 output_height = config.output_height >> vertical_scale;
u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format);
u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format);
@@ -156,16 +186,14 @@ inline void Write(u32 addr, const T data) {
break;
}
- // TODO(Subv): Implement the box filter when scaling is enabled
- // right now we're just skipping the extra pixels.
for (u32 y = 0; y < output_height; ++y) {
for (u32 x = 0; x < output_width; ++x) {
- Math::Vec4<u8> src_color = { 0, 0, 0, 0 };
+ Math::Vec4<u8> src_color;
// Calculate the [x,y] position of the input image
// based on the current output position and the scale
- u32 input_x = x * horizontal_scale;
- u32 input_y = y * vertical_scale;
+ u32 input_x = x << horizontal_scale;
+ u32 input_y = y << vertical_scale;
if (config.flip_vertically) {
// Flip the y value of the output data,
@@ -196,30 +224,15 @@ inline void Write(u32 addr, const T data) {
}
const u8* src_pixel = src_pointer + src_offset;
- switch (config.input_format) {
- case Regs::PixelFormat::RGBA8:
- src_color = Color::DecodeRGBA8(src_pixel);
- break;
-
- case Regs::PixelFormat::RGB8:
- src_color = Color::DecodeRGB8(src_pixel);
- break;
-
- case Regs::PixelFormat::RGB565:
- src_color = Color::DecodeRGB565(src_pixel);
- break;
-
- case Regs::PixelFormat::RGB5A1:
- src_color = Color::DecodeRGB5A1(src_pixel);
- break;
-
- case Regs::PixelFormat::RGBA4:
- src_color = Color::DecodeRGBA4(src_pixel);
- break;
-
- default:
- LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", config.input_format.Value());
- break;
+ src_color = DecodePixel(config.input_format, src_pixel);
+ if (config.scaling == config.ScaleX) {
+ Math::Vec4<u8> pixel = DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel);
+ src_color = ((src_color + pixel) / 2).Cast<u8>();
+ } else if (config.scaling == config.ScaleXY) {
+ Math::Vec4<u8> pixel1 = DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel);
+ Math::Vec4<u8> pixel2 = DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel);
+ Math::Vec4<u8> pixel3 = DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel);
+ src_color = (((src_color + pixel1) + (pixel2 + pixel3)) / 4).Cast<u8>();
}
u8* dst_pixel = dst_pointer + dst_offset;
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index a8f8f78b7..2b26b31cf 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -240,7 +240,6 @@ ResultStatus AppLoader_NCCH::Load() {
LOG_DEBUG(Loader, "Bss size: 0x%08X", bss_size);
LOG_DEBUG(Loader, "Core version: %d" , core_version);
LOG_DEBUG(Loader, "Thread priority: 0x%X" , priority);
- LOG_DEBUG(Loader, "Resource limit descriptor: 0x%08X", exheader_header.arm11_system_local_caps.resource_limit_descriptor);
LOG_DEBUG(Loader, "Resource limit category: %d" , resource_limit_category);
// Read ExeFS...