diff --git a/src/mudlib/embedded_if_session.py b/src/mudlib/embedded_if_session.py index 130c462..c5404d3 100644 --- a/src/mudlib/embedded_if_session.py +++ b/src/mudlib/embedded_if_session.py @@ -52,8 +52,8 @@ class EmbeddedIFSession: branch data (V3) or store byte (V5+). Process them so execution resumes at the next instruction. - MUD-level _do_save during sread/aread: PC points past the read - instruction. No post-processing needed (phantom output suppressed - in start()). + instruction (store byte pre-consumed in op_aread/op_read_char). + No post-processing needed (phantom output suppressed in start()). """ if not self.save_path.exists(): return False diff --git a/src/mudlib/zmachine/zcpu.py b/src/mudlib/zmachine/zcpu.py index b83ed53..0f76d69 100644 --- a/src/mudlib/zmachine/zcpu.py +++ b/src/mudlib/zmachine/zcpu.py @@ -808,7 +808,13 @@ class ZCpu: text_buffer_addr = args[0] parse_buffer_addr = args[1] if len(args) > 1 else 0 - # Read input from keyboard + # Consume store byte BEFORE blocking in read_line(). This ensures + # the PC is past the entire instruction when MUD-level saves capture + # state during read_line(). Without this, saves point PC at the store + # byte, which gets misinterpreted as an opcode on restore. + store_addr = self._opdecoder.get_store_address() + + # Read input from keyboard (blocks until player types something) text = self._ui.keyboard_input.read_line() text = text.lower().strip("\n\r") @@ -840,7 +846,7 @@ class ZCpu: offset = pos + word_len # Store terminating character (13 = newline) - self._write_result(13) + self._write_result(13, store_addr=store_addr) def op_print_char(self, char): """Output the given ZSCII character.""" @@ -968,8 +974,11 @@ class ZCpu: if time != 0 or input_routine != 0: raise ZCpuNotImplemented + # Consume store byte BEFORE blocking in read_char() — same reason + # as op_aread: PC must be past the full instruction for MUD saves. + store_addr = self._opdecoder.get_store_address() char = self._ui.keyboard_input.read_char() - self._write_result(char) + self._write_result(char, store_addr=store_addr) def op_scan_table(self, x, table, length, *args): """Search a table for a value, branch if found, store address (V4+).