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

View file

@ -14,29 +14,3 @@ arch_cond!(
riscv64: "riscv64", riscv64: "riscv64",
x86_64: "x86_64", 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() }; static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() };
#[repr(u8)] #[repr(u8)]
#[derive(Debug, Eq, Hash, PartialEq)] enum Interrupt {
pub enum Interrupt {
Timer = 32, Timer = 32,
ApicErr = u8::MAX - 1, ApicErr = u8::MAX - 1,
Spurious = u8::MAX, Spurious = u8::MAX,
@ -62,49 +60,17 @@ extern "x86-interrupt" fn page_fault(
} }
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) { extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
// interrupt(Interrupt::Timer);
unsafe { unsafe {
LAPIC.end_of_interrupt(); LAPIC.end_of_interrupt();
} }
} }
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) { extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
interrupt(Interrupt::ApicErr);
panic!("Internal APIC error"); panic!("Internal APIC error");
} }
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) { extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
interrupt(Interrupt::Spurious);
unsafe { unsafe {
LAPIC.end_of_interrupt(); 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"))] #[cfg(not(target_feature = "avx2"))]
unsafe extern "C" fn _kernel_start() -> ! { unsafe extern "C" fn _kernel_start() -> ! {
// Initialise SSE, then jump to kernel entrypoint // Initialise SSE, then jump to kernel entrypoint
core::arch::naked_asm!( core::arch::asm!(
// Initialise SSE // Initialise SSE
"mov rax, cr0", "mov rax, cr0",
"and ax, 0xfffb", "and ax, 0xfffb",
@ -46,6 +46,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
// Jump to the kernel entry point // Jump to the kernel entry point
"jmp {}", "jmp {}",
sym start, sym start,
options(noreturn),
) )
} }
@ -53,7 +54,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
#[naked] #[naked]
#[cfg(target_feature = "avx2")] #[cfg(target_feature = "avx2")]
unsafe extern "C" fn _kernel_start() -> ! { unsafe extern "C" fn _kernel_start() -> ! {
core::arch::naked_asm!( core::arch::asm!(
// Enable protected mode and configure control registers // Enable protected mode and configure control registers
"mov rax, cr0", "mov rax, cr0",
"and ax, 0xFFFB", // Clear CR0.EM (bit 2) for coprocessor emulation "and ax, 0xFFFB", // Clear CR0.EM (bit 2) for coprocessor emulation
@ -99,6 +100,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
"jmp {0}", "jmp {0}",
sym start, sym start,
sym oops, sym oops,
options(noreturn),
) )
} }
@ -109,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
unsafe extern "C" fn start() -> ! { unsafe extern "C" fn start() -> ! {
logging::init(); logging::init();
crate::logger::init().expect("failed to set logger"); 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); static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
memory::init_pt(VirtAddr::new( memory::init_pt(VirtAddr::new(
@ -188,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
// TODO: Add in rdseed and rdrand as sources for randomness // TODO: Add in rdseed and rdrand as sources for randomness
let _rand = xml::XMLElement::new("Random"); let _rand = xml::XMLElement::new("Random");
log::debug!("Getting boot modules"); log::trace!("Getting boot modules");
let bm = MOD_REQ.get_response().get(); let bm = MOD_REQ.get_response().get();
let mut bootmodules = alloc::vec::Vec::new(); let mut bootmodules = alloc::vec::Vec::new();
@ -226,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
break; break;
} }
} }
log::debug!("Boot module count: {:?}", bootmodules.len()); log::info!("Boot module count: {:?}", bootmodules.len());
assert_eq!(bm.module_count, bootmodules.len() as u64); 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) }; 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 class = ((reg2 >> 16) & 0x0000_FFFF) as u16;
let pci_class = PciFullClass::from_u16(class); let pci_class = PciFullClass::from_u16(class);
let header_type = get_header_type(bus, device, 0); let header_type = get_header_type(bus, device, 0);

View file

@ -1,17 +1,8 @@
//! Environment call handling routines //! 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,
use crate::{ service_definition_service::sds_msg_handler,
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 { use {
@ -67,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
true => IpcBuffer::new(true, length), true => IpcBuffer::new(true, length),
}, },
); );
info!("Buffer ID: {}", buff_id);
vm.registers[1] = hbvm::value::Value(buff_id); vm.registers[1] = hbvm::value::Value(buff_id);
} }
2 => { 2 => {
log::error!("Oops, deleting buffers is not implemented.")
// Delete buffer // Delete buffer
} }
3 => { 3 => {
@ -152,43 +143,6 @@ pub fn handler(vm: &mut Vm) {
Ok(()) => {} Ok(()) => {}
Err(_) => log::error!("Improper dt query"), 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 => { buffer_id => {
let mut buffs = IPC_BUFFERS.lock(); let mut buffs = IPC_BUFFERS.lock();
@ -228,7 +182,7 @@ pub fn handler(vm: &mut Vm) {
} else { } else {
unsafe { unsafe {
let ptr = map_ptr as *mut u8; 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); 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> { pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
let msg_vec = block_read(mem_addr, length); let msg_vec = block_read(mem_addr, length);
use log::Level::*; let log_level = msg_vec[0];
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 strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap()); 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; 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) { match core::str::from_utf8(&str) {
Ok(strr) => { 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( log::logger().log(
&Record::builder() &Record::builder()
.args(format_args!("{}", strr)) .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)] #[inline(always)]
unsafe fn memset(dest: *mut u8, src: *const u8, count: usize, size: usize) { unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) {
let total_size = count * size; const BLOCK_SIZE: usize = 64;
src.copy_to_nonoverlapping(dest, size); let mut remaining = count * size;
let mut copied = size; if remaining < 16 {
src.copy_to_nonoverlapping(dest, remaining);
return;
}
while copied < total_size { let mut buffer = [0u8; BLOCK_SIZE];
let copy_size = copied.min(total_size - copied); let mut buffer_size = size;
dest.add(copied).copy_from_nonoverlapping(dest, copy_size); src.copy_to_nonoverlapping(buffer.as_mut_ptr(), size);
copied += copy_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(); // let a: protocol::Protocol = protocol.into();
buff_id buff_id
} }
pub fn sds_search_service(protocol: &str) -> u64 {
fn sds_search_service(protocol: &str) -> u64 {
let services = SERVICES.lock(); let services = SERVICES.lock();
let compare = Protocol::from(protocol); let compare = Protocol::from(protocol);
for (bid, protocol_canidate) in &services.0 { for (bid, protocol_canidate) in &services.0 {

View file

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

View file

@ -8,10 +8,7 @@ use {
device_tree::DeviceTree, device_tree::DeviceTree,
holeybytes::ExecThread, holeybytes::ExecThread,
ipc::buffer::IpcBuffer, ipc::buffer::IpcBuffer,
task::Executor,
}, },
alloc::boxed::Box,
core::cell::LazyCell,
hashbrown::HashMap, hashbrown::HashMap,
hbvm::mem::Address, hbvm::mem::Address,
limine::{Framebuffer, FramebufferRequest, NonNullPtr}, limine::{Framebuffer, FramebufferRequest, NonNullPtr},
@ -22,14 +19,6 @@ use {
pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! { pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
debug!("Entered kmain"); debug!("Entered kmain");
#[cfg(feature = "ktest")] {
use crate::ktest;
debug!("TESTING");
ktest::test_main();
loop {};
}
// let kcmd = build_cmd("Kernel Command Line", cmdline); // let kcmd = build_cmd("Kernel Command Line", cmdline);
// trace!("Cmdline: {kcmd:?}"); // trace!("Cmdline: {kcmd:?}");
@ -76,24 +65,13 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
fb1.address.as_ptr().unwrap() as *const u8 fb1.address.as_ptr().unwrap() as *const u8
); );
let mut executor = crate::task::Executor::new(256);
unsafe { unsafe {
let executor = LazyCell::<Executor>::force_mut(&mut EXECUTOR);
for module in boot_modules.iter() { for module in boot_modules.iter() {
let cmd = module.cmd.trim_matches('"'); let cmd = module.cmd.trim_matches('"');
let cmd_len = cmd.len() as u64; let cmd_len = cmd.len() as u64;
log::info!( log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
"Starting {}",
module
.path
.split('/')
.last()
.unwrap()
.split('.')
.next()
.unwrap()
);
log::debug!("Spawning {} with arguments \"{}\"", module.path, cmd);
// decode AbleOS Executable format // decode AbleOS Executable format
let header = &module.bytes[0..46]; 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 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 data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
let end = (code_length + data_length) as usize; 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)); let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0));
if cmd_len > 0 { if cmd_len > 0 {
thr.set_arguments(cmd.as_ptr() as u64, cmd_len); 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 { if let Err(e) = thr.await {
log::error!("{e:?}"); log::error!("{e:?}");
} }
})); })
} }
debug!("Random number: {}", hardware_random_u64()); debug!("Random number: {}", hardware_random_u64());
@ -135,10 +113,6 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
crate::arch::spin_loop() 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(|| { pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
let dt = DeviceTree::new(); let dt = DeviceTree::new();
Mutex::new(dt) Mutex::new(dt)
@ -156,3 +130,10 @@ pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
Mutex::new(bufs) 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. //! 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 //! 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_std]
#![no_main]
#![feature( #![feature(
slice_split_once, slice_split_once,
exclusive_wrapper, exclusive_wrapper,
new_uninit,
core_intrinsics, core_intrinsics,
abi_x86_interrupt, abi_x86_interrupt,
lazy_get,
alloc_error_handler, alloc_error_handler,
ptr_sub_ptr, ptr_sub_ptr,
custom_test_frameworks,
naked_functions, 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; extern crate alloc;
mod allocator; mod allocator;
@ -32,10 +33,6 @@ mod memory;
mod task; mod task;
mod utils; mod utils;
// #[cfg(feature = "tests")]
mod ktest;
use alloc::string::ToString;
use versioning::Version; use versioning::Version;
/// Kernel's 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")); let _ = crate::arch::log(format_args!("{msg}\r\n"));
loop {} 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) YieldNow(false)
} }
pub struct Executor { pub struct Executor<F: Future<Output = ()> + Send> {
tasks: Slab<Task>, tasks: Slab<Task<F>>,
task_queue: Arc<TaskQueue>, task_queue: Arc<TaskQueue>,
} }
impl Executor { impl<F: Future<Output = ()> + Send> Executor<F> {
pub fn new() -> Self { pub fn new(size: usize) -> Self {
Self { Self {
tasks: Slab::new(), tasks: Slab::with_capacity(size),
task_queue: Arc::new(TaskQueue::new()), task_queue: Arc::new(TaskQueue::new()),
} }
} }
#[inline] #[inline]
pub fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) -> usize { pub fn spawn(&mut self, future: F) {
let id = self.tasks.insert(Task::new(future)); self.task_queue
self.task_queue.queue.push(id); .queue
id .push(self.tasks.insert(Task::new(future)));
} }
pub fn run(&mut self) { pub fn run(&mut self) {
@ -83,17 +83,17 @@ impl Executor {
} }
} }
struct Task { struct Task<F: Future<Output = ()> + Send> {
future: Pin<Box<dyn Future<Output = ()> + Send>>, future: Pin<Box<F>>,
waker: Option<TaskWaker>, waker: Option<TaskWaker>,
} }
impl Task { impl<F: Future<Output = ()> + Send> Task<F> {
#[inline(always)] #[inline(always)]
pub fn new(future: Pin<Box<dyn Future<Output = ()> + Send>>) -> Self { pub fn new(future: F) -> Self {
Self { Self {
future, future: Box::pin(future),
waker: None, waker: None,
} }
} }

View file

@ -1,6 +1,6 @@
{ {
"arch": "aarch64", "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, "disable-redzone": true,
"env": "", "env": "",
"executables": true, "executables": true,

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@ stn := @use("../../../../libraries/stn/src/lib.hb");
.{Vec2} := stn.math .{Vec2} := stn.math
render := @use("../../../../libraries/render/src/lib.hb"); render := @use("../../../../libraries/render/src/lib.hb");
.{Surface, Color} := render; .{Surface} := render;
.{Font} := render.text .{Font} := render.text
Label := struct { Label := struct {
@ -12,8 +12,6 @@ Label := struct {
surface: Surface, surface: Surface,
text: ^u8, text: ^u8,
text_length: uint, text_length: uint,
bg: Color,
fg: Color,
} }
set_label_text := fn(label: Label, text: ^u8): void { 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 { render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void {
if label.is_dirty { if label.is_dirty {
render.clear(label.surface, label.bg) render.clear(label.surface, render.black)
render.put_text(label.surface, font, .(0, 0), label.fg, label.text) render.put_text(label.surface, font, .(0, 0), render.white, label.text)
} }
render.put_surface(surface, label.surface, pos, false) 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 { new_label := fn(text: ^u8): Label {
text_surface := render.new_surface(1024, 20) text_surface := render.new_surface(1024, 20)
text_length := string.length(text) 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 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"); keycodes := @use("keycodes.hb");
.{KeyCode} := keycodes .{KeyCode} := keycodes
KeyEvent := packed struct { KeyEvent := struct {
up: bool, // 0 if down
just_triggered: bool, // 1 if up
up: u8,
// 0 if not just triggered
// 1 if just triggered
just_triggered: u8,
key: KeyCode, key: KeyCode,
} }

View file

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

View file

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

View file

@ -1,5 +1,5 @@
.{Color, Surface, new_surface, put_surface} := @use("../lib.hb"); .{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 { BitmapFileHeader := packed struct {
magic: u16, magic: u16,
@ -41,7 +41,7 @@ from := fn(bmp: ^u8): ?Surface {
return null 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) rhs := new_surface(info_header.width, info_header.height)
put_surface(rhs, lhs, .(0, 0), true) put_surface(rhs, lhs, .(0, 0), true)

View file

@ -1,5 +1,5 @@
.{Color, Surface, new_surface} := @use("../lib.hb"); .{Color, Surface, new_surface} := @use("../lib.hb");
.{log} := @use("../../../stn/src/lib.hb") .{log, memory} := @use("../../../stn/src/lib.hb")
/* source: /* source:
https://github.com/phoboslab/qoi/blob/master/qoi.h */ https://github.com/phoboslab/qoi/blob/master/qoi.h */
@ -13,7 +13,7 @@ $QOI_OP_RUN := 0xC0
$QOI_OP_RGB := 0xFE $QOI_OP_RGB := 0xFE
$QOI_OP_RGBA := 0xFF $QOI_OP_RGBA := 0xFF
$QOI_MASK_2 := 0xC0 $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 return (c.r * 3 + c.g * 5 + c.b * 7 + c.a * 11) % 64
} }
$QOI_MAGIC := 0x716F6966 $QOI_MAGIC := 0x716F6966
@ -89,7 +89,7 @@ from := fn(qoi: ^u8): ?Surface {
run = b1 & 0x3F run = b1 & 0x3F
} }
index[QOI_COLOR_HASH(px)] = px index[@inline(QOI_COLOR_HASH, px)] = px
}; };
*(surface.buf + px_pos) = 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_pixel := mode.put_pixel
put_rect := mode.put_rect put_rect := mode.put_rect
put_filled_rect := mode.put_filled_rect put_filled_rect := mode.put_filled_rect
put_trirect := mode.put_trirect
put_circle := mode.put_circle put_circle := mode.put_circle
put_filled_circle := mode.put_filled_circle put_filled_circle := mode.put_filled_circle
put_textured_circle := mode.put_textured_circle put_textured_circle := mode.put_textured_circle
put_line := mode.put_line put_line := mode.put_line
put_vline := mode.put_vline
put_hline := mode.put_hline
clear := mode.clear clear := mode.clear
put_surface := mode.put_surface put_surface := mode.put_surface
put_scaled := mode.put_scaled
put_text := mode.put_text put_text := mode.put_text
// thanks peony for these three! // thanks peony for these three!
//put_trirect := mode.put_trirect put_trirect := mode.put_trirect
//put_vline := mode.put_vline put_vline := mode.put_vline
//put_hline := mode.put_hline put_hline := mode.put_hline
// Display // Display
sync := mode.sync 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"); .{Color, text} := @use("lib.hb");
.{get_glyph, get_glyph_unicode, Font, UNC_TABLE_SIZE} := text; .{get_glyph, get_glyph_unicode, Font, UNC_TABLE_SIZE} := text;
.{Vec2} := math .{Vec2} := math
// safety: don't use before init() or you will get a memory access violation // safety: don't use before init() or you will get a memory access violation
framebuffer := memory.dangling(Color) //framebuffer := memory.dangling(Color)
Surface := struct { Surface := struct {
buf: ^Color, buf: ^Color,
width: uint, width: uint,
height: uint, height: uint,
size: uint,
} }
new_surface := fn(width: uint, height: uint): Surface { new_surface := fn(width: uint, height: uint): Surface {
return .( return .(
memory.alloc(Color, width * height), @inline(memory.alloc, Color, width * height),
width, width,
height, height,
width * height,
) )
} }
clone_surface := fn(surface: ^Surface): Surface { clone_surface := fn(surface: ^Surface): Surface {
new := new_surface(surface.width, surface.height) 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 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") framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
width := dt.get(uint, "framebuffer/fb0/width\0") width := dt.get(uint, "framebuffer/fb0/width\0")
height := dt.get(uint, "framebuffer/fb0/height\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 { if doublebuffer {
return new_surface(width, height) return new_surface(@unwrap(width), @unwrap(height))
} else { } else {
return .(framebuffer, width, height, width * height) return .(@unwrap(framebuffer), @unwrap(width), @unwrap(height))
} }
} }
$clear := fn(surface: Surface, color: Color): void { clear := fn(surface: Surface, color: Color): void {
memory.set(Color, &color, surface.buf, surface.width * surface.height) return @inline(memory.set, Color, &color, surface.buf, surface.width * surface.height)
} }
$sync := fn(surface: Surface): void { sync := fn(surface: Surface): void {
memory.copy(Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height)) // 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 return x + surface.width * y
} }
$indexptr := fn(surface: Surface, x: uint, y: uint): ^Color { indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
return surface.buf + index(surface, x, y) return surface.buf + @inline(index, surface, x, y)
} }
$put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void { put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
return *indexptr(surface, pos.x, pos.y) = color *@inline(indexptr, surface, pos.x, pos.y) = color
return
} }
put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void { put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
top_start_idx := indexptr(surface, pos.x, pos.y) top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
bottom_start_idx := indexptr(surface, pos.x, pos.y + tr.y - 1) bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1)
rows_to_fill := tr.y rows_to_fill := tr.y
loop if rows_to_fill <= 1 break else { loop if rows_to_fill <= 1 break else {
memory.set(Color, &color, top_start_idx, tr.x) @inline(memory.set, Color, &color, top_start_idx, tr.x)
memory.set(Color, &color, bottom_start_idx, tr.x) @inline(memory.set, Color, &color, bottom_start_idx, tr.x)
top_start_idx += surface.width top_start_idx += surface.width
bottom_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 { 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 return
} }
put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void { put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
start_idx := indexptr(surface, pos.x, pos.y) start_idx := @inline(indexptr, surface, pos.x, pos.y)
end_idx := indexptr(surface, pos.x, pos.y + tr.y) end_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y)
right_start_idx := indexptr(surface, pos.x + tr.x, pos.y) right_start_idx := @inline(indexptr, surface, pos.x + tr.x, pos.y)
loop if start_idx > end_idx break else { loop if start_idx > end_idx break else {
*start_idx = color; *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 right_start_idx += surface.width
} }
memory.set(Color, &color, indexptr(surface, pos.x, pos.y), @bitcast(tr.x + 1)) @inline(memory.set, Color, &color, @inline(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 + tr.y), @bitcast(tr.x + 1))
return return
} }
@ -110,7 +140,7 @@ put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Colo
y := p0.y y := p0.y
x := p0.x x := p0.x
loop if x == p1.x break else { loop if x == p1.x break else {
*indexptr(surface, x, y) = color *@inline(indexptr, surface, x, y) = color
if D > 0 { if D > 0 {
y += yi y += yi
D += 2 * (dy - dx) 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 x := p0.x
y := p0.y y := p0.y
loop if y == p1.y break else { loop if y == p1.y break else {
*indexptr(surface, x, y) = color *@inline(indexptr, surface, x, y) = color
if D > 0 { if D > 0 {
x += xi x += xi
D += 2 * (dx - dy) 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 { 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 { if p0.x > p1.x {
@inline(put_line_low, surface, p1, p0, color) @inline(put_line_low, surface, p1, p0, color)
} else { } else {
@ -167,8 +197,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
src_top_cursor := top.buf src_top_cursor := top.buf
src_bottom_cursor := top.buf + top.width * (top.height - 1) src_bottom_cursor := top.buf + top.width * (top.height - 1)
dst_top_idx := indexptr(surface, pos.x, pos.y) dst_top_idx := @inline(indexptr, surface, pos.x, pos.y)
dst_bottom_idx := indexptr(surface, pos.x, pos.y + top.height - 1) dst_bottom_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1)
dst_increment := surface.width 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 rows_to_copy := top.height
loop if rows_to_copy <= 1 break else { loop if rows_to_copy <= 1 break else {
memory.copy(Color, src_top_cursor, dst_top_idx, top.width) @inline(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_bottom_cursor, dst_bottom_idx, top.width)
dst_top_idx += dst_increment dst_top_idx += dst_increment
dst_bottom_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 { 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 return
@ -231,7 +332,7 @@ put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): vo
y := y0 y := y0
loop if y == y1 break else { loop if y == y1 break else {
*indexptr(surface, x, y) = color *@inline(indexptr, surface, x, y) = color
y += 1 y += 1
} }
@ -245,8 +346,7 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
x0 = x1 x0 = x1
x1 = tmp x1 = tmp
} }
// x0 = math.min(x0, x1) @inline(memory.set, Color, &color, @inline(indexptr, surface, x0, y), @bitcast(x1 - x0 - 1))
memory.set(Color, &color, indexptr(surface, x0, y), @bitcast(x1 - x0 - 1))
return 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 { put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
x := 0 x := 0
y := radius y := radius
error := @as(int, 3) - @intcast(2 * radius); error := @as(int, 3) - @as(int, @intcast(2 * radius));
*indexptr(surface, pos.x + radius, pos.y) = color; *@inline(indexptr, surface, pos.x + radius, pos.y) = color;
*indexptr(surface, pos.x - radius, pos.y) = color; *@inline(indexptr, surface, pos.x - radius, pos.y) = color;
*indexptr(surface, pos.x, pos.y + radius) = color; *@inline(indexptr, surface, pos.x, pos.y + radius) = color;
*indexptr(surface, pos.x, pos.y - radius) = color *@inline(indexptr, surface, pos.x, pos.y - radius) = color
loop if y < x break else { loop if y < x break else {
x += 1 x += 1
if error > 0 { if error > 0 {
y -= 1 y -= 1
error += 4 * (@intcast(x) - @intcast(y)) + 10 error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
} else { } else {
error += 4 * @intcast(x) + 6 error += 4 * @intcast(x) + 6
}; };
*indexptr(surface, pos.x + x, pos.y + y) = color; *@inline(indexptr, surface, pos.x + x, pos.y + y) = color;
*indexptr(surface, pos.x + y, pos.y + x) = color; *@inline(indexptr, surface, pos.x + y, pos.y + x) = color;
*indexptr(surface, pos.x - x, pos.y + y) = color; *@inline(indexptr, surface, pos.x - x, pos.y + y) = color;
*indexptr(surface, pos.x - y, pos.y + x) = color; *@inline(indexptr, surface, pos.x - y, pos.y + x) = color;
*indexptr(surface, pos.x + x, pos.y - y) = color; *@inline(indexptr, surface, pos.x + x, pos.y - y) = color;
*indexptr(surface, pos.x + y, pos.y - x) = color; *@inline(indexptr, surface, pos.x + y, pos.y - x) = color;
*indexptr(surface, pos.x - x, pos.y - y) = color; *@inline(indexptr, surface, pos.x - x, pos.y - y) = color;
*indexptr(surface, pos.x - y, pos.y - x) = color *@inline(indexptr, surface, pos.x - y, pos.y - x) = color
} }
return 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 { put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
x := 0 x := 0
y := radius y := radius
error := @as(int, 3) - @intcast(2 * radius) error := @as(int, 3) - @as(int, @intcast(2 * radius))
put_hline(surface, pos.y - x, pos.x - radius, pos.x + radius, color); @inline(put_hline, surface, pos.y - x, pos.x - radius, pos.x + radius, color);
*indexptr(surface, pos.x, pos.y + radius) = color; *@inline(indexptr, surface, pos.x, pos.y + radius) = color;
*indexptr(surface, pos.x, pos.y - radius) = color *@inline(indexptr, surface, pos.x, pos.y - radius) = color
loop if y < x break else { loop if y < x break else {
x += 1 x += 1
if error > 0 { if error > 0 {
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)
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 y -= 1
error += 4 * (@intcast(x) - @intcast(y)) + 10 error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
} else { } else {
error += 4 * @intcast(x) + 6 error += 4 * @intcast(x) + 6
} }
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)
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 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 { put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void {
x := 0 x := 0
y := radius y := radius
error := @as(int, 3) - @intcast(2 * radius) error := @as(int, 3) - @as(int, @intcast(2 * radius))
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y), indexptr(surface, pos.x - y, pos.y), 2 * y); @inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y), @inline(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); *@inline(indexptr, surface, pos.x, pos.y + y) = *@inline(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) *@inline(indexptr, surface, pos.x, pos.y - y) = *@inline(indexptr, source, source_pos.x, source_pos.y - y)
loop if y < x break else { loop if y < x break else {
x += 1 x += 1
if error > 0 { 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) @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)
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)
y -= 1 y -= 1
error += 4 * (@intcast(x) - @intcast(y)) + 10 error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
} else { } else {
error += 4 * @intcast(x) + 6 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) @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)
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)
} }
return return
} }
utf8_len_table := [u8].(0, 0, 2, 3)
put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void { put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
cursor := Vec2(uint).(pos.x, pos.y) 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 str += 1
continue continue
} }
glyph_data = get_glyph(font, *str) glyph_data = @inline(get_glyph, font, *str)
} else { } else {
if *str < UNC_TABLE_SIZE { if *str < UNC_TABLE_SIZE {
glyph_index := *(font.unicode + *str) 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 cursor.y += next_line_y
} }
dest := indexptr(surface, cursor.x, cursor.y) dest := @inline(indexptr, surface, cursor.x, cursor.y)
rows := font.height rows := font.height
loop if rows == 0 break else { loop if rows == 0 break else {

View file

@ -74,16 +74,16 @@ font_from_psf2 := fn(psf: ^u8, unicode: bool): ?Font {
return 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 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 { init_unicode := fn(font: ^Font): void {
font.unicode = memory.alloc(u16, UNC_TABLE_SIZE) 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 table := font.data + font.num_glyphs * font.bytes_per_glyph
curr_glyph := @as(u16, 0) curr_glyph := @as(u16, 0)
@ -121,6 +121,8 @@ init_unicode := fn(font: ^Font): void {
next_byte := *table next_byte := *table
if (next_byte & 0xC0) != 0x80 { if (next_byte & 0xC0) != 0x80 {
valid = false valid = false
}
if valid == false {
break break
} }
unicode = unicode << 6 | next_byte & 0x3F 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") 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)) 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)) 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) 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) return @eca(3, buffer_id, msg, length)
} }
BufferMsg := packed struct {operation: u8, msg: ^u8, msg_len: uint} 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)) return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
} }
$create_nameless := fn(): uint { search := fn(msg: ^u8): int {
return @eca(1, 0)
}
$delete_buffer := fn(buffer_id: uint): void {
return @eca(2, buffer_id)
}
search := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg)) 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") .{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)) return @eca(3, 5, query, @inline(string.length, query))
} }

View file

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

View file

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

View file

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

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 { display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
is_negative := num < 0
if is_negative num = -num
ptr := p 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 { if num == 0 {
*ptr = 0x30; *ptr = 48
*(ptr + 1) = 0 ptr += 1
return p } else {
} loop if num == 0 break else {
digit := num % @bitcast(radix)
loop if num == 0 break else { if digit < 10 {
remainder := num % @bitcast(radix) *ptr = @intcast(digit) + 48
num /= @bitcast(radix); } else {
*ptr = @intcast(remainder + 0x30) *ptr = @intcast(digit) + 55
if remainder > 9 { }
*ptr = @intcast(remainder - 10 + 0x41) ptr += 1
num /= @bitcast(radix)
} }
ptr += 1
} }
if is_negative { if negative {
*ptr = 0x2D *ptr = 45
ptr += 1 ptr += 1
} };
// ! it gets broked when you do this ??
// *ptr = 0 *ptr = 0
@inline(reverse, digits_start)
@inline(reverse, p)
return p return p
} }
reverse := fn(s: ^u8): void { reverse := fn(s: ^u8): void {
j := s + @inline(length, s) - 1 i := 0
j := @inline(length, s) - 1
temp := @as(u8, 0) temp := @as(u8, 0)
loop if s < j { loop if i >= j break else {
temp = *s; temp = *(s + i);
*s = *j; *(s + i) = *(s + j);
*j = temp *(s + j) = temp
s += 1 i += 1
j -= 1 j -= 1
} else return }
return
} }
equals := fn(lhs: ^u8, rhs: ^u8): bool { equals := fn(lhs: ^u8, rhs: ^u8): bool {
if lhs == rhs { if lhs == rhs {
return true return true
} }
loop if *lhs != *rhs { i := 0
loop if *(lhs + i) != *(rhs + i) {
return false return false
} else if *lhs == 0 { } else if *lhs == 0 {
return true return true
} else { } else {
lhs += 1 i += 1
rhs += 1
} }
} }
clear := fn(ptr: ^u8): void { contains := fn(haystack: ^u8, needle: ^u8): bool {
loop if *ptr == 0 break else { haystack_len := @inline(length, haystack)
*ptr = 0 needle_len := @inline(length, needle)
ptr += 1
if needle_len == 0 {
return true
}
if haystack_len < needle_len {
return false
} }
}
split_once := fn(haystack: ^u8, needle: u8): ?^u8 { max_start := haystack_len - needle_len
loop if *haystack == needle return haystack else if *haystack == 0 return null else haystack += 1
}
split_once_str := fn(haystack: ^u8, needle: ^u8): ?^u8 { pos := 0
if *needle == 0 return null loop if pos > max_start break else {
is_match := true
offset := 0
loop if *haystack == 0 return null else { loop if offset >= needle_len break else {
if *haystack == *needle { if *(haystack + pos + offset) != *(needle + offset) {
h := haystack is_match = false
n := needle
loop {
n += 1
h += 1
if *n == 0 {
return haystack
} else if *h == 0 | *h != *n {
break
}
} }
} if is_match == false {
haystack += 1 break
}
}
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
}
} }
offset += 1
} }
haystack += 1
}
}
left_trim := fn(str: ^u8, sub: ^u8): ^u8 { if is_match {
original := str return true
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
} }
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") win_buff := buffer.create("XHorizon\0")
screen := render.init(true) screen := render.init(true)
if screen == null {
log.error("Screen could not be initialized!\0")
return 1
}
// Clear the screen to black. // Clear the screen to black.
render.clear(screen, render.black) render.clear(screen, render.black)
@ -56,13 +60,43 @@ main := fn(): int {
loop { loop {
// Clear the screen // Clear the screen
render.clear(screen, render.black) render.clear(screen, render.black)
render.put_surface(screen, wallpaper, .(0, 0), false) render.put_surface(screen, wallpaper, .(0, 0), false)
// TODO: Read the window buffer here // 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 { if false {
// Scroll bar :ThumbsUp: // Scroll bar :ThumbsUp:
render.put_rect(screen, .(100, 100), .(100, 10), render.white) 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) 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) pos := Vec2(uint).(1, screen.height - 21)
render_label_to_surface(screen, text_label, font, pos) render_label_to_surface(screen, text_label, font, pos)
render.put_rect(screen, .(0, screen.height - 21), .(screen.width - 1, 20), render.white) 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() mouse_event := intouch.recieve_mouse_event()
// //
if mouse_event != null { 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 := @as(i16, mouse_event.x_change)
change_x = change_x << 8 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, .(0, 0), .(screen.width - 1, screen.height - 1), render.white)
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), 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 // 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 # 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!! ## !!Assumptions!!
Anyone who works on this should work to keep this list as small as possible/remove as many of these as possible. 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. - Both PS/2 ports being broken doesn't need handling.
- One PS/2 port being broken doesn't need special attention. - One PS/2 port being broken doesn't need special attention.
- PS/2 controller doesn't need to perform a self-check. - 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"); .{memory, log} := @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)
mouse_buffer := 0 DeviceID := struct {value: u16}
keyboard_buffer := 0
info := Info.(0)
send_command := fn(port: ^Port, byte: u8): void { Mouse3Button := DeviceID.(0x0)
tries := 3 MouseScrollwheel := DeviceID.(0x3)
loop if tries == 0 break else { Mouse5Button := DeviceID.(0x4)
controller.send_byte(port, byte) Spacesaver := DeviceID.(0xAB84)
loop { Keyboard122Key := DeviceID.(0xAB86)
info = controller.get_info() KeyboardJapaneseG := DeviceID.(0xAB90)
if controller.has_input(info) == false { KeyboardJapanesep := DeviceID.(0xAB91)
continue KeyboardJapaneseA := DeviceID.(0xAB92)
} KeyboardNCDSun := DeviceID.(0xACA1)
input := controller.get_input() NoDevice := DeviceID.(0xFFFF)
if controller.get_port(info) != port {
if check_complete(port) == false { Port := struct {exists: bool, device: DeviceID, command_queued: bool, command_queue: u8}
port.packet[port.packet_length] = input
port.packet_length += 1 check_bit := fn(value: u8, bit: u8, state: u8): bool {
} return value >> bit & 1 == state
continue }
}
if input == 0xFA { ports := [Port].(.(true, NoDevice, false, 0xFF), .(true, NoDevice, false, 0xFF))
return
} else { initialize_controller := fn(): void {
break memory.outb(0x64, 0xAD)
} memory.outb(0x64, 0xA7)
} //Disables ports to make sure that they won't interfere with the setup process.
tries -= 1
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 { handle_input := fn(port: uint, input: u8): 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
} }
main := fn(): 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 { loop {
info = controller.get_info() port_info := memory.inb(0x64)
//Enables port 1.
if controller.timed_out(info) { if (port_info & 0x40) > 0 {
log.error("Timeout error! Cannot handle these!\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") log.error("Parity error! Cannot handle these!\0")
} }
/*
if controller.has_input(info) { if (port_info & 1) == 0 {
port := controller.get_port(info) if ports[0].exists & ports[0].command_queued {
if port.packet_length > 0 & check_complete(port) { memory.outb(0x60, ports[0].command_queue)
process(port) ports[0].command_queued = false
} }
input := controller.get_input() if ports[1].exists & ports[1].command_queued {
/*if input == 0xAA & port.can_hot_plug { memory.outb(0x64, 0xD4)
port.device = devices.NO_DEVICE memory.outb(0x60, ports[1].command_queue)
controller.send_byte(port, 0xF4) ports[1].command_queued = false
}*/
port.packet[port.packet_length] = input
port.packet_length += 1
if check_complete(port) {
process(port)
port.packet_length = 0
} }
}*/ }
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} := @use("../../../libraries/stn/src/lib.hb")
.{memory, log, buffer} := stn
intouch := @use("../../../libraries/intouch/src/lib.hb");
.{KeyEvent} := intouch
send_byte := fn(byte: u8): u8 { send_byte := fn(byte: u8): u8 {
memory.outb(96, byte) memory.outb(96, byte)
@ -10,31 +6,23 @@ send_byte := fn(byte: u8): u8 {
} }
main := fn(): int { main := fn(): int {
buf := buffer.create("PS/2 Keyboard\0") buf := buffer.create("XKeyboard\0")
_ = send_byte(238) _ = send_byte(238)
log.info("PS/2 Driver Loaded\0") log.info("PS/2 Driver Loaded\0")
if send_byte(238) == 238 { if send_byte(238) == 238 {
log.info("PS/2 Keyboard Echoed\0") log.info("PS/2 Keyboard Echoed\0")
} }
if send_byte(244) == 250 { if send_byte(244) == 250 {
log.info("Enabled scanning\0") log.info("Enabled scanning\0")
} }
prev_input := 250 prev_input := 250
loop { loop {
loop if (memory.inb(0x64) & 0x20) == 0x20 break
input := memory.inb(96) input := memory.inb(96)
if input == prev_input { if input == prev_input {
continue continue
} }
prev_input = input prev_input = input
kevent := KeyEvent.(false, true, input) buffer.write(u8, &input, buf)
buffer.write(KeyEvent, buf, &kevent)
} }
return 0 return 0
} }

View file

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

View file

@ -10,12 +10,12 @@ example := fn(): void {
color := render.light_cyan color := render.light_cyan
n := @as(u8, 1) n := @as(u8, 1)
loop { loop {
// ! dead code elimination bug
render.clear(screen, color) render.clear(screen, color)
render.sync(screen) render.sync(screen)
if color.b == 255 | color.b == 0 { if (color.b & 255) == 255 | (color.b & 255) == 0 {
n = -n n = -n
} }
color.b += 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 bottom := buf + msg_len
memory.copy(u8, msg, buf, msg_len) @inline(memory.copy, u8, msg, buf, msg_len)
cursor := bottom cursor := bottom
draw_window(window, font, buf, cursor) 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 default_entry = 1
timeout = 0 timeout = 0
verbose = false verbose = false
# interface_resolution = "1920x1080x24" interface_resolution = "1600x900x24"
interface_resolution = "1024x768x24" # interface_resolution = "640x480x32"
# interface_resolution = "640x480x24"
# Terminal related settings # Terminal related settings
# term_wallpaper = "boot:///background.bmp" # term_wallpaper = "boot:///background.bmp"
term_wallpaper = "boot:///empty-background.bmp" term_wallpaper = "boot:///empty-background.bmp"
@ -16,29 +15,53 @@ comment = "Default AbleOS boot entry."
protocol = "limine" protocol = "limine"
kernel_path = "boot:///kernel_${ARCH}" kernel_path = "boot:///kernel_${ARCH}"
kernel_cmdline = "" kernel_cmdline = ""
# resolution = "1920x1080x24" # resolution = "640x480x32"
resolution = "1024x768x24" resolution = "1600x900x24"
# resolution = "640x480x24"
[boot.limine.ableos.modules] [boot.limine.ableos.modules]
# [boot.limine.ableos.modules.render_example] # [boot.limine.ableos.modules.render_example]
# path = "boot:///render_example.hbf" # path = "boot:///render_example.hbf"
# [boot.limine.ableos.modules.horizon] # [boot.limine.ableos.modules.mouse_driver]
# path = "boot:///horizon.hbf" # path = "boot:///mouse_driver.hbf"
# [boot.limine.ableos.modules.ps2_mouse_driver] # [boot.limine.ableos.modules.serial_driver]
# path = "boot:///ps2_mouse_driver.hbf" # 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] # [boot.limine.ableos.modules.ps2_keyboard_driver]
# path = "boot:///ps2_keyboard_driver.hbf" # path = "boot:///ps2_keyboard_driver.hbf"
[boot.limine.ableos.modules.ps2_driver] # [boot.limine.ableos.modules.filesystem_fat32]
path = "boot:///ps2_driver.hbf" # [boot.limine.ableos.modules.ps2_keyboard_driv
# path = "boot:///filesystem_fat32.hbf"
# [boot.limine.ableos.modules.sunset_client] # [boot.limine.ableos.modules.pumpkin_print]
# path = "boot:///sunset_client.hbf" # path = "boot:///pumpkin_print.hbf"
# [boot.limine.ableos.modules.sunset_server] [boot.limine.ableos.modules.ps2_mouse_driver]
# path = "boot:///sunset_server.hbf" 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)