aboutsummaryrefslogtreecommitdiffstats
path: root/asm
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2023-02-25 21:01:03 +0000
committerGravatar Peter McGoron 2023-02-25 21:01:03 +0000
commit09d636c02cdbb13d10f1435d918cc36116715fc4 (patch)
treec7099a6c49ffa4521e144c5ed5a19186d08ec1ec /asm
parentget rid of unused lablen (diff)
export creole_decode; add db test
Diffstat (limited to 'asm')
-rw-r--r--asm/ffi.py25
-rw-r--r--asm/test.py10
2 files changed, 35 insertions, 0 deletions
diff --git a/asm/ffi.py b/asm/ffi.py
index 13731dd..e7903af 100644
--- a/asm/ffi.py
+++ b/asm/ffi.py
@@ -44,6 +44,11 @@ class RunRet(Enum):
def is_halt(self):
return not (self == RunRet.CONTINUE or self == RunRet.SYSCALL)
+class CWord(Structure):
+ _fields_ = [("len", c_int),
+ ("high_bits", c_int),
+ ("word", c_uint)]
+
class CReader(Structure):
_fields_ = [("p", POINTER(c_ubyte)),
("left", c_size_t)]
@@ -78,6 +83,8 @@ class InvalidSyscallError(Exception):
class CompileError(Exception):
def __init__(self, r):
self.r = r
+class DataOverflowError(Exception):
+ pass
class Environment:
def getreg(self, reg, signed=False):
@@ -106,6 +113,24 @@ class Environment:
return creole.from_2c(self.cenv.stk[stk])
else:
return self.cenv.stk[stk]
+ def getdat(self, n):
+ if n >= self.cenv.datlen or n < 0:
+ raise DataOverflowError(n)
+ rdr = CReader()
+ rdr.p = self.cenv.dats[n]
+ # Python does not allow for direct pointer arithmetic
+ rdr_p_v = addressof(rdr.p.contents)
+ r_start_p_v = addressof(self.cenv.r_start.p)
+
+ rdr.left = self.cenv.r_start.left - (rdr_p_v - r_start_p_v)
+
+ l = []
+ w = CWord()
+ while dll.creole_decode(byref(rdr), byref(w)) == 1:
+ if w.word == 0 and w.len == 1:
+ break
+ l.append(w.word)
+ return l
def pop(self):
if stk == 0:
diff --git a/asm/test.py b/asm/test.py
index e49d46d..986a06d 100644
--- a/asm/test.py
+++ b/asm/test.py
@@ -438,6 +438,16 @@ class DataTest(unittest.TestCase):
p = Program()
p.parse_asm_line("db d0 [4d2,1234,0,5]")
self.assertEqual(p(), b'\x0b\xc0\x80\xe0\x93\x92\xf0\x81\x88\xb4\xc0\x80\xc0\x85\x00')
+ def test_alloc_multiple(self):
+ p = Program()
+ p.parse_lines([
+ "db d0 [1,2,3,4]",
+ "db d1 [10,11,12,13]"
+ ])
+ ex = ffi.Environment(p())
+ self.assertEqual(ex(), ffi.RunRet.STOP)
+ self.assertEqual(ex.getdat(0), [1,2,3,4])
+ self.assertEqual(ex.getdat(1), [0x10,0x11,0x12,0x13])
class SCEnv(ffi.Environment):
def syscall(self, s):