summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp11
-rw-r--r--src/core/hle/kernel/mutex.cpp4
-rw-r--r--src/core/hle/service/dsp_dsp.cpp22
-rw-r--r--src/core/hle/service/dsp_dsp.h3
-rw-r--r--src/core/hle/service/fs/archive.cpp44
-rw-r--r--src/core/hle/service/fs/archive.h3
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/soc_u.cpp10
-rw-r--r--src/core/hle/service/y2r_u.cpp45
-rw-r--r--src/core/hle/service/y2r_u.h23
10 files changed, 149 insertions, 18 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 38705e3cd..736bbc36a 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -51,6 +51,17 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
HLE::Reschedule(__func__);
}
break;
+
+ case ArbitrationType::DecrementAndWaitIfLessThan:
+ {
+ s32 memory_value = Memory::Read32(address) - 1;
+ Memory::Write32(address, memory_value);
+ if (memory_value <= value) {
+ Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address);
+ HLE::Reschedule(__func__);
+ }
+ break;
+ }
default:
LOG_ERROR(Kernel, "unknown type=%d", type);
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 558068c79..3dfeffc9b 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -168,9 +168,9 @@ Handle CreateMutex(bool initial_locked, const std::string& name) {
ResultVal<bool> Mutex::WaitSynchronization() {
bool wait = locked;
if (locked) {
+ waiting_threads.push_back(GetCurrentThreadHandle());
Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle());
- }
- else {
+ } else {
// Lock the mutex when the first thread accesses it
locked = true;
MutexAcquireLock(this);
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 2cf4d118f..d4affdfbf 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -12,9 +12,23 @@
namespace DSP_DSP {
-static u32 read_pipe_count;
-static Handle semaphore_event;
-static Handle interrupt_event;
+static u32 read_pipe_count = 0;
+static Handle semaphore_event = 0;
+static Handle interrupt_event = 0;
+
+void SignalInterrupt() {
+ // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
+ // application that a DSP interrupt occurred, without specifying which one. Since we do not
+ // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games
+ // that check the DSP interrupt signal event to run. We should figure out the different types of
+ // DSP interrupts, and trigger them at the appropriate times.
+
+ if (interrupt_event == 0) {
+ LOG_WARNING(Service_DSP, "cannot signal interrupt until DSP event has been created!");
+ return;
+ }
+ Kernel::SignalEvent(interrupt_event);
+}
/**
* DSP_DSP::ConvertProcessAddressFromDspDram service function
@@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
void WriteReg0x10(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- Kernel::SignalEvent(interrupt_event);
+ SignalInterrupt();
cmd_buff[1] = 0; // No error
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 0b8b64600..fa13bfb7c 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -20,4 +20,7 @@ public:
}
};
+/// Signals that a DSP interrupt has occurred to userland code
+void SignalInterrupt();
+
} // namespace
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index f19ca3a9f..f761c6ab9 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -10,9 +10,11 @@
#include "common/make_unique.h"
#include "common/math_util.h"
-#include "core/file_sys/archive_savedata.h"
-#include "core/file_sys/archive_extsavedata.h"
#include "core/file_sys/archive_backend.h"
+#include "core/file_sys/archive_extsavedata.h"
+#include "core/file_sys/archive_romfs.h"
+#include "core/file_sys/archive_savedata.h"
+#include "core/file_sys/archive_savedatacheck.h"
#include "core/file_sys/archive_sdmc.h"
#include "core/file_sys/directory_backend.h"
#include "core/hle/service/fs/archive.h"
@@ -50,6 +52,9 @@ enum class FileCommand : u32 {
SetAttributes = 0x08070040,
Close = 0x08080000,
Flush = 0x08090000,
+ SetPriority = 0x080A0040,
+ GetPriority = 0x080B0000,
+ OpenLinkFile = 0x080C0000,
};
// Command to access directory
@@ -63,7 +68,7 @@ enum class DirectoryCommand : u32 {
class Archive {
public:
Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code)
- : backend(std::move(backend)), id_code(id_code) {
+ : id_code(id_code), backend(std::move(backend)) {
}
std::string GetName() const { return "Archive: " + backend->GetName(); }
@@ -75,12 +80,13 @@ public:
class File : public Kernel::Session {
public:
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
- : backend(std::move(backend)), path(path) {
+ : path(path), backend(std::move(backend)), priority(0) {
}
std::string GetName() const override { return "Path: " + path.DebugStr(); }
FileSys::Path path; ///< Path of the file
+ u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
ResultVal<bool> SyncRequest() override {
@@ -145,6 +151,27 @@ public:
break;
}
+ case FileCommand::OpenLinkFile:
+ {
+ LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
+ cmd_buff[3] = GetHandle();
+ break;
+ }
+
+ case FileCommand::SetPriority:
+ {
+ priority = cmd_buff[1];
+ LOG_TRACE(Service_FS, "SetPriority %u", priority);
+ break;
+ }
+
+ case FileCommand::GetPriority:
+ {
+ cmd_buff[2] = priority;
+ LOG_TRACE(Service_FS, "GetPriority");
+ break;
+ }
+
// Unknown command...
default:
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
@@ -160,7 +187,7 @@ public:
class Directory : public Kernel::Session {
public:
Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path)
- : backend(std::move(backend)), path(path) {
+ : path(path), backend(std::move(backend)) {
}
std::string GetName() const override { return "Directory: " + path.DebugStr(); }
@@ -327,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
ErrorSummary::Canceled, ErrorLevel::Status);
}
-ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) {
+ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
return InvalidHandle(ErrorModule::FS);
@@ -435,6 +462,11 @@ void ArchiveInit() {
else
LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
sharedextsavedata_directory.c_str());
+
+ // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
+ std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX);
+ auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory);
+ CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);
}
/// Shutdown archives
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index c23b8cc46..9e9efa019 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 {
SystemSaveData = 0x00000008,
SDMC = 0x00000009,
SDMCWriteOnly = 0x0000000A,
+ SaveDataCheck = 0x2345678A,
};
typedef u64 ArchiveHandle;
@@ -90,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
* @param file_size The size of the new file, filled with zeroes
* @return File creation result code
*/
-ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size);
+ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size);
/**
* Create a Directory from an Archive
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0f3cc2aa8..c5233e687 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -37,6 +37,7 @@
#include "core/hle/service/soc_u.h"
#include "core/hle/service/srv.h"
#include "core/hle/service/ssl_c.h"
+#include "core/hle/service/y2r_u.h"
namespace Service {
@@ -122,6 +123,7 @@ void Init() {
g_manager->AddService(new PTM_U::Interface);
g_manager->AddService(new SOC_U::Interface);
g_manager->AddService(new SSL_C::Interface);
+ g_manager->AddService(new Y2R_U::Interface);
LOG_DEBUG(Service, "initialized OK");
}
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 9fbf18b26..f502c6afe 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -308,11 +308,11 @@ static void Socket(Service::Interface* self) {
u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol));
- if (socket_handle != SOCKET_ERROR_VALUE)
+ if ((s32)socket_handle != SOCKET_ERROR_VALUE)
open_sockets[socket_handle] = { socket_handle, true };
int result = 0;
- if (socket_handle == SOCKET_ERROR_VALUE)
+ if ((s32)socket_handle == SOCKET_ERROR_VALUE)
result = TranslateError(GET_ERRNO);
cmd_buffer[1] = result;
@@ -404,7 +404,7 @@ static void Fcntl(Service::Interface* self) {
}
#endif
} else {
- LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call");
+ LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call", ctr_cmd);
result = TranslateError(EINVAL); // TODO: Find the correct error
posix_ret = -1;
return;
@@ -436,11 +436,11 @@ static void Accept(Service::Interface* self) {
socklen_t addr_len = sizeof(addr);
u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
- if (ret != SOCKET_ERROR_VALUE)
+ if ((s32)ret != SOCKET_ERROR_VALUE)
open_sockets[ret] = { ret, true };
int result = 0;
- if (ret == SOCKET_ERROR_VALUE) {
+ if ((s32)ret == SOCKET_ERROR_VALUE) {
result = TranslateError(GET_ERRNO);
} else {
CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr);
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
new file mode 100644
index 000000000..f9e3619dd
--- /dev/null
+++ b/src/core/hle/service/y2r_u.cpp
@@ -0,0 +1,45 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+#include "core/hle/hle.h"
+#include "core/hle/kernel/event.h"
+#include "core/hle/service/y2r_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Y2R_U
+
+namespace Y2R_U {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010040, nullptr, "SetInputFormat"},
+ {0x00030040, nullptr, "SetOutputFormat"},
+ {0x00050040, nullptr, "SetRotation"},
+ {0x00070040, nullptr, "SetBlockAlignment"},
+ {0x000D0040, nullptr, "SetTransferEndInterrupt"},
+ {0x000F0000, nullptr, "GetTransferEndEvent"},
+ {0x00100102, nullptr, "SetSendingY"},
+ {0x00110102, nullptr, "SetSendingU"},
+ {0x00120102, nullptr, "SetSendingV"},
+ {0x00180102, nullptr, "SetReceiving"},
+ {0x001A0040, nullptr, "SetInputLineWidth"},
+ {0x001C0040, nullptr, "SetInputLines"},
+ {0x00200040, nullptr, "SetStandardCoefficient"},
+ {0x00220040, nullptr, "SetAlpha"},
+ {0x00260000, nullptr, "StartConversion"},
+ {0x00270000, nullptr, "StopConversion"},
+ {0x00280000, nullptr, "IsBusyConversion"},
+ {0x002A0000, nullptr, "PingProcess"},
+ {0x002B0000, nullptr, "DriverInitialize"},
+ {0x002C0000, nullptr, "DriverFinalize"}
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
new file mode 100644
index 000000000..171aecfd1
--- /dev/null
+++ b/src/core/hle/service/y2r_u.h
@@ -0,0 +1,23 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Y2R_U
+
+namespace Y2R_U {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "y2r:u";
+ }
+};
+
+} // namespace