From 6f6e466c08c961286b4c69205a19bbd728363f53 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 16 May 2022 11:59:03 -0400 Subject: [PATCH] Make a first sketch of the coroutine-esque structure I'm going to experiment with here. --- .../Implementation/68000Mk2Implementation.hpp | 51 +++++++++++++++++++ .../Implementation/68000Mk2Storage.hpp | 5 ++ 2 files changed, 56 insertions(+) diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index 88e6ce03c..cf1ad3c47 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -12,6 +12,57 @@ namespace CPU { namespace MC68000Mk2 { +template +void Processor::run_for(HalfCycles duration) { + // Accumulate the newly paid-in cycles. If this instance remains in deficit, exit. + time_remaining += duration; + if(time_remaining <= HalfCycles(0)) return; + + // Check whether all remaining time has been expended; if so then exit, having set this line up as + // the next resumption point. +#define ConsiderExit() if(time_remaining <= HalfCycles(0)) { state = __LINE__; return; } [[fallthrough]]; case __LINE__: + + // Subtracts `n` half-cycles from `time_remaining`; if permit_overrun is false, also ConsiderExit() +#define Spend(n) cycles_owed -= HalfCycles(n); if constexpr (!permit_overrun) ConsiderExit() + + // Performs ConsiderExit() only if permit_overrun is true +#define CheckOverrun() if constexpr (permit_overrun) ConsiderExit() + + // + // So structure is, in general: + // + // case Action: + // do_something(); + // Spend(20); + // do_something_else(); + // Spend(10); + // do_a_third_thing(); + // Spend(30); + // CheckOverrun(); + // + // state = next_action; + // break; + // + // Additional notes: + // + // Action and all equivalents should be negative values, since the + // switch-for-computed-goto-for-a-coroutine structure uses __LINE__ for + // its invented entry- and exit-points, meaning that negative numbers are + // the easiest group that is safely definitely never going to collide. + + // Otherwise continue for all time, until back in debt. + // Formatting is slightly obtuse here to make this look more like a coroutine. + while(true) { switch(state) { + + + }} + +#undef CheckOverrun +#undef Spend +#undef ConsiderExit + +} + } } diff --git a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp index be8d58c0b..80522171a 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp @@ -13,7 +13,12 @@ namespace CPU { namespace MC68000Mk2 { struct ProcessorBase { + enum State: int { + Reset = -1, + }; + HalfCycles time_remaining; + int state = State::Reset; }; }