diff --git a/demos/bunny/wasmmark/build.zig b/demos/bunny/wasmmark/build.zig index 4d425ae0..8b95316a 100644 --- a/demos/bunny/wasmmark/build.zig +++ b/demos/bunny/wasmmark/build.zig @@ -1,5 +1,8 @@ const std = @import("std"); +const tic80_reserved_memory = 96 * 1024; +const tic80_stack_size = 8 * 1024; + pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); const target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); @@ -13,14 +16,12 @@ pub fn build(b: *std.Build) !void { exe.rdynamic = true; exe.entry = .disabled; exe.import_memory = true; - exe.stack_size = 8192; + // TIC-80 reserves the first 96 KiB of linear memory, so reserve that space + // inside the stack region and leave 8 KiB of actual stack above it. + exe.stack_size = tic80_reserved_memory + tic80_stack_size; exe.initial_memory = 65536 * 4; exe.max_memory = 65536 * 4; exe.export_table = true; - // all the memory below 96kb is reserved for TIC and memory mapped I/O - // so our own usage must start above the 96kb mark - exe.global_base = 96 * 1024; - b.installArtifact(exe); } diff --git a/demos/wasm/build.zig b/demos/wasm/build.zig index 4d425ae0..8b95316a 100644 --- a/demos/wasm/build.zig +++ b/demos/wasm/build.zig @@ -1,5 +1,8 @@ const std = @import("std"); +const tic80_reserved_memory = 96 * 1024; +const tic80_stack_size = 8 * 1024; + pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); const target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); @@ -13,14 +16,12 @@ pub fn build(b: *std.Build) !void { exe.rdynamic = true; exe.entry = .disabled; exe.import_memory = true; - exe.stack_size = 8192; + // TIC-80 reserves the first 96 KiB of linear memory, so reserve that space + // inside the stack region and leave 8 KiB of actual stack above it. + exe.stack_size = tic80_reserved_memory + tic80_stack_size; exe.initial_memory = 65536 * 4; exe.max_memory = 65536 * 4; exe.export_table = true; - // all the memory below 96kb is reserved for TIC and memory mapped I/O - // so our own usage must start above the 96kb mark - exe.global_base = 96 * 1024; - b.installArtifact(exe); } diff --git a/templates/c/Makefile b/templates/c/Makefile index f941b1ec..49ea3727 100644 --- a/templates/c/Makefile +++ b/templates/c/Makefile @@ -21,8 +21,10 @@ else endif # Linker flags -LDFLAGS = -Wl,-zstack-size=8192,--no-entry,--import-memory -mexec-model=reactor \ - -Wl,--initial-memory=262144,--max-memory=262144,--global-base=98304 +# TIC-80 reserves the first 96 KiB of linear memory, so reserve that space +# inside the stack region and leave 8 KiB of actual stack above it. +LDFLAGS = -Wl,-zstack-size=106496,--stack-first,--no-entry,--import-memory -mexec-model=reactor \ + -Wl,--initial-memory=262144,--max-memory=262144 ifeq ($(DEBUG), 1) LDFLAGS += -Wl,--export-all,--no-gc-sections else diff --git a/templates/c/README.md b/templates/c/README.md index 32a00fd8..6680ab39 100644 --- a/templates/c/README.md +++ b/templates/c/README.md @@ -16,6 +16,8 @@ Define the environment variable WASI_SDK_PATH; e.g., if you installed WASI into ```$HOME/wasi-sdk```, then ```export WASI_SDK_PATH=$HOME/wasi-sdk```. +The default linker settings reserve TIC-80's first 96 KiB of linear memory by using a stack-first layout with `96 KiB + 8 KiB` of configured stack. + Edit ```src/main.c``` to implement your game. You are of course free to organize your code in more than one C source file. @@ -48,4 +50,4 @@ You can then run your cartridge as follows: The script ```buildcart.sh``` does the above steps as a convenience. ## Additional Notes -TIC-80 API functions that merely duplicate standard library functionality are not imported. Please use the `memcpy` and `memset` functions provided by the C standard library instead. \ No newline at end of file +TIC-80 API functions that merely duplicate standard library functionality are not imported. Please use the `memcpy` and `memset` functions provided by the C standard library instead. diff --git a/templates/d/README.md b/templates/d/README.md index d4d5c4d1..eae373f8 100644 --- a/templates/d/README.md +++ b/templates/d/README.md @@ -36,6 +36,8 @@ drwxr-xr-x 3 pierce pierce 4096 Apr 24 16:19 share/ Define the environment variable WASI_SDK_PATH; e.g., if you installed WASI libc into ```$HOME/wasi-sdk/share/wasi-sysroot```, then ```export WASI_SDK_PATH=$HOME/wasi-sdk```. +The default linker settings reserve TIC-80's first 96 KiB of linear memory by using a stack-first layout with `96 KiB + 8 KiB` of configured stack. + Edit ```src/main.d``` to implement your game. You are of course free to organize your code in more than one D source file. diff --git a/templates/d/dub.json b/templates/d/dub.json index eb1a3824..7c38b600 100644 --- a/templates/d/dub.json +++ b/templates/d/dub.json @@ -11,6 +11,10 @@ "--strip-all", "--allow-undefined", "--stack-first", + "-zstack-size=106496", + "--import-memory", + "--initial-memory=262144", + "--max-memory=262144", "--no-entry" ] }, @@ -25,6 +29,10 @@ "--strip-all", "--allow-undefined", "--stack-first", + "-zstack-size=106496", + "--import-memory", + "--initial-memory=262144", + "--max-memory=262144", "--no-entry", "$WASI_SDK_PATH/share/wasi-sysroot/lib/wasm32-wasi/libc.a" ] diff --git a/templates/nim/README.md b/templates/nim/README.md index f6052b5d..c7987ee1 100644 --- a/templates/nim/README.md +++ b/templates/nim/README.md @@ -3,6 +3,8 @@ This is a Nim / TIC-80 starter template. To build wasm binary and import it into the 'cart.tic' file, ensure you have a Nim compiler, Wasi-SDK and Tic-80 on your system and run: +The linker settings reserve TIC-80's first 96 KiB of linear memory by using a stack-first layout with `96 KiB + 8 KiB` of configured stack. + ``` nimble buildcart ``` diff --git a/templates/nim/config.nims b/templates/nim/config.nims index b45316f7..05950b92 100644 --- a/templates/nim/config.nims +++ b/templates/nim/config.nims @@ -34,7 +34,9 @@ switch("clang.linkerexe", wasi / "bin" / "clang") switch("passC", "--sysroot=" & (wasi / "share" / "wasi-sysroot")) -switch("passL", "-Wl,-zstack-size=8192,--no-entry,--import-memory -mexec-model=reactor -Wl,--initial-memory=262144,--max-memory=262144,--global-base=98304") +# TIC-80 reserves the first 96 KiB of linear memory, so reserve that space +# inside the stack region and leave 8 KiB of actual stack above it. +switch("passL", "-Wl,-zstack-size=106496,--stack-first,--no-entry,--import-memory -mexec-model=reactor -Wl,--initial-memory=262144,--max-memory=262144") when not defined(release): switch("assertions", "off") diff --git a/templates/rust/.cargo/config.toml b/templates/rust/.cargo/config.toml index d10ae703..6aa9e2f2 100644 --- a/templates/rust/.cargo/config.toml +++ b/templates/rust/.cargo/config.toml @@ -3,6 +3,9 @@ target = "wasm32-unknown-unknown" [target.wasm32-unknown-unknown] rustflags = [ + # TIC-80 reserves the first 96 KiB of linear memory, so reserve that space + # inside the stack region and leave 8 KiB of actual stack above it. + "-C", "link-arg=--stack-first", "-C", "link-arg=--import-memory", "-C", "link-arg=--initial-memory=262144", "-C", "link-arg=--max-memory=262144", diff --git a/templates/rust/README.md b/templates/rust/README.md index 8e36b0b4..d05b3615 100644 --- a/templates/rust/README.md +++ b/templates/rust/README.md @@ -3,6 +3,8 @@ ## Important Note Don't access TIC-80's I/O memory by dereferencing raw pointers. The optimiser will ruin attempts to do this, because Rust has no equivalent to C's `volatile` for direct access. Instead, use [`std::ptr::read_volatile`](https://doc.rust-lang.org/std/ptr/fn.read_volatile.html) and [`std::ptr::write_volatile`](https://doc.rust-lang.org/std/ptr/fn.write_volatile.html), or just use the standard TIC-80 `peek`/`poke`. +This template also reserves TIC-80's first 96 KiB of linear memory by forcing a stack-first layout and inflating the configured stack size to `96 KiB + 8 KiB`. + This is a Rust / TIC-80 starter template. Before using it, make sure you have installed the `wasm32-unknown-unknown` target using rustup: ``` rustup target add wasm32-unknown-unknown diff --git a/templates/zig/README.md b/templates/zig/README.md index cff70d73..95f25387 100644 --- a/templates/zig/README.md +++ b/templates/zig/README.md @@ -2,6 +2,8 @@ This is a ZIG / TIC-80 starter template. To build it, ensure you have the latest development release (`0.14.0-dev.1421+f87dd43c1` or newer), then run: +The build reserves TIC-80's first 96 KiB of linear memory by folding that space into the configured stack size and leaving 8 KiB of actual stack above it. + ``` zig build --release=small ``` diff --git a/templates/zig/build.zig b/templates/zig/build.zig index 4d425ae0..8b95316a 100644 --- a/templates/zig/build.zig +++ b/templates/zig/build.zig @@ -1,5 +1,8 @@ const std = @import("std"); +const tic80_reserved_memory = 96 * 1024; +const tic80_stack_size = 8 * 1024; + pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); const target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); @@ -13,14 +16,12 @@ pub fn build(b: *std.Build) !void { exe.rdynamic = true; exe.entry = .disabled; exe.import_memory = true; - exe.stack_size = 8192; + // TIC-80 reserves the first 96 KiB of linear memory, so reserve that space + // inside the stack region and leave 8 KiB of actual stack above it. + exe.stack_size = tic80_reserved_memory + tic80_stack_size; exe.initial_memory = 65536 * 4; exe.max_memory = 65536 * 4; exe.export_table = true; - // all the memory below 96kb is reserved for TIC and memory mapped I/O - // so our own usage must start above the 96kb mark - exe.global_base = 96 * 1024; - b.installArtifact(exe); }