1
0
Fork 0
forked from AbleOS/ableos

Compare commits

..

43 commits

Author SHA1 Message Date
peony 2d2bec803f Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-11-10 13:00:45 +01:00
peony 388d8c8c20 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-11-10 12:54:02 +01:00
peony 5c131eae13 misc 2024-11-10 12:51:51 +01:00
peony 7f920e2f65 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-11-10 11:02:04 +01:00
peony 97f7aa49f7 PS/2 work 2024-11-10 10:59:30 +01:00
peony 52b6272439 PS/2 work 2024-11-10 10:59:01 +01:00
peony d764dc9dd6 Don't ask. 2024-11-08 20:41:30 +01:00
peony d0f078cf10 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-11-04 02:58:58 +01:00
peony daced693fa Attempt at enabling the scrollwheel. 2024-11-04 02:47:09 +01:00
peony 2b13242f7f Mouse driver is good now! 2024-11-04 00:43:29 +01:00
peony d154c9fab1 Fixed mouse driver I think 2024-11-04 00:33:37 +01:00
peony f31d35703d Mouse driver finished for 3 button mice. 2024-11-03 23:04:10 +01:00
peony e670a0ef53 Simple mouse driver commands 2024-11-02 14:20:44 +01:00
peony 376a5213ac Removed triangle drawing stuff 2024-11-01 21:53:59 +01:00
peony 552b613151 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-11-01 21:17:14 +01:00
peony 5a44a707eb Nothin, null even 2024-11-01 20:42:18 +01:00
peony f52e3979a2 render.init safety checks 2024-11-01 20:26:31 +01:00
peony e3ec34684f framebuffer is ?^Color now. 2024-11-01 18:56:15 +01:00
peony d19f15aa5c I am good at this/s 2024-11-01 18:35:30 +01:00
peony 9e0a508a6f Very informative commit message 2024-11-01 18:34:10 +01:00
peony 20bb741bf1 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-27 16:59:03 +01:00
peony a95f1b5a4b Cube work 2024-10-27 16:54:59 +01:00
peony e6b972a7f3 Circle drawing, slightly bugged 2024-10-26 16:02:47 +02:00
peony 4a0f65753e Tri work 2024-10-25 17:58:19 +02:00
peony d143acb8b6 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-25 17:43:23 +02:00
peony f65f04460b more stubs 2024-10-25 17:39:00 +02:00
peony 223a1c15ad Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-25 16:28:45 +02:00
peony fe85a91548 Triangle rendering stubs. 2024-10-25 16:27:57 +02:00
peony f5ffed5662 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-25 16:01:02 +02:00
peony 382a4f5510 Literally 0 mouse driver work 2024-10-25 15:57:53 +02:00
peony f023773b2e Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-20 14:47:40 +02:00
peony b7d668c83a More mouse work 2024-10-20 14:46:25 +02:00
peony 92bf9207b3 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-20 14:21:48 +02:00
peony 0da9467a0f Bncha mouse driver stubs 2024-10-20 14:18:16 +02:00
peony f6dd752b77 Removed resize from the render TODO 2024-10-19 18:00:03 +02:00
peony 851e0bd94a Uuugh 2024-10-19 17:58:55 +02:00
peony 38c6f6cf47 Merge 2024-10-19 17:56:40 +02:00
peony 1c9ca8962e Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-19 17:56:20 +02:00
peony 8d36083729 Fixed scaling bug 2024-10-19 17:40:42 +02:00
peony ad351155da Added put_scaled. 2024-10-19 17:35:20 +02:00
peony 1039db1247 Merge branch 'master' of https://git.ablecorp.us/AbleOS/ableos 2024-10-16 00:39:27 +02:00
peony fbdf737306 Adds a very broken (literally doesn't work) sound driver. 2024-10-16 00:32:32 +02:00
peony 15c978f90f Merge remote-tracking branch 'ableos/master' 2024-10-14 22:06:05 +02:00
78 changed files with 877 additions and 1893 deletions

126
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
version = 3
[[package]]
name = "aarch64-cpu"
@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "allocator-api2"
version = "0.2.20"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f"
[[package]]
name = "anyhow"
@ -65,6 +65,15 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
dependencies = [
"allocator-api2",
]
[[package]]
name = "byteorder"
version = "1.5.0"
@ -73,9 +82,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.2.1"
version = "1.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
dependencies = [
"shlex",
]
@ -199,6 +208,12 @@ dependencies = [
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.1"
@ -213,23 +228,24 @@ dependencies = [
[[package]]
name = "hbbytecode"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#86ca959ea3eae1cb32298e135a444820583d24a0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
[[package]]
name = "hblang"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#86ca959ea3eae1cb32298e135a444820583d24a0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
dependencies = [
"hashbrown",
"hashbrown 0.15.1",
"hbbytecode",
"hbvm",
"log",
"regalloc2",
]
[[package]]
name = "hbvm"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#86ca959ea3eae1cb32298e135a444820583d24a0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
dependencies = [
"hbbytecode",
]
@ -380,7 +396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.15.1",
]
[[package]]
@ -390,9 +406,8 @@ dependencies = [
"aarch64-cpu",
"crossbeam-queue",
"derive_more",
"hashbrown",
"hashbrown 0.15.1",
"hbvm",
"ktest_macro",
"limine",
"log",
"sbi",
@ -405,14 +420,6 @@ dependencies = [
"xml",
]
[[package]]
name = "ktest_macro"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@ -421,9 +428,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.164"
version = "0.2.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
[[package]]
name = "limine"
@ -433,9 +440,9 @@ checksum = "02034f8f6b3e7bf050f310fbaf6db0018b8e54b75598d0a4c97172054752fede"
[[package]]
name = "litemap"
version = "0.7.4"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
[[package]]
name = "lock_api"
@ -512,9 +519,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "proc-macro2"
version = "1.0.92"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
@ -546,6 +553,19 @@ dependencies = [
"bitflags 2.6.0",
]
[[package]]
name = "regalloc2"
version = "0.10.2"
source = "git+https://github.com/jakubDoka/regalloc2?branch=reuse-allocations#21c43e3ee182824e92e2b25f1d3c03ed47f9c02b"
dependencies = [
"allocator-api2",
"bumpalo",
"hashbrown 0.14.5",
"log",
"rustc-hash",
"smallvec",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
@ -582,6 +602,12 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "rustc-hash"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
[[package]]
name = "rustc_version"
version = "0.4.1"
@ -593,9 +619,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.18"
version = "0.23.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f"
checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e"
dependencies = [
"log",
"once_cell",
@ -649,18 +675,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.215"
version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.215"
version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
dependencies = [
"proc-macro2",
"quote",
@ -726,9 +752,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.89"
version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
@ -798,9 +824,9 @@ dependencies = [
[[package]]
name = "uart_16550"
version = "0.3.2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e492212ac378a5e00da953718dafb1340d9fbaf4f27d6f3c5cab03d931d1c049"
checksum = "4922792855b1bce30997fbaa5418597902c278a92d20dfe348e6f062c3bd861d"
dependencies = [
"bitflags 2.6.0",
"rustversion",
@ -809,9 +835,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.14"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-xid"
@ -842,9 +868,9 @@ dependencies = [
[[package]]
name = "url"
version = "2.5.4"
version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada"
dependencies = [
"form_urlencoded",
"idna",
@ -885,9 +911,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "webpki-roots"
version = "0.26.7"
version = "0.26.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e"
checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958"
dependencies = [
"rustls-pki-types",
]
@ -1044,9 +1070,9 @@ dependencies = [
[[package]]
name = "yoke"
version = "0.7.5"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
dependencies = [
"serde",
"stable_deref_trait",
@ -1056,9 +1082,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
version = "0.7.5"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
dependencies = [
"proc-macro2",
"quote",
@ -1068,18 +1094,18 @@ dependencies = [
[[package]]
name = "zerofrom"
version = "0.1.5"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
version = "0.1.5"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
dependencies = [
"proc-macro2",
"quote",

View file

@ -1,96 +0,0 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1732014248,
"narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "23e89b7da85c3640bbc2173fe04f4bd114342367",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1728538411,
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1732328983,
"narHash": "sha256-RHt12f/slrzDpSL7SSkydh8wUE4Nr4r23HlpWywed9E=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "ed8aa5b64f7d36d9338eb1d0a3bb60cf52069a72",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,30 +0,0 @@
{
description = "A devShell example";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, rust-overlay, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs {
inherit system overlays;
};
rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
in
with pkgs;
{
devShells.default = mkShell {
buildInputs = [
rustToolchain
qemu_full
];
};
}
);
}

View file

@ -3,15 +3,12 @@ edition = "2021"
name = "kernel"
version = "0.2.0"
[features]
ktest = []
[dependencies]
# embedded-graphics = "0.8"
hbvm = { git = "https://git.ablecorp.us/AbleOS/holey-bytes.git", features = [
"nightly",
] }
ktest_macro = { path = "ktest_macro" }
log = "0.4"
spin = "0.9"
slab = { version = "0.4", default-features = false }

View file

@ -1,11 +0,0 @@
[package]
edition = "2021"
name = "ktest_macro"
version = "0.1.0"
[lib]
proc-macro = true
[dependencies]
quote = "1.0.37"
syn = { version = "2.0.89", features = ["full"] }

View file

@ -1,29 +0,0 @@
extern crate proc_macro;
extern crate quote;
extern crate syn;
use {
proc_macro::TokenStream,
quote::quote,
syn::{parse_macro_input, ItemFn}
};
#[proc_macro_attribute]
pub fn ktest(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as ItemFn);
let test_name = &input.sig.ident;
let static_var_name = syn::Ident::new(
&format!("__ktest_{}", test_name),
test_name.span(),
);
let out = quote! {
// #[cfg(feature = "ktest")]
#input
// #[cfg(feature = "ktest")]
#[unsafe(link_section = ".note.ktest")]
#[used]
pub static #static_var_name: fn() = #test_name;
};
TokenStream::from(out)
}

View file

@ -38,16 +38,8 @@ SECTIONS
.data : {
*(.data .data.*)
*(.got .got.*)
} :data
/* Add the .ktest section for test functions */
.note.ktest : {
__ktest_start = .; /* Mark the beginning of the section */
*(.note.ktest) /* Include all items in the .ktest section */
__ktest_end = .; /* Mark the end of the section */
}
.bss : {
*(COMMON)
*(.bss .bss.*)

View file

@ -14,29 +14,3 @@ arch_cond!(
riscv64: "riscv64",
x86_64: "x86_64",
);
#[cfg(target_arch = "x86_64")]
use {crate::arch::interrupts::Interrupt, alloc::string::String};
#[cfg(target_arch = "x86_64")]
pub struct InterruptList {
list: HashMap<Interrupt, String>,
}
#[cfg(target_arch = "x86_64")]
use hashbrown::HashMap;
#[cfg(target_arch = "x86_64")]
impl InterruptList {
pub fn new() -> Self {
Self {
list: HashMap::new(),
}
}
}
#[cfg(target_arch = "x86_64")]
use spin::{Lazy, Mutex};
#[cfg(target_arch = "x86_64")]
pub static INTERRUPT_LIST: Lazy<Mutex<InterruptList>> = Lazy::new(|| {
let mut il = InterruptList::new();
use crate::alloc::string::ToString;
il.list.insert(Interrupt::Timer, "PS/2 Mouse".to_string());
Mutex::new(il)
});

View file

@ -11,9 +11,7 @@ static mut LAPIC: LocalApic = unsafe { MaybeUninit::zeroed().assume_init() };
static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() };
#[repr(u8)]
#[derive(Debug, Eq, Hash, PartialEq)]
pub enum Interrupt {
enum Interrupt {
Timer = 32,
ApicErr = u8::MAX - 1,
Spurious = u8::MAX,
@ -62,49 +60,17 @@ extern "x86-interrupt" fn page_fault(
}
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
// interrupt(Interrupt::Timer);
unsafe {
LAPIC.end_of_interrupt();
}
}
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
interrupt(Interrupt::ApicErr);
panic!("Internal APIC error");
}
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
interrupt(Interrupt::Spurious);
unsafe {
LAPIC.end_of_interrupt();
}
}
fn interrupt(interrupt_type: Interrupt) {
use crate::arch::INTERRUPT_LIST;
let il = INTERRUPT_LIST.lock();
let val = il.list.get(&interrupt_type).unwrap();
use crate::holeybytes::kernel_services::service_definition_service::sds_search_service;
let buffer = sds_search_service(val);
if buffer != 0 {
use {crate::kmain::IPC_BUFFERS, alloc::vec::Vec};
let mut buffs = IPC_BUFFERS.lock();
match buffs.get_mut(&buffer) {
Some(buff) => {
let mut msg_vec = Vec::new();
msg_vec.push(0xFF);
buff.push(msg_vec.to_vec());
log::debug!("Sent Message {:?} to Buffer({})", msg_vec, buffer);
}
None => {
log::error!("Access of non-existent buffer {}", buffer)
}
}
// log::info!("{}", buffer);
}
}

View file

@ -33,7 +33,7 @@ const INITIAL_KERNEL_HEAP_SIZE: *const () = _initial_kernel_heap_size as _;
#[cfg(not(target_feature = "avx2"))]
unsafe extern "C" fn _kernel_start() -> ! {
// Initialise SSE, then jump to kernel entrypoint
core::arch::naked_asm!(
core::arch::asm!(
// Initialise SSE
"mov rax, cr0",
"and ax, 0xfffb",
@ -46,6 +46,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
// Jump to the kernel entry point
"jmp {}",
sym start,
options(noreturn),
)
}
@ -53,7 +54,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
#[naked]
#[cfg(target_feature = "avx2")]
unsafe extern "C" fn _kernel_start() -> ! {
core::arch::naked_asm!(
core::arch::asm!(
// Enable protected mode and configure control registers
"mov rax, cr0",
"and ax, 0xFFFB", // Clear CR0.EM (bit 2) for coprocessor emulation
@ -99,6 +100,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
"jmp {0}",
sym start,
sym oops,
options(noreturn),
)
}
@ -109,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
unsafe extern "C" fn start() -> ! {
logging::init();
crate::logger::init().expect("failed to set logger");
log::debug!("Initialising AKern {}", crate::VERSION);
log::info!("Initialising AKern {}", crate::VERSION);
static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
memory::init_pt(VirtAddr::new(
@ -188,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
// TODO: Add in rdseed and rdrand as sources for randomness
let _rand = xml::XMLElement::new("Random");
log::debug!("Getting boot modules");
log::trace!("Getting boot modules");
let bm = MOD_REQ.get_response().get();
let mut bootmodules = alloc::vec::Vec::new();
@ -226,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
break;
}
}
log::debug!("Boot module count: {:?}", bootmodules.len());
log::info!("Boot module count: {:?}", bootmodules.len());
assert_eq!(bm.module_count, bootmodules.len() as u64);
}

View file

@ -69,7 +69,7 @@ pub fn check_device(bus: u8, device: u8) -> Option<PciDeviceInfo> {
}
let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) };
log::debug!("pci device-({}) addr {} is {}", device, addr, reg2);
log::info!("pci device-({}) addr {} is {}", device, addr, reg2);
let class = ((reg2 >> 16) & 0x0000_FFFF) as u16;
let pci_class = PciFullClass::from_u16(class);
let header_type = get_header_type(bus, device, 0);

View file

@ -1,17 +1,8 @@
//! Environment call handling routines
use {alloc::boxed::Box, core::cell::LazyCell, hbvm::mem::Address};
use crate::{
holeybytes::{
kernel_services::{
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
service_definition_service::sds_msg_handler,
},
ExecThread,
},
kmain::EXECUTOR,
task::Executor,
use crate::holeybytes::kernel_services::{
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
service_definition_service::sds_msg_handler,
};
use {
@ -67,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
true => IpcBuffer::new(true, length),
},
);
info!("Buffer ID: {}", buff_id);
vm.registers[1] = hbvm::value::Value(buff_id);
}
2 => {
log::error!("Oops, deleting buffers is not implemented.")
// Delete buffer
}
3 => {
@ -152,43 +143,6 @@ pub fn handler(vm: &mut Vm) {
Ok(()) => {}
Err(_) => log::error!("Improper dt query"),
},
6 => unsafe {
let program = block_read(mem_addr, length);
// decode AbleOS Executable format
let header = &program[0..46];
let magic_slice = &header[0..3];
if magic_slice != [0x15, 0x91, 0xD2] {
log::error!("Invalid magic number at the start of executable.");
return;
}
let executable_format_version =
u32::from_le_bytes(header[3..7].try_into().unwrap());
let offset = if executable_format_version == 0 {
47
} else {
error!("Invalid executable format.");
return;
};
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
let end = (code_length + data_length) as usize;
log::debug!("{code_length} + {data_length} = {end}");
let thr = ExecThread::new(&program[offset..end], Address::new(0));
vm.registers[1] = Value(
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
.unwrap()
.spawn(Box::pin(async move {
if let Err(e) = thr.await {
log::error!("{e:?}");
}
})) as u64,
);
log::debug!("spawned a process");
},
buffer_id => {
let mut buffs = IPC_BUFFERS.lock();
@ -228,7 +182,7 @@ pub fn handler(vm: &mut Vm) {
} else {
unsafe {
let ptr = map_ptr as *mut u8;
ptr.copy_from_nonoverlapping(msg.as_ptr(), msg.len());
ptr.copy_from(msg.as_ptr(), msg.len());
}
debug!("Recieve {:?} from Buffer({})", msg, buffer_id);

View file

@ -9,20 +9,7 @@ use log::Record;
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
let msg_vec = block_read(mem_addr, length);
use log::Level::*;
let log_level = match msg_vec[0] {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
if log_level > log::max_level() {
return Ok(());
}
let log_level = msg_vec[0];
let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap());
let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize;
@ -33,6 +20,18 @@ pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(),
match core::str::from_utf8(&str) {
Ok(strr) => {
use log::Level::*;
let log_level = match log_level {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
log::logger().log(
&Record::builder()
.args(format_args!("{}", strr))

View file

@ -25,16 +25,42 @@ fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryS
}
#[inline(always)]
unsafe fn memset(dest: *mut u8, src: *const u8, count: usize, size: usize) {
let total_size = count * size;
src.copy_to_nonoverlapping(dest, size);
unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) {
const BLOCK_SIZE: usize = 64;
let mut remaining = count * size;
let mut copied = size;
if remaining < 16 {
src.copy_to_nonoverlapping(dest, remaining);
return;
}
while copied < total_size {
let copy_size = copied.min(total_size - copied);
dest.add(copied).copy_from_nonoverlapping(dest, copy_size);
copied += copy_size;
let mut buffer = [0u8; BLOCK_SIZE];
let mut buffer_size = size;
src.copy_to_nonoverlapping(buffer.as_mut_ptr(), size);
while core::intrinsics::likely(buffer_size * 2 <= BLOCK_SIZE) {
buffer
.as_mut_ptr()
.copy_to_nonoverlapping(buffer.as_mut_ptr().add(buffer_size), buffer_size);
buffer_size *= 2;
}
let buffer_ptr = buffer.as_ptr() as *const u64;
while (dest as usize) & 7 != 0 && remaining >= 8 {
buffer.as_ptr().copy_to_nonoverlapping(dest, 1);
dest = dest.add(1);
remaining -= 1;
}
while core::intrinsics::likely(remaining >= 8) {
*(dest as *mut u64) = *buffer_ptr;
dest = dest.add(8);
remaining -= 8;
}
if remaining > 0 {
buffer.as_ptr().copy_to_nonoverlapping(dest, remaining);
}
}

View file

@ -92,7 +92,8 @@ fn sds_create_service(protocol: &'static str) -> u64 {
// let a: protocol::Protocol = protocol.into();
buff_id
}
pub fn sds_search_service(protocol: &str) -> u64 {
fn sds_search_service(protocol: &str) -> u64 {
let services = SERVICES.lock();
let compare = Protocol::from(protocol);
for (bid, protocol_canidate) in &services.0 {

View file

@ -1,5 +1,5 @@
mod ecah;
pub mod kernel_services;
mod kernel_services;
mod mem;
use {

View file

@ -8,10 +8,7 @@ use {
device_tree::DeviceTree,
holeybytes::ExecThread,
ipc::buffer::IpcBuffer,
task::Executor,
},
alloc::boxed::Box,
core::cell::LazyCell,
hashbrown::HashMap,
hbvm::mem::Address,
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
@ -22,14 +19,6 @@ use {
pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
debug!("Entered kmain");
#[cfg(feature = "ktest")] {
use crate::ktest;
debug!("TESTING");
ktest::test_main();
loop {};
}
// let kcmd = build_cmd("Kernel Command Line", cmdline);
// trace!("Cmdline: {kcmd:?}");
@ -76,24 +65,13 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
fb1.address.as_ptr().unwrap() as *const u8
);
let mut executor = crate::task::Executor::new(256);
unsafe {
let executor = LazyCell::<Executor>::force_mut(&mut EXECUTOR);
for module in boot_modules.iter() {
let cmd = module.cmd.trim_matches('"');
let cmd_len = cmd.len() as u64;
log::info!(
"Starting {}",
module
.path
.split('/')
.last()
.unwrap()
.split('.')
.next()
.unwrap()
);
log::debug!("Spawning {} with arguments \"{}\"", module.path, cmd);
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
// decode AbleOS Executable format
let header = &module.bytes[0..46];
@ -114,17 +92,17 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
let end = (code_length + data_length) as usize;
log::debug!("{code_length} + {data_length} = {end}");
log::info!("{code_length} + {data_length} = {end}");
let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0));
if cmd_len > 0 {
thr.set_arguments(cmd.as_ptr() as u64, cmd_len);
}
executor.spawn(Box::pin(async move {
executor.spawn(async move {
if let Err(e) = thr.await {
log::error!("{e:?}");
}
}));
})
}
debug!("Random number: {}", hardware_random_u64());
@ -135,10 +113,6 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
crate::arch::spin_loop()
}
// ! SAFETY: this is not threadsafe at all, like even a little bit.
// ! SERIOUSLY
pub static mut EXECUTOR: LazyCell<Executor> = LazyCell::new(|| Executor::new());
pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
let dt = DeviceTree::new();
Mutex::new(dt)
@ -156,3 +130,10 @@ pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
Mutex::new(bufs)
});
#[test_case]
fn trivial_assertion() {
trace!("trivial assertion... ");
assert_eq!(1, 1);
info!("[ok]");
}

View file

@ -1,38 +0,0 @@
pub use ktest_macro::ktest;
use log::debug;
extern "C" {
static __ktest_start: fn();
static __ktest_end: fn();
}
// TODO: Get test_fn linker name (may require no_mangle in macro)
// More info on tests (run the rest even if panic)
// Implement ktest for arm and riscv (Later problems, see below)
// Allow for arch specific tests (Leave for now)
// Allow for ktest test name attr
// Usefull message at the end of testing
pub fn test_main() {
unsafe {
let mut current_test = &__ktest_start as *const fn();
let mut current = 1;
let test_end = &__ktest_end as *const fn();
while current_test < test_end {
let test_fn = *current_test;
debug!("Running test {}", current);
test_fn();
debug!("Test {} passed", current);
current_test = current_test.add(1);
current += 1;
}
}
}
#[ktest]
pub fn trivial_assertion() {
assert_eq!(1, 1);
}

View file

@ -2,19 +2,20 @@
//! Named akern.
//! Akern is woefully undersupported at the moment but we are looking to add support improve hardware discovery and make our lives as kernel and operating system developers easier and better
#![no_std]
#![no_main]
#![feature(
slice_split_once,
exclusive_wrapper,
new_uninit,
core_intrinsics,
abi_x86_interrupt,
lazy_get,
alloc_error_handler,
ptr_sub_ptr,
custom_test_frameworks,
naked_functions,
pointer_is_aligned_to,
pointer_is_aligned_to
)]
#![allow(dead_code, internal_features, static_mut_refs)]
#![test_runner(crate::test_runner)]
#![allow(dead_code, internal_features)]
extern crate alloc;
mod allocator;
@ -32,10 +33,6 @@ mod memory;
mod task;
mod utils;
// #[cfg(feature = "tests")]
mod ktest;
use alloc::string::ToString;
use versioning::Version;
/// Kernel's version
@ -59,7 +56,15 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
));
}
let msg = info.message().to_string().replace("\n", "\r\n");
let msg = info.message();
let _ = crate::arch::log(format_args!("{msg}\r\n"));
loop {}
}
#[cfg(test)]
fn test_runner(tests: &[&dyn Fn()]) {
println!("Running {} tests", tests.len());
for test in tests {
test();
}
}

View file

@ -29,24 +29,24 @@ pub fn yield_now() -> impl Future<Output = ()> {
YieldNow(false)
}
pub struct Executor {
tasks: Slab<Task>,
pub struct Executor<F: Future<Output = ()> + Send> {
tasks: Slab<Task<F>>,
task_queue: Arc<TaskQueue>,
}
impl Executor {
pub fn new() -> Self {
impl<F: Future<Output = ()> + Send> Executor<F> {
pub fn new(size: usize) -> Self {
Self {
tasks: Slab::new(),
tasks: Slab::with_capacity(size),
task_queue: Arc::new(TaskQueue::new()),
}
}
#[inline]
pub fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) -> usize {
let id = self.tasks.insert(Task::new(future));
self.task_queue.queue.push(id);
id
pub fn spawn(&mut self, future: F) {
self.task_queue
.queue
.push(self.tasks.insert(Task::new(future)));
}
pub fn run(&mut self) {
@ -83,17 +83,17 @@ impl Executor {
}
}
struct Task {
future: Pin<Box<dyn Future<Output = ()> + Send>>,
struct Task<F: Future<Output = ()> + Send> {
future: Pin<Box<F>>,
waker: Option<TaskWaker>,
}
impl Task {
impl<F: Future<Output = ()> + Send> Task<F> {
#[inline(always)]
pub fn new(future: Pin<Box<dyn Future<Output = ()> + Send>>) -> Self {
pub fn new(future: F) -> Self {
Self {
future,
waker: None,
future: Box::pin(future),
waker: None,
}
}

View file

@ -1,6 +1,6 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"disable-redzone": true,
"env": "",
"executables": true,

View file

@ -1,6 +1,5 @@
#![allow(unused)]
use std::{
collections::HashMap,
fmt::format,
fs::{read_to_string, File},
io::{BufWriter, Write},
@ -14,7 +13,6 @@ pub struct Package {
name: String,
binaries: Vec<String>,
build_cmd: String,
args: HashMap<String, String>,
}
impl Package {
@ -48,46 +46,36 @@ impl Package {
let mut binaries = vec![];
for (count, (name, table)) in bin_table.into_iter().enumerate() {
// if count != 0 {
binaries.push(name.clone());
// }
}
let build_table = data.get("build").unwrap();
let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into();
build_cmd.remove(0);
let mut args: HashMap<String, String> = match build_table.get("args") {
None => HashMap::new(),
Some(v) => v
.as_table()
.unwrap()
.into_iter()
.map(|(k, v)| (k.clone(), v.to_string()))
.collect::<HashMap<String, String>>(),
};
// build_cmd.pop();
Self {
name,
binaries,
build_cmd,
args,
}
}
pub fn build(&self, out: &mut Vec<u8>) -> std::io::Result<()> {
if self.binaries.contains(&"hblang".to_string()) {
let file = self.build_cmd.split_ascii_whitespace().last().unwrap();
let path = format!("sysdata/programs/{}/{}", self.name, file);
// compile here
let mut warnings = String::new();
hblang::run_compiler(
&path,
Options {
fmt: true,
in_house_regalloc: true,
..Default::default()
},
out,
&mut warnings,
)?;
match std::fs::create_dir("target/programs") {
@ -99,11 +87,9 @@ impl Package {
hblang::run_compiler(
&path,
Options {
in_house_regalloc: true,
..Default::default()
},
out,
&mut warnings,
)?;
std::fs::write(format!("target/programs/{}.hbf", self.name), &out)?;
out.clear();
@ -112,11 +98,9 @@ impl Package {
&path,
Options {
dump_asm: true,
in_house_regalloc: true,
..Default::default()
},
out,
&mut warnings,
)?;
std::fs::write(format!("target/programs/{}.hba", self.name), &out)?;
out.clear();

View file

@ -27,7 +27,6 @@ fn main() -> Result<(), Error> {
let mut release = false;
let mut debuginfo = false;
let mut target = Target::X86_64;
let mut tests = false;
for arg in args {
if arg == "-r" || arg == "--release" {
release = true;
@ -39,42 +38,17 @@ fn main() -> Result<(), Error> {
target = Target::Aarch64;
} else if arg == "avx2" {
target = Target::X86_64Avx2;
} else if arg == "--ktest" {
tests = true;
} else {
return Err(report!(Error::InvalidSubCom));
}
}
build(release, target, debuginfo, tests).change_context(Error::Build)
build(release, target, debuginfo).change_context(Error::Build)
}
// Some("test" | "t") => {
// let mut release = false;
// let mut debuginfo = false;
// let mut target = Target::X86_64;
// for arg in args {
// if arg == "-r" || arg == "--release" {
// release = true;
// } else if arg == "-d" || arg == "--debuginfo" {
// debuginfo = true;
// } else if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
// target = Target::Riscv64Virt;
// } else if arg == "arm64" || arg == "aarch64" || arg == "aarch64-virt" {
// target = Target::Aarch64;
// } else if arg == "avx2" {
// target = Target::X86_64Avx2;
// } else {
// return Err(report!(Error::InvalidSubCom));
// }
// }
// test(release, target, debuginfo).change_context(Error::Build)
// }
Some("run" | "r") => {
let mut release = false;
let mut debuginfo = false;
let mut target = Target::X86_64;
let mut tests = false;
let mut do_accel = true;
for arg in args {
if arg == "-r" || arg == "--release" {
@ -89,14 +63,12 @@ fn main() -> Result<(), Error> {
do_accel = false;
} else if arg == "avx2" {
target = Target::X86_64Avx2;
} else if arg == "--ktest" {
tests = true;
} else {
return Err(report!(Error::InvalidSubCom));
}
}
build(release, target, debuginfo, tests)?;
build(release, target, debuginfo)?;
run(release, target, do_accel)
}
Some("help" | "h") => {
@ -110,7 +82,6 @@ fn main() -> Result<(), Error> {
" -r / --release: build in release mode\n",
" -d / --debuginfo: build with debug info\n",
" --noaccel: run without acceleration (e.g, no kvm)\n",
" --ktest: Enables tests via ktest\n",
"[ rv64 / riscv64 / riscv64-virt / aarch64 / arm64 / aarch64-virt / avx2 ]: sets target"
),);
Ok(())
@ -339,7 +310,7 @@ fn copy_file_to_img(fpath: &str, fs: &FileSystem<File>) {
.expect("Copy failed");
}
fn build(release: bool, target: Target, debuginfo: bool, tests: bool) -> Result<(), Error> {
fn build(release: bool, target: Target, debuginfo: bool) -> Result<(), Error> {
let fs = get_fs().change_context(Error::Io)?;
let mut com = Command::new("cargo");
com.current_dir("kernel");
@ -351,10 +322,6 @@ fn build(release: bool, target: Target, debuginfo: bool, tests: bool) -> Result<
com.env("RUSTFLAGS", "-Cdebug-assertions=true");
}
if tests {
com.args(["--features", "ktest"]);
}
if target == Target::Riscv64Virt {
com.args(["--target", "targets/riscv64-virt-ableos.json"]);
}
@ -411,7 +378,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
};
let (mut com, mut com2) = (Command::new(target_str), Command::new(target_str));
let ovmf_path = fetch_ovmf(target);
#[cfg(target_arch = "x86_64")]
let accel = if do_accel {
let supported = String::from_utf8(
com2.args(["--accel", "help"])
@ -447,8 +413,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
} else {
"accel=tcg"
};
#[cfg(not(target_arch = "x86_64"))]
let accel = "accel=tcg";
match target {
Target::X86_64 | Target::X86_64Avx2 => {
@ -464,6 +428,11 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
"-monitor", "none",
"-machine", accel,
"-cpu", "max",
//"-serial", "stdio",
//"-d", "trace:ps2_mouse_send_packet",
//"-d", "trace:ps2_mouse_event_disabled",
"-audiodev", "pa,id=speaker",
"-machine", "pcspk-audiodev=speaker",
"-device", "isa-debug-exit,iobase=0xf4,iosize=0x04",
]);
}
@ -506,7 +475,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
}
}
fn fetch_ovmf(target: Target) -> Result<String, OvmfFetchError> {
let (ovmf_url, ovmf_path) = match target {
Target::X86_64 | Target::X86_64Avx2 => (

View file

@ -1,5 +1,3 @@
[toolchain]
# old toolchain
# channel = "nightly-2024-07-27"
channel = "nightly-2024-11-20"
channel = "nightly-2024-07-27"
components = ["rust-src", "llvm-tools"]

View file

@ -3,7 +3,7 @@ stn := @use("../../../../libraries/stn/src/lib.hb");
.{Vec2} := stn.math
render := @use("../../../../libraries/render/src/lib.hb");
.{Surface, Color} := render;
.{Surface} := render;
.{Font} := render.text
Label := struct {
@ -12,8 +12,6 @@ Label := struct {
surface: Surface,
text: ^u8,
text_length: uint,
bg: Color,
fg: Color,
}
set_label_text := fn(label: Label, text: ^u8): void {
@ -26,8 +24,8 @@ set_label_text := fn(label: Label, text: ^u8): void {
render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void {
if label.is_dirty {
render.clear(label.surface, label.bg)
render.put_text(label.surface, font, .(0, 0), label.fg, label.text)
render.clear(label.surface, render.black)
render.put_text(label.surface, font, .(0, 0), render.white, label.text)
}
render.put_surface(surface, label.surface, pos, false)
}
@ -35,12 +33,6 @@ render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: V
new_label := fn(text: ^u8): Label {
text_surface := render.new_surface(1024, 20)
text_length := string.length(text)
label := Label.(3, true, text_surface, text, text_length, render.black, render.white)
label := Label.(3, true, text_surface, text, text_length)
return label
}
$set_color := fn(label: Label, bg: Color, fg: Color): void {
label.bg = bg
label.fg = fg
label.is_dirty = true
}

View file

@ -1,9 +1,13 @@
keycodes := @use("keycodes.hb");
.{KeyCode} := keycodes
KeyEvent := packed struct {
up: bool,
just_triggered: bool,
KeyEvent := struct {
// 0 if down
// 1 if up
up: u8,
// 0 if not just triggered
// 1 if just triggered
just_triggered: u8,
key: KeyCode,
}

View file

@ -6,17 +6,6 @@ events := @use("events.hb");
.{KeyEvent, MouseEvent} := events
recieve_key_event := fn(): ?KeyEvent {
kevent := KeyEvent.(false, false, 0)
buf_id := buffer.search("PS/2 Keyboard\0")
// Read out of the Keyboard buffer here
buffer.recv(KeyEvent, buf_id, &kevent)
if kevent.just_triggered {
return kevent
}
return null
}
@ -26,7 +15,7 @@ recieve_mouse_event := fn(): ?MouseEvent {
buf_id := buffer.search("PS/2 Mouse\0")
// Read out of the Mouse buffer here
buffer.recv(MouseEvent, buf_id, &mevent)
buffer.recv(MouseEvent, buf_id, @bitcast(&mevent))
if mevent.x_change != 0 | mevent.y_change != 0 | mevent.left | mevent.middle | mevent.right {
return mevent

View file

@ -1,4 +1,7 @@
# Images
- General over image format
- Support formats:
- PNG
- Animation
# API
@ -7,7 +10,6 @@
- Invert
- Surface Operations:
- FlipH
- Resize
- Wrap the colour operations
- Tile
- Gradient overlay

View file

@ -1,5 +1,5 @@
.{Color, Surface, new_surface, put_surface} := @use("../lib.hb");
.{log} := @use("../../../stn/src/lib.hb")
.{log, memory} := @use("../../../stn/src/lib.hb")
BitmapFileHeader := packed struct {
magic: u16,
@ -41,7 +41,7 @@ from := fn(bmp: ^u8): ?Surface {
return null
}
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height, info_header.width * info_header.height)
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height)
rhs := new_surface(info_header.width, info_header.height)
put_surface(rhs, lhs, .(0, 0), true)

View file

@ -1,5 +1,5 @@
.{Color, Surface, new_surface} := @use("../lib.hb");
.{log} := @use("../../../stn/src/lib.hb")
.{log, memory} := @use("../../../stn/src/lib.hb")
/* source:
https://github.com/phoboslab/qoi/blob/master/qoi.h */
@ -13,7 +13,7 @@ $QOI_OP_RUN := 0xC0
$QOI_OP_RGB := 0xFE
$QOI_OP_RGBA := 0xFF
$QOI_MASK_2 := 0xC0
$QOI_COLOR_HASH := fn(c: Color): u8 {
QOI_COLOR_HASH := fn(c: Color): u8 {
return (c.r * 3 + c.g * 5 + c.b * 7 + c.a * 11) % 64
}
$QOI_MAGIC := 0x716F6966
@ -89,7 +89,7 @@ from := fn(qoi: ^u8): ?Surface {
run = b1 & 0x3F
}
index[QOI_COLOR_HASH(px)] = px
index[@inline(QOI_COLOR_HASH, px)] = px
};
*(surface.buf + px_pos) = px

View file

@ -38,20 +38,18 @@ $light_cyan := Color.(255, 255, 0, 255)
put_pixel := mode.put_pixel
put_rect := mode.put_rect
put_filled_rect := mode.put_filled_rect
put_trirect := mode.put_trirect
put_circle := mode.put_circle
put_filled_circle := mode.put_filled_circle
put_textured_circle := mode.put_textured_circle
put_line := mode.put_line
put_vline := mode.put_vline
put_hline := mode.put_hline
clear := mode.clear
put_surface := mode.put_surface
put_scaled := mode.put_scaled
put_text := mode.put_text
// thanks peony for these three!
//put_trirect := mode.put_trirect
//put_vline := mode.put_vline
//put_hline := mode.put_hline
put_trirect := mode.put_trirect
put_vline := mode.put_vline
put_hline := mode.put_hline
// Display
sync := mode.sync

View file

@ -1,72 +1,102 @@
.{math, memory, dt} := @use("../../stn/src/lib.hb");
.{math, memory, dt, log} := @use("../../stn/src/lib.hb");
.{Color, text} := @use("lib.hb");
.{get_glyph, get_glyph_unicode, Font, UNC_TABLE_SIZE} := text;
.{Vec2} := math
// safety: don't use before init() or you will get a memory access violation
framebuffer := memory.dangling(Color)
//framebuffer := memory.dangling(Color)
Surface := struct {
buf: ^Color,
width: uint,
height: uint,
size: uint,
}
new_surface := fn(width: uint, height: uint): Surface {
return .(
memory.alloc(Color, width * height),
@inline(memory.alloc, Color, width * height),
width,
height,
width * height,
)
}
clone_surface := fn(surface: ^Surface): Surface {
new := new_surface(surface.width, surface.height)
memory.copy(Color, surface.buf, new.buf, @intcast(surface.size))
@inline(memory.copy, Color, surface.buf, new.buf, @intcast(surface.width * surface.height))
return new
}
init := fn(doublebuffer: bool): Surface {
// ! is broken, check memory.free function
free_surface := fn(surface: Surface): void {
return @inline(memory.free, Color, surface.buf, @intcast(surface.width * surface.height), false)
}
framebuffer := @as(?^Color, null)
init := fn(doublebuffer: bool): ?Surface {
framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
width := dt.get(uint, "framebuffer/fb0/width\0")
height := dt.get(uint, "framebuffer/fb0/height\0")
errlevel := 0
if framebuffer == null {
log.error("'framebuffer/fb0/ptr' is null\0")
errlevel = 1
}
if width == null {
log.error("'framebuffer/fb0/width' is null\0")
errlevel = 1
}
if height == null {
log.error("'framebuffer/fb0/height' is null\0")
errlevel = 1
}
if errlevel > 0 return null
if doublebuffer {
return new_surface(width, height)
return new_surface(@unwrap(width), @unwrap(height))
} else {
return .(framebuffer, width, height, width * height)
return .(@unwrap(framebuffer), @unwrap(width), @unwrap(height))
}
}
$clear := fn(surface: Surface, color: Color): void {
memory.set(Color, &color, surface.buf, surface.width * surface.height)
clear := fn(surface: Surface, color: Color): void {
return @inline(memory.set, Color, &color, surface.buf, surface.width * surface.height)
}
$sync := fn(surface: Surface): void {
memory.copy(Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
sync := fn(surface: Surface): void {
// vague safety
if framebuffer == null {
return
}
if surface.buf == framebuffer {
return
}
return @inline(memory.copy, Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
}
$index := fn(surface: Surface, x: uint, y: uint): uint {
index := fn(surface: Surface, x: uint, y: uint): uint {
return x + surface.width * y
}
$indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
return surface.buf + index(surface, x, y)
indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
return surface.buf + @inline(index, surface, x, y)
}
$put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
return *indexptr(surface, pos.x, pos.y) = color
put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
*@inline(indexptr, surface, pos.x, pos.y) = color
return
}
put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
top_start_idx := indexptr(surface, pos.x, pos.y)
bottom_start_idx := indexptr(surface, pos.x, pos.y + tr.y - 1)
top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1)
rows_to_fill := tr.y
loop if rows_to_fill <= 1 break else {
memory.set(Color, &color, top_start_idx, tr.x)
memory.set(Color, &color, bottom_start_idx, tr.x)
@inline(memory.set, Color, &color, top_start_idx, tr.x)
@inline(memory.set, Color, &color, bottom_start_idx, tr.x)
top_start_idx += surface.width
bottom_start_idx -= surface.width
@ -74,16 +104,16 @@ put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color:
}
if rows_to_fill == 1 {
memory.set(Color, &color, top_start_idx, tr.x)
@inline(memory.set, Color, &color, top_start_idx, tr.x)
}
return
}
put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
start_idx := indexptr(surface, pos.x, pos.y)
end_idx := indexptr(surface, pos.x, pos.y + tr.y)
right_start_idx := indexptr(surface, pos.x + tr.x, pos.y)
start_idx := @inline(indexptr, surface, pos.x, pos.y)
end_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y)
right_start_idx := @inline(indexptr, surface, pos.x + tr.x, pos.y)
loop if start_idx > end_idx break else {
*start_idx = color;
@ -92,8 +122,8 @@ put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color):
right_start_idx += surface.width
}
memory.set(Color, &color, indexptr(surface, pos.x, pos.y), @bitcast(tr.x + 1))
memory.set(Color, &color, indexptr(surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y), @bitcast(tr.x + 1))
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
return
}
@ -110,7 +140,7 @@ put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Colo
y := p0.y
x := p0.x
loop if x == p1.x break else {
*indexptr(surface, x, y) = color
*@inline(indexptr, surface, x, y) = color
if D > 0 {
y += yi
D += 2 * (dy - dx)
@ -134,7 +164,7 @@ put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Col
x := p0.x
y := p0.y
loop if y == p1.y break else {
*indexptr(surface, x, y) = color
*@inline(indexptr, surface, x, y) = color
if D > 0 {
x += xi
D += 2 * (dx - dy)
@ -147,7 +177,7 @@ put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Col
}
put_line := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
if math.abs(uint, p1.y - p0.y) < math.abs(uint, p1.x - p0.x) {
if math.abs(uint, @intcast(@as(int, @intcast(p1.y)) - @as(int, @intcast(p0.y)))) < math.abs(uint, @intcast(@as(int, @intcast(p1.x)) - @as(int, @intcast(p0.x)))) {
if p0.x > p1.x {
@inline(put_line_low, surface, p1, p0, color)
} else {
@ -167,8 +197,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
src_top_cursor := top.buf
src_bottom_cursor := top.buf + top.width * (top.height - 1)
dst_top_idx := indexptr(surface, pos.x, pos.y)
dst_bottom_idx := indexptr(surface, pos.x, pos.y + top.height - 1)
dst_top_idx := @inline(indexptr, surface, pos.x, pos.y)
dst_bottom_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1)
dst_increment := surface.width
@ -182,8 +212,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
rows_to_copy := top.height
loop if rows_to_copy <= 1 break else {
memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
memory.copy(Color, src_bottom_cursor, dst_bottom_idx, top.width)
@inline(memory.copy, Color, src_top_cursor, dst_top_idx, top.width)
@inline(memory.copy, Color, src_bottom_cursor, dst_bottom_idx, top.width)
dst_top_idx += dst_increment
dst_bottom_idx -= dst_increment
@ -193,7 +223,78 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
}
if rows_to_copy == 1 {
memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
}
return
}
put_scaled := fn(surface: Surface, source: Surface, pos: Vec2(int), size: Vec2(int)): void {
step := Vec2(int).(1, 1)
if size.x < 0 {
pos.x += source.width - 1
size.x = -size.x
step.x = -1
}
if size.y < 0 {
pos.y += source.height - 1
size.y = -size.y
step.y = -1
}
surface_idx := @inline(index, surface, pos.x, pos.y)
source_pos := Vec2(int).(0, 0)
subpixel_pos := Vec2(int).(0, 0)
step_size := size / .(source.width, source.height)
if size.x < source.width {
step_size.x = source.width / size.x
}
if size.y < source.height {
step_size.y = source.height / size.y
}
one_up_step := size / (size - step_size * .(source.width, source.height))
pos = .(0, 0)
loop if pos.y >= size.y break else {
loop if pos.x >= size.x break else {
*surface_idx = *@inline(index, source, source_pos.x, source_pos.y)
surface_idx += step.x
if size.x < source.width {
if source_pos.x % one_up_step.x == 0 {
source_pos.x += 1
}
source_pos.x += step_size.x
} else {
subpixel_pos.x += 1
if subpixel_pos.x > step_size.x | source_pos.x % one_up_step.x == 0 & subpixel_pos.x >= step_size.x {
source_pos.x += 1
subpixel_pos.x = 0
}
}
pos.x += 1
}
if size.y < source.height {
if source_pos.y % one_up_step.y == 0 {
source_pos.y += 1
}
source_pos.y += step_size.y
} else {
subpixel_pos.y += 1
if subpixel_pos.y > step_size.y | source_pos.y % one_up_step.y == 0 & subpixel_pos.y >= step_size.y {
source_pos.y += 1
subpixel_pos.y = 0
}
}
surface_idx += surface.width * step.y - size.x * step.x
source_pos.x = 0
pos.x = 0
pos.y += 1
}
return
@ -231,7 +332,7 @@ put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): vo
y := y0
loop if y == y1 break else {
*indexptr(surface, x, y) = color
*@inline(indexptr, surface, x, y) = color
y += 1
}
@ -245,8 +346,7 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
x0 = x1
x1 = tmp
}
// x0 = math.min(x0, x1)
memory.set(Color, &color, indexptr(surface, x0, y), @bitcast(x1 - x0 - 1))
@inline(memory.set, Color, &color, @inline(indexptr, surface, x0, y), @bitcast(x1 - x0 - 1))
return
}
@ -254,29 +354,29 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
x := 0
y := radius
error := @as(int, 3) - @intcast(2 * radius);
*indexptr(surface, pos.x + radius, pos.y) = color;
*indexptr(surface, pos.x - radius, pos.y) = color;
*indexptr(surface, pos.x, pos.y + radius) = color;
*indexptr(surface, pos.x, pos.y - radius) = color
error := @as(int, 3) - @as(int, @intcast(2 * radius));
*@inline(indexptr, surface, pos.x + radius, pos.y) = color;
*@inline(indexptr, surface, pos.x - radius, pos.y) = color;
*@inline(indexptr, surface, pos.x, pos.y + radius) = color;
*@inline(indexptr, surface, pos.x, pos.y - radius) = color
loop if y < x break else {
x += 1
if error > 0 {
y -= 1
error += 4 * (@intcast(x) - @intcast(y)) + 10
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
} else {
error += 4 * @intcast(x) + 6
};
*indexptr(surface, pos.x + x, pos.y + y) = color;
*indexptr(surface, pos.x + y, pos.y + x) = color;
*indexptr(surface, pos.x - x, pos.y + y) = color;
*indexptr(surface, pos.x - y, pos.y + x) = color;
*indexptr(surface, pos.x + x, pos.y - y) = color;
*indexptr(surface, pos.x + y, pos.y - x) = color;
*indexptr(surface, pos.x - x, pos.y - y) = color;
*indexptr(surface, pos.x - y, pos.y - x) = color
*@inline(indexptr, surface, pos.x + x, pos.y + y) = color;
*@inline(indexptr, surface, pos.x + y, pos.y + x) = color;
*@inline(indexptr, surface, pos.x - x, pos.y + y) = color;
*@inline(indexptr, surface, pos.x - y, pos.y + x) = color;
*@inline(indexptr, surface, pos.x + x, pos.y - y) = color;
*@inline(indexptr, surface, pos.x + y, pos.y - x) = color;
*@inline(indexptr, surface, pos.x - x, pos.y - y) = color;
*@inline(indexptr, surface, pos.x - y, pos.y - x) = color
}
return
@ -285,24 +385,24 @@ put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color):
put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
x := 0
y := radius
error := @as(int, 3) - @intcast(2 * radius)
put_hline(surface, pos.y - x, pos.x - radius, pos.x + radius, color);
*indexptr(surface, pos.x, pos.y + radius) = color;
*indexptr(surface, pos.x, pos.y - radius) = color
error := @as(int, 3) - @as(int, @intcast(2 * radius))
@inline(put_hline, surface, pos.y - x, pos.x - radius, pos.x + radius, color);
*@inline(indexptr, surface, pos.x, pos.y + radius) = color;
*@inline(indexptr, surface, pos.x, pos.y - radius) = color
loop if y < x break else {
x += 1
if error > 0 {
put_hline(surface, pos.y + y, pos.x - x, pos.x + x, color)
put_hline(surface, pos.y - y, pos.x - x, pos.x + x, color)
@inline(put_hline, surface, pos.y + y, pos.x - x, pos.x + x, color)
@inline(put_hline, surface, pos.y - y, pos.x - x, pos.x + x, color)
y -= 1
error += 4 * (@intcast(x) - @intcast(y)) + 10
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
} else {
error += 4 * @intcast(x) + 6
}
put_hline(surface, pos.y + x, pos.x - y, pos.x + y, color)
put_hline(surface, pos.y - x, pos.x - y, pos.x + y, color)
@inline(put_hline, surface, pos.y + x, pos.x - y, pos.x + y, color)
@inline(put_hline, surface, pos.y - x, pos.x - y, pos.x + y, color)
}
return
@ -311,31 +411,29 @@ put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color:
put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void {
x := 0
y := radius
error := @as(int, 3) - @intcast(2 * radius)
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y), indexptr(surface, pos.x - y, pos.y), 2 * y);
*indexptr(surface, pos.x, pos.y + y) = *indexptr(source, source_pos.x, source_pos.y + y);
*indexptr(surface, pos.x, pos.y - y) = *indexptr(source, source_pos.x, source_pos.y - y)
error := @as(int, 3) - @as(int, @intcast(2 * radius))
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y), @inline(indexptr, surface, pos.x - y, pos.y), 2 * y);
*@inline(indexptr, surface, pos.x, pos.y + y) = *@inline(indexptr, source, source_pos.x, source_pos.y + y);
*@inline(indexptr, surface, pos.x, pos.y - y) = *@inline(indexptr, source, source_pos.x, source_pos.y - y)
loop if y < x break else {
x += 1
if error > 0 {
memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y + y), indexptr(surface, pos.x - x, pos.y + y), 2 * x)
memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y - y), indexptr(surface, pos.x - x, pos.y - y), 2 * x)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y + y), @inline(indexptr, surface, pos.x - x, pos.y + y), 2 * x)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y - y), @inline(indexptr, surface, pos.x - x, pos.y - y), 2 * x)
y -= 1
error += 4 * (@intcast(x) - @intcast(y)) + 10
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
} else {
error += 4 * @intcast(x) + 6
}
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y + x), indexptr(surface, pos.x - y, pos.y + x), 2 * y)
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y - x), indexptr(surface, pos.x - y, pos.y - x), 2 * y)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y + x), @inline(indexptr, surface, pos.x - y, pos.y + x), 2 * y)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y - x), @inline(indexptr, surface, pos.x - y, pos.y - x), 2 * y)
}
return
}
utf8_len_table := [u8].(0, 0, 2, 3)
put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
cursor := Vec2(uint).(pos.x, pos.y)
@ -363,7 +461,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
str += 1
continue
}
glyph_data = get_glyph(font, *str)
glyph_data = @inline(get_glyph, font, *str)
} else {
if *str < UNC_TABLE_SIZE {
glyph_index := *(font.unicode + *str)
@ -435,7 +533,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
cursor.y += next_line_y
}
dest := indexptr(surface, cursor.x, cursor.y)
dest := @inline(indexptr, surface, cursor.x, cursor.y)
rows := font.height
loop if rows == 0 break else {

View file

@ -74,16 +74,16 @@ font_from_psf2 := fn(psf: ^u8, unicode: bool): ?Font {
return font
}
$get_glyph := fn(font: Font, index: u8): ^u8 {
get_glyph := fn(font: Font, index: u8): ^u8 {
return font.data + @as(uint, index) * font.bytes_per_glyph
}
$UNC_TABLE_SIZE := 1 << 16
UNC_TABLE_SIZE := 1 << 16
init_unicode := fn(font: ^Font): void {
font.unicode = memory.alloc(u16, UNC_TABLE_SIZE)
memory.set(u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE)
@inline(memory.set, u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE)
table := font.data + font.num_glyphs * font.bytes_per_glyph
curr_glyph := @as(u16, 0)
@ -121,6 +121,8 @@ init_unicode := fn(font: ^Font): void {
next_byte := *table
if (next_byte & 0xC0) != 0x80 {
valid = false
}
if valid == false {
break
}
unicode = unicode << 6 | next_byte & 0x3F

View file

@ -0,0 +1 @@
Simple sound driver.

View file

@ -0,0 +1,23 @@
.{memory, log, string} := @use("../../stn/src/lib.hb")
start := fn(): void {
memory.outb(0x61, memory.inb(0x61) | 3)
return
}
stop := fn(): void {
memory.outb(0x61, memory.inb(0x61) & 0xFC)
return
}
set_frequency := fn(frequency: u16): void {
dfreq := 0xFFFE & 1193180 / frequency
memory.outb(0x43, 0xB6)
fmtpage := memory.request_page(1)
log.info(string.display_int(@as(u8, @intcast(dfreq) & 0xFF), fmtpage))
log.info(string.display_int(@as(u8, @intcast(dfreq >> 8) & 0xFF), fmtpage))
memory.outb(0x42, @as(u8, @intcast(dfreq) & 0xFF))
memory.outb(0x42, @as(u8, @intcast(dfreq >> 8) & 0xFF))
//memory.outb(0x20, 0x20)
return
}

View file

@ -1,35 +1,27 @@
string := @use("string.hb")
$recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
recv := fn($Expr: type, buffer_id: int, memory_map_location: ^u8): void {
return @eca(4, buffer_id, memory_map_location, @sizeof(Expr))
}
$write := fn($Expr: type, buffer_id: uint, msg: ^Expr): void {
write := fn($Expr: type, msg: ^Expr, buffer_id: int): void {
return @eca(3, buffer_id, msg, @sizeof(Expr))
}
$recv_length := fn(length: uint, memory_map_location: ^u8, buffer_id: uint): void {
recv_length := fn(buffer_id: int, memory_map_location: ^u8, length: int): void {
return @eca(4, buffer_id, memory_map_location, length)
}
$write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
write_length := fn(msg: ^u8, buffer_id: int, length: int): void {
return @eca(3, buffer_id, msg, length)
}
BufferMsg := packed struct {operation: u8, msg: ^u8, msg_len: uint}
create := fn(msg: ^u8): uint {
create := fn(msg: ^u8): int {
return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
}
$create_nameless := fn(): uint {
return @eca(1, 0)
}
$delete_buffer := fn(buffer_id: uint): void {
return @eca(2, buffer_id)
}
search := fn(msg: ^u8): uint {
search := fn(msg: ^u8): int {
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
}

View file

@ -1,5 +1,5 @@
.{string} := @use("../../stn/src/lib.hb")
get := fn($Expr: type, query: ^u8): Expr {
get := fn($Expr: type, query: ^u8): ?Expr {
return @eca(3, 5, query, @inline(string.length, query))
}

View file

@ -7,7 +7,6 @@ math := @use("math.hb")
random := @use("random.hb")
file := @use("file_io.hb")
dt := @use("dt.hb")
process := @use("process.hb")
panic := fn(message: ?^u8): never {
log.error("Error: Panic Called, Message:\0")

View file

@ -1,24 +1,29 @@
$abs := fn($Expr: type, x: Expr): Expr {
return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
abs := fn($Expr: type, x: Expr): Expr {
mask := x >> @bitcast(@sizeof(Expr) - 1)
return (x ^ mask) - mask
}
$min := fn($Expr: type, a: Expr, b: Expr): Expr {
return b + (a - b & a - b >> @sizeof(Expr) - 1)
min := fn($Expr: type, a: Expr, b: Expr): Expr {
c := a - b
return b + (c & c >> @bitcast(@sizeof(Expr) - 1))
}
$max := fn($Expr: type, a: Expr, b: Expr): Expr {
return a - (a - b & a - b >> @sizeof(Expr) - 1)
max := fn($Expr: type, a: Expr, b: Expr): Expr {
c := a - b
return a - (c & c >> @bitcast(@sizeof(Expr) - 1))
}
$sign := fn($Expr: type, x: Expr): i8 {
return @bitcast(x > 0) - @bitcast(x < 0)
}
$log := fn($Expr: type, base: uint, x: Expr): uint {
// if x <= 0 {}
// if base <= 1 {}
result := 0
loop if x < base break else {
x /= base
result += 1
signum := fn($Expr: type, x: Expr): int {
if x > @as(Expr, @intcast(0)) {
return 1
} else if x < @as(Expr, @intcast(0)) {
return -1
} else {
return 0
}
return result
}
signincl := fn($Expr: type, x: Expr): int {
if x > @as(Expr, @intcast(0)) {
return 1
}
return -1
}
Vec2 := fn($Expr: type): type {
@ -35,7 +40,7 @@ $TABLE_SIZE := @as(i32, 256)
sin := fn(theta: f32): f32 {
si := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
d := theta - @floatcast(@itf(si)) * 2.0 * PI / @floatcast(@itf(TABLE_SIZE))
d := theta - @floatcast(@itf(si)) * 2.0 * PI / @itf(TABLE_SIZE)
ci := si + TABLE_SIZE / 4 & TABLE_SIZE - 1
si &= TABLE_SIZE - 1
return SIN_TABLE[@bitcast(si)] + (SIN_TABLE[@bitcast(ci)] - 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
@ -43,10 +48,10 @@ sin := fn(theta: f32): f32 {
cos := fn(theta: f32): f32 {
ci := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
d := theta - @floatcast(@itf(ci)) * 2.0 * PI / @floatcast(@itf(TABLE_SIZE))
d := theta - @floatcast(@itf(ci)) * 2.0 * PI / @itf(TABLE_SIZE)
si := ci + TABLE_SIZE / 4 & TABLE_SIZE - 1
ci &= TABLE_SIZE - 1
return SIN_TABLE[@bitcast(si)] - (SIN_TABLE[@bitcast(ci)] + 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
return SIN_TABLE[@bitcast(si)] + (SIN_TABLE[@bitcast(ci)] - 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
}
tan := fn(theta: f32): f32 {

View file

@ -1,29 +1,24 @@
$PAGE_SIZE := 4096
$MAX_ALLOC := 0xFF
$MAX_FREE := 0xFF
PAGE_SIZE := 4096
MAX_ALLOC := 0xFF
MAX_FREE := 0xFF
$uninit := fn($Expr: type): ?Expr {
return null
}
$dangling := fn($Expr: type): ^Expr {
dangling := fn($Expr: type): ^Expr {
return @bitcast(@alignof(Expr))
}
$calc_pages := fn($Expr: type, num: uint): uint {
calc_pages := fn($Expr: type, num: uint): uint {
return 1 + @sizeof(Expr) * num / PAGE_SIZE
}
// ! will be replaced, don't get attached
alloc := fn($Expr: type, num: uint): ^Expr {
pages := calc_pages(Expr, num)
pages := @inline(calc_pages, Expr, num)
if pages <= MAX_ALLOC {
return @bitcast(request_page(@intcast(pages)))
}
ptr := request_page(MAX_ALLOC)
ptr := request_page(0xFF)
remaining := pages - MAX_ALLOC
loop if remaining < MAX_ALLOC break else {
_ = request_page(MAX_ALLOC)
_ = request_page(@intcast(MAX_ALLOC))
remaining -= MAX_ALLOC
}
_ = request_page(@intcast(remaining))
@ -31,46 +26,46 @@ alloc := fn($Expr: type, num: uint): ^Expr {
}
// ! stub
$free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
return
}
RqPageMsg := packed struct {a: u8, count: u8}
$request_page := fn(count: u8): ^u8 {
request_page := fn(count: u8): ^u8 {
return @eca(3, 2, &RqPageMsg.(0, count), @sizeof(RqPageMsg))
}
RlPageMsg := packed struct {a: u8, count: u8, ptr: ^u8}
$release_page := fn(ptr: ^u8, count: u8): void {
release_page := fn(ptr: ^u8, count: u8): void {
return @eca(3, 2, &RlPageMsg.(1, count, ptr), @sizeof(RlPageMsg))
}
OutbMsg := packed struct {a: u8, b: u8, addr: u16, value: u8}
$outb := fn(addr: u16, value: u8): void {
outb := fn(addr: u16, value: u8): void {
return @eca(3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg))
}
InbMsg := packed struct {a: u8, b: u8, addr: u16}
$inb := fn(addr: u16): u8 {
inb := fn(addr: u16): u8 {
return @eca(3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg))
}
OutlMsg := packed struct {a: u8, b: u8, addr: u16, value: u32}
$outl := fn(addr: u16, value: u32): void {
outl := fn(addr: u16, value: u32): void {
return @eca(3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg))
}
InlMsg := packed struct {a: u8, b: u8, addr: u16}
$inl := fn(addr: u16): u32 {
inl := fn(addr: u16): u32 {
return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg))
}
CopyMsg := packed struct {a: u8, count: u32, src: ^u8, dest: ^u8}
$copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
return @eca(3, 2, &CopyMsg.(4, @intcast(count * @sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))
}
SetMsg := packed struct {a: u8, count: u32, size: u32, src: ^u8, dest: ^u8}
$set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
return @eca(3, 2, &SetMsg.(5, @intcast(count), @intcast(@sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
}

View file

@ -1,12 +0,0 @@
// ! will be rewritten to take a file object when filesystem is exist
// returns PID
$spawn := fn(proc_exe: ^u8, length: uint): uint {
return @eca(3, 6, proc_exe, length)
}
/* TODO:
- Spawn an empty process
- Call a function to load bytes into that process from a function
Or
- Manually fill the bytes in
- Execute the process via a run type command */

View file

@ -1,15 +1,7 @@
$any := fn($Expr: type): Expr {
any := fn($Expr: type): Expr {
return *@eca(3, 4, &@as(Expr, idk), @sizeof(Expr))
}
$range := fn($Expr: type, min: Expr, max: Expr): Expr {
return *@eca(3, 4, &@as(Expr, idk), @sizeof(Expr)) % (max - min) + *@bitcast(&1) + min
}
$fill := fn($Expr: type, ptr: ^Expr): void {
return @eca(3, 4, ptr, @sizeof(Expr))
}
$fill_buffer := fn(buf: ^u8, len: uint): void {
return @eca(3, 4, buf, len)
range := fn($Expr: type, min: Expr, max: Expr): Expr {
return @inline(any, Expr) % (max - min) + @intcast(1) + min
}

View file

@ -1,6 +0,0 @@
subscribe_to_interrupt := fn(interrupt_number: u8): bool {
return false
}
// Pauses execution until the interrupt occures
sleep_until_interrupt := fn(interrupt_number: u8): void {
}

View file

@ -4,213 +4,118 @@ length := fn(ptr: ^u8): uint {
}
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
is_negative := num < 0
if is_negative num = -num
ptr := p
negative := num < 0
if negative {
num = -num
}
if radix == 2 {
*ptr = 48
ptr += 1;
*ptr = 98
ptr += 1
} else if radix == 16 {
*ptr = 48
ptr += 1;
*ptr = 120
ptr += 1
} else if radix == 8 {
*ptr = 48
ptr += 1;
*ptr = 111
ptr += 1
}
digits_start := ptr
if num == 0 {
*ptr = 0x30;
*(ptr + 1) = 0
return p
}
loop if num == 0 break else {
remainder := num % @bitcast(radix)
num /= @bitcast(radix);
*ptr = @intcast(remainder + 0x30)
if remainder > 9 {
*ptr = @intcast(remainder - 10 + 0x41)
*ptr = 48
ptr += 1
} else {
loop if num == 0 break else {
digit := num % @bitcast(radix)
if digit < 10 {
*ptr = @intcast(digit) + 48
} else {
*ptr = @intcast(digit) + 55
}
ptr += 1
num /= @bitcast(radix)
}
ptr += 1
}
if is_negative {
*ptr = 0x2D
if negative {
*ptr = 45
ptr += 1
}
// ! it gets broked when you do this ??
// *ptr = 0
};
*ptr = 0
@inline(reverse, digits_start)
@inline(reverse, p)
return p
}
reverse := fn(s: ^u8): void {
j := s + @inline(length, s) - 1
i := 0
j := @inline(length, s) - 1
temp := @as(u8, 0)
loop if s < j {
temp = *s;
*s = *j;
*j = temp
s += 1
loop if i >= j break else {
temp = *(s + i);
*(s + i) = *(s + j);
*(s + j) = temp
i += 1
j -= 1
} else return
}
return
}
equals := fn(lhs: ^u8, rhs: ^u8): bool {
if lhs == rhs {
return true
}
loop if *lhs != *rhs {
i := 0
loop if *(lhs + i) != *(rhs + i) {
return false
} else if *lhs == 0 {
return true
} else {
lhs += 1
rhs += 1
i += 1
}
}
clear := fn(ptr: ^u8): void {
loop if *ptr == 0 break else {
*ptr = 0
ptr += 1
contains := fn(haystack: ^u8, needle: ^u8): bool {
haystack_len := @inline(length, haystack)
needle_len := @inline(length, needle)
if needle_len == 0 {
return true
}
if haystack_len < needle_len {
return false
}
}
split_once := fn(haystack: ^u8, needle: u8): ?^u8 {
loop if *haystack == needle return haystack else if *haystack == 0 return null else haystack += 1
}
max_start := haystack_len - needle_len
split_once_str := fn(haystack: ^u8, needle: ^u8): ?^u8 {
if *needle == 0 return null
pos := 0
loop if pos > max_start break else {
is_match := true
offset := 0
loop if *haystack == 0 return null else {
if *haystack == *needle {
h := haystack
n := needle
loop {
n += 1
h += 1
if *n == 0 {
return haystack
} else if *h == 0 | *h != *n {
break
}
loop if offset >= needle_len break else {
if *(haystack + pos + offset) != *(needle + offset) {
is_match = false
}
}
haystack += 1
}
}
Split := struct {
str: ^u8,
needle: u8,
done: bool,
}
split := fn(iter: ^u8, needle: u8): Split {
return .(
iter,
needle,
false,
)
}
iter_split := fn(iter: ^Split): ?^u8 {
if iter.done | *iter.str == 0 {
return null
}
next := split_once(iter.str + 1, iter.needle)
if next == null {
iter.done = true
return iter.str
}
s := iter.str
iter.str = next + 1
return s
}
SplitStr := struct {
str: ^u8,
needle: ^u8,
done: bool,
}
split_str := fn(iter: ^u8, needle: ^u8): SplitStr {
return .(
iter,
needle,
false,
)
}
iter_split_str := fn(iter: ^SplitStr): ?^u8 {
if iter.done | *iter.str == 0 {
return null
}
next := split_once_str(iter.str, iter.needle)
if next == null {
iter.done = true
return iter.str
}
s := iter.str
iter.str = next + length(iter.needle)
return s
}
find_once := fn(haystack: ^u8, needle: u8): ?uint {
return @bitcast(@inline(split_once, haystack, needle) - haystack)
}
find_once_str := fn(haystack: ^u8, needle: ^u8): ?uint {
return @bitcast(@inline(split_once_str, haystack, needle) - haystack)
}
count := fn(haystack: ^u8, needle: ^u8): uint {
c := 0
loop if *haystack == needle {
c += 1
haystack += 1
} else if *haystack == 0 return c else haystack += 1
}
count_str := fn(haystack: ^u8, needle: ^u8): uint {
if *needle == 0 return 0
c := 0
loop if *haystack == 0 return c else {
if *haystack == *needle {
h := haystack
n := needle
loop {
n += 1
h += 1
if *n == 0 {
c += 1
break
} else if *h == 0 | *h != *n {
break
}
if is_match == false {
break
}
offset += 1
}
haystack += 1
}
}
left_trim := fn(str: ^u8, sub: ^u8): ^u8 {
original := str
if *str == *sub {
loop if *sub == 0 {
return str
} else if *str != *sub {
return original
} else if *str == 0 {
return original
} else {
str += 1
sub += 1
if is_match {
return true
}
pos += 1
}
return str
return false
}

View file

@ -1,63 +0,0 @@
.{math: .{Vec2}, buffer, log, memory, string} := @use("../../stn/src/lib.hb");
.{Channel, Window, send_header, send_message, await_channel, await_header, await_message, message, BUFFER_SERVER, BUFFER_CLIENT, WindowProps, WindowData} := @use("./lib.hb");
.{new_surface, Color} := @use("../../render/src/lib.hb")
// ! in the future this should be safely handled
channel := Channel.(0, 0)
find_server := fn(): void {
log.info("client: locating server\0")
channel2 := await_channel()
channel.server = channel2.server
channel.client = channel2.client
log.info("client: server located\0")
}
new := fn(props: WindowProps): ?Window {
send_header(message.syn, channel.server)
response := await_message(Channel, channel.client)
if response.header.kind != message.ack {
return null
}
log.info("client: recv ack\0")
send_message(WindowProps, message.props, props, response.body.server)
windowdata := await_message(WindowData, response.body.client)
if windowdata.header.kind != message.ack {
return null
}
log.info("client: recv windowdata\0")
surface := new_surface(windowdata.body.props.dimensions.x, windowdata.body.props.dimensions.y)
return .(windowdata.body, surface)
}
quit := fn(client: Window): void {
send_header(message.quit, client.data.channel.server)
}
connected := fn(client: Window): bool {
return true
}
shutdown_server := fn(client: Window): bool {
return false
}
update_props := fn(client: Window): bool {
return false
}
update_permissions := fn(client: Window): bool {
return false
}
send_frame := fn(client: Window): bool {
send_header(message.frame_ready, client.data.channel.server)
response := await_message(uint, client.data.channel.client)
if response.header.kind != message.ack {
return false
}
// ! FOR NOW, server will ALWAYS be local,
// ! so we can send pointer to surface.
send_message(^Color, message.ack, client.surface.buf, client.data.channel.server)
return true
}

View file

@ -1,97 +0,0 @@
.{math: .{Vec2}, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface} := @use("../../render/src/lib.hb")
$BUFFER_SERVER := "sunset_server\0"
$BUFFER_CLIENT := "sunset_client\0"
Channel := packed struct {
client: uint,
server: uint,
}
client := @use("./client.hb")
server := @use("./server.hb")
message := @use("./message.hb")
permissions := @use("./permissions.hb")
$send_message := fn($Expr: type, kind: MessageKind, msg: Expr, buffer_id: uint): void {
buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg)))
}
$send_header := fn(kind: MessageKind, buffer_id: uint): void {
buffer.write(?MessageHeader, buffer_id, &@as(?MessageHeader, .(kind)))
}
$recv_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
response := @as(?Message(Expr), null)
buffer.recv(?Message(Expr), buffer_id, &response)
return response
}
$recv_header := fn(buffer_id: uint): ?MessageHeader {
response := @as(?MessageHeader, null)
buffer.recv(?MessageHeader, buffer_id, &response)
return response
}
await_channel := fn(): Channel {
channel := Channel.(0, 0)
loop if channel.server != 0 break else {
channel.server = buffer.search(BUFFER_SERVER)
}
loop if channel.client != 0 break else {
channel.client = buffer.search(BUFFER_CLIENT)
}
return channel
}
await_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
response := @as(?Message(Expr), null)
loop {
buffer.recv(?Message(Expr), buffer_id, &response)
if response != null {
return @as(Message(Expr), response)
}
}
}
await_header := fn(buffer_id: uint): MessageHeader {
response := @as(?MessageHeader, null)
loop {
buffer.recv(?MessageHeader, buffer_id, &response)
if response != null {
return @as(?MessageHeader, response)
}
}
}
MessageKind := u8
MessageHeader := packed struct {
kind: MessageKind,
}
Message := fn($Expr: type): type {
return packed struct {
header: MessageHeader,
body: Expr,
}
}
WindowProps := struct {
position: Vec2(uint),
dimensions: Vec2(uint),
// ! replace with owned string type later
title: ^u8,
}
WindowData := struct {
props: WindowProps,
channel: Channel,
permissions: uint,
}
Window := struct {
data: WindowData,
surface: Surface,
}

View file

@ -1,8 +0,0 @@
// ! all values in this file are subject to change.
$syn := 1
$ack := 2
$refused := 3
$quit := 4
$props := 5
$shutdown := 6
$frame_ready := 7

View file

@ -1,5 +0,0 @@
$none := 0b0
$exclusive_framebuffer := 0b1
$shutdown := 0b100
$default := none

View file

@ -1,135 +0,0 @@
.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
.{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text, clear, white, black} := @use("../../render/src/lib.hb");
.{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("./lib.hb")
WindowServer := struct {
window_count: uint,
channel: Channel,
// ! replace this with a collection when we get an allocator
windows: [?Window; 10],
font: text.Font,
}
// ! in the future this should be safely handled
server := @as(WindowServer, idk)
psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf")
start := fn(): void {
font := text.font_from_psf2(@bitcast(&psf), false)
if font == null {
log.error("server: failed to load asset\0")
return
}
server = .(
0,
.{client: buffer.create(BUFFER_CLIENT), server: buffer.create(BUFFER_SERVER)},
.(null, null, null, null, null, null, null, null, null, null),
@as(text.Font, font),
)
log.info("server: started server\0")
}
incoming := fn(): bool {
msg := recv_header(server.channel.server)
if msg == null {
return true
}
if msg.kind == message.syn {
log.info("server: recv syn\0")
channel := Channel.(buffer.create_nameless(), buffer.create_nameless())
send_message(Channel, message.ack, channel, server.channel.client)
props := await_message(WindowProps, channel.server)
if props.header.kind != message.props {
return true
}
log.info("server: recv props\0")
// ! do inspection of requested props here
data := WindowData.(props.body, channel, permissions.default)
send_message(WindowData, message.ack, data, channel.client)
surface := new_window_decorations(data.props.dimensions)
// decorations
{
title := data.props.title
title_length := string.length(title)
deco_length := title_length * 10
// draw the window tab bar
put_filled_rect(surface, .(0, 0), .(data.props.dimensions.x + DECO_WIDTH + deco_length, DECO_HEIGHT_TOP), DECO_COLOUR)
// Draw the window tab
put_filled_rect(surface, .(0, 0), .(deco_length, DECO_HEIGHT_TOP - 1), DECO_COLOUR_DARKER)
// Draw the outside box
put_rect(surface, .(0, 0), data.props.dimensions + .(DECO_WIDTH - 1, DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM - 1), DECO_COLOUR)
put_text(surface, server.font, .(2, 1), .(0, 0, 0, 255), data.props.title)
}
server.windows[server.window_count] = .(data, surface)
server.window_count += 1
}
return true
}
$DECO_WIDTH := 2
$DECO_HEIGHT_TOP := 20
$DECO_HEIGHT_BOTTOM := 1
$DECO_COLOUR := Color.(100, 200, 255, 255)
$DECO_COLOUR_DARKER := Color.(89, 57, 89, 255)
new_window_decorations := fn(dimensions: math.Vec2(uint)): Surface {
return new_surface(
dimensions.x + DECO_WIDTH,
dimensions.y + DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM,
)
}
// ! compositor code. this currently disallows tearing.
collect_frames := fn(): void {
i := 0
loop if i == 10 break else {
window := server.windows[i]
if window == null {
i += 1
continue
}
header := recv_header(window.data.channel.server)
if header == null {
i += 1
continue
}
if header.kind != message.frame_ready {
i += 1
continue
}
send_header(message.ack, window.data.channel.client)
ptr := await_message(^Color, window.data.channel.server)
if ptr.header.kind != message.ack {
return
}
put_surface(
window.surface,
Surface.(
ptr.body,
window.data.props.dimensions.x,
window.data.props.dimensions.y,
window.data.props.dimensions.x * window.data.props.dimensions.y,
),
.(DECO_WIDTH / 2, DECO_HEIGHT_TOP),
false,
)
i += 1
}
}
render_clients := fn(screen: Surface): void {
i := 0
loop if i == 10 break else {
window := server.windows[i]
if window == null {
i += 1
continue
}
put_surface(screen, window.surface, window.data.props.position, false)
i += 1
}
}

View file

@ -28,6 +28,10 @@ main := fn(): int {
win_buff := buffer.create("XHorizon\0")
screen := render.init(true)
if screen == null {
log.error("Screen could not be initialized!\0")
return 1
}
// Clear the screen to black.
render.clear(screen, render.black)
@ -56,13 +60,43 @@ main := fn(): int {
loop {
// Clear the screen
render.clear(screen, render.black)
render.put_surface(screen, wallpaper, .(0, 0), false)
// TODO: Read the window buffer here
{
// ret := buffer.recv([u8; 4096], win_buff, mem_buf)
// for some reason this null check causes the compiler to spin forever
// if ret == null {
// log.info("No messages\0")
// } else {
// log.info("Handle Messages\0")
// }
}
// get input events from drivers via intouch
// key_event := intouch.recieve_key_event();
// log.info("before mouse event check\0");
{
// Note: MLokis, this inline halts the compiler forever
// mouse_event := @inline(intouch.recieve_mouse_event)
// Note: MLokis, this function returns null unless the mouse is moving
mouse_event := intouch.recieve_mouse_event()
//
if mouse_event != null {
log.warn("Mouse event recieved\0")
mouse_x += mouse_event.x_change
mouse_y += mouse_event.y_change
set_label_text(text_label, "Mouse Moved\0")
}
// render mouse
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
// Send events to focused window
}
// TODO: Get windows out of a collection and iter through
if false {
// Scroll bar :ThumbsUp:
render.put_rect(screen, .(100, 100), .(100, 10), render.white)
@ -72,35 +106,18 @@ main := fn(): int {
render.put_filled_rect(screen, .(90, 120), .(10, 20), render.white)
}
{
// osu dots
render.put_rect(screen, .(400, 100), .(100, 100), render.red)
render.put_rect(screen, .(100, 100 + 300), .(100, 100), render.red)
}
{
pos := Vec2(uint).(1, screen.height - 21)
render_label_to_surface(screen, text_label, font, pos)
render.put_rect(screen, .(0, screen.height - 21), .(screen.width - 1, 20), render.white)
}
// Screen border
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white)
// get input events from drivers via intouch
if false {
key_event := intouch.recieve_key_event()
if key_event != null {
log.info("Key event \0")
}
}
{
mouse_event := intouch.recieve_mouse_event()
//
if mouse_event != null {
// log.warn("Mouse event received\0")
// log.warn("Mouse event recieved\0")
change_x := @as(i16, mouse_event.x_change)
change_x = change_x << 8
@ -137,9 +154,15 @@ main := fn(): int {
}
}
render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white)
// render mouse
lum := render.indexptr(screen, mouse_x, mouse_y)
if lum.r / 3 + lum.g / 3 + lum.b / 3 < 128 {
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
} else {
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
}
// Send events to focused window
}

View file

@ -1,11 +0,0 @@
[package]
name = "processes"
authors = ["koniifer"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,7 +0,0 @@
.{log} := @use("../../../libraries/stn/src/lib.hb")
main := fn(): void {
log.info("Hello, World!\0")
loop {
}
}

View file

@ -1,19 +0,0 @@
.{process, log, string, memory} := @use("../../../libraries/stn/src/lib.hb")
exe := @embed("./hello_world_and_spin.hbf")
main := fn(): void {
buf := "\0\0\0\0\0\0\0"
loop {
log.info(
string.display_int(
@bitcast(process.spawn(@bitcast(&exe), 356)),
buf,
10,
),
)
// spin so we don't spawn 10 quattuordecillion processes
i := 0
loop if i == 1000000 break else i += 1
}
}

View file

@ -1,6 +1,6 @@
# Unified PS/2 Driver
Te entire thing is held together inspite
Te entire thing is heavily documented with comments because I'm not sure how else to make this understandable.
## !!Assumptions!!
Anyone who works on this should work to keep this list as small as possible/remove as many of these as possible.
@ -10,14 +10,3 @@ Anyone who works on this should work to keep this list as small as possible/remo
- Both PS/2 ports being broken doesn't need handling.
- One PS/2 port being broken doesn't need special attention.
- PS/2 controller doesn't need to perform a self-check.
- These DeviceIDs never exist:
- 0xFFFD
- 0xFFFE
- 0xFFFF
- 0x01xx
- 0x03xx
- 0x04xx
- Literally all PS/2 keyboards can be handeled the exact same way. We have the capability for detecting different keyboard types, I just don't bother with it because that would litreally take months to get working.
- The device doesn't send any data while we're waiting for an `ACK`.
Supporting mice in the keyboard port and vice versa was a ***bad*** idea, but I do not regret it because it means we're "superior" to real world operating systems.

View file

@ -1,26 +0,0 @@
//Do not question.
$bit0 := fn(value: u8): bool {
return (value & 0x1) > 0
}
$bit1 := fn(value: u8): bool {
return (value & 0x2) > 0
}
$bit2 := fn(value: u8): bool {
return (value & 0x4) > 0
}
$bit3 := fn(value: u8): bool {
return (value & 0x8) > 0
}
$bit4 := fn(value: u8): bool {
return (value & 0x10) > 0
}
$bit5 := fn(value: u8): bool {
return (value & 0x20) > 0
}
$bit6 := fn(value: u8): bool {
return (value & 0x40) > 0
}
$bit7 := fn(value: u8): bool {
return (value & 0x80) > 0
}

View file

@ -1,95 +0,0 @@
.{memory, log} := @use("../../../libraries/stn/src/lib.hb");
.{bit0, bit1, bit5, bit6, bit7} := @use("bits.hb");
.{Port, PORT_AT_STARTUP} := @use("port.hb")
port1 := @as(Port, PORT_AT_STARTUP)
port2 := @as(Port, PORT_AT_STARTUP)
$disable_port1 := fn(): void memory.outb(0x64, 0xAD)
$enable_port1 := fn(): void memory.outb(0x64, 0xAE)
$disable_port2 := fn(): void memory.outb(0x64, 0xA7)
$enable_port2 := fn(): void memory.outb(0x64, 0xA8)
test_port1 := fn(): bool {
memory.outb(0x64, 0xAB)
loop if has_input(get_info()) break
input := get_input()
return input == 0x0
}
test_port2 := fn(): bool {
memory.outb(0x64, 0xA9)
loop if has_input(get_info()) break
input := get_input()
return input == 0x0
}
get_config_byte := fn(): u8 {
memory.outb(0x64, 0x20)
loop if has_input(get_info()) break
return get_input()
}
Info := struct {d: u8}
$get_info := fn(): Info return .(memory.inb(0x64))
//inline when can
has_input := fn(info: Info): bool return bit0(info.d)
can_send := fn(info: Info): bool return bit1(info.d) == false
timed_out := fn(info: Info): bool return bit6(info.d)
check_parity := fn(info: Info): bool return bit7(info.d)
get_port := fn(info: Info): ^Port {
if bit5(info.d) {
return &port2
} else {
return &port1
}
}
send_byte := fn(port: ^Port, byte: u8): void {
if port == &port2 {
memory.outb(0x64, 0xD4)
}
loop if can_send(get_info()) break
memory.outb(0x60, byte)
}
$get_input := fn(): u8 return memory.inb(0x60)
$write_out := fn(data: u8): void memory.outb(0x60, data)
flush_input := fn(): void {
loop if has_input(get_info()) == false break else get_info()
}
init := fn(): void {
disable_port1()
disable_port2()
//Disables ports to make sure that they won't interfere with the setup process.
flush_input()
enable_port2()
port2.exists = bit5(@inline(get_config_byte)) == false
disable_port2()
flush_input()
port1.exists = test_port1()
if port2.exists {
port2.exists = test_port2()
}
if (port1.exists | port2.exists) == false {
log.error("No ports detected! No input will be processed! Cannot handle this!\0")
}
if port1.exists {
log.info("Port 1 exists.\0")
enable_port1()
}
if port2.exists {
log.info("Port 2 exists.\0")
enable_port2()
}
}

View file

@ -1,15 +0,0 @@
DeviceID := struct {value: u16}
$MOUSE_3_BUTTON := DeviceID.(0x0)
$MOUSE_SCROLLWHEEL := DeviceID.(0x3)
$MOUSE_5_BUTTON := DeviceID.(0x4)
$KEYBOARD_SPACESAVER := DeviceID.(0x84AB)
$KEYBOARD_122_KEY := DeviceID.(0x86AB)
$KEYBOARD_JAPANESE_G := DeviceID.(0x90AB)
$KEYBOARD_JAPANESE_P := DeviceID.(0x91AB)
$KEYBOARD_JAPANESE_A := DeviceID.(0x92AB)
$KEYBOARD_NCD_SUN := DeviceID.(0xA1AC)
$MOUSE_INIT_1 := DeviceID.(0xFFFD)
$MOUSE_INIT_2 := DeviceID.(0xFFFE)
$NO_DEVICE := DeviceID.(0xFFFF)

View file

@ -1,152 +1,108 @@
.{memory, log, buffer, string} := @use("../../../libraries/stn/src/lib.hb");
.{MouseEvent} := @use("../../../libraries/intouch/src/lib.hb").events;
.{bit0, bit1, bit2, bit3, bit4} := @use("bits.hb")
devices := @use("devices.hb")
controller := @use("controller.hb");
.{Info, Port} := controller
mouse := @use("mouse.hb")
format_page := memory.dangling(u8)
.{memory, log} := @use("../../../libraries/stn/src/lib.hb")
mouse_buffer := 0
keyboard_buffer := 0
info := Info.(0)
DeviceID := struct {value: u16}
send_command := fn(port: ^Port, byte: u8): void {
tries := 3
loop if tries == 0 break else {
controller.send_byte(port, byte)
loop {
info = controller.get_info()
if controller.has_input(info) == false {
continue
}
input := controller.get_input()
if controller.get_port(info) != port {
if check_complete(port) == false {
port.packet[port.packet_length] = input
port.packet_length += 1
}
continue
}
if input == 0xFA {
return
} else {
break
}
}
tries -= 1
Mouse3Button := DeviceID.(0x0)
MouseScrollwheel := DeviceID.(0x3)
Mouse5Button := DeviceID.(0x4)
Spacesaver := DeviceID.(0xAB84)
Keyboard122Key := DeviceID.(0xAB86)
KeyboardJapaneseG := DeviceID.(0xAB90)
KeyboardJapanesep := DeviceID.(0xAB91)
KeyboardJapaneseA := DeviceID.(0xAB92)
KeyboardNCDSun := DeviceID.(0xACA1)
NoDevice := DeviceID.(0xFFFF)
Port := struct {exists: bool, device: DeviceID, command_queued: bool, command_queue: u8}
check_bit := fn(value: u8, bit: u8, state: u8): bool {
return value >> bit & 1 == state
}
ports := [Port].(.(true, NoDevice, false, 0xFF), .(true, NoDevice, false, 0xFF))
initialize_controller := fn(): void {
memory.outb(0x64, 0xAD)
memory.outb(0x64, 0xA7)
//Disables ports to make sure that they won't interfere with the setup process.
loop if (memory.inb(0x64) & 1) == 0 break else memory.inb(0x60)
//Flushes any output because apperantly that might interfere with stuff.
memory.outb(0x64, 0xA8)
//Enables port 2.
memory.outb(0x64, 0x20)
//Gimme configuration byte.
loop if (memory.inb(0x64) & 1) == 1 break
ports[1].exists = @inline(check_bit, memory.inb(0x60), 5, 0)
if ports[1].exists {
memory.outb(0x64, 0xA7)
}
loop if (memory.inb(0x64) & 1) == 0 break else memory.inb(0x60)
//Flushes any output because apperantly that might interfere with stuff.
memory.outb(0x64, 0xAB)
loop if (memory.inb(0x64) & 1) == 1 break
ports[0].exists = memory.inb(0x60) == 0x0
//Test port 1.
if ports[1].exists {
memory.outb(0x64, 0xA9)
loop if (memory.inb(0x64) & 1) == 1 break
ports[1].exists = memory.inb(0x60) == 0x0
}
//Test port 2.
if (ports[0].exists | ports[1].exists) == false {
log.error("No ports detected! No input will be processed! Cannot handle this!\0")
}
if ports[0].exists {
memory.outb(0x64, 0xAE)
//Enables port 1.
ports[0].command_queued = true
}
if ports[1].exists {
memory.outb(0x64, 0xA8)
//Enables port 2.
ports[1].command_queued = true
}
}
enable_streaming := fn(port: ^Port): void {
@inline(send_command, port, 0xF4)
}
process := fn(port: ^controller.Port): void {
if port.device.value < devices.MOUSE_5_BUTTON.value {
event := MouseEvent.(0, 0, false, false, false)
event.left = bit0(port.packet[0])
event.right = bit1(port.packet[0])
event.middle = bit2(port.packet[0])
event.x_change = @intcast(port.packet[1])
event.y_change = @intcast(port.packet[2])
buffer.write(MouseEvent, mouse_buffer, &event)
} else if port.device == devices.MOUSE_INIT_1 {
port.device.value = port.packet[0]
if port.device != devices.MOUSE_SCROLLWHEEL {
enable_streaming(port)
return
}
port.device = devices.MOUSE_INIT_2
} else if port.device == devices.MOUSE_INIT_2 {
port.device.value = port.packet[0]
} else if port.device == devices.NO_DEVICE {
if port.packet_length == 1 {
port.device.value = port.packet[0]
enable_streaming(port)
//TODO: Upgrade mouse.
} else {
port.device.value = port.packet[1] | port.packet[0] << 8
enable_streaming(port)
}
log.info("Identified device!\0")
log.info(string.display_int(port.device.value, format_page, 16))
} else {
log.info("KEY PRESSED\0")
}
}
check_complete := fn(port: ^controller.Port): bool {
last_value := port.packet[port.packet_length - 1]
if port.device == devices.NO_DEVICE {
if last_value == 0 | last_value == 3 | last_value == 4 {
return true
} else if port.packet_length == 2 {
return true
}
} else if port.device == devices.MOUSE_3_BUTTON {
if port.packet_length == 3 return true
} else if port.device == devices.MOUSE_SCROLLWHEEL | port.device == devices.MOUSE_5_BUTTON {
if port.packet_length == 4 return true
} else {
if port.packet[0] == 0xE1 {
if port.packet_length == 6 {
return true
}
} else if port.packet[0] != 0xE0 {
return true
} else if port.packet_length == 2 & port.packet[1] != 0x2A & port.packet[1] != 0xB7 {
return true
} else if port.packet_length == 4 {
return true
}
}
return false
handle_input := fn(port: uint, input: u8): void {
}
main := fn(): void {
mouse_buffer = buffer.create("PS/2 Mouse\0")
format_page = memory.alloc(u8, 1024)
controller.init()
if controller.port1.exists {
//log.info("Port 1 exists.\0")
controller.send_byte(@bitcast(0), 0xF4)
}
if controller.port2.exists {
//controller.send_byte(&controller.port2, 0xF4)
}
loop {
info = controller.get_info()
if controller.timed_out(info) {
port_info := memory.inb(0x64)
//Enables port 1.
if (port_info & 0x40) > 0 {
log.error("Timeout error! Cannot handle these!\0")
}
if controller.check_parity(info) {
if (port_info & 0x80) > 0 {
log.error("Parity error! Cannot handle these!\0")
}
/*
if controller.has_input(info) {
port := controller.get_port(info)
if port.packet_length > 0 & check_complete(port) {
process(port)
if (port_info & 1) == 0 {
if ports[0].exists & ports[0].command_queued {
memory.outb(0x60, ports[0].command_queue)
ports[0].command_queued = false
}
input := controller.get_input()
/*if input == 0xAA & port.can_hot_plug {
port.device = devices.NO_DEVICE
controller.send_byte(port, 0xF4)
}*/
port.packet[port.packet_length] = input
port.packet_length += 1
if check_complete(port) {
process(port)
port.packet_length = 0
if ports[1].exists & ports[1].command_queued {
memory.outb(0x64, 0xD4)
memory.outb(0x60, ports[1].command_queue)
ports[1].command_queued = false
}
}*/
}
port := 0
if ports[1].exists {
port = port_info >> 5 & 1
}
if ports[port].exists {
@inline(handle_input, port, memory.inb(0x60))
}
}
}

View file

@ -1,21 +0,0 @@
Button := struct {id: u8}
$LEFT_BUTTON := Button.(1)
$RIGHT_BUTTON := Button.(2)
$MIDDLE_BUTTON := Button.(4)
$BUTTON4 := Button.(8)
$BUTTON5 := Button.(16)
SampleRate := struct {value: u8}
$SR10 := SampleRate.(10)
$SR20 := SampleRate.(20)
$SR40 := SampleRate.(40)
$SR60 := SampleRate.(60)
$SR80 := SampleRate.(80)
$SR100 := SampleRate.(100)
$SR200 := SampleRate.(200)
Resolution := struct {value: u8}
$RES_1COUNT_PER_MM := Resolution.(0)
$RES_2COUNT_PER_MM := Resolution.(1)
$RES_4COUNT_PER_MM := Resolution.(2)
$RES_8COUNT_PER_MM := Resolution.(3)

View file

@ -1,21 +0,0 @@
.{DeviceID, NO_DEVICE} := @use("devices.hb")
State := struct {s: u8}
$Recive := State.(0)
$Reboot := State.(1)
Port := packed struct {
exists: bool,
device: DeviceID,
packet: [u8; 8],
packet_length: u8,
can_hot_plug: bool,
}
$PORT_AT_STARTUP := Port.(
true,
NO_DEVICE,
.(0, 0, 0, 0, 0, 0, 0, 0),
0,
true,
)

View file

@ -1,8 +1,4 @@
stn := @use("../../../libraries/stn/src/lib.hb");
.{memory, log, buffer} := stn
intouch := @use("../../../libraries/intouch/src/lib.hb");
.{KeyEvent} := intouch
.{memory, log, buffer} := @use("../../../libraries/stn/src/lib.hb")
send_byte := fn(byte: u8): u8 {
memory.outb(96, byte)
@ -10,31 +6,23 @@ send_byte := fn(byte: u8): u8 {
}
main := fn(): int {
buf := buffer.create("PS/2 Keyboard\0")
buf := buffer.create("XKeyboard\0")
_ = send_byte(238)
log.info("PS/2 Driver Loaded\0")
if send_byte(238) == 238 {
log.info("PS/2 Keyboard Echoed\0")
}
if send_byte(244) == 250 {
log.info("Enabled scanning\0")
}
prev_input := 250
loop {
loop if (memory.inb(0x64) & 0x20) == 0x20 break
input := memory.inb(96)
if input == prev_input {
continue
}
prev_input = input
kevent := KeyEvent.(false, true, input)
buffer.write(KeyEvent, buf, &kevent)
buffer.write(u8, &input, buf)
}
return 0
}

View file

@ -145,7 +145,7 @@ main := fn(): int {
event.x_change = x_change
event.y_change = y_change
buffer.write(MouseEvent, mouse_buffer, &event)
buffer.write(MouseEvent, &event, mouse_buffer)
}
return 0

View file

@ -10,12 +10,12 @@ example := fn(): void {
color := render.light_cyan
n := @as(u8, 1)
loop {
// ! dead code elimination bug
render.clear(screen, color)
render.sync(screen)
if color.b == 255 | color.b == 0 {
if (color.b & 255) == 255 | (color.b & 255) == 0 {
n = -n
}
color.b += n
}
return
}

View file

@ -0,0 +1,72 @@
.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math;
.{log, string, memory} := @use("../../../../libraries/stn/src/lib.hb");
.{Color, Surface} := @use("../../../../libraries/render/src/lib.hb")
render := @use("../../../../libraries/render/src/lib.hb")
Face := struct {a: uint, b: uint, c: uint, mode: u8, color: Color, texture: ^Surface}
WIREFRAME := @as(u8, 0)
FILLED := @as(u8, 1)
TEXTURED := @as(u8, 2)
Vec3 := struct {x: int, y: int, z: int}
vertecies := [Vec3].(.(-1, -1, -1), .(1, -1, -1), .(1, 1, -1), .(-1, 1, -1), .(-1, -1, 1), .(1, -1, 1), .(1, 1, 1), .(-1, 1, 1))
projected := @as([Vec3; 8], idk)
faces := [Face].(Face.(0, 1, 2, WIREFRAME, .(255, 0, 0, 255), null))
d := @as(int, 1)
example := fn(): void {
screen := render.init(true)
unit := @as(int, 0)
half_width := @as(int, @intcast(screen.width / 2))
half_height := @as(int, @intcast(screen.height / 2))
if screen.width < screen.height {
unit = @intcast(half_width / 2)
} else {
unit = @intcast(half_height / 2)
}
format_page := @as([u8; 1024], idk)
loop {
index := 0
loop if index == 8 break else {
vertex := vertecies[index]
vertex = .(vertex.x * unit, vertex.y * unit, vertex.z * unit + unit)
vertex = .(vertex.x * d / (vertex.z / unit + d) + half_width, vertex.y * d / (vertex.z / unit + d) + half_height, vertex.z)
projected[index] = vertex
log.info(string.display_int(vertex.x, @bitcast(&format_page), 10))
log.info(string.display_int(vertex.y, @bitcast(&format_page), 10))
index += 1
}
index = 0
render.clear(screen, render.black)
loop if index == 1 break else {
face := faces[index]
a := projected[face.a]
b := projected[face.b]
c := projected[face.c]
if face.mode == WIREFRAME {
//render.put_tri(screen, .(@intcast(0), @intcast(0)), .(@intcast(512), @intcast(128)), .(@intcast(256), @intcast(256)), .(255, 0, 0, 255))
//face.color)
}
index += 1
}
//render.put_line(screen, .(1, 1), .(512, 128), .(255, 0, 0, 255))
//render.put_line(screen, .(256, 256), .(512, 128), .(255, 0, 0, 255))
render.put_tri(screen, .(1, 1), .(512, 128), .(256, 256), .(255, 0, 0, 255))
//render.put_filled_tri(screen, .(128, 256), .(512, 512), .(10, 10), .(255, 255, 255, 255))
render.sync(screen)
}
return
}

View file

@ -0,0 +1,26 @@
.{Vec2, sin_i, cos_i} := @use("../../../../libraries/stn/src/lib.hb").math
render := @use("../../../../libraries/render/src/lib.hb")
able_bmp := @embed("./assets/able.bmp")
mini_bmp := @embed("./assets/mini.bmp")
example := fn(): void {
able := render.image.surface_from_bmp(@bitcast(&able_bmp))
mini := render.image.surface_from_bmp(@bitcast(&mini_bmp))
angle := @as(int, 0)
screen := render.init(true)
loop {
render.clear(screen, render.black)
render.put_filled_circle(screen, .(screen.width / 2, screen.height / 2), 128, render.light_yellow)
render.put_circle(screen, .(screen.width / 2, screen.height / 2), 256, render.light_blue)
render.put_textured_circle(screen, able, .(able.width / 2, able.height / 2), .(screen.width / 2 + @intcast(sin_i(angle, @as(int, 256))), screen.height / 2 + @intcast(cos_i(angle, @as(int, 256)))), able.width / 2 - 1)
render.put_textured_circle(screen, mini, .(mini.width / 2, mini.height / 2), .(screen.width / 2 + @intcast(sin_i(angle + 180, @as(int, 256))), screen.height / 2 + @intcast(cos_i(angle + 180, @as(int, 256)))), mini.width / 2 - 1)
render.sync(screen)
angle += 1
}
return
}

View file

@ -1,35 +0,0 @@
.{Vec2, sin, cos, PI} := @use("../../../../libraries/stn/src/lib.hb").math
render := @use("../../../../libraries/render/src/lib.hb")
able_bmp := @embed("../../../../assets/able.bmp")
mini_bmp := @embed("../../../../assets/mini.bmp")
/* expected result:
two textured circles rotating
around one yellow filled circle
with a blue line showing their
'orbit' */
example := fn(): void {
able := render.image.from(@bitcast(&able_bmp))
mini := render.image.from(@bitcast(&mini_bmp))
if able == null | mini == null {
return
}
angle := 0.0
screen := render.init(true)
loop {
render.clear(screen, render.black)
render.put_filled_circle(screen, .(screen.width / 2, screen.height / 2), 128, render.light_yellow)
render.put_circle(screen, .(screen.width / 2, screen.height / 2), 256, render.light_blue)
render.put_textured_circle(screen, able, .(able.width / 2, able.height / 2), .(screen.width / 2 + @intcast(@fti(sin(angle) * 256)), screen.height / 2 + @intcast(@fti(cos(angle) * 256))), able.width / 2 - 1)
render.put_textured_circle(screen, mini, .(mini.width / 2, mini.height / 2), .(screen.width / 2 + @intcast(@fti(sin(angle + PI) * 256)), screen.height / 2 + @intcast(@fti(cos(angle + PI) * 256))), mini.width / 2 - 1)
render.sync(screen)
angle += 0.01
}
return
}

View file

@ -0,0 +1,17 @@
.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math
render := @use("../../../../libraries/render/src/lib.hb")
bmp_1 := @embed("./assets/able.bmp")
bmp_2 := @embed("./assets/mini.bmp")
example := fn(): void {
screen := render.init(true)
image := render.image.surface_from_bmp(@bitcast(&bmp_2))
loop {
render.clear(screen, render.black)
render.put_scaled(screen, image, .(100, 100), .(image.width / 2 + image.width / 4, image.height * 3))
render.sync(screen)
}
}

View file

@ -46,7 +46,7 @@ example := fn(): void {
bottom := buf + msg_len
memory.copy(u8, msg, buf, msg_len)
@inline(memory.copy, u8, msg, buf, msg_len)
cursor := bottom
draw_window(window, font, buf, cursor)

View file

@ -1,11 +0,0 @@
[package]
name = "sunset_client"
authors = ["koniifer"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,29 +0,0 @@
.{log} := @use("../../../libraries/stn/src/lib.hb")
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
bmp := @embed("../../../assets/mini.bmp")
main := fn(): void {
sunset.client.find_server()
image := render.image.bmp.from(@bitcast(&bmp))
if image == null {
log.error("got no image\0")
return
}
window := sunset.client.new(.(.(100, 100), .(200, 200), "Hello,\0"))
if window == null {
log.error("got no window\0")
return
}
x := 0
loop {
render.clear(window.surface, render.black)
render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 20), false)
_ = sunset.client.send_frame(window)
x += 1
}
}

View file

@ -1,11 +0,0 @@
[package]
name = "sunset_client_2"
authors = ["koniifer"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,29 +0,0 @@
.{log} := @use("../../../libraries/stn/src/lib.hb")
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
bmp := @embed("../../../assets/able.bmp")
main := fn(): void {
sunset.client.find_server()
image := render.image.bmp.from(@bitcast(&bmp))
if image == null {
log.error("got no image\0")
return
}
window := sunset.client.new(.(.(400, 300), .(400, 240), "Sunset!\0"))
if window == null {
log.error("got no window\0")
return
}
x := 0
loop {
render.clear(window.surface, render.black)
render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 40), false)
_ = sunset.client.send_frame(window)
x += 1
}
}

View file

@ -1,11 +0,0 @@
[package]
name = "sunset_server"
authors = ["koniifer"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,99 +0,0 @@
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
intouch := @use("../../../libraries/intouch/src/lib.hb")
horizon_api := @use("../../../libraries/horizon_api/src/lib.hb");
.{new_label, render_label_to_surface, set_label_text, set_color} := horizon_api.widgets.label
stn := @use("../../../libraries/stn/src/lib.hb");
.{Vec2} := stn.math
psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf")
img := @embed("../../../assets/wallpaper.qoi")
main := fn(): int {
sunset.server.start()
screen := render.init(true)
render.clear(screen, render.black)
font := @unwrap(render.text.font_from_psf2(@bitcast(&psf), false))
wallpaper := render.image.from(@bitcast(&img))
if wallpaper == null {
// stn.panic("Wallpaper not loaded\0")
return 1
}
mouse_x := 100
mouse_y := 100
text_label := new_label("Hi\0")
set_color(text_label, sunset.server.DECO_COLOUR, render.black)
loop {
mouse_event := intouch.recieve_mouse_event()
if mouse_event != null {
change_x := @as(i16, mouse_event.x_change)
change_x = change_x << 8
change_x = change_x >> 8
mouse_x += change_x
if mouse_x <= 0 {
mouse_x = 0
}
if mouse_x >= screen.width - 20 {
mouse_x = @intcast(screen.width - 21)
}
change_y := @as(i16, mouse_event.y_change)
change_y = change_y << 8
change_y = change_y >> 8
mouse_y -= change_y
if mouse_y < 0 {
mouse_y = 1
}
if mouse_y >= screen.height - 20 {
mouse_y = @intcast(screen.height - 21)
}
if mouse_event.left {
set_label_text(text_label, "LEFT CLICK\0")
}
if mouse_event.middle {
set_label_text(text_label, "MIDDLE CLICK\0")
}
if mouse_event.right {
set_label_text(text_label, "RIGHT CLICK\0")
}
}
{
render.clear(screen, render.black)
render.put_surface(screen, wallpaper, .(0, 0), false)
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), sunset.server.DECO_COLOUR)
}
if sunset.server.incoming() {
sunset.server.collect_frames()
sunset.server.render_clients(screen)
}
{
pos := Vec2(uint).(1, screen.height - 21)
render_label_to_surface(screen, text_label, font, pos)
render.put_rect(screen, .(0, screen.height - 21), .(screen.width - 1, 20), sunset.server.DECO_COLOUR)
}
// Mouse cursor
{
render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), sunset.server.DECO_COLOUR_DARKER)
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), sunset.server.DECO_COLOUR)
}
render.sync(screen)
}
return 0
}

View file

@ -0,0 +1,30 @@
.{log, string, memory, buffer} := @use("../../../libraries/stn/src/lib.hb")
sound := @use("../../../libraries/sound/src/lib.hb")
service_search := fn(): void {
a := "\{01}\0"
@eca(3, 0, a, 2)
return
}
beep := fn(): void {
sound.set_frequency(1024)
sound.start()
return
}
main := fn(): int {
//loop {
// memory.outb(0x61, memory.inb(0x61) & 0xFE | 1)
// memory.outb(0x61, memory.inb(0x61) & 0xFE)
//}
beep()
//service_search()
buf := "\0\0\0\0"
x := @as(int, 0)
loop if x > 255 break else {
log.info(string.display_int(x, buf, 2))
x += 1
}
return 0
}

View file

@ -3,9 +3,8 @@
default_entry = 1
timeout = 0
verbose = false
# interface_resolution = "1920x1080x24"
interface_resolution = "1024x768x24"
# interface_resolution = "640x480x24"
interface_resolution = "1600x900x24"
# interface_resolution = "640x480x32"
# Terminal related settings
# term_wallpaper = "boot:///background.bmp"
term_wallpaper = "boot:///empty-background.bmp"
@ -16,29 +15,53 @@ comment = "Default AbleOS boot entry."
protocol = "limine"
kernel_path = "boot:///kernel_${ARCH}"
kernel_cmdline = ""
# resolution = "1920x1080x24"
resolution = "1024x768x24"
# resolution = "640x480x24"
# resolution = "640x480x32"
resolution = "1600x900x24"
[boot.limine.ableos.modules]
# [boot.limine.ableos.modules.render_example]
# path = "boot:///render_example.hbf"
# [boot.limine.ableos.modules.horizon]
# path = "boot:///horizon.hbf"
# [boot.limine.ableos.modules.mouse_driver]
# path = "boot:///mouse_driver.hbf"
# [boot.limine.ableos.modules.ps2_mouse_driver]
# path = "boot:///ps2_mouse_driver.hbf"
# [boot.limine.ableos.modules.serial_driver]
# path = "boot:///serial_driver.hbf"
# [boot.limine.ableos.modules.serial_driver_test]
# path = "boot:///serial_driver_test.hbf"
[boot.limine.ableos.modules.horizon]
path = "boot:///horizon.hbf"
# [boot.limine.ableos.modules.horizon_testing_program]
# path = "boot:///horizon_testing_program.hbf"
# [boot.limine.ableos.modules.dt_buffer_test]
# path = "boot:///dt_buffer_test.hbf"
# [boot.limine.ableos.modules.svga_driver]
# path = "boot:///svga_driver.hbf"
# [boot.limine.ableos.modules.ps2_keyboard_driver]
# path = "boot:///ps2_keyboard_driver.hbf"
[boot.limine.ableos.modules.ps2_driver]
path = "boot:///ps2_driver.hbf"
# [boot.limine.ableos.modules.filesystem_fat32]
# [boot.limine.ableos.modules.ps2_keyboard_driv
# path = "boot:///filesystem_fat32.hbf"
# [boot.limine.ableos.modules.sunset_client]
# path = "boot:///sunset_client.hbf"
# [boot.limine.ableos.modules.pumpkin_print]
# path = "boot:///pumpkin_print.hbf"
# [boot.limine.ableos.modules.sunset_server]
# path = "boot:///sunset_server.hbf"
[boot.limine.ableos.modules.ps2_mouse_driver]
path = "boot:///ps2_mouse_driver.hbf"
# [boot.limine.ableos.modules.ps2_driver]
# path = "boot:///ps2_driver.hbf"
# [boot.limine.ableos.modules.app_bar]
# path = "boot:///app_bar.hbf"
# [boot.limine.ableos.modules.test_abc]
# path = "boot:///test_abc.hbf"

40
todo.md
View file

@ -1,40 +0,0 @@
@konii
Windowing System
Rendering
@able
Windowing System
Interrupt Forwarding
@peony
PS/2
XYZ
@kodin
AIDL AbleOS Interface Description Language
UI-SEXPR lispy ui decl language
@morshy
Simple Userland Allocator
@funky
Kernel Testing Framework (A rust framework for testing the kernel)
@unassigned
FileIO (Fat32)
DiskIO (Undecided Disk type)
Proper Memory Protection
Channels (Two buffers bundled together to form two way communication)
Userland Testing Framework (An hblang framework for testing the userspace)
PCI/E (Honestly I have no fucking clue whats going on with PCI or why userland cant properly read it)
Kernel Reimpl (Do not you dare think about this yet its only here as an option to show goals)
AbleOS Compiler Collection
acc-asm
hblang^2 (hblang compiler in hblang)