diff --git a/src/dp32proto/dpdebugger.py b/src/dp32proto/dpdebugger.py index 4167cb2..13c224d 100644 --- a/src/dp32proto/dpdebugger.py +++ b/src/dp32proto/dpdebugger.py @@ -71,6 +71,8 @@ class Debugger: "c": self._continue, "breakpoint": self._breakpoint, "b": self._breakpoint, + "clearbreakpoints": self._breakpointsclear, + "cbp": self._breakpointsclear, "print": self._print, "p": self._print, "run": self._run, @@ -119,9 +121,7 @@ class Debugger: addr = -1 # находим за линейное время. Плохая практика, но так как # сходные коды вряд ли будут длиннее 1000 строк - приемлемо - print(self._dbg_dict) for addr, desc in self._dbg_dict["instructions"].items(): - print("_______________", desc, "__________") desc = cast(DbgInstrDesc, desc) if not desc["srcline"] == desired_addr: continue @@ -131,6 +131,11 @@ class Debugger: return f"Couldn't place breakpoint on src line {desired_addr}" + def _breakpointsclear(self, args: list[str]): + self._breakpoints.clear() + self._vm.breakpoints.clear() + return "Cleared all breakpoints" + def _print(self, args: list[str]) -> str: to_print = args[0] if to_print == "pc": @@ -178,6 +183,7 @@ class Debugger: return ("You passed wrong offset parameter. It should be either " "name of some label or explicit decimal or hexdecimal " "number, in the second case it should start with 0x") + offset = self._vm._to_raw_bytes_offset(offset) try: sym = self.UNPACK_SYMBOL_TABLE[size_arg] @@ -187,7 +193,7 @@ class Debugger: "options as size: b/B - byte, h/H - 2 bytes, " "w/W - 4 bytes. Big - unsigned, small - signed") contents = struct.unpack( - sym*amount, + ">"+sym*amount, self._vm.mem[offset:offset+size*amount] ) return f"{mem_location}:" + " ".join(map(str, contents)) diff --git a/src/dp32proto/vm.py b/src/dp32proto/vm.py index ae23a32..c74a232 100644 --- a/src/dp32proto/vm.py +++ b/src/dp32proto/vm.py @@ -262,6 +262,25 @@ class VM: cond, disp ) + @staticmethod + def _perform_ariphmetic_operation( + lhs: int, + rhs: int, + op: Callable[[int, int], int] + ) -> tuple[int, VMCC]: + cc = VMCC(0) + result = op(lhs, rhs) + if result < 0: + cc |= VMCC.NEGATIVE + elif result == 0: + cc |= VMCC.ZERO + # самая дорогая проверка на переполнение) + try: + struct.pack('i', result) + except struct.error: + cc |= VMCC.OVERFLOW + return result, cc + def _math_callback_gen( self, operation: Callable[[int, int], int] @@ -274,10 +293,16 @@ class VM: def callback(self, r3: int, r1: int, r2: int): lhs = self.registers[r1].value rhs = self.registers[r2].value - self.registers[r3] = c_int32(operation(lhs, rhs)) + result, cc = self._perform_ariphmetic_operation( + lhs, + rhs, + operation) + self.registers[r3] = c_int32(result) + self.cc = cc return callback + def _math_quick_callback_gen( self, operation: Callable[[int, int], int] @@ -293,24 +318,21 @@ class VM: def callback(self, r3: int, r1: int, i8: int) -> None: self.cc = VMCC(0) lhs = self.registers[r1].value - result = operation(lhs, i8) - if result < 0: - self.cc |= VMCC.NEGATIVE - elif result == 0: - self.cc |= VMCC.ZERO - # самая дорогая проверка на переполнение) - try: - struct.pack('i', result) - except struct.error: - self.cc |= VMCC.OVERFLOW + result, flags = self._perform_ariphmetic_operation( + lhs, + i8, + operation) self.registers[r3] = c_int32(result) + self.cc = flags return callback def _load_callback(self, r3: int, r1: int, disp: int) -> None: addr = self._to_raw_bytes_offset(self.registers[r1].value + disp) + raw_bytes = self.mem[addr:addr+WORD_SIZE] self.registers[r3] = c_int32( struct.unpack( - ">i", self.mem[addr:addr+WORD_SIZE])[0] + ">i", raw_bytes + )[0] ) def _store_callback(self, r3: int, r1: int, disp: int) -> None: