diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp
index dcdc7e38..f9ec44ef 100644
--- a/include/kernel/kernel.hpp
+++ b/include/kernel/kernel.hpp
@@ -71,6 +71,7 @@ class Kernel {
 	void sendSyncRequest();
 	void svcCloseHandle();
 	void connectToPort();
+	void outputDebugString();
 
 public:
 	Kernel(std::array<u32, 16>& regs, Memory& mem) : regs(regs), mem(mem), handleCounter(0), serviceManager(regs, mem) {
diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp
index 3b941ad0..1fef9224 100644
--- a/src/core/kernel/kernel.cpp
+++ b/src/core/kernel/kernel.cpp
@@ -12,6 +12,7 @@ void Kernel::serviceSVC(u32 svc) {
 		case 0x38: getResourceLimit(); break;
 		case 0x39: getResourceLimitLimitValues(); break;
 		case 0x3A: getResourceLimitCurrentValues(); break;
+		case 0x3D: outputDebugString(); break;
 		default: Helpers::panic("Unimplemented svc: %X @ %08X", svc, regs[15]); break;
 	}
 }
@@ -87,6 +88,17 @@ void Kernel::svcCloseHandle() {
 	regs[0] = SVCResult::Success;
 }
 
+// OutputDebugString(const char* str, int size)
+// TODO: Does this actually write an error code in r0?
+void Kernel::outputDebugString() {
+	const u32 pointer = regs[0];
+	const u32 size = regs[1];
+
+	std::string message = mem.readString(pointer, size);
+	printf("OutputDebugString(message = \"%s\")\n", message.c_str());
+	regs[0] = SVCResult::Success;
+}
+
 std::string Kernel::getProcessName(u32 pid) {
 	if (pid == KernelHandles::CurrentProcess) {
 		return "current";
diff --git a/src/main.cpp b/src/main.cpp
index 7d52a53b..627adbf1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -7,7 +7,7 @@ int main (int argc, char *argv[]) {
         Helpers::panic("Failed to initialize OpenGL");
     }
 
-    auto elfPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "simple_tri.elf");
+    auto elfPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "OutputDebugString.elf");
     if (!emu.loadELF(elfPath)) {
         Helpers::panic("Failed to load ELF file: %s", elfPath.c_str());
     }