Massive refactoring of all code + audio skeleton.

This should make it easier to find files and (in the future) split things
up into separate libraries.
It also changes around emulator initialization to make it a little more
difficult to do things out of order and a little more sensible as to when
real init work happens.
Also adding a skeleton audio system/driver and reworking CPU register
access to be more extensible.
This commit is contained in:
Ben Vanik 2013-10-23 20:42:24 -07:00
parent c996a4bbaf
commit b7ffd46319
182 changed files with 3919 additions and 3286 deletions

View File

@ -7,9 +7,13 @@
******************************************************************************
*/
#include <xenia/gpu/xenos/ucode.h>
#ifndef XENIA_APU_APU_PRIVATE_H_
#define XENIA_APU_APU_PRIVATE_H_
#include <gflags/gflags.h>
using namespace xe;
using namespace xe::gpu;
using namespace xe::gpu::xenos;
DECLARE_string(apu);
#endif // XENIA_APU_APU_PRIVATE_H_

39
src/xenia/apu/apu.cc Normal file
View File

@ -0,0 +1,39 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/apu/apu.h>
#include <xenia/apu/apu-private.h>
using namespace xe;
using namespace xe::apu;
DEFINE_string(apu, "any",
"Audio system. Use: [any, nop]");
#include <xenia/apu/nop/nop_apu.h>
AudioSystem* xe::apu::CreateNop(Emulator* emulator) {
return xe::apu::nop::Create(emulator);
}
AudioSystem* xe::apu::Create(Emulator* emulator) {
if (FLAGS_apu.compare("nop") == 0) {
return CreateNop(emulator);
} else {
// Create best available.
AudioSystem* best = NULL;
// Fallback to nop.
return CreateNop(emulator);
}
}

32
src/xenia/apu/apu.h Normal file
View File

@ -0,0 +1,32 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_APU_APU_H_
#define XENIA_APU_APU_H_
#include <xenia/apu/audio_system.h>
XEDECLARECLASS1(xe, Emulator);
namespace xe {
namespace apu {
AudioSystem* Create(Emulator* emulator);
AudioSystem* CreateNop(Emulator* emulator);
} // namespace apu
} // namespace xe
#endif // XENIA_APU_APU_H_

View File

@ -0,0 +1,23 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/apu/audio_driver.h>
using namespace xe;
using namespace xe::apu;
AudioDriver::AudioDriver(xe_memory_ref memory) {
memory_ = xe_memory_retain(memory);
}
AudioDriver::~AudioDriver() {
xe_memory_release(memory_);
}

View File

@ -0,0 +1,39 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_APU_AUDIO_DRIVER_H_
#define XENIA_APU_AUDIO_DRIVER_H_
#include <xenia/core.h>
namespace xe {
namespace apu {
class AudioDriver {
public:
virtual ~AudioDriver();
xe_memory_ref memory() const { return memory_; }
virtual void Initialize() = 0;
protected:
AudioDriver(xe_memory_ref memory);
xe_memory_ref memory_;
};
} // namespace apu
} // namespace xe
#endif // XENIA_APU_AUDIO_DRIVER_H_

View File

@ -0,0 +1,116 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/apu/audio_system.h>
#include <xenia/emulator.h>
#include <xenia/cpu/processor.h>
#include <xenia/apu/audio_driver.h>
using namespace xe;
using namespace xe::apu;
using namespace xe::cpu::ppc;
AudioSystem::AudioSystem(Emulator* emulator) :
emulator_(emulator),
thread_(0), running_(false), driver_(0) {
memory_ = xe_memory_retain(emulator->memory());
// Create the run loop used for any windows/etc.
// This must be done on the thread we create the driver.
run_loop_ = xe_run_loop_create();
}
AudioSystem::~AudioSystem() {
// TODO(benvanik): thread join.
running_ = false;
xe_thread_release(thread_);
xe_run_loop_release(run_loop_);
xe_memory_release(memory_);
}
X_STATUS AudioSystem::Setup() {
processor_ = emulator_->processor();
// Let the processor know we want register access callbacks.
RegisterAccessCallbacks callbacks;
callbacks.context = this;
callbacks.handles = (RegisterHandlesCallback)HandlesRegisterThunk;
callbacks.read = (RegisterReadCallback)ReadRegisterThunk;
callbacks.write = (RegisterWriteCallback)WriteRegisterThunk;
emulator_->processor()->AddRegisterAccessCallbacks(callbacks);
// Create worker thread.
// This will initialize the audio system.
// Init needs to happen there so that any thread-local stuff
// is created on the right thread.
running_ = true;
thread_ = xe_thread_create(
"AudioSystem",
(xe_thread_callback)ThreadStartThunk, this);
xe_thread_start(thread_);
return X_STATUS_SUCCESS;
}
void AudioSystem::ThreadStart() {
xe_run_loop_ref run_loop = xe_run_loop_retain(run_loop_);
// Initialize driver and ringbuffer.
Initialize();
XEASSERTNOTNULL(driver_);
// Main run loop.
while (running_) {
// Peek main run loop.
if (xe_run_loop_pump(run_loop)) {
break;
}
if (!running_) {
break;
}
// Pump worker.
//worker_->Pump();
// Pump audio system.
Pump();
}
running_ = false;
Shutdown();
xe_run_loop_release(run_loop);
// TODO(benvanik): call module API to kill?
}
void AudioSystem::Initialize() {
}
void AudioSystem::Shutdown() {
}
bool AudioSystem::HandlesRegister(uint32_t addr) {
return (addr & 0xFFFF0000) == 0x7FEA0000;
}
uint64_t AudioSystem::ReadRegister(uint32_t addr) {
uint32_t r = addr & 0xFFFF;
XELOGAPU("ReadRegister(%.4X)", r);
return 0;
}
void AudioSystem::WriteRegister(uint32_t addr, uint64_t value) {
uint32_t r = addr & 0xFFFF;
XELOGAPU("WriteRegister(%.4X, %.8X)", r, value);
}

View File

@ -0,0 +1,82 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_APU_AUDIO_SYSTEM_H_
#define XENIA_APU_AUDIO_SYSTEM_H_
#include <xenia/core.h>
#include <xenia/xbox.h>
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, cpu, Processor);
namespace xe {
namespace apu {
class AudioDriver;
class AudioSystem {
public:
virtual ~AudioSystem();
Emulator* emulator() const { return emulator_; }
xe_memory_ref memory() const { return memory_; }
cpu::Processor* processor() const { return processor_; }
virtual X_STATUS Setup();
bool HandlesRegister(uint32_t addr);
virtual uint64_t ReadRegister(uint32_t addr);
virtual void WriteRegister(uint32_t addr, uint64_t value);
protected:
virtual void Initialize();
virtual void Pump() = 0;
virtual void Shutdown();
private:
static void ThreadStartThunk(AudioSystem* this_ptr) {
this_ptr->ThreadStart();
}
void ThreadStart();
static bool HandlesRegisterThunk(AudioSystem* as, uint32_t addr) {
return as->HandlesRegister(addr);
}
static uint64_t ReadRegisterThunk(AudioSystem* as, uint32_t addr) {
return as->ReadRegister(addr);
}
static void WriteRegisterThunk(AudioSystem* as, uint32_t addr,
uint64_t value) {
as->WriteRegister(addr, value);
}
protected:
AudioSystem(Emulator* emulator);
Emulator* emulator_;
xe_memory_ref memory_;
cpu::Processor* processor_;
xe_run_loop_ref run_loop_;
xe_thread_ref thread_;
bool running_;
AudioDriver* driver_;
};
} // namespace apu
} // namespace xe
#endif // XENIA_APU_AUDIO_SYSTEM_H_

View File

@ -0,0 +1,31 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_APU_NOP_NOP_APU_PRIVATE_H_
#define XENIA_APU_NOP_NOP_APU_PRIVATE_H_
#include <xenia/core.h>
#include <xenia/apu/nop/nop_apu.h>
namespace xe {
namespace apu {
namespace nop {
} // namespace nop
} // namespace apu
} // namespace xe
#endif // XENIA_APU_NOP_NOP_APU_PRIVATE_H_

View File

@ -0,0 +1,44 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/apu/nop/nop_apu.h>
#include <xenia/apu/nop/nop_audio_system.h>
using namespace xe;
using namespace xe::apu;
using namespace xe::apu::nop;
namespace {
void InitializeIfNeeded();
void CleanupOnShutdown();
void InitializeIfNeeded() {
static bool has_initialized = false;
if (has_initialized) {
return;
}
has_initialized = true;
//
atexit(CleanupOnShutdown);
}
void CleanupOnShutdown() {
}
}
AudioSystem* xe::apu::nop::Create(Emulator* emulator) {
InitializeIfNeeded();
return new NopAudioSystem(emulator);
}

View File

@ -13,20 +13,20 @@
#include <xenia/core.h>
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, apu, AudioSystem);
namespace xe {
namespace gpu {
class CreationParams;
class GraphicsSystem;
namespace apu {
namespace nop {
GraphicsSystem* Create(const CreationParams* params);
AudioSystem* Create(Emulator* emulator);
} // namespace nop
} // namespace gpu
} // namespace apu
} // namespace xe

View File

@ -0,0 +1,28 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/apu/nop/nop_audio_driver.h>
#include <xenia/apu/apu-private.h>
using namespace xe;
using namespace xe::apu;
using namespace xe::apu::nop;
NopAudioDriver::NopAudioDriver(xe_memory_ref memory) :
AudioDriver(memory) {
}
NopAudioDriver::~NopAudioDriver() {
}
void NopAudioDriver::Initialize() {
}

View File

@ -0,0 +1,40 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_APU_NOP_NOP_AUDIO_DRIVER_H_
#define XENIA_APU_NOP_NOP_AUDIO_DRIVER_H_
#include <xenia/core.h>
#include <xenia/apu/audio_driver.h>
#include <xenia/apu/nop/nop_apu-private.h>
namespace xe {
namespace apu {
namespace nop {
class NopAudioDriver : public AudioDriver {
public:
NopAudioDriver(xe_memory_ref memory);
virtual ~NopAudioDriver();
virtual void Initialize();
protected:
};
} // namespace nop
} // namespace apu
} // namespace xe
#endif // XENIA_APU_NOP_NOP_AUDIO_DRIVER_H_

