106 lines
3.6 KiB
Nim
106 lines
3.6 KiB
Nim
# Markus Maiwald (Architect) | Voxis Forge (AI)
|
|
# libc.nim - Sovereign Libc for Nexus
|
|
# (C) 2026 Markus Maiwald
|
|
|
|
import ion_client
|
|
|
|
|
|
proc memcpy*(dest, src: pointer, n: uint64): pointer {.importc, cdecl.}
|
|
template copyMem*(dest, src: pointer, n: uint64) = discard memcpy(dest, src, n)
|
|
|
|
|
|
|
|
proc syscall*(nr: int, a0: uint64 = 0, a1: uint64 = 0, a2: uint64 = 0): int =
|
|
var res: int
|
|
let n = cast[uint64](nr)
|
|
let v0 = a0
|
|
let v1 = a1
|
|
let v2 = a2
|
|
{.emit: """
|
|
register unsigned long a7 __asm__("a7") = `n`;
|
|
register unsigned long a0_ __asm__("a0") = `v0`;
|
|
register unsigned long a1_ __asm__("a1") = `v1`;
|
|
register unsigned long a2_ __asm__("a2") = `v2`;
|
|
__asm__ volatile("ecall" : "+r"(a0_) : "r"(a7), "r"(a1_), "r"(a2_) : "memory");
|
|
`res` = (int)a0_;
|
|
""".}
|
|
return res
|
|
|
|
# --- LIBC IO SHIMS ---
|
|
|
|
proc write*(fd: int, buf: pointer, count: uint64): int {.exportc, cdecl.} =
|
|
# Always use syscall, even for stdout/stderr. Kernel handles it.
|
|
return int(syscall(0x204, uint64(fd), cast[uint64](buf), count))
|
|
|
|
proc read*(fd: int, buf: pointer, count: uint64): int {.exportc, cdecl.} =
|
|
return int(syscall(0x203, uint64(fd), cast[uint64](buf), count))
|
|
|
|
proc open*(path: cstring, flags: int = 0): int {.exportc, cdecl.} =
|
|
return int(syscall(0x200, cast[uint64](path), uint64(flags)))
|
|
|
|
proc close*(fd: int): int {.exportc, cdecl.} =
|
|
return int(syscall(0x201, uint64(fd)))
|
|
|
|
proc print*(s: string) =
|
|
if s.len > 0: discard write(1, unsafeAddr s[0], uint64(s.len))
|
|
|
|
proc readdir*(buf: pointer, max_len: uint64): int {.exportc, cdecl.} =
|
|
return int(syscall(0x202, cast[uint64](buf), max_len))
|
|
|
|
proc exit*(status: int) {.exportc, cdecl.} =
|
|
discard syscall(0x01, uint64(status))
|
|
while true: discard
|
|
|
|
proc yield_fiber*() {.exportc: "yield", cdecl.} =
|
|
discard syscall(0x100, 0)
|
|
|
|
proc pledge*(promises: uint64): int {.exportc, cdecl.} =
|
|
return int(syscall(0x101, promises))
|
|
|
|
proc spawn*(entry: pointer, arg: uint64): int {.exportc, cdecl.} =
|
|
return int(syscall(0x500, cast[uint64](entry), arg))
|
|
|
|
proc join*(fid: int): int {.exportc, cdecl.} =
|
|
return int(syscall(0x501, uint64(fid)))
|
|
|
|
proc upgrade*(id: int, path: cstring): int {.exportc, cdecl.} =
|
|
return -1 # Not implemented yet
|
|
|
|
proc get_vfs_listing*(): seq[string] =
|
|
var buf: array[4096, char]
|
|
let n = readdir(addr buf[0], 4096)
|
|
if n <= 0: return @[]
|
|
|
|
result = @[]
|
|
var current = ""
|
|
for i in 0..<n:
|
|
if buf[i] == '\n':
|
|
if current.len > 0:
|
|
result.add(current)
|
|
current = ""
|
|
else:
|
|
current.add(buf[i])
|
|
if current.len > 0: result.add(current)
|
|
|
|
# Surface API (Glyph)
|
|
proc sys_surface_create*(width, height: int): int {.exportc, cdecl.} =
|
|
return int(syscall(0x300, uint64(width), uint64(height)))
|
|
|
|
proc sys_surface_flip*(surf_id: int = 0) {.exportc, cdecl.} =
|
|
discard syscall(0x301, uint64(surf_id))
|
|
|
|
proc sys_surface_get_ptr*(surf_id: int): pointer {.exportc, cdecl.} =
|
|
return cast[pointer](syscall(0x302, uint64(surf_id)))
|
|
|
|
# Stubs for Glyph/NipBox compatibility
|
|
proc socket*(domain, sock_type, protocol: int): int {.exportc, cdecl.} = return -1
|
|
proc connect*(fd: int, addr_ptr: pointer, len: int): int {.exportc, cdecl.} = return -1
|
|
proc send*(fd: int, buf: pointer, count: uint64, flags: int): int {.exportc, cdecl.} = return 0
|
|
proc recv*(fd: int, buf: pointer, count: uint64, flags: int): int {.exportc, cdecl.} = return 0
|
|
proc lseek*(fd: int, offset: int, whence: int): int {.exportc, cdecl.} = return 0
|
|
proc fstat*(fd: int, buf: pointer): int {.exportc, cdecl.} = return 0
|
|
proc stat*(path: cstring, buf: pointer): int {.exportc, cdecl.} = return 0
|
|
|
|
proc membrane_init*() {.importc, cdecl.}
|
|
proc pump_membrane_stack*() {.importc, cdecl.}
|