mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Make a first sketch of the coroutine-esque structure I'm going to experiment with here.
This commit is contained in:
parent
b0518040b5
commit
6f6e466c08
@ -12,6 +12,57 @@
|
|||||||
namespace CPU {
|
namespace CPU {
|
||||||
namespace MC68000Mk2 {
|
namespace MC68000Mk2 {
|
||||||
|
|
||||||
|
template <class BusHandler, bool dtack_is_implicit, bool permit_overrun, bool signal_will_perform>
|
||||||
|
void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perform>::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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,12 @@ namespace CPU {
|
|||||||
namespace MC68000Mk2 {
|
namespace MC68000Mk2 {
|
||||||
|
|
||||||
struct ProcessorBase {
|
struct ProcessorBase {
|
||||||
|
enum State: int {
|
||||||
|
Reset = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
HalfCycles time_remaining;
|
||||||
|
int state = State::Reset;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user