Use new APIs in the core
This commit is contained in:
parent
241da7fbed
commit
47d382135b
@ -38,7 +38,7 @@ namespace basic {
|
|||||||
//% blockId=device_show_leds
|
//% blockId=device_show_leds
|
||||||
//% block="show leds" icon="\uf00a"
|
//% block="show leds" icon="\uf00a"
|
||||||
void showLeds(ImageLiteral leds, int interval = 400) {
|
void showLeds(ImageLiteral leds, int interval = 400) {
|
||||||
uBit.display.print(MicroBitImage(getbytes(leds)), 0, 0, 0, interval);
|
uBit.display.print(MicroBitImage(imageBytes(leds)), 0, 0, 0, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +82,7 @@ namespace basic {
|
|||||||
*/
|
*/
|
||||||
//% help=basic/show-animation imageLiteral=1 async
|
//% help=basic/show-animation imageLiteral=1 async
|
||||||
void showAnimation(ImageLiteral leds, int interval = 400) {
|
void showAnimation(ImageLiteral leds, int interval = 400) {
|
||||||
uBit.display.animate(MicroBitImage(getbytes(leds)), interval, 5, 0);
|
uBit.display.animate(MicroBitImage(imageBytes(leds)), interval, 5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,13 +91,13 @@ namespace basic {
|
|||||||
*/
|
*/
|
||||||
//% help=basic/plot-leds weight=80
|
//% help=basic/plot-leds weight=80
|
||||||
void plotLeds(ImageLiteral leds) {
|
void plotLeds(ImageLiteral leds) {
|
||||||
MicroBitImage i(getbytes(leds));
|
MicroBitImage i(imageBytes(leds));
|
||||||
uBit.display.print(i, 0, 0, 0, 0);
|
uBit.display.print(i, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void forever_stub(void *a) {
|
void forever_stub(void *a) {
|
||||||
while (true) {
|
while (true) {
|
||||||
action::run((Action)a);
|
runAction0((Action)a);
|
||||||
uBit.sleep(20);
|
uBit.sleep(20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,10 +127,7 @@ namespace control {
|
|||||||
//% help=control/in-background
|
//% help=control/in-background
|
||||||
//% blockId="control_in_background" block="run in background" blockGap=8
|
//% blockId="control_in_background" block="run in background" blockGap=8
|
||||||
void inBackground(Action a) {
|
void inBackground(Action a) {
|
||||||
if (a != 0) {
|
runInBackground(a);
|
||||||
incr(a);
|
|
||||||
create_fiber((void(*)(void*))action::run, (void*)a, fiberDone);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,13 +92,6 @@ namespace String {
|
|||||||
{
|
{
|
||||||
return ManagedString::EmptyString.leakData();
|
return ManagedString::EmptyString.leakData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The proper StringData* representation is already laid out in memory by the code generator.
|
|
||||||
//%
|
|
||||||
uint32_t mkLiteral(uint32_t lit)
|
|
||||||
{
|
|
||||||
return (uint32_t)getstr(lit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NumberMethods {
|
namespace NumberMethods {
|
||||||
@ -187,138 +180,50 @@ namespace ArrayImpl {
|
|||||||
//%
|
//%
|
||||||
RefCollection *mk(uint32_t flags)
|
RefCollection *mk(uint32_t flags)
|
||||||
{
|
{
|
||||||
RefCollection *r = new RefCollection(flags);
|
return new RefCollection(flags);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//%
|
//%
|
||||||
int length(RefCollection *c) { return c->data.size(); }
|
int length(RefCollection *c) { return c->length(); }
|
||||||
|
|
||||||
//%
|
//%
|
||||||
void push(RefCollection *c, uint32_t x) {
|
void push(RefCollection *c, uint32_t x) { c->push(x); }
|
||||||
if (c->flags & 1) incr(x);
|
|
||||||
c->data.push_back(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool in_range(RefCollection *c, int x) {
|
|
||||||
return (0 <= x && x < (int)c->data.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
uint32_t getAt(RefCollection *c, int x) {
|
uint32_t getAt(RefCollection *c, int x) { return c->getAt(x); }
|
||||||
if (in_range(c, x)) {
|
|
||||||
uint32_t tmp = c->data.at(x);
|
|
||||||
if (c->flags & 1) incr(tmp);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error(ERR_OUT_OF_BOUNDS);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
void removeAt(RefCollection *c, int x) {
|
void removeAt(RefCollection *c, int x) { c->removeAt(x); }
|
||||||
if (!in_range(c, x))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (c->flags & 1) decr(c->data.at(x));
|
|
||||||
c->data.erase(c->data.begin()+x);
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
void setAt(RefCollection *c, int x, uint32_t y) {
|
void setAt(RefCollection *c, int x, uint32_t y) { c->setAt(x, y); }
|
||||||
if (!in_range(c, x))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (c->flags & 1) {
|
|
||||||
decr(c->data.at(x));
|
|
||||||
incr(y);
|
|
||||||
}
|
|
||||||
c->data.at(x) = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
int indexOf(RefCollection *c, uint32_t x, int start) {
|
int indexOf(RefCollection *c, uint32_t x, int start) { return c->indexOf(x, start); }
|
||||||
if (!in_range(c, start))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (c->flags & 2) {
|
|
||||||
StringData *xx = (StringData*)x;
|
|
||||||
for (uint32_t i = start; i < c->data.size(); ++i) {
|
|
||||||
StringData *ee = (StringData*)c->data.at(i);
|
|
||||||
if (xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0)
|
|
||||||
return (int)i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (uint32_t i = start; i < c->data.size(); ++i)
|
|
||||||
if (c->data.at(i) == x)
|
|
||||||
return (int)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
int removeElement(RefCollection *c, uint32_t x) {
|
int removeElement(RefCollection *c, uint32_t x) { return c->removeElement(x); }
|
||||||
int idx = indexOf(c, x, 0);
|
|
||||||
if (idx >= 0) {
|
|
||||||
removeAt(c, idx);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ActionImpl {
|
// Import some stuff directly
|
||||||
|
namespace ks {
|
||||||
//%
|
//%
|
||||||
Action mk(int reflen, int totallen, int startptr)
|
void registerWithDal(int id, int event, Action a);
|
||||||
{
|
|
||||||
check(0 <= reflen && reflen <= totallen, ERR_SIZE, 1);
|
|
||||||
check(reflen <= totallen && totallen <= 255, ERR_SIZE, 2);
|
|
||||||
check(bytecode[startptr] == 0xffff, ERR_INVALID_BINARY_HEADER, 3);
|
|
||||||
check(bytecode[startptr + 1] == 0, ERR_INVALID_BINARY_HEADER, 4);
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t tmp = (uint32_t)&bytecode[startptr];
|
|
||||||
|
|
||||||
if (totallen == 0) {
|
|
||||||
return tmp; // no closure needed
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ptr = ::operator new(sizeof(RefAction) + totallen * sizeof(uint32_t));
|
|
||||||
RefAction *r = new (ptr) RefAction();
|
|
||||||
r->len = totallen;
|
|
||||||
r->reflen = reflen;
|
|
||||||
r->func = (ActionCB)((tmp + 4) | 1);
|
|
||||||
memset(r->fields, 0, r->len * sizeof(uint32_t));
|
|
||||||
|
|
||||||
return (Action)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
uint32_t mkLiteral(uint32_t lit)
|
void runAction0(Action a);
|
||||||
{
|
|
||||||
return (uint32_t)getstr(lit);
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
void run1(Action a, int arg)
|
void runAction1(Action a, int arg);
|
||||||
{
|
|
||||||
if (hasVTable(a))
|
|
||||||
((RefAction*)a)->run(arg);
|
|
||||||
else {
|
|
||||||
check(*(uint16_t*)a == 0xffff, ERR_INVALID_BINARY_HEADER, 4);
|
|
||||||
((ActionCB)((a + 4) | 1))(NULL, NULL, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
//%
|
||||||
void run(Action a)
|
Action mkAction(int reflen, int totallen, int startptr);
|
||||||
{
|
//%
|
||||||
ActionImpl::run1(a, 0);
|
RefRecord* mkRecord(int reflen, int totallen);
|
||||||
}
|
//%
|
||||||
|
void debugMemLeaks();
|
||||||
|
//%
|
||||||
|
int incr(uint32_t e);
|
||||||
|
//%
|
||||||
|
void decr(uint32_t e);
|
||||||
|
//%
|
||||||
|
uint32_t *allocate(uint16_t sz);
|
||||||
|
//%
|
||||||
|
int templateHash();
|
||||||
|
//%
|
||||||
|
int programHash();
|
||||||
|
//%
|
||||||
|
void *ptrOfLiteral(int offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace RecordImpl {
|
namespace RecordImpl {
|
||||||
@ -440,13 +345,70 @@ namespace ksrt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//%
|
//%
|
||||||
uint32_t incr(uint32_t ptr) {
|
void panic(int code)
|
||||||
bitvm::incr(ptr);
|
{
|
||||||
return ptr;
|
uBit.panic(code);
|
||||||
}
|
|
||||||
|
|
||||||
//%
|
|
||||||
void decr(uint32_t ptr) {
|
|
||||||
bitvm::decr(ptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace buffer {
|
||||||
|
|
||||||
|
RefBuffer *mk(uint32_t size)
|
||||||
|
{
|
||||||
|
RefBuffer *r = new RefBuffer();
|
||||||
|
r->data.resize(size);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *cptr(RefBuffer *c)
|
||||||
|
{
|
||||||
|
return (char*)&c->data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int count(RefBuffer *c) { return c->data.size(); }
|
||||||
|
|
||||||
|
void fill(RefBuffer *c, int v)
|
||||||
|
{
|
||||||
|
memset(cptr(c), v, count(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_random(RefBuffer *c)
|
||||||
|
{
|
||||||
|
int len = count(c);
|
||||||
|
for (int i = 0; i < len; ++i)
|
||||||
|
c->data[i] = uBit.random(0x100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(RefBuffer *c, uint32_t x) {
|
||||||
|
c->data.push_back(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool in_range(RefBuffer *c, int x) {
|
||||||
|
return (0 <= x && x < (int)c->data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t at(RefBuffer *c, int x) {
|
||||||
|
if (in_range(c, x)) {
|
||||||
|
return c->data[x];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error(ERR_OUT_OF_BOUNDS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(RefBuffer *c, int x, uint32_t y) {
|
||||||
|
if (!in_range(c, x))
|
||||||
|
return;
|
||||||
|
c->data[x] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace bitvm_bits {
|
||||||
|
RefBuffer *create_buffer(int size)
|
||||||
|
{
|
||||||
|
return buffer::mk(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@ namespace images {
|
|||||||
//% weight=75 help=images/create-image
|
//% weight=75 help=images/create-image
|
||||||
//% blockId=device_build_image block="create image"
|
//% blockId=device_build_image block="create image"
|
||||||
Image createImage(ImageLiteral leds) {
|
Image createImage(ImageLiteral leds) {
|
||||||
return MicroBitImage(getbytes(leds)).clone().leakData();
|
return MicroBitImage(imageBytes(leds)).clone().leakData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
#include "BitVM.h"
|
#include "kindscript.h"
|
||||||
|
|
||||||
namespace bitvm {
|
|
||||||
namespace bitvm_micro_bit {
|
|
||||||
void registerWithDal(int id, int event, Action a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
using namespace ks;
|
||||||
MicroBitPin *getPin(int id);
|
MicroBitPin *getPin(int id);
|
||||||
using namespace bitvm::bitvm_micro_bit;
|
|
||||||
typedef ImageData* Image;
|
typedef ImageData* Image;
|
||||||
|
|
||||||
|
@ -178,4 +178,25 @@ namespace pins {
|
|||||||
wait_ms(5);
|
wait_ms(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
void i2cReadBuffer(int address, RefBuffer *buf)
|
||||||
|
{
|
||||||
|
uBit.i2c.read(address << 1, buf->cptr(), buf->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2cWriteBuffer(int address, RefBuffer *buf)
|
||||||
|
{
|
||||||
|
uBit.i2c.write(address << 1, buf->cptr(), buf->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int i2cReadRaw(int address, char *data, int length, int repeated)
|
||||||
|
{
|
||||||
|
return uBit.i2c.read(address, data, length, repeated);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i2cWriteRaw(int address, const char *data, int length, int repeated)
|
||||||
|
{
|
||||||
|
return uBit.i2c.write(address, data, length, repeated);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user