clang-format on most of kernel/
This commit is contained in:
parent
854bcdb60a
commit
1c4dcd5e0e
|
@ -22,8 +22,8 @@
|
|||
#include <xenia/kernel/fs/filesystem.h>
|
||||
#include <xenia/ui/window.h>
|
||||
|
||||
namespace xe {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::apu;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::gpu;
|
||||
|
@ -218,3 +218,5 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
|||
|
||||
return xboxkrnl_->LaunchModule(module_path.c_str());
|
||||
}
|
||||
|
||||
} // namespace xe
|
||||
|
|
|
@ -11,24 +11,22 @@
|
|||
|
||||
#include <xenia/kernel/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
XApp::XApp(KernelState* kernel_state, uint32_t app_id)
|
||||
: kernel_state_(kernel_state), app_id_(app_id),
|
||||
: kernel_state_(kernel_state),
|
||||
app_id_(app_id),
|
||||
membase_(kernel_state->memory()->membase()) {}
|
||||
|
||||
|
||||
void XAppManager::RegisterApp(std::unique_ptr<XApp> app) {
|
||||
assert_zero(app_lookup_.count(app->app_id()));
|
||||
app_lookup_.insert({app->app_id(), app.get()});
|
||||
apps_.push_back(std::move(app));
|
||||
}
|
||||
|
||||
|
||||
X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, uint32_t arg2) {
|
||||
X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message,
|
||||
uint32_t arg1, uint32_t arg2) {
|
||||
const auto& it = app_lookup_.find(app_id);
|
||||
if (it == app_lookup_.end()) {
|
||||
return X_ERROR_NOT_FOUND;
|
||||
|
@ -36,8 +34,9 @@ X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, uin
|
|||
return it->second->DispatchMessageSync(message, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length) {
|
||||
X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message,
|
||||
uint32_t buffer_ptr,
|
||||
size_t buffer_length) {
|
||||
const auto& it = app_lookup_.find(app_id);
|
||||
if (it == app_lookup_.end()) {
|
||||
return X_ERROR_NOT_FOUND;
|
||||
|
@ -45,6 +44,5 @@ X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, ui
|
|||
return it->second->DispatchMessageAsync(message, buffer_ptr, buffer_length);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -15,23 +15,21 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class KernelState;
|
||||
|
||||
|
||||
class XApp {
|
||||
public:
|
||||
uint32_t app_id() const { return app_id_; }
|
||||
|
||||
virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) = 0;
|
||||
virtual X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) = 0;
|
||||
virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1,
|
||||
uint32_t arg2) = 0;
|
||||
virtual X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr,
|
||||
size_t buffer_length) = 0;
|
||||
|
||||
protected:
|
||||
XApp(KernelState* kernel_state, uint32_t app_id);
|
||||
|
@ -41,22 +39,21 @@ protected:
|
|||
uint8_t* membase_;
|
||||
};
|
||||
|
||||
|
||||
class XAppManager {
|
||||
public:
|
||||
void RegisterApp(std::unique_ptr<XApp> app);
|
||||
|
||||
X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, uint32_t arg2);
|
||||
X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length);
|
||||
X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1,
|
||||
uint32_t arg2);
|
||||
X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message,
|
||||
uint32_t buffer_ptr, size_t buffer_length);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<XApp>> apps_;
|
||||
std::unordered_map<uint32_t, XApp*> app_lookup_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_APP_H_
|
||||
|
|
|
@ -11,17 +11,14 @@
|
|||
|
||||
#include <xenia/kernel/apps/xmp_app.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace apps {
|
||||
|
||||
|
||||
void RegisterApps(KernelState* kernel_state, XAppManager* manager) {
|
||||
manager->RegisterApp(std::make_unique<XXMPApp>(kernel_state));
|
||||
}
|
||||
|
||||
|
||||
} // namespace apps
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -16,18 +16,14 @@
|
|||
#include <xenia/kernel/app.h>
|
||||
#include <xenia/kernel/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace apps {
|
||||
|
||||
|
||||
void RegisterApps(KernelState* kernel_state, XAppManager* manager);
|
||||
|
||||
|
||||
} // namespace apps
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_
|
||||
|
|
|
@ -9,12 +9,10 @@
|
|||
|
||||
#include <xenia/kernel/apps/xmp_app.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace apps {
|
||||
|
||||
|
||||
X_RESULT XXMPApp::XMPGetStatus(uint32_t unk, uint32_t status_ptr) {
|
||||
// Some stupid games will hammer this on a thread - induce a delay
|
||||
// here to keep from starving real threads.
|
||||
|
@ -28,7 +26,8 @@ X_RESULT XXMPApp::XMPGetStatus(uint32_t unk, uint32_t status_ptr) {
|
|||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr) {
|
||||
X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr,
|
||||
uint32_t disabled_ptr) {
|
||||
// Some stupid games will hammer this on a thread - induce a delay
|
||||
// here to keep from starving real threads.
|
||||
Sleep(1);
|
||||
|
@ -42,7 +41,8 @@ X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabl
|
|||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) {
|
||||
X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1,
|
||||
uint32_t arg2) {
|
||||
// http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp
|
||||
switch (message) {
|
||||
case 0x00070009: {
|
||||
|
@ -75,19 +75,20 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t
|
|||
return X_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) {
|
||||
X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr,
|
||||
size_t buffer_length) {
|
||||
switch (message) {
|
||||
case 0x00070009: {
|
||||
uint32_t unk =
|
||||
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0); // 0x00000002
|
||||
uint32_t unk = poly::load_and_swap<uint32_t>(membase_ + buffer_ptr +
|
||||
0); // 0x00000002
|
||||
uint32_t status_ptr = poly::load_and_swap<uint32_t>(
|
||||
membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0
|
||||
assert_true(buffer_length == 8);
|
||||
return XMPGetStatus(unk, status_ptr);
|
||||
}
|
||||
case 0x0007001B: {
|
||||
uint32_t unk =
|
||||
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0); // 0x00000002
|
||||
uint32_t unk = poly::load_and_swap<uint32_t>(membase_ + buffer_ptr +
|
||||
0); // 0x00000002
|
||||
uint32_t unk_ptr = poly::load_and_swap<uint32_t>(
|
||||
membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0
|
||||
uint32_t disabled_ptr = poly::load_and_swap<uint32_t>(
|
||||
|
@ -101,7 +102,6 @@ X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, si
|
|||
return X_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
} // namespace apps
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -16,27 +16,26 @@
|
|||
#include <xenia/kernel/app.h>
|
||||
#include <xenia/kernel/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace apps {
|
||||
|
||||
|
||||
class XXMPApp : public XApp {
|
||||
public:
|
||||
XXMPApp(KernelState* kernel_state) : XApp(kernel_state, 0xFA) {}
|
||||
|
||||
X_RESULT XMPGetStatus(uint32_t unk, uint32_t status_ptr);
|
||||
X_RESULT XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr);
|
||||
X_RESULT XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr,
|
||||
uint32_t disabled_ptr);
|
||||
|
||||
X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) override;
|
||||
X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) override;
|
||||
X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1,
|
||||
uint32_t arg2) override;
|
||||
X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr,
|
||||
size_t buffer_length) override;
|
||||
};
|
||||
|
||||
|
||||
} // namespace apps
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_
|
||||
|
|
|
@ -12,17 +12,18 @@
|
|||
#include <xenia/kernel/xobject.h>
|
||||
#include <xenia/kernel/objects/xevent.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
XAsyncRequest::XAsyncRequest(
|
||||
KernelState* kernel_state, XObject* object,
|
||||
CompletionCallback callback, void* callback_context) :
|
||||
kernel_state_(kernel_state), object_(object),
|
||||
callback_(callback), callback_context_(callback_context),
|
||||
apc_routine_(0), apc_context_(0) {
|
||||
XAsyncRequest::XAsyncRequest(KernelState* kernel_state, XObject* object,
|
||||
CompletionCallback callback,
|
||||
void* callback_context)
|
||||
: kernel_state_(kernel_state),
|
||||
object_(object),
|
||||
callback_(callback),
|
||||
callback_context_(callback_context),
|
||||
apc_routine_(0),
|
||||
apc_context_(0) {
|
||||
object_->Retain();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,8 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
@ -25,13 +23,11 @@ class KernelState;
|
|||
class XEvent;
|
||||
class XObject;
|
||||
|
||||
|
||||
class XAsyncRequest {
|
||||
public:
|
||||
typedef void (*CompletionCallback)(XAsyncRequest* request, void* context);
|
||||
|
||||
XAsyncRequest(
|
||||
KernelState* kernel_state, XObject* object,
|
||||
XAsyncRequest(KernelState* kernel_state, XObject* object,
|
||||
CompletionCallback callback, void* callback_context);
|
||||
virtual ~XAsyncRequest();
|
||||
|
||||
|
@ -53,9 +49,7 @@ protected:
|
|||
uint32_t apc_context_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_ASYNC_REQUEST_H_
|
||||
|
|
|
@ -12,27 +12,19 @@
|
|||
#include <xenia/kernel/kernel_state.h>
|
||||
#include <xenia/kernel/native_list.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
Dispatcher::Dispatcher(KernelState* kernel_state) :
|
||||
kernel_state_(kernel_state) {
|
||||
Dispatcher::Dispatcher(KernelState* kernel_state)
|
||||
: kernel_state_(kernel_state) {
|
||||
dpc_list_ = new NativeList(kernel_state->memory());
|
||||
}
|
||||
|
||||
Dispatcher::~Dispatcher() {
|
||||
delete dpc_list_;
|
||||
}
|
||||
Dispatcher::~Dispatcher() { delete dpc_list_; }
|
||||
|
||||
void Dispatcher::Lock() {
|
||||
lock_.lock();
|
||||
}
|
||||
void Dispatcher::Lock() { lock_.lock(); }
|
||||
|
||||
void Dispatcher::Unlock() {
|
||||
lock_.unlock();
|
||||
}
|
||||
void Dispatcher::Unlock() { lock_.unlock(); }
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
class KernelState;
|
||||
class NativeList;
|
||||
|
||||
|
||||
class Dispatcher {
|
||||
public:
|
||||
Dispatcher(KernelState* kernel_state);
|
||||
|
@ -38,7 +36,6 @@ public:
|
|||
NativeList* dpc_list() const { return dpc_list_; }
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
KernelState* kernel_state_;
|
||||
|
||||
|
@ -46,9 +43,7 @@ private:
|
|||
NativeList* dpc_list_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
||||
|
|
|
@ -22,19 +22,17 @@
|
|||
#include <xenia/kernel/objects/xthread.h>
|
||||
#include <xenia/kernel/objects/xuser_module.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// This is a global object initialized with the XboxkrnlModule.
|
||||
// It references the current kernel state object that all kernel methods should
|
||||
// be using to stash their variables.
|
||||
KernelState* shared_kernel_state_ = nullptr;
|
||||
|
||||
|
||||
KernelState::KernelState(Emulator* emulator) :
|
||||
emulator_(emulator), memory_(emulator->memory()),
|
||||
KernelState::KernelState(Emulator* emulator)
|
||||
: emulator_(emulator),
|
||||
memory_(emulator->memory()),
|
||||
executable_module_(NULL) {
|
||||
processor_ = emulator->processor();
|
||||
file_system_ = emulator->file_system();
|
||||
|
@ -67,9 +65,7 @@ KernelState::~KernelState() {
|
|||
shared_kernel_state_ = NULL;
|
||||
}
|
||||
|
||||
KernelState* KernelState::shared() {
|
||||
return shared_kernel_state_;
|
||||
}
|
||||
KernelState* KernelState::shared() { return shared_kernel_state_; }
|
||||
|
||||
void KernelState::RegisterModule(XModule* module) {}
|
||||
|
||||
|
@ -170,7 +166,8 @@ void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) {
|
|||
}
|
||||
}
|
||||
|
||||
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) {
|
||||
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
|
||||
uint32_t length) {
|
||||
auto ptr = memory()->membase() + overlapped_ptr;
|
||||
XOverlappedSetResult(ptr, result);
|
||||
XOverlappedSetLength(ptr, length);
|
||||
|
@ -190,16 +187,18 @@ void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, u
|
|||
XThread* thread = nullptr;
|
||||
if (XSUCCEEDED(object_table()->GetObject(
|
||||
thread_handle, reinterpret_cast<XObject**>(&thread)))) {
|
||||
// TODO(benvanik): queue APC on the thread that requested the overlapped operation.
|
||||
// TODO(benvanik): queue APC on the thread that requested the overlapped
|
||||
// operation.
|
||||
thread->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) {
|
||||
void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr,
|
||||
X_RESULT result,
|
||||
uint32_t length) {
|
||||
auto ptr = memory()->membase() + overlapped_ptr;
|
||||
XOverlappedSetContext(ptr,
|
||||
XThread::GetCurrentThreadHandle());
|
||||
XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle());
|
||||
CompleteOverlapped(overlapped_ptr, result, length);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,11 @@
|
|||
|
||||
#include <xenia/kernel/native_list.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
NativeList::NativeList(Memory* memory) :
|
||||
memory_(memory),
|
||||
head_(kInvalidPointer) {
|
||||
}
|
||||
NativeList::NativeList(Memory* memory)
|
||||
: memory_(memory), head_(kInvalidPointer) {}
|
||||
|
||||
void NativeList::Insert(uint32_t ptr) {
|
||||
uint8_t* mem = memory_->membase();
|
||||
|
@ -67,9 +63,7 @@ uint32_t NativeList::Shift() {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
bool NativeList::HasPending() {
|
||||
return head_ != kInvalidPointer;
|
||||
}
|
||||
bool NativeList::HasPending() { return head_ != kInvalidPointer; }
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -15,11 +15,9 @@
|
|||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// List is designed for storing pointers to objects in the guest heap.
|
||||
// All values in the list should be assumed to be in big endian.
|
||||
|
||||
|
@ -48,9 +46,7 @@ private:
|
|||
uint32_t head_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_NATIVE_LIST_H_
|
||||
|
|
|
@ -14,16 +14,11 @@
|
|||
#include <xenia/kernel/xobject.h>
|
||||
#include <xenia/kernel/objects/xthread.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
ObjectTable::ObjectTable() :
|
||||
table_capacity_(0),
|
||||
table_(NULL),
|
||||
last_free_entry_(0) {
|
||||
}
|
||||
ObjectTable::ObjectTable()
|
||||
: table_capacity_(0), table_(NULL), last_free_entry_(0) {}
|
||||
|
||||
ObjectTable::~ObjectTable() {
|
||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||
|
@ -182,7 +177,6 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
|
|||
if (object) {
|
||||
object->Retain();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*out_object = object;
|
||||
|
|
|
@ -17,14 +17,11 @@
|
|||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XObject;
|
||||
|
||||
|
||||
class ObjectTable {
|
||||
public:
|
||||
ObjectTable();
|
||||
|
@ -38,9 +35,7 @@ private:
|
|||
X_HANDLE TranslateHandle(X_HANDLE handle);
|
||||
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
||||
|
||||
typedef struct {
|
||||
XObject* object;
|
||||
} ObjectTableEntry;
|
||||
typedef struct { XObject* object; } ObjectTableEntry;
|
||||
|
||||
std::mutex table_mutex_;
|
||||
uint32_t table_capacity_;
|
||||
|
@ -48,9 +43,7 @@ private:
|
|||
uint32_t last_free_entry_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
||||
|
|
|
@ -9,17 +9,15 @@
|
|||
|
||||
#include <xenia/kernel/objects/xenumerator.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
XEnumerator::XEnumerator(KernelState* kernel_state)
|
||||
: XObject(kernel_state, kTypeEnumerator) {}
|
||||
|
||||
XEnumerator::~XEnumerator() {}
|
||||
|
||||
XEnumerator::XEnumerator(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeEnumerator) {
|
||||
}
|
||||
void XEnumerator::Initialize() {}
|
||||
|
||||
XEnumerator::~XEnumerator() {
|
||||
}
|
||||
|
||||
void XEnumerator::Initialize() {
|
||||
}
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
#define XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XEnumerator : public XObject {
|
||||
public:
|
||||
XEnumerator(KernelState* kernel_state);
|
||||
|
@ -29,9 +26,7 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_
|
||||
|
|
|
@ -9,15 +9,11 @@
|
|||
|
||||
#include <xenia/kernel/objects/xevent.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XEvent::XEvent(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeEvent),
|
||||
handle_(NULL) {
|
||||
}
|
||||
XEvent::XEvent(KernelState* kernel_state)
|
||||
: XObject(kernel_state, kTypeEvent), handle_(NULL) {}
|
||||
|
||||
XEvent::~XEvent() {
|
||||
if (handle_) {
|
||||
|
@ -60,10 +56,9 @@ int32_t XEvent::Pulse(uint32_t priority_increment, bool wait) {
|
|||
return PulseEvent(handle_) ? 1 : 0;
|
||||
}
|
||||
|
||||
int32_t XEvent::Reset() {
|
||||
return ResetEvent(handle_) ? 1 : 0;
|
||||
}
|
||||
int32_t XEvent::Reset() { return ResetEvent(handle_) ? 1 : 0; }
|
||||
|
||||
void XEvent::Clear() {
|
||||
ResetEvent(handle_);
|
||||
}
|
||||
void XEvent::Clear() { ResetEvent(handle_); }
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
#define XENIA_KERNEL_XBOXKRNL_XEVENT_H_
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XEvent : public XObject {
|
||||
public:
|
||||
XEvent(KernelState* kernel_state);
|
||||
|
@ -38,9 +35,7 @@ private:
|
|||
HANDLE handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XEVENT_H_
|
||||
|
|
|
@ -12,14 +12,11 @@
|
|||
#include <xenia/kernel/async_request.h>
|
||||
#include <xenia/kernel/objects/xevent.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XFile::XFile(KernelState* kernel_state, fs::Mode mode) :
|
||||
mode_(mode), position_(0),
|
||||
XObject(kernel_state, kTypeFile) {
|
||||
XFile::XFile(KernelState* kernel_state, fs::Mode mode)
|
||||
: mode_(mode), position_(0), XObject(kernel_state, kTypeFile) {
|
||||
async_event_ = new XEvent(kernel_state);
|
||||
async_event_->Initialize(false, false);
|
||||
}
|
||||
|
@ -30,9 +27,7 @@ XFile::~XFile() {
|
|||
async_event_->Delete();
|
||||
}
|
||||
|
||||
void* XFile::GetWaitHandle() {
|
||||
return async_event_->GetWaitHandle();
|
||||
}
|
||||
void* XFile::GetWaitHandle() { return async_event_->GetWaitHandle(); }
|
||||
|
||||
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||
size_t* out_bytes_read) {
|
||||
|
@ -40,7 +35,8 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
|||
// Read from current position.
|
||||
byte_offset = position_;
|
||||
}
|
||||
X_STATUS result = ReadSync(buffer, buffer_length, byte_offset, out_bytes_read);
|
||||
X_STATUS result =
|
||||
ReadSync(buffer, buffer_length, byte_offset, out_bytes_read);
|
||||
if (XSUCCEEDED(result)) {
|
||||
position_ += *out_bytes_read;
|
||||
}
|
||||
|
@ -56,3 +52,6 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
|||
X_STATUS result = X_STATUS_NOT_IMPLEMENTED;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
@ -75,7 +74,8 @@ public:
|
|||
poly::store_and_swap<uint64_t>(dst + 48, info->allocation_size);
|
||||
poly::store_and_swap<uint32_t>(dst + 56, info->attributes);
|
||||
poly::store_and_swap<uint32_t>(dst + 60, info->file_name_length);
|
||||
xe_copy_memory(dst + 64, info->file_name_length, info->file_name, info->file_name_length);
|
||||
xe_copy_memory(dst + 64, info->file_name_length, info->file_name,
|
||||
info->file_name_length);
|
||||
dst += info->next_entry_offset;
|
||||
src += info->next_entry_offset;
|
||||
} while (info->next_entry_offset != 0);
|
||||
|
@ -99,7 +99,8 @@ public:
|
|||
poly::store_and_swap<uint32_t>(dst + 8, this->serial_number);
|
||||
poly::store_and_swap<uint32_t>(dst + 12, this->label_length);
|
||||
poly::store_and_swap<uint32_t>(dst + 16, this->supports_objects);
|
||||
xe_copy_memory(dst + 20, this->label_length, this->label, this->label_length);
|
||||
xe_copy_memory(dst + 20, this->label_length, this->label,
|
||||
this->label_length);
|
||||
}
|
||||
};
|
||||
static_assert_size(XVolumeInfo, 24);
|
||||
|
@ -116,9 +117,11 @@ public:
|
|||
void Write(uint8_t* base, uint32_t p) {
|
||||
uint8_t* dst = base + p;
|
||||
poly::store_and_swap<uint32_t>(dst + 0, this->attributes);
|
||||
poly::store_and_swap<uint32_t>(dst + 4, this->maximum_component_name_length);
|
||||
poly::store_and_swap<uint32_t>(dst + 4,
|
||||
this->maximum_component_name_length);
|
||||
poly::store_and_swap<uint32_t>(dst + 8, this->fs_name_length);
|
||||
xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, this->fs_name_length);
|
||||
xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name,
|
||||
this->fs_name_length);
|
||||
}
|
||||
};
|
||||
static_assert_size(XFileSystemAttributeInfo, 16);
|
||||
|
@ -150,9 +153,8 @@ public:
|
|||
|
||||
protected:
|
||||
XFile(KernelState* kernel_state, fs::Mode mode);
|
||||
virtual X_STATUS ReadSync(
|
||||
void* buffer, size_t buffer_length, size_t byte_offset,
|
||||
size_t* out_bytes_read) = 0;
|
||||
virtual X_STATUS ReadSync(void* buffer, size_t buffer_length,
|
||||
size_t byte_offset, size_t* out_bytes_read) = 0;
|
||||
|
||||
private:
|
||||
fs::Mode mode_;
|
||||
|
@ -163,9 +165,7 @@ private:
|
|||
size_t position_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XFILE_H_
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
#include <xenia/cpu/cpu.h>
|
||||
#include <xenia/kernel/objects/xthread.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) :
|
||||
XModule(kernel_state, path) {
|
||||
XKernelModule::XKernelModule(KernelState* kernel_state, const char* path)
|
||||
: XModule(kernel_state, path) {
|
||||
emulator_ = kernel_state->emulator();
|
||||
memory_ = emulator_->memory();
|
||||
export_resolver_ = kernel_state->emulator()->export_resolver();
|
||||
|
@ -28,11 +25,13 @@ XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) :
|
|||
OnLoad();
|
||||
}
|
||||
|
||||
XKernelModule::~XKernelModule() {
|
||||
}
|
||||
XKernelModule::~XKernelModule() {}
|
||||
|
||||
void* XKernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||
// TODO(benvanik): check export tables.
|
||||
XELOGE("GetProcAddressByOrdinal not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -14,12 +14,11 @@
|
|||
|
||||
XEDECLARECLASS1(xe, Emulator);
|
||||
XEDECLARECLASS1(xe, ExportResolver);
|
||||
XEDECLARECLASS2(xe, kernel, KernelState);
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
class KernelState;
|
||||
|
||||
class XKernelModule : public XModule {
|
||||
public:
|
||||
|
@ -34,9 +33,7 @@ protected:
|
|||
ExportResolver* export_resolver_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
|
||||
#include <xdb/protocol.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XModule::XModule(KernelState* kernel_state, const std::string& path) :
|
||||
XObject(kernel_state, kTypeModule), path_(path) {
|
||||
XModule::XModule(KernelState* kernel_state, const std::string& path)
|
||||
: XObject(kernel_state, kTypeModule), path_(path) {
|
||||
auto last_slash = path.find_last_of('/');
|
||||
if (last_slash == path.npos) {
|
||||
last_slash = path.find_last_of('\\');
|
||||
|
@ -54,8 +51,10 @@ void XModule::OnLoad() {
|
|||
kernel_state_->RegisterModule(this);
|
||||
}
|
||||
|
||||
X_STATUS XModule::GetSection(
|
||||
const char* name,
|
||||
uint32_t* out_section_data, uint32_t* out_section_size) {
|
||||
X_STATUS XModule::GetSection(const char* name, uint32_t* out_section_data,
|
||||
uint32_t* out_section_size) {
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
#include <string>
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XModule : public XObject {
|
||||
public:
|
||||
XModule(KernelState* kernel_state, const std::string& path);
|
||||
|
@ -30,9 +27,8 @@ public:
|
|||
const std::string& name() const { return name_; }
|
||||
|
||||
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
|
||||
virtual X_STATUS GetSection(
|
||||
const char* name,
|
||||
uint32_t* out_section_data, uint32_t* out_section_size);
|
||||
virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data,
|
||||
uint32_t* out_section_size);
|
||||
|
||||
protected:
|
||||
void OnLoad();
|
||||
|
@ -41,9 +37,7 @@ protected:
|
|||
std::string path_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XMODULE_H_
|
||||
|
|
|
@ -9,15 +9,11 @@
|
|||
|
||||
#include <xenia/kernel/objects/xmutant.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XMutant::XMutant(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeMutant),
|
||||
handle_(NULL) {
|
||||
}
|
||||
XMutant::XMutant(KernelState* kernel_state)
|
||||
: XObject(kernel_state, kTypeMutant), handle_(NULL) {}
|
||||
|
||||
XMutant::~XMutant() {
|
||||
if (handle_) {
|
||||
|
@ -38,8 +34,8 @@ void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
|
|||
assert_always();
|
||||
}
|
||||
|
||||
X_STATUS XMutant::ReleaseMutant(
|
||||
uint32_t priority_increment, bool abandon, bool wait) {
|
||||
X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon,
|
||||
bool wait) {
|
||||
// TODO(benvanik): abandoning.
|
||||
assert_false(abandon);
|
||||
BOOL result = ReleaseMutex(handle_);
|
||||
|
@ -49,3 +45,6 @@ X_STATUS XMutant::ReleaseMutant(
|
|||
return X_STATUS_MUTANT_NOT_OWNED;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
#define XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XMutant : public XObject {
|
||||
public:
|
||||
XMutant(KernelState* kernel_state);
|
||||
|
@ -35,9 +32,7 @@ private:
|
|||
HANDLE handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
||||
|
|
|
@ -9,15 +9,14 @@
|
|||
|
||||
#include <xenia/kernel/objects/xnotify_listener.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XNotifyListener::XNotifyListener(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeNotifyListener),
|
||||
wait_handle_(NULL), mask_(0), notification_count_(0) {
|
||||
}
|
||||
XNotifyListener::XNotifyListener(KernelState* kernel_state)
|
||||
: XObject(kernel_state, kTypeNotifyListener),
|
||||
wait_handle_(NULL),
|
||||
mask_(0),
|
||||
notification_count_(0) {}
|
||||
|
||||
XNotifyListener::~XNotifyListener() {
|
||||
kernel_state_->UnregisterNotifyListener(this);
|
||||
|
@ -53,8 +52,8 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
|
|||
SetEvent(wait_handle_);
|
||||
}
|
||||
|
||||
bool XNotifyListener::DequeueNotification(
|
||||
XNotificationID* out_id, uint32_t* out_data) {
|
||||
bool XNotifyListener::DequeueNotification(XNotificationID* out_id,
|
||||
uint32_t* out_data) {
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
bool dequeued = false;
|
||||
if (notification_count_) {
|
||||
|
@ -71,8 +70,8 @@ bool XNotifyListener::DequeueNotification(
|
|||
return dequeued;
|
||||
}
|
||||
|
||||
bool XNotifyListener::DequeueNotification(
|
||||
XNotificationID id, uint32_t* out_data) {
|
||||
bool XNotifyListener::DequeueNotification(XNotificationID id,
|
||||
uint32_t* out_data) {
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
bool dequeued = false;
|
||||
if (notification_count_) {
|
||||
|
@ -89,3 +88,6 @@ bool XNotifyListener::DequeueNotification(
|
|||
}
|
||||
return dequeued;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -7,23 +7,17 @@
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
// This should probably be in XAM, but I don't want to build an extensible
|
||||
// object system. Meh.
|
||||
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XNotifyListener : public XObject {
|
||||
public:
|
||||
XNotifyListener(KernelState* kernel_state);
|
||||
|
@ -45,9 +39,7 @@ private:
|
|||
uint64_t mask_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||
|
|
|
@ -9,15 +9,11 @@
|
|||
|
||||
#include <xenia/kernel/objects/xsemaphore.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XSemaphore::XSemaphore(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeSemaphore),
|
||||
handle_(NULL) {
|
||||
}
|
||||
XSemaphore::XSemaphore(KernelState* kernel_state)
|
||||
: XObject(kernel_state, kTypeSemaphore), handle_(NULL) {}
|
||||
|
||||
XSemaphore::~XSemaphore() {
|
||||
if (handle_) {
|
||||
|
@ -43,3 +39,6 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_count) {
|
|||
::ReleaseSemaphore(handle_, release_count, &previous_count);
|
||||
return previous_count;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
#define XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XSemaphore : public XObject {
|
||||
public:
|
||||
XSemaphore(KernelState* kernel_state);
|
||||
|
@ -35,9 +32,7 @@ private:
|
|||
HANDLE handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_
|
||||
|
|
|
@ -16,27 +16,20 @@
|
|||
#include <xenia/kernel/objects/xevent.h>
|
||||
#include <xenia/kernel/objects/xuser_module.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace alloy;
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::kernel;
|
||||
|
||||
uint32_t next_xthread_id = 0;
|
||||
thread_local XThread* current_thread_tls;
|
||||
std::mutex critical_region_;
|
||||
XThread* shared_kernel_thread_ = 0;
|
||||
|
||||
namespace {
|
||||
static uint32_t next_xthread_id = 0;
|
||||
static thread_local XThread* current_thread_tls;
|
||||
static std::mutex critical_region_;
|
||||
static XThread* shared_kernel_thread_ = 0;
|
||||
}
|
||||
|
||||
|
||||
XThread::XThread(KernelState* kernel_state,
|
||||
uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup,
|
||||
uint32_t start_address, uint32_t start_context,
|
||||
uint32_t creation_flags) :
|
||||
XObject(kernel_state, kTypeThread),
|
||||
XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup, uint32_t start_address,
|
||||
uint32_t start_context, uint32_t creation_flags)
|
||||
: XObject(kernel_state, kTypeThread),
|
||||
thread_id_(++next_xthread_id),
|
||||
thread_handle_(0),
|
||||
thread_state_address_(0),
|
||||
|
@ -108,8 +101,7 @@ XThread* XThread::GetCurrentThread() {
|
|||
XThread::EnterCriticalRegion();
|
||||
thread = shared_kernel_thread_;
|
||||
if (!thread) {
|
||||
thread = new XThread(
|
||||
KernelState::shared(), 32 * 1024, 0, 0, 0, 0);
|
||||
thread = new XThread(KernelState::shared(), 32 * 1024, 0, 0, 0, 0);
|
||||
shared_kernel_thread_ = thread;
|
||||
current_thread_tls = thread;
|
||||
}
|
||||
|
@ -127,13 +119,9 @@ uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) {
|
|||
return poly::load_and_swap<uint32_t>(thread_state_block + 0x14C);
|
||||
}
|
||||
|
||||
uint32_t XThread::thread_state() {
|
||||
return thread_state_address_;
|
||||
}
|
||||
uint32_t XThread::thread_state() { return thread_state_address_; }
|
||||
|
||||
uint32_t XThread::thread_id() {
|
||||
return thread_id_;
|
||||
}
|
||||
uint32_t XThread::thread_id() { return thread_id_; }
|
||||
|
||||
uint32_t XThread::last_error() {
|
||||
uint8_t* p = memory()->Translate(thread_state_address_);
|
||||
|
@ -163,8 +151,8 @@ X_STATUS XThread::Create() {
|
|||
// 0x160: last error
|
||||
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
|
||||
// structure.
|
||||
thread_state_address_ = (uint32_t)memory()->HeapAlloc(
|
||||
0, 2048, MEMORY_FLAG_ZERO);
|
||||
thread_state_address_ =
|
||||
(uint32_t)memory()->HeapAlloc(0, 2048, alloy::MEMORY_FLAG_ZERO);
|
||||
if (!thread_state_address_) {
|
||||
XELOGW("Unable to allocate thread state block");
|
||||
return X_STATUS_NO_MEMORY;
|
||||
|
@ -178,14 +166,14 @@ X_STATUS XThread::Create() {
|
|||
// Allocate thread scratch.
|
||||
// This is used by interrupts/APCs/etc so we can round-trip pointers through.
|
||||
scratch_size_ = 4 * 16;
|
||||
scratch_address_ = (uint32_t)memory()->HeapAlloc(
|
||||
0, scratch_size_, MEMORY_FLAG_ZERO);
|
||||
scratch_address_ =
|
||||
(uint32_t)memory()->HeapAlloc(0, scratch_size_, alloy::MEMORY_FLAG_ZERO);
|
||||
|
||||
// Allocate TLS block.
|
||||
const xe_xex2_header_t* header = module->xex_header();
|
||||
uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size;
|
||||
tls_address_ = (uint32_t)memory()->HeapAlloc(
|
||||
0, tls_size, MEMORY_FLAG_ZERO);
|
||||
tls_address_ =
|
||||
(uint32_t)memory()->HeapAlloc(0, tls_size, alloy::MEMORY_FLAG_ZERO);
|
||||
if (!tls_address_) {
|
||||
XELOGW("Unable to allocate thread local storage block");
|
||||
module->Release();
|
||||
|
@ -194,8 +182,7 @@ X_STATUS XThread::Create() {
|
|||
|
||||
// Copy in default TLS info.
|
||||
// TODO(benvanik): is this correct?
|
||||
memory()->Copy(
|
||||
tls_address_, header->tls_info.raw_data_address, tls_size);
|
||||
memory()->Copy(tls_address_, header->tls_info.raw_data_address, tls_size);
|
||||
|
||||
// Setup the thread state block (last error/etc).
|
||||
uint8_t* p = memory()->Translate(thread_state_address_);
|
||||
|
@ -207,9 +194,9 @@ X_STATUS XThread::Create() {
|
|||
|
||||
// Allocate processor thread state.
|
||||
// This is thread safe.
|
||||
thread_state_ = new XenonThreadState(
|
||||
kernel_state()->processor()->runtime(),
|
||||
thread_id_, creation_params_.stack_size, thread_state_address_);
|
||||
thread_state_ =
|
||||
new XenonThreadState(kernel_state()->processor()->runtime(), thread_id_,
|
||||
creation_params_.stack_size, thread_state_address_);
|
||||
|
||||
X_STATUS return_code = PlatformCreate();
|
||||
if (XFAILED(return_code)) {
|
||||
|
@ -268,13 +255,10 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) {
|
|||
|
||||
X_STATUS XThread::PlatformCreate() {
|
||||
bool suspended = creation_params_.creation_flags & 0x1;
|
||||
thread_handle_ = CreateThread(
|
||||
NULL,
|
||||
creation_params_.stack_size,
|
||||
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32,
|
||||
this,
|
||||
suspended ? CREATE_SUSPENDED : 0,
|
||||
NULL);
|
||||
thread_handle_ =
|
||||
CreateThread(NULL, creation_params_.stack_size,
|
||||
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this,
|
||||
suspended ? CREATE_SUSPENDED : 0, NULL);
|
||||
if (!thread_handle_) {
|
||||
uint32_t last_error = GetLastError();
|
||||
// TODO(benvanik): translate?
|
||||
|
@ -319,20 +303,15 @@ X_STATUS XThread::PlatformCreate() {
|
|||
if (creation_params_.creation_flags & 0x1) {
|
||||
#if XE_PLATFORM_OSX
|
||||
result_code = pthread_create_suspended_np(
|
||||
reinterpret_cast<pthread_t*>(&thread_handle_),
|
||||
&attr,
|
||||
&XThreadStartCallbackPthreads,
|
||||
this);
|
||||
reinterpret_cast<pthread_t*>(&thread_handle_), &attr,
|
||||
&XThreadStartCallbackPthreads, this);
|
||||
#else
|
||||
// TODO(benvanik): pthread_create_suspended_np on linux
|
||||
assert_always();
|
||||
#endif // OSX
|
||||
} else {
|
||||
result_code = pthread_create(
|
||||
reinterpret_cast<pthread_t*>(&thread_handle_),
|
||||
&attr,
|
||||
&XThreadStartCallbackPthreads,
|
||||
this);
|
||||
result_code = pthread_create(reinterpret_cast<pthread_t*>(&thread_handle_),
|
||||
&attr, &XThreadStartCallbackPthreads, this);
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
@ -389,28 +368,21 @@ void XThread::EnterCriticalRegion() {
|
|||
critical_region_.lock();
|
||||
}
|
||||
|
||||
void XThread::LeaveCriticalRegion() {
|
||||
critical_region_.unlock();
|
||||
}
|
||||
void XThread::LeaveCriticalRegion() { critical_region_.unlock(); }
|
||||
|
||||
uint32_t XThread::RaiseIrql(uint32_t new_irql) {
|
||||
return irql_.exchange(new_irql);
|
||||
}
|
||||
|
||||
void XThread::LowerIrql(uint32_t new_irql) {
|
||||
irql_ = new_irql;
|
||||
}
|
||||
void XThread::LowerIrql(uint32_t new_irql) { irql_ = new_irql; }
|
||||
|
||||
void XThread::LockApc() {
|
||||
apc_lock_.lock();
|
||||
}
|
||||
void XThread::LockApc() { apc_lock_.lock(); }
|
||||
|
||||
void XThread::UnlockApc() {
|
||||
bool needs_apc = apc_list_->HasPending();
|
||||
apc_lock_.unlock();
|
||||
if (needs_apc) {
|
||||
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs),
|
||||
thread_handle_,
|
||||
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs), thread_handle_,
|
||||
reinterpret_cast<ULONG_PTR>(this));
|
||||
}
|
||||
}
|
||||
|
@ -447,16 +419,15 @@ void XThread::DeliverAPCs(void* data) {
|
|||
poly::store_and_swap<uint32_t>(scratch_ptr + 4, normal_context);
|
||||
poly::store_and_swap<uint32_t>(scratch_ptr + 8, system_arg1);
|
||||
poly::store_and_swap<uint32_t>(scratch_ptr + 12, system_arg2);
|
||||
// kernel_routine(apc_address, &normal_routine, &normal_context, &system_arg1, &system_arg2)
|
||||
// kernel_routine(apc_address, &normal_routine, &normal_context,
|
||||
// &system_arg1, &system_arg2)
|
||||
uint64_t kernel_args[] = {
|
||||
apc_address,
|
||||
thread->scratch_address_ + 0,
|
||||
thread->scratch_address_ + 4,
|
||||
thread->scratch_address_ + 8,
|
||||
apc_address, thread->scratch_address_ + 0,
|
||||
thread->scratch_address_ + 4, thread->scratch_address_ + 8,
|
||||
thread->scratch_address_ + 12,
|
||||
};
|
||||
processor->ExecuteInterrupt(
|
||||
0, kernel_routine, kernel_args, poly::countof(kernel_args));
|
||||
processor->ExecuteInterrupt(0, kernel_routine, kernel_args,
|
||||
poly::countof(kernel_args));
|
||||
normal_routine = poly::load_and_swap<uint32_t>(scratch_ptr + 0);
|
||||
normal_context = poly::load_and_swap<uint32_t>(scratch_ptr + 4);
|
||||
system_arg1 = poly::load_and_swap<uint32_t>(scratch_ptr + 8);
|
||||
|
@ -468,8 +439,8 @@ void XThread::DeliverAPCs(void* data) {
|
|||
thread->UnlockApc();
|
||||
// normal_routine(normal_context, system_arg1, system_arg2)
|
||||
uint64_t normal_args[] = {normal_context, system_arg1, system_arg2};
|
||||
processor->ExecuteInterrupt(
|
||||
0, normal_routine, normal_args, poly::countof(normal_args));
|
||||
processor->ExecuteInterrupt(0, normal_routine, normal_args,
|
||||
poly::countof(normal_args));
|
||||
thread->LockApc();
|
||||
}
|
||||
}
|
||||
|
@ -494,16 +465,14 @@ void XThread::RundownAPCs() {
|
|||
if (rundown_routine) {
|
||||
// rundown_routine(apc)
|
||||
uint64_t args[] = {apc_address};
|
||||
kernel_state()->processor()->ExecuteInterrupt(
|
||||
0, rundown_routine, args, poly::countof(args));
|
||||
kernel_state()->processor()->ExecuteInterrupt(0, rundown_routine, args,
|
||||
poly::countof(args));
|
||||
}
|
||||
}
|
||||
UnlockApc();
|
||||
}
|
||||
|
||||
int32_t XThread::QueryPriority() {
|
||||
return GetThreadPriority(thread_handle_);
|
||||
}
|
||||
int32_t XThread::QueryPriority() { return GetThreadPriority(thread_handle_); }
|
||||
|
||||
void XThread::SetPriority(int32_t increment) {
|
||||
SetThreadPriority(thread_handle_, increment);
|
||||
|
@ -538,8 +507,8 @@ X_STATUS XThread::Suspend(uint32_t* out_suspend_count) {
|
|||
}
|
||||
}
|
||||
|
||||
X_STATUS XThread::Delay(
|
||||
uint32_t processor_mode, uint32_t alertable, uint64_t interval) {
|
||||
X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t interval) {
|
||||
int64_t timeout_ticks = interval;
|
||||
DWORD timeout_ms;
|
||||
if (timeout_ticks > 0) {
|
||||
|
@ -564,6 +533,7 @@ X_STATUS XThread::Delay(
|
|||
}
|
||||
}
|
||||
|
||||
void* XThread::GetWaitHandle() {
|
||||
return event_->GetWaitHandle();
|
||||
}
|
||||
void* XThread::GetWaitHandle() { return event_->GetWaitHandle(); }
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -15,26 +15,21 @@
|
|||
#include <string>
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
XEDECLARECLASS2(xe, cpu, XenonThreadState);
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
class NativeList;
|
||||
class XEvent;
|
||||
|
||||
|
||||
class XThread : public XObject {
|
||||
public:
|
||||
XThread(KernelState* kernel_state,
|
||||
uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup,
|
||||
uint32_t start_address, uint32_t start_context,
|
||||
uint32_t creation_flags);
|
||||
XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup, uint32_t start_address,
|
||||
uint32_t start_context, uint32_t creation_flags);
|
||||
virtual ~XThread();
|
||||
|
||||
static XThread* GetCurrentThread();
|
||||
|
@ -68,8 +63,8 @@ public:
|
|||
|
||||
X_STATUS Resume(uint32_t* out_suspend_count);
|
||||
X_STATUS Suspend(uint32_t* out_suspend_count);
|
||||
X_STATUS Delay(
|
||||
uint32_t processor_mode, uint32_t alertable, uint64_t interval);
|
||||
X_STATUS Delay(uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t interval);
|
||||
|
||||
virtual void* GetWaitHandle();
|
||||
|
||||
|
@ -106,9 +101,7 @@ private:
|
|||
XEvent* event_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XTHREAD_H_
|
||||
|
|
|
@ -11,15 +11,11 @@
|
|||
|
||||
#include <xenia/cpu/processor.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XTimer::XTimer(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeTimer),
|
||||
handle_(NULL) {
|
||||
}
|
||||
XTimer::XTimer(KernelState* kernel_state)
|
||||
: XObject(kernel_state, kTypeTimer), handle_(NULL) {}
|
||||
|
||||
XTimer::~XTimer() {
|
||||
if (handle_) {
|
||||
|
@ -46,8 +42,7 @@ void XTimer::Initialize(uint32_t timer_type) {
|
|||
handle_ = CreateWaitableTimer(NULL, manual_reset, NULL);
|
||||
}
|
||||
|
||||
X_STATUS XTimer::SetTimer(
|
||||
int64_t due_time, uint32_t period_ms,
|
||||
X_STATUS XTimer::SetTimer(int64_t due_time, uint32_t period_ms,
|
||||
uint32_t routine, uint32_t routine_arg, bool resume) {
|
||||
// Stash routine for callback.
|
||||
current_routine_ = routine;
|
||||
|
@ -55,10 +50,10 @@ X_STATUS XTimer::SetTimer(
|
|||
|
||||
LARGE_INTEGER due_time_li;
|
||||
due_time_li.QuadPart = due_time;
|
||||
BOOL result = SetWaitableTimer(
|
||||
handle_, &due_time_li, period_ms,
|
||||
routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL, this,
|
||||
resume ? TRUE : FALSE);
|
||||
BOOL result =
|
||||
SetWaitableTimer(handle_, &due_time_li, period_ms,
|
||||
routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL,
|
||||
this, resume ? TRUE : FALSE);
|
||||
|
||||
// Caller is checking for STATUS_TIMER_RESUME_IGNORED.
|
||||
// This occurs if result == TRUE but error is set.
|
||||
|
@ -69,8 +64,8 @@ X_STATUS XTimer::SetTimer(
|
|||
return result ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
void XTimer::CompletionRoutine(
|
||||
XTimer* timer, DWORD timer_low, DWORD timer_high) {
|
||||
void XTimer::CompletionRoutine(XTimer* timer, DWORD timer_low,
|
||||
DWORD timer_high) {
|
||||
assert_true(timer->current_routine_);
|
||||
|
||||
// Queue APC to call back routine with (arg, low, high).
|
||||
|
@ -81,6 +76,9 @@ void XTimer::CompletionRoutine(
|
|||
}
|
||||
|
||||
X_STATUS XTimer::Cancel() {
|
||||
return CancelWaitableTimer(handle_) == 0 ?
|
||||
X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL;
|
||||
return CancelWaitableTimer(handle_) == 0 ? X_STATUS_SUCCESS
|
||||
: X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
#define XENIA_KERNEL_XBOXKRNL_XTIMER_H_
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XTimer : public XObject {
|
||||
public:
|
||||
XTimer(KernelState* kernel_state);
|
||||
|
@ -27,8 +24,8 @@ public:
|
|||
void Initialize(uint32_t timer_type);
|
||||
|
||||
// completion routine, arg to completion routine
|
||||
X_STATUS SetTimer(int64_t due_time, uint32_t period_ms,
|
||||
uint32_t routine, uint32_t routine_arg, bool resume);
|
||||
X_STATUS SetTimer(int64_t due_time, uint32_t period_ms, uint32_t routine,
|
||||
uint32_t routine_arg, bool resume);
|
||||
X_STATUS Cancel();
|
||||
|
||||
virtual void* GetWaitHandle() { return handle_; }
|
||||
|
@ -39,13 +36,11 @@ private:
|
|||
uint32_t current_routine_;
|
||||
uint32_t current_routine_arg_;
|
||||
|
||||
static void CompletionRoutine(
|
||||
XTimer* timer, DWORD timer_low, DWORD timer_high);
|
||||
static void CompletionRoutine(XTimer* timer, DWORD timer_low,
|
||||
DWORD timer_high);
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_TIMER_H_
|
||||
|
|
|
@ -14,24 +14,17 @@
|
|||
#include <xenia/kernel/objects/xfile.h>
|
||||
#include <xenia/kernel/objects/xthread.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::kernel;
|
||||
|
||||
XUserModule::XUserModule(KernelState* kernel_state, const char* path)
|
||||
: XModule(kernel_state, path), xex_(NULL) {}
|
||||
|
||||
XUserModule::XUserModule(KernelState* kernel_state, const char* path) :
|
||||
XModule(kernel_state, path),
|
||||
xex_(NULL) {
|
||||
}
|
||||
XUserModule::~XUserModule() { xe_xex2_release(xex_); }
|
||||
|
||||
XUserModule::~XUserModule() {
|
||||
xe_xex2_release(xex_);
|
||||
}
|
||||
|
||||
xe_xex2_ref XUserModule::xex() {
|
||||
return xe_xex2_retain(xex_);
|
||||
}
|
||||
xe_xex2_ref XUserModule::xex() { return xe_xex2_retain(xex_); }
|
||||
|
||||
const xe_xex2_header_t* XUserModule::xex_header() {
|
||||
return xe_xex2_get_header(xex_);
|
||||
|
@ -134,9 +127,8 @@ void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
X_STATUS XUserModule::GetSection(
|
||||
const char* name,
|
||||
uint32_t* out_section_data, uint32_t* out_section_size) {
|
||||
X_STATUS XUserModule::GetSection(const char* name, uint32_t* out_section_data,
|
||||
uint32_t* out_section_size) {
|
||||
auto header = xe_xex2_get_header(xex_);
|
||||
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||
auto& res = header->resource_infos[n];
|
||||
|
@ -158,12 +150,8 @@ X_STATUS XUserModule::Launch(uint32_t flags) {
|
|||
Dump();
|
||||
|
||||
// Create a thread to run in.
|
||||
XThread* thread = new XThread(
|
||||
kernel_state(),
|
||||
header->exe_stack_size,
|
||||
0,
|
||||
header->exe_entry_point, NULL,
|
||||
0);
|
||||
XThread* thread = new XThread(kernel_state(), header->exe_stack_size, 0,
|
||||
header->exe_entry_point, NULL, 0);
|
||||
|
||||
X_STATUS result = thread->Create();
|
||||
if (XFAILED(result)) {
|
||||
|
@ -196,11 +184,10 @@ void XUserModule::Dump() {
|
|||
printf("\n");
|
||||
printf(" Execution Info:\n");
|
||||
printf(" Media ID: %.8X\n", header->execution_info.media_id);
|
||||
printf(" Version: %d.%d.%d.%d\n",
|
||||
header->execution_info.version.major,
|
||||
printf(
|
||||
" Version: %d.%d.%d.%d\n", header->execution_info.version.major,
|
||||
header->execution_info.version.minor,
|
||||
header->execution_info.version.build,
|
||||
header->execution_info.version.qfe);
|
||||
header->execution_info.version.build, header->execution_info.version.qfe);
|
||||
printf(" Base Version: %d.%d.%d.%d\n",
|
||||
header->execution_info.base_version.major,
|
||||
header->execution_info.base_version.minor,
|
||||
|
@ -227,9 +214,9 @@ void XUserModule::Dump() {
|
|||
printf(" Headers:\n");
|
||||
for (size_t n = 0; n < header->header_count; n++) {
|
||||
const xe_xex2_opt_header_t* opt_header = &header->headers[n];
|
||||
printf(" %.8X (%.8X, %4db) %.8X = %11d\n",
|
||||
opt_header->key, opt_header->offset, opt_header->length,
|
||||
opt_header->value, opt_header->value);
|
||||
printf(" %.8X (%.8X, %4db) %.8X = %11d\n", opt_header->key,
|
||||
opt_header->offset, opt_header->length, opt_header->value,
|
||||
opt_header->value);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
@ -237,8 +224,8 @@ void XUserModule::Dump() {
|
|||
printf("Resources:\n");
|
||||
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||
auto& res = header->resource_infos[n];
|
||||
printf(" %-8s %.8X-%.8X, %db\n",
|
||||
res.name, res.address, res.address + res.size, res.size);
|
||||
printf(" %-8s %.8X-%.8X, %db\n", res.name, res.address,
|
||||
res.address + res.size, res.size);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
@ -262,9 +249,9 @@ void XUserModule::Dump() {
|
|||
header->exe_address + (i * xe_xex2_section_length);
|
||||
const size_t end_address =
|
||||
start_address + (section->info.page_count * xe_xex2_section_length);
|
||||
printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n",
|
||||
(int)n, type, section->info.page_count, (int)start_address,
|
||||
(int)end_address, section->info.page_count * xe_xex2_section_length);
|
||||
printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n", (int)n, type,
|
||||
section->info.page_count, (int)start_address, (int)end_address,
|
||||
section->info.page_count * xe_xex2_section_length);
|
||||
i += section->info.page_count;
|
||||
}
|
||||
printf("\n");
|
||||
|
@ -273,8 +260,7 @@ void XUserModule::Dump() {
|
|||
printf("Static Libraries:\n");
|
||||
for (size_t n = 0; n < header->static_library_count; n++) {
|
||||
const xe_xex2_static_library_t* library = &header->static_libraries[n];
|
||||
printf(" %-8s : %d.%d.%d.%d\n",
|
||||
library->name, library->major,
|
||||
printf(" %-8s : %d.%d.%d.%d\n", library->name, library->major,
|
||||
library->minor, library->build, library->qfe);
|
||||
}
|
||||
printf("\n");
|
||||
|
@ -286,15 +272,15 @@ void XUserModule::Dump() {
|
|||
|
||||
xe_xex2_import_info_t* import_infos;
|
||||
size_t import_info_count;
|
||||
if (!xe_xex2_get_import_infos(xex_, library,
|
||||
&import_infos, &import_info_count)) {
|
||||
if (!xe_xex2_get_import_infos(xex_, library, &import_infos,
|
||||
&import_info_count)) {
|
||||
printf(" %s - %d imports\n", library->name, (int)import_info_count);
|
||||
printf(" Version: %d.%d.%d.%d\n",
|
||||
library->version.major, library->version.minor,
|
||||
library->version.build, library->version.qfe);
|
||||
printf(" Min Version: %d.%d.%d.%d\n",
|
||||
library->min_version.major, library->min_version.minor,
|
||||
library->min_version.build, library->min_version.qfe);
|
||||
printf(" Version: %d.%d.%d.%d\n", library->version.major,
|
||||
library->version.minor, library->version.build,
|
||||
library->version.qfe);
|
||||
printf(" Min Version: %d.%d.%d.%d\n", library->min_version.major,
|
||||
library->min_version.minor, library->min_version.build,
|
||||
library->min_version.qfe);
|
||||
printf("\n");
|
||||
|
||||
// Counts.
|
||||
|
@ -323,15 +309,15 @@ void XUserModule::Dump() {
|
|||
(int)(known_count / (float)import_info_count * 100.0f),
|
||||
known_count, unknown_count);
|
||||
printf(" Implemented: %3d%% (%d implemented, %d unimplemented)\n",
|
||||
(int)(impl_count / (float)import_info_count * 100.0f),
|
||||
impl_count, unimpl_count);
|
||||
(int)(impl_count / (float)import_info_count * 100.0f), impl_count,
|
||||
unimpl_count);
|
||||
printf("\n");
|
||||
|
||||
// Listing.
|
||||
for (size_t m = 0; m < import_info_count; m++) {
|
||||
const xe_xex2_import_info_t* info = &import_infos[m];
|
||||
KernelExport* kernel_export = export_resolver->GetExportByOrdinal(
|
||||
library->name, info->ordinal);
|
||||
KernelExport* kernel_export =
|
||||
export_resolver->GetExportByOrdinal(library->name, info->ordinal);
|
||||
const char* name = "UNKNOWN";
|
||||
bool implemented = false;
|
||||
if (kernel_export) {
|
||||
|
@ -339,14 +325,12 @@ void XUserModule::Dump() {
|
|||
implemented = kernel_export->is_implemented;
|
||||
}
|
||||
if (kernel_export && kernel_export->type == KernelExport::Variable) {
|
||||
printf(" V %.8X %.3X (%3d) %s %s\n",
|
||||
info->value_address, info->ordinal, info->ordinal,
|
||||
implemented ? " " : "!!", name);
|
||||
printf(" V %.8X %.3X (%3d) %s %s\n", info->value_address,
|
||||
info->ordinal, info->ordinal, implemented ? " " : "!!", name);
|
||||
} else if (info->thunk_address) {
|
||||
printf(" F %.8X %.8X %.3X (%3d) %s %s\n",
|
||||
info->value_address, info->thunk_address, info->ordinal,
|
||||
info->ordinal, implemented ? " " : "!!", name);
|
||||
|
||||
printf(" F %.8X %.8X %.3X (%3d) %s %s\n", info->value_address,
|
||||
info->thunk_address, info->ordinal, info->ordinal,
|
||||
implemented ? " " : "!!", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -359,3 +343,6 @@ void XUserModule::Dump() {
|
|||
printf(" TODO\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -13,14 +13,12 @@
|
|||
#include <xenia/kernel/objects/xmodule.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/xbox.h>
|
||||
#include <xenia/kernel/util/xex2.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XUserModule : public XModule {
|
||||
public:
|
||||
XUserModule(KernelState* kernel_state, const char* path);
|
||||
|
@ -33,9 +31,8 @@ public:
|
|||
X_STATUS LoadFromMemory(const void* addr, const size_t length);
|
||||
|
||||
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
|
||||
virtual X_STATUS GetSection(
|
||||
const char* name,
|
||||
uint32_t* out_section_data, uint32_t* out_section_size);
|
||||
virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data,
|
||||
uint32_t* out_section_size);
|
||||
|
||||
X_STATUS Launch(uint32_t flags);
|
||||
|
||||
|
@ -47,9 +44,7 @@ private:
|
|||
xe_xex2_ref xex_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XUSER_MODULE_H_
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
|
||||
#include <xenia/kernel/user_profile.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
UserProfile::UserProfile() {
|
||||
xuid_ = 0xBABEBABEBABEBABE;
|
||||
name_ = "User";
|
||||
|
@ -78,13 +76,11 @@ UserProfile::UserProfile() {
|
|||
AddSetting(std::make_unique<BinarySetting>(0x63E83FFD, zeros));
|
||||
}
|
||||
|
||||
|
||||
void UserProfile::AddSetting(std::unique_ptr<Setting> setting) {
|
||||
settings_.insert({setting->setting_id, setting.get()});
|
||||
setting_list_.push_back(std::move(setting));
|
||||
}
|
||||
|
||||
|
||||
UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) {
|
||||
const auto& it = settings_.find(setting_id);
|
||||
if (it == settings_.end()) {
|
||||
|
@ -93,6 +89,5 @@ UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) {
|
|||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -20,11 +20,9 @@
|
|||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class UserProfile {
|
||||
public:
|
||||
struct Setting {
|
||||
|
@ -54,13 +52,14 @@ public:
|
|||
Setting(uint32_t setting_id, Type type, size_t size)
|
||||
: setting_id(setting_id), type(type), size(size) {}
|
||||
virtual size_t extra_size() const { return 0; }
|
||||
virtual size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) {
|
||||
poly::store_and_swap<uint8_t>(user_data + kTypeOffset, static_cast<uint8_t>(type));
|
||||
virtual size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) {
|
||||
poly::store_and_swap<uint8_t>(user_data + kTypeOffset,
|
||||
static_cast<uint8_t>(type));
|
||||
return buffer_offset;
|
||||
}
|
||||
bool is_title_specific() const {
|
||||
return (setting_id & 0x3F00) == 0x3F00;
|
||||
}
|
||||
bool is_title_specific() const { return (setting_id & 0x3F00) == 0x3F00; }
|
||||
|
||||
protected:
|
||||
const size_t kTypeOffset = 0;
|
||||
const size_t kValueOffset = 8;
|
||||
|
@ -70,7 +69,8 @@ public:
|
|||
Int32Setting(uint32_t setting_id, int32_t value)
|
||||
: Setting(setting_id, Type::INT32, 4), value(value) {}
|
||||
int32_t value;
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
poly::store_and_swap<int32_t>(user_data + kValueOffset, value);
|
||||
return buffer_offset;
|
||||
|
@ -80,7 +80,8 @@ public:
|
|||
Int64Setting(uint32_t setting_id, int64_t value)
|
||||
: Setting(setting_id, Type::INT64, 8), value(value) {}
|
||||
int64_t value;
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
poly::store_and_swap<int64_t>(user_data + kValueOffset, value);
|
||||
return buffer_offset;
|
||||
|
@ -90,7 +91,8 @@ public:
|
|||
DoubleSetting(uint32_t setting_id, double value)
|
||||
: Setting(setting_id, Type::DOUBLE, 8), value(value) {}
|
||||
double value;
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
poly::store_and_swap<double>(user_data + kValueOffset, value);
|
||||
return buffer_offset;
|
||||
|
@ -103,7 +105,8 @@ public:
|
|||
size_t extra_size() const override {
|
||||
return value.empty() ? 0 : 2 * (static_cast<int32_t>(value.size()) + 1);
|
||||
}
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
int32_t length;
|
||||
if (value.empty()) {
|
||||
|
@ -124,7 +127,8 @@ public:
|
|||
FloatSetting(uint32_t setting_id, float value)
|
||||
: Setting(setting_id, Type::FLOAT, 4), value(value) {}
|
||||
float value;
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
poly::store_and_swap<float>(user_data + kValueOffset, value);
|
||||
return buffer_offset;
|
||||
|
@ -137,7 +141,8 @@ public:
|
|||
size_t extra_size() const override {
|
||||
return static_cast<int32_t>(value.size());
|
||||
}
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
int32_t length;
|
||||
if (value.empty()) {
|
||||
|
@ -158,7 +163,8 @@ public:
|
|||
DateTimeSetting(uint32_t setting_id, int64_t value)
|
||||
: Setting(setting_id, Type::DATETIME, 8), value(value) {}
|
||||
int64_t value;
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override {
|
||||
size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
size_t buffer_offset) override {
|
||||
buffer_offset = Setting::Append(user_data, buffer, buffer_offset);
|
||||
poly::store_and_swap<int64_t>(user_data + kValueOffset, value);
|
||||
return buffer_offset;
|
||||
|
@ -181,9 +187,7 @@ private:
|
|||
std::unordered_map<uint32_t, Setting*> settings_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_USER_PROFILE_H_
|
||||
|
|
|
@ -25,7 +25,6 @@ using namespace alloy;
|
|||
|
||||
DEFINE_bool(xex_dev_key, false, "Use the devkit key.");
|
||||
|
||||
|
||||
typedef struct xe_xex2 {
|
||||
xe_ref_t ref;
|
||||
|
||||
|
@ -41,20 +40,16 @@ typedef struct xe_xex2 {
|
|||
} library_imports[16];
|
||||
} xe_xex2_t;
|
||||
|
||||
|
||||
int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||
xe_xex2_header_t *header);
|
||||
int xe_xex2_decrypt_key(xe_xex2_header_t *header);
|
||||
int xe_xex2_read_image(xe_xex2_ref xex,
|
||||
const uint8_t *xex_addr, const size_t xex_length,
|
||||
Memory* memory);
|
||||
int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
|
||||
const size_t xex_length, Memory *memory);
|
||||
int xe_xex2_load_pe(xe_xex2_ref xex);
|
||||
int xe_xex2_find_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t *library);
|
||||
|
||||
|
||||
xe_xex2_ref xe_xex2_load(Memory* memory,
|
||||
const void* addr, const size_t length,
|
||||
xe_xex2_ref xe_xex2_load(Memory *memory, const void *addr, const size_t length,
|
||||
xe_xex2_options_t options) {
|
||||
xe_xex2_ref xex = (xe_xex2_ref)xe_calloc(sizeof(xe_xex2));
|
||||
xe_ref_init((xe_ref)xex);
|
||||
|
@ -62,7 +57,8 @@ xe_xex2_ref xe_xex2_load(Memory* memory,
|
|||
xex->memory = memory;
|
||||
xex->sections = new std::vector<PESection *>();
|
||||
|
||||
XEEXPECTZERO(xe_xex2_read_header((const uint8_t*)addr, length, &xex->header));
|
||||
XEEXPECTZERO(
|
||||
xe_xex2_read_header((const uint8_t *)addr, length, &xex->header));
|
||||
|
||||
XEEXPECTZERO(xe_xex2_decrypt_key(&xex->header));
|
||||
|
||||
|
@ -127,7 +123,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
return 1;
|
||||
}
|
||||
|
||||
header->module_flags = (xe_xex2_module_flags)poly::load_and_swap<uint32_t>(p + 0x04);
|
||||
header->module_flags =
|
||||
(xe_xex2_module_flags)poly::load_and_swap<uint32_t>(p + 0x04);
|
||||
header->exe_offset = poly::load_and_swap<uint32_t>(p + 0x08);
|
||||
header->unknown0 = poly::load_and_swap<uint32_t>(p + 0x0C);
|
||||
header->certificate_offset = poly::load_and_swap<uint32_t>(p + 0x10);
|
||||
|
@ -163,24 +160,21 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
case XEX_HEADER_SYSTEM_FLAGS:
|
||||
header->system_flags = (xe_xex2_system_flags)data_offset;
|
||||
break;
|
||||
case XEX_HEADER_RESOURCE_INFO:
|
||||
{
|
||||
case XEX_HEADER_RESOURCE_INFO: {
|
||||
header->resource_info_count = (opt_header->length - 4) / 16;
|
||||
header->resource_infos = (xe_xex2_resource_info_t *)xe_calloc(
|
||||
sizeof(xe_xex2_resource_info_t) * header->resource_info_count);
|
||||
const uint8_t *ph = pp + 0x04;
|
||||
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||
auto &res = header->resource_infos[n];
|
||||
XEEXPECTZERO(xe_copy_memory(res.name,
|
||||
sizeof(res.name), ph + 0x00, 8));
|
||||
XEEXPECTZERO(
|
||||
xe_copy_memory(res.name, sizeof(res.name), ph + 0x00, 8));
|
||||
res.address = poly::load_and_swap<uint32_t>(ph + 0x08);
|
||||
res.size = poly::load_and_swap<uint32_t>(ph + 0x0C);
|
||||
ph += 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_EXECUTION_INFO:
|
||||
{
|
||||
} break;
|
||||
case XEX_HEADER_EXECUTION_INFO: {
|
||||
xe_xex2_execution_info_t *ex = &header->execution_info;
|
||||
ex->media_id = poly::load_and_swap<uint32_t>(pp + 0x00);
|
||||
ex->version.value = poly::load_and_swap<uint32_t>(pp + 0x04);
|
||||
|
@ -191,34 +185,46 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
ex->disc_number = poly::load_and_swap<uint8_t>(pp + 0x12);
|
||||
ex->disc_count = poly::load_and_swap<uint8_t>(pp + 0x13);
|
||||
ex->savegame_id = poly::load_and_swap<uint32_t>(pp + 0x14);
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_GAME_RATINGS:
|
||||
{
|
||||
} break;
|
||||
case XEX_HEADER_GAME_RATINGS: {
|
||||
xe_xex2_game_ratings_t *ratings = &header->game_ratings;
|
||||
ratings->esrb = (xe_xex2_rating_esrb_value)poly::load_and_swap<uint8_t>(pp + 0x00);
|
||||
ratings->pegi = (xe_xex2_rating_pegi_value)poly::load_and_swap<uint8_t>(pp + 0x01);
|
||||
ratings->pegifi = (xe_xex2_rating_pegi_fi_value)poly::load_and_swap<uint8_t>(pp + 0x02);
|
||||
ratings->pegipt = (xe_xex2_rating_pegi_pt_value)poly::load_and_swap<uint8_t>(pp + 0x03);
|
||||
ratings->bbfc = (xe_xex2_rating_bbfc_value)poly::load_and_swap<uint8_t>(pp + 0x04);
|
||||
ratings->cero = (xe_xex2_rating_cero_value)poly::load_and_swap<uint8_t>(pp + 0x05);
|
||||
ratings->usk = (xe_xex2_rating_usk_value)poly::load_and_swap<uint8_t>(pp + 0x06);
|
||||
ratings->oflcau = (xe_xex2_rating_oflc_au_value)poly::load_and_swap<uint8_t>(pp + 0x07);
|
||||
ratings->oflcnz = (xe_xex2_rating_oflc_nz_value)poly::load_and_swap<uint8_t>(pp + 0x08);
|
||||
ratings->kmrb = (xe_xex2_rating_kmrb_value)poly::load_and_swap<uint8_t>(pp + 0x09);
|
||||
ratings->brazil = (xe_xex2_rating_brazil_value)poly::load_and_swap<uint8_t>(pp + 0x0A);
|
||||
ratings->fpb = (xe_xex2_rating_fpb_value)poly::load_and_swap<uint8_t>(pp + 0x0B);
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_TLS_INFO:
|
||||
{
|
||||
ratings->esrb =
|
||||
(xe_xex2_rating_esrb_value)poly::load_and_swap<uint8_t>(pp + 0x00);
|
||||
ratings->pegi =
|
||||
(xe_xex2_rating_pegi_value)poly::load_and_swap<uint8_t>(pp + 0x01);
|
||||
ratings->pegifi =
|
||||
(xe_xex2_rating_pegi_fi_value)poly::load_and_swap<uint8_t>(pp +
|
||||
0x02);
|
||||
ratings->pegipt =
|
||||
(xe_xex2_rating_pegi_pt_value)poly::load_and_swap<uint8_t>(pp +
|
||||
0x03);
|
||||
ratings->bbfc =
|
||||
(xe_xex2_rating_bbfc_value)poly::load_and_swap<uint8_t>(pp + 0x04);
|
||||
ratings->cero =
|
||||
(xe_xex2_rating_cero_value)poly::load_and_swap<uint8_t>(pp + 0x05);
|
||||
ratings->usk =
|
||||
(xe_xex2_rating_usk_value)poly::load_and_swap<uint8_t>(pp + 0x06);
|
||||
ratings->oflcau =
|
||||
(xe_xex2_rating_oflc_au_value)poly::load_and_swap<uint8_t>(pp +
|
||||
0x07);
|
||||
ratings->oflcnz =
|
||||
(xe_xex2_rating_oflc_nz_value)poly::load_and_swap<uint8_t>(pp +
|
||||
0x08);
|
||||
ratings->kmrb =
|
||||
(xe_xex2_rating_kmrb_value)poly::load_and_swap<uint8_t>(pp + 0x09);
|
||||
ratings->brazil =
|
||||
(xe_xex2_rating_brazil_value)poly::load_and_swap<uint8_t>(pp +
|
||||
0x0A);
|
||||
ratings->fpb =
|
||||
(xe_xex2_rating_fpb_value)poly::load_and_swap<uint8_t>(pp + 0x0B);
|
||||
} break;
|
||||
case XEX_HEADER_TLS_INFO: {
|
||||
xe_xex2_tls_info_t *tls = &header->tls_info;
|
||||
tls->slot_count = poly::load_and_swap<uint32_t>(pp + 0x00);
|
||||
tls->raw_data_address = poly::load_and_swap<uint32_t>(pp + 0x04);
|
||||
tls->data_size = poly::load_and_swap<uint32_t>(pp + 0x08);
|
||||
tls->raw_data_size = poly::load_and_swap<uint32_t>(pp + 0x0C);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case XEX_HEADER_IMAGE_BASE_ADDRESS:
|
||||
header->exe_address = opt_header->value;
|
||||
break;
|
||||
|
@ -231,8 +237,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
case XEX_HEADER_DEFAULT_HEAP_SIZE:
|
||||
header->exe_heap_size = opt_header->value;
|
||||
break;
|
||||
case XEX_HEADER_IMPORT_LIBRARIES:
|
||||
{
|
||||
case XEX_HEADER_IMPORT_LIBRARIES: {
|
||||
const size_t max_count = poly::countof(header->import_libraries);
|
||||
size_t count = poly::load_and_swap<uint32_t>(pp + 0x08);
|
||||
assert_true(count <= max_count);
|
||||
|
@ -255,7 +260,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
library->version.value = poly::load_and_swap<uint32_t>(pp + 0x1C);
|
||||
library->min_version.value = poly::load_and_swap<uint32_t>(pp + 0x20);
|
||||
|
||||
const uint16_t name_index = poly::load_and_swap<uint16_t>(pp + 0x24) & 0xFF;
|
||||
const uint16_t name_index =
|
||||
poly::load_and_swap<uint16_t>(pp + 0x24) & 0xFF;
|
||||
for (size_t i = 0, j = 0; i < string_table_size;) {
|
||||
assert_true(j <= 0xFF);
|
||||
if (j == name_index) {
|
||||
|
@ -275,8 +281,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
}
|
||||
|
||||
library->record_count = poly::load_and_swap<uint16_t>(pp + 0x26);
|
||||
library->records = (uint32_t*)xe_calloc(
|
||||
library->record_count * sizeof(uint32_t));
|
||||
library->records =
|
||||
(uint32_t *)xe_calloc(library->record_count * sizeof(uint32_t));
|
||||
XEEXPECTNOTNULL(library->records);
|
||||
pp += 0x28;
|
||||
for (size_t i = 0; i < library->record_count; i++) {
|
||||
|
@ -284,10 +290,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
pp += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_STATIC_LIBRARIES:
|
||||
{
|
||||
} break;
|
||||
case XEX_HEADER_STATIC_LIBRARIES: {
|
||||
const size_t max_count = poly::countof(header->static_libraries);
|
||||
size_t count = (opt_header->length - 4) / 16;
|
||||
assert_true(count <= max_count);
|
||||
|
@ -311,10 +315,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
library->qfe = qfeapproval & ~0x8000;
|
||||
pp += 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_FILE_FORMAT_INFO:
|
||||
{
|
||||
} break;
|
||||
case XEX_HEADER_FILE_FORMAT_INFO: {
|
||||
xe_xex2_file_format_info_t *fmt = &header->file_format_info;
|
||||
fmt->encryption_type =
|
||||
(xe_xex2_encryption_type)poly::load_and_swap<uint16_t>(pp + 0x04);
|
||||
|
@ -325,26 +327,26 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
// TODO: XEX_COMPRESSION_NONE
|
||||
assert_always();
|
||||
break;
|
||||
case XEX_COMPRESSION_BASIC:
|
||||
{
|
||||
case XEX_COMPRESSION_BASIC: {
|
||||
xe_xex2_file_basic_compression_info_t *comp_info =
|
||||
&fmt->compression_info.basic;
|
||||
uint32_t info_size = poly::load_and_swap<uint32_t>(pp + 0x00);
|
||||
comp_info->block_count = (info_size - 8) / 8;
|
||||
comp_info->blocks = (xe_xex2_file_basic_compression_block_t*)
|
||||
xe_calloc(comp_info->block_count *
|
||||
comp_info->blocks =
|
||||
(xe_xex2_file_basic_compression_block_t *)xe_calloc(
|
||||
comp_info->block_count *
|
||||
sizeof(xe_xex2_file_basic_compression_block_t));
|
||||
XEEXPECTNOTNULL(comp_info->blocks);
|
||||
for (size_t m = 0; m < comp_info->block_count; m++) {
|
||||
xe_xex2_file_basic_compression_block_t *block =
|
||||
&comp_info->blocks[m];
|
||||
block->data_size = poly::load_and_swap<uint32_t>(pp + 0x08 + (m * 8));
|
||||
block->zero_size = poly::load_and_swap<uint32_t>(pp + 0x0C + (m * 8));
|
||||
block->data_size =
|
||||
poly::load_and_swap<uint32_t>(pp + 0x08 + (m * 8));
|
||||
block->zero_size =
|
||||
poly::load_and_swap<uint32_t>(pp + 0x0C + (m * 8));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_COMPRESSION_NORMAL:
|
||||
{
|
||||
} break;
|
||||
case XEX_COMPRESSION_NORMAL: {
|
||||
xe_xex2_file_normal_compression_info_t *comp_info =
|
||||
&fmt->compression_info.normal;
|
||||
uint32_t window_size = poly::load_and_swap<uint32_t>(pp + 0x08);
|
||||
|
@ -361,15 +363,13 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
XEEXPECTZERO(xe_copy_memory(comp_info->block_hash,
|
||||
sizeof(comp_info->block_hash),
|
||||
pp + 0x10, 20));
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case XEX_COMPRESSION_DELTA:
|
||||
// TODO: XEX_COMPRESSION_DELTA
|
||||
assert_always();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,30 +381,33 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
XEEXPECTZERO(xe_copy_memory(ldr->rsa_signature, sizeof(ldr->rsa_signature),
|
||||
pc + 0x008, 256));
|
||||
ldr->unklength = poly::load_and_swap<uint32_t>(pc + 0x108);
|
||||
ldr->image_flags = (xe_xex2_image_flags)poly::load_and_swap<uint32_t>(pc + 0x10C);
|
||||
ldr->image_flags =
|
||||
(xe_xex2_image_flags)poly::load_and_swap<uint32_t>(pc + 0x10C);
|
||||
ldr->load_address = poly::load_and_swap<uint32_t>(pc + 0x110);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->section_digest, sizeof(ldr->section_digest),
|
||||
pc + 0x114, 20));
|
||||
ldr->import_table_count = poly::load_and_swap<uint32_t>(pc + 0x128);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->import_table_digest,
|
||||
sizeof(ldr->import_table_digest),
|
||||
pc + 0x12C, 20));
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->media_id, sizeof(ldr->media_id),
|
||||
pc + 0x140, 16));
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->file_key, sizeof(ldr->file_key),
|
||||
pc + 0x150, 16));
|
||||
sizeof(ldr->import_table_digest), pc + 0x12C,
|
||||
20));
|
||||
XEEXPECTZERO(
|
||||
xe_copy_memory(ldr->media_id, sizeof(ldr->media_id), pc + 0x140, 16));
|
||||
XEEXPECTZERO(
|
||||
xe_copy_memory(ldr->file_key, sizeof(ldr->file_key), pc + 0x150, 16));
|
||||
ldr->export_table = poly::load_and_swap<uint32_t>(pc + 0x160);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->header_digest, sizeof(ldr->header_digest),
|
||||
pc + 0x164, 20));
|
||||
ldr->game_regions = (xe_xex2_region_flags)poly::load_and_swap<uint32_t>(pc + 0x178);
|
||||
ldr->media_flags = (xe_xex2_media_flags)poly::load_and_swap<uint32_t>(pc + 0x17C);
|
||||
ldr->game_regions =
|
||||
(xe_xex2_region_flags)poly::load_and_swap<uint32_t>(pc + 0x178);
|
||||
ldr->media_flags =
|
||||
(xe_xex2_media_flags)poly::load_and_swap<uint32_t>(pc + 0x17C);
|
||||
|
||||
// Section info follows loader info.
|
||||
ps = p + header->certificate_offset + 0x180;
|
||||
header->section_count = poly::load_and_swap<uint32_t>(ps + 0x000);
|
||||
ps += 4;
|
||||
header->sections = (xe_xex2_section_t*)xe_calloc(
|
||||
header->section_count * sizeof(xe_xex2_section_t));
|
||||
header->sections = (xe_xex2_section_t *)xe_calloc(header->section_count *
|
||||
sizeof(xe_xex2_section_t));
|
||||
XEEXPECTNOTNULL(header->sections);
|
||||
for (size_t n = 0; n < header->section_count; n++) {
|
||||
xe_xex2_section_t *section = &header->sections[n];
|
||||
|
@ -424,12 +427,10 @@ XECLEANUP:
|
|||
int xe_xex2_decrypt_key(xe_xex2_header_t *header) {
|
||||
const static uint8_t xe_xex2_retail_key[16] = {
|
||||
0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3,
|
||||
0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91
|
||||
};
|
||||
0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91};
|
||||
const static uint8_t xe_xex2_devkit_key[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
// Guess key based on file info.
|
||||
// TODO: better way to finding out which key to use?
|
||||
|
@ -443,8 +444,7 @@ int xe_xex2_decrypt_key(xe_xex2_header_t *header) {
|
|||
// Decrypt the header key.
|
||||
uint32_t rk[4 * (MAXNR + 1)];
|
||||
int32_t Nr = rijndaelKeySetupDec(rk, xexkey, 128);
|
||||
rijndaelDecrypt(rk, Nr,
|
||||
header->loader_info.file_key, header->session_key);
|
||||
rijndaelDecrypt(rk, Nr, header->loader_info.file_key, header->session_key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -455,14 +455,14 @@ typedef struct mspack_memory_file_t {
|
|||
off_t buffer_size;
|
||||
off_t offset;
|
||||
} mspack_memory_file;
|
||||
mspack_memory_file *mspack_memory_open(struct mspack_system *sys,
|
||||
void* buffer, const size_t buffer_size) {
|
||||
mspack_memory_file *mspack_memory_open(struct mspack_system *sys, void *buffer,
|
||||
const size_t buffer_size) {
|
||||
assert_true(buffer_size < INT_MAX);
|
||||
if (buffer_size >= INT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
mspack_memory_file *memfile = (mspack_memory_file*)xe_calloc(
|
||||
sizeof(mspack_memory_file));
|
||||
mspack_memory_file *memfile =
|
||||
(mspack_memory_file *)xe_calloc(sizeof(mspack_memory_file));
|
||||
if (!memfile) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -500,15 +500,13 @@ int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) {
|
|||
void *mspack_memory_alloc(struct mspack_system *sys, size_t chars) {
|
||||
return xe_calloc(chars);
|
||||
}
|
||||
void mspack_memory_free(void *ptr) {
|
||||
xe_free(ptr);
|
||||
}
|
||||
void mspack_memory_free(void *ptr) { xe_free(ptr); }
|
||||
void mspack_memory_copy(void *src, void *dest, size_t chars) {
|
||||
xe_copy_memory(dest, chars, src, chars);
|
||||
}
|
||||
struct mspack_system *mspack_memory_sys_create() {
|
||||
struct mspack_system *sys = (struct mspack_system *)xe_calloc(
|
||||
sizeof(struct mspack_system));
|
||||
struct mspack_system *sys =
|
||||
(struct mspack_system *)xe_calloc(sizeof(struct mspack_system));
|
||||
if (!sys) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -519,9 +517,7 @@ struct mspack_system *mspack_memory_sys_create() {
|
|||
sys->copy = mspack_memory_copy;
|
||||
return sys;
|
||||
}
|
||||
void mspack_memory_sys_destroy(struct mspack_system *sys) {
|
||||
xe_free(sys);
|
||||
}
|
||||
void mspack_memory_sys_destroy(struct mspack_system *sys) { xe_free(sys); }
|
||||
|
||||
void xe_xex2_decrypt_buffer(const uint8_t *session_key,
|
||||
const uint8_t *input_buffer,
|
||||
|
@ -546,17 +542,15 @@ void xe_xex2_decrypt_buffer(const uint8_t *session_key,
|
|||
|
||||
int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
Memory* memory) {
|
||||
const size_t xex_length, Memory *memory) {
|
||||
// Allocate in-place the XEX memory.
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
size_t uncompressed_size = exe_length;
|
||||
uint32_t alloc_result = (uint32_t)memory->HeapAlloc(
|
||||
header->exe_address, uncompressed_size,
|
||||
MEMORY_FLAG_ZERO);
|
||||
header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO);
|
||||
if (!alloc_result) {
|
||||
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
|
||||
header->exe_address, uncompressed_size);
|
||||
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address,
|
||||
uncompressed_size);
|
||||
return 2;
|
||||
}
|
||||
uint8_t *buffer = memory->Translate(header->exe_address);
|
||||
|
@ -598,11 +592,10 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
|
|||
|
||||
// Allocate in-place the XEX memory.
|
||||
uint32_t alloc_result = (uint32_t)memory->HeapAlloc(
|
||||
header->exe_address, uncompressed_size,
|
||||
MEMORY_FLAG_ZERO);
|
||||
header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO);
|
||||
if (!alloc_result) {
|
||||
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
|
||||
header->exe_address, uncompressed_size);
|
||||
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address,
|
||||
uncompressed_size);
|
||||
XEFAIL();
|
||||
}
|
||||
uint8_t *buffer = memory->Translate(header->exe_address);
|
||||
|
@ -621,8 +614,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
|
|||
XEEXPECTZERO(xe_copy_memory(d, uncompressed_size - (d - buffer), p,
|
||||
exe_length - (p - source_buffer)));
|
||||
break;
|
||||
case XEX_ENCRYPTION_NORMAL:
|
||||
{
|
||||
case XEX_ENCRYPTION_NORMAL: {
|
||||
const uint8_t *ct = p;
|
||||
uint8_t *pt = d;
|
||||
for (size_t n = 0; n < data_size; n += 16, ct += 16, pt += 16) {
|
||||
|
@ -635,8 +627,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
|
|||
ivec[i] = ct[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
default:
|
||||
assert_always();
|
||||
return 1;
|
||||
|
@ -654,8 +645,7 @@ XECLEANUP:
|
|||
|
||||
int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
Memory* memory) {
|
||||
const size_t xex_length, Memory *memory) {
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
const uint8_t *exe_buffer = (const uint8_t *)xex_addr + header->exe_offset;
|
||||
|
||||
|
@ -736,11 +726,10 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
|
|||
|
||||
// Allocate in-place the XEX memory.
|
||||
uint32_t alloc_result = (uint32_t)memory->HeapAlloc(
|
||||
header->exe_address, uncompressed_size,
|
||||
MEMORY_FLAG_ZERO);
|
||||
header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO);
|
||||
if (!alloc_result) {
|
||||
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.",
|
||||
header->exe_address, uncompressed_size);
|
||||
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address,
|
||||
uncompressed_size);
|
||||
result_code = 2;
|
||||
XEFAIL();
|
||||
}
|
||||
|
@ -749,18 +738,15 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
|
|||
// Setup decompressor and decompress.
|
||||
sys = mspack_memory_sys_create();
|
||||
XEEXPECTNOTNULL(sys);
|
||||
lzxsrc = mspack_memory_open(sys, (void*)compress_buffer, d - compress_buffer);
|
||||
lzxsrc =
|
||||
mspack_memory_open(sys, (void *)compress_buffer, d - compress_buffer);
|
||||
XEEXPECTNOTNULL(lzxsrc);
|
||||
lzxdst = mspack_memory_open(sys, buffer, uncompressed_size);
|
||||
XEEXPECTNOTNULL(lzxdst);
|
||||
lzxd = lzxd_init(
|
||||
sys,
|
||||
(struct mspack_file *)lzxsrc,
|
||||
(struct mspack_file *)lzxdst,
|
||||
header->file_format_info.compression_info.normal.window_bits,
|
||||
0,
|
||||
32768,
|
||||
(off_t)header->loader_info.image_size);
|
||||
lzxd =
|
||||
lzxd_init(sys, (struct mspack_file *)lzxsrc, (struct mspack_file *)lzxdst,
|
||||
header->file_format_info.compression_info.normal.window_bits, 0,
|
||||
32768, (off_t)header->loader_info.image_size);
|
||||
XEEXPECTNOTNULL(lzxd);
|
||||
XEEXPECTZERO(lzxd_decompress(lzxd, (off_t)header->loader_info.image_size));
|
||||
|
||||
|
@ -796,14 +782,14 @@ int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
|
|||
const xe_xex2_header_t *header = &xex->header;
|
||||
switch (header->file_format_info.compression_type) {
|
||||
case XEX_COMPRESSION_NONE:
|
||||
return xe_xex2_read_image_uncompressed(
|
||||
header, xex_addr, xex_length, memory);
|
||||
return xe_xex2_read_image_uncompressed(header, xex_addr, xex_length,
|
||||
memory);
|
||||
case XEX_COMPRESSION_BASIC:
|
||||
return xe_xex2_read_image_basic_compressed(
|
||||
header, xex_addr, xex_length, memory);
|
||||
return xe_xex2_read_image_basic_compressed(header, xex_addr, xex_length,
|
||||
memory);
|
||||
case XEX_COMPRESSION_NORMAL:
|
||||
return xe_xex2_read_image_compressed(
|
||||
header, xex_addr, xex_length, memory);
|
||||
return xe_xex2_read_image_compressed(header, xex_addr, xex_length,
|
||||
memory);
|
||||
default:
|
||||
assert_always();
|
||||
return 1;
|
||||
|
@ -879,8 +865,8 @@ int xe_xex2_load_pe(xe_xex2_ref xex) {
|
|||
sechdr = IMAGE_FIRST_SECTION(nthdr);
|
||||
for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) {
|
||||
PESection *section = (PESection *)xe_calloc(sizeof(PESection));
|
||||
xe_copy_memory(section->name, sizeof(section->name),
|
||||
sechdr->Name, sizeof(sechdr->Name));
|
||||
xe_copy_memory(section->name, sizeof(section->name), sechdr->Name,
|
||||
sizeof(sechdr->Name));
|
||||
section->name[8] = 0;
|
||||
section->raw_address = sechdr->PointerToRawData;
|
||||
section->raw_size = sechdr->SizeOfRawData;
|
||||
|
@ -957,22 +943,18 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex,
|
|||
// assert_true(library_index == ((value >> 16) & 0xFF));
|
||||
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
{
|
||||
case 0x00: {
|
||||
xe_xex2_import_info_t *info = &infos[i++];
|
||||
info->ordinal = value & 0xFFFF;
|
||||
info->value_address = record;
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
{
|
||||
} break;
|
||||
case 0x01: {
|
||||
// Thunk for previous record.
|
||||
assert_true(i > 0);
|
||||
xe_xex2_import_info_t *info = &infos[i - 1];
|
||||
assert_true(info->ordinal == (value & 0xFFFF));
|
||||
info->thunk_address = record;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
default:
|
||||
// assert_always();
|
||||
break;
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
#include <xenia/core.h>
|
||||
#include <xenia/kernel/util/xex2_info.h>
|
||||
|
||||
typedef struct {
|
||||
int reserved;
|
||||
} xe_xex2_options_t;
|
||||
typedef struct { int reserved; } xe_xex2_options_t;
|
||||
|
||||
struct xe_xex2;
|
||||
typedef struct xe_xex2* xe_xex2_ref;
|
||||
|
@ -45,9 +43,8 @@ public:
|
|||
uint32_t flags; // kXEPESection*
|
||||
};
|
||||
|
||||
xe_xex2_ref xe_xex2_load(xe::Memory* memory,
|
||||
const void* addr, const size_t length,
|
||||
xe_xex2_options_t options);
|
||||
xe_xex2_ref xe_xex2_load(xe::Memory* memory, const void* addr,
|
||||
const size_t length, xe_xex2_options_t options);
|
||||
xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex);
|
||||
void xe_xex2_release(xe_xex2_ref xex);
|
||||
|
||||
|
@ -59,5 +56,4 @@ int xe_xex2_get_import_infos(xe_xex2_ref xex,
|
|||
xe_xex2_import_info_t** out_import_infos,
|
||||
size_t* out_import_info_count);
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_UTIL_XEX2_H_
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
XEX_HEADER_RESOURCE_INFO = 0x000002FF,
|
||||
XEX_HEADER_FILE_FORMAT_INFO = 0x000003FF,
|
||||
|
@ -456,5 +455,4 @@ typedef struct {
|
|||
xe_xex2_section_t* sections;
|
||||
} xe_xex2_header_t;
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XEX2_INFO_H_
|
||||
|
|
|
@ -14,20 +14,15 @@
|
|||
#include <xenia/kernel/xam_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XamContentGetLicenseMask_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamContentGetLicenseMask_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t mask_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XamContentGetLicenseMask(%.8X, %.8X)",
|
||||
mask_ptr,
|
||||
overlapped_ptr);
|
||||
XELOGD("XamContentGetLicenseMask(%.8X, %.8X)", mask_ptr, overlapped_ptr);
|
||||
|
||||
// Arcade games seem to call this and check the result mask for random bits.
|
||||
// If we fail, the games seem to use a hardcoded mask, which is likely trial.
|
||||
|
@ -42,10 +37,9 @@ SHIM_CALL XamContentGetLicenseMask_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// http://gameservice.googlecode.com/svn-history/r14/trunk/ContentManager.cpp
|
||||
SHIM_CALL XamContentCreateEnumerator_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamContentCreateEnumerator_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t arg1 = SHIM_GET_ARG_32(1);
|
||||
uint32_t arg2 = SHIM_GET_ARG_32(2);
|
||||
|
@ -54,8 +48,7 @@ SHIM_CALL XamContentCreateEnumerator_shim(
|
|||
uint32_t arg5 = SHIM_GET_ARG_32(5);
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(6);
|
||||
|
||||
XELOGD(
|
||||
"XamContentCreateEnumerator(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
XELOGD("XamContentCreateEnumerator(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
arg0, arg1, arg2, arg3, arg4, arg5, handle_ptr);
|
||||
|
||||
SHIM_SET_MEM_32(handle_ptr, X_INVALID_HANDLE_VALUE);
|
||||
|
@ -63,9 +56,8 @@ SHIM_CALL XamContentCreateEnumerator_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_NO_MORE_FILES);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamShowDeviceSelectorUI_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamShowDeviceSelectorUI_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t arg1 = SHIM_GET_ARG_32(1);
|
||||
uint32_t arg2 = SHIM_GET_ARG_32(2);
|
||||
|
@ -73,19 +65,16 @@ SHIM_CALL XamShowDeviceSelectorUI_shim(
|
|||
uint32_t arg4 = SHIM_GET_ARG_32(4);
|
||||
uint32_t arg5 = SHIM_GET_ARG_32(5);
|
||||
|
||||
XELOGD(
|
||||
"XamShowDeviceSelectorUI(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
arg0, arg1, arg2, arg3, arg4, arg5);
|
||||
XELOGD("XamShowDeviceSelectorUI(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", arg0,
|
||||
arg1, arg2, arg3, arg4, arg5);
|
||||
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterContentExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterContentExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamContentGetLicenseMask, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamContentCreateEnumerator, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamShowDeviceSelectorUI, state);
|
||||
|
|
|
@ -16,13 +16,10 @@
|
|||
#include <xenia/kernel/util/shim_utils.h>
|
||||
#include <xenia/kernel/util/xex2.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XamGetSystemVersion_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamGetSystemVersion_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("XamGetSystemVersion()");
|
||||
// eh, just picking one. If we go too low we may break new games, but
|
||||
// this value seems to be used for conditionally loading symbols and if
|
||||
|
@ -32,9 +29,7 @@ SHIM_CALL XamGetSystemVersion_shim(
|
|||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XGetAVPack_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XGetAVPack_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
// DWORD
|
||||
// Not sure what the values are for this, but 6 is VGA.
|
||||
// Other likely values are 3/4/8 for HDMI or something.
|
||||
|
@ -43,17 +38,13 @@ SHIM_CALL XGetAVPack_shim(
|
|||
SHIM_SET_RETURN_64(6);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XGetGameRegion_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XGetGameRegion_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("XGetGameRegion()");
|
||||
|
||||
SHIM_SET_RETURN_64(XEX_REGION_ALL);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XGetLanguage_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XGetLanguage_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("XGetLanguage()");
|
||||
|
||||
uint32_t desired_language = X_LANGUAGE_ENGLISH;
|
||||
|
@ -71,36 +62,28 @@ SHIM_CALL XGetLanguage_shim(
|
|||
SHIM_SET_RETURN_64(desired_language);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamLoaderGetLaunchDataSize_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamLoaderGetLaunchDataSize_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t size_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XamLoaderGetLaunchDataSize(%.8X)",
|
||||
size_ptr);
|
||||
XELOGD("XamLoaderGetLaunchDataSize(%.8X)", size_ptr);
|
||||
|
||||
SHIM_SET_MEM_32(size_ptr, 0);
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamLoaderGetLaunchData_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamLoaderGetLaunchData_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t buffer_size = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XamLoaderGetLaunchData(%.8X, %d)",
|
||||
buffer_ptr, buffer_size);
|
||||
XELOGD("XamLoaderGetLaunchData(%.8X, %d)", buffer_ptr, buffer_size);
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamEnumerate_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamEnumerate_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t zero = SHIM_GET_ARG_32(1);
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -108,14 +91,11 @@ SHIM_CALL XamEnumerate_shim(
|
|||
uint32_t item_count_ptr = SHIM_GET_ARG_32(4);
|
||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(5);
|
||||
|
||||
XELOGD(
|
||||
"XamEnumerate(%.8X, %d, %d, %.8X, %d, %.8X, %.8X)",
|
||||
handle, zero, buffer_ptr, buffer_length, item_count_ptr,
|
||||
overlapped_ptr);
|
||||
XELOGD("XamEnumerate(%.8X, %d, %d, %.8X, %d, %.8X, %.8X)", handle, zero,
|
||||
buffer_ptr, buffer_length, item_count_ptr, overlapped_ptr);
|
||||
|
||||
XEnumerator* e = nullptr;
|
||||
if (XFAILED(state->object_table()->GetObject(
|
||||
handle, (XObject**)&e))) {
|
||||
if (XFAILED(state->object_table()->GetObject(handle, (XObject**)&e))) {
|
||||
SHIM_SET_RETURN_64(X_ERROR_INVALID_HANDLE);
|
||||
return;
|
||||
}
|
||||
|
@ -135,13 +115,11 @@ SHIM_CALL XamEnumerate_shim(
|
|||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterInfoExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterInfoExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamGetSystemVersion, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XGetAVPack, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XGetGameRegion, state);
|
||||
|
|
|
@ -16,52 +16,39 @@
|
|||
#include <xenia/kernel/xam_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using xe::hid::InputSystem;
|
||||
|
||||
|
||||
SHIM_CALL XamResetInactivity_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamResetInactivity_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XamResetInactivity(%d)",
|
||||
unk);
|
||||
XELOGD("XamResetInactivity(%d)", unk);
|
||||
|
||||
// Result ignored.
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamEnableInactivityProcessing_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamEnableInactivityProcessing_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t zero = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamEnableInactivityProcessing(%d, %d)",
|
||||
zero,
|
||||
unk);
|
||||
XELOGD("XamEnableInactivityProcessing(%d, %d)", zero, unk);
|
||||
|
||||
// Expects 0.
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetcapabilities(v=vs.85).aspx
|
||||
SHIM_CALL XamInputGetCapabilities_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamInputGetCapabilities_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t flags = SHIM_GET_ARG_32(1);
|
||||
uint32_t caps_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamInputGetCapabilities(%d, %.8X, %.8X)",
|
||||
user_index,
|
||||
flags,
|
||||
XELOGD("XamInputGetCapabilities(%d, %.8X, %.8X)", user_index, flags,
|
||||
caps_ptr);
|
||||
|
||||
if (!caps_ptr) {
|
||||
|
@ -79,19 +66,13 @@ SHIM_CALL XamInputGetCapabilities_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetstate(v=vs.85).aspx
|
||||
SHIM_CALL XamInputGetState_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamInputGetState_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t one = SHIM_GET_ARG_32(1);
|
||||
uint32_t state_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamInputGetState(%d, %.8X, %.8X)",
|
||||
user_index,
|
||||
one,
|
||||
state_ptr);
|
||||
XELOGD("XamInputGetState(%d, %.8X, %.8X)", user_index, one, state_ptr);
|
||||
|
||||
// Games call this with a NULL state ptr, probably as a query.
|
||||
|
||||
|
@ -107,19 +88,13 @@ SHIM_CALL XamInputGetState_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputsetstate(v=vs.85).aspx
|
||||
SHIM_CALL XamInputSetState_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamInputSetState_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk = SHIM_GET_ARG_32(1);
|
||||
uint32_t vibration_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamInputSetState(%d, %.8X, %.8X)",
|
||||
user_index,
|
||||
unk,
|
||||
vibration_ptr);
|
||||
XELOGD("XamInputSetState(%d, %.8X, %.8X)", user_index, unk, vibration_ptr);
|
||||
|
||||
if (!vibration_ptr) {
|
||||
SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS);
|
||||
|
@ -133,10 +108,8 @@ SHIM_CALL XamInputSetState_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetkeystroke(v=vs.85).aspx
|
||||
SHIM_CALL XamInputGetKeystroke_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamInputGetKeystroke_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t flags = SHIM_GET_ARG_32(1);
|
||||
uint32_t keystroke_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -145,10 +118,7 @@ SHIM_CALL XamInputGetKeystroke_shim(
|
|||
// user index = index or XUSER_INDEX_ANY
|
||||
// flags = XINPUT_FLAG_GAMEPAD (| _ANYUSER | _ANYDEVICE)
|
||||
|
||||
XELOGD(
|
||||
"XamInputGetKeystroke(%d, %.8X, %.8X)",
|
||||
user_index,
|
||||
flags,
|
||||
XELOGD("XamInputGetKeystroke(%d, %.8X, %.8X)", user_index, flags,
|
||||
keystroke_ptr);
|
||||
|
||||
if (!keystroke_ptr) {
|
||||
|
@ -166,21 +136,17 @@ SHIM_CALL XamInputGetKeystroke_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
// Same as non-ex, just takes a pointer to user index.
|
||||
SHIM_CALL XamInputGetKeystrokeEx_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamInputGetKeystrokeEx_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t user_index_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t flags = SHIM_GET_ARG_32(1);
|
||||
uint32_t keystroke_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
uint32_t user_index = SHIM_MEM_32(user_index_ptr);
|
||||
|
||||
XELOGD(
|
||||
"XamInputGetKeystroke(%.8X(%.d), %.8X, %.8X)",
|
||||
user_index_ptr, user_index,
|
||||
flags,
|
||||
keystroke_ptr);
|
||||
XELOGD("XamInputGetKeystroke(%.8X(%.d), %.8X, %.8X)", user_index_ptr,
|
||||
user_index, flags, keystroke_ptr);
|
||||
|
||||
if (!keystroke_ptr) {
|
||||
SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS);
|
||||
|
@ -198,18 +164,13 @@ SHIM_CALL XamInputGetKeystrokeEx_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserGetDeviceContext_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserGetDeviceContext_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk = SHIM_GET_ARG_32(1);
|
||||
uint32_t out_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamUserGetDeviceContext(%d, %d, %.8X)",
|
||||
user_index,
|
||||
unk,
|
||||
out_ptr);
|
||||
XELOGD("XamUserGetDeviceContext(%d, %d, %.8X)", user_index, unk, out_ptr);
|
||||
|
||||
// Games check the result - usually with some masking.
|
||||
// If this function fails they assume zero, so let's fail AND
|
||||
|
@ -222,13 +183,11 @@ SHIM_CALL XamUserGetDeviceContext_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterInputExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterInputExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamResetInactivity, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamEnableInactivityProcessing, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamInputGetCapabilities, state);
|
||||
|
|
|
@ -14,21 +14,19 @@
|
|||
#include <xenia/kernel/kernel_state.h>
|
||||
#include <xenia/kernel/xam_private.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) :
|
||||
XKernelModule(kernel_state, "xe:\\xam.xex") {
|
||||
XamModule::XamModule(Emulator* emulator, KernelState* kernel_state)
|
||||
: XKernelModule(kernel_state, "xe:\\xam.xex") {
|
||||
// Build the export table used for resolution.
|
||||
#include <xenia/kernel/util/export_table_pre.inc>
|
||||
static KernelExport xam_export_table[] = {
|
||||
#include <xenia/kernel/xam_table.inc>
|
||||
};
|
||||
#include <xenia/kernel/util/export_table_post.inc>
|
||||
export_resolver_->RegisterTable(
|
||||
"xam.xex", xam_export_table, poly::countof(xam_export_table));
|
||||
export_resolver_->RegisterTable("xam.xex", xam_export_table,
|
||||
poly::countof(xam_export_table));
|
||||
|
||||
// Register all exported functions.
|
||||
xam::RegisterContentExports(export_resolver_, kernel_state);
|
||||
|
@ -43,8 +41,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) :
|
|||
xam::RegisterVoiceExports(export_resolver_, kernel_state);
|
||||
}
|
||||
|
||||
XamModule::~XamModule() {
|
||||
}
|
||||
XamModule::~XamModule() {}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/kernel/xam_ordinals.h>
|
||||
#include <xenia/kernel/objects/xkernel_module.h>
|
||||
|
@ -20,7 +19,6 @@
|
|||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XamModule : public XKernelModule {
|
||||
public:
|
||||
XamModule(Emulator* emulator, KernelState* kernel_state);
|
||||
|
@ -29,9 +27,7 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XAM_H_
|
||||
|
|
|
@ -15,62 +15,50 @@
|
|||
#include <xenia/kernel/objects/xevent.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XMsgInProcessCall_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XMsgInProcessCall_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t app = SHIM_GET_ARG_32(0);
|
||||
uint32_t message = SHIM_GET_ARG_32(1);
|
||||
uint32_t arg1 = SHIM_GET_ARG_32(2);
|
||||
uint32_t arg2 = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD(
|
||||
"XMsgInProcessCall(%.8X, %.8X, %.8X, %.8X)",
|
||||
app, message, arg1, arg2);
|
||||
XELOGD("XMsgInProcessCall(%.8X, %.8X, %.8X, %.8X)", app, message, arg1, arg2);
|
||||
|
||||
auto result = state->app_manager()->DispatchMessageSync(
|
||||
app, message, arg1, arg2);
|
||||
auto result =
|
||||
state->app_manager()->DispatchMessageSync(app, message, arg1, arg2);
|
||||
if (result == X_ERROR_NOT_FOUND) {
|
||||
XELOGE("XMsgInProcessCall: app %.8X undefined", app);
|
||||
}
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XMsgStartIORequest_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XMsgStartIORequest_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t app = SHIM_GET_ARG_32(0);
|
||||
uint32_t message = SHIM_GET_ARG_32(1);
|
||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t buffer = SHIM_GET_ARG_32(3);
|
||||
uint32_t buffer_length = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)",
|
||||
app, message, overlapped_ptr, buffer, buffer_length);
|
||||
XELOGD("XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", app, message,
|
||||
overlapped_ptr, buffer, buffer_length);
|
||||
|
||||
assert_zero(overlapped_ptr);
|
||||
|
||||
auto result = state->app_manager()->DispatchMessageAsync(
|
||||
app, message, buffer, buffer_length);
|
||||
auto result = state->app_manager()->DispatchMessageAsync(app, message, buffer,
|
||||
buffer_length);
|
||||
if (result == X_ERROR_NOT_FOUND) {
|
||||
XELOGE("XMsgStartIORequest: app %.8X undefined", app);
|
||||
}
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XMsgCancelIORequest_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XMsgCancelIORequest_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t wait = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XMsgCancelIORequest(%.8X, %d)",
|
||||
overlapped_ptr, wait);
|
||||
XELOGD("XMsgCancelIORequest(%.8X, %d)", overlapped_ptr, wait);
|
||||
|
||||
X_HANDLE event_handle = XOverlappedGetEvent(SHIM_MEM_ADDR(overlapped_ptr));
|
||||
if (event_handle && wait) {
|
||||
|
@ -85,13 +73,11 @@ SHIM_CALL XMsgCancelIORequest_shim(
|
|||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterMsgExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterMsgExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state);
|
||||
|
|
|
@ -16,48 +16,33 @@
|
|||
#include <xenia/kernel/xam_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL NetDll_XNetStartup_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_XNetStartup_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t params_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"NetDll_XNetStartup(%d, %.8X)",
|
||||
arg0,
|
||||
params_ptr);
|
||||
XELOGD("NetDll_XNetStartup(%d, %.8X)", arg0, params_ptr);
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_XNetCleanup_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_XNetCleanup_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t params_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"NetDll_XNetCleanup(%d, %.8X)",
|
||||
arg0,
|
||||
params_ptr);
|
||||
XELOGD("NetDll_XNetCleanup(%d, %.8X)", arg0, params_ptr);
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_XNetRandom_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_XNetRandom_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t length = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"NetDll_XNetRandom(%d, %.8X, %d)",
|
||||
arg0,
|
||||
buffer_ptr,
|
||||
length);
|
||||
XELOGD("NetDll_XNetRandom(%d, %.8X, %d)", arg0, buffer_ptr, length);
|
||||
|
||||
// For now, constant values.
|
||||
// This makes replicating things easier.
|
||||
|
@ -66,17 +51,12 @@ SHIM_CALL NetDll_XNetRandom_shim(
|
|||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_WSAStartup_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_WSAStartup_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t version = SHIM_GET_ARG_16(1);
|
||||
uint32_t data_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"NetDll_WSAStartup(%d, %.4X, %.8X)",
|
||||
arg0,
|
||||
version,
|
||||
data_ptr);
|
||||
XELOGD("NetDll_WSAStartup(%d, %.4X, %.8X)", arg0, version, data_ptr);
|
||||
|
||||
if (data_ptr) {
|
||||
SHIM_SET_MEM_16(data_ptr + 0x000, version);
|
||||
|
@ -94,109 +74,76 @@ SHIM_CALL NetDll_WSAStartup_shim(
|
|||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_WSAGetLastError_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_WSAGetLastError_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
XELOGD("NetDll_WSAGetLastError()");
|
||||
SHIM_SET_RETURN_32(10093L); // WSANOTINITIALISED
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_XNetGetTitleXnAddr_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_XNetGetTitleXnAddr_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t arg1 = SHIM_GET_ARG_32(1);
|
||||
XELOGD(
|
||||
"NetDll_XNetGetTitleXnAddr(%d, %.8X)",
|
||||
arg0,
|
||||
arg1);
|
||||
XELOGD("NetDll_XNetGetTitleXnAddr(%d, %.8X)", arg0, arg1);
|
||||
SHIM_SET_RETURN_32(0x00000001);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_XNetGetEthernetLinkStatus_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_XNetGetEthernetLinkStatus_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
// Games seem to call this before *Startup. If we return 0, they don't even
|
||||
// try.
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
XELOGD(
|
||||
"NetDll_XNetGetEthernetLinkStatus(%d)",
|
||||
arg0);
|
||||
XELOGD("NetDll_XNetGetEthernetLinkStatus(%d)", arg0);
|
||||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_inet_addr_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_inet_addr_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t cp_ptr = SHIM_GET_ARG_32(0);
|
||||
XELOGD(
|
||||
"NetDll_inet_addr(%.8X)",
|
||||
cp_ptr);
|
||||
XELOGD("NetDll_inet_addr(%.8X)", cp_ptr);
|
||||
SHIM_SET_RETURN_32(0xFFFFFFFF); // X_INADDR_NONE
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_socket_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_socket_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t af = SHIM_GET_ARG_32(1);
|
||||
uint32_t type = SHIM_GET_ARG_32(2);
|
||||
uint32_t protocol = SHIM_GET_ARG_32(3);
|
||||
XELOGD(
|
||||
"NetDll_socket(%d, %d, %d, %d)",
|
||||
arg0,
|
||||
af,
|
||||
type,
|
||||
protocol);
|
||||
XELOGD("NetDll_socket(%d, %d, %d, %d)", arg0, af, type, protocol);
|
||||
SHIM_SET_RETURN_32(X_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_setsockopt_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_setsockopt_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t socket_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t level = SHIM_GET_ARG_32(2);
|
||||
uint32_t optname = SHIM_GET_ARG_32(3);
|
||||
uint32_t optval_ptr = SHIM_GET_ARG_32(4);
|
||||
uint32_t optlen = SHIM_GET_ARG_32(5);
|
||||
XELOGD(
|
||||
"NetDll_setsockopt(%d, %.8X, %d, %d, %.8X, %d)",
|
||||
arg0,
|
||||
socket_ptr,
|
||||
level,
|
||||
optname,
|
||||
optval_ptr,
|
||||
optlen);
|
||||
XELOGD("NetDll_setsockopt(%d, %.8X, %d, %d, %.8X, %d)", arg0, socket_ptr,
|
||||
level, optname, optval_ptr, optlen);
|
||||
SHIM_SET_RETURN_32(X_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_connect_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_connect_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t socket_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t sockaddr_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t namelen = SHIM_GET_ARG_32(2);
|
||||
XELOGD(
|
||||
"NetDll_connect(%.8X, %.8X, %d)",
|
||||
socket_ptr,
|
||||
sockaddr_ptr,
|
||||
namelen);
|
||||
XELOGD("NetDll_connect(%.8X, %.8X, %d)", socket_ptr, sockaddr_ptr, namelen);
|
||||
SHIM_SET_RETURN_32(X_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_recv_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_recv_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t socket_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t buf_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t len = SHIM_GET_ARG_32(3);
|
||||
uint32_t flags = SHIM_GET_ARG_32(4);
|
||||
XELOGD(
|
||||
"NetDll_recv(%d, %.8X, %.8X, %d, %d)",
|
||||
arg0,
|
||||
socket_ptr,
|
||||
buf_ptr,
|
||||
len,
|
||||
XELOGD("NetDll_recv(%d, %.8X, %.8X, %d, %d)", arg0, socket_ptr, buf_ptr, len,
|
||||
flags);
|
||||
SHIM_SET_RETURN_32(X_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_recvfrom_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_recvfrom_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t socket_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t buf_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -204,42 +151,27 @@ SHIM_CALL NetDll_recvfrom_shim(
|
|||
uint32_t flags = SHIM_GET_ARG_32(4);
|
||||
uint32_t from_ptr = SHIM_GET_ARG_32(5);
|
||||
uint32_t fromlen_ptr = SHIM_GET_ARG_32(6);
|
||||
XELOGD(
|
||||
"NetDll_recvfrom(%d, %.8X, %.8X, %d, %d, %.8X, %.8X)",
|
||||
arg0,
|
||||
socket_ptr,
|
||||
buf_ptr,
|
||||
len,
|
||||
flags,
|
||||
from_ptr,
|
||||
fromlen_ptr);
|
||||
XELOGD("NetDll_recvfrom(%d, %.8X, %.8X, %d, %d, %.8X, %.8X)", arg0,
|
||||
socket_ptr, buf_ptr, len, flags, from_ptr, fromlen_ptr);
|
||||
SHIM_SET_RETURN_32(X_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
SHIM_CALL NetDll_send_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NetDll_send_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t socket_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t buf_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t len = SHIM_GET_ARG_32(3);
|
||||
uint32_t flags = SHIM_GET_ARG_32(4);
|
||||
XELOGD(
|
||||
"NetDll_send(%d,%.8X, %.8X, %d, %d)",
|
||||
arg0,
|
||||
socket_ptr,
|
||||
buf_ptr,
|
||||
len,
|
||||
XELOGD("NetDll_send(%d,%.8X, %.8X, %d, %d)", arg0, socket_ptr, buf_ptr, len,
|
||||
flags);
|
||||
SHIM_SET_RETURN_32(X_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterNetExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterNetExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", NetDll_XNetStartup, state);
|
||||
SHIM_SET_MAPPING("xam.xex", NetDll_XNetCleanup, state);
|
||||
SHIM_SET_MAPPING("xam.xex", NetDll_XNetRandom, state);
|
||||
|
|
|
@ -15,20 +15,15 @@
|
|||
#include <xenia/kernel/objects/xnotify_listener.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XamNotifyCreateListener_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamNotifyCreateListener_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint64_t mask = SHIM_GET_ARG_64(0);
|
||||
uint32_t one = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XamNotifyCreateListener(%.8llX, %d)",
|
||||
mask,
|
||||
one);
|
||||
XELOGD("XamNotifyCreateListener(%.8llX, %d)", mask, one);
|
||||
|
||||
// r4=1 may indicate user process?
|
||||
|
||||
|
@ -42,20 +37,14 @@ SHIM_CALL XamNotifyCreateListener_shim(
|
|||
SHIM_SET_RETURN_64(handle);
|
||||
}
|
||||
|
||||
|
||||
// http://ffplay360.googlecode.com/svn/Test/Common/AtgSignIn.cpp
|
||||
SHIM_CALL XNotifyGetNext_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XNotifyGetNext_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t match_id = SHIM_GET_ARG_32(1);
|
||||
uint32_t id_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t param_ptr = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD(
|
||||
"XNotifyGetNext(%.8X, %.8X, %.8X, %.8X)",
|
||||
handle,
|
||||
match_id,
|
||||
id_ptr,
|
||||
XELOGD("XNotifyGetNext(%.8X, %.8X, %.8X, %.8X)", handle, match_id, id_ptr,
|
||||
param_ptr);
|
||||
|
||||
if (!handle) {
|
||||
|
@ -65,8 +54,7 @@ SHIM_CALL XNotifyGetNext_shim(
|
|||
|
||||
// Grab listener.
|
||||
XNotifyListener* listener = NULL;
|
||||
if (XFAILED(state->object_table()->GetObject(
|
||||
handle, (XObject**)&listener))) {
|
||||
if (XFAILED(state->object_table()->GetObject(handle, (XObject**)&listener))) {
|
||||
SHIM_SET_RETURN_64(0);
|
||||
return;
|
||||
}
|
||||
|
@ -95,25 +83,19 @@ SHIM_CALL XNotifyGetNext_shim(
|
|||
SHIM_SET_RETURN_64(dequeued ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XNotifyPositionUI_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XNotifyPositionUI_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t position = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XNotifyPositionUI(%.8X)",
|
||||
position);
|
||||
XELOGD("XNotifyPositionUI(%.8X)", position);
|
||||
|
||||
// Ignored.
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterNotifyExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterNotifyExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamNotifyCreateListener, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XNotifyGetNext, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XNotifyPositionUI, state);
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
|
||||
|
||||
// Build an ordinal enum to make it easy to lookup ordinals.
|
||||
#include <xenia/kernel/util/ordinal_table_pre.inc>
|
||||
namespace ordinals {
|
||||
|
@ -25,5 +23,4 @@ enum {
|
|||
} // namespace ordinals
|
||||
#include <xenia/kernel/util/ordinal_table_post.inc>
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XAM_ORDINALS_H_
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/xam_ordinals.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
@ -23,7 +21,8 @@ class KernelState;
|
|||
|
||||
namespace xam {
|
||||
// Registration functions, one per file.
|
||||
void RegisterContentExports(ExportResolver* export_resolver, KernelState* state);
|
||||
void RegisterContentExports(ExportResolver* export_resolver,
|
||||
KernelState* state);
|
||||
void RegisterInfoExports(ExportResolver* export_resolver, KernelState* state);
|
||||
void RegisterInputExports(ExportResolver* export_resolver, KernelState* state);
|
||||
void RegisterMsgExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
@ -38,5 +37,4 @@ void RegisterVoiceExports(ExportResolver* export_resolver, KernelState* state);
|
|||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XAM_PRIVATE_H_
|
||||
|
|
|
@ -14,13 +14,11 @@
|
|||
#include <xenia/kernel/xam_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
// http://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/?jdfwkey=sb0vm
|
||||
SHIM_CALL XamShowMessageBoxUI_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamShowMessageBoxUI_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t title_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t text_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -61,12 +59,10 @@ SHIM_CALL XamShowMessageBoxUI_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterUIExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterUIExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamShowMessageBoxUI, state);
|
||||
}
|
||||
|
|
|
@ -16,22 +16,15 @@
|
|||
#include <xenia/kernel/objects/xthread.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XamUserGetXUID_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserGetXUID_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk = SHIM_GET_ARG_32(1);
|
||||
uint32_t xuid_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamUserGetXUID(%d, %.8X, %.8X)",
|
||||
user_index,
|
||||
unk,
|
||||
xuid_ptr);
|
||||
XELOGD("XamUserGetXUID(%d, %.8X, %.8X)", user_index, unk, xuid_ptr);
|
||||
|
||||
if (user_index == 0) {
|
||||
const auto& user_profile = state->user_profile();
|
||||
|
@ -44,14 +37,11 @@ SHIM_CALL XamUserGetXUID_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserGetSigninState_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserGetSigninState_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XamUserGetSigninState(%d)",
|
||||
user_index);
|
||||
XELOGD("XamUserGetSigninState(%d)", user_index);
|
||||
|
||||
// Lie and say we are signed in, but local-only.
|
||||
// This should keep games from asking us to sign in and also keep them
|
||||
|
@ -64,16 +54,12 @@ SHIM_CALL XamUserGetSigninState_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserGetSigninInfo_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserGetSigninInfo_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t flags = SHIM_GET_ARG_32(1);
|
||||
uint32_t info_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamUserGetSigninInfo(%d, %.8X, %.8X)",
|
||||
user_index, flags, info_ptr);
|
||||
XELOGD("XamUserGetSigninInfo(%d, %.8X, %.8X)", user_index, flags, info_ptr);
|
||||
|
||||
if (user_index == 0) {
|
||||
const auto& user_profile = state->user_profile();
|
||||
|
@ -90,16 +76,12 @@ SHIM_CALL XamUserGetSigninInfo_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserGetName_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserGetName_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t buffer_len = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamUserGetName(%d, %.8X, %d)",
|
||||
user_index, buffer_ptr, buffer_len);
|
||||
XELOGD("XamUserGetName(%d, %.8X, %d)", user_index, buffer_ptr, buffer_len);
|
||||
|
||||
if (user_index == 0) {
|
||||
const auto& user_profile = state->user_profile();
|
||||
|
@ -111,10 +93,9 @@ SHIM_CALL XamUserGetName_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/xboxtools.cpp
|
||||
SHIM_CALL XamUserReadProfileSettings_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t title_id = SHIM_GET_ARG_32(0);
|
||||
uint32_t user_index = SHIM_GET_ARG_32(1);
|
||||
uint32_t unk_0 = SHIM_GET_ARG_32(2);
|
||||
|
@ -130,7 +111,8 @@ SHIM_CALL XamUserReadProfileSettings_shim(
|
|||
uint32_t buffer_size = SHIM_MEM_32(buffer_size_ptr);
|
||||
|
||||
XELOGD(
|
||||
"XamUserReadProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, %.8X)",
|
||||
"XamUserReadProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, "
|
||||
"%.8X)",
|
||||
title_id, user_index, unk_0, unk_1, setting_count, setting_ids_ptr,
|
||||
buffer_size_ptr, buffer_size, buffer_ptr, overlapped_ptr);
|
||||
|
||||
|
@ -171,14 +153,16 @@ SHIM_CALL XamUserReadProfileSettings_shim(
|
|||
uint32_t setting_id = SHIM_MEM_32(setting_ids_ptr + n * 4);
|
||||
auto setting = user_profile->GetSetting(setting_id);
|
||||
if (setting) {
|
||||
auto extra_size = static_cast<uint32_t>(setting->extra_size());;
|
||||
auto extra_size = static_cast<uint32_t>(setting->extra_size());
|
||||
;
|
||||
size_needed += extra_size;
|
||||
}
|
||||
}
|
||||
SHIM_SET_MEM_32(buffer_size_ptr, size_needed);
|
||||
if (buffer_size < size_needed) {
|
||||
if (overlapped_ptr) {
|
||||
state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_INSUFFICIENT_BUFFER);
|
||||
state->CompleteOverlappedImmediate(overlapped_ptr,
|
||||
X_ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
SHIM_SET_RETURN_32(X_ERROR_INSUFFICIENT_BUFFER);
|
||||
return;
|
||||
|
@ -201,8 +185,7 @@ SHIM_CALL XamUserReadProfileSettings_shim(
|
|||
SHIM_SET_MEM_32(user_data_ptr + 16, setting_id);
|
||||
if (setting) {
|
||||
buffer_offset = setting->Append(SHIM_MEM_ADDR(user_data_ptr + 24),
|
||||
SHIM_MEM_ADDR(buffer_ptr),
|
||||
buffer_offset);
|
||||
SHIM_MEM_ADDR(buffer_ptr), buffer_offset);
|
||||
} else {
|
||||
memset(SHIM_MEM_ADDR(user_data_ptr + 24), 0, 16);
|
||||
}
|
||||
|
@ -217,9 +200,8 @@ SHIM_CALL XamUserReadProfileSettings_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserWriteProfileSettings_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserWriteProfileSettings_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t unknown = SHIM_GET_ARG_32(1);
|
||||
uint32_t setting_count = SHIM_GET_ARG_32(2);
|
||||
|
@ -227,7 +209,8 @@ SHIM_CALL XamUserWriteProfileSettings_shim(
|
|||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"XamUserWriteProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, %.8X)",
|
||||
"XamUserWriteProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, "
|
||||
"%.8X)",
|
||||
user_index, unknown, setting_count, settings_ptr, overlapped_ptr);
|
||||
|
||||
if (!setting_count || !settings_ptr) {
|
||||
|
@ -251,22 +234,19 @@ SHIM_CALL XamUserWriteProfileSettings_shim(
|
|||
if (overlapped_ptr) {
|
||||
state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS);
|
||||
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserCheckPrivilege_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserCheckPrivilege_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t user_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t mask = SHIM_GET_ARG_32(1);
|
||||
uint32_t out_value_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamUserCheckPrivilege(%d, %.8X, %.8X)",
|
||||
user_index, mask, out_value_ptr);
|
||||
XELOGD("XamUserCheckPrivilege(%d, %.8X, %.8X)", user_index, mask,
|
||||
out_value_ptr);
|
||||
|
||||
// If we deny everything, games should hopefully not try to do stuff.
|
||||
SHIM_SET_MEM_32(out_value_ptr, 0);
|
||||
|
@ -274,15 +254,11 @@ SHIM_CALL XamUserCheckPrivilege_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamShowSigninUI_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamShowSigninUI_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk_0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk_mask = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XamShowSigninUI(%d, %.8X)",
|
||||
unk_0, unk_mask);
|
||||
XELOGD("XamShowSigninUI(%d, %.8X)", unk_0, unk_mask);
|
||||
|
||||
// Mask values vary. Probably matching user types? Local/remote?
|
||||
// Games seem to sit and loop until we trigger this notification.
|
||||
|
@ -291,9 +267,8 @@ SHIM_CALL XamShowSigninUI_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamUserCreateAchievementEnumerator_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamUserCreateAchievementEnumerator_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t title_id = SHIM_GET_ARG_32(0);
|
||||
uint32_t user_index = SHIM_GET_ARG_32(1);
|
||||
uint32_t xuid = SHIM_GET_ARG_32(2);
|
||||
|
@ -304,7 +279,8 @@ SHIM_CALL XamUserCreateAchievementEnumerator_shim(
|
|||
uint32_t handle_ptr = SHIM_GET_ARG_32(7);
|
||||
|
||||
XELOGD(
|
||||
"XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, %.8X)",
|
||||
"XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, "
|
||||
"%.8X)",
|
||||
title_id, user_index, xuid, flags, offset, count, buffer, handle_ptr);
|
||||
|
||||
XEnumerator* e = new XEnumerator(state);
|
||||
|
@ -315,9 +291,7 @@ SHIM_CALL XamUserCreateAchievementEnumerator_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamWriteGamerTile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamWriteGamerTile_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t arg0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t arg1 = SHIM_GET_ARG_32(1);
|
||||
uint32_t arg2 = SHIM_GET_ARG_32(2);
|
||||
|
@ -325,26 +299,22 @@ SHIM_CALL XamWriteGamerTile_shim(
|
|||
uint32_t arg4 = SHIM_GET_ARG_32(4);
|
||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(5);
|
||||
|
||||
XELOGD(
|
||||
"XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
arg0, arg1, arg2, arg3, arg4, overlapped_ptr);
|
||||
XELOGD("XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", arg0, arg1,
|
||||
arg2, arg3, arg4, overlapped_ptr);
|
||||
|
||||
if (overlapped_ptr) {
|
||||
state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS);
|
||||
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterUserExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterUserExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamUserGetXUID, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamUserGetSigninState, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamUserGetSigninInfo, state);
|
||||
|
|
|
@ -14,11 +14,9 @@
|
|||
#include <xenia/kernel/xam_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// TODO(benvanik): actually check to see if these are the same.
|
||||
void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode);
|
||||
SHIM_CALL XGetVideoMode_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
|
@ -27,12 +25,10 @@ SHIM_CALL XGetVideoMode_shim(PPCContext* ppc_state, KernelState* state) {
|
|||
xeVdQueryVideoMode(video_mode);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterVideoExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterVideoExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XGetVideoMode, state);
|
||||
}
|
||||
|
|
|
@ -15,20 +15,15 @@
|
|||
#include <xenia/kernel/xam_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XamVoiceCreate_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamVoiceCreate_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk1 = SHIM_GET_ARG_32(0); // 0
|
||||
uint32_t unk2 = SHIM_GET_ARG_32(1); // 0xF
|
||||
uint32_t out_voice_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XamVoiceCreate(%.8X, %.8X, %.8X)",
|
||||
unk1, unk2, out_voice_ptr);
|
||||
XELOGD("XamVoiceCreate(%.8X, %.8X, %.8X)", unk1, unk2, out_voice_ptr);
|
||||
|
||||
// Null out the ptr.
|
||||
SHIM_SET_MEM_32(out_voice_ptr, 0);
|
||||
|
@ -36,37 +31,28 @@ SHIM_CALL XamVoiceCreate_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamVoiceClose_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamVoiceClose_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t voice_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XamVoiceClose(%.8X)",
|
||||
voice_ptr);
|
||||
XELOGD("XamVoiceClose(%.8X)", voice_ptr);
|
||||
|
||||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XamVoiceHeadsetPresent_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XamVoiceHeadsetPresent_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t voice_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XamVoiceHeadsetPresent(%.8X)",
|
||||
voice_ptr);
|
||||
XELOGD("XamVoiceHeadsetPresent(%.8X)", voice_ptr);
|
||||
|
||||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterVoiceExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xam::RegisterVoiceExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xam.xex", XamVoiceCreate, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamVoiceClose, state);
|
||||
SHIM_SET_MAPPING("xam.xex", XamVoiceHeadsetPresent, state);
|
||||
|
|
|
@ -16,18 +16,13 @@
|
|||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL XMACreateContext_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XMACreateContext_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t context_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XMACreateContext(%.8X)",
|
||||
context_ptr);
|
||||
XELOGD("XMACreateContext(%.8X)", context_ptr);
|
||||
|
||||
// TODO(benvanik): allocate and return -- see if size required or just dummy?
|
||||
// Games will call MmGetPhysicalAddress on the result.
|
||||
|
@ -36,41 +31,32 @@ SHIM_CALL XMACreateContext_shim(
|
|||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XMAReleaseContext_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XMAReleaseContext_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t context_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XMAReleaseContext(%.8X)",
|
||||
context_ptr);
|
||||
XELOGD("XMAReleaseContext(%.8X)", context_ptr);
|
||||
|
||||
// TODO(benvanik): free
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioGetSpeakerConfig_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioGetSpeakerConfig_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t config_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XAudioGetSpeakerConfig(%.8X)",
|
||||
config_ptr);
|
||||
XELOGD("XAudioGetSpeakerConfig(%.8X)", config_ptr);
|
||||
|
||||
SHIM_SET_MEM_32(config_ptr, 0x00010001);
|
||||
|
||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t driver_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t out_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XAudioGetVoiceCategoryVolumeChangeMask(%.8X, %.8X)",
|
||||
driver_ptr, out_ptr);
|
||||
XELOGD("XAudioGetVoiceCategoryVolumeChangeMask(%.8X, %.8X)", driver_ptr,
|
||||
out_ptr);
|
||||
|
||||
assert_true((driver_ptr & 0xFFFF0000) == 0x41550000);
|
||||
|
||||
|
@ -83,15 +69,12 @@ SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioGetVoiceCategoryVolume_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioGetVoiceCategoryVolume_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t unk = SHIM_GET_ARG_32(0);
|
||||
uint32_t out_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XAudioGetVoiceCategoryVolume(%.8X, %.8X)",
|
||||
unk, out_ptr);
|
||||
XELOGD("XAudioGetVoiceCategoryVolume(%.8X, %.8X)", unk, out_ptr);
|
||||
|
||||
// Expects a floating point single. Volume %?
|
||||
SHIM_SET_MEM_F32(out_ptr, 1.0f);
|
||||
|
@ -99,29 +82,23 @@ SHIM_CALL XAudioGetVoiceCategoryVolume_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioEnableDucker_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioEnableDucker_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XAudioEnableDucker(%.8X)",
|
||||
unk);
|
||||
XELOGD("XAudioEnableDucker(%.8X)", unk);
|
||||
|
||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioRegisterRenderDriverClient_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioRegisterRenderDriverClient_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t callback_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t driver_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
uint32_t callback = SHIM_MEM_32(callback_ptr + 0);
|
||||
uint32_t callback_arg = SHIM_MEM_32(callback_ptr + 4);
|
||||
|
||||
XELOGD(
|
||||
"XAudioRegisterRenderDriverClient(%.8X(%.8X, %.8X), %.8X)",
|
||||
XELOGD("XAudioRegisterRenderDriverClient(%.8X(%.8X, %.8X), %.8X)",
|
||||
callback_ptr, callback, callback_arg, driver_ptr);
|
||||
|
||||
auto audio_system = state->emulator()->audio_system();
|
||||
|
@ -134,18 +111,16 @@ SHIM_CALL XAudioRegisterRenderDriverClient_shim(
|
|||
}
|
||||
|
||||
assert_true(!(index & ~0x0000FFFF));
|
||||
SHIM_SET_MEM_32(driver_ptr, 0x41550000 | (static_cast<uint32_t>(index) & 0x0000FFFF));
|
||||
SHIM_SET_MEM_32(driver_ptr,
|
||||
0x41550000 | (static_cast<uint32_t>(index) & 0x0000FFFF));
|
||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioUnregisterRenderDriverClient_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioUnregisterRenderDriverClient_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t driver_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XAudioUnregisterRenderDriverClient(%.8X)",
|
||||
driver_ptr);
|
||||
XELOGD("XAudioUnregisterRenderDriverClient(%.8X)", driver_ptr);
|
||||
|
||||
assert_true((driver_ptr & 0xFFFF0000) == 0x41550000);
|
||||
|
||||
|
@ -154,15 +129,12 @@ SHIM_CALL XAudioUnregisterRenderDriverClient_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XAudioSubmitRenderDriverFrame_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XAudioSubmitRenderDriverFrame_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t driver_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t samples_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XAudioSubmitRenderDriverFrame(%.8X, %.8X)",
|
||||
driver_ptr, samples_ptr);
|
||||
XELOGD("XAudioSubmitRenderDriverFrame(%.8X, %.8X)", driver_ptr, samples_ptr);
|
||||
|
||||
assert_true((driver_ptr & 0xFFFF0000) == 0x41550000);
|
||||
|
||||
|
@ -172,13 +144,11 @@ SHIM_CALL XAudioSubmitRenderDriverFrame_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterAudioExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterAudioExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XMACreateContext, state);
|
||||
// SHIM_SET_MAPPING("xboxkrnl.exe", XMAInitializeContext, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XMAReleaseContext, state);
|
||||
|
@ -202,7 +172,8 @@ void xe::kernel::xboxkrnl::RegisterAudioExports(
|
|||
// SHIM_SET_MAPPING("xboxkrnl.exe", XMAGetInputBufferReadOffset, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetSpeakerConfig, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolumeChangeMask, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolumeChangeMask,
|
||||
state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolume, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XAudioEnableDucker, state);
|
||||
|
||||
|
|
|
@ -15,15 +15,11 @@
|
|||
#include <xenia/kernel/objects/xthread.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// TODO: clean me up!
|
||||
SHIM_CALL DbgPrint_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
|
||||
SHIM_CALL DbgPrint_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t format_ptr = SHIM_GET_ARG_32(0);
|
||||
if (format_ptr == 0) {
|
||||
SHIM_SET_RETURN_64(-1);
|
||||
|
@ -34,7 +30,8 @@ SHIM_CALL DbgPrint_shim(
|
|||
|
||||
int arg_index = 0;
|
||||
|
||||
char buffer[512]; // TODO: ensure it never writes past the end of the buffer...
|
||||
char buffer[512]; // TODO: ensure it never writes past the end of the
|
||||
// buffer...
|
||||
char* b = buffer;
|
||||
for (; *format != '\0'; ++format) {
|
||||
const char* start = format;
|
||||
|
@ -58,10 +55,7 @@ SHIM_CALL DbgPrint_shim(
|
|||
end = format;
|
||||
|
||||
// skip flags
|
||||
while (*end == '-' ||
|
||||
*end == '+' ||
|
||||
*end == ' ' ||
|
||||
*end == '#' ||
|
||||
while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' ||
|
||||
*end == '0') {
|
||||
++end;
|
||||
}
|
||||
|
@ -76,8 +70,7 @@ SHIM_CALL DbgPrint_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
arg_extras++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -94,8 +87,7 @@ SHIM_CALL DbgPrint_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
++arg_extras;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -115,28 +107,23 @@ SHIM_CALL DbgPrint_shim(
|
|||
if (*end == 'h') {
|
||||
++end;
|
||||
}
|
||||
}
|
||||
else if (*end == 'l') {
|
||||
} else if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 4;
|
||||
if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 8;
|
||||
}
|
||||
}
|
||||
else if (*end == 'j') {
|
||||
} else if (*end == 'j') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'z') {
|
||||
} else if (*end == 'z') {
|
||||
arg_size = 4;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 't') {
|
||||
} else if (*end == 't') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'L') {
|
||||
} else if (*end == 'L') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
|
@ -145,21 +132,10 @@ SHIM_CALL DbgPrint_shim(
|
|||
break;
|
||||
}
|
||||
|
||||
if (*end == 'd' ||
|
||||
*end == 'i' ||
|
||||
*end == 'u' ||
|
||||
*end == 'o' ||
|
||||
*end == 'x' ||
|
||||
*end == 'X' ||
|
||||
*end == 'f' ||
|
||||
*end == 'F' ||
|
||||
*end == 'e' ||
|
||||
*end == 'E' ||
|
||||
*end == 'g' ||
|
||||
*end == 'G' ||
|
||||
*end == 'a' ||
|
||||
*end == 'A' ||
|
||||
*end == 'c') {
|
||||
if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' ||
|
||||
*end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' ||
|
||||
*end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' ||
|
||||
*end == 'a' || *end == 'A' || *end == 'c') {
|
||||
char local[512];
|
||||
local[0] = '\0';
|
||||
strncat(local, start, end + 1 - start);
|
||||
|
@ -167,47 +143,42 @@ SHIM_CALL DbgPrint_shim(
|
|||
assert_true(arg_size == 8 || arg_size == 4);
|
||||
if (arg_size == 8) {
|
||||
if (arg_extras == 0) {
|
||||
uint64_t value = arg_index < 7
|
||||
uint64_t value =
|
||||
arg_index < 7
|
||||
? SHIM_GET_ARG_64(1 + arg_index)
|
||||
: SHIM_MEM_32(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8));
|
||||
int result = sprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (arg_size == 4) {
|
||||
} else if (arg_size == 4) {
|
||||
if (arg_extras == 0) {
|
||||
uint64_t value = arg_index < 7
|
||||
uint64_t value =
|
||||
arg_index < 7
|
||||
? SHIM_GET_ARG_64(1 + arg_index)
|
||||
: SHIM_MEM_32(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8));
|
||||
int result = sprintf(b, local, (uint32_t)value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*end == 'n')
|
||||
{
|
||||
} else if (*end == 'n') {
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = arg_index < 7
|
||||
? SHIM_GET_ARG_32(1 + arg_index)
|
||||
: (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8));
|
||||
: (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 +
|
||||
((1 + arg_index) * 8));
|
||||
SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char)));
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (*end == 's' ||
|
||||
*end == 'p') {
|
||||
} else if (*end == 's' || *end == 'p') {
|
||||
char local[512];
|
||||
local[0] = '\0';
|
||||
strncat(local, start, end + 1 - start);
|
||||
|
@ -216,17 +187,16 @@ SHIM_CALL DbgPrint_shim(
|
|||
if (arg_extras == 0) {
|
||||
uint32_t value = arg_index < 7
|
||||
? SHIM_GET_ARG_32(1 + arg_index)
|
||||
: (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8));
|
||||
: (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 +
|
||||
((1 + arg_index) * 8));
|
||||
const void* pointer = (const void*)SHIM_MEM_ADDR(value);
|
||||
int result = sprintf(b, local, pointer);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
break;
|
||||
}
|
||||
|
@ -238,16 +208,12 @@ SHIM_CALL DbgPrint_shim(
|
|||
XELOGD("(DbgPrint) %s", buffer);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL DbgBreakPoint_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL DbgBreakPoint_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("DbgBreakPoint()");
|
||||
DebugBreak();
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlRaiseException_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t record_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
uint32_t code = SHIM_MEM_32(record_ptr + 0);
|
||||
|
@ -255,9 +221,7 @@ SHIM_CALL RtlRaiseException_shim(
|
|||
// ...
|
||||
uint32_t param_count = SHIM_MEM_32(record_ptr + 16);
|
||||
|
||||
XELOGD(
|
||||
"RtlRaiseException(%.8X(%.8X))",
|
||||
record_ptr, code);
|
||||
XELOGD("RtlRaiseException(%.8X(%.8X))", record_ptr, code);
|
||||
|
||||
if (code == 0x406D1388) {
|
||||
// SetThreadName. FFS.
|
||||
|
@ -294,22 +258,21 @@ SHIM_CALL RtlRaiseException_shim(
|
|||
DebugBreak();
|
||||
}
|
||||
|
||||
|
||||
void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) {
|
||||
XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4);
|
||||
void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2,
|
||||
uint32_t param3, uint32_t param4) {
|
||||
XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1,
|
||||
param2, param3, param4);
|
||||
fflush(stdout);
|
||||
DebugBreak();
|
||||
assert_always();
|
||||
}
|
||||
|
||||
SHIM_CALL KeBugCheck_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL KeBugCheck_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t code = SHIM_GET_ARG_32(0);
|
||||
xeKeBugCheckEx(code, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
SHIM_CALL KeBugCheckEx_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL KeBugCheckEx_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t code = SHIM_GET_ARG_32(0);
|
||||
uint32_t param1 = SHIM_GET_ARG_32(1);
|
||||
uint32_t param2 = SHIM_GET_ARG_32(2);
|
||||
|
@ -318,13 +281,11 @@ SHIM_CALL KeBugCheckEx_shim(
|
|||
xeKeBugCheckEx(code, param1, param2, param3, param4);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterDebugExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterDebugExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", DbgBreakPoint, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlRaiseException, state);
|
||||
|
|
|
@ -14,18 +14,13 @@
|
|||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL HalReturnToFirmware_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL HalReturnToFirmware_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t routine = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"HalReturnToFirmware(%d)",
|
||||
routine);
|
||||
XELOGD("HalReturnToFirmware(%d)", routine);
|
||||
|
||||
// void
|
||||
// IN FIRMWARE_REENTRY Routine
|
||||
|
@ -39,12 +34,10 @@ SHIM_CALL HalReturnToFirmware_shim(
|
|||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterHalExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterHalExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", HalReturnToFirmware, state);
|
||||
}
|
||||
|
|
|
@ -18,15 +18,12 @@
|
|||
#include <xenia/kernel/util/shim_utils.h>
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
SHIM_CALL NtCreateFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t desired_access = SHIM_GET_ARG_32(1);
|
||||
uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -40,16 +37,10 @@ SHIM_CALL NtCreateFile_shim(
|
|||
|
||||
char* object_name = attrs.object_name.Duplicate();
|
||||
|
||||
XELOGD(
|
||||
"NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)",
|
||||
handle_ptr,
|
||||
desired_access,
|
||||
object_attributes_ptr,
|
||||
!object_name ? "(null)" : object_name,
|
||||
io_status_block_ptr,
|
||||
allocation_size_ptr,
|
||||
file_attributes,
|
||||
share_access,
|
||||
XELOGD("NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)",
|
||||
handle_ptr, desired_access, object_attributes_ptr,
|
||||
!object_name ? "(null)" : object_name, io_status_block_ptr,
|
||||
allocation_size_ptr, file_attributes, share_access,
|
||||
creation_disposition);
|
||||
|
||||
uint64_t allocation_size = 0; // is this correct???
|
||||
|
@ -67,16 +58,15 @@ SHIM_CALL NtCreateFile_shim(
|
|||
XFile* root_file = NULL;
|
||||
if (attrs.root_directory != 0xFFFFFFFD && // ObDosDevices
|
||||
attrs.root_directory != 0) {
|
||||
result = state->object_table()->GetObject(
|
||||
attrs.root_directory, (XObject**)&root_file);
|
||||
result = state->object_table()->GetObject(attrs.root_directory,
|
||||
(XObject**)&root_file);
|
||||
assert_true(XSUCCEEDED(result));
|
||||
assert_true(root_file->type() == XObject::Type::kTypeFile);
|
||||
|
||||
auto root_path = root_file->absolute_path();
|
||||
auto target_path = root_path + object_name;
|
||||
entry = fs->ResolvePath(target_path);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Resolve the file using the virtual file system.
|
||||
entry = fs->ResolvePath(object_name);
|
||||
}
|
||||
|
@ -87,9 +77,7 @@ SHIM_CALL NtCreateFile_shim(
|
|||
XFile* file = NULL;
|
||||
if (entry && entry->type() == Entry::Type::FILE) {
|
||||
// Open the file.
|
||||
result = entry->Open(
|
||||
state,
|
||||
mode,
|
||||
result = entry->Open(state, mode,
|
||||
false, // TODO(benvanik): pick async mode, if needed.
|
||||
&file);
|
||||
} else {
|
||||
|
@ -119,8 +107,7 @@ SHIM_CALL NtCreateFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtOpenFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtOpenFile_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t desired_access = SHIM_GET_ARG_32(1);
|
||||
uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -131,13 +118,9 @@ SHIM_CALL NtOpenFile_shim(
|
|||
|
||||
char* object_name = attrs.object_name.Duplicate();
|
||||
|
||||
XELOGD(
|
||||
"NtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)",
|
||||
handle_ptr,
|
||||
desired_access,
|
||||
object_attributes_ptr,
|
||||
!object_name ? "(null)" : object_name,
|
||||
io_status_block_ptr,
|
||||
XELOGD("NtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)", handle_ptr,
|
||||
desired_access, object_attributes_ptr,
|
||||
!object_name ? "(null)" : object_name, io_status_block_ptr,
|
||||
open_options);
|
||||
|
||||
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
||||
|
@ -146,8 +129,8 @@ SHIM_CALL NtOpenFile_shim(
|
|||
|
||||
XFile* root_file = NULL;
|
||||
if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices
|
||||
result = state->object_table()->GetObject(
|
||||
attrs.root_directory, (XObject**)&root_file);
|
||||
result = state->object_table()->GetObject(attrs.root_directory,
|
||||
(XObject**)&root_file);
|
||||
assert_true(XSUCCEEDED(result));
|
||||
assert_true(root_file->type() == XObject::Type::kTypeFile);
|
||||
assert_always();
|
||||
|
@ -162,13 +145,10 @@ SHIM_CALL NtOpenFile_shim(
|
|||
XFile* file = NULL;
|
||||
if (entry && entry->type() == Entry::Type::FILE) {
|
||||
// Open the file.
|
||||
result = entry->Open(
|
||||
state,
|
||||
mode,
|
||||
result = entry->Open(state, mode,
|
||||
false, // TODO(benvanik): pick async mode, if needed.
|
||||
&file);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
result = X_STATUS_NO_SUCH_FILE;
|
||||
info = X_FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
|
@ -205,8 +185,7 @@ void xeNtReadFileCompleted(XAsyncRequest* request, xeNtReadFileState* state) {
|
|||
delete state;
|
||||
}
|
||||
|
||||
SHIM_CALL NtReadFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtReadFile_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t event_handle = SHIM_GET_ARG_32(1);
|
||||
uint32_t apc_routine_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -217,16 +196,9 @@ SHIM_CALL NtReadFile_shim(
|
|||
uint32_t byte_offset_ptr = SHIM_GET_ARG_32(7);
|
||||
size_t byte_offset = byte_offset_ptr ? SHIM_MEM_64(byte_offset_ptr) : 0;
|
||||
|
||||
XELOGD(
|
||||
"NtReadFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%d))",
|
||||
file_handle,
|
||||
event_handle,
|
||||
apc_routine_ptr,
|
||||
apc_context,
|
||||
io_status_block_ptr,
|
||||
buffer,
|
||||
buffer_length,
|
||||
byte_offset_ptr,
|
||||
XELOGD("NtReadFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%d))",
|
||||
file_handle, event_handle, apc_routine_ptr, apc_context,
|
||||
io_status_block_ptr, buffer, buffer_length, byte_offset_ptr,
|
||||
byte_offset);
|
||||
|
||||
// Async not supported yet.
|
||||
|
@ -239,15 +211,13 @@ SHIM_CALL NtReadFile_shim(
|
|||
XEvent* ev = NULL;
|
||||
bool signal_event = false;
|
||||
if (event_handle) {
|
||||
result = state->object_table()->GetObject(
|
||||
event_handle, (XObject**)&ev);
|
||||
result = state->object_table()->GetObject(event_handle, (XObject**)&ev);
|
||||
}
|
||||
|
||||
// Grab file.
|
||||
XFile* file = NULL;
|
||||
if (XSUCCEEDED(result)) {
|
||||
result = state->object_table()->GetObject(
|
||||
file_handle, (XObject**)&file);
|
||||
result = state->object_table()->GetObject(file_handle, (XObject**)&file);
|
||||
}
|
||||
|
||||
// Execute read.
|
||||
|
@ -260,16 +230,14 @@ SHIM_CALL NtReadFile_shim(
|
|||
// TODO(benvanik): async path.
|
||||
if (true) {
|
||||
// Synchronous request.
|
||||
if (!byte_offset_ptr ||
|
||||
byte_offset == 0xFFFFFFFFfffffffe) {
|
||||
if (!byte_offset_ptr || byte_offset == 0xFFFFFFFFfffffffe) {
|
||||
// FILE_USE_FILE_POINTER_POSITION
|
||||
byte_offset = -1;
|
||||
}
|
||||
|
||||
// Read now.
|
||||
size_t bytes_read = 0;
|
||||
result = file->Read(
|
||||
SHIM_MEM_ADDR(buffer), buffer_length, byte_offset,
|
||||
result = file->Read(SHIM_MEM_ADDR(buffer), buffer_length, byte_offset,
|
||||
&bytes_read);
|
||||
if (XSUCCEEDED(result)) {
|
||||
info = (int32_t)bytes_read;
|
||||
|
@ -311,29 +279,22 @@ SHIM_CALL NtReadFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtSetInformationFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtSetInformationFile_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t file_info_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t length = SHIM_GET_ARG_32(3);
|
||||
uint32_t file_info_class = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"NtSetInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
file_handle,
|
||||
io_status_block_ptr,
|
||||
file_info_ptr,
|
||||
length,
|
||||
file_info_class);
|
||||
XELOGD("NtSetInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", file_handle,
|
||||
io_status_block_ptr, file_info_ptr, length, file_info_class);
|
||||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
uint32_t info = 0;
|
||||
|
||||
// Grab file.
|
||||
XFile* file = NULL;
|
||||
result = state->object_table()->GetObject(
|
||||
file_handle, (XObject**)&file);
|
||||
result = state->object_table()->GetObject(file_handle, (XObject**)&file);
|
||||
|
||||
if (XSUCCEEDED(result)) {
|
||||
result = X_STATUS_SUCCESS;
|
||||
|
@ -369,29 +330,23 @@ SHIM_CALL NtSetInformationFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtQueryInformationFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t file_info_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t length = SHIM_GET_ARG_32(3);
|
||||
uint32_t file_info_class = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"NtQueryInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
file_handle,
|
||||
io_status_block_ptr,
|
||||
file_info_ptr,
|
||||
length,
|
||||
file_info_class);
|
||||
XELOGD("NtQueryInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", file_handle,
|
||||
io_status_block_ptr, file_info_ptr, length, file_info_class);
|
||||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
uint32_t info = 0;
|
||||
|
||||
// Grab file.
|
||||
XFile* file = NULL;
|
||||
result = state->object_table()->GetObject(
|
||||
file_handle, (XObject**)&file);
|
||||
result = state->object_table()->GetObject(file_handle, (XObject**)&file);
|
||||
|
||||
if (XSUCCEEDED(result)) {
|
||||
result = X_STATUS_SUCCESS;
|
||||
|
@ -439,9 +394,9 @@ SHIM_CALL NtQueryInformationFile_shim(
|
|||
if (XSUCCEEDED(result)) {
|
||||
if (bytes_read == sizeof(magic)) {
|
||||
info = 4;
|
||||
SHIM_SET_MEM_32(file_info_ptr, magic == poly::byte_swap(0x0FF512ED));
|
||||
}
|
||||
else {
|
||||
SHIM_SET_MEM_32(file_info_ptr,
|
||||
magic == poly::byte_swap(0x0FF512ED));
|
||||
} else {
|
||||
result = X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
@ -472,8 +427,8 @@ SHIM_CALL NtQueryInformationFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtQueryFullAttributesFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t object_attributes_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t file_info_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
|
@ -481,18 +436,15 @@ SHIM_CALL NtQueryFullAttributesFile_shim(
|
|||
|
||||
char* object_name = attrs.object_name.Duplicate();
|
||||
|
||||
XELOGD(
|
||||
"NtQueryFullAttributesFile(%.8X(%s), %.8X)",
|
||||
object_attributes_ptr,
|
||||
!object_name ? "(null)" : object_name,
|
||||
file_info_ptr);
|
||||
XELOGD("NtQueryFullAttributesFile(%.8X(%s), %.8X)", object_attributes_ptr,
|
||||
!object_name ? "(null)" : object_name, file_info_ptr);
|
||||
|
||||
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
||||
|
||||
XFile* root_file = NULL;
|
||||
if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices
|
||||
result = state->object_table()->GetObject(
|
||||
attrs.root_directory, (XObject**)&root_file);
|
||||
result = state->object_table()->GetObject(attrs.root_directory,
|
||||
(XObject**)&root_file);
|
||||
assert_true(XSUCCEEDED(result));
|
||||
assert_true(root_file->type() == XObject::Type::kTypeFile);
|
||||
assert_always();
|
||||
|
@ -514,30 +466,23 @@ SHIM_CALL NtQueryFullAttributesFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtQueryVolumeInformationFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtQueryVolumeInformationFile_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t fs_info_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t length = SHIM_GET_ARG_32(3);
|
||||
uint32_t fs_info_class = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"NtQueryVolumeInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
file_handle,
|
||||
io_status_block_ptr,
|
||||
fs_info_ptr,
|
||||
length,
|
||||
fs_info_class);
|
||||
|
||||
XELOGD("NtQueryVolumeInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
file_handle, io_status_block_ptr, fs_info_ptr, length, fs_info_class);
|
||||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
uint32_t info = 0;
|
||||
|
||||
// Grab file.
|
||||
XFile* file = NULL;
|
||||
result = state->object_table()->GetObject(
|
||||
file_handle, (XObject**)&file);
|
||||
result = state->object_table()->GetObject(file_handle, (XObject**)&file);
|
||||
|
||||
if (XSUCCEEDED(result)) {
|
||||
result = X_STATUS_SUCCESS;
|
||||
|
@ -585,8 +530,7 @@ SHIM_CALL NtQueryVolumeInformationFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtQueryDirectoryFile_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t event_handle = SHIM_GET_ARG_32(1);
|
||||
uint32_t apc_routine = SHIM_GET_ARG_32(2);
|
||||
|
@ -605,16 +549,10 @@ SHIM_CALL NtQueryDirectoryFile_shim(
|
|||
}
|
||||
|
||||
XELOGD(
|
||||
"NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%s), %d)",
|
||||
file_handle,
|
||||
event_handle,
|
||||
apc_routine,
|
||||
apc_context,
|
||||
io_status_block_ptr,
|
||||
file_info_ptr,
|
||||
length,
|
||||
file_name_ptr,
|
||||
!file_name ? "(null)" : file_name,
|
||||
"NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%s), "
|
||||
"%d)",
|
||||
file_handle, event_handle, apc_routine, apc_context, io_status_block_ptr,
|
||||
file_info_ptr, length, file_name_ptr, !file_name ? "(null)" : file_name,
|
||||
restart_scan);
|
||||
|
||||
if (length < 72) {
|
||||
|
@ -627,11 +565,11 @@ SHIM_CALL NtQueryDirectoryFile_shim(
|
|||
uint32_t info = 0;
|
||||
|
||||
XFile* file = NULL;
|
||||
result = state->object_table()->GetObject(
|
||||
file_handle, (XObject**)&file);
|
||||
result = state->object_table()->GetObject(file_handle, (XObject**)&file);
|
||||
if (XSUCCEEDED(result)) {
|
||||
XDirectoryInfo* dir_info = (XDirectoryInfo*)xe_calloc(length);
|
||||
result = file->QueryDirectory(dir_info, length, file_name, restart_scan != 0);
|
||||
result =
|
||||
file->QueryDirectory(dir_info, length, file_name, restart_scan != 0);
|
||||
if (XSUCCEEDED(result)) {
|
||||
dir_info->Write(SHIM_MEM_BASE, file_info_ptr);
|
||||
info = length;
|
||||
|
@ -655,27 +593,23 @@ SHIM_CALL NtQueryDirectoryFile_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL FscSetCacheElementCount_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL FscSetCacheElementCount_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t unk_0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk_1 = SHIM_GET_ARG_32(1);
|
||||
// unk_0 = 0
|
||||
// unk_1 looks like a count? in what units? 256 is a common value
|
||||
|
||||
XELOGD(
|
||||
"FscSetCacheElementCount(%.8X, %.8X)",
|
||||
unk_0, unk_1);
|
||||
XELOGD("FscSetCacheElementCount(%.8X, %.8X)", unk_0, unk_1);
|
||||
|
||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterIoExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterIoExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateFile, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtOpenFile, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReadFile, state);
|
||||
|
|
|
@ -15,13 +15,11 @@
|
|||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL NtAllocateVirtualMemory_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtAllocateVirtualMemory_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
||||
|
@ -30,10 +28,8 @@ SHIM_CALL NtAllocateVirtualMemory_shim(
|
|||
uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask
|
||||
uint32_t unknown = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)",
|
||||
base_addr_ptr, base_addr_value,
|
||||
region_size_ptr, region_size_value,
|
||||
XELOGD("NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)",
|
||||
base_addr_ptr, base_addr_value, region_size_ptr, region_size_value,
|
||||
allocation_type, protect_bits, unknown);
|
||||
|
||||
// NTSTATUS
|
||||
|
@ -92,8 +88,8 @@ SHIM_CALL NtAllocateVirtualMemory_shim(
|
|||
|
||||
// Allocate.
|
||||
uint32_t flags = (allocation_type & X_MEM_NOZERO);
|
||||
uint32_t addr = (uint32_t)state->memory()->HeapAlloc(
|
||||
base_addr_value, adjusted_size, flags);
|
||||
uint32_t addr = (uint32_t)state->memory()->HeapAlloc(base_addr_value,
|
||||
adjusted_size, flags);
|
||||
if (!addr) {
|
||||
// Failed - assume no memory available.
|
||||
SHIM_SET_RETURN_32(X_STATUS_NO_MEMORY);
|
||||
|
@ -107,9 +103,7 @@ SHIM_CALL NtAllocateVirtualMemory_shim(
|
|||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL NtFreeVirtualMemory_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtFreeVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
||||
|
@ -118,10 +112,8 @@ SHIM_CALL NtFreeVirtualMemory_shim(
|
|||
uint32_t free_type = SHIM_GET_ARG_32(2);
|
||||
uint32_t unknown = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD(
|
||||
"NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)",
|
||||
base_addr_ptr, base_addr_value,
|
||||
region_size_ptr, region_size_value,
|
||||
XELOGD("NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)",
|
||||
base_addr_ptr, base_addr_value, region_size_ptr, region_size_value,
|
||||
free_type, unknown);
|
||||
|
||||
// NTSTATUS
|
||||
|
@ -146,8 +138,7 @@ SHIM_CALL NtFreeVirtualMemory_shim(
|
|||
|
||||
// Free.
|
||||
uint32_t flags = 0;
|
||||
uint32_t freed_size = state->memory()->HeapFree(
|
||||
base_addr_value, flags);
|
||||
uint32_t freed_size = state->memory()->HeapFree(base_addr_value, flags);
|
||||
if (!freed_size) {
|
||||
SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL);
|
||||
return;
|
||||
|
@ -158,15 +149,14 @@ SHIM_CALL NtFreeVirtualMemory_shim(
|
|||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
SHIM_CALL NtQueryVirtualMemory_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
||||
uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1);
|
||||
X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr);
|
||||
X_MEMORY_BASIC_INFORMATION* memory_basic_information =
|
||||
(X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr);
|
||||
|
||||
XELOGD(
|
||||
"NtQueryVirtualMemory(%.8X, %.8X)",
|
||||
base_address, memory_basic_information_ptr);
|
||||
XELOGD("NtQueryVirtualMemory(%.8X, %.8X)", base_address,
|
||||
memory_basic_information_ptr);
|
||||
|
||||
MEMORY_BASIC_INFORMATION mem_info;
|
||||
size_t result = state->memory()->QueryInformation(base_address, &mem_info);
|
||||
|
@ -208,9 +198,8 @@ SHIM_CALL NtQueryVirtualMemory_shim(
|
|||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL MmAllocatePhysicalMemoryEx_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL MmAllocatePhysicalMemoryEx_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t type = SHIM_GET_ARG_32(0);
|
||||
uint32_t region_size = SHIM_GET_ARG_32(1);
|
||||
uint32_t protect_bits = SHIM_GET_ARG_32(2);
|
||||
|
@ -218,10 +207,8 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim(
|
|||
uint32_t max_addr_range = SHIM_GET_ARG_32(4);
|
||||
uint32_t alignment = SHIM_GET_ARG_32(5);
|
||||
|
||||
XELOGD(
|
||||
"MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
type, region_size, protect_bits,
|
||||
min_addr_range, max_addr_range, alignment);
|
||||
XELOGD("MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", type,
|
||||
region_size, protect_bits, min_addr_range, max_addr_range, alignment);
|
||||
|
||||
// Type will usually be 0 (user request?), where 1 and 2 are sometimes made
|
||||
// by D3D/etc.
|
||||
|
@ -285,15 +272,11 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim(
|
|||
SHIM_SET_RETURN_32(base_address);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL MmFreePhysicalMemory_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL MmFreePhysicalMemory_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t type = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_address = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"MmFreePhysicalAddress(%d, %.8X)",
|
||||
type, base_address);
|
||||
XELOGD("MmFreePhysicalAddress(%d, %.8X)", type, base_address);
|
||||
|
||||
// base_address = result of MmAllocatePhysicalMemory.
|
||||
|
||||
|
@ -307,42 +290,32 @@ SHIM_CALL MmFreePhysicalMemory_shim(
|
|||
// state->memory(), base_address, size);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL MmQueryAddressProtect_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL MmQueryAddressProtect_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"MmQueryAddressProtect(%.8X)",
|
||||
base_address);
|
||||
XELOGD("MmQueryAddressProtect(%.8X)", base_address);
|
||||
|
||||
uint32_t access = state->memory()->QueryProtect(base_address);
|
||||
|
||||
SHIM_SET_RETURN_32(access);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL MmQueryAllocationSize_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL MmQueryAllocationSize_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"MmQueryAllocationSize(%.8X)",
|
||||
base_address);
|
||||
XELOGD("MmQueryAllocationSize(%.8X)", base_address);
|
||||
|
||||
size_t size = state->memory()->QuerySize(base_address);
|
||||
|
||||
SHIM_SET_RETURN_32(static_cast<uint32_t>(size));
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL MmQueryStatistics_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL MmQueryStatistics_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t stats_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"MmQueryStatistics(%.8X)",
|
||||
stats_ptr);
|
||||
XELOGD("MmQueryStatistics(%.8X)", stats_ptr);
|
||||
|
||||
uint32_t size = SHIM_MEM_32(stats_ptr + 0);
|
||||
if (size != 104) {
|
||||
|
@ -364,8 +337,10 @@ SHIM_CALL MmQueryStatistics_shim(
|
|||
SHIM_SET_MEM_32(stats_ptr + 4 * 1, 0x00020000); // TotalPhysicalPages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 2, 0x00000300); // KernelPages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 3, 0x00020000); // TitleAvailablePages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 4, 0x2FFF0000); // TitleTotalVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 5, 0x00160000); // TitleReservedVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 4,
|
||||
0x2FFF0000); // TitleTotalVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 5,
|
||||
0x00160000); // TitleReservedVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 6, 0x00001000); // TitlePhysicalPages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 7, 0x00000010); // TitlePoolPages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 8, 0x00000100); // TitleStackPages
|
||||
|
@ -375,8 +350,10 @@ SHIM_CALL MmQueryStatistics_shim(
|
|||
SHIM_SET_MEM_32(stats_ptr + 4 * 12, 0x00000100); // TitlePageTablePages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 13, 0x00000100); // TitleCachePages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 14, 0x00000000); // SystemAvailablePages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 15, 0x00000000); // SystemTotalVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 16, 0x00000000); // SystemReservedVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 15,
|
||||
0x00000000); // SystemTotalVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 16,
|
||||
0x00000000); // SystemReservedVirtualMemoryBytes
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 17, 0x00000000); // SystemPhysicalPages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 18, 0x00000000); // SystemPoolPages
|
||||
SHIM_SET_MEM_32(stats_ptr + 4 * 19, 0x00000000); // SystemStackPages
|
||||
|
@ -390,15 +367,11 @@ SHIM_CALL MmQueryStatistics_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx
|
||||
SHIM_CALL MmGetPhysicalAddress_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL MmGetPhysicalAddress_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"MmGetPhysicalAddress(%.8X)",
|
||||
base_address);
|
||||
XELOGD("MmGetPhysicalAddress(%.8X)", base_address);
|
||||
|
||||
// PHYSICAL_ADDRESS MmGetPhysicalAddress(
|
||||
// _In_ PVOID BaseAddress
|
||||
|
@ -420,16 +393,13 @@ SHIM_CALL MmGetPhysicalAddress_shim(
|
|||
SHIM_SET_RETURN_32(base_address);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL ExAllocatePoolTypeWithTag_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL ExAllocatePoolTypeWithTag_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t size = SHIM_GET_ARG_32(0);
|
||||
uint32_t tag = SHIM_GET_ARG_32(1);
|
||||
uint32_t zero = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"ExAllocatePoolTypeWithTag(%d, %.8X, %d)",
|
||||
size, tag, zero);
|
||||
XELOGD("ExAllocatePoolTypeWithTag(%d, %.8X, %d)", size, tag, zero);
|
||||
|
||||
uint32_t alignment = 8;
|
||||
uint32_t adjusted_size = size;
|
||||
|
@ -445,42 +415,30 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim(
|
|||
SHIM_SET_RETURN_32(addr);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL ExFreePool_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL ExFreePool_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"ExFreePool(%.8X)",
|
||||
base_address);
|
||||
XELOGD("ExFreePool(%.8X)", base_address);
|
||||
|
||||
state->memory()->HeapFree(base_address, 0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL KeLockL2_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL KeLockL2_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
// Ignored for now. This is just a perf optimization, I think.
|
||||
// It may be useful as a hint for CPU-GPU transfer.
|
||||
|
||||
XELOGD(
|
||||
"KeLockL2(?)");
|
||||
XELOGD("KeLockL2(?)");
|
||||
|
||||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL KeUnlockL2_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD(
|
||||
"KeUnlockL2(?)");
|
||||
SHIM_CALL KeUnlockL2_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("KeUnlockL2(?)");
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterMemoryExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtAllocateVirtualMemory, state);
|
||||
|
|
|
@ -15,24 +15,20 @@
|
|||
#include <xenia/kernel/objects/xthread.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL KeEnableFpuExceptions_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL KeEnableFpuExceptions_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t enabled = SHIM_GET_ARG_32(0);
|
||||
XELOGD("KeEnableFpuExceptions(%d)", enabled);
|
||||
// TODO(benvanik): can we do anything about exceptions?
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterMiscExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterMiscExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeEnableFpuExceptions, state);
|
||||
}
|
||||
|
|
|
@ -17,17 +17,14 @@
|
|||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/objects/xuser_module.h>
|
||||
|
||||
|
||||
DEFINE_bool(abort_before_entry, false,
|
||||
"Abort execution right before launching the module.");
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) :
|
||||
XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") {
|
||||
XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
: XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") {
|
||||
// Build the export table used for resolution.
|
||||
#include <xenia/kernel/util/export_table_pre.inc>
|
||||
static KernelExport xboxkrnl_export_table[] = {
|
||||
|
@ -60,16 +57,14 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) :
|
|||
// arguments. If we wanted to see what would happen we could fake that.
|
||||
uint32_t pKeDebugMonitorData = (uint32_t)memory_->HeapAlloc(0, 256, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::KeDebugMonitorData,
|
||||
pKeDebugMonitorData);
|
||||
"xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData);
|
||||
poly::store_and_swap<uint32_t>(mem + pKeDebugMonitorData, 0);
|
||||
|
||||
// KeCertMonitorData (?*)
|
||||
// Always set to zero, ignored.
|
||||
uint32_t pKeCertMonitorData = (uint32_t)memory_->HeapAlloc(0, 4, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::KeCertMonitorData,
|
||||
pKeCertMonitorData);
|
||||
"xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData);
|
||||
poly::store_and_swap<uint32_t>(mem + pKeCertMonitorData, 0);
|
||||
|
||||
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
|
||||
|
@ -79,10 +74,11 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) :
|
|||
// was whether an HDD was present. Not sure what the other flags are.
|
||||
uint32_t pXboxHardwareInfo = (uint32_t)memory_->HeapAlloc(0, 16, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::XboxHardwareInfo,
|
||||
pXboxHardwareInfo);
|
||||
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0, 0x00000000); // flags
|
||||
poly::store_and_swap<uint8_t> (mem + pXboxHardwareInfo + 4, 0x06); // cpu count
|
||||
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
|
||||
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0,
|
||||
0x00000000); // flags
|
||||
poly::store_and_swap<uint8_t>(mem + pXboxHardwareInfo + 4,
|
||||
0x06); // cpu count
|
||||
// Remaining 11b are zeroes?
|
||||
|
||||
// XexExecutableModuleHandle (?**)
|
||||
|
@ -95,13 +91,14 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) :
|
|||
// 0x80101058 <- pointer to xex header
|
||||
// 0x80101100 <- xex header base
|
||||
uint32_t ppXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 4, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::XexExecutableModuleHandle,
|
||||
export_resolver_->SetVariableMapping("xboxkrnl.exe",
|
||||
ordinals::XexExecutableModuleHandle,
|
||||
ppXexExecutableModuleHandle);
|
||||
uint32_t pXexExecutableModuleHandle =
|
||||
(uint32_t)memory_->HeapAlloc(0, 256, 0);
|
||||
poly::store_and_swap<uint32_t>(mem + ppXexExecutableModuleHandle, pXexExecutableModuleHandle);
|
||||
poly::store_and_swap<uint32_t>(mem + pXexExecutableModuleHandle + 0x58, 0x80101100);
|
||||
uint32_t pXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 256, 0);
|
||||
poly::store_and_swap<uint32_t>(mem + ppXexExecutableModuleHandle,
|
||||
pXexExecutableModuleHandle);
|
||||
poly::store_and_swap<uint32_t>(mem + pXexExecutableModuleHandle + 0x58,
|
||||
0x80101100);
|
||||
|
||||
// ExLoadedCommandLine (char*)
|
||||
// The name of the xex. Not sure this is ever really used on real devices.
|
||||
|
@ -109,19 +106,17 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) :
|
|||
// Always set to "default.xex" (with quotes) for now.
|
||||
uint32_t pExLoadedCommandLine = (uint32_t)memory_->HeapAlloc(0, 1024, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::ExLoadedCommandLine,
|
||||
pExLoadedCommandLine);
|
||||
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine);
|
||||
char command_line[] = "\"default.xex\"";
|
||||
xe_copy_memory(mem + pExLoadedCommandLine, 1024,
|
||||
command_line, poly::countof(command_line) + 1);
|
||||
xe_copy_memory(mem + pExLoadedCommandLine, 1024, command_line,
|
||||
poly::countof(command_line) + 1);
|
||||
|
||||
// XboxKrnlVersion (8b)
|
||||
// Kernel version, looks like 2b.2b.2b.2b.
|
||||
// I've only seen games check >=, so we just fake something here.
|
||||
uint32_t pXboxKrnlVersion = (uint32_t)memory_->HeapAlloc(0, 8, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::XboxKrnlVersion,
|
||||
pXboxKrnlVersion);
|
||||
"xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion);
|
||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2);
|
||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 2, 0xFFFF);
|
||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 4, 0xFFFF);
|
||||
|
@ -130,15 +125,13 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) :
|
|||
// KeTimeStampBundle (ad)
|
||||
uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::KeTimeStampBundle,
|
||||
pKeTimeStampBundle);
|
||||
"xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle);
|
||||
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 0);
|
||||
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 8, 0);
|
||||
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 12, 0);
|
||||
}
|
||||
|
||||
XboxkrnlModule::~XboxkrnlModule() {
|
||||
}
|
||||
XboxkrnlModule::~XboxkrnlModule() {}
|
||||
|
||||
int XboxkrnlModule::LaunchModule(const char* path) {
|
||||
// Create and register the module. We keep it local to this function and
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/kernel/xboxkrnl_ordinals.h>
|
||||
#include <xenia/kernel/objects/xkernel_module.h>
|
||||
|
@ -20,13 +19,11 @@
|
|||
// All of the exported functions:
|
||||
#include <xenia/kernel/xboxkrnl_rtl.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
class KernelState;
|
||||
|
||||
|
||||
class XboxkrnlModule : public XKernelModule {
|
||||
public:
|
||||
XboxkrnlModule(Emulator* emulator, KernelState* kernel_state);
|
||||
|
@ -37,9 +34,7 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_MODULE_H_
|
||||
|
|
|
@ -16,13 +16,11 @@
|
|||
#include <xenia/kernel/util/shim_utils.h>
|
||||
#include <xenia/kernel/util/xex2.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
X_STATUS xeExGetXConfigSetting(
|
||||
uint16_t category, uint16_t setting, void* buffer, uint16_t buffer_size,
|
||||
X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||
void* buffer, uint16_t buffer_size,
|
||||
uint16_t* required_size) {
|
||||
uint16_t setting_size = 0;
|
||||
uint32_t value = 0;
|
||||
|
@ -102,23 +100,20 @@ X_STATUS xeExGetXConfigSetting(
|
|||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL ExGetXConfigSetting_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL ExGetXConfigSetting_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint16_t category = SHIM_GET_ARG_16(0);
|
||||
uint16_t setting = SHIM_GET_ARG_16(1);
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(2);
|
||||
uint16_t buffer_size = SHIM_GET_ARG_16(3);
|
||||
uint32_t required_size_ptr = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)",
|
||||
category, setting, buffer_ptr, buffer_size, required_size_ptr);
|
||||
XELOGD("ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)", category, setting,
|
||||
buffer_ptr, buffer_size, required_size_ptr);
|
||||
|
||||
void* buffer = buffer_ptr ? SHIM_MEM_ADDR(buffer_ptr) : NULL;
|
||||
uint16_t required_size = 0;
|
||||
X_STATUS result = xeExGetXConfigSetting(
|
||||
category, setting, buffer, buffer_size, &required_size);
|
||||
X_STATUS result = xeExGetXConfigSetting(category, setting, buffer,
|
||||
buffer_size, &required_size);
|
||||
|
||||
if (required_size_ptr) {
|
||||
SHIM_SET_MEM_16(required_size_ptr, required_size);
|
||||
|
@ -127,14 +122,11 @@ SHIM_CALL ExGetXConfigSetting_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XexCheckExecutablePrivilege_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t privilege = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XexCheckExecutablePrivilege(%.8X)",
|
||||
privilege);
|
||||
XELOGD("XexCheckExecutablePrivilege(%.8X)", privilege);
|
||||
|
||||
// BOOL
|
||||
// DWORD Privilege
|
||||
|
@ -159,16 +151,12 @@ SHIM_CALL XexCheckExecutablePrivilege_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XexGetModuleHandle_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
|
||||
const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
|
||||
uint32_t module_handle_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XexGetModuleHandle(%s, %.8X)",
|
||||
module_name, module_handle_ptr);
|
||||
XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr);
|
||||
|
||||
XModule* module = state->GetModule(module_name);
|
||||
if (!module) {
|
||||
|
@ -184,18 +172,15 @@ SHIM_CALL XexGetModuleHandle_shim(
|
|||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XexGetModuleSection_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t name_ptr = SHIM_GET_ARG_32(1);
|
||||
const char* name = (const char*)SHIM_MEM_ADDR(name_ptr);
|
||||
uint32_t data_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t size_ptr = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD(
|
||||
"XexGetModuleSection(%.8X, %s, %.8X, %.8X)",
|
||||
handle, name, data_ptr, size_ptr);
|
||||
XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", handle, name, data_ptr,
|
||||
size_ptr);
|
||||
|
||||
XModule* module = NULL;
|
||||
X_STATUS result =
|
||||
|
@ -215,18 +200,15 @@ SHIM_CALL XexGetModuleSection_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XexLoadImage_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XexLoadImage_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
|
||||
const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
|
||||
uint32_t module_flags = SHIM_GET_ARG_32(1);
|
||||
uint32_t min_version = SHIM_GET_ARG_32(2);
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD(
|
||||
"XexLoadImage(%s, %.8X, %.8X, %.8X)",
|
||||
module_name, module_flags, min_version, handle_ptr);
|
||||
XELOGD("XexLoadImage(%s, %.8X, %.8X, %.8X)", module_name, module_flags,
|
||||
min_version, handle_ptr);
|
||||
|
||||
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
||||
|
||||
|
@ -244,14 +226,10 @@ SHIM_CALL XexLoadImage_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XexUnloadImage_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XexUnloadImage_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"XexUnloadImage(%.8X)",
|
||||
handle);
|
||||
XELOGD("XexUnloadImage(%.8X)", handle);
|
||||
|
||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||
|
||||
|
@ -260,16 +238,14 @@ SHIM_CALL XexUnloadImage_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL XexGetProcedureAddress_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t module_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t ordinal = SHIM_GET_ARG_32(1);
|
||||
uint32_t out_function_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"XexGetProcedureAddress(%.8X, %.8X, %.8X)",
|
||||
module_handle, ordinal, out_function_ptr);
|
||||
XELOGD("XexGetProcedureAddress(%.8X, %.8X, %.8X)", module_handle, ordinal,
|
||||
out_function_ptr);
|
||||
|
||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||
|
||||
|
@ -278,8 +254,8 @@ SHIM_CALL XexGetProcedureAddress_shim(
|
|||
if (!module_handle) {
|
||||
module = state->GetExecutableModule();
|
||||
} else {
|
||||
result = state->object_table()->GetObject(
|
||||
module_handle, (XObject**)&module);
|
||||
result =
|
||||
state->object_table()->GetObject(module_handle, (XObject**)&module);
|
||||
}
|
||||
|
||||
if (XSUCCEEDED(result)) {
|
||||
|
@ -294,9 +270,8 @@ SHIM_CALL XexGetProcedureAddress_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL ExRegisterTitleTerminateNotification_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL ExRegisterTitleTerminateNotification_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t registration_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t create = SHIM_GET_ARG_32(1);
|
||||
|
||||
|
@ -305,8 +280,7 @@ SHIM_CALL ExRegisterTitleTerminateNotification_shim(
|
|||
// list entry flink
|
||||
// list entry blink
|
||||
|
||||
XELOGD(
|
||||
"ExRegisterTitleTerminateNotification(%.8X(%.8X), %.1X)",
|
||||
XELOGD("ExRegisterTitleTerminateNotification(%.8X(%.8X), %.1X)",
|
||||
registration_ptr, routine, create);
|
||||
|
||||
if (create) {
|
||||
|
@ -318,11 +292,9 @@ SHIM_CALL ExRegisterTitleTerminateNotification_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterModuleExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", ExGetXConfigSetting, state);
|
||||
|
|
|
@ -16,21 +16,16 @@
|
|||
#include <xenia/kernel/objects/xthread.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
SHIM_CALL ObReferenceObjectByHandle_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t out_object_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"ObReferenceObjectByHandle(%.8X, %.8X, %.8X)",
|
||||
handle,
|
||||
object_type_ptr,
|
||||
XELOGD("ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", handle, object_type_ptr,
|
||||
out_object_ptr);
|
||||
|
||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||
|
@ -47,8 +42,7 @@ SHIM_CALL ObReferenceObjectByHandle_shim(
|
|||
{
|
||||
XThread* thread = (XThread*)object;
|
||||
native_ptr = thread->thread_state();
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (out_object_ptr) {
|
||||
|
@ -59,14 +53,10 @@ SHIM_CALL ObReferenceObjectByHandle_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL ObDereferenceObject_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t native_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"ObDereferenceObject(%.8X)",
|
||||
native_ptr);
|
||||
XELOGD("ObDereferenceObject(%.8X)", native_ptr);
|
||||
|
||||
// Check if a dummy value from ObReferenceObjectByHandle.
|
||||
if (native_ptr == 0xDEADF00D) {
|
||||
|
@ -83,16 +73,13 @@ SHIM_CALL ObDereferenceObject_shim(
|
|||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL NtDuplicateObject_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtDuplicateObject_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t new_handle_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t options = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"NtDuplicateObject(%.8X, %.8X, %.8X)",
|
||||
handle, new_handle_ptr, options);
|
||||
XELOGD("NtDuplicateObject(%.8X, %.8X, %.8X)", handle, new_handle_ptr,
|
||||
options);
|
||||
|
||||
// NOTE: new_handle_ptr can be zero to just close a handle.
|
||||
// NOTE: this function seems to be used to get the current thread handle
|
||||
|
@ -123,14 +110,10 @@ SHIM_CALL NtDuplicateObject_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL NtClose_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL NtClose_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"NtClose(%.8X)",
|
||||
handle);
|
||||
XELOGD("NtClose(%.8X)", handle);
|
||||
|
||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||
|
||||
|
@ -139,13 +122,11 @@ SHIM_CALL NtClose_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterObExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterObExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtDuplicateObject, state);
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
|
||||
|
||||
// Build an ordinal enum to make it easy to lookup ordinals.
|
||||
#include <xenia/kernel/util/ordinal_table_pre.inc>
|
||||
namespace ordinals {
|
||||
|
@ -25,5 +23,4 @@ enum {
|
|||
} // namespace ordinals
|
||||
#include <xenia/kernel/util/ordinal_table_post.inc>
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_ORDINALS_H_
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/xboxkrnl_ordinals.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
@ -42,5 +40,4 @@ void RegisterVideoExports(ExportResolver* export_resolver, KernelState* state);
|
|||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_PRIVATE_H_
|
||||
|
|
|
@ -17,21 +17,16 @@
|
|||
#include <xenia/kernel/util/shim_utils.h>
|
||||
#include <xenia/kernel/util/xex2.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561778
|
||||
SHIM_CALL RtlCompareMemory_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlCompareMemory_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t source1_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source2_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t length = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"RtlCompareMemory(%.8X, %.8X, %d)",
|
||||
source1_ptr, source2_ptr, length);
|
||||
XELOGD("RtlCompareMemory(%.8X, %.8X, %d)", source1_ptr, source2_ptr, length);
|
||||
|
||||
// SIZE_T
|
||||
// _In_ const VOID *Source1,
|
||||
|
@ -55,17 +50,14 @@ SHIM_CALL RtlCompareMemory_shim(
|
|||
SHIM_SET_RETURN_64(c);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff552123
|
||||
SHIM_CALL RtlCompareMemoryUlong_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlCompareMemoryUlong_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t length = SHIM_GET_ARG_32(1);
|
||||
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"RtlCompareMemoryUlong(%.8X, %d, %.8X)",
|
||||
source_ptr, length, pattern);
|
||||
XELOGD("RtlCompareMemoryUlong(%.8X, %d, %.8X)", source_ptr, length, pattern);
|
||||
|
||||
// SIZE_T
|
||||
// _In_ PVOID Source,
|
||||
|
@ -96,17 +88,14 @@ SHIM_CALL RtlCompareMemoryUlong_shim(
|
|||
SHIM_SET_RETURN_64(c);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff552263
|
||||
SHIM_CALL RtlFillMemoryUlong_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlFillMemoryUlong_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t length = SHIM_GET_ARG_32(1);
|
||||
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"RtlFillMemoryUlong(%.8X, %d, %.8X)",
|
||||
destination_ptr, length, pattern);
|
||||
XELOGD("RtlFillMemoryUlong(%.8X, %d, %.8X)", destination_ptr, length,
|
||||
pattern);
|
||||
|
||||
// VOID
|
||||
// _Out_ PVOID Destination,
|
||||
|
@ -129,23 +118,20 @@ SHIM_CALL RtlFillMemoryUlong_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// typedef struct _STRING {
|
||||
// USHORT Length;
|
||||
// USHORT MaximumLength;
|
||||
// PCHAR Buffer;
|
||||
// } ANSI_STRING, *PANSI_STRING;
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561918
|
||||
SHIM_CALL RtlInitAnsiString_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlInitAnsiString_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
const char* source = source_ptr ? (char*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
||||
XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)",
|
||||
destination_ptr, source_ptr, source ? source : "<null>");
|
||||
XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)", destination_ptr, source_ptr,
|
||||
source ? source : "<null>");
|
||||
|
||||
// VOID
|
||||
// _Out_ PANSI_STRING DestinationString,
|
||||
|
@ -163,10 +149,8 @@ SHIM_CALL RtlInitAnsiString_shim(
|
|||
SHIM_SET_MEM_32(destination_ptr + 4, source_ptr);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561899
|
||||
SHIM_CALL RtlFreeAnsiString_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlFreeAnsiString_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD("RtlFreeAnsiString(%.8X)", string_ptr);
|
||||
|
@ -186,17 +170,14 @@ SHIM_CALL RtlFreeAnsiString_shim(
|
|||
SHIM_SET_MEM_32(string_ptr + 4, 0);
|
||||
}
|
||||
|
||||
|
||||
// typedef struct _UNICODE_STRING {
|
||||
// USHORT Length;
|
||||
// USHORT MaximumLength;
|
||||
// PWSTR Buffer;
|
||||
// } UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561934
|
||||
SHIM_CALL RtlInitUnicodeString_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlInitUnicodeString_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
|
@ -223,10 +204,8 @@ SHIM_CALL RtlInitUnicodeString_shim(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561903
|
||||
SHIM_CALL RtlFreeUnicodeString_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlFreeUnicodeString_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD("RtlFreeUnicodeString(%.8X)", string_ptr);
|
||||
|
@ -246,16 +225,15 @@ SHIM_CALL RtlFreeUnicodeString_shim(
|
|||
SHIM_SET_MEM_32(string_ptr + 4, 0);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff562969
|
||||
SHIM_CALL RtlUnicodeStringToAnsiString_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t alloc_dest = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)",
|
||||
destination_ptr, source_ptr, alloc_dest);
|
||||
XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", destination_ptr,
|
||||
source_ptr, alloc_dest);
|
||||
|
||||
// NTSTATUS
|
||||
// _Inout_ PANSI_STRING DestinationString,
|
||||
|
@ -294,9 +272,8 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlMultiByteToUnicodeN_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlMultiByteToUnicodeN_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t destination_len = SHIM_GET_ARG_32(1);
|
||||
uint32_t written_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -310,22 +287,19 @@ SHIM_CALL RtlMultiByteToUnicodeN_shim(
|
|||
|
||||
auto source = (uint8_t*)SHIM_MEM_ADDR(source_ptr);
|
||||
auto destination = (uint16_t*)SHIM_MEM_ADDR(destination_ptr);
|
||||
for (uint32_t i = 0; i < copy_len; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < copy_len; i++) {
|
||||
*destination++ = poly::byte_swap(*source++);
|
||||
}
|
||||
|
||||
if (written_ptr != 0)
|
||||
{
|
||||
if (written_ptr != 0) {
|
||||
SHIM_SET_MEM_32(written_ptr, copy_len << 1);
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlUnicodeToMultiByteN_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlUnicodeToMultiByteN_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t destination_len = SHIM_GET_ARG_32(1);
|
||||
uint32_t written_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -339,28 +313,23 @@ SHIM_CALL RtlUnicodeToMultiByteN_shim(
|
|||
|
||||
auto source = (uint16_t*)SHIM_MEM_ADDR(source_ptr);
|
||||
auto destination = (uint8_t*)SHIM_MEM_ADDR(destination_ptr);
|
||||
for (uint32_t i = 0; i < copy_len; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < copy_len; i++) {
|
||||
uint16_t c = poly::byte_swap(*source++);
|
||||
*destination++ = c < 256 ? (uint8_t)c : '?';
|
||||
}
|
||||
|
||||
if (written_ptr != 0)
|
||||
{
|
||||
if (written_ptr != 0) {
|
||||
SHIM_SET_MEM_32(written_ptr, copy_len);
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlNtStatusToDosError_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlNtStatusToDosError_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t status = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"RtlNtStatusToDosError(%.4X)",
|
||||
status);
|
||||
XELOGD("RtlNtStatusToDosError(%.4X)", status);
|
||||
|
||||
if (!status || (status & 0x20000000)) {
|
||||
// Success.
|
||||
|
@ -379,9 +348,8 @@ SHIM_CALL RtlNtStatusToDosError_shim(
|
|||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlImageXexHeaderField_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t xex_header_base = SHIM_GET_ARG_32(0);
|
||||
uint32_t image_field = SHIM_GET_ARG_32(1);
|
||||
|
||||
|
@ -392,9 +360,7 @@ SHIM_CALL RtlImageXexHeaderField_shim(
|
|||
// The only ImageField I've seen in the wild is
|
||||
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
||||
|
||||
XELOGD(
|
||||
"RtlImageXexHeaderField(%.8X, %.8X)",
|
||||
xex_header_base, image_field);
|
||||
XELOGD("RtlImageXexHeaderField(%.8X, %.8X)", xex_header_base, image_field);
|
||||
|
||||
// PVOID
|
||||
// PVOID XexHeaderBase
|
||||
|
@ -428,7 +394,6 @@ SHIM_CALL RtlImageXexHeaderField_shim(
|
|||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one
|
||||
// on the 360 (32b vs. 28b). This means that we can't do in-place splatting of
|
||||
// the critical sections. Also, the 360 never calls RtlDeleteCriticalSection
|
||||
|
@ -440,8 +405,8 @@ SHIM_CALL RtlImageXexHeaderField_shim(
|
|||
// the user code will never know.
|
||||
//
|
||||
// Ref: http://msdn.microsoft.com/en-us/magazine/cc164040.aspx
|
||||
// Ref: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/critical.c?view=markup
|
||||
|
||||
// Ref:
|
||||
// http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/critical.c?view=markup
|
||||
|
||||
// This structure tries to match the one on the 360 as best I can figure out.
|
||||
// Unfortunately some games have the critical sections pre-initialized in
|
||||
|
@ -472,9 +437,8 @@ void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs) {
|
|||
cs->owning_thread_id = 0;
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlInitializeCriticalSection_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlInitializeCriticalSection_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD("RtlInitializeCriticalSection(%.8X)", cs_ptr);
|
||||
|
@ -483,9 +447,8 @@ SHIM_CALL RtlInitializeCriticalSection_shim(
|
|||
xeRtlInitializeCriticalSection(cs);
|
||||
}
|
||||
|
||||
|
||||
X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(
|
||||
X_RTL_CRITICAL_SECTION* cs, uint32_t spin_count) {
|
||||
X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs,
|
||||
uint32_t spin_count) {
|
||||
// NTSTATUS
|
||||
// _Out_ LPCRITICAL_SECTION lpCriticalSection,
|
||||
// _In_ DWORD dwSpinCount
|
||||
|
@ -506,22 +469,19 @@ X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(
|
|||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t spin_count = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)",
|
||||
cs_ptr, spin_count);
|
||||
XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)", cs_ptr,
|
||||
spin_count);
|
||||
|
||||
auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||
X_STATUS result = xeRtlInitializeCriticalSectionAndSpinCount(
|
||||
cs, spin_count);
|
||||
X_STATUS result = xeRtlInitializeCriticalSectionAndSpinCount(cs, spin_count);
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
||||
// TODO(benvanik): remove the need for passing in thread_id.
|
||||
void xeRtlEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) {
|
||||
// VOID
|
||||
|
@ -556,8 +516,8 @@ spin:
|
|||
cs->recursion_count = 1;
|
||||
}
|
||||
|
||||
SHIM_CALL RtlEnterCriticalSection_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlEnterCriticalSection_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
// XELOGD("RtlEnterCriticalSection(%.8X)", cs_ptr);
|
||||
|
@ -569,9 +529,9 @@ SHIM_CALL RtlEnterCriticalSection_shim(
|
|||
xeRtlEnterCriticalSection(cs, thread_id);
|
||||
}
|
||||
|
||||
|
||||
// TODO(benvanik): remove the need for passing in thread_id.
|
||||
uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) {
|
||||
uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs,
|
||||
uint32_t thread_id) {
|
||||
// DWORD
|
||||
// _Inout_ LPCRITICAL_SECTION lpCriticalSection
|
||||
|
||||
|
@ -589,9 +549,8 @@ uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t threa
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlTryEnterCriticalSection_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlTryEnterCriticalSection_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
// XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr);
|
||||
|
@ -604,7 +563,6 @@ SHIM_CALL RtlTryEnterCriticalSection_shim(
|
|||
SHIM_SET_RETURN_64(result);
|
||||
}
|
||||
|
||||
|
||||
void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) {
|
||||
// VOID
|
||||
// _Inout_ LPCRITICAL_SECTION lpCriticalSection
|
||||
|
@ -625,9 +583,8 @@ void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlLeaveCriticalSection_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlLeaveCriticalSection_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
// XELOGD("RtlLeaveCriticalSection(%.8X)", cs_ptr);
|
||||
|
@ -636,9 +593,7 @@ SHIM_CALL RtlLeaveCriticalSection_shim(
|
|||
xeRtlLeaveCriticalSection(cs);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlTimeToTimeFields_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlTimeToTimeFields_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t time_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t time_fields_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
|
@ -661,9 +616,7 @@ SHIM_CALL RtlTimeToTimeFields_shim(
|
|||
SHIM_SET_MEM_16(time_fields_ptr + 12, st.wMilliseconds);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL RtlTimeFieldsToTime_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL RtlTimeFieldsToTime_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t time_fields_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t time_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
|
@ -690,13 +643,11 @@ SHIM_CALL RtlTimeFieldsToTime_shim(
|
|||
SHIM_SET_RETURN_64(1);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterRtlExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterRtlExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareMemory, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareMemoryUlong, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlFillMemoryUlong, state);
|
||||
|
@ -717,7 +668,8 @@ void xe::kernel::xboxkrnl::RegisterRtlExports(
|
|||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlImageXexHeaderField, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSection, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSectionAndSpinCount, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSectionAndSpinCount,
|
||||
state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlEnterCriticalSection, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlTryEnterCriticalSection, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlLeaveCriticalSection, state);
|
||||
|
|
|
@ -17,15 +17,11 @@
|
|||
#include <xenia/kernel/util/shim_utils.h>
|
||||
#include <xenia/kernel/util/xex2.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// TODO: clean me up!
|
||||
SHIM_CALL vsprintf_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
|
||||
SHIM_CALL vsprintf_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t arg_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -63,10 +59,7 @@ SHIM_CALL vsprintf_shim(
|
|||
end = format;
|
||||
|
||||
// skip flags
|
||||
while (*end == '-' ||
|
||||
*end == '+' ||
|
||||
*end == ' ' ||
|
||||
*end == '#' ||
|
||||
while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' ||
|
||||
*end == '0') {
|
||||
++end;
|
||||
}
|
||||
|
@ -81,8 +74,7 @@ SHIM_CALL vsprintf_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
arg_extras++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -99,8 +91,7 @@ SHIM_CALL vsprintf_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
++arg_extras;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -120,28 +111,23 @@ SHIM_CALL vsprintf_shim(
|
|||
if (*end == 'h') {
|
||||
++end;
|
||||
}
|
||||
}
|
||||
else if (*end == 'l') {
|
||||
} else if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 4;
|
||||
if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 8;
|
||||
}
|
||||
}
|
||||
else if (*end == 'j') {
|
||||
} else if (*end == 'j') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'z') {
|
||||
} else if (*end == 'z') {
|
||||
arg_size = 4;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 't') {
|
||||
} else if (*end == 't') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'L') {
|
||||
} else if (*end == 'L') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
|
@ -150,21 +136,10 @@ SHIM_CALL vsprintf_shim(
|
|||
break;
|
||||
}
|
||||
|
||||
if (*end == 'd' ||
|
||||
*end == 'i' ||
|
||||
*end == 'u' ||
|
||||
*end == 'o' ||
|
||||
*end == 'x' ||
|
||||
*end == 'X' ||
|
||||
*end == 'f' ||
|
||||
*end == 'F' ||
|
||||
*end == 'e' ||
|
||||
*end == 'E' ||
|
||||
*end == 'g' ||
|
||||
*end == 'G' ||
|
||||
*end == 'a' ||
|
||||
*end == 'A' ||
|
||||
*end == 'c') {
|
||||
if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' ||
|
||||
*end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' ||
|
||||
*end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' ||
|
||||
*end == 'a' || *end == 'A' || *end == 'c') {
|
||||
char local[512];
|
||||
local[0] = '\0';
|
||||
strncat(local, start, end + 1 - start);
|
||||
|
@ -172,58 +147,52 @@ SHIM_CALL vsprintf_shim(
|
|||
assert_true(arg_size == 8 || arg_size == 4);
|
||||
if (arg_size == 8) {
|
||||
if (arg_extras == 0) {
|
||||
uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint64_t value = SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
int result = sprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (arg_size == 4) {
|
||||
} else if (arg_size == 4) {
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
int result = sprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*end == 'n')
|
||||
{
|
||||
} else if (*end == 'n') {
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char)));
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (*end == 's' ||
|
||||
*end == 'p') {
|
||||
} else if (*end == 's' || *end == 'p') {
|
||||
char local[512];
|
||||
local[0] = '\0';
|
||||
strncat(local, start, end + 1 - start);
|
||||
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
const void* pointer = (const void*)SHIM_MEM_ADDR(value);
|
||||
int result = sprintf(b, local, pointer);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
break;
|
||||
}
|
||||
|
@ -233,11 +202,8 @@ SHIM_CALL vsprintf_shim(
|
|||
SHIM_SET_RETURN_32((uint32_t)(b - buffer));
|
||||
}
|
||||
|
||||
|
||||
// TODO: clean me up!
|
||||
SHIM_CALL _vsnprintf_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
|
||||
SHIM_CALL _vsnprintf_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t count = SHIM_GET_ARG_32(1);
|
||||
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -248,7 +214,9 @@ SHIM_CALL _vsnprintf_shim(
|
|||
return;
|
||||
}
|
||||
|
||||
char* buffer = (char*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past the end of the buffer (count)...
|
||||
char* buffer = (char*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never
|
||||
// writes past the end of
|
||||
// the buffer (count)...
|
||||
const char* format = (const char*)SHIM_MEM_ADDR(format_ptr);
|
||||
|
||||
int arg_index = 0;
|
||||
|
@ -276,10 +244,7 @@ SHIM_CALL _vsnprintf_shim(
|
|||
end = format;
|
||||
|
||||
// skip flags
|
||||
while (*end == '-' ||
|
||||
*end == '+' ||
|
||||
*end == ' ' ||
|
||||
*end == '#' ||
|
||||
while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' ||
|
||||
*end == '0') {
|
||||
++end;
|
||||
}
|
||||
|
@ -294,8 +259,7 @@ SHIM_CALL _vsnprintf_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
arg_extras++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -312,8 +276,7 @@ SHIM_CALL _vsnprintf_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
++arg_extras;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -333,28 +296,23 @@ SHIM_CALL _vsnprintf_shim(
|
|||
if (*end == 'h') {
|
||||
++end;
|
||||
}
|
||||
}
|
||||
else if (*end == 'l') {
|
||||
} else if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 4;
|
||||
if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 8;
|
||||
}
|
||||
}
|
||||
else if (*end == 'j') {
|
||||
} else if (*end == 'j') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'z') {
|
||||
} else if (*end == 'z') {
|
||||
arg_size = 4;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 't') {
|
||||
} else if (*end == 't') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'L') {
|
||||
} else if (*end == 'L') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
|
@ -363,21 +321,10 @@ SHIM_CALL _vsnprintf_shim(
|
|||
break;
|
||||
}
|
||||
|
||||
if (*end == 'd' ||
|
||||
*end == 'i' ||
|
||||
*end == 'u' ||
|
||||
*end == 'o' ||
|
||||
*end == 'x' ||
|
||||
*end == 'X' ||
|
||||
*end == 'f' ||
|
||||
*end == 'F' ||
|
||||
*end == 'e' ||
|
||||
*end == 'E' ||
|
||||
*end == 'g' ||
|
||||
*end == 'G' ||
|
||||
*end == 'a' ||
|
||||
*end == 'A' ||
|
||||
*end == 'c') {
|
||||
if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' ||
|
||||
*end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' ||
|
||||
*end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' ||
|
||||
*end == 'a' || *end == 'A' || *end == 'c') {
|
||||
char local[512];
|
||||
local[0] = '\0';
|
||||
strncat(local, start, end + 1 - start);
|
||||
|
@ -385,58 +332,52 @@ SHIM_CALL _vsnprintf_shim(
|
|||
assert_true(arg_size == 8 || arg_size == 4);
|
||||
if (arg_size == 8) {
|
||||
if (arg_extras == 0) {
|
||||
uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint64_t value = SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
int result = sprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (arg_size == 4) {
|
||||
} else if (arg_size == 4) {
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
int result = sprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*end == 'n')
|
||||
{
|
||||
} else if (*end == 'n') {
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char)));
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (*end == 's' ||
|
||||
*end == 'p') {
|
||||
} else if (*end == 's' || *end == 'p') {
|
||||
char local[512];
|
||||
local[0] = '\0';
|
||||
strncat(local, start, end + 1 - start);
|
||||
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
const void* pointer = (const void*)SHIM_MEM_ADDR(value);
|
||||
int result = sprintf(b, local, pointer);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
break;
|
||||
}
|
||||
|
@ -446,11 +387,8 @@ SHIM_CALL _vsnprintf_shim(
|
|||
SHIM_SET_RETURN_32((uint32_t)(b - buffer));
|
||||
}
|
||||
|
||||
|
||||
// TODO: clean me up!
|
||||
SHIM_CALL _vswprintf_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
|
||||
SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t arg_ptr = SHIM_GET_ARG_32(2);
|
||||
|
@ -460,14 +398,17 @@ SHIM_CALL _vswprintf_shim(
|
|||
return;
|
||||
}
|
||||
|
||||
wchar_t*buffer = (wchar_t*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past the end of the buffer (count)...
|
||||
wchar_t* buffer =
|
||||
(wchar_t*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past
|
||||
// the end of the buffer (count)...
|
||||
const wchar_t* format = (const wchar_t*)SHIM_MEM_ADDR(format_ptr);
|
||||
|
||||
// this will work since a null is the same regardless of endianness
|
||||
size_t format_length = wcslen(format);
|
||||
|
||||
// swap the format buffer
|
||||
wchar_t* swapped_format = (wchar_t*)xe_malloc((format_length + 1) * sizeof(wchar_t));
|
||||
wchar_t* swapped_format =
|
||||
(wchar_t*)xe_malloc((format_length + 1) * sizeof(wchar_t));
|
||||
for (size_t i = 0; i < format_length; ++i) {
|
||||
swapped_format[i] = poly::byte_swap(format[i]);
|
||||
}
|
||||
|
@ -501,10 +442,7 @@ SHIM_CALL _vswprintf_shim(
|
|||
end = format;
|
||||
|
||||
// skip flags
|
||||
while (*end == '-' ||
|
||||
*end == '+' ||
|
||||
*end == ' ' ||
|
||||
*end == '#' ||
|
||||
while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' ||
|
||||
*end == '0') {
|
||||
++end;
|
||||
}
|
||||
|
@ -519,8 +457,7 @@ SHIM_CALL _vswprintf_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
arg_extras++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -537,8 +474,7 @@ SHIM_CALL _vswprintf_shim(
|
|||
if (*end == '*') {
|
||||
++end;
|
||||
++arg_extras;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (*end >= '0' && *end <= '9') {
|
||||
++end;
|
||||
}
|
||||
|
@ -558,28 +494,23 @@ SHIM_CALL _vswprintf_shim(
|
|||
if (*end == 'h') {
|
||||
++end;
|
||||
}
|
||||
}
|
||||
else if (*end == 'l') {
|
||||
} else if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 4;
|
||||
if (*end == 'l') {
|
||||
++end;
|
||||
arg_size = 8;
|
||||
}
|
||||
}
|
||||
else if (*end == 'j') {
|
||||
} else if (*end == 'j') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'z') {
|
||||
} else if (*end == 'z') {
|
||||
arg_size = 4;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 't') {
|
||||
} else if (*end == 't') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
else if (*end == 'L') {
|
||||
} else if (*end == 'L') {
|
||||
arg_size = 8;
|
||||
++end;
|
||||
}
|
||||
|
@ -588,21 +519,10 @@ SHIM_CALL _vswprintf_shim(
|
|||
break;
|
||||
}
|
||||
|
||||
if (*end == 'd' ||
|
||||
*end == 'i' ||
|
||||
*end == 'u' ||
|
||||
*end == 'o' ||
|
||||
*end == 'x' ||
|
||||
*end == 'X' ||
|
||||
*end == 'f' ||
|
||||
*end == 'F' ||
|
||||
*end == 'e' ||
|
||||
*end == 'E' ||
|
||||
*end == 'g' ||
|
||||
*end == 'G' ||
|
||||
*end == 'a' ||
|
||||
*end == 'A' ||
|
||||
*end == 'c') {
|
||||
if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' ||
|
||||
*end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' ||
|
||||
*end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' ||
|
||||
*end == 'a' || *end == 'A' || *end == 'c') {
|
||||
wchar_t local[512];
|
||||
local[0] = '\0';
|
||||
wcsncat(local, start, end + 1 - start);
|
||||
|
@ -610,67 +530,64 @@ SHIM_CALL _vswprintf_shim(
|
|||
assert_true(arg_size == 8 || arg_size == 4);
|
||||
if (arg_size == 8) {
|
||||
if (arg_extras == 0) {
|
||||
uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint64_t value = SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
int result = wsprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (arg_size == 4) {
|
||||
} else if (arg_size == 4) {
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
int result = wsprintf(b, local, value);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*end == 'n')
|
||||
{
|
||||
} else if (*end == 'n') {
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(wchar_t)));
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (*end == 'p') {
|
||||
} else if (*end == 'p') {
|
||||
wchar_t local[512];
|
||||
local[0] = '\0';
|
||||
wcsncat(local, start, end + 1 - start);
|
||||
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
const void* pointer = (void*)SHIM_MEM_ADDR(value);
|
||||
int result = wsprintf(b, local, pointer);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else if (*end == 's') {
|
||||
} else if (*end == 's') {
|
||||
wchar_t local[512];
|
||||
local[0] = '\0';
|
||||
wcsncat(local, start, end + 1 - start);
|
||||
|
||||
assert_true(arg_size == 4);
|
||||
if (arg_extras == 0) {
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
uint32_t value = (uint32_t)SHIM_MEM_64(
|
||||
arg_ptr + (arg_index * 8)); // TODO: check if this is correct...
|
||||
const wchar_t* data = (const wchar_t*)SHIM_MEM_ADDR(value);
|
||||
size_t data_length = wcslen(data);
|
||||
wchar_t* swapped_data = (wchar_t*)xe_malloc((data_length + 1) * sizeof(wchar_t));
|
||||
wchar_t* swapped_data =
|
||||
(wchar_t*)xe_malloc((data_length + 1) * sizeof(wchar_t));
|
||||
for (size_t i = 0; i < data_length; ++i) {
|
||||
swapped_data[i] = poly::byte_swap(data[i]);
|
||||
}
|
||||
|
@ -679,12 +596,10 @@ SHIM_CALL _vswprintf_shim(
|
|||
xe_free(swapped_data);
|
||||
b += result;
|
||||
arg_index++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_true(false);
|
||||
break;
|
||||
}
|
||||
|
@ -695,19 +610,16 @@ SHIM_CALL _vswprintf_shim(
|
|||
xe_free(swapped_format);
|
||||
|
||||
// swap the result buffer
|
||||
for (wchar_t* swap = buffer; swap != b; ++swap)
|
||||
{
|
||||
for (wchar_t* swap = buffer; swap != b; ++swap) {
|
||||
*swap = poly::byte_swap(*swap);
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32((uint32_t)((b - buffer) / sizeof(wchar_t)));
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterStringExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", vsprintf, state);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,27 +14,21 @@
|
|||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
SHIM_CALL XUsbcamCreate_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL XUsbcamCreate_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk1 = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk2 = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"XUsbcamCreate(%.8X, %.8X)",
|
||||
unk1, unk2);
|
||||
XELOGD("XUsbcamCreate(%.8X, %.8X)", unk1, unk2);
|
||||
|
||||
SHIM_SET_RETURN_32(-1);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterUsbcamExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", XUsbcamCreate, state);
|
||||
|
|
|
@ -19,13 +19,11 @@
|
|||
#include <xenia/kernel/xboxkrnl_rtl.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
using xe::gpu::GraphicsSystem;
|
||||
|
||||
|
||||
// http://www.tweakoz.com/orkid/
|
||||
// http://www.tweakoz.com/orkid/dox/d3/d52/xb360init_8cpp_source.html
|
||||
// https://github.com/Free60Project/xenosfb/
|
||||
|
@ -36,30 +34,25 @@ using xe::gpu::GraphicsSystem;
|
|||
// http://web.archive.org/web/20100423054747/http://msdn.microsoft.com/en-us/library/bb313878.aspx
|
||||
// http://web.archive.org/web/20090510235238/http://msdn.microsoft.com/en-us/library/bb313942.aspx
|
||||
// http://svn.dd-wrt.com/browser/src/linux/universal/linux-3.8/drivers/gpu/drm/radeon/radeon_ring.c
|
||||
// http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped Down Direct3D: Xbox 360 Command Buffer and Resource Management"
|
||||
// http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped
|
||||
// Down Direct3D: Xbox 360 Command Buffer and Resource Management"
|
||||
|
||||
|
||||
SHIM_CALL VdGetCurrentDisplayGamma_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdGetCurrentDisplayGamma_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t arg0_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t arg1_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"VdGetCurrentDisplayGamma(%.8X, %.8X)",
|
||||
arg0_ptr, arg1_ptr);
|
||||
XELOGD("VdGetCurrentDisplayGamma(%.8X, %.8X)", arg0_ptr, arg1_ptr);
|
||||
|
||||
SHIM_SET_MEM_32(arg0_ptr, 2);
|
||||
SHIM_SET_MEM_F32(arg1_ptr, 2.22222233f);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdGetCurrentDisplayInformation_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdGetCurrentDisplayInformation_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"VdGetCurrentDisplayInformation(%.8X)",
|
||||
ptr);
|
||||
XELOGD("VdGetCurrentDisplayInformation(%.8X)", ptr);
|
||||
|
||||
// Expecting a length 0x58 struct of stuff.
|
||||
SHIM_SET_MEM_32(ptr + 0, (1280 << 16) | 720);
|
||||
|
@ -86,16 +79,12 @@ SHIM_CALL VdGetCurrentDisplayInformation_shim(
|
|||
SHIM_SET_MEM_32(ptr + 84, 1280); // display width
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdQueryVideoFlags_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD(
|
||||
"VdQueryVideoFlags()");
|
||||
SHIM_CALL VdQueryVideoFlags_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("VdQueryVideoFlags()");
|
||||
|
||||
SHIM_SET_RETURN_64(0x00000006);
|
||||
}
|
||||
|
||||
|
||||
void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) {
|
||||
if (video_mode == NULL) {
|
||||
return;
|
||||
|
@ -124,31 +113,24 @@ void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) {
|
|||
video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdQueryVideoMode_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdQueryVideoMode_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t video_mode_ptr = SHIM_GET_ARG_32(0);
|
||||
X_VIDEO_MODE* video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(video_mode_ptr);
|
||||
|
||||
XELOGD(
|
||||
"VdQueryVideoMode(%.8X)",
|
||||
video_mode_ptr);
|
||||
XELOGD("VdQueryVideoMode(%.8X)", video_mode_ptr);
|
||||
|
||||
xeVdQueryVideoMode(video_mode);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdInitializeEngines_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdInitializeEngines_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t callback = SHIM_GET_ARG_32(1);
|
||||
uint32_t unk1 = SHIM_GET_ARG_32(2);
|
||||
uint32_t unk2_ptr = SHIM_GET_ARG_32(3);
|
||||
uint32_t unk3_ptr = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
"VdInitializeEngines(%.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
unk0, callback, unk1, unk2_ptr, unk3_ptr);
|
||||
XELOGD("VdInitializeEngines(%.8X, %.8X, %.8X, %.8X, %.8X)", unk0, callback,
|
||||
unk1, unk2_ptr, unk3_ptr);
|
||||
|
||||
// r3 = 0x4F810000
|
||||
// r4 = function ptr (cleanup callback?)
|
||||
|
@ -156,26 +138,20 @@ SHIM_CALL VdInitializeEngines_shim(
|
|||
// r6/r7 = some binary data in .data
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdShutdownEngines_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD(
|
||||
"VdShutdownEngines()");
|
||||
SHIM_CALL VdShutdownEngines_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("VdShutdownEngines()");
|
||||
|
||||
// Ignored for now.
|
||||
// Games seem to call an Initialize/Shutdown pair to query info, then
|
||||
// re-initialize.
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdSetGraphicsInterruptCallback_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdSetGraphicsInterruptCallback_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t callback = SHIM_GET_ARG_32(0);
|
||||
uint32_t user_data = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"VdSetGraphicsInterruptCallback(%.8X, %.8X)",
|
||||
callback, user_data);
|
||||
XELOGD("VdSetGraphicsInterruptCallback(%.8X, %.8X)", callback, user_data);
|
||||
|
||||
GraphicsSystem* gs = state->emulator()->graphics_system();
|
||||
if (!gs) {
|
||||
|
@ -189,15 +165,12 @@ SHIM_CALL VdSetGraphicsInterruptCallback_shim(
|
|||
gs->SetInterruptCallback(callback, user_data);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdInitializeRingBuffer_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdInitializeRingBuffer_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t page_count = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"VdInitializeRingBuffer(%.8X, %.8X)",
|
||||
ptr, page_count);
|
||||
XELOGD("VdInitializeRingBuffer(%.8X, %.8X)", ptr, page_count);
|
||||
|
||||
GraphicsSystem* gs = state->emulator()->graphics_system();
|
||||
if (!gs) {
|
||||
|
@ -214,15 +187,12 @@ SHIM_CALL VdInitializeRingBuffer_shim(
|
|||
gs->InitializeRingBuffer(ptr, page_count);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t block_size = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)",
|
||||
ptr, block_size);
|
||||
XELOGD("VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", ptr, block_size);
|
||||
|
||||
GraphicsSystem* gs = state->emulator()->graphics_system();
|
||||
if (!gs) {
|
||||
|
@ -242,90 +212,74 @@ SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(
|
|||
// also 0x3C offset into WriteBacks is PrimaryRingBufferReadIndex
|
||||
//(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31)
|
||||
//(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C
|
||||
//(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20
|
||||
//(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF
|
||||
//(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 #
|
||||
//r10 = r11 >> 20
|
||||
//(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 #
|
||||
//r11 = r11 & 0x1FFFFFFF
|
||||
//(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200
|
||||
//(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000
|
||||
//(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10,
|
||||
//0,19,19 # r10 = r10 & 0x1000
|
||||
//(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11
|
||||
//(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack
|
||||
//(1:17:39 AM) Rick: .text:8201B364 bl
|
||||
//VdEnableRingBufferRPtrWriteBack
|
||||
// TODO(benvanik): something?
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdGetSystemCommandBuffer_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdGetSystemCommandBuffer_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
uint32_t p0_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t p1_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
"VdGetSystemCommandBuffer(%.8X, %.8X)",
|
||||
p0_ptr,
|
||||
p1_ptr);
|
||||
XELOGD("VdGetSystemCommandBuffer(%.8X, %.8X)", p0_ptr, p1_ptr);
|
||||
|
||||
SHIM_SET_MEM_32(p0_ptr, 0xBEEF0000);
|
||||
SHIM_SET_MEM_32(p1_ptr, 0xBEEF0001);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdSetSystemCommandBufferGpuIdentifierAddress_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"VdSetSystemCommandBufferGpuIdentifierAddress(%.8X)",
|
||||
unk);
|
||||
XELOGD("VdSetSystemCommandBufferGpuIdentifierAddress(%.8X)", unk);
|
||||
|
||||
// r3 = 0x2B10(d3d?) + 8
|
||||
}
|
||||
|
||||
|
||||
// VdVerifyMEInitCommand
|
||||
// r3
|
||||
// r4 = 19
|
||||
// no op?
|
||||
|
||||
|
||||
// VdCallGraphicsNotificationRoutines
|
||||
// r3 = 1
|
||||
// r4 = ?
|
||||
// callbacks get 0, r3, r4
|
||||
|
||||
|
||||
SHIM_CALL VdIsHSIOTrainingSucceeded_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD(
|
||||
"VdIsHSIOTrainingSucceeded()");
|
||||
SHIM_CALL VdIsHSIOTrainingSucceeded_shim(PPCContext* ppc_state,
|
||||
KernelState* state) {
|
||||
XELOGD("VdIsHSIOTrainingSucceeded()");
|
||||
|
||||
// Not really sure what this should be - code does weird stuff here:
|
||||
// (cntlzw r11, r3 / extrwi r11, r11, 1, 26)
|
||||
SHIM_SET_RETURN_64(1);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdPersistDisplay_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD(
|
||||
"VdPersistDisplay(?)");
|
||||
SHIM_CALL VdPersistDisplay_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
XELOGD("VdPersistDisplay(?)");
|
||||
|
||||
// ?
|
||||
SHIM_SET_RETURN_64(1);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdRetrainEDRAMWorker_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdRetrainEDRAMWorker_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk0 = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
"VdRetrainEDRAMWorker(%.8X)",
|
||||
unk0);
|
||||
XELOGD("VdRetrainEDRAMWorker(%.8X)", unk0);
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdRetrainEDRAM_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdRetrainEDRAM_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk0 = SHIM_GET_ARG_32(0);
|
||||
uint32_t unk1 = SHIM_GET_ARG_32(1);
|
||||
uint32_t unk2 = SHIM_GET_ARG_32(2);
|
||||
|
@ -333,16 +287,13 @@ SHIM_CALL VdRetrainEDRAM_shim(
|
|||
uint32_t unk4 = SHIM_GET_ARG_32(4);
|
||||
uint32_t unk5 = SHIM_GET_ARG_32(5);
|
||||
|
||||
XELOGD(
|
||||
"VdRetrainEDRAM(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
unk0, unk1, unk2, unk3, unk4, unk5);
|
||||
XELOGD("VdRetrainEDRAM(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", unk0, unk1, unk2,
|
||||
unk3, unk4, unk5);
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL VdSwap_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
SHIM_CALL VdSwap_shim(PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t unk0 = SHIM_GET_ARG_32(0); // ptr into primary ringbuffer
|
||||
uint32_t unk1 = SHIM_GET_ARG_32(1);
|
||||
uint32_t unk2 = SHIM_GET_ARG_32(2);
|
||||
|
@ -352,16 +303,8 @@ SHIM_CALL VdSwap_shim(
|
|||
uint32_t unk6 = SHIM_GET_ARG_32(6);
|
||||
uint32_t unk7 = SHIM_GET_ARG_32(7);
|
||||
|
||||
XELOGD(
|
||||
"VdSwap(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||
unk0,
|
||||
unk1,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
unk5,
|
||||
unk6,
|
||||
unk7);
|
||||
XELOGD("VdSwap(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", unk0, unk1,
|
||||
unk2, unk3, unk4, unk5, unk6, unk7);
|
||||
|
||||
// The caller seems to reserve 64 words (256b) in the primary ringbuffer
|
||||
// for this method to do what it needs. We just zero them out and send a
|
||||
|
@ -370,20 +313,17 @@ SHIM_CALL VdSwap_shim(
|
|||
// use this method.
|
||||
xe_zero_struct(SHIM_MEM_ADDR(unk0), 64 * 4);
|
||||
auto dwords = reinterpret_cast<uint32_t*>(SHIM_MEM_ADDR(unk0));
|
||||
dwords[0] = poly::byte_swap((0x03 << 30) |
|
||||
((1 - 1) << 16) |
|
||||
dwords[0] = poly::byte_swap((0x03 << 30) | ((1 - 1) << 16) |
|
||||
(xe::gpu::xenos::PM4_XE_SWAP << 8));
|
||||
|
||||
SHIM_SET_RETURN_64(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterVideoExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
|
||||
KernelState* state) {
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdGetCurrentDisplayGamma, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdGetCurrentDisplayInformation, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdQueryVideoFlags, state);
|
||||
|
@ -394,8 +334,8 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(
|
|||
SHIM_SET_MAPPING("xboxkrnl.exe", VdInitializeRingBuffer, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdEnableRingBufferRPtrWriteBack, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdGetSystemCommandBuffer, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe",
|
||||
VdSetSystemCommandBufferGpuIdentifierAddress, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdSetSystemCommandBufferGpuIdentifierAddress,
|
||||
state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdIsHSIOTrainingSucceeded, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdPersistDisplay, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdRetrainEDRAMWorker, state);
|
||||
|
|
|
@ -14,16 +14,15 @@
|
|||
#include <xenia/kernel/objects/xmutant.h>
|
||||
#include <xenia/kernel/objects/xsemaphore.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
XObject::XObject(KernelState* kernel_state, Type type) :
|
||||
kernel_state_(kernel_state),
|
||||
XObject::XObject(KernelState* kernel_state, Type type)
|
||||
: kernel_state_(kernel_state),
|
||||
handle_ref_count_(0),
|
||||
pointer_ref_count_(1),
|
||||
type_(type), handle_(X_INVALID_HANDLE_VALUE) {
|
||||
type_(type),
|
||||
handle_(X_INVALID_HANDLE_VALUE) {
|
||||
kernel_state->object_table()->AddHandle(this, &handle_);
|
||||
}
|
||||
|
||||
|
@ -32,21 +31,13 @@ XObject::~XObject() {
|
|||
assert_zero(pointer_ref_count_);
|
||||
}
|
||||
|
||||
Memory* XObject::memory() const {
|
||||
return kernel_state_->memory();
|
||||
}
|
||||
Memory* XObject::memory() const { return kernel_state_->memory(); }
|
||||
|
||||
XObject::Type XObject::type() {
|
||||
return type_;
|
||||
}
|
||||
XObject::Type XObject::type() { return type_; }
|
||||
|
||||
X_HANDLE XObject::handle() const {
|
||||
return handle_;
|
||||
}
|
||||
X_HANDLE XObject::handle() const { return handle_; }
|
||||
|
||||
void XObject::RetainHandle() {
|
||||
++handle_ref_count_;
|
||||
}
|
||||
void XObject::RetainHandle() { ++handle_ref_count_; }
|
||||
|
||||
bool XObject::ReleaseHandle() {
|
||||
if (--handle_ref_count_ == 0) {
|
||||
|
@ -55,9 +46,7 @@ bool XObject::ReleaseHandle() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void XObject::Retain() {
|
||||
++pointer_ref_count_;
|
||||
}
|
||||
void XObject::Retain() { ++pointer_ref_count_; }
|
||||
|
||||
void XObject::Release() {
|
||||
if (--pointer_ref_count_ == 0) {
|
||||
|
@ -92,8 +81,7 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
|||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD timeout_ms = opt_timeout ?
|
||||
TimeoutTicksToMs(*opt_timeout) : INFINITE;
|
||||
DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE;
|
||||
|
||||
DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable);
|
||||
switch (result) {
|
||||
|
@ -111,38 +99,32 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
|||
}
|
||||
}
|
||||
|
||||
X_STATUS XObject::SignalAndWait(
|
||||
XObject* signal_object, XObject* wait_object,
|
||||
uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t* opt_timeout) {
|
||||
DWORD timeout_ms = opt_timeout ?
|
||||
TimeoutTicksToMs(*opt_timeout) : INFINITE;
|
||||
X_STATUS XObject::SignalAndWait(XObject* signal_object, XObject* wait_object,
|
||||
uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout) {
|
||||
DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE;
|
||||
|
||||
DWORD result = SignalObjectAndWait(
|
||||
signal_object->GetWaitHandle(),
|
||||
wait_object->GetWaitHandle(),
|
||||
timeout_ms,
|
||||
DWORD result = SignalObjectAndWait(signal_object->GetWaitHandle(),
|
||||
wait_object->GetWaitHandle(), timeout_ms,
|
||||
alertable ? TRUE : FALSE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
X_STATUS XObject::WaitMultiple(
|
||||
uint32_t count, XObject** objects,
|
||||
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout) {
|
||||
X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
|
||||
uint32_t wait_type, uint32_t wait_reason,
|
||||
uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t* opt_timeout) {
|
||||
void** wait_handles = (void**)alloca(sizeof(void*) * count);
|
||||
for (uint32_t n = 0; n < count; n++) {
|
||||
wait_handles[n] = objects[n]->GetWaitHandle();
|
||||
assert_not_null(wait_handles[n]);
|
||||
}
|
||||
|
||||
DWORD timeout_ms = opt_timeout ?
|
||||
TimeoutTicksToMs(*opt_timeout) : INFINITE;
|
||||
DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE;
|
||||
|
||||
DWORD result = WaitForMultipleObjectsEx(
|
||||
count, wait_handles,
|
||||
wait_type ? FALSE : TRUE, timeout_ms, alertable);
|
||||
count, wait_handles, wait_type ? FALSE : TRUE, timeout_ms, alertable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -164,7 +146,8 @@ void XObject::SetNativePointer(uint32_t native_ptr) {
|
|||
uint64_t object_ptr = reinterpret_cast<uint64_t>(this);
|
||||
object_ptr |= 0x1;
|
||||
header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32));
|
||||
header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||
header_be->wait_list_blink =
|
||||
poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||
}
|
||||
|
||||
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||
|
@ -193,8 +176,7 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
|||
|
||||
if (header.wait_list_blink & 0x1) {
|
||||
// Already initialized.
|
||||
uint64_t object_ptr =
|
||||
((uint64_t)header.wait_list_flink << 32) |
|
||||
uint64_t object_ptr = ((uint64_t)header.wait_list_flink << 32) |
|
||||
((header.wait_list_blink) & ~0x1);
|
||||
XObject* object = reinterpret_cast<XObject*>(object_ptr);
|
||||
// TODO(benvanik): assert nothing has been changed in the struct.
|
||||
|
@ -210,22 +192,19 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
|||
XEvent* ev = new XEvent(kernel_state);
|
||||
ev->InitializeNative(native_ptr, header);
|
||||
object = ev;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case 2: // MutantObject
|
||||
{
|
||||
XMutant* mutant = new XMutant(kernel_state);
|
||||
mutant->InitializeNative(native_ptr, header);
|
||||
object = mutant;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case 5: // SemaphoreObject
|
||||
{
|
||||
XSemaphore* sem = new XSemaphore(kernel_state);
|
||||
sem->InitializeNative(native_ptr, header);
|
||||
object = sem;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case 3: // ProcessObject
|
||||
case 4: // QueueObject
|
||||
case 6: // ThreadObject
|
||||
|
@ -248,7 +227,8 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
|||
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
|
||||
object_ptr |= 0x1;
|
||||
header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32));
|
||||
header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||
header_be->wait_list_blink =
|
||||
poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
// http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
|
||||
typedef struct {
|
||||
uint32_t type_flags;
|
||||
|
@ -29,7 +27,6 @@ typedef struct {
|
|||
uint32_t wait_list_blink;
|
||||
} DISPATCH_HEADER;
|
||||
|
||||
|
||||
class XObject {
|
||||
public:
|
||||
enum Type {
|
||||
|
@ -62,17 +59,15 @@ public:
|
|||
// Reference()
|
||||
// Dereference()
|
||||
|
||||
X_STATUS Wait(
|
||||
uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t* opt_timeout);
|
||||
static X_STATUS SignalAndWait(
|
||||
XObject* signal_object, XObject* wait_object,
|
||||
uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t* opt_timeout);
|
||||
static X_STATUS WaitMultiple(
|
||||
uint32_t count, XObject** objects,
|
||||
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
||||
X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout);
|
||||
static X_STATUS SignalAndWait(XObject* signal_object, XObject* wait_object,
|
||||
uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout);
|
||||
static X_STATUS WaitMultiple(uint32_t count, XObject** objects,
|
||||
uint32_t wait_type, uint32_t wait_reason,
|
||||
uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t* opt_timeout);
|
||||
|
||||
static XObject* GetObject(KernelState* kernel_state, void* native_ptr,
|
||||
int32_t as_type = -1);
|
||||
|
@ -95,9 +90,7 @@ private:
|
|||
X_HANDLE handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XOBJECT_H_
|
||||
|
|
Loading…
Reference in New Issue