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
|
||||
//% block="show leds" icon="\uf00a"
|
||||
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
|
||||
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
|
||||
void plotLeds(ImageLiteral leds) {
|
||||
MicroBitImage i(getbytes(leds));
|
||||
MicroBitImage i(imageBytes(leds));
|
||||
uBit.display.print(i, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void forever_stub(void *a) {
|
||||
while (true) {
|
||||
action::run((Action)a);
|
||||
runAction0((Action)a);
|
||||
uBit.sleep(20);
|
||||
}
|
||||
}
|
||||
|
@ -127,10 +127,7 @@ namespace control {
|
||||
//% help=control/in-background
|
||||
//% blockId="control_in_background" block="run in background" blockGap=8
|
||||
void inBackground(Action a) {
|
||||
if (a != 0) {
|
||||
incr(a);
|
||||
create_fiber((void(*)(void*))action::run, (void*)a, fiberDone);
|
||||
}
|
||||
runInBackground(a);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,13 +92,6 @@ namespace String {
|
||||
{
|
||||
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 {
|
||||
@ -187,138 +180,50 @@ namespace ArrayImpl {
|
||||
//%
|
||||
RefCollection *mk(uint32_t flags)
|
||||
{
|
||||
RefCollection *r = new RefCollection(flags);
|
||||
return r;
|
||||
return new RefCollection(flags);
|
||||
}
|
||||
|
||||
//%
|
||||
int length(RefCollection *c) { return c->data.size(); }
|
||||
|
||||
int length(RefCollection *c) { return c->length(); }
|
||||
//%
|
||||
void push(RefCollection *c, uint32_t 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());
|
||||
}
|
||||
|
||||
void push(RefCollection *c, uint32_t x) { c->push(x); }
|
||||
//%
|
||||
uint32_t getAt(RefCollection *c, int 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;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getAt(RefCollection *c, int x) { return c->getAt(x); }
|
||||
//%
|
||||
void removeAt(RefCollection *c, int x) {
|
||||
if (!in_range(c, x))
|
||||
return;
|
||||
|
||||
if (c->flags & 1) decr(c->data.at(x));
|
||||
c->data.erase(c->data.begin()+x);
|
||||
}
|
||||
|
||||
void removeAt(RefCollection *c, int x) { c->removeAt(x); }
|
||||
//%
|
||||
void setAt(RefCollection *c, int x, uint32_t y) {
|
||||
if (!in_range(c, x))
|
||||
return;
|
||||
|
||||
if (c->flags & 1) {
|
||||
decr(c->data.at(x));
|
||||
incr(y);
|
||||
}
|
||||
c->data.at(x) = y;
|
||||
}
|
||||
|
||||
void setAt(RefCollection *c, int x, uint32_t y) { c->setAt(x, y); }
|
||||
//%
|
||||
int indexOf(RefCollection *c, uint32_t x, int 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 indexOf(RefCollection *c, uint32_t x, int start) { return c->indexOf(x, start); }
|
||||
//%
|
||||
int removeElement(RefCollection *c, uint32_t x) {
|
||||
int idx = indexOf(c, x, 0);
|
||||
if (idx >= 0) {
|
||||
removeAt(c, idx);
|
||||
return 1;
|
||||
int removeElement(RefCollection *c, uint32_t x) { return c->removeElement(x); }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ActionImpl {
|
||||
// Import some stuff directly
|
||||
namespace ks {
|
||||
//%
|
||||
Action mk(int reflen, int totallen, int startptr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void registerWithDal(int id, int event, Action a);
|
||||
//%
|
||||
uint32_t mkLiteral(uint32_t lit)
|
||||
{
|
||||
return (uint32_t)getstr(lit);
|
||||
}
|
||||
|
||||
void runAction0(Action a);
|
||||
//%
|
||||
void run1(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 runAction1(Action a, int arg);
|
||||
//%
|
||||
void run(Action a)
|
||||
{
|
||||
ActionImpl::run1(a, 0);
|
||||
}
|
||||
Action mkAction(int reflen, int totallen, int startptr);
|
||||
//%
|
||||
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 {
|
||||
@ -440,13 +345,70 @@ namespace ksrt {
|
||||
}
|
||||
|
||||
//%
|
||||
uint32_t incr(uint32_t ptr) {
|
||||
bitvm::incr(ptr);
|
||||
return ptr;
|
||||
void panic(int code)
|
||||
{
|
||||
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
|
||||
//% blockId=device_build_image block="create image"
|
||||
Image createImage(ImageLiteral leds) {
|
||||
return MicroBitImage(getbytes(leds)).clone().leakData();
|
||||
return MicroBitImage(imageBytes(leds)).clone().leakData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,12 +1,6 @@
|
||||
#include "BitVM.h"
|
||||
|
||||
namespace bitvm {
|
||||
namespace bitvm_micro_bit {
|
||||
void registerWithDal(int id, int event, Action a);
|
||||
}
|
||||
}
|
||||
#include "kindscript.h"
|
||||
|
||||
using namespace ks;
|
||||
MicroBitPin *getPin(int id);
|
||||
using namespace bitvm::bitvm_micro_bit;
|
||||
typedef ImageData* Image;
|
||||
|
||||
|
@ -178,4 +178,25 @@ namespace pins {
|
||||
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