diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/arm/skyeye_common/arm_regformat.h | 2 | ||||
-rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.cpp | 20 | ||||
-rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.h | 4 | ||||
-rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpinstr.cpp | 75 | ||||
-rw-r--r-- | src/core/hle/service/soc_u.cpp | 18 | ||||
-rw-r--r-- | src/core/hw/gpu.cpp | 79 | ||||
-rw-r--r-- | src/core/loader/ncch.cpp | 1 |
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... |