View File

@ -0,0 +1,40 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/apu/nop/nop_audio_system.h>
#include <xenia/apu/apu-private.h>
#include <xenia/apu/nop/nop_audio_driver.h>
using namespace xe;
using namespace xe::apu;
using namespace xe::apu::nop;
NopAudioSystem::NopAudioSystem(Emulator* emulator) :
AudioSystem(emulator) {
}
NopAudioSystem::~NopAudioSystem() {
}
void NopAudioSystem::Initialize() {
AudioSystem::Initialize();
XEASSERTNULL(driver_);
driver_ = new NopAudioDriver(memory_);
}
void NopAudioSystem::Pump() {
}
void NopAudioSystem::Shutdown() {
AudioSystem::Shutdown();
}

View File

@ -0,0 +1,43 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_APU_NOP_NOP_AUDIO_SYSTEM_H_
#define XENIA_APU_NOP_NOP_AUDIO_SYSTEM_H_
#include <xenia/core.h>
#include <xenia/apu/audio_system.h>
#include <xenia/apu/nop/nop_apu-private.h>
namespace xe {
namespace apu {
namespace nop {
class NopAudioSystem : public AudioSystem {
public:
NopAudioSystem(Emulator* emulator);
virtual ~NopAudioSystem();
protected:
virtual void Initialize();
virtual void Pump();
virtual void Shutdown();
private:
};
} // namespace nop
} // namespace apu
} // namespace xe
#endif // XENIA_APU_NOP_NOP_AUDIO_SYSTEM_H_

View File

@ -0,0 +1,12 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'nop_apu-private.h',
'nop_apu.cc',
'nop_apu.h',
'nop_audio_driver.cc',
'nop_audio_driver.h',
'nop_audio_system.cc',
'nop_audio_system.h',
],
}

View File

@ -0,0 +1,23 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'apu-private.h',
'apu.cc',
'apu.h',
'audio_driver.cc',
'audio_driver.h',
'audio_system.cc',
'audio_system.h',
],
'includes': [
'nop/sources.gypi',
],
'conditions': [
['OS == "win"', {
'includes': [
],
}],
],
}

View File

@ -24,6 +24,7 @@
#define XE_OPTION_LOG_DEBUG 1
#define XE_OPTION_LOG_CPU 1
#define XE_OPTION_LOG_SDB 0
#define XE_OPTION_LOG_APU 1
#define XE_OPTION_LOG_GPU 1
#define XE_OPTION_LOG_KERNEL 1
#define XE_OPTION_LOG_FS 1

View File

@ -15,7 +15,7 @@
#include <xenia/core/crc32.h>
#include <xenia/core/file.h>
#include <xenia/core/hash.h>
#include <xenia/core/memory.h>
#include <xenia/memory.h>
#include <xenia/core/mmap.h>
#include <xenia/core/mutex.h>
#include <xenia/core/pal.h>

View File

@ -7,8 +7,6 @@
'file.h',
'hash.cc',
'hash.h',
'memory.cc',
'memory.h',
'mmap.h',
'mutex.h',
'pal.h',

View File

