mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +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 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 {
|
||||
|
||||
struct ProcessorBase {
|
||||
enum State: int {
|
||||
Reset = -1,
|
||||
};
|
||||
|
||||
HalfCycles time_remaining;
|
||||
int state = State::Reset;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user