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

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.

Porting software → · Writing an app →