From e2fe4fd26a09c82573c6d6b3cca31c37879753a7 Mon Sep 17 00:00:00 2001 From: skejeton Date: Thu, 4 Jul 2024 17:54:57 -0300 Subject: [PATCH] init --- .gdbinit | 2 + .gitignore | 7 + .gitmodules | 6 + Makefile | 35 + README.md | 88 +++ cover.png | Bin 0 -> 39606 bytes fs/api/asm.um | 29 + fs/api/gfx.um | 40 ++ fs/api/rw.um | 31 + fs/api/sym.um | 16 + fs/api/vfs.um | 40 ++ fs/kernel/idt.um | 33 + fs/kernel/input.um | 150 +++++ fs/kernel/kernel.um | 26 + fs/kernel/pic.um | 50 ++ fs/main.um | 28 + fs/res/background.qoi | Bin 0 -> 66935 bytes fs/res/icons.qoi | Bin 0 -> 1120 bytes fs/subdir/test.txt | 1 + fs/user/about.um | 30 + fs/user/blackjack.um | 474 ++++++++++++++ fs/user/console.um | 32 + fs/user/filesystem.um | 35 + fs/user/microui.um | 1293 +++++++++++++++++++++++++++++++++++++ fs/user/progman.um | 24 + fs/user/tasks.um | 77 +++ fs/user/taskview.um | 22 + fs/user/test.um | 39 ++ fs/user/user.um | 158 +++++ mkfs.py | 45 ++ src/compile_flags.txt | 6 + src/mock_libc/alloc.c | 96 +++ src/mock_libc/alloc.h | 7 + src/mock_libc/arith.c | 292 +++++++++ src/mock_libc/assert.h | 1 + src/mock_libc/ctype.h | 1 + src/mock_libc/dlfcn.h | 1 + src/mock_libc/errno.h | 1 + src/mock_libc/fcntl.h | 1 + src/mock_libc/fmt.c | 802 +++++++++++++++++++++++ src/mock_libc/fmt.h | 36 ++ src/mock_libc/math.h | 1 + src/mock_libc/mock_libc.c | 511 +++++++++++++++ src/mock_libc/mock_libc.h | 183 ++++++ src/mock_libc/setjmp.h | 1 + src/mock_libc/stdio.h | 1 + src/mock_libc/stdlib.h | 1 + src/mock_libc/string.h | 1 + src/mock_libc/sys/stat.h | 1 + src/mock_libc/sys/types.h | 2 + src/mock_libc/time.h | 1 + src/mock_libc/unistd.h | 1 + src/mock_libc/vfs.c | 392 +++++++++++ src/mock_libc/vfs.h | 26 + src/qoi | 1 + src/sys/boot.s | 272 ++++++++ src/sys/font8x8.c | 153 +++++ src/sys/gfx.c | 340 ++++++++++ src/sys/gfx.h | 13 + src/sys/irq.s | 25 + src/sys/lib.s | 33 + src/sys/link.ld | 22 + src/sys/main.c | 66 ++ src/sys/panic.c | 41 ++ src/sys/umka.c | 371 +++++++++++ src/sys/umka.h | 7 + src/umka | 1 + src/umka.c | 15 + src/unity.c | 16 + test/compile_flags.txt | 2 + test/integr.bat | 10 + test/integr.c | 61 ++ test/jmp.def | 4 + test/testalloc.bat | 5 + test/testalloc.c | 41 ++ test/testfmt.bat | 5 + test/testfmt.c | 204 ++++++ test/testvfs.bat | 5 + test/testvfs.c | 47 ++ 79 files changed, 6937 insertions(+) create mode 100644 .gdbinit create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Makefile create mode 100644 README.md create mode 100644 cover.png create mode 100644 fs/api/asm.um create mode 100644 fs/api/gfx.um create mode 100644 fs/api/rw.um create mode 100644 fs/api/sym.um create mode 100644 fs/api/vfs.um create mode 100644 fs/kernel/idt.um create mode 100644 fs/kernel/input.um create mode 100644 fs/kernel/kernel.um create mode 100644 fs/kernel/pic.um create mode 100644 fs/main.um create mode 100644 fs/res/background.qoi create mode 100644 fs/res/icons.qoi create mode 100644 fs/subdir/test.txt create mode 100644 fs/user/about.um create mode 100644 fs/user/blackjack.um create mode 100644 fs/user/console.um create mode 100644 fs/user/filesystem.um create mode 100644 fs/user/microui.um create mode 100644 fs/user/progman.um create mode 100644 fs/user/tasks.um create mode 100644 fs/user/taskview.um create mode 100644 fs/user/test.um create mode 100644 fs/user/user.um create mode 100644 mkfs.py create mode 100644 src/compile_flags.txt create mode 100644 src/mock_libc/alloc.c create mode 100644 src/mock_libc/alloc.h create mode 100644 src/mock_libc/arith.c create mode 100644 src/mock_libc/assert.h create mode 100644 src/mock_libc/ctype.h create mode 100644 src/mock_libc/dlfcn.h create mode 100644 src/mock_libc/errno.h create mode 100644 src/mock_libc/fcntl.h create mode 100644 src/mock_libc/fmt.c create mode 100644 src/mock_libc/fmt.h create mode 100644 src/mock_libc/math.h create mode 100644 src/mock_libc/mock_libc.c create mode 100644 src/mock_libc/mock_libc.h create mode 100644 src/mock_libc/setjmp.h create mode 100644 src/mock_libc/stdio.h create mode 100644 src/mock_libc/stdlib.h create mode 100644 src/mock_libc/string.h create mode 100644 src/mock_libc/sys/stat.h create mode 100644 src/mock_libc/sys/types.h create mode 100644 src/mock_libc/time.h create mode 100644 src/mock_libc/unistd.h create mode 100644 src/mock_libc/vfs.c create mode 100644 src/mock_libc/vfs.h create mode 160000 src/qoi create mode 100644 src/sys/boot.s create mode 100644 src/sys/font8x8.c create mode 100644 src/sys/gfx.c create mode 100644 src/sys/gfx.h create mode 100644 src/sys/irq.s create mode 100644 src/sys/lib.s create mode 100644 src/sys/link.ld create mode 100644 src/sys/main.c create mode 100644 src/sys/panic.c create mode 100644 src/sys/umka.c create mode 100644 src/sys/umka.h create mode 160000 src/umka create mode 100644 src/umka.c create mode 100644 src/unity.c create mode 100644 test/compile_flags.txt create mode 100644 test/integr.bat create mode 100644 test/integr.c create mode 100644 test/jmp.def create mode 100644 test/testalloc.bat create mode 100644 test/testalloc.c create mode 100644 test/testfmt.bat create mode 100644 test/testfmt.c create mode 100644 test/testvfs.bat create mode 100644 test/testvfs.c diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000..3e2a7dd --- /dev/null +++ b/.gdbinit @@ -0,0 +1,2 @@ +target remote :1234 +symbol-file bin/sys.o \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..abd69b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.exe +*.rdi +*.lib +*.ilk +*.pdb + +bin \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7aa2de6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "src/umka"] + path = src/umka + url = https://github.com/vtereshkov/umka-lang +[submodule "src/qoi"] + path = src/qoi + url = https://github.com/phoboslab/qoi diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6410e16 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +CFLAGS= -I src/qoi -I src/mock_libc -g -Isrc/umka/src -m32 -march=i686 -Os -fno-builtin -fcf-protection=none -nostdlib -ffreestanding -mno-red-zone -fno-exceptions +EMU=qemu-system-x86_64 + +all: pre-build do-build + +pre-build: + mkdir -p bin + python3 mkfs.py fs bin/fs.bin + +do-build: bin/unity.o bin/umka.o bin/boot.o + ld -melf_i386 -r -b binary -o bin/fs.o bin/fs.bin + gcc $(CFLAGS) bin/unity.o bin/umka.o bin/fs.o bin/boot.o -o bin/sys.o -T src/sys/link.ld + objcopy -O binary bin/sys.o bin/sys.img + +run: all + $(EMU) -no-shutdown -no-reboot -m 128 -drive file=bin/sys.img,format=raw + +debug: all + @$(EMU) -no-shutdown -no-reboot -s -S -m 128 -drive file=bin/sys.img,format=raw & + sleep 1 + gdb -tui + +bin/unity.o: $(wildcard src/sys/*.c) $(wildcard src/mock_libc/*.c) + gcc $(CFLAGS) -c src/unity.c -o bin/unity.o + +bin/umka.o: src/umka.c $(wildcard src/umka/src/*.c) + gcc $(CFLAGS) -c src/umka.c -o bin/umka.o + +bin/boot.o: $(wildcard ./src/sys/*.s) + nasm -f elf32 src/sys/boot.s -o bin/boot.o + +clean: + rm -f bin/*.o + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..15974b8 --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# Umka OS + +A proof of concept operating system written in Umka. (With blackjack and hookers (maybe just blackjack)) + +![Windows in the OS](cover.png) + +# Table of Contents + +* [Usage and Installation](#usage-and-installation) +* [Building](#building) +* [Why and how](#why-and-how) +* [Technology](#technology) +* [Contributing](#contributing) + +# Usage and Installation + +Currently, this OS uses a legacy BIOS bootloader, so it's unlikely to run on actual hardware. +Later I'll make an effort to port this to UEFI. + +To try it out, I recommend to go to the release pages, download the latest sys.img, and run the following command: + +``` +qemu-system-x86_64 -m 128 -drive file=sys.img,format=raw +``` + +You need to install QEMU for this to work. Alternatively you can try any other virtual machine software such as VirtualBox (but I did not test it). + +# Building + +To build, use the Makefile provided in the repository. Dependencies are: + +* gcc +* binutils +* python3 +* nasm + +Upon clone, install submodules: `git submodule init --recursive` + +# Why and how + +Because I can :P + +It started as a random idea, it was going to be a lot of work from the start. + +I started with re-implementing libc subset used by Umka, which you can find under `sys/mock_libc`. +A few basic things had to be implemented, for the most part a simple allocator and a virtual file system. +After that was done, I implemented the formatting functions (which took me longer than I expected.) + +When it came to the OS, I scraped some of my old code, found my old bootloader, fixed it, and booted into Umka. +And it didn't go all that smooth, there was a lot of trouble. I'm going to need to write a dedicated post for that later. This took me about a week to make this, it's a bit rushed, but it works. + +# Technology + +The standard library: + +* `alloc.c` Custom allocator. No brainer, since I can't use libc provided by the system. The allocator is pretty inefficient but a good enough free-list allocator. +* `vfs.c` Virtual file system. It's just a tree data structure, it's somewhat hacky - for example, files can contain other files, because there's not distinction between directories. The virtual file system is needed for file operations. The file `mkfs.py` creates an embedded image of the filesystem from the `fs/` directory. +* `fmt.c` This was probably the most work out of the C standard library, mostly the scanning and formatting functions, and yes in the end they did trip me up during the OS development, even after testing. +* `arith.c` Not written by me, these are public domain floating point functions, otherwise it wouldn't compile. + +Moving on to the system: + +The system has a kernel, written mostly in Umka, with exception for IRQ handling (due to multithreading constraints). + +* `main.c` Bootstraps the VFS image, sets up Umka and graphics. +* `gfx.c` A primitve graphics output library, it uses [rxi's cached software rendering](https://rxi.github.io/cached_software_rendering.html) to increase the render performance significantly. +* `umka.c` Where most of the stuff happens, here the IRQ's are handled and sent to Umka. + +From this point, most of the code is handled in Umka, you can find it in `fs/` + +* `main.um` Is mostly just a relay to call other functions. +* `kernel.um` `idt.um` `input.um` `pic.um` a simple kernel, it handles the IDT initialization, and the mouse driver. +* `microui.um` a very nice recreation of microui for Umka by @thacuber2a03 +* `user.um` and the programs ... the provided example software, it even includes a blackjack game, check it out! + +And extra: + +* `qoi.c`, I use QOI for icons and the background. + +Limitations: + +* It's limited by 480kb, since it can not address more memory in the bootloader. Could potentially be solved later by using UEFI instead. + +There's not much advanced things here, but it all somehow works, and that feels really good. + +# Contributing + +Always welcome =) Please mind the 480 KB limit. \ No newline at end of file diff --git a/cover.png b/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..a87efafee72bcb9ec25c84539ad95e2b2029d6f3 GIT binary patch literal 39606 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
017R@!%kIe6Li&r>QZ@8x~htfG~4m$SdoCTNFF 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 literal 0 HcmV?d00001 diff --git a/fs/api/asm.um b/fs/api/asm.um new file mode 100644 index 0000000..b3064fc --- /dev/null +++ b/fs/api/asm.um @@ -0,0 +1,29 @@ +fn api__asm_in8(port: uint16): uint8 +fn api__asm_out8(port: uint16, data: uint8) +fn api__asm_lidt(addr: ^void, limit: uint16) +fn api__asm_sti() +fn api__asm_cli() + +fn in8*(port: uint16): uint8 { + return api__asm_in8(port) +} + +fn out8*(port: uint16, data: uint8) { + api__asm_out8(port, data) +} + +fn lidt*(addr: ^void, limit: uint16) { + api__asm_lidt(addr, limit) +} + +fn sti*() { + api__asm_sti() +} + +fn cli*() { + api__asm_cli() +} + +fn iowait*() { + out8(0x80, 0) +} \ No newline at end of file diff --git a/fs/api/gfx.um b/fs/api/gfx.um new file mode 100644 index 0000000..993b2e9 --- /dev/null +++ b/fs/api/gfx.um @@ -0,0 +1,40 @@ +fn api__gfxSetColor(r, g, b, a: uint8) +fn api__gfxDrawRect(x, y, w, h: int) +fn api__gfxDrawClip(x, y, w, h: int) +fn api__gfxDrawChar(x, y: int, c: char) +fn api__gfxDrawBackground() +fn api__gfxDrawIcon(x, y: int, c: char) +fn api__gfxDims(w, h: ^int) +fn api__gfxSwap() + +fn setColor*(r, g, b, a: uint8) { + api__gfxSetColor(r, g, b, a) +} + +fn drawRect*(x, y, w, h: int) { + api__gfxDrawRect(x, y, w, h) +} + +fn drawClip*(x, y, w, h: int) { + api__gfxDrawClip(x, y, w, h) +} + +fn drawChar*(x, y: int, c: char) { + api__gfxDrawChar(x, y, c) +} + +fn drawIcon*(x, y: int, c: char) { + api__gfxDrawIcon(x, y, c) +} + +fn drawBackground*() { + api__gfxDrawBackground() +} + +fn dims*(w, h: ^int) { + api__gfxDims(w, h) +} + +fn swap*() { + api__gfxSwap() +} diff --git a/fs/api/rw.um b/fs/api/rw.um new file mode 100644 index 0000000..93d013e --- /dev/null +++ b/fs/api/rw.um @@ -0,0 +1,31 @@ +import ("std.um") + +fn api__writes8(data: []uint8, addr: ^void) +fn api__reads8(addr: ^void, count: uint): ^[]uint8 +fn api__reads(addr: ^void, count: uint): str +fn api__getaddr(addr: ^void): uint +fn api__getptr(addr: uint): ^void + +fn getaddr*(addr: ^void): uint { + return api__getaddr(addr) +} + +fn getptr*(addr: uint): ^void { + return api__getptr(addr) +} + +fn writes8*(addr: ^void, data: []uint8) { + api__writes8(data, addr) +} + +fn write*(addr: ^void, data: any) { + writes8(addr, std::tobytes(data)) +} + +fn reads8*(addr: ^void, count: uint): []uint8 { + return api__reads8(addr, count)^ +} + +fn reads*(addr: ^void, count: uint): str { + return api__reads(addr, count) +} diff --git a/fs/api/sym.um b/fs/api/sym.um new file mode 100644 index 0000000..fc1b922 --- /dev/null +++ b/fs/api/sym.um @@ -0,0 +1,16 @@ +import ( + "std.um" +) + +var symbols: map[str]^void + +fn register*(symbol: str, addr: ^void) { + symbols[symbol] = addr +} + +fn get*(symbol: str): ^void { + if symbols[symbol] == null { + std::assert(false, "Symbol not found: " + symbol) + } + return symbols[symbol] +} \ No newline at end of file diff --git a/fs/api/vfs.um b/fs/api/vfs.um new file mode 100644 index 0000000..b80a39a --- /dev/null +++ b/fs/api/vfs.um @@ -0,0 +1,40 @@ +import "std.um" + +type FSO* = [1]^void + +fn api__vfsHookFlush(to: std::File, handler: fn(data: ^void, size: uint)) +fn api__vfsRoot(): ^void +fn api__vfsNext(of: ^void): ^void +fn api__vfsChild(of: ^void): ^void +fn api__vfsFSOOpen(fso: ^void): std::File +fn api__vfsFSOName(fso: ^void): str + +fn hookFlush*(to: std::File, handler: fn(data: ^void, size: uint)) { + api__vfsHookFlush(to, handler) +} + +fn root*(): FSO { + return {api__vfsRoot()} +} + +fn (fso: ^FSO) valid*(): bool { + return fso[0] != null +} + +fn (fso: ^FSO) next*(): FSO { + return {api__vfsNext(fso[0])} +} + +fn (fso: ^FSO) child*(): FSO { + return {api__vfsChild(fso[0])} +} + +fn (fso: ^FSO) open*(): std::File { + return api__vfsFSOOpen(fso[0]) +} + +fn (fso: ^FSO) name*(): str { + return api__vfsFSOName(fso[0]) +} + + diff --git a/fs/kernel/idt.um b/fs/kernel/idt.um new file mode 100644 index 0000000..eabe420 --- /dev/null +++ b/fs/kernel/idt.um @@ -0,0 +1,33 @@ +import ( + "/api/asm.um" + "/api/rw.um" +) + +type IdtEntry = struct { + offsetLow: uint16 + selector: uint16 + zero: uint8 + kind: uint8 + offsetHigh: uint16 +} + +var idt: [256]IdtEntry + +fn init*() { + printf("[IDT] Loading at %v (%x bytes)\n", &idt, sizeof(idt)-1) + asm::lidt(&idt, sizeof(idt)-1) +} + +fn register*(entry: uint8, fnaddr: ^void) { + addr := rw::getaddr(fnaddr) + + printf("[IDT] Registering entry %d at %x\n", entry, addr) + + idt[entry] = { + offsetLow: addr & 0xFFFF, + selector: 0x08, + zero: 0, + kind: 0x8E, + offsetHigh: (addr >> 16) & 0xFFFF + } +} diff --git a/fs/kernel/input.um b/fs/kernel/input.um new file mode 100644 index 0000000..3124d29 --- /dev/null +++ b/fs/kernel/input.um @@ -0,0 +1,150 @@ +import ( + "std.um" + "idt.um" + "pic.um" + "/api/asm.um" + "/api/sym.um" +) + +type ( + Packet* = any + + MousePacket* = struct { + dx: int + dy: int + lmb: bool + rmb: bool + mmb: bool + } +) + +const ( + ps2cmd = 0x64 + ps2data = 0x60 + + keyboardInt = 33 + mouseInt = 44 + + keyboard = 1 << 1 + slave = 1 << 2 + mouse = 1 << 12 +) + +var ( + packets: []Packet +) + +fn mouseWaitWrite() { + for i := 0; i < 100000; i++ { + if asm::in8(ps2cmd) & 2 == 0 { + return + } + } + + std::assert(false, "Mouse write timeout") +} + +fn mouseWaitRead() { + for i := 0; i < 100000; i++ { + if asm::in8(ps2cmd) & 1 == 1 { + return + } + } + + std::assert(false, "Mouse read timeout") +} + +fn mouseWriteCmd(cmd: uint8) { + mouseWaitWrite() + asm::out8(ps2cmd, cmd) +} + +fn mouseWrite(data: uint8) { + mouseWaitWrite() + asm::out8(ps2cmd, 0xD4) + mouseWaitWrite() + asm::out8(ps2data, data) +} + +fn mouseRead(): uint8 { + mouseWaitRead() + return asm::in8(ps2data) +} + +fn initMouse() { + mouseWriteCmd(0xA8) // A8h - Enable + mouseWriteCmd(0x20) // 20h - Get config + mouseWaitRead() + status := asm::in8(ps2data) | 2 // Enable IRQ bit + mouseWriteCmd(0x60) // 60h - Set config + mouseWaitWrite() + asm::out8(ps2data, status) + mouseWrite(0xF6) // Set defaults + mouseRead() + mouseWrite(0xF4) // Enable packets + mouseRead() +} + +mouseCycle := 0 +mouseBytes := [3]uint8{0, 0, 0} +fn handleMouseIrq(bytes: []uint8) { + for i, byte in bytes { + switch mouseCycle { + case 0: + if byte & 0x8 == 0 { + break + } + + mouseBytes[0] = byte + mouseCycle++ + case 1: + mouseBytes[1] = byte + mouseCycle++ + case 2: + mouseBytes[2] = byte + mouseCycle = 0 + + if (mouseBytes[0] & 0x80) > 0 || (mouseBytes[0] & 0x40) > 0 { + break + } + + dx := int16(mouseBytes[1]) - ((mouseBytes[0] << 4) & 0x100) + dy := int16(mouseBytes[2]) - ((mouseBytes[0] << 3) & 0x100) + + packet := MousePacket{ + dx: dx, + dy: dy, + lmb: mouseBytes[0] & 1 > 0, + rmb: mouseBytes[0] & 2 > 0, + mmb: mouseBytes[0] & 4 > 0 + } + + packets = append(packets, packet) + } + } +} + +fn init*() { + idt::register(keyboardInt, sym::get("irq1")) + idt::register(mouseInt, sym::get("irq12")) + idt::init() + + initMouse() + + pic::init() + pic::setMask(0xFFFF ~ (mouse | keyboard | slave)) +} + +fn irq*(irq: uint8, bytes: []uint8) { + switch irq { + case 12: handleMouseIrq(bytes) + } +} + +fn relay*(f: fn(event: Packet)) { + for i, packet in packets { + f(packet) + } + + packets = {} +} diff --git a/fs/kernel/kernel.um b/fs/kernel/kernel.um new file mode 100644 index 0000000..61e784b --- /dev/null +++ b/fs/kernel/kernel.um @@ -0,0 +1,26 @@ +import ( + "std.um" + "input.um" + "/api/vfs.um" + "/api/rw.um" + "/user/user.um" +) + +fn outputConsole(data: ^void, size: uint) { + user::output(rw::reads(data, size)) +} + +fn init*() { + vfs::hookFlush(std::stdout(), outputConsole) + vfs::hookFlush(std::stderr(), outputConsole) + input::init() + user::init() +} + +fn irq*(irq: uint8, bytes: []uint8) { + input::irq(irq, bytes) +} + +fn schedule*() { + user::schedule() +} \ No newline at end of file diff --git a/fs/kernel/pic.um b/fs/kernel/pic.um new file mode 100644 index 0000000..1d7ac9c --- /dev/null +++ b/fs/kernel/pic.um @@ -0,0 +1,50 @@ +import ( + "/api/asm.um" +) + +const ( + masterCommand = 0x20 + masterData = 0x21 + slaveCommand = 0xA0 + slaveData = 0xA1 + + icw1Icw4 = 0x01 + icw1Init = 0x10 + icw48086 = 0x01 + + masterIrqs = 0x20 + slaveIrqs = 0x28 + slavePin = 2 +) + +fn init*() { + asm::iowait() + asm::out8(masterCommand, icw1Init | icw1Icw4) + asm::iowait() + asm::out8(slaveCommand, icw1Init | icw1Icw4) + asm::iowait() + asm::out8(masterData, masterIrqs) + asm::iowait() + asm::out8(slaveData, slaveIrqs) + asm::iowait() + asm::out8(masterData, 1 << slavePin) + asm::iowait() + asm::out8(slaveData, slavePin) + asm::iowait() + asm::out8(masterData, icw48086) + asm::iowait() + asm::out8(slaveData, icw48086) +} + +fn getMask*(): uint16 { + master := asm::in8(masterData) + slave := asm::in8(slaveData) + return (uint16(slave) << 8) | uint16(master) +} + +fn setMask*(mask: uint16) { + master := mask & 0xFF + slave := mask >> 8 + asm::out8(masterData, master) + asm::out8(slaveData, slave) +} \ No newline at end of file diff --git a/fs/main.um b/fs/main.um new file mode 100644 index 0000000..ad2b71d --- /dev/null +++ b/fs/main.um @@ -0,0 +1,28 @@ +import ( + "api/sym.um" + "kernel/kernel.um" + "api/rw.um" +) + + +fn system__register*(name: str, addr: ^void) { + sym::register(name, addr) +} + +fn api__setupTypePtr(i: int, t: ^void) +fn system__init*() { + api__setupTypePtr(0, typeptr(uint8)) + api__setupTypePtr(1, typeptr(uint16)) + api__setupTypePtr(2, typeptr(uint32)) + api__setupTypePtr(3, typeptr([]uint8)) + kernel::init() +} + +fn system__irq*(irq: uint8, data: ^void, count: uint) { + bytes := rw::reads8(data, count) + kernel::irq(irq, bytes) +} + +fn system__schedule*() { + kernel::schedule() +} diff --git a/fs/res/background.qoi b/fs/res/background.qoi new file mode 100644 index 0000000000000000000000000000000000000000..a514d0cf7aa7a2a44a86c3e213b37ca5d38f7a6c GIT binary patch literal 66935 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