mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-03 20:37:18 +12:00
First stuff running with scheduler
This commit is contained in:
parent
97f97dc6e2
commit
fa82dad38d
5 changed files with 86 additions and 36 deletions
|
@ -94,7 +94,7 @@ class MyEnvironment final : public Dynarmic::A32::UserCallbacks {
|
|||
}
|
||||
|
||||
void AddTicks(u64 ticks) override {
|
||||
totalTicks += ticks;
|
||||
scheduler.currentTimestamp += ticks;
|
||||
|
||||
if (ticks > ticksLeft) {
|
||||
ticksLeft = 0;
|
||||
|
@ -111,7 +111,7 @@ class MyEnvironment final : public Dynarmic::A32::UserCallbacks {
|
|||
return getCyclesForInstruction(isThumb, instruction);
|
||||
}
|
||||
|
||||
MyEnvironment(Memory& mem, Kernel& kernel, Scheduler& scheduler) : mem(mem), kernel(kernel), scheduler(scheduler) {}
|
||||
MyEnvironment(Memory& mem, Kernel& kernel, Scheduler& scheduler) : mem(mem), kernel(kernel), scheduler(scheduler) {}
|
||||
};
|
||||
|
||||
class CPU {
|
||||
|
@ -122,12 +122,13 @@ class CPU {
|
|||
Dynarmic::ExclusiveMonitor exclusiveMonitor{1};
|
||||
MyEnvironment env;
|
||||
Memory& mem;
|
||||
Scheduler scheduler;
|
||||
Scheduler& scheduler;
|
||||
Emulator& emu;
|
||||
|
||||
public:
|
||||
static constexpr u64 ticksPerSec = 268111856;
|
||||
|
||||
CPU(Memory& mem, Kernel& kernel);
|
||||
CPU(Memory& mem, Kernel& kernel, Emulator& emu);
|
||||
void reset();
|
||||
|
||||
void setReg(int index, u32 value) {
|
||||
|
@ -166,29 +167,14 @@ class CPU {
|
|||
}
|
||||
|
||||
u64 getTicks() {
|
||||
return env.totalTicks;
|
||||
return scheduler.currentTimestamp;
|
||||
}
|
||||
|
||||
// Get reference to tick count. Memory needs access to this
|
||||
u64& getTicksRef() {
|
||||
return env.totalTicks;
|
||||
return scheduler.currentTimestamp;
|
||||
}
|
||||
|
||||
void clearCache() { jit->ClearCache(); }
|
||||
|
||||
void runFrame() {
|
||||
env.ticksLeft = ticksPerSec / 60;
|
||||
execute:
|
||||
const auto exitReason = jit->Run();
|
||||
|
||||
if (static_cast<u32>(exitReason) != 0) [[unlikely]] {
|
||||
// Cache invalidation needs to exit the JIT so it returns a CacheInvalidation HaltReason. In our case, we just go back to executing
|
||||
// The goto might be terrible but it does guarantee that this does not recursively call run and crash, instead getting optimized to a jump
|
||||
if (Dynarmic::Has(exitReason, Dynarmic::HaltReason::CacheInvalidation)) {
|
||||
goto execute;
|
||||
} else {
|
||||
Helpers::panic("Exit reason: %d\nPC: %08X", static_cast<u32>(exitReason), getReg(15));
|
||||
}
|
||||
}
|
||||
}
|
||||
void runFrame();
|
||||
};
|
|
@ -15,6 +15,7 @@
|
|||
#include "io_file.hpp"
|
||||
#include "lua_manager.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#ifdef PANDA3DS_ENABLE_HTTP_SERVER
|
||||
#include "http_server.hpp"
|
||||
|
@ -42,6 +43,7 @@ class Emulator {
|
|||
Kernel kernel;
|
||||
Crypto::AESEngine aesEngine;
|
||||
Cheats cheats;
|
||||
Scheduler scheduler;
|
||||
|
||||
// Variables to keep track of whether the user is controlling the 3DS analog stick with their keyboard
|
||||
// This is done so when a gamepad is connected, we won't automatically override the 3DS analog stick settings with the gamepad's state
|
||||
|
@ -85,6 +87,8 @@ class Emulator {
|
|||
// change ROMs. If Reload is selected, the emulator will reload its selected ROM. This is useful for eg a "reset" button that keeps the current
|
||||
// ROM and just resets the emu
|
||||
enum class ReloadOption { NoReload, Reload };
|
||||
// Used in CPU::runFrame
|
||||
bool frameDone = false;
|
||||
|
||||
Emulator();
|
||||
~Emulator();
|
||||
|
@ -94,6 +98,8 @@ class Emulator {
|
|||
void reset(ReloadOption reload);
|
||||
void run(void* frontend = nullptr);
|
||||
void runFrame();
|
||||
// Poll the scheduler for events
|
||||
void pollScheduler();
|
||||
|
||||
void resume(); // Resume the emulator
|
||||
void pause(); // Pause the emulator
|
||||
|
@ -121,6 +127,7 @@ class Emulator {
|
|||
Cheats& getCheats() { return cheats; }
|
||||
ServiceManager& getServiceManager() { return kernel.getServiceManager(); }
|
||||
LuaManager& getLua() { return lua; }
|
||||
Scheduler& getScheduler() { return scheduler; }
|
||||
|
||||
RendererType getRendererType() const { return config.rendererType; }
|
||||
Renderer* getRenderer() { return gpu.getRenderer(); }
|
||||
|
|
|
@ -18,6 +18,7 @@ struct Scheduler {
|
|||
using EventMap = boost::container::flat_multimap<Key, Val, std::less<Key>, boost::container::static_vector<std::pair<Key, Val>, size>>;
|
||||
|
||||
EventMap<u64, EventType, totalNumberOfEvents> events;
|
||||
u64 currentTimestamp = 0;
|
||||
u64 nextTimestamp = 0;
|
||||
|
||||
// Set nextTimestamp to the timestamp of the next event
|
||||
|
@ -38,6 +39,8 @@ struct Scheduler {
|
|||
};
|
||||
|
||||
void reset() {
|
||||
currentTimestamp = 0;
|
||||
|
||||
// Clear any pending events
|
||||
events.clear();
|
||||
// Add a dummy event to always keep the scheduler non-empty
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue