Compare commits
2 Commits
320f876f97
...
f1e083d7bb
| Author | SHA1 | Date | |
|---|---|---|---|
| f1e083d7bb | |||
| fe5d51258b |
24
src/vm.py
24
src/vm.py
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import ClassVar, Callable
|
from typing import ClassVar, Callable
|
||||||
from ctypes import c_uint32, c_int32, c_uint8
|
from ctypes import c_uint32, c_int32
|
||||||
import struct
|
import struct
|
||||||
from optable import OPCODES, OpcodeDescription, OpL, OpA, OpF, OpD
|
from optable import OPCODES, OpcodeDescription, OpL, OpA, OpF, OpD
|
||||||
from enum import IntFlag, auto
|
from enum import IntFlag, auto
|
||||||
@ -21,11 +21,20 @@ class VMCC(IntFlag):
|
|||||||
NEGATIVE = 1 << 1
|
NEGATIVE = 1 << 1
|
||||||
ZERO = 1 << 0
|
ZERO = 1 << 0
|
||||||
|
|
||||||
|
class Breakpoint(Exception):
|
||||||
|
address: int
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class VM:
|
class VM:
|
||||||
instr_callbacks: ClassVar[dict[OpcodeDescription, Callable]]
|
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.mem: bytearray = mem
|
||||||
self.cc: VMCC = VMCC(0)
|
self.cc: VMCC = VMCC(0)
|
||||||
self.pc: c_uint32 = c_uint32(0)
|
self.pc: c_uint32 = c_uint32(0)
|
||||||
@ -114,11 +123,10 @@ class VM:
|
|||||||
"""
|
"""
|
||||||
Continue from current breakpoint
|
Continue from current breakpoint
|
||||||
"""
|
"""
|
||||||
while ((self.pc.value < len(self.mem) // 4)
|
while self.pc.value < len(self.mem):
|
||||||
and not self.pc.value in self.breakpoints):
|
if self.pc.value in self.breakpoints:
|
||||||
|
raise Breakpoint(self.pc.value)
|
||||||
self.step()
|
self.step()
|
||||||
print("breakpoint")
|
|
||||||
input()
|
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -132,7 +140,7 @@ class VM:
|
|||||||
return OPCODES[opcode]
|
return OPCODES[opcode]
|
||||||
|
|
||||||
def _parse_arguments(self, opdesc: OpcodeDescription) -> tuple[int, ...]:
|
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])
|
main_part = struct.unpack(">BBBb", self.mem[addr:addr+4])
|
||||||
|
|
||||||
if not OpF.UNEXPANDED in opdesc.flags or OpF.QUICK in opdesc.flags:
|
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:
|
def _branch_callback(self, cond: int, disp: int) -> None:
|
||||||
c = Condition(cond)
|
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:
|
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._vm_flags |= VMFlags.AFTER_BRANCH
|
||||||
self.pc = c_uint32(self.pc.value + disp)
|
self.pc = c_uint32(self.pc.value + disp)
|
||||||
|
|||||||
Reference in New Issue
Block a user