diff --git a/src/vm.py b/src/vm.py index d603b2d..a8d4097 100644 --- a/src/vm.py +++ b/src/vm.py @@ -96,23 +96,53 @@ class VM: """ opcode = self.mem[self.pc.value] opdesc = self._fetch_opcode_desc(opcode) + args = self._parse_arguments(opdesc) if not VMFlags.AFTER_BRANCH: self.pc = c_uint32(self.cc.value + 1) - self._vm_flags + self._vm_flags &= ~(VMFlags.AFTER_BRANCH) def continue_(self) -> None: """ Continue from current breakpoint """ - pass + while ((self.pc.value < len(self.mem) // 4) + and not self.pc.value in self.breakpoints): + self.step() + print("breakpoint") + input() def run(self) -> None: """ Run from very beginning """ + self.pc = c_uint32(0) + while (self.pc.value < len(self.mem) // 4): + self.continue_() def _fetch_opcode_desc(self, opcode: int): return OPCODES[opcode] + + def _parse_arguments(self, opdesc: OpcodeDescription) -> tuple[int, ...]: + addr = self.pc.value + main_part = struct.unpack(">BBBb", self.mem[addr:addr+4]) + + if not OpF.UNEXPANDED in opdesc.flags or OpF.QUICK in opdesc.flags: + upper_part = struct.unpack(">i", self.mem[addr+4:addr+8]) + return (*main_part, *upper_part) + return main_part + + def _run_callback( + self, + opdesc: OpcodeDescription, + args: tuple[int, ...] + ) -> None: + if opdesc.layout == OpL.MATH: + assert len(args) == 4 + _, r3, r1, r2_or_i8 = args + self.instr_callbacks[opdesc]( + r3, r1, r2_or_i8 + ) + if opdesc.layout == OpL.MEM def _math_callback_gen( self, @@ -149,12 +179,12 @@ class VM: def _load_callback(self, r3: int, r1: int, disp: int) -> None: addr = (self.registers[r1].value + disp) * 4 self.registers[r3] = c_int32( - struct.unpack("i", self.mem[addr:addr+4])[0] + struct.unpack(">i", self.mem[addr:addr+4])[0] ) def _store_callback(self, r3: int, r1: int, disp: int) -> None: addr = (self.registers[r1].value + disp) * 4 - self.mem[addr:addr+4] = struct.pack("i", self.registers[r3].value) + self.mem[addr:addr+4] = struct.pack(">i", self.registers[r3].value) def _branch_callback(self, cond: int, disp: int) -> None: c = Condition(cond)