From 6d29ec00fb045b39e3564c4bfa9191182dea4aa4 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 10 Feb 2026 16:59:29 -0500 Subject: [PATCH] Implement stub opcodes for game compatibility set_colour, piracy, erase_line, get_cursor, not_v5, print_table --- src/mudlib/zmachine/zcpu.py | 43 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/mudlib/zmachine/zcpu.py b/src/mudlib/zmachine/zcpu.py index 5c59c1a..0053577 100644 --- a/src/mudlib/zmachine/zcpu.py +++ b/src/mudlib/zmachine/zcpu.py @@ -463,8 +463,8 @@ class ZCpu: self._call(routine_addr, [arg1], False) def op_set_colour(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + """Set foreground and background colors (no-op for text MUD).""" + pass def op_throw(self, *args): """TODO: Write docstring here.""" @@ -716,8 +716,8 @@ class ZCpu: self._branch(expected_checksum == actual_checksum) def op_piracy(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + """Anti-piracy check. Always branches true (all interpreters pass this).""" + self._branch(True) ## VAR opcodes (opcodes 224-255) @@ -913,16 +913,17 @@ class ZCpu: self._ui.screen.erase_window(window_number) def op_erase_line(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + """Erase current line on screen (no-op for text MUD).""" + pass def op_set_cursor(self, x, y): """Set the cursor position within the active window.""" self._ui.screen.set_cursor_position(x, y) - def op_get_cursor(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + def op_get_cursor(self, table_addr): + """Get cursor position into table. For MUD, always write row=1, col=1.""" + self._memory.write_word(table_addr, 1) # row + self._memory.write_word(table_addr + 2, 1) # col def op_set_text_style(self, text_style): """Set the text style.""" @@ -1004,9 +1005,10 @@ class ZCpu: self._write_result(0) self._branch(False) - def op_not_v5(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + def op_not_v5(self, value): + """Bitwise NOT (VAR form). Same as op_not.""" + result = ~value & 0xFFFF + self._write_result(result) def op_call_vn(self, routine_addr, *args): """Call routine with up to 3 arguments and discard the result.""" @@ -1055,7 +1057,12 @@ class ZCpu: offset = pos + word_len def op_encode_text(self, *args): - """TODO: Write docstring here.""" + """Encode ZSCII text to Z-encoded string (V5+). + + This opcode converts ZSCII text into Z-machine's packed text format + (3 characters per 2 bytes). Complex operation, rarely used. + Not implemented - will raise ZCpuNotImplemented if any game calls it. + """ raise ZCpuNotImplemented def op_copy_table(self, first, second, size): @@ -1080,9 +1087,13 @@ class ZCpu: for i in range(count - 1, -1, -1): self._memory[second + i] = self._memory[first + i] - def op_print_table(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + def op_print_table(self, zscii_text, width, height=1, skip=0): + """Formatted table printing (no-op for text MUD). + + Spec: print width chars per line for height lines from zscii_text. + Skip bytes between rows. For now, no-op to avoid crashes. + """ + pass def op_check_arg_count(self, arg_number): """Branch if the Nth argument was passed to the current routine."""