Compare commits

...

13 Commits

7 changed files with 364 additions and 33 deletions

View File

@ -1,13 +1,14 @@
test: test_asm c_test/encode_decode c_test/creole test: test_asm c_test/encode_decode c_test/creole
CFLAGS=-DCREOLE_TEST
asm/libcreole.so: creole.c creole.h asm/libcreole.so: creole.c creole.h
$(CC) -Wall -fPIC -c creole.c -o c_test/creole.o $(CC) $(CFLAGS) -Wall -fPIC -c creole.c -o c_test/creole.o
$(CC) -shared -o asm/libcreole.so c_test/creole.o $(CC) -shared -o asm/libcreole.so c_test/creole.o
test_asm: asm/libcreole.so test_asm: asm/libcreole.so
cd asm && python3 test.py -f cd asm && python3 test.py -f
c_test/encode_decode: c_test/encode_decode.c creole.c creole.h c_test/encode_decode: c_test/encode_decode.c creole.c creole.h
$(CC) creole.c c_test/encode_decode.c -Wall -pedantic -std=c89 -g -fopenmp -o c_test/encode_decode $(CC) $(CFLAGS) creole.c c_test/encode_decode.c -Wall -pedantic -std=c99 -g -fopenmp -o c_test/encode_decode
# c_test/encode_decode # c_test/encode_decode
c_test/creole: c_test/creole.c creole.c creole.h c_test/greatest.h c_test/creole: c_test/creole.c creole.c creole.h c_test/greatest.h
$(CC) -g c_test/creole.c -Wall -pedantic -std=c89 -o c_test/creole $(CC) $(CFLAGS) -g c_test/creole.c -Wall -pedantic -std=c99 -o c_test/creole
c_test/creole c_test/creole

18
asm/comm.py Normal file
View File

@ -0,0 +1,18 @@
from creole import *
import socket
def connect(ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
return s
def execute(creole_instance, socket):
code = creole_instance()
l = len(code)
assert l <= 0xFFFF
socket.sendall(bytes([l & 0xFF, l >> 8]) + code)
def connect_exec(cr, ip="192.168.1.50", port=6626):
s = connect(ip, port)
execute(cr, s)
return s.recv(1024)

View File

@ -75,7 +75,7 @@ class StringArgument(Argument):
def __call__(self): def __call__(self):
b = bytes() b = bytes()
for v in self.val: for v in self.val:
b = b + Argument(ArgType.IMM, int(v, base=16))() b = b + Argument(ArgType.IMM, int(v, base=10))()
return b return b
class LabelArgument(Argument): class LabelArgument(Argument):
@ -210,6 +210,25 @@ class Instruction(Enum):
J = "JE", "_render_j", ArgType.LAB J = "JE", "_render_j", ArgType.LAB
JNE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL JNE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL
DB = 11, "_render_default", ArgType.DAT, ArgType.STR DB = 11, "_render_default", ArgType.DAT, ArgType.STR
READ_ADC = 12, "_render_default", ArgType.VAL, ArgType.REG
READ_DAC = 13, "_render_default", ArgType.VAL, ArgType.REG
WRITE_DAC = 14, "_render_default", ArgType.VAL, ArgType.VAL
SLEEP = 15, "_render_default", ArgType.VAL
CLOOP_READ = 16, "_render_default", ArgType.VAL, ArgType.REG, ArgType.REG
CLOOP_WRITE = 17, "_render_default", ArgType.VAL, ArgType.VAL, ArgType.VAL
WF_LOAD = 18, "_render_default", ArgType.VAL, ArgType.DAT
WF_ARM = 19, "_render_default", ArgType.VAL, ArgType.VAL, ArgType.VAL
SENDVAL = 20, "_render_default", ArgType.VAL
SENDDAT = 21, "_render_default", ArgType.DAT
WF_DISARM = 22, "_render_default", ArgType.VAL
TAKE_ADC = 23, "_render_default", ArgType.VAL, ArgType.VAL
RELEASE_ADC = 24, "_render_default", ArgType.VAL
TAKE_DAC = 25, "_render_default", ArgType.VAL, ArgType.VAL
RELEASE_DAC = 26, "_render_default", ArgType.VAL
TAKE_WF = 27, "_render_default", ArgType.VAL, ArgType.VAL
RELEASE_WF = 28, "_render_default", ArgType.VAL
TAKE_CLOOP = 29, "_render_default", ArgType.VAL
RELEASE_CLOOP = 30, "_render_default"
def __int__(self): def __int__(self):
""" Returns the opcode associated with the Instruction. """ Returns the opcode associated with the Instruction.
@ -459,7 +478,7 @@ class Program:
assert len(b) < encoding_types[lablen][0] assert len(b) < encoding_types[lablen][0]
return b return b
def __init__(self, reglen=16, datlen=16): def __init__(self, reglen=32, datlen=64):
self.asm = [] self.asm = []
self.reglen = reglen self.reglen = reglen
self.datlen = datlen self.datlen = datlen

View File

@ -60,7 +60,7 @@ class Reader:
class CEnv(Structure): class CEnv(Structure):
_fields_ = [ _fields_ = [
("dats", POINTER(POINTER(c_ubyte))), ("dats", POINTER(CReader)),
("datlen", c_size_t), ("datlen", c_size_t),
("reg", POINTER(c_uint)), ("reg", POINTER(c_uint)),
("reglen", c_size_t), ("reglen", c_size_t),
@ -68,7 +68,8 @@ class CEnv(Structure):
("stkptr", c_size_t), ("stkptr", c_size_t),
("stklen", c_size_t), ("stklen", c_size_t),
("r_current", CReader), ("r_current", CReader),
("r_start", CReader) ("r_start", CReader),
("fd", c_int)
] ]
class RegisterOverflowError(Exception): class RegisterOverflowError(Exception):
@ -116,13 +117,7 @@ class Environment:
def getdat(self, n): def getdat(self, n):
if n >= self.cenv.datlen or n < 0: if n >= self.cenv.datlen or n < 0:
raise DataOverflowError(n) raise DataOverflowError(n)
rdr = CReader() rdr = self.cenv.dats[n]
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 = [] l = []
w = CWord() w = CWord()
@ -143,7 +138,7 @@ class Environment:
def __init__(self, prog=None, reglen=32, datlen=32, stklen=4096, prglen=4096): def __init__(self, prog=None, reglen=32, datlen=32, stklen=4096, prglen=4096):
cenv = CEnv() cenv = CEnv()
cenv.dats = (POINTER(c_ubyte) * datlen)() cenv.dats = (CReader * datlen)()
cenv.datlen = datlen cenv.datlen = datlen
cenv.reglen = reglen cenv.reglen = reglen

25
asm/test_comm.py Normal file
View File

@ -0,0 +1,25 @@
from comm import *
# These require a connection!
def test_print_char():
p = Program()
p.parse_asm_line(f"SENDVAL 100")
assert connect_exec(p) == b'100'
def test_print_string():
p = Program()
p.parse_lines([
"j .l",
f"db d0 {[ord(x) for x in 'hello world']}",
".l",
"senddat d0"
])
return connect_exec(p).decode()
def test_run_adc():
p = Program()
p.parse_lines([
"read_adc 0 r0",
"sendval r0"
])
return connect_exec(p).decode()

260
creole.c
View File

@ -12,8 +12,17 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include "creole.h" #ifndef CREOLE_TEST
# include <zephyr/kernel.h>
# include <zephyr/logging/log.h>
# include <zephyr/sys_clock.h>
# include "access.h"
# include "control_loop_cmds.h"
# include "sock.h"
LOG_MODULE_REGISTER(creole, 4);
#endif
#include "creole.h"
/************************************************************************* /*************************************************************************
* Static information * Static information
************************************************************************/ ************************************************************************/
@ -37,7 +46,7 @@ enum creole_arg_type {
[i] = v, [i] = v,
* in C89 indicies are implicit from 0 to the maximum filled-in value. * in C89 indicies are implicit from 0 to the maximum filled-in value.
*/ */
#define defop(s, n, a1, a2, a3) {n, {a1, a2, a3}} #define defop(s, n, a1, a2, a3) [CREOLE_##s] = {n, {a1, a2, a3}}
static const struct { static const struct {
int arglen; int arglen;
enum creole_arg_type argtype[CREOLE_MAX_ARG]; enum creole_arg_type argtype[CREOLE_MAX_ARG];
@ -53,7 +62,28 @@ static const struct {
defop(JLE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL), defop(JLE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
defop(JE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL), defop(JE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
defop(JNE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL), defop(JNE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
defop(DB, 1, TYPE_IMM, TYPE_NONE, TYPE_NONE) defop(DB, 1, TYPE_IMM, TYPE_NONE, TYPE_NONE),
defop(READ_ADC, 2, TYPE_VAL, TYPE_REG, TYPE_NONE),
defop(READ_DAC, 2, TYPE_VAL, TYPE_REG, TYPE_NONE),
defop(WRITE_DAC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
defop(SLEEP, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(CLOOP_READ, 2, TYPE_VAL, TYPE_REG, TYPE_NONE),
defop(CLOOP_WRITE, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
defop(WF_LOAD, 2, TYPE_VAL, TYPE_IMM, TYPE_NONE),
defop(WF_ARM, 3, TYPE_VAL, TYPE_VAL, TYPE_VAL),
defop(SENDVAL, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(SENDDAT, 1, TYPE_IMM, TYPE_NONE, TYPE_NONE),
defop(WF_DISARM, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(TAKE_ADC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
defop(RELEASE_ADC, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(TAKE_DAC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
defop(RELEASE_DAC, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(TAKE_WF, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
defop(RELEASE_WF, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(TAKE_CLOOP, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
defop(RELEASE_CLOOP, 0, TYPE_NONE, TYPE_NONE, TYPE_NONE),
defop(SWITCH_ADC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
defop(SWITCH_DAC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE)
}; };
/************************************************************************* /*************************************************************************
@ -327,6 +357,7 @@ int creole_encode(creole_word i, unsigned encode_to, unsigned high_bits,
struct ins { struct ins {
unsigned char *start; unsigned char *start;
unsigned char *datapt; unsigned char *datapt;
size_t dataptlen;
enum creole_opcode opcode; enum creole_opcode opcode;
creole_word w[CREOLE_MAX_ARG]; creole_word w[CREOLE_MAX_ARG];
creole_word w_flags[CREOLE_MAX_ARG]; creole_word w_flags[CREOLE_MAX_ARG];
@ -393,10 +424,12 @@ parse_line(struct creole_env *env, struct ins *ins, struct creole_reader *r)
if (ins->opcode == CREOLE_DB) { if (ins->opcode == CREOLE_DB) {
ins->datapt = r->p; ins->datapt = r->p;
ins->dataptlen = 0;
do { do {
if (!creole_decode(r, &w)) if (!creole_decode(r, &w))
return CREOLE_ARG_READ_ERROR; return CREOLE_ARG_READ_ERROR;
} while (w.len != 1); } while (w.len != 1);
ins->dataptlen = r->p - ins->datapt - 1;
if (w.word != 0) if (w.word != 0)
return CREOLE_LAST_READ_ERROR; return CREOLE_LAST_READ_ERROR;
return CREOLE_COMPILE_OK; return CREOLE_COMPILE_OK;
@ -419,7 +452,8 @@ add_to_env(struct creole_env *env, struct ins *ins)
{ {
switch (ins->opcode) { switch (ins->opcode) {
case CREOLE_DB: case CREOLE_DB:
env->dats[ins->w[0]] = ins->datapt; env->dats[ins->w[0]].p = ins->datapt;
env->dats[ins->w[0]].left = ins->dataptlen;
break; break;
default: default:
; ;
@ -526,6 +560,67 @@ int creole_jump(struct creole_env *env, creole_word off)
return 1; return 1;
} }
#ifndef CREOLE_TEST
static size_t
load_into_array(const struct creole_reader *start, creole_word *buf, size_t buflen)
{
size_t i = 0;
struct creole_word w;
struct creole_reader r = *start;
while (creole_decode(&r, &w) && i < buflen) {
buf[i++] = w.word;
}
return i;
}
static creole_word
upsilon_load_waveform(struct creole_env *env, creole_word slot,
creole_word db)
{
creole_word buf[MAX_WL_SIZE];
size_t len = load_into_array(env->dats + db, buf, ARRAY_SIZE(buf));
if (len < MAX_WL_SIZE)
return 0;
return waveform_load(buf, slot, K_FOREVER);
}
static creole_word
upsilon_sendval(struct creole_env *env, creole_word num)
{
char buf[32];
struct bufptr bp = {buf, sizeof(buf)};
return sock_printf(env->fd, &bp, "%u", num) == BUF_OK;
}
static creole_word
upsilon_senddat(struct creole_env *env, creole_word db)
{
#define SENDDAT_BUFLEN 1024
char buf[SENDDAT_BUFLEN];
struct bufptr bp = {buf, 0};
struct creole_word w;
struct creole_reader r = env->dats[db];
while (creole_decode(&r, &w) && bp.left < SENDDAT_BUFLEN) {
if (w.word > 0xFF)
return -EINVAL;
buf[bp.left++] = w.word;
}
if (r.left != 0) {
return -E2BIG;
}
return sock_write_buf(env->fd, &bp);
}
#endif /* CREOLE_TEST */
/* Upsilon interface */
#define chk_sign_op(OPER) do { \ #define chk_sign_op(OPER) do { \
switch (check_sign_bits(ins.w_flags[1], ins.w_flags[2])) { \ switch (check_sign_bits(ins.w_flags[1], ins.w_flags[2])) { \
case ALL_UNSIGNED: \ case ALL_UNSIGNED: \
@ -559,25 +654,32 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
switch (ins.opcode) { switch (ins.opcode) {
case CREOLE_DB: case CREOLE_DB:
env->dats[ins.w[0]] = ins.datapt; env->dats[ins.w[0]].p = ins.datapt;
env->dats[ins.w[0]].left = ins.dataptlen;
break;
case CREOLE_PUSH: case CREOLE_PUSH:
check(read_val(env, &ins, 0, &a1)); check(read_val(env, &ins, 0, &a1));
check(creole_push(env, a1)); check(creole_push(env, a1));
break; break;
case CREOLE_POP: case CREOLE_POP:
check(creole_pop(env, &a1)); check(creole_pop(env, &a1));
check(creole_reg_write(env, ins.w[0], a1)); check(creole_reg_write(env, ins.w[0], a1));
break; break;
case CREOLE_ADD: case CREOLE_ADD:
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
check(read_val(env, &ins, 2, &a2)); check(read_val(env, &ins, 2, &a2));
check(creole_reg_write(env, ins.w[0], a1 + a2)); check(creole_reg_write(env, ins.w[0], a1 + a2));
break; break;
case CREOLE_MUL: case CREOLE_MUL:
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
check(read_val(env, &ins, 2, &a2)); check(read_val(env, &ins, 2, &a2));
check(creole_reg_write(env, ins.w[0], a1 * a2)); check(creole_reg_write(env, ins.w[0], a1 * a2));
break; break;
case CREOLE_DIV: case CREOLE_DIV:
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
check(read_val(env, &ins, 2, &a2)); check(read_val(env, &ins, 2, &a2));
@ -587,10 +689,12 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
chk_sign_op(/); chk_sign_op(/);
check(creole_reg_write(env, ins.w[0], a1)); check(creole_reg_write(env, ins.w[0], a1));
break; break;
case CREOLE_SYS: case CREOLE_SYS:
check(read_val(env, &ins, 0, sc)); check(read_val(env, &ins, 0, sc));
rcode = CREOLE_STEP_SYSCALL; rcode = CREOLE_STEP_SYSCALL;
break; break;
case CREOLE_JL: case CREOLE_JL:
check(read_val(env, &ins, 0, &a0)); check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
@ -599,6 +703,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
if (a1 && !creole_jump(env, a0)) if (a1 && !creole_jump(env, a0))
return CREOLE_JUMP_OVERFLOW; return CREOLE_JUMP_OVERFLOW;
break; break;
case CREOLE_JLE: case CREOLE_JLE:
check(read_val(env, &ins, 0, &a0)); check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
@ -607,6 +712,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
if (a1 && !creole_jump(env, a0)) if (a1 && !creole_jump(env, a0))
return CREOLE_JUMP_OVERFLOW; return CREOLE_JUMP_OVERFLOW;
break; break;
case CREOLE_JE: case CREOLE_JE:
check(read_val(env, &ins, 0, &a0)); check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
@ -614,6 +720,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
if (a1 == a2 && !creole_jump(env, a0)) if (a1 == a2 && !creole_jump(env, a0))
return CREOLE_JUMP_OVERFLOW; return CREOLE_JUMP_OVERFLOW;
break; break;
case CREOLE_JNE: case CREOLE_JNE:
check(read_val(env, &ins, 0, &a0)); check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1)); check(read_val(env, &ins, 1, &a1));
@ -621,8 +728,151 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
if (a1 != a2 && !creole_jump(env, a0)) if (a1 != a2 && !creole_jump(env, a0))
return CREOLE_JUMP_OVERFLOW; return CREOLE_JUMP_OVERFLOW;
break; break;
#ifndef CREOLE_TEST
case CREOLE_READ_ADC:
check(read_val(env, &ins, 0, &a0));
a1 = adc_read(a0, K_FOREVER, &a2);
check(creole_reg_write(env, ins.w[1], a2));
check(creole_push(env, a1));
break;
case CREOLE_READ_DAC:
check(read_val(env, &ins, 0, &a0));
a1 = dac_read_write(a0, 0x1 << 23 | 0x1 << 20, K_FOREVER, NULL);
if (a1 == 0) {
a1 = dac_read_write(a0, 0, K_FOREVER, &a2);
check(creole_reg_write(env, ins.w[1], a2));
}
check(creole_push(env, a1));
break;
case CREOLE_WRITE_DAC:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1));
a2 = dac_read_write(a0, 0x1 << 20 | a1, K_FOREVER, NULL);
check(creole_push(env, a2));
break;
case CREOLE_SLEEP:
check(read_val(env, &ins, 0, &a0));
k_sleep(K_USEC(a0));
check(creole_push(env, 0));
break;
case CREOLE_CLOOP_READ:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 0, &a1));
check(read_val(env, &ins, 0, &a2));
if (valid_register(env, a1) && valid_register(env, a2)) {
a0 = cloop_read(a0, env->reg + a1, env->reg + a2, K_FOREVER);
check(creole_push(env, a0));
} else {
check(creole_push(env, -EINVAL));
}
break;
case CREOLE_CLOOP_WRITE:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 0, &a1));
check(read_val(env, &ins, 0, &a2));
a0 = cloop_write(a0, a1, a2, K_FOREVER);
check(creole_push(env, a0));
break;
case CREOLE_WF_LOAD:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1));
check(creole_push(env, upsilon_load_waveform(env, a0, a1)));
break;
case CREOLE_WF_ARM:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1));
check(read_val(env, &ins, 2, &a2));
check(creole_push(env, waveform_arm(a0, a1, a2, K_FOREVER)));
break;
case CREOLE_WF_DISARM:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, waveform_disarm(a0)));
break;
case CREOLE_SENDVAL:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, upsilon_sendval(env, a0)));
break;
case CREOLE_SENDDAT:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, upsilon_senddat(env, a0)));
break;
case CREOLE_TAKE_ADC:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 0, &a1));
check(creole_push(env, adc_take(a0, K_USEC(a1))));
break;
case CREOLE_RELEASE_ADC:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, adc_release(a0)));
break;
case CREOLE_TAKE_DAC:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 0, &a1));
check(creole_push(env, dac_take(a0, K_USEC(a1))));
break;
case CREOLE_RELEASE_DAC:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, dac_release(a0)));
break;
case CREOLE_TAKE_WF:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 0, &a1));
check(creole_push(env, waveform_take(a0, K_USEC(a1))));
break;
case CREOLE_RELEASE_WF:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, waveform_release(a0)));
break;
case CREOLE_TAKE_CLOOP:
check(read_val(env, &ins, 0, &a0));
check(creole_push(env, cloop_take(K_USEC(a0))));
break;
case CREOLE_RELEASE_CLOOP:
check(creole_push(env, cloop_release()));
break;
case CREOLE_SWITCH_ADC:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1));
check(creole_push(env, adc_switch(a0, a1, K_FOREVER)));
break;
case CREOLE_SWITCH_DAC:
check(read_val(env, &ins, 0, &a0));
check(read_val(env, &ins, 1, &a1));
check(creole_push(env, dac_switch(a0, a1, K_FOREVER)));
break;
#endif /* CREOLE_TEST */
default: default:
rcode = CREOLE_STEP_UNKNOWN_OPCODE; rcode = CREOLE_STEP_UNKNOWN_OPCODE;
break;
} }
return rcode; return rcode;

