rax, rdi, rsi, rdx are in/out paramters. rbx, rbp, rsp, r12-r15 are preserved. rcx, rflags, r8-r11 are clobbered. interrupts (including the timer!) are disabled during system calls. stream result: 0 = success 1 = bad handle 2 = io error 3 = out of bounds 4 = does not exist 5 = not a regular file 6 = not an executable 7 = not writable 8 = not seekable 9 = socket id already used 10 = socket id not in use 11 = socket listener closed 12 = other end closed 13 = already exists 14 = not sized encode color: rax in: 0 edi in: r + g * 256 + b * 65536 eax out: encoded color get framebuffer: rax in: 1 rax out: pointer to framebuffer rdi out: width + height * 2 ** 32 esi out: pitch framebuffer is always 32 bpp. use the encode color syscall to encode colors. pitch is in dwords, not in bytes. open file: rax in: 2 rdi in: pointer to file path rsi in: file path length rdx in: bit 0: allow creation bit 1: only allow creation rax out: stream result rdi out: stream handle (if rax = success) end this thread: rax in: 3 edi in: exit code (signed, only used if this was last thread) get new pages: rax in: 4 rdi in: number of pages to allocate rax out: start of first page the allocated pages are next to each other, writable, and not executable. get input packet: rax in: 5 al out: bit 7: was mouse packet if bit 7: bit 0: left mouse button down bit 1: right mouse button down bit 2: middle mouse button down if bit 7: di out: mouse x change (signed) si out: mouse y change (signed) else: edi out: key packet create private socket: rax in: 6 rax out: end 1 stream handle rdi out: end 2 stream handle create socket listener: rax in: 7 rdi in: pointer to id string rsi in: id string length rax out: stream result rdi out: listener handle (if rax = 0) stop socket listener: rax in: 8 rdi in: listener handle accept socket connection: rax in: 9 rdi in: listener handle rax out: stream result rdi out: stream handle connect to socket: rax in: 10 rdi in: pointer to id string rsi in: id string length rax out: stream result rdi out: stream handle (if rax = 0) close stream: rax in: 11 rdi in: stream handle seek stream: returns "not seekable" for sockets rax in: 12 rdi in: stream handle sil in: 0 = relative to beginning 1 = relative to end 2 = relative to current position rdx in: offset (signed) rax out: stream result read from stream: rax in: 13 rdi in: stream handle rsi in: count rdx in: pointer to buffer rax out: stream result write to stream: rax in: 14 rdi in: stream handle rsi in: count rdx in: pointer to buffer rax out: stream result get stream length: returns "not sized" for sockets rax in: 15 rdi in: stream handle rax out: stream result rdi out: stream length (if rax = success) start process: rax in: 16 rdi in: pointer to process start info struct rax out: stream result rdi out: process handle (if rax = success) process start info struct: qword: file path length qword: pointer to file path qword: count of environment variables qword: pointer to array of environment variable structs qword: count of gifted stream ends qword: pointer to array of gifted stream structs environment variable struct: qword: name length qword: pointer to name qword: value length qword: pointer to value gifted stream struct: qword: stream handle here qword: new stream handle in child new handle must be < 65536 any gifted streams must not have threads waiting to read from our end end this process: rax in: 17 edi in: exit code (signed) set stream length: returns "not sized" for sockets rax in: 18 rdi in: stream handle rsi in: new length rax out: stream result get other end process handle: returns "other end closed" for files rax in: 19 rdi in: stream handle rax out: stream result rdi out: process handle (if rax = success)