Add step() method to ZCpu for async MUD integration

Extracts the run loop body into step() which executes one instruction
and returns True/False for continue/halt. run() now delegates to step().
This commit is contained in:
Jared Miller 2026-02-09 20:59:03 -05:00
parent fb8cbf7219
commit d218929f02
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -168,31 +168,34 @@ class ZCpu:
log(f"Jump to offset {branch_offset:+d}")
self._opdecoder.program_counter += branch_offset - 2
def step(self):
"""Execute a single instruction. Returns True if execution should continue."""
current_pc = self._opdecoder.program_counter
log(f"Reading next opcode at address {current_pc:x}")
(opcode_class, opcode_number, operands) = self._opdecoder.get_next_instruction()
implemented, func = self._get_handler(opcode_class, opcode_number)
log_disasm(
current_pc,
zopdecoder.OPCODE_STRINGS[opcode_class],
opcode_number,
func.__name__,
", ".join([str(x) for x in operands]),
)
if not implemented:
log(f"Unimplemented opcode {func.__name__}, halting execution")
return False
# The returned function is unbound, so we must pass
# self to it ourselves.
func(self, *operands)
return True
def run(self):
"""The Magic Function that takes little bits and bytes, twirls
them around, and brings the magic to your screen!"""
log("Execution started")
while True:
current_pc = self._opdecoder.program_counter
log(f"Reading next opcode at address {current_pc:x}")
(opcode_class, opcode_number, operands) = (
self._opdecoder.get_next_instruction()
)
implemented, func = self._get_handler(opcode_class, opcode_number)
log_disasm(
current_pc,
zopdecoder.OPCODE_STRINGS[opcode_class],
opcode_number,
func.__name__,
", ".join([str(x) for x in operands]),
)
if not implemented:
log(f"Unimplemented opcode {func.__name__}, halting execution")
break
# The returned function is unbound, so we must pass
# self to it ourselves.
func(self, *operands)
while self.step():
pass
##
## Opcode implementation functions start here.