fix: при выполнении арифметических операций теперь меняет флаги
This commit is contained in:
21
src/vm.py
21
src/vm.py
@ -16,13 +16,18 @@ class Condition:
|
|||||||
self.n: bool = bool(cond & (1 << 1))
|
self.n: bool = bool(cond & (1 << 1))
|
||||||
self.z: bool = bool(cond & (1 << 0))
|
self.z: bool = bool(cond & (1 << 0))
|
||||||
|
|
||||||
|
class VMCC(IntFlag):
|
||||||
|
OVERFLOW = 1 << 2
|
||||||
|
NEGATIVE = 1 << 1
|
||||||
|
ZERO = 1 << 0
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class VM:
|
class VM:
|
||||||
instr_callbacks: ClassVar[dict[OpcodeDescription, Callable]]
|
instr_callbacks: ClassVar[dict[OpcodeDescription, Callable]]
|
||||||
|
|
||||||
def __init__(self, mem):
|
def __init__(self, mem):
|
||||||
self.mem: bytearray = mem
|
self.mem: bytearray = mem
|
||||||
self.cc: c_uint8 = c_uint8(0)
|
self.cc: VMCC = VMCC(0)
|
||||||
self.pc: c_uint32 = c_uint32(0)
|
self.pc: c_uint32 = c_uint32(0)
|
||||||
self.registers: list[c_int32] = [c_int32(0) for _ in range(256)]
|
self.registers: list[c_int32] = [c_int32(0) for _ in range(256)]
|
||||||
self.breakpoints: set[int] = field(default_factory=set)
|
self.breakpoints: set[int] = field(default_factory=set)
|
||||||
@ -193,6 +198,7 @@ class VM:
|
|||||||
lhs = self.registers[r1].value
|
lhs = self.registers[r1].value
|
||||||
rhs = self.registers[r2].value
|
rhs = self.registers[r2].value
|
||||||
self.registers[r3] = c_int32(operation(lhs, rhs))
|
self.registers[r3] = c_int32(operation(lhs, rhs))
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
def _math_quick_callback_gen(
|
def _math_quick_callback_gen(
|
||||||
@ -208,8 +214,19 @@ class VM:
|
|||||||
операций с пометкой QUICK
|
операций с пометкой QUICK
|
||||||
"""
|
"""
|
||||||
def callback(self, r3: int, r1: int, i8: int) -> None:
|
def callback(self, r3: int, r1: int, i8: int) -> None:
|
||||||
|
self.cc = VMCC(0)
|
||||||
lhs = self.registers[r1].value
|
lhs = self.registers[r1].value
|
||||||
self.registers[r3] = c_int32(operation(lhs, i8))
|
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
|
||||||
|
self.registers[r3] = c_int32(result)
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
def _load_callback(self, r3: int, r1: int, disp: int) -> None:
|
def _load_callback(self, r3: int, r1: int, disp: int) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user