some more changes

This commit is contained in:
2026-02-16 13:57:43 +01:00
parent d97b3f0413
commit 9b6cb0af7c
6 changed files with 163 additions and 30 deletions

View File

@@ -59,7 +59,10 @@ static nn_Exit luaArch_luaToNN(luaArch *arch, lua_State *L, int luaIdx) {
if(lua_isnoneornil(L, luaIdx)) { if(lua_isnoneornil(L, luaIdx)) {
return nn_pushnull(C); return nn_pushnull(C);
} }
if(lua_isnumber(L, luaIdx)) { // lua_isnumber() automatically casts
// because the Lua C API designers
// were high
if(lua_type(L, luaIdx) == LUA_TNUMBER) {
return nn_pushnumber(C, lua_tonumber(L, luaIdx)); return nn_pushnumber(C, lua_tonumber(L, luaIdx));
} }
if(lua_isstring(L, luaIdx)) { if(lua_isstring(L, luaIdx)) {

View File

@@ -21,6 +21,17 @@ function coroutine.resume(co, ...)
end end
end end
function coroutine.wrap(f)
local co = coroutine.create(f)
return function(...)
local t = {coroutine.resume(co, ...)}
if t[1] then
return table.unpack(t, 2)
end
error(t[2], 2)
end
end
local clist, cinvoke, computer, component, print, unicode = component.list, component.invoke, computer, component, print, unicode local clist, cinvoke, computer, component, print, unicode = component.list, component.invoke, computer, component, print, unicode
debug.print = print debug.print = print
debug.sysyield = sysyield debug.sysyield = sysyield
@@ -232,6 +243,9 @@ collectgarbage("stop")
local eeprom = component.list("eeprom", true)() local eeprom = component.list("eeprom", true)()
assert(eeprom, "missing firmware") assert(eeprom, "missing firmware")
local arch = component.invoke(eeprom, "getArchitecture")
if arch then computer.setArchitecture(arch) end
local code = assert(component.invoke(eeprom, "get")) local code = assert(component.invoke(eeprom, "get"))
local f = assert(load(code, "=bios")) local f = assert(load(code, "=bios"))

View File

@@ -983,11 +983,21 @@ void *ne_sandbox_alloc(void *state, void *memory, size_t oldSize, size_t newSize
return mem; return mem;
} }
double accumulatedEnergyCost = 0;
double totalEnergyLoss = 0;
double ne_energy_accumulator(void *state, nn_Computer *c, double n) {
accumulatedEnergyCost += n;
totalEnergyLoss += n;
return nn_getTotalEnergy(c);
}
int main() { int main() {
const char *player = getenv("USER"); const char *player = getenv("USER");
if(player == NULL) player = "me"; if(player == NULL) player = "me";
bool sandboxMem = getenv("NN_MEMSAND") != NULL; bool sandboxMem = getenv("NN_MEMSAND") != NULL;
bool showStats = getenv("NN_STAT") != NULL;
nn_Context ctx; nn_Context ctx;
nn_initContext(&ctx); nn_initContext(&ctx);
@@ -1032,7 +1042,7 @@ int main() {
.isReadonly = false, .isReadonly = false,
}; };
nn_ComponentType *etype = nn_createVEEPROM(u, &nn_defaultEEPROM, &veeprom); nn_ComponentType *etype = nn_createVEEPROM(u, &nn_defaultEEPROMs[3], &veeprom);
nn_ComponentType *fstype[5]; nn_ComponentType *fstype[5];
fstype[0] = nn_createFilesystem(u, &nn_defaultFloppy, ne_fsState_handler, NULL); fstype[0] = nn_createFilesystem(u, &nn_defaultFloppy, ne_fsState_handler, NULL);
for(size_t i = 1; i < 5; i++) { for(size_t i = 1; i < 5; i++) {
@@ -1043,6 +1053,10 @@ int main() {
nn_ComponentType *gputype = nn_createGPU(u, &nn_defaultGPUs[3], ne_gpu_handler, NULL); nn_ComponentType *gputype = nn_createGPU(u, &nn_defaultGPUs[3], ne_gpu_handler, NULL);
nn_Computer *c = nn_createComputer(u, NULL, "computer0", 8 * NN_MiB, 256, 256); nn_Computer *c = nn_createComputer(u, NULL, "computer0", 8 * NN_MiB, 256, 256);
if(showStats) {
// collects stats
nn_setEnergyHandler(c, NULL, ne_energy_accumulator);
}
nn_setArchitecture(c, &arch); nn_setArchitecture(c, &arch);
nn_addSupportedArchitecture(c, &arch); nn_addSupportedArchitecture(c, &arch);
@@ -1051,7 +1065,7 @@ int main() {
nn_addComponent(c, etype, "eeprom", 0, etype); nn_addComponent(c, etype, "eeprom", 0, etype);
ne_FsState *mainFS = ne_newFS("OpenOS", true); ne_FsState *mainFS = ne_newFS("OpenOS", true);
nn_addComponent(c, fstype[0], "mainFS", 2, mainFS); nn_addComponent(c, fstype[4], "mainFS", 2, mainFS);
nn_addComponent(c, keytype, "mainKB", 4, NULL); nn_addComponent(c, keytype, "mainKB", 4, NULL);
ne_ScreenBuffer *scrbuf = ne_newScreenBuf(&ctx, nn_defaultScreens[2], "mainKB"); ne_ScreenBuffer *scrbuf = ne_newScreenBuf(&ctx, nn_defaultScreens[2], "mainKB");
@@ -1066,6 +1080,10 @@ int main() {
double tickDelay = 0.05; double tickDelay = 0.05;
double tickClock = 0; double tickClock = 0;
if(getenv("NN_TICKDELAY") != NULL) {
tickDelay = atof(getenv("NN_TICKDELAY"));
}
struct {int key; nn_codepoint unicode;} keybuf[512]; struct {int key; nn_codepoint unicode;} keybuf[512];
memset(keybuf, 0, sizeof(keybuf)); memset(keybuf, 0, sizeof(keybuf));
size_t keycap = sizeof(keybuf) / sizeof(keybuf[0]); size_t keycap = sizeof(keybuf) / sizeof(keybuf[0]);
@@ -1100,7 +1118,19 @@ int main() {
} }
} }
if(sand.buf != NULL) DrawText(TextFormat("mem used: %.2f%%", (double)sand.used / sand.cap * 100), 10, 10, 20, WHITE); int statY = 10;
if(sand.buf != NULL) {
DrawText(TextFormat("mem used: %.2f%%", (double)sand.used / sand.cap * 100), 10, statY, 20, WHITE);
statY += 20;
}
if(showStats) {
double wattage = accumulatedEnergyCost;
if(tickDelay > 0) wattage /= tickDelay;
DrawText(TextFormat("power usage: %.2f W", wattage), 10, statY, 20, WHITE);
statY += 20;
DrawText(TextFormat("energy loss: %.2f J", totalEnergyLoss), 10, statY, 20, WHITE);
statY += 20;
}
EndDrawing(); EndDrawing();
@@ -1142,6 +1172,7 @@ int main() {
tickClock -= GetFrameTime(); tickClock -= GetFrameTime();
if(tickClock <= 0) { if(tickClock <= 0) {
accumulatedEnergyCost = 0;
tickClock = tickDelay; tickClock = tickDelay;
nn_clearstack(c); nn_clearstack(c);

View File

@@ -46,11 +46,20 @@ local function getBootCode(addr)
-- Generic MBR bootcode -- Generic MBR bootcode
if firstSector:sub(-2, -1) == "\x55\xAA" then if firstSector:sub(-2, -1) == "\x55\xAA" then
local codeEnd = sectorSize - 67 -- no laughing!!!! local codeEnd = sectorSize - 66
local term = string.find(firstSector, "\0", 5, true) local term = string.find(firstSector, "\0", 5, true)
return load(string.sub(firstSector, 5, term and (term - 1) or codeEnd)) return load(string.sub(firstSector, 5, term and (term - 1) or codeEnd))
end end
-- TODO: whatever else NC might be testing -- TODO: whatever else NC might be testing
local sectorsIn32K = math.ceil(32768 / sectorSize)
local bootCode = {firstSector}
for i=2,sectorsIn32K do
table.insert(bootCode, drive.readSector(i))
end
local rawCode = table.concat(bootCode)
local term = string.find(rawCode, "\0")
rawCode = string.sub(rawCode, 1, term and (term - 1) or -1)
return load(rawCode)
end end
local paths = { local paths = {

View File

@@ -979,6 +979,11 @@ bool nn_removeEnergy(nn_Computer *computer, double energy) {
return false; return false;
} }
void nn_setEnergyHandler(nn_Computer *computer, void *energyState, nn_EnergyHandler *handler) {
computer->energyState = energyState;
computer->energyHandler = handler;
}
size_t nn_getTotalMemory(nn_Computer *computer) { size_t nn_getTotalMemory(nn_Computer *computer) {
return computer->totalMemory; return computer->totalMemory;
} }
@@ -1878,9 +1883,11 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return NN_OK; return NN_OK;
case NN_COMP_CALL: case NN_COMP_CALL:
if(nn_strcmp(method, "getSize") == 0) { if(nn_strcmp(method, "getSize") == 0) {
req->returnCount = 1;
return nn_pushnumber(computer, state->eeprom.size); return nn_pushnumber(computer, state->eeprom.size);
} }
if(nn_strcmp(method, "getDataSize") == 0) { if(nn_strcmp(method, "getDataSize") == 0) {
req->returnCount = 1;
return nn_pushnumber(computer, state->eeprom.dataSize); return nn_pushnumber(computer, state->eeprom.dataSize);
} }
if(nn_strcmp(method, "isReadOnly") == 0) { if(nn_strcmp(method, "isReadOnly") == 0) {
@@ -1891,7 +1898,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushbool(computer, ereq.buflen != 0); return nn_pushbool(computer, ereq.buflen != 0);
} }
if(nn_strcmp(method, "getChecksum") == 0) { if(nn_strcmp(method, "getChecksum") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.readEnergyCost);
// yup, on-stack. // yup, on-stack.
// Perhaps in the future we'll make it heap-allocated. // Perhaps in the future we'll make it heap-allocated.
char buf[state->eeprom.size]; char buf[state->eeprom.size];
@@ -1907,7 +1914,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushlstring(computer, encoded, 8); return nn_pushlstring(computer, encoded, 8);
} }
if(nn_strcmp(method, "makeReadonly") == 0) { if(nn_strcmp(method, "makeReadonly") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.readEnergyCost);
// 1st argument is a string, which is the checksum we're meant to have // 1st argument is a string, which is the checksum we're meant to have
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
size_t len; size_t len;
@@ -1940,7 +1947,6 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushbool(computer, true); return nn_pushbool(computer, true);
} }
if(nn_strcmp(method, "getLabel") == 0) { if(nn_strcmp(method, "getLabel") == 0) {
nn_costComponent(computer, req->compAddress, 1);
char buf[NN_MAX_LABEL]; char buf[NN_MAX_LABEL];
ereq.action = NN_EEPROM_GETLABEL; ereq.action = NN_EEPROM_GETLABEL;
ereq.buf = buf; ereq.buf = buf;
@@ -1952,7 +1958,6 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushlstring(computer, buf, ereq.buflen); return nn_pushlstring(computer, buf, ereq.buflen);
} }
if(nn_strcmp(method, "setLabel") == 0) { if(nn_strcmp(method, "setLabel") == 0) {
nn_costComponent(computer, req->compAddress, 1);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
size_t len; size_t len;
const char *s = nn_tolstring(computer, 0, &len); const char *s = nn_tolstring(computer, 0, &len);
@@ -1968,7 +1973,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushlstring(computer, buf, ereq.buflen); return nn_pushlstring(computer, buf, ereq.buflen);
} }
if(nn_strcmp(method, "get") == 0) { if(nn_strcmp(method, "get") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.readEnergyCost);
// yup, on-stack. // yup, on-stack.
// Perhaps in the future we'll make it heap-allocated. // Perhaps in the future we'll make it heap-allocated.
char buf[state->eeprom.size]; char buf[state->eeprom.size];
@@ -1981,7 +1986,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushlstring(computer, buf, ereq.buflen); return nn_pushlstring(computer, buf, ereq.buflen);
} }
if(nn_strcmp(method, "getData") == 0) { if(nn_strcmp(method, "getData") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.readDataEnergyCost);
// yup, on-stack. // yup, on-stack.
// Perhaps in the future we'll make it heap-allocated. // Perhaps in the future we'll make it heap-allocated.
char buf[state->eeprom.dataSize]; char buf[state->eeprom.dataSize];
@@ -1994,7 +1999,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return nn_pushlstring(computer, buf, ereq.buflen); return nn_pushlstring(computer, buf, ereq.buflen);
} }
if(nn_strcmp(method, "getArchitecture") == 0) { if(nn_strcmp(method, "getArchitecture") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.readDataEnergyCost);
char buf[NN_MAX_ARCHNAME]; char buf[NN_MAX_ARCHNAME];
ereq.action = NN_EEPROM_GETARCH; ereq.action = NN_EEPROM_GETARCH;
ereq.buf = buf; ereq.buf = buf;
@@ -2002,10 +2007,11 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
nn_Exit e = state->handler(&ereq); nn_Exit e = state->handler(&ereq);
if(e) return e; if(e) return e;
req->returnCount = 1; req->returnCount = 1;
if(ereq.buflen == 0) return nn_pushnull(computer);
return nn_pushlstring(computer, buf, ereq.buflen); return nn_pushlstring(computer, buf, ereq.buflen);
} }
if(nn_strcmp(method, "set") == 0) { if(nn_strcmp(method, "set") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.writeEnergyCost);
if(nn_getstacksize(computer) < 1) { if(nn_getstacksize(computer) < 1) {
nn_setError(computer, "bad argument #1 (string expected)"); nn_setError(computer, "bad argument #1 (string expected)");
return NN_EBADCALL; return NN_EBADCALL;
@@ -2027,7 +2033,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return state->handler(&ereq); return state->handler(&ereq);
} }
if(nn_strcmp(method, "setData") == 0) { if(nn_strcmp(method, "setData") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.writeDataEnergyCost);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
size_t len; size_t len;
const char *s = nn_tolstring(computer, 0, &len); const char *s = nn_tolstring(computer, 0, &len);
@@ -2042,7 +2048,9 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return state->handler(&ereq); return state->handler(&ereq);
} }
if(nn_strcmp(method, "setArchitecture") == 0) { if(nn_strcmp(method, "setArchitecture") == 0) {
nn_costComponent(computer, req->compAddress, 1); nn_removeEnergy(computer, state->eeprom.writeDataEnergyCost);
nn_Exit err = nn_defaultstring(computer, 0, "");
if(err) return err;
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
size_t len; size_t len;
const char *s = nn_tolstring(computer, 0, &len); const char *s = nn_tolstring(computer, 0, &len);
@@ -2064,10 +2072,45 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
nn_EEPROM nn_defaultEEPROM = (nn_EEPROM) { nn_EEPROM nn_defaultEEPROM = (nn_EEPROM) {
.size = 4 * NN_KiB, .size = 4 * NN_KiB,
.dataSize = 256, .dataSize = 256,
.readEnergyCost = 10, .readEnergyCost = 1,
.writeEnergyCost = 100, .writeEnergyCost = 100,
.readDataEnergyCost = 10, .readDataEnergyCost = 0.1,
.writeDataEnergyCost = 50, .writeDataEnergyCost = 5,
};
nn_EEPROM nn_defaultEEPROMs[4] = {
(nn_EEPROM) {
.size = 4 * NN_KiB,
.dataSize = 256,
.readEnergyCost = 1,
.writeEnergyCost = 100,
.readDataEnergyCost = 0.1,
.writeDataEnergyCost = 5,
},
(nn_EEPROM) {
.size = 8 * NN_KiB,
.dataSize = 1 * NN_KiB,
.readEnergyCost = 2,
.writeEnergyCost = 200,
.readDataEnergyCost = 0.2,
.writeDataEnergyCost = 10,
},
(nn_EEPROM) {
.size = 16 * NN_KiB,
.dataSize = 2 * NN_KiB,
.readEnergyCost = 4,
.writeEnergyCost = 400,
.readDataEnergyCost = 0.4,
.writeDataEnergyCost = 20,
},
(nn_EEPROM) {
.size = 32 * NN_KiB,
.dataSize = 4 * NN_KiB,
.readEnergyCost = 8,
.writeEnergyCost = 800,
.readDataEnergyCost = 0.8,
.writeDataEnergyCost = 40,
},
}; };
nn_ComponentType *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, nn_EEPROMHandler *handler, void *userdata) { nn_ComponentType *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, nn_EEPROMHandler *handler, void *userdata) {
@@ -2089,7 +2132,7 @@ nn_ComponentType *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom
{"setData", "function(data: string) - Set the current EEPROM data contents.", NN_INDIRECT}, {"setData", "function(data: string) - Set the current EEPROM data contents.", NN_INDIRECT},
{"getArchitecture", "function(): string - Get the current EEPROM architecture intended.", NN_INDIRECT}, {"getArchitecture", "function(): string - Get the current EEPROM architecture intended.", NN_INDIRECT},
{"setArchitecture", "function(data: string) - Set the current EEPROM architecture intended.", NN_INDIRECT}, {"setArchitecture", "function(data: string) - Set the current EEPROM architecture intended.", NN_INDIRECT},
{"isReadOnly", "function(): boolean - Returns whether the EEPROM is read-only.", NN_INDIRECT}, {"isReadOnly", "function(): boolean - Returns whether the EEPROM is read-only.", NN_DIRECT},
{"makeReadonly", "function(checksum: string) - Makes the EEPROM read-only, this cannot be undone.", NN_INDIRECT}, {"makeReadonly", "function(checksum: string) - Makes the EEPROM read-only, this cannot be undone.", NN_INDIRECT},
{"getChecksum", "function(): string - Returns a simple checksum of the EEPROM's contents and data.", NN_INDIRECT}, {"getChecksum", "function(): string - Returns a simple checksum of the EEPROM's contents and data.", NN_INDIRECT},
{NULL, NULL, NN_INDIRECT}, {NULL, NULL, NN_INDIRECT},
@@ -2309,6 +2352,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return nn_pushlstring(computer, fsreq.strarg1, fsreq.strarg1len); return nn_pushlstring(computer, fsreq.strarg1, fsreq.strarg1len);
} }
if(nn_strcmp(method, "open") == 0) { if(nn_strcmp(method, "open") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.writesPerTick);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
err = nn_defaultstring(computer, 1, "r"); err = nn_defaultstring(computer, 1, "r");
if(err) return err; if(err) return err;
@@ -2341,6 +2385,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return state->handler(&fsreq); return state->handler(&fsreq);
} }
if(nn_strcmp(method, "read") == 0) { if(nn_strcmp(method, "read") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkinteger(computer, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL; if(nn_checkinteger(computer, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
err = nn_defaultinteger(computer, 1, NN_MAX_READ); err = nn_defaultinteger(computer, 1, NN_MAX_READ);
if(err) return err; if(err) return err;
@@ -2358,9 +2403,11 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
if(err) return err; if(err) return err;
req->returnCount = 1; req->returnCount = 1;
if(fsreq.strarg1 == NULL) return nn_pushnull(computer); if(fsreq.strarg1 == NULL) return nn_pushnull(computer);
nn_removeEnergy(computer, state->fs.dataEnergyCost * fsreq.strarg1len);
return nn_pushlstring(computer, fsreq.strarg1, fsreq.strarg1len); return nn_pushlstring(computer, fsreq.strarg1, fsreq.strarg1len);
} }
if(nn_strcmp(method, "write") == 0) { if(nn_strcmp(method, "write") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.writesPerTick);
if(nn_checkinteger(computer, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL; if(nn_checkinteger(computer, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
if(nn_checkstring(computer, 1, "bad argument #2 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 1, "bad argument #2 (string expected)")) return NN_EBADCALL;
fsreq.action = NN_FS_WRITE; fsreq.action = NN_FS_WRITE;
@@ -2369,9 +2416,11 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
err = state->handler(&fsreq); err = state->handler(&fsreq);
if(err) return err; if(err) return err;
req->returnCount = 1; req->returnCount = 1;
nn_removeEnergy(computer, state->fs.dataEnergyCost * fsreq.strarg1len);
return nn_pushbool(computer, true); return nn_pushbool(computer, true);
} }
if(nn_strcmp(method, "seek") == 0) { if(nn_strcmp(method, "seek") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkinteger(computer, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL; if(nn_checkinteger(computer, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
err = nn_defaultstring(computer, 1, "cur"); err = nn_defaultstring(computer, 1, "cur");
if(err) return err; if(err) return err;
@@ -2398,6 +2447,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return nn_pushnumber(computer, fsreq.off); return nn_pushnumber(computer, fsreq.off);
} }
if(nn_strcmp(method, "list") == 0) { if(nn_strcmp(method, "list") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
char truepath[NN_MAX_PATH]; char truepath[NN_MAX_PATH];
size_t pathlen; size_t pathlen;
@@ -2449,6 +2499,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return err; return err;
} }
if(nn_strcmp(method, "exists") == 0) { if(nn_strcmp(method, "exists") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
char truepath[NN_MAX_PATH]; char truepath[NN_MAX_PATH];
size_t pathlen; size_t pathlen;
@@ -2468,6 +2519,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return nn_pushbool(computer, fsreq.size != 0); return nn_pushbool(computer, fsreq.size != 0);
} }
if(nn_strcmp(method, "size") == 0) { if(nn_strcmp(method, "size") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
char truepath[NN_MAX_PATH]; char truepath[NN_MAX_PATH];
size_t pathlen; size_t pathlen;
@@ -2487,6 +2539,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return nn_pushnumber(computer, fsreq.size); return nn_pushnumber(computer, fsreq.size);
} }
if(nn_strcmp(method, "lastModified") == 0) { if(nn_strcmp(method, "lastModified") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
char truepath[NN_MAX_PATH]; char truepath[NN_MAX_PATH];
size_t pathlen; size_t pathlen;
@@ -2506,6 +2559,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return nn_pushnumber(computer, fsreq.size * 1000); return nn_pushnumber(computer, fsreq.size * 1000);
} }
if(nn_strcmp(method, "isDirectory") == 0) { if(nn_strcmp(method, "isDirectory") == 0) {
nn_costComponent(computer, req->compAddress, state->fs.readsPerTick);
if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL; if(nn_checkstring(computer, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
char truepath[NN_MAX_PATH]; char truepath[NN_MAX_PATH];
size_t pathlen; size_t pathlen;
@@ -2685,8 +2739,8 @@ nn_GPU nn_defaultGPUs[4] = {
.setPerTick = 4, .setPerTick = 4,
.setForegroundPerTick = 2, .setForegroundPerTick = 2,
.setBackgroundPerTick = 2, .setBackgroundPerTick = 2,
.energyPerWrite = 0.02, .energyPerWrite = 0.0002,
.energyPerClear = 0.01, .energyPerClear = 0.0001,
}, },
(nn_GPU) { (nn_GPU) {
.maxWidth = 80, .maxWidth = 80,
@@ -2698,8 +2752,8 @@ nn_GPU nn_defaultGPUs[4] = {
.setPerTick = 8, .setPerTick = 8,
.setForegroundPerTick = 4, .setForegroundPerTick = 4,
.setBackgroundPerTick = 4, .setBackgroundPerTick = 4,
.energyPerWrite = 0.1, .energyPerWrite = 0.001,
.energyPerClear = 0.05, .energyPerClear = 0.0005,
}, },
(nn_GPU) { (nn_GPU) {
.maxWidth = 160, .maxWidth = 160,
@@ -2711,8 +2765,8 @@ nn_GPU nn_defaultGPUs[4] = {
.setPerTick = 16, .setPerTick = 16,
.setForegroundPerTick = 8, .setForegroundPerTick = 8,
.setBackgroundPerTick = 8, .setBackgroundPerTick = 8,
.energyPerWrite = 0.2, .energyPerWrite = 0.002,
.energyPerClear = 0.1, .energyPerClear = 0.001,
}, },
(nn_GPU) { (nn_GPU) {
.maxWidth = 240, .maxWidth = 240,
@@ -2724,8 +2778,8 @@ nn_GPU nn_defaultGPUs[4] = {
.setPerTick = 32, .setPerTick = 32,
.setForegroundPerTick = 16, .setForegroundPerTick = 16,
.setBackgroundPerTick = 16, .setBackgroundPerTick = 16,
.energyPerWrite = 0.25, .energyPerWrite = 0.0025,
.energyPerClear = 0.12, .energyPerClear = 0.0012,
}, },
}; };
@@ -2816,6 +2870,8 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
size_t len; size_t len;
greq.text = (char *)nn_tolstring(C, 2, &len); greq.text = (char *)nn_tolstring(C, 2, &len);
if(len > conf.maxWidth) len = conf.maxWidth; if(len > conf.maxWidth) len = conf.maxWidth;
// assumes no spaces
nn_removeEnergy(C, conf.energyPerWrite * len);
greq.width = len; greq.width = len;
greq.x = nn_tointeger(C, 0); greq.x = nn_tointeger(C, 0);
greq.y = nn_tointeger(C, 1); greq.y = nn_tointeger(C, 1);
@@ -2869,6 +2925,14 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
greq.y = nn_tointeger(C, 1); greq.y = nn_tointeger(C, 1);
greq.width = nn_tointeger(C, 2); greq.width = nn_tointeger(C, 2);
greq.height = nn_tointeger(C, 3); greq.height = nn_tointeger(C, 3);
if(greq.width > conf.maxWidth) greq.width = conf.maxWidth;
if(greq.height > conf.maxHeight) greq.height = conf.maxHeight;
// no free energy for you
if(greq.width < 0) greq.width = 0;
if(greq.height < 0) greq.height = 0;
// assumes no spaces
nn_removeEnergy(C, conf.energyPerClear * greq.width * greq.height);
err = state->handler(&greq); err = state->handler(&greq);
if(err) return err; if(err) return err;
req->returnCount = 1; req->returnCount = 1;
@@ -2889,6 +2953,14 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
greq.height = nn_tointeger(C, 3); greq.height = nn_tointeger(C, 3);
greq.tx = nn_tointeger(C, 4); greq.tx = nn_tointeger(C, 4);
greq.ty = nn_tointeger(C, 5); greq.ty = nn_tointeger(C, 5);
if(greq.width > conf.maxWidth) greq.width = conf.maxWidth;
if(greq.height > conf.maxHeight) greq.height = conf.maxHeight;
// no free energy for you
if(greq.width < 0) greq.width = 0;
if(greq.height < 0) greq.height = 0;
if(greq.codepoint == ' ') nn_removeEnergy(C, conf.energyPerWrite * greq.width * greq.height);
else nn_removeEnergy(C, conf.energyPerClear * greq.width * greq.height);
err = state->handler(&greq); err = state->handler(&greq);
if(err) return err; if(err) return err;
req->returnCount = 1; req->returnCount = 1;

View File

@@ -795,7 +795,11 @@ typedef struct nn_EEPROM {
double writeDataEnergyCost; double writeDataEnergyCost;
} nn_EEPROM; } nn_EEPROM;
extern nn_EEPROM nn_defaultEEPROM; // Tier 1 - The normal EEPROM equivalent
// Tier 2 - A better EEPROM
// Tier 3 - An even better EEPROM
// Tier 4- The best EEPROM
extern nn_EEPROM nn_defaultEEPROMs[4];
typedef struct nn_VEEPROM { typedef struct nn_VEEPROM {
const char *code; const char *code;
@@ -951,7 +955,7 @@ typedef struct nn_Filesystem {
// the maximum capacity of the filesystem // the maximum capacity of the filesystem
size_t spaceTotal; size_t spaceTotal;
// how many read calls can be done per tick // how many read calls can be done per tick
// list, exists, isDirectory, seek also count as reads. // list, exists, size, lastModified, isDirectory, seek also count as reads.
double readsPerTick; double readsPerTick;
// how many write calls can be done per tick // how many write calls can be done per tick
// makeDirectory, open, remove and rename also count as writes. // makeDirectory, open, remove and rename also count as writes.