rumpk/libs/membrane/libc.nim

86 lines
2.1 KiB
Nim

import socket
import ../../core/ion/memory
import ion_client
proc console_write(p: pointer, len: csize_t) {.importc, cdecl.}
# --- SYSCALL PRIMITIVE ---
proc nexus_syscall*(nr: int, arg: int): int {.exportc, cdecl.} =
var res: int
asm """
mv a7, %1
mv a0, %2
ecall
mv %0, a0
: "=r"(`res`)
: "r"(`nr`), "r"(`arg`)
: "a0", "a7"
"""
return res
# --- POSIX SOCKET API SHIMS ---
type
SockAddrIn = object
sin_family: uint16
sin_port: uint16
sin_addr: uint32
sin_zero: array[8, char]
proc socket*(domain, sock_type, protocol: int): int {.exportc, cdecl.} =
return new_socket()
proc connect*(fd: int, sock_addr: pointer, len: int): int {.exportc, cdecl.} =
if sock_addr == nil: return -1
let sin = cast[ptr SockAddrIn](sock_addr)
return connect_flow(fd, sin.sin_addr, sin.sin_port)
proc send*(fd: cint, buf: pointer, count: csize_t, flags: cint): int {.exportc, cdecl.} =
return send_flow(int(fd), buf, int(count))
proc recv*(fd: cint, buf: pointer, count: csize_t, flags: cint): int {.exportc, cdecl.} =
# TODO: Implement RX buffering in socket.nim
return 0
# --- LIBC IO SHIMS ---
proc write*(fd: cint, buf: pointer, count: csize_t): int {.exportc, cdecl.} =
if fd == 1 or fd == 2:
when defined(is_kernel):
# Not used here
return -1
else:
# Direct UART for Phase 7
console_write(buf, count)
return int(count)
return send_flow(int(fd), buf, int(count))
proc read*(fd: cint, buf: pointer, count: csize_t): int {.exportc, cdecl.} =
if fd == 0:
# UART Input unimplemented
return 0
return recv(fd, buf, count, 0)
proc exit*(status: cint) {.exportc, cdecl.} =
while true:
# Exit loop - yield forever or shutdown
discard nexus_syscall(0, 0)
proc open*(pathname: cstring, flags: cint): cint {.exportc, cdecl.} =
# Filesystem not active yet
return -1
proc close*(fd: cint): cint {.exportc, cdecl.} =
# TODO: Close socket
return 0
# moved to top
proc sleep*(seconds: uint32) {.exportc, cdecl.} =
var i: int = 0
let limit = int(seconds) * 50_000_000
while i < limit:
i += 1