Compare commits
No commits in common. "master" and "master" have entirely different histories.
|
@ -1,3 +1,3 @@
|
||||||
[alias]
|
[alias]
|
||||||
repbuild = "run --manifest-path ./repbuild/Cargo.toml -- "
|
repbuild = "run --manifest-path ./repbuild/Cargo.toml -r --"
|
||||||
dev = "run --manifest-path ./dev/Cargo.toml -r --"
|
dev = "run --manifest-path ./dev/Cargo.toml -r --"
|
||||||
|
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -1,6 +1,4 @@
|
||||||
{
|
{
|
||||||
"editor.insertSpaces": false,
|
|
||||||
"editor.detectIndentation": false,
|
|
||||||
"rust-analyzer.checkOnSave.allTargets": false,
|
"rust-analyzer.checkOnSave.allTargets": false,
|
||||||
"rust-analyzer.showUnlinkedFileNotification": false,
|
"rust-analyzer.showUnlinkedFileNotification": false,
|
||||||
"C_Cpp.errorSquiggles": "disabled"
|
"C_Cpp.errorSquiggles": "disabled"
|
||||||
|
|
591
Cargo.lock
generated
591
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,15 +13,30 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.21"
|
version = "0.2.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-tzdata"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.95"
|
version = "1.0.91"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
|
@ -65,6 +80,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 +97,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.6"
|
version = "1.1.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
|
checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
@ -87,19 +111,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-queue"
|
name = "chrono"
|
||||||
version = "0.3.12"
|
version = "0.4.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
|
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||||
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.21"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
|
@ -129,17 +173,6 @@ dependencies = [
|
||||||
"logos",
|
"logos",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "displaydoc"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -164,6 +197,7 @@ checksum = "05669f8e7e2d7badc545c513710f0eba09c2fbef683eb859fd79c46c355048e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"chrono",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -175,9 +209,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.4"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
|
@ -201,9 +235,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.2"
|
version = "0.14.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
|
@ -213,174 +253,78 @@ 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#d1bc70892b442376138e854450b0f423302962ef"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#faa8dd2e6fabe2e0e4a375e677171856da491c61"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hblang"
|
name = "hblang"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d1bc70892b442376138e854450b0f423302962ef"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#faa8dd2e6fabe2e0e4a375e677171856da491c61"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown 0.15.0",
|
||||||
"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#d1bc70892b442376138e854450b0f423302962ef"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#faa8dd2e6fabe2e0e4a375e677171856da491c61"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hbbytecode",
|
"hbbytecode",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "iana-time-zone"
|
||||||
version = "1.5.0"
|
version = "0.1.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
|
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"android_system_properties",
|
||||||
"yoke",
|
"core-foundation-sys",
|
||||||
"zerofrom",
|
"iana-time-zone-haiku",
|
||||||
"zerovec",
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_locid"
|
name = "iana-time-zone-haiku"
|
||||||
version = "1.5.0"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"cc",
|
||||||
"litemap",
|
|
||||||
"tinystr",
|
|
||||||
"writeable",
|
|
||||||
"zerovec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_locid_transform"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
|
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
"icu_locid",
|
|
||||||
"icu_locid_transform_data",
|
|
||||||
"icu_provider",
|
|
||||||
"tinystr",
|
|
||||||
"zerovec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_locid_transform_data"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_normalizer"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
|
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
"icu_collections",
|
|
||||||
"icu_normalizer_data",
|
|
||||||
"icu_properties",
|
|
||||||
"icu_provider",
|
|
||||||
"smallvec",
|
|
||||||
"utf16_iter",
|
|
||||||
"utf8_iter",
|
|
||||||
"write16",
|
|
||||||
"zerovec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_normalizer_data"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_properties"
|
|
||||||
version = "1.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
|
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
"icu_collections",
|
|
||||||
"icu_locid_transform",
|
|
||||||
"icu_properties_data",
|
|
||||||
"icu_provider",
|
|
||||||
"tinystr",
|
|
||||||
"zerovec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_properties_data"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_provider"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
|
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
"icu_locid",
|
|
||||||
"icu_provider_macros",
|
|
||||||
"stable_deref_trait",
|
|
||||||
"tinystr",
|
|
||||||
"writeable",
|
|
||||||
"yoke",
|
|
||||||
"zerofrom",
|
|
||||||
"zerovec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_provider_macros"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "1.0.3"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
|
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"idna_adapter",
|
"unicode-bidi",
|
||||||
"smallvec",
|
"unicode-normalization",
|
||||||
"utf8_iter",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "idna_adapter"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
|
|
||||||
dependencies = [
|
|
||||||
"icu_normalizer",
|
|
||||||
"icu_properties",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.7.0"
|
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 = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.15.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.72"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -390,9 +334,8 @@ dependencies = [
|
||||||
"aarch64-cpu",
|
"aarch64-cpu",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"hashbrown",
|
"hashbrown 0.15.0",
|
||||||
"hbvm",
|
"hbvm",
|
||||||
"ktest_macro",
|
|
||||||
"limine",
|
"limine",
|
||||||
"log",
|
"log",
|
||||||
"sbi",
|
"sbi",
|
||||||
|
@ -401,18 +344,10 @@ dependencies = [
|
||||||
"uart_16550",
|
"uart_16550",
|
||||||
"versioning",
|
"versioning",
|
||||||
"x2apic",
|
"x2apic",
|
||||||
"x86_64 0.15.2",
|
"x86_64 0.15.1",
|
||||||
"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 +356,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.169"
|
version = "0.2.161"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "limine"
|
name = "limine"
|
||||||
|
@ -431,12 +366,6 @@ version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02034f8f6b3e7bf050f310fbaf6db0018b8e54b75598d0a4c97172054752fede"
|
checksum = "02034f8f6b3e7bf050f310fbaf6db0018b8e54b75598d0a4c97172054752fede"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "litemap"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
@ -455,18 +384,18 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "logos"
|
name = "logos"
|
||||||
version = "0.14.4"
|
version = "0.14.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458"
|
checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"logos-derive",
|
"logos-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "logos-codegen"
|
name = "logos-codegen"
|
||||||
version = "0.14.4"
|
version = "0.14.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f"
|
checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"beef",
|
"beef",
|
||||||
"fnv",
|
"fnv",
|
||||||
|
@ -479,9 +408,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "logos-derive"
|
name = "logos-derive"
|
||||||
version = "0.14.4"
|
version = "0.14.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d"
|
checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"logos-codegen",
|
"logos-codegen",
|
||||||
]
|
]
|
||||||
|
@ -492,6 +421,15 @@ version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.2"
|
version = "1.20.2"
|
||||||
|
@ -512,18 +450,18 @@ 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",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.38"
|
version = "1.0.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -546,6 +484,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 +533,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 +550,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.20"
|
version = "0.23.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
|
checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -608,9 +565,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.10.1"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
|
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
|
@ -625,9 +582,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.19"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sbi"
|
name = "sbi"
|
||||||
|
@ -643,24 +600,24 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.24"
|
version = "1.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.217"
|
version = "1.0.213"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.217"
|
version = "1.0.213"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -706,12 +663,6 @@ dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "stable_deref_trait"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "str-reader"
|
name = "str-reader"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -726,9 +677,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.93"
|
version = "2.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
|
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -736,25 +687,19 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "tinyvec"
|
||||||
version = "0.13.1"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"tinyvec_macros",
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinystr"
|
name = "tinyvec_macros"
|
||||||
version = "0.7.6"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
"zerovec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tock-registers"
|
name = "tock-registers"
|
||||||
|
@ -798,9 +743,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",
|
||||||
|
@ -808,10 +753,25 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-bidi"
|
||||||
version = "1.0.14"
|
version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
|
@ -827,9 +787,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ureq"
|
name = "ureq"
|
||||||
version = "2.12.1"
|
version = "2.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d"
|
checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"log",
|
"log",
|
||||||
|
@ -842,27 +802,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.4"
|
version = "2.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
|
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf16_iter"
|
|
||||||
version = "1.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf8_iter"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "versioning"
|
name = "versioning"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -884,14 +832,78 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "wasm-bindgen"
|
||||||
version = "0.26.7"
|
version = "0.2.95"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e"
|
checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.26.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
@ -967,25 +979,13 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.21"
|
version = "0.6.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6f5bb5257f2407a5425c6e749bfd9692192a73e70a6060516ac04f889087d68"
|
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "write16"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "writeable"
|
|
||||||
version = "0.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x2apic"
|
name = "x2apic"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -996,7 +996,7 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"paste",
|
"paste",
|
||||||
"raw-cpuid 10.7.0",
|
"raw-cpuid 10.7.0",
|
||||||
"x86_64 0.14.13",
|
"x86_64 0.14.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1012,9 +1012,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.14.13"
|
version = "0.14.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c101112411baafbb4bf8d33e4c4a80ab5b02d74d2612331c61e8192fc9710491"
|
checksum = "96cb6fd45bfeab6a5055c5bffdb08768bd0c069f1d946debe585bbb380a7c062"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
|
@ -1024,9 +1024,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.15.2"
|
version = "0.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae"
|
checksum = "4bc79523af8abf92fb1a970c3e086c5a343f6bcc1a0eb890f575cbb3b45743df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
|
@ -1042,75 +1042,8 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "yoke"
|
|
||||||
version = "0.7.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"stable_deref_trait",
|
|
||||||
"yoke-derive",
|
|
||||||
"zerofrom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "yoke-derive"
|
|
||||||
version = "0.7.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"synstructure",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerofrom"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
|
|
||||||
dependencies = [
|
|
||||||
"zerofrom-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerofrom-derive"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"synstructure",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerovec"
|
|
||||||
version = "0.10.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
|
|
||||||
dependencies = [
|
|
||||||
"yoke",
|
|
||||||
"zerofrom",
|
|
||||||
"zerovec-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerovec-derive"
|
|
||||||
version = "0.10.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
# Style Guide
|
|
||||||
This style guide has two modes that a guideline may be.
|
|
||||||
|
|
||||||
`strict` means that prs will be rejected if they do not follow the guideline.
|
|
||||||
|
|
||||||
`loose` means that a pr would be accepted but should later be fixed.
|
|
||||||
|
|
||||||
## Empty Functions | loose
|
|
||||||
Empty functions are typically a sign of an unfinished program or driver.
|
|
||||||
|
|
||||||
In cases where there is a clear reason to have an empty function it will be allowed.
|
|
||||||
For example FakeAlloc is only empty functions because it is a example of an the allocator api.
|
|
||||||
|
|
||||||
### Allowed
|
|
||||||
```rust
|
|
||||||
/// in example.hb
|
|
||||||
a := fn(): void {}
|
|
||||||
```
|
|
||||||
### Not Allowed
|
|
||||||
```rust
|
|
||||||
/// in fat32.hb
|
|
||||||
a := fn(): void {}
|
|
||||||
```
|
|
||||||
## Magic Functions | loose
|
|
||||||
'Magic functions' are what I am calling small helper functions that do one or two things.
|
|
||||||
### Example
|
|
||||||
```rust
|
|
||||||
a := null
|
|
||||||
magic_a := fn(){
|
|
||||||
a = 10
|
|
||||||
}
|
|
||||||
```
|
|
||||||
The exact policy I want to have here is a bit fuzzy. I think that functions like this are nice in certain situations and not in others.
|
|
||||||
Regardless of if you use them or not, put a comment above the function explaining rational.
|
|
||||||
|
|
||||||
|
|
||||||
## Magic Numbers | loose
|
|
||||||
The policy on magic numbers is make them const and have a comment above them. Typically linking to a source of information about the magic number.
|
|
||||||
|
|
||||||
This helps cut down on magic numbers while making acceptable names and atleast half assed documentation.
|
|
||||||
|
|
||||||
Constants are inlined anyways, so its the same thing in the binary.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// The standard vga port is mapped at 0xB8000
|
|
||||||
$VGA_PTR := 0xB8000
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tabs Vs Spaces | strict
|
|
||||||
I prefer for hblang code to use hard tabs.
|
|
||||||
|
|
||||||
The rational behind this is that a tab is `1 Indent` which some developers might want to be various different sizes when displayed
|
|
||||||
|
|
||||||
Soft tabs do not allow this user/editor specific as soft tabs always become spaces.
|
|
||||||
|
|
||||||
Bottom line is this is an accessibility feature.
|
|
||||||
|
|
||||||
There are some samples below.
|
|
||||||
```
|
|
||||||
\t means hard tab
|
|
||||||
\n means new line
|
|
||||||
\0x20 means space
|
|
||||||
```
|
|
||||||
|
|
||||||
### Allowed
|
|
||||||
```rust
|
|
||||||
if x == y {\n
|
|
||||||
\tlog(z)\n
|
|
||||||
}\n
|
|
||||||
```
|
|
||||||
|
|
||||||
### Not Allowed
|
|
||||||
```rust
|
|
||||||
if x == y {\n
|
|
||||||
\0x20\0x20\0x20\0x20log(z)\n
|
|
||||||
}\n
|
|
||||||
```
|
|
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", "alloc", "disasm"
|
"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 }
|
||||||
|
@ -27,6 +24,10 @@ version = "0.3"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["alloc", "nightly"]
|
features = ["alloc", "nightly"]
|
||||||
|
|
||||||
|
# [dependencies.clparse]
|
||||||
|
# git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
|
# default-features = false
|
||||||
|
|
||||||
[dependencies.derive_more]
|
[dependencies.derive_more]
|
||||||
version = "1"
|
version = "1"
|
||||||
default-features = false
|
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,86 +0,0 @@
|
||||||
extern crate proc_macro;
|
|
||||||
extern crate quote;
|
|
||||||
extern crate syn;
|
|
||||||
|
|
||||||
use {
|
|
||||||
proc_macro::TokenStream,
|
|
||||||
quote::quote,
|
|
||||||
syn::{parse::Parse, parse_macro_input, Expr, ItemFn, Token}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct KtestInput {
|
|
||||||
lhs: Expr,
|
|
||||||
_comma: Token![,],
|
|
||||||
rhs: Expr,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for KtestInput {
|
|
||||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
||||||
Ok(Self {
|
|
||||||
lhs: input.parse()?,
|
|
||||||
_comma: input.parse()?,
|
|
||||||
rhs: input.parse()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn ktest_eq(item: TokenStream) -> TokenStream {
|
|
||||||
let input = parse_macro_input!(item as KtestInput);
|
|
||||||
|
|
||||||
let lhs = input.lhs;
|
|
||||||
let rhs = input.rhs;
|
|
||||||
|
|
||||||
let out = quote! {
|
|
||||||
if #lhs != #rhs {
|
|
||||||
return Err(name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TokenStream::from(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn ktest_neq(item: TokenStream) -> TokenStream {
|
|
||||||
let input = parse_macro_input!(item as KtestInput);
|
|
||||||
|
|
||||||
let lhs = input.lhs;
|
|
||||||
let rhs = input.rhs;
|
|
||||||
|
|
||||||
let out = quote! {
|
|
||||||
if #lhs == #rhs {
|
|
||||||
return Err(name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TokenStream::from(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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 test_string = test_name.to_string();
|
|
||||||
let static_var_name = syn::Ident::new(
|
|
||||||
&format!("__ktest_{}", test_name).to_uppercase(),
|
|
||||||
test_name.span(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let block = &input.block;
|
|
||||||
let out = quote! {
|
|
||||||
#[cfg(feature = "ktest")]
|
|
||||||
fn #test_name() -> Result<String, String> {
|
|
||||||
use crate::alloc::string::ToString;
|
|
||||||
let name = #test_string.to_string();
|
|
||||||
|
|
||||||
#block
|
|
||||||
|
|
||||||
return Ok(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "ktest")]
|
|
||||||
#[unsafe(link_section = ".note.ktest")]
|
|
||||||
#[used]
|
|
||||||
pub static #static_var_name: fn() -> Result<String, String> = #test_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
TokenStream::from(out)
|
|
||||||
}
|
|
|
@ -6,11 +6,6 @@ SECTIONS
|
||||||
.text.boot : { *(.text.boot) }
|
.text.boot : { *(.text.boot) }
|
||||||
.text : { *(.text) }
|
.text : { *(.text) }
|
||||||
.data : { *(.data) }
|
.data : { *(.data) }
|
||||||
.note.ktest : {
|
|
||||||
__ktest_start = .;
|
|
||||||
*(.note.ktest)
|
|
||||||
__ktest_end = .;
|
|
||||||
}
|
|
||||||
.rodata : { *(.rodata) }
|
.rodata : { *(.rodata) }
|
||||||
.bss : {
|
.bss : {
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
|
|
|
@ -38,15 +38,7 @@ 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)
|
||||||
|
|
|
@ -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,52 +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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
fn interrupt(interrupt_type: Interrupt) {
|
|
||||||
use crate::{arch::INTERRUPT_LIST, kmain::EXECUTOR};
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
EXECUTOR.send_interrupt(interrupt_type as u8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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::{
|
||||||
|
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
|
||||||
use crate::{
|
service_definition_service::sds_msg_handler,
|
||||||
holeybytes::{
|
|
||||||
kernel_services::{
|
|
||||||
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
|
|
||||||
service_definition_service::sds_msg_handler,
|
|
||||||
},
|
|
||||||
ExecThread,
|
|
||||||
},
|
|
||||||
kmain::EXECUTOR,
|
|
||||||
task::Executor,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
@ -33,7 +24,7 @@ unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn handler(vm: &mut Vm, pid: &usize) {
|
pub fn handler(vm: &mut Vm) {
|
||||||
let ecall_number = vm.registers[2].cast::<u64>();
|
let ecall_number = vm.registers[2].cast::<u64>();
|
||||||
|
|
||||||
match ecall_number {
|
match ecall_number {
|
||||||
|
@ -67,10 +58,10 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
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 => {
|
||||||
|
@ -80,10 +71,6 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
let length = vm.registers[5].cast::<u64>() as usize;
|
let length = vm.registers[5].cast::<u64>() as usize;
|
||||||
trace!("IPC address: {:?}", mem_addr);
|
trace!("IPC address: {:?}", mem_addr);
|
||||||
|
|
||||||
unsafe { LazyCell::<Executor>::get_mut(&mut EXECUTOR) }
|
|
||||||
.unwrap()
|
|
||||||
.send_buffer(buffer_id as usize);
|
|
||||||
|
|
||||||
match buffer_id {
|
match buffer_id {
|
||||||
0 => match sds_msg_handler(vm, mem_addr, length) {
|
0 => match sds_msg_handler(vm, mem_addr, length) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
|
@ -156,43 +143,6 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
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();
|
||||||
|
@ -213,6 +163,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
let buffer_id = vm.registers[3].cast::<u64>();
|
let buffer_id = vm.registers[3].cast::<u64>();
|
||||||
let map_ptr = vm.registers[4].cast::<u64>();
|
let map_ptr = vm.registers[4].cast::<u64>();
|
||||||
let max_length = vm.registers[5].cast::<u64>();
|
let max_length = vm.registers[5].cast::<u64>();
|
||||||
|
|
||||||
let mut buffs = IPC_BUFFERS.lock();
|
let mut buffs = IPC_BUFFERS.lock();
|
||||||
let buff: &mut IpcBuffer = match buffs.get_mut(&buffer_id) {
|
let buff: &mut IpcBuffer = match buffs.get_mut(&buffer_id) {
|
||||||
Some(buff) => buff,
|
Some(buff) => buff,
|
||||||
|
@ -231,7 +182,7 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
} 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);
|
||||||
|
@ -246,28 +197,6 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
vm.registers[3] = x
|
vm.registers[3] = x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6 => {
|
|
||||||
// Wait till interrupt
|
|
||||||
use crate::kmain::EXECUTOR;
|
|
||||||
let interrupt_type = vm.registers[3].cast::<u8>();
|
|
||||||
debug!("Interrupt subscribed: {}", interrupt_type);
|
|
||||||
unsafe {
|
|
||||||
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
|
|
||||||
.unwrap()
|
|
||||||
.interrupt_subscribe(*pid, interrupt_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
7 => {
|
|
||||||
// Wait till buffer
|
|
||||||
use crate::kmain::EXECUTOR;
|
|
||||||
let buffer_id = vm.registers[3].cast::<u64>() as usize;
|
|
||||||
debug!("Buffer subscribed: {}", buffer_id);
|
|
||||||
unsafe {
|
|
||||||
LazyCell::<Executor>::get_mut(&mut EXECUTOR)
|
|
||||||
.unwrap()
|
|
||||||
.buffer_subscribe(*pid, buffer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
|
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,24 +74,29 @@ pub fn memory_msg_handler(
|
||||||
let msg_type = msg_vec[0];
|
let msg_type = msg_vec[0];
|
||||||
match msg_type {
|
match msg_type {
|
||||||
0 => unsafe {
|
0 => unsafe {
|
||||||
let page_count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap()) as usize;
|
let page_count = msg_vec[1];
|
||||||
|
|
||||||
let ptr = alloc(Layout::from_size_align_unchecked(page_count * 4096, 1));
|
let ptr = alloc(Layout::from_size_align_unchecked(
|
||||||
|
page_count as usize * 4096,
|
||||||
|
8,
|
||||||
|
));
|
||||||
|
|
||||||
log::debug!("Allocating {} pages @ {:?}", page_count, ptr);
|
log::debug!("Allocating {} pages @ {:x}", page_count, ptr as u64);
|
||||||
|
|
||||||
vm.registers[1] = hbvm::value::Value(ptr as u64);
|
vm.registers[1] = hbvm::value::Value(ptr as u64);
|
||||||
|
log::debug!("Kernel ptr: {:x}", ptr as u64);
|
||||||
},
|
},
|
||||||
|
|
||||||
1 => unsafe {
|
1 => unsafe {
|
||||||
let page_count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap()) as usize;
|
let page_count = msg_vec[1];
|
||||||
|
|
||||||
let mptr = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as *mut u8;
|
let mptr_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap();
|
||||||
log::debug!("Deallocating {} pages @ {:?}", page_count, mptr);
|
let mptr: u64 = u64::from_le_bytes(mptr_raw);
|
||||||
|
log::debug!("Deallocating {} pages @ {:x}", page_count, mptr);
|
||||||
|
|
||||||
dealloc(
|
dealloc(
|
||||||
mptr,
|
mptr as *mut u8,
|
||||||
Layout::from_size_align_unchecked(page_count * 4096, 1),
|
Layout::from_size_align_unchecked(page_count as usize * 4096, 8),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
2 => {
|
2 => {
|
||||||
|
@ -91,21 +122,18 @@ pub fn memory_msg_handler(
|
||||||
log::debug!(" {} pages", page_count);
|
log::debug!(" {} pages", page_count);
|
||||||
}
|
}
|
||||||
4 => unsafe {
|
4 => unsafe {
|
||||||
let count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap_unchecked()) as usize;
|
let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
|
||||||
let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8;
|
let src = u64::from_le_bytes(msg_vec[5..13].try_into().unwrap_unchecked()) as *const u8;
|
||||||
let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8;
|
let dest = u64::from_le_bytes(msg_vec[13..21].try_into().unwrap_unchecked()) as *mut u8;
|
||||||
debug_assert!(src.addr() & 0xFFFF000000000000 != 0);
|
|
||||||
debug_assert!(dest.addr() & 0xFFFF000000000000 != 0);
|
|
||||||
src.copy_to_nonoverlapping(dest, count);
|
src.copy_to_nonoverlapping(dest, count);
|
||||||
},
|
},
|
||||||
5 => unsafe {
|
5 => unsafe {
|
||||||
let count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap_unchecked()) as usize;
|
let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
|
||||||
let size = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as usize;
|
let size = u32::from_le_bytes(msg_vec[5..9].try_into().unwrap_unchecked()) as usize;
|
||||||
let src =
|
let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8;
|
||||||
u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *const u8;
|
let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8;
|
||||||
let dest = u64::from_le_bytes(msg_vec[25..33].try_into().unwrap_unchecked()) as *mut u8;
|
|
||||||
debug_assert!(src.addr() & 0xFFFF000000000000 != 0);
|
|
||||||
debug_assert!(dest.addr() & 0xFFFF000000000000 != 0);
|
|
||||||
memset(dest, src, count, size);
|
memset(dest, src, count, size);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -15,10 +15,8 @@ fn calc_start_of_page(ptr: u64) -> u64 {
|
||||||
panic!("unaligned");
|
panic!("unaligned");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
// TODO: map page aligned segments of memory into a table or some sort here
|
// TODO: map page aligned segments of memory into a table or some sort here
|
||||||
logger: hbvm::mem::InstrLogger,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
|
@ -58,11 +56,4 @@ impl hbvm::mem::Memory for Memory {
|
||||||
unsafe fn prog_read<T: Copy>(&mut self, addr: Address) -> T {
|
unsafe fn prog_read<T: Copy>(&mut self, addr: Address) -> T {
|
||||||
(addr.get() as *const T).read()
|
(addr.get() as *const T).read()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn log_instr(&mut self, _at: Address, _regs: &[hbvm::value::Value]) {
|
|
||||||
// log::debug!("exec: [{:02x}] {}", at.get(), unsafe {
|
|
||||||
// self.logger.display_instr(at, regs)
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod ecah;
|
mod ecah;
|
||||||
pub mod kernel_services;
|
mod kernel_services;
|
||||||
mod mem;
|
mod mem;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
@ -36,7 +36,7 @@ impl ExecThread {
|
||||||
|
|
||||||
pub unsafe fn new(program: &[u8], entrypoint: Address) -> Self {
|
pub unsafe fn new(program: &[u8], entrypoint: Address) -> Self {
|
||||||
let mut vm = Vm::new(
|
let mut vm = Vm::new(
|
||||||
mem::Memory::default(),
|
mem::Memory {},
|
||||||
Address::new(program.as_ptr() as u64 + entrypoint.get()),
|
Address::new(program.as_ptr() as u64 + entrypoint.get()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -65,12 +65,7 @@ impl<'p> Future for ExecThread {
|
||||||
return Poll::Ready(Err(err));
|
return Poll::Ready(Err(err));
|
||||||
}
|
}
|
||||||
Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
|
Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
|
||||||
Ok(VmRunOk::Ecall) => ecah::handler(
|
Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm),
|
||||||
&mut self.vm,
|
|
||||||
cx.ext()
|
|
||||||
.downcast_ref()
|
|
||||||
.expect("PID did not exist in Context"),
|
|
||||||
),
|
|
||||||
Ok(VmRunOk::Timer) => (),
|
Ok(VmRunOk::Timer) => (),
|
||||||
Ok(VmRunOk::Breakpoint) => {
|
Ok(VmRunOk::Breakpoint) => {
|
||||||
log::error!(
|
log::error!(
|
||||||
|
|
|
@ -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,18 +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,
|
|
||||||
log::info,
|
|
||||||
};
|
|
||||||
info!("Running tests");
|
|
||||||
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:?}");
|
||||||
|
|
||||||
|
@ -79,26 +64,14 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
"Graphics front ptr {:?}",
|
"Graphics front ptr {:?}",
|
||||||
fb1.address.as_ptr().unwrap() as *const u8
|
fb1.address.as_ptr().unwrap() as *const u8
|
||||||
);
|
);
|
||||||
log::info!("Started AbleOS");
|
|
||||||
|
|
||||||
|
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];
|
||||||
|
@ -119,30 +92,27 @@ 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 {
|
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());
|
||||||
|
|
||||||
executor.run();
|
executor.run();
|
||||||
};
|
};
|
||||||
|
|
||||||
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)
|
||||||
|
@ -160,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,51 +0,0 @@
|
||||||
pub use ktest_macro::*;
|
|
||||||
|
|
||||||
use {
|
|
||||||
alloc::string::String,
|
|
||||||
log::{error, info},
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
static __ktest_start: fn() -> Result<String, String>;
|
|
||||||
static __ktest_end: fn() -> Result<String, String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement ktest for arm and riscv (Later problems, see below)
|
|
||||||
// Allow for arch specific tests (Leave for now)
|
|
||||||
// Should panic tests
|
|
||||||
// Test specific panic handler
|
|
||||||
pub fn test_main() {
|
|
||||||
unsafe {
|
|
||||||
let mut current_test = &__ktest_start as *const fn() -> Result<String, String>;
|
|
||||||
let test_end = &__ktest_end as *const fn() -> Result<String, String>;
|
|
||||||
|
|
||||||
let mut pass = 0;
|
|
||||||
let mut fail = 0;
|
|
||||||
|
|
||||||
while current_test < test_end {
|
|
||||||
let test_fn = *current_test;
|
|
||||||
|
|
||||||
let test_name = test_fn();
|
|
||||||
match test_name {
|
|
||||||
Ok(name) => {
|
|
||||||
info!("Test: {} passed", name);
|
|
||||||
pass += 1;
|
|
||||||
},
|
|
||||||
Err(name) => {
|
|
||||||
error!("Test: {} failed", name);
|
|
||||||
fail += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_test = current_test.add(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
info!("{}/{} tests passed", pass, pass + fail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ktest]
|
|
||||||
pub fn trivial_assertion() {
|
|
||||||
ktest_eq!(1, 1);
|
|
||||||
ktest_neq!(0, 1);
|
|
||||||
}
|
|
|
@ -2,21 +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,
|
||||||
local_waker,
|
|
||||||
context_ext,
|
|
||||||
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;
|
||||||
|
@ -34,9 +33,6 @@ mod memory;
|
||||||
mod task;
|
mod task;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
#[allow(improper_ctypes, non_upper_case_globals)]
|
|
||||||
mod ktest;
|
|
||||||
|
|
||||||
use versioning::Version;
|
use versioning::Version;
|
||||||
|
|
||||||
/// Kernel's version
|
/// Kernel's version
|
||||||
|
@ -49,7 +45,6 @@ pub const VERSION: Version = Version {
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[cfg(target_os = "none")]
|
#[cfg(target_os = "none")]
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||||
use alloc::string::ToString;
|
|
||||||
arch::register_dump();
|
arch::register_dump();
|
||||||
|
|
||||||
if let Some(loc) = info.location() {
|
if let Some(loc) = info.location() {
|
||||||
|
@ -61,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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,26 +36,13 @@ impl log::Log for Logger {
|
||||||
Level::Debug => "25",
|
Level::Debug => "25",
|
||||||
Level::Trace => "103",
|
Level::Trace => "103",
|
||||||
};
|
};
|
||||||
let module = record
|
let module = record.module_path().unwrap_or_default();
|
||||||
.module_path()
|
let line = record.line().unwrap_or_default();
|
||||||
.unwrap_or_default()
|
crate::arch::log(format_args!(
|
||||||
.rsplit_once(':')
|
"\x1b[38;5;{lvl_color}m{lvl}\x1b[0m [{module}:{line}]: {}\r\n",
|
||||||
.unwrap_or_default()
|
record.args(),
|
||||||
.1;
|
))
|
||||||
if module == "" {
|
.expect("write to serial console");
|
||||||
crate::arch::log(format_args!(
|
|
||||||
"\x1b[38;5;{lvl_color}m{lvl}\x1b[0m: {}\r\n",
|
|
||||||
record.args(),
|
|
||||||
))
|
|
||||||
.expect("write to serial console");
|
|
||||||
} else {
|
|
||||||
let line = record.line().unwrap_or_default();
|
|
||||||
crate::arch::log(format_args!(
|
|
||||||
"\x1b[38;5;{lvl_color}m{lvl}\x1b[0m [{module}:{line}]: {}\r\n",
|
|
||||||
record.args(),
|
|
||||||
))
|
|
||||||
.expect("write to serial console");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
use {
|
use {
|
||||||
alloc::{
|
alloc::{boxed::Box, sync::Arc},
|
||||||
boxed::Box,
|
|
||||||
collections::{BTreeMap, BTreeSet},
|
|
||||||
sync::Arc,
|
|
||||||
},
|
|
||||||
core::{
|
core::{
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||||
task::{Context, ContextBuilder, Poll, RawWaker, RawWakerVTable, Waker},
|
|
||||||
},
|
},
|
||||||
crossbeam_queue::SegQueue,
|
crossbeam_queue::SegQueue,
|
||||||
slab::Slab,
|
slab::Slab,
|
||||||
|
@ -19,6 +14,7 @@ pub fn yield_now() -> impl Future<Output = ()> {
|
||||||
impl Future for YieldNow {
|
impl Future for YieldNow {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
if self.0 {
|
if self.0 {
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
|
@ -33,184 +29,150 @@ pub fn yield_now() -> impl Future<Output = ()> {
|
||||||
YieldNow(false)
|
YieldNow(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Process: Future<Output = ()> + Send {}
|
pub struct Executor<F: Future<Output = ()> + Send> {
|
||||||
impl<T: Future<Output = ()> + Send> Process for T {}
|
tasks: Slab<Task<F>>,
|
||||||
|
task_queue: Arc<TaskQueue>,
|
||||||
pub struct Executor {
|
|
||||||
tasks: Slab<Task>,
|
|
||||||
task_queue: Arc<SegQueue<usize>>,
|
|
||||||
interrupt_lookup: [Option<usize>; u8::MAX as usize],
|
|
||||||
buffer_lookup: BTreeMap<usize, BTreeSet<usize>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(SegQueue::new()),
|
task_queue: Arc::new(TaskQueue::new()),
|
||||||
interrupt_lookup: [None; u8::MAX as usize],
|
|
||||||
buffer_lookup: BTreeMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(&mut self, future: Pin<Box<dyn Process>>) -> usize {
|
#[inline]
|
||||||
let id = self.tasks.insert(Task::new(future));
|
pub fn spawn(&mut self, future: F) {
|
||||||
self.task_queue.push(id);
|
self.task_queue
|
||||||
|
.queue
|
||||||
id
|
.push(self.tasks.insert(Task::new(future)));
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pause(&self, id: usize) {
|
|
||||||
if let Some(task) = self.tasks.get(id) {
|
|
||||||
task.set_paused(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unpause(&self, id: usize) {
|
|
||||||
if let Some(task) = self.tasks.get(id) {
|
|
||||||
task.set_paused(false);
|
|
||||||
self.task_queue.push(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn interrupt_subscribe(&mut self, pid: usize, interrupt_type: u8) {
|
|
||||||
self.pause(pid);
|
|
||||||
self.interrupt_lookup[interrupt_type as usize] = Some(pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn buffer_subscribe(&mut self, pid: usize, buffer_id: usize) {
|
|
||||||
self.pause(pid);
|
|
||||||
if let Some(buf) = self.buffer_lookup.get_mut(&buffer_id) {
|
|
||||||
buf.insert(pid);
|
|
||||||
} else {
|
|
||||||
self.buffer_lookup.insert(buffer_id, BTreeSet::from([pid]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
let mut task_batch = [0; 32];
|
let mut task_batch = [0; 32];
|
||||||
loop {
|
let mut batch_len = 0;
|
||||||
let mut batch_len = 0;
|
|
||||||
|
|
||||||
while let Some(id) = self.task_queue.pop() {
|
loop {
|
||||||
task_batch[batch_len] = id;
|
self.task_queue.batch_pop(&mut task_batch, &mut batch_len);
|
||||||
batch_len += 1;
|
|
||||||
if batch_len == task_batch.len() {
|
if batch_len == 0 {
|
||||||
|
if self.task_queue.is_empty() {
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if batch_len == 0 {
|
for &id in &task_batch[..batch_len] {
|
||||||
// break;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for &(mut id) in &task_batch[..batch_len] {
|
|
||||||
if let Some(task) = self.tasks.get_mut(id) {
|
if let Some(task) = self.tasks.get_mut(id) {
|
||||||
if task.is_paused() {
|
let waker = task
|
||||||
continue;
|
.waker
|
||||||
}
|
.get_or_insert_with(|| TaskWaker::new(id, Arc::clone(&self.task_queue)));
|
||||||
|
|
||||||
let waker = create_waker(id, Arc::clone(&self.task_queue));
|
let waker = unsafe { Waker::from_raw(TaskWaker::into_raw_waker(waker)) };
|
||||||
let mut cx = ContextBuilder::from_waker(&waker).ext(&mut id).build();
|
let mut cx = Context::from_waker(&waker);
|
||||||
|
|
||||||
if let Poll::Ready(()) = task.poll(&mut cx) {
|
if let Poll::Ready(()) = task.poll(&mut cx) {
|
||||||
self.tasks.remove(id);
|
self.tasks.remove(id);
|
||||||
self.interrupt_lookup.map(|pid| {
|
self.task_queue.free_tasks.push(id);
|
||||||
if let Some(pid) = pid {
|
|
||||||
if pid == id {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pid;
|
|
||||||
});
|
|
||||||
self.buffer_lookup.iter_mut().for_each(|(_, pid_set)| {
|
|
||||||
pid_set.remove(&id);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_interrupt(&self, interrupt: u8) {
|
|
||||||
let id = self.interrupt_lookup[interrupt as usize];
|
|
||||||
if let Some(id) = id {
|
|
||||||
self.unpause(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn send_buffer(&self, id: usize) {
|
|
||||||
if let Some(buf) = self.buffer_lookup.get(&id) {
|
|
||||||
buf.iter().for_each(|pid| self.unpause(*pid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Task {
|
struct Task<F: Future<Output = ()> + Send> {
|
||||||
future: Pin<Box<dyn Process>>,
|
future: Pin<Box<F>>,
|
||||||
paused: AtomicBool,
|
waker: Option<TaskWaker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Task {
|
impl<F: Future<Output = ()> + Send> Task<F> {
|
||||||
fn new(future: Pin<Box<dyn Process>>) -> Self {
|
#[inline(always)]
|
||||||
|
pub fn new(future: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
future,
|
future: Box::pin(future),
|
||||||
paused: AtomicBool::new(false),
|
waker: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn poll(&mut self, cx: &mut Context) -> Poll<()> {
|
fn poll(&mut self, cx: &mut Context) -> Poll<()> {
|
||||||
self.future.as_mut().poll(cx)
|
self.future.as_mut().poll(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_paused(&self) -> bool {
|
|
||||||
self.paused.load(Ordering::Acquire)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_paused(&self, paused: bool) {
|
|
||||||
self.paused.store(paused, Ordering::Release)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_waker(task_id: usize, task_queue: Arc<SegQueue<usize>>) -> Waker {
|
|
||||||
let data = Box::new(TaskWaker {
|
|
||||||
task_id,
|
|
||||||
task_queue,
|
|
||||||
});
|
|
||||||
let raw_waker = RawWaker::new(Box::into_raw(data) as *const (), &VTABLE);
|
|
||||||
unsafe { Waker::from_raw(raw_waker) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct TaskWaker {
|
struct TaskWaker {
|
||||||
task_id: usize,
|
id: usize,
|
||||||
task_queue: Arc<SegQueue<usize>>,
|
task_queue: Arc<TaskQueue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaskWaker {
|
impl TaskWaker {
|
||||||
|
#[inline(always)]
|
||||||
|
fn new(id: usize, task_queue: Arc<TaskQueue>) -> Self {
|
||||||
|
Self { id, task_queue }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn wake(&self) {
|
fn wake(&self) {
|
||||||
self.task_queue.push(self.task_id);
|
self.task_queue.queue.push(self.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_raw_waker(waker: &TaskWaker) -> RawWaker {
|
||||||
|
let ptr = waker as *const TaskWaker;
|
||||||
|
RawWaker::new(ptr.cast(), &VTABLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const VTABLE: RawWakerVTable = RawWakerVTable::new(clone_raw, wake_raw, wake_by_ref_raw, drop_raw);
|
const VTABLE: RawWakerVTable = RawWakerVTable::new(clone_raw, wake_raw, wake_by_ref_raw, drop_raw);
|
||||||
|
|
||||||
unsafe fn clone_raw(ptr: *const ()) -> RawWaker {
|
unsafe fn clone_raw(ptr: *const ()) -> RawWaker {
|
||||||
let task_waker = Box::from_raw(ptr as *mut TaskWaker);
|
let waker = &*(ptr as *const TaskWaker);
|
||||||
let raw_waker = RawWaker::new(Box::into_raw(task_waker.clone()) as *const (), &VTABLE);
|
TaskWaker::into_raw_waker(waker)
|
||||||
raw_waker
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn wake_raw(ptr: *const ()) {
|
unsafe fn wake_raw(ptr: *const ()) {
|
||||||
let task_waker = Box::from_raw(ptr as *mut TaskWaker);
|
let waker = &*(ptr as *const TaskWaker);
|
||||||
task_waker.wake();
|
waker.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn wake_by_ref_raw(ptr: *const ()) {
|
unsafe fn wake_by_ref_raw(ptr: *const ()) {
|
||||||
let task_waker = &*(ptr as *const TaskWaker);
|
let waker = &*(ptr as *const TaskWaker);
|
||||||
task_waker.wake();
|
waker.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn drop_raw(ptr: *const ()) {
|
unsafe fn drop_raw(_: *const ()) {}
|
||||||
drop(Box::from_raw(ptr as *mut TaskWaker));
|
|
||||||
|
struct TaskQueue {
|
||||||
|
queue: SegQueue<usize>,
|
||||||
|
next_task: usize,
|
||||||
|
free_tasks: SegQueue<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskQueue {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
queue: SegQueue::new(),
|
||||||
|
next_task: 0,
|
||||||
|
free_tasks: SegQueue::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn batch_pop(&self, output: &mut [usize], len: &mut usize) {
|
||||||
|
*len = 0;
|
||||||
|
while let Some(id) = self.queue.pop() {
|
||||||
|
output[*len] = id;
|
||||||
|
*len += 1;
|
||||||
|
if *len == output.len() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.queue.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
{
|
{
|
||||||
"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,
|
||||||
"features": "+strict-align,+neon,+fp-armv8",
|
"features": "+strict-align,+neon,+fp-armv8",
|
||||||
"linker": "rust-lld",
|
"linker": "rust-lld",
|
||||||
"linker-flavor": "ld.lld",
|
"linker-flavor": "ld.lld",
|
||||||
"linker-is-gnu": true,
|
"linker-is-gnu": true,
|
||||||
"pre-link-args": {
|
"pre-link-args": {
|
||||||
"ld.lld": [
|
"ld.lld": [
|
||||||
"-Tkernel/lds/aarch64-qemu.ld"
|
"-Tkernel/lds/aarch64-qemu.ld"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"llvm-target": "aarch64-unknown-none",
|
"llvm-target": "aarch64-unknown-none",
|
||||||
"max-atomic-width": 128,
|
"max-atomic-width": 128,
|
||||||
"os": "none",
|
"os": "none",
|
||||||
"panic-strategy": "abort",
|
"panic-strategy": "abort",
|
||||||
"relocation-model": "static",
|
"relocation-model": "static",
|
||||||
"target-c-int-width": "32",
|
"target-c-int-width": "32",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
"vendor": "ablecorp"
|
"vendor": ""
|
||||||
}
|
}
|
|
@ -6,16 +6,29 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
str-reader = "0.1"
|
str-reader = "0.1"
|
||||||
derive_more = { version = "1", default-features = false, features = [
|
derive_more = { version = "1", default-features = false, features = [
|
||||||
|
"add",
|
||||||
|
"add_assign",
|
||||||
|
"constructor",
|
||||||
"display",
|
"display",
|
||||||
|
"from",
|
||||||
|
"into",
|
||||||
|
"mul",
|
||||||
|
"mul_assign",
|
||||||
|
"not",
|
||||||
|
"sum",
|
||||||
] }
|
] }
|
||||||
error-stack = "0.5"
|
error-stack = "0.5"
|
||||||
fatfs = { version = "0.3", default-features = false, features = [
|
fatfs = "0.3"
|
||||||
"std",
|
|
||||||
"alloc",
|
|
||||||
] }
|
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
hblang.git = "https://git.ablecorp.us/AbleOS/holey-bytes.git"
|
hblang = { git = "https://git.ablecorp.us/AbleOS/holey-bytes.git", features = [
|
||||||
# hblang.path = "../../holey-bytes/lang/"
|
"std",
|
||||||
|
"opts",
|
||||||
|
], default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
raw-cpuid = "11"
|
raw-cpuid = "11"
|
||||||
ureq = { version = "2", default-features = false, features = ["tls"] }
|
ureq = { version = "2", default-features = false, features = ["tls"] }
|
||||||
|
|
||||||
|
# [dependencies.reqwest]
|
||||||
|
# version = "0.12"
|
||||||
|
# default-features = false
|
||||||
|
# features = ["rustls-tls", "blocking"]
|
||||||
|
|
|
@ -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,47 +46,48 @@ 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 {
|
||||||
|
println!("{}", name);
|
||||||
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) -> 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);
|
|
||||||
// compile here
|
|
||||||
|
|
||||||
let mut warnings = String::new();
|
let path = format!("sysdata/programs/{}/{}", self.name, file);
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
// compile here
|
||||||
|
|
||||||
hblang::run_compiler(
|
hblang::run_compiler(
|
||||||
&path,
|
&path,
|
||||||
Options {
|
Options {
|
||||||
fmt: true,
|
fmt: true,
|
||||||
resolver: Some(hblang::ABLEOS_PATH_RESOLVER),
|
optimize: true,
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
out,
|
&mut bytes,
|
||||||
&mut warnings,
|
)?;
|
||||||
|
|
||||||
|
hblang::run_compiler(
|
||||||
|
&path,
|
||||||
|
Options {
|
||||||
|
optimize: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut bytes,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
match std::fs::create_dir("target/programs") {
|
match std::fs::create_dir("target/programs") {
|
||||||
|
@ -96,33 +95,18 @@ impl Package {
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (),
|
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (),
|
||||||
Err(e) => panic!("{}", e),
|
Err(e) => panic!("{}", e),
|
||||||
}
|
}
|
||||||
|
std::fs::write(format!("target/programs/{}.hbf", self.name), &bytes).unwrap();
|
||||||
|
bytes.clear();
|
||||||
hblang::run_compiler(
|
hblang::run_compiler(
|
||||||
&path,
|
&path,
|
||||||
Options {
|
Options {
|
||||||
resolver: Some(hblang::ABLEOS_PATH_RESOLVER),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
out,
|
|
||||||
&mut warnings,
|
|
||||||
)?;
|
|
||||||
std::fs::write(format!("target/programs/{}.hbf", self.name), &out)?;
|
|
||||||
out.clear();
|
|
||||||
|
|
||||||
let err = hblang::run_compiler(
|
|
||||||
&path,
|
|
||||||
Options {
|
|
||||||
resolver: Some(hblang::ABLEOS_PATH_RESOLVER),
|
|
||||||
dump_asm: true,
|
dump_asm: true,
|
||||||
|
optimize: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
out,
|
&mut bytes,
|
||||||
&mut warnings,
|
)?;
|
||||||
);
|
std::fs::write(format!("target/programs/{}.hba", self.name), &bytes).unwrap();
|
||||||
std::fs::write(format!("target/programs/{}.hba", self.name), &out)?;
|
|
||||||
out.clear();
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
mod dev;
|
mod dev;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
core::fmt::Write as _,
|
|
||||||
derive_more::Display,
|
derive_more::Display,
|
||||||
dev::Package,
|
dev::Package,
|
||||||
error_stack::{bail, report, Context, Report, Result, ResultExt},
|
error_stack::{bail, report, Context, Report, Result, ResultExt},
|
||||||
|
@ -27,7 +26,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 +37,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 +62,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 +81,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(())
|
||||||
|
@ -234,9 +204,6 @@ TERM_BACKDROP={}
|
||||||
let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap();
|
let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap();
|
||||||
// let mut real_modules = modules.clone();
|
// let mut real_modules = modules.clone();
|
||||||
|
|
||||||
let mut errors = String::new();
|
|
||||||
let mut out = Vec::new();
|
|
||||||
|
|
||||||
modules
|
modules
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, value)| -> Result<(), io::Error> {
|
.map(|(_, value)| -> Result<(), io::Error> {
|
||||||
|
@ -251,26 +218,11 @@ TERM_BACKDROP={}
|
||||||
let p = Package::load_from_file(
|
let p = Package::load_from_file(
|
||||||
format!("sysdata/programs/{}/meta.toml", path).to_owned(),
|
format!("sysdata/programs/{}/meta.toml", path).to_owned(),
|
||||||
);
|
);
|
||||||
match p.build(&mut out) {
|
p.build()?;
|
||||||
Ok(()) => {}
|
|
||||||
Err(e) => {
|
|
||||||
writeln!(errors, "========= while compiling {} {} =========", path, e)
|
|
||||||
.unwrap();
|
|
||||||
errors.push_str(&String::from_utf8_lossy(&out));
|
|
||||||
out.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.for_each(drop);
|
.for_each(drop);
|
||||||
|
|
||||||
if !errors.is_empty() {
|
|
||||||
let _ = writeln!(errors, "!!! STOPPING DUE TO PREVIOUS ERRORS !!!");
|
|
||||||
std::eprint!("{errors}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
modules.into_iter().for_each(|(_key, value)| {
|
modules.into_iter().for_each(|(_key, value)| {
|
||||||
if value.is_table() {
|
if value.is_table() {
|
||||||
let path = value.get("path").expect("You must have `path` as a value");
|
let path = value.get("path").expect("You must have `path` as a value");
|
||||||
|
@ -339,7 +291,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 +303,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 +359,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,24 +394,16 @@ 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 => {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
com.args([
|
com.args([
|
||||||
"-bios", &ovmf_path.change_context(Error::OvmfFetch)?,
|
"-bios", &ovmf_path.change_context(Error::OvmfFetch)?,
|
||||||
//"-hda", "target/disk.img",
|
"-drive", "file=target/disk.img,format=raw",
|
||||||
"-drive", "file=target/disk.img,index=0,if=ide,format=raw",
|
|
||||||
"-device", "vmware-svga",
|
"-device", "vmware-svga",
|
||||||
// "-serial", "stdio",
|
|
||||||
"-m", "2G",
|
"-m", "2G",
|
||||||
"-smp", "1",
|
"-smp", "1",
|
||||||
"-audiodev",
|
|
||||||
"pa,id=speaker",
|
|
||||||
"-machine",
|
|
||||||
"pcspk-audiodev=speaker",
|
|
||||||
"-parallel", "none",
|
"-parallel", "none",
|
||||||
"-monitor", "none",
|
"-monitor", "none",
|
||||||
"-machine", accel,
|
"-machine", accel,
|
||||||
|
@ -490,7 +429,7 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
com.args([
|
com.args([
|
||||||
"-M", "virt",
|
"-M", "virt",
|
||||||
"-cpu", "max",
|
"-cpu", "neoverse-n2",
|
||||||
"-device", "ramfb",
|
"-device", "ramfb",
|
||||||
"-device", "qemu-xhci",
|
"-device", "qemu-xhci",
|
||||||
"-device", "usb-kbd",
|
"-device", "usb-kbd",
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
# old toolchain
|
channel = "nightly-2024-07-27"
|
||||||
# channel = "nightly-2024-07-27"
|
|
||||||
# last stable
|
|
||||||
# channel = "nightly-2024-11-20"
|
|
||||||
channel = "nightly"
|
|
||||||
components = ["rust-src", "llvm-tools"]
|
components = ["rust-src", "llvm-tools"]
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 100 KiB |
Binary file not shown.
Binary file not shown.
|
@ -1,4 +0,0 @@
|
||||||
(horizontal
|
|
||||||
spacing : 10
|
|
||||||
(label "hi")
|
|
||||||
(label "goodbye"))
|
|
|
@ -1 +0,0 @@
|
||||||
(label "hello")
|
|
|
@ -1,3 +0,0 @@
|
||||||
(vertical
|
|
||||||
(label "hello")
|
|
||||||
(label "hello" color:red))
|
|
|
@ -5,37 +5,42 @@ render := @use("../../../libraries/render/src/lib.hb")
|
||||||
|
|
||||||
input := @use("../../intouch/src/lib.hb")
|
input := @use("../../intouch/src/lib.hb")
|
||||||
|
|
||||||
widgets := @use("widgets/widgets.hb")
|
widgets := @use("widgets.hb")
|
||||||
ui := @use("ui.hb")
|
|
||||||
|
|
||||||
WindowID := struct {
|
WindowID := struct {
|
||||||
host_id: uint,
|
host_id: int,
|
||||||
window_id: uint,
|
window_id: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
VoidWindowID := WindowID.(0, 0)
|
VoidWindowID := WindowID.(0, 0)
|
||||||
|
|
||||||
create_window := fn(channel: uint): ^render.Surface {
|
create_window := fn(channel: int): ^render.Surface {
|
||||||
// get the horizon buffer
|
// get the horizon buffer
|
||||||
// request a new window and provide the callback buffer
|
// request a new window and provide the callback buffer
|
||||||
// wait to recieve a message
|
// wait to recieve a message
|
||||||
|
|
||||||
windowing_system_buffer := buffer.search("XHorizon")
|
windowing_system_buffer := buffer.search("XHorizon\0")
|
||||||
mem_buf := memory.request_page(1)
|
mem_buf := memory.request_page(1)
|
||||||
|
|
||||||
if windowing_system_buffer == 0 {
|
if windowing_system_buffer == 0 {
|
||||||
return @as(^render.Surface, idk)
|
return @as(^render.Surface, idk)
|
||||||
} else {
|
} else {
|
||||||
|
// ! bad able, stop using string messages :ragey:
|
||||||
|
// msg := "\{01}\0"
|
||||||
|
// msg_length := 2
|
||||||
|
|
||||||
|
// @as(void, @eca(3, windowing_system_buffer, msg, msg_length))
|
||||||
|
|
||||||
x := 0
|
x := 0
|
||||||
loop if x > 1000 break else x += 1
|
loop if x > 1000 break else x += 1
|
||||||
|
|
||||||
ret := buffer.recv([4096]u8, windowing_system_buffer, mem_buf)
|
ret := buffer.recv([u8; 4096], windowing_system_buffer, mem_buf)
|
||||||
if ret == null {
|
if ret == 0 {
|
||||||
log.info("No messages")
|
log.info("No messages\0")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *mem_buf == 0 {
|
if *mem_buf == 0 {
|
||||||
log.info("No messages")
|
log.info("No messages\0")
|
||||||
}
|
}
|
||||||
|
|
||||||
return @as(^render.Surface, idk)
|
return @as(^render.Surface, idk)
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
stn := @use("../../../libraries/stn/src/lib.hb");
|
|
||||||
.{string, log} := stn;
|
|
||||||
.{Vec2} := stn.math
|
|
||||||
|
|
||||||
render := @use("../../../libraries/render/src/lib.hb");
|
|
||||||
.{Surface} := render;
|
|
||||||
.{Font} := render.text
|
|
||||||
|
|
||||||
UI := struct {raw: []u8, is_dirty: bool, surface: Surface, // Each child has their WidgetType as their first byte
|
|
||||||
// children: ^^u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
render_ui := fn(surface: Surface, ui: UI): void {
|
|
||||||
if ui.is_dirty {
|
|
||||||
render.clear(ui.surface, render.black)
|
|
||||||
ui.is_dirty = false
|
|
||||||
}
|
|
||||||
pos := Vec2(uint).(0, 0)
|
|
||||||
render.put_surface(surface, ui.surface, pos, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
sexpr_parser := fn(sexpr: []u8): UI {
|
|
||||||
i := 0
|
|
||||||
paren_balance := 0
|
|
||||||
loop {
|
|
||||||
if i == sexpr.len {
|
|
||||||
if paren_balance != 0 {
|
|
||||||
log.error("Unbalanced Parens")
|
|
||||||
}
|
|
||||||
break
|
|
||||||
} else if sexpr[i] == '(' {
|
|
||||||
log.info("Open paren")
|
|
||||||
paren_balance += 1
|
|
||||||
} else if sexpr[i] == ')' {
|
|
||||||
log.info("Closed paren")
|
|
||||||
paren_balance -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_surface := render.new_surface(100, 100)
|
|
||||||
return UI.(sexpr, true, ui_surface)
|
|
||||||
}
|
|
20
sysdata/libraries/horizon_api/src/widgets.hb
Normal file
20
sysdata/libraries/horizon_api/src/widgets.hb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Widget types
|
||||||
|
|
||||||
|
// End types
|
||||||
|
|
||||||
|
LayoutChildHorizontalFirst := 0
|
||||||
|
LayoutChildVerticalFirst := 1
|
||||||
|
|
||||||
|
Size := struct {
|
||||||
|
min_width: int,
|
||||||
|
max_width: int,
|
||||||
|
min_height: int,
|
||||||
|
max_height: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget := struct {
|
||||||
|
size: Size,
|
||||||
|
clickable: bool,
|
||||||
|
layout: u8,
|
||||||
|
a: bool,
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
render := @use("../../../../libraries/render/src/lib.hb");
|
|
||||||
.{Surface} := render
|
|
||||||
|
|
||||||
Image := struct {
|
|
||||||
magic: uint,
|
|
||||||
is_dirty: bool,
|
|
||||||
surface: Surface,
|
|
||||||
}
|
|
||||||
|
|
||||||
image_from_surface := fn(surface: Surface): Image {
|
|
||||||
img := Image.(4, true, surface)
|
|
||||||
return img
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
stn := @use("../../../../libraries/stn/src/lib.hb");
|
|
||||||
.{string, log} := stn;
|
|
||||||
.{Vec2} := stn.math
|
|
||||||
|
|
||||||
render := @use("../../../../libraries/render/src/lib.hb");
|
|
||||||
.{Surface, Color} := render;
|
|
||||||
.{Font} := render.text
|
|
||||||
|
|
||||||
Label := struct {
|
|
||||||
magic: uint,
|
|
||||||
is_dirty: bool,
|
|
||||||
surface: Surface,
|
|
||||||
text: []u8,
|
|
||||||
bg: Color,
|
|
||||||
fg: Color,
|
|
||||||
|
|
||||||
new_label := fn(text: []u8, width: uint): Self {
|
|
||||||
text_surface := render.Surface.new(width, 20)
|
|
||||||
label := Self.(3, true, text_surface, text, render.BLACK, render.WHITE)
|
|
||||||
return label
|
|
||||||
}
|
|
||||||
|
|
||||||
$set_label_text := fn(self: ^Self, text: []u8): void {
|
|
||||||
self.is_dirty = true
|
|
||||||
self.text = text
|
|
||||||
}
|
|
||||||
|
|
||||||
$set_color := fn(self: ^Self, bg: Color, fg: Color): void {
|
|
||||||
self.bg = bg
|
|
||||||
self.fg = fg
|
|
||||||
self.is_dirty = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void {
|
|
||||||
if label.is_dirty {
|
|
||||||
label.surface.clear(label.bg)
|
|
||||||
label.surface.put_text(font, .(0, 0), label.fg, label.text)
|
|
||||||
}
|
|
||||||
surface.put_surface(label.surface, pos, false)
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
NoWidget := 0
|
|
||||||
|
|
||||||
VerticalWidgetType := 1
|
|
||||||
HorizontalWidgetType := 2
|
|
||||||
|
|
||||||
LabelWidgetType := 3
|
|
||||||
ImageWidgetType := 4
|
|
|
@ -1,36 +0,0 @@
|
||||||
// Widget types
|
|
||||||
|
|
||||||
// End types
|
|
||||||
stn := @use("../../../../libraries/stn/src/lib.hb");
|
|
||||||
.{string, log} := stn;
|
|
||||||
.{Vec2} := stn.math
|
|
||||||
|
|
||||||
render := @use("../../../../libraries/render/src/lib.hb");
|
|
||||||
.{Surface} := render;
|
|
||||||
.{Font} := render.text
|
|
||||||
|
|
||||||
widget_types := @use("widget_types.hb")
|
|
||||||
label := @use("label.hb")
|
|
||||||
image := @use("image.hb")
|
|
||||||
|
|
||||||
Size := struct {
|
|
||||||
min_width: int,
|
|
||||||
max_width: int,
|
|
||||||
min_height: int,
|
|
||||||
max_height: int,
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertical := packed struct {
|
|
||||||
magic: uint,
|
|
||||||
// array of children, idk
|
|
||||||
// use a vec or linked list or whatever
|
|
||||||
|
|
||||||
children: ^^u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
Horizontal := packed struct {
|
|
||||||
magic: uint,
|
|
||||||
// array of children, idk
|
|
||||||
// use a vec or linked list or whatever
|
|
||||||
children: ^^u8,
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
keycodes := @use("keycodes.hb");
|
|
||||||
.{KeyCode} := keycodes
|
|
||||||
|
|
||||||
KeyEvent := packed struct {
|
|
||||||
up: bool,
|
|
||||||
just_triggered: bool,
|
|
||||||
key: KeyCode,
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseEvent := packed struct {
|
|
||||||
x_change: i8,
|
|
||||||
y_change: i8,
|
|
||||||
left: bool,
|
|
||||||
middle: bool,
|
|
||||||
right: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
GamepadEvent := struct {}
|
|
|
@ -1,121 +1,67 @@
|
||||||
/*
|
|
||||||
Originally I was modelling this after the following(1). I have since changed my mind.
|
|
||||||
I am now modelling it as I see fit. This is likely not the final version.
|
|
||||||
|
|
||||||
1) https://www.libsdl.org/release/SDL-1.2.15/include/SDL_keysym.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
KeyCode := u32
|
KeyCode := u32
|
||||||
|
|
||||||
// Typically this is not a keycode you will ever recieve.
|
// https://www.libsdl.org/release/SDL-1.2.15/include/SDL_keysym.h
|
||||||
None := KeyCode.(0)
|
Backspace := KeyCode.(8)
|
||||||
|
Tab := KeyCode.(9)
|
||||||
|
Clear := KeyCode.(12)
|
||||||
|
Return := KeyCode.(13)
|
||||||
|
Pause := KeyCode.(19)
|
||||||
|
Escape := KeyCode.(27)
|
||||||
|
Space := KeyCode.(32)
|
||||||
|
|
||||||
Escape := KeyCode.(1)
|
A := KeyCode.(97)
|
||||||
/* Alphabet keycodes */
|
/*
|
||||||
|
ETC
|
||||||
|
*/
|
||||||
|
Z := KeyCode.(122)
|
||||||
|
|
||||||
A := KeyCode.(2)
|
Delete := KeyCode.(127)
|
||||||
B := KeyCode.(3)
|
|
||||||
C := KeyCode.(4)
|
|
||||||
D := KeyCode.(5)
|
|
||||||
E := KeyCode.(6)
|
|
||||||
F := KeyCode.(7)
|
|
||||||
G := KeyCode.(8)
|
|
||||||
H := KeyCode.(9)
|
|
||||||
I := KeyCode.(10)
|
|
||||||
J := KeyCode.(11)
|
|
||||||
K := KeyCode.(12)
|
|
||||||
L := KeyCode.(13)
|
|
||||||
M := KeyCode.(14)
|
|
||||||
N := KeyCode.(15)
|
|
||||||
O := KeyCode.(16)
|
|
||||||
P := KeyCode.(17)
|
|
||||||
Q := KeyCode.(18)
|
|
||||||
R := KeyCode.(19)
|
|
||||||
S := KeyCode.(20)
|
|
||||||
T := KeyCode.(21)
|
|
||||||
U := KeyCode.(22)
|
|
||||||
V := KeyCode.(23)
|
|
||||||
W := KeyCode.(24)
|
|
||||||
X := KeyCode.(25)
|
|
||||||
Y := KeyCode.(26)
|
|
||||||
Z := KeyCode.(27)
|
|
||||||
|
|
||||||
/* Numeric keycodes*/
|
|
||||||
|
|
||||||
Number0 := KeyCode.(28)
|
|
||||||
Number1 := KeyCode.(29)
|
|
||||||
Number2 := KeyCode.(30)
|
|
||||||
Number3 := KeyCode.(31)
|
|
||||||
Number4 := KeyCode.(32)
|
|
||||||
Number5 := KeyCode.(33)
|
|
||||||
Number6 := KeyCode.(34)
|
|
||||||
Number7 := KeyCode.(35)
|
|
||||||
Number8 := KeyCode.(36)
|
|
||||||
Number9 := KeyCode.(37)
|
|
||||||
|
|
||||||
KeypadNumber0 := KeyCode.(38)
|
|
||||||
KeypadNumber1 := KeyCode.(39)
|
|
||||||
KeypadNumber2 := KeyCode.(40)
|
|
||||||
KeypadNumber3 := KeyCode.(41)
|
|
||||||
KeypadNumber4 := KeyCode.(42)
|
|
||||||
KeypadNumber5 := KeyCode.(43)
|
|
||||||
KeypadNumber6 := KeyCode.(44)
|
|
||||||
KeypadNumber7 := KeyCode.(45)
|
|
||||||
KeypadNumber8 := KeyCode.(46)
|
|
||||||
KeypadNumber9 := KeyCode.(47)
|
|
||||||
|
|
||||||
KeypadPeriod := KeyCode.(48)
|
|
||||||
KeypadDivide := KeyCode.(49)
|
|
||||||
KeypadMultiply := KeyCode.(50)
|
|
||||||
KeypadMinus := KeyCode.(51)
|
|
||||||
KeypadPlus := KeyCode.(52)
|
|
||||||
KeypadEnter := KeyCode.(53)
|
|
||||||
KeypadEquals := KeyCode.(54)
|
|
||||||
|
|
||||||
Delete := KeyCode.(55)
|
|
||||||
/* Locking Keys */
|
|
||||||
NumLock := KeyCode.(56)
|
|
||||||
CapsLock := KeyCode.(57)
|
|
||||||
ScrollLock := KeyCode.(58)
|
|
||||||
|
|
||||||
/* "Alt Gr" key */
|
|
||||||
Mode := KeyCode.(59)
|
|
||||||
|
|
||||||
/* Multi-key compose key */
|
|
||||||
Compose := KeyCode.(60)
|
|
||||||
|
|
||||||
LeftAlt := KeyCode.(61)
|
|
||||||
LeftControl := KeyCode.(62)
|
|
||||||
LeftMeta := KeyCode.(63)
|
|
||||||
LeftShift := KeyCode.(64)
|
|
||||||
/* Left "Windows" key */
|
|
||||||
LeftSuper := KeyCode.(65)
|
|
||||||
|
|
||||||
RightAlt := KeyCode.(66)
|
|
||||||
RightControl := KeyCode.(67)
|
|
||||||
RightMeta := KeyCode.(68)
|
|
||||||
RightShift := KeyCode.(69)
|
|
||||||
/* Right "Windows" key */
|
|
||||||
RightSuper := KeyCode.(70)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This block of any triggers on any press of any of the keys.
|
ETC
|
||||||
Typically this is the event to care about.
|
|
||||||
*/
|
*/
|
||||||
AnyNumber0 := KeyCode.(71)
|
|
||||||
AnyNumber1 := KeyCode.(72)
|
|
||||||
AnyNumber2 := KeyCode.(73)
|
|
||||||
AnyNumber3 := KeyCode.(74)
|
|
||||||
AnyNumber4 := KeyCode.(75)
|
|
||||||
AnyNumber5 := KeyCode.(76)
|
|
||||||
AnyNumber6 := KeyCode.(77)
|
|
||||||
AnyNumber7 := KeyCode.(78)
|
|
||||||
AnyNumber8 := KeyCode.(79)
|
|
||||||
AnyNumber9 := KeyCode.(80)
|
|
||||||
|
|
||||||
AnyAlt := KeyCode.(81)
|
KeypadNumber0 := KeyCode.(256)
|
||||||
AnyControl := KeyCode.(82)
|
KeypadNumber1 := KeyCode.(257)
|
||||||
AnyMeta := KeyCode.(83)
|
KeypadNumber2 := KeyCode.(258)
|
||||||
AnyShift := KeyCode.(84)
|
KeypadNumber3 := KeyCode.(259)
|
||||||
/* Any "Windows" key */
|
KeypadNumber4 := KeyCode.(260)
|
||||||
AnySuper := KeyCode.(85)
|
KeypadNumber5 := KeyCode.(261)
|
||||||
|
KeypadNumber6 := KeyCode.(262)
|
||||||
|
KeypadNumber7 := KeyCode.(263)
|
||||||
|
KeypadNumber8 := KeyCode.(264)
|
||||||
|
KeypadNumber9 := KeyCode.(265)
|
||||||
|
|
||||||
|
KeypadPeriod := KeyCode.(266)
|
||||||
|
KeypadDivide := KeyCode.(267)
|
||||||
|
KeypadMultiply := KeyCode.(268)
|
||||||
|
KeypadMinus := KeyCode.(269)
|
||||||
|
KeypadPlus := KeyCode.(270)
|
||||||
|
KeypadEnter := KeyCode.(271)
|
||||||
|
KeypadEquals := KeyCode.(272)
|
||||||
|
|
||||||
|
NumLock := KeyCode.(300)
|
||||||
|
CapsLock := KeyCode.(301)
|
||||||
|
ScrollLock := KeyCode.(302)
|
||||||
|
|
||||||
|
RightShift := KeyCode.(303)
|
||||||
|
LeftShift := KeyCode.(304)
|
||||||
|
|
||||||
|
RightControl := KeyCode.(305)
|
||||||
|
LeftControl := KeyCode.(306)
|
||||||
|
RightAlt := KeyCode.(307)
|
||||||
|
LeftAlt := KeyCode.(308)
|
||||||
|
RightMeta := KeyCode.(309)
|
||||||
|
LeftMeta := KeyCode.(310)
|
||||||
|
|
||||||
|
/* Left "Windows" key */
|
||||||
|
LeftSuper := KeyCode.(311)
|
||||||
|
|
||||||
|
/* Right "Windows" key */
|
||||||
|
RightSuper := KeyCode.(312)
|
||||||
|
|
||||||
|
/* "Alt Gr" key */
|
||||||
|
Mode := KeyCode.(313)
|
||||||
|
|
||||||
|
/* Multi-key compose key */
|
||||||
|
Compose := KeyCode.(314)
|
|
@ -1,36 +1,22 @@
|
||||||
stn := @use("stn");
|
keycodes := @use("keycodes.hb");
|
||||||
.{log, buffer, memory} := stn
|
.{KeyCode} := keycodes
|
||||||
keycodes := @use("keycodes.hb")
|
|
||||||
|
|
||||||
events := @use("events.hb");
|
MouseEvent := struct {
|
||||||
.{KeyEvent, MouseEvent} := events
|
x_change: u8,
|
||||||
|
y_change: u8,
|
||||||
recieve_key_event := fn(): ?KeyEvent {
|
left: u8,
|
||||||
kevent := KeyEvent.(false, false, 0)
|
middle: u8,
|
||||||
|
right: u8,
|
||||||
buf_id := buffer.search("PS/2 Keyboard")
|
|
||||||
|
|
||||||
// Read out of the Keyboard buffer here
|
|
||||||
buffer.recv(KeyEvent, buf_id, &kevent)
|
|
||||||
|
|
||||||
if kevent.just_triggered {
|
|
||||||
return kevent
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recieve_mouse_event := fn(): ?MouseEvent {
|
KeyEvent := struct {
|
||||||
mevent := MouseEvent.(0, 0, false, false, false)
|
// 0 if down
|
||||||
|
// 1 if up
|
||||||
|
up: u8,
|
||||||
|
// 0 if not just triggered
|
||||||
|
// 1 if just triggered
|
||||||
|
just_triggered: u8,
|
||||||
|
key: KeyCode,
|
||||||
|
}
|
||||||
|
|
||||||
buf_id := buffer.search("PS/2 Mouse")
|
GamepadEvent := struct {}
|
||||||
|
|
||||||
// Read out of the Mouse buffer here
|
|
||||||
buffer.recv(MouseEvent, buf_id, &mevent)
|
|
||||||
|
|
||||||
if mevent.x_change != 0 | mevent.y_change != 0 | mevent.left | mevent.middle | mevent.right {
|
|
||||||
return mevent
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
.{string, memory, buffer, log} := @use("stn")
|
.{string, memory, buffer, log} := @use("../../stn/src/lib.hb")
|
||||||
|
|
||||||
PCIAddress := struct {
|
PCIAddress := struct {
|
||||||
bus: u8,
|
bus: u8,
|
||||||
|
@ -51,9 +51,9 @@ check_device := fn(bus: u8, device: u8): PciDeviceInfo {
|
||||||
pci_id := get_ids(bus, device, 0)
|
pci_id := get_ids(bus, device, 0)
|
||||||
|
|
||||||
if pci_id.vendor == 0xFFFF {
|
if pci_id.vendor == 0xFFFF {
|
||||||
log.warn(":|")
|
log.warn(":|\0")
|
||||||
} else {
|
} else {
|
||||||
log.info(":)")
|
log.info(":)\0")
|
||||||
}
|
}
|
||||||
address := calculate_address(bus, device, 0, 0x8)
|
address := calculate_address(bus, device, 0, 0x8)
|
||||||
reg2 := config_read32(bus, device, 0, 0x8)
|
reg2 := config_read32(bus, device, 0, 0x8)
|
||||||
|
|
|
@ -3,4 +3,7 @@ Rendering interface for SVGA and Software renderers
|
||||||
# TODO:
|
# TODO:
|
||||||
|
|
||||||
- SVGA Driver
|
- SVGA Driver
|
||||||
- needs pci driver
|
- needs pci driver
|
||||||
|
- needs init (requiring program)
|
||||||
|
- Double Buffer mode for Software renderer
|
||||||
|
- needs init (requiring program)
|
|
@ -1,4 +1,7 @@
|
||||||
# Images
|
# Images
|
||||||
|
- General over image format
|
||||||
|
- Support formats:
|
||||||
|
- PNG
|
||||||
- Animation
|
- Animation
|
||||||
|
|
||||||
# API
|
# API
|
||||||
|
|
102
sysdata/libraries/render/src/image.hb
Normal file
102
sysdata/libraries/render/src/image.hb
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
.{Color, Surface, new_surface} := @use("./lib.hb");
|
||||||
|
.{log, memory} := @use("../../stn/src/lib.hb")
|
||||||
|
|
||||||
|
BitmapFileHeader := packed struct {
|
||||||
|
img_type: u16,
|
||||||
|
size: u32,
|
||||||
|
reserved_1: u16,
|
||||||
|
reserved_2: u16,
|
||||||
|
offset: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapInfoHeader := packed struct {
|
||||||
|
size: u32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
planes: u16,
|
||||||
|
bits: u16,
|
||||||
|
compression: u32,
|
||||||
|
image_size: u32,
|
||||||
|
x_resolution: i32,
|
||||||
|
y_resolution: i32,
|
||||||
|
n_colours: u32,
|
||||||
|
important_colours: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapColorHeader := packed struct {
|
||||||
|
red_mask: u32,
|
||||||
|
green_mask: u32,
|
||||||
|
blue_mask: u32,
|
||||||
|
alpha_mask: u32,
|
||||||
|
color_space_type: u32,
|
||||||
|
unused: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_from_bmp := fn(bmp: ^u8): Surface {
|
||||||
|
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
||||||
|
if file_header.img_type != 0x4D42 {
|
||||||
|
log.error("failed to load bmp image: not a bmp image, idiot\0")
|
||||||
|
return idk
|
||||||
|
}
|
||||||
|
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
||||||
|
bmp += file_header.offset
|
||||||
|
|
||||||
|
px := info_header.width * info_header.height
|
||||||
|
ptr := @as(^Color, @bitcast(bmp))
|
||||||
|
tmp := @as(Color, idk)
|
||||||
|
row := @as(i32, 0)
|
||||||
|
|
||||||
|
loop if row == info_header.height / 2 break else {
|
||||||
|
col := @as(i32, 0)
|
||||||
|
loop if col == info_header.width break else {
|
||||||
|
top_index := row * info_header.width + col
|
||||||
|
bottom_index := (info_header.height - 1 - row) * info_header.width + col
|
||||||
|
|
||||||
|
tmp = *(ptr + top_index);
|
||||||
|
*(ptr + top_index) = *(ptr + bottom_index);
|
||||||
|
*(ptr + bottom_index) = tmp
|
||||||
|
|
||||||
|
col += 1
|
||||||
|
}
|
||||||
|
row += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return .(@bitcast(bmp), info_header.width, info_header.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
new_surface_from_bmp := fn(bmp: ^u8): Surface {
|
||||||
|
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
||||||
|
if file_header.img_type != 0x4D42 {
|
||||||
|
log.error("failed to load bmp image: not a bmp image, idiot\0")
|
||||||
|
return idk
|
||||||
|
}
|
||||||
|
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
||||||
|
bmp += file_header.offset
|
||||||
|
|
||||||
|
width := @as(uint, @intcast(info_header.width))
|
||||||
|
height := @as(uint, @intcast(info_header.height))
|
||||||
|
|
||||||
|
surface := new_surface(width, height)
|
||||||
|
top_start_idx := surface.buf
|
||||||
|
bottom_start_idx := surface.buf + width * (height - 1)
|
||||||
|
rows_to_copy := height
|
||||||
|
top_cursor := @as(^Color, @bitcast(bmp))
|
||||||
|
bottom_cursor := top_cursor + width * (height - 1)
|
||||||
|
|
||||||
|
loop if rows_to_copy <= 1 break else {
|
||||||
|
@inline(memory.copy, Color, top_cursor, bottom_start_idx, @bitcast(width))
|
||||||
|
@inline(memory.copy, Color, bottom_cursor, top_start_idx, @bitcast(width))
|
||||||
|
|
||||||
|
top_start_idx += surface.width
|
||||||
|
bottom_start_idx -= surface.width
|
||||||
|
top_cursor += width
|
||||||
|
bottom_cursor -= width
|
||||||
|
rows_to_copy -= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if rows_to_copy == 1 {
|
||||||
|
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(width))
|
||||||
|
}
|
||||||
|
|
||||||
|
return surface
|
||||||
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
.{Color, Surface, new_surface, put_surface} := @use("lib:render");
|
|
||||||
.{log} := @use("stn")
|
|
||||||
|
|
||||||
BitmapFileHeader := packed struct {
|
|
||||||
magic: u16,
|
|
||||||
size: u32,
|
|
||||||
reserved_1: u16,
|
|
||||||
reserved_2: u16,
|
|
||||||
offset: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
BitmapInfoHeader := packed struct {
|
|
||||||
size: u32,
|
|
||||||
width: i32,
|
|
||||||
height: i32,
|
|
||||||
planes: u16,
|
|
||||||
bits: u16,
|
|
||||||
compression: u32,
|
|
||||||
image_size: u32,
|
|
||||||
x_resolution: i32,
|
|
||||||
y_resolution: i32,
|
|
||||||
n_colours: u32,
|
|
||||||
important_colours: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
BitmapColorHeader := packed struct {
|
|
||||||
red_mask: u32,
|
|
||||||
green_mask: u32,
|
|
||||||
blue_mask: u32,
|
|
||||||
alpha_mask: u32,
|
|
||||||
color_space_type: u32,
|
|
||||||
unused: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
from := fn(bmp: ^u8): ?Surface {
|
|
||||||
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
|
||||||
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
|
||||||
|
|
||||||
if file_header.magic != 0x4D42 | info_header.width == 0 | info_header.height == 0 {
|
|
||||||
log.error("Invalid BMP image.")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height, info_header.width * info_header.height)
|
|
||||||
rhs := Surface.new(info_header.width, info_header.height)
|
|
||||||
rhs.put_surface(lhs, .(0, 0), true)
|
|
||||||
|
|
||||||
return rhs
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
.{log} := @use("stn");
|
|
||||||
.{Surface} := @use("lib:render")
|
|
||||||
bmp := @use("bmp.hb")
|
|
||||||
qoi := @use("qoi.hb")
|
|
||||||
$BMP := 0x4D42
|
|
||||||
$QOI := 0x66696F71
|
|
||||||
|
|
||||||
get_format := fn(file: ^u8): ?uint {
|
|
||||||
if *@as(^u16, @bitcast(file)) == BMP {
|
|
||||||
return BMP
|
|
||||||
} else if *@as(^u32, @bitcast(file)) == QOI {
|
|
||||||
return QOI
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
from := fn(file: ^u8): ?Surface {
|
|
||||||
format := get_format(file)
|
|
||||||
|
|
||||||
if format == null {
|
|
||||||
log.error("Could not detect image format.")
|
|
||||||
return null
|
|
||||||
} else if format == BMP {
|
|
||||||
return bmp.from(file)
|
|
||||||
} else if format == QOI {
|
|
||||||
return qoi.from(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
.{Color, Surface, new_surface} := @use("lib:render");
|
|
||||||
.{log} := @use("stn")
|
|
||||||
|
|
||||||
/* source:
|
|
||||||
https://github.com/phoboslab/qoi/blob/master/qoi.h */
|
|
||||||
|
|
||||||
$QOI_SRGB := 0
|
|
||||||
$QOI_LINEAR := 1
|
|
||||||
$QOI_OP_INDEX := 0x0
|
|
||||||
$QOI_OP_DIFF := 0x40
|
|
||||||
$QOI_OP_LUMA := 0x80
|
|
||||||
$QOI_OP_RUN := 0xC0
|
|
||||||
$QOI_OP_RGB := 0xFE
|
|
||||||
$QOI_OP_RGBA := 0xFF
|
|
||||||
$QOI_MASK_2 := 0xC0
|
|
||||||
$QOI_COLOR_HASH := fn(c: Color): u8 {
|
|
||||||
return (c.r * 3 + c.g * 5 + c.b * 7 + c.a * 11) % 64
|
|
||||||
}
|
|
||||||
$QOI_MAGIC := 0x716F6966
|
|
||||||
$QOI_PIXELS_MAX := 400000000
|
|
||||||
|
|
||||||
QuiteOkayHeader := packed struct {
|
|
||||||
magic: u32,
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
channels: u8,
|
|
||||||
colorspace: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
be_to_le := fn(big: u32): u32 {
|
|
||||||
return big >> 24 | big >> 8 & 0xFF00 | big << 8 & 0xFF0000 | big << 24
|
|
||||||
}
|
|
||||||
|
|
||||||
from := fn(qoi: ^u8): ?Surface {
|
|
||||||
header := @as(^QuiteOkayHeader, @bitcast(qoi))
|
|
||||||
|
|
||||||
qoi += @sizeof(QuiteOkayHeader)
|
|
||||||
|
|
||||||
width := be_to_le(header.width)
|
|
||||||
height := be_to_le(header.height)
|
|
||||||
|
|
||||||
if be_to_le(header.magic) != QOI_MAGIC | width == 0 | height == 0 | header.channels < 3 | header.channels > 4 {
|
|
||||||
log.error("Invalid QOI image.")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
surface := Surface.new(width, height)
|
|
||||||
index := @as([64]Color, idk)
|
|
||||||
|
|
||||||
run := 0
|
|
||||||
px := Color.(0, 0, 0, 255)
|
|
||||||
px_pos := 0
|
|
||||||
|
|
||||||
total_pixels := width * height
|
|
||||||
|
|
||||||
loop if px_pos >= total_pixels break else {
|
|
||||||
if run > 0 {
|
|
||||||
run -= 1
|
|
||||||
} else {
|
|
||||||
b1 := *qoi
|
|
||||||
qoi += 1
|
|
||||||
|
|
||||||
if b1 == QOI_OP_RGB {
|
|
||||||
px.r = *qoi
|
|
||||||
px.g = *(qoi + 1)
|
|
||||||
px.b = *(qoi + 2)
|
|
||||||
qoi += 3
|
|
||||||
} else if b1 == QOI_OP_RGBA {
|
|
||||||
px.r = *qoi
|
|
||||||
px.g = *(qoi + 1)
|
|
||||||
px.b = *(qoi + 2)
|
|
||||||
px.a = *(qoi + 3)
|
|
||||||
qoi += 4
|
|
||||||
} else if (b1 & QOI_MASK_2) == QOI_OP_INDEX {
|
|
||||||
px = index[b1 & 0x3F]
|
|
||||||
} else if (b1 & QOI_MASK_2) == QOI_OP_DIFF {
|
|
||||||
px.r = px.r + (b1 >> 4 & 0x3) - 2 & 0xFF
|
|
||||||
px.g = px.g + (b1 >> 2 & 0x3) - 2 & 0xFF
|
|
||||||
px.b = px.b + (b1 & 0x3) - 2 & 0xFF
|
|
||||||
} else if (b1 & QOI_MASK_2) == QOI_OP_LUMA {
|
|
||||||
b2 := *qoi
|
|
||||||
vg := (b1 & 0x3F) - 32
|
|
||||||
|
|
||||||
px.r = px.r + vg - 8 + (b2 >> 4 & 0xF) & 0xFF
|
|
||||||
px.g = px.g + vg & 0xFF
|
|
||||||
px.b = px.b + vg - 8 + (b2 & 0xF) & 0xFF
|
|
||||||
qoi += 1
|
|
||||||
} else if (b1 & QOI_MASK_2) == QOI_OP_RUN {
|
|
||||||
run = b1 & 0x3F
|
|
||||||
}
|
|
||||||
|
|
||||||
index[QOI_COLOR_HASH(px)] = px
|
|
||||||
};
|
|
||||||
|
|
||||||
*(surface.buf + px_pos) = px
|
|
||||||
|
|
||||||
px_pos += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return surface
|
|
||||||
}
|
|
|
@ -1,28 +1,51 @@
|
||||||
software := @use("software.hb")
|
software := @use("software.hb")
|
||||||
image := @use("image/lib.hb")
|
image := @use("image.hb")
|
||||||
text := @use("text.hb")
|
text := @use("text.hb")
|
||||||
|
|
||||||
// default mode
|
// default mode
|
||||||
mode := software
|
mode := software
|
||||||
|
|
||||||
init := mode.init
|
init := mode.init
|
||||||
|
doublebuffer := mode.doublebuffer
|
||||||
Surface := mode.Surface
|
Surface := mode.Surface
|
||||||
|
new_surface := mode.new_surface
|
||||||
|
surface_from_ptr := mode.surface_from_ptr
|
||||||
|
clone_surface := mode.clone_surface
|
||||||
|
free_surface := mode.free_surface
|
||||||
|
index := mode.index
|
||||||
|
indexptr := mode.indexptr
|
||||||
|
|
||||||
// Colours
|
// Colours
|
||||||
Color := packed struct {b: u8, g: u8, r: u8, a: u8}
|
Color := packed struct {b: u8, g: u8, r: u8, a: u8}
|
||||||
$WHITE := Color.(255, 255, 255, 255)
|
white := Color.(255, 255, 255, 255)
|
||||||
$BLACK := Color.(0, 0, 0, 255)
|
black := Color.(0, 0, 0, 255)
|
||||||
$GRAY := Color.(127, 127, 127, 255)
|
gray := Color.(127, 127, 127, 255)
|
||||||
$RED := Color.(0, 0, 205, 255)
|
red := Color.(0, 0, 205, 255)
|
||||||
$GREEN := Color.(0, 205, 0, 255)
|
green := Color.(0, 205, 0, 255)
|
||||||
$YELLOW := Color.(0, 205, 205, 255)
|
yellow := Color.(0, 205, 205, 255)
|
||||||
$BLUE := Color.(205, 0, 0, 255)
|
blue := Color.(205, 0, 0, 255)
|
||||||
$MAGENTA := Color.(205, 0, 205, 255)
|
magenta := Color.(205, 0, 205, 255)
|
||||||
$CYAN := Color.(205, 205, 0, 255)
|
cyan := Color.(205, 205, 0, 255)
|
||||||
$LIGHT_GRAY := Color.(229, 229, 229, 255)
|
light_gray := Color.(229, 229, 229, 255)
|
||||||
$LIGHT_RED := Color.(0, 0, 255, 255)
|
light_red := Color.(0, 0, 255, 255)
|
||||||
$LIGHT_GREEN := Color.(0, 255, 0, 255)
|
light_green := Color.(0, 255, 0, 255)
|
||||||
$LIGHT_YELLOW := Color.(0, 255, 255, 255)
|
light_yellow := Color.(0, 255, 255, 255)
|
||||||
$LIGHT_BLUE := Color.(255, 0, 0, 255)
|
light_blue := Color.(255, 0, 0, 255)
|
||||||
$LIGHT_MAGENTA := Color.(255, 0, 255, 255)
|
light_magenta := Color.(255, 0, 255, 255)
|
||||||
$LIGHT_CYAN := Color.(255, 255, 0, 255)
|
light_cyan := Color.(255, 255, 0, 255)
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
put_pixel := mode.put_pixel
|
||||||
|
put_rect := mode.put_rect
|
||||||
|
put_filled_rect := mode.put_filled_rect
|
||||||
|
put_line := mode.put_line
|
||||||
|
clear := mode.clear
|
||||||
|
put_surface := mode.put_surface
|
||||||
|
put_text := mode.put_text
|
||||||
|
// thanks peony for these three!
|
||||||
|
put_trirect := mode.put_trirect
|
||||||
|
put_vline := mode.put_vline
|
||||||
|
put_hline := mode.put_hline
|
||||||
|
|
||||||
|
// Display
|
||||||
|
sync := mode.sync
|
|
@ -1,443 +1,320 @@
|
||||||
.{math, memory, dt} := @use("stn");
|
.{math, memory, dt} := @use("../../stn/src/lib.hb");
|
||||||
.{Color, text} := @use("lib:render");
|
.{Color, text} := @use("lib.hb");
|
||||||
.{get_glyph, get_glyph_unicode, Font, UNC_TABLE_SIZE} := text;
|
.{get_glyph, Font} := text;
|
||||||
.{Vec2} := math
|
.{Vec2} := math
|
||||||
|
|
||||||
// safety: don't use before init() or you will get a memory access violation
|
|
||||||
framebuffer := memory.dangling(Color)
|
|
||||||
utf8_len_table := u8.[0, 0, 2, 3]
|
|
||||||
|
|
||||||
init := fn(doublebuffer: bool): Surface {
|
|
||||||
framebuffer = dt.get(^Color, "framebuffer/fb0/ptr")
|
|
||||||
width := dt.get(uint, "framebuffer/fb0/width")
|
|
||||||
height := dt.get(uint, "framebuffer/fb0/height")
|
|
||||||
if doublebuffer {
|
|
||||||
return Surface.new(width, height)
|
|
||||||
} else {
|
|
||||||
return .(framebuffer, width, height, width * height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Surface := struct {
|
Surface := struct {
|
||||||
buf: ^Color,
|
buf: ^Color,
|
||||||
width: uint,
|
width: uint,
|
||||||
height: uint,
|
height: uint,
|
||||||
size: uint,
|
}
|
||||||
|
|
||||||
new := fn(width: uint, height: uint): Self {
|
new_surface := fn(width: uint, height: uint): Surface {
|
||||||
size := width * height
|
return .(
|
||||||
return .(
|
@inline(memory.alloc, Color, width * height),
|
||||||
memory.alloc(Color, size),
|
width,
|
||||||
width,
|
height,
|
||||||
height,
|
)
|
||||||
size,
|
}
|
||||||
)
|
|
||||||
|
surface_from_ptr := fn(ptr: ^Color, width: uint, height: uint): Surface {
|
||||||
|
return .(
|
||||||
|
ptr,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
clone_surface := fn(surface: ^Surface): Surface {
|
||||||
|
new := new_surface(surface.width, surface.height)
|
||||||
|
@inline(memory.copy, Color, surface.buf, new.buf, @intcast(surface.width * surface.height))
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
|
// ! 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, idk)
|
||||||
|
|
||||||
|
init := fn(doublebuffer: bool): Surface {
|
||||||
|
framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
|
||||||
|
width := dt.get(uint, "framebuffer/fb0/width\0")
|
||||||
|
height := dt.get(uint, "framebuffer/fb0/height\0")
|
||||||
|
if doublebuffer {
|
||||||
|
return new_surface(width, height)
|
||||||
|
} else {
|
||||||
|
return .(framebuffer, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear := fn(surface: Surface, color: Color): void {
|
||||||
|
return @inline(memory.set, Color, &color, surface.buf, surface.width * surface.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
sync := fn(surface: Surface): void {
|
||||||
|
// vague safety
|
||||||
|
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 {
|
||||||
|
return x + surface.width * y
|
||||||
|
}
|
||||||
|
|
||||||
|
indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
|
||||||
|
return surface.buf + @inline(index, surface, x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
|
||||||
|
*@inline(indexptr, surface, pos.x, pos.y) = color
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
||||||
|
top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||||
|
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1)
|
||||||
|
rows_to_fill := tr.y
|
||||||
|
|
||||||
|
loop if rows_to_fill <= 1 break else {
|
||||||
|
@inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
|
||||||
|
@inline(memory.set, Color, &color, bottom_start_idx, @bitcast(tr.x))
|
||||||
|
|
||||||
|
top_start_idx += surface.width
|
||||||
|
bottom_start_idx -= surface.width
|
||||||
|
rows_to_fill -= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
clone := fn(self: ^Self): Self {
|
if rows_to_fill == 1 {
|
||||||
new_self := Self.new(self.width, self.height)
|
@inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
|
||||||
memory.copy(Color, self.buf, new_self.buf, self.size)
|
|
||||||
return new_self
|
|
||||||
}
|
|
||||||
$clear := fn(self: Self, color: Color): void {
|
|
||||||
memory.set(Color, &color, self.buf, self.size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sync := fn(self: Self): void {
|
return
|
||||||
memory.copy(Color, self.buf, framebuffer, self.size)
|
}
|
||||||
|
|
||||||
|
put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
||||||
|
start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||||
|
end_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y)
|
||||||
|
right_start_idx := @inline(indexptr, surface, pos.x + tr.x, pos.y)
|
||||||
|
|
||||||
|
loop if start_idx > end_idx break else {
|
||||||
|
*start_idx = color;
|
||||||
|
*right_start_idx = color
|
||||||
|
start_idx += surface.width
|
||||||
|
right_start_idx += surface.width
|
||||||
}
|
}
|
||||||
|
|
||||||
$index := fn(self: Self, x: uint, y: uint): uint {
|
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y), @bitcast(tr.x + 1))
|
||||||
return x + self.width * y
|
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
|
||||||
|
dx := @as(int, @bitcast(p1.x - p0.x))
|
||||||
|
dy := @as(int, @bitcast(p1.y - p0.y))
|
||||||
|
yi := 1
|
||||||
|
if dy < 0 {
|
||||||
|
yi = -1
|
||||||
|
dy = -dy
|
||||||
}
|
}
|
||||||
|
D := @as(int, 2) * dy - dx
|
||||||
$indexptr := fn(self: Self, x: uint, y: uint): ^Color {
|
y := p0.y
|
||||||
return self.buf + self.index(x, y)
|
x := p0.x
|
||||||
}
|
loop if x == p1.x break else {
|
||||||
|
*@inline(indexptr, surface, x, y) = color
|
||||||
$put_pixel := fn(self: Self, pos: Vec2(uint), color: Color): void {
|
if D > 0 {
|
||||||
*self.indexptr(pos.x, pos.y) = color
|
y += yi
|
||||||
}
|
D += 2 * (dy - dx)
|
||||||
|
|
||||||
put_filled_rect := fn(self: Self, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
|
||||||
top_start_idx := self.indexptr(pos.x, pos.y)
|
|
||||||
bottom_start_idx := self.indexptr(pos.x, pos.y + tr.y - 1)
|
|
||||||
rows_to_fill := tr.y
|
|
||||||
|
|
||||||
loop if rows_to_fill <= 1 break else {
|
|
||||||
memory.set(Color, &color, top_start_idx, tr.x)
|
|
||||||
memory.set(Color, &color, bottom_start_idx, tr.x)
|
|
||||||
|
|
||||||
top_start_idx += self.width
|
|
||||||
bottom_start_idx -= self.width
|
|
||||||
rows_to_fill -= 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if rows_to_fill == 1 {
|
|
||||||
memory.set(Color, &color, top_start_idx, tr.x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
put_rect := fn(self: Self, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
|
||||||
start_idx := self.indexptr(pos.x, pos.y)
|
|
||||||
end_idx := self.indexptr(pos.x, pos.y + tr.y)
|
|
||||||
right_start_idx := self.indexptr(pos.x + tr.x, pos.y)
|
|
||||||
|
|
||||||
loop if start_idx > end_idx break else {
|
|
||||||
*start_idx = color;
|
|
||||||
*right_start_idx = color
|
|
||||||
start_idx += self.width
|
|
||||||
right_start_idx += self.width
|
|
||||||
}
|
|
||||||
|
|
||||||
memory.set(Color, &color, self.indexptr(pos.x, pos.y), @bitcast(tr.x + 1))
|
|
||||||
memory.set(Color, &color, self.indexptr(pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
put_line_low := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
|
|
||||||
dx := @as(int, @bitcast(p1.x - p0.x))
|
|
||||||
dy := @as(int, @bitcast(p1.y - p0.y))
|
|
||||||
yi := 1
|
|
||||||
if dy < 0 {
|
|
||||||
yi = -1
|
|
||||||
dy = -dy
|
|
||||||
}
|
|
||||||
D := @as(int, 2) * dy - dx
|
|
||||||
y := p0.y
|
|
||||||
x := p0.x
|
|
||||||
loop if x == p1.x break else {
|
|
||||||
*self.indexptr(x, y) = color
|
|
||||||
if D > 0 {
|
|
||||||
y += yi
|
|
||||||
D += 2 * (dy - dx)
|
|
||||||
} else {
|
|
||||||
D += 2 * dy
|
|
||||||
}
|
|
||||||
x += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
put_line_high := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
|
|
||||||
dx := @as(int, @bitcast(p1.x - p0.x))
|
|
||||||
dy := @as(int, @bitcast(p1.y - p0.y))
|
|
||||||
xi := 1
|
|
||||||
if dy < 0 {
|
|
||||||
xi = -1
|
|
||||||
dx = -dx
|
|
||||||
}
|
|
||||||
D := @as(int, 2) * dx - dy
|
|
||||||
x := p0.x
|
|
||||||
y := p0.y
|
|
||||||
loop if y == p1.y break else {
|
|
||||||
*self.indexptr(x, y) = color
|
|
||||||
if D > 0 {
|
|
||||||
x += xi
|
|
||||||
D += 2 * (dx - dy)
|
|
||||||
} else {
|
|
||||||
D += 2 * dx
|
|
||||||
}
|
|
||||||
y += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
put_line := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
|
|
||||||
if math.abs(int, @bitcast(p1.y - p0.y)) < math.abs(int, @bitcast(p1.x - p0.x)) {
|
|
||||||
if p0.x > p1.x {
|
|
||||||
@inline(put_line_low, self, p1, p0, color)
|
|
||||||
} else {
|
|
||||||
@inline(put_line_low, self, p0, p1, color)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if p0.y > p1.y {
|
D += 2 * dy
|
||||||
@inline(put_line_high, self, p1, p0, color)
|
}
|
||||||
} else {
|
x += 1
|
||||||
@inline(put_line_high, self, p0, p1, color)
|
}
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
|
||||||
|
dx := @as(int, @bitcast(p1.x - p0.x))
|
||||||
|
dy := @as(int, @bitcast(p1.y - p0.y))
|
||||||
|
xi := 1
|
||||||
|
if dy < 0 {
|
||||||
|
xi = -1
|
||||||
|
dx = -dx
|
||||||
|
}
|
||||||
|
D := @as(int, 2) * dx - dy
|
||||||
|
x := p0.x
|
||||||
|
y := p0.y
|
||||||
|
loop if y == p1.y break else {
|
||||||
|
*@inline(indexptr, surface, x, y) = color
|
||||||
|
if D > 0 {
|
||||||
|
x += xi
|
||||||
|
D += 2 * (dx - dy)
|
||||||
|
} else {
|
||||||
|
D += 2 * dx
|
||||||
|
}
|
||||||
|
y += 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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 p0.x > p1.x {
|
||||||
|
@inline(put_line_low, surface, p1, p0, color)
|
||||||
|
} else {
|
||||||
|
@inline(put_line_low, surface, p0, p1, color)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if p0.y > p1.y {
|
||||||
|
@inline(put_line_high, surface, p1, p0, color)
|
||||||
|
} else {
|
||||||
|
@inline(put_line_high, surface, p0, p1, color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
put_surface := fn(self: Self, top: Self, pos: Vec2(uint), flip_v: bool): void {
|
put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool): void {
|
||||||
src_top_cursor := top.buf
|
top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||||
src_bottom_cursor := top.buf + top.width * (top.height - 1)
|
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1)
|
||||||
|
rows_to_copy := top.height
|
||||||
dst_top_idx := self.indexptr(pos.x, pos.y)
|
top_cursor := top.buf
|
||||||
dst_bottom_idx := self.indexptr(pos.x, pos.y + top.height - 1)
|
bottom_cursor := top.buf + top.width * (top.height - 1)
|
||||||
|
|
||||||
dst_increment := self.width
|
|
||||||
|
|
||||||
|
loop if rows_to_copy <= 1 break else {
|
||||||
if flip_v {
|
if flip_v {
|
||||||
dst_increment = -dst_increment
|
@inline(memory.copy, Color, top_cursor, bottom_start_idx, @bitcast(top.width))
|
||||||
tmp := dst_top_idx
|
@inline(memory.copy, Color, bottom_cursor, top_start_idx, @bitcast(top.width))
|
||||||
dst_top_idx = dst_bottom_idx
|
} else {
|
||||||
dst_bottom_idx = tmp
|
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
|
||||||
|
@inline(memory.copy, Color, bottom_cursor, bottom_start_idx, @bitcast(top.width))
|
||||||
}
|
}
|
||||||
|
|
||||||
rows_to_copy := top.height
|
top_start_idx += surface.width
|
||||||
|
bottom_start_idx -= surface.width
|
||||||
loop if rows_to_copy <= 1 break else {
|
top_cursor += top.width
|
||||||
memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
|
bottom_cursor -= top.width
|
||||||
memory.copy(Color, src_bottom_cursor, dst_bottom_idx, top.width)
|
rows_to_copy -= 2
|
||||||
|
|
||||||
dst_top_idx += dst_increment
|
|
||||||
dst_bottom_idx -= dst_increment
|
|
||||||
src_top_cursor += top.width
|
|
||||||
src_bottom_cursor -= top.width
|
|
||||||
rows_to_copy -= 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if rows_to_copy == 1 {
|
|
||||||
memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// peony-made
|
if rows_to_copy == 1 {
|
||||||
put_trirect := fn(self: Self, pos: Vec2(uint), size: Vec2(int), color0: Color, color1: Color): void {
|
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
|
||||||
step := Vec2(int).(1, 1)
|
|
||||||
if size.x < 0 {
|
|
||||||
step.x = -1
|
|
||||||
}
|
|
||||||
if size.y < 0 {
|
|
||||||
step.y /= @bitcast(size.x)
|
|
||||||
}
|
|
||||||
|
|
||||||
start_y := pos.y
|
|
||||||
target := pos + @bitcast(size)
|
|
||||||
|
|
||||||
loop if pos.x == target.x break else {
|
|
||||||
@inline(put_vline, self, pos.x, pos.y, target.y, color0)
|
|
||||||
@inline(put_vline, self, pos.x, pos.y, start_y, color1)
|
|
||||||
pos += @bitcast(step)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// peony-made
|
return
|
||||||
put_vline := fn(self: Self, x: uint, y0: uint, y1: uint, color: Color): void {
|
}
|
||||||
if y1 < y0 {
|
|
||||||
tmp := y0
|
|
||||||
y0 = y1
|
|
||||||
y1 = tmp
|
|
||||||
}
|
|
||||||
y := y0
|
|
||||||
|
|
||||||
loop if y == y1 break else {
|
// peony-made
|
||||||
*self.indexptr(x, y) = color
|
put_trirect := fn(surface: Surface, pos: Vec2(uint), size: Vec2(int), color0: Color, color1: Color): void {
|
||||||
y += 1
|
step := Vec2(int).(1, 1)
|
||||||
}
|
if size.x < 0 {
|
||||||
|
step.x = -1
|
||||||
|
}
|
||||||
|
if size.y < 0 {
|
||||||
|
step.y /= @bitcast(size.x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// peony-made
|
start_y := pos.y
|
||||||
put_hline := fn(self: Self, y: uint, x0: uint, x1: uint, color: Color): void {
|
target := pos + @bitcast(size)
|
||||||
if x1 < x0 {
|
|
||||||
tmp := x0
|
loop if pos.x == target.x break else {
|
||||||
x0 = x1
|
@inline(put_vline, surface, pos.x, pos.y, target.y, color0)
|
||||||
x1 = tmp
|
@inline(put_vline, surface, pos.x, pos.y, start_y, color1)
|
||||||
}
|
pos += @bitcast(step)
|
||||||
memory.set(Color, &color, self.indexptr(x0, y), @bitcast(x1 - x0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
put_circle := fn(self: Self, pos: Vec2(uint), radius: uint, color: Color): void {
|
return
|
||||||
x := 0
|
}
|
||||||
y := radius
|
|
||||||
error := @as(int, 3) - 2 * @intcast(radius)
|
// peony-made
|
||||||
loop if x > y break else {
|
put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): void {
|
||||||
self.put_pixel(pos + .(x, y), color)
|
if y1 < y0 {
|
||||||
self.put_pixel(pos + .(-x, y), color)
|
tmp := y0
|
||||||
self.put_pixel(pos + .(x, -y), color)
|
y0 = y1
|
||||||
self.put_pixel(pos + .(-x, -y), color)
|
y1 = tmp
|
||||||
self.put_pixel(pos + .(y, x), color)
|
}
|
||||||
self.put_pixel(pos + .(-y, x), color)
|
y := y0
|
||||||
self.put_pixel(pos + .(y, -x), color)
|
|
||||||
self.put_pixel(pos + .(-y, -x), color)
|
loop if y == y1 break else {
|
||||||
if error < 0 {
|
*@inline(indexptr, surface, x, y) = color
|
||||||
error += 4 * @intcast(x) + 6
|
y += 1
|
||||||
} else {
|
|
||||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
|
||||||
y -= 1
|
|
||||||
}
|
|
||||||
x += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
put_filled_circle := fn(self: Self, pos: Vec2(uint), radius: uint, color: Color): void {
|
return
|
||||||
x := 0
|
}
|
||||||
y := radius
|
|
||||||
error := @as(int, 3) - 2 * @intcast(radius)
|
|
||||||
|
|
||||||
loop if x > y break else {
|
// peony-made
|
||||||
self.put_hline(pos.y + y, pos.x - x, pos.x + x, color)
|
put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): void {
|
||||||
self.put_hline(pos.y - y, pos.x - x, pos.x + x, color)
|
if x1 < x0 {
|
||||||
|
tmp := x0
|
||||||
if x != y {
|
x0 = x1
|
||||||
self.put_hline(pos.y + x, pos.x - y, pos.x + y, color)
|
x1 = tmp
|
||||||
self.put_hline(pos.y - x, pos.x - y, pos.x + y, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if error < 0 {
|
|
||||||
error += 4 * @intcast(x) + 6
|
|
||||||
} else {
|
|
||||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
|
||||||
y -= 1
|
|
||||||
}
|
|
||||||
x += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@inline(memory.set, Color, &color, @inline(indexptr, surface, x0, y), @bitcast(x1 - x0 - 1))
|
||||||
|
|
||||||
put_textured_circle := fn(self: Self, source: Self, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void {
|
return
|
||||||
x := 0
|
}
|
||||||
y := radius
|
|
||||||
error := @as(int, 3) - 2 * @intcast(radius)
|
|
||||||
|
|
||||||
loop if x > y break else {
|
put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
|
||||||
memory.copy(Color, source.indexptr(source_pos.x - x, source_pos.y + y), self.indexptr(pos.x - x, pos.y + y), 2 * x)
|
cursor := Vec2(uint).(pos.x, pos.y)
|
||||||
memory.copy(Color, source.indexptr(source_pos.x - x, source_pos.y - y), self.indexptr(pos.x - x, pos.y - y), 2 * x)
|
current_char := str
|
||||||
|
|
||||||
if x != y {
|
loop if *current_char == 0 break else {
|
||||||
memory.copy(Color, source.indexptr(source_pos.x - y, source_pos.y + x), self.indexptr(pos.x - y, pos.y + x), 2 * y)
|
if *current_char == 10 {
|
||||||
memory.copy(Color, source.indexptr(source_pos.x - y, source_pos.y - x), self.indexptr(pos.x - y, pos.y - x), 2 * y)
|
cursor.x = pos.x
|
||||||
}
|
cursor.y += font.height + font.line_gap
|
||||||
|
current_char += 1
|
||||||
if error < 0 {
|
continue
|
||||||
error += 4 * @intcast(x) + 6
|
|
||||||
} else {
|
|
||||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
|
||||||
y -= 1
|
|
||||||
}
|
|
||||||
x += 1
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
put_text := fn(self: Self, font: Font, pos: Vec2(uint), color: Color, str: []u8): void {
|
glyph_data := @inline(get_glyph, font, @intcast(*current_char))
|
||||||
cursor := Vec2(uint).(pos.x, pos.y)
|
if glyph_data == idk {
|
||||||
|
current_char += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
max_y := self.height - font.height
|
if cursor.x % surface.width + font.width >= surface.width {
|
||||||
next_line_y := font.height + font.line_gap
|
cursor.x = pos.x
|
||||||
char_advance := font.width + font.char_gap
|
cursor.y += font.height + font.line_gap
|
||||||
self_width := self.width
|
}
|
||||||
|
if cursor.y + font.height > surface.height break
|
||||||
|
|
||||||
i := 0
|
dest := @inline(indexptr, surface, cursor.x, cursor.y)
|
||||||
|
src := glyph_data
|
||||||
|
rows_remaining := font.height
|
||||||
|
|
||||||
loop if i >= str.len break else {
|
loop if rows_remaining == 0 break else {
|
||||||
if cursor.y > max_y break
|
byte := *glyph_data
|
||||||
|
pixel_dest := dest
|
||||||
|
mask := @as(u8, 0x80)
|
||||||
|
bits_remaining := font.width
|
||||||
|
|
||||||
glyph_data := @as(^u8, idk)
|
loop if bits_remaining == 0 break else {
|
||||||
code_point := @as(uint, 0)
|
if (byte & mask) != 0 {
|
||||||
|
*pixel_dest = color
|
||||||
if (str[i] & 0x80) == 0 {
|
|
||||||
if str[i] == '\n' {
|
|
||||||
cursor.x = pos.x
|
|
||||||
cursor.y += next_line_y
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
pixel_dest += 1
|
||||||
if font.unicode == null {
|
mask >>= 1
|
||||||
if str[i] > font.num_glyphs {
|
if mask == 0 {
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
glyph_data = get_glyph(font, str[i])
|
|
||||||
} else {
|
|
||||||
if str[i] < UNC_TABLE_SIZE {
|
|
||||||
glyph_index := *(font.unicode + str[i])
|
|
||||||
if glyph_index == 0xFFFF {
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
glyph_data = font.data + glyph_index * font.bytes_per_glyph
|
|
||||||
} else {
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
} else if font.unicode != null {
|
|
||||||
first_byte := str[i]
|
|
||||||
num_bytes := @as(uint, 0)
|
|
||||||
|
|
||||||
num_bytes = utf8_len_table[first_byte >> 5 & 0x3]
|
|
||||||
|
|
||||||
if num_bytes == 0 {
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
code_point = first_byte & (0x7F >> num_bytes | 0x1F)
|
|
||||||
|
|
||||||
valid_sequence := true
|
|
||||||
bytes_processed := 1
|
|
||||||
|
|
||||||
loop if bytes_processed >= num_bytes break else {
|
|
||||||
i += 1
|
|
||||||
if i == str.len | (str[i] & 0xC0) != 0x80 {
|
|
||||||
valid_sequence = false
|
|
||||||
}
|
|
||||||
if valid_sequence == false {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
code_point = code_point << 6 | str[i] & 0x3F
|
|
||||||
bytes_processed += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid_sequence == false {
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
if code_point == '\n' {
|
|
||||||
cursor.x = pos.x
|
|
||||||
cursor.y += next_line_y
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if code_point >= UNC_TABLE_SIZE {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
glyph_index := *(font.unicode + code_point)
|
|
||||||
if glyph_index == 0xFFFF {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
glyph_data = font.data + glyph_index * font.bytes_per_glyph
|
|
||||||
}
|
|
||||||
|
|
||||||
if cursor.x + font.width >= self_width {
|
|
||||||
cursor.x = pos.x
|
|
||||||
cursor.y += next_line_y
|
|
||||||
}
|
|
||||||
|
|
||||||
dest := self.indexptr(cursor.x, cursor.y)
|
|
||||||
rows := font.height
|
|
||||||
|
|
||||||
loop if rows == 0 break else {
|
|
||||||
byte := *glyph_data
|
|
||||||
pixel_dest := dest
|
|
||||||
mask := @as(u8, 0x80)
|
|
||||||
bits := font.width
|
|
||||||
|
|
||||||
loop if bits == 0 break else {
|
|
||||||
if (byte & mask) != 0 {
|
|
||||||
*pixel_dest = color
|
|
||||||
}
|
|
||||||
pixel_dest += 1
|
|
||||||
mask >>= 1
|
|
||||||
if mask == 0 & bits > 0 {
|
|
||||||
glyph_data += 1
|
|
||||||
byte = *glyph_data
|
|
||||||
mask = 0x80
|
|
||||||
}
|
|
||||||
bits -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if mask != 0x80 {
|
|
||||||
glyph_data += 1
|
glyph_data += 1
|
||||||
|
byte = *glyph_data
|
||||||
|
mask = 0x80
|
||||||
}
|
}
|
||||||
dest += self_width
|
bits_remaining -= 1
|
||||||
rows -= 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.x += char_advance
|
glyph_data += 1
|
||||||
|
dest += surface.width
|
||||||
|
rows_remaining -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor.x += font.width + font.char_gap
|
||||||
|
current_char += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
.{log, memory} := @use("stn")
|
.{log} := @use("../../stn/src/lib.hb")
|
||||||
|
|
||||||
PSF1Header := packed struct {
|
PSF1Header := packed struct {
|
||||||
magic: u16,
|
magic: u16,
|
||||||
|
@ -23,16 +23,16 @@ Font := struct {
|
||||||
height: uint,
|
height: uint,
|
||||||
num_glyphs: uint,
|
num_glyphs: uint,
|
||||||
bytes_per_glyph: uint,
|
bytes_per_glyph: uint,
|
||||||
|
has_unicode_table: bool,
|
||||||
line_gap: uint,
|
line_gap: uint,
|
||||||
char_gap: uint,
|
char_gap: uint,
|
||||||
unicode: ?^u16,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
font_from_psf1 := fn(psf: ^u8): ?Font {
|
font_from_psf1 := fn(psf: ^u8): Font {
|
||||||
header := @as(^PSF1Header, @bitcast(psf))
|
header := @as(^PSF1Header, @bitcast(psf))
|
||||||
if header.magic != 0x436 {
|
if header.magic != 0x436 {
|
||||||
log.error("failed to load psf font: not a psf1 font, idiot")
|
log.error("failed to load psf font: not a psf1 font, idiot\0")
|
||||||
return null
|
return idk
|
||||||
}
|
}
|
||||||
|
|
||||||
psf += @sizeof(PSF1Header)
|
psf += @sizeof(PSF1Header)
|
||||||
|
@ -40,121 +40,36 @@ font_from_psf1 := fn(psf: ^u8): ?Font {
|
||||||
return .(
|
return .(
|
||||||
psf,
|
psf,
|
||||||
8,
|
8,
|
||||||
header.character_size,
|
@intcast(header.character_size),
|
||||||
256,
|
256,
|
||||||
header.character_size,
|
@intcast(header.character_size),
|
||||||
|
false,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
null,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
font_from_psf2 := fn(psf: ^u8, unicode: bool): ?Font {
|
font_from_psf2 := fn(psf: ^u8): Font {
|
||||||
header := @as(^PSF2Header, @bitcast(psf))
|
header := @as(^PSF2Header, @bitcast(psf))
|
||||||
if header.magic != 0x864AB572 {
|
if header.magic != 0x864AB572 {
|
||||||
log.error("failed to load psf font: not a psf2 font, idiot")
|
log.error("failed to load psf font: not a psf2 font, idiot\0")
|
||||||
return null
|
return idk
|
||||||
}
|
}
|
||||||
|
|
||||||
psf += header.header_size
|
psf += header.header_size
|
||||||
|
|
||||||
font := Font.(
|
return .(
|
||||||
psf,
|
psf,
|
||||||
header.width,
|
@intcast(header.width),
|
||||||
header.height,
|
@intcast(header.height),
|
||||||
header.num_glyph,
|
@intcast(header.num_glyph),
|
||||||
header.bytes_per_glyph,
|
@intcast(header.bytes_per_glyph),
|
||||||
|
(header.flags & 1) != 0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
null,
|
|
||||||
)
|
)
|
||||||
if (header.flags & 1) != 0 & unicode {
|
|
||||||
init_unicode(&font)
|
|
||||||
}
|
|
||||||
return font
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$get_glyph := fn(font: Font, index: u8): ^u8 {
|
get_glyph := fn(font: Font, index: uint): ^u8 {
|
||||||
return font.data + @as(uint, index) * font.bytes_per_glyph
|
return font.data + index * font.bytes_per_glyph
|
||||||
}
|
|
||||||
|
|
||||||
$UNC_TABLE_SIZE := 1 << 16
|
|
||||||
|
|
||||||
init_unicode := fn(font: ^Font): void {
|
|
||||||
font.unicode = memory.alloc(u16, UNC_TABLE_SIZE)
|
|
||||||
|
|
||||||
memory.set(u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE)
|
|
||||||
|
|
||||||
table := font.data + font.num_glyphs * font.bytes_per_glyph
|
|
||||||
curr_glyph := @as(u16, 0)
|
|
||||||
|
|
||||||
loop if curr_glyph >= font.num_glyphs break else {
|
|
||||||
loop {
|
|
||||||
byte := *table
|
|
||||||
table += 1
|
|
||||||
|
|
||||||
if byte == 0xFF break
|
|
||||||
if byte == 0xFE {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
unicode := @as(uint, 0)
|
|
||||||
bytes_to_read := @as(uint, 1)
|
|
||||||
|
|
||||||
if (byte & 0x80) == 0 {
|
|
||||||
unicode = byte
|
|
||||||
} else if (byte & 0xE0) == 0xC0 {
|
|
||||||
unicode = byte & 0x1F
|
|
||||||
bytes_to_read = 2
|
|
||||||
} else if (byte & 0xF0) == 0xE0 {
|
|
||||||
unicode = byte & 0xF
|
|
||||||
bytes_to_read = 3
|
|
||||||
} else if (byte & 0xF8) == 0xF0 {
|
|
||||||
unicode = byte & 0x7
|
|
||||||
bytes_to_read = 4
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
valid := true
|
|
||||||
loop if bytes_to_read <= 1 break else {
|
|
||||||
next_byte := *table
|
|
||||||
if (next_byte & 0xC0) != 0x80 {
|
|
||||||
valid = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
unicode = unicode << 6 | next_byte & 0x3F
|
|
||||||
table += 1
|
|
||||||
bytes_to_read -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid == false continue
|
|
||||||
|
|
||||||
if bytes_to_read == 4 {
|
|
||||||
if unicode < 0x10000 | unicode > 0x10FFFF continue
|
|
||||||
|
|
||||||
if unicode <= 0xFFFF {
|
|
||||||
if unicode < UNC_TABLE_SIZE {
|
|
||||||
*(@unwrap(font.unicode) + unicode) = curr_glyph
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unicode -= 0x10000
|
|
||||||
high_surrogate := 0xD800 | unicode >> 10 & 0x3FF
|
|
||||||
low_surrogate := 0xDC00 | unicode & 0x3FF
|
|
||||||
|
|
||||||
if high_surrogate < UNC_TABLE_SIZE {
|
|
||||||
*(@unwrap(font.unicode) + high_surrogate) = curr_glyph
|
|
||||||
}
|
|
||||||
if low_surrogate < UNC_TABLE_SIZE {
|
|
||||||
*(@unwrap(font.unicode) + low_surrogate) = curr_glyph
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if unicode < UNC_TABLE_SIZE {
|
|
||||||
*(@unwrap(font.unicode) + unicode) = curr_glyph
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
curr_glyph += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
AllocReturn := struct {
|
|
||||||
byte_count: uint,
|
|
||||||
ptr: ?^u8,
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
.{log, panic, memory} := @use("stn")
|
|
||||||
alloc_return := @use("alloc_return.hb")
|
|
||||||
|
|
||||||
/* the block size is 64 bytes, 64 blocks of 64 bytes.
|
|
||||||
this will very quickly lead to exhaustion of free blocks.
|
|
||||||
*/
|
|
||||||
BlockAlloc := struct {
|
|
||||||
// hi
|
|
||||||
state: uint,
|
|
||||||
ptr: ?^u8,
|
|
||||||
|
|
||||||
$init := fn(): Self {
|
|
||||||
alloc_page_ptr := memory.request_page(1)
|
|
||||||
state := 0xFFFFFFFFFFFFFFFF
|
|
||||||
return .(state, alloc_page_ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
alloc := fn(self: Self, alloc_type: type, count: uint): alloc_return.AllocReturn {
|
|
||||||
offset := 0
|
|
||||||
state_2 := 0
|
|
||||||
loop {
|
|
||||||
xyz := self.state & 1
|
|
||||||
abc := if xyz == 1 {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
// check if the `offset` bit is 1, if it is move to the next offset
|
|
||||||
if abc {
|
|
||||||
offset += 1
|
|
||||||
return .(0, null)
|
|
||||||
} else {
|
|
||||||
log.info("Already Allocated")
|
|
||||||
}
|
|
||||||
|
|
||||||
// else {
|
|
||||||
// // self it to 1 and return the ptr to the allocation
|
|
||||||
// self.state |= a
|
|
||||||
// // return ptr + offset * 64
|
|
||||||
// if self.ptr != null {
|
|
||||||
// return .(64, self.ptr + offset * 64)
|
|
||||||
// } else {
|
|
||||||
// // panic.panic("Allocator is not inited.")
|
|
||||||
// // return .(0, null)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// there are only 64 blocks
|
|
||||||
if offset >= 64 {
|
|
||||||
return .(0, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dealloc := fn(self: Self, ptr: ^u8, alloc_type: type, count: uint): void {
|
|
||||||
// size := size_of(alloc_type)*count
|
|
||||||
size := 64
|
|
||||||
// get the size alligned to the nearest block
|
|
||||||
// rounded_size := nearest_block_size_rounded_up(size)
|
|
||||||
rounded_size := 64
|
|
||||||
|
|
||||||
state_bit_start := {
|
|
||||||
// Do math here to figure out what starting ptr corresponds to what bit
|
|
||||||
3
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := 0
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if rounded_size > 0 {
|
|
||||||
// set state_bit_start+offset to 0
|
|
||||||
|
|
||||||
// at the end move to the next one
|
|
||||||
offset += 1
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
rounded_size -= 64
|
|
||||||
}
|
|
||||||
return void
|
|
||||||
}
|
|
||||||
|
|
||||||
$deinit := fn(self: Self): void {
|
|
||||||
self.state = 0
|
|
||||||
self.ptr = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// request a kernel page
|
|
||||||
// ptr := memory.alloc(1)
|
|
|
@ -1,19 +0,0 @@
|
||||||
alloc_return := @use("alloc_return.hb")
|
|
||||||
|
|
||||||
FakeAlloc := struct {
|
|
||||||
$init := fn(): Self {
|
|
||||||
return .()
|
|
||||||
}
|
|
||||||
|
|
||||||
$alloc := fn(self: Self, alloc_type: type, count: uint): alloc_return.AllocReturn {
|
|
||||||
return .(0, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
$dealloc := fn(self: Self, ptr: ^u8, alloc_type: type, count: uint): void {
|
|
||||||
return void
|
|
||||||
}
|
|
||||||
// Nothing to clean up here
|
|
||||||
$deinit := fn(self: Self): void {
|
|
||||||
return void
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
.{BlockAlloc} := @use("block_alloc.hb");
|
|
||||||
.{FakeAlloc} := @use("fake_alloc.hb")
|
|
|
@ -1,25 +0,0 @@
|
||||||
allocators := @use("alloc/alloc.hb")
|
|
||||||
|
|
||||||
AStruct := struct {
|
|
||||||
a_field: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
main := fn():void{
|
|
||||||
alloc := allocators.FakeAlloc.init()
|
|
||||||
astruct := alloc.alloc(AStruct, 2)
|
|
||||||
if astruct.ptr != null{
|
|
||||||
panic("FakeAlloc actually allocated.")
|
|
||||||
}
|
|
||||||
alloc.dealloc(astruct_ptr, AStruct, 2)
|
|
||||||
alloc.deinit()
|
|
||||||
|
|
||||||
balloc := allocators.BlockAlloc.init()
|
|
||||||
bstruct_ptr := balloc.alloc(AStruct, 2)
|
|
||||||
if bstruct_ptr == null {
|
|
||||||
panic("BlockAlloc actually didn't allocate.")
|
|
||||||
}
|
|
||||||
balloc.dealloc(bstruct_ptr, AStruct, 2)
|
|
||||||
balloc.deinit()
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
BIN
sysdata/libraries/stn/src/assets/sin_table
Normal file
BIN
sysdata/libraries/stn/src/assets/sin_table
Normal file
Binary file not shown.
|
@ -1,37 +1,27 @@
|
||||||
$await := fn(buffer_id: uint): void {
|
string := @use("string.hb")
|
||||||
return @eca(7, buffer_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
$recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
|
recv := fn($Expr: type, buffer_id: int, memory_map_location: ^u8): ^Expr {
|
||||||
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.ptr, msg.len), @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)
|
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
|
||||||
}
|
|
||||||
|
|
||||||
$delete := fn(buffer_id: uint): void {
|
|
||||||
return @eca(2, buffer_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
$search := fn(msg: []u8): uint {
|
|
||||||
return @eca(3, 0, BufferMsg.(3, msg.ptr, msg.len), @sizeof(BufferMsg))
|
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
$get := fn($Expr: type, query: []u8): Expr {
|
.{string} := @use("../../stn/src/lib.hb")
|
||||||
return @eca(3, 5, query, query.len)
|
|
||||||
|
get := fn($Expr: type, query: ^u8): Expr {
|
||||||
|
return @eca(3, 5, query, @inline(string.length, query))
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ acs := @use("acs.hb");
|
||||||
.{DiskID, FileID} := acs
|
.{DiskID, FileID} := acs
|
||||||
|
|
||||||
// Paths without a node-disk component are to be treated as local files.
|
// Paths without a node-disk component are to be treated as local files.
|
||||||
// file_path := "DID:/test"
|
// file_path := "DID:/test\0";
|
||||||
Path := struct {
|
Path := struct {
|
||||||
// DiskID holds the host id
|
// DiskID holds the host id
|
||||||
disk_id: DiskID,
|
disk_id: DiskID,
|
||||||
|
|
|
@ -1,285 +0,0 @@
|
||||||
.{Kind, usize, string, signed_int, panic, float, integer, memory, log: .{LogLevel}} := @use("stn")
|
|
||||||
|
|
||||||
fmt_int := fn(v: @Any(), str: []u8, radix: @TypeOf(v)): uint {
|
|
||||||
is_negative := signed_int(@TypeOf(v)) & v < 0
|
|
||||||
prefix_len := 0
|
|
||||||
if is_negative {
|
|
||||||
v = -v
|
|
||||||
str[0] = '-'
|
|
||||||
prefix_len += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if radix == 16 {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0x".ptr)
|
|
||||||
prefix_len += 2
|
|
||||||
} else if radix == 2 {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0b".ptr)
|
|
||||||
prefix_len += 2
|
|
||||||
} else if radix == 8 {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0o".ptr)
|
|
||||||
prefix_len += 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if v == 0 {
|
|
||||||
str[prefix_len] = '0'
|
|
||||||
return prefix_len + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
i := prefix_len
|
|
||||||
loop if v <= 0 break else {
|
|
||||||
remainder := v % radix
|
|
||||||
v /= radix
|
|
||||||
if remainder > 9 {
|
|
||||||
str[i] = @intcast(remainder - 10 + 'A')
|
|
||||||
} else {
|
|
||||||
str[i] = @intcast(remainder + '0')
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
string.reverse(str[prefix_len..i])
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt_bool := fn(v: bool, str: []u8): uint {
|
|
||||||
if v {
|
|
||||||
*@as(^[4]u8, @bitcast(str.ptr)) = *@bitcast("true".ptr)
|
|
||||||
return 4
|
|
||||||
} else {
|
|
||||||
*@as(^[5]u8, @bitcast(str.ptr)) = *@bitcast("false".ptr)
|
|
||||||
return 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$FP_TOLERANCE := 0.00000001
|
|
||||||
|
|
||||||
fmt_float := fn(v: @Any(), str: []u8, precision: uint, radix: int): uint {
|
|
||||||
is_negative := v < 0
|
|
||||||
|
|
||||||
prefix_len := 0
|
|
||||||
|
|
||||||
if is_negative {
|
|
||||||
v = -v
|
|
||||||
str[0] = '-'
|
|
||||||
prefix_len += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if radix == 16 {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0x".ptr)
|
|
||||||
prefix_len += 2
|
|
||||||
} else if radix == 2 {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0b".ptr)
|
|
||||||
prefix_len += 2
|
|
||||||
} else if radix == 8 {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0o".ptr)
|
|
||||||
prefix_len += 2
|
|
||||||
}
|
|
||||||
|
|
||||||
integer_part := @fti(v)
|
|
||||||
fractional_part := v - @itf(integer_part)
|
|
||||||
|
|
||||||
i := prefix_len
|
|
||||||
loop if integer_part == 0 & i > prefix_len break else {
|
|
||||||
remainder := integer_part % radix
|
|
||||||
integer_part /= radix
|
|
||||||
if remainder > 9 {
|
|
||||||
str[i] = @intcast(remainder - 10 + 'A')
|
|
||||||
} else {
|
|
||||||
str[i] = @intcast(remainder + '0')
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
string.reverse(str[prefix_len..i])
|
|
||||||
str[i] = '.'
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
p := precision
|
|
||||||
loop if p <= 0 | fractional_part < FP_TOLERANCE break else {
|
|
||||||
fractional_part *= @itf(radix)
|
|
||||||
digit := @fti(fractional_part)
|
|
||||||
if digit > 9 {
|
|
||||||
str[i] = @intcast(digit - 10 + 'A')
|
|
||||||
} else {
|
|
||||||
str[i] = @intcast(digit + '0')
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
fractional_part -= @itf(digit)
|
|
||||||
p -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt_container := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
|
|
||||||
T2 := @TypeOf(v)
|
|
||||||
kind := Kind.of(T2)
|
|
||||||
i := 0
|
|
||||||
len := 0
|
|
||||||
if kind == .Struct {
|
|
||||||
*@as(^[@intcast(@nameof(T2).len)]u8, @bitcast(str.ptr + len)) = *@bitcast(@nameof(T2).ptr)
|
|
||||||
len += @nameof(T2).len;
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
|
|
||||||
len += 2
|
|
||||||
} else if kind == .Slice {
|
|
||||||
*@as(^[@intcast(@nameof(@ChildOf(T2)).len)]u8, @bitcast(str.ptr + len)) = *@bitcast(@nameof(@ChildOf(T2)).ptr)
|
|
||||||
len += @nameof(@ChildOf(T2)).len;
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".[".ptr)
|
|
||||||
len += 2
|
|
||||||
} else if kind == .Tuple {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
|
|
||||||
len += 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if kind == .Slice {
|
|
||||||
loop {
|
|
||||||
len += @inline(format, v[i], str[len..], opts)
|
|
||||||
i += 1
|
|
||||||
if i == v.len break else {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(", ".ptr)
|
|
||||||
len += 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$loop {
|
|
||||||
len += @inline(format, v[i], str[len..], opts)
|
|
||||||
i += 1
|
|
||||||
if i == @lenof(T2) break else {
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(", ".ptr)
|
|
||||||
len += 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if kind == .Struct | kind == .Tuple {
|
|
||||||
*@as(^[1]u8, @bitcast(str.ptr + len)) = *@bitcast(")".ptr)
|
|
||||||
len += 1
|
|
||||||
} else if kind == .Slice {
|
|
||||||
*@as(^[1]u8, @bitcast(str.ptr + len)) = *@bitcast("]".ptr)
|
|
||||||
len += 1
|
|
||||||
}
|
|
||||||
return len
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt_nullable := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
|
|
||||||
if v == null {
|
|
||||||
*@as(^[4]u8, @bitcast(str.ptr)) = *@bitcast("null".ptr)
|
|
||||||
return 4
|
|
||||||
} else {
|
|
||||||
return @inline(format, @as(@ChildOf(@TypeOf(v)), v), str, opts)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt_enum := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
|
|
||||||
T := @TypeOf(v)
|
|
||||||
len := @nameof(T).len;
|
|
||||||
*@as(^[@intcast(@nameof(T).len)]u8, @bitcast(str.ptr)) = *@bitcast(@nameof(T).ptr);
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
|
|
||||||
len += 2
|
|
||||||
len += fmt_int(@as(usize(T), @bitcast(v)), str[len..], 10);
|
|
||||||
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(")".ptr)
|
|
||||||
return len + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO:
|
|
||||||
* Custom formatters using struct methods (T._fmt(self, str): uint),
|
|
||||||
* Format struct fields "Name.{a: x, b: y, c: z}"
|
|
||||||
* Optionally tabulate
|
|
||||||
* Add more FormatOption fields
|
|
||||||
* Support scientific notation for floating point
|
|
||||||
* Support format string
|
|
||||||
*/
|
|
||||||
|
|
||||||
FormatOptions := struct {
|
|
||||||
precision: uint = 2,
|
|
||||||
radix: uint = 10,
|
|
||||||
// temporarily here, will change later maybe
|
|
||||||
log: LogLevel = .Info,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SAFETY:
|
|
||||||
* Assumes the buffer is wide enough for the formatted text and a null char
|
|
||||||
* Does not clear the buffer for you
|
|
||||||
*/
|
|
||||||
|
|
||||||
format := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
|
|
||||||
T := @TypeOf(v)
|
|
||||||
match Kind.of(T) {
|
|
||||||
.Pointer => return @inline(fmt_int, @as(uint, @bitcast(v)), str, 16),
|
|
||||||
.Builtin => {
|
|
||||||
if integer(T) {
|
|
||||||
return @inline(fmt_int, v, str, @intcast(opts.radix))
|
|
||||||
} else if T == bool {
|
|
||||||
return @inline(fmt_bool, v, str)
|
|
||||||
} else if float(T) {
|
|
||||||
return @inline(fmt_float, v, str, opts.precision, @intcast(opts.radix))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.Opt => return @inline(fmt_nullable, v, str, opts),
|
|
||||||
.Enum => return @inline(fmt_enum, v, str, opts),
|
|
||||||
.Struct => return @inline(fmt_container, v, str, opts),
|
|
||||||
.Tuple => return @inline(fmt_container, v, str, opts),
|
|
||||||
.Slice => if T != []u8 return @inline(fmt_container, v, str, opts) else {
|
|
||||||
i := 0
|
|
||||||
loop if i == v.len break else {
|
|
||||||
str[i] = v[i]
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
return v.len
|
|
||||||
},
|
|
||||||
_ => @error("Type: \"", T, "\" is not supported."),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
format_with_str := fn(v: @Any(), read: []u8, write: []u8, opts: FormatOptions): uint {
|
|
||||||
T := @TypeOf(v)
|
|
||||||
n := string.count(read, '{')
|
|
||||||
if n != string.count(read, '}') panic("Missing closing '}' in format string.")
|
|
||||||
if Kind.of(T) == .Tuple {
|
|
||||||
if @lenof(T) != n panic("Format string has different number of '{}' than args given.")
|
|
||||||
m := 0
|
|
||||||
i := 0
|
|
||||||
j := 0
|
|
||||||
$loop if m > @lenof(T) break else {
|
|
||||||
if m == @lenof(T) {
|
|
||||||
loop if i == read.len break else {
|
|
||||||
write[j] = read[i]
|
|
||||||
i += 1
|
|
||||||
j += 1
|
|
||||||
}
|
|
||||||
m += 1
|
|
||||||
} else {
|
|
||||||
v2 := v[m]
|
|
||||||
loop if i == read.len break else {
|
|
||||||
if read[i] == '{' & read[i + 1] == '}' {
|
|
||||||
j += format(v2, write[j..], opts)
|
|
||||||
i += 2
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
write[j] = read[i]
|
|
||||||
i += 1
|
|
||||||
j += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return j
|
|
||||||
} else if n > 1 {
|
|
||||||
panic("Format string has multiple '{}' but value provided is not a tuple.")
|
|
||||||
} else {
|
|
||||||
i := 0
|
|
||||||
j := 0
|
|
||||||
loop if i == read.len break else {
|
|
||||||
if read[i] == '{' & read[i + 1] == '}' {
|
|
||||||
j += format(v, write[j..], opts)
|
|
||||||
i += 2
|
|
||||||
} else {
|
|
||||||
write[j] = read[i]
|
|
||||||
i += 1
|
|
||||||
j += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return j
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
/*
|
|
||||||
* This code is an implementation of the FoldHash algorithm from https://github.com/orlp/foldhash,
|
|
||||||
* originally written by Orson Peters under the zlib license.
|
|
||||||
*
|
|
||||||
* Changes to the original code were made to meet the simplicity requirements of this implementation.
|
|
||||||
* Behaviour aims to be equivalent but not identical to the original code.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2024 Orson Peters
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied warranty. In
|
|
||||||
* no event will the authors be held liable for any damages arising from the use of
|
|
||||||
* this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose, including
|
|
||||||
* commercial applications, and to alter it and redistribute it freely, subject to
|
|
||||||
* the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim
|
|
||||||
* that you wrote the original software. If you use this software in a product,
|
|
||||||
* an acknowledgment in the product documentation would be appreciated but is
|
|
||||||
* not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/;
|
|
||||||
|
|
||||||
.{math, random} := @use("stn")
|
|
||||||
|
|
||||||
$ARBITRARY0 := 0x243F6A8885A308D3
|
|
||||||
$ARBITRARY1 := 0x13198A2E03707344
|
|
||||||
$ARBITRARY2 := 0xA4093822299F31D0
|
|
||||||
$ARBITRARY3 := 0x82EFA98EC4E6C89
|
|
||||||
$ARBITRARY4 := 0x452821E638D01377
|
|
||||||
$ARBITRARY5 := 0xBE5466CF34E90C6C
|
|
||||||
$ARBITRARY6 := 0xC0AC29B7C97C50DD
|
|
||||||
$ARBITRARY7 := 0x3F84D5B5B5470917
|
|
||||||
$ARBITRARY8 := 0x9216D5D98979FB1B
|
|
||||||
$ARBITRARY9 := 0xD1310BA698DFB5AC
|
|
||||||
$FIXED_GLOBAL_SEED := uint.[ARBITRARY4, ARBITRARY5, ARBITRARY6, ARBITRARY7]
|
|
||||||
|
|
||||||
global_seed := 0
|
|
||||||
|
|
||||||
u128 := packed struct {a: uint, b: uint}
|
|
||||||
|
|
||||||
$folded_multiply := fn(x: uint, y: uint): uint {
|
|
||||||
lx := @as(u32, @intcast(x))
|
|
||||||
ly := @as(u32, @intcast(y))
|
|
||||||
hx := x >> 32
|
|
||||||
hy := y >> 32
|
|
||||||
afull := lx * hy
|
|
||||||
bfull := hx * ly
|
|
||||||
return afull ^ (bfull << 32 | bfull >> 32)
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_bytes_medium := fn(bytes: ^u8, len: uint, s0: uint, s1: uint, fold_seed: uint): uint {
|
|
||||||
lo := bytes
|
|
||||||
end := bytes + len
|
|
||||||
hi := end - 16
|
|
||||||
|
|
||||||
loop if lo >= hi break else {
|
|
||||||
a := *@as(^uint, @bitcast(lo))
|
|
||||||
b := *@as(^uint, @bitcast(lo + 8))
|
|
||||||
c := *@as(^uint, @bitcast(hi))
|
|
||||||
d := *@as(^uint, @bitcast(hi + 8))
|
|
||||||
s0 = folded_multiply(a ^ s0, c ^ fold_seed)
|
|
||||||
s1 = folded_multiply(b ^ s1, d ^ fold_seed)
|
|
||||||
hi -= 16
|
|
||||||
lo += 16
|
|
||||||
}
|
|
||||||
return s0 ^ s1
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_bytes_long := fn(bytes: ^u8, len: uint, s0: uint, s1: uint, s2: uint, s3: uint, fold_seed: uint): uint {
|
|
||||||
$chunk_size := 64
|
|
||||||
chunks := len / chunk_size
|
|
||||||
remainder := len % chunk_size
|
|
||||||
|
|
||||||
ptr := bytes
|
|
||||||
i := 0
|
|
||||||
loop if i >= chunks break else {
|
|
||||||
a := *@as(^uint, @bitcast(ptr))
|
|
||||||
b := *@as(^uint, @bitcast(ptr + 8))
|
|
||||||
c := *@as(^uint, @bitcast(ptr + 16))
|
|
||||||
d := *@as(^uint, @bitcast(ptr + 24))
|
|
||||||
e := *@as(^uint, @bitcast(ptr + 32))
|
|
||||||
f := *@as(^uint, @bitcast(ptr + 40))
|
|
||||||
g := *@as(^uint, @bitcast(ptr + 48))
|
|
||||||
h := *@as(^uint, @bitcast(ptr + 56))
|
|
||||||
|
|
||||||
s0 = folded_multiply(a ^ s0, e ^ fold_seed)
|
|
||||||
s1 = folded_multiply(b ^ s1, f ^ fold_seed)
|
|
||||||
s2 = folded_multiply(c ^ s2, g ^ fold_seed)
|
|
||||||
s3 = folded_multiply(d ^ s3, h ^ fold_seed)
|
|
||||||
|
|
||||||
ptr += chunk_size
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
s0 ^= s2
|
|
||||||
s1 ^= s3
|
|
||||||
|
|
||||||
if remainder > 0 {
|
|
||||||
remainder_start := bytes + len - math.max(uint, remainder, 16)
|
|
||||||
return @inline(hash_bytes_medium, remainder_start, math.max(uint, remainder, 16), s0, s1, fold_seed)
|
|
||||||
}
|
|
||||||
|
|
||||||
return s0 ^ s1
|
|
||||||
}
|
|
||||||
|
|
||||||
FoldHasher := struct {
|
|
||||||
accumulator: uint,
|
|
||||||
original_seed: uint,
|
|
||||||
sponge: u128,
|
|
||||||
sponge_len: u8,
|
|
||||||
fold_seed: uint,
|
|
||||||
expand_seed: uint,
|
|
||||||
expand_seed2: uint,
|
|
||||||
expand_seed3: uint,
|
|
||||||
|
|
||||||
$new := fn(seed: uint): Self {
|
|
||||||
return .(
|
|
||||||
seed,
|
|
||||||
seed,
|
|
||||||
.(0, 0),
|
|
||||||
0,
|
|
||||||
FIXED_GLOBAL_SEED[0],
|
|
||||||
FIXED_GLOBAL_SEED[1],
|
|
||||||
FIXED_GLOBAL_SEED[2],
|
|
||||||
FIXED_GLOBAL_SEED[3],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
default := fn(): Self {
|
|
||||||
if global_seed == 0 {
|
|
||||||
// ! consider this "secure enough" for now
|
|
||||||
global_seed = random.any(uint)
|
|
||||||
}
|
|
||||||
return Self.new(global_seed)
|
|
||||||
}
|
|
||||||
|
|
||||||
write := fn(self: ^Self, bytes: ^u8, len: uint): void {
|
|
||||||
s0 := self.accumulator
|
|
||||||
s1 := self.expand_seed
|
|
||||||
if len <= 16 {
|
|
||||||
if len >= 8 {
|
|
||||||
s0 ^= *@bitcast(bytes)
|
|
||||||
s1 ^= *@bitcast(bytes + len - 8)
|
|
||||||
} else if len >= 4 {
|
|
||||||
s0 ^= *@as(^u32, @bitcast(bytes))
|
|
||||||
s1 ^= *@as(^u32, @bitcast(bytes + len - 4))
|
|
||||||
} else if len > 0 {
|
|
||||||
lo := *bytes
|
|
||||||
mid := *(bytes + len / 2)
|
|
||||||
hi := *(bytes + len - 1)
|
|
||||||
s0 ^= lo
|
|
||||||
s1 ^= @as(uint, hi) << 8 | mid
|
|
||||||
}
|
|
||||||
self.accumulator = folded_multiply(s0, s1)
|
|
||||||
} else if len < 256 {
|
|
||||||
self.accumulator = @inline(hash_bytes_medium, bytes, len, s0, s1, self.fold_seed)
|
|
||||||
} else {
|
|
||||||
self.accumulator = @inline(hash_bytes_long, bytes, len, s0, s1, self.expand_seed2, self.expand_seed3, self.fold_seed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
finish := fn(self: ^Self): uint {
|
|
||||||
if self.sponge_len > 0 {
|
|
||||||
return folded_multiply(self.sponge.b ^ self.accumulator, self.sponge.a ^ self.fold_seed)
|
|
||||||
} else {
|
|
||||||
return self.accumulator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reset := fn(self: ^Self): void {
|
|
||||||
self.accumulator = self.original_seed
|
|
||||||
self.sponge = .(0, 0)
|
|
||||||
self.sponge_len = 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
//! NON CRYPTOGRAPHIC HASHER
|
|
||||||
foldhash := @use("foldhash.hb")
|
|
|
@ -1,7 +1,4 @@
|
||||||
acs := @use("acs.hb")
|
acs := @use("acs.hb")
|
||||||
allocators := @use("alloc/lib.hb")
|
|
||||||
fmt := @use("fmt.hb")
|
|
||||||
hashers := @use("hash/lib.hb")
|
|
||||||
string := @use("string.hb")
|
string := @use("string.hb")
|
||||||
log := @use("log.hb")
|
log := @use("log.hb")
|
||||||
memory := @use("memory.hb")
|
memory := @use("memory.hb")
|
||||||
|
@ -9,58 +6,4 @@ buffer := @use("buffer.hb")
|
||||||
math := @use("math.hb")
|
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")
|
|
||||||
sleep := @use("sleep.hb")
|
|
||||||
|
|
||||||
panic := fn(message: ?[]u8): never {
|
|
||||||
log.printf("HBLang Panic: {}", message, .{log: .Error})
|
|
||||||
die
|
|
||||||
}
|
|
||||||
|
|
||||||
Kind := enum {
|
|
||||||
Builtin,
|
|
||||||
Struct,
|
|
||||||
Tuple,
|
|
||||||
Enum,
|
|
||||||
Union,
|
|
||||||
Pointer,
|
|
||||||
Slice,
|
|
||||||
Opt,
|
|
||||||
Function,
|
|
||||||
Template,
|
|
||||||
Global,
|
|
||||||
Const,
|
|
||||||
Module,
|
|
||||||
$of := fn($T: type): Self {
|
|
||||||
return @bitcast(@kindof(T))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$unsigned_int := fn($T: type): bool {
|
|
||||||
return T == uint | T == u8 | T == u16 | T == u32
|
|
||||||
}
|
|
||||||
|
|
||||||
$signed_int := fn($T: type): bool {
|
|
||||||
return T == int | T == i8 | T == i16 | T == i32
|
|
||||||
}
|
|
||||||
|
|
||||||
$integer := fn($T: type): bool {
|
|
||||||
return unsigned_int(T) | signed_int(T)
|
|
||||||
}
|
|
||||||
|
|
||||||
$float := fn($T: type): bool {
|
|
||||||
return T == f32 | T == f64
|
|
||||||
}
|
|
||||||
|
|
||||||
$usize := fn($T: type): type {
|
|
||||||
if @sizeof(T) == 1 return u8 else if @sizeof(T) == 2 return u16 else if @sizeof(T) == 4 return u32 else return uint
|
|
||||||
}
|
|
||||||
|
|
||||||
$bits := fn($T: type): usize(T) {
|
|
||||||
return @sizeof(T) << 3
|
|
||||||
}
|
|
||||||
|
|
||||||
$bitmask := fn($T: type): usize(T) {
|
|
||||||
return -1
|
|
||||||
}
|
|
|
@ -1,41 +1,13 @@
|
||||||
.{string, fmt, memory} := @use("stn")
|
string := @use("string.hb")
|
||||||
|
|
||||||
LogMsg := packed struct {level: LogLevel, string: ^u8, strlen: uint}
|
LogMsg := packed struct {level: u8, string: ^u8, strlen: uint}
|
||||||
|
|
||||||
LogLevel := enum {
|
log := fn(level: u8, message: ^u8): void {
|
||||||
Error,
|
return @eca(3, 1, LogMsg.(level, message, @inline(string.length, message)), @sizeof(LogMsg))
|
||||||
Warn,
|
|
||||||
Info,
|
|
||||||
Debug,
|
|
||||||
Trace,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$log := fn(level: LogLevel, message: []u8): void {
|
error := fn(message: ^u8): void return @inline(log, 0, message)
|
||||||
return @eca(3, 1, LogMsg.(level, message.ptr, message.len), @sizeof(LogMsg))
|
warn := fn(message: ^u8): void return @inline(log, 1, message)
|
||||||
}
|
info := fn(message: ^u8): void return @inline(log, 2, message)
|
||||||
|
debug := fn(message: ^u8): void return @inline(log, 3, message)
|
||||||
$error := fn(message: []u8): void return log(LogLevel.Error, message)
|
trace := fn(message: ^u8): void return @inline(log, 4, message)
|
||||||
$warn := fn(message: []u8): void return log(LogLevel.Warn, message)
|
|
||||||
$info := fn(message: []u8): void return log(LogLevel.Info, message)
|
|
||||||
$debug := fn(message: []u8): void return log(LogLevel.Debug, message)
|
|
||||||
$trace := fn(message: []u8): void return log(LogLevel.Trace, message)
|
|
||||||
|
|
||||||
print_buffer := memory.dangling(u8)
|
|
||||||
|
|
||||||
print := fn(v: @Any(), opts: fmt.FormatOptions): void {
|
|
||||||
if print_buffer == memory.dangling(u8) {
|
|
||||||
print_buffer = memory.request_page(1)
|
|
||||||
}
|
|
||||||
len := @inline(fmt.format, v, print_buffer[0..memory.PAGE_SIZE], opts)
|
|
||||||
@eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg))
|
|
||||||
memory.set(u8, &0, print_buffer, len)
|
|
||||||
}
|
|
||||||
|
|
||||||
printf := fn(str: []u8, v: @Any(), opts: fmt.FormatOptions): void {
|
|
||||||
if print_buffer == memory.dangling(u8) {
|
|
||||||
print_buffer = memory.request_page(1)
|
|
||||||
}
|
|
||||||
len := @inline(fmt.format_with_str, v, str, print_buffer[0..memory.PAGE_SIZE], opts)
|
|
||||||
@eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg))
|
|
||||||
memory.set(u8, &0, print_buffer, len)
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,79 +1,67 @@
|
||||||
$PAGE_SIZE := 4096
|
PAGE_SIZE := 4096
|
||||||
$MAX_ALLOC := 0xFF
|
MAX_ALLOC := 0xFF
|
||||||
$MAX_FREE := 0xFF
|
MAX_FREE := 0xFF
|
||||||
|
|
||||||
$uninit := fn($Expr: type): Expr {
|
calc_pages := fn($Expr: type, num: uint): uint {
|
||||||
return idk
|
return 1 + @sizeof(Expr) * num / PAGE_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
$nulled := fn($Expr: type): ?Expr {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
$dangling := fn($Expr: type): ^Expr {
|
|
||||||
return @bitcast(@alignof(Expr))
|
|
||||||
}
|
|
||||||
|
|
||||||
$calc_pages := fn($Expr: type, num: uint): uint {
|
|
||||||
return (num + PAGE_SIZE - 1) / PAGE_SIZE
|
|
||||||
}
|
|
||||||
|
|
||||||
// ! will be replaced, don't get attached
|
|
||||||
alloc := fn($Expr: type, num: uint): ^Expr {
|
alloc := fn($Expr: type, num: uint): ^Expr {
|
||||||
return @bitcast(request_page(@intcast(calc_pages(Expr, num))))
|
pages := @inline(calc_pages, Expr, num)
|
||||||
|
if pages <= MAX_ALLOC {
|
||||||
|
return @bitcast(request_page(@intcast(pages)))
|
||||||
|
}
|
||||||
|
ptr := request_page(0xFF)
|
||||||
|
remaining := pages - MAX_ALLOC
|
||||||
|
loop if remaining < MAX_ALLOC break else {
|
||||||
|
_ := request_page(@intcast(MAX_ALLOC))
|
||||||
|
remaining -= MAX_ALLOC
|
||||||
|
}
|
||||||
|
_ := request_page(@intcast(remaining))
|
||||||
|
return @bitcast(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! stub
|
// ! stub
|
||||||
$free := fn($Expr: type, ptr: ^Expr, num: uint): void {
|
free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
|
||||||
release_page(@bitcast(ptr), @intcast(calc_pages(Expr, num)))
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
RqPageMsg := packed struct {a: u8, count: uint}
|
RqPageMsg := packed struct {a: u8, count: u8}
|
||||||
$request_page := fn(count: uint): ^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: uint, ptr: ^u8}
|
RlPageMsg := packed struct {a: u8, count: u8, ptr: ^u8}
|
||||||
$release_page := fn(ptr: ^u8, count: uint): 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))
|
||||||
}
|
}
|
||||||
|
|
||||||
OutsMsg := packed struct {a: u8, b: u8, addr: u16, value: u16}
|
CopyMsg := packed struct {a: u8, count: u32, src: ^u8, dest: ^u8}
|
||||||
$outs := fn(addr: u16, value: u32): void {
|
copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||||
return @eca(3, 3, &OutsMsg.(1, 1, addr, value), @sizeof(OutsMsg))
|
return @eca(3, 2, &CopyMsg.(4, @intcast(count * @sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))
|
||||||
}
|
}
|
||||||
|
|
||||||
InsMsg := packed struct {a: u8, b: u8, addr: u16}
|
SetMsg := packed struct {a: u8, count: u32, size: u32, src: ^u8, dest: ^u8}
|
||||||
$ins := fn(addr: u16): u16 {
|
set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||||
return @eca(3, 3, &InsMsg.(0, 1, addr), @sizeof(InsMsg))
|
return @eca(3, 2, &SetMsg.(5, @intcast(count), @intcast(@sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
|
||||||
}
|
|
||||||
|
|
||||||
CopyMsg := packed struct {a: u8, count: uint, src: ^u8, dest: ^u8}
|
|
||||||
$copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
|
||||||
return @eca(3, 2, &CopyMsg.(4, count * @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))
|
|
||||||
}
|
|
||||||
|
|
||||||
SetMsg := packed struct {a: u8, count: uint, size: uint, src: ^u8, dest: ^u8}
|
|
||||||
$set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
|
||||||
return @eca(3, 2, &SetMsg.(5, count, @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,7 +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 {
|
|
||||||
@eca(6, interrupt_number)
|
|
||||||
}
|
|
|
@ -1,172 +1,72 @@
|
||||||
// todo: splice function
|
length := fn(ptr: ^u8): uint {
|
||||||
|
len := @as(uint, 0)
|
||||||
|
// loop if *(ptr + len) == 0 return len else len += 1
|
||||||
|
loop if *(ptr + len) == 0 break else len += 1
|
||||||
|
return len
|
||||||
|
}
|
||||||
|
|
||||||
reverse := fn(str: []u8): void {
|
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
|
||||||
if str.len == 0 return;
|
ptr := p
|
||||||
j := str.len - 1
|
negative := num < 0
|
||||||
i := 0
|
if negative {
|
||||||
|
num = -num
|
||||||
|
}
|
||||||
|
|
||||||
|
if radix == 2 {
|
||||||
|
*ptr = 48
|
||||||
|
ptr += 1;
|
||||||
|
*ptr = 98
|
||||||
|
ptr += 1
|
||||||
|
} else if radix == 16 {
|
||||||
|
*ptr = 48
|
||||||
|
ptr += 1;
|
||||||
|
*ptr = 120
|
||||||
|
ptr += 1
|
||||||
|
} else if radix == 8 {
|
||||||
|
*ptr = 48
|
||||||
|
ptr += 1;
|
||||||
|
*ptr = 111
|
||||||
|
ptr += 1
|
||||||
|
}
|
||||||
|
digits_start := ptr
|
||||||
|
if num == 0 {
|
||||||
|
*ptr = 48
|
||||||
|
ptr += 1
|
||||||
|
} else {
|
||||||
|
loop if num == 0 break else {
|
||||||
|
digit := num % @bitcast(radix)
|
||||||
|
if digit < 10 {
|
||||||
|
*ptr = @intcast(digit) + 48
|
||||||
|
} else {
|
||||||
|
*ptr = @intcast(digit) + 55
|
||||||
|
}
|
||||||
|
ptr += 1
|
||||||
|
num /= @bitcast(radix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if negative {
|
||||||
|
*ptr = 45
|
||||||
|
ptr += 1
|
||||||
|
};
|
||||||
|
|
||||||
|
*ptr = 0
|
||||||
|
|
||||||
|
@inline(reverse, digits_start)
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse := fn(s: ^u8): void {
|
||||||
|
i := @as(uint, 0)
|
||||||
|
j := @inline(length, s) - 1
|
||||||
temp := @as(u8, 0)
|
temp := @as(u8, 0)
|
||||||
loop if i < j {
|
loop if i >= j break else {
|
||||||
temp = str[i]
|
temp = *(s + i);
|
||||||
str[i] = str[j]
|
*(s + i) = *(s + j);
|
||||||
str[j] = temp
|
*(s + j) = temp
|
||||||
i += 1
|
i += 1
|
||||||
j -= 1
|
j -= 1
|
||||||
} else return
|
|
||||||
}
|
|
||||||
|
|
||||||
equals := fn(lhs: []u8, rhs: []u8): bool {
|
|
||||||
if lhs.len != rhs.len return false
|
|
||||||
if lhs.ptr == rhs.ptr return true
|
|
||||||
i := 0
|
|
||||||
loop if i == lhs.len break else {
|
|
||||||
if lhs[i] != rhs[i] return false
|
|
||||||
i += 1
|
|
||||||
}
|
}
|
||||||
return true
|
return
|
||||||
}
|
|
||||||
|
|
||||||
clear := fn(str: []u8): void {
|
|
||||||
i := 0
|
|
||||||
loop if i == str.len break else {
|
|
||||||
str[i] = 0
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
split_once := fn(haystack: []u8, needle: @Any()): ?struct {left: []u8, right: []u8} {
|
|
||||||
T := @TypeOf(needle)
|
|
||||||
i := 0
|
|
||||||
if T == []u8 {
|
|
||||||
if needle.len == 0 return null
|
|
||||||
loop {
|
|
||||||
if i + needle.len > haystack.len return null
|
|
||||||
if haystack[i] == needle[0] {
|
|
||||||
matches := true
|
|
||||||
n := 1
|
|
||||||
loop {
|
|
||||||
if n == needle.len break
|
|
||||||
if haystack[i + n] != needle[n] {
|
|
||||||
matches = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches return .(haystack[0..i], haystack[i + needle.len..])
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
} else if T == u8 {
|
|
||||||
loop {
|
|
||||||
if haystack[i] == needle {
|
|
||||||
return .(haystack[0..i], haystack[i + 1..])
|
|
||||||
} else if i == haystack.len return null
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
@error("Type of needle must be []u8 or u8.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
split := fn(iter: []u8, needle: @Any()): struct {
|
|
||||||
str: []u8,
|
|
||||||
needle: @TypeOf(needle),
|
|
||||||
done: bool,
|
|
||||||
|
|
||||||
next := fn(self: ^Self): ?[]u8 {
|
|
||||||
if self.done return null;
|
|
||||||
|
|
||||||
splits := split_once(self.str, self.needle)
|
|
||||||
if splits != null {
|
|
||||||
self.str = splits.right
|
|
||||||
return splits.left
|
|
||||||
} else {
|
|
||||||
self.done = true
|
|
||||||
return self.str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} {
|
|
||||||
T := @TypeOf(needle)
|
|
||||||
if T != []u8 & T != u8 {
|
|
||||||
@error("Type of needle must be []u8 or u8.")
|
|
||||||
}
|
|
||||||
return .(iter, needle, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
chars := fn(iter: []u8): struct {
|
|
||||||
str: []u8,
|
|
||||||
|
|
||||||
next := fn(self: ^Self): ?u8 {
|
|
||||||
if self.str.len == 0 return null
|
|
||||||
self.str = self.str[1..]
|
|
||||||
return self.str[0]
|
|
||||||
}
|
|
||||||
} {
|
|
||||||
return .(iter)
|
|
||||||
}
|
|
||||||
|
|
||||||
count := fn(haystack: []u8, needle: @Any()): uint {
|
|
||||||
T := @TypeOf(needle)
|
|
||||||
i := 0
|
|
||||||
c := 0
|
|
||||||
if T == []u8 {
|
|
||||||
if needle.len == 0 return null
|
|
||||||
loop {
|
|
||||||
if i + needle.len > haystack.len return c
|
|
||||||
if haystack[i] == needle[0] {
|
|
||||||
matches := true
|
|
||||||
n := 1
|
|
||||||
loop {
|
|
||||||
if n == needle.len break
|
|
||||||
if haystack[i + n] != needle[n] {
|
|
||||||
matches = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches c += 1
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
} else if T == u8 {
|
|
||||||
loop {
|
|
||||||
if haystack[i] == needle c += 1 else if i == haystack.len return c
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
@error("Type of needle must be []u8 or u8.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
left_trim := fn(str: []u8, sub: []u8): []u8 {
|
|
||||||
i := 0
|
|
||||||
if str[0] == sub[0] {
|
|
||||||
loop if i == sub.len {
|
|
||||||
return str[i..str.len]
|
|
||||||
} else if str[i] != sub[i] | i == str.len {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
right_trim := fn(str: []u8, sub: []u8): []u8 {
|
|
||||||
i := 0
|
|
||||||
if str[str.len - 1] == sub[sub.len - 1] {
|
|
||||||
loop if i == sub.len {
|
|
||||||
return str[0..str.len - i]
|
|
||||||
} else if str[str.len - i - 1] != sub[sub.len - i - 1] | i == str.len {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
trim := fn(str: []u8, sub: []u8): []u8 {
|
|
||||||
return right_trim(left_trim(str, sub), sub)
|
|
||||||
}
|
}
|
|
@ -1,63 +0,0 @@
|
||||||
.{math: .{Vec2}, buffer, log, memory, string} := @use("stn");
|
|
||||||
.{Channel, Window, send_header, send_message, await_channel, await_header, await_message, message, BUFFER_SERVER, BUFFER_CLIENT, WindowProps, WindowData} := @use("lib:sunset_proto");
|
|
||||||
.{Surface, Color} := @use("lib:render")
|
|
||||||
|
|
||||||
// ! in the future this should be safely handled
|
|
||||||
channel := Channel.(0, 0)
|
|
||||||
|
|
||||||
find_server := fn(): void {
|
|
||||||
log.info("client: locating server")
|
|
||||||
channel2 := await_channel()
|
|
||||||
channel.server = channel2.server
|
|
||||||
channel.client = channel2.client
|
|
||||||
log.info("client: server located")
|
|
||||||
}
|
|
||||||
|
|
||||||
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")
|
|
||||||
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")
|
|
||||||
surface := Surface.new(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,100 +0,0 @@
|
||||||
.{math: .{Vec2}, buffer, memory} := @use("stn");
|
|
||||||
.{Surface} := @use("lib:render")
|
|
||||||
|
|
||||||
$BUFFER_SERVER := "sunset_server"
|
|
||||||
$BUFFER_CLIENT := "sunset_client"
|
|
||||||
|
|
||||||
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 {
|
|
||||||
// awaiting here causes flickering... idk why
|
|
||||||
buffer.await(buffer_id)
|
|
||||||
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 {
|
|
||||||
// awaiting here causes flickering... idk why
|
|
||||||
buffer.await(buffer_id)
|
|
||||||
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),
|
|
||||||
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,131 +0,0 @@
|
||||||
.{math, log, string, random, buffer, memory} := @use("stn");
|
|
||||||
.{Color, Surface, text} := @use("lib:render");
|
|
||||||
.{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("lib:sunset_proto")
|
|
||||||
|
|
||||||
WindowServer := struct {
|
|
||||||
window_count: uint,
|
|
||||||
channel: Channel,
|
|
||||||
// ! replace this with a collection when we get an allocator
|
|
||||||
windows: [10]?Window,
|
|
||||||
font: text.Font,
|
|
||||||
}
|
|
||||||
|
|
||||||
// ! in the future this should be safely handled
|
|
||||||
server := @as(WindowServer, idk)
|
|
||||||
|
|
||||||
psf := @embed("sysdata: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")
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
incoming := fn(): bool {
|
|
||||||
msg := recv_header(server.channel.server)
|
|
||||||
if msg == null {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if msg.kind == message.syn {
|
|
||||||
log.info("server: recv syn")
|
|
||||||
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")
|
|
||||||
// ! 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
|
|
||||||
deco_length := title.len * 10
|
|
||||||
// draw the window tab bar
|
|
||||||
surface.put_filled_rect(.(0, 0), .(data.props.dimensions.x + DECO_WIDTH + deco_length, DECO_HEIGHT_TOP), DECO_COLOUR)
|
|
||||||
// Draw the window tab
|
|
||||||
surface.put_filled_rect(.(0, 0), .(deco_length, DECO_HEIGHT_TOP - 1), DECO_COLOUR_DARKER)
|
|
||||||
|
|
||||||
// Draw the outside box
|
|
||||||
surface.put_rect(.(0, 0), data.props.dimensions + .(DECO_WIDTH - 1, DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM - 1), DECO_COLOUR)
|
|
||||||
|
|
||||||
surface.put_text(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 @inline(Surface.new, 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 {
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
window.surface.put_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
|
|
||||||
}
|
|
||||||
screen.put_surface(window.surface, window.data.props.position, false)
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
# ablefetch
|
|
|
@ -1,43 +0,0 @@
|
||||||
stn := @use("stn")
|
|
||||||
sunset := @use("lib:sunset_proto")
|
|
||||||
render := @use("lib:render")
|
|
||||||
psf := @embed("sysdata:assets/consolefonts/tamsyn/10x20r.psf")
|
|
||||||
horizon_api := @use("lib:horizon_api");
|
|
||||||
|
|
||||||
.{Vec2} := stn.math;
|
|
||||||
.{log} := stn;
|
|
||||||
.{set_color, render_label_to_surface, Label} := horizon_api.widgets.label
|
|
||||||
|
|
||||||
main := fn(): void {
|
|
||||||
sunset.client.find_server()
|
|
||||||
|
|
||||||
window := sunset.client.new(.(.(10, 10), .(400, 300), "ableFetch!"))
|
|
||||||
font := @unwrap(render.text.font_from_psf2(@bitcast(&psf), false))
|
|
||||||
// pos := Vec2(uint).(1, 100)
|
|
||||||
|
|
||||||
if window == null {
|
|
||||||
log.error("got no window")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
text_label := Label.new_label("kernel : akern 0.2.0", 300)
|
|
||||||
text_label_2 := Label.new_label("os : ableos", 300)
|
|
||||||
text_label_3 := Label.new_label("wm : sunset", 300)
|
|
||||||
text_label.set_color(render.BLACK, render.WHITE)
|
|
||||||
|
|
||||||
text_label_2.set_color(render.BLACK, render.WHITE)
|
|
||||||
text_label_3.set_color(render.BLACK, render.WHITE)
|
|
||||||
|
|
||||||
pos1 := Vec2(uint).(1, 1)
|
|
||||||
pos2 := Vec2(uint).(1, 20)
|
|
||||||
pos3 := Vec2(uint).(1, 40)
|
|
||||||
|
|
||||||
render_label_to_surface(window.surface, text_label, font, pos1)
|
|
||||||
render_label_to_surface(window.surface, text_label_2, font, pos2)
|
|
||||||
render_label_to_surface(window.surface, text_label_3, font, pos3)
|
|
||||||
loop {
|
|
||||||
// stn.log.info("AAAA")
|
|
||||||
_ = sunset.client.send_frame(window)
|
|
||||||
// stn.sleep.sleep_until_interrupt(100)
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue