Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
Peter McGoron | 52279a9afc | |
Peter McGoron | 448b70cc97 | |
Peter McGoron @ planck | 73c5beb90e | |
Peter McGoron | 56c6523e15 | |
Peter McGoron @ planck | 0ead095044 | |
Peter McGoron @ planck | c7fc965fcf | |
Peter McGoron | dc1abae13a | |
Peter McGoron | 13c67aba9a | |
Peter McGoron | c18db4be57 | |
Peter McGoron | 22674528da | |
Peter McGoron | 6d30be57f7 | |
Peter McGoron | 8335395dec | |
Peter McGoron | 945bcd68a5 |
7
Makefile
7
Makefile
|
@ -1,13 +1,14 @@
|
|||
test: test_asm c_test/encode_decode c_test/creole
|
||||
CFLAGS=-DCREOLE_TEST
|
||||
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
|
||||
|
||||
test_asm: asm/libcreole.so
|
||||
cd asm && python3 test.py -f
|
||||
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/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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Version 0.2.1
|
||||
Version 0.2.0
|
||||
|
||||
Creole is a bytecode designed for microcontrollers. It's C source file
|
||||
is less than 1000 lines long and does not depend on the C standard
|
||||
|
|
|
@ -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)
|
|
@ -75,7 +75,7 @@ class StringArgument(Argument):
|
|||
def __call__(self):
|
||||
b = bytes()
|
||||
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
|
||||
|
||||
class LabelArgument(Argument):
|
||||
|
@ -210,6 +210,25 @@ class Instruction(Enum):
|
|||
J = "JE", "_render_j", ArgType.LAB
|
||||
JNE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL
|
||||
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):
|
||||
""" Returns the opcode associated with the Instruction.
|
||||
|
@ -459,7 +478,7 @@ class Program:
|
|||
assert len(b) < encoding_types[lablen][0]
|
||||
return b
|
||||
|
||||
def __init__(self, reglen=16, datlen=16):
|
||||
def __init__(self, reglen=32, datlen=64):
|
||||
self.asm = []
|
||||
self.reglen = reglen
|
||||
self.datlen = datlen
|
||||
|
|
15
asm/ffi.py
15
asm/ffi.py
|
@ -60,7 +60,7 @@ class Reader:
|
|||
|
||||
class CEnv(Structure):
|
||||
_fields_ = [
|
||||
("dats", POINTER(POINTER(c_ubyte))),
|
||||
("dats", POINTER(CReader)),
|
||||
("datlen", c_size_t),
|
||||
("reg", POINTER(c_uint)),
|
||||
("reglen", c_size_t),
|
||||
|
@ -68,7 +68,8 @@ class CEnv(Structure):
|
|||
("stkptr", c_size_t),
|
||||
("stklen", c_size_t),
|
||||
("r_current", CReader),
|
||||
("r_start", CReader)
|
||||
("r_start", CReader),
|
||||
("fd", c_int)
|
||||
]
|
||||
|
||||
class RegisterOverflowError(Exception):
|
||||
|
@ -116,13 +117,7 @@ class Environment:
|
|||
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)
|
||||
rdr = self.cenv.dats[n]
|
||||
|
||||
l = []
|
||||
w = CWord()
|
||||
|
@ -143,7 +138,7 @@ class Environment:
|
|||
|
||||
def __init__(self, prog=None, reglen=32, datlen=32, stklen=4096, prglen=4096):
|
||||
cenv = CEnv()
|
||||
cenv.dats = (POINTER(c_ubyte) * datlen)()
|
||||
cenv.dats = (CReader * datlen)()
|
||||
cenv.datlen = datlen
|
||||
|
||||
cenv.reglen = reglen
|
||||
|
|
|
@ -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()
|
259
creole.c
259
creole.c
|
@ -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
|
||||
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
|
||||
************************************************************************/
|
||||
|
@ -37,7 +46,7 @@ enum creole_arg_type {
|
|||
[i] = v,
|
||||
* 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 {
|
||||
int arglen;
|
||||
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(JE, 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 {
|
||||
unsigned char *start;
|
||||
unsigned char *datapt;
|
||||
size_t dataptlen;
|
||||
enum creole_opcode opcode;
|
||||
creole_word w[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) {
|
||||
ins->datapt = r->p;
|
||||
ins->dataptlen = 0;
|
||||
do {
|
||||
if (!creole_decode(r, &w))
|
||||
return CREOLE_ARG_READ_ERROR;
|
||||
} while (w.len != 1);
|
||||
ins->dataptlen = r->p - ins->datapt - 1;
|
||||
if (w.word != 0)
|
||||
return CREOLE_LAST_READ_ERROR;
|
||||
return CREOLE_COMPILE_OK;
|
||||
|
@ -419,7 +452,8 @@ add_to_env(struct creole_env *env, struct ins *ins)
|
|||
{
|
||||
switch (ins->opcode) {
|
||||
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;
|
||||
default:
|
||||
;
|
||||
|
@ -526,6 +560,67 @@ int creole_jump(struct creole_env *env, creole_word off)
|
|||
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 { \
|
||||
switch (check_sign_bits(ins.w_flags[1], ins.w_flags[2])) { \
|
||||
case ALL_UNSIGNED: \
|
||||
|
@ -559,26 +654,32 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
|||
|
||||
switch (ins.opcode) {
|
||||
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:
|
||||
check(read_val(env, &ins, 0, &a1));
|
||||
check(creole_push(env, a1));
|
||||
break;
|
||||
|
||||
case CREOLE_POP:
|
||||
check(creole_pop(env, &a1));
|
||||
check(creole_reg_write(env, ins.w[0], a1));
|
||||
break;
|
||||
|
||||
case CREOLE_ADD:
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
check(read_val(env, &ins, 2, &a2));
|
||||
check(creole_reg_write(env, ins.w[0], a1 + a2));
|
||||
break;
|
||||
|
||||
case CREOLE_MUL:
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
check(read_val(env, &ins, 2, &a2));
|
||||
check(creole_reg_write(env, ins.w[0], a1 * a2));
|
||||
break;
|
||||
|
||||
case CREOLE_DIV:
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
check(read_val(env, &ins, 2, &a2));
|
||||
|
@ -588,10 +689,12 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
|||
chk_sign_op(/);
|
||||
check(creole_reg_write(env, ins.w[0], a1));
|
||||
break;
|
||||
|
||||
case CREOLE_SYS:
|
||||
check(read_val(env, &ins, 0, sc));
|
||||
rcode = CREOLE_STEP_SYSCALL;
|
||||
break;
|
||||
|
||||
case CREOLE_JL:
|
||||
check(read_val(env, &ins, 0, &a0));
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
|
@ -600,6 +703,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
|||
if (a1 && !creole_jump(env, a0))
|
||||
return CREOLE_JUMP_OVERFLOW;
|
||||
break;
|
||||
|
||||
case CREOLE_JLE:
|
||||
check(read_val(env, &ins, 0, &a0));
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
|
@ -608,6 +712,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
|||
if (a1 && !creole_jump(env, a0))
|
||||
return CREOLE_JUMP_OVERFLOW;
|
||||
break;
|
||||
|
||||
case CREOLE_JE:
|
||||
check(read_val(env, &ins, 0, &a0));
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
|
@ -615,6 +720,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
|||
if (a1 == a2 && !creole_jump(env, a0))
|
||||
return CREOLE_JUMP_OVERFLOW;
|
||||
break;
|
||||
|
||||
case CREOLE_JNE:
|
||||
check(read_val(env, &ins, 0, &a0));
|
||||
check(read_val(env, &ins, 1, &a1));
|
||||
|
@ -622,8 +728,151 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
|||
if (a1 != a2 && !creole_jump(env, a0))
|
||||
return CREOLE_JUMP_OVERFLOW;
|
||||
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:
|
||||
rcode = CREOLE_STEP_UNKNOWN_OPCODE;
|
||||
break;
|
||||
}
|
||||
|
||||
return rcode;
|
||||
|
|
51
creole.h
51
creole.h
|
@ -19,7 +19,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|||
|
||||
#define CREOLE_MAJOR 0
|
||||
#define CREOLE_MINOR 2
|
||||
#define CREOLE_BUGFIX 1
|
||||
#define CREOLE_BUGFIX 0
|
||||
|
||||
#ifndef CREOLE_WORD
|
||||
# define CREOLE_WORD unsigned int
|
||||
|
@ -34,18 +34,39 @@ typedef CREOLE_WORD creole_word;
|
|||
typedef CREOLE_SIGNED_WORD creole_signed;
|
||||
|
||||
enum creole_opcode {
|
||||
CREOLE_NOOP,
|
||||
CREOLE_PUSH,
|
||||
CREOLE_POP,
|
||||
CREOLE_ADD,
|
||||
CREOLE_MUL,
|
||||
CREOLE_DIV,
|
||||
CREOLE_SYS,
|
||||
CREOLE_JL,
|
||||
CREOLE_JLE,
|
||||
CREOLE_JE,
|
||||
CREOLE_JNE,
|
||||
CREOLE_DB,
|
||||
CREOLE_NOOP = 0,
|
||||
CREOLE_PUSH = 1,
|
||||
CREOLE_POP = 2,
|
||||
CREOLE_ADD = 3,
|
||||
CREOLE_MUL = 4,
|
||||
CREOLE_DIV = 5,
|
||||
CREOLE_SYS = 6,
|
||||
CREOLE_JL = 7,
|
||||
CREOLE_JLE = 8,
|
||||
CREOLE_JE = 9,
|
||||
CREOLE_JNE = 10,
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -96,7 +117,7 @@ struct creole_reader {
|
|||
};
|
||||
|
||||
struct creole_env {
|
||||
unsigned char **dats;
|
||||
struct creole_reader *dats;
|
||||
size_t datlen;
|
||||
|
||||
creole_word *reg;
|
||||
|
@ -107,6 +128,8 @@ struct creole_env {
|
|||
|
||||
struct creole_reader r_current;
|
||||
struct creole_reader r_start;
|
||||
|
||||
int fd;
|
||||
};
|
||||
|
||||
int creole_decode(struct creole_reader *r, struct creole_word *w);
|
||||
|
|
Loading…
Reference in New Issue