From 9e53e5fd3801cb78551435940f21cf9f5fdc0778 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Fri, 29 May 2026 15:43:28 -0500 Subject: [PATCH] GNO Support --- .gitignore | 3 + demos/buildGno.sh | 59 ++ demos/gnoCat.bin | Bin 0 -> 18112 bytes demos/gnoCat.c | 15 + demos/gnoCat.map | 221 +++++ demos/gnoCat.o | Bin 0 -> 1576 bytes demos/gnoCat.omf | Bin 0 -> 38830 bytes demos/gnoCat.reloc | Bin 0 -> 2212 bytes demos/gnoFile.bin | Bin 0 -> 26146 bytes demos/gnoFile.c | 31 + demos/gnoFile.map | 269 ++++++ demos/gnoFile.o | Bin 0 -> 2320 bytes demos/gnoFile.omf | Bin 0 -> 40506 bytes demos/gnoFile.reloc | Bin 0 -> 3988 bytes demos/gnoFmt.bin | Bin 0 -> 17952 bytes demos/gnoFmt.c | 21 + demos/gnoFmt.map | 203 +++++ demos/gnoFmt.o | Bin 0 -> 1600 bytes demos/gnoFmt.omf | Bin 0 -> 39409 bytes demos/gnoFmt.reloc | Bin 0 -> 3184 bytes demos/gnoHello.bin | Bin 0 -> 16139 bytes demos/gnoHello.c | 14 + demos/gnoHello.map | 203 +++++ demos/gnoHello.o | Bin 0 -> 1600 bytes demos/gnoHello.omf | Bin 0 -> 38683 bytes demos/gnoHello.reloc | Bin 0 -> 1960 bytes demos/gnoStdin.bin | Bin 0 -> 8031 bytes demos/gnoStdin.c | 23 + demos/gnoStdin.map | 201 +++++ demos/gnoStdin.o | Bin 0 -> 2108 bytes demos/gnoStdin.omf | Bin 0 -> 38151 bytes demos/gnoStdin.reloc | Bin 0 -> 1048 bytes demos/helloBeep.bin | Bin 3153 -> 3046 bytes demos/helloBeep.map | 210 +++-- demos/helloBeep.omf | Bin 37408 -> 37394 bytes demos/helloBeep.reloc | Bin 544 -> 520 bytes demos/helloText.bin | Bin 4470 -> 4363 bytes demos/helloText.map | 274 +++--- demos/helloText.omf | Bin 37703 -> 37689 bytes demos/helloText.reloc | Bin 1036 -> 1012 bytes runtime/build.sh | 4 + runtime/include/gno/kernel.h | 48 + runtime/src/crt0.s | 26 +- runtime/src/crt0Gno.s | 141 +++ runtime/src/crt0Gsos.s | 143 +-- runtime/src/gnoGsos.s | 42 + runtime/src/gnoKernel.s | 852 ++++++++++++++++++ runtime/src/libc.c | 73 +- runtime/src/libcGno.c | 295 ++++++ runtime/src/snprintf.c | 3 - scripts/genGnoKernel.py | 236 +++++ scripts/runInGno.sh | 171 ++++ src/link816/link816.cpp | 61 +- .../lib/Target/W65816/W65816AsmPrinter.cpp | 29 +- .../Target/W65816/W65816StackSlotCleanup.cpp | 8 + 55 files changed, 3490 insertions(+), 389 deletions(-) create mode 100755 demos/buildGno.sh create mode 100644 demos/gnoCat.bin create mode 100644 demos/gnoCat.c create mode 100644 demos/gnoCat.map create mode 100644 demos/gnoCat.o create mode 100644 demos/gnoCat.omf create mode 100644 demos/gnoCat.reloc create mode 100644 demos/gnoFile.bin create mode 100644 demos/gnoFile.c create mode 100644 demos/gnoFile.map create mode 100644 demos/gnoFile.o create mode 100644 demos/gnoFile.omf create mode 100644 demos/gnoFile.reloc create mode 100644 demos/gnoFmt.bin create mode 100644 demos/gnoFmt.c create mode 100644 demos/gnoFmt.map create mode 100644 demos/gnoFmt.o create mode 100644 demos/gnoFmt.omf create mode 100644 demos/gnoFmt.reloc create mode 100644 demos/gnoHello.bin create mode 100644 demos/gnoHello.c create mode 100644 demos/gnoHello.map create mode 100644 demos/gnoHello.o create mode 100644 demos/gnoHello.omf create mode 100644 demos/gnoHello.reloc create mode 100644 demos/gnoStdin.bin create mode 100644 demos/gnoStdin.c create mode 100644 demos/gnoStdin.map create mode 100644 demos/gnoStdin.o create mode 100644 demos/gnoStdin.omf create mode 100644 demos/gnoStdin.reloc create mode 100644 runtime/include/gno/kernel.h create mode 100644 runtime/src/crt0Gno.s create mode 100644 runtime/src/gnoGsos.s create mode 100644 runtime/src/gnoKernel.s create mode 100644 runtime/src/libcGno.c create mode 100644 scripts/genGnoKernel.py create mode 100755 scripts/runInGno.sh diff --git a/.gitignore b/.gitignore index f6d5a10..41b833c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ tests/coremark/coreMark.bin *.swo .DS_Store *~ + +stuff/ +ROM Source Code.zip diff --git a/demos/buildGno.sh b/demos/buildGno.sh new file mode 100755 index 0000000..1f4e944 --- /dev/null +++ b/demos/buildGno.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# buildGno.sh — compile a C source into a GNO/ME-loadable OMF shell command. +# +# Usage: bash demos/buildGno.sh +# demos/.c -> demos/.omf +# +# Uses crt0Gno (GNO entry contract) + the GNO libc backend, then wraps +# the flat image in a relocatable ExpressLoad OMF via omfEmit — the +# GS/OS Loader (which GNO uses to launch commands) requires a real OMF, +# not a flat binary. + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +[ $# -ge 1 ] || { echo "usage: $0 " >&2; exit 2; } +BASE="$1" +SRC="$SCRIPT_DIR/$BASE.c" +[ -f "$SRC" ] || { echo "no source: $SRC" >&2; exit 2; } + +CLANG="$ROOT/tools/llvm-mos-build/bin/clang" +LINK="$ROOT/tools/link816" +OMF="$ROOT/tools/omfEmit" +RT="$ROOT/runtime" + +OBJ="$SCRIPT_DIR/$BASE.o" +BIN="$SCRIPT_DIR/$BASE.bin" +MAP="$SCRIPT_DIR/$BASE.map" +RELOC="$SCRIPT_DIR/$BASE.reloc" +OUT="$SCRIPT_DIR/$BASE.omf" + +echo "compile: $BASE.c -> $BASE.o" +"$CLANG" --target=w65816 -I"$RT/include" -O2 -ffunction-sections -c "$SRC" -o "$OBJ" + +echo "link: -> $BASE.bin" +"$LINK" -o "$BIN" --text-base 0x1000 --bss-base 0xA000 \ + --map "$MAP" --reloc-out "$RELOC" \ + "$RT/crt0Gno.o" "$OBJ" \ + "$RT/libcGno.o" "$RT/gnoKernel.o" "$RT/gnoGsos.o" \ + "$RT/libc.o" "$RT/snprintf.o" "$RT/extras.o" \ + "$RT/softFloat.o" "$RT/softDouble.o" \ + "$RT/libgcc.o" + +echo "OMF: -> $BASE.omf" +# Declare a dedicated DP/Stack (OMF KIND=0x1012) segment. Without it GNO +# falls back to a 4 KB default stack shared with DP and placed low in bank 0, +# which is too small / mis-placed for GS/OS file I/O: GNO's GS/OS interceptor +# (StackGSOS) carves its direct-page work area off the caller's S and the FST +# nests deep below it, corrupting the saved SP on certain stack-buffer layouts. +# A sized $12 segment makes the Loader allocate a larger bank-0 block (S set +# high in it), giving headroom and moving stack buffers off the collision. +# This is the idiomatic ORCA/GNO mechanism (== #pragma stacksize). +"$OMF" --input "$BIN" --map "$MAP" \ + --base 0x1000 --entry __start --output "$OUT" \ + --name "$(echo "$BASE" | tr '[:lower:]' '[:upper:]' | cut -c1-8)" \ + --expressload --relocs "$RELOC" --stack-size "${GNO_STACK_SIZE:-0x4000}" + +ls -la "$OUT" +echo "done: $OUT (run with: bash scripts/runInGno.sh $OUT --check 0x025000=C0DE)" diff --git a/demos/gnoCat.bin b/demos/gnoCat.bin new file mode 100644 index 0000000000000000000000000000000000000000..b1ffe9465429b8ea8778b94b720ba207d5b97bd5 GIT binary patch literal 18112 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 +#include + +int main(int argc, char **argv) { + char line[80]; + printf("Type a line:\n"); + if (fgets(line, sizeof(line), stdin)) + printf("You typed: %s", line); + else + printf("(EOF)\n"); + *(volatile uint16_t *)0x025000UL = 0xC0DE; + for (volatile unsigned long i = 0; i < 300000UL; i++) {} + return 0; +} diff --git a/demos/gnoCat.map b/demos/gnoCat.map new file mode 100644 index 0000000..4a0af32 --- /dev/null +++ b/demos/gnoCat.map @@ -0,0 +1,221 @@ +# section layout +.text : 0x001000 .. 0x0051f7 ( 16887 bytes) +.rodata : 0x0051f7 .. 0x0056c0 ( 1225 bytes) +.bss : 0x00a000 .. 0x00a182 ( 386 bytes) + +# per-input-file .text contributions + 113 /home/scott/claude/llvm816/runtime/crt0Gno.o + 458 /home/scott/claude/llvm816/demos/gnoCat.o + 3444 /home/scott/claude/llvm816/runtime/libcGno.o + 925 /home/scott/claude/llvm816/runtime/gnoKernel.o + 34 /home/scott/claude/llvm816/runtime/gnoGsos.o + 32141 /home/scott/claude/llvm816/runtime/libc.o + 9075 /home/scott/claude/llvm816/runtime/snprintf.o + 10814 /home/scott/claude/llvm816/runtime/extras.o + 4364 /home/scott/claude/llvm816/runtime/softFloat.o + 13051 /home/scott/claude/llvm816/runtime/softDouble.o + 2552 /home/scott/claude/llvm816/runtime/libgcc.o + +# global symbols (sorted by address) +0x000000 __bss_bank +0x000000 __bss_seg0_bank +0x000000 __bss_seg1_bank +0x000000 __bss_seg1_lo16 +0x000000 __bss_seg1_size +0x000000 __bss_seg2_bank +0x000000 __bss_seg2_lo16 +0x000000 __bss_seg2_size +0x000000 __bss_seg3_bank +0x000000 __bss_seg3_lo16 +0x000000 __bss_seg3_size +0x000182 __bss_seg0_size +0x000182 __bss_size +0x001000 __start +0x001000 __text_start +0x001071 main +0x00123b gsosRead +0x001251 __putByte +0x00139e __getByte +0x00153e __gnoStartup +0x0017e0 _exit +0x001811 __gnoGsosCall +0x001826 __gnoCallNum +0x001828 __gnoPBlock +0x001833 memset +0x001891 puts +0x00194b vprintf +0x00276e writeULong +0x0028e0 writeUDec +0x002a20 writeHex +0x002baf printf +0x002c34 fgetc +0x00306c fgets +0x003170 __adddf3 +0x003cfa __subdf3 +0x003d34 __muldf3 +0x0043b7 __floatsidf +0x004535 __floatunsidf +0x004654 __fixdfsi +0x0047ff __jsl_indir +0x004802 __mulhi3 +0x004821 __umulhisi3 +0x004878 __ashlhi3 +0x004887 __lshrhi3 +0x004897 __ashrhi3 +0x0048aa __udivhi3 +0x0048b6 __umodhi3 +0x0048c2 __divhi3 +0x0048dc __modhi3 +0x0048f6 __divmod_setup +0x004929 __udivmod_core +0x004947 __mulsi3 +0x004a00 __ashlsi3 +0x004a15 __lshrsi3 +0x004a2a __ashrsi3 +0x004a44 __udivmodsi_core +0x004a7c __udivsi3 +0x004a90 __umodsi3 +0x004aa4 __divsi3 +0x004acb __modsi3 +0x004af2 __divmodsi_setup +0x004b43 __divmoddi4_stash +0x004b60 __retdi +0x004b6d __ashldi3 +0x004b90 __lshrdi3 +0x004bb3 __ashrdi3 +0x004bd9 __muldi3 +0x004c40 __ucmpdi2 +0x004c69 __cmpdi2 +0x004ca0 __udivdi3 +0x004ca9 __umoddi3 +0x004cc2 __udivmoddi_core +0x004d0f __divdi3 +0x004d2e __moddi3 +0x004d5b __absdi_a +0x004d63 __absdi_b +0x004d6b __negdi_a +0x004d89 __negdi_b +0x004da7 setjmp +0x004dcf longjmp +0x004df9 __umulhisi3_qsq +0x0051f7 __rodata_start +0x0051f7 __text_end +0x005589 writeHex.digits +0x0055a4 __mfs +0x005684 stdin +0x005688 stdout +0x00568c stderr +0x005690 __c_lconv +0x0056c0 __init_array_end +0x0056c0 __init_array_start +0x0056c0 __rodata_end +0x00a000 __bss_lo16 +0x00a000 __bss_seg0_lo16 +0x00a000 __bss_start +0x00a000 argBuf +0x00a100 argVec +0x00a180 __indirTarget +0x00a182 __bss_end +0x00a182 __heap_start +0x00bf00 __heap_end +__absdi_a = 0x004d5b +__absdi_b = 0x004d63 +__adddf3 = 0x003170 +__ashldi3 = 0x004b6d +__ashlhi3 = 0x004878 +__ashlsi3 = 0x004a00 +__ashrdi3 = 0x004bb3 +__ashrhi3 = 0x004897 +__ashrsi3 = 0x004a2a +__bss_bank = 0x000000 +__bss_end = 0x00a182 +__bss_lo16 = 0x00a000 +__bss_seg0_bank = 0x000000 +__bss_seg0_lo16 = 0x00a000 +__bss_seg0_size = 0x000182 +__bss_seg1_bank = 0x000000 +__bss_seg1_lo16 = 0x000000 +__bss_seg1_size = 0x000000 +__bss_seg2_bank = 0x000000 +__bss_seg2_lo16 = 0x000000 +__bss_seg2_size = 0x000000 +__bss_seg3_bank = 0x000000 +__bss_seg3_lo16 = 0x000000 +__bss_seg3_size = 0x000000 +__bss_size = 0x000182 +__bss_start = 0x00a000 +__c_lconv = 0x005690 +__cmpdi2 = 0x004c69 +__divdi3 = 0x004d0f +__divhi3 = 0x0048c2 +__divmod_setup = 0x0048f6 +__divmoddi4_stash = 0x004b43 +__divmodsi_setup = 0x004af2 +__divsi3 = 0x004aa4 +__fixdfsi = 0x004654 +__floatsidf = 0x0043b7 +__floatunsidf = 0x004535 +__getByte = 0x00139e +__gnoCallNum = 0x001826 +__gnoGsosCall = 0x001811 +__gnoPBlock = 0x001828 +__gnoStartup = 0x00153e +__heap_end = 0x00bf00 +__heap_start = 0x00a182 +__indirTarget = 0x00a180 +__init_array_end = 0x0056c0 +__init_array_start = 0x0056c0 +__jsl_indir = 0x0047ff +__lshrdi3 = 0x004b90 +__lshrhi3 = 0x004887 +__lshrsi3 = 0x004a15 +__mfs = 0x0055a4 +__moddi3 = 0x004d2e +__modhi3 = 0x0048dc +__modsi3 = 0x004acb +__muldf3 = 0x003d34 +__muldi3 = 0x004bd9 +__mulhi3 = 0x004802 +__mulsi3 = 0x004947 +__negdi_a = 0x004d6b +__negdi_b = 0x004d89 +__putByte = 0x001251 +__retdi = 0x004b60 +__rodata_end = 0x0056c0 +__rodata_start = 0x0051f7 +__start = 0x001000 +__subdf3 = 0x003cfa +__text_end = 0x0051f7 +__text_start = 0x001000 +__ucmpdi2 = 0x004c40 +__udivdi3 = 0x004ca0 +__udivhi3 = 0x0048aa +__udivmod_core = 0x004929 +__udivmoddi_core = 0x004cc2 +__udivmodsi_core = 0x004a44 +__udivsi3 = 0x004a7c +__umoddi3 = 0x004ca9 +__umodhi3 = 0x0048b6 +__umodsi3 = 0x004a90 +__umulhisi3 = 0x004821 +__umulhisi3_qsq = 0x004df9 +_exit = 0x0017e0 +argBuf = 0x00a000 +argVec = 0x00a100 +fgetc = 0x002c34 +fgets = 0x00306c +gsosRead = 0x00123b +longjmp = 0x004dcf +main = 0x001071 +memset = 0x001833 +printf = 0x002baf +puts = 0x001891 +setjmp = 0x004da7 +stderr = 0x00568c +stdin = 0x005684 +stdout = 0x005688 +vprintf = 0x00194b +writeHex = 0x002a20 +writeHex.digits = 0x005589 +writeUDec = 0x0028e0 +writeULong = 0x00276e diff --git a/demos/gnoCat.o b/demos/gnoCat.o new file mode 100644 index 0000000000000000000000000000000000000000..8a86f9bf758a8c28af25005044aec57c9700bbed GIT binary patch literal 1576 zcma)6OK1~e5T5O3jkP|iw%AgosiIcYZ62nL)q^6fMbs92pa{z5(R4A%mgKM498_F- z5y657dlVPZ76kF2w^DjiFACmE@TR8--W2OM|L!&+cyPkx`{wokGrPmy9XdO#D9S2% zq5xTanG3k=h=g9+far4g<*~#!L0!)m7v_m}BlL>M*7z^zXd_PZ$ov?MJR>^RVIGw6 za=B~=AE?19{gmGQG*T-rm+w){nqOIZL}N`T?V%2{2}j}%lh2nfyBp?$(>+spF!L4k zDbbUP6P&3ynzY%lcR8Bf^{!$E-I7jO(kV;eRp%9)=BOVkkHKCOqPFS;KWMaODlh|7 zl_Aa1_Nev_M^Sf3$4eZF;pc8je>42eRi3o5UB4-G$d|gUw98i7y;eF*bfP$_$sM=} z+qs*qj#3-SQRPfqFw>^mOfB-DmVeJQyEapRXL3zuNm zE_W+`IB%8Kh|Za*fuo63EOI2$KRysm#*W5Q{qaOH9uG&;(L}_E^haZf0V5f~Wesw< z&JNIzwH;-*ieJ5`q|qVI@evEW4e{2x1m;~0c6)<8+F);j-Gpm41G!$++=MpvuY&?R zJ2rCveXB0$lOV1WxBA7Ok`)40cEK2zvitxq-y`P3XY)>P}rTMv}tFiq|H^{hoOS!28V6KJdmo z-X~vt+5-pIobUoW(F8y9W+?Z=v5im*$~93a%O4nA>kG$Nd2JYZhgiDtPVz35|9&1n r8|J<|L|(o4v6FDBXIJ_9dmQKI!ovNr_<33I`Xl(fSuf5dtgX<$MG6fq literal 0 HcmV?d00001 diff --git a/demos/gnoCat.omf b/demos/gnoCat.omf new file mode 100644 index 0000000000000000000000000000000000000000..09a08c3b4224ec460d13323f824a114d42b1cc6b GIT binary patch literal 38830 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 literal 0 HcmV?d00001 diff --git a/demos/gnoFile.c b/demos/gnoFile.c new file mode 100644 index 0000000..6f08eac --- /dev/null +++ b/demos/gnoFile.c @@ -0,0 +1,31 @@ +// gnoFile.c — buffered FILE* file I/O on GNO/ME. Writes a file, reopens +// it, reads it back, and verifies the content round-trips byte-for-byte. +// Proves fopen/fwrite/fread/fclose route to real GS/OS files via libc's +// FILE* layer + GNO's inline-form GS/OS dispatch. +#include +#include +#include + +int main(int argc, char **argv) { + const char *path = "llvm816.txt"; + const char *msg = "written by llvm816 under GNO"; + + FILE *f = fopen(path, "w"); + if (!f) { printf("fopen(w) failed\n"); return 1; } + fwrite(msg, 1, strlen(msg), f); + fclose(f); + + char buf[64]; + f = fopen(path, "r"); + if (!f) { printf("fopen(r) failed\n"); return 1; } + size_t n = fread(buf, 1, sizeof(buf) - 1, f); + fclose(f); + buf[n] = 0; + + int ok = (n == strlen(msg)) && (strcmp(buf, msg) == 0); + printf("read %d bytes, content %s\n", (int)n, ok ? "OK" : "MISMATCH"); + + *(volatile uint16_t *)0x025000UL = ok ? 0xC0DE : 0xBAD0; + for (volatile unsigned long i = 0; i < 400000UL; i++) {} + return 0; +} diff --git a/demos/gnoFile.map b/demos/gnoFile.map new file mode 100644 index 0000000..5ef7640 --- /dev/null +++ b/demos/gnoFile.map @@ -0,0 +1,269 @@ +# section layout +.text : 0x001000 .. 0x006f8a ( 24458 bytes) +.rodata : 0x006f8a .. 0x007622 ( 1688 bytes) +.bss : 0x00a000 .. 0x00a402 ( 1026 bytes) + +# per-input-file .text contributions + 113 /home/scott/claude/llvm816/runtime/crt0Gno.o + 737 /home/scott/claude/llvm816/demos/gnoFile.o + 3444 /home/scott/claude/llvm816/runtime/libcGno.o + 925 /home/scott/claude/llvm816/runtime/gnoKernel.o + 34 /home/scott/claude/llvm816/runtime/gnoGsos.o + 32139 /home/scott/claude/llvm816/runtime/libc.o + 9073 /home/scott/claude/llvm816/runtime/snprintf.o + 10814 /home/scott/claude/llvm816/runtime/extras.o + 4364 /home/scott/claude/llvm816/runtime/softFloat.o + 13051 /home/scott/claude/llvm816/runtime/softDouble.o + 2552 /home/scott/claude/llvm816/runtime/libgcc.o + +# global symbols (sorted by address) +0x000000 __bss_bank +0x000000 __bss_seg0_bank +0x000000 __bss_seg1_bank +0x000000 __bss_seg1_lo16 +0x000000 __bss_seg1_size +0x000000 __bss_seg2_bank +0x000000 __bss_seg2_lo16 +0x000000 __bss_seg2_size +0x000000 __bss_seg3_bank +0x000000 __bss_seg3_lo16 +0x000000 __bss_seg3_size +0x000402 __bss_seg0_size +0x000402 __bss_size +0x001000 __start +0x001000 __text_start +0x001071 main +0x001352 gsosCreate +0x001368 gsosOpen +0x00137e gsosRead +0x001394 gsosWrite +0x0013aa gsosClose +0x0013c0 gsosGetEOF +0x0013d6 gsosSetEOF +0x0013ec gsosSetMark +0x001402 __putByte +0x00154f __putByteErr +0x00169c __gnoStartup +0x00193e _exit +0x00196f __gnoGsosCall +0x001984 __gnoCallNum +0x001986 __gnoPBlock +0x001991 memset +0x0019ef memcmp +0x001a9c puts +0x001b56 vprintf +0x002977 writeULong +0x002ae9 writeUDec +0x002c29 writeHex +0x002db8 printf +0x002e3d putcharStd +0x002e83 fclose +0x0030d3 fwrite +0x00389a fopen +0x00489c fread +0x004f03 __adddf3 +0x005a8d __subdf3 +0x005ac7 __muldf3 +0x00614a __floatsidf +0x0062c8 __floatunsidf +0x0063e7 __fixdfsi +0x006592 __jsl_indir +0x006595 __mulhi3 +0x0065b4 __umulhisi3 +0x00660b __ashlhi3 +0x00661a __lshrhi3 +0x00662a __ashrhi3 +0x00663d __udivhi3 +0x006649 __umodhi3 +0x006655 __divhi3 +0x00666f __modhi3 +0x006689 __divmod_setup +0x0066bc __udivmod_core +0x0066da __mulsi3 +0x006793 __ashlsi3 +0x0067a8 __lshrsi3 +0x0067bd __ashrsi3 +0x0067d7 __udivmodsi_core +0x00680f __udivsi3 +0x006823 __umodsi3 +0x006837 __divsi3 +0x00685e __modsi3 +0x006885 __divmodsi_setup +0x0068d6 __divmoddi4_stash +0x0068f3 __retdi +0x006900 __ashldi3 +0x006923 __lshrdi3 +0x006946 __ashrdi3 +0x00696c __muldi3 +0x0069d3 __ucmpdi2 +0x0069fc __cmpdi2 +0x006a33 __udivdi3 +0x006a3c __umoddi3 +0x006a55 __udivmoddi_core +0x006aa2 __divdi3 +0x006ac1 __moddi3 +0x006aee __absdi_a +0x006af6 __absdi_b +0x006afe __negdi_a +0x006b1c __negdi_b +0x006b3a setjmp +0x006b62 longjmp +0x006b8c __umulhisi3_qsq +0x006f8a __rodata_start +0x006f8a __text_end +0x00736f writeHex.digits +0x00738a __monthDays +0x007506 __mfs +0x0075e6 stdin +0x0075ea stdout +0x0075ee stderr +0x0075f2 __c_lconv +0x007622 __init_array_end +0x007622 __init_array_start +0x007622 __rodata_end +0x00a000 __bss_lo16 +0x00a000 __bss_seg0_lo16 +0x00a000 __bss_start +0x00a000 argBuf +0x00a100 argVec +0x00a180 freeList +0x00a184 bumpPtr +0x00a188 heapEnd +0x00a18c __atexitFn +0x00a190 errno +0x00a192 __toolboxInited +0x00a194 __vblPrev +0x00a196 __vblBase +0x00a19a __mfsReg +0x00a2ba __quickFn +0x00a2be __gsosPathBuf +0x00a3c0 __sigHandlers +0x00a400 __indirTarget +0x00a402 __bss_end +0x00a402 __heap_start +0x00bf00 __heap_end +__absdi_a = 0x006aee +__absdi_b = 0x006af6 +__adddf3 = 0x004f03 +__ashldi3 = 0x006900 +__ashlhi3 = 0x00660b +__ashlsi3 = 0x006793 +__ashrdi3 = 0x006946 +__ashrhi3 = 0x00662a +__ashrsi3 = 0x0067bd +__atexitFn = 0x00a18c +__bss_bank = 0x000000 +__bss_end = 0x00a402 +__bss_lo16 = 0x00a000 +__bss_seg0_bank = 0x000000 +__bss_seg0_lo16 = 0x00a000 +__bss_seg0_size = 0x000402 +__bss_seg1_bank = 0x000000 +__bss_seg1_lo16 = 0x000000 +__bss_seg1_size = 0x000000 +__bss_seg2_bank = 0x000000 +__bss_seg2_lo16 = 0x000000 +__bss_seg2_size = 0x000000 +__bss_seg3_bank = 0x000000 +__bss_seg3_lo16 = 0x000000 +__bss_seg3_size = 0x000000 +__bss_size = 0x000402 +__bss_start = 0x00a000 +__c_lconv = 0x0075f2 +__cmpdi2 = 0x0069fc +__divdi3 = 0x006aa2 +__divhi3 = 0x006655 +__divmod_setup = 0x006689 +__divmoddi4_stash = 0x0068d6 +__divmodsi_setup = 0x006885 +__divsi3 = 0x006837 +__fixdfsi = 0x0063e7 +__floatsidf = 0x00614a +__floatunsidf = 0x0062c8 +__gnoCallNum = 0x001984 +__gnoGsosCall = 0x00196f +__gnoPBlock = 0x001986 +__gnoStartup = 0x00169c +__gsosPathBuf = 0x00a2be +__heap_end = 0x00bf00 +__heap_start = 0x00a402 +__indirTarget = 0x00a400 +__init_array_end = 0x007622 +__init_array_start = 0x007622 +__jsl_indir = 0x006592 +__lshrdi3 = 0x006923 +__lshrhi3 = 0x00661a +__lshrsi3 = 0x0067a8 +__mfs = 0x007506 +__mfsReg = 0x00a19a +__moddi3 = 0x006ac1 +__modhi3 = 0x00666f +__modsi3 = 0x00685e +__monthDays = 0x00738a +__muldf3 = 0x005ac7 +__muldi3 = 0x00696c +__mulhi3 = 0x006595 +__mulsi3 = 0x0066da +__negdi_a = 0x006afe +__negdi_b = 0x006b1c +__putByte = 0x001402 +__putByteErr = 0x00154f +__quickFn = 0x00a2ba +__retdi = 0x0068f3 +__rodata_end = 0x007622 +__rodata_start = 0x006f8a +__sigHandlers = 0x00a3c0 +__start = 0x001000 +__subdf3 = 0x005a8d +__text_end = 0x006f8a +__text_start = 0x001000 +__toolboxInited = 0x00a192 +__ucmpdi2 = 0x0069d3 +__udivdi3 = 0x006a33 +__udivhi3 = 0x00663d +__udivmod_core = 0x0066bc +__udivmoddi_core = 0x006a55 +__udivmodsi_core = 0x0067d7 +__udivsi3 = 0x00680f +__umoddi3 = 0x006a3c +__umodhi3 = 0x006649 +__umodsi3 = 0x006823 +__umulhisi3 = 0x0065b4 +__umulhisi3_qsq = 0x006b8c +__vblBase = 0x00a196 +__vblPrev = 0x00a194 +_exit = 0x00193e +argBuf = 0x00a000 +argVec = 0x00a100 +bumpPtr = 0x00a184 +errno = 0x00a190 +fclose = 0x002e83 +fopen = 0x00389a +fread = 0x00489c +freeList = 0x00a180 +fwrite = 0x0030d3 +gsosClose = 0x0013aa +gsosCreate = 0x001352 +gsosGetEOF = 0x0013c0 +gsosOpen = 0x001368 +gsosRead = 0x00137e +gsosSetEOF = 0x0013d6 +gsosSetMark = 0x0013ec +gsosWrite = 0x001394 +heapEnd = 0x00a188 +longjmp = 0x006b62 +main = 0x001071 +memcmp = 0x0019ef +memset = 0x001991 +printf = 0x002db8 +putcharStd = 0x002e3d +puts = 0x001a9c +setjmp = 0x006b3a +stderr = 0x0075ee +stdin = 0x0075e6 +stdout = 0x0075ea +vprintf = 0x001b56 +writeHex = 0x002c29 +writeHex.digits = 0x00736f +writeUDec = 0x002ae9 +writeULong = 0x002977 diff --git a/demos/gnoFile.o b/demos/gnoFile.o new file mode 100644 index 0000000000000000000000000000000000000000..d6204bab82c8edf07839564e0e4c2dafa067f078 GIT binary patch literal 2320 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 literal 0 HcmV?d00001 diff --git a/demos/gnoFile.reloc b/demos/gnoFile.reloc new file mode 100644 index 0000000000000000000000000000000000000000..34843319420a484a8b23db8ab9c3ca4a0480ea9e GIT binary patch literal 3988 zcmYk;e@s?Y7zgmv`x+WLB~45uG^m!~53&YGf&|S887Kw>O+ZLYXNux<%LNV%#fbry ze=w#?jYt|A1~OBY_^V-&k>SRWE&m{Kg&QR`NY?l4JZI<2xH})d?{lAf?mhQj-W882 z6{_%4sgwu9d~BXijAP*70^>OH3Rp?aO0YUjDKEzNu+{n)Z-Qf=FfNAA=9oTv;RE7* zaLtRRrWrmWc`N+O9Ft#%_XHVt!p%~13$}f3!?uqP&ZjoY)Ca(J-|evNzZ-rab2|+G zDm{0e2m;o zzCr$t{0}+)ao7K2tcg8V18moN_IT$ca<6ukS+D*H&S99Z&BNiX_!Eaz8(`ai8(fA> z-%C3%?icUExK|u75ucAUH6dc%XFlc8l=o78kMi|XT%Vm{-6zdYsonXee>-fCbwjLc zI-YcSk67oGQ(gWA`J7nSWKMH68^k&vp?vyNuI72Mu31R#fOpO`*YHpH_tnOul>1J1 zeP)PtpG3GP-PGs8Nvn+az!gcxN8#^NjW5C1CBFmPV-3R>GfYj1zfzHJ8-EICi-Tvl zd^=o)b<}fcg6*~K6zhEL(@G5ln3@or-`qgs6xg0`0c>l$sGTCmnhD$Us)cR;Rz-cB(dK?)ofpDe^6?oQh3DIzdj)LkzZC2G zg?Lw`;~v#cgj4Vw>U}fCI$sCdeK(7BzIe7$rvUAUXWcdN3wGDUKLoE{so4eF>*n{I zQZeYI_ni~wu0tr?P-W&22iJ%<&QmIDoyoV7OW_@omy>JYYRNw%pN1PHZy{fSJ0$NS z_blGTSRI$|D zgzb7QUFz=79&%2c%P*5Zd<~PzG;L&W0~TwV&>d|;VUhvohsx7_vI58M1iqH_}7 z4K{Dk?+MHa(^d~)`y3U&;XH4JQk!HB8RQ9Xy8LtU>SVWXA#9ITNv@-s|Hv~_T>WBl z3T)?gl3a!_CAR`>s!Q^^@=pw)t7u_L=yW%l+|=vDf)9Y`+U#g%7@C z?voz!>*-2ez^3o{mE?4|T=GoH3n?$6d=}Qz_75iq;@x>0f9w9?!kxuurb>c{oVi21kk8;pO6MaIUxm zE)sXb72+=Vq_`Vy5%<6y;y(C}_%1vq?uRF>HS@U-2Z;yaCD^=5sUeJ^k`Kf2;t@Dm zJO<~AJ@4Xwnb-#|5&Oc2#FOD;;;HaOu|NE?H~@Yq4uZ$!nfV06)5I^pVd79YO1uD0 z7B7O=h$G+);%NAQI2N|&8xPk@zKrrD_*==7;alQV_?|eO>a)n%xs+T+K0rQ1t|lKL*N~5rkCW@jr^t=uCUOh;Jh_eBPQFI&Aa|0x$lc@~av%9F zxu1NWJV+iQ50gj8V`LA$kNDzw@Z#C&hkdYV-^Um%9>f?c9>Ta!>WATS@d$a0>?v?H OK4f3=Wb#z9Kly(b^XW1G literal 0 HcmV?d00001 diff --git a/demos/gnoFmt.bin b/demos/gnoFmt.bin new file mode 100644 index 0000000000000000000000000000000000000000..016fc5f32ca5f400af7b5e2d7b47c7683812ab43 GIT binary patch literal 17952 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 literal 0 HcmV?d00001 diff --git a/demos/gnoFmt.c b/demos/gnoFmt.c new file mode 100644 index 0000000..ea30c7d --- /dev/null +++ b/demos/gnoFmt.c @@ -0,0 +1,21 @@ +// gnoFmt.c — snprintf format checks (stack %s was the bug). +// m0 = "%s" of stack str -> 0x4241 ("AB") +// m1 = "%s" of literal -> 0x5857 ("WX") +// m2 = "%ld" of 42L -> 0x3234 ("42") (original slot-alias case) +// m3 = "%d" of 1234 -> 0x3231 ("12") +#include +#include +static uint16_t two(const char *s) { return (uint16_t)((uint8_t)s[0] | ((uint8_t)s[1] << 8)); } +int main(int argc, char **argv) { + char s[8]; s[0]='A'; s[1]='B'; s[2]='C'; s[3]='D'; s[4]=0; + char o0[16]; snprintf(o0, sizeof o0, "%s", s); + char o1[16]; snprintf(o1, sizeof o1, "%s", "WXYZ"); + char o2[16]; snprintf(o2, sizeof o2, "%ld", 42L); + char o3[16]; snprintf(o3, sizeof o3, "%d", 1234); + *(volatile uint16_t *)0x025000UL = two(o0); + *(volatile uint16_t *)0x025002UL = two(o1); + *(volatile uint16_t *)0x025004UL = two(o2); + *(volatile uint16_t *)0x025006UL = two(o3); + for (volatile unsigned long i = 0; i < 300000UL; i++) {} + return 0; +} diff --git a/demos/gnoFmt.map b/demos/gnoFmt.map new file mode 100644 index 0000000..63ff30e --- /dev/null +++ b/demos/gnoFmt.map @@ -0,0 +1,203 @@ +# section layout +.text : 0x001000 .. 0x0055fe ( 17918 bytes) +.rodata : 0x0055fe .. 0x005620 ( 34 bytes) +.bss : 0x00a000 .. 0x00a18e ( 398 bytes) + +# per-input-file .text contributions + 113 /home/scott/claude/llvm816/runtime/crt0Gno.o + 628 /home/scott/claude/llvm816/demos/gnoFmt.o + 3444 /home/scott/claude/llvm816/runtime/libcGno.o + 925 /home/scott/claude/llvm816/runtime/gnoKernel.o + 34 /home/scott/claude/llvm816/runtime/gnoGsos.o + 32173 /home/scott/claude/llvm816/runtime/libc.o + 9075 /home/scott/claude/llvm816/runtime/snprintf.o + 10814 /home/scott/claude/llvm816/runtime/extras.o + 4364 /home/scott/claude/llvm816/runtime/softFloat.o + 13051 /home/scott/claude/llvm816/runtime/softDouble.o + 2552 /home/scott/claude/llvm816/runtime/libgcc.o + +# global symbols (sorted by address) +0x000000 __bss_bank +0x000000 __bss_seg0_bank +0x000000 __bss_seg1_bank +0x000000 __bss_seg1_lo16 +0x000000 __bss_seg1_size +0x000000 __bss_seg2_bank +0x000000 __bss_seg2_lo16 +0x000000 __bss_seg2_size +0x000000 __bss_seg3_bank +0x000000 __bss_seg3_lo16 +0x000000 __bss_seg3_size +0x00018e __bss_seg0_size +0x00018e __bss_size +0x001000 __start +0x001000 __text_start +0x001071 main +0x0012e5 __gnoStartup +0x001587 _exit +0x0015b8 __gnoGsosCall +0x0015cd __gnoCallNum +0x0015cf __gnoPBlock +0x0015da memset +0x001638 snprintf +0x001788 format +0x002f1d emitULong +0x0031f0 emitUDec +0x00348a emitHex +0x0036f5 __adddf3 +0x00427f __subdf3 +0x0042b9 __muldf3 +0x00493c __floatunsidf +0x004a5b __fixdfsi +0x004c06 __jsl_indir +0x004c09 __mulhi3 +0x004c28 __umulhisi3 +0x004c7f __ashlhi3 +0x004c8e __lshrhi3 +0x004c9e __ashrhi3 +0x004cb1 __udivhi3 +0x004cbd __umodhi3 +0x004cc9 __divhi3 +0x004ce3 __modhi3 +0x004cfd __divmod_setup +0x004d30 __udivmod_core +0x004d4e __mulsi3 +0x004e07 __ashlsi3 +0x004e1c __lshrsi3 +0x004e31 __ashrsi3 +0x004e4b __udivmodsi_core +0x004e83 __udivsi3 +0x004e97 __umodsi3 +0x004eab __divsi3 +0x004ed2 __modsi3 +0x004ef9 __divmodsi_setup +0x004f4a __divmoddi4_stash +0x004f67 __retdi +0x004f74 __ashldi3 +0x004f97 __lshrdi3 +0x004fba __ashrdi3 +0x004fe0 __muldi3 +0x005047 __ucmpdi2 +0x005070 __cmpdi2 +0x0050a7 __udivdi3 +0x0050b0 __umoddi3 +0x0050c9 __udivmoddi_core +0x005116 __divdi3 +0x005135 __moddi3 +0x005162 __absdi_a +0x00516a __absdi_b +0x005172 __negdi_a +0x005190 __negdi_b +0x0051ae setjmp +0x0051d6 longjmp +0x005200 __umulhisi3_qsq +0x0055fe __rodata_start +0x0055fe __text_end +0x005608 emitHex.digits +0x005620 __init_array_end +0x005620 __init_array_start +0x005620 __rodata_end +0x00a000 __bss_lo16 +0x00a000 __bss_seg0_lo16 +0x00a000 __bss_start +0x00a000 argBuf +0x00a100 argVec +0x00a180 gCur +0x00a184 gEnd +0x00a188 gTotal +0x00a18c __indirTarget +0x00a18e __bss_end +0x00a18e __heap_start +0x00bf00 __heap_end +__absdi_a = 0x005162 +__absdi_b = 0x00516a +__adddf3 = 0x0036f5 +__ashldi3 = 0x004f74 +__ashlhi3 = 0x004c7f +__ashlsi3 = 0x004e07 +__ashrdi3 = 0x004fba +__ashrhi3 = 0x004c9e +__ashrsi3 = 0x004e31 +__bss_bank = 0x000000 +__bss_end = 0x00a18e +__bss_lo16 = 0x00a000 +__bss_seg0_bank = 0x000000 +__bss_seg0_lo16 = 0x00a000 +__bss_seg0_size = 0x00018e +__bss_seg1_bank = 0x000000 +__bss_seg1_lo16 = 0x000000 +__bss_seg1_size = 0x000000 +__bss_seg2_bank = 0x000000 +__bss_seg2_lo16 = 0x000000 +__bss_seg2_size = 0x000000 +__bss_seg3_bank = 0x000000 +__bss_seg3_lo16 = 0x000000 +__bss_seg3_size = 0x000000 +__bss_size = 0x00018e +__bss_start = 0x00a000 +__cmpdi2 = 0x005070 +__divdi3 = 0x005116 +__divhi3 = 0x004cc9 +__divmod_setup = 0x004cfd +__divmoddi4_stash = 0x004f4a +__divmodsi_setup = 0x004ef9 +__divsi3 = 0x004eab +__fixdfsi = 0x004a5b +__floatunsidf = 0x00493c +__gnoCallNum = 0x0015cd +__gnoGsosCall = 0x0015b8 +__gnoPBlock = 0x0015cf +__gnoStartup = 0x0012e5 +__heap_end = 0x00bf00 +__heap_start = 0x00a18e +__indirTarget = 0x00a18c +__init_array_end = 0x005620 +__init_array_start = 0x005620 +__jsl_indir = 0x004c06 +__lshrdi3 = 0x004f97 +__lshrhi3 = 0x004c8e +__lshrsi3 = 0x004e1c +__moddi3 = 0x005135 +__modhi3 = 0x004ce3 +__modsi3 = 0x004ed2 +__muldf3 = 0x0042b9 +__muldi3 = 0x004fe0 +__mulhi3 = 0x004c09 +__mulsi3 = 0x004d4e +__negdi_a = 0x005172 +__negdi_b = 0x005190 +__retdi = 0x004f67 +__rodata_end = 0x005620 +__rodata_start = 0x0055fe +__start = 0x001000 +__subdf3 = 0x00427f +__text_end = 0x0055fe +__text_start = 0x001000 +__ucmpdi2 = 0x005047 +__udivdi3 = 0x0050a7 +__udivhi3 = 0x004cb1 +__udivmod_core = 0x004d30 +__udivmoddi_core = 0x0050c9 +__udivmodsi_core = 0x004e4b +__udivsi3 = 0x004e83 +__umoddi3 = 0x0050b0 +__umodhi3 = 0x004cbd +__umodsi3 = 0x004e97 +__umulhisi3 = 0x004c28 +__umulhisi3_qsq = 0x005200 +_exit = 0x001587 +argBuf = 0x00a000 +argVec = 0x00a100 +emitHex = 0x00348a +emitHex.digits = 0x005608 +emitUDec = 0x0031f0 +emitULong = 0x002f1d +format = 0x001788 +gCur = 0x00a180 +gEnd = 0x00a184 +gTotal = 0x00a188 +longjmp = 0x0051d6 +main = 0x001071 +memset = 0x0015da +setjmp = 0x0051ae +snprintf = 0x001638 diff --git a/demos/gnoFmt.o b/demos/gnoFmt.o new file mode 100644 index 0000000000000000000000000000000000000000..ac755bd9b3bbd0a33316b1b1b8bff925e8130ad2 GIT binary patch literal 1600 zcma)6-Afcv6hE`G)1nrAAu1AX$zm4Hex+_nVPEQll@U=7fzE!UWBXydQ)CcDlMoRU z6d659gW~oSzSK(+zWEmY1&eRJ74&YubLY-Fh!36JGv{}I=XdX%bMMSNzBoFhD9R>D zQxMrb`y6!92@#G`BeH9;fz+>QY9DAdGi3Kvi9R_!bF~+98`bj{76LS1b2G=0vAe5h z&n-}$>k{fNS534Kq>b==Z7n>4DLEQhTpjsKgnxA(jeH~mJ5EP%?}x%TcZ_xrUGa;4 z26s@L-cn%ED7BgavO}oGM3EY(Yh*`6aS>4*YW`AtMPq^Ljhn9mV*x16liev4okD?h zQ1D5z4-5XV$L|t+l5=GfAC-%+-ja#YdNUi7qQtEVQhP}9ymy{`8Z}j@?>wOuQ!$M?Tsa}iB#N(_a&04ej^?4 z#)G%bhJE88{i(kiC-eVmG}eVqQt9+-y~i_yo7l?_bU9B#1n{966X=8;Tn7e`mzs` zZsi_W#G75n6#>e*ydgNfV3Z+YO(9^PB{nZ5eAdx=>s>$Ij=>F$QN_ zfv(^}arJazj2L^?;cp(Km*aKR(M{fpCvX~+4RU>Kp6({FuRRK5y$PA;DeT)>e^#CDh9rDQ`?ET|!7BQo341@Iv12Gqbzd;HAEA-`_vK z&+bfd*l0XwNB*3D;fyKMFQqC=drT73 zMBhI_C5w#D?w{aO8n}JT1HWZ#-2+<~Ykc4Z#-=^Hea!L)USzD9u{mAY(-vv3*S)bl zd;6HK?5ElK!2KJxm~Ljh4aceJ>Fmn`*_Uq_x+<`qv8{po?%mLt6Mq5wq8EP}4s9Rv zJSMGv9+S2#$~iQI<=mCd8cuB=Q&INOVrH+%tgmHi0hVdu1zMm{>uR1jX?+}98<0I- z^r)WZs`D^+xGi5$=SynF)*D$@_S(Sq>}m{I$g1_%tB;+!>=<}YVbxDFhSqs3r)(&@ zP5eQ}u~CeO43`fenh{OZZX^oRK#B?d6qvM-W!A?r)eLUx!K4XImoPO?FqbEo1J5r9 z9$**6HP5=@fw+s}KrxZ2Zb9J|6zDdJ_F|^GM7t~89xvJpnd%hn&hU2E2Dn)Za1)Rs zNVr*baFc3(IiQ*aQ>snS+d}iGO0xmXaiuNr5T3Ru=v5VNZZok+)qtvz1x?gt;wHDE zW^jX&5zIuxCQJ%Bty?16Eoip{d&NQncOPa->{(SLE9ruj^bjkV_29(7m3rbp5~R_R zsoc=NDXxe;S+S?&{yim$iITp3Pfd|M8EH?lD);19d{g>p4U_MjzU^Z+LFq)#GzH(9cIc5rjo%Fwm99ulYJfr!XywTi{-%uF@sI`F?D+j9>}_c zcrdEX!h-L$WwYS!Hbzs#8^B9qA_iDKM)y?lM|JUJ#YJuC0XQ2}Cr`?(bz+&

