diff --git a/src/mudlib/embedded_if_session.py b/src/mudlib/embedded_if_session.py index 490fcd7..139c947 100644 --- a/src/mudlib/embedded_if_session.py +++ b/src/mudlib/embedded_if_session.py @@ -165,7 +165,8 @@ class EmbeddedIFSession: except Exception as e: tb = traceback.format_exc() logger.error(f"Interpreter crashed:\n{tb}") - self._error = f"interpreter error: {e}" + msg = str(e) or type(e).__name__ + self._error = f"interpreter error: {msg}" finally: self._done = True self._keyboard._waiting.set() diff --git a/src/mudlib/zmachine/zcpu.py b/src/mudlib/zmachine/zcpu.py index 0053577..4778bb4 100644 --- a/src/mudlib/zmachine/zcpu.py +++ b/src/mudlib/zmachine/zcpu.py @@ -226,17 +226,27 @@ class ZCpu: return table def step_fast(self): - """Execute a single instruction without tracing. + """Execute a single instruction with lightweight tracing. Returns True if execution should continue. """ + current_pc = self._opdecoder.program_counter (opcode_class, opcode_number, operands) = self._opdecoder.get_next_instruction() entry = self._dispatch[opcode_class][opcode_number] if entry is None: - raise ZCpuIllegalInstruction + self._trace.append(f" {current_pc:06x} ILLEGAL") + self._dump_trace() + raise ZCpuIllegalInstruction( + f"illegal opcode class={opcode_class} num={opcode_number}" + f" at PC={current_pc:#x}" + ) implemented, func = entry if not implemented: return False + self._trace.append( + f" {current_pc:06x} {func.__name__}" + f"({', '.join(str(x) for x in operands)})" + ) try: func(self, *operands) except (ZCpuQuit, ZCpuRestart):