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