removed RuntimeContext struct

This commit is contained in:
Anthony Pesch 2015-07-04 00:21:03 -07:00
parent c4b78cc565
commit 7258b89778
18 changed files with 198 additions and 288 deletions

View File

@ -63,6 +63,7 @@ set(DREAVM_SOURCES
src/cpu/ir/pass_runner.cc
src/cpu/ir/validate_block_pass.cc
src/cpu/sh4.cc
src/cpu/sh4_context.cc
src/cpu/runtime.cc
src/emu/disc.cc
src/emu/emulator.cc
@ -270,6 +271,7 @@ set(DREAVM_TEST_SOURCES
src/cpu/ir/pass_runner.cc
src/cpu/ir/validate_block_pass.cc
src/cpu/sh4.cc
src/cpu/sh4_context.cc
src/cpu/runtime.cc
src/emu/profiler.cc
src/emu/scheduler.cc

View File

@ -12,8 +12,8 @@ namespace interpreter {
class InterpreterContext;
typedef uint32_t (*InstrFn)(RuntimeContext *runtime, Register *registers,
Instr *instr, uint32_t idx);
typedef uint32_t (*InstrFn)(emu::Memory *memory, void *guest_ctx,
Register *registers, Instr *instr, uint32_t idx);
union Register {
int8_t i8;

View File

@ -15,7 +15,7 @@ InterpreterBlock::InterpreterBlock(int guest_cycles, Instr *instrs,
InterpreterBlock::~InterpreterBlock() { free(instrs_); }
uint32_t InterpreterBlock::Call(RuntimeContext &runtime_ctx) {
uint32_t InterpreterBlock::Call(emu::Memory *memory, void *guest_ctx) {
Register *registers =
reinterpret_cast<Register *>(alloca(sizeof(Register) * num_registers_));
@ -33,7 +33,7 @@ uint32_t InterpreterBlock::Call(RuntimeContext &runtime_ctx) {
// 3. branch is a far, direct branch, absolute i32 address is returned
// cases 2 or 3 will always occur as the last instruction of the block,
// so the return can be assumed to be an i32 address then
i = instr->fn(&runtime_ctx, registers, instr, i);
i = instr->fn(memory, guest_ctx, registers, instr, i);
}
return i;

View File

@ -19,7 +19,7 @@ class InterpreterBlock : public RuntimeBlock {
int num_registers);
~InterpreterBlock();
uint32_t Call(RuntimeContext &runtime_ctx);
uint32_t Call(emu::Memory *memory, void *guest_ctx);
private:
Instr *instrs_;

View File

@ -177,10 +177,10 @@ struct helper<T, ARG, IMM_MASK,
}
};
#define CALLBACK(name) \
template <typename R = void, typename A0 = void, typename A1 = void, \
int IMM_MASK = 0> \
static uint32_t name(RuntimeContext *ctx, Register *r, Instr *i, \
#define CALLBACK(name) \
template <typename R = void, typename A0 = void, typename A1 = void, \
int IMM_MASK = 0> \
static uint32_t name(Memory *memory, void *guest_ctx, Register *r, Instr *i, \
uint32_t idx)
#define LOAD_ARG0() helper<A0, 0, IMM_MASK>::LoadArg(r, i)
#define LOAD_ARG1() helper<A1, 1, IMM_MASK>::LoadArg(r, i)
@ -203,8 +203,7 @@ CALLBACK(PRINTF) {
CALLBACK(LOAD_CONTEXT) {
A0 offset = LOAD_ARG0();
R v = *reinterpret_cast<R *>(reinterpret_cast<uint8_t *>(ctx->guest_ctx) +
offset);
R v = *reinterpret_cast<R *>(reinterpret_cast<uint8_t *>(guest_ctx) + offset);
STORE_RESULT(v);
return NEXT_INSTR;
}
@ -212,49 +211,48 @@ CALLBACK(LOAD_CONTEXT) {
CALLBACK(STORE_CONTEXT) {
A0 offset = LOAD_ARG0();
A1 v = LOAD_ARG1();
*reinterpret_cast<A1 *>(reinterpret_cast<uint8_t *>(ctx->guest_ctx) +
offset) = v;
*reinterpret_cast<A1 *>(reinterpret_cast<uint8_t *>(guest_ctx) + offset) = v;
return NEXT_INSTR;
}
CALLBACK(LOAD_I8) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = ctx->R8(ctx, addr);
R v = memory->R8(addr);
STORE_RESULT(v);
return NEXT_INSTR;
}
CALLBACK(LOAD_I16) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = ctx->R16(ctx, addr);
R v = memory->R16(addr);
STORE_RESULT(v);
return NEXT_INSTR;
}
CALLBACK(LOAD_I32) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = ctx->R32(ctx, addr);
R v = memory->R32(addr);
STORE_RESULT(v);
return NEXT_INSTR;
}
CALLBACK(LOAD_I64) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = ctx->R64(ctx, addr);
R v = memory->R64(addr);
STORE_RESULT(v);
return NEXT_INSTR;
}
CALLBACK(LOAD_F32) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = ctx->RF32(ctx, addr);
R v = memory->RF32(addr);
STORE_RESULT(v);
return NEXT_INSTR;
}
CALLBACK(LOAD_F64) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = ctx->RF64(ctx, addr);
R v = memory->RF64(addr);
STORE_RESULT(v);
return NEXT_INSTR;
}
@ -348,42 +346,42 @@ CALLBACK(LOAD_DYN_F64) {
CALLBACK(STORE_I8) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
ctx->W8(ctx, addr, v);
memory->W8(addr, v);
return NEXT_INSTR;
}
CALLBACK(STORE_I16) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
ctx->W16(ctx, addr, v);
memory->W16(addr, v);
return NEXT_INSTR;
}
CALLBACK(STORE_I32) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
ctx->W32(ctx, addr, v);
memory->W32(addr, v);
return NEXT_INSTR;
}
CALLBACK(STORE_I64) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
ctx->W64(ctx, addr, v);
memory->W64(addr, v);
return NEXT_INSTR;
}
CALLBACK(STORE_F32) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
ctx->WF32(ctx, addr, v);
memory->WF32(addr, v);
return NEXT_INSTR;
}
CALLBACK(STORE_F64) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
ctx->WF64(ctx, addr, v);
memory->WF64(addr, v);
return NEXT_INSTR;
}
@ -757,7 +755,7 @@ CALLBACK(BRANCH_INDIRECT) {
CALLBACK(CALL_EXTERNAL) {
A0 addr = LOAD_ARG0();
void (*func)(void *) = (void (*)(void *))(intptr_t)addr;
func(ctx->guest_ctx);
func(guest_ctx);
return NEXT_INSTR;
}

View File

@ -10,4 +10,6 @@ X64Block::X64Block(int guest_cycles) : RuntimeBlock(guest_cycles) {}
X64Block::~X64Block() {}
uint32_t X64Block::Call(RuntimeContext &runtime_ctx) { return 0xdeadbeef; }
uint32_t X64Block::Call(emu::Memory *memory, void *guest_ctx) {
return 0xdeadbeef;
}

View File

@ -15,7 +15,7 @@ class X64Block : public RuntimeBlock {
X64Block(int guest_cycles);
~X64Block();
uint32_t Call(RuntimeContext &runtime_ctx);
uint32_t Call(emu::Memory *memory, void *guest_ctx);
private:
};

View File

@ -9,10 +9,6 @@ using namespace dreavm::cpu::frontend::sh4;
using namespace dreavm::cpu::ir;
using namespace dreavm::emu;
void SRUpdated(SH4Context *ctx) { ctx->SRUpdated(); }
void FPSCRUpdated(SH4Context *ctx) { ctx->FPSCRUpdated(); }
SH4Builder::SH4Builder(Memory &memory)
: memory_(memory), has_delay_instr_(false), last_instr_(nullptr) {}

View File

@ -13,54 +13,6 @@ using namespace dreavm::cpu;
using namespace dreavm::cpu::ir;
using namespace dreavm::emu;
static uint8_t R8(RuntimeContext *ctx, uint32_t addr) {
return ctx->runtime->memory().R8(addr);
}
static uint16_t R16(RuntimeContext *ctx, uint32_t addr) {
return ctx->runtime->memory().R16(addr);
}
static uint32_t R32(RuntimeContext *ctx, uint32_t addr) {
return ctx->runtime->memory().R32(addr);
}
static uint64_t R64(RuntimeContext *ctx, uint32_t addr) {
return ctx->runtime->memory().R64(addr);
}
static float RF32(RuntimeContext *ctx, uint32_t addr) {
return ctx->runtime->memory().RF32(addr);
}
static double RF64(RuntimeContext *ctx, uint32_t addr) {
return ctx->runtime->memory().RF64(addr);
}
static void W8(RuntimeContext *ctx, uint32_t addr, uint8_t value) {
ctx->runtime->memory().W8(addr, value);
}
static void W16(RuntimeContext *ctx, uint32_t addr, uint16_t value) {
ctx->runtime->memory().W16(addr, value);
}
static void W32(RuntimeContext *ctx, uint32_t addr, uint32_t value) {
ctx->runtime->memory().W32(addr, value);
}
static void W64(RuntimeContext *ctx, uint32_t addr, uint64_t value) {
ctx->runtime->memory().W64(addr, value);
}
static void WF32(RuntimeContext *ctx, uint32_t addr, float value) {
ctx->runtime->memory().WF32(addr, value);
}
static void WF64(RuntimeContext *ctx, uint32_t addr, double value) {
ctx->runtime->memory().WF64(addr, value);
}
Runtime::Runtime(Memory &memory)
: memory_(memory),
frontend_(nullptr),
@ -68,20 +20,6 @@ Runtime::Runtime(Memory &memory)
pending_reset_(false) {
blocks_ = new std::unique_ptr<RuntimeBlock>[MAX_BLOCKS];
runtime_ctx_.runtime = this;
runtime_ctx_.R8 = &::R8;
runtime_ctx_.R16 = &::R16;
runtime_ctx_.R32 = &::R32;
runtime_ctx_.R64 = &::R64;
runtime_ctx_.RF32 = &::RF32;
runtime_ctx_.RF64 = &::RF64;
runtime_ctx_.W8 = &::W8;
runtime_ctx_.W16 = &::W16;
runtime_ctx_.W32 = &::W32;
runtime_ctx_.W64 = &::W64;
runtime_ctx_.WF32 = &::WF32;
runtime_ctx_.WF64 = &::WF64;
pass_runner_.AddPass(std::unique_ptr<Pass>(new ValidateBlockPass()));
pass_runner_.AddPass(std::unique_ptr<Pass>(new ControlFlowAnalysisPass()));
pass_runner_.AddPass(std::unique_ptr<Pass>(new ContextPromotionPass()));

View File

@ -31,25 +31,6 @@ static inline uint32_t BlockOffset(uint32_t addr) {
class Runtime;
class RuntimeBlock;
struct RuntimeContext {
RuntimeContext() : runtime(nullptr), guest_ctx(nullptr) {}
Runtime *runtime;
void *guest_ctx;
uint8_t (*R8)(RuntimeContext *, uint32_t);
uint16_t (*R16)(RuntimeContext *, uint32_t);
uint32_t (*R32)(RuntimeContext *, uint32_t);
uint64_t (*R64)(RuntimeContext *, uint32_t);
float (*RF32)(RuntimeContext *, uint32_t);
double (*RF64)(RuntimeContext *, uint32_t);
void (*W8)(RuntimeContext *, uint32_t, uint8_t);
void (*W16)(RuntimeContext *, uint32_t, uint16_t);
void (*W32)(RuntimeContext *, uint32_t, uint32_t);
void (*W64)(RuntimeContext *, uint32_t, uint64_t);
void (*WF32)(RuntimeContext *, uint32_t, float);
void (*WF64)(RuntimeContext *, uint32_t, double);
};
class RuntimeBlock {
public:
RuntimeBlock(int guest_cycles) : guest_cycles_(guest_cycles) {}
@ -57,7 +38,7 @@ class RuntimeBlock {
int guest_cycles() { return guest_cycles_; }
virtual uint32_t Call(RuntimeContext &runtime_ctx) = 0;
virtual uint32_t Call(emu::Memory *memory, void *guest_ctx) = 0;
private:
int guest_cycles_;
@ -69,7 +50,6 @@ class Runtime {
~Runtime();
emu::Memory &memory() { return memory_; }
RuntimeContext &ctx() { return runtime_ctx_; }
bool Init(frontend::Frontend *frontend, backend::Backend *backend);
RuntimeBlock *ResolveBlock(uint32_t addr);
@ -82,7 +62,6 @@ class Runtime {
emu::Memory &memory_;
frontend::Frontend *frontend_;
backend::Backend *backend_;
RuntimeContext runtime_ctx_;
ir::PassRunner pass_runner_;
// FIXME 64 mb, could cut down to 8 mb if indices were stored instead of
// pointers

View File

@ -14,63 +14,6 @@ InterruptInfo interrupts[NUM_INTERRUPTS] = {
#undef SH4_INT
};
void SH4Context::SetRegisterBank(int bank) {
if (bank == 0) {
for (int s = 0; s < 8; s++) {
rbnk[1][s] = r[s];
r[s] = rbnk[0][s];
}
} else {
for (int s = 0; s < 8; s++) {
rbnk[0][s] = r[s];
r[s] = rbnk[1][s];
}
}
}
void SH4Context::SwapFPRegisters() {
unsigned s;
uint32_t z;
for (s = 0; s <= 15; s++) {
z = fr[s];
fr[s] = xf[s];
xf[s] = z;
}
}
void SH4Context::SwapFPCouples() {
int s;
uint32_t z;
for (s = 0; s <= 15; s = s + 2) {
z = fr[s];
fr[s] = fr[s + 1];
fr[s + 1] = z;
z = xf[s];
xf[s] = xf[s + 1];
xf[s + 1] = z;
}
}
void SH4Context::SRUpdated() {
if (sr.RB != old_sr.RB) {
SetRegisterBank(sr.RB ? 1 : 0);
}
old_sr = sr;
sh4->UpdatePendingInterrupts();
}
void SH4Context::FPSCRUpdated() {
if (fpscr.FR != old_fpscr.FR) {
SwapFPRegisters();
}
if (fpscr.PR != old_fpscr.PR) {
SwapFPCouples();
}
old_fpscr = fpscr;
}
SH4::SH4(emu::Scheduler &scheduler, Memory &memory)
: scheduler_(scheduler), memory_(memory) {}
@ -78,9 +21,6 @@ SH4::~SH4() {}
bool SH4::Init(Runtime *runtime) {
runtime_ = runtime;
if (runtime_) {
runtime_->ctx().guest_ctx = &ctx_;
}
scheduler_.AddDevice(this);
@ -108,7 +48,7 @@ int64_t SH4::Execute(int64_t cycles) {
RuntimeBlock *block = runtime_->ResolveBlock(ctx_.pc);
CHECK(block);
uint32_t nextpc = block->Call(runtime_->ctx());
uint32_t nextpc = block->Call(&memory_, &ctx_);
remaining -= block->guest_cycles();
ctx_.pc = nextpc;
@ -316,8 +256,8 @@ void SH4::InitMemory() {
void SH4::InitContext() {
memset(&ctx_, 0, sizeof(ctx_));
ctx_.sh4 = this;
// ctx_.pc = 0xa0000000;
ctx_.pc = 0x0c010000;
ctx_.pc = 0xa0000000;
// ctx_.pc = 0x0c010000;
ctx_.pr = 0xdeadbeef;
#define SH4_REG(addr, name, flags, default, reset, sleep, standby, type) \
if (default != HELD) { \
@ -399,10 +339,7 @@ void SH4::CheckPendingInterrupts() {
ctx_.sr.BL = 1;
ctx_.sr.MD = 1;
ctx_.sr.RB = 1;
if (ctx_.old_sr.RB != ctx_.sr.RB) {
ctx_.SetRegisterBank(1);
}
ctx_.old_sr = ctx_.sr;
SRUpdated(&ctx_);
ctx_.pc = ctx_.vbr + 0x600;
if (ctx_.sleep_mode == 1) {
ctx_.sleep_mode = 2;

View File

@ -1,6 +1,7 @@
#ifndef SH4_H
#define SH4_H
#include "cpu/sh4_context.h"
#include "emu/device.h"
#include "emu/memory.h"
#include "emu/scheduler.h"
@ -12,8 +13,6 @@ namespace cpu {
class Runtime;
enum { MAX_FRAMES = 4096 };
// registers
enum {
UNDEFINED = 0x0,
@ -48,40 +47,6 @@ union CCR_T {
uint32_t full;
};
union SR_T {
struct {
uint32_t T : 1;
uint32_t S : 1;
uint32_t reserved : 2;
uint32_t IMASK : 4;
uint32_t Q : 1;
uint32_t M : 1;
uint32_t reserved1 : 5;
uint32_t FD : 1;
uint32_t reserved2 : 12;
uint32_t BL : 1;
uint32_t RB : 1;
uint32_t MD : 1;
uint32_t reserved3 : 1;
};
uint32_t full;
};
union FPSCR_T {
struct {
uint32_t RM : 2;
uint32_t flag : 5;
uint32_t enable : 5;
uint32_t cause : 6;
uint32_t DN : 1;
uint32_t PR : 1;
uint32_t SZ : 1;
uint32_t FR : 1;
uint32_t reserved : 10;
};
uint32_t full;
};
union CHCR_T {
struct {
uint32_t DE : 1;
@ -140,40 +105,8 @@ enum DDTRW { //
DDT_W
};
// SH4 state is split into the SH4Context class for the JIT to easily access
class SH4;
class SH4Context {
public:
void SetRegisterBank(int bank);
void SwapFPRegisters();
void SwapFPCouples();
void SRUpdated();
void FPSCRUpdated();
SH4 *sh4;
uint32_t pc, spc;
uint32_t pr;
uint32_t gbr, vbr;
uint32_t mach, macl;
uint32_t r[16], rbnk[2][8], sgr;
uint32_t fr[16], xf[16];
uint32_t fpul;
uint32_t dbr;
uint32_t m[0x4000];
uint32_t sq[2][8];
uint8_t sleep_mode;
uint32_t ea;
int64_t icount, nextcheck;
SR_T sr, ssr, old_sr;
FPSCR_T fpscr, old_fpscr;
};
class SH4 : public emu::Device {
friend class SH4Context;
friend void SRUpdated(SH4Context *ctx);
friend void RunSH4Test(const SH4Test &);
public:
@ -205,10 +138,10 @@ class SH4 : public emu::Device {
void InitMemory();
void InitContext();
SH4Context ctx_;
emu::Scheduler &scheduler_;
emu::Memory &memory_;
Runtime *runtime_;
SH4Context ctx_;
#define SH4_REG(addr, name, flags, default, reset, sleep, standby, type) \
type &name{reinterpret_cast<type &>(ctx_.m[name##_OFFSET])};
#include "cpu/sh4_regs.inc"

65
src/cpu/sh4_context.cc Normal file
View File

@ -0,0 +1,65 @@
#include "core/core.h"
#include "cpu/sh4.h"
#include "cpu/sh4_context.h"
namespace dreavm {
namespace cpu {
static void SetRegisterBank(SH4Context *ctx, int bank) {
if (bank == 0) {
for (int s = 0; s < 8; s++) {
ctx->rbnk[1][s] = ctx->r[s];
ctx->r[s] = ctx->rbnk[0][s];
}
} else {
for (int s = 0; s < 8; s++) {
ctx->rbnk[0][s] = ctx->r[s];
ctx->r[s] = ctx->rbnk[1][s];
}
}
}
static void SwapFPRegisters(SH4Context *ctx) {
unsigned s;
uint32_t z;
for (s = 0; s <= 15; s++) {
z = ctx->fr[s];
ctx->fr[s] = ctx->xf[s];
ctx->xf[s] = z;
}
}
static void SwapFPCouples(SH4Context *ctx) {
int s;
uint32_t z;
for (s = 0; s <= 15; s = s + 2) {
z = ctx->fr[s];
ctx->fr[s] = ctx->fr[s + 1];
ctx->fr[s + 1] = z;
z = ctx->xf[s];
ctx->xf[s] = ctx->xf[s + 1];
ctx->xf[s + 1] = z;
}
}
void SRUpdated(SH4Context *ctx) {
if (ctx->sr.RB != ctx->old_sr.RB) {
SetRegisterBank(ctx, ctx->sr.RB ? 1 : 0);
}
ctx->sh4->UpdatePendingInterrupts();
ctx->old_sr = ctx->sr;
}
void FPSCRUpdated(SH4Context *ctx) {
if (ctx->fpscr.FR != ctx->old_fpscr.FR) {
SwapFPRegisters(ctx);
}
if (ctx->fpscr.PR != ctx->old_fpscr.PR) {
SwapFPCouples(ctx);
}
ctx->old_fpscr = ctx->fpscr;
}
}
}

67
src/cpu/sh4_context.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef SH4_CONTEXT_H
#define SH4_CONTEXT_H
#include <stdint.h>
namespace dreavm {
namespace cpu {
union SR_T {
struct {
uint32_t T : 1;
uint32_t S : 1;
uint32_t reserved : 2;
uint32_t IMASK : 4;
uint32_t Q : 1;
uint32_t M : 1;
uint32_t reserved1 : 5;
uint32_t FD : 1;
uint32_t reserved2 : 12;
uint32_t BL : 1;
uint32_t RB : 1;
uint32_t MD : 1;
uint32_t reserved3 : 1;
};
uint32_t full;
};
union FPSCR_T {
struct {
uint32_t RM : 2;
uint32_t flag : 5;
uint32_t enable : 5;
uint32_t cause : 6;
uint32_t DN : 1;
uint32_t PR : 1;
uint32_t SZ : 1;
uint32_t FR : 1;
uint32_t reserved : 10;
};
uint32_t full;
};
class SH4;
struct SH4Context {
SH4 *sh4;
uint32_t pc, spc;
uint32_t pr;
uint32_t gbr, vbr;
uint32_t mach, macl;
uint32_t r[16], rbnk[2][8], sgr;
uint32_t fr[16], xf[16];
uint32_t fpul;
uint32_t dbr;
uint32_t m[0x4000];
uint32_t sq[2][8];
uint8_t sleep_mode;
SR_T sr, ssr, old_sr;
FPSCR_T fpscr, old_fpscr;
};
void SRUpdated(SH4Context *ctx);
void FPSCRUpdated(SH4Context *ctx);
}
}
#endif

View File

@ -20,27 +20,20 @@ using namespace dreavm::system;
Emulator::Emulator(System &sys)
: sys_(sys),
scheduler_(new Scheduler()),
memory_(new Memory()),
rt_frontend_(new SH4Frontend(*memory_)),
rt_backend_(new InterpreterBackend(*memory_)),
// rt_backend_(new X64Backend(*memory_)),
runtime_(new Runtime(*memory_)),
processor_(new SH4(*scheduler_, *memory_)),
holly_(new Holly(*scheduler_, *memory_, *processor_)) {
runtime_(memory_),
processor_(scheduler_, memory_),
holly_(scheduler_, memory_, processor_) {
rt_frontend_ = new SH4Frontend(memory_);
rt_backend_ = new InterpreterBackend(memory_);
// rt_backend_ = new X64Backend(*memory_);
rb_ = new GLBackend(sys);
}
Emulator::~Emulator() {
Profiler::Shutdown();
delete rb_;
delete holly_;
delete processor_;
delete runtime_;
delete rt_backend_;
delete rt_frontend_;
delete memory_;
delete scheduler_;
}
bool Emulator::Init() {
@ -64,17 +57,17 @@ bool Emulator::Init() {
return false;
}
if (!runtime_->Init(rt_frontend_, rt_backend_)) {
if (!runtime_.Init(rt_frontend_, rt_backend_)) {
return false;
}
// order here is important, sh4 memory handlers need to override
// some of the broader holly handlers
if (!holly_->Init(rb_)) {
if (!holly_.Init(rb_)) {
return false;
}
if (!processor_->Init(runtime_)) {
if (!processor_.Init(&runtime_)) {
return false;
}
@ -102,7 +95,7 @@ bool Emulator::LaunchBIN(const char *path) {
// load to 0x0c010000 (area 3) which is where 1ST_READ.BIN is normally
// loaded to
memory_->Memcpy(0x0c010000, data, size);
memory_.Memcpy(0x0c010000, data, size);
free(data);
return true;
}
@ -114,7 +107,7 @@ bool Emulator::LaunchGDI(const char *path) {
return false;
}
holly_->gdrom().SetDisc(std::move(gdi));
holly_.gdrom().SetDisc(std::move(gdi));
return true;
}
@ -122,14 +115,14 @@ bool Emulator::LaunchGDI(const char *path) {
void Emulator::Tick() {
PumpEvents();
scheduler_->Tick();
scheduler_.Tick();
RenderFrame();
}
// for memory mapping notes, see 2.1 System Mapping in the hardware manual
bool Emulator::MountRam() {
memory_->Alloc(0x0, 0x1fffffff, 0xe0000000);
memory_.Alloc(0x0, 0x1fffffff, 0xe0000000);
return true;
}
@ -164,7 +157,7 @@ bool Emulator::LoadBios(const char *path) {
return false;
}
memory_->Memcpy(BIOS_START, data, size);
memory_.Memcpy(BIOS_START, data, size);
free(data);
return true;
}
@ -200,7 +193,7 @@ bool Emulator::LoadFlash(const char *path) {
return false;
}
memory_->Memcpy(FLASH_START, data, size);
memory_.Memcpy(FLASH_START, data, size);
free(data);
return true;
}
@ -212,7 +205,7 @@ void Emulator::PumpEvents() {
// let the profiler take a stab at the input first
if (!Profiler::HandleInput(ev.key.code, ev.key.value)) {
// else, forward to holly
holly_->HandleInput(0, ev.key.code, ev.key.value);
holly_.HandleInput(0, ev.key.code, ev.key.value);
}
} else if (ev.type == SE_MOUSEMOVE) {
Profiler::HandleMouseMove(ev.mousemove.x, ev.mousemove.y);
@ -231,7 +224,7 @@ void Emulator::RenderFrame() {
// render stats
char stats[512];
snprintf(stats, sizeof(stats), "%.2f%%, %.2f fps, %.2f vbps",
scheduler_->perf(), holly_->fps(), holly_->vbps());
scheduler_.perf(), holly_.fps(), holly_.vbps());
LOG_EVERY_N(INFO, 10) << stats;
rb_->RenderText2D(0.0f, 0.0f, 12, 0xffffffff, stats);

View File

@ -4,6 +4,7 @@
#include "cpu/sh4.h"
#include "cpu/backend/backend.h"
#include "cpu/frontend/frontend.h"
#include "cpu/runtime.h"
#include "holly/holly.h"
#include "holly/maple_controller.h"
#include "renderer/backend.h"
@ -31,13 +32,13 @@ class Emulator {
void RenderFrame();
system::System &sys_;
emu::Scheduler *scheduler_;
emu::Memory *memory_;
emu::Scheduler scheduler_;
emu::Memory memory_;
cpu::Runtime runtime_;
cpu::SH4 processor_;
holly::Holly holly_;
cpu::frontend::Frontend *rt_frontend_;
cpu::backend::Backend *rt_backend_;
cpu::Runtime *runtime_;
cpu::SH4 *processor_;
holly::Holly *holly_;
renderer::Backend *rb_;
};
}

View File

@ -45,11 +45,10 @@ int main(int argc, char **argv) {
LOG(FATAL) << "Failed to load bin.";
}
// if (!emu.LaunchGDI(
// "../dreamcast/Crazy Taxi 2 v1.004 (2001)(Sega)(NTSC)(US)[!]/Crazy "
// "Taxi 2 v1.004 (2001)(Sega)(NTSC)(US)[!].gdi")) {
// LOG(FATAL) << "Failed to load GDI.";
// }
if (!emu.LaunchGDI(
"../dreamcast/Crazy Taxi 2 v1.004 (2001)(Sega)(NTSC)(US)[!]/Crazy Taxi 2 v1.004 (2001)(Sega)(NTSC)(US)[!].gdi")) {
LOG(FATAL) << "Failed to load GDI.";
}
while (1) {
sys.Tick();

View File

@ -20,7 +20,6 @@ namespace cpu {
void RunSH4Test(const SH4Test &test) {
Scheduler scheduler;
Memory memory;
SH4 sh4(scheduler, memory);
// initialize runtime
frontend::sh4::SH4Frontend sh4_frontend(memory);
@ -29,6 +28,7 @@ void RunSH4Test(const SH4Test &test) {
ASSERT_TRUE(runtime.Init(&sh4_frontend, &int_backend));
// initialize device
SH4 sh4(scheduler, memory);
ASSERT_TRUE(sh4.Init(&runtime));
// mount the test binary and a small stack