Pre-consume store byte in op_aread and op_read_char before blocking reads
Without this, MUD-level saves during read_line/read_char capture PC pointing at the store byte, which gets misinterpreted as an opcode on restore.
This commit is contained in:
parent
ad47ee05bd
commit
1b3a3646d6
2 changed files with 14 additions and 5 deletions
|
|
@ -52,8 +52,8 @@ class EmbeddedIFSession:
|
||||||
branch data (V3) or store byte (V5+). Process them so execution
|
branch data (V3) or store byte (V5+). Process them so execution
|
||||||
resumes at the next instruction.
|
resumes at the next instruction.
|
||||||
- MUD-level _do_save during sread/aread: PC points past the read
|
- MUD-level _do_save during sread/aread: PC points past the read
|
||||||
instruction. No post-processing needed (phantom output suppressed
|
instruction (store byte pre-consumed in op_aread/op_read_char).
|
||||||
in start()).
|
No post-processing needed (phantom output suppressed in start()).
|
||||||
"""
|
"""
|
||||||
if not self.save_path.exists():
|
if not self.save_path.exists():
|
||||||
return False
|
return False
|
||||||
|
|
|
||||||
|
|
@ -808,7 +808,13 @@ class ZCpu:
|
||||||
text_buffer_addr = args[0]
|
text_buffer_addr = args[0]
|
||||||
parse_buffer_addr = args[1] if len(args) > 1 else 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 = self._ui.keyboard_input.read_line()
|
||||||
text = text.lower().strip("\n\r")
|
text = text.lower().strip("\n\r")
|
||||||
|
|
||||||
|
|
@ -840,7 +846,7 @@ class ZCpu:
|
||||||
offset = pos + word_len
|
offset = pos + word_len
|
||||||
|
|
||||||
# Store terminating character (13 = newline)
|
# Store terminating character (13 = newline)
|
||||||
self._write_result(13)
|
self._write_result(13, store_addr=store_addr)
|
||||||
|
|
||||||
def op_print_char(self, char):
|
def op_print_char(self, char):
|
||||||
"""Output the given ZSCII character."""
|
"""Output the given ZSCII character."""
|
||||||
|
|
@ -968,8 +974,11 @@ class ZCpu:
|
||||||
if time != 0 or input_routine != 0:
|
if time != 0 or input_routine != 0:
|
||||||
raise ZCpuNotImplemented
|
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()
|
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):
|
def op_scan_table(self, x, table, length, *args):
|
||||||
"""Search a table for a value, branch if found, store address (V4+).
|
"""Search a table for a value, branch if found, store address (V4+).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue