Writing a program
A Mizu program is a C file built with the SDK. There is no C library underneath by
default: koi.h is the whole interface to the system, and it is small enough to read.
The SDK
The SDK is the sdk/ folder of the Mizu
source, refreshed by make sdk. It needs any x86-64 GCC that produces ELF64; nothing
of the kernel source.
./koicc hello.c # HELLO.EXE
./koicc main.c board.c -o games # several sources, one GAMES.EXE
./koicc -m app.c # APP.APP, an app for the desktop
./koicc -d images.c png.c # IMAGES.DLL, a library
./koicc -c tool.c # with a C library (musl), if built
Copy the result to a Mizu drive and run it from the Run box or the Command Prompt. What you write is yours: using these headers puts no licence on it.
Hello
#include "koi.h"
int main(const char* arguments) {
koi_print("Hello.\n");
if (arguments[0]) {
koi_print("You gave me: ");
koi_print(arguments);
koi_print("\n");
}
return 0;
}
main gets the rest of the command line as one string; its return value is the exit
code. Memory from koi_alloc and open files are released when the program ends.
Files
long file = koi_open("Z:\\NOTES.TXT", OPEN_READ);
char text[512];
long got;
if (file < 0) return 1;
got = koi_read(file, text, sizeof(text) - 1);
koi_close(file);
text[got > 0 ? got : 0] = 0;
OPEN_WRITE creates or truncates. koi_findfirst and
koi_findnext walk a directory; koi_exists says whether a path is a file or a
directory. koi_beside("DATA.BIN", path, size) gives a path next to the program
itself, wherever its package put it.
The screen
A program can take the whole screen, draw into its buffer and give it back; the console comes
back exactly as it was. Nothing shows until koi_gfx_present.
KOI_SCREEN screen;
if (koi_gfx_enter(&screen) != 0) return 1;
koi_gfx_clear(koi_gfx_color(8, 30, 80));
koi_gfx_text(40, 40, "Water.", koi_gfx_color(255, 255, 255), KOI_TEXT_TRANSPARENT);
koi_gfx_present();
while (!koi_keypressed()) koi_sleep(20);
koi_getchar();
koi_gfx_leave();
screen.pixels may also be written directly (pitch bytes a row). To draw in a
window on the desktop instead, write an app.
Keyboard, pointer, sound
koi_getcharwaits for a key;koi_keypressedasks without waiting;koi_keyeventgives presses and releases, for games.koi_mouse(&pointer)fills aKOI_POINTER: position, buttons, wheel, and press counts to tell clicks apart.koi_sound_play_simpleplays a buffer of samples;koi_sound_openandkoi_sound_queuestream decoded audio. One 48 kHz stereo mix always runs.
MP3 comes with the SDK: minimp3.h (public domain) decodes a frame at a time, and a
stream plays it. Feed it from a file or from koi_tcp_receive for internet radio.
#define MINIMP3_IMPLEMENTATION
#define MINIMP3_NO_SIMD
#include "minimp3.h"
static mp3dec_t mp3;
static short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
mp3dec_frame_info_t info;
int voice = -1;
mp3dec_init(&mp3);
while (at < size) {
int frames = mp3dec_decode_frame(&mp3, data + at, size - at, pcm, &info);
if (!info.frame_bytes) break; /* wants more data */
at += info.frame_bytes;
if (frames <= 0) continue;
if (voice < 0) voice = koi_sound_open(info.hz, 16, info.channels, 255);
for (int done = 0; done < frames;) {
done += koi_sound_queue(voice, pcm + done * info.channels, frames - done);
if (done < frames) koi_sleep(5); /* the stream is full */
}
}
Network
unsigned int address;
int link;
if (koi_net_resolve("koiayame.com", &address) != 0) return 1;
link = koi_tls_connect(address, 443, "koiayame.com", 8000);
if (link < 0) return 1;
koi_tls_send(link, request, length, 8000);
/* koi_tls_receive(link, buffer, size, timeout) until it returns 0 */
koi_tls_close(link);
TCP has the same shape (koi_tcp_*). koi_tls_checked says whether the
server's certificate was verified. Calls block with a timeout; put them on a thread in anything
interactive.
Threads
static KOI_LOCK lock;
static void worker(void* argument) {
koi_lock(&lock);
/* ... */
koi_unlock(&lock);
}
unsigned char* stack = koi_alloc(256 * 1024);
koi_thread_start(worker, stack + 256 * 1024, 0);
Threads share the program's memory and files and bring their own stack. A thread ends by returning. Keep the stack allocated while it runs.
Randomness and time
koi_random(buffer, length) fills bytes from the kernel's generator, good for keys and
nonces. koi_uptime counts milliseconds since start; koi_sysinfo(KOI_INFO_DATE, 0)
and KOI_INFO_TIME give the wall clock.
The ABI
Each program is stamped with KOI_ABI_VERSION from syscall.h. The
interface is frozen since version 18 (Mizu 1.0): calls are only added, and a number never changes
meaning or comes back for something else. The kernel refuses a program built for a newer ABI than
its own, or one older than KOI_ABI_MINIMUM; programs built for anything in between
run as they are. Calls from 0x100 up belong to the system and are refused to other programs. The
system call table lists every call.