From e61dcc3ac4074a502708b0c6b5ec9f31968c9b03 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 10 Feb 2026 13:37:27 -0500 Subject: [PATCH] Implement extended opcode decoder for V5+ The 0xBE prefix byte triggers extended opcode parsing. Reads the opcode number from the next byte, then parses operand types using the same format as VAR opcodes. Required for all V5+ games. --- src/mudlib/zmachine/zopdecoder.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mudlib/zmachine/zopdecoder.py b/src/mudlib/zmachine/zopdecoder.py index b734934..60613f9 100644 --- a/src/mudlib/zmachine/zopdecoder.py +++ b/src/mudlib/zmachine/zopdecoder.py @@ -70,7 +70,7 @@ class ZOpDecoder: log(f"Decode opcode {opcode:x}") # Determine the opcode type, and hand off further parsing. - if self._memory.version == 5 and opcode == 0xBE: + if self._memory.version >= 5 and opcode == 0xBE: # Extended opcode return self._parse_opcode_extended() @@ -134,7 +134,16 @@ class ZOpDecoder: def _parse_opcode_extended(self): """Parse an extended opcode (v5+ feature).""" - raise NotImplementedError("Extended opcodes (v5+) not yet implemented") + log("Opcode is extended") + + # Read the extended opcode number + opcode_num = self._get_pc() + log(f"Extended opcode number: {opcode_num:x}") + + # Parse the operand types byte and retrieve operands + operands = self._parse_operands_byte() + + return (OPCODE_EXT, opcode_num, operands) def _parse_operand(self, operand_type): """Read and return an operand of the given type.