forked from AbleOS/ableos
Compare commits
43 commits
Author | SHA1 | Date | |
---|---|---|---|
peony | 2d2bec803f | ||
peony | 388d8c8c20 | ||
peony | 5c131eae13 | ||
peony | 7f920e2f65 | ||
peony | 97f7aa49f7 | ||
peony | 52b6272439 | ||
peony | d764dc9dd6 | ||
peony | d0f078cf10 | ||
peony | daced693fa | ||
peony | 2b13242f7f | ||
peony | d154c9fab1 | ||
peony | f31d35703d | ||
peony | e670a0ef53 | ||
peony | 376a5213ac | ||
peony | 552b613151 | ||
peony | 5a44a707eb | ||
peony | f52e3979a2 | ||
peony | e3ec34684f | ||
peony | d19f15aa5c | ||
peony | 9e0a508a6f | ||
peony | 20bb741bf1 | ||
peony | a95f1b5a4b | ||
peony | e6b972a7f3 | ||
peony | 4a0f65753e | ||
peony | d143acb8b6 | ||
peony | f65f04460b | ||
peony | 223a1c15ad | ||
peony | fe85a91548 | ||
peony | f5ffed5662 | ||
peony | 382a4f5510 | ||
peony | f023773b2e | ||
peony | b7d668c83a | ||
peony | 92bf9207b3 | ||
peony | 0da9467a0f | ||
peony | f6dd752b77 | ||
peony | 851e0bd94a | ||
peony | 38c6f6cf47 | ||
peony | 1c9ca8962e | ||
peony | 8d36083729 | ||
peony | ad351155da | ||
peony | 1039db1247 | ||
peony | fbdf737306 | ||
peony | 15c978f90f |
126
Cargo.lock
generated
126
Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aarch64-cpu"
|
||||
|
@ -13,9 +13,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.20"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
|
||||
checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f"
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
|
@ -65,6 +65,15 @@ version = "2.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
@ -73,9 +82,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.1"
|
||||
version = "1.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
@ -199,6 +208,12 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.1"
|
||||
|
@ -213,23 +228,24 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#86ca959ea3eae1cb32298e135a444820583d24a0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
|
||||
|
||||
[[package]]
|
||||
name = "hblang"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#86ca959ea3eae1cb32298e135a444820583d24a0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.15.1",
|
||||
"hbbytecode",
|
||||
"hbvm",
|
||||
"log",
|
||||
"regalloc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hbvm"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#86ca959ea3eae1cb32298e135a444820583d24a0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
|
||||
dependencies = [
|
||||
"hbbytecode",
|
||||
]
|
||||
|
@ -380,7 +396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"hashbrown 0.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -390,9 +406,8 @@ dependencies = [
|
|||
"aarch64-cpu",
|
||||
"crossbeam-queue",
|
||||
"derive_more",
|
||||
"hashbrown",
|
||||
"hashbrown 0.15.1",
|
||||
"hbvm",
|
||||
"ktest_macro",
|
||||
"limine",
|
||||
"log",
|
||||
"sbi",
|
||||
|
@ -405,14 +420,6 @@ dependencies = [
|
|||
"xml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ktest_macro"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
@ -421,9 +428,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.164"
|
||||
version = "0.2.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
|
||||
[[package]]
|
||||
name = "limine"
|
||||
|
@ -433,9 +440,9 @@ checksum = "02034f8f6b3e7bf050f310fbaf6db0018b8e54b75598d0a4c97172054752fede"
|
|||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.7.4"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
||||
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -512,9 +519,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -546,6 +553,19 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regalloc2"
|
||||
version = "0.10.2"
|
||||
source = "git+https://github.com/jakubDoka/regalloc2?branch=reuse-allocations#21c43e3ee182824e92e2b25f1d3c03ed47f9c02b"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"bumpalo",
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
|
@ -582,6 +602,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
|
@ -593,9 +619,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.18"
|
||||
version = "0.23.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f"
|
||||
checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
|
@ -649,18 +675,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.215"
|
||||
version = "1.0.214"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
|
||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.215"
|
||||
version = "1.0.214"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
|
||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -726,9 +752,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.89"
|
||||
version = "2.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
|
||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -798,9 +824,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uart_16550"
|
||||
version = "0.3.2"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e492212ac378a5e00da953718dafb1340d9fbaf4f27d6f3c5cab03d931d1c049"
|
||||
checksum = "4922792855b1bce30997fbaa5418597902c278a92d20dfe348e6f062c3bd861d"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"rustversion",
|
||||
|
@ -809,9 +835,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
|
@ -842,9 +868,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.4"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
|
||||
checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
|
@ -885,9 +911,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.7"
|
||||
version = "0.26.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e"
|
||||
checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
@ -1044,9 +1070,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.7.5"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
|
||||
checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
|
@ -1056,9 +1082,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.7.5"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
||||
checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1068,18 +1094,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.5"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
|
||||
checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
|
||||
dependencies = [
|
||||
"zerofrom-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom-derive"
|
||||
version = "0.1.5"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
|
||||
checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
96
flake.lock
96
flake.lock
|
@ -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
|
||||
}
|
30
flake.nix
30
flake.nix
|
@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
|
@ -3,15 +3,12 @@ edition = "2021"
|
|||
name = "kernel"
|
||||
version = "0.2.0"
|
||||
|
||||
[features]
|
||||
ktest = []
|
||||
|
||||
[dependencies]
|
||||
# embedded-graphics = "0.8"
|
||||
hbvm = { git = "https://git.ablecorp.us/AbleOS/holey-bytes.git", features = [
|
||||
"nightly",
|
||||
] }
|
||||
ktest_macro = { path = "ktest_macro" }
|
||||
log = "0.4"
|
||||
spin = "0.9"
|
||||
slab = { version = "0.4", default-features = false }
|
||||
|
|
|
@ -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"] }
|
|
@ -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)
|
||||
}
|
|
@ -38,15 +38,7 @@ SECTIONS
|
|||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
*(.got .got.*)
|
||||
} :data
|
||||
|
||||
/* Add the .ktest section for test functions */
|
||||
.note.ktest : {
|
||||
__ktest_start = .; /* Mark the beginning of the section */
|
||||
*(.note.ktest) /* Include all items in the .ktest section */
|
||||
__ktest_end = .; /* Mark the end of the section */
|
||||
}
|
||||
|
||||
.bss : {
|
||||
*(COMMON)
|
||||
|
|
|
@ -14,29 +14,3 @@ arch_cond!(
|
|||
riscv64: "riscv64",
|
||||
x86_64: "x86_64",
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use {crate::arch::interrupts::Interrupt, alloc::string::String};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub struct InterruptList {
|
||||
list: HashMap<Interrupt, String>,
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use hashbrown::HashMap;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
impl InterruptList {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
list: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use spin::{Lazy, Mutex};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub static INTERRUPT_LIST: Lazy<Mutex<InterruptList>> = Lazy::new(|| {
|
||||
let mut il = InterruptList::new();
|
||||
use crate::alloc::string::ToString;
|
||||
il.list.insert(Interrupt::Timer, "PS/2 Mouse".to_string());
|
||||
Mutex::new(il)
|
||||
});
|
||||
|
|
|
@ -11,9 +11,7 @@ static mut LAPIC: LocalApic = unsafe { MaybeUninit::zeroed().assume_init() };
|
|||
static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Eq, Hash, PartialEq)]
|
||||
|
||||
pub enum Interrupt {
|
||||
enum Interrupt {
|
||||
Timer = 32,
|
||||
ApicErr = u8::MAX - 1,
|
||||
Spurious = u8::MAX,
|
||||
|
@ -62,49 +60,17 @@ extern "x86-interrupt" fn page_fault(
|
|||
}
|
||||
|
||||
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
|
||||
// interrupt(Interrupt::Timer);
|
||||
|
||||
unsafe {
|
||||
LAPIC.end_of_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
|
||||
interrupt(Interrupt::ApicErr);
|
||||
|
||||
panic!("Internal APIC error");
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
|
||||
interrupt(Interrupt::Spurious);
|
||||
|
||||
unsafe {
|
||||
LAPIC.end_of_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
fn interrupt(interrupt_type: Interrupt) {
|
||||
use crate::arch::INTERRUPT_LIST;
|
||||
let il = INTERRUPT_LIST.lock();
|
||||
let val = il.list.get(&interrupt_type).unwrap();
|
||||
|
||||
use crate::holeybytes::kernel_services::service_definition_service::sds_search_service;
|
||||
let buffer = sds_search_service(val);
|
||||
if buffer != 0 {
|
||||
use {crate::kmain::IPC_BUFFERS, alloc::vec::Vec};
|
||||
let mut buffs = IPC_BUFFERS.lock();
|
||||
match buffs.get_mut(&buffer) {
|
||||
Some(buff) => {
|
||||
let mut msg_vec = Vec::new();
|
||||
msg_vec.push(0xFF);
|
||||
buff.push(msg_vec.to_vec());
|
||||
log::debug!("Sent Message {:?} to Buffer({})", msg_vec, buffer);
|
||||
}
|
||||
None => {
|
||||
log::error!("Access of non-existent buffer {}", buffer)
|
||||
}
|
||||
}
|
||||
|
||||
// log::info!("{}", buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ const INITIAL_KERNEL_HEAP_SIZE: *const () = _initial_kernel_heap_size as _;
|
|||
#[cfg(not(target_feature = "avx2"))]
|
||||
unsafe extern "C" fn _kernel_start() -> ! {
|
||||
// Initialise SSE, then jump to kernel entrypoint
|
||||
core::arch::naked_asm!(
|
||||
core::arch::asm!(
|
||||
// Initialise SSE
|
||||
"mov rax, cr0",
|
||||
"and ax, 0xfffb",
|
||||
|
@ -46,6 +46,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
|||
// Jump to the kernel entry point
|
||||
"jmp {}",
|
||||
sym start,
|
||||
options(noreturn),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -53,7 +54,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
|||
#[naked]
|
||||
#[cfg(target_feature = "avx2")]
|
||||
unsafe extern "C" fn _kernel_start() -> ! {
|
||||
core::arch::naked_asm!(
|
||||
core::arch::asm!(
|
||||
// Enable protected mode and configure control registers
|
||||
"mov rax, cr0",
|
||||
"and ax, 0xFFFB", // Clear CR0.EM (bit 2) for coprocessor emulation
|
||||
|
@ -99,6 +100,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
|||
"jmp {0}",
|
||||
sym start,
|
||||
sym oops,
|
||||
options(noreturn),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -109,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
|
|||
unsafe extern "C" fn start() -> ! {
|
||||
logging::init();
|
||||
crate::logger::init().expect("failed to set logger");
|
||||
log::debug!("Initialising AKern {}", crate::VERSION);
|
||||
log::info!("Initialising AKern {}", crate::VERSION);
|
||||
|
||||
static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
|
||||
memory::init_pt(VirtAddr::new(
|
||||
|
@ -188,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
|
|||
// TODO: Add in rdseed and rdrand as sources for randomness
|
||||
let _rand = xml::XMLElement::new("Random");
|
||||
|
||||
log::debug!("Getting boot modules");
|
||||
log::trace!("Getting boot modules");
|
||||
let bm = MOD_REQ.get_response().get();
|
||||
|
||||
let mut bootmodules = alloc::vec::Vec::new();
|
||||
|
@ -226,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
|
|||
break;
|
||||
}
|
||||
}
|
||||
log::debug!("Boot module count: {:?}", bootmodules.len());
|
||||
log::info!("Boot module count: {:?}", bootmodules.len());
|
||||
assert_eq!(bm.module_count, bootmodules.len() as u64);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ pub fn check_device(bus: u8, device: u8) -> Option<PciDeviceInfo> {
|
|||
}
|
||||
|
||||
let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) };
|
||||
log::debug!("pci device-({}) addr {} is {}", device, addr, reg2);
|
||||
log::info!("pci device-({}) addr {} is {}", device, addr, reg2);
|
||||
let class = ((reg2 >> 16) & 0x0000_FFFF) as u16;
|
||||
let pci_class = PciFullClass::from_u16(class);
|
||||
let header_type = get_header_type(bus, device, 0);
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
//! Environment call handling routines
|
||||
|
||||
use {alloc::boxed::Box, core::cell::LazyCell, hbvm::mem::Address};
|
||||
|
||||
use crate::{
|
||||
holeybytes::{
|
||||
kernel_services::{
|
||||
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
|
||||
service_definition_service::sds_msg_handler,
|
||||
},
|
||||
ExecThread,
|
||||
},
|
||||
kmain::EXECUTOR,
|
||||
task::Executor,
|
||||
use crate::holeybytes::kernel_services::{
|
||||
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
|
||||
service_definition_service::sds_msg_handler,
|
||||
};
|
||||
|
||||
use {
|
||||
|
@ -67,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
|
|||
true => IpcBuffer::new(true, length),
|
||||
},
|
||||
);
|
||||
info!("Buffer ID: {}", buff_id);
|
||||
vm.registers[1] = hbvm::value::Value(buff_id);
|
||||
}
|
||||
2 => {
|
||||
log::error!("Oops, deleting buffers is not implemented.")
|
||||
// Delete buffer
|
||||
}
|
||||
3 => {
|
||||
|
@ -152,43 +143,6 @@ pub fn handler(vm: &mut Vm) {
|
|||
Ok(()) => {}
|
||||
Err(_) => log::error!("Improper dt query"),
|
||||
},
|
||||
6 => unsafe {
|
||||
let program = block_read(mem_addr, length);
|
||||
|
||||
// decode AbleOS Executable format
|
||||
let header = &program[0..46];
|
||||
let magic_slice = &header[0..3];
|
||||
if magic_slice != [0x15, 0x91, 0xD2] {
|
||||
log::error!("Invalid magic number at the start of executable.");
|
||||
return;
|
||||
}
|
||||
|
||||
let executable_format_version =
|
||||
u32::from_le_bytes(header[3..7].try_into().unwrap());
|
||||
let offset = if executable_format_version == 0 {
|
||||
47
|
||||
} else {
|
||||
error!("Invalid executable format.");
|
||||
return;
|
||||
};
|
||||
|
||||
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
|
||||
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
|
||||
let end = (code_length + data_length) as usize;
|
||||
log::debug!("{code_length} + {data_length} = {end}");
|
||||
|
||||
let thr = ExecThread::new(&program[offset..end], Address::new(0));
|
||||
vm.registers[1] = Value(
|
||||
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
|
||||
.unwrap()
|
||||
.spawn(Box::pin(async move {
|
||||
if let Err(e) = thr.await {
|
||||
log::error!("{e:?}");
|
||||
}
|
||||
})) as u64,
|
||||
);
|
||||
log::debug!("spawned a process");
|
||||
},
|
||||
|
||||
buffer_id => {
|
||||
let mut buffs = IPC_BUFFERS.lock();
|
||||
|
@ -228,7 +182,7 @@ pub fn handler(vm: &mut Vm) {
|
|||
} else {
|
||||
unsafe {
|
||||
let ptr = map_ptr as *mut u8;
|
||||
ptr.copy_from_nonoverlapping(msg.as_ptr(), msg.len());
|
||||
ptr.copy_from(msg.as_ptr(), msg.len());
|
||||
}
|
||||
|
||||
debug!("Recieve {:?} from Buffer({})", msg, buffer_id);
|
||||
|
|
|
@ -9,20 +9,7 @@ use log::Record;
|
|||
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
||||
let msg_vec = block_read(mem_addr, length);
|
||||
|
||||
use log::Level::*;
|
||||
let log_level = match msg_vec[0] {
|
||||
0 | 48 => Error,
|
||||
1 | 49 => Warn,
|
||||
2 | 50 => Info,
|
||||
3 | 51 => Debug,
|
||||
4 | 52 => Trace,
|
||||
_ => {
|
||||
return Err(LogError::InvalidLogFormat);
|
||||
}
|
||||
};
|
||||
if log_level > log::max_level() {
|
||||
return Ok(());
|
||||
}
|
||||
let log_level = msg_vec[0];
|
||||
let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap());
|
||||
let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize;
|
||||
|
||||
|
@ -33,6 +20,18 @@ pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(),
|
|||
|
||||
match core::str::from_utf8(&str) {
|
||||
Ok(strr) => {
|
||||
use log::Level::*;
|
||||
let log_level = match log_level {
|
||||
0 | 48 => Error,
|
||||
1 | 49 => Warn,
|
||||
2 | 50 => Info,
|
||||
3 | 51 => Debug,
|
||||
4 | 52 => Trace,
|
||||
_ => {
|
||||
return Err(LogError::InvalidLogFormat);
|
||||
}
|
||||
};
|
||||
|
||||
log::logger().log(
|
||||
&Record::builder()
|
||||
.args(format_args!("{}", strr))
|
||||
|
|
|
@ -25,16 +25,42 @@ fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryS
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn memset(dest: *mut u8, src: *const u8, count: usize, size: usize) {
|
||||
let total_size = count * size;
|
||||
src.copy_to_nonoverlapping(dest, size);
|
||||
unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
let mut remaining = count * size;
|
||||
|
||||
let mut copied = size;
|
||||
if remaining < 16 {
|
||||
src.copy_to_nonoverlapping(dest, remaining);
|
||||
return;
|
||||
}
|
||||
|
||||
while copied < total_size {
|
||||
let copy_size = copied.min(total_size - copied);
|
||||
dest.add(copied).copy_from_nonoverlapping(dest, copy_size);
|
||||
copied += copy_size;
|
||||
let mut buffer = [0u8; BLOCK_SIZE];
|
||||
let mut buffer_size = size;
|
||||
src.copy_to_nonoverlapping(buffer.as_mut_ptr(), size);
|
||||
|
||||
while core::intrinsics::likely(buffer_size * 2 <= BLOCK_SIZE) {
|
||||
buffer
|
||||
.as_mut_ptr()
|
||||
.copy_to_nonoverlapping(buffer.as_mut_ptr().add(buffer_size), buffer_size);
|
||||
buffer_size *= 2;
|
||||
}
|
||||
|
||||
let buffer_ptr = buffer.as_ptr() as *const u64;
|
||||
|
||||
while (dest as usize) & 7 != 0 && remaining >= 8 {
|
||||
buffer.as_ptr().copy_to_nonoverlapping(dest, 1);
|
||||
dest = dest.add(1);
|
||||
remaining -= 1;
|
||||
}
|
||||
|
||||
while core::intrinsics::likely(remaining >= 8) {
|
||||
*(dest as *mut u64) = *buffer_ptr;
|
||||
dest = dest.add(8);
|
||||
remaining -= 8;
|
||||
}
|
||||
|
||||
if remaining > 0 {
|
||||
buffer.as_ptr().copy_to_nonoverlapping(dest, remaining);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,8 @@ fn sds_create_service(protocol: &'static str) -> u64 {
|
|||
// let a: protocol::Protocol = protocol.into();
|
||||
buff_id
|
||||
}
|
||||
pub fn sds_search_service(protocol: &str) -> u64 {
|
||||
|
||||
fn sds_search_service(protocol: &str) -> u64 {
|
||||
let services = SERVICES.lock();
|
||||
let compare = Protocol::from(protocol);
|
||||
for (bid, protocol_canidate) in &services.0 {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
mod ecah;
|
||||
pub mod kernel_services;
|
||||
mod kernel_services;
|
||||
mod mem;
|
||||
|
||||
use {
|
||||
|
|
|
@ -8,10 +8,7 @@ use {
|
|||
device_tree::DeviceTree,
|
||||
holeybytes::ExecThread,
|
||||
ipc::buffer::IpcBuffer,
|
||||
task::Executor,
|
||||
},
|
||||
alloc::boxed::Box,
|
||||
core::cell::LazyCell,
|
||||
hashbrown::HashMap,
|
||||
hbvm::mem::Address,
|
||||
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
|
||||
|
@ -22,14 +19,6 @@ use {
|
|||
pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||
debug!("Entered kmain");
|
||||
|
||||
#[cfg(feature = "ktest")] {
|
||||
use crate::ktest;
|
||||
debug!("TESTING");
|
||||
ktest::test_main();
|
||||
|
||||
loop {};
|
||||
}
|
||||
|
||||
// let kcmd = build_cmd("Kernel Command Line", cmdline);
|
||||
// trace!("Cmdline: {kcmd:?}");
|
||||
|
||||
|
@ -76,24 +65,13 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
|||
fb1.address.as_ptr().unwrap() as *const u8
|
||||
);
|
||||
|
||||
let mut executor = crate::task::Executor::new(256);
|
||||
unsafe {
|
||||
let executor = LazyCell::<Executor>::force_mut(&mut EXECUTOR);
|
||||
for module in boot_modules.iter() {
|
||||
let cmd = module.cmd.trim_matches('"');
|
||||
let cmd_len = cmd.len() as u64;
|
||||
|
||||
log::info!(
|
||||
"Starting {}",
|
||||
module
|
||||
.path
|
||||
.split('/')
|
||||
.last()
|
||||
.unwrap()
|
||||
.split('.')
|
||||
.next()
|
||||
.unwrap()
|
||||
);
|
||||
log::debug!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
||||
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
||||
|
||||
// decode AbleOS Executable format
|
||||
let header = &module.bytes[0..46];
|
||||
|
@ -114,17 +92,17 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
|||
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
|
||||
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
|
||||
let end = (code_length + data_length) as usize;
|
||||
log::debug!("{code_length} + {data_length} = {end}");
|
||||
log::info!("{code_length} + {data_length} = {end}");
|
||||
|
||||
let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0));
|
||||
if cmd_len > 0 {
|
||||
thr.set_arguments(cmd.as_ptr() as u64, cmd_len);
|
||||
}
|
||||
executor.spawn(Box::pin(async move {
|
||||
executor.spawn(async move {
|
||||
if let Err(e) = thr.await {
|
||||
log::error!("{e:?}");
|
||||
}
|
||||
}));
|
||||
})
|
||||
}
|
||||
|
||||
debug!("Random number: {}", hardware_random_u64());
|
||||
|
@ -135,10 +113,6 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
|||
crate::arch::spin_loop()
|
||||
}
|
||||
|
||||
// ! SAFETY: this is not threadsafe at all, like even a little bit.
|
||||
// ! SERIOUSLY
|
||||
pub static mut EXECUTOR: LazyCell<Executor> = LazyCell::new(|| Executor::new());
|
||||
|
||||
pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
|
||||
let dt = DeviceTree::new();
|
||||
Mutex::new(dt)
|
||||
|
@ -156,3 +130,10 @@ pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
|
|||
|
||||
Mutex::new(bufs)
|
||||
});
|
||||
|
||||
#[test_case]
|
||||
fn trivial_assertion() {
|
||||
trace!("trivial assertion... ");
|
||||
assert_eq!(1, 1);
|
||||
info!("[ok]");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -2,19 +2,20 @@
|
|||
//! Named akern.
|
||||
//! Akern is woefully undersupported at the moment but we are looking to add support improve hardware discovery and make our lives as kernel and operating system developers easier and better
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(
|
||||
slice_split_once,
|
||||
exclusive_wrapper,
|
||||
new_uninit,
|
||||
core_intrinsics,
|
||||
abi_x86_interrupt,
|
||||
lazy_get,
|
||||
alloc_error_handler,
|
||||
ptr_sub_ptr,
|
||||
custom_test_frameworks,
|
||||
naked_functions,
|
||||
pointer_is_aligned_to,
|
||||
pointer_is_aligned_to
|
||||
)]
|
||||
#![allow(dead_code, internal_features, static_mut_refs)]
|
||||
#![test_runner(crate::test_runner)]
|
||||
#![allow(dead_code, internal_features)]
|
||||
extern crate alloc;
|
||||
|
||||
mod allocator;
|
||||
|
@ -32,10 +33,6 @@ mod memory;
|
|||
mod task;
|
||||
mod utils;
|
||||
|
||||
// #[cfg(feature = "tests")]
|
||||
mod ktest;
|
||||
|
||||
use alloc::string::ToString;
|
||||
use versioning::Version;
|
||||
|
||||
/// Kernel's version
|
||||
|
@ -59,7 +56,15 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
|
|||
));
|
||||
}
|
||||
|
||||
let msg = info.message().to_string().replace("\n", "\r\n");
|
||||
let msg = info.message();
|
||||
let _ = crate::arch::log(format_args!("{msg}\r\n"));
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn test_runner(tests: &[&dyn Fn()]) {
|
||||
println!("Running {} tests", tests.len());
|
||||
for test in tests {
|
||||
test();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,24 +29,24 @@ pub fn yield_now() -> impl Future<Output = ()> {
|
|||
YieldNow(false)
|
||||
}
|
||||
|
||||
pub struct Executor {
|
||||
tasks: Slab<Task>,
|
||||
pub struct Executor<F: Future<Output = ()> + Send> {
|
||||
tasks: Slab<Task<F>>,
|
||||
task_queue: Arc<TaskQueue>,
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
pub fn new() -> Self {
|
||||
impl<F: Future<Output = ()> + Send> Executor<F> {
|
||||
pub fn new(size: usize) -> Self {
|
||||
Self {
|
||||
tasks: Slab::new(),
|
||||
tasks: Slab::with_capacity(size),
|
||||
task_queue: Arc::new(TaskQueue::new()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) -> usize {
|
||||
let id = self.tasks.insert(Task::new(future));
|
||||
self.task_queue.queue.push(id);
|
||||
id
|
||||
pub fn spawn(&mut self, future: F) {
|
||||
self.task_queue
|
||||
.queue
|
||||
.push(self.tasks.insert(Task::new(future)));
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
|
@ -83,17 +83,17 @@ impl Executor {
|
|||
}
|
||||
}
|
||||
|
||||
struct Task {
|
||||
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
||||
struct Task<F: Future<Output = ()> + Send> {
|
||||
future: Pin<Box<F>>,
|
||||
waker: Option<TaskWaker>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
impl<F: Future<Output = ()> + Send> Task<F> {
|
||||
#[inline(always)]
|
||||
pub fn new(future: Pin<Box<dyn Future<Output = ()> + Send>>) -> Self {
|
||||
pub fn new(future: F) -> Self {
|
||||
Self {
|
||||
future,
|
||||
waker: None,
|
||||
future: Box::pin(future),
|
||||
waker: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"arch": "aarch64",
|
||||
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
|
||||
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
|
||||
"disable-redzone": true,
|
||||
"env": "",
|
||||
"executables": true,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#![allow(unused)]
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::format,
|
||||
fs::{read_to_string, File},
|
||||
io::{BufWriter, Write},
|
||||
|
@ -14,7 +13,6 @@ pub struct Package {
|
|||
name: String,
|
||||
binaries: Vec<String>,
|
||||
build_cmd: String,
|
||||
args: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
|
@ -48,46 +46,36 @@ impl Package {
|
|||
let mut binaries = vec![];
|
||||
|
||||
for (count, (name, table)) in bin_table.into_iter().enumerate() {
|
||||
// if count != 0 {
|
||||
binaries.push(name.clone());
|
||||
// }
|
||||
}
|
||||
let build_table = data.get("build").unwrap();
|
||||
|
||||
let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into();
|
||||
build_cmd.remove(0);
|
||||
let mut args: HashMap<String, String> = match build_table.get("args") {
|
||||
None => HashMap::new(),
|
||||
Some(v) => v
|
||||
.as_table()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.clone(), v.to_string()))
|
||||
.collect::<HashMap<String, String>>(),
|
||||
};
|
||||
// build_cmd.pop();
|
||||
|
||||
Self {
|
||||
name,
|
||||
binaries,
|
||||
build_cmd,
|
||||
args,
|
||||
}
|
||||
}
|
||||
pub fn build(&self, out: &mut Vec<u8>) -> std::io::Result<()> {
|
||||
if self.binaries.contains(&"hblang".to_string()) {
|
||||
let file = self.build_cmd.split_ascii_whitespace().last().unwrap();
|
||||
|
||||
let path = format!("sysdata/programs/{}/{}", self.name, file);
|
||||
// compile here
|
||||
|
||||
let mut warnings = String::new();
|
||||
|
||||
hblang::run_compiler(
|
||||
&path,
|
||||
Options {
|
||||
fmt: true,
|
||||
in_house_regalloc: true,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
&mut warnings,
|
||||
)?;
|
||||
|
||||
match std::fs::create_dir("target/programs") {
|
||||
|
@ -99,11 +87,9 @@ impl Package {
|
|||
hblang::run_compiler(
|
||||
&path,
|
||||
Options {
|
||||
in_house_regalloc: true,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
&mut warnings,
|
||||
)?;
|
||||
std::fs::write(format!("target/programs/{}.hbf", self.name), &out)?;
|
||||
out.clear();
|
||||
|
@ -112,11 +98,9 @@ impl Package {
|
|||
&path,
|
||||
Options {
|
||||
dump_asm: true,
|
||||
in_house_regalloc: true,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
&mut warnings,
|
||||
)?;
|
||||
std::fs::write(format!("target/programs/{}.hba", self.name), &out)?;
|
||||
out.clear();
|
||||
|
|
|
@ -27,7 +27,6 @@ fn main() -> Result<(), Error> {
|
|||
let mut release = false;
|
||||
let mut debuginfo = false;
|
||||
let mut target = Target::X86_64;
|
||||
let mut tests = false;
|
||||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
|
@ -39,42 +38,17 @@ fn main() -> Result<(), Error> {
|
|||
target = Target::Aarch64;
|
||||
} else if arg == "avx2" {
|
||||
target = Target::X86_64Avx2;
|
||||
} else if arg == "--ktest" {
|
||||
tests = true;
|
||||
} else {
|
||||
return Err(report!(Error::InvalidSubCom));
|
||||
}
|
||||
}
|
||||
|
||||
build(release, target, debuginfo, tests).change_context(Error::Build)
|
||||
build(release, target, debuginfo).change_context(Error::Build)
|
||||
}
|
||||
// Some("test" | "t") => {
|
||||
// let mut release = false;
|
||||
// let mut debuginfo = false;
|
||||
// let mut target = Target::X86_64;
|
||||
// for arg in args {
|
||||
// if arg == "-r" || arg == "--release" {
|
||||
// release = true;
|
||||
// } else if arg == "-d" || arg == "--debuginfo" {
|
||||
// debuginfo = true;
|
||||
// } else if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
// target = Target::Riscv64Virt;
|
||||
// } else if arg == "arm64" || arg == "aarch64" || arg == "aarch64-virt" {
|
||||
// target = Target::Aarch64;
|
||||
// } else if arg == "avx2" {
|
||||
// target = Target::X86_64Avx2;
|
||||
// } else {
|
||||
// return Err(report!(Error::InvalidSubCom));
|
||||
// }
|
||||
// }
|
||||
|
||||
// test(release, target, debuginfo).change_context(Error::Build)
|
||||
// }
|
||||
Some("run" | "r") => {
|
||||
let mut release = false;
|
||||
let mut debuginfo = false;
|
||||
let mut target = Target::X86_64;
|
||||
let mut tests = false;
|
||||
let mut do_accel = true;
|
||||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
|
@ -89,14 +63,12 @@ fn main() -> Result<(), Error> {
|
|||
do_accel = false;
|
||||
} else if arg == "avx2" {
|
||||
target = Target::X86_64Avx2;
|
||||
} else if arg == "--ktest" {
|
||||
tests = true;
|
||||
} else {
|
||||
return Err(report!(Error::InvalidSubCom));
|
||||
}
|
||||
}
|
||||
|
||||
build(release, target, debuginfo, tests)?;
|
||||
build(release, target, debuginfo)?;
|
||||
run(release, target, do_accel)
|
||||
}
|
||||
Some("help" | "h") => {
|
||||
|
@ -110,7 +82,6 @@ fn main() -> Result<(), Error> {
|
|||
" -r / --release: build in release mode\n",
|
||||
" -d / --debuginfo: build with debug info\n",
|
||||
" --noaccel: run without acceleration (e.g, no kvm)\n",
|
||||
" --ktest: Enables tests via ktest\n",
|
||||
"[ rv64 / riscv64 / riscv64-virt / aarch64 / arm64 / aarch64-virt / avx2 ]: sets target"
|
||||
),);
|
||||
Ok(())
|
||||
|
@ -339,7 +310,7 @@ fn copy_file_to_img(fpath: &str, fs: &FileSystem<File>) {
|
|||
.expect("Copy failed");
|
||||
}
|
||||
|
||||
fn build(release: bool, target: Target, debuginfo: bool, tests: bool) -> Result<(), Error> {
|
||||
fn build(release: bool, target: Target, debuginfo: bool) -> Result<(), Error> {
|
||||
let fs = get_fs().change_context(Error::Io)?;
|
||||
let mut com = Command::new("cargo");
|
||||
com.current_dir("kernel");
|
||||
|
@ -351,10 +322,6 @@ fn build(release: bool, target: Target, debuginfo: bool, tests: bool) -> Result<
|
|||
com.env("RUSTFLAGS", "-Cdebug-assertions=true");
|
||||
}
|
||||
|
||||
if tests {
|
||||
com.args(["--features", "ktest"]);
|
||||
}
|
||||
|
||||
if target == Target::Riscv64Virt {
|
||||
com.args(["--target", "targets/riscv64-virt-ableos.json"]);
|
||||
}
|
||||
|
@ -411,7 +378,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
|
|||
};
|
||||
let (mut com, mut com2) = (Command::new(target_str), Command::new(target_str));
|
||||
let ovmf_path = fetch_ovmf(target);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let accel = if do_accel {
|
||||
let supported = String::from_utf8(
|
||||
com2.args(["--accel", "help"])
|
||||
|
@ -447,8 +413,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
|
|||
} else {
|
||||
"accel=tcg"
|
||||
};
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
let accel = "accel=tcg";
|
||||
|
||||
match target {
|
||||
Target::X86_64 | Target::X86_64Avx2 => {
|
||||
|
@ -464,6 +428,11 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
|
|||
"-monitor", "none",
|
||||
"-machine", accel,
|
||||
"-cpu", "max",
|
||||
//"-serial", "stdio",
|
||||
//"-d", "trace:ps2_mouse_send_packet",
|
||||
//"-d", "trace:ps2_mouse_event_disabled",
|
||||
"-audiodev", "pa,id=speaker",
|
||||
"-machine", "pcspk-audiodev=speaker",
|
||||
"-device", "isa-debug-exit,iobase=0xf4,iosize=0x04",
|
||||
]);
|
||||
}
|
||||
|
@ -506,7 +475,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn fetch_ovmf(target: Target) -> Result<String, OvmfFetchError> {
|
||||
let (ovmf_url, ovmf_path) = match target {
|
||||
Target::X86_64 | Target::X86_64Avx2 => (
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
[toolchain]
|
||||
# old toolchain
|
||||
# channel = "nightly-2024-07-27"
|
||||
channel = "nightly-2024-11-20"
|
||||
channel = "nightly-2024-07-27"
|
||||
components = ["rust-src", "llvm-tools"]
|
||||
|
|
|
@ -3,7 +3,7 @@ stn := @use("../../../../libraries/stn/src/lib.hb");
|
|||
.{Vec2} := stn.math
|
||||
|
||||
render := @use("../../../../libraries/render/src/lib.hb");
|
||||
.{Surface, Color} := render;
|
||||
.{Surface} := render;
|
||||
.{Font} := render.text
|
||||
|
||||
Label := struct {
|
||||
|
@ -12,8 +12,6 @@ Label := struct {
|
|||
surface: Surface,
|
||||
text: ^u8,
|
||||
text_length: uint,
|
||||
bg: Color,
|
||||
fg: Color,
|
||||
}
|
||||
|
||||
set_label_text := fn(label: Label, text: ^u8): void {
|
||||
|
@ -26,8 +24,8 @@ set_label_text := fn(label: Label, text: ^u8): void {
|
|||
|
||||
render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void {
|
||||
if label.is_dirty {
|
||||
render.clear(label.surface, label.bg)
|
||||
render.put_text(label.surface, font, .(0, 0), label.fg, label.text)
|
||||
render.clear(label.surface, render.black)
|
||||
render.put_text(label.surface, font, .(0, 0), render.white, label.text)
|
||||
}
|
||||
render.put_surface(surface, label.surface, pos, false)
|
||||
}
|
||||
|
@ -35,12 +33,6 @@ render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: V
|
|||
new_label := fn(text: ^u8): Label {
|
||||
text_surface := render.new_surface(1024, 20)
|
||||
text_length := string.length(text)
|
||||
label := Label.(3, true, text_surface, text, text_length, render.black, render.white)
|
||||
label := Label.(3, true, text_surface, text, text_length)
|
||||
return label
|
||||
}
|
||||
|
||||
$set_color := fn(label: Label, bg: Color, fg: Color): void {
|
||||
label.bg = bg
|
||||
label.fg = fg
|
||||
label.is_dirty = true
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
keycodes := @use("keycodes.hb");
|
||||
.{KeyCode} := keycodes
|
||||
|
||||
KeyEvent := packed struct {
|
||||
up: bool,
|
||||
just_triggered: bool,
|
||||
KeyEvent := struct {
|
||||
// 0 if down
|
||||
// 1 if up
|
||||
up: u8,
|
||||
// 0 if not just triggered
|
||||
// 1 if just triggered
|
||||
just_triggered: u8,
|
||||
key: KeyCode,
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,6 @@ events := @use("events.hb");
|
|||
.{KeyEvent, MouseEvent} := events
|
||||
|
||||
recieve_key_event := fn(): ?KeyEvent {
|
||||
kevent := KeyEvent.(false, false, 0)
|
||||
|
||||
buf_id := buffer.search("PS/2 Keyboard\0")
|
||||
|
||||
// Read out of the Keyboard buffer here
|
||||
buffer.recv(KeyEvent, buf_id, &kevent)
|
||||
|
||||
if kevent.just_triggered {
|
||||
return kevent
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -26,7 +15,7 @@ recieve_mouse_event := fn(): ?MouseEvent {
|
|||
buf_id := buffer.search("PS/2 Mouse\0")
|
||||
|
||||
// Read out of the Mouse buffer here
|
||||
buffer.recv(MouseEvent, buf_id, &mevent)
|
||||
buffer.recv(MouseEvent, buf_id, @bitcast(&mevent))
|
||||
|
||||
if mevent.x_change != 0 | mevent.y_change != 0 | mevent.left | mevent.middle | mevent.right {
|
||||
return mevent
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
# Images
|
||||
- General over image format
|
||||
- Support formats:
|
||||
- PNG
|
||||
- Animation
|
||||
|
||||
# API
|
||||
|
@ -7,7 +10,6 @@
|
|||
- Invert
|
||||
- Surface Operations:
|
||||
- FlipH
|
||||
- Resize
|
||||
- Wrap the colour operations
|
||||
- Tile
|
||||
- Gradient overlay
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.{Color, Surface, new_surface, put_surface} := @use("../lib.hb");
|
||||
.{log} := @use("../../../stn/src/lib.hb")
|
||||
.{log, memory} := @use("../../../stn/src/lib.hb")
|
||||
|
||||
BitmapFileHeader := packed struct {
|
||||
magic: u16,
|
||||
|
@ -41,7 +41,7 @@ from := fn(bmp: ^u8): ?Surface {
|
|||
return null
|
||||
}
|
||||
|
||||
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height, info_header.width * info_header.height)
|
||||
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height)
|
||||
rhs := new_surface(info_header.width, info_header.height)
|
||||
put_surface(rhs, lhs, .(0, 0), true)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.{Color, Surface, new_surface} := @use("../lib.hb");
|
||||
.{log} := @use("../../../stn/src/lib.hb")
|
||||
.{log, memory} := @use("../../../stn/src/lib.hb")
|
||||
|
||||
/* source:
|
||||
https://github.com/phoboslab/qoi/blob/master/qoi.h */
|
||||
|
@ -13,7 +13,7 @@ $QOI_OP_RUN := 0xC0
|
|||
$QOI_OP_RGB := 0xFE
|
||||
$QOI_OP_RGBA := 0xFF
|
||||
$QOI_MASK_2 := 0xC0
|
||||
$QOI_COLOR_HASH := fn(c: Color): u8 {
|
||||
QOI_COLOR_HASH := fn(c: Color): u8 {
|
||||
return (c.r * 3 + c.g * 5 + c.b * 7 + c.a * 11) % 64
|
||||
}
|
||||
$QOI_MAGIC := 0x716F6966
|
||||
|
@ -89,7 +89,7 @@ from := fn(qoi: ^u8): ?Surface {
|
|||
run = b1 & 0x3F
|
||||
}
|
||||
|
||||
index[QOI_COLOR_HASH(px)] = px
|
||||
index[@inline(QOI_COLOR_HASH, px)] = px
|
||||
};
|
||||
|
||||
*(surface.buf + px_pos) = px
|
||||
|
|
|
@ -38,20 +38,18 @@ $light_cyan := Color.(255, 255, 0, 255)
|
|||
put_pixel := mode.put_pixel
|
||||
put_rect := mode.put_rect
|
||||
put_filled_rect := mode.put_filled_rect
|
||||
put_trirect := mode.put_trirect
|
||||
put_circle := mode.put_circle
|
||||
put_filled_circle := mode.put_filled_circle
|
||||
put_textured_circle := mode.put_textured_circle
|
||||
put_line := mode.put_line
|
||||
put_vline := mode.put_vline
|
||||
put_hline := mode.put_hline
|
||||
clear := mode.clear
|
||||
put_surface := mode.put_surface
|
||||
put_scaled := mode.put_scaled
|
||||
put_text := mode.put_text
|
||||
// thanks peony for these three!
|
||||
//put_trirect := mode.put_trirect
|
||||
//put_vline := mode.put_vline
|
||||
//put_hline := mode.put_hline
|
||||
put_trirect := mode.put_trirect
|
||||
put_vline := mode.put_vline
|
||||
put_hline := mode.put_hline
|
||||
|
||||
// Display
|
||||
sync := mode.sync
|
|
@ -1,72 +1,102 @@
|
|||
.{math, memory, dt} := @use("../../stn/src/lib.hb");
|
||||
.{math, memory, dt, log} := @use("../../stn/src/lib.hb");
|
||||
.{Color, text} := @use("lib.hb");
|
||||
.{get_glyph, get_glyph_unicode, Font, UNC_TABLE_SIZE} := text;
|
||||
.{Vec2} := math
|
||||
|
||||
// safety: don't use before init() or you will get a memory access violation
|
||||
framebuffer := memory.dangling(Color)
|
||||
//framebuffer := memory.dangling(Color)
|
||||
|
||||
Surface := struct {
|
||||
buf: ^Color,
|
||||
width: uint,
|
||||
height: uint,
|
||||
size: uint,
|
||||
}
|
||||
|
||||
new_surface := fn(width: uint, height: uint): Surface {
|
||||
return .(
|
||||
memory.alloc(Color, width * height),
|
||||
@inline(memory.alloc, Color, width * height),
|
||||
width,
|
||||
height,
|
||||
width * height,
|
||||
)
|
||||
}
|
||||
|
||||
clone_surface := fn(surface: ^Surface): Surface {
|
||||
new := new_surface(surface.width, surface.height)
|
||||
memory.copy(Color, surface.buf, new.buf, @intcast(surface.size))
|
||||
@inline(memory.copy, Color, surface.buf, new.buf, @intcast(surface.width * surface.height))
|
||||
return new
|
||||
}
|
||||
|
||||
init := fn(doublebuffer: bool): Surface {
|
||||
// ! is broken, check memory.free function
|
||||
free_surface := fn(surface: Surface): void {
|
||||
return @inline(memory.free, Color, surface.buf, @intcast(surface.width * surface.height), false)
|
||||
}
|
||||
|
||||
framebuffer := @as(?^Color, null)
|
||||
|
||||
init := fn(doublebuffer: bool): ?Surface {
|
||||
framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
|
||||
width := dt.get(uint, "framebuffer/fb0/width\0")
|
||||
height := dt.get(uint, "framebuffer/fb0/height\0")
|
||||
|
||||
errlevel := 0
|
||||
if framebuffer == null {
|
||||
log.error("'framebuffer/fb0/ptr' is null\0")
|
||||
errlevel = 1
|
||||
}
|
||||
if width == null {
|
||||
log.error("'framebuffer/fb0/width' is null\0")
|
||||
errlevel = 1
|
||||
}
|
||||
if height == null {
|
||||
log.error("'framebuffer/fb0/height' is null\0")
|
||||
errlevel = 1
|
||||
}
|
||||
|
||||
if errlevel > 0 return null
|
||||
|
||||
if doublebuffer {
|
||||
return new_surface(width, height)
|
||||
return new_surface(@unwrap(width), @unwrap(height))
|
||||
} else {
|
||||
return .(framebuffer, width, height, width * height)
|
||||
return .(@unwrap(framebuffer), @unwrap(width), @unwrap(height))
|
||||
}
|
||||
}
|
||||
|
||||
$clear := fn(surface: Surface, color: Color): void {
|
||||
memory.set(Color, &color, surface.buf, surface.width * surface.height)
|
||||
clear := fn(surface: Surface, color: Color): void {
|
||||
return @inline(memory.set, Color, &color, surface.buf, surface.width * surface.height)
|
||||
}
|
||||
|
||||
$sync := fn(surface: Surface): void {
|
||||
memory.copy(Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
|
||||
sync := fn(surface: Surface): void {
|
||||
// vague safety
|
||||
if framebuffer == null {
|
||||
return
|
||||
}
|
||||
if surface.buf == framebuffer {
|
||||
return
|
||||
}
|
||||
return @inline(memory.copy, Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
|
||||
}
|
||||
|
||||
$index := fn(surface: Surface, x: uint, y: uint): uint {
|
||||
index := fn(surface: Surface, x: uint, y: uint): uint {
|
||||
return x + surface.width * y
|
||||
}
|
||||
|
||||
$indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
|
||||
return surface.buf + index(surface, x, y)
|
||||
indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
|
||||
return surface.buf + @inline(index, surface, x, y)
|
||||
}
|
||||
|
||||
$put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
|
||||
return *indexptr(surface, pos.x, pos.y) = color
|
||||
put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
|
||||
*@inline(indexptr, surface, pos.x, pos.y) = color
|
||||
return
|
||||
}
|
||||
|
||||
put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
||||
top_start_idx := indexptr(surface, pos.x, pos.y)
|
||||
bottom_start_idx := indexptr(surface, pos.x, pos.y + tr.y - 1)
|
||||
top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1)
|
||||
rows_to_fill := tr.y
|
||||
|
||||
loop if rows_to_fill <= 1 break else {
|
||||
memory.set(Color, &color, top_start_idx, tr.x)
|
||||
memory.set(Color, &color, bottom_start_idx, tr.x)
|
||||
@inline(memory.set, Color, &color, top_start_idx, tr.x)
|
||||
@inline(memory.set, Color, &color, bottom_start_idx, tr.x)
|
||||
|
||||
top_start_idx += surface.width
|
||||
bottom_start_idx -= surface.width
|
||||
|
@ -74,16 +104,16 @@ put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color:
|
|||
}
|
||||
|
||||
if rows_to_fill == 1 {
|
||||
memory.set(Color, &color, top_start_idx, tr.x)
|
||||
@inline(memory.set, Color, &color, top_start_idx, tr.x)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
||||
start_idx := indexptr(surface, pos.x, pos.y)
|
||||
end_idx := indexptr(surface, pos.x, pos.y + tr.y)
|
||||
right_start_idx := indexptr(surface, pos.x + tr.x, pos.y)
|
||||
start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
end_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y)
|
||||
right_start_idx := @inline(indexptr, surface, pos.x + tr.x, pos.y)
|
||||
|
||||
loop if start_idx > end_idx break else {
|
||||
*start_idx = color;
|
||||
|
@ -92,8 +122,8 @@ put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color):
|
|||
right_start_idx += surface.width
|
||||
}
|
||||
|
||||
memory.set(Color, &color, indexptr(surface, pos.x, pos.y), @bitcast(tr.x + 1))
|
||||
memory.set(Color, &color, indexptr(surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
|
||||
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y), @bitcast(tr.x + 1))
|
||||
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -110,7 +140,7 @@ put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Colo
|
|||
y := p0.y
|
||||
x := p0.x
|
||||
loop if x == p1.x break else {
|
||||
*indexptr(surface, x, y) = color
|
||||
*@inline(indexptr, surface, x, y) = color
|
||||
if D > 0 {
|
||||
y += yi
|
||||
D += 2 * (dy - dx)
|
||||
|
@ -134,7 +164,7 @@ put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Col
|
|||
x := p0.x
|
||||
y := p0.y
|
||||
loop if y == p1.y break else {
|
||||
*indexptr(surface, x, y) = color
|
||||
*@inline(indexptr, surface, x, y) = color
|
||||
if D > 0 {
|
||||
x += xi
|
||||
D += 2 * (dx - dy)
|
||||
|
@ -147,7 +177,7 @@ put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Col
|
|||
}
|
||||
|
||||
put_line := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
|
||||
if math.abs(uint, p1.y - p0.y) < math.abs(uint, p1.x - p0.x) {
|
||||
if math.abs(uint, @intcast(@as(int, @intcast(p1.y)) - @as(int, @intcast(p0.y)))) < math.abs(uint, @intcast(@as(int, @intcast(p1.x)) - @as(int, @intcast(p0.x)))) {
|
||||
if p0.x > p1.x {
|
||||
@inline(put_line_low, surface, p1, p0, color)
|
||||
} else {
|
||||
|
@ -167,8 +197,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
|
|||
src_top_cursor := top.buf
|
||||
src_bottom_cursor := top.buf + top.width * (top.height - 1)
|
||||
|
||||
dst_top_idx := indexptr(surface, pos.x, pos.y)
|
||||
dst_bottom_idx := indexptr(surface, pos.x, pos.y + top.height - 1)
|
||||
dst_top_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
dst_bottom_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1)
|
||||
|
||||
dst_increment := surface.width
|
||||
|
||||
|
@ -182,8 +212,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
|
|||
rows_to_copy := top.height
|
||||
|
||||
loop if rows_to_copy <= 1 break else {
|
||||
memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
|
||||
memory.copy(Color, src_bottom_cursor, dst_bottom_idx, top.width)
|
||||
@inline(memory.copy, Color, src_top_cursor, dst_top_idx, top.width)
|
||||
@inline(memory.copy, Color, src_bottom_cursor, dst_bottom_idx, top.width)
|
||||
|
||||
dst_top_idx += dst_increment
|
||||
dst_bottom_idx -= dst_increment
|
||||
|
@ -193,7 +223,78 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
|
|||
}
|
||||
|
||||
if rows_to_copy == 1 {
|
||||
memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
|
||||
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
put_scaled := fn(surface: Surface, source: Surface, pos: Vec2(int), size: Vec2(int)): void {
|
||||
step := Vec2(int).(1, 1)
|
||||
if size.x < 0 {
|
||||
pos.x += source.width - 1
|
||||
size.x = -size.x
|
||||
step.x = -1
|
||||
}
|
||||
if size.y < 0 {
|
||||
pos.y += source.height - 1
|
||||
size.y = -size.y
|
||||
step.y = -1
|
||||
}
|
||||
surface_idx := @inline(index, surface, pos.x, pos.y)
|
||||
|
||||
source_pos := Vec2(int).(0, 0)
|
||||
subpixel_pos := Vec2(int).(0, 0)
|
||||
step_size := size / .(source.width, source.height)
|
||||
if size.x < source.width {
|
||||
step_size.x = source.width / size.x
|
||||
}
|
||||
if size.y < source.height {
|
||||
step_size.y = source.height / size.y
|
||||
}
|
||||
one_up_step := size / (size - step_size * .(source.width, source.height))
|
||||
|
||||
pos = .(0, 0)
|
||||
loop if pos.y >= size.y break else {
|
||||
loop if pos.x >= size.x break else {
|
||||
*surface_idx = *@inline(index, source, source_pos.x, source_pos.y)
|
||||
surface_idx += step.x
|
||||
|
||||
if size.x < source.width {
|
||||
if source_pos.x % one_up_step.x == 0 {
|
||||
source_pos.x += 1
|
||||
}
|
||||
source_pos.x += step_size.x
|
||||
} else {
|
||||
subpixel_pos.x += 1
|
||||
if subpixel_pos.x > step_size.x | source_pos.x % one_up_step.x == 0 & subpixel_pos.x >= step_size.x {
|
||||
source_pos.x += 1
|
||||
subpixel_pos.x = 0
|
||||
}
|
||||
}
|
||||
|
||||
pos.x += 1
|
||||
}
|
||||
|
||||
if size.y < source.height {
|
||||
if source_pos.y % one_up_step.y == 0 {
|
||||
source_pos.y += 1
|
||||
}
|
||||
source_pos.y += step_size.y
|
||||
} else {
|
||||
subpixel_pos.y += 1
|
||||
if subpixel_pos.y > step_size.y | source_pos.y % one_up_step.y == 0 & subpixel_pos.y >= step_size.y {
|
||||
source_pos.y += 1
|
||||
subpixel_pos.y = 0
|
||||
}
|
||||
}
|
||||
|
||||
surface_idx += surface.width * step.y - size.x * step.x
|
||||
|
||||
source_pos.x = 0
|
||||
pos.x = 0
|
||||
|
||||
pos.y += 1
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -231,7 +332,7 @@ put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): vo
|
|||
y := y0
|
||||
|
||||
loop if y == y1 break else {
|
||||
*indexptr(surface, x, y) = color
|
||||
*@inline(indexptr, surface, x, y) = color
|
||||
y += 1
|
||||
}
|
||||
|
||||
|
@ -245,8 +346,7 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
|
|||
x0 = x1
|
||||
x1 = tmp
|
||||
}
|
||||
// x0 = math.min(x0, x1)
|
||||
memory.set(Color, &color, indexptr(surface, x0, y), @bitcast(x1 - x0 - 1))
|
||||
@inline(memory.set, Color, &color, @inline(indexptr, surface, x0, y), @bitcast(x1 - x0 - 1))
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -254,29 +354,29 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
|
|||
put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
|
||||
x := 0
|
||||
y := radius
|
||||
error := @as(int, 3) - @intcast(2 * radius);
|
||||
*indexptr(surface, pos.x + radius, pos.y) = color;
|
||||
*indexptr(surface, pos.x - radius, pos.y) = color;
|
||||
*indexptr(surface, pos.x, pos.y + radius) = color;
|
||||
*indexptr(surface, pos.x, pos.y - radius) = color
|
||||
error := @as(int, 3) - @as(int, @intcast(2 * radius));
|
||||
*@inline(indexptr, surface, pos.x + radius, pos.y) = color;
|
||||
*@inline(indexptr, surface, pos.x - radius, pos.y) = color;
|
||||
*@inline(indexptr, surface, pos.x, pos.y + radius) = color;
|
||||
*@inline(indexptr, surface, pos.x, pos.y - radius) = color
|
||||
|
||||
loop if y < x break else {
|
||||
x += 1
|
||||
|
||||
if error > 0 {
|
||||
y -= 1
|
||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
||||
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
|
||||
} else {
|
||||
error += 4 * @intcast(x) + 6
|
||||
};
|
||||
*indexptr(surface, pos.x + x, pos.y + y) = color;
|
||||
*indexptr(surface, pos.x + y, pos.y + x) = color;
|
||||
*indexptr(surface, pos.x - x, pos.y + y) = color;
|
||||
*indexptr(surface, pos.x - y, pos.y + x) = color;
|
||||
*indexptr(surface, pos.x + x, pos.y - y) = color;
|
||||
*indexptr(surface, pos.x + y, pos.y - x) = color;
|
||||
*indexptr(surface, pos.x - x, pos.y - y) = color;
|
||||
*indexptr(surface, pos.x - y, pos.y - x) = color
|
||||
*@inline(indexptr, surface, pos.x + x, pos.y + y) = color;
|
||||
*@inline(indexptr, surface, pos.x + y, pos.y + x) = color;
|
||||
*@inline(indexptr, surface, pos.x - x, pos.y + y) = color;
|
||||
*@inline(indexptr, surface, pos.x - y, pos.y + x) = color;
|
||||
*@inline(indexptr, surface, pos.x + x, pos.y - y) = color;
|
||||
*@inline(indexptr, surface, pos.x + y, pos.y - x) = color;
|
||||
*@inline(indexptr, surface, pos.x - x, pos.y - y) = color;
|
||||
*@inline(indexptr, surface, pos.x - y, pos.y - x) = color
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -285,24 +385,24 @@ put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color):
|
|||
put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
|
||||
x := 0
|
||||
y := radius
|
||||
error := @as(int, 3) - @intcast(2 * radius)
|
||||
put_hline(surface, pos.y - x, pos.x - radius, pos.x + radius, color);
|
||||
*indexptr(surface, pos.x, pos.y + radius) = color;
|
||||
*indexptr(surface, pos.x, pos.y - radius) = color
|
||||
error := @as(int, 3) - @as(int, @intcast(2 * radius))
|
||||
@inline(put_hline, surface, pos.y - x, pos.x - radius, pos.x + radius, color);
|
||||
*@inline(indexptr, surface, pos.x, pos.y + radius) = color;
|
||||
*@inline(indexptr, surface, pos.x, pos.y - radius) = color
|
||||
|
||||
loop if y < x break else {
|
||||
x += 1
|
||||
|
||||
if error > 0 {
|
||||
put_hline(surface, pos.y + y, pos.x - x, pos.x + x, color)
|
||||
put_hline(surface, pos.y - y, pos.x - x, pos.x + x, color)
|
||||
@inline(put_hline, surface, pos.y + y, pos.x - x, pos.x + x, color)
|
||||
@inline(put_hline, surface, pos.y - y, pos.x - x, pos.x + x, color)
|
||||
y -= 1
|
||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
||||
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
|
||||
} else {
|
||||
error += 4 * @intcast(x) + 6
|
||||
}
|
||||
put_hline(surface, pos.y + x, pos.x - y, pos.x + y, color)
|
||||
put_hline(surface, pos.y - x, pos.x - y, pos.x + y, color)
|
||||
@inline(put_hline, surface, pos.y + x, pos.x - y, pos.x + y, color)
|
||||
@inline(put_hline, surface, pos.y - x, pos.x - y, pos.x + y, color)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -311,31 +411,29 @@ put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color:
|
|||
put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void {
|
||||
x := 0
|
||||
y := radius
|
||||
error := @as(int, 3) - @intcast(2 * radius)
|
||||
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y), indexptr(surface, pos.x - y, pos.y), 2 * y);
|
||||
*indexptr(surface, pos.x, pos.y + y) = *indexptr(source, source_pos.x, source_pos.y + y);
|
||||
*indexptr(surface, pos.x, pos.y - y) = *indexptr(source, source_pos.x, source_pos.y - y)
|
||||
error := @as(int, 3) - @as(int, @intcast(2 * radius))
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y), @inline(indexptr, surface, pos.x - y, pos.y), 2 * y);
|
||||
*@inline(indexptr, surface, pos.x, pos.y + y) = *@inline(indexptr, source, source_pos.x, source_pos.y + y);
|
||||
*@inline(indexptr, surface, pos.x, pos.y - y) = *@inline(indexptr, source, source_pos.x, source_pos.y - y)
|
||||
|
||||
loop if y < x break else {
|
||||
x += 1
|
||||
|
||||
if error > 0 {
|
||||
memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y + y), indexptr(surface, pos.x - x, pos.y + y), 2 * x)
|
||||
memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y - y), indexptr(surface, pos.x - x, pos.y - y), 2 * x)
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y + y), @inline(indexptr, surface, pos.x - x, pos.y + y), 2 * x)
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y - y), @inline(indexptr, surface, pos.x - x, pos.y - y), 2 * x)
|
||||
y -= 1
|
||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
||||
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
|
||||
} else {
|
||||
error += 4 * @intcast(x) + 6
|
||||
}
|
||||
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y + x), indexptr(surface, pos.x - y, pos.y + x), 2 * y)
|
||||
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y - x), indexptr(surface, pos.x - y, pos.y - x), 2 * y)
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y + x), @inline(indexptr, surface, pos.x - y, pos.y + x), 2 * y)
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y - x), @inline(indexptr, surface, pos.x - y, pos.y - x), 2 * y)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
utf8_len_table := [u8].(0, 0, 2, 3)
|
||||
|
||||
put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
|
||||
cursor := Vec2(uint).(pos.x, pos.y)
|
||||
|
||||
|
@ -363,7 +461,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
|
|||
str += 1
|
||||
continue
|
||||
}
|
||||
glyph_data = get_glyph(font, *str)
|
||||
glyph_data = @inline(get_glyph, font, *str)
|
||||
} else {
|
||||
if *str < UNC_TABLE_SIZE {
|
||||
glyph_index := *(font.unicode + *str)
|
||||
|
@ -435,7 +533,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
|
|||
cursor.y += next_line_y
|
||||
}
|
||||
|
||||
dest := indexptr(surface, cursor.x, cursor.y)
|
||||
dest := @inline(indexptr, surface, cursor.x, cursor.y)
|
||||
rows := font.height
|
||||
|
||||
loop if rows == 0 break else {
|
||||
|
|
|
@ -74,16 +74,16 @@ font_from_psf2 := fn(psf: ^u8, unicode: bool): ?Font {
|
|||
return font
|
||||
}
|
||||
|
||||
$get_glyph := fn(font: Font, index: u8): ^u8 {
|
||||
get_glyph := fn(font: Font, index: u8): ^u8 {
|
||||
return font.data + @as(uint, index) * font.bytes_per_glyph
|
||||
}
|
||||
|
||||
$UNC_TABLE_SIZE := 1 << 16
|
||||
UNC_TABLE_SIZE := 1 << 16
|
||||
|
||||
init_unicode := fn(font: ^Font): void {
|
||||
font.unicode = memory.alloc(u16, UNC_TABLE_SIZE)
|
||||
|
||||
memory.set(u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE)
|
||||
@inline(memory.set, u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE)
|
||||
|
||||
table := font.data + font.num_glyphs * font.bytes_per_glyph
|
||||
curr_glyph := @as(u16, 0)
|
||||
|
@ -121,6 +121,8 @@ init_unicode := fn(font: ^Font): void {
|
|||
next_byte := *table
|
||||
if (next_byte & 0xC0) != 0x80 {
|
||||
valid = false
|
||||
}
|
||||
if valid == false {
|
||||
break
|
||||
}
|
||||
unicode = unicode << 6 | next_byte & 0x3F
|
||||
|
|
1
sysdata/libraries/sound/README.md
Normal file
1
sysdata/libraries/sound/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
Simple sound driver.
|
23
sysdata/libraries/sound/src/lib.hb
Normal file
23
sysdata/libraries/sound/src/lib.hb
Normal 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
|
||||
}
|
|
@ -1,35 +1,27 @@
|
|||
string := @use("string.hb")
|
||||
|
||||
$recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
|
||||
recv := fn($Expr: type, buffer_id: int, memory_map_location: ^u8): void {
|
||||
return @eca(4, buffer_id, memory_map_location, @sizeof(Expr))
|
||||
}
|
||||
|
||||
$write := fn($Expr: type, buffer_id: uint, msg: ^Expr): void {
|
||||
write := fn($Expr: type, msg: ^Expr, buffer_id: int): void {
|
||||
return @eca(3, buffer_id, msg, @sizeof(Expr))
|
||||
}
|
||||
|
||||
$recv_length := fn(length: uint, memory_map_location: ^u8, buffer_id: uint): void {
|
||||
recv_length := fn(buffer_id: int, memory_map_location: ^u8, length: int): void {
|
||||
return @eca(4, buffer_id, memory_map_location, length)
|
||||
}
|
||||
|
||||
$write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
|
||||
write_length := fn(msg: ^u8, buffer_id: int, length: int): void {
|
||||
return @eca(3, buffer_id, msg, length)
|
||||
}
|
||||
|
||||
BufferMsg := packed struct {operation: u8, msg: ^u8, msg_len: uint}
|
||||
|
||||
create := fn(msg: ^u8): uint {
|
||||
create := fn(msg: ^u8): int {
|
||||
return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
|
||||
}
|
||||
|
||||
$create_nameless := fn(): uint {
|
||||
return @eca(1, 0)
|
||||
}
|
||||
|
||||
$delete_buffer := fn(buffer_id: uint): void {
|
||||
return @eca(2, buffer_id)
|
||||
}
|
||||
|
||||
search := fn(msg: ^u8): uint {
|
||||
search := fn(msg: ^u8): int {
|
||||
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
.{string} := @use("../../stn/src/lib.hb")
|
||||
|
||||
get := fn($Expr: type, query: ^u8): Expr {
|
||||
get := fn($Expr: type, query: ^u8): ?Expr {
|
||||
return @eca(3, 5, query, @inline(string.length, query))
|
||||
}
|
|
@ -7,7 +7,6 @@ math := @use("math.hb")
|
|||
random := @use("random.hb")
|
||||
file := @use("file_io.hb")
|
||||
dt := @use("dt.hb")
|
||||
process := @use("process.hb")
|
||||
|
||||
panic := fn(message: ?^u8): never {
|
||||
log.error("Error: Panic Called, Message:\0")
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
$abs := fn($Expr: type, x: Expr): Expr {
|
||||
return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
|
||||
abs := fn($Expr: type, x: Expr): Expr {
|
||||
mask := x >> @bitcast(@sizeof(Expr) - 1)
|
||||
return (x ^ mask) - mask
|
||||
}
|
||||
$min := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
return b + (a - b & a - b >> @sizeof(Expr) - 1)
|
||||
min := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
c := a - b
|
||||
return b + (c & c >> @bitcast(@sizeof(Expr) - 1))
|
||||
}
|
||||
$max := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
return a - (a - b & a - b >> @sizeof(Expr) - 1)
|
||||
max := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
c := a - b
|
||||
return a - (c & c >> @bitcast(@sizeof(Expr) - 1))
|
||||
}
|
||||
$sign := fn($Expr: type, x: Expr): i8 {
|
||||
return @bitcast(x > 0) - @bitcast(x < 0)
|
||||
}
|
||||
$log := fn($Expr: type, base: uint, x: Expr): uint {
|
||||
// if x <= 0 {}
|
||||
// if base <= 1 {}
|
||||
result := 0
|
||||
loop if x < base break else {
|
||||
x /= base
|
||||
result += 1
|
||||
signum := fn($Expr: type, x: Expr): int {
|
||||
if x > @as(Expr, @intcast(0)) {
|
||||
return 1
|
||||
} else if x < @as(Expr, @intcast(0)) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
return result
|
||||
}
|
||||
signincl := fn($Expr: type, x: Expr): int {
|
||||
if x > @as(Expr, @intcast(0)) {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
Vec2 := fn($Expr: type): type {
|
||||
|
@ -35,7 +40,7 @@ $TABLE_SIZE := @as(i32, 256)
|
|||
|
||||
sin := fn(theta: f32): f32 {
|
||||
si := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
|
||||
d := theta - @floatcast(@itf(si)) * 2.0 * PI / @floatcast(@itf(TABLE_SIZE))
|
||||
d := theta - @floatcast(@itf(si)) * 2.0 * PI / @itf(TABLE_SIZE)
|
||||
ci := si + TABLE_SIZE / 4 & TABLE_SIZE - 1
|
||||
si &= TABLE_SIZE - 1
|
||||
return SIN_TABLE[@bitcast(si)] + (SIN_TABLE[@bitcast(ci)] - 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
|
||||
|
@ -43,10 +48,10 @@ sin := fn(theta: f32): f32 {
|
|||
|
||||
cos := fn(theta: f32): f32 {
|
||||
ci := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
|
||||
d := theta - @floatcast(@itf(ci)) * 2.0 * PI / @floatcast(@itf(TABLE_SIZE))
|
||||
d := theta - @floatcast(@itf(ci)) * 2.0 * PI / @itf(TABLE_SIZE)
|
||||
si := ci + TABLE_SIZE / 4 & TABLE_SIZE - 1
|
||||
ci &= TABLE_SIZE - 1
|
||||
return SIN_TABLE[@bitcast(si)] - (SIN_TABLE[@bitcast(ci)] + 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
|
||||
return SIN_TABLE[@bitcast(si)] + (SIN_TABLE[@bitcast(ci)] - 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
|
||||
}
|
||||
|
||||
tan := fn(theta: f32): f32 {
|
||||
|
|
|
@ -1,29 +1,24 @@
|
|||
$PAGE_SIZE := 4096
|
||||
$MAX_ALLOC := 0xFF
|
||||
$MAX_FREE := 0xFF
|
||||
PAGE_SIZE := 4096
|
||||
MAX_ALLOC := 0xFF
|
||||
MAX_FREE := 0xFF
|
||||
|
||||
$uninit := fn($Expr: type): ?Expr {
|
||||
return null
|
||||
}
|
||||
|
||||
$dangling := fn($Expr: type): ^Expr {
|
||||
dangling := fn($Expr: type): ^Expr {
|
||||
return @bitcast(@alignof(Expr))
|
||||
}
|
||||
|
||||
$calc_pages := fn($Expr: type, num: uint): uint {
|
||||
calc_pages := fn($Expr: type, num: uint): uint {
|
||||
return 1 + @sizeof(Expr) * num / PAGE_SIZE
|
||||
}
|
||||
|
||||
// ! will be replaced, don't get attached
|
||||
alloc := fn($Expr: type, num: uint): ^Expr {
|
||||
pages := calc_pages(Expr, num)
|
||||
pages := @inline(calc_pages, Expr, num)
|
||||
if pages <= MAX_ALLOC {
|
||||
return @bitcast(request_page(@intcast(pages)))
|
||||
}
|
||||
ptr := request_page(MAX_ALLOC)
|
||||
ptr := request_page(0xFF)
|
||||
remaining := pages - MAX_ALLOC
|
||||
loop if remaining < MAX_ALLOC break else {
|
||||
_ = request_page(MAX_ALLOC)
|
||||
_ = request_page(@intcast(MAX_ALLOC))
|
||||
remaining -= MAX_ALLOC
|
||||
}
|
||||
_ = request_page(@intcast(remaining))
|
||||
|
@ -31,46 +26,46 @@ alloc := fn($Expr: type, num: uint): ^Expr {
|
|||
}
|
||||
|
||||
// ! stub
|
||||
$free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
|
||||
free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
|
||||
return
|
||||
}
|
||||
|
||||
RqPageMsg := packed struct {a: u8, count: u8}
|
||||
$request_page := fn(count: u8): ^u8 {
|
||||
request_page := fn(count: u8): ^u8 {
|
||||
return @eca(3, 2, &RqPageMsg.(0, count), @sizeof(RqPageMsg))
|
||||
}
|
||||
|
||||
RlPageMsg := packed struct {a: u8, count: u8, ptr: ^u8}
|
||||
$release_page := fn(ptr: ^u8, count: u8): void {
|
||||
release_page := fn(ptr: ^u8, count: u8): void {
|
||||
return @eca(3, 2, &RlPageMsg.(1, count, ptr), @sizeof(RlPageMsg))
|
||||
}
|
||||
|
||||
OutbMsg := packed struct {a: u8, b: u8, addr: u16, value: u8}
|
||||
$outb := fn(addr: u16, value: u8): void {
|
||||
outb := fn(addr: u16, value: u8): void {
|
||||
return @eca(3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg))
|
||||
}
|
||||
|
||||
InbMsg := packed struct {a: u8, b: u8, addr: u16}
|
||||
$inb := fn(addr: u16): u8 {
|
||||
inb := fn(addr: u16): u8 {
|
||||
return @eca(3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg))
|
||||
}
|
||||
|
||||
OutlMsg := packed struct {a: u8, b: u8, addr: u16, value: u32}
|
||||
$outl := fn(addr: u16, value: u32): void {
|
||||
outl := fn(addr: u16, value: u32): void {
|
||||
return @eca(3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg))
|
||||
}
|
||||
|
||||
InlMsg := packed struct {a: u8, b: u8, addr: u16}
|
||||
$inl := fn(addr: u16): u32 {
|
||||
inl := fn(addr: u16): u32 {
|
||||
return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg))
|
||||
}
|
||||
|
||||
CopyMsg := packed struct {a: u8, count: u32, src: ^u8, dest: ^u8}
|
||||
$copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||
copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||
return @eca(3, 2, &CopyMsg.(4, @intcast(count * @sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))
|
||||
}
|
||||
|
||||
SetMsg := packed struct {a: u8, count: u32, size: u32, src: ^u8, dest: ^u8}
|
||||
$set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||
set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||
return @eca(3, 2, &SetMsg.(5, @intcast(count), @intcast(@sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
|
||||
}
|
|
@ -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 */
|
|
@ -1,15 +1,7 @@
|
|||
$any := fn($Expr: type): Expr {
|
||||
any := fn($Expr: type): Expr {
|
||||
return *@eca(3, 4, &@as(Expr, idk), @sizeof(Expr))
|
||||
}
|
||||
|
||||
$range := fn($Expr: type, min: Expr, max: Expr): Expr {
|
||||
return *@eca(3, 4, &@as(Expr, idk), @sizeof(Expr)) % (max - min) + *@bitcast(&1) + min
|
||||
}
|
||||
|
||||
$fill := fn($Expr: type, ptr: ^Expr): void {
|
||||
return @eca(3, 4, ptr, @sizeof(Expr))
|
||||
}
|
||||
|
||||
$fill_buffer := fn(buf: ^u8, len: uint): void {
|
||||
return @eca(3, 4, buf, len)
|
||||
range := fn($Expr: type, min: Expr, max: Expr): Expr {
|
||||
return @inline(any, Expr) % (max - min) + @intcast(1) + min
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -4,213 +4,118 @@ length := fn(ptr: ^u8): uint {
|
|||
}
|
||||
|
||||
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
|
||||
is_negative := num < 0
|
||||
if is_negative num = -num
|
||||
|
||||
ptr := p
|
||||
negative := num < 0
|
||||
if negative {
|
||||
num = -num
|
||||
}
|
||||
|
||||
if radix == 2 {
|
||||
*ptr = 48
|
||||
ptr += 1;
|
||||
*ptr = 98
|
||||
ptr += 1
|
||||
} else if radix == 16 {
|
||||
*ptr = 48
|
||||
ptr += 1;
|
||||
*ptr = 120
|
||||
ptr += 1
|
||||
} else if radix == 8 {
|
||||
*ptr = 48
|
||||
ptr += 1;
|
||||
*ptr = 111
|
||||
ptr += 1
|
||||
}
|
||||
digits_start := ptr
|
||||
if num == 0 {
|
||||
*ptr = 0x30;
|
||||
*(ptr + 1) = 0
|
||||
return p
|
||||
}
|
||||
|
||||
loop if num == 0 break else {
|
||||
remainder := num % @bitcast(radix)
|
||||
num /= @bitcast(radix);
|
||||
*ptr = @intcast(remainder + 0x30)
|
||||
if remainder > 9 {
|
||||
*ptr = @intcast(remainder - 10 + 0x41)
|
||||
*ptr = 48
|
||||
ptr += 1
|
||||
} else {
|
||||
loop if num == 0 break else {
|
||||
digit := num % @bitcast(radix)
|
||||
if digit < 10 {
|
||||
*ptr = @intcast(digit) + 48
|
||||
} else {
|
||||
*ptr = @intcast(digit) + 55
|
||||
}
|
||||
ptr += 1
|
||||
num /= @bitcast(radix)
|
||||
}
|
||||
ptr += 1
|
||||
}
|
||||
|
||||
if is_negative {
|
||||
*ptr = 0x2D
|
||||
if negative {
|
||||
*ptr = 45
|
||||
ptr += 1
|
||||
}
|
||||
// ! it gets broked when you do this ??
|
||||
// *ptr = 0
|
||||
};
|
||||
|
||||
*ptr = 0
|
||||
|
||||
@inline(reverse, digits_start)
|
||||
|
||||
@inline(reverse, p)
|
||||
return p
|
||||
}
|
||||
|
||||
reverse := fn(s: ^u8): void {
|
||||
j := s + @inline(length, s) - 1
|
||||
i := 0
|
||||
j := @inline(length, s) - 1
|
||||
temp := @as(u8, 0)
|
||||
loop if s < j {
|
||||
temp = *s;
|
||||
*s = *j;
|
||||
*j = temp
|
||||
s += 1
|
||||
loop if i >= j break else {
|
||||
temp = *(s + i);
|
||||
*(s + i) = *(s + j);
|
||||
*(s + j) = temp
|
||||
i += 1
|
||||
j -= 1
|
||||
} else return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
equals := fn(lhs: ^u8, rhs: ^u8): bool {
|
||||
if lhs == rhs {
|
||||
return true
|
||||
}
|
||||
loop if *lhs != *rhs {
|
||||
i := 0
|
||||
loop if *(lhs + i) != *(rhs + i) {
|
||||
return false
|
||||
} else if *lhs == 0 {
|
||||
return true
|
||||
} else {
|
||||
lhs += 1
|
||||
rhs += 1
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
|
||||
clear := fn(ptr: ^u8): void {
|
||||
loop if *ptr == 0 break else {
|
||||
*ptr = 0
|
||||
ptr += 1
|
||||
contains := fn(haystack: ^u8, needle: ^u8): bool {
|
||||
haystack_len := @inline(length, haystack)
|
||||
needle_len := @inline(length, needle)
|
||||
|
||||
if needle_len == 0 {
|
||||
return true
|
||||
}
|
||||
if haystack_len < needle_len {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
split_once := fn(haystack: ^u8, needle: u8): ?^u8 {
|
||||
loop if *haystack == needle return haystack else if *haystack == 0 return null else haystack += 1
|
||||
}
|
||||
max_start := haystack_len - needle_len
|
||||
|
||||
split_once_str := fn(haystack: ^u8, needle: ^u8): ?^u8 {
|
||||
if *needle == 0 return null
|
||||
pos := 0
|
||||
loop if pos > max_start break else {
|
||||
is_match := true
|
||||
offset := 0
|
||||
|
||||
loop if *haystack == 0 return null else {
|
||||
if *haystack == *needle {
|
||||
h := haystack
|
||||
n := needle
|
||||
|
||||
loop {
|
||||
n += 1
|
||||
h += 1
|
||||
if *n == 0 {
|
||||
return haystack
|
||||
} else if *h == 0 | *h != *n {
|
||||
break
|
||||
}
|
||||
loop if offset >= needle_len break else {
|
||||
if *(haystack + pos + offset) != *(needle + offset) {
|
||||
is_match = false
|
||||
}
|
||||
}
|
||||
haystack += 1
|
||||
}
|
||||
}
|
||||
|
||||
Split := struct {
|
||||
str: ^u8,
|
||||
needle: u8,
|
||||
done: bool,
|
||||
}
|
||||
|
||||
split := fn(iter: ^u8, needle: u8): Split {
|
||||
return .(
|
||||
iter,
|
||||
needle,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
iter_split := fn(iter: ^Split): ?^u8 {
|
||||
if iter.done | *iter.str == 0 {
|
||||
return null
|
||||
}
|
||||
|
||||
next := split_once(iter.str + 1, iter.needle)
|
||||
|
||||
if next == null {
|
||||
iter.done = true
|
||||
return iter.str
|
||||
}
|
||||
s := iter.str
|
||||
iter.str = next + 1
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
SplitStr := struct {
|
||||
str: ^u8,
|
||||
needle: ^u8,
|
||||
done: bool,
|
||||
}
|
||||
|
||||
split_str := fn(iter: ^u8, needle: ^u8): SplitStr {
|
||||
return .(
|
||||
iter,
|
||||
needle,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
iter_split_str := fn(iter: ^SplitStr): ?^u8 {
|
||||
if iter.done | *iter.str == 0 {
|
||||
return null
|
||||
}
|
||||
|
||||
next := split_once_str(iter.str, iter.needle)
|
||||
|
||||
if next == null {
|
||||
iter.done = true
|
||||
return iter.str
|
||||
}
|
||||
|
||||
s := iter.str
|
||||
|
||||
iter.str = next + length(iter.needle)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
find_once := fn(haystack: ^u8, needle: u8): ?uint {
|
||||
return @bitcast(@inline(split_once, haystack, needle) - haystack)
|
||||
}
|
||||
|
||||
find_once_str := fn(haystack: ^u8, needle: ^u8): ?uint {
|
||||
return @bitcast(@inline(split_once_str, haystack, needle) - haystack)
|
||||
}
|
||||
|
||||
count := fn(haystack: ^u8, needle: ^u8): uint {
|
||||
c := 0
|
||||
loop if *haystack == needle {
|
||||
c += 1
|
||||
haystack += 1
|
||||
} else if *haystack == 0 return c else haystack += 1
|
||||
}
|
||||
|
||||
count_str := fn(haystack: ^u8, needle: ^u8): uint {
|
||||
if *needle == 0 return 0
|
||||
c := 0
|
||||
loop if *haystack == 0 return c else {
|
||||
if *haystack == *needle {
|
||||
h := haystack
|
||||
n := needle
|
||||
|
||||
loop {
|
||||
n += 1
|
||||
h += 1
|
||||
if *n == 0 {
|
||||
c += 1
|
||||
break
|
||||
} else if *h == 0 | *h != *n {
|
||||
break
|
||||
}
|
||||
if is_match == false {
|
||||
break
|
||||
}
|
||||
offset += 1
|
||||
}
|
||||
haystack += 1
|
||||
}
|
||||
}
|
||||
|
||||
left_trim := fn(str: ^u8, sub: ^u8): ^u8 {
|
||||
original := str
|
||||
if *str == *sub {
|
||||
loop if *sub == 0 {
|
||||
return str
|
||||
} else if *str != *sub {
|
||||
return original
|
||||
} else if *str == 0 {
|
||||
return original
|
||||
} else {
|
||||
str += 1
|
||||
sub += 1
|
||||
if is_match {
|
||||
return true
|
||||
}
|
||||
pos += 1
|
||||
}
|
||||
return str
|
||||
|
||||
return false
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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,
|
||||
}
|
|
@ -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
|
|
@ -1,5 +0,0 @@
|
|||
$none := 0b0
|
||||
$exclusive_framebuffer := 0b1
|
||||
$shutdown := 0b100
|
||||
|
||||
$default := none
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -28,6 +28,10 @@ main := fn(): int {
|
|||
win_buff := buffer.create("XHorizon\0")
|
||||
|
||||
screen := render.init(true)
|
||||
if screen == null {
|
||||
log.error("Screen could not be initialized!\0")
|
||||
return 1
|
||||
}
|
||||
|
||||
// Clear the screen to black.
|
||||
render.clear(screen, render.black)
|
||||
|
@ -56,13 +60,43 @@ main := fn(): int {
|
|||
loop {
|
||||
// Clear the screen
|
||||
render.clear(screen, render.black)
|
||||
|
||||
render.put_surface(screen, wallpaper, .(0, 0), false)
|
||||
|
||||
// TODO: Read the window buffer here
|
||||
{
|
||||
// ret := buffer.recv([u8; 4096], win_buff, mem_buf)
|
||||
// for some reason this null check causes the compiler to spin forever
|
||||
// if ret == null {
|
||||
// log.info("No messages\0")
|
||||
// } else {
|
||||
// log.info("Handle Messages\0")
|
||||
// }
|
||||
}
|
||||
|
||||
// get input events from drivers via intouch
|
||||
// key_event := intouch.recieve_key_event();
|
||||
// log.info("before mouse event check\0");
|
||||
{
|
||||
// Note: MLokis, this inline halts the compiler forever
|
||||
// mouse_event := @inline(intouch.recieve_mouse_event)
|
||||
// Note: MLokis, this function returns null unless the mouse is moving
|
||||
mouse_event := intouch.recieve_mouse_event()
|
||||
//
|
||||
|
||||
if mouse_event != null {
|
||||
log.warn("Mouse event recieved\0")
|
||||
|
||||
mouse_x += mouse_event.x_change
|
||||
mouse_y += mouse_event.y_change
|
||||
set_label_text(text_label, "Mouse Moved\0")
|
||||
}
|
||||
// render mouse
|
||||
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
|
||||
// Send events to focused window
|
||||
}
|
||||
|
||||
// TODO: Get windows out of a collection and iter through
|
||||
|
||||
if false {
|
||||
// Scroll bar :ThumbsUp:
|
||||
render.put_rect(screen, .(100, 100), .(100, 10), render.white)
|
||||
|
@ -72,35 +106,18 @@ main := fn(): int {
|
|||
render.put_filled_rect(screen, .(90, 120), .(10, 20), render.white)
|
||||
}
|
||||
|
||||
{
|
||||
// osu dots
|
||||
render.put_rect(screen, .(400, 100), .(100, 100), render.red)
|
||||
render.put_rect(screen, .(100, 100 + 300), .(100, 100), render.red)
|
||||
}
|
||||
|
||||
{
|
||||
pos := Vec2(uint).(1, screen.height - 21)
|
||||
render_label_to_surface(screen, text_label, font, pos)
|
||||
render.put_rect(screen, .(0, screen.height - 21), .(screen.width - 1, 20), render.white)
|
||||
}
|
||||
|
||||
// Screen border
|
||||
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white)
|
||||
|
||||
// get input events from drivers via intouch
|
||||
if false {
|
||||
key_event := intouch.recieve_key_event()
|
||||
if key_event != null {
|
||||
log.info("Key event \0")
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
mouse_event := intouch.recieve_mouse_event()
|
||||
//
|
||||
|
||||
if mouse_event != null {
|
||||
// log.warn("Mouse event received\0")
|
||||
// log.warn("Mouse event recieved\0")
|
||||
|
||||
change_x := @as(i16, mouse_event.x_change)
|
||||
change_x = change_x << 8
|
||||
|
@ -137,9 +154,15 @@ main := fn(): int {
|
|||
}
|
||||
}
|
||||
|
||||
render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
|
||||
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
|
||||
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white)
|
||||
|
||||
// render mouse
|
||||
lum := render.indexptr(screen, mouse_x, mouse_y)
|
||||
if lum.r / 3 + lum.g / 3 + lum.b / 3 < 128 {
|
||||
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
|
||||
} else {
|
||||
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
|
||||
}
|
||||
// Send events to focused window
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
[package]
|
||||
name = "processes"
|
||||
authors = ["koniifer"]
|
||||
|
||||
[dependants.libraries]
|
||||
|
||||
[dependants.binaries]
|
||||
hblang.version = "1.0.0"
|
||||
|
||||
[build]
|
||||
command = "hblang src/main.hb"
|
|
@ -1,7 +0,0 @@
|
|||
.{log} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
main := fn(): void {
|
||||
log.info("Hello, World!\0")
|
||||
loop {
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
# Unified PS/2 Driver
|
||||
|
||||
Te entire thing is held together inspite
|
||||
Te entire thing is heavily documented with comments because I'm not sure how else to make this understandable.
|
||||
|
||||
## !!Assumptions!!
|
||||
Anyone who works on this should work to keep this list as small as possible/remove as many of these as possible.
|
||||
|
@ -10,14 +10,3 @@ Anyone who works on this should work to keep this list as small as possible/remo
|
|||
- Both PS/2 ports being broken doesn't need handling.
|
||||
- One PS/2 port being broken doesn't need special attention.
|
||||
- PS/2 controller doesn't need to perform a self-check.
|
||||
- These DeviceIDs never exist:
|
||||
- 0xFFFD
|
||||
- 0xFFFE
|
||||
- 0xFFFF
|
||||
- 0x01xx
|
||||
- 0x03xx
|
||||
- 0x04xx
|
||||
- Literally all PS/2 keyboards can be handeled the exact same way. We have the capability for detecting different keyboard types, I just don't bother with it because that would litreally take months to get working.
|
||||
- The device doesn't send any data while we're waiting for an `ACK`.
|
||||
|
||||
Supporting mice in the keyboard port and vice versa was a ***bad*** idea, but I do not regret it because it means we're "superior" to real world operating systems.
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -1,152 +1,108 @@
|
|||
.{memory, log, buffer, string} := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{MouseEvent} := @use("../../../libraries/intouch/src/lib.hb").events;
|
||||
.{bit0, bit1, bit2, bit3, bit4} := @use("bits.hb")
|
||||
devices := @use("devices.hb")
|
||||
controller := @use("controller.hb");
|
||||
.{Info, Port} := controller
|
||||
mouse := @use("mouse.hb")
|
||||
format_page := memory.dangling(u8)
|
||||
.{memory, log} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
mouse_buffer := 0
|
||||
keyboard_buffer := 0
|
||||
info := Info.(0)
|
||||
DeviceID := struct {value: u16}
|
||||
|
||||
send_command := fn(port: ^Port, byte: u8): void {
|
||||
tries := 3
|
||||
loop if tries == 0 break else {
|
||||
controller.send_byte(port, byte)
|
||||
loop {
|
||||
info = controller.get_info()
|
||||
if controller.has_input(info) == false {
|
||||
continue
|
||||
}
|
||||
input := controller.get_input()
|
||||
if controller.get_port(info) != port {
|
||||
if check_complete(port) == false {
|
||||
port.packet[port.packet_length] = input
|
||||
port.packet_length += 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
if input == 0xFA {
|
||||
return
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
tries -= 1
|
||||
Mouse3Button := DeviceID.(0x0)
|
||||
MouseScrollwheel := DeviceID.(0x3)
|
||||
Mouse5Button := DeviceID.(0x4)
|
||||
Spacesaver := DeviceID.(0xAB84)
|
||||
Keyboard122Key := DeviceID.(0xAB86)
|
||||
KeyboardJapaneseG := DeviceID.(0xAB90)
|
||||
KeyboardJapanesep := DeviceID.(0xAB91)
|
||||
KeyboardJapaneseA := DeviceID.(0xAB92)
|
||||
KeyboardNCDSun := DeviceID.(0xACA1)
|
||||
NoDevice := DeviceID.(0xFFFF)
|
||||
|
||||
Port := struct {exists: bool, device: DeviceID, command_queued: bool, command_queue: u8}
|
||||
|
||||
check_bit := fn(value: u8, bit: u8, state: u8): bool {
|
||||
return value >> bit & 1 == state
|
||||
}
|
||||
|
||||
ports := [Port].(.(true, NoDevice, false, 0xFF), .(true, NoDevice, false, 0xFF))
|
||||
|
||||
initialize_controller := fn(): void {
|
||||
memory.outb(0x64, 0xAD)
|
||||
memory.outb(0x64, 0xA7)
|
||||
//Disables ports to make sure that they won't interfere with the setup process.
|
||||
|
||||
loop if (memory.inb(0x64) & 1) == 0 break else memory.inb(0x60)
|
||||
//Flushes any output because apperantly that might interfere with stuff.
|
||||
|
||||
memory.outb(0x64, 0xA8)
|
||||
//Enables port 2.
|
||||
memory.outb(0x64, 0x20)
|
||||
//Gimme configuration byte.
|
||||
loop if (memory.inb(0x64) & 1) == 1 break
|
||||
ports[1].exists = @inline(check_bit, memory.inb(0x60), 5, 0)
|
||||
if ports[1].exists {
|
||||
memory.outb(0x64, 0xA7)
|
||||
}
|
||||
|
||||
loop if (memory.inb(0x64) & 1) == 0 break else memory.inb(0x60)
|
||||
//Flushes any output because apperantly that might interfere with stuff.
|
||||
|
||||
memory.outb(0x64, 0xAB)
|
||||
loop if (memory.inb(0x64) & 1) == 1 break
|
||||
ports[0].exists = memory.inb(0x60) == 0x0
|
||||
//Test port 1.
|
||||
|
||||
if ports[1].exists {
|
||||
memory.outb(0x64, 0xA9)
|
||||
loop if (memory.inb(0x64) & 1) == 1 break
|
||||
ports[1].exists = memory.inb(0x60) == 0x0
|
||||
}
|
||||
//Test port 2.
|
||||
|
||||
if (ports[0].exists | ports[1].exists) == false {
|
||||
log.error("No ports detected! No input will be processed! Cannot handle this!\0")
|
||||
}
|
||||
|
||||
if ports[0].exists {
|
||||
memory.outb(0x64, 0xAE)
|
||||
//Enables port 1.
|
||||
ports[0].command_queued = true
|
||||
}
|
||||
if ports[1].exists {
|
||||
memory.outb(0x64, 0xA8)
|
||||
//Enables port 2.
|
||||
ports[1].command_queued = true
|
||||
}
|
||||
}
|
||||
|
||||
enable_streaming := fn(port: ^Port): void {
|
||||
@inline(send_command, port, 0xF4)
|
||||
}
|
||||
|
||||
process := fn(port: ^controller.Port): void {
|
||||
if port.device.value < devices.MOUSE_5_BUTTON.value {
|
||||
event := MouseEvent.(0, 0, false, false, false)
|
||||
|
||||
event.left = bit0(port.packet[0])
|
||||
event.right = bit1(port.packet[0])
|
||||
event.middle = bit2(port.packet[0])
|
||||
|
||||
event.x_change = @intcast(port.packet[1])
|
||||
event.y_change = @intcast(port.packet[2])
|
||||
|
||||
buffer.write(MouseEvent, mouse_buffer, &event)
|
||||
} else if port.device == devices.MOUSE_INIT_1 {
|
||||
port.device.value = port.packet[0]
|
||||
if port.device != devices.MOUSE_SCROLLWHEEL {
|
||||
enable_streaming(port)
|
||||
return
|
||||
}
|
||||
port.device = devices.MOUSE_INIT_2
|
||||
} else if port.device == devices.MOUSE_INIT_2 {
|
||||
port.device.value = port.packet[0]
|
||||
} else if port.device == devices.NO_DEVICE {
|
||||
if port.packet_length == 1 {
|
||||
port.device.value = port.packet[0]
|
||||
enable_streaming(port)
|
||||
//TODO: Upgrade mouse.
|
||||
} else {
|
||||
port.device.value = port.packet[1] | port.packet[0] << 8
|
||||
enable_streaming(port)
|
||||
}
|
||||
log.info("Identified device!\0")
|
||||
log.info(string.display_int(port.device.value, format_page, 16))
|
||||
} else {
|
||||
log.info("KEY PRESSED\0")
|
||||
}
|
||||
}
|
||||
|
||||
check_complete := fn(port: ^controller.Port): bool {
|
||||
last_value := port.packet[port.packet_length - 1]
|
||||
if port.device == devices.NO_DEVICE {
|
||||
if last_value == 0 | last_value == 3 | last_value == 4 {
|
||||
return true
|
||||
} else if port.packet_length == 2 {
|
||||
return true
|
||||
}
|
||||
} else if port.device == devices.MOUSE_3_BUTTON {
|
||||
if port.packet_length == 3 return true
|
||||
} else if port.device == devices.MOUSE_SCROLLWHEEL | port.device == devices.MOUSE_5_BUTTON {
|
||||
if port.packet_length == 4 return true
|
||||
} else {
|
||||
if port.packet[0] == 0xE1 {
|
||||
if port.packet_length == 6 {
|
||||
return true
|
||||
}
|
||||
} else if port.packet[0] != 0xE0 {
|
||||
return true
|
||||
} else if port.packet_length == 2 & port.packet[1] != 0x2A & port.packet[1] != 0xB7 {
|
||||
return true
|
||||
} else if port.packet_length == 4 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
handle_input := fn(port: uint, input: u8): void {
|
||||
}
|
||||
|
||||
main := fn(): void {
|
||||
mouse_buffer = buffer.create("PS/2 Mouse\0")
|
||||
format_page = memory.alloc(u8, 1024)
|
||||
|
||||
controller.init()
|
||||
|
||||
if controller.port1.exists {
|
||||
//log.info("Port 1 exists.\0")
|
||||
controller.send_byte(@bitcast(0), 0xF4)
|
||||
}
|
||||
if controller.port2.exists {
|
||||
//controller.send_byte(&controller.port2, 0xF4)
|
||||
}
|
||||
|
||||
loop {
|
||||
info = controller.get_info()
|
||||
|
||||
if controller.timed_out(info) {
|
||||
port_info := memory.inb(0x64)
|
||||
//Enables port 1.
|
||||
if (port_info & 0x40) > 0 {
|
||||
log.error("Timeout error! Cannot handle these!\0")
|
||||
}
|
||||
if controller.check_parity(info) {
|
||||
if (port_info & 0x80) > 0 {
|
||||
log.error("Parity error! Cannot handle these!\0")
|
||||
}
|
||||
/*
|
||||
if controller.has_input(info) {
|
||||
port := controller.get_port(info)
|
||||
if port.packet_length > 0 & check_complete(port) {
|
||||
process(port)
|
||||
|
||||
if (port_info & 1) == 0 {
|
||||
if ports[0].exists & ports[0].command_queued {
|
||||
memory.outb(0x60, ports[0].command_queue)
|
||||
ports[0].command_queued = false
|
||||
}
|
||||
input := controller.get_input()
|
||||
/*if input == 0xAA & port.can_hot_plug {
|
||||
port.device = devices.NO_DEVICE
|
||||
controller.send_byte(port, 0xF4)
|
||||
}*/
|
||||
port.packet[port.packet_length] = input
|
||||
port.packet_length += 1
|
||||
if check_complete(port) {
|
||||
process(port)
|
||||
port.packet_length = 0
|
||||
if ports[1].exists & ports[1].command_queued {
|
||||
memory.outb(0x64, 0xD4)
|
||||
memory.outb(0x60, ports[1].command_queue)
|
||||
ports[1].command_queued = false
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
port := 0
|
||||
if ports[1].exists {
|
||||
port = port_info >> 5 & 1
|
||||
}
|
||||
|
||||
if ports[port].exists {
|
||||
@inline(handle_input, port, memory.inb(0x60))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -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,
|
||||
)
|
|
@ -1,8 +1,4 @@
|
|||
stn := @use("../../../libraries/stn/src/lib.hb");
|
||||
.{memory, log, buffer} := stn
|
||||
|
||||
intouch := @use("../../../libraries/intouch/src/lib.hb");
|
||||
.{KeyEvent} := intouch
|
||||
.{memory, log, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||
|
||||
send_byte := fn(byte: u8): u8 {
|
||||
memory.outb(96, byte)
|
||||
|
@ -10,31 +6,23 @@ send_byte := fn(byte: u8): u8 {
|
|||
}
|
||||
|
||||
main := fn(): int {
|
||||
buf := buffer.create("PS/2 Keyboard\0")
|
||||
buf := buffer.create("XKeyboard\0")
|
||||
_ = send_byte(238)
|
||||
log.info("PS/2 Driver Loaded\0")
|
||||
|
||||
if send_byte(238) == 238 {
|
||||
log.info("PS/2 Keyboard Echoed\0")
|
||||
}
|
||||
|
||||
if send_byte(244) == 250 {
|
||||
log.info("Enabled scanning\0")
|
||||
}
|
||||
|
||||
prev_input := 250
|
||||
loop {
|
||||
loop if (memory.inb(0x64) & 0x20) == 0x20 break
|
||||
|
||||
input := memory.inb(96)
|
||||
|
||||
if input == prev_input {
|
||||
continue
|
||||
}
|
||||
prev_input = input
|
||||
kevent := KeyEvent.(false, true, input)
|
||||
|
||||
buffer.write(KeyEvent, buf, &kevent)
|
||||
buffer.write(u8, &input, buf)
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -145,7 +145,7 @@ main := fn(): int {
|
|||
event.x_change = x_change
|
||||
event.y_change = y_change
|
||||
|
||||
buffer.write(MouseEvent, mouse_buffer, &event)
|
||||
buffer.write(MouseEvent, &event, mouse_buffer)
|
||||
}
|
||||
|
||||
return 0
|
||||
|
|
|
@ -10,12 +10,12 @@ example := fn(): void {
|
|||
color := render.light_cyan
|
||||
n := @as(u8, 1)
|
||||
loop {
|
||||
// ! dead code elimination bug
|
||||
render.clear(screen, color)
|
||||
render.sync(screen)
|
||||
if color.b == 255 | color.b == 0 {
|
||||
if (color.b & 255) == 255 | (color.b & 255) == 0 {
|
||||
n = -n
|
||||
}
|
||||
color.b += n
|
||||
}
|
||||
return
|
||||
}
|
72
sysdata/programs/render_example/src/examples/cube.hb
Normal file
72
sysdata/programs/render_example/src/examples/cube.hb
Normal 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
|
||||
}
|
26
sysdata/programs/render_example/src/examples/gravity.hb
Normal file
26
sysdata/programs/render_example/src/examples/gravity.hb
Normal 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
|
||||
}
|
|
@ -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
|
||||
}
|
17
sysdata/programs/render_example/src/examples/scale.hb
Normal file
17
sysdata/programs/render_example/src/examples/scale.hb
Normal 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)
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ example := fn(): void {
|
|||
|
||||
bottom := buf + msg_len
|
||||
|
||||
memory.copy(u8, msg, buf, msg_len)
|
||||
@inline(memory.copy, u8, msg, buf, msg_len)
|
||||
cursor := bottom
|
||||
|
||||
draw_window(window, font, buf, cursor)
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -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
|
||||
}
|
30
sysdata/programs/tests/src/main.hb
Normal file
30
sysdata/programs/tests/src/main.hb
Normal 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
|
||||
}
|
|
@ -3,9 +3,8 @@
|
|||
default_entry = 1
|
||||
timeout = 0
|
||||
verbose = false
|
||||
# interface_resolution = "1920x1080x24"
|
||||
interface_resolution = "1024x768x24"
|
||||
# interface_resolution = "640x480x24"
|
||||
interface_resolution = "1600x900x24"
|
||||
# interface_resolution = "640x480x32"
|
||||
# Terminal related settings
|
||||
# term_wallpaper = "boot:///background.bmp"
|
||||
term_wallpaper = "boot:///empty-background.bmp"
|
||||
|
@ -16,29 +15,53 @@ comment = "Default AbleOS boot entry."
|
|||
protocol = "limine"
|
||||
kernel_path = "boot:///kernel_${ARCH}"
|
||||
kernel_cmdline = ""
|
||||
# resolution = "1920x1080x24"
|
||||
resolution = "1024x768x24"
|
||||
# resolution = "640x480x24"
|
||||
# resolution = "640x480x32"
|
||||
resolution = "1600x900x24"
|
||||
|
||||
[boot.limine.ableos.modules]
|
||||
|
||||
# [boot.limine.ableos.modules.render_example]
|
||||
# path = "boot:///render_example.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.horizon]
|
||||
# path = "boot:///horizon.hbf"
|
||||
# [boot.limine.ableos.modules.mouse_driver]
|
||||
# path = "boot:///mouse_driver.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.ps2_mouse_driver]
|
||||
# path = "boot:///ps2_mouse_driver.hbf"
|
||||
# [boot.limine.ableos.modules.serial_driver]
|
||||
# path = "boot:///serial_driver.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.serial_driver_test]
|
||||
# path = "boot:///serial_driver_test.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.horizon]
|
||||
path = "boot:///horizon.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.horizon_testing_program]
|
||||
# path = "boot:///horizon_testing_program.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.dt_buffer_test]
|
||||
# path = "boot:///dt_buffer_test.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.svga_driver]
|
||||
# path = "boot:///svga_driver.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.ps2_keyboard_driver]
|
||||
# path = "boot:///ps2_keyboard_driver.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.ps2_driver]
|
||||
path = "boot:///ps2_driver.hbf"
|
||||
# [boot.limine.ableos.modules.filesystem_fat32]
|
||||
# [boot.limine.ableos.modules.ps2_keyboard_driv
|
||||
# path = "boot:///filesystem_fat32.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.sunset_client]
|
||||
# path = "boot:///sunset_client.hbf"
|
||||
# [boot.limine.ableos.modules.pumpkin_print]
|
||||
# path = "boot:///pumpkin_print.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.sunset_server]
|
||||
# path = "boot:///sunset_server.hbf"
|
||||
[boot.limine.ableos.modules.ps2_mouse_driver]
|
||||
path = "boot:///ps2_mouse_driver.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.ps2_driver]
|
||||
# path = "boot:///ps2_driver.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.app_bar]
|
||||
# path = "boot:///app_bar.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.test_abc]
|
||||
# path = "boot:///test_abc.hbf"
|
||||
|
|
40
todo.md
40
todo.md
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue