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

@@ -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) {