GNO Support
This commit is contained in:
parent
f4503f73c0
commit
9e53e5fd38
55 changed files with 3490 additions and 389 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -20,3 +20,6 @@ tests/coremark/coreMark.bin
|
||||||
*.swo
|
*.swo
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*~
|
*~
|
||||||
|
|
||||||
|
stuff/
|
||||||
|
ROM Source Code.zip
|
||||||
|
|
|
||||||
59
demos/buildGno.sh
Executable file
59
demos/buildGno.sh
Executable file
|
|
@ -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 <basename>
|
||||||
|
# demos/<basename>.c -> demos/<basename>.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 <basename>" >&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)"
|
||||||
BIN
demos/gnoCat.bin
Normal file
BIN
demos/gnoCat.bin
Normal file
Binary file not shown.
15
demos/gnoCat.c
Normal file
15
demos/gnoCat.c
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
// gnoCat.c — read one line from stdin (GNO console) and echo it.
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
221
demos/gnoCat.map
Normal file
221
demos/gnoCat.map
Normal file
|
|
@ -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
|
||||||
BIN
demos/gnoCat.o
Normal file
BIN
demos/gnoCat.o
Normal file
Binary file not shown.
BIN
demos/gnoCat.omf
Normal file
BIN
demos/gnoCat.omf
Normal file
Binary file not shown.
BIN
demos/gnoCat.reloc
Normal file
BIN
demos/gnoCat.reloc
Normal file
Binary file not shown.
BIN
demos/gnoFile.bin
Normal file
BIN
demos/gnoFile.bin
Normal file
Binary file not shown.
31
demos/gnoFile.c
Normal file
31
demos/gnoFile.c
Normal file
|
|
@ -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 <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
269
demos/gnoFile.map
Normal file
269
demos/gnoFile.map
Normal file
|
|
@ -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
|
||||||
BIN
demos/gnoFile.o
Normal file
BIN
demos/gnoFile.o
Normal file
Binary file not shown.
BIN
demos/gnoFile.omf
Normal file
BIN
demos/gnoFile.omf
Normal file
Binary file not shown.
BIN
demos/gnoFile.reloc
Normal file
BIN
demos/gnoFile.reloc
Normal file
Binary file not shown.
BIN
demos/gnoFmt.bin
Normal file
BIN
demos/gnoFmt.bin
Normal file
Binary file not shown.
21
demos/gnoFmt.c
Normal file
21
demos/gnoFmt.c
Normal file
|
|
@ -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 <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
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;
|
||||||
|
}
|
||||||
203
demos/gnoFmt.map
Normal file
203
demos/gnoFmt.map
Normal file
|
|
@ -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
|
||||||
BIN
demos/gnoFmt.o
Normal file
BIN
demos/gnoFmt.o
Normal file
Binary file not shown.
BIN
demos/gnoFmt.omf
Normal file
BIN
demos/gnoFmt.omf
Normal file
Binary file not shown.
BIN
demos/gnoFmt.reloc
Normal file
BIN
demos/gnoFmt.reloc
Normal file
Binary file not shown.
BIN
demos/gnoHello.bin
Normal file
BIN
demos/gnoHello.bin
Normal file
Binary file not shown.
14
demos/gnoHello.c
Normal file
14
demos/gnoHello.c
Normal file
|
|
@ -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 <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
203
demos/gnoHello.map
Normal file
203
demos/gnoHello.map
Normal file
|
|
@ -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
|
||||||
BIN
demos/gnoHello.o
Normal file
BIN
demos/gnoHello.o
Normal file
Binary file not shown.
BIN
demos/gnoHello.omf
Normal file
BIN
demos/gnoHello.omf
Normal file
Binary file not shown.
BIN
demos/gnoHello.reloc
Normal file
BIN
demos/gnoHello.reloc
Normal file
Binary file not shown.
BIN
demos/gnoStdin.bin
Normal file
BIN
demos/gnoStdin.bin
Normal file
Binary file not shown.
23
demos/gnoStdin.c
Normal file
23
demos/gnoStdin.c
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// gnoStdin.c — stdin verification, now with a printf BEFORE the read
|
||||||
|
// (mirroring gnoCat) to test whether prior stdout output corrupts fgets.
|
||||||
|
// 0xC0DE = exact "FILE-STDIN-OK"; 0xBAD1 = other; 0xBAD0 = EOF.
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
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;
|
||||||
|
}
|
||||||
201
demos/gnoStdin.map
Normal file
201
demos/gnoStdin.map
Normal file
|
|
@ -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
|
||||||
BIN
demos/gnoStdin.o
Normal file
BIN
demos/gnoStdin.o
Normal file
Binary file not shown.
BIN
demos/gnoStdin.omf
Normal file
BIN
demos/gnoStdin.omf
Normal file
Binary file not shown.
BIN
demos/gnoStdin.reloc
Normal file
BIN
demos/gnoStdin.reloc
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -1,16 +1,16 @@
|
||||||
# section layout
|
# section layout
|
||||||
.text : 0x001000 .. 0x001c3d ( 3133 bytes)
|
.text : 0x001000 .. 0x001be6 ( 3046 bytes)
|
||||||
.rodata : 0x001c3d .. 0x001c51 ( 20 bytes)
|
.rodata : 0x001be6 .. 0x001be6 ( 0 bytes)
|
||||||
.bss : 0x00a000 .. 0x00a002 ( 2 bytes)
|
.bss : 0x00a000 .. 0x00a002 ( 2 bytes)
|
||||||
|
|
||||||
# per-input-file .text contributions
|
# per-input-file .text contributions
|
||||||
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
99 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
395 /home/scott/claude/llvm816/demos/helloBeep.o
|
395 /home/scott/claude/llvm816/demos/helloBeep.o
|
||||||
30853 /home/scott/claude/llvm816/runtime/libc.o
|
32173 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
9098 /home/scott/claude/llvm816/runtime/snprintf.o
|
9075 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
10865 /home/scott/claude/llvm816/runtime/extras.o
|
10814 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
4374 /home/scott/claude/llvm816/runtime/softFloat.o
|
4364 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
13388 /home/scott/claude/llvm816/runtime/softDouble.o
|
13051 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
1139 /home/scott/claude/llvm816/runtime/desktop.o
|
1139 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
|
@ -32,55 +32,54 @@
|
||||||
0x000002 __bss_size
|
0x000002 __bss_size
|
||||||
0x001000 __start
|
0x001000 __start
|
||||||
0x001000 __text_start
|
0x001000 __text_start
|
||||||
0x0010ba main
|
0x001063 main
|
||||||
0x001245 __jsl_indir
|
0x0011ee __jsl_indir
|
||||||
0x001248 __mulhi3
|
0x0011f1 __mulhi3
|
||||||
0x001267 __umulhisi3
|
0x001210 __umulhisi3
|
||||||
0x0012be __ashlhi3
|
0x001267 __ashlhi3
|
||||||
0x0012cd __lshrhi3
|
0x001276 __lshrhi3
|
||||||
0x0012dd __ashrhi3
|
0x001286 __ashrhi3
|
||||||
0x0012f0 __udivhi3
|
0x001299 __udivhi3
|
||||||
0x0012fc __umodhi3
|
0x0012a5 __umodhi3
|
||||||
0x001308 __divhi3
|
0x0012b1 __divhi3
|
||||||
0x001322 __modhi3
|
0x0012cb __modhi3
|
||||||
0x00133c __divmod_setup
|
0x0012e5 __divmod_setup
|
||||||
0x00136f __udivmod_core
|
0x001318 __udivmod_core
|
||||||
0x00138d __mulsi3
|
0x001336 __mulsi3
|
||||||
0x001446 __ashlsi3
|
0x0013ef __ashlsi3
|
||||||
0x00145b __lshrsi3
|
0x001404 __lshrsi3
|
||||||
0x001470 __ashrsi3
|
0x001419 __ashrsi3
|
||||||
0x00148a __udivmodsi_core
|
0x001433 __udivmodsi_core
|
||||||
0x0014c2 __udivsi3
|
0x00146b __udivsi3
|
||||||
0x0014d6 __umodsi3
|
0x00147f __umodsi3
|
||||||
0x0014ea __divsi3
|
0x001493 __divsi3
|
||||||
0x001511 __modsi3
|
0x0014ba __modsi3
|
||||||
0x001538 __divmodsi_setup
|
0x0014e1 __divmodsi_setup
|
||||||
0x001589 __divmoddi4_stash
|
0x001532 __divmoddi4_stash
|
||||||
0x0015a6 __retdi
|
0x00154f __retdi
|
||||||
0x0015b3 __ashldi3
|
0x00155c __ashldi3
|
||||||
0x0015d6 __lshrdi3
|
0x00157f __lshrdi3
|
||||||
0x0015f9 __ashrdi3
|
0x0015a2 __ashrdi3
|
||||||
0x00161f __muldi3
|
0x0015c8 __muldi3
|
||||||
0x001686 __ucmpdi2
|
0x00162f __ucmpdi2
|
||||||
0x0016af __cmpdi2
|
0x001658 __cmpdi2
|
||||||
0x0016e6 __udivdi3
|
0x00168f __udivdi3
|
||||||
0x0016ef __umoddi3
|
0x001698 __umoddi3
|
||||||
0x001708 __udivmoddi_core
|
0x0016b1 __udivmoddi_core
|
||||||
0x001755 __divdi3
|
0x0016fe __divdi3
|
||||||
0x001774 __moddi3
|
0x00171d __moddi3
|
||||||
0x0017a1 __absdi_a
|
0x00174a __absdi_a
|
||||||
0x0017a9 __absdi_b
|
0x001752 __absdi_b
|
||||||
0x0017b1 __negdi_a
|
0x00175a __negdi_a
|
||||||
0x0017cf __negdi_b
|
0x001778 __negdi_b
|
||||||
0x0017ed setjmp
|
0x001796 setjmp
|
||||||
0x001815 longjmp
|
0x0017be longjmp
|
||||||
0x00183f __umulhisi3_qsq
|
0x0017e8 __umulhisi3_qsq
|
||||||
0x001c3d __rodata_start
|
0x001be6 __init_array_end
|
||||||
0x001c3d __text_end
|
0x001be6 __init_array_start
|
||||||
0x001c3d gChainPath
|
0x001be6 __rodata_end
|
||||||
0x001c51 __init_array_end
|
0x001be6 __rodata_start
|
||||||
0x001c51 __init_array_start
|
0x001be6 __text_end
|
||||||
0x001c51 __rodata_end
|
|
||||||
0x00a000 __bss_lo16
|
0x00a000 __bss_lo16
|
||||||
0x00a000 __bss_seg0_lo16
|
0x00a000 __bss_seg0_lo16
|
||||||
0x00a000 __bss_start
|
0x00a000 __bss_start
|
||||||
|
|
@ -88,14 +87,14 @@
|
||||||
0x00a002 __bss_end
|
0x00a002 __bss_end
|
||||||
0x00a002 __heap_start
|
0x00a002 __heap_start
|
||||||
0x00bf00 __heap_end
|
0x00bf00 __heap_end
|
||||||
__absdi_a = 0x0017a1
|
__absdi_a = 0x00174a
|
||||||
__absdi_b = 0x0017a9
|
__absdi_b = 0x001752
|
||||||
__ashldi3 = 0x0015b3
|
__ashldi3 = 0x00155c
|
||||||
__ashlhi3 = 0x0012be
|
__ashlhi3 = 0x001267
|
||||||
__ashlsi3 = 0x001446
|
__ashlsi3 = 0x0013ef
|
||||||
__ashrdi3 = 0x0015f9
|
__ashrdi3 = 0x0015a2
|
||||||
__ashrhi3 = 0x0012dd
|
__ashrhi3 = 0x001286
|
||||||
__ashrsi3 = 0x001470
|
__ashrsi3 = 0x001419
|
||||||
__bss_bank = 0x000000
|
__bss_bank = 0x000000
|
||||||
__bss_end = 0x00a002
|
__bss_end = 0x00a002
|
||||||
__bss_lo16 = 0x00a000
|
__bss_lo16 = 0x00a000
|
||||||
|
|
@ -113,49 +112,48 @@ __bss_seg3_lo16 = 0x000000
|
||||||
__bss_seg3_size = 0x000000
|
__bss_seg3_size = 0x000000
|
||||||
__bss_size = 0x000002
|
__bss_size = 0x000002
|
||||||
__bss_start = 0x00a000
|
__bss_start = 0x00a000
|
||||||
__cmpdi2 = 0x0016af
|
__cmpdi2 = 0x001658
|
||||||
__divdi3 = 0x001755
|
__divdi3 = 0x0016fe
|
||||||
__divhi3 = 0x001308
|
__divhi3 = 0x0012b1
|
||||||
__divmod_setup = 0x00133c
|
__divmod_setup = 0x0012e5
|
||||||
__divmoddi4_stash = 0x001589
|
__divmoddi4_stash = 0x001532
|
||||||
__divmodsi_setup = 0x001538
|
__divmodsi_setup = 0x0014e1
|
||||||
__divsi3 = 0x0014ea
|
__divsi3 = 0x001493
|
||||||
__heap_end = 0x00bf00
|
__heap_end = 0x00bf00
|
||||||
__heap_start = 0x00a002
|
__heap_start = 0x00a002
|
||||||
__indirTarget = 0x00a000
|
__indirTarget = 0x00a000
|
||||||
__init_array_end = 0x001c51
|
__init_array_end = 0x001be6
|
||||||
__init_array_start = 0x001c51
|
__init_array_start = 0x001be6
|
||||||
__jsl_indir = 0x001245
|
__jsl_indir = 0x0011ee
|
||||||
__lshrdi3 = 0x0015d6
|
__lshrdi3 = 0x00157f
|
||||||
__lshrhi3 = 0x0012cd
|
__lshrhi3 = 0x001276
|
||||||
__lshrsi3 = 0x00145b
|
__lshrsi3 = 0x001404
|
||||||
__moddi3 = 0x001774
|
__moddi3 = 0x00171d
|
||||||
__modhi3 = 0x001322
|
__modhi3 = 0x0012cb
|
||||||
__modsi3 = 0x001511
|
__modsi3 = 0x0014ba
|
||||||
__muldi3 = 0x00161f
|
__muldi3 = 0x0015c8
|
||||||
__mulhi3 = 0x001248
|
__mulhi3 = 0x0011f1
|
||||||
__mulsi3 = 0x00138d
|
__mulsi3 = 0x001336
|
||||||
__negdi_a = 0x0017b1
|
__negdi_a = 0x00175a
|
||||||
__negdi_b = 0x0017cf
|
__negdi_b = 0x001778
|
||||||
__retdi = 0x0015a6
|
__retdi = 0x00154f
|
||||||
__rodata_end = 0x001c51
|
__rodata_end = 0x001be6
|
||||||
__rodata_start = 0x001c3d
|
__rodata_start = 0x001be6
|
||||||
__start = 0x001000
|
__start = 0x001000
|
||||||
__text_end = 0x001c3d
|
__text_end = 0x001be6
|
||||||
__text_start = 0x001000
|
__text_start = 0x001000
|
||||||
__ucmpdi2 = 0x001686
|
__ucmpdi2 = 0x00162f
|
||||||
__udivdi3 = 0x0016e6
|
__udivdi3 = 0x00168f
|
||||||
__udivhi3 = 0x0012f0
|
__udivhi3 = 0x001299
|
||||||
__udivmod_core = 0x00136f
|
__udivmod_core = 0x001318
|
||||||
__udivmoddi_core = 0x001708
|
__udivmoddi_core = 0x0016b1
|
||||||
__udivmodsi_core = 0x00148a
|
__udivmodsi_core = 0x001433
|
||||||
__udivsi3 = 0x0014c2
|
__udivsi3 = 0x00146b
|
||||||
__umoddi3 = 0x0016ef
|
__umoddi3 = 0x001698
|
||||||
__umodhi3 = 0x0012fc
|
__umodhi3 = 0x0012a5
|
||||||
__umodsi3 = 0x0014d6
|
__umodsi3 = 0x00147f
|
||||||
__umulhisi3 = 0x001267
|
__umulhisi3 = 0x001210
|
||||||
__umulhisi3_qsq = 0x00183f
|
__umulhisi3_qsq = 0x0017e8
|
||||||
gChainPath = 0x001c3d
|
longjmp = 0x0017be
|
||||||
longjmp = 0x001815
|
main = 0x001063
|
||||||
main = 0x0010ba
|
setjmp = 0x001796
|
||||||
setjmp = 0x0017ed
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,16 +1,16 @@
|
||||||
# section layout
|
# section layout
|
||||||
.text : 0x001000 .. 0x002108 ( 4360 bytes)
|
.text : 0x001000 .. 0x0020b1 ( 4273 bytes)
|
||||||
.rodata : 0x002108 .. 0x002176 ( 110 bytes)
|
.rodata : 0x0020b1 .. 0x00210b ( 90 bytes)
|
||||||
.bss : 0x00a000 .. 0x00a00a ( 10 bytes)
|
.bss : 0x00a000 .. 0x00a00a ( 10 bytes)
|
||||||
|
|
||||||
# per-input-file .text contributions
|
# 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
|
546 /home/scott/claude/llvm816/demos/helloText.o
|
||||||
30853 /home/scott/claude/llvm816/runtime/libc.o
|
32173 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
9098 /home/scott/claude/llvm816/runtime/snprintf.o
|
9075 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
10865 /home/scott/claude/llvm816/runtime/extras.o
|
10814 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
4374 /home/scott/claude/llvm816/runtime/softFloat.o
|
4364 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
13388 /home/scott/claude/llvm816/runtime/softDouble.o
|
13051 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
1139 /home/scott/claude/llvm816/runtime/desktop.o
|
1139 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
|
@ -32,71 +32,70 @@
|
||||||
0x00000a __bss_size
|
0x00000a __bss_size
|
||||||
0x001000 __start
|
0x001000 __start
|
||||||
0x001000 __text_start
|
0x001000 __text_start
|
||||||
0x0010ba main
|
0x001063 main
|
||||||
0x0012dc CtlStartUp
|
0x001285 CtlStartUp
|
||||||
0x0012ec EMStartUp
|
0x001295 EMStartUp
|
||||||
0x00130b GetNextEvent
|
0x0012b4 GetNextEvent
|
||||||
0x001322 FMStartUp
|
0x0012cb FMStartUp
|
||||||
0x001332 LEStartUp
|
0x0012db LEStartUp
|
||||||
0x001342 LoadOneTool
|
0x0012eb LoadOneTool
|
||||||
0x001352 NewHandle
|
0x0012fb NewHandle
|
||||||
0x001378 MenuStartUp
|
0x001321 MenuStartUp
|
||||||
0x001388 QDStartUp
|
0x001331 QDStartUp
|
||||||
0x00139e DrawString
|
0x001347 DrawString
|
||||||
0x0013b0 MoveTo
|
0x001359 MoveTo
|
||||||
0x0013c0 startdesk
|
0x001369 startdesk
|
||||||
0x0016de paintDesktopBackdrop
|
0x001687 paintDesktopBackdrop
|
||||||
0x001710 __jsl_indir
|
0x0016b9 __jsl_indir
|
||||||
0x001713 __mulhi3
|
0x0016bc __mulhi3
|
||||||
0x001732 __umulhisi3
|
0x0016db __umulhisi3
|
||||||
0x001789 __ashlhi3
|
0x001732 __ashlhi3
|
||||||
0x001798 __lshrhi3
|
0x001741 __lshrhi3
|
||||||
0x0017a8 __ashrhi3
|
0x001751 __ashrhi3
|
||||||
0x0017bb __udivhi3
|
0x001764 __udivhi3
|
||||||
0x0017c7 __umodhi3
|
0x001770 __umodhi3
|
||||||
0x0017d3 __divhi3
|
0x00177c __divhi3
|
||||||
0x0017ed __modhi3
|
0x001796 __modhi3
|
||||||
0x001807 __divmod_setup
|
0x0017b0 __divmod_setup
|
||||||
0x00183a __udivmod_core
|
0x0017e3 __udivmod_core
|
||||||
0x001858 __mulsi3
|
0x001801 __mulsi3
|
||||||
0x001911 __ashlsi3
|
0x0018ba __ashlsi3
|
||||||
0x001926 __lshrsi3
|
0x0018cf __lshrsi3
|
||||||
0x00193b __ashrsi3
|
0x0018e4 __ashrsi3
|
||||||
0x001955 __udivmodsi_core
|
0x0018fe __udivmodsi_core
|
||||||
0x00198d __udivsi3
|
0x001936 __udivsi3
|
||||||
0x0019a1 __umodsi3
|
0x00194a __umodsi3
|
||||||
0x0019b5 __divsi3
|
0x00195e __divsi3
|
||||||
0x0019dc __modsi3
|
0x001985 __modsi3
|
||||||
0x001a03 __divmodsi_setup
|
0x0019ac __divmodsi_setup
|
||||||
0x001a54 __divmoddi4_stash
|
0x0019fd __divmoddi4_stash
|
||||||
0x001a71 __retdi
|
0x001a1a __retdi
|
||||||
0x001a7e __ashldi3
|
0x001a27 __ashldi3
|
||||||
0x001aa1 __lshrdi3
|
0x001a4a __lshrdi3
|
||||||
0x001ac4 __ashrdi3
|
0x001a6d __ashrdi3
|
||||||
0x001aea __muldi3
|
0x001a93 __muldi3
|
||||||
0x001b51 __ucmpdi2
|
0x001afa __ucmpdi2
|
||||||
0x001b7a __cmpdi2
|
0x001b23 __cmpdi2
|
||||||
0x001bb1 __udivdi3
|
0x001b5a __udivdi3
|
||||||
0x001bba __umoddi3
|
0x001b63 __umoddi3
|
||||||
0x001bd3 __udivmoddi_core
|
0x001b7c __udivmoddi_core
|
||||||
0x001c20 __divdi3
|
0x001bc9 __divdi3
|
||||||
0x001c3f __moddi3
|
0x001be8 __moddi3
|
||||||
0x001c6c __absdi_a
|
0x001c15 __absdi_a
|
||||||
0x001c74 __absdi_b
|
0x001c1d __absdi_b
|
||||||
0x001c7c __negdi_a
|
0x001c25 __negdi_a
|
||||||
0x001c9a __negdi_b
|
0x001c43 __negdi_b
|
||||||
0x001cb8 setjmp
|
0x001c61 setjmp
|
||||||
0x001ce0 longjmp
|
0x001c89 longjmp
|
||||||
0x001d0a __umulhisi3_qsq
|
0x001cb3 __umulhisi3_qsq
|
||||||
0x002108 __rodata_start
|
0x0020b1 __rodata_start
|
||||||
0x002108 __text_end
|
0x0020b1 __text_end
|
||||||
0x002108 gChainPath
|
0x0020b1 line1
|
||||||
0x00211c line1
|
0x0020c6 line2
|
||||||
0x002131 line2
|
0x0020f3 line3
|
||||||
0x00215e line3
|
0x00210b __init_array_end
|
||||||
0x002176 __init_array_end
|
0x00210b __init_array_start
|
||||||
0x002176 __init_array_start
|
0x00210b __rodata_end
|
||||||
0x002176 __rodata_end
|
|
||||||
0x00a000 __bss_lo16
|
0x00a000 __bss_lo16
|
||||||
0x00a000 __bss_seg0_lo16
|
0x00a000 __bss_seg0_lo16
|
||||||
0x00a000 __bss_start
|
0x00a000 __bss_start
|
||||||
|
|
@ -107,25 +106,25 @@
|
||||||
0x00a00a __bss_end
|
0x00a00a __bss_end
|
||||||
0x00a00a __heap_start
|
0x00a00a __heap_start
|
||||||
0x00bf00 __heap_end
|
0x00bf00 __heap_end
|
||||||
CtlStartUp = 0x0012dc
|
CtlStartUp = 0x001285
|
||||||
DrawString = 0x00139e
|
DrawString = 0x001347
|
||||||
EMStartUp = 0x0012ec
|
EMStartUp = 0x001295
|
||||||
FMStartUp = 0x001322
|
FMStartUp = 0x0012cb
|
||||||
GetNextEvent = 0x00130b
|
GetNextEvent = 0x0012b4
|
||||||
LEStartUp = 0x001332
|
LEStartUp = 0x0012db
|
||||||
LoadOneTool = 0x001342
|
LoadOneTool = 0x0012eb
|
||||||
MenuStartUp = 0x001378
|
MenuStartUp = 0x001321
|
||||||
MoveTo = 0x0013b0
|
MoveTo = 0x001359
|
||||||
NewHandle = 0x001352
|
NewHandle = 0x0012fb
|
||||||
QDStartUp = 0x001388
|
QDStartUp = 0x001331
|
||||||
__absdi_a = 0x001c6c
|
__absdi_a = 0x001c15
|
||||||
__absdi_b = 0x001c74
|
__absdi_b = 0x001c1d
|
||||||
__ashldi3 = 0x001a7e
|
__ashldi3 = 0x001a27
|
||||||
__ashlhi3 = 0x001789
|
__ashlhi3 = 0x001732
|
||||||
__ashlsi3 = 0x001911
|
__ashlsi3 = 0x0018ba
|
||||||
__ashrdi3 = 0x001ac4
|
__ashrdi3 = 0x001a6d
|
||||||
__ashrhi3 = 0x0017a8
|
__ashrhi3 = 0x001751
|
||||||
__ashrsi3 = 0x00193b
|
__ashrsi3 = 0x0018e4
|
||||||
__bss_bank = 0x000000
|
__bss_bank = 0x000000
|
||||||
__bss_end = 0x00a00a
|
__bss_end = 0x00a00a
|
||||||
__bss_lo16 = 0x00a000
|
__bss_lo16 = 0x00a000
|
||||||
|
|
@ -143,57 +142,56 @@ __bss_seg3_lo16 = 0x000000
|
||||||
__bss_seg3_size = 0x000000
|
__bss_seg3_size = 0x000000
|
||||||
__bss_size = 0x00000a
|
__bss_size = 0x00000a
|
||||||
__bss_start = 0x00a000
|
__bss_start = 0x00a000
|
||||||
__cmpdi2 = 0x001b7a
|
__cmpdi2 = 0x001b23
|
||||||
__divdi3 = 0x001c20
|
__divdi3 = 0x001bc9
|
||||||
__divhi3 = 0x0017d3
|
__divhi3 = 0x00177c
|
||||||
__divmod_setup = 0x001807
|
__divmod_setup = 0x0017b0
|
||||||
__divmoddi4_stash = 0x001a54
|
__divmoddi4_stash = 0x0019fd
|
||||||
__divmodsi_setup = 0x001a03
|
__divmodsi_setup = 0x0019ac
|
||||||
__divsi3 = 0x0019b5
|
__divsi3 = 0x00195e
|
||||||
__heap_end = 0x00bf00
|
__heap_end = 0x00bf00
|
||||||
__heap_start = 0x00a00a
|
__heap_start = 0x00a00a
|
||||||
__indirTarget = 0x00a008
|
__indirTarget = 0x00a008
|
||||||
__init_array_end = 0x002176
|
__init_array_end = 0x00210b
|
||||||
__init_array_start = 0x002176
|
__init_array_start = 0x00210b
|
||||||
__jsl_indir = 0x001710
|
__jsl_indir = 0x0016b9
|
||||||
__lshrdi3 = 0x001aa1
|
__lshrdi3 = 0x001a4a
|
||||||
__lshrhi3 = 0x001798
|
__lshrhi3 = 0x001741
|
||||||
__lshrsi3 = 0x001926
|
__lshrsi3 = 0x0018cf
|
||||||
__moddi3 = 0x001c3f
|
__moddi3 = 0x001be8
|
||||||
__modhi3 = 0x0017ed
|
__modhi3 = 0x001796
|
||||||
__modsi3 = 0x0019dc
|
__modsi3 = 0x001985
|
||||||
__muldi3 = 0x001aea
|
__muldi3 = 0x001a93
|
||||||
__mulhi3 = 0x001713
|
__mulhi3 = 0x0016bc
|
||||||
__mulsi3 = 0x001858
|
__mulsi3 = 0x001801
|
||||||
__negdi_a = 0x001c7c
|
__negdi_a = 0x001c25
|
||||||
__negdi_b = 0x001c9a
|
__negdi_b = 0x001c43
|
||||||
__retdi = 0x001a71
|
__retdi = 0x001a1a
|
||||||
__rodata_end = 0x002176
|
__rodata_end = 0x00210b
|
||||||
__rodata_start = 0x002108
|
__rodata_start = 0x0020b1
|
||||||
__start = 0x001000
|
__start = 0x001000
|
||||||
__text_end = 0x002108
|
__text_end = 0x0020b1
|
||||||
__text_start = 0x001000
|
__text_start = 0x001000
|
||||||
__ucmpdi2 = 0x001b51
|
__ucmpdi2 = 0x001afa
|
||||||
__udivdi3 = 0x001bb1
|
__udivdi3 = 0x001b5a
|
||||||
__udivhi3 = 0x0017bb
|
__udivhi3 = 0x001764
|
||||||
__udivmod_core = 0x00183a
|
__udivmod_core = 0x0017e3
|
||||||
__udivmoddi_core = 0x001bd3
|
__udivmoddi_core = 0x001b7c
|
||||||
__udivmodsi_core = 0x001955
|
__udivmodsi_core = 0x0018fe
|
||||||
__udivsi3 = 0x00198d
|
__udivsi3 = 0x001936
|
||||||
__umoddi3 = 0x001bba
|
__umoddi3 = 0x001b63
|
||||||
__umodhi3 = 0x0017c7
|
__umodhi3 = 0x001770
|
||||||
__umodsi3 = 0x0019a1
|
__umodsi3 = 0x00194a
|
||||||
__umulhisi3 = 0x001732
|
__umulhisi3 = 0x0016db
|
||||||
__umulhisi3_qsq = 0x001d0a
|
__umulhisi3_qsq = 0x001cb3
|
||||||
gChainPath = 0x002108
|
|
||||||
gDpBase = 0x00a006
|
gDpBase = 0x00a006
|
||||||
gDpHandle = 0x00a002
|
gDpHandle = 0x00a002
|
||||||
gUserId = 0x00a000
|
gUserId = 0x00a000
|
||||||
line1 = 0x00211c
|
line1 = 0x0020b1
|
||||||
line2 = 0x002131
|
line2 = 0x0020c6
|
||||||
line3 = 0x00215e
|
line3 = 0x0020f3
|
||||||
longjmp = 0x001ce0
|
longjmp = 0x001c89
|
||||||
main = 0x0010ba
|
main = 0x001063
|
||||||
paintDesktopBackdrop = 0x0016de
|
paintDesktopBackdrop = 0x001687
|
||||||
setjmp = 0x001cb8
|
setjmp = 0x001c61
|
||||||
startdesk = 0x0013c0
|
startdesk = 0x001369
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -39,6 +39,10 @@ cc() {
|
||||||
|
|
||||||
asm "$SRC/crt0.s"
|
asm "$SRC/crt0.s"
|
||||||
asm "$SRC/crt0Gsos.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"
|
asm "$SRC/libgcc.s"
|
||||||
cc "$SRC/libc.c"
|
cc "$SRC/libc.c"
|
||||||
cc "$SRC/strtol.c"
|
cc "$SRC/strtol.c"
|
||||||
|
|
|
||||||
48
runtime/include/gno/kernel.h
Normal file
48
runtime/include/gno/kernel.h
Normal file
|
|
@ -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 <stdint.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -84,6 +84,9 @@ __start:
|
||||||
phb ; save current DBR
|
phb ; save current DBR
|
||||||
|
|
||||||
; ---- segment 0 ----
|
; ---- 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
|
rep #0x20
|
||||||
ldx #__bss_seg0_size
|
ldx #__bss_seg0_size
|
||||||
beq .Lbss_seg1
|
beq .Lbss_seg1
|
||||||
|
|
@ -92,14 +95,11 @@ __start:
|
||||||
.byte __bss_seg0_bank
|
.byte __bss_seg0_bank
|
||||||
pha
|
pha
|
||||||
plb
|
plb
|
||||||
rep #0x20
|
|
||||||
ldx #0
|
ldx #0
|
||||||
.Lbss_loop0:
|
.Lbss_loop0:
|
||||||
cpx #__bss_seg0_size
|
cpx #__bss_seg0_size
|
||||||
bcs .Lbss_seg1
|
bcs .Lbss_seg1
|
||||||
sep #0x20
|
|
||||||
stz __bss_seg0_lo16, x
|
stz __bss_seg0_lo16, x
|
||||||
rep #0x20
|
|
||||||
inx
|
inx
|
||||||
bra .Lbss_loop0
|
bra .Lbss_loop0
|
||||||
.Lbss_seg1:
|
.Lbss_seg1:
|
||||||
|
|
@ -112,14 +112,11 @@ __start:
|
||||||
.byte __bss_seg1_bank
|
.byte __bss_seg1_bank
|
||||||
pha
|
pha
|
||||||
plb
|
plb
|
||||||
rep #0x20
|
|
||||||
ldx #0
|
ldx #0
|
||||||
.Lbss_loop1:
|
.Lbss_loop1:
|
||||||
cpx #__bss_seg1_size
|
cpx #__bss_seg1_size
|
||||||
bcs .Lbss_seg2
|
bcs .Lbss_seg2
|
||||||
sep #0x20
|
|
||||||
stz __bss_seg1_lo16, x
|
stz __bss_seg1_lo16, x
|
||||||
rep #0x20
|
|
||||||
inx
|
inx
|
||||||
bra .Lbss_loop1
|
bra .Lbss_loop1
|
||||||
.Lbss_seg2:
|
.Lbss_seg2:
|
||||||
|
|
@ -132,14 +129,11 @@ __start:
|
||||||
.byte __bss_seg2_bank
|
.byte __bss_seg2_bank
|
||||||
pha
|
pha
|
||||||
plb
|
plb
|
||||||
rep #0x20
|
|
||||||
ldx #0
|
ldx #0
|
||||||
.Lbss_loop2:
|
.Lbss_loop2:
|
||||||
cpx #__bss_seg2_size
|
cpx #__bss_seg2_size
|
||||||
bcs .Lbss_seg3
|
bcs .Lbss_seg3
|
||||||
sep #0x20
|
|
||||||
stz __bss_seg2_lo16, x
|
stz __bss_seg2_lo16, x
|
||||||
rep #0x20
|
|
||||||
inx
|
inx
|
||||||
bra .Lbss_loop2
|
bra .Lbss_loop2
|
||||||
.Lbss_seg3:
|
.Lbss_seg3:
|
||||||
|
|
@ -152,17 +146,15 @@ __start:
|
||||||
.byte __bss_seg3_bank
|
.byte __bss_seg3_bank
|
||||||
pha
|
pha
|
||||||
plb
|
plb
|
||||||
rep #0x20
|
|
||||||
ldx #0
|
ldx #0
|
||||||
.Lbss_loop3:
|
.Lbss_loop3:
|
||||||
cpx #__bss_seg3_size
|
cpx #__bss_seg3_size
|
||||||
bcs .Lbss_done
|
bcs .Lbss_done
|
||||||
sep #0x20
|
|
||||||
stz __bss_seg3_lo16, x
|
stz __bss_seg3_lo16, x
|
||||||
rep #0x20
|
|
||||||
inx
|
inx
|
||||||
bra .Lbss_loop3
|
bra .Lbss_loop3
|
||||||
.Lbss_done:
|
.Lbss_done:
|
||||||
|
rep #0x20 ; back to M=16 after the M=8 store loop
|
||||||
plb ; restore caller's DBR
|
plb ; restore caller's DBR
|
||||||
|
|
||||||
; Run static constructors. The linker emits
|
; Run static constructors. The linker emits
|
||||||
|
|
@ -225,8 +217,12 @@ __start:
|
||||||
; nothing. After return, A holds the exit code.
|
; nothing. After return, A holds the exit code.
|
||||||
jsl main
|
jsl main
|
||||||
|
|
||||||
; Halt via BRK $00. MAME / debuggers catch this as a clean
|
; main returned. Bare metal has no OS to return to, so spin.
|
||||||
; program termination.
|
; (Previously a BRK $00 here, but headless MAME mis-vectors BRK to
|
||||||
.byte 0x00, 0x00
|
; $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
|
.size __start, . - __start
|
||||||
|
|
|
||||||
141
runtime/src/crt0Gno.s
Normal file
141
runtime/src/crt0Gno.s
Normal file
|
|
@ -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
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
; - No language-card RAM enable (GS/OS configures memory).
|
; - No language-card RAM enable (GS/OS configures memory).
|
||||||
; - No stack base reset (GS/OS allocated and set our SP).
|
; - No stack base reset (GS/OS allocated and set our SP).
|
||||||
; - Honors GS/OS's DBR=our-bank, DP=allocated-page setup.
|
; - Honors GS/OS's DBR=our-bank, DP=allocated-page setup.
|
||||||
; - On main() return, calls GS/OS QUIT(pcount=2) to chain to a
|
; - On main() return, calls GS/OS QUIT(pcount=0) to return control to
|
||||||
; known next application (default: /SYSTEM/START.ORIG which
|
; the launching program (Finder / shell / boot chain) — the standard
|
||||||
; test setups must save off the original boot launcher to).
|
; GS/OS application exit.
|
||||||
;
|
;
|
||||||
; Entry from the System Loader (per Apple IIgs Toolbox Reference):
|
; Entry from the System Loader (per Apple IIgs Toolbox Reference):
|
||||||
; E=0 (native), M=0 (16-bit accumulator), X=0 (16-bit index)
|
; 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.
|
; wrong bank without this. PHK + PLB copies PBR into DBR.
|
||||||
phk
|
phk
|
||||||
plb
|
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
|
; 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-
|
; `[dp],y`-style accesses; GS/OS hands us a Memory-Manager-
|
||||||
|
|
@ -69,44 +57,28 @@ __start:
|
||||||
; LDAi16imm_bank expansion)
|
; LDAi16imm_bank expansion)
|
||||||
rep #0x20
|
rep #0x20
|
||||||
|
|
||||||
; --- Diagnostic markers between crt0 phases. Bank-explicit
|
; BSS zero-init. With DBR=our bank, `stz abs,X` writes to
|
||||||
; `sta long` to $00:007E so they're visible from a host probe
|
; ourBank:X — correct as long as __bss_start/__bss_end fit in the
|
||||||
; regardless of DBR/PBR.
|
; segment's bank. M held at 8 across the loop (X stays 16-bit) so
|
||||||
sep #0x20
|
; we don't flip SEP/REP per byte.
|
||||||
.byte 0xa9, 0x7e ; lda #$7E
|
rep #0x30 ; M=16, X=16
|
||||||
.byte 0x8f, 0x7e, 0x00, 0x00 ; sta long $00:007E (post-DP)
|
sep #0x20 ; M=8 for the byte stores; X remains 16-bit
|
||||||
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
|
|
||||||
ldx #__bss_start
|
ldx #__bss_start
|
||||||
.Lbss_loop:
|
.Lbss_loop:
|
||||||
cpx #__bss_end
|
cpx #__bss_end
|
||||||
bcs .Lbss_done
|
bcs .Lbss_done
|
||||||
sep #0x20
|
stz 0x0000, x ; 1-byte store (M=8)
|
||||||
stz 0x0000, x
|
|
||||||
rep #0x20
|
|
||||||
inx
|
inx
|
||||||
bra .Lbss_loop
|
bra .Lbss_loop
|
||||||
.Lbss_done:
|
.Lbss_done:
|
||||||
sep #0x20
|
rep #0x20 ; restore M=16
|
||||||
.byte 0xa9, 0x7d ; lda #$7D
|
|
||||||
.byte 0x8f, 0x7d, 0x00, 0x00 ; sta long $00:007D (post-BSS)
|
|
||||||
rep #0x20
|
|
||||||
|
|
||||||
; Walk .init_array (C++ ctors).
|
; Walk .init_array (C++ ctors). The `jsl __jsl_indir` and the
|
||||||
;
|
; `jsl main` below are relocated by the GS/OS Loader: omfEmit emits
|
||||||
; ⚠ KNOWN BROKEN under real GS/OS Loader for non-zero-bank
|
; a cRELOC (0xF5) IMM24 site for each intra-segment JSL, so the
|
||||||
; placement: `jsl __jsl_indir` bakes a bank-0 operand at link
|
; Loader patches the full 24-bit operand (bank included) to the
|
||||||
; time. When the Loader places us at bank $1f or similar, the
|
; placed address. Non-zero-bank placement works as long as the OMF
|
||||||
; JSL targets bank 0 (= GS/OS code) instead of our actual bank
|
; is built with --relocs (demos/build.sh / buildGno.sh do).
|
||||||
; — 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.
|
|
||||||
rep #0x30
|
rep #0x30
|
||||||
ldx #__init_array_start
|
ldx #__init_array_start
|
||||||
.Linit_loop:
|
.Linit_loop:
|
||||||
|
|
@ -127,86 +99,31 @@ __start:
|
||||||
bra .Linit_loop
|
bra .Linit_loop
|
||||||
.Linit_done:
|
.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.
|
; Call main. Standard W65816 C ABI: arg0 in A; we pass none.
|
||||||
rep #0x30
|
rep #0x30
|
||||||
jsl main
|
jsl main
|
||||||
|
|
||||||
; ---- QUIT (pcount=2) chain to gChainPath ---------------------
|
; ---- QUIT (pcount=0): return to the launching program ----------
|
||||||
; Parm block layout in DP $80..$87:
|
; The standard GS/OS application exit. A pcount=0 parm block (just
|
||||||
; $80,$81 pcount = 2
|
; a zero pcount word) tells QUIT to return control to whoever
|
||||||
; $82..$85 pathname long ptr (lo, mid, bank, pad)
|
; launched us (Finder, a shell, the boot chain) with default flags
|
||||||
; $86,$87 flags = 0
|
; (non-restartable) — no hardcoded chain path needed. A program
|
||||||
;
|
; that wants to chain elsewhere can provide its own _exit/crt0.
|
||||||
; 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.
|
|
||||||
|
|
||||||
rep #0x30
|
rep #0x30
|
||||||
|
stz 0x80 ; pcount = 0 (parm block at DP $0080, bank 0)
|
||||||
; 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).
|
|
||||||
tdc
|
tdc
|
||||||
clc
|
clc
|
||||||
adc #0x80
|
adc #0x80
|
||||||
pha
|
pha ; parm-block ptr: low 16 (offset)
|
||||||
pea 0
|
pea 0 ; parm-block ptr: high 16 (bank 0)
|
||||||
ldx #0x2029 ; QUIT class-1 call number
|
ldx #0x2029 ; QUIT class-1 call number
|
||||||
jsl 0xe100a8 ; GS/OS dispatcher
|
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
|
||||||
pla
|
pla
|
||||||
.byte 0x00, 0x00
|
.Lhang:
|
||||||
|
bra .Lhang
|
||||||
|
|
||||||
.size __start, . - __start
|
.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"
|
|
||||||
|
|
|
||||||
42
runtime/src/gnoGsos.s
Normal file
42
runtime/src/gnoGsos.s
Normal file
|
|
@ -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
|
||||||
852
runtime/src/gnoKernel.s
Normal file
852
runtime/src/gnoKernel.s
Normal file
|
|
@ -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
|
||||||
|
|
@ -51,6 +51,14 @@ typedef struct {
|
||||||
u16 refNum;
|
u16 refNum;
|
||||||
unsigned long position;
|
unsigned long position;
|
||||||
} __GsosMarkRecGS;
|
} __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
|
// 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
|
// drag iigsGsos.o into the link. fopen guards GSOS path on a NULL
|
||||||
// check (see __gsosAvailable below).
|
// check (see __gsosAvailable below).
|
||||||
|
|
@ -62,6 +70,7 @@ extern u16 gsosGetEOF (__GsosEOFRecGS *p) __attribute__((weak));
|
||||||
extern u16 gsosSetEOF (__GsosEOFRecGS *p) __attribute__((weak));
|
extern u16 gsosSetEOF (__GsosEOFRecGS *p) __attribute__((weak));
|
||||||
extern u16 gsosSetMark(__GsosMarkRecGS *p) __attribute__((weak));
|
extern u16 gsosSetMark(__GsosMarkRecGS *p) __attribute__((weak));
|
||||||
extern u16 gsosGetMark(__GsosMarkRecGS *p) __attribute__((weak));
|
extern u16 gsosGetMark(__GsosMarkRecGS *p) __attribute__((weak));
|
||||||
|
extern u16 gsosCreate (__GsosCreateParm *p) __attribute__((weak));
|
||||||
|
|
||||||
static int __gsosAvailable(void) {
|
static int __gsosAvailable(void) {
|
||||||
// gsosOpen is the entry point — if iigsGsos.o is linked, all the
|
// 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
|
// glue, or a console emulator) override this with a strong
|
||||||
// definition. Marked `weak` so users can replace it.
|
// definition. Marked `weak` so users can replace it.
|
||||||
__attribute__((weak))
|
__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) {
|
int putchar(int c) {
|
||||||
*(volatile char *)0xE2 = (char)c;
|
if (__putByte)
|
||||||
|
__putByte((char)c);
|
||||||
|
else
|
||||||
|
*(volatile char *)0xE2 = (char)c;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,7 +258,14 @@ int puts(const char *s) {
|
||||||
//
|
//
|
||||||
// Callers wanting non-blocking input or Event Manager integration
|
// Callers wanting non-blocking input or Event Manager integration
|
||||||
// should call ReadCh/GetNextEvent directly via iigs/toolbox.h.
|
// 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) {
|
int getchar(void) {
|
||||||
|
if (__getByte)
|
||||||
|
return __getByte();
|
||||||
volatile unsigned char *kbd = (volatile unsigned char *)0xC000;
|
volatile unsigned char *kbd = (volatile unsigned char *)0xC000;
|
||||||
volatile unsigned char *strb = (volatile unsigned char *)0xC010;
|
volatile unsigned char *strb = (volatile unsigned char *)0xC010;
|
||||||
while (((*kbd) & 0x80) == 0) {
|
while (((*kbd) & 0x80) == 0) {
|
||||||
|
|
@ -926,6 +950,22 @@ clock_t clock(void) {
|
||||||
#define FILE_KIND_MEM 3
|
#define FILE_KIND_MEM 3
|
||||||
#define FILE_KIND_GSOS 4
|
#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 {
|
typedef struct __sFILE {
|
||||||
u8 kind;
|
u8 kind;
|
||||||
u8 writable;
|
u8 writable;
|
||||||
|
|
@ -1006,7 +1046,7 @@ int mfsUnregister(const char *path) {
|
||||||
int fputc(int c, FILE *stream) {
|
int fputc(int c, FILE *stream) {
|
||||||
if (!stream) return -1;
|
if (!stream) return -1;
|
||||||
if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR)
|
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->kind == FILE_KIND_MEM) {
|
||||||
if (!stream->writable) { stream->err = 1; return -1; }
|
if (!stream->writable) { stream->err = 1; return -1; }
|
||||||
if (stream->pos >= stream->cap) { 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) {
|
int fputs(const char *s, FILE *stream) {
|
||||||
if (!stream || !s) return -1;
|
if (!stream || !s) return -1;
|
||||||
if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (stream->kind == FILE_KIND_MEM || stream->kind == FILE_KIND_GSOS) {
|
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) {
|
int vfprintf(FILE *stream, const char *fmt, va_list ap) {
|
||||||
if (!stream) return -1;
|
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);
|
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) {
|
if (stream->kind == FILE_KIND_GSOS) {
|
||||||
// Format into a stack buffer, then push to GS/OS via fwrite.
|
// Format into a stack buffer, then push to GS/OS via fwrite.
|
||||||
// 256 bytes covers most format-string outputs; longer strings
|
// 256 bytes covers most format-string outputs; longer strings
|
||||||
|
|
@ -1269,6 +1322,16 @@ FILE *fopen(const char *path, const char *mode) {
|
||||||
// → NULL.
|
// → NULL.
|
||||||
if (!__gsosAvailable()) return (FILE *)0;
|
if (!__gsosAvailable()) return (FILE *)0;
|
||||||
if (__buildGSString(path) < 0) 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
|
// pCount=3 covers refNum + pathname + requestAccess. GS/OS 6.0.2
|
||||||
// Open ($2010) requires requestAccess to be non-zero for any actual
|
// Open ($2010) requires requestAccess to be non-zero for any actual
|
||||||
// open; passing only pCount=2 (refNum + pathname) leaves the access
|
// 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) {
|
if (stream->kind == FILE_KIND_STDOUT || stream->kind == FILE_KIND_STDERR) {
|
||||||
size_t items = 0;
|
size_t items = 0;
|
||||||
while (items < nmemb) {
|
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++;
|
items++;
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
|
|
|
||||||
295
runtime/src/libcGno.c
Normal file
295
runtime/src/libcGno.c
Normal file
|
|
@ -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 <stdint.h>
|
||||||
|
#include <gno/kernel.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -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.
|
// 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) {
|
static int format(const char *fmt, va_list ap) {
|
||||||
while (*fmt) {
|
while (*fmt) {
|
||||||
char c = *fmt++;
|
char c = *fmt++;
|
||||||
|
|
|
||||||
236
scripts/genGnoKernel.py
Normal file
236
scripts/genGnoKernel.py
Normal file
|
|
@ -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 <stdint.h>",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
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()
|
||||||
171
scripts/runInGno.sh
Executable file
171
scripts/runInGno.sh
Executable file
|
|
@ -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 <program.omf> [--check addr=hexval ...] [--snapshots]
|
||||||
|
#
|
||||||
|
# <program.omf> 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/<name> (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 "<name>\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 <program.omf> [--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/<name>.
|
||||||
|
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" <<EOF
|
||||||
|
local nat = manager.machine.natkeyboard
|
||||||
|
local frame = 0
|
||||||
|
local idx = 1
|
||||||
|
local function gf(p, n) local x = manager.machine.ioport.ports[p]; return x and x.fields[n] end
|
||||||
|
local key_cmd = gf(":macadb:KEY3", "Command / Open Apple")
|
||||||
|
local function press(f) if f then f:set_value(1) end end
|
||||||
|
local function release(f) if f then f:set_value(0) end end
|
||||||
|
local snaps = $SNAPSHOTS
|
||||||
|
local function snap(t) if snaps == 1 then manager.machine.video:snapshot() end; print("MAME-STAGE "..t.." frame="..frame) end
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
{$F_VOL, function() nat:post("G") end},
|
||||||
|
{$F_VOL + 200, function() press(key_cmd) end},
|
||||||
|
{$F_VOL + 206, function() nat:post("o") end},
|
||||||
|
{$F_VOL + 260, function() release(key_cmd) end},
|
||||||
|
{$F_VOL + 400, function() snap("vol-open") end},
|
||||||
|
{$F_KERN, function() nat:post("K") end},
|
||||||
|
{$F_KERN + 200, function() press(key_cmd) end},
|
||||||
|
{$F_KERN + 206, function() nat:post("o") end},
|
||||||
|
{$F_KERN + 260, function() release(key_cmd) end},
|
||||||
|
{$F_LOGIN - 200,function() snap("login") end},
|
||||||
|
{$F_LOGIN, function() nat:post("root\n") end},
|
||||||
|
{$F_RUN - 200, function() snap("shell") end},
|
||||||
|
{$F_RUN, function() nat:post("${GNO_RUNCMD:-$NAME}\n") end},
|
||||||
|
${STDIN_STEP}
|
||||||
|
{$F_POLL, function() snap("running") end},
|
||||||
|
}
|
||||||
|
emu.register_frame_done(function()
|
||||||
|
frame = frame + 1
|
||||||
|
while idx <= #steps and frame >= 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
|
||||||
|
|
@ -363,7 +363,14 @@ static void applyReloc(std::vector<uint8_t> &buf, uint32_t off,
|
||||||
if (gRecordSites) {
|
if (gRecordSites) {
|
||||||
uint32_t targetBank = target & 0xFF0000;
|
uint32_t targetBank = target & 0xFF0000;
|
||||||
uint32_t baseBank = gTextBaseForSites & 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;
|
Imm24Site s;
|
||||||
s.patchOff = patchAddr - gTextBaseForSites;
|
s.patchOff = patchAddr - gTextBaseForSites;
|
||||||
s.offsetRef = target - gTextBaseForSites;
|
s.offsetRef = target - gTextBaseForSites;
|
||||||
|
|
@ -386,7 +393,9 @@ static void applyReloc(std::vector<uint8_t> &buf, uint32_t off,
|
||||||
if (gRecordSites) {
|
if (gRecordSites) {
|
||||||
uint32_t targetBank = target & 0xFF0000;
|
uint32_t targetBank = target & 0xFF0000;
|
||||||
uint32_t baseBank = gTextBaseForSites & 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;
|
Imm24Site s;
|
||||||
s.patchOff = patchAddr - gTextBaseForSites;
|
s.patchOff = patchAddr - gTextBaseForSites;
|
||||||
s.offsetRef = target - gTextBaseForSites;
|
s.offsetRef = target - gTextBaseForSites;
|
||||||
|
|
@ -413,7 +422,9 @@ static void applyReloc(std::vector<uint8_t> &buf, uint32_t off,
|
||||||
// and shouldn't be relocated by the Loader.
|
// and shouldn't be relocated by the Loader.
|
||||||
uint32_t targetBank = target & 0xFF0000;
|
uint32_t targetBank = target & 0xFF0000;
|
||||||
uint32_t baseBank = gTextBaseForSites & 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;
|
Imm24Site s;
|
||||||
s.patchOff = patchAddr - gTextBaseForSites;
|
s.patchOff = patchAddr - gTextBaseForSites;
|
||||||
s.offsetRef = target - gTextBaseForSites;
|
s.offsetRef = target - gTextBaseForSites;
|
||||||
|
|
@ -464,6 +475,15 @@ struct Linker {
|
||||||
uint32_t segmentCap = 0;
|
uint32_t segmentCap = 0;
|
||||||
uint32_t segmentBankBase = 0x040000;
|
uint32_t segmentBankBase = 0x040000;
|
||||||
std::string manifestPath;
|
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).
|
// Per-section identity: (object index, section index within obj).
|
||||||
using SecID = std::pair<size_t, uint32_t>;
|
using SecID = std::pair<size_t, uint32_t>;
|
||||||
|
|
@ -1433,12 +1453,20 @@ static void usage(const char *argv0) {
|
||||||
"usage: %s -o <output> [--text-base ADDR] [--rodata-base ADDR]\n"
|
"usage: %s -o <output> [--text-base ADDR] [--rodata-base ADDR]\n"
|
||||||
" [--bss-base ADDR] [--map FILE] [--debug-out FILE]\n"
|
" [--bss-base ADDR] [--map FILE] [--debug-out FILE]\n"
|
||||||
" [--reloc-out FILE] [--no-gc-sections]\n"
|
" [--reloc-out FILE] [--no-gc-sections]\n"
|
||||||
|
" [--filetype N] [--aux N]\n"
|
||||||
" <input.o> ...\n"
|
" <input.o> ...\n"
|
||||||
"\n"
|
"\n"
|
||||||
" --reloc-out FILE write IMM24 relocation site list (binary:\n"
|
" --reloc-out FILE write IMM24 relocation site list (binary:\n"
|
||||||
" <count:u32><patchOff:u32 offsetRef:u32>...)\n"
|
" <count:u32><patchOff:u32 offsetRef:u32>...)\n"
|
||||||
" consumed by omfEmit --relocs to emit cRELOC\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"
|
||||||
|
" <output>.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);
|
argv0);
|
||||||
std::exit(2);
|
std::exit(2);
|
||||||
}
|
}
|
||||||
|
|
@ -1497,6 +1525,16 @@ int main(int argc, char **argv) {
|
||||||
} else if (a == "--manifest") {
|
} else if (a == "--manifest") {
|
||||||
if (++i >= argc) usage(argv[0]);
|
if (++i >= argc) usage(argv[0]);
|
||||||
linker.manifestPath = argv[i++];
|
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") {
|
} else if (a == "-h" || a == "--help") {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
} else if (!a.empty() && a[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");
|
if (!f) die("cannot open '" + outPath + "' for writing");
|
||||||
f.write(reinterpret_cast<const char *>(image.data()), image.size());
|
f.write(reinterpret_cast<const char *>(image.data()), image.size());
|
||||||
|
|
||||||
|
// ProDOS filetype/aux sidecar. Emit as `<output>.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 (!mapPath.empty()) linker.writeMap(mapPath);
|
||||||
if (!debugOutPath.empty()) linker.writeDebugSidecar(debugOutPath);
|
if (!debugOutPath.empty()) linker.writeDebugSidecar(debugOutPath);
|
||||||
if (!relocOutPath.empty()) {
|
if (!relocOutPath.empty()) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "TargetInfo/W65816TargetInfo.h"
|
#include "TargetInfo/W65816TargetInfo.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
|
#include "llvm/IR/GlobalValue.h"
|
||||||
#include "llvm/MC/MCContext.h"
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
#include "llvm/MC/MCInst.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
|
// first; the Loader's cRELOC `BitShift=16` mechanism doesn't track
|
||||||
// the placed bank (segPlacedBase appears 16-bit-only in the formula
|
// 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`
|
// 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
|
// so this is a size win too.
|
||||||
// ignored — only the SDNode's value-type matters, which is i16
|
//
|
||||||
// bank|pad.
|
// 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;
|
MCInst Lda;
|
||||||
Lda.setOpcode(W65816::LDA_DP);
|
if (WeakUndef) {
|
||||||
Lda.addOperand(MCOperand::createImm(0xBE));
|
Lda.setOpcode(W65816::LDA_Imm16);
|
||||||
|
Lda.addOperand(MCOperand::createImm(0));
|
||||||
|
} else {
|
||||||
|
Lda.setOpcode(W65816::LDA_DP);
|
||||||
|
Lda.addOperand(MCOperand::createImm(0xBE));
|
||||||
|
}
|
||||||
EmitToStreamer(*OutStreamer, Lda);
|
EmitToStreamer(*OutStreamer, Lda);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -884,6 +884,14 @@ bool W65816StackSlotCleanup::runOnMachineFunction(MachineFunction &MF) {
|
||||||
// real test and a flag-using branch.
|
// real test and a flag-using branch.
|
||||||
return Opc == W65816::LDAi16imm ||
|
return Opc == W65816::LDAi16imm ||
|
||||||
Opc == W65816::LDAi8imm ||
|
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::LDXi16imm ||
|
||||||
Opc == W65816::LDA_StackRel ||
|
Opc == W65816::LDA_StackRel ||
|
||||||
Opc == W65816::LDA_StackRelIndY ||
|
Opc == W65816::LDA_StackRelIndY ||
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue