feat: процедура выполнения опкода
This commit is contained in:
49
src/vm.py
49
src/vm.py
@ -1,6 +1,6 @@
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import ClassVar, Callable, Any
|
||||
from typing import ClassVar, Callable
|
||||
from ctypes import c_uint32, c_int32, c_uint8
|
||||
import struct
|
||||
from optable import OPCODES, OpcodeDescription, OpL, OpA, OpF, OpD
|
||||
@ -86,7 +86,7 @@ class VM:
|
||||
self._branch_callback,
|
||||
OpD(OpF.QUICK, OpL.BRANCH, OpA.BRANCH):
|
||||
self._branch_callback,
|
||||
OpD(OpF(0), OpL.BRANCH, OpA.MEM_BRANCH):
|
||||
OpD(OpF(0), OpL.BRANCH, OpA.IND_BRANCH):
|
||||
self._branch_indexed_callback
|
||||
}
|
||||
|
||||
@ -94,12 +94,16 @@ class VM:
|
||||
"""
|
||||
Make one step (only step into)
|
||||
"""
|
||||
# По какой-то причине адрессация работает
|
||||
# так, будто мы на 1 слово впереди опкода
|
||||
if not VMFlags.AFTER_BRANCH:
|
||||
self.pc = c_uint32(self.cc.value + 1)
|
||||
# сбрасываем флаг AFTER_BRANCH
|
||||
self._vm_flags &= ~(VMFlags.AFTER_BRANCH)
|
||||
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 &= ~(VMFlags.AFTER_BRANCH)
|
||||
self._run_callback(opdesc, args)
|
||||
|
||||
def continue_(self) -> None:
|
||||
"""
|
||||
@ -142,7 +146,39 @@ class VM:
|
||||
self.instr_callbacks[opdesc](
|
||||
r3, r1, r2_or_i8
|
||||
)
|
||||
if opdesc.layout == OpL.MEM
|
||||
if opdesc.layout == OpL.MEM:
|
||||
if OpF.QUICK in opdesc.flags:
|
||||
assert len(args) == 4
|
||||
_, r3, r1, i8 = args
|
||||
self.instr_callbacks[opdesc](
|
||||
r3, r1, i8
|
||||
)
|
||||
else:
|
||||
assert len(args) == 5
|
||||
_, r3, r1, _, disp = args
|
||||
self.instr_callbacks[opdesc](
|
||||
r3, r1, disp
|
||||
)
|
||||
|
||||
if opdesc.layout == OpL.BRANCH:
|
||||
if OpF.QUICK in opdesc.flags:
|
||||
assert len(args) == 4
|
||||
_, cond, _, i8 = args
|
||||
self.instr_callbacks[opdesc](
|
||||
cond, i8
|
||||
)
|
||||
elif opdesc.action == OpA.IND_BRANCH:
|
||||
assert len(args) == 5
|
||||
_, cond, r1, _, disp = args
|
||||
self.instr_callbacks[opdesc](
|
||||
cond, r1, disp
|
||||
)
|
||||
else:
|
||||
assert len(args) == 5
|
||||
_, cond, _, _, disp = args
|
||||
self.instr_callbacks[opdesc](
|
||||
cond, disp
|
||||
)
|
||||
|
||||
def _math_callback_gen(
|
||||
self,
|
||||
@ -200,3 +236,4 @@ class VM:
|
||||
self._vm_flags |= VMFlags.AFTER_BRANCH
|
||||
addr = self.registers[r1].value + disp
|
||||
self.pc = c_uint32(addr)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user