@ -12,7 +12,7 @@
#include <xenia/common.h>
#include <xenia/core/memory.h>
#include <xenia/memory.h>
namespace xe {

View File

@ -16,11 +16,10 @@
using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
ExecModule::ExecModule(
xe_memory_ref memory, shared_ptr<ExportResolver> export_resolver,
xe_memory_ref memory, ExportResolver* export_resolver,
SymbolTable* sym_table,
const char* module_name, const char* module_path) {
memory_ = xe_memory_retain(memory);
@ -42,7 +41,7 @@ SymbolDatabase* ExecModule::sdb() {
int ExecModule::PrepareRawBinary(uint32_t start_address, uint32_t end_address) {
sdb_ = shared_ptr<sdb::SymbolDatabase>(
new sdb::RawSymbolDatabase(memory_, export_resolver_.get(),
new sdb::RawSymbolDatabase(memory_, export_resolver_,
sym_table_, start_address, end_address));
code_addr_low_ = start_address;
@ -53,7 +52,7 @@ int ExecModule::PrepareRawBinary(uint32_t start_address, uint32_t end_address) {
int ExecModule::PrepareXexModule(xe_xex2_ref xex) {
sdb_ = shared_ptr<sdb::SymbolDatabase>(
new sdb::XexSymbolDatabase(memory_, export_resolver_.get(),
new sdb::XexSymbolDatabase(memory_, export_resolver_,
sym_table_, xex));
code_addr_low_ = UINT_MAX;

View File

@ -13,8 +13,8 @@
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/export_resolver.h>
#include <xenia/cpu/sdb.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/xex2.h>
@ -25,7 +25,7 @@ namespace cpu {
class ExecModule {
public:
ExecModule(
xe_memory_ref memory, shared_ptr<kernel::ExportResolver> export_resolver,
xe_memory_ref memory, ExportResolver* export_resolver,
sdb::SymbolTable* sym_table,
const char* module_name, const char* module_path);
~ExecModule();
@ -44,7 +44,7 @@ private:
int Init();
xe_memory_ref memory_;
shared_ptr<kernel::ExportResolver> export_resolver_;
ExportResolver* export_resolver_;
sdb::SymbolTable* sym_table_;
char* module_name_;
char* module_path_;

View File

@ -15,13 +15,12 @@
#include <xenia/cpu/sdb.h>
#include <xenia/cpu/ppc/instr.h>
#include <xenia/cpu/ppc/state.h>
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
namespace {

View File

@ -13,9 +13,9 @@
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/export_resolver.h>
#include <xenia/cpu/ppc/state.h>
#include <xenia/cpu/sdb/symbol.h>
#include <xenia/kernel/export.h>
namespace xe {
@ -33,7 +33,7 @@ typedef struct {
xe_ppc_state_t* state, uint64_t cia, uint64_t ea);
void (_cdecl *XeTraceKernelCall)(
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
kernel::KernelExport* kernel_export);
KernelExport* kernel_export);
void (_cdecl *XeTraceUserCall)(
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
sdb::FunctionSymbol* fn);

View File

@ -30,8 +30,8 @@ public:
}
virtual int Setup() = 0;
virtual void SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write) = 0;
virtual void AddRegisterAccessCallbacks(
ppc::RegisterAccessCallbacks callbacks) = 0;
virtual int InitModule(ExecModule* module) = 0;
virtual int UninitModule(ExecModule* module) = 0;

View File

@ -13,6 +13,7 @@
#include <xenia/common.h>
#include <xenia/cpu/ppc/instr.h>
#include <xenia/cpu/ppc/registers.h>
#include <xenia/cpu/ppc/state.h>
#endif // XENIA_CPU_PPC_H_

View File

@ -0,0 +1,40 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_CPU_PPC_REGISTERS_H_
#define XENIA_CPU_PPC_REGISTERS_H_
#include <xenia/common.h>
namespace xe {
namespace cpu {
namespace ppc {
typedef bool (*RegisterHandlesCallback)(void* context, uint32_t addr);
typedef uint64_t (*RegisterReadCallback)(void* context, uint32_t addr);
typedef void (*RegisterWriteCallback)(void* context, uint32_t addr,
uint64_t value);
typedef struct {
void* context;
RegisterHandlesCallback handles;
RegisterReadCallback read;
RegisterWriteCallback write;
} RegisterAccessCallbacks;
} // namespace ppc
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_PPC_REGISTERS_H_

View File

@ -10,6 +10,7 @@
'instr.cc',
'instr.h',
'instr_tables.h',
'registers.h',
'state.cc',
'state.h',
],

View File

@ -13,12 +13,8 @@
#include <stdint.h>
namespace xe {
namespace cpu {
class Processor;
class ThreadState;
} // namespace cpu
} // namespace xe
XEDECLARECLASS2(xe, cpu, Processor);
XEDECLARECLASS2(xe, cpu, ThreadState);
// namespace FPRF {

View File

@ -9,16 +9,15 @@
#include <xenia/cpu/processor.h>
#include <xenia/emulator.h>
#include <xenia/cpu/jit.h>
#include <xenia/cpu/ppc/disasm.h>
#include <xenia/cpu/ppc/state.h>
#include <xenia/gpu/graphics_system.h>
using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
namespace {
@ -46,11 +45,14 @@ namespace {
}
Processor::Processor(xe_memory_ref memory, shared_ptr<Backend> backend) :
Processor::Processor(Emulator* emulator, Backend* backend) :
sym_table_(NULL), jit_(NULL),
interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL) {
memory_ = xe_memory_retain(memory);
emulator_ = emulator;
backend_ = backend;
memory_ = xe_memory_retain(emulator->memory());
export_resolver_ = emulator->export_resolver();
sym_lock_ = xe_mutex_alloc(10000);
InitializeIfNeeded();
@ -76,34 +78,9 @@ Processor::~Processor() {
delete sym_table_;
xe_mutex_free(sym_lock_);
graphics_system_.reset();
export_resolver_.reset();
backend_.reset();
xe_memory_release(memory_);
}
xe_memory_ref Processor::memory() {
return xe_memory_retain(memory_);
}
shared_ptr<gpu::GraphicsSystem> Processor::graphics_system() {
return graphics_system_;
}
void Processor::set_graphics_system(
shared_ptr<gpu::GraphicsSystem> graphics_system) {
graphics_system_ = graphics_system;
}
shared_ptr<ExportResolver> Processor::export_resolver() {
return export_resolver_;
}
void Processor::set_export_resolver(
shared_ptr<ExportResolver> export_resolver) {
export_resolver_ = export_resolver;
}
int Processor::Setup() {
XEASSERTNULL(jit_);
@ -121,15 +98,15 @@ int Processor::Setup() {
return 1;
}
XEASSERTNOTNULL(graphics_system_.get());
jit_->SetupGpuPointers(
graphics_system_.get(),
(void*)&xe::gpu::GraphicsSystem::ReadRegisterThunk,
(void*)&xe::gpu::GraphicsSystem::WriteRegisterThunk);
return 0;
}
void Processor::AddRegisterAccessCallbacks(
ppc::RegisterAccessCallbacks callbacks) {
XEASSERTNOTNULL(jit_);
jit_->AddRegisterAccessCallbacks(callbacks);
}
int Processor::LoadRawBinary(const xechar_t* path, uint32_t start_address) {
ExecModule* exec_module = NULL;
const xechar_t* name = xestrrchr(path, XE_PATH_SEPARATOR) + 1;

View File

@ -18,15 +18,10 @@
#include <xenia/cpu/exec_module.h>
#include <xenia/cpu/thread_state.h>
#include <xenia/cpu/sdb/symbol_table.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/xex2.h>
namespace xe {
namespace gpu {
class GraphicsSystem;
} // namespace gpu
} // namespace xe
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS1(xe, ExportResolver);
namespace xe {
@ -37,17 +32,16 @@ class JIT;
class Processor {
public:
Processor(xe_memory_ref memory, shared_ptr<Backend> backend);
Processor(Emulator* emulator, Backend* backend);
~Processor();
xe_memory_ref memory();
shared_ptr<gpu::GraphicsSystem> graphics_system();
void set_graphics_system(shared_ptr<gpu::GraphicsSystem> graphics_system);
shared_ptr<kernel::ExportResolver> export_resolver();
void set_export_resolver(shared_ptr<kernel::ExportResolver> export_resolver);
xe_memory_ref memory() const { return memory_; }
ExportResolver* export_resolver() const { return export_resolver_; }
int Setup();
void AddRegisterAccessCallbacks(ppc::RegisterAccessCallbacks callbacks);
int LoadRawBinary(const xechar_t* path, uint32_t start_address);
int LoadXexModule(const char* name, const char* path, xe_xex2_ref xex);
@ -69,10 +63,10 @@ public:
void* GetFunctionPointer(uint32_t address);
private:
Emulator* emulator_;
Backend* backend_;
xe_memory_ref memory_;
shared_ptr<Backend> backend_;
shared_ptr<gpu::GraphicsSystem> graphics_system_;
shared_ptr<kernel::ExportResolver> export_resolver_;
ExportResolver* export_resolver_;
sdb::SymbolTable* sym_table_;
JIT* jit_;

View File

@ -17,7 +17,6 @@ using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::ppc;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
RawSymbolDatabase::RawSymbolDatabase(

View File

@ -21,7 +21,7 @@ namespace sdb {
class RawSymbolDatabase : public SymbolDatabase {
public:
RawSymbolDatabase(xe_memory_ref memory,
kernel::ExportResolver* export_resolver,
ExportResolver* export_resolver,
SymbolTable* sym_table,
uint32_t start_address, uint32_t end_address);
virtual ~RawSymbolDatabase();

View File

@ -17,7 +17,6 @@ using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::ppc;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
Symbol::Symbol(SymbolType type) :

View File

@ -15,7 +15,7 @@
#include <map>
#include <vector>
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
namespace xe {
@ -125,7 +125,7 @@ public:
FunctionType type;
uint32_t flags;
kernel::KernelExport* kernel_export;
KernelExport* kernel_export;
ExceptionEntrySymbol* ee;
// Implementation-specific value. This could be a JIT'ed function ref
@ -149,7 +149,7 @@ public:
uint32_t address;
kernel::KernelExport* kernel_export;
KernelExport* kernel_export;
};
class ExceptionEntrySymbol : public Symbol {

View File

@ -20,12 +20,12 @@ using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::ppc;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
SymbolDatabase::SymbolDatabase(xe_memory_ref memory,
ExportResolver* export_resolver,
SymbolTable* sym_table) {
SymbolTable* sym_table) :
function_count_(0), variable_count_(0) {
memory_ = xe_memory_retain(memory);
export_resolver_ = export_resolver;
sym_table_ = sym_table;

View File

@ -16,7 +16,7 @@
#include <map>
#include <vector>
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
#include <xenia/cpu/sdb/symbol.h>
#include <xenia/cpu/sdb/symbol_table.h>
@ -28,7 +28,7 @@ namespace sdb {
class SymbolDatabase {
public:
SymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver,
SymbolDatabase(xe_memory_ref memory, ExportResolver* export_resolver,
SymbolTable* sym_table);
virtual ~SymbolDatabase();
@ -64,7 +64,7 @@ protected:
virtual bool IsValueInTextRange(uint32_t value) = 0;
xe_memory_ref memory_;
kernel::ExportResolver* export_resolver_;
ExportResolver* export_resolver_;
SymbolTable* sym_table_;
size_t function_count_;
size_t variable_count_;

View File

@ -17,7 +17,6 @@ using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::ppc;
using namespace xe::cpu::sdb;
using namespace xe::kernel;
namespace {

View File

@ -23,7 +23,7 @@ namespace sdb {
class XexSymbolDatabase : public SymbolDatabase {
public:
XexSymbolDatabase(xe_memory_ref memory,
kernel::ExportResolver* export_resolver,
ExportResolver* export_resolver,
SymbolTable* sym_table, xe_xex2_ref xex);
virtual ~XexSymbolDatabase();

View File

@ -9,7 +9,7 @@
#include <xenia/cpu/thread_state.h>
#include <xenia/core/memory.h>
#include <xenia/memory.h>
#include <xenia/cpu/processor.h>

View File

@ -454,8 +454,8 @@ XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
uint64_t constant_ea;
if (i.D.RA && e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
if ((constant_ea & 0xFFFF0000) == 0x7FC80000) {
GpVar reg(e.read_gpu_register((uint32_t)constant_ea));
GpVar reg;
if (e.check_constant_gpr_read((uint32_t)constant_ea, &reg)) {
e.update_gpr_value(i.D.RT, reg);
e.clear_constant_gpr_value(i.D.RT);
return 0;
@ -824,8 +824,7 @@ XEEMITTER(stw, 0x90000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
uint64_t constant_ea;
if (i.D.RA && e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
if ((constant_ea & 0xFFFF0000) == 0x7FC80000) {
e.write_gpu_register((uint32_t)constant_ea, e.gpr_value(i.D.RT));
if (e.check_constant_gpr_write((uint32_t)constant_ea, e.gpr_value(i.D.RT))) {
return 0;
}
}

View File

@ -94,11 +94,9 @@ X64Emitter::~X64Emitter() {
lock_ = NULL;
}
void X64Emitter::SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write) {
gpu_this_ = gpu_this;
gpu_read_ = gpu_read;
gpu_write_ = gpu_write;
void X64Emitter::AddRegisterAccessCallbacks(
RegisterAccessCallbacks callbacks) {
access_callbacks_.push_back(callbacks);
}
void X64Emitter::Lock() {
@ -1155,44 +1153,6 @@ int X64Emitter::GenerateIndirectionBranch(uint32_t cia, GpVar& target,
return 0;
}
GpVar X64Emitter::read_gpu_register(uint32_t r) {
X86Compiler& c = compiler_;
GpVar this_imm(c.newGpVar());
c.mov(this_imm, imm((uint64_t)gpu_this_));
GpVar reg_imm(c.newGpVar());
c.mov(reg_imm, imm(r & 0xFFFF));
X86CompilerFuncCall* call = c.call(gpu_read_);
call->setPrototype(kX86FuncConvDefault,
FuncBuilder2<uint64_t, void*, uint32_t>());
call->setArgument(0, this_imm);
call->setArgument(1, reg_imm);
GpVar res(c.newGpVar());
call->setReturn(res);
return res;
}
void X64Emitter::write_gpu_register(uint32_t r, GpVar& v) {
X86Compiler& c = compiler_;
GpVar this_imm(c.newGpVar());
c.alloc(this_imm, rcx);
c.mov(this_imm, imm((uint64_t)gpu_this_));
GpVar reg_imm(c.newGpVar());
c.alloc(reg_imm, rdx);
c.mov(reg_imm, imm(r & 0xFFFF));
c.alloc(v, r8);
X86CompilerFuncCall* call = c.call(gpu_write_);
call->setPrototype(kX86FuncConvDefault,
FuncBuilder3<void, void*, uint32_t, uint64_t>());
call->setArgument(0, this_imm);
call->setArgument(1, reg_imm);
call->setArgument(2, v);
}
void X64Emitter::SetupLocals() {
X86Compiler& c = compiler_;
@ -1505,6 +1465,69 @@ void X64Emitter::clear_all_constant_gpr_values() {
}
}
bool X64Emitter::check_constant_gpr_read(uint32_t addr, GpVar* reg) {
X86Compiler& c = compiler_;
for (std::vector<RegisterAccessCallbacks>::const_iterator it =
access_callbacks_.begin(); it != access_callbacks_.end(); ++it) {
if (!it->handles(it->context, addr)) {
continue;
}
GpVar this_imm(c.newGpVar());
c.mov(this_imm, imm((uint64_t)it->context));
GpVar reg_imm(c.newGpVar());
c.mov(reg_imm, imm(addr));
X86CompilerFuncCall* call = c.call(it->read);
call->setPrototype(
kX86FuncConvDefault,
FuncBuilder2<uint64_t, void*, uint32_t>());
call->setArgument(0, this_imm);
call->setArgument(1, reg_imm);
GpVar res(c.newGpVar());
call->setReturn(res);
*reg = res;
// Don't let the caller handle the write.
return true;
}
return false;
}
bool X64Emitter::check_constant_gpr_write(uint32_t addr, GpVar& reg) {
X86Compiler& c = compiler_;
for (std::vector<RegisterAccessCallbacks>::const_iterator it =
access_callbacks_.begin(); it != access_callbacks_.end(); ++it) {
if (!it->handles(it->context, addr)) {
continue;
}
GpVar this_imm(c.newGpVar());
c.alloc(this_imm, rcx);
c.mov(this_imm, imm((uint64_t)it->context));
GpVar reg_imm(c.newGpVar());
c.alloc(reg_imm, rdx);
c.mov(reg_imm, imm(addr));
c.alloc(reg, r8);
X86CompilerFuncCall* call = c.call(it->write);
call->setPrototype(
kX86FuncConvDefault,
FuncBuilder3<void, void*, uint32_t, uint64_t>());
call->setArgument(0, this_imm);
call->setArgument(1, reg_imm);
call->setArgument(2, reg);
// Don't let the caller handle the write.
return true;
}
return false;
}
GpVar X64Emitter::xer_value() {
X86Compiler& c = compiler_;
if (FLAGS_cache_registers) {

View File

@ -11,8 +11,8 @@
#define XENIA_CPU_X64_X64_EMITTER_H_
#include <xenia/cpu/global_exports.h>
#include <xenia/cpu/ppc.h>
#include <xenia/cpu/sdb.h>
#include <xenia/cpu/ppc/instr.h>
#include <asmjit/asmjit.h>
@ -31,7 +31,7 @@ public:
X64Emitter(xe_memory_ref memory);
~X64Emitter();
void SetupGpuPointers(void* gpu_this, void* gpu_read, void* gpu_write);
void AddRegisterAccessCallbacks(ppc::RegisterAccessCallbacks callbacks);
void Lock();
void Unlock();
@ -75,6 +75,9 @@ public:
void clear_constant_gpr_value(uint32_t n);
void clear_all_constant_gpr_values();
bool check_constant_gpr_read(uint32_t addr, AsmJit::GpVar* reg);
bool check_constant_gpr_write(uint32_t addr, AsmJit::GpVar& reg);
AsmJit::GpVar xer_value();
void update_xer_value(AsmJit::GpVar& value);
void update_xer_with_overflow(AsmJit::GpVar& value);
@ -139,9 +142,7 @@ private:
xe_mutex_t* lock_;
uint32_t cpu_feature_mask_;
void* gpu_this_;
void* gpu_read_;
void* gpu_write_;
std::vector<ppc::RegisterAccessCallbacks> access_callbacks_;
static uint64_t reserved_addr_;

View File

@ -18,6 +18,7 @@
using namespace xe;
using namespace xe::cpu;
using namespace xe::cpu::ppc;
using namespace xe::cpu::sdb;
using namespace xe::cpu::x64;
@ -53,9 +54,8 @@ XECLEANUP:
return result_code;
}
void X64JIT::SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write) {
emitter_->SetupGpuPointers(gpu_this, gpu_read, gpu_write);
void X64JIT::AddRegisterAccessCallbacks(RegisterAccessCallbacks callbacks) {
emitter_->AddRegisterAccessCallbacks(callbacks);
}
namespace {

View File

@ -29,8 +29,8 @@ public:
virtual ~X64JIT();
virtual int Setup();
virtual void SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write);
virtual void AddRegisterAccessCallbacks(
ppc::RegisterAccessCallbacks callbacks);
virtual int InitModule(ExecModule* module);
virtual int UninitModule(ExecModule* module);

View File

@ -11,6 +11,7 @@
#include <gflags/gflags.h>
#include <xenia/emulator.h>
#include <xenia/dbg/content_source.h>
#include <xenia/dbg/listener.h>
@ -25,7 +26,8 @@ DEFINE_int32(remote_debug_port, 6200,
"Websocket port to listen for debugger connections on.");
Debugger::Debugger() {
Debugger::Debugger(Emulator* emulator) :
emulator_(emulator) {
//listener_ = auto_ptr<Listener>(new WsListener(this, FLAGS_remote_debug_port));
}

View File

@ -17,6 +17,9 @@
#include <vector>
XEDECLARECLASS1(xe, Emulator);
namespace xe {
namespace dbg {
@ -28,7 +31,7 @@ class Listener;
class Debugger {
public:
Debugger();
Debugger(Emulator* emulator);
virtual ~Debugger();
void RegisterContentSource(ContentSource* content_source);
@ -45,6 +48,7 @@ private:
friend class Client;
private:
Emulator* emulator_;
auto_ptr<Listener> listener_;
std::vector<Client*> clients_;
std::map<uint32_t, ContentSource*> content_sources_;

196
src/xenia/emulator.cc Normal file
View File

@ -0,0 +1,196 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/emulator.h>
#include <xenia/apu/apu.h>
#include <xenia/cpu/cpu.h>
#include <xenia/dbg/debugger.h>
#include <xenia/gpu/gpu.h>
#include <xenia/kernel/kernel.h>
#include <xenia/kernel/modules.h>
#include <xenia/kernel/xboxkrnl/fs/filesystem.h>
using namespace xe;
using namespace xe::apu;
using namespace xe::cpu;
using namespace xe::dbg;
using namespace xe::gpu;
using namespace xe::kernel;
using namespace xe::kernel::xam;
using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
Emulator::Emulator(const xechar_t* command_line) :
memory_(0),
debugger_(0),
cpu_backend_(0), processor_(0), audio_system_(0), graphics_system_(0),
export_resolver_(0), file_system_(0),
xboxkrnl_(0), xam_(0) {
XEIGNORE(xestrcpy(command_line_, XECOUNT(command_line_), command_line));
}
Emulator::~Emulator() {
// Note that we delete things in the reverse order they were initialized.
delete xam_;
delete xboxkrnl_;
delete file_system_;
delete graphics_system_;
delete audio_system_;
delete processor_;
delete cpu_backend_;
delete debugger_;
delete export_resolver_;
xe_memory_release(memory_);
}
X_STATUS Emulator::Setup() {
X_STATUS result = X_STATUS_UNSUCCESSFUL;
// Create memory system first, as it is required for other systems.
xe_memory_options_t memory_options;
xe_zero_struct(&memory_options, sizeof(memory_options));
memory_ = xe_memory_create(memory_options);
XEEXPECTNOTNULL(memory_);
// Shared export resolver used to attach and query for HLE exports.
export_resolver_ = new ExportResolver();
XEEXPECTNOTNULL(export_resolver_);
// Create the debugger.
debugger_ = new Debugger(this);
XEEXPECTNOTNULL(debugger_);
// Initialize the CPU.
cpu_backend_ = new xe::cpu::x64::X64Backend();
XEEXPECTNOTNULL(cpu_backend_);
processor_ = new Processor(this, cpu_backend_);
XEEXPECTNOTNULL(processor_);
// Initialize the APU.
audio_system_ = xe::apu::Create(this);
XEEXPECTNOTNULL(audio_system_);
// Initialize the GPU.
graphics_system_ = xe::gpu::Create(this);
XEEXPECTNOTNULL(graphics_system_);
// Setup the core components.
result = processor_->Setup();
XEEXPECTZERO(result);
result = audio_system_->Setup();
XEEXPECTZERO(result);
result = graphics_system_->Setup();
XEEXPECTZERO(result);
// Bring up the virtual filesystem used by the kernel.
file_system_ = new FileSystem();
XEEXPECTNOTNULL(file_system_);
// HLE kernel modules.
xboxkrnl_ = new XboxkrnlModule(this);
XEEXPECTNOTNULL(xboxkrnl_);
xam_ = new XamModule(this);
XEEXPECTNOTNULL(xam_);
// Prepare the debugger.
// This may pause waiting for connections.
result = debugger_->Startup();
XEEXPECTZERO(result);
return result;
XECLEANUP:
return result;
}
X_STATUS Emulator::LaunchXexFile(const xechar_t* path) {
// We create a virtual filesystem pointing to its directory and symlink
// that to the game filesystem.
// e.g., /my/files/foo.xex will get a local fs at:
// \\Device\\Harddisk0\\Partition1
// and then get that symlinked to game:\, so
// -> game:\foo.xex
int result_code = 0;
// Get just the filename (foo.xex).
const xechar_t* file_name = xestrrchr(path, XE_PATH_SEPARATOR);
if (file_name) {
// Skip slash.
file_name++;
} else {
// No slash found, whole thing is a file.
file_name = path;
}
// Get the parent path of the file.
xechar_t parent_path[XE_MAX_PATH];
XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path));
parent_path[file_name - path] = 0;
// Register the local directory in the virtual filesystem.
result_code = file_system_->RegisterHostPathDevice(
"\\Device\\Harddisk1\\Partition0", parent_path);
if (result_code) {
XELOGE("Unable to mount local directory");
return result_code;
}
// Create symlinks to the device.
file_system_->CreateSymbolicLink(
"game:", "\\Device\\Harddisk1\\Partition0");
file_system_->CreateSymbolicLink(
"d:", "\\Device\\Harddisk1\\Partition0");
// Get the file name of the module to load from the filesystem.
char fs_path[XE_MAX_PATH];
XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\"));
char* fs_path_ptr = fs_path + xestrlena(fs_path);
*fs_path_ptr = 0;
#if XE_WCHAR
XEIGNORE(xestrnarrow(fs_path_ptr, XECOUNT(fs_path), file_name));
#else
XEIGNORE(xestrcpya(fs_path_ptr, XECOUNT(fs_path), file_name));
#endif
// Launch the game.
return xboxkrnl_->LaunchModule(fs_path);
}
X_STATUS Emulator::LaunchDiscImage(const xechar_t* path) {
int result_code = 0;
// Register the disc image in the virtual filesystem.
result_code = file_system_->RegisterDiscImageDevice(
"\\Device\\Cdrom0", path);
if (result_code) {
XELOGE("Unable to mount disc image");
return result_code;
}
// Create symlinks to the device.
file_system_->CreateSymbolicLink(
"game:",
"\\Device\\Cdrom0");
file_system_->CreateSymbolicLink(
"d:",
"\\Device\\Cdrom0");
// Launch the game.
return xboxkrnl_->LaunchModule("game:\\default.xex");
}

77
src/xenia/emulator.h Normal file
View File

@ -0,0 +1,77 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_EMULATOR_H_
#define XENIA_EMULATOR_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/xbox.h>
XEDECLARECLASS1(xe, ExportResolver);
XEDECLARECLASS2(xe, apu, AudioSystem);
XEDECLARECLASS2(xe, cpu, Backend);
XEDECLARECLASS2(xe, cpu, Processor);
XEDECLARECLASS2(xe, dbg, Debugger);
XEDECLARECLASS2(xe, gpu, GraphicsSystem);
XEDECLARECLASS3(xe, kernel, xam, XamModule);
XEDECLARECLASS3(xe, kernel, xboxkrnl, XboxkrnlModule);
XEDECLARECLASS4(xe, kernel, xboxkrnl, fs, FileSystem);
namespace xe {
class Emulator {
public:
Emulator(const xechar_t* command_line);
~Emulator();
const xechar_t* command_line() const { return command_line_; }
xe_memory_ref memory() const { return memory_; }
dbg::Debugger* debugger() const { return debugger_; }
cpu::Processor* processor() const { return processor_; }
apu::AudioSystem* audio_system() const { return audio_system_; }
gpu::GraphicsSystem* graphics_system() const { return graphics_system_; }
ExportResolver* export_resolver() const { return export_resolver_; }
kernel::xboxkrnl::fs::FileSystem* file_system() const { return file_system_; }
X_STATUS Setup();
// TODO(benvanik): raw binary.
X_STATUS LaunchXexFile(const xechar_t* path);
X_STATUS LaunchDiscImage(const xechar_t* path);
private:
xechar_t command_line_[XE_MAX_PATH];
xe_memory_ref memory_;
dbg::Debugger* debugger_;
cpu::Backend* cpu_backend_;
cpu::Processor* processor_;
apu::AudioSystem* audio_system_;
gpu::GraphicsSystem* graphics_system_;
ExportResolver* export_resolver_;
kernel::xboxkrnl::fs::FileSystem* file_system_;
kernel::xboxkrnl::XboxkrnlModule* xboxkrnl_;
kernel::xam::XamModule* xam_;
};
} // namespace xe
#endif // XENIA_EMULATOR_H_

View File

@ -7,11 +7,10 @@
******************************************************************************
*/
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
using namespace xe;
using namespace xe::kernel;
ExportResolver::ExportResolver() {

View File

@ -7,8 +7,8 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_EXPORT_H_
#define XENIA_KERNEL_EXPORT_H_
#ifndef XENIA_EXPORT_RESOLVER_H_
#define XENIA_EXPORT_RESOLVER_H_
#include <xenia/core.h>
@ -19,7 +19,6 @@ typedef struct xe_ppc_state xe_ppc_state_t;
namespace xe {
namespace kernel {
typedef void (*xe_kernel_export_impl_fn)();
@ -92,8 +91,7 @@ private:
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_EXPORT_H_
#endif // XENIA_EXPORT_RESOLVER_H_

View File

@ -7,12 +7,12 @@
******************************************************************************
*/
#ifndef XENIA_GPU_D3D11_D3D11_PRIVATE_H_
#define XENIA_GPU_D3D11_D3D11_PRIVATE_H_
#ifndef XENIA_GPU_D3D11_D3D11_GPU_PRIVATE_H_
#define XENIA_GPU_D3D11_D3D11_GPU_PRIVATE_H_
#include <xenia/core.h>
#include <xenia/gpu/d3d11/d3d11.h>
#include <xenia/gpu/d3d11/d3d11_gpu.h>
namespace xe {
@ -28,4 +28,4 @@ namespace d3d11 {
} // namespace xe
#endif // XENIA_GPU_D3D11_D3D11_PRIVATE_H_
#endif // XENIA_GPU_D3D11_D3D11_GPU_PRIVATE_H_

View File

@ -7,7 +7,7 @@
******************************************************************************
*/
#include <xenia/gpu/d3d11/d3d11.h>
#include <xenia/gpu/d3d11/d3d11_gpu.h>
#include <xenia/gpu/d3d11/d3d11_graphics_system.h>
@ -38,7 +38,7 @@ namespace {
}
GraphicsSystem* xe::gpu::d3d11::Create(const CreationParams* params) {
GraphicsSystem* xe::gpu::d3d11::Create(Emulator* emulator) {
InitializeIfNeeded();
return new D3D11GraphicsSystem(params);
return new D3D11GraphicsSystem(emulator);
}

View File

@ -7,22 +7,22 @@
******************************************************************************
*/
#ifndef XENIA_GPU_D3D11_D3D11_H_
#define XENIA_GPU_D3D11_D3D11_H_
#ifndef XENIA_GPU_D3D11_D3D11_GPU_H_
#define XENIA_GPU_D3D11_D3D11_GPU_H_
#include <xenia/core.h>
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, gpu, GraphicsSystem);
namespace xe {
namespace gpu {
class CreationParams;
class GraphicsSystem;
namespace d3d11 {
GraphicsSystem* Create(const CreationParams* params);
GraphicsSystem* Create(Emulator* emulator);
} // namespace d3d11
@ -30,4 +30,4 @@ GraphicsSystem* Create(const CreationParams* params);
} // namespace xe
#endif // XENIA_GPU_D3D11_D3D11_H_
#endif // XENIA_GPU_D3D11_D3D11_GPU_H_

View File

@ -13,7 +13,7 @@
#include <xenia/core.h>
#include <xenia/gpu/graphics_driver.h>
#include <xenia/gpu/d3d11/d3d11-private.h>
#include <xenia/gpu/d3d11/d3d11_gpu-private.h>
#include <xenia/gpu/xenos/xenos.h>
#include <d3d11.h>

View File

@ -21,7 +21,8 @@ using namespace xe::gpu::d3d11;
namespace {
void __stdcall D3D11GraphicsSystemVsyncCallback(D3D11GraphicsSystem* gs, BOOLEAN) {
void __stdcall D3D11GraphicsSystemVsyncCallback(
D3D11GraphicsSystem* gs, BOOLEAN) {
gs->MarkVblank();
gs->DispatchInterruptCallback(0);
}
@ -29,10 +30,10 @@ void __stdcall D3D11GraphicsSystemVsyncCallback(D3D11GraphicsSystem* gs, BOOLEAN
}
D3D11GraphicsSystem::D3D11GraphicsSystem(const CreationParams* params) :
D3D11GraphicsSystem::D3D11GraphicsSystem(Emulator* emulator) :
window_(0), dxgi_factory_(0), device_(0),
timer_queue_(NULL), vsync_timer_(NULL),
GraphicsSystem(params) {
GraphicsSystem(emulator) {
}
D3D11GraphicsSystem::~D3D11GraphicsSystem() {

View File

@ -13,7 +13,7 @@
#include <xenia/core.h>
#include <xenia/gpu/graphics_system.h>
#include <xenia/gpu/d3d11/d3d11-private.h>
#include <xenia/gpu/d3d11/d3d11_gpu-private.h>
#include <d3d11.h>
@ -25,12 +25,12 @@ namespace d3d11 {
class D3D11Window;
GraphicsSystem* Create(const CreationParams* params);
GraphicsSystem* Create(Emulator* emulator);
class D3D11GraphicsSystem : public GraphicsSystem {
public:
D3D11GraphicsSystem(const CreationParams* params);
D3D11GraphicsSystem(Emulator* emulator);
virtual ~D3D11GraphicsSystem();
protected:

View File

@ -1,9 +1,9 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'd3d11-private.h',
'd3d11.cc',
'd3d11.h',
'd3d11_gpu-private.h',
'd3d11_gpu.cc',
'd3d11_gpu.h',
'd3d11_graphics_driver.cc',
'd3d11_graphics_driver.h',
'd3d11_graphics_system.cc',

View File

@ -20,39 +20,39 @@ DEFINE_string(gpu, "any",
"Graphics system. Use: [any, nop, d3d11]");
#include <xenia/gpu/nop/nop.h>
GraphicsSystem* xe::gpu::CreateNop(const CreationParams* params) {
return xe::gpu::nop::Create(params);
#include <xenia/gpu/nop/nop_gpu.h>
GraphicsSystem* xe::gpu::CreateNop(Emulator* emulator) {
return xe::gpu::nop::Create(emulator);
}
#if XE_PLATFORM(WIN32)
#include <xenia/gpu/d3d11/d3d11.h>
GraphicsSystem* xe::gpu::CreateD3D11(const CreationParams* params) {
return xe::gpu::d3d11::Create(params);
#include <xenia/gpu/d3d11/d3d11_gpu.h>
GraphicsSystem* xe::gpu::CreateD3D11(Emulator* emulator) {
return xe::gpu::d3d11::Create(emulator);
}
#endif // WIN32
GraphicsSystem* xe::gpu::Create(const CreationParams* params) {
GraphicsSystem* xe::gpu::Create(Emulator* emulator) {
if (FLAGS_gpu.compare("nop") == 0) {
return CreateNop(params);
return CreateNop(emulator);
#if XE_PLATFORM(WIN32)
} else if (FLAGS_gpu.compare("d3d11") == 0) {
return CreateD3D11(params);
return CreateD3D11(emulator);
#endif // WIN32
} else {
// Create best available.
GraphicsSystem* best = NULL;
#if XE_PLATFORM(WIN32)
best = CreateD3D11(params);
best = CreateD3D11(emulator);
if (best) {
return best;
}
#endif // WIN32
// Fallback to nop.
return CreateNop(params);
return CreateNop(emulator);
}
}

View File

@ -13,16 +13,19 @@
#include <xenia/gpu/graphics_system.h>
XEDECLARECLASS1(xe, Emulator);
namespace xe {
namespace gpu {
GraphicsSystem* Create(const CreationParams* params);
GraphicsSystem* Create(Emulator* emulator);
GraphicsSystem* CreateNop(const CreationParams* params);
GraphicsSystem* CreateNop(Emulator* emulator);
#if XE_PLATFORM(WIN32)
GraphicsSystem* CreateD3D11(const CreationParams* params);
GraphicsSystem* CreateD3D11(Emulator* emulator);
#endif // WIN32

View File

@ -24,7 +24,3 @@ GraphicsDriver::GraphicsDriver(xe_memory_ref memory) :
GraphicsDriver::~GraphicsDriver() {
xe_memory_release(memory_);
}
xe_memory_ref GraphicsDriver::memory() {
return xe_memory_retain(memory_);
}

View File

@ -23,7 +23,7 @@ class GraphicsDriver {
public:
virtual ~GraphicsDriver();
xe_memory_ref memory();
xe_memory_ref memory() const { return memory_; }
xenos::RegisterFile* register_file() { return &register_file_; };
void set_address_translation(uint32_t value) {
address_translation_ = value;

View File

@ -9,6 +9,7 @@
#include <xenia/gpu/graphics_system.h>
#include <xenia/emulator.h>
#include <xenia/cpu/processor.h>
#include <xenia/gpu/graphics_driver.h>
#include <xenia/gpu/ring_buffer_worker.h>
@ -16,33 +17,21 @@
using namespace xe;
using namespace xe::cpu::ppc;
using namespace xe::gpu;
using namespace xe::gpu::xenos;
GraphicsSystem::GraphicsSystem(const CreationParams* params) :
GraphicsSystem::GraphicsSystem(Emulator* emulator) :
emulator_(emulator),
thread_(0), running_(false), driver_(0), worker_(0),
interrupt_callback_(0), interrupt_callback_data_(0),
last_interrupt_time_(0), swap_pending_(false) {
memory_ = xe_memory_retain(params->memory);
worker_ = new RingBufferWorker(this, memory_);
// Set during Initialize();
driver_ = 0;
memory_ = xe_memory_retain(emulator->memory());
// Create the run loop used for any windows/etc.
// This must be done on the thread we create the driver.
run_loop_ = xe_run_loop_create();
// Create worker thread.
// This will initialize the graphics system.
// Init needs to happen there so that any thread-local stuff
// is created on the right thread.
running_ = true;
thread_ = xe_thread_create(
"GraphicsSystem",
(xe_thread_callback)ThreadStartThunk, this);
xe_thread_start(thread_);
}
GraphicsSystem::~GraphicsSystem() {
@ -57,16 +46,31 @@ GraphicsSystem::~GraphicsSystem() {
xe_memory_release(memory_);
}
xe_memory_ref GraphicsSystem::memory() {
return xe_memory_retain(memory_);
}
X_STATUS GraphicsSystem::Setup() {
processor_ = emulator_->processor();
shared_ptr<cpu::Processor> GraphicsSystem::processor() {
return processor_;
}
// Create worker.
worker_ = new RingBufferWorker(this, memory_);
void GraphicsSystem::set_processor(shared_ptr<cpu::Processor> processor) {
processor_ = processor;
// Let the processor know we want register access callbacks.
RegisterAccessCallbacks callbacks;
callbacks.context = this;
callbacks.handles = (RegisterHandlesCallback)HandlesRegisterThunk;
callbacks.read = (RegisterReadCallback)ReadRegisterThunk;
callbacks.write = (RegisterWriteCallback)WriteRegisterThunk;
emulator_->processor()->AddRegisterAccessCallbacks(callbacks);
// Create worker thread.
// This will initialize the graphics system.
// Init needs to happen there so that any thread-local stuff
// is created on the right thread.
running_ = true;
thread_ = xe_thread_create(
"GraphicsSystem",
(xe_thread_callback)ThreadStartThunk, this);
xe_thread_start(thread_);
return X_STATUS_SUCCESS;
}
void GraphicsSystem::ThreadStart() {
@ -128,7 +132,12 @@ void GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr,
worker_->EnableReadPointerWriteBack(ptr, block_size);
}
uint64_t GraphicsSystem::ReadRegister(uint32_t r) {
bool GraphicsSystem::HandlesRegister(uint32_t addr) {
return (addr & 0xFFFF0000) == 0x7FC80000;
}
uint64_t GraphicsSystem::ReadRegister(uint32_t addr) {
uint32_t r = addr & 0xFFFF;
XELOGGPU("ReadRegister(%.4X)", r);
RegisterFile* regs = driver_->register_file();
@ -142,7 +151,8 @@ uint64_t GraphicsSystem::ReadRegister(uint32_t r) {
return regs->values[r].u32;
}
void GraphicsSystem::WriteRegister(uint32_t r, uint64_t value) {
void GraphicsSystem::WriteRegister(uint32_t addr, uint64_t value) {
uint32_t r = addr & 0xFFFF;
XELOGGPU("WriteRegister(%.4X, %.8X)", r, value);
RegisterFile* regs = driver_->register_file();

View File

@ -11,13 +11,11 @@
#define XENIA_GPU_GRAPHICS_SYSTEM_H_
#include <xenia/core.h>
#include <xenia/xbox.h>
namespace xe {
namespace cpu {
class Processor;
} // namespace cpu
} // namespace xe
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, cpu, Processor);
namespace xe {
@ -27,47 +25,29 @@ class GraphicsDriver;
class RingBufferWorker;
class CreationParams {
public:
xe_memory_ref memory;
CreationParams() :
memory(0) {
}
};
class GraphicsSystem {
public:
virtual ~GraphicsSystem();
xe_memory_ref memory();
shared_ptr<cpu::Processor> processor();
void set_processor(shared_ptr<cpu::Processor> processor);
Emulator* emulator() const { return emulator_; }
xe_memory_ref memory() const { return memory_; }
cpu::Processor* processor() const { return processor_; }
virtual X_STATUS Setup();
void SetInterruptCallback(uint32_t callback, uint32_t user_data);
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count);
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
virtual uint64_t ReadRegister(uint32_t r);
virtual void WriteRegister(uint32_t r, uint64_t value);
bool HandlesRegister(uint32_t addr);
virtual uint64_t ReadRegister(uint32_t addr);
virtual void WriteRegister(uint32_t addr, uint64_t value);
void MarkVblank();
void DispatchInterruptCallback(uint32_t source, uint32_t cpu = 0xFFFFFFFF);
bool swap_pending() const { return swap_pending_; }
void set_swap_pending(bool value) { swap_pending_ = value; }
public:
// TODO(benvanik): have an HasRegisterHandler() so that the JIT can
// just poke the register file directly.
static uint64_t ReadRegisterThunk(GraphicsSystem* this_ptr, uint32_t r) {
return this_ptr->ReadRegister(r);
}
static void WriteRegisterThunk(GraphicsSystem* this_ptr, uint32_t r,
uint64_t value) {
this_ptr->WriteRegister(r, value);
}
protected:
virtual void Initialize();
virtual void Pump() = 0;
@ -79,11 +59,23 @@ private:
}
void ThreadStart();
protected:
GraphicsSystem(const CreationParams* params);
static bool HandlesRegisterThunk(GraphicsSystem* gs, uint32_t addr) {
return gs->HandlesRegister(addr);
}
static uint64_t ReadRegisterThunk(GraphicsSystem* gs, uint32_t addr) {
return gs->ReadRegister(addr);
}
static void WriteRegisterThunk(GraphicsSystem* gs, uint32_t addr,
uint64_t value) {
gs->WriteRegister(addr, value);
}
protected:
GraphicsSystem(Emulator* emulator);
Emulator* emulator_;
xe_memory_ref memory_;
shared_ptr<cpu::Processor> processor_;
cpu::Processor* processor_;
xe_run_loop_ref run_loop_;
xe_thread_ref thread_;

View File

@ -7,12 +7,12 @@
******************************************************************************
*/
#ifndef XENIA_GPU_NOP_NOP_PRIVATE_H_
#define XENIA_GPU_NOP_NOP_PRIVATE_H_
#ifndef XENIA_GPU_NOP_NOP_GPU_PRIVATE_H_
#define XENIA_GPU_NOP_NOP_GPU_PRIVATE_H_
#include <xenia/core.h>
#include <xenia/gpu/nop/nop.h>
#include <xenia/gpu/nop/nop_gpu.h>
namespace xe {

View File

@ -7,7 +7,7 @@
******************************************************************************
*/
#include <xenia/gpu/nop/nop.h>
#include <xenia/gpu/nop/nop_gpu.h>
#include <xenia/gpu/nop/nop_graphics_system.h>
@ -38,7 +38,7 @@ namespace {
}
GraphicsSystem* xe::gpu::nop::Create(const CreationParams* params) {
GraphicsSystem* xe::gpu::nop::Create(Emulator* emulator) {
InitializeIfNeeded();
return new NopGraphicsSystem(params);
return new NopGraphicsSystem(emulator);
}

View File

@ -0,0 +1,33 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_NOP_NOP_GPU_H_
#define XENIA_GPU_NOP_NOP_GPU_H_
#include <xenia/core.h>
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, gpu, GraphicsSystem);
namespace xe {
namespace gpu {
namespace nop {
GraphicsSystem* Create(Emulator* emulator);
} // namespace nop
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_NOP_NOP_GPU_H_

View File

@ -13,7 +13,7 @@
#include <xenia/core.h>
#include <xenia/gpu/graphics_driver.h>
#include <xenia/gpu/nop/nop-private.h>
#include <xenia/gpu/nop/nop_gpu-private.h>
#include <xenia/gpu/xenos/xenos.h>

View File

@ -28,8 +28,8 @@ void __stdcall NopGraphicsSystemVsyncCallback(NopGraphicsSystem* gs, BOOLEAN) {
}
NopGraphicsSystem::NopGraphicsSystem(const CreationParams* params) :
GraphicsSystem(params),
NopGraphicsSystem::NopGraphicsSystem(Emulator* emulator) :
GraphicsSystem(emulator),
timer_queue_(NULL),
vsync_timer_(NULL) {
}

View File

@ -13,7 +13,7 @@
#include <xenia/core.h>
#include <xenia/gpu/graphics_system.h>
#include <xenia/gpu/nop/nop-private.h>
#include <xenia/gpu/nop/nop_gpu-private.h>
namespace xe {
@ -23,7 +23,7 @@ namespace nop {
class NopGraphicsSystem : public GraphicsSystem {
public:
NopGraphicsSystem(const CreationParams* params);
NopGraphicsSystem(Emulator* emulator);
virtual ~NopGraphicsSystem();
protected:

View File

@ -1,9 +1,9 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'nop-private.h',
'nop.cc',
'nop.h',
'nop_gpu-private.h',
'nop_gpu.cc',
'nop_gpu.h',
'nop_graphics_driver.cc',
'nop_graphics_driver.h',
'nop_graphics_system.cc',

View File

@ -570,7 +570,7 @@ uint32_t RingBufferWorker::ExecutePacket(PacketArgs& args) {
switch (type) {
case 0x4: // REGISTER
index += 0x2000;
for (int n = 0; n < count - 1; n++, index++) {
for (uint32_t n = 0; n < count - 1; n++, index++) {
uint32_t data = READ_PTR();
const char* reg_name = xenos::GetRegisterName(index);
XELOGGPU("[%.8X] %.8X -> %.4X %s",

View File

@ -5,7 +5,6 @@
'register_table.inc',
'registers.cc',
'registers.h',
'ucode.cc',
'ucode.h',
'ucode_disassembler.cc',
'ucode_disassembler.h',

View File

@ -10,7 +10,6 @@
#ifndef XENIA_KERNEL_KERNEL_H_
#define XENIA_KERNEL_KERNEL_H_
#include <xenia/kernel/runtime.h>
#include <xenia/kernel/modules/modules.h>
#include <xenia/kernel/modules.h>
#endif // XENIA_KERNEL_KERNEL_H_

View File

@ -9,21 +9,20 @@
#include <xenia/kernel/kernel_module.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/runtime.h>
#include <xenia/emulator.h>
#include <xenia/export_resolver.h>
using namespace xe;
using namespace xe::kernel;
KernelModule::KernelModule(Runtime* runtime) {
runtime_ = runtime;
memory_ = runtime->memory();
export_resolver_ = runtime->export_resolver();
KernelModule::KernelModule(Emulator* emulator) :
emulator_(emulator) {
memory_ = xe_memory_retain(emulator_->memory());
export_resolver_ = emulator->export_resolver();
}
KernelModule::~KernelModule() {
export_resolver_.reset();
xe_memory_release(memory_);
}

View File

@ -14,23 +14,23 @@
#include <xenia/core.h>
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS1(xe, ExportResolver);
namespace xe {
namespace kernel {
class ExportResolver;
class Runtime;
class KernelModule {
public:
KernelModule(Runtime* runtime);
KernelModule(Emulator* emulator);
virtual ~KernelModule();
protected:
Runtime* runtime_;
Emulator* emulator_;
xe_memory_ref memory_;
shared_ptr<ExportResolver> export_resolver_;
ExportResolver* export_resolver_;
};

View File

@ -10,7 +10,7 @@
#ifndef XENIA_KERNEL_MODULES_H_
#define XENIA_KERNEL_MODULES_H_
#include <xenia/kernel/modules/xam/xam_module.h>
#include <xenia/kernel/modules/xboxkrnl/module.h>
#include <xenia/kernel/xam/xam_module.h>
#include <xenia/kernel/xboxkrnl/xboxkrnl_module.h>
#endif // XENIA_KERNEL_MODULES_H_

View File

@ -1,11 +0,0 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'modules.h',
],
'includes': [
'xam/sources.gypi',
'xboxkrnl/sources.gypi',
],
}

View File

@ -1,78 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/kernel_module.h>
#include <xenia/kernel/xbox.h>
#include <xenia/kernel/modules/xboxkrnl/object_table.h>
#include <xenia/kernel/modules/xboxkrnl/fs/filesystem.h>
namespace xe {
namespace cpu {
class Processor;
}
}
namespace xe {
namespace kernel {
namespace xboxkrnl {
class XModule;
namespace fs {
class FileSystem;
}
class KernelState {
public:
KernelState(Runtime* runtime);
~KernelState();
static KernelState* shared();
Runtime* runtime();
xe_memory_ref memory();
cpu::Processor* processor();
fs::FileSystem* filesystem();
ObjectTable* object_table() const;
XModule* GetModule(const char* name);
XModule* GetExecutableModule();
void SetExecutableModule(XModule* module);
private:
Runtime* runtime_;
xe_memory_ref memory_;
shared_ptr<cpu::Processor> processor_;
shared_ptr<fs::FileSystem> filesystem_;
ObjectTable* object_table_;
xe_mutex_t* object_mutex_;
XModule* executable_module_;
friend class XObject;
};
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_H_

View File

@ -1,136 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/kernel/runtime.h>
#include <xenia/kernel/modules/modules.h>
#include <xenia/kernel/modules/xboxkrnl/fs/filesystem.h>
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl::fs;
Runtime::Runtime(shared_ptr<cpu::Processor> processor,
const xechar_t* command_line) {
memory_ = processor->memory();
processor_ = processor;
XEIGNORE(xestrcpy(command_line_, XECOUNT(command_line_), command_line));
export_resolver_ = shared_ptr<ExportResolver>(new ExportResolver());
filesystem_ = shared_ptr<FileSystem>(new FileSystem());
xboxkrnl_ = auto_ptr<xboxkrnl::XboxkrnlModule>(
new xboxkrnl::XboxkrnlModule(this));
xam_ = auto_ptr<xam::XamModule>(
new xam::XamModule(this));
}
Runtime::~Runtime() {
xe_memory_release(memory_);
}
const xechar_t* Runtime::command_line() {
return command_line_;
}
xe_memory_ref Runtime::memory() {
return xe_memory_retain(memory_);
}
shared_ptr<cpu::Processor> Runtime::processor() {
return processor_;
}
shared_ptr<ExportResolver> Runtime::export_resolver() {
return export_resolver_;
}
shared_ptr<FileSystem> Runtime::filesystem() {
return filesystem_;
}
int Runtime::LaunchXexFile(const xechar_t* path) {
// We create a virtual filesystem pointing to its directory and symlink
// that to the game filesystem.
// e.g., /my/files/foo.xex will get a local fs at:
// \\Device\\Harddisk0\\Partition1
// and then get that symlinked to game:\, so
// -> game:\foo.xex
int result_code = 0;
// Get just the filename (foo.xex).
const xechar_t* file_name = xestrrchr(path, XE_PATH_SEPARATOR);
if (file_name) {
// Skip slash.
file_name++;
} else {
// No slash found, whole thing is a file.
file_name = path;
}
// Get the parent path of the file.
xechar_t parent_path[XE_MAX_PATH];
XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path));
parent_path[file_name - path] = 0;
// Register the local directory in the virtual filesystem.
result_code = filesystem_->RegisterHostPathDevice(
"\\Device\\Harddisk1\\Partition0", parent_path);
if (result_code) {
XELOGE("Unable to mount local directory");
return result_code;
}
// Create symlinks to the device.
filesystem_->CreateSymbolicLink(
"game:", "\\Device\\Harddisk1\\Partition0");
filesystem_->CreateSymbolicLink(
"d:", "\\Device\\Harddisk1\\Partition0");
// Get the file name of the module to load from the filesystem.
char fs_path[XE_MAX_PATH];
XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\"));
char* fs_path_ptr = fs_path + xestrlena(fs_path);
*fs_path_ptr = 0;
#if XE_WCHAR
XEIGNORE(xestrnarrow(fs_path_ptr, XECOUNT(fs_path), file_name));
#else
XEIGNORE(xestrcpya(fs_path_ptr, XECOUNT(fs_path), file_name));
#endif
// Launch the game.
return xboxkrnl_->LaunchModule(fs_path);
}
int Runtime::LaunchDiscImage(const xechar_t* path) {
int result_code = 0;
// Register the disc image in the virtual filesystem.
result_code = filesystem_->RegisterDiscImageDevice(
"\\Device\\Cdrom0", path);
if (result_code) {
XELOGE("Unable to mount disc image");
return result_code;
}
// Create symlinks to the device.
filesystem_->CreateSymbolicLink(
"game:",
"\\Device\\Cdrom0");
filesystem_->CreateSymbolicLink(
"d:",
"\\Device\\Cdrom0");
// Launch the game.
return xboxkrnl_->LaunchModule("game:\\default.xex");
}

View File

@ -1,77 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_RUNTIME_H_
#define XENIA_KERNEL_RUNTIME_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/cpu/cpu.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/xex2.h>
namespace xe {
namespace cpu {
class Processor;
}
namespace kernel {
namespace xboxkrnl {
class XboxkrnlModule;
namespace fs {
class FileSystem;
}
}
namespace xam {
class XamModule;
}
}
}
namespace xe {
namespace kernel {
class KernelModule;
class Runtime {
public:
Runtime(shared_ptr<cpu::Processor> processor, const xechar_t* command_line);
~Runtime();
const xechar_t* command_line();
xe_memory_ref memory();
shared_ptr<cpu::Processor> processor();
shared_ptr<ExportResolver> export_resolver();
shared_ptr<xboxkrnl::fs::FileSystem> filesystem();
int LaunchXexFile(const xechar_t* path);
int LaunchDiscImage(const xechar_t* path);
private:
xechar_t command_line_[XE_MAX_PATH];
xe_memory_ref memory_;
shared_ptr<cpu::Processor> processor_;
shared_ptr<ExportResolver> export_resolver_;
shared_ptr<xboxkrnl::fs::FileSystem> filesystem_;
auto_ptr<xboxkrnl::XboxkrnlModule> xboxkrnl_;
auto_ptr<xam::XamModule> xam_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_RUNTIME_H_

View File

@ -14,7 +14,7 @@
#include <xenia/core.h>
#include <xenia/cpu/ppc.h>
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
#include <xenia/kernel/kernel_module.h>

View File

@ -1,22 +1,19 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'export.cc',
'export.h',
'kernel.h',
'kernel_module.cc',
'kernel_module.h',
'runtime.cc',
'runtime.h',
'modules.h',
'shim_utils.h',
'xbox.h',
'xex2.cc',
'xex2.h',
'xex2_info.h',
],
'includes': [
'modules/sources.gypi',
'xam/sources.gypi',
'xboxkrnl/sources.gypi',
'util/sources.gypi',
],
}

View File

@ -14,7 +14,7 @@
* // Build the export table used for resolution.
* #include <xenia/kernel/util/export_table_pre.inc>
* static KernelExport my_module_export_table[] = {
* #include <xenia/kernel/modules/my_module/my_module_table.inc>
* #include <xenia/kernel/my_module/my_module_table.inc>
* };
* #include <xenia/kernel/util/export_table_post.inc>
* export_resolver_->RegisterTable(

View File

@ -15,7 +15,7 @@
* #include <xenia/kernel/util/ordinal_table_pre.inc>
* namespace ordinals {
* enum {
* #include <xenia/kernel/modules/my_module/my_module_table.inc>
* #include <xenia/kernel/my_module/my_module_table.inc>
* };
* } // namespace ordinals
* #include <xenia/kernel/util/ordinal_table_post.inc>

View File

@ -7,11 +7,11 @@
******************************************************************************
*/
#include <xenia/kernel/modules/xam/xam_content.h>
#include <xenia/kernel/xam/xam_content.h>
#include <xenia/kernel/shim_utils.h>
#include <xenia/kernel/modules/xam/xam_private.h>
#include <xenia/kernel/modules/xam/xam_state.h>
#include <xenia/kernel/xam/xam_private.h>
#include <xenia/kernel/xam/xam_state.h>
using namespace xe;

View File

@ -7,13 +7,13 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_CONTENT_H_
#define XENIA_KERNEL_MODULES_XAM_CONTENT_H_
#ifndef XENIA_KERNEL_XAM_CONTENT_H_
#define XENIA_KERNEL_XAM_CONTENT_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/xbox.h>
#include <xenia/xbox.h>
namespace xe {
@ -28,4 +28,4 @@ namespace xam {
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_CONTENT_H_
#endif // XENIA_KERNEL_XAM_CONTENT_H_

View File

@ -7,12 +7,12 @@
******************************************************************************
*/
#include <xenia/kernel/modules/xam/xam_info.h>
#include <xenia/kernel/xam/xam_info.h>
#include <xenia/kernel/shim_utils.h>
#include <xenia/kernel/xex2.h>
#include <xenia/kernel/modules/xam/xam_private.h>
#include <xenia/kernel/modules/xam/xam_state.h>
#include <xenia/kernel/xam/xam_private.h>
#include <xenia/kernel/xam/xam_state.h>
using namespace xe;

View File

@ -7,13 +7,13 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_INFO_H_
#define XENIA_KERNEL_MODULES_XAM_INFO_H_
#ifndef XENIA_KERNEL_XAM_INFO_H_
#define XENIA_KERNEL_XAM_INFO_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/xbox.h>
#include <xenia/xbox.h>
namespace xe {
@ -28,4 +28,4 @@ namespace xam {
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_INFO_H_
#endif // XENIA_KERNEL_XAM_INFO_H_

View File

@ -7,11 +7,11 @@
******************************************************************************
*/
#include <xenia/kernel/modules/xam/xam_input.h>
#include <xenia/kernel/xam/xam_input.h>
#include <xenia/kernel/shim_utils.h>
#include <xenia/kernel/modules/xam/xam_private.h>
#include <xenia/kernel/modules/xam/xam_state.h>
#include <xenia/kernel/xam/xam_private.h>
#include <xenia/kernel/xam/xam_state.h>
using namespace xe;

View File

@ -7,13 +7,13 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_INPUT_H_
#define XENIA_KERNEL_MODULES_XAM_INPUT_H_
#ifndef XENIA_KERNEL_XAM_INPUT_H_
#define XENIA_KERNEL_XAM_INPUT_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/xbox.h>
#include <xenia/xbox.h>
namespace xe {
@ -28,4 +28,4 @@ namespace xam {
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_INPUT_H_
#endif // XENIA_KERNEL_XAM_INPUT_H_

View File

@ -7,11 +7,11 @@
******************************************************************************
*/
#include <xenia/kernel/modules/xam/xam_module.h>
#include <xenia/kernel/xam/xam_module.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/modules/xam/xam_private.h>
#include <xenia/kernel/modules/xam/xam_state.h>
#include <xenia/export_resolver.h>
#include <xenia/kernel/xam/xam_private.h>
#include <xenia/kernel/xam/xam_state.h>
using namespace xe;
@ -22,31 +22,31 @@ using namespace xe::kernel::xam;
XamState* xe::kernel::xam::shared_xam_state_ = NULL;
XamModule::XamModule(Runtime* runtime) :
KernelModule(runtime) {
XamModule::XamModule(Emulator* emulator) :
KernelModule(emulator) {
// Build the export table used for resolution.
#include <xenia/kernel/util/export_table_pre.inc>
static KernelExport xam_export_table[] = {
#include <xenia/kernel/modules/xam/xam_table.inc>
#include <xenia/kernel/xam/xam_table.inc>
};
#include <xenia/kernel/util/export_table_post.inc>
export_resolver_->RegisterTable(
"xam.xex", xam_export_table, XECOUNT(xam_export_table));
// Setup the xam state instance.
xam_state = auto_ptr<XamState>(new XamState(memory_, export_resolver_));
xam_state_ = new XamState(emulator);
// Setup the shared global state object.
XEASSERTNULL(shared_xam_state_);
shared_xam_state_ = xam_state.get();
shared_xam_state_ = xam_state_;
// Register all exported functions.
RegisterContentExports(export_resolver_.get(), xam_state.get());
RegisterInfoExports(export_resolver_.get(), xam_state.get());
RegisterInputExports(export_resolver_.get(), xam_state.get());
RegisterNetExports(export_resolver_.get(), xam_state.get());
RegisterUserExports(export_resolver_.get(), xam_state.get());
RegisterVideoExports(export_resolver_.get(), xam_state.get());
RegisterContentExports(export_resolver_, xam_state_);
RegisterInfoExports(export_resolver_, xam_state_);
RegisterInputExports(export_resolver_, xam_state_);
RegisterNetExports(export_resolver_, xam_state_);
RegisterUserExports(export_resolver_, xam_state_);
RegisterVideoExports(export_resolver_, xam_state_);
}
XamModule::~XamModule() {

View File

@ -7,18 +7,18 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_H_
#define XENIA_KERNEL_MODULES_XAM_H_
#ifndef XENIA_KERNEL_XAM_H_
#define XENIA_KERNEL_XAM_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
#include <xenia/kernel/kernel_module.h>
#include <xenia/kernel/modules/xam/xam_ordinals.h>
#include <xenia/kernel/xam/xam_ordinals.h>
// All of the exported functions:
#include <xenia/kernel/modules/xam/xam_info.h>
#include <xenia/kernel/xam/xam_info.h>
namespace xe {
@ -30,11 +30,11 @@ class XamState;
class XamModule : public KernelModule {
public:
XamModule(Runtime* runtime);
XamModule(Emulator* emulator);
virtual ~XamModule();
private:
auto_ptr<XamState> xam_state;
XamState* xam_state_;
};
@ -43,4 +43,4 @@ private:
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_H_
#endif // XENIA_KERNEL_XAM_H_

View File

@ -7,11 +7,11 @@
******************************************************************************
*/
#include <xenia/kernel/modules/xam/xam_net.h>
#include <xenia/kernel/xam/xam_net.h>
#include <xenia/kernel/shim_utils.h>
#include <xenia/kernel/modules/xam/xam_private.h>
#include <xenia/kernel/modules/xam/xam_state.h>
#include <xenia/kernel/xam/xam_private.h>
#include <xenia/kernel/xam/xam_state.h>
using namespace xe;

View File

@ -7,13 +7,13 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_NET_H_
#define XENIA_KERNEL_MODULES_XAM_NET_H_
#ifndef XENIA_KERNEL_XAM_NET_H_
#define XENIA_KERNEL_XAM_NET_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/xbox.h>
#include <xenia/xbox.h>
namespace xe {
@ -28,4 +28,4 @@ namespace xam {
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_NET_H_
#endif // XENIA_KERNEL_XAM_NET_H_

View File

@ -7,23 +7,23 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_ORDINALS_H_
#define XENIA_KERNEL_MODULES_XAM_ORDINALS_H_
#ifndef XENIA_KERNEL_XAM_ORDINALS_H_
#define XENIA_KERNEL_XAM_ORDINALS_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/export.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 {
enum {
#include <xenia/kernel/modules/xam/xam_table.inc>
#include <xenia/kernel/xam/xam_table.inc>
};
} // namespace ordinals
#include <xenia/kernel/util/ordinal_table_post.inc>
#endif // XENIA_KERNEL_MODULES_XAM_ORDINALS_H_
#endif // XENIA_KERNEL_XAM_ORDINALS_H_

View File

@ -7,13 +7,13 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_PRIVATE_H_
#define XENIA_KERNEL_MODULES_XAM_PRIVATE_H_
#ifndef XENIA_KERNEL_XAM_PRIVATE_H_
#define XENIA_KERNEL_XAM_PRIVATE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/modules/xam/xam_ordinals.h>
#include <xenia/kernel/xam/xam_ordinals.h>
namespace xe {
@ -43,4 +43,4 @@ void RegisterVideoExports(ExportResolver* export_resolver, XamState* state);
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_PRIVATE_H_
#endif // XENIA_KERNEL_XAM_PRIVATE_H_

View File

@ -7,7 +7,9 @@
******************************************************************************
*/
#include <xenia/kernel/modules/xam/xam_state.h>
#include <xenia/kernel/xam/xam_state.h>
#include <xenia/emulator.h>
using namespace xe;
@ -20,12 +22,12 @@ namespace {
}
XamState::XamState(xe_memory_ref memory,
shared_ptr<ExportResolver> export_resolver) {
this->memory = xe_memory_retain(memory);
export_resolver_ = export_resolver;
XamState::XamState(Emulator* emulator) :
emulator_(emulator) {
memory_ = xe_memory_retain(emulator->memory());
export_resolver_ = emulator->export_resolver();
}
XamState::~XamState() {
xe_memory_release(memory);
xe_memory_release(memory_);
}

View File

@ -7,13 +7,13 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
#define XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
#ifndef XENIA_KERNEL_XAM_XAM_STATE_H_
#define XENIA_KERNEL_XAM_XAM_STATE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/export.h>
#include <xenia/export_resolver.h>
#include <xenia/kernel/kernel_module.h>
@ -24,13 +24,15 @@ namespace xam {
class XamState {
public:
XamState(xe_memory_ref memory, shared_ptr<ExportResolver> export_resolver);
XamState(Emulator* emulator);
~XamState();
xe_memory_ref memory;
xe_memory_ref memory() const { return memory_; }
private:
shared_ptr<ExportResolver> export_resolver_;
Emulator* emulator_;
xe_memory_ref memory_;
ExportResolver* export_resolver_;
};
@ -39,4 +41,4 @@ private:
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
#endif // XENIA_KERNEL_XAM_XAM_STATE_H_

Some files were not shown because too many files have changed in this diff Show More