Compare commits

...

2 Commits

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass, field
from typing import ClassVar, Callable
from ctypes import c_uint32, c_int32, c_uint8
from ctypes import c_uint32, c_int32
import struct
from optable import OPCODES, OpcodeDescription, OpL, OpA, OpF, OpD
from enum import IntFlag, auto
@ -21,11 +21,20 @@ class VMCC(IntFlag):
NEGATIVE = 1 << 1
ZERO = 1 << 0
class Breakpoint(Exception):
address: int
@dataclass
class VM:
instr_callbacks: ClassVar[dict[OpcodeDescription, Callable]]
mem: bytearray
cc: VMCC
pc: c_uint32
registers: list[c_int32]
breakpoints: set[int]
_vm_flags: VMFlags
def __init__(self, mem):
def __init__(self, mem: bytearray):
self.mem: bytearray = mem
self.cc: VMCC = VMCC(0)
self.pc: c_uint32 = c_uint32(0)
@ -114,11 +123,10 @@ class VM:
"""
Continue from current breakpoint
"""
while ((self.pc.value < len(self.mem) // 4)
and not self.pc.value in self.breakpoints):
while self.pc.value < len(self.mem):
if self.pc.value in self.breakpoints:
raise Breakpoint(self.pc.value)
self.step()
print("breakpoint")
input()
def run(self) -> None:
"""
@ -132,7 +140,7 @@ class VM:
return OPCODES[opcode]
def _parse_arguments(self, opdesc: OpcodeDescription) -> tuple[int, ...]:
addr = self.pc.value
addr = self.pc.value * 4
main_part = struct.unpack(">BBBb", self.mem[addr:addr+4])
if not OpF.UNEXPANDED in opdesc.flags or OpF.QUICK in opdesc.flags:
@ -241,7 +249,7 @@ class VM:
def _branch_callback(self, cond: int, disp: int) -> None:
c = Condition(cond)
vm_c = Condition(self.cc.value)
vm_c = Condition(self.cc)
if (c.v & vm_c.v) & (c.n & vm_c.n) & (c.z & vm_c.z) == c.i:
self._vm_flags |= VMFlags.AFTER_BRANCH
self.pc = c_uint32(self.pc.value + disp)