View File

@ -34,18 +34,39 @@ typedef CREOLE_WORD creole_word;
typedef CREOLE_SIGNED_WORD creole_signed; typedef CREOLE_SIGNED_WORD creole_signed;
enum creole_opcode { enum creole_opcode {
CREOLE_NOOP, CREOLE_NOOP = 0,
CREOLE_PUSH, CREOLE_PUSH = 1,
CREOLE_POP, CREOLE_POP = 2,
CREOLE_ADD, CREOLE_ADD = 3,
CREOLE_MUL, CREOLE_MUL = 4,
CREOLE_DIV, CREOLE_DIV = 5,
CREOLE_SYS, CREOLE_SYS = 6,
CREOLE_JL, CREOLE_JL = 7,
CREOLE_JLE, CREOLE_JLE = 8,
CREOLE_JE, CREOLE_JE = 9,
CREOLE_JNE, CREOLE_JNE = 10,
CREOLE_DB, CREOLE_DB = 11,
CREOLE_READ_ADC = 12,
CREOLE_READ_DAC = 13,
CREOLE_WRITE_DAC = 14,
CREOLE_SLEEP = 15,
CREOLE_CLOOP_READ = 16,
CREOLE_CLOOP_WRITE = 17,
CREOLE_WF_LOAD = 18,
CREOLE_WF_ARM = 19,
CREOLE_SENDVAL = 20,
CREOLE_SENDDAT = 21,
CREOLE_WF_DISARM = 22,
CREOLE_TAKE_ADC = 23,
CREOLE_RELEASE_ADC = 24,
CREOLE_TAKE_DAC = 25,
CREOLE_RELEASE_DAC = 26,
CREOLE_TAKE_WF = 27,
CREOLE_RELEASE_WF = 28,
CREOLE_TAKE_CLOOP = 29,
CREOLE_RELEASE_CLOOP = 30,
CREOLE_SWITCH_ADC = 31,
CREOLE_SWITCH_DAC = 32,
CREOLE_OPCODE_LEN CREOLE_OPCODE_LEN
}; };
@ -96,7 +117,7 @@ struct creole_reader {
}; };
struct creole_env { struct creole_env {
unsigned char **dats; struct creole_reader *dats;
size_t datlen; size_t datlen;
creole_word *reg; creole_word *reg;
@ -107,6 +128,8 @@ struct creole_env {
struct creole_reader r_current; struct creole_reader r_current;
struct creole_reader r_start; struct creole_reader r_start;
int fd;
}; };
int creole_decode(struct creole_reader *r, struct creole_word *w); int creole_decode(struct creole_reader *r, struct creole_word *w);