From 45ec779d4d47ec83eac47e415202dc4baea98f2d Mon Sep 17 00:00:00 2001 From: ionut Date: Fri, 1 May 2026 17:57:26 +0300 Subject: [PATCH] eeprom is complete --- src/main.c | 39 ++++++++++++++++++++------------- src/ncomplib.c | 48 ++++++++++++++++++++++++++++++++++++++++ src/neonucleus.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++- src/neonucleus.h | 1 + 4 files changed, 129 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index 16dcf30..95dd01a 100644 --- a/src/main.c +++ b/src/main.c @@ -479,8 +479,8 @@ int main(int argc, char **argv) { double nextSecond = 0; double wattage = 0; - nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[2]); - nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[2]); + nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[3]); + nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[3]); nn_Component *keyboard = nn_createComponent( u, "mainKB", "keyboard"); @@ -567,25 +567,34 @@ int main(int argc, char **argv) { int ty = (double)(GetMouseY() - offY) / cheight + 1; if(tx >= 1 && ty >= 1 && tx <= scrw && ty <= scrh) { - // we only care about left click here - if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - nn_pushTouch(c, scraddr, tx, ty, 0, player); - } - if(IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) { - nn_pushDrop(c, scraddr, tx, ty, 0, player); - } - if(IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - if(ltx != tx || lty != ty) { - ltx = tx; - lty = ty; - //scrollBuf = 0; - nn_pushDrag(c, scraddr, tx, ty, 0, player); + struct {int btn; int ocbtn;} btns[] = { + {MOUSE_BUTTON_LEFT, 0}, + {MOUSE_BUTTON_RIGHT, 1}, + {MOUSE_BUTTON_MIDDLE, 2}, + }; + size_t btnc = sizeof(btns) / sizeof(btns[0]); + for(size_t i = 0; i < btnc; i++) { + // we only care about left click here + int mbtn = btns[i].btn; + int ocbtn = btns[i].ocbtn; + if(IsMouseButtonPressed(mbtn)) { + nn_pushTouch(c, scraddr, tx, ty, ocbtn, player); + } + if(IsMouseButtonReleased(mbtn)) { + nn_pushDrop(c, scraddr, tx, ty, ocbtn, player); + } + if(IsMouseButtonDown(mbtn)) { + if(ltx != tx || lty != ty) { + nn_pushDrag(c, scraddr, tx, ty, ocbtn, player); + } } } if(fabs(scrollBuf) >= 1) { nn_pushScroll(c, scraddr, tx, ty, scrollBuf, player); scrollBuf = 0; } + ltx = tx; + lty = ty; } } diff --git a/src/ncomplib.c b/src/ncomplib.c index aaf3d24..687c44d 100644 --- a/src/ncomplib.c +++ b/src/ncomplib.c @@ -1847,45 +1847,93 @@ static nn_Exit ncl_eepromHandler(nn_EEPROMRequest *req) { return NN_OK; } if(req->action == NN_EEPROM_GET) { + nn_lock(ctx, state->lock); memcpy(req->buf, state->code, state->codelen); req->buflen = state->codelen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_GETDATA) { + nn_lock(ctx, state->lock); memcpy(req->buf, state->data, state->datalen); req->buflen = state->datalen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_GETLABEL) { + nn_lock(ctx, state->lock); memcpy(req->buf, state->label, state->labellen); req->buflen = state->labellen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_GETARCH) { + nn_lock(ctx, state->lock); memcpy(req->buf, state->archname, state->archlen); req->buflen = state->archlen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_SET) { + nn_lock(ctx, state->lock); + if(state->isReadonly) { + nn_unlock(ctx, state->lock); + nn_setError(C, "eeprom is readonly"); + return NN_EBADCALL; + } memcpy(state->code, req->robuf, req->buflen); state->codelen = req->buflen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_SETDATA) { + nn_lock(ctx, state->lock); + if(state->isReadonly) { + nn_unlock(ctx, state->lock); + nn_setError(C, "eeprom is readonly"); + return NN_EBADCALL; + } memcpy(state->data, req->robuf, req->buflen); state->datalen = req->buflen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_SETLABEL) { + nn_lock(ctx, state->lock); + if(state->isReadonly) { + nn_unlock(ctx, state->lock); + nn_setError(C, "eeprom is readonly"); + return NN_EBADCALL; + } if(req->buflen > NN_MAX_LABEL) req->buflen = NN_MAX_LABEL; memcpy(state->label, req->robuf, req->buflen); state->labellen = req->buflen; + nn_unlock(ctx, state->lock); return NN_OK; } if(req->action == NN_EEPROM_SETARCH) { + nn_lock(ctx, state->lock); + if(state->isReadonly) { + nn_unlock(ctx, state->lock); + nn_setError(C, "eeprom is readonly"); + return NN_EBADCALL; + } if(req->buflen > NN_MAX_ARCHNAME) req->buflen = NN_MAX_ARCHNAME; memcpy(state->archname, req->robuf, req->buflen); state->archlen = req->buflen; + nn_unlock(ctx, state->lock); + return NN_OK; + } + if(req->action == NN_EEPROM_ISRO) { + nn_lock(ctx, state->lock); + req->readonly = state->isReadonly; + nn_unlock(ctx, state->lock); + return NN_OK; + } + if(req->action == NN_EEPROM_MKRO) { + nn_lock(ctx, state->lock); + state->isReadonly = true; + nn_unlock(ctx, state->lock); return NN_OK; } if(C) nn_setError(C, "ncl-eeprom: not implemented yet"); diff --git a/src/neonucleus.c b/src/neonucleus.c index 5b97ce5..2835d8e 100644 --- a/src/neonucleus.c +++ b/src/neonucleus.c @@ -3927,6 +3927,61 @@ static nn_Exit nn_eepromHandler(nn_ComponentRequest *req) { req->returnCount = 1; return nn_pushbool(C, true); } + if(method == NN_EENUM_ISRO) { + ereq.action = NN_EEPROM_ISRO; + e = state->handler(&ereq); + if(e) return e; + req->returnCount = 1; + return nn_pushbool(C, ereq.readonly); + } + if(method == NN_EENUM_GETCHKSUM) { + nn_removeEnergy(C, eeprom.readEnergyCost); + ereq.action = NN_EEPROM_GET; + NN_VLA(char, buf, eeprom.size); + ereq.buf = buf; + ereq.buflen = eeprom.size; + e = state->handler(&ereq); + if(e) return e; + req->returnCount = 1; + char checkbuf[8]; + unsigned int chksumInt = nn_computeCRC32(buf, ereq.buflen); + nn_crc32ChecksumBytes(chksumInt, checkbuf); + return nn_pushlstring(C, checkbuf, 8); + } + if(method == NN_EENUM_MKRO) { + if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; + + size_t expectedLen; + const char *expected = nn_tolstring(C, 0, &expectedLen); + + if(expectedLen != 8) { + nn_setError(C, "malformed checksum"); + return NN_EBADCALL; + } + + nn_removeEnergy(C, eeprom.readEnergyCost); + ereq.action = NN_EEPROM_GET; + NN_VLA(char, buf, eeprom.size); + ereq.buf = buf; + ereq.buflen = eeprom.size; + e = state->handler(&ereq); + if(e) return e; + req->returnCount = 1; + char checkbuf[8]; + unsigned int chksumInt = nn_computeCRC32(buf, ereq.buflen); + nn_crc32ChecksumBytes(chksumInt, checkbuf); + + if(nn_memcmp(expected, checkbuf, 8) != 0) { + nn_setError(C, "incorrect checksum, verify EEPROM is correct"); + return NN_EBADCALL; + } + + ereq.action = NN_EEPROM_MKRO; + e = state->handler(&ereq); + if(e) return e; + + return nn_pushbool(C, true); + } nn_setError(C, "not implemented yet"); return NN_EBADCALL; } @@ -3945,7 +4000,7 @@ nn_Component *nn_createEEPROM(nn_Universe *universe, const char *address, const [NN_EENUM_SETDATA] = {"setData", "function(data: string) - Set the data on the EEPROM", NN_INDIRECT}, [NN_EENUM_SETLABEL] = {"setLabel", "function(label?: string) - Set the label", NN_INDIRECT}, [NN_EENUM_SETARCH] = {"setArchitecture", "function(arch?: string) - Set the desired architecture", NN_INDIRECT}, - [NN_EENUM_ISRO] = {"isReadonly", "function(): boolean - Returns whether the EEPROM is read-only.", NN_DIRECT}, + [NN_EENUM_ISRO] = {"isReadOnly", "function(): boolean - Returns whether the EEPROM is read-only.", NN_DIRECT}, [NN_EENUM_GETCHKSUM] = {"getChecksum", "function(): string - Returns a checksum of the EEPROM code.", NN_DIRECT}, [NN_EENUM_MKRO] = {"makeReadonly", "function(checksum: string): boolean - Make the EEPROM read-only if checksum passes.", NN_INDIRECT}, }; diff --git a/src/neonucleus.h b/src/neonucleus.h index 3360456..a24f266 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -995,6 +995,7 @@ typedef struct nn_EEPROMRequest { union { char *buf; const char *robuf; + bool readonly; }; size_t buflen; } nn_EEPROMRequest;