diff --git a/libs/microbit/basic.cpp b/libs/microbit/basic.cpp index 26a2a0d3..ebfd5dc4 100644 --- a/libs/microbit/basic.cpp +++ b/libs/microbit/basic.cpp @@ -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); } } diff --git a/libs/microbit/control.cpp b/libs/microbit/control.cpp index 40bfe2e1..ad9dd3c9 100644 --- a/libs/microbit/control.cpp +++ b/libs/microbit/control.cpp @@ -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); } /** diff --git a/libs/microbit/core.cpp b/libs/microbit/core.cpp index 14da2265..92dd6285 100644 --- a/libs/microbit/core.cpp +++ b/libs/microbit/core.cpp @@ -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; - } - - return 0; - } + int removeElement(RefCollection *c, uint32_t x) { return c->removeElement(x); } } -namespace ActionImpl { - //% - 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; - } - - //% - uint32_t mkLiteral(uint32_t lit) - { - return (uint32_t)getstr(lit); - } - - //% - 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 run(Action a) - { - ActionImpl::run1(a, 0); - } +// Import some stuff directly +namespace ks { + //% + void registerWithDal(int id, int event, Action a); + //% + void runAction0(Action a); + //% + void runAction1(Action a, int arg); + //% + 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 decr(uint32_t ptr) { - bitvm::decr(ptr); + void panic(int code) + { + uBit.panic(code); } } + + + + 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); + } + } diff --git a/libs/microbit/images.cpp b/libs/microbit/images.cpp index 0f0d28d6..6ee28086 100644 --- a/libs/microbit/images.cpp +++ b/libs/microbit/images.cpp @@ -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(); } /** diff --git a/libs/microbit/ksbit.h b/libs/microbit/ksbit.h index 22e10105..ce4a2616 100644 --- a/libs/microbit/ksbit.h +++ b/libs/microbit/ksbit.h @@ -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; diff --git a/libs/microbit/pins.cpp b/libs/microbit/pins.cpp index 96fe580e..12f9631a 100644 --- a/libs/microbit/pins.cpp +++ b/libs/microbit/pins.cpp @@ -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); + } }