diff --git a/sim.c b/sim.c index 9a5084f..3b12f31 100644 --- a/sim.c +++ b/sim.c @@ -71,6 +71,14 @@ static inline void oper_move_relative_or_explode(Gbuffer gbuf, Mbuffer mbuf, gbuf[y * width + x] = '.'; } +static inline Usz UCLAMP(Usz val, Usz min, Usz max) { + if (val < min) + return min; + if (val > max) + return max; + return val; +} + #define ORCA_EXPAND_SOLO_OPER_CHARS(_oper_char, _oper_name) \ Orca_oper_char_##_oper_name = _oper_char, #define ORCA_EXPAND_DUAL_OPER_CHARS(_upper_oper_char, _lower_oper_char, \ @@ -211,7 +219,8 @@ static inline void oper_move_relative_or_explode(Gbuffer gbuf, Mbuffer mbuf, _('H', 'h', halt) \ _('I', 'i', increment) \ _('J', 'j', jump) \ - _('M', 'm', modulo) + _('M', 'm', modulo) \ + _('O', 'o', offset) ORCA_DECLARE_OPERATORS(ORCA_SOLO_OPERATORS, ORCA_DUAL_OPERATORS) @@ -314,6 +323,26 @@ BEGIN_DUAL_PHASE_1(modulo) POKE(1, 0, glyphs_mod(PEEK(0, 1), PEEK(0, 2))); END_PHASE +BEGIN_DUAL_PHASE_0(offset) + REALIZE_DUAL; + Isz read_y = (Isz)UCLAMP(INDEX(PEEK(0, -1)), 0, 16); + Isz read_x = (Isz)UCLAMP(INDEX(PEEK(0, -2)), 1, 16); + BEGIN_DUAL_PORTS + I_PORT(0, -1, LOCKING | HASTE); + I_PORT(0, -2, LOCKING | HASTE); + I_PORT(read_y, read_x, LOCKING); + O_PORT(0, 1, LOCKING); + END_PORTS + // wrong + STOP_IF_DUAL_INACTIVE; + BEGIN_HASTE + POKE(0, 1, PEEK(read_y, read_x)); + STUN(0, 1); + END_HASTE +END_PHASE +BEGIN_DUAL_PHASE_1(offset) +END_PHASE + //////// Run simulation #define SIM_EXPAND_SOLO_PHASE_0(_oper_char, _oper_name) \