@f% 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 C8faPo literal 0 HcmV?d00001 diff --git a/demos/gnoFmt.reloc b/demos/gnoFmt.reloc new file mode 100644 index 0000000000000000000000000000000000000000..c6e367904a258e1f91d8037c22cc185fc2d1f59b GIT binary patch literal 3184 zcmYk;Z%md|7{~FWq$rh|X#^nsHFcq=Kf(r8g$~Vr++~|d_wV{j`;fr+CjL0Re zfo-PEjTcUASc47CX-#y-Vx~++wwAWEwX*dhEZeNU_s;q4TyAIgXP3Woo$I;p=MPgS zIJdy@ufw^CT*_JRz3;so7uI{%7_Y&5LgqO+MP2-{61ie4iij z(#gI)jwgivnarVjHl7sfDO3M588FPbH8~{s1LKmrsE66gIbUuzZo%96uVmY2cz~7o zbFLRy$uXz7UJM@OIvo5gv+oN1kK(t2&*9eKZ}INn-*8*7%XF?icn5A{CFkDYs{F55 zJqxGAd4uH-(=ioGW}Th^Q6gKGMV-VV*kBZGh8*kWiq+h zafSk{8On|8OlCdS{2Q?PA2vQ^GIJk{{Zm-|Yq9oj!0P#q$$X4;e^%tg%v!9y2aWqo zW(;fZ_gLrNG|tG4nLPZ*!~Xr*g*DH9th0VG{?BBJ9*TWRvCgV8UTZQhVD;aO)&H3B zIg?qC7yDOY^#X4&UYlac5bH}jGZQ=JsnLSv02eC3&u=ZA##{2)Z@$>Uzz2CSoX>x0Ha_zr6#+lEd3CsY5~)c4Xu{kx4jc!sN4NuO@x zqxg2H_nP{MsgIiaHJ;TfR?=rhP4sr-!^S=MD^`;K)YSV-J-ascDaH+~BtMVqtHCL* j>QjN6LVXEW%~ON5_i3!X^;mm1VeQ>w+=x3^$+`an|LKf> literal 0 HcmV?d00001 diff --git a/demos/gnoHello.bin b/demos/gnoHello.bin new file mode 100644 index 0000000000000000000000000000000000000000..c2c0d962f2f63242382ee99c2dff8034d8011410 GIT binary patch literal 16139 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 Ut#|nY!F6!a&F$@OHjlCY28CQ}O8@`> literal 0 HcmV?d00001 diff --git a/demos/gnoHello.c b/demos/gnoHello.c new file mode 100644 index 0000000..d73d05f --- /dev/null +++ b/demos/gnoHello.c @@ -0,0 +1,14 @@ +// gnoHello.c — GNO/ME shell command demo: prints a greeting + formatted +// output via standard stdio (libc printf/puts over the GNO console). +#include +#include + +int main(int argc, char **argv) { + puts("Hello from llvm816 on GNO/ME!"); + printf("argc=%d argv0=%s\n", argc, (argc > 0 && argv) ? argv[0] : "(none)"); + printf("sum 1..10 = %d, hex = %x\n", 55, 0xC0DE); + + *(volatile uint16_t *)0x025000UL = 0xC0DE; // harness marker + for (volatile unsigned long i = 0; i < 600000UL; i++) {} + return 0; +} diff --git a/demos/gnoHello.map b/demos/gnoHello.map new file mode 100644 index 0000000..aa80ff1 --- /dev/null +++ b/demos/gnoHello.map @@ -0,0 +1,203 @@ +# section layout +.text : 0x001000 .. 0x004b2e ( 15150 bytes) +.rodata : 0x004b2e .. 0x004f0b ( 989 bytes) +.bss : 0x00a000 .. 0x00a182 ( 386 bytes) + +# per-input-file .text contributions + 113 /home/scott/claude/llvm816/runtime/crt0Gno.o + 501 /home/scott/claude/llvm816/demos/gnoHello.o + 3444 /home/scott/claude/llvm816/runtime/libcGno.o + 925 /home/scott/claude/llvm816/runtime/gnoKernel.o + 34 /home/scott/claude/llvm816/runtime/gnoGsos.o + 32139 /home/scott/claude/llvm816/runtime/libc.o + 9073 /home/scott/claude/llvm816/runtime/snprintf.o + 10814 /home/scott/claude/llvm816/runtime/extras.o + 4364 /home/scott/claude/llvm816/runtime/softFloat.o + 13051 /home/scott/claude/llvm816/runtime/softDouble.o + 2552 /home/scott/claude/llvm816/runtime/libgcc.o + +# global symbols (sorted by address) +0x000000 __bss_bank +0x000000 __bss_seg0_bank +0x000000 __bss_seg1_bank +0x000000 __bss_seg1_lo16 +0x000000 __bss_seg1_size +0x000000 __bss_seg2_bank +0x000000 __bss_seg2_lo16 +0x000000 __bss_seg2_size +0x000000 __bss_seg3_bank +0x000000 __bss_seg3_lo16 +0x000000 __bss_seg3_size +0x000182 __bss_seg0_size +0x000182 __bss_size +0x001000 __start +0x001000 __text_start +0x001071 main +0x001266 __putByte +0x0013b3 __gnoStartup +0x001655 _exit +0x001686 __gnoGsosCall +0x00169b __gnoCallNum +0x00169d __gnoPBlock +0x0016a8 memset +0x001706 puts +0x0017c0 vprintf +0x0025e1 writeULong +0x002753 writeUDec +0x002893 writeHex +0x002a22 printf +0x002aa7 __adddf3 +0x003631 __subdf3 +0x00366b __muldf3 +0x003cee __floatsidf +0x003e6c __floatunsidf +0x003f8b __fixdfsi +0x004136 __jsl_indir +0x004139 __mulhi3 +0x004158 __umulhisi3 +0x0041af __ashlhi3 +0x0041be __lshrhi3 +0x0041ce __ashrhi3 +0x0041e1 __udivhi3 +0x0041ed __umodhi3 +0x0041f9 __divhi3 +0x004213 __modhi3 +0x00422d __divmod_setup +0x004260 __udivmod_core +0x00427e __mulsi3 +0x004337 __ashlsi3 +0x00434c __lshrsi3 +0x004361 __ashrsi3 +0x00437b __udivmodsi_core +0x0043b3 __udivsi3 +0x0043c7 __umodsi3 +0x0043db __divsi3 +0x004402 __modsi3 +0x004429 __divmodsi_setup +0x00447a __divmoddi4_stash +0x004497 __retdi +0x0044a4 __ashldi3 +0x0044c7 __lshrdi3 +0x0044ea __ashrdi3 +0x004510 __muldi3 +0x004577 __ucmpdi2 +0x0045a0 __cmpdi2 +0x0045d7 __udivdi3 +0x0045e0 __umoddi3 +0x0045f9 __udivmoddi_core +0x004646 __divdi3 +0x004665 __moddi3 +0x004692 __absdi_a +0x00469a __absdi_b +0x0046a2 __negdi_a +0x0046c0 __negdi_b +0x0046de setjmp +0x004706 longjmp +0x004730 __umulhisi3_qsq +0x004b2e __rodata_start +0x004b2e __text_end +0x004ef0 writeHex.digits +0x004f0b __init_array_end +0x004f0b __init_array_start +0x004f0b __rodata_end +0x00a000 __bss_lo16 +0x00a000 __bss_seg0_lo16 +0x00a000 __bss_start +0x00a000 argBuf +0x00a100 argVec +0x00a180 __indirTarget +0x00a182 __bss_end +0x00a182 __heap_start +0x00bf00 __heap_end +__absdi_a = 0x004692 +__absdi_b = 0x00469a +__adddf3 = 0x002aa7 +__ashldi3 = 0x0044a4 +__ashlhi3 = 0x0041af +__ashlsi3 = 0x004337 +__ashrdi3 = 0x0044ea +__ashrhi3 = 0x0041ce +__ashrsi3 = 0x004361 +__bss_bank = 0x000000 +__bss_end = 0x00a182 +__bss_lo16 = 0x00a000 +__bss_seg0_bank = 0x000000 +__bss_seg0_lo16 = 0x00a000 +__bss_seg0_size = 0x000182 +__bss_seg1_bank = 0x000000 +__bss_seg1_lo16 = 0x000000 +__bss_seg1_size = 0x000000 +__bss_seg2_bank = 0x000000 +__bss_seg2_lo16 = 0x000000 +__bss_seg2_size = 0x000000 +__bss_seg3_bank = 0x000000 +__bss_seg3_lo16 = 0x000000 +__bss_seg3_size = 0x000000 +__bss_size = 0x000182 +__bss_start = 0x00a000 +__cmpdi2 = 0x0045a0 +__divdi3 = 0x004646 +__divhi3 = 0x0041f9 +__divmod_setup = 0x00422d +__divmoddi4_stash = 0x00447a +__divmodsi_setup = 0x004429 +__divsi3 = 0x0043db +__fixdfsi = 0x003f8b +__floatsidf = 0x003cee +__floatunsidf = 0x003e6c +__gnoCallNum = 0x00169b +__gnoGsosCall = 0x001686 +__gnoPBlock = 0x00169d +__gnoStartup = 0x0013b3 +__heap_end = 0x00bf00 +__heap_start = 0x00a182 +__indirTarget = 0x00a180 +__init_array_end = 0x004f0b +__init_array_start = 0x004f0b +__jsl_indir = 0x004136 +__lshrdi3 = 0x0044c7 +__lshrhi3 = 0x0041be +__lshrsi3 = 0x00434c +__moddi3 = 0x004665 +__modhi3 = 0x004213 +__modsi3 = 0x004402 +__muldf3 = 0x00366b +__muldi3 = 0x004510 +__mulhi3 = 0x004139 +__mulsi3 = 0x00427e +__negdi_a = 0x0046a2 +__negdi_b = 0x0046c0 +__putByte = 0x001266 +__retdi = 0x004497 +__rodata_end = 0x004f0b +__rodata_start = 0x004b2e +__start = 0x001000 +__subdf3 = 0x003631 +__text_end = 0x004b2e +__text_start = 0x001000 +__ucmpdi2 = 0x004577 +__udivdi3 = 0x0045d7 +__udivhi3 = 0x0041e1 +__udivmod_core = 0x004260 +__udivmoddi_core = 0x0045f9 +__udivmodsi_core = 0x00437b +__udivsi3 = 0x0043b3 +__umoddi3 = 0x0045e0 +__umodhi3 = 0x0041ed +__umodsi3 = 0x0043c7 +__umulhisi3 = 0x004158 +__umulhisi3_qsq = 0x004730 +_exit = 0x001655 +argBuf = 0x00a000 +argVec = 0x00a100 +longjmp = 0x004706 +main = 0x001071 +memset = 0x0016a8 +printf = 0x002a22 +puts = 0x001706 +setjmp = 0x0046de +vprintf = 0x0017c0 +writeHex = 0x002893 +writeHex.digits = 0x004ef0 +writeUDec = 0x002753 +writeULong = 0x0025e1 diff --git a/demos/gnoHello.o b/demos/gnoHello.o new file mode 100644 index 0000000000000000000000000000000000000000..9832ad14ce47d273d17cd3dd3d544d090f6211f1 GIT binary patch literal 1600 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 literal 0 HcmV?d00001 diff --git a/demos/gnoHello.reloc b/demos/gnoHello.reloc new file mode 100644 index 0000000000000000000000000000000000000000..16e1e4031240338ef67fb034a38ae30e24adfdc4 GIT binary patch literal 1960 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 +#include +#include +int main(int argc, char **argv) { + char line[80]; + line[0] = 0; + printf("Type a line:\n"); // <-- prior stdout write, like gnoCat + char *r = fgets(line, sizeof(line), stdin); + size_t n = strlen(line); + while (n && (line[n-1] == '\n' || line[n-1] == '\r')) line[--n] = 0; + uint16_t mark; + if (r && strcmp(line, "FILE-STDIN-OK") == 0) mark = 0xC0DE; + else if (r && n > 0) mark = 0xBAD1; + else mark = 0xBAD0; + *(volatile uint16_t *)0x025000UL = mark; + *(volatile uint16_t *)0x025002UL = (uint16_t)n; + *(volatile uint16_t *)0x025004UL = (uint16_t)(uint8_t)line[0]; + for (volatile unsigned long i = 0; i < 300000UL; i++) {} + return 0; +} diff --git a/demos/gnoStdin.map b/demos/gnoStdin.map new file mode 100644 index 0000000..0f5ad8b --- /dev/null +++ b/demos/gnoStdin.map @@ -0,0 +1,201 @@ +# section layout +.text : 0x001000 .. 0x002a9c ( 6812 bytes) +.rodata : 0x002a9c .. 0x002f5f ( 1219 bytes) +.bss : 0x00a000 .. 0x00a182 ( 386 bytes) + +# per-input-file .text contributions + 113 /home/scott/claude/llvm816/runtime/crt0Gno.o + 802 /home/scott/claude/llvm816/demos/gnoStdin.o + 3444 /home/scott/claude/llvm816/runtime/libcGno.o + 925 /home/scott/claude/llvm816/runtime/gnoKernel.o + 34 /home/scott/claude/llvm816/runtime/gnoGsos.o + 32139 /home/scott/claude/llvm816/runtime/libc.o + 9073 /home/scott/claude/llvm816/runtime/snprintf.o + 10814 /home/scott/claude/llvm816/runtime/extras.o + 4364 /home/scott/claude/llvm816/runtime/softFloat.o + 13051 /home/scott/claude/llvm816/runtime/softDouble.o + 2552 /home/scott/claude/llvm816/runtime/libgcc.o + +# global symbols (sorted by address) +0x000000 __bss_bank +0x000000 __bss_seg0_bank +0x000000 __bss_seg1_bank +0x000000 __bss_seg1_lo16 +0x000000 __bss_seg1_size +0x000000 __bss_seg2_bank +0x000000 __bss_seg2_lo16 +0x000000 __bss_seg2_size +0x000000 __bss_seg3_bank +0x000000 __bss_seg3_lo16 +0x000000 __bss_seg3_size +0x000182 __bss_seg0_size +0x000182 __bss_size +0x001000 __start +0x001000 __text_start +0x001071 main +0x001393 gsosRead +0x0013a9 __putByte +0x0014f6 __getByte +0x001696 __gnoStartup +0x001938 _exit +0x001969 __gnoGsosCall +0x00197e __gnoCallNum +0x001980 __gnoPBlock +0x00198b memcmp +0x001a38 strlen +0x001aae puts +0x001b68 fgetc +0x001fa0 fgets +0x0020a4 __jsl_indir +0x0020a7 __mulhi3 +0x0020c6 __umulhisi3 +0x00211d __ashlhi3 +0x00212c __lshrhi3 +0x00213c __ashrhi3 +0x00214f __udivhi3 +0x00215b __umodhi3 +0x002167 __divhi3 +0x002181 __modhi3 +0x00219b __divmod_setup +0x0021ce __udivmod_core +0x0021ec __mulsi3 +0x0022a5 __ashlsi3 +0x0022ba __lshrsi3 +0x0022cf __ashrsi3 +0x0022e9 __udivmodsi_core +0x002321 __udivsi3 +0x002335 __umodsi3 +0x002349 __divsi3 +0x002370 __modsi3 +0x002397 __divmodsi_setup +0x0023e8 __divmoddi4_stash +0x002405 __retdi +0x002412 __ashldi3 +0x002435 __lshrdi3 +0x002458 __ashrdi3 +0x00247e __muldi3 +0x0024e5 __ucmpdi2 +0x00250e __cmpdi2 +0x002545 __udivdi3 +0x00254e __umoddi3 +0x002567 __udivmoddi_core +0x0025b4 __divdi3 +0x0025d3 __moddi3 +0x002600 __absdi_a +0x002608 __absdi_b +0x002610 __negdi_a +0x00262e __negdi_b +0x00264c setjmp +0x002674 longjmp +0x00269e __umulhisi3_qsq +0x002a9c __rodata_start +0x002a9c __text_end +0x002e28 writeHex.digits +0x002e43 __mfs +0x002f23 stdin +0x002f27 stdout +0x002f2b stderr +0x002f2f __c_lconv +0x002f5f __init_array_end +0x002f5f __init_array_start +0x002f5f __rodata_end +0x00a000 __bss_lo16 +0x00a000 __bss_seg0_lo16 +0x00a000 __bss_start +0x00a000 argBuf +0x00a100 argVec +0x00a180 __indirTarget +0x00a182 __bss_end +0x00a182 __heap_start +0x00bf00 __heap_end +__absdi_a = 0x002600 +__absdi_b = 0x002608 +__ashldi3 = 0x002412 +__ashlhi3 = 0x00211d +__ashlsi3 = 0x0022a5 +__ashrdi3 = 0x002458 +__ashrhi3 = 0x00213c +__ashrsi3 = 0x0022cf +__bss_bank = 0x000000 +__bss_end = 0x00a182 +__bss_lo16 = 0x00a000 +__bss_seg0_bank = 0x000000 +__bss_seg0_lo16 = 0x00a000 +__bss_seg0_size = 0x000182 +__bss_seg1_bank = 0x000000 +__bss_seg1_lo16 = 0x000000 +__bss_seg1_size = 0x000000 +__bss_seg2_bank = 0x000000 +__bss_seg2_lo16 = 0x000000 +__bss_seg2_size = 0x000000 +__bss_seg3_bank = 0x000000 +__bss_seg3_lo16 = 0x000000 +__bss_seg3_size = 0x000000 +__bss_size = 0x000182 +__bss_start = 0x00a000 +__c_lconv = 0x002f2f +__cmpdi2 = 0x00250e +__divdi3 = 0x0025b4 +__divhi3 = 0x002167 +__divmod_setup = 0x00219b +__divmoddi4_stash = 0x0023e8 +__divmodsi_setup = 0x002397 +__divsi3 = 0x002349 +__getByte = 0x0014f6 +__gnoCallNum = 0x00197e +__gnoGsosCall = 0x001969 +__gnoPBlock = 0x001980 +__gnoStartup = 0x001696 +__heap_end = 0x00bf00 +__heap_start = 0x00a182 +__indirTarget = 0x00a180 +__init_array_end = 0x002f5f +__init_array_start = 0x002f5f +__jsl_indir = 0x0020a4 +__lshrdi3 = 0x002435 +__lshrhi3 = 0x00212c +__lshrsi3 = 0x0022ba +__mfs = 0x002e43 +__moddi3 = 0x0025d3 +__modhi3 = 0x002181 +__modsi3 = 0x002370 +__muldi3 = 0x00247e +__mulhi3 = 0x0020a7 +__mulsi3 = 0x0021ec +__negdi_a = 0x002610 +__negdi_b = 0x00262e +__putByte = 0x0013a9 +__retdi = 0x002405 +__rodata_end = 0x002f5f +__rodata_start = 0x002a9c +__start = 0x001000 +__text_end = 0x002a9c +__text_start = 0x001000 +__ucmpdi2 = 0x0024e5 +__udivdi3 = 0x002545 +__udivhi3 = 0x00214f +__udivmod_core = 0x0021ce +__udivmoddi_core = 0x002567 +__udivmodsi_core = 0x0022e9 +__udivsi3 = 0x002321 +__umoddi3 = 0x00254e +__umodhi3 = 0x00215b +__umodsi3 = 0x002335 +__umulhisi3 = 0x0020c6 +__umulhisi3_qsq = 0x00269e +_exit = 0x001938 +argBuf = 0x00a000 +argVec = 0x00a100 +fgetc = 0x001b68 +fgets = 0x001fa0 +gsosRead = 0x001393 +longjmp = 0x002674 +main = 0x001071 +memcmp = 0x00198b +puts = 0x001aae +setjmp = 0x00264c +stderr = 0x002f2b +stdin = 0x002f23 +stdout = 0x002f27 +strlen = 0x001a38 +writeHex.digits = 0x002e28 diff --git a/demos/gnoStdin.o b/demos/gnoStdin.o new file mode 100644 index 0000000000000000000000000000000000000000..e173e0612dedf57c71df6a6eaf3bb91bc98a8be1 GIT binary patch literal 2108 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 S_BaVj!r*6<^1sodP5u|PKt%=s literal 0 HcmV?d00001 diff --git a/demos/gnoStdin.reloc b/demos/gnoStdin.reloc new file mode 100644 index 0000000000000000000000000000000000000000..a9671432770bcacbae05ecfe2bf59e09095713cb GIT binary patch literal 1048 zcmYk)PbkA-7zgkNGed0t76%SmYHSXYm9({qFijN46$g_YtT-uV<-'Hw8AB@S+` zN-4LUWH(Wgm78+l;`{bKZ@=g8^nQNdp7+`N{(f5|A|Hwli7K)9QQ0HyQ8>}99Ttwk z8Sa^dFFZt5Sd*xnQ#%C*Yqj(6b*G+V!8dg}KZm_M{}S$D-@#{Y-BW^t+`nHzbjovb z@Bz=a@Z+oOvct9$XEAvJHh1i(u{|dItjza%b=me}w#j{P8jtF}%dnZBf-@-f4%e|} z*_&9m+5PoISJK`%&~4VGrj|usP2QZ1%pvX74*}&hQ7D yz15gu+yDo7rux4}yY#o~g%j*Pc#Ay%huMR0ggq=gA{-Kq3Qq`63&(}$h5rGiVPGQw literal 0 HcmV?d00001 diff --git a/demos/helloBeep.bin b/demos/helloBeep.bin index ee30577c63423d7505bea7c9837cd5887f5680a3..ab6485303ca1fb17b81a4b3359929ac0789f3084 100644 GIT binary patch delta 397 zcmZ9Hze>YU6vl7bG-3y-+BU&1*E*DLA%gS;1ht!+x+pD@lGQR5VT_sw~Z8Uqht9BMO;*)u1=W#FLMM zd<68SRhEz{9MIICi;;_-hd|1JUiS}3CqOUi!{y|ekEw>7n#-WwhJZ-83qo`!373sG zeu)o7D;VSEUCTS^L()gTXaG=v)>+!UDu s4|`F#EmoD#h{?a>J92QJy*)r({E5h~IX1#15yp0L!1`h9X6l6h2Ey5`$p8QV delta 489 zcmaDReo>;{d-WrQmG%Ag3=D@94jHUuV2FOC;GNOBFJ=EB1)xk_e;q_-5yOH9Oba$} zK2j(Fs(jJ#2`E|HUkjBClz9*+vq7xw!2$+`jSqSm7Ti*D6=L}H0tgzO0#(-Z*FaP% z?Gj)(WbjB~t*wkiCKJO7>q82Q7#JQY?6sAdx&UZy$A!;8S1>WOHdISwE?{VF0=lTR zrL_&nYhdvB!oaXdQ$cA3!^4aWphe017{%=+S|2TaVDXqmfW`Cwe<`k2OCMSMwU?M| z!IWW;FTC_scI&gnEUhmTfb2Kf3O2$(#+6q~-)S;2eBjIg>X67}WXR5d$V|S#v>asM z3!s5dpTG@#0XDFY`ISPK$g)>UUu3sFXnO=S^vPnj)@LBGcOauJL>0Ow&tOqz0Wmi3 zXW?RG?3{dxH4R7_vS|RxC^j>`PEiF8@uuzn6u^wh^Vkv%J4Kg1bA6}D(9rrzVWGIf zN^ziyrN2HfD{K^RG6E@F`V3WavH`oOFi?{9-_mCSAY}^ht1!6wS5 z&~c@(MGHAyxmkE}X1QiO2e{Or=h9X+^{z&1MuQf?agnpF-2mU*6R(QigzHUgM{=$M zPuNd@JC)nmYZwvJDR1C<%xG4aZ`PiChgDKF)W74zBZsJ30oys_<4=Q`Dv5s;lvm% zN7ml-XfW7c$ns)hjCr%2NieN0o!9At&J(QrL#0dlT0#Vw_uulT<+5G=lY3T^?OWd8 zu-0QzB57r7A5i$cBmZUyT{Ttr1hl@l6mo=!(>5VgapYbS>k5E5fa=MmzgPv(sEZ2ME&?Hg{Q;TKRad8@uCZc>+7E=Z=RI$A(Yg7&-}n1@9^Uh4j_7k_ zvX7jRrWWW_+#`)mJ#C9vG!sch0P-~7oB_CM(GHER^u5hfY(`U~qL~5RB>GZ?MQ@{7 zjBaB&k{bC_cKXat-_qf@sRLxq3D7?_glb@~h+lLQ&EeFrFdLSuA>VA#7p*>TKY_(O zJv9Sh(KoHW$2#tP@O}qhL4ZZ?dHZ!>F?|q=L2tTV)|v-ujZ&BuW))VXc>WruEwy;~P%_GX0$UXtPI&tz z2y3EAzmgaD!Xhr*-1xV!XfGU8N;FwFUowheX2vaCx-siy1%6lNs{?MDOy6}hD*TX} zc2r7IBK_QXizM9X4)rL87WL$zgqylNvDf?5KBS}S_1=WrD1^#>h_XF8?V%YD8pht1 zOtYTY2`(Ci|H^G<8oT)0-`R%olNJ8Tj(ww0&Bv}8W#nq^wCkZ#R|8Gmz1=;bi%s1< z=el~1U+QWUDjsf9lgU%{MyTE1M$P0SBhCNHq>SxgEAb zoeAEJ3oHqI7AQGgDt22U?TBW)NpVQ*CuX&GOqj!ifkcW;?)y@+kpQd74b~4AyQo zCbIPJ7se;!hw&39;=%oo$-gG=@VnmZ;hlfqXCJ%=Y`rtYXP=MR+MQzU&aigpSi4)S N-M#S<-x&A*`~kFxE1v)W diff --git a/demos/helloText.bin b/demos/helloText.bin index c0349535143b5d475eb82589e0ef6b582687fcf6..814d34b87530e63734499fa3e91aea7c88000bff 100644 GIT binary patch delta 640 zcmY+7O=#0#7{{NaiCNlJYHPoi2yb8UqqlUR6!an@R(8>g;Jk=VOzFXkr>YoMGKHZq zg7=z`u}p=I2qMA;Ie76ThzGr-*;ZnwWw5eCrJZkT9qhe4e}4bx{XM&Q9zU6S?MN2D zO%F}U>gvpzgB;02I@H~8y}>>JU)c?i9?7|pTq8B-)&W-B=VSHn_(KYMK6%QfBjGzS zaHJXKVWzA=sSBXz5nh6(EGq*?S~^$!ISGQL(72oc{4@nRvw#7b*21@mvo{h@HCLCd z6@)J*pnD#y(}4fOPygW618|2x?IdN<@8b3sN}%aKajg@&M-{Z|Oo4i-J!39pw&GBI z3-ywIm<}#=sgNZA-im8YMu>hUWk6y>!m~nD9g(9$QecJSKSm@OkdZ67?@A5#?z3qz zC=IU0XUf3TID;ogYplVQ3=ZdPoqa{6ZBg}1x46#4m@9jG6X9jkEB0+so95)gdfIGP z)Rw`hJ|g*71vSznd~KVZJPq5tOnzj_6jbCR!2KpmqV|!;>@e9L&r@_itNjk&4aR)rR4^V#&P4lJ^hlU}KR`jy z)*`p1e%5SV>f}LDdnhTQVr2(s9tF9r1^5!aiJHDrhl2|?}LO@+EIzu)=(`J8j7@HUS1yfu*? zOU3{)DATM1+%Qp(M3x3VW)OA8l4E5@1;ubG3l0+v(qt~aMa|LV=z%%pH-`KRwG)N{ zuxLE7D=XMl2Rk|X#n)+aBso$};`c7dG@EGN?iV90%=TuG3SgoScK~?E8OW}#>=vOZutdwmzk9Jxd5{v2lx)LlS1b~ z392Vp46s^cINb}l(=9*dy{(v7%S0z$%;s!RweTQDWy?^Weob*Z_+ zd)r$Mnl(qwpjvZuLv2}AYfFmCFCSigvIGbS^~{5GkMM@6b2boDGunRgF1~wz-{YLq z%(h);gUs2az(rBZM@crtlN_S^MikjZx_rxPg+>-O9TIJb5eA~tfg``N%~-@7C9ba> z5pyMC*q--atDnhhxhOFvOiEo#9V1ypwSvXwJam-@99SrA=_!YUVM8AIx$}-ScAaOf zai*fRGUP#Dz2oopkhREC#qDs&qh-4ajSwe0=$;P^`e;Dg+2qiOZ@k6IY1#kGEn;Xz z`s>?dP5VQ#hhbq)%et)EEv-Q3%k-(^PxOkq4QVzx-ZL%uIqmR Domn3C diff --git a/demos/helloText.map b/demos/helloText.map index 01ce8b6..df5a3b0 100644 --- a/demos/helloText.map +++ b/demos/helloText.map @@ -1,16 +1,16 @@ # section layout -.text : 0x001000 .. 0x002108 ( 4360 bytes) -.rodata : 0x002108 .. 0x002176 ( 110 bytes) +.text : 0x001000 .. 0x0020b1 ( 4273 bytes) +.rodata : 0x0020b1 .. 0x00210b ( 90 bytes) .bss : 0x00a000 .. 0x00a00a ( 10 bytes) # per-input-file .text contributions - 186 /home/scott/claude/llvm816/runtime/crt0Gsos.o + 99 /home/scott/claude/llvm816/runtime/crt0Gsos.o 546 /home/scott/claude/llvm816/demos/helloText.o - 30853 /home/scott/claude/llvm816/runtime/libc.o - 9098 /home/scott/claude/llvm816/runtime/snprintf.o - 10865 /home/scott/claude/llvm816/runtime/extras.o - 4374 /home/scott/claude/llvm816/runtime/softFloat.o - 13388 /home/scott/claude/llvm816/runtime/softDouble.o + 32173 /home/scott/claude/llvm816/runtime/libc.o + 9075 /home/scott/claude/llvm816/runtime/snprintf.o + 10814 /home/scott/claude/llvm816/runtime/extras.o + 4364 /home/scott/claude/llvm816/runtime/softFloat.o + 13051 /home/scott/claude/llvm816/runtime/softDouble.o 176 /home/scott/claude/llvm816/runtime/iigsGsos.o 20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o 1139 /home/scott/claude/llvm816/runtime/desktop.o @@ -32,71 +32,70 @@ 0x00000a __bss_size 0x001000 __start 0x001000 __text_start -0x0010ba main -0x0012dc CtlStartUp -0x0012ec EMStartUp -0x00130b GetNextEvent -0x001322 FMStartUp -0x001332 LEStartUp -0x001342 LoadOneTool -0x001352 NewHandle -0x001378 MenuStartUp -0x001388 QDStartUp -0x00139e DrawString -0x0013b0 MoveTo -0x0013c0 startdesk -0x0016de paintDesktopBackdrop -0x001710 __jsl_indir -0x001713 __mulhi3 -0x001732 __umulhisi3 -0x001789 __ashlhi3 -0x001798 __lshrhi3 -0x0017a8 __ashrhi3 -0x0017bb __udivhi3 -0x0017c7 __umodhi3 -0x0017d3 __divhi3 -0x0017ed __modhi3 -0x001807 __divmod_setup -0x00183a __udivmod_core -0x001858 __mulsi3 -0x001911 __ashlsi3 -0x001926 __lshrsi3 -0x00193b __ashrsi3 -0x001955 __udivmodsi_core -0x00198d __udivsi3 -0x0019a1 __umodsi3 -0x0019b5 __divsi3 -0x0019dc __modsi3 -0x001a03 __divmodsi_setup -0x001a54 __divmoddi4_stash -0x001a71 __retdi -0x001a7e __ashldi3 -0x001aa1 __lshrdi3 -0x001ac4 __ashrdi3 -0x001aea __muldi3 -0x001b51 __ucmpdi2 -0x001b7a __cmpdi2 -0x001bb1 __udivdi3 -0x001bba __umoddi3 -0x001bd3 __udivmoddi_core -0x001c20 __divdi3 -0x001c3f __moddi3 -0x001c6c __absdi_a -0x001c74 __absdi_b -0x001c7c __negdi_a -0x001c9a __negdi_b -0x001cb8 setjmp -0x001ce0 longjmp -0x001d0a __umulhisi3_qsq -0x002108 __rodata_start -0x002108 __text_end -0x002108 gChainPath -0x00211c line1 -0x002131 line2 -0x00215e line3 -0x002176 __init_array_end -0x002176 __init_array_start -0x002176 __rodata_end +0x001063 main +0x001285 CtlStartUp +0x001295 EMStartUp +0x0012b4 GetNextEvent +0x0012cb FMStartUp +0x0012db LEStartUp +0x0012eb LoadOneTool +0x0012fb NewHandle +0x001321 MenuStartUp +0x001331 QDStartUp +0x001347 DrawString +0x001359 MoveTo +0x001369 startdesk +0x001687 paintDesktopBackdrop +0x0016b9 __jsl_indir +0x0016bc __mulhi3 +0x0016db __umulhisi3 +0x001732 __ashlhi3 +0x001741 __lshrhi3 +0x001751 __ashrhi3 +0x001764 __udivhi3 +0x001770 __umodhi3 +0x00177c __divhi3 +0x001796 __modhi3 +0x0017b0 __divmod_setup +0x0017e3 __udivmod_core +0x001801 __mulsi3 +0x0018ba __ashlsi3 +0x0018cf __lshrsi3 +0x0018e4 __ashrsi3 +0x0018fe __udivmodsi_core +0x001936 __udivsi3 +0x00194a __umodsi3 +0x00195e __divsi3 +0x001985 __modsi3 +0x0019ac __divmodsi_setup +0x0019fd __divmoddi4_stash +0x001a1a __retdi +0x001a27 __ashldi3 +0x001a4a __lshrdi3 +0x001a6d __ashrdi3 +0x001a93 __muldi3 +0x001afa __ucmpdi2 +0x001b23 __cmpdi2 +0x001b5a __udivdi3 +0x001b63 __umoddi3 +0x001b7c __udivmoddi_core +0x001bc9 __divdi3 +0x001be8 __moddi3 +0x001c15 __absdi_a +0x001c1d __absdi_b +0x001c25 __negdi_a +0x001c43 __negdi_b +0x001c61 setjmp +0x001c89 longjmp +0x001cb3 __umulhisi3_qsq +0x0020b1 __rodata_start +0x0020b1 __text_end +0x0020b1 line1 +0x0020c6 line2 +0x0020f3 line3 +0x00210b __init_array_end +0x00210b __init_array_start +0x00210b __rodata_end 0x00a000 __bss_lo16 0x00a000 __bss_seg0_lo16 0x00a000 __bss_start @@ -107,25 +106,25 @@ 0x00a00a __bss_end 0x00a00a __heap_start 0x00bf00 __heap_end -CtlStartUp = 0x0012dc -DrawString = 0x00139e -EMStartUp = 0x0012ec -FMStartUp = 0x001322 -GetNextEvent = 0x00130b -LEStartUp = 0x001332 -LoadOneTool = 0x001342 -MenuStartUp = 0x001378 -MoveTo = 0x0013b0 -NewHandle = 0x001352 -QDStartUp = 0x001388 -__absdi_a = 0x001c6c -__absdi_b = 0x001c74 -__ashldi3 = 0x001a7e -__ashlhi3 = 0x001789 -__ashlsi3 = 0x001911 -__ashrdi3 = 0x001ac4 -__ashrhi3 = 0x0017a8 -__ashrsi3 = 0x00193b +CtlStartUp = 0x001285 +DrawString = 0x001347 +EMStartUp = 0x001295 +FMStartUp = 0x0012cb +GetNextEvent = 0x0012b4 +LEStartUp = 0x0012db +LoadOneTool = 0x0012eb +MenuStartUp = 0x001321 +MoveTo = 0x001359 +NewHandle = 0x0012fb +QDStartUp = 0x001331 +__absdi_a = 0x001c15 +__absdi_b = 0x001c1d +__ashldi3 = 0x001a27 +__ashlhi3 = 0x001732 +__ashlsi3 = 0x0018ba +__ashrdi3 = 0x001a6d +__ashrhi3 = 0x001751 +__ashrsi3 = 0x0018e4 __bss_bank = 0x000000 __bss_end = 0x00a00a __bss_lo16 = 0x00a000 @@ -143,57 +142,56 @@ __bss_seg3_lo16 = 0x000000 __bss_seg3_size = 0x000000 __bss_size = 0x00000a __bss_start = 0x00a000 -__cmpdi2 = 0x001b7a -__divdi3 = 0x001c20 -__divhi3 = 0x0017d3 -__divmod_setup = 0x001807 -__divmoddi4_stash = 0x001a54 -__divmodsi_setup = 0x001a03 -__divsi3 = 0x0019b5 +__cmpdi2 = 0x001b23 +__divdi3 = 0x001bc9 +__divhi3 = 0x00177c +__divmod_setup = 0x0017b0 +__divmoddi4_stash = 0x0019fd +__divmodsi_setup = 0x0019ac +__divsi3 = 0x00195e __heap_end = 0x00bf00 __heap_start = 0x00a00a __indirTarget = 0x00a008 -__init_array_end = 0x002176 -__init_array_start = 0x002176 -__jsl_indir = 0x001710 -__lshrdi3 = 0x001aa1 -__lshrhi3 = 0x001798 -__lshrsi3 = 0x001926 -__moddi3 = 0x001c3f -__modhi3 = 0x0017ed -__modsi3 = 0x0019dc -__muldi3 = 0x001aea -__mulhi3 = 0x001713 -__mulsi3 = 0x001858 -__negdi_a = 0x001c7c -__negdi_b = 0x001c9a -__retdi = 0x001a71 -__rodata_end = 0x002176 -__rodata_start = 0x002108 +__init_array_end = 0x00210b +__init_array_start = 0x00210b +__jsl_indir = 0x0016b9 +__lshrdi3 = 0x001a4a +__lshrhi3 = 0x001741 +__lshrsi3 = 0x0018cf +__moddi3 = 0x001be8 +__modhi3 = 0x001796 +__modsi3 = 0x001985 +__muldi3 = 0x001a93 +__mulhi3 = 0x0016bc +__mulsi3 = 0x001801 +__negdi_a = 0x001c25 +__negdi_b = 0x001c43 +__retdi = 0x001a1a +__rodata_end = 0x00210b +__rodata_start = 0x0020b1 __start = 0x001000 -__text_end = 0x002108 +__text_end = 0x0020b1 __text_start = 0x001000 -__ucmpdi2 = 0x001b51 -__udivdi3 = 0x001bb1 -__udivhi3 = 0x0017bb -__udivmod_core = 0x00183a -__udivmoddi_core = 0x001bd3 -__udivmodsi_core = 0x001955 -__udivsi3 = 0x00198d -__umoddi3 = 0x001bba -__umodhi3 = 0x0017c7 -__umodsi3 = 0x0019a1 -__umulhisi3 = 0x001732 -__umulhisi3_qsq = 0x001d0a -gChainPath = 0x002108 +__ucmpdi2 = 0x001afa +__udivdi3 = 0x001b5a +__udivhi3 = 0x001764 +__udivmod_core = 0x0017e3 +__udivmoddi_core = 0x001b7c +__udivmodsi_core = 0x0018fe +__udivsi3 = 0x001936 +__umoddi3 = 0x001b63 +__umodhi3 = 0x001770 +__umodsi3 = 0x00194a +__umulhisi3 = 0x0016db +__umulhisi3_qsq = 0x001cb3 gDpBase = 0x00a006 gDpHandle = 0x00a002 gUserId = 0x00a000 -line1 = 0x00211c -line2 = 0x002131 -line3 = 0x00215e -longjmp = 0x001ce0 -main = 0x0010ba -paintDesktopBackdrop = 0x0016de -setjmp = 0x001cb8 -startdesk = 0x0013c0 +line1 = 0x0020b1 +line2 = 0x0020c6 +line3 = 0x0020f3 +longjmp = 0x001c89 +main = 0x001063 +paintDesktopBackdrop = 0x001687 +setjmp = 0x001c61 +startdesk = 0x001369 diff --git a/demos/helloText.omf b/demos/helloText.omf index 0671c40f22ba739d243185d01d52fd18e1e394a2..4f3c40a4f6c213a909c93fa8bd2c809a324a1c87 100644 GIT binary patch delta 1329 zcmZ9IU2Icj7{{OUzUTDo6e*ki*xDthClXn_up?2Izy-J{RlJaRK^BM@n4z^XA%+Bl zXe;#$y})caE=HrKYdw<^AYF>exPYV@Ok5N%{6>?qjizj*A?zc%rN!qt@0ihZ^MC)p z_y2#MH|Lu%HZjJA2G}!f_%m&IFerUA{K=E)N~{R5XG+_dFfI*Tu4t9ml$M8F)srhJ zhoPQXB9vF7RW(`)3|4ah z4_*=Q+5f{Me%_ z_Nn}}$1SmDhj~?fk>q9XgCzUBkF0BUXvf0GzierAFh{-n`s-3u!%tLCHH3swWQue^8NyK=d;q49=! zs4bOVWDo=xLg@q#$tF-YpgbhxF>nnna@YbB4wN_?0F*!n;c)kVT7-c%X3DLxxi(TU$}$hj)=5) z4=wb_b|EH@P+>bc2G0rjiabZ~h;VNUcTzY@o@BVFWWzLkF6ei%LG)J<{Zqh2`5Hk` z>}iT(FAR|5@UVc}1bkYF(wmMr>{ncL;9p~K%Te~CNKRW)&S@t_guL!7kxOTUeP7rQ zg?rp(H+Bo@bGKX=-7RFF`-~gie&Gg%dq=qUJWaY=5%Pd)yFEglSC6T9Hz3?W;lAA^ p?9Zy7UizEbMe>KZoK`oIyD1{`BC;eRe~XCEYezbT=-xgr`~$Fv)7Ah0 delta 1422 zcmZ8dZ)h837=P})yIk&aap|(PG0EU^Otj$EKRPL$A6#X%-5icIbymmx!(=J#K%tb* zbxml!tY5S(hp7EfvV`lJ!bWFM+0;7nWvDQP4HTJM8ru+S33YZdt8PB;y=_7B<@f&n zJiq6;T%06VCdueg@*){KtBob9xaqNp=2$_?#71HOIW1S40eGpP?T;F>N59Nz=nRYu zFee4cypo)e3tA5*OYz%io*Fr|X7+~iy`h=PL_P^{A^(mu`J?Wsg4GiK;tQDUAL(aF z{gMZAwFT{*Gvwr8?%h!+`e8wq4_XjuVB zRcrbb%tfQvS39-4;g@;{Wa31>>;?U%d5GKo#Eci-vSz0ctL6Y97n(<|=rHDT*HNVcRNAUeR@3dd&xpf`EV zZZWV+N0TZZs@S<9J}nKoeVrf?12JVn?hk!d|JdUlA^uFv4#~H3l*=7{1e8bOzM`*o&->*ztg@%8W zZRUa$t!wmIi(N)BEf^&Y-%DMZuIQR$4mc-iV+k7<<~JHk zcH?e&G1UIxwQGUFPw#2;VeV63>xlTR;@)yK#En(0JE-*pF<`AO^ICs!u%70u;{VLsM&4S% zPyfT1x9%Fn^{{x)DthSHD^?kCJS)226}D`KnzoL%$le1rZIM0U$j;}&tbIPW&i}yUO*|~|VaopG2|aC-AW+yT zI4HCVcBEYxrjb_}J1r~`WFJsQV48_v2~9L|m9bll&D$&ne+xQ2Q4;NpD%z#n#Tx|0 z8YVu@#An5NnmokB!%RF*84n32zR$!nVxPUxVP8=p;eSZrX-RP-yuctQH9C>St}?tX zNtAxiSedck82iv^51wZ*F1O2=JkQ`0nOBfqWb7x#@{IkeM5q^b*>IAJAA@0o<$kF?BBB8|`GNb4{HbT+q%v zb>@8{XLu-chGp}Sa_^Ofi<?N&KF6 z?GND1G~{t5CZe1tLi z80D*!Z&1GFi2P~4NN$XH`7n6|Uci|BCn%q!{Fd?uxLV)OGhC;BrG6f6()=B^=PAH; X?GJ3%{=)VQQLM9TW8?-nu6zCiP}XBK literal 1036 zcmYk)ODIHP7zW_a+|HOwX1201u~6=;W+h6EC{4ztq^xWxN*b{?mUfthvbC6`D3oL) zsj;9~xGn5VVn-~zf9Lx<@8au!dcEI&4$i2EG+|^z#D}996H)iWOG!7+kaKWYI}>oi z5%J@k$DCk{^O&&i7RZ2a{)G26|Ay;y_ZQyLJXqy*;&6v{60q&mQYQsZ zX{V7oH*i$%d@wJfze@$qYW{=Mr+H04B%p4EL+T7{cXRN%?oLx)fGhaJ;zzPY`5yTS z?$zBgvGVr`|J0ok{Ak5+I!OQs^&d7 c?fVSCc6SK2yTh>Eoq_G{0(luOV$5^@0dtj97XSbN diff --git a/runtime/build.sh b/runtime/build.sh index 5464c33..1ac56ad 100755 --- a/runtime/build.sh +++ b/runtime/build.sh @@ -39,6 +39,10 @@ cc() { asm "$SRC/crt0.s" asm "$SRC/crt0Gsos.s" +asm "$SRC/crt0Gno.s" +asm "$SRC/gnoKernel.s" +asm "$SRC/gnoGsos.s" +cc "$SRC/libcGno.c" asm "$SRC/libgcc.s" cc "$SRC/libc.c" cc "$SRC/strtol.c" diff --git a/runtime/include/gno/kernel.h b/runtime/include/gno/kernel.h new file mode 100644 index 0000000..d313c2e --- /dev/null +++ b/runtime/include/gno/kernel.h @@ -0,0 +1,48 @@ +// AUTOGENERATED by scripts/genGnoKernel.py — DO NOT EDIT. +// GNO kernel toolset $03 wrappers, callable from C. +// Convention: each K* returns the kernel result (or -1 on error); +// the last argument is `int *errno` and gets the kernel's errno. +// +// These are LOW-LEVEL primitives — libc routines in libcGno.c +// wrap them into POSIX-named fork/exec/wait/etc. +#ifndef GNO_KERNEL_H +#define GNO_KERNEL_H + +#include + +extern int Kgetpid(void); // 0x0903 +extern int Kkill(int a0, int a1, void * a2); // 0x0A03 +extern int Kfork(void * a0, void * a1); // 0x0B03 +extern int Kgetppid(void * a0); // 0x4003 +extern int Kwait(void * a0, void * a1); // 0x1703 +extern int K_execve(void * a0, void * a1, void * a2); // 0x1D03 +extern unsigned long Ksignal(int a0, void * a1, void * a2); // 0x1603 +extern unsigned long Kalarm(void * a0, void * a1); // 0x1E03 +extern unsigned long Kalarm10(void * a0, void * a1); // 0x4203 +extern int Ksigpause(void * a0, void * a1); // 0x2103 +extern unsigned long Ksigsetmask(void * a0, void * a1); // 0x1B03 +extern unsigned long Ksigblock(void * a0, void * a1); // 0x1C03 +extern int Kdup(int a0, void * a1); // 0x2203 +extern int Kdup2(int a0, int a1, void * a2); // 0x2303 +extern int Kpipe(void * a0, void * a1); // 0x2403 +extern int Kioctl(int a0, void * a1, void * a2, void * a3); // 0x2603 +extern int Kstat(void * a0, void * a1, void * a2); // 0x2703 +extern int Kfstat(int a0, void * a1, void * a2); // 0x2803 +extern int Klstat(void * a0, void * a1, void * a2); // 0x2903 +extern int Kgetuid(void * a0); // 0x2A03 +extern int Kgetgid(void * a0); // 0x2B03 +extern int Kgeteuid(void * a0); // 0x2C03 +extern int Kgetegid(void * a0); // 0x2D03 +extern int Ksetuid(int a0, void * a1); // 0x2E03 +extern int Ksetgid(int a0, void * a1); // 0x2F03 +extern int Ktcnewpgrp(int a0, void * a1); // 0x1803 +extern int Ksettpgrp(int a0, void * a1); // 0x1903 +extern int Ktctpgrp(int a0, int a1, void * a2); // 0x1A03 +extern int K_getpgrp(int a0, void * a1); // 0x2503 +extern int Ksetpgrp(int a0, int a1, void * a2); // 0x3403 +extern int Kkvm_open(void * a0); // 0x1103 +extern int Kkvm_close(void * a0, void * a1); // 0x1203 +extern unsigned long Ktimes(void * a0, void * a1); // 0x3503 +extern void KSetGNOQuitRec(int a0, void * a1, int a2, void * a3); // 0x4103 + +#endif diff --git a/runtime/src/crt0.s b/runtime/src/crt0.s index 64bad95..721f022 100644 --- a/runtime/src/crt0.s +++ b/runtime/src/crt0.s @@ -84,6 +84,9 @@ __start: phb ; save current DBR ; ---- segment 0 ---- + ; The `sep #0x20` that sets the segment's data bank also puts us in + ; M=8 for the whole store loop (X stays 16-bit), so we don't flip + ; SEP/REP per byte; each segment label below re-enters via `rep`. rep #0x20 ldx #__bss_seg0_size beq .Lbss_seg1 @@ -92,14 +95,11 @@ __start: .byte __bss_seg0_bank pha plb - rep #0x20 ldx #0 .Lbss_loop0: cpx #__bss_seg0_size bcs .Lbss_seg1 - sep #0x20 stz __bss_seg0_lo16, x - rep #0x20 inx bra .Lbss_loop0 .Lbss_seg1: @@ -112,14 +112,11 @@ __start: .byte __bss_seg1_bank pha plb - rep #0x20 ldx #0 .Lbss_loop1: cpx #__bss_seg1_size bcs .Lbss_seg2 - sep #0x20 stz __bss_seg1_lo16, x - rep #0x20 inx bra .Lbss_loop1 .Lbss_seg2: @@ -132,14 +129,11 @@ __start: .byte __bss_seg2_bank pha plb - rep #0x20 ldx #0 .Lbss_loop2: cpx #__bss_seg2_size bcs .Lbss_seg3 - sep #0x20 stz __bss_seg2_lo16, x - rep #0x20 inx bra .Lbss_loop2 .Lbss_seg3: @@ -152,17 +146,15 @@ __start: .byte __bss_seg3_bank pha plb - rep #0x20 ldx #0 .Lbss_loop3: cpx #__bss_seg3_size bcs .Lbss_done - sep #0x20 stz __bss_seg3_lo16, x - rep #0x20 inx bra .Lbss_loop3 .Lbss_done: + rep #0x20 ; back to M=16 after the M=8 store loop plb ; restore caller's DBR ; Run static constructors. The linker emits @@ -225,8 +217,12 @@ __start: ; nothing. After return, A holds the exit code. jsl main - ; Halt via BRK $00. MAME / debuggers catch this as a clean - ; program termination. - .byte 0x00, 0x00 + ; main returned. Bare metal has no OS to return to, so spin. + ; (Previously a BRK $00 here, but headless MAME mis-vectors BRK to + ; $0000 and wild-jumps, which reads as a crash. A tight loop is the + ; conventional bare-metal halt; IRQs are already masked above, so + ; this just idles.) +.Lhalt: + bra .Lhalt .size __start, . - __start diff --git a/runtime/src/crt0Gno.s b/runtime/src/crt0Gno.s new file mode 100644 index 0000000..c19963e --- /dev/null +++ b/runtime/src/crt0Gno.s @@ -0,0 +1,141 @@ +; crt0Gno.s — GNO/ME shell command crt0. +; +; Use this INSTEAD OF crt0.s / crt0Gsos.s when building an OMF intended +; to run as a GNO shell command (filetype $B5 EXE, aux 0). +; +; GNO/ME entry contract for a shell command (per ORCA's ~GNO_COMMAND): +; E=0 (native), M=0 (16-bit accumulator), X=0 (16-bit index) +; A:X = command line pointer (32-bit; A=low word, X=high word) +; Y = user ID (currently unused by us) +; DBR = bank of our entry segment (set by GS/OS Loader) +; DP = pointer to a Memory-Manager-allocated DP page +; The GS/OS Loader's launch frame on the stack is discarded by Quit. +; +; Differences from crt0Gsos.s: +; - The kernel passes a command-line pointer in A:X (not on the stack). +; - Instead of QUIT chaining to a hardcoded path, we just QUIT(pcount=0) +; so control returns to the GNO shell that launched us. +; - main() receives (int argc, char **argv) — crt0 calls a C helper +; __gnoStartup(cmdline) which parses the command line and invokes +; main(), then falls through to QUIT. + + .text + + .globl __start +__start: + ; GNO entry contract (from kern ~GNO_COMMAND, lib/libc/gno/gnocmd.asm): + ; A = user ID + ; Y:X = command-line pointer (Y = low word, X = high word) — a + ; NUL-terminated C string of the invocation command line. + ; Stash the cmdline pointer (Y:X) to bank-0 scratch $00:00B0..B3 + ; and the user ID (A) to $00:00B6, BEFORE we switch to DP=0. + ; Bank-explicit `sta long` so we don't depend on DP/DBR here. + rep #0x30 + .byte 0x8f, 0xb6, 0x00, 0x00 ; sta long $00:00B6 (user ID) + tya + .byte 0x8f, 0xb0, 0x00, 0x00 ; sta long $00:00B0 (cmdline low word = Y) + txa + .byte 0x8f, 0xb2, 0x00, 0x00 ; sta long $00:00B2 (cmdline high word = X) + + ; Set DBR := PBR (our entry-segment bank) — same Loader-contract + ; mitigation as crt0Gsos.s. + phk + plb + + ; Save GNO's per-process direct page BEFORE zeroing it. GNO's + ; GS/OS-call interceptor uses the caller's DP to identify the + ; calling process (and find its fd table). Our codegen needs + ; DP=0, so we stash GNO's DP at $00:00B4 and restore it around + ; GS/OS calls (see __gnoSaveDP / gsosWrite-under-GNO path). + rep #0x30 + tdc ; A = current (GNO) DP + .byte 0x8f, 0xb4, 0x00, 0x00 ; sta long $00:00B4 (stash GNO DP word) + + ; Set DP=0 — backend assumes DP=0 for `sta dp` / `[dp],y` etc. + lda #0 + tcd + + ; Persistent "current data bank" byte at DP $BE = PBR (our bank). + ; See crt0.s comment for rationale (codegen reads this for the + ; bank half of `&symbol` 32-bit pointers). + sep #0x20 + phk + pla + sta 0xbe + stz 0xbf ; pad so `lda 0xbe` in 16-bit M reads $00PBR + rep #0x20 + + ; BSS zero-init (DBR-relative byte stores). M is held at 8 across + ; the whole loop while X stays 16-bit, so we don't flip SEP/REP per + ; byte (llvm-mc still encodes cpx/ldx as 16-bit X-immediates in M=8). + rep #0x30 ; M=16, X=16 + sep #0x20 ; M=8 for the byte stores; X remains 16-bit + ldx #__bss_start +.Lbss_loop: + cpx #__bss_end + bcs .Lbss_done + stz 0x0000, x ; 1-byte store (M=8) + inx + bra .Lbss_loop +.Lbss_done: + rep #0x20 ; restore M=16 + + ; Walk .init_array (C++ ctors). Inlined from crt0Gsos.s. The + ; `jsl __jsl_indir` and `jsl main` operands are relocated by the + ; GS/OS Loader: omfEmit emits a cRELOC (0xF5) IMM24 site for each + ; intra-segment JSL, so the Loader patches the full 24-bit operand + ; (bank included) to the placed address. Non-zero-bank placement is + ; handled correctly as long as the OMF is built with --relocs (which + ; demos/buildGno.sh does). + rep #0x30 + ldx #__init_array_start +.Linit_loop: + cpx #__init_array_end + bcs .Linit_done + stx 0xe0 + ldy #0 + lda (0xe0), y + sta __indirTarget + phx + jsl __jsl_indir + plx + inx + inx + inx + inx + bra .Linit_loop +.Linit_done: + + ; Reload cmdline ptr from $00:00B0..$00:00B3 into A:X. + ; Use bank-explicit `lda long` so we don't depend on DBR. + rep #0x30 + .byte 0xaf, 0xb0, 0x00, 0x00 ; lda long $00:00B0 -> A (cmdline lo word) + pha ; stash A on stack briefly + .byte 0xaf, 0xb2, 0x00, 0x00 ; lda long $00:00B2 -> A (cmdline hi word) + tax ; X = cmdline hi + pla ; A = cmdline lo + + ; Call __gnoStartup(cmdline) — C helper in libcGno.c which: + ; 1. parses the command line into argc/argv, + ; 2. calls main(argc, argv), + ; 3. returns whatever main returned. + jsl __gnoStartup + + ; ---- Terminate via _exit (libcGno.c) ---- + ; __gnoStartup returned with A = main()'s exit status. _exit issues + ; GS/OS QUIT through GNO's INLINE dispatch (__gnoGsosCall), which is + ; REQUIRED under GNO: the old stack-based QUIT here (ldx #$2029 ; + ; jsl $e100a8 with the pblock pushed) was misread by GNO's OurGSOS + ; interceptor — it reads the call number + pblock from the inline + ; bytes after the jsl, not the stack — so the QUIT was mis-dispatched, + ; the process was left restartable, and GNO RE-RAN main() a second + ; time (silently draining redirected stdin on the first pass). + jsl _exit + + ; _exit does not return. If it ever does, spin rather than fall + ; into a BRK (headless MAME mis-vectors BRK to $0000, which looks + ; like a wild crash) or off the end of the segment. +.Lhang: + bra .Lhang + + .size __start, . - __start diff --git a/runtime/src/crt0Gsos.s b/runtime/src/crt0Gsos.s index 9fa865c..82382d2 100644 --- a/runtime/src/crt0Gsos.s +++ b/runtime/src/crt0Gsos.s @@ -6,9 +6,9 @@ ; - No language-card RAM enable (GS/OS configures memory). ; - No stack base reset (GS/OS allocated and set our SP). ; - Honors GS/OS's DBR=our-bank, DP=allocated-page setup. -; - On main() return, calls GS/OS QUIT(pcount=2) to chain to a -; known next application (default: /SYSTEM/START.ORIG which -; test setups must save off the original boot launcher to). +; - On main() return, calls GS/OS QUIT(pcount=0) to return control to +; the launching program (Finder / shell / boot chain) — the standard +; GS/OS application exit. ; ; Entry from the System Loader (per Apple IIgs Toolbox Reference): ; E=0 (native), M=0 (16-bit accumulator), X=0 (16-bit index) @@ -33,18 +33,6 @@ __start: ; wrong bank without this. PHK + PLB copies PBR into DBR. phk plb - ; Diagnostic: stash a marker at $00:007F via `sta long` (bank- - ; explicit, immune to DBR uncertainty) immediately on entry. - ; Runtime probes use this to detect whether the Loader actually - ; reached our code or silently rejected the OMF earlier. - ; The assembler doesn't track SEP/REP state, so the LDA #imm - ; needs explicit `.byte` form: the standard `lda #$7F` would - ; assemble as 3 bytes (16-bit imm) and the trailing $00 would - ; execute as BRK at runtime once M=8. - sep #0x20 - .byte 0xa9, 0x7f ; lda #$7F (8-bit imm) - .byte 0x8f, 0x7f, 0x00, 0x00 ; sta long $00:007F - rep #0x20 ; Set DP=0. The C compiler assumes DP=0 for all `sta dp` and ; `[dp],y`-style accesses; GS/OS hands us a Memory-Manager- @@ -69,44 +57,28 @@ __start: ; LDAi16imm_bank expansion) rep #0x20 - ; --- Diagnostic markers between crt0 phases. Bank-explicit - ; `sta long` to $00:007E so they're visible from a host probe - ; regardless of DBR/PBR. - sep #0x20 - .byte 0xa9, 0x7e ; lda #$7E - .byte 0x8f, 0x7e, 0x00, 0x00 ; sta long $00:007E (post-DP) - rep #0x20 - - ; BSS zero-init. With DBR=our bank, `stz abs,X` writes to - ; ourBank:X — correct as long as __bss_start/__bss_end fit in - ; the segment's bank. - rep #0x30 + ; BSS zero-init. With DBR=our bank, `stz abs,X` writes to + ; ourBank:X — correct as long as __bss_start/__bss_end fit in the + ; segment's bank. M held at 8 across the loop (X stays 16-bit) so + ; we don't flip SEP/REP per byte. + rep #0x30 ; M=16, X=16 + sep #0x20 ; M=8 for the byte stores; X remains 16-bit ldx #__bss_start .Lbss_loop: cpx #__bss_end bcs .Lbss_done - sep #0x20 - stz 0x0000, x - rep #0x20 + stz 0x0000, x ; 1-byte store (M=8) inx bra .Lbss_loop .Lbss_done: - sep #0x20 - .byte 0xa9, 0x7d ; lda #$7D - .byte 0x8f, 0x7d, 0x00, 0x00 ; sta long $00:007D (post-BSS) - rep #0x20 + rep #0x20 ; restore M=16 - ; Walk .init_array (C++ ctors). - ; - ; ⚠ KNOWN BROKEN under real GS/OS Loader for non-zero-bank - ; placement: `jsl __jsl_indir` bakes a bank-0 operand at link - ; time. When the Loader places us at bank $1f or similar, the - ; JSL targets bank 0 (= GS/OS code) instead of our actual bank - ; — so this loop crashes if init_array has any entries. Same - ; applies to `jsl main` below. Closing the gap requires either - ; RELOC opcode emission in omfEmit (so the Loader patches the - ; JSL bank bytes at load time) or runtime self-patching of JSL - ; opcodes in crt0. Tracked separately. + ; Walk .init_array (C++ ctors). The `jsl __jsl_indir` and the + ; `jsl main` below are relocated by the GS/OS Loader: omfEmit emits + ; a cRELOC (0xF5) IMM24 site for each intra-segment JSL, so the + ; Loader patches the full 24-bit operand (bank included) to the + ; placed address. Non-zero-bank placement works as long as the OMF + ; is built with --relocs (demos/build.sh / buildGno.sh do). rep #0x30 ldx #__init_array_start .Linit_loop: @@ -127,86 +99,31 @@ __start: bra .Linit_loop .Linit_done: - ; Marker: about to JSL main. - sep #0x20 - .byte 0xa9, 0x7c ; lda #$7C - .byte 0x8f, 0x7c, 0x00, 0x00 ; sta long $00:007C (about to call main) - rep #0x20 - ; Call main. Standard W65816 C ABI: arg0 in A; we pass none. rep #0x30 jsl main - ; ---- QUIT (pcount=2) chain to gChainPath --------------------- - ; Parm block layout in DP $80..$87: - ; $80,$81 pcount = 2 - ; $82..$85 pathname long ptr (lo, mid, bank, pad) - ; $86,$87 flags = 0 - ; - ; The path is a GSString (2-byte length + chars). It must live - ; in bank-0 memory (GS/OS reads parm fields as bank-0). DP is in - ; bank 0, so we copy the GSString from our segment into DP $A0. - + ; ---- QUIT (pcount=0): return to the launching program ---------- + ; The standard GS/OS application exit. A pcount=0 parm block (just + ; a zero pcount word) tells QUIT to return control to whoever + ; launched us (Finder, a shell, the boot chain) with default flags + ; (non-restartable) — no hardcoded chain path needed. A program + ; that wants to chain elsewhere can provide its own _exit/crt0. rep #0x30 - - ; Copy length byte first to compute total bytes to copy. - sep #0x20 - lda gChainPath ; low byte of GSString length - clc - adc #2 ; +2 for the length word itself - tay ; Y = bytes to copy (paths < 256 chars) - rep #0x20 - - ldx #0 -.LcopyPath: - sep #0x20 - lda gChainPath, x ; DBR-relative read (DBR = our bank) - sta 0xa0, x ; DP write (in bank 0) - rep #0x20 - inx - dey - bne .LcopyPath - - ; Build parm block at DP $80. - rep #0x30 - lda #2 - sta 0x80 ; pcount - - tdc - clc - adc #0xa0 - sta 0x82 ; pathname long-ptr low+mid 16 - lda #0 - sta 0x84 ; bank byte (0) + pad byte (0) - sta 0x86 ; flags = 0 - - ; Push 32-bit parm-block pointer (low half + bank-0). + stz 0x80 ; pcount = 0 (parm block at DP $0080, bank 0) tdc clc adc #0x80 - pha - pea 0 + pha ; parm-block ptr: low 16 (offset) + pea 0 ; parm-block ptr: high 16 (bank 0) ldx #0x2029 ; QUIT class-1 call number jsl 0xe100a8 ; GS/OS dispatcher - ; QUIT only returns on failure. Clean up + BRK. + ; QUIT only returns on failure. Clean up the pushed pointer and + ; spin (don't fall into a BRK, which headless MAME mis-vectors). pla pla - .byte 0x00, 0x00 +.Lhang: + bra .Lhang .size __start, . - __start - - -; gChainPath — GSString chain target for QUIT after main(). Default -; is "/SYSTEM/START.ORIG" (saved-original boot launcher). Programs -; that need a different target must rename this symbol; the linker -; resolves whichever def is present. -; -; GSString: 2-byte length word + N chars. Length here = 18 -; ("/SYSTEM/START.ORIG"). - - .section .rodata,"a" - .globl gChainPath -gChainPath: - .byte 18, 0 - .ascii "/SYSTEM/START.ORIG" diff --git a/runtime/src/gnoGsos.s b/runtime/src/gnoGsos.s new file mode 100644 index 0000000..2061eb6 --- /dev/null +++ b/runtime/src/gnoGsos.s @@ -0,0 +1,42 @@ +; gnoGsos.s — GS/OS calls from inside a GNO/ME process. +; +; GNO patches GS/OS entry $E100A8 to its interceptor (OurGSOS in +; kern/gno/gsos.asm), which reads the call number + parameter-block +; pointer from the 6 INLINE bytes after the JSL and bumps the return +; address +6 to skip them: +; +; jsl $E100A8 +; dc i2 callNum ; 2 bytes +; dc i4 pBlockPtr ; 4 bytes (bank : offset) +; <-- OurGSOS returns here +; +; The plain stack-based form (callNum in X, pBlock pushed) that bare +; GS/OS accepts does NOT work under GNO. We self-modify the inline +; callNum + pBlock operands, then dispatch. +; +; __gnoGsosCall(void *pBlock, unsigned short callNum) -> u16 error +; C ABI: arg0 (pBlock ptr32) in A:X (A=offset, X=bank); arg1 +; (callNum i16) at (4,s). Returns the GS/OS error in A (0 = OK). + + .text + .globl __gnoGsosCall +__gnoGsosCall: + rep #0x30 + sta __gnoPBlock ; inline pBlock offset (low 16) + txa + sta __gnoPBlock+2 ; inline pBlock bank+pad (X = bank : pad) + lda 4, s ; callNum from the stack + sta __gnoCallNum ; inline callNum + lda 0xb4 ; restore GNO's per-process DP + tcd + jsl 0xe100a8 +__gnoCallNum: + .word 0 ; patched: GS/OS call number +__gnoPBlock: + .long 0 ; patched: param-block pointer + ; --- OurGSOS returns here (return addr bumped +6) --- + tay ; Y = error (survives DP change) + lda #0 + tcd ; DP := 0 for the C caller + tya + rtl diff --git a/runtime/src/gnoKernel.s b/runtime/src/gnoKernel.s new file mode 100644 index 0000000..98cfec3 --- /dev/null +++ b/runtime/src/gnoKernel.s @@ -0,0 +1,852 @@ +; AUTOGENERATED by scripts/genGnoKernel.py — DO NOT EDIT by hand. +; +; GNO/ME kernel toolset $03 wrappers. +; Dispatcher: JSL $E10000 with LDX #funcId. +; +; C ABI: arg0 (i16) in A, arg0 (i32) in A:X, arg1+ on stack +; (caller-pushed, lo-word first for 32-bit values). +; Each wrapper re-pushes args in Pascal order (high-word first +; for 32-bit), allocates result space, dispatches, pops result. + + .text + +; Kgetpid(void) -> i16 +; toolset 3, func 0x0903 + .section .text.Kgetpid,"ax" + .globl Kgetpid +Kgetpid: + ; --- result space (2 bytes) --- + pea 0 + ldx #0x0903 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kkill(i16, i16, i32) -> i16 +; toolset 3, func 0x0A03 + .section .text.Kkill,"ax" + .globl Kkill +Kkill: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (2B) --- + lda 8, s + pha + ; --- arg2 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x0A03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kfork(i32, i32) -> i16 +; toolset 3, func 0x0B03 + .section .text.Kfork,"ax" + .globl Kfork +Kfork: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ldx #0x0B03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kgetpid_dup(void) -> i16 +; toolset 3, func 0x0903 + .section .text.Kgetpid_dup,"ax" + .globl Kgetpid_dup +Kgetpid_dup: + ; --- result space (2 bytes) --- + pea 0 + ldx #0x0903 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kgetppid(i32) -> i16 +; toolset 3, func 0x4003 + .section .text.Kgetppid,"ax" + .globl Kgetppid +Kgetppid: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ldx #0x4003 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kwait(i32, i32) -> i16 +; toolset 3, func 0x1703 + .section .text.Kwait,"ax" + .globl Kwait +Kwait: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ldx #0x1703 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; K_execve(i32, i32, i32) -> i16 +; toolset 3, func 0x1D03 + .section .text.K_execve,"ax" + .globl K_execve +K_execve: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ; --- arg2 (4B) --- + lda 20, s + pha + lda 20, s + pha + ldx #0x1D03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ksignal(i16, i32, i32) -> i32 +; toolset 3, func 0x1603 + .section .text.Ksignal,"ax" + .globl Ksignal +Ksignal: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (4 bytes) --- + pea 0 + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ; --- arg2 (4B) --- + lda 20, s + pha + lda 20, s + pha + ldx #0x1603 + jsl 0xe10000 + pla ; result lo -> A + plx ; result hi -> X + rtl + +; Kalarm(i32, i32) -> i32 +; toolset 3, func 0x1E03 + .section .text.Kalarm,"ax" + .globl Kalarm +Kalarm: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (4 bytes) --- + pea 0 + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x1E03 + jsl 0xe10000 + pla ; result lo -> A + plx ; result hi -> X + rtl + +; Kalarm10(i32, i32) -> i32 +; toolset 3, func 0x4203 + .section .text.Kalarm10,"ax" + .globl Kalarm10 +Kalarm10: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (4 bytes) --- + pea 0 + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x4203 + jsl 0xe10000 + pla ; result lo -> A + plx ; result hi -> X + rtl + +; Ksigpause(i32, i32) -> i16 +; toolset 3, func 0x2103 + .section .text.Ksigpause,"ax" + .globl Ksigpause +Ksigpause: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ldx #0x2103 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ksigsetmask(i32, i32) -> i32 +; toolset 3, func 0x1B03 + .section .text.Ksigsetmask,"ax" + .globl Ksigsetmask +Ksigsetmask: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (4 bytes) --- + pea 0 + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x1B03 + jsl 0xe10000 + pla ; result lo -> A + plx ; result hi -> X + rtl + +; Ksigblock(i32, i32) -> i32 +; toolset 3, func 0x1C03 + .section .text.Ksigblock,"ax" + .globl Ksigblock +Ksigblock: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (4 bytes) --- + pea 0 + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x1C03 + jsl 0xe10000 + pla ; result lo -> A + plx ; result hi -> X + rtl + +; Kdup(i16, i32) -> i16 +; toolset 3, func 0x2203 + .section .text.Kdup,"ax" + .globl Kdup +Kdup: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ldx #0x2203 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kdup2(i16, i16, i32) -> i16 +; toolset 3, func 0x2303 + .section .text.Kdup2,"ax" + .globl Kdup2 +Kdup2: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (2B) --- + lda 8, s + pha + ; --- arg2 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x2303 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kpipe(i32, i32) -> i16 +; toolset 3, func 0x2403 + .section .text.Kpipe,"ax" + .globl Kpipe +Kpipe: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ldx #0x2403 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kioctl(i16, i32, i32, i32) -> i16 +; toolset 3, func 0x2603 + .section .text.Kioctl,"ax" + .globl Kioctl +Kioctl: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ; --- arg2 (4B) --- + lda 18, s + pha + lda 18, s + pha + ; --- arg3 (4B) --- + lda 26, s + pha + lda 26, s + pha + ldx #0x2603 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kstat(i32, i32, i32) -> i16 +; toolset 3, func 0x2703 + .section .text.Kstat,"ax" + .globl Kstat +Kstat: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ; --- arg2 (4B) --- + lda 20, s + pha + lda 20, s + pha + ldx #0x2703 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kfstat(i16, i32, i32) -> i16 +; toolset 3, func 0x2803 + .section .text.Kfstat,"ax" + .globl Kfstat +Kfstat: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ; --- arg2 (4B) --- + lda 18, s + pha + lda 18, s + pha + ldx #0x2803 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Klstat(i32, i32, i32) -> i16 +; toolset 3, func 0x2903 + .section .text.Klstat,"ax" + .globl Klstat +Klstat: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ; --- arg2 (4B) --- + lda 20, s + pha + lda 20, s + pha + ldx #0x2903 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kgetuid(i32) -> i16 +; toolset 3, func 0x2A03 + .section .text.Kgetuid,"ax" + .globl Kgetuid +Kgetuid: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ldx #0x2A03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kgetgid(i32) -> i16 +; toolset 3, func 0x2B03 + .section .text.Kgetgid,"ax" + .globl Kgetgid +Kgetgid: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ldx #0x2B03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kgeteuid(i32) -> i16 +; toolset 3, func 0x2C03 + .section .text.Kgeteuid,"ax" + .globl Kgeteuid +Kgeteuid: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ldx #0x2C03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kgetegid(i32) -> i16 +; toolset 3, func 0x2D03 + .section .text.Kgetegid,"ax" + .globl Kgetegid +Kgetegid: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ldx #0x2D03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ksetuid(i16, i32) -> i16 +; toolset 3, func 0x2E03 + .section .text.Ksetuid,"ax" + .globl Ksetuid +Ksetuid: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ldx #0x2E03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ksetgid(i16, i32) -> i16 +; toolset 3, func 0x2F03 + .section .text.Ksetgid,"ax" + .globl Ksetgid +Ksetgid: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ldx #0x2F03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ktcnewpgrp(i16, i32) -> i16 +; toolset 3, func 0x1803 + .section .text.Ktcnewpgrp,"ax" + .globl Ktcnewpgrp +Ktcnewpgrp: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ldx #0x1803 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ksettpgrp(i16, i32) -> i16 +; toolset 3, func 0x1903 + .section .text.Ksettpgrp,"ax" + .globl Ksettpgrp +Ksettpgrp: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ldx #0x1903 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ktctpgrp(i16, i16, i32) -> i16 +; toolset 3, func 0x1A03 + .section .text.Ktctpgrp,"ax" + .globl Ktctpgrp +Ktctpgrp: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (2B) --- + lda 8, s + pha + ; --- arg2 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x1A03 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; K_getpgrp(i16, i32) -> i16 +; toolset 3, func 0x2503 + .section .text.K_getpgrp,"ax" + .globl K_getpgrp +K_getpgrp: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 10, s + pha + lda 10, s + pha + ldx #0x2503 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ksetpgrp(i16, i16, i32) -> i16 +; toolset 3, func 0x3403 + .section .text.Ksetpgrp,"ax" + .globl Ksetpgrp +Ksetpgrp: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (2B) --- + lda 8, s + pha + ; --- arg2 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x3403 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kkvm_open(i32) -> i16 +; toolset 3, func 0x1103 + .section .text.Kkvm_open,"ax" + .globl Kkvm_open +Kkvm_open: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ldx #0x1103 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Kkvm_close(i32, i32) -> i16 +; toolset 3, func 0x1203 + .section .text.Kkvm_close,"ax" + .globl Kkvm_close +Kkvm_close: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (2 bytes) --- + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 12, s + pha + lda 12, s + pha + ldx #0x1203 + jsl 0xe10000 + pla ; result lo -> A + rtl + +; Ktimes(i32, i32) -> i32 +; toolset 3, func 0x3503 + .section .text.Ktimes,"ax" + .globl Ktimes +Ktimes: + ; --- stash arg0 (in A/X) --- + sta 0xE0 + stx 0xE2 + ; --- result space (4 bytes) --- + pea 0 + pea 0 + ; --- arg0 --- + lda 0xE2 + pha + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 14, s + pha + lda 14, s + pha + ldx #0x3503 + jsl 0xe10000 + pla ; result lo -> A + plx ; result hi -> X + rtl + +; KSetGNOQuitRec(i16, i32, i16, i32) -> void +; toolset 3, func 0x4103 + .section .text.KSetGNOQuitRec,"ax" + .globl KSetGNOQuitRec +KSetGNOQuitRec: + ; --- stash arg0 (in A) --- + sta 0xE0 + ; --- arg0 --- + lda 0xE0 + pha + ; --- arg1 (4B) --- + lda 8, s + pha + lda 8, s + pha + ; --- arg2 (2B) --- + lda 14, s + pha + ; --- arg3 (4B) --- + lda 20, s + pha + lda 20, s + pha + ldx #0x4103 + jsl 0xe10000 + rtl diff --git a/runtime/src/libc.c b/runtime/src/libc.c index de80b47..cc3ebdf 100644 --- a/runtime/src/libc.c +++ b/runtime/src/libc.c @@ -51,6 +51,14 @@ typedef struct { u16 refNum; unsigned long position; } __GsosMarkRecGS; +typedef struct { + u16 pCount; + void *pathname; + u16 access; + u16 fileType; + unsigned long auxType; + u16 storageType; +} __GsosCreateParm; // Weak so programs that never call into the GS/OS file backend don't // drag iigsGsos.o into the link. fopen guards GSOS path on a NULL // check (see __gsosAvailable below). @@ -62,6 +70,7 @@ extern u16 gsosGetEOF (__GsosEOFRecGS *p) __attribute__((weak)); extern u16 gsosSetEOF (__GsosEOFRecGS *p) __attribute__((weak)); extern u16 gsosSetMark(__GsosMarkRecGS *p) __attribute__((weak)); extern u16 gsosGetMark(__GsosMarkRecGS *p) __attribute__((weak)); +extern u16 gsosCreate (__GsosCreateParm *p) __attribute__((weak)); static int __gsosAvailable(void) { // gsosOpen is the entry point — if iigsGsos.o is linked, all the @@ -219,8 +228,16 @@ int atoi(const char *s) { // glue, or a console emulator) override this with a strong // definition. Marked `weak` so users can replace it. __attribute__((weak)) +// Console byte sink. Default writes the IIgs MAME console hook at $E2. +// A hosted environment (e.g. GNO/ME) provides a strong __putByte that +// routes to its console (see runtime/src/libcGno.c). +extern void __putByte(char c) __attribute__((weak)); + int putchar(int c) { - *(volatile char *)0xE2 = (char)c; + if (__putByte) + __putByte((char)c); + else + *(volatile char *)0xE2 = (char)c; return c; } @@ -241,7 +258,14 @@ int puts(const char *s) { // // Callers wanting non-blocking input or Event Manager integration // should call ReadCh/GetNextEvent directly via iigs/toolbox.h. +// Console byte source. Default polls the IIgs keyboard at $C000. A +// hosted environment (GNO/ME) provides a strong __getByte that reads +// its console (returns -1 on EOF). +extern int __getByte(void) __attribute__((weak)); + int getchar(void) { + if (__getByte) + return __getByte(); volatile unsigned char *kbd = (volatile unsigned char *)0xC000; volatile unsigned char *strb = (volatile unsigned char *)0xC010; while (((*kbd) & 0x80) == 0) { @@ -926,6 +950,22 @@ clock_t clock(void) { #define FILE_KIND_MEM 3 #define FILE_KIND_GSOS 4 +// Console byte sink for stderr. A hosted environment (GNO/ME) provides +// a strong __putByteErr that targets the stderr stream (GNO fd 3); when +// absent, stderr just shares stdout's sink (the historical behavior). +extern void __putByteErr(char c) __attribute__((weak)); + +// Write one byte to the stdout (kind 1) or stderr (kind 2) console +// stream. Single dispatch point so every stderr write path routes to +// the right backend hook without duplicating the test. +static int putcharStd(int kind, int c) { + if (kind == FILE_KIND_STDERR && __putByteErr) { + __putByteErr((char)c); + return c; + } + return putchar(c); +} + typedef struct __sFILE { u8 kind; u8 writable; @@ -1006,7 +1046,7 @@ int mfsUnregister(const char *path) { int fputc(int c, FILE *stream) { if (!stream) return -1; if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR) - return putchar(c); + return putcharStd(stream->kind, c); if (stream->kind == FILE_KIND_MEM) { if (!stream->writable) { stream->err = 1; return -1; } if (stream->pos >= stream->cap) { stream->err = 1; return -1; } @@ -1030,7 +1070,7 @@ int fputc(int c, FILE *stream) { int fputs(const char *s, FILE *stream) { if (!stream || !s) return -1; if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR) { - while (*s) { putchar(*s); s++; } + while (*s) { putcharStd(stream->kind, *s); s++; } return 0; } if (stream->kind == FILE_KIND_MEM || stream->kind == FILE_KIND_GSOS) { @@ -1083,8 +1123,21 @@ int fprintf(FILE *stream, const char *fmt, ...) { int vfprintf(FILE *stream, const char *fmt, va_list ap) { if (!stream) return -1; - if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR) + if (stream->kind == FILE_KIND_STDOUT) return vprintf(fmt, ap); + if (stream->kind == FILE_KIND_STDERR) { + // Route formatted stderr output to the stderr console hook (GNO + // fd 3) rather than vprintf's stdout putchar. Format into a + // stack buffer, then emit byte-by-byte via putcharStd. + char tmp[256]; + int n = vsnprintf(tmp, sizeof(tmp), fmt, ap); + if (n < 0) return -1; + size_t outLen = ((size_t)n < sizeof(tmp) - 1) + ? (size_t)n : sizeof(tmp) - 1; + for (size_t i = 0; i < outLen; i++) + putcharStd(FILE_KIND_STDERR, tmp[i]); + return n; + } if (stream->kind == FILE_KIND_GSOS) { // Format into a stack buffer, then push to GS/OS via fwrite. // 256 bytes covers most format-string outputs; longer strings @@ -1269,6 +1322,16 @@ FILE *fopen(const char *path, const char *mode) { // → NULL. if (!__gsosAvailable()) return (FILE *)0; if (__buildGSString(path) < 0) return (FILE *)0; + // For write/append modes, Create the file first (GS/OS Open does + // not create). A "duplicate filename" ($47) result is fine — the + // file already exists. Guarded on the weak gsosCreate so bare + // builds without it keep the old write-existing-only behavior. + if (wantWrite && gsosCreate) { + // access $C3 (destroy/rename/write/read), fileType $04 (TXT), + // auxType 0, storageType 1 (seedling — GS/OS grows as needed). + __GsosCreateParm cp = { 5, &__gsosPathBuf, 0xC3, 0x04, 0, 1 }; + (void)gsosCreate(&cp); // ignore result; Open reports real errors + } // pCount=3 covers refNum + pathname + requestAccess. GS/OS 6.0.2 // Open ($2010) requires requestAccess to be non-zero for any actual // open; passing only pCount=2 (refNum + pathname) leaves the access @@ -1372,7 +1435,7 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR) { size_t items = 0; while (items < nmemb) { - for (size_t b = 0; b < size; b++) putchar(*in++); + for (size_t b = 0; b < size; b++) putcharStd(stream->kind, *in++); items++; } return items; diff --git a/runtime/src/libcGno.c b/runtime/src/libcGno.c new file mode 100644 index 0000000..a873365 --- /dev/null +++ b/runtime/src/libcGno.c @@ -0,0 +1,295 @@ +// libcGno.c — GNO/ME backend for our libc. +// +// Two roles: +// 1. The GNO half of stdio: provides the GS/OS class-1 call wrappers +// (gsosOpen/Read/Write/Close/...) that libc.c's FILE* layer calls +// via weak externs, using GNO's INLINE GS/OS dispatch — so fopen / +// fread / fwrite / fprintf / fgets to real GS/OS files Just Work. +// Also provides the __putByte / __getByte console hooks libc.c +// uses for putchar / getchar, routing them to the GNO console. +// 2. POSIX process glue: __gnoStartup (argv parse + main), _exit, and +// the fork/exec/wait/etc. wrappers over the K* kernel primitives. + +#include +#include + +extern int main(int argc, char **argv); + +// GS/OS class-1 paramblock shapes (layout-matched to libc.c's). +typedef struct { + uint16_t pCount; + uint16_t refNum; + void *dataBuffer; + unsigned long requestCount; + unsigned long transferCount; +} GnoIORec; +typedef struct { uint16_t pCount; uint16_t refNum; void *pathname; uint16_t requestAccess; } GnoOpenParm; +typedef struct { uint16_t pCount; uint16_t refNum; } GnoRefNumRec; +typedef struct { uint16_t pCount; uint16_t refNum; unsigned long val; } GnoEOFRec; +typedef struct { uint16_t pCount; uint16_t refNum; unsigned long val; } GnoMarkRec; +typedef struct { uint16_t pCount; void *pathname; uint16_t access; uint16_t fileType; unsigned long auxType; uint16_t storageType; } GnoCreateParm; + +// GS/OS class-1 call numbers. +#define GSOS_CREATE 0x2001 +#define GSOS_OPEN 0x2010 +#define GSOS_READ 0x2012 +#define GSOS_WRITE 0x2013 +#define GSOS_CLOSE 0x2014 +#define GSOS_SETMARK 0x2016 +#define GSOS_GETMARK 0x2017 +#define GSOS_SETEOF 0x2018 +#define GSOS_GETEOF 0x2019 + +// Generic inline-form GS/OS dispatch (asm helper, runtime/src/gnoGsos.s). +// GNO's $E100A8 interceptor reads callNum + pBlock from the inline bytes +// after the JSL; the helper self-modifies them and restores GNO's +// process DP around the call. Returns the GS/OS error (0 = OK). +extern uint16_t __gnoGsosCall(void *pBlock, unsigned short callNum); + + +// ---- GS/OS file-call wrappers (override libc.c's weak externs) ------- +// libc.c's FILE* layer (fopen with FILE_KIND_GSOS, fread/fwrite/fgetc/ +// fputc/fclose) calls these. Routing them through GNO's inline dispatch +// makes the whole buffered-stdio surface work for real GS/OS files. +uint16_t gsosCreate(GnoCreateParm *p){ return __gnoGsosCall(p, GSOS_CREATE); } +uint16_t gsosOpen(GnoOpenParm *p) { return __gnoGsosCall(p, GSOS_OPEN); } +uint16_t gsosRead(GnoIORec *p) { return __gnoGsosCall(p, GSOS_READ); } +uint16_t gsosWrite(GnoIORec *p) { return __gnoGsosCall(p, GSOS_WRITE); } +uint16_t gsosClose(GnoRefNumRec *p) { return __gnoGsosCall(p, GSOS_CLOSE); } +uint16_t gsosGetEOF(GnoEOFRec *p) { return __gnoGsosCall(p, GSOS_GETEOF); } +uint16_t gsosSetEOF(GnoEOFRec *p) { return __gnoGsosCall(p, GSOS_SETEOF); } +uint16_t gsosSetMark(GnoMarkRec *p) { return __gnoGsosCall(p, GSOS_SETMARK); } +uint16_t gsosGetMark(GnoMarkRec *p) { return __gnoGsosCall(p, GSOS_GETMARK); } + + +// ---- console hooks (override libc.c's weak __putByte/__getByte) ------ +// GNO fds are 1-based GS/OS refNums mapped through the per-process +// open-files table by the kernel's GS/OS interceptor (GNORdWr, +// kern/gno/gsos.asm:1794): stdin = 1, stdout = 2, stderr = 3 +// (include/unistd.h:51-53; main.c:388-390). A GS/OS Read/Write with +// that refNum is the exact mechanism GNO's own libc read()/write() use +// (lib/libc/sys/syscall.c:756/1271) -- the interceptor routes it to the +// file ('<'), pipe ('|'), or TTY behind the fd, so redirection is +// honored transparently. putchar/getchar in libc.c route here; the +// rest of stdio (puts/printf/fgets/...) builds on them. +// +// GNO 1-based fd indices for the inherited standard streams. +#define GNO_FD_STDIN 1 +#define GNO_FD_STDOUT 2 +#define GNO_FD_STDERR 3 + +// GS/OS error returned at end-of-file ($4C). GNO's read() treats this +// as a successful (possibly short) transfer, not a hard error +// (syscall.c:765; texttool.asm:2250). +#define GSOS_ERR_EOF 0x4C + +void __putByte(char c) { + if (c == '\n') c = '\r'; // GNO console (Apple II TTY) wants CR + GnoIORec r = { 4, GNO_FD_STDOUT, &c, 1, 0 }; + __gnoGsosCall(&r, GSOS_WRITE); +} + +// Strong override for stderr (libc.c routes FILE_KIND_STDERR here). +// stderr is fd 3 -- distinct from stdout so '2>file' redirection works. +void __putByteErr(char c) { + if (c == '\n') c = '\r'; + GnoIORec r = { 4, GNO_FD_STDERR, &c, 1, 0 }; + __gnoGsosCall(&r, GSOS_WRITE); +} + +int __getByte(void) { + unsigned char c; + GnoIORec r = { 4, GNO_FD_STDIN, &c, 1, 0 }; + uint16_t err = __gnoGsosCall(&r, GSOS_READ); + // Match GNO's read(): err 0 OR $4C is a valid transfer; only a + // zero-byte transfer is genuine EOF. Reading refNum 1 reaches the + // live inherited stdin -- the file behind '<', the pipe behind '|', + // or the console TTY -- via the kernel's GNORdWr interceptor. + if ((err != 0 && err != GSOS_ERR_EOF) || r.transferCount != 1) + return -1; // EOF / error + return (int)c; +} + + +// ---- raw POSIX read/write (used by demos that want fd-level I/O) ----- +// POSIX callers pass Unix 0/1/2; GNO's fd table is 1-based (stdin = 1), +// so translate 0/1/2 -> 1/2/3 in one place. Any other fd is assumed to +// already be a GNO 1-based fd (e.g. from pipe()/dup()) and passed +// straight through. +static uint16_t gnoFd(int fd) { + if (fd >= 0 && fd <= 2) + return (uint16_t)(fd + 1); + return (uint16_t)fd; +} + + +long write(int fd, const void *buf, unsigned long n) { + GnoIORec r = { 4, gnoFd(fd), (void *)buf, n, 0 }; + if (__gnoGsosCall(&r, GSOS_WRITE) != 0) return -1; + return (long)r.transferCount; +} + +long read(int fd, void *buf, unsigned long n) { + GnoIORec r = { 4, gnoFd(fd), buf, n, 0 }; + uint16_t err = __gnoGsosCall(&r, GSOS_READ); + if (err != 0 && err != GSOS_ERR_EOF) return -1; + return (long)r.transferCount; +} + + +// Tokenize cmdline in-place using simple whitespace rules. GNO's +// shell does proper quote handling — we'll match that once we have a +// test harness to drive it. For the initial hello-world the cmdline +// is just the program name (no args), so a degenerate parser suffices. +// +// Writes into the static argv[] and writable copy buf[]. Caps argc +// at 31; longer command lines have their tail args silently dropped. +#define ARG_MAX 32 +#define CMD_MAX 256 + +static char argBuf[CMD_MAX]; +static char *argVec[ARG_MAX]; + + +static int parseCmdline(const char *cmd, char ***argvOut) { + int n = 0; + int i = 0; + // Copy cmdline into our writable buffer up to CMD_MAX-1. + while (i < CMD_MAX - 1 && cmd[i]) { + argBuf[i] = cmd[i]; + i++; + } + argBuf[i] = 0; + + // Tokenize on whitespace. Replace separator runs with NULs, + // record argv entries pointing at the first non-NUL char of each + // run. + char *p = argBuf; + while (n < ARG_MAX - 1 && *p) { + while (*p == ' ' || *p == '\t') + p++; + if (!*p) + break; + argVec[n++] = p; + while (*p && *p != ' ' && *p != '\t') + p++; + if (*p) + *p++ = 0; + } + argVec[n] = 0; + *argvOut = argVec; + return n; +} + + +// crt0Gno.s entry point. Receives the command-line pointer the kernel +// handed us (Y:X on entry; crt0 forwards it as a ptr32 arg here). +// GNO prepends an 8-byte "BYTEWRKS" signature to the command line +// (kern/gno/sys.c builds child->args = "BYTEWRKS" + name; ~GNO_PARSEARG +// skips it with `add4 commandline,#8`). Skip those 8 bytes, parse into +// argc/argv, invoke main(), and return to crt0 for the QUIT call. +int __gnoStartup(const char *cmdline) { + char **argv; + int argc; + if (cmdline) cmdline += 8; // skip "BYTEWRKS" prefix + argc = parseCmdline(cmdline, &argv); + return main(argc, argv); +} + + +// GS/OS QUIT ($2029) paramblock. pCount=0 => plain QUIT: GNO's +// CommonQuit reaps the process and returns control to the launcher (gsh). +typedef struct { uint16_t pCount; } GnoQuitParm; + +#define GSOS_QUIT 0x2029 + +// _exit: GNO/ME program termination via GS/OS QUIT, issued through the +// SAME inline GS/OS dispatch (__gnoGsosCall) as every other call here. +// +// Critical: this MUST use the inline form, not the stack-based form +// (`ldx #$2029 ; jsl $e100a8` with the pblock pushed). GNO patches +// $E100A8 to OurGSOS, which reads the call number + pblock from the 6 +// inline bytes AFTER the jsl. The stack form leaves those inline bytes +// as whatever opcode follows, so OurGSOS mis-dispatches the QUIT and the +// process is left restartable — GNO then RE-RUNS main() (observed: +// main executes twice, silently draining redirected stdin on the first +// pass). Routing QUIT through __gnoGsosCall (inline form + process-DP +// restore) terminates cleanly, so main() runs exactly once. +__attribute__((noreturn)) +void _exit(int status) { + (void)status; + GnoQuitParm q = { 0 }; // pCount=0 — plain QUIT to launcher + __gnoGsosCall(&q, GSOS_QUIT); // inline dispatch; does not return + for (;;) { } // unreachable +} + + +// Stubs for the K*-wrapped POSIX surface. These mirror what +// runtime/src/gnoKernel.s already provides; we just rename them. +// Errno handling: each K* takes a `int *errno` arg; on failure the +// kernel writes the errno value there and returns -1. Our wrappers +// stash it into the global `errno` variable. +// +// Only the minimum needed for the demo is non-trivial — the rest +// are scaffold-only and will be filled in as we add tests. + +extern int errno; // defined in libc.c + + +int fork(void) { + int err = 0; + int r = Kfork(0, &err); + if (r < 0) errno = err; + return r; +} + + +int kill(int pid, int sig) { + int err = 0; + int r = Kkill(pid, sig, &err); + if (r < 0) errno = err; + return r; +} + + +int getpid(void) { + return Kgetpid(); +} + + +int getppid(void) { + int err = 0; + int r = Kgetppid(&err); + if (r < 0) errno = err; + return r; +} + + +int dup(int oldfd) { + int err = 0; + int r = Kdup(oldfd, &err); + if (r < 0) errno = err; + return r; +} + + +int dup2(int oldfd, int newfd) { + int err = 0; + int r = Kdup2(oldfd, newfd, &err); + if (r < 0) errno = err; + return r; +} + + +int pipe(int fds[2]) { + int err = 0; + int r = Kpipe(fds, &err); + if (r < 0) errno = err; + return r; +} + + +unsigned long alarm(unsigned long seconds) { + int err = 0; + return Kalarm((void *)seconds, &err); +} diff --git a/runtime/src/snprintf.c b/runtime/src/snprintf.c index 158c0ae..025a40f 100644 --- a/runtime/src/snprintf.c +++ b/runtime/src/snprintf.c @@ -204,9 +204,6 @@ static void emitDouble(double v, int prec, char spec) { // fmt is arg0 (A register); see banner comment for why the order matters. -// Previously optnone (slot-alias bug under p:16:16; see -// feedback_snprintf_va_arg_slot_alias.md). Re-enabled greedy under -// ptr32 — testing whether the bug recurs. static int format(const char *fmt, va_list ap) { while (*fmt) { char c = *fmt++; diff --git a/scripts/genGnoKernel.py b/scripts/genGnoKernel.py new file mode 100644 index 0000000..11ace72 --- /dev/null +++ b/scripts/genGnoKernel.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 +# genGnoKernel.py — generate wrappers for the GNO kernel toolset. +# +# The GNO kernel is implemented as Apple IIgs user toolset $03. Each +# kernel function is identified by a 16-bit number $XX03 where XX is +# the function index and 03 is the toolset. The dispatcher is the +# standard IIgs tool dispatcher at $E10000. +# +# Function list is hard-coded from include/gno/kerntool.h in the GNO +# Consortium source (https://github.com/GnoConsortium/gno). The +# canonical ORCA-style signature is preserved in a comment. +# +# Output: runtime/src/gnoKernel.s — asm wrappers callable from our C +# ABI (arg0 in A, arg0 i32 in A:X, rest pushed RTL on stack). Each +# wrapper re-pushes args in toolbox/Pascal order (high-word first for +# 32-bit values), allocates result space, JSLs $E10000, pops the +# result back into A:X if non-void. +# +# Run after editing the function table: +# python3 scripts/genGnoKernel.py +# +# The libc layer in runtime/src/libcGno.c wraps these K* primitives +# into POSIX names (fork, exec, wait, etc.). + +from pathlib import Path + +OUT_ASM = Path("/home/scott/claude/llvm816/runtime/src/gnoKernel.s") +OUT_HEADER = Path("/home/scott/claude/llvm816/runtime/include/gno/kernel.h") + +# Each entry: (funcId, name, retSize, [argSize, ...]) +# Sizes in bytes (2 = i16, 4 = i32 / ptr32). Names follow ORCA's K* prefix. +# +# Pulled from include/gno/kerntool.h in the GNO Consortium repo. +SYSCALLS = [ + # ---- Process control ---- + (0x0903, "Kgetpid", 2, []), # () -> int + (0x0A03, "Kkill", 2, [2, 2, 4]), # (pid, sig, *errno) -> int + (0x0B03, "Kfork", 2, [4, 4]), # (*subr, *errno) -> int + (0x0903, "Kgetpid_dup", 2, []), # alias kept for sanity check + (0x4003, "Kgetppid", 2, [4]), # (*errno) -> int + (0x1703, "Kwait", 2, [4, 4]), # (*status, *errno) -> int + (0x1D03, "K_execve", 2, [4, 4, 4]), # (*file, *cmdline, *err) -> int + (0x1603, "Ksignal", 4, [2, 4, 4]), # (sig, func_ptr, *err) -> sig_t + (0x1E03, "Kalarm", 4, [4, 4]), # (seconds, *errno) -> longword + (0x4203, "Kalarm10", 4, [4, 4]), # (seconds-tenths, *errno) -> longword + (0x2103, "Ksigpause", 2, [4, 4]), # (mask, *errno) -> int + (0x1B03, "Ksigsetmask", 4, [4, 4]), # (mask, *errno) -> longword + (0x1C03, "Ksigblock", 4, [4, 4]), # (mask, *errno) -> longword + + # ---- File descriptors ---- + (0x2203, "Kdup", 2, [2, 4]), # (oldfd, *errno) -> int + (0x2303, "Kdup2", 2, [2, 2, 4]), # (oldfd, newfd, *errno) -> int + (0x2403, "Kpipe", 2, [4, 4]), # (*fildes[2], *errno) -> int + (0x2603, "Kioctl", 2, [2, 4, 4, 4]), # (fd, req:ulong, *ptr, *errno) -> int + + # ---- stat ---- + (0x2703, "Kstat", 2, [4, 4, 4]), # (*path, *sbuf, *errno) -> int + (0x2803, "Kfstat", 2, [2, 4, 4]), # (fd, *sbuf, *errno) -> int + (0x2903, "Klstat", 2, [4, 4, 4]), # (*path, *sbuf, *errno) -> int + + # ---- IDs ---- + (0x2A03, "Kgetuid", 2, [4]), # (*errno) -> int + (0x2B03, "Kgetgid", 2, [4]), # (*errno) -> int + (0x2C03, "Kgeteuid", 2, [4]), # (*errno) -> int + (0x2D03, "Kgetegid", 2, [4]), # (*errno) -> int + (0x2E03, "Ksetuid", 2, [2, 4]), # (uid, *errno) -> int + (0x2F03, "Ksetgid", 2, [2, 4]), # (gid, *errno) -> int + + # ---- Process groups / TTY ---- + (0x1803, "Ktcnewpgrp", 2, [2, 4]), # (fdtty, *errno) -> int + (0x1903, "Ksettpgrp", 2, [2, 4]), # (fdtty, *errno) -> int + (0x1A03, "Ktctpgrp", 2, [2, 2, 4]), # (fdtty, pid, *err) -> int + (0x2503, "K_getpgrp", 2, [2, 4]), # (pid, *errno) -> pid_t + (0x3403, "Ksetpgrp", 2, [2, 2, 4]), # (pid, pgrp, *errno) -> int + + # ---- Kernel VM (process inspection) ---- + (0x1103, "Kkvm_open", 2, [4]), # (*errno) -> int + (0x1203, "Kkvm_close", 2, [4, 4]), # (kvmt, *errno) -> int + + # ---- Misc ---- + (0x3503, "Ktimes", 4, [4, 4]), # (*tms, *errno) -> clock_t + + # ---- Quit setup ---- + (0x4103, "KSetGNOQuitRec", 0, [2, 4, 2, 4]), # (pCount, GSStringPtr, flags, *err) -> void +] + +DISPATCHER = 0xE10000 + + +def emitWrapper(funcId, name, retSize, argSizes): + """Emit one .s function body for the given GNO kernel call.""" + lines = [] + argTypes = [f"i{size*8}" for size in argSizes] + lines.append(f"; {name}({', '.join(argTypes) or 'void'}) -> " + f"{'void' if retSize == 0 else f'i{retSize*8}'}") + lines.append(f"; toolset 3, func 0x{funcId:04X}") + lines.append(f"\t.section .text.{name},\"ax\"") + lines.append(f"\t.globl {name}") + lines.append(f"{name}:") + + scratchDP = 0xE0 + firstArgIs32 = bool(argSizes) and argSizes[0] == 4 + + # Stash arg0 if any args. arg0 in A (i16) or A:X (i32). + if argSizes: + lines.append(f"\t; --- stash arg0 (in A{'/X' if firstArgIs32 else ''}) ---") + lines.append(f"\tsta 0x{scratchDP:02X}") + if firstArgIs32: + lines.append(f"\tstx 0x{scratchDP + 2:02X}") + + # Result space (rounded up to whole words). + resultWords = (retSize + 1) // 2 + if resultWords > 0: + lines.append(f"\t; --- result space ({retSize} bytes) ---") + for _ in range(resultWords): + lines.append("\tpea 0") + + # Push args in Pascal order (high-word first for 32-bit). + pushedBytes = resultWords * 2 + + # arg0. + if argSizes: + lines.append("\t; --- arg0 ---") + if firstArgIs32: + lines.append(f"\tlda 0x{scratchDP + 2:02X}") + lines.append("\tpha") + pushedBytes += 2 + lines.append(f"\tlda 0x{scratchDP:02X}") + lines.append("\tpha") + pushedBytes += 2 + + # arg1+. + stackArgOffset = 4 # caller's first stack arg (after 3-byte JSL ret addr) + for i, size in enumerate(argSizes[1:], start=1): + lines.append(f"\t; --- arg{i} ({size}B) ---") + if size <= 2: + lines.append(f"\tlda {stackArgOffset + pushedBytes}, s") + lines.append("\tpha") + pushedBytes += 2 + stackArgOffset += 2 + elif size == 4: + # High word first. Caller pushed low-word-first, so HI is at + # caller offset +2. After PHA, the LO becomes accessible at + # the SAME stack-rel offset (PHA shifted SP by 2). + lines.append(f"\tlda {stackArgOffset + pushedBytes + 2}, s") + lines.append("\tpha") + pushedBytes += 2 + lines.append(f"\tlda {stackArgOffset + pushedBytes}, s") + lines.append("\tpha") + pushedBytes += 2 + stackArgOffset += 4 + else: + raise RuntimeError(f"unhandled arg size {size} in {name}") + + # Dispatch. + lines.append(f"\tldx #0x{funcId:04X}") + lines.append(f"\tjsl 0x{DISPATCHER:x}") + + # Pop result. + if resultWords > 0: + lines.append("\tpla ; result lo -> A") + if resultWords == 2: + lines.append("\tplx ; result hi -> X") + lines.append("\trtl") + lines.append("") + return lines + + +def emitHeader(): + """Generate a C header with extern decls for use by libc.""" + hLines = [ + "// AUTOGENERATED by scripts/genGnoKernel.py — DO NOT EDIT.", + "// GNO kernel toolset $03 wrappers, callable from C.", + "// Convention: each K* returns the kernel result (or -1 on error);", + "// the last argument is `int *errno` and gets the kernel's errno.", + "//", + "// These are LOW-LEVEL primitives — libc routines in libcGno.c", + "// wrap them into POSIX-named fork/exec/wait/etc.", + "#ifndef GNO_KERNEL_H", + "#define GNO_KERNEL_H", + "", + "#include ", + "", + ] + for funcId, name, retSize, argSizes in SYSCALLS: + # Skip the sanity-check duplicate. + if name.endswith("_dup"): + continue + retC = "void" if retSize == 0 else ( + "int" if retSize == 2 else "unsigned long") + argC = [] + for i, size in enumerate(argSizes): + t = "int" if size == 2 else "void *" + argC.append(f"{t} a{i}") + hLines.append(f"extern {retC} {name}({', '.join(argC) or 'void'});" + f" // 0x{funcId:04X}") + hLines.append("") + hLines.append("#endif") + hLines.append("") + return hLines + + +def main(): + asmLines = [ + "; AUTOGENERATED by scripts/genGnoKernel.py — DO NOT EDIT by hand.", + ";", + "; GNO/ME kernel toolset $03 wrappers.", + "; Dispatcher: JSL $E10000 with LDX #funcId.", + ";", + "; C ABI: arg0 (i16) in A, arg0 (i32) in A:X, arg1+ on stack", + "; (caller-pushed, lo-word first for 32-bit values).", + "; Each wrapper re-pushes args in Pascal order (high-word first", + "; for 32-bit), allocates result space, dispatches, pops result.", + "", + "\t.text", + "", + ] + seen = set() + for funcId, name, retSize, argSizes in SYSCALLS: + if name in seen: + continue + seen.add(name) + asmLines.extend(emitWrapper(funcId, name, retSize, argSizes)) + + OUT_ASM.parent.mkdir(parents=True, exist_ok=True) + OUT_ASM.write_text("\n".join(asmLines)) + print(f"wrote {OUT_ASM} ({len(asmLines)} lines, " + f"{len(seen) - 1} wrappers)") + + OUT_HEADER.parent.mkdir(parents=True, exist_ok=True) + OUT_HEADER.write_text("\n".join(emitHeader())) + print(f"wrote {OUT_HEADER}") + + +if __name__ == "__main__": + main() diff --git a/scripts/runInGno.sh b/scripts/runInGno.sh new file mode 100755 index 0000000..95ca90a --- /dev/null +++ b/scripts/runInGno.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash +# runInGno.sh — run a llvm816-built shell command under real GNO/ME in MAME. +# +# Boots GS/OS 6.0.4 + GNO/ME 2.0.6, logs in as root, runs the given +# program at the gsh prompt, and polls bank-2 memory for a signature. +# +# Usage: +# runInGno.sh [--check addr=hexval ...] [--snapshots] +# +# a GS/OS-loadable OMF (NOT a flat link816 .bin). +# Build it through omfEmit — see demos/buildGno.sh. +# --check A=V after the program runs, assert mem[A] (16-bit) == V. +# --snapshots save PNGs of each boot/login/run stage to +# $GNO_SNAP_DIR (default /tmp/gnosnaps) for headless +# debugging. +# +# The program is placed on the disk as /bin/ (lowercased) and as +# /HELLO, so it can be invoked by bare name at the gsh prompt. +# +# Boot timeline (frame numbers tuned against MAME apple2gs; override +# via the GNO_*_FRAMES env vars if your MAME build differs): +# ~3600 GS/OS Finder ready, GNO + System Disk icons visible +# 3800 select GNO volume, Open Apple+O to open it +# 4600 select KERN, Open Apple+O to launch the GNO kernel +# ~16000 getty shows "login:" prompt +# 16200 type "root\n" (root has empty password) +# ~18000 gsh "% " prompt +# 18800 type "\n" to run the program +# 19500+ poll bank-2 markers + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +PROG="${1:-}" +shift || true +[ -n "$PROG" ] || { echo "usage: $0 [--check A=V ...] [--snapshots]" >&2; exit 2; } +[ -f "$PROG" ] || { echo "program not found: $PROG" >&2; exit 2; } + +CADIUS="$ROOT/tools/cadius/cadius" +SYSDISK="$ROOT/tools/gsos/6.0.4 - System.Disk.po" +BASE="$ROOT/tools/gno/gnobase.po" + +[ -x "$CADIUS" ] || { echo "cadius missing" >&2; exit 1; } +[ -f "$SYSDISK" ] || { echo "GS/OS System Disk missing: $SYSDISK" >&2; exit 1; } +[ -f "$BASE" ] || { echo "GNO base disk missing — run tools/gno/buildDisk.sh" >&2; exit 1; } + +SNAPSHOTS=0 +CHECK_LUA="" +ADDR_LIST=(); EXPECT_LIST=() +while [ $# -gt 0 ]; do + case "$1" in + --snapshots) SNAPSHOTS=1; shift;; + --check) + shift + while [ $# -gt 0 ] && [[ "$1" != "--"* ]]; do + a="${1%=*}"; v="${1#*=}" + ADDR_LIST+=("$a"); EXPECT_LIST+=("$v") + shift + done;; + *) echo "unknown arg: $1" >&2; exit 2;; + esac +done + +WORK=$(mktemp -d -t gno-run.XXXXXX) +trap 'rm -rf "$WORK"' EXIT +DATA="$WORK/data.po" +cp "$BASE" "$DATA" + +NAME=$(basename "$PROG" | sed 's/\.[^.]*$//' | tr '[:upper:]' '[:lower:]' | cut -c1-15) +cp "$PROG" "$WORK/${NAME}#B50100" +cp "$PROG" "$WORK/HELLO#B50100" +"$CADIUS" ADDFILE "$DATA" /GNO.BOOT/bin "$WORK/${NAME}#B50100" >/dev/null +"$CADIUS" ADDFILE "$DATA" /GNO.BOOT "$WORK/HELLO#B50100" >/dev/null +# Optional: drop an extra TXT file in /home/root (the login cwd) for +# stdin-redirect tests. Reference it relatively or as /home/root/. +if [ -n "${GNO_ADDFILE:-}" ] && [ -f "${GNO_ADDFILE}" ]; then + cp "${GNO_ADDFILE}" "$WORK/$(basename "${GNO_ADDFILE}")#040000" + "$CADIUS" ADDFILE "$DATA" /GNO.BOOT/home/root "$WORK/$(basename "${GNO_ADDFILE}")#040000" >/dev/null +fi + +SNAPDIR="${GNO_SNAP_DIR:-/tmp/gnosnaps}" +if [ "$SNAPSHOTS" = 1 ]; then + mkdir -p "$SNAPDIR"; rm -rf "$SNAPDIR/apple2gs"/* 2>/dev/null || true +fi + +# Frame tuning. +F_VOL=${GNO_VOL_FRAMES:-3800} +F_KERN=${GNO_KERN_FRAMES:-4600} +F_LOGIN=${GNO_LOGIN_FRAMES:-16200} +F_RUN=${GNO_RUN_FRAMES:-18800} +F_POLL=${GNO_POLL_FRAMES:-20000} +F_END=${GNO_END_FRAMES:-21000} +SECS=${MAME_SECS:-380} + +# Optional: inject a line into the console after the program launches +# (for testing interactive stdin reads). GNO_STDIN is the text; it is +# posted with a trailing newline at frame F_RUN + GNO_STDIN_DELAY. +STDIN_STEP="" +if [ -n "${GNO_STDIN:-}" ]; then + STDIN_STEP="{$((F_RUN + ${GNO_STDIN_DELAY:-1600})), function() nat:post(\"${GNO_STDIN}\\n\") end}," +fi + +# Build the bank-2 probe Lua for each --check. +for i in "${!ADDR_LIST[@]}"; do + CHECK_LUA="$CHECK_LUA print(string.format('MAME-READ addr=0x%06x val=0x%04x', ${ADDR_LIST[$i]}, mem:read_u16(${ADDR_LIST[$i]})))"$'\n' +done + +LUA="$WORK/gno.lua" +cat > "$LUA" <= steps[idx][1] do steps[idx][2](); idx = idx + 1 end + if frame == $F_POLL then + local mem = manager.machine.devices[":maincpu"].spaces["program"] +$CHECK_LUA + end + if frame > $F_END then manager.machine:exit() end +end) +EOF + +OUT=$(SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy timeout "${MAME_WALL:-120}" mame apple2gs \ + -rompath "$ROOT/tools/mame/roms" \ + -flop3 "$SYSDISK" -flop4 "$DATA" \ + -snapshot_directory "$SNAPDIR" \ + -autoboot_script "$LUA" \ + -video none -sound none -nothrottle -seconds_to_run "$SECS" 2>&1) + +echo "$OUT" | grep -E "^MAME-" || true + +rc=0 +for i in "${!ADDR_LIST[@]}"; do + a="${ADDR_LIST[$i]}"; exp="${EXPECT_LIST[$i]}" + got=$(echo "$OUT" | awk -v a="$a" 'index($0, "addr=" a) { print $NF }' | tail -1) + got="${got#val=}" + want="0x$(printf '%04x' "0x$exp")" + if [ "$got" = "$want" ]; then + echo "[llvm816] GNO check OK: $a = $got" + else + echo "[llvm816 FAIL] GNO check $a: expected $want got ${got:-(none)}" + rc=1 + fi +done +exit $rc diff --git a/src/link816/link816.cpp b/src/link816/link816.cpp index d25517f..9fa595a 100644 --- a/src/link816/link816.cpp +++ b/src/link816/link816.cpp @@ -363,7 +363,14 @@ static void applyReloc(std::vector &buf, uint32_t off, if (gRecordSites) { uint32_t targetBank = target & 0xFF0000; uint32_t baseBank = gTextBaseForSites & 0xFF0000; - if (targetBank == baseBank) { + // A target below the text base is never an intra-segment + // relocatable site: it is an undefined-weak symbol (resolveSym + // resolves those to 0) or an absolute address. Recording a + // cRELOC for it would (a) underflow offsetRef = target - textBase + // (omfEmit rejects it as out-of-range) and (b) make the Loader + // rewrite a genuine null to segPlacedBase, breaking the + // `if (weakFn) weakFn()` null test that the null is meant to fail. + if (targetBank == baseBank && target >= gTextBaseForSites) { Imm24Site s; s.patchOff = patchAddr - gTextBaseForSites; s.offsetRef = target - gTextBaseForSites; @@ -386,7 +393,9 @@ static void applyReloc(std::vector &buf, uint32_t off, if (gRecordSites) { uint32_t targetBank = target & 0xFF0000; uint32_t baseBank = gTextBaseForSites & 0xFF0000; - if (targetBank == baseBank) { + // See R_W65816_IMM16: skip undefined-weak/absolute targets + // below the text base (no valid intra-segment cRELOC). + if (targetBank == baseBank && target >= gTextBaseForSites) { Imm24Site s; s.patchOff = patchAddr - gTextBaseForSites; s.offsetRef = target - gTextBaseForSites; @@ -413,7 +422,9 @@ static void applyReloc(std::vector &buf, uint32_t off, // and shouldn't be relocated by the Loader. uint32_t targetBank = target & 0xFF0000; uint32_t baseBank = gTextBaseForSites & 0xFF0000; - if (targetBank == baseBank) { + // See R_W65816_IMM16: skip undefined-weak/absolute targets + // below the text base (no valid intra-segment cRELOC). + if (targetBank == baseBank && target >= gTextBaseForSites) { Imm24Site s; s.patchOff = patchAddr - gTextBaseForSites; s.offsetRef = target - gTextBaseForSites; @@ -464,6 +475,15 @@ struct Linker { uint32_t segmentCap = 0; uint32_t segmentBankBase = 0x040000; std::string manifestPath; + // ProDOS file metadata for the resulting OMF. Set via --filetype / + // --aux. Used by disk-image builders (e.g. cppo, Cadius) to set + // the on-disk filetype/aux when copying the .bin onto a 2mg. + // For GS/OS apps: filetype=$B3 (S16), aux=0. + // For GNO shell commands: filetype=$B5 (EXE), aux=0 (or $DC00 for + // non-compliant programs that bypass GNO's keyboard buffer). + // -1 sentinel = "not set" (caller hasn't asked for a sidecar). + int32_t fileType = -1; + int32_t auxType = -1; // Per-section identity: (object index, section index within obj). using SecID = std::pair; @@ -1433,12 +1453,20 @@ static void usage(const char *argv0) { "usage: %s -o [--text-base ADDR] [--rodata-base ADDR]\n" " [--bss-base ADDR] [--map FILE] [--debug-out FILE]\n" " [--reloc-out FILE] [--no-gc-sections]\n" + " [--filetype N] [--aux N]\n" " ...\n" "\n" " --reloc-out FILE write IMM24 relocation site list (binary:\n" " ...)\n" " consumed by omfEmit --relocs to emit cRELOC\n" - " opcodes for runtime bank-byte fixup.\n", + " opcodes for runtime bank-byte fixup.\n" + " --filetype N ProDOS filetype (0..0xFF) for the OMF. $B3=S16\n" + " (GS/OS app), $B5=EXE (GNO shell command). Writes\n" + " .meta sidecar consumed by disk-image\n" + " builders.\n" + " --aux N ProDOS auxtype (0..0xFFFF). Typically 0 for\n" + " compliant programs; $DC00 = GNO non-compliant\n" + " (bypasses interrupt-driven keyboard buffer).\n", argv0); std::exit(2); } @@ -1497,6 +1525,16 @@ int main(int argc, char **argv) { } else if (a == "--manifest") { if (++i >= argc) usage(argv[0]); linker.manifestPath = argv[i++]; + } else if (a == "--filetype") { + if (++i >= argc) usage(argv[0]); + linker.fileType = (int32_t)parseInt(argv[i++]); + if (linker.fileType < 0 || linker.fileType > 0xFF) + die("--filetype must be 0..0xFF"); + } else if (a == "--aux") { + if (++i >= argc) usage(argv[0]); + linker.auxType = (int32_t)parseInt(argv[i++]); + if (linker.auxType < 0 || linker.auxType > 0xFFFF) + die("--aux must be 0..0xFFFF"); } else if (a == "-h" || a == "--help") { usage(argv[0]); } else if (!a.empty() && a[0] == '-') { @@ -1523,6 +1561,21 @@ int main(int argc, char **argv) { if (!f) die("cannot open '" + outPath + "' for writing"); f.write(reinterpret_cast(image.data()), image.size()); + // ProDOS filetype/aux sidecar. Emit as `.meta` — simple + // line-oriented `key: 0xVALUE` format consumed by the disk-image + // builder (cppo/Cadius/our scripts). Default filetype if not + // specified: 0xB3 (S16) for single-segment, the multi-segment + // builder writes 0xB3 anyway. + if (linker.fileType >= 0 || linker.auxType >= 0) { + std::string metaPath = outPath + ".meta"; + std::ofstream mf(metaPath); + if (!mf) die("cannot open '" + metaPath + "' for writing"); + if (linker.fileType >= 0) + mf << "filetype: 0x" << std::hex << linker.fileType << "\n"; + if (linker.auxType >= 0) + mf << "aux: 0x" << std::hex << linker.auxType << "\n"; + } + if (!mapPath.empty()) linker.writeMap(mapPath); if (!debugOutPath.empty()) linker.writeDebugSidecar(debugOutPath); if (!relocOutPath.empty()) { diff --git a/src/llvm/lib/Target/W65816/W65816AsmPrinter.cpp b/src/llvm/lib/Target/W65816/W65816AsmPrinter.cpp index f063a4b..502da4d 100644 --- a/src/llvm/lib/Target/W65816/W65816AsmPrinter.cpp +++ b/src/llvm/lib/Target/W65816/W65816AsmPrinter.cpp @@ -18,6 +18,7 @@ #include "TargetInfo/W65816TargetInfo.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -311,12 +312,30 @@ void W65816AsmPrinter::emitInstruction(const MachineInstr *MI) { // first; the Loader's cRELOC `BitShift=16` mechanism doesn't track // the placed bank (segPlacedBase appears 16-bit-only in the formula // it actually uses). `lda $BE` is also 2 bytes vs 3 for `lda #imm` - // so this is a size win too. The symbol operand on the pseudo is - // ignored — only the SDNode's value-type matters, which is i16 - // bank|pad. + // so this is a size win too. + // + // EXCEPTION — external-weak symbols: a `&weakfn` whose definition may + // be absent at link time must be representable as NULL. If we emit + // `lda $BE` for its bank, the runtime PBR (non-zero when GS/OS loads + // the segment in a non-zero bank) makes the pointer always non-null, + // so `if (weakfn) weakfn()` is always taken and jumps to the + // unresolved (=0) target — a crash. For an external-weak global the + // bank must be a literal 0 instead, so an undefined-weak ref is a + // genuine null and a strong link-time def still works (its low16 is + // non-zero so the null test passes and the direct call uses the + // symbol's own reloc, not this bank byte). Defined/normal globals + // and compiler external symbols (libgcc helpers) keep `lda $BE`. + const MachineOperand &Sym = MI->getOperand(1); + bool WeakUndef = Sym.isGlobal() && + Sym.getGlobal()->hasExternalWeakLinkage(); MCInst Lda; - Lda.setOpcode(W65816::LDA_DP); - Lda.addOperand(MCOperand::createImm(0xBE)); + if (WeakUndef) { + Lda.setOpcode(W65816::LDA_Imm16); + Lda.addOperand(MCOperand::createImm(0)); + } else { + Lda.setOpcode(W65816::LDA_DP); + Lda.addOperand(MCOperand::createImm(0xBE)); + } EmitToStreamer(*OutStreamer, Lda); return; } diff --git a/src/llvm/lib/Target/W65816/W65816StackSlotCleanup.cpp b/src/llvm/lib/Target/W65816/W65816StackSlotCleanup.cpp index 0e41f9d..51accc8 100644 --- a/src/llvm/lib/Target/W65816/W65816StackSlotCleanup.cpp +++ b/src/llvm/lib/Target/W65816/W65816StackSlotCleanup.cpp @@ -884,6 +884,14 @@ bool W65816StackSlotCleanup::runOnMachineFunction(MachineFunction &MF) { // real test and a flag-using branch. return Opc == W65816::LDAi16imm || Opc == W65816::LDAi8imm || + // LDAi16imm_bank lowers to `lda $BE` (LDA_DP of the program- + // bank byte). Under GNO/ME the program bank is non-zero, so + // this load sets N/Z != the CMP's result. Between a CMP and a + // BEQ/BNE (e.g. the bank half of an i32 `select`/`if(!p)` + // pointer pick), it corrupts the test and the wrong half is + // selected -- the `%s`-of-stack-string garbling bug. Plain + // LDAi16imm was already listed; its _bank sibling must be too. + Opc == W65816::LDAi16imm_bank || Opc == W65816::LDXi16imm || Opc == W65816::LDA_StackRel || Opc == W65816::LDA_StackRelIndY ||