mirror of https://github.com/mgba-emu/mgba.git
Core: Revise clock timing (WIP)
This commit is contained in:
parent
e45519075a
commit
b2e2965273
|
@ -88,7 +88,8 @@ static inline void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode execution
|
||||||
case MODE_THUMB:
|
case MODE_THUMB:
|
||||||
cpu->cpsr.t = 1;
|
cpu->cpsr.t = 1;
|
||||||
}
|
}
|
||||||
cpu->nextEvent = cpu->cycles;
|
cpu->nextEvent -= cpu->cycles;
|
||||||
|
cpu->cycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _ARMReadCPSR(struct ARMCore* cpu) {
|
static inline void _ARMReadCPSR(struct ARMCore* cpu) {
|
||||||
|
|
|
@ -166,7 +166,7 @@ void ARMRaiseIRQ(struct ARMCore* cpu) {
|
||||||
_ARMSetMode(cpu, MODE_ARM);
|
_ARMSetMode(cpu, MODE_ARM);
|
||||||
cpu->spsr = cpsr;
|
cpu->spsr = cpsr;
|
||||||
cpu->cpsr.i = 1;
|
cpu->cpsr.i = 1;
|
||||||
cpu->cycles += currentCycles;
|
cpu->cycles -= currentCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMRaiseSWI(struct ARMCore* cpu) {
|
void ARMRaiseSWI(struct ARMCore* cpu) {
|
||||||
|
@ -186,7 +186,7 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
|
||||||
_ARMSetMode(cpu, MODE_ARM);
|
_ARMSetMode(cpu, MODE_ARM);
|
||||||
cpu->spsr = cpsr;
|
cpu->spsr = cpsr;
|
||||||
cpu->cpsr.i = 1;
|
cpu->cpsr.i = 1;
|
||||||
cpu->cycles += currentCycles;
|
cpu->cycles -= currentCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMRaiseUndefined(struct ARMCore* cpu) {
|
void ARMRaiseUndefined(struct ARMCore* cpu) {
|
||||||
|
@ -206,7 +206,7 @@ void ARMRaiseUndefined(struct ARMCore* cpu) {
|
||||||
_ARMSetMode(cpu, MODE_ARM);
|
_ARMSetMode(cpu, MODE_ARM);
|
||||||
cpu->spsr = cpsr;
|
cpu->spsr = cpsr;
|
||||||
cpu->cpsr.i = 1;
|
cpu->cpsr.i = 1;
|
||||||
cpu->cycles += currentCycles;
|
cpu->cycles -= currentCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ARMStep(struct ARMCore* cpu) {
|
static inline void ARMStep(struct ARMCore* cpu) {
|
||||||
|
@ -265,7 +265,7 @@ static inline void ARMStep(struct ARMCore* cpu) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!conditionMet) {
|
if (!conditionMet) {
|
||||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
cpu->cycles -= ARM_PREFETCH_CYCLES;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,18 +288,18 @@ void ARMRun(struct ARMCore* cpu) {
|
||||||
} else {
|
} else {
|
||||||
ARMStep(cpu);
|
ARMStep(cpu);
|
||||||
}
|
}
|
||||||
if (cpu->cycles >= cpu->nextEvent) {
|
if (cpu->cycles <= 0) {
|
||||||
cpu->irqh.processEvents(cpu);
|
cpu->irqh.processEvents(cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMRunLoop(struct ARMCore* cpu) {
|
void ARMRunLoop(struct ARMCore* cpu) {
|
||||||
if (cpu->executionMode == MODE_THUMB) {
|
if (cpu->executionMode == MODE_THUMB) {
|
||||||
while (cpu->cycles < cpu->nextEvent) {
|
while (cpu->cycles > 0) {
|
||||||
ThumbStep(cpu);
|
ThumbStep(cpu);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (cpu->cycles < cpu->nextEvent) {
|
while (cpu->cycles > 0) {
|
||||||
ARMStep(cpu);
|
ARMStep(cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,9 @@ void ARMDebuggerDeinit(struct mDebuggerPlatform* platform) {
|
||||||
static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
|
static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
|
||||||
struct ARMDebugger* debugger = (struct ARMDebugger*) platform;
|
struct ARMDebugger* debugger = (struct ARMDebugger*) platform;
|
||||||
struct ARMCore* cpu = debugger->cpu;
|
struct ARMCore* cpu = debugger->cpu;
|
||||||
cpu->nextEvent = cpu->cycles;
|
cpu->nextEvent -= cpu->cycles;
|
||||||
|
cpu->cycles = 0;
|
||||||
|
|
||||||
if (reason == DEBUGGER_ENTER_BREAKPOINT) {
|
if (reason == DEBUGGER_ENTER_BREAKPOINT) {
|
||||||
struct ARMDebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu));
|
struct ARMDebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu));
|
||||||
if (breakpoint && breakpoint->isSw) {
|
if (breakpoint && breakpoint->isSw) {
|
||||||
|
|
|
@ -288,7 +288,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
||||||
static void _ARMInstruction ## NAME (struct ARMCore* cpu, uint32_t opcode) { \
|
static void _ARMInstruction ## NAME (struct ARMCore* cpu, uint32_t opcode) { \
|
||||||
int currentCycles = ARM_PREFETCH_CYCLES; \
|
int currentCycles = ARM_PREFETCH_CYCLES; \
|
||||||
BODY; \
|
BODY; \
|
||||||
cpu->cycles += currentCycles; \
|
cpu->cycles -= currentCycles; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, S_BODY, SHIFTER, BODY) \
|
#define DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, S_BODY, SHIFTER, BODY) \
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
static void _ThumbInstruction ## NAME (struct ARMCore* cpu, uint16_t opcode) { \
|
static void _ThumbInstruction ## NAME (struct ARMCore* cpu, uint16_t opcode) { \
|
||||||
int currentCycles = THUMB_PREFETCH_CYCLES; \
|
int currentCycles = THUMB_PREFETCH_CYCLES; \
|
||||||
BODY; \
|
BODY; \
|
||||||
cpu->cycles += currentCycles; \
|
cpu->cycles -= currentCycles; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(NAME, BODY) \
|
#define DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(NAME, BODY) \
|
||||||
|
|
|
@ -23,9 +23,10 @@ void mTimingClear(struct mTiming* timing) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t when) {
|
void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t when) {
|
||||||
int32_t nextEvent = when + *timing->relativeCycles;
|
int32_t nextEvent = when + *timing->nextEvent - *timing->relativeCycles;
|
||||||
event->when = nextEvent + timing->masterCycles;
|
event->when = nextEvent + timing->masterCycles;
|
||||||
if (nextEvent < *timing->nextEvent) {
|
if (when < *timing->relativeCycles) {
|
||||||
|
*timing->relativeCycles = when;
|
||||||
*timing->nextEvent = nextEvent;
|
*timing->nextEvent = nextEvent;
|
||||||
}
|
}
|
||||||
struct mTimingEvent** previous = &timing->root;
|
struct mTimingEvent** previous = &timing->root;
|
||||||
|
@ -91,7 +92,7 @@ int32_t mTimingTick(struct mTiming* timing, int32_t cycles) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mTimingCurrentTime(const struct mTiming* timing) {
|
int32_t mTimingCurrentTime(const struct mTiming* timing) {
|
||||||
return timing->masterCycles + *timing->relativeCycles;
|
return timing->masterCycles + *timing->nextEvent - *timing->relativeCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mTimingNextEvent(struct mTiming* timing) {
|
int32_t mTimingNextEvent(struct mTiming* timing) {
|
||||||
|
@ -99,9 +100,9 @@ int32_t mTimingNextEvent(struct mTiming* timing) {
|
||||||
if (!next) {
|
if (!next) {
|
||||||
return INT_MAX;
|
return INT_MAX;
|
||||||
}
|
}
|
||||||
return next->when - timing->masterCycles - *timing->relativeCycles;
|
return next->when - timing->masterCycles - *timing->nextEvent + *timing->relativeCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent* event) {
|
int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent* event) {
|
||||||
return event->when - timing->masterCycles - *timing->relativeCycles;
|
return event->when - timing->masterCycles - *timing->nextEvent + *timing->relativeCycles;
|
||||||
}
|
}
|
||||||
|
|
11
src/gb/gb.c
11
src/gb/gb.c
|
@ -639,10 +639,10 @@ void GBUpdateIRQs(struct GB* gb) {
|
||||||
void GBProcessEvents(struct LR35902Core* cpu) {
|
void GBProcessEvents(struct LR35902Core* cpu) {
|
||||||
struct GB* gb = (struct GB*) cpu->master;
|
struct GB* gb = (struct GB*) cpu->master;
|
||||||
do {
|
do {
|
||||||
int32_t cycles = cpu->cycles;
|
int32_t cycles = cpu->nextEvent - cpu->cycles;
|
||||||
int32_t nextEvent;
|
int32_t nextEvent;
|
||||||
|
|
||||||
cpu->cycles = 0;
|
cpu->cycles = INT_MAX;
|
||||||
cpu->nextEvent = INT_MAX;
|
cpu->nextEvent = INT_MAX;
|
||||||
|
|
||||||
nextEvent = cycles;
|
nextEvent = cycles;
|
||||||
|
@ -650,9 +650,10 @@ void GBProcessEvents(struct LR35902Core* cpu) {
|
||||||
nextEvent = mTimingTick(&gb->timing, nextEvent);
|
nextEvent = mTimingTick(&gb->timing, nextEvent);
|
||||||
} while (gb->cpuBlocked);
|
} while (gb->cpuBlocked);
|
||||||
cpu->nextEvent = nextEvent;
|
cpu->nextEvent = nextEvent;
|
||||||
|
cpu->cycles = nextEvent;
|
||||||
|
|
||||||
if (cpu->halted) {
|
if (cpu->halted) {
|
||||||
cpu->cycles = cpu->nextEvent;
|
cpu->cycles = 0;
|
||||||
if (!gb->memory.ie || !gb->memory.ime) {
|
if (!gb->memory.ie || !gb->memory.ime) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +661,7 @@ void GBProcessEvents(struct LR35902Core* cpu) {
|
||||||
if (gb->earlyExit) {
|
if (gb->earlyExit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (cpu->cycles >= cpu->nextEvent);
|
} while (cpu->cycles <= 0);
|
||||||
gb->earlyExit = false;
|
gb->earlyExit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +714,7 @@ static void _enableInterrupts(struct mTiming* timing, void* user, uint32_t cycle
|
||||||
void GBHalt(struct LR35902Core* cpu) {
|
void GBHalt(struct LR35902Core* cpu) {
|
||||||
struct GB* gb = (struct GB*) cpu->master;
|
struct GB* gb = (struct GB*) cpu->master;
|
||||||
if (!(gb->memory.ie & gb->memory.io[REG_IF])) {
|
if (!(gb->memory.ie & gb->memory.io[REG_IF])) {
|
||||||
cpu->cycles = cpu->nextEvent;
|
cpu->cycles = 0;
|
||||||
cpu->halted = true;
|
cpu->halted = true;
|
||||||
} else if (gb->model < GB_MODEL_CGB) {
|
} else if (gb->model < GB_MODEL_CGB) {
|
||||||
mLOG(GB, STUB, "Unimplemented HALT bug");
|
mLOG(GB, STUB, "Unimplemented HALT bug");
|
||||||
|
|
|
@ -476,8 +476,9 @@ void GBMemoryDMA(struct GB* gb, uint16_t base) {
|
||||||
}
|
}
|
||||||
mTimingDeschedule(&gb->timing, &gb->memory.dmaEvent);
|
mTimingDeschedule(&gb->timing, &gb->memory.dmaEvent);
|
||||||
mTimingSchedule(&gb->timing, &gb->memory.dmaEvent, 8);
|
mTimingSchedule(&gb->timing, &gb->memory.dmaEvent, 8);
|
||||||
if (gb->cpu->cycles + 8 < gb->cpu->nextEvent) {
|
if (gb->cpu->cycles < 8) {
|
||||||
gb->cpu->nextEvent = gb->cpu->cycles + 8;
|
gb->cpu->nextEvent += 8 - gb->cpu->cycles;
|
||||||
|
gb->cpu->cycles = 8;
|
||||||
}
|
}
|
||||||
gb->memory.dmaSource = base;
|
gb->memory.dmaSource = base;
|
||||||
gb->memory.dmaDest = 0;
|
gb->memory.dmaDest = 0;
|
||||||
|
|
|
@ -43,7 +43,8 @@ void GBSerialize(struct GB* gb, struct GBSerializedState* state) {
|
||||||
STORE_16LE(gb->cpu->sp, 0, &state->cpu.sp);
|
STORE_16LE(gb->cpu->sp, 0, &state->cpu.sp);
|
||||||
STORE_16LE(gb->cpu->pc, 0, &state->cpu.pc);
|
STORE_16LE(gb->cpu->pc, 0, &state->cpu.pc);
|
||||||
|
|
||||||
STORE_32LE(gb->cpu->cycles, 0, &state->cpu.cycles);
|
int32_t cycles = gb->cpu->nextEvent - gb->cpu->cycles;
|
||||||
|
STORE_32LE(cycles, 0, &state->cpu.cycles);
|
||||||
STORE_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
STORE_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
||||||
|
|
||||||
STORE_16LE(gb->cpu->index, 0, &state->cpu.index);
|
STORE_16LE(gb->cpu->index, 0, &state->cpu.index);
|
||||||
|
@ -163,8 +164,10 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
||||||
gb->doubleSpeed = GBSerializedCpuFlagsGetDoubleSpeed(flags);
|
gb->doubleSpeed = GBSerializedCpuFlagsGetDoubleSpeed(flags);
|
||||||
gb->audio.timingFactor = gb->doubleSpeed + 1;
|
gb->audio.timingFactor = gb->doubleSpeed + 1;
|
||||||
|
|
||||||
LOAD_32LE(gb->cpu->cycles, 0, &state->cpu.cycles);
|
int32_t cycles;
|
||||||
|
LOAD_32LE(cycles, 0, &state->cpu.cycles);
|
||||||
LOAD_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
LOAD_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
||||||
|
gb->cpu->cycles = gb->cpu->nextEvent - cycles;
|
||||||
gb->timing.root = NULL;
|
gb->timing.root = NULL;
|
||||||
|
|
||||||
uint32_t when;
|
uint32_t when;
|
||||||
|
|
|
@ -251,23 +251,20 @@ static void GBAProcessEvents(struct ARMCore* cpu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t nextEvent = cpu->nextEvent;
|
int32_t nextEvent = cpu->nextEvent;
|
||||||
while (cpu->cycles >= nextEvent) {
|
while (cpu->cycles <= 0) {
|
||||||
|
int32_t cycles = cpu->nextEvent - cpu->cycles;
|
||||||
cpu->nextEvent = INT_MAX;
|
cpu->nextEvent = INT_MAX;
|
||||||
nextEvent = 0;
|
cpu->cycles = INT_MAX;
|
||||||
|
nextEvent = cycles;
|
||||||
do {
|
do {
|
||||||
int32_t cycles = cpu->cycles;
|
nextEvent = mTimingTick(&gba->timing, nextEvent);
|
||||||
cpu->cycles = 0;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (cycles < 0) {
|
|
||||||
mLOG(GBA, FATAL, "Negative cycles passed: %i", cycles);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
nextEvent = mTimingTick(&gba->timing, nextEvent + cycles);
|
|
||||||
} while (gba->cpuBlocked);
|
} while (gba->cpuBlocked);
|
||||||
|
|
||||||
cpu->nextEvent = nextEvent;
|
cpu->nextEvent = nextEvent;
|
||||||
|
cpu->cycles = nextEvent;
|
||||||
|
|
||||||
if (cpu->halted) {
|
if (cpu->halted) {
|
||||||
cpu->cycles = nextEvent;
|
cpu->cycles = 0;
|
||||||
if (!gba->memory.io[REG_IME >> 1] || !gba->memory.io[REG_IE >> 1]) {
|
if (!gba->memory.io[REG_IME >> 1] || !gba->memory.io[REG_IE >> 1]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -499,12 +496,13 @@ void GBATestIRQ(struct ARMCore* cpu) {
|
||||||
struct GBA* gba = (struct GBA*) cpu->master;
|
struct GBA* gba = (struct GBA*) cpu->master;
|
||||||
if (gba->memory.io[REG_IME >> 1] && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
|
if (gba->memory.io[REG_IME >> 1] && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
|
||||||
gba->springIRQ = gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1];
|
gba->springIRQ = gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1];
|
||||||
gba->cpu->nextEvent = gba->cpu->cycles;
|
gba->cpu->nextEvent -= gba->cpu->cycles;
|
||||||
|
gba->cpu->cycles = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAHalt(struct GBA* gba) {
|
void GBAHalt(struct GBA* gba) {
|
||||||
gba->cpu->nextEvent = gba->cpu->cycles;
|
gba->cpu->cycles = 0;
|
||||||
gba->cpu->halted = 1;
|
gba->cpu->halted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +514,7 @@ void GBAStop(struct GBA* gba) {
|
||||||
callbacks->sleep(callbacks->context);
|
callbacks->sleep(callbacks->context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gba->cpu->nextEvent = gba->cpu->cycles;
|
gba->cpu->cycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBADebug(struct GBA* gba, uint16_t flags) {
|
void GBADebug(struct GBA* gba, uint16_t flags) {
|
||||||
|
|
|
@ -1613,7 +1613,7 @@ int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait) {
|
||||||
memory->lastPrefetchedPc = cpu->gprs[ARM_PC] + WORD_SIZE_THUMB * (loads + previousLoads - 1);
|
memory->lastPrefetchedPc = cpu->gprs[ARM_PC] + WORD_SIZE_THUMB * (loads + previousLoads - 1);
|
||||||
|
|
||||||
// The next |loads|S waitstates disappear entirely, so long as they're all in a row
|
// The next |loads|S waitstates disappear entirely, so long as they're all in a row
|
||||||
cpu->cycles -= (s - 1) * loads;
|
cpu->cycles += (s - 1) * loads;
|
||||||
return wait;
|
return wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,9 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
|
||||||
}
|
}
|
||||||
STORE_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
|
STORE_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
|
||||||
STORE_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
|
STORE_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
|
||||||
STORE_32(gba->cpu->cycles, 0, &state->cpu.cycles);
|
|
||||||
|
int32_t cycles = gba->cpu->nextEvent - gba->cpu->cycles;
|
||||||
|
STORE_32(cycles, 0, &state->cpu.cycles);
|
||||||
STORE_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
STORE_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
||||||
for (i = 0; i < 6; ++i) {
|
for (i = 0; i < 6; ++i) {
|
||||||
int j;
|
int j;
|
||||||
|
@ -136,8 +138,12 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
||||||
}
|
}
|
||||||
LOAD_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
|
LOAD_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
|
||||||
LOAD_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
|
LOAD_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
|
||||||
LOAD_32(gba->cpu->cycles, 0, &state->cpu.cycles);
|
|
||||||
|
int32_t cycles;
|
||||||
|
LOAD_32(cycles, 0, &state->cpu.cycles);
|
||||||
LOAD_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
LOAD_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
||||||
|
gba->cpu->cycles = gba->cpu->nextEvent - cycles;
|
||||||
|
|
||||||
for (i = 0; i < 6; ++i) {
|
for (i = 0; i < 6; ++i) {
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 7; ++j) {
|
for (j = 0; j < 7; ++j) {
|
||||||
|
|
|
@ -123,7 +123,8 @@ static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebug
|
||||||
UNUSED(info);
|
UNUSED(info);
|
||||||
struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
|
struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
|
||||||
struct LR35902Core* cpu = debugger->cpu;
|
struct LR35902Core* cpu = debugger->cpu;
|
||||||
cpu->nextEvent = cpu->cycles;
|
cpu->nextEvent -= cpu->cycles;
|
||||||
|
cpu->cycles = 0;
|
||||||
|
|
||||||
if (debugger->d.p->entered) {
|
if (debugger->d.p->entered) {
|
||||||
debugger->d.p->entered(debugger->d.p, reason, info);
|
debugger->d.p->entered(debugger->d.p, reason, info);
|
||||||
|
|
|
@ -102,7 +102,7 @@ static void _LR35902InstructionIRQ(struct LR35902Core* cpu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _LR35902Step(struct LR35902Core* cpu) {
|
static void _LR35902Step(struct LR35902Core* cpu) {
|
||||||
++cpu->cycles;
|
--cpu->cycles;
|
||||||
enum LR35902ExecutionState state = cpu->executionState;
|
enum LR35902ExecutionState state = cpu->executionState;
|
||||||
cpu->executionState = LR35902_CORE_IDLE_0;
|
cpu->executionState = LR35902_CORE_IDLE_0;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
@ -137,44 +137,44 @@ static void _LR35902Step(struct LR35902Core* cpu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LR35902Tick(struct LR35902Core* cpu) {
|
void LR35902Tick(struct LR35902Core* cpu) {
|
||||||
while (cpu->cycles >= cpu->nextEvent) {
|
while (cpu->cycles <= 0) {
|
||||||
cpu->irqh.processEvents(cpu);
|
cpu->irqh.processEvents(cpu);
|
||||||
}
|
}
|
||||||
_LR35902Step(cpu);
|
_LR35902Step(cpu);
|
||||||
if (cpu->cycles + 2 >= cpu->nextEvent) {
|
if (cpu->cycles <= 2) {
|
||||||
int32_t diff = cpu->nextEvent - cpu->cycles;
|
int32_t diff = cpu->cycles;
|
||||||
cpu->cycles = cpu->nextEvent;
|
cpu->cycles = 0;
|
||||||
cpu->executionState += diff;
|
cpu->executionState += diff;
|
||||||
cpu->irqh.processEvents(cpu);
|
cpu->irqh.processEvents(cpu);
|
||||||
cpu->cycles += LR35902_CORE_EXECUTE - cpu->executionState;
|
cpu->cycles -= LR35902_CORE_EXECUTE - cpu->executionState;
|
||||||
} else {
|
} else {
|
||||||
cpu->cycles += 2;
|
cpu->cycles -= 2;
|
||||||
}
|
}
|
||||||
cpu->executionState = LR35902_CORE_FETCH;
|
cpu->executionState = LR35902_CORE_FETCH;
|
||||||
cpu->instruction(cpu);
|
cpu->instruction(cpu);
|
||||||
++cpu->cycles;
|
--cpu->cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LR35902Run(struct LR35902Core* cpu) {
|
void LR35902Run(struct LR35902Core* cpu) {
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while (running || cpu->executionState != LR35902_CORE_FETCH) {
|
while (running || cpu->executionState != LR35902_CORE_FETCH) {
|
||||||
if (cpu->cycles >= cpu->nextEvent) {
|
if (cpu->cycles <= 0) {
|
||||||
cpu->irqh.processEvents(cpu);
|
cpu->irqh.processEvents(cpu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_LR35902Step(cpu);
|
_LR35902Step(cpu);
|
||||||
if (cpu->cycles + 2 >= cpu->nextEvent) {
|
if (cpu->cycles <= 2) {
|
||||||
int32_t diff = cpu->nextEvent - cpu->cycles;
|
int32_t diff = cpu->cycles;
|
||||||
cpu->cycles = cpu->nextEvent;
|
cpu->cycles = 0;
|
||||||
cpu->executionState += diff;
|
cpu->executionState += diff;
|
||||||
cpu->irqh.processEvents(cpu);
|
cpu->irqh.processEvents(cpu);
|
||||||
cpu->cycles += LR35902_CORE_EXECUTE - cpu->executionState;
|
cpu->cycles -= LR35902_CORE_EXECUTE - cpu->executionState;
|
||||||
running = false;
|
running = false;
|
||||||
} else {
|
} else {
|
||||||
cpu->cycles += 2;
|
cpu->cycles -= 2;
|
||||||
}
|
}
|
||||||
cpu->executionState = LR35902_CORE_FETCH;
|
cpu->executionState = LR35902_CORE_FETCH;
|
||||||
cpu->instruction(cpu);
|
cpu->instruction(cpu);
|
||||||
++cpu->cycles;
|
--cpu->cycles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue