mirror of https://github.com/inolen/redream.git
simplify sh4 execute loop
This commit is contained in:
parent
51eb95e184
commit
4308e570e5
|
@ -14,7 +14,7 @@ bool AICA::Init() {
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t AICA::Execute(uint32_t cycles) {
|
||||
int AICA::Execute(int cycles) {
|
||||
// uint16_t MCIEB = *reinterpret_cast<uint16_t *>(&aica_regs_[MCIEB_OFFSET]);
|
||||
// uint16_t MCIPD = *reinterpret_cast<uint16_t *>(&aica_regs_[MCIPD_OFFSET]);
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ class AICA : public hw::Device {
|
|||
public:
|
||||
AICA(hw::Dreamcast *dc);
|
||||
|
||||
uint32_t GetClockFrequency() { return 22579200; }
|
||||
int GetClockFrequency() { return 22579200; }
|
||||
|
||||
bool Init();
|
||||
uint32_t Execute(uint32_t cycles);
|
||||
int Execute(int cycles);
|
||||
|
||||
static uint32_t ReadRegister(void *ctx, uint32_t addr);
|
||||
static void WriteRegister(void *ctx, uint32_t addr, uint32_t value);
|
||||
|
|
|
@ -10,8 +10,8 @@ class Device {
|
|||
public:
|
||||
virtual ~Device(){};
|
||||
|
||||
virtual uint32_t GetClockFrequency() = 0;
|
||||
virtual uint32_t Execute(uint32_t cycles) = 0;
|
||||
virtual int GetClockFrequency() = 0;
|
||||
virtual int Execute(int cycles) = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,14 +76,14 @@ void Scheduler::Tick(const std::chrono::nanoseconds &delta) {
|
|||
for (auto &info : devices_) {
|
||||
auto delta = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
target_time - info.current_time);
|
||||
uint32_t cycles_per_second = info.device->GetClockFrequency();
|
||||
uint32_t cycles_to_run = static_cast<uint32_t>(
|
||||
(delta.count() * static_cast<uint64_t>(cycles_per_second)) /
|
||||
int cycles_per_second = info.device->GetClockFrequency();
|
||||
int cycles_to_run = static_cast<int>(
|
||||
(delta.count() * static_cast<int64_t>(cycles_per_second)) /
|
||||
NS_PER_SEC);
|
||||
uint32_t ran = info.device->Execute(cycles_to_run);
|
||||
int ran = info.device->Execute(cycles_to_run);
|
||||
|
||||
info.current_time += std::chrono::nanoseconds(
|
||||
(ran * static_cast<uint64_t>(NS_PER_SEC)) / cycles_per_second);
|
||||
(ran * static_cast<int64_t>(NS_PER_SEC)) / cycles_per_second);
|
||||
}
|
||||
|
||||
base_time_ = target_time;
|
||||
|
|
|
@ -53,10 +53,10 @@ bool SH4::Init() {
|
|||
|
||||
void SH4::SetPC(uint32_t pc) { ctx_.pc = pc; }
|
||||
|
||||
uint32_t SH4::Execute(uint32_t cycles) {
|
||||
int SH4::Execute(int cycles) {
|
||||
PROFILER_RUNTIME("SH4::Execute");
|
||||
|
||||
uint32_t remaining = cycles;
|
||||
int remaining = cycles;
|
||||
|
||||
// update timers
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
@ -64,18 +64,11 @@ uint32_t SH4::Execute(uint32_t cycles) {
|
|||
RunTimer(i, cycles >> 2);
|
||||
}
|
||||
|
||||
while (ctx_.pc) {
|
||||
while (ctx_.pc && remaining > 0) {
|
||||
RuntimeBlock *block = runtime_.GetBlock(ctx_.pc, &ctx_);
|
||||
|
||||
// be careful not to wrap around
|
||||
uint32_t next_remaining = remaining - block->guest_cycles();
|
||||
if (next_remaining > remaining) {
|
||||
break;
|
||||
}
|
||||
|
||||
// run the block
|
||||
ctx_.pc = block->call()(&memory_, &ctx_, block);
|
||||
remaining = next_remaining;
|
||||
remaining -= block->guest_cycles();
|
||||
|
||||
CheckPendingCacheReset();
|
||||
CheckPendingInterrupts();
|
||||
|
@ -459,7 +452,7 @@ bool SH4::TimerEnabled(int n) { //
|
|||
return TSTR & (1 << n);
|
||||
}
|
||||
|
||||
void SH4::RunTimer(int n, uint32_t cycles) {
|
||||
void SH4::RunTimer(int n, int cycles) {
|
||||
static const int tcr_shift[] = {2, 4, 6, 8, 10, 0, 0, 0};
|
||||
|
||||
if (!TimerEnabled(n)) {
|
||||
|
|
|
@ -118,11 +118,11 @@ class SH4 : public hw::Device {
|
|||
public:
|
||||
SH4(hw::Memory &memory, jit::Runtime &runtime);
|
||||
|
||||
uint32_t GetClockFrequency() { return 200000000; }
|
||||
int GetClockFrequency() { return 200000000; }
|
||||
|
||||
bool Init();
|
||||
void SetPC(uint32_t pc);
|
||||
uint32_t Execute(uint32_t cycles);
|
||||
int Execute(int cycles);
|
||||
|
||||
// DMAC
|
||||
void DDT(int channel, DDTRW rw, uint32_t addr);
|
||||
|
@ -165,7 +165,7 @@ class SH4 : public hw::Device {
|
|||
|
||||
// TMU
|
||||
bool TimerEnabled(int n);
|
||||
void RunTimer(int n, uint32_t cycles);
|
||||
void RunTimer(int n, int cycles);
|
||||
|
||||
hw::Memory &memory_;
|
||||
jit::Runtime &runtime_;
|
||||
|
|
|
@ -14,7 +14,8 @@ InterpreterBlock::InterpreterBlock(int guest_cycles, IntInstr *instrs,
|
|||
|
||||
void InterpreterBlock::Dump() { LOG_INFO("Unimplemented"); }
|
||||
|
||||
uint32_t InterpreterBlock::Call(Memory *memory, void *guest_ctx, RuntimeBlock *block) {
|
||||
uint32_t InterpreterBlock::Call(Memory *memory, void *guest_ctx,
|
||||
RuntimeBlock *block) {
|
||||
InterpreterBlock *self = reinterpret_cast<InterpreterBlock *>(block);
|
||||
IntValue *registers = reinterpret_cast<IntValue *>(
|
||||
alloca(int_num_registers * sizeof(IntValue)));
|
||||
|
|
|
@ -18,7 +18,8 @@ class InterpreterBlock : public RuntimeBlock {
|
|||
void Dump();
|
||||
|
||||
private:
|
||||
static uint32_t Call(hw::Memory *memory, void *guest_ctx, RuntimeBlock *block);
|
||||
static uint32_t Call(hw::Memory *memory, void *guest_ctx,
|
||||
RuntimeBlock *block);
|
||||
|
||||
IntInstr *instrs_;
|
||||
int num_instrs_;
|
||||
|
|
|
@ -23,8 +23,7 @@ enum {
|
|||
MAX_BLOCKS = 0x1000000 >> BLOCK_ADDR_SHIFT,
|
||||
};
|
||||
|
||||
#define BLOCK_OFFSET(addr) \
|
||||
((addr & BLOCK_ADDR_MASK) >> BLOCK_ADDR_SHIFT)
|
||||
#define BLOCK_OFFSET(addr) ((addr & BLOCK_ADDR_MASK) >> BLOCK_ADDR_SHIFT)
|
||||
|
||||
Runtime::Runtime(Memory &memory, frontend::Frontend &frontend,
|
||||
backend::Backend &backend)
|
||||
|
|
|
@ -16,11 +16,12 @@ class Frontend;
|
|||
}
|
||||
|
||||
class RuntimeBlock;
|
||||
typedef uint32_t(*RuntimeCall)(hw::Memory *, void *, RuntimeBlock *);
|
||||
typedef uint32_t (*RuntimeCall)(hw::Memory *, void *, RuntimeBlock *);
|
||||
|
||||
class RuntimeBlock {
|
||||
public:
|
||||
RuntimeBlock(int guest_cycles, RuntimeCall call) : guest_cycles_(guest_cycles), call_(call) {}
|
||||
RuntimeBlock(int guest_cycles, RuntimeCall call)
|
||||
: guest_cycles_(guest_cycles), call_(call) {}
|
||||
virtual ~RuntimeBlock() {}
|
||||
|
||||
int guest_cycles() { return guest_cycles_; }
|
||||
|
|
Loading…
Reference in New Issue