/** * @file syscalls.h * @brief User-space system call wrappers for ClaudeOS. * * Provides inline functions that invoke INT 0x80 with the appropriate * system call numbers and arguments. */ #ifndef USERSPACE_SYSCALLS_H #define USERSPACE_SYSCALLS_H typedef unsigned int uint32_t; typedef int int32_t; /* System call numbers (must match kernel's syscall.h) */ #define SYS_EXIT 0 #define SYS_WRITE 1 #define SYS_READ 2 #define SYS_FORK 3 #define SYS_GETPID 4 #define SYS_YIELD 5 #define SYS_WAITPID 6 #define SYS_EXEC 7 #define SYS_GETENV 8 #define SYS_SETENV 9 #define SYS_READDIR 10 #define SYS_OPEN 11 #define SYS_CLOSE 12 #define SYS_SOCKET 13 #define SYS_CONNECT 14 #define SYS_SEND 15 #define SYS_RECV 16 #define SYS_SOCKSTATE 17 #define SYS_GFX 18 static inline int32_t syscall0(int num) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num)); return ret; } static inline int32_t syscall1(int num, uint32_t arg1) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num), "b"(arg1)); return ret; } static inline int32_t syscall2(int num, uint32_t arg1, uint32_t arg2) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num), "b"(arg1), "c"(arg2)); return ret; } static inline int32_t syscall3(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num), "b"(arg1), "c"(arg2), "d"(arg3)); return ret; } static inline void exit(int code) { syscall1(SYS_EXIT, (uint32_t)code); __builtin_unreachable(); } static inline int32_t write(int fd, const void *buf, uint32_t len) { return syscall3(SYS_WRITE, (uint32_t)fd, (uint32_t)buf, len); } static inline int32_t read(int fd, void *buf, uint32_t len) { return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, len); } static inline int32_t fork(void) { return syscall0(SYS_FORK); } static inline int32_t getpid(void) { return syscall0(SYS_GETPID); } static inline void yield(void) { syscall0(SYS_YIELD); } static inline int32_t waitpid(int32_t pid) { return syscall1(SYS_WAITPID, (uint32_t)pid); } static inline int32_t exec(const char *path) { return syscall1(SYS_EXEC, (uint32_t)path); } static inline int32_t getenv(const char *key, char *buf, uint32_t bufsize) { return syscall3(SYS_GETENV, (uint32_t)key, (uint32_t)buf, bufsize); } static inline int32_t setenv(const char *key, const char *value) { return syscall2(SYS_SETENV, (uint32_t)key, (uint32_t)value); } /** * Read a directory entry. * @param path Directory path. * @param idx Entry index (0-based). * @param name Buffer for entry name (128 bytes min). * @return Entry type (1=file, 2=dir) on success, -1 at end. */ static inline int32_t readdir(const char *path, uint32_t idx, char *name) { return syscall3(SYS_READDIR, (uint32_t)path, idx, (uint32_t)name); } /** * Open a file by path. * @param path File path. * @param flags Open flags (currently unused, pass 0). * @return File descriptor (>= 3) on success, -1 on failure. */ static inline int32_t open(const char *path, uint32_t flags) { return syscall2(SYS_OPEN, (uint32_t)path, flags); } /** * Close a file descriptor. * @param fd File descriptor. * @return 0 on success, -1 on failure. */ static inline int32_t close(int32_t fd) { return syscall1(SYS_CLOSE, (uint32_t)fd); } /* ================================================================ * Networking system calls * ================================================================ */ /** Socket type constants. */ #define SOCK_TCP 0 #define SOCK_UDP 1 /** TCP state constants (match kernel tcp.h). */ #define TCP_STATE_CLOSED 0 #define TCP_STATE_SYN_SENT 2 #define TCP_STATE_ESTABLISHED 4 #define TCP_STATE_CLOSE_WAIT 7 /** * Create a network socket. * @param type SOCK_TCP (0) or SOCK_UDP (1). * @return Socket descriptor (>= 0) or -1 on failure. */ static inline int32_t socket(uint32_t type) { return syscall1(SYS_SOCKET, type); } /** * Connect a TCP socket to a remote host. * @param sockfd Socket descriptor. * @param ip Remote IP address (host byte order). * @param port Remote port (host byte order). * @return 0 on success (SYN sent), -1 on failure. */ static inline int32_t connect(int32_t sockfd, uint32_t ip, uint32_t port) { return syscall3(SYS_CONNECT, (uint32_t)sockfd, ip, port); } /** * Send data on a connected socket. * @param sockfd Socket descriptor. * @param buf Data buffer. * @param len Data length. * @return Bytes sent, or -1 on failure. */ static inline int32_t net_send(int32_t sockfd, const void *buf, uint32_t len) { return syscall3(SYS_SEND, (uint32_t)sockfd, (uint32_t)buf, len); } /** * Receive data from a connected socket (non-blocking). * @param sockfd Socket descriptor. * @param buf Buffer. * @param bufsize Buffer size. * @return Bytes received, 0 if no data, -1 on error/closed. */ static inline int32_t net_recv(int32_t sockfd, void *buf, uint32_t bufsize) { return syscall3(SYS_RECV, (uint32_t)sockfd, (uint32_t)buf, bufsize); } /** * Get the state of a TCP socket. * @param sockfd Socket descriptor. * @return TCP state constant, or -1. */ static inline int32_t sockstate(int32_t sockfd) { return syscall1(SYS_SOCKSTATE, (uint32_t)sockfd); } /* ================================================================ * Graphics system calls * ================================================================ */ /** Graphics sub-commands. */ #define GFX_CMD_ENTER 0 #define GFX_CMD_LEAVE 1 #define GFX_CMD_PIXEL 2 #define GFX_CMD_CLEAR 3 #define GFX_CMD_FILL_RECT 4 #define GFX_CMD_LINE 5 #define GFX_CMD_CIRCLE 6 #define GFX_CMD_GET_INFO 7 /** Graphics mode dimensions. */ #define GFX_WIDTH 320 #define GFX_HEIGHT 200 /** Palette color constants. */ #define GFX_BLACK 0 #define GFX_BLUE 1 #define GFX_GREEN 2 #define GFX_CYAN 3 #define GFX_RED 4 #define GFX_MAGENTA 5 #define GFX_BROWN 6 #define GFX_LIGHT_GREY 7 #define GFX_DARK_GREY 8 #define GFX_LIGHT_BLUE 9 #define GFX_LIGHT_GREEN 10 #define GFX_LIGHT_CYAN 11 #define GFX_LIGHT_RED 12 #define GFX_LIGHT_MAGENTA 13 #define GFX_YELLOW 14 #define GFX_WHITE 15 /** Command structs for complex drawing operations. */ typedef struct { uint32_t x, y, w, h, color; } gfx_rect_t; typedef struct { uint32_t x1, y1, x2, y2, color; } gfx_line_t; typedef struct { uint32_t cx, cy, r, color; } gfx_circle_t; /** Convert RGB (0-255) to palette index using 6x6x6 color cube. */ static inline uint32_t gfx_rgb(uint32_t r, uint32_t g, uint32_t b) { return 16 + (r / 51) * 36 + (g / 51) * 6 + (b / 51); } /** Enter graphics mode (320x200x256). */ static inline int32_t gfx_enter(void) { return syscall1(SYS_GFX, GFX_CMD_ENTER); } /** Leave graphics mode, return to text. */ static inline int32_t gfx_leave(void) { return syscall1(SYS_GFX, GFX_CMD_LEAVE); } /** Set a pixel. */ static inline int32_t gfx_pixel(uint32_t x, uint32_t y, uint32_t color) { return syscall3(SYS_GFX, GFX_CMD_PIXEL, (x | (y << 16)), color); } /** Clear screen with a color. */ static inline int32_t gfx_clear(uint32_t color) { return syscall2(SYS_GFX, GFX_CMD_CLEAR, color); } /** Fill a rectangle. */ static inline int32_t gfx_fill_rect(const gfx_rect_t *r) { return syscall2(SYS_GFX, GFX_CMD_FILL_RECT, (uint32_t)r); } /** Draw a line. */ static inline int32_t gfx_line(const gfx_line_t *l) { return syscall2(SYS_GFX, GFX_CMD_LINE, (uint32_t)l); } /** Draw a filled circle. */ static inline int32_t gfx_circle(const gfx_circle_t *c) { return syscall2(SYS_GFX, GFX_CMD_CIRCLE, (uint32_t)c); } /** Get graphics info: returns (width | height<<16). */ static inline int32_t gfx_get_info(void) { return syscall1(SYS_GFX, GFX_CMD_GET_INFO); } /* Basic string operations for user-space */ static inline uint32_t strlen(const char *s) { uint32_t len = 0; while (s[len]) len++; return len; } static inline int strcmp(const char *a, const char *b) { while (*a && *a == *b) { a++; b++; } return (unsigned char)*a - (unsigned char)*b; } static inline int strncmp(const char *a, const char *b, uint32_t n) { while (n && *a && *a == *b) { a++; b++; n--; } return n ? ((unsigned char)*a - (unsigned char)*b) : 0; } static inline char *strcpy(char *dst, const char *src) { char *d = dst; while ((*d++ = *src++)); return dst; } static inline char *strncpy(char *dst, const char *src, uint32_t n) { char *d = dst; while (n && (*d++ = *src++)) n--; while (n--) *d++ = '\0'; return dst; } static inline void *memset(void *s, int c, uint32_t n) { unsigned char *p = (unsigned char *)s; while (n--) *p++ = (unsigned char)c; return s; } static inline void *memcpy(void *dst, const void *src, uint32_t n) { unsigned char *d = (unsigned char *)dst; const unsigned char *s = (const unsigned char *)src; while (n--) *d++ = *s++; return dst; } /** Print a string to stdout. */ static inline void puts(const char *s) { write(1, s, strlen(s)); } /** Print a single character to stdout. */ static inline void putchar(char c) { write(1, &c, 1); } #endif /* USERSPACE_SYSCALLS_H */