diff --git a/build.zig b/build.zig index 9a94825..62edd2c 100644 --- a/build.zig +++ b/build.zig @@ -1,11 +1,17 @@ const std = @import("std"); const builtin = @import("builtin"); -fn addEngineSources(b: *std.Build, c: *std.Build.Step.Compile, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) void { +const LibBuildOpts = struct { + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + baremetal: bool, +}; + +fn addEngineSources(b: *std.Build, c: *std.Build.Step.Compile, opts: LibBuildOpts) void { const dataMod = b.createModule(.{ .root_source_file = b.path("src/data.zig"), - .target = target, - .optimize = optimize, + .target = opts.target, + .optimize = opts.optimize, }); const zigObj = b.addObject(.{ .name = "zig_wrappers", @@ -13,12 +19,9 @@ fn addEngineSources(b: *std.Build, c: *std.Build.Step.Compile, target: std.Build .pic = true, }); c.addObject(zigObj); - - c.linkLibC(); // we need a libc - + c.addCSourceFiles(.{ .files = &[_][]const u8{ - "src/tinycthread.c", "src/lock.c", "src/utils.c", "src/value.c", @@ -34,8 +37,20 @@ fn addEngineSources(b: *std.Build, c: *std.Build.Step.Compile, target: std.Build "src/components/gpu.c", "src/components/keyboard.c", }, + .flags = &.{ + if(opts.baremetal) "-DNN_BAREMETAL" else "", + }, }); + if(!opts.baremetal) { + c.linkLibC(); // we need a libc + c.addCSourceFiles(.{ + .files = &.{ + "src/tinycthread.c", + }, + }); + } + c.addIncludePath(b.path("src")); } @@ -92,6 +107,12 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); + const opts = LibBuildOpts { + .target = target, + .optimize = optimize, + .baremetal = b.option(bool, "baremetal", "Compiles without libc integration") orelse false, + }; + const includeFiles = b.addInstallHeaderFile(b.path("src/neonucleus.h"), "neonucleus.h"); const engineStatic = b.addStaticLibrary(.{ @@ -101,7 +122,7 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); - addEngineSources(b, engineStatic, target, optimize); + addEngineSources(b, engineStatic, opts); const engineShared = b.addSharedLibrary(.{ .name = getSharedEngineName(os), @@ -109,7 +130,7 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); - addEngineSources(b, engineShared, target, optimize); + addEngineSources(b, engineShared, opts); const engineStep = b.step("engine", "Builds the engine as a static library"); engineStep.dependOn(&engineStatic.step); @@ -162,24 +183,4 @@ pub fn build(b: *std.Build) void { const run_step = b.step("run", "Run the emulator"); run_step.dependOn(emulatorStep); run_step.dependOn(&run_cmd.step); - - const lib_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/engine.zig"), - .target = target, - .optimize = optimize, - }); - - const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); - - const exe_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); - - const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); - - const test_step = b.step("test", "Run unit tests"); - test_step.dependOn(&run_lib_unit_tests.step); - test_step.dependOn(&run_exe_unit_tests.step); } diff --git a/src/components/drive.c b/src/components/drive.c index 2a4ea23..5beed0b 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -1,5 +1,4 @@ #include "../neonucleus.h" -#include #include void nn_drive_destroy(void *_, nn_component *component, nn_drive *drive) { diff --git a/src/components/filesystem.c b/src/components/filesystem.c index 6f4a606..9e1afca 100644 --- a/src/components/filesystem.c +++ b/src/components/filesystem.c @@ -1,5 +1,4 @@ #include "../neonucleus.h" -#include #include void nn_fs_destroy(void *_, nn_component *component, nn_filesystem *fs) { diff --git a/src/components/gpu.c b/src/components/gpu.c index e1feb10..b815a47 100644 --- a/src/components/gpu.c +++ b/src/components/gpu.c @@ -1,7 +1,5 @@ #include "../neonucleus.h" #include "screen.h" -#include -#include typedef struct nni_gpu { nn_Alloc alloc; @@ -173,7 +171,7 @@ void nni_gpu_get(nni_gpu *gpu, void *_, nn_component *component, nn_computer *co void nni_gpu_getScreen(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) { if(gpu->screenAddress == NULL) return; - nn_return_string(computer, gpu->screenAddress, strlen(gpu->screenAddress)); + nn_return_string(computer, gpu->screenAddress, nn_strlen(gpu->screenAddress)); } void nni_gpu_maxResolution(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) { diff --git a/src/components/screen.c b/src/components/screen.c index 82c9733..72e28ac 100644 --- a/src/components/screen.c +++ b/src/components/screen.c @@ -1,6 +1,4 @@ #include "screen.h" -#include -#include nn_screen *nn_newScreen(nn_Context *context, int maxWidth, int maxHeight, int maxDepth, int editableColors, int paletteColors) { nn_Alloc *alloc = &context->allocator; @@ -20,7 +18,7 @@ nn_screen *nn_newScreen(nn_Context *context, int maxWidth, int maxHeight, int ma screen->editableColors = editableColors; screen->paletteColors = paletteColors; screen->palette = nn_alloc(alloc, sizeof(int) * screen->paletteColors); - memset(screen->palette, 0, sizeof(int) * screen->paletteColors); + nn_memset(screen->palette, 0, sizeof(int) * screen->paletteColors); screen->aspectRatioWidth = 1; screen->aspectRatioHeight = 1; screen->isOn = true; @@ -97,7 +95,7 @@ void nn_addKeyboard(nn_screen *screen, nn_address address) { void nn_removeKeyboard(nn_screen *screen, nn_address address) { size_t j = 0; for(size_t i = 0; i < screen->keyboardCount; i++) { - if(strcmp(screen->keyboards[i], address) == 0) { + if(nn_strcmp(screen->keyboards[i], address) == 0) { nn_deallocStr(&screen->ctx.allocator, screen->keyboards[i]); } else { screen->keyboards[j] = screen->keyboards[i]; @@ -217,7 +215,7 @@ void nn_screenComp_getKeyboards(nn_screen *screen, void *_, nn_component *compon size_t len = arr.array->len; for(size_t i = 0; i < len; i++) { - size_t addrlen = strlen(nn_getKeyboard(screen, i)); + size_t addrlen = nn_strlen(nn_getKeyboard(screen, i)); nn_value addr = nn_values_string(&screen->ctx.allocator, nn_getKeyboard(screen, i), addrlen); nn_values_set(arr, i, addr); } diff --git a/src/lock.c b/src/lock.c index ea4b1d4..7b336a7 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,5 +1,4 @@ #include "neonucleus.h" -#include #ifndef NN_BAREMETAL #include "tinycthread.h" diff --git a/src/neonucleus.h b/src/neonucleus.h index b86483a..53d0d84 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -149,7 +149,11 @@ typedef struct nn_Context { nn_Rng rng; } nn_Context; -// TODO: write a bunch of utils so this *can* work on baremetal. +// libc-like utils + +void nn_memset(void *buf, unsigned char byte, size_t len); +int nn_strcmp(const char *a, const char *b); +size_t nn_strlen(const char *a); #ifndef NN_BAREMETAL nn_Alloc nn_libcAllocator(); diff --git a/src/unicode.c b/src/unicode.c index 6161b48..dc5ac77 100644 --- a/src/unicode.c +++ b/src/unicode.c @@ -1,6 +1,4 @@ #include "neonucleus.h" -#include -#include #include // both tables copied from: https://github.com/MightyPirates/OpenComputers/blob/52da41b5e171b43fea80342dc75d808f97a0f797/src/main/scala/li/cil/oc/util/FontUtils.scala @@ -225,9 +223,6 @@ char *nn_unicode_char(nn_Alloc *alloc, unsigned int *codepoints, size_t codepoin j += codepointLen; } buf[j] = '\0'; - // this can only fail if size_t is smaller than a pointer and overflowed. - // IF THIS HAPPENS, THE SYSTEM HEADERS ARE BUGGED. - assert(j == len); return buf; } diff --git a/src/utils.c b/src/utils.c index a2c4572..ff0c4ef 100644 --- a/src/utils.c +++ b/src/utils.c @@ -204,3 +204,32 @@ int nn_mapColor(int color, int *palette, int paletteSize) { } return bestColor; } + +void nn_memset(void *buf, unsigned char byte, size_t len) { + unsigned char *bytes = buf; + for(size_t i = 0; i < len; i++) bytes[i] = byte; +} + +int nn_strcmp(const char *a, const char *b) { + size_t i = 0; + while(true) { + unsigned char ca = a[i]; + unsigned char cb = b[i]; + + if(ca < cb) { + return -1; + } + if(ca > cb) { + return -1; + } + if(ca == 0 && cb == 0) { // reached terminator + return 0; + } + } +} + +size_t nn_strlen(const char *a) { + size_t l = 0; + while(a[l]) l++; + return l; +}