From 76a14b3bae409c268e76daf721962136b690aa7e Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Tue, 23 Jan 2024 19:20:56 +0200 Subject: [PATCH] Implement CAM::GetMaxBytes/SetTransferBytes --- include/services/cam.hpp | 2 ++ src/core/services/cam.cpp | 49 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/services/cam.hpp b/include/services/cam.hpp index 5ef3edba..60ede3b9 100644 --- a/include/services/cam.hpp +++ b/include/services/cam.hpp @@ -37,6 +37,7 @@ class CAMService { // Service commands void driverInitialize(u32 messagePointer); void driverFinalize(u32 messagePointer); + void getMaxBytes(u32 messagePointer); void getMaxLines(u32 messagePointer); void getBufferErrorInterruptEvent(u32 messagePointer); void getSuitableY2RCoefficients(u32 messagePointer); @@ -45,6 +46,7 @@ class CAMService { void setFrameRate(u32 messagePointer); void setReceiving(u32 messagePointer); void setSize(u32 messagePointer); + void setTransferBytes(u32 messagePointer); void setTransferLines(u32 messagePointer); void setTrimming(u32 messagePointer); void setTrimmingParamsCenter(u32 messagePointer); diff --git a/src/core/services/cam.cpp b/src/core/services/cam.cpp index e617ef2f..b3dfd1dc 100644 --- a/src/core/services/cam.cpp +++ b/src/core/services/cam.cpp @@ -14,7 +14,9 @@ namespace CAMCommands { DriverFinalize = 0x003A0000, SetTransferLines = 0x00090100, GetMaxLines = 0x000A0080, + SetTransferBytes = 0x000B0100, GetTransferBytes = 0x000C0040, + GetMaxBytes = 0x000D0080, SetTrimming = 0x000E0080, SetTrimmingParamsCenter = 0x00120140, SetSize = 0x001F00C0, // Set size has different headers between cam:u and New3DS QTM module @@ -73,6 +75,7 @@ void CAMService::handleSyncRequest(u32 messagePointer) { case CAMCommands::DriverInitialize: driverInitialize(messagePointer); break; case CAMCommands::DriverFinalize: driverFinalize(messagePointer); break; case CAMCommands::GetBufferErrorInterruptEvent: getBufferErrorInterruptEvent(messagePointer); break; + case CAMCommands::GetMaxBytes: getMaxBytes(messagePointer); break; case CAMCommands::GetMaxLines: getMaxLines(messagePointer); break; case CAMCommands::GetSuitableY2rStandardCoefficient: getSuitableY2RCoefficients(messagePointer); break; case CAMCommands::GetTransferBytes: getTransferBytes(messagePointer); break; @@ -87,7 +90,7 @@ void CAMService::handleSyncRequest(u32 messagePointer) { default: Helpers::warn("Unimplemented CAM service requested. Command: %08X\n", command); - mem.write32(messagePointer + 4, 0); + mem.write32(messagePointer + 4, Result::Success); break; } } @@ -114,6 +117,28 @@ void CAMService::setContrast(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); } +void CAMService::setTransferBytes(u32 messagePointer) { + const u32 portIndex = mem.read8(messagePointer + 4); + const u32 bytes = mem.read16(messagePointer + 8); + // ...why do these parameters even exist? + const u16 width = mem.read16(messagePointer + 12); + const u16 height = mem.read16(messagePointer + 16); + const PortSelect port(portIndex); + + if (port.isValid()) { + for (int i : port.getPortIndices()) { + ports[i].transferBytes = bytes; + } + } else { + Helpers::warn("CAM::SetTransferBytes: Invalid port\n"); + } + + log("CAM::SetTransferBytes (port = %d, bytes = %d, width = %d, height = %d)\n", portIndex, bytes, width, height); + + mem.write32(messagePointer, IPC::responseHeader(0x9, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} + void CAMService::setTransferLines(u32 messagePointer) { const u32 portIndex = mem.read8(messagePointer + 4); const u16 lines = mem.read16(messagePointer + 8); @@ -214,6 +239,28 @@ void CAMService::getMaxLines(u32 messagePointer) { } } +void CAMService::getMaxBytes(u32 messagePointer) { + const u16 width = mem.read16(messagePointer + 4); + const u16 height = mem.read16(messagePointer + 8); + log("CAM::GetMaxBytes (width = %d, height = %d)\n", width, height); + + constexpr u32 MIN_TRANSFER_UNIT = 256; + constexpr u32 MAX_BUFFER_SIZE = 2560; + if (width * height * 2 % MIN_TRANSFER_UNIT != 0) { + Helpers::panic("CAM::GetMaxLines out of range"); + } else { + u32 bytes = MAX_BUFFER_SIZE; + + while (width * height * 2 % bytes != 0) { + bytes -= MIN_TRANSFER_UNIT; + } + + mem.write32(messagePointer, IPC::responseHeader(0xA, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, bytes); + } +} + void CAMService::getSuitableY2RCoefficients(u32 messagePointer) { log("CAM::GetSuitableY2RCoefficients\n"); mem.write32(messagePointer, IPC::responseHeader(0x36, 2, 0));