From b21393ccf45aba5fcd1565113495ba7c20ffabf0 Mon Sep 17 00:00:00 2001 From: Eemeli <eemeli.o.lehtonen@utu.fi> Date: Sun, 15 Jan 2023 05:43:30 +0200 Subject: [PATCH] framebuffer logger + some ansi escapes --- .cargo/runner.sh | 2 + Cargo.lock | 510 ++++++++++++++++++++++++++ Cargo.toml | 3 + build.rs | 73 ++-- src/arch/x86_64/idt.rs | 38 +- src/arch/x86_64/limine/framebuffer.rs | 15 +- src/arch/x86_64/limine/mod.rs | 3 - src/log.rs | 34 +- src/main.rs | 21 +- src/qemu.rs | 3 - src/video/font.rs | 325 ++++++++++++---- src/video/framebuffer.rs | 126 +++++-- src/video/mod.rs | 1 + 13 files changed, 1006 insertions(+), 148 deletions(-) diff --git a/.cargo/runner.sh b/.cargo/runner.sh index b7c557b..1f65173 100755 --- a/.cargo/runner.sh +++ b/.cargo/runner.sh @@ -41,6 +41,7 @@ target/limine/limine-deploy $KERNEL.iso if [ "$(basename $KERNEL)" = "hyperion" ]; then # Run the created image with QEMU. qemu-system-x86_64 \ + -enable-kvm \ -machine q35 \ -cpu qemu64 \ -M smm=off \ @@ -55,6 +56,7 @@ else set +e # Run the created image with QEMU. qemu-system-x86_64 \ + -enable-kvm \ -machine q35 \ -cpu qemu64 \ -M smm=off \ diff --git a/Cargo.lock b/Cargo.lock index 1131368..e26fdd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "autocfg" version = "1.1.0" @@ -20,10 +26,196 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bytemuck" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "exr" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "smallvec", + "threadpool", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "half" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hyperion" version = "0.1.0" dependencies = [ + "image", "limine", "spin", "uart_16550", @@ -31,6 +223,55 @@ dependencies = [ "x86_64", ] +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + [[package]] name = "limine" version = "0.1.9" @@ -47,18 +288,184 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "proc-macro2" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "rustversion" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "spin" version = "0.9.4" @@ -68,6 +475,37 @@ dependencies = [ "lock_api", ] +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "uart_16550" version = "0.2.18" @@ -79,12 +517,84 @@ dependencies = [ "x86_64", ] +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + [[package]] name = "volatile" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "x86_64" version = "0.14.10" diff --git a/Cargo.toml b/Cargo.toml index ecdebf3..49de3ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,6 @@ x86_64 = "0.14.10" uart_16550 = "0.2.18" limine = { version = "0.1.9", optional = true } #tracing = { version = "0.1.37", default-features = false } + +[build-dependencies] +image = "0.24.5" diff --git a/build.rs b/build.rs index 14da3e8..fd0ad99 100644 --- a/build.rs +++ b/build.rs @@ -1,11 +1,8 @@ use std::{ env::var, error::Error, - fs::{self, File, OpenOptions}, - io::Read, + fs::{self, File}, io::Write, - path::PathBuf, - process::Command, }; // @@ -43,30 +40,56 @@ fn main() -> Result<(), Box<dyn Error>> { panic!(); }; - let unifont_path = "target/hyperion/unifont.bmp"; - let read_unifont = || { - let mut file = OpenOptions::new() - .read(true) - .create(false) - .write(false) - .open(unifont_path)?; + // generate kernel font from the bitmap image - let mut buf = Vec::new(); - file.read_to_end(buf)?; - Ok::<_, Box<dyn Error>>(buf) - }; - - let unifont = if let Ok(file) = read_unifont() { - file - } else { - Command::new("wget") - .arg("http://unifoundry.com/pub/unifont/unifont-15.0.01/unifont-15.0.01.bmp") - .args(["-O", unifont_path]) - .spawn() + let bmp_date = fs::metadata("./src/video/font.bmp") + .unwrap() + .modified() + .unwrap(); + let rs_date = fs::metadata("./src/video/font.rs") + .unwrap() + .modified() + .unwrap(); + // panic!("{bmp_date:?} {rs_date:?}"); + if bmp_date > rs_date { + let mut generated_rs = File::options() + .write(true) + .truncate(true) + .open("./src/video/font.rs") .unwrap(); - read_unifont().unwrap() - }; + let bmp = image::open("./src/video/font.bmp").unwrap().to_luma8(); + assert_eq!(bmp.width(), 4096); + assert_eq!(bmp.height(), 16); + write!( + generated_rs, + "pub static FONT: [([u16; 16], bool); 256] = [" + ) + .unwrap(); + + for i in 0..=255_u8 { + let mut byte = ([0u16; 16], false); + + bmp.chunks(16) + .skip(i as usize) + .step_by(256) + .enumerate() + .for_each(|(i, s)| { + s.iter().enumerate().for_each(|(j, b)| { + if *b != 255 { + byte.0[i] |= 1 << j + } + }) + }); + + // set the flag if the character is 16 wide instead of 8 wide + byte.1 = !byte.0.iter().all(|c| *c < 0x100); + + write!(generated_rs, "\n\t{byte:?},").unwrap(); + } + + write!(generated_rs, "\n];").unwrap(); + } Ok(()) } diff --git a/src/arch/x86_64/idt.rs b/src/arch/x86_64/idt.rs index 6866baa..9c9f128 100644 --- a/src/arch/x86_64/idt.rs +++ b/src/arch/x86_64/idt.rs @@ -27,7 +27,43 @@ extern "x86-interrupt" fn double_fault(stack: InterruptStackFrame, ec: u64) -> ! // TODO: This won't be safe when multiple CPUs are running crate::qemu::unlock(); } - panic!("INT: Double fault ({ec})\n{stack:#?}") + + crate::qemu::_print(format_args_nl!("INT: Double fault ({ec})\n{stack:#?}")); + + let mut sp = stack.stack_pointer.as_ptr() as *const [u8; 8]; + for i in 0isize..256 { + let sp = unsafe { sp.offset(i) }; + let bytes: [u8; 8] = unsafe { *sp }; + let graphic = |c: u8| { + if c.is_ascii_graphic() { + c as char + } else { + '.' + } + }; + crate::qemu::_print(format_args_nl!( + "{:#x}: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {}{}{}{}{}{}{}{}", + sp as usize, + bytes[0], + bytes[1], + bytes[2], + bytes[3], + bytes[4], + bytes[5], + bytes[6], + bytes[7], + graphic(bytes[0]), + graphic(bytes[1]), + graphic(bytes[2]), + graphic(bytes[3]), + graphic(bytes[4]), + graphic(bytes[5]), + graphic(bytes[6]), + graphic(bytes[7]), + )); + } + + panic!(); } // diff --git a/src/arch/x86_64/limine/framebuffer.rs b/src/arch/x86_64/limine/framebuffer.rs index 8b53040..08b9332 100644 --- a/src/arch/x86_64/limine/framebuffer.rs +++ b/src/arch/x86_64/limine/framebuffer.rs @@ -1,6 +1,6 @@ use crate::{ println, - video::framebuffer::{Framebuffer, FBO}, + video::framebuffer::{get_fbo, Framebuffer, FramebufferInfo, FBO}, }; use core::slice; use limine::LimineFramebufferRequest; @@ -24,14 +24,17 @@ pub fn init() { let buf = unsafe { slice::from_raw_parts_mut(fb.address.as_ptr()?, fb.size()) }; Some(Framebuffer { buf, - width: fb.width as _, - height: fb.height as _, - pitch: fb.pitch as _, + info: FramebufferInfo { + width: fb.width as _, + height: fb.height as _, + pitch: fb.pitch as _, + }, }) }); - if let Some(fbo) = fbo { + if let Some(mut fbo) = fbo { + fbo.clear(); FBO.call_once(|| Mutex::new(fbo)); } - println!("Global framebuffer {:#?}", FBO.get()) + println!("Global framebuffer: {:#?}", get_fbo().map(|f| f.info)) } diff --git a/src/arch/x86_64/limine/mod.rs b/src/arch/x86_64/limine/mod.rs index 032aa5e..754f283 100644 --- a/src/arch/x86_64/limine/mod.rs +++ b/src/arch/x86_64/limine/mod.rs @@ -18,9 +18,6 @@ pub extern "C" fn _start() -> ! { framebuffer::init(); - // the initial terminal logger crashes if used after initializing GDT and IDT - crate::log::disable_term(); - gdt::init(); idt::init(); diff --git a/src/log.rs b/src/log.rs index 92d39e7..0cb6a59 100644 --- a/src/log.rs +++ b/src/log.rs @@ -19,12 +19,20 @@ macro_rules! println { // -pub fn enable_term() { - LOGGER.term.store(true, Ordering::SeqCst); +// pub fn enable_term() { +// LOGGER.term.store(true, Ordering::SeqCst); +// } +// +// pub fn disable_term() { +// LOGGER.term.store(false, Ordering::SeqCst); +// } + +pub fn enable_fbo() { + LOGGER.fbo.store(true, Ordering::SeqCst); } -pub fn disable_term() { - LOGGER.term.store(false, Ordering::SeqCst); +pub fn disable_fbo() { + LOGGER.fbo.store(false, Ordering::SeqCst); } pub fn enable_qemu() { @@ -40,24 +48,34 @@ pub fn disable_qemu() { static LOGGER: Lazy<Logger> = Lazy::new(Logger::init); struct Logger { - term: AtomicBool, + // Log to a bootloader given terminal + // term: AtomicBool, + + // Log to a framebuffer + fbo: AtomicBool, + + // Log to a QEMU serial qemu: AtomicBool, } impl Logger { fn init() -> Self { Logger { - term: true.into(), + // term: false.into(), + fbo: true.into(), qemu: true.into(), } } fn print(&self, args: Arguments) { + // if self.term.load(Ordering::SeqCst) { + // crate::arch::boot::_print(args); + // } if self.qemu.load(Ordering::SeqCst) { crate::qemu::_print(args); } - if self.term.load(Ordering::SeqCst) { - crate::arch::boot::_print(args); + if self.fbo.load(Ordering::SeqCst) { + crate::video::logger::_print(args); } } } diff --git a/src/main.rs b/src/main.rs index 420484f..e7e77af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,10 @@ use spin::Mutex; -use crate::video::framebuffer::{Color, FBO}; +use crate::{ + term::escape::encode::EscapeEncoder, + video::framebuffer::{get_fbo, Color, FBO}, +}; // @@ -20,6 +23,7 @@ pub mod arch; pub mod log; pub mod panic; pub mod qemu; +pub mod term; #[cfg(test)] pub mod testfw; pub mod video; @@ -39,8 +43,8 @@ pub static BOOTLOADER: Mutex<&'static str> = Mutex::new(KERNEL); // fn kernel_main() -> ! { - println!("Hello from {KERNEL}"); - println!(" - {KERNEL} was booted with {}", BOOTLOADER.lock()); + println!("Hello from {}", KERNEL.cyan()); + println!(" - {} was booted with {}", KERNEL.cyan(), BOOTLOADER.lock()); // error handling test // stack_overflow(79999999); @@ -48,13 +52,10 @@ fn kernel_main() -> ! { // *(0xFFFFFFFFDEADC0DE as *mut u8) = 42; // } - if let Some(fbo) = FBO.get() { - let mut fbo = fbo.lock(); - fbo.fill(40, 40, 40, 40, Color::RED); - fbo.fill(50, 50, 60, 40, Color::GREEN); - fbo.fill(5, 15, 80, 20, Color::BLUE); - - fbo.put_bytes(100, 100, b"ABABABAB\0", Color::WHITE, Color::BLACK); + if let Some(mut fbo) = get_fbo() { + fbo.fill(240, 240, 40, 40, Color::RED); + fbo.fill(250, 250, 60, 40, Color::GREEN); + fbo.fill(205, 215, 80, 20, Color::BLUE); } #[cfg(test)] diff --git a/src/qemu.rs b/src/qemu.rs index f65d38d..a2e715f 100644 --- a/src/qemu.rs +++ b/src/qemu.rs @@ -13,9 +13,6 @@ pub fn _print(args: Arguments) { } /// Unlocks the COM1 writer IF it is locked by this exact thread -/// -/// SAFETY: this is unsafe unless called from the same thread, this is intended for double fault -/// handling pub unsafe fn unlock() { // TODO: SMP // if COM1_LOCKER.load(Ordering::SeqCst) != crate::THREAD { diff --git a/src/video/font.rs b/src/video/font.rs index 25a6137..1224e22 100644 --- a/src/video/font.rs +++ b/src/video/font.rs @@ -1,67 +1,258 @@ -// #[derive(Debug, Clone, Copy, Default)] -// pub struct FontChar { -// bitmap: [u8; 16], -// } - -#[allow(clippy::unusual_byte_groupings)] -pub static FONT: [[u8; 16]; 256] = { - let default = [ - 0b_11111111, - 0b_11111111, - 0b_11000011, - 0b_11000011, // - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, // - 0b_11111111, - 0b_11111111, - ]; - - let mut font = [default; 256]; - - font[b'A' as usize] = [ - 0b_00000000, - 0b_00000000, - 0b_00000000, // - 0b_01111110, - 0b_11111111, - 0b_11100111, - 0b_11000011, - 0b_11111111, - 0b_11111111, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_11000011, - 0b_00000000, // - 0b_00000000, - 0b_00000000, - ]; - font[b'B' as usize] = [ - 0b_00000000, - 0b_00000000, - 0b_00000000, // - 0b_11111110, - 0b_11111111, - 0b_11000111, - 0b_11000111, - 0b_11111110, - 0b_11111110, - 0b_11000111, - 0b_11000111, - 0b_11111111, - 0b_11111110, - 0b_00000000, // - 0b_00000000, - 0b_00000000, - ]; - - font -}; +pub static FONT: [([u16; 16], bool); 256] = [ + ([21845, 32768, 1, 32768, 1, 35410, 2647, 35418, 31123, 32768, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 51612, 19011, 64076, 19025, 51598, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 42460, 9347, 39052, 9361, 42126, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 42462, 9347, 39070, 9347, 42142, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 64926, 4675, 37470, 4675, 37278, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 45662, 19011, 51934, 27459, 62046, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 42380, 5203, 35934, 5203, 42386, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 35790, 2131, 35790, 2131, 64462, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40056, 649, 35960, 4233, 36472, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40772, 1093, 33916, 1093, 33860, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40708, 261, 40708, 261, 33148, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40772, 1093, 33860, 1065, 33808, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40828, 261, 40828, 261, 33028, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 36728, 4357, 36612, 2309, 37240, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 36472, 4357, 37176, 4417, 36412, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40824, 1029, 33848, 1089, 40764, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47260, 2213, 47268, 2213, 48028, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 37262, 6227, 36946, 4179, 47502, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 39310, 8275, 36946, 2131, 47502, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 39310, 8275, 38994, 8275, 39310, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 41358, 12371, 43090, 14419, 41358, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 51602, 10839, 39510, 11227, 51794, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 51756, 22851, 59532, 18577, 51342, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40414, 9347, 40094, 9347, 40094, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 42188, 11555, 46562, 9507, 42284, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 37244, 6917, 38268, 4357, 37244, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47708, 19011, 47692, 19025, 47502, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 62366, 2115, 35230, 2563, 61918, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 36472, 265, 34424, 2057, 34568, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 36464, 265, 34408, 2121, 34672, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 36408, 329, 34360, 2089, 34632, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 36424, 329, 34376, 2121, 34608, 1, 32768, 1, 32768, 1, 43690], true), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 0, 0], false), + ([0, 0, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 72, 72, 72, 126, 36, 36, 126, 18, 18, 18, 0, 0], false), + ([0, 0, 0, 0, 16, 124, 146, 18, 28, 112, 144, 146, 124, 16, 0, 0], false), + ([0, 0, 0, 0, 140, 82, 82, 44, 16, 16, 104, 148, 148, 98, 0, 0], false), + ([0, 0, 0, 0, 56, 68, 68, 40, 24, 148, 162, 66, 98, 156, 0, 0], false), + ([0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 32, 16, 16, 8, 8, 8, 8, 8, 8, 16, 16, 32, 0], false), + ([0, 0, 0, 4, 8, 8, 16, 16, 16, 16, 16, 16, 8, 8, 4, 0], false), + ([0, 0, 0, 0, 0, 0, 16, 146, 84, 56, 84, 146, 16, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 16, 16, 16, 254, 16, 16, 16, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 16, 16, 8], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0], false), + ([0, 0, 0, 0, 64, 64, 32, 16, 16, 8, 8, 4, 2, 2, 0, 0], false), + ([0, 0, 0, 0, 24, 36, 66, 98, 82, 74, 70, 66, 36, 24, 0, 0], false), + ([0, 0, 0, 0, 16, 24, 20, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 64, 48, 8, 4, 2, 2, 126, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 64, 56, 64, 64, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 32, 48, 40, 36, 34, 34, 126, 32, 32, 32, 0, 0], false), + ([0, 0, 0, 0, 126, 2, 2, 2, 62, 64, 64, 64, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 56, 4, 2, 2, 62, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 126, 64, 64, 32, 32, 32, 16, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 66, 60, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 66, 124, 64, 64, 64, 32, 28, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 24, 24, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 24, 16, 16, 8, 0], false), + ([0, 0, 0, 0, 0, 64, 32, 16, 8, 4, 8, 16, 32, 64, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 64, 32, 16, 16, 0, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 56, 68, 82, 106, 74, 74, 74, 114, 4, 120, 0, 0], false), + ([0, 0, 0, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 62, 66, 66, 66, 62, 66, 66, 66, 66, 62, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 2, 2, 2, 2, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 30, 34, 66, 66, 66, 66, 66, 66, 34, 30, 0, 0], false), + ([0, 0, 0, 0, 126, 2, 2, 2, 62, 2, 2, 2, 2, 126, 0, 0], false), + ([0, 0, 0, 0, 126, 2, 2, 2, 62, 2, 2, 2, 2, 2, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 2, 2, 114, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 0, 0, 66, 66, 66, 66, 126, 66, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 0, 0, 248, 32, 32, 32, 32, 32, 32, 34, 34, 28, 0, 0], false), + ([0, 0, 0, 0, 66, 34, 18, 10, 6, 6, 10, 18, 34, 66, 0, 0], false), + ([0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 126, 0, 0], false), + ([0, 0, 0, 0, 66, 66, 102, 102, 90, 90, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 66, 70, 70, 74, 74, 82, 82, 98, 98, 66, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 62, 66, 66, 66, 62, 2, 2, 2, 2, 2, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 90, 102, 60, 192, 0], false), + ([0, 0, 0, 0, 62, 66, 66, 66, 62, 18, 34, 34, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 2, 12, 48, 64, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 254, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 130, 130, 130, 68, 68, 68, 40, 40, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 66, 66, 66, 66, 90, 90, 102, 102, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 66, 66, 36, 36, 24, 24, 36, 36, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 130, 130, 68, 68, 40, 16, 16, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 126, 64, 64, 32, 16, 8, 4, 2, 2, 126, 0, 0], false), + ([0, 0, 0, 112, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 112, 0], false), + ([0, 0, 0, 0, 2, 2, 4, 8, 8, 16, 16, 32, 64, 64, 0, 0], false), + ([0, 0, 0, 14, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 14, 0], false), + ([0, 0, 24, 36, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0], false), + ([0, 4, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 0, 2, 2, 2, 58, 70, 66, 66, 66, 66, 70, 58, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 60, 66, 2, 2, 2, 2, 66, 60, 0, 0], false), + ([0, 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 60, 66, 66, 126, 2, 2, 66, 60, 0, 0], false), + ([0, 0, 0, 48, 8, 8, 8, 62, 8, 8, 8, 8, 8, 8, 0, 0], false), + ([0, 0, 0, 0, 0, 64, 92, 34, 34, 34, 28, 4, 60, 66, 66, 60], false), + ([0, 0, 0, 2, 2, 2, 58, 70, 66, 66, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 0, 16, 16, 0, 24, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 0, 32, 32, 0, 48, 32, 32, 32, 32, 32, 32, 32, 18, 12], false), + ([0, 0, 0, 2, 2, 2, 34, 18, 10, 6, 10, 18, 34, 66, 0, 0], false), + ([0, 0, 0, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 110, 146, 146, 146, 146, 146, 146, 146, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 58, 70, 66, 66, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 58, 70, 66, 66, 66, 66, 70, 58, 2, 2], false), + ([0, 0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 66, 98, 92, 64, 64], false), + ([0, 0, 0, 0, 0, 0, 58, 70, 66, 2, 2, 2, 2, 2, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 60, 66, 2, 12, 48, 64, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 8, 8, 8, 62, 8, 8, 8, 8, 8, 48, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 66, 66, 66, 66, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 66, 66, 66, 36, 36, 36, 24, 24, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 130, 146, 146, 146, 146, 146, 146, 108, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 66, 66, 36, 24, 24, 36, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 66, 66, 66, 66, 66, 100, 88, 64, 64, 60], false), + ([0, 0, 0, 0, 0, 0, 126, 64, 32, 16, 8, 4, 2, 126, 0, 0], false), + ([0, 0, 0, 48, 8, 8, 16, 16, 8, 4, 8, 16, 16, 8, 8, 48], false), + ([0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], false), + ([0, 0, 0, 12, 16, 16, 8, 8, 16, 32, 16, 8, 8, 16, 16, 12], false), + ([0, 0, 0, 140, 146, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([21845, 32768, 1, 32768, 1, 35790, 2131, 35794, 2131, 64462, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47502, 19027, 52174, 19011, 47682, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47506, 19027, 47710, 2643, 35218, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 51662, 19027, 63950, 18515, 51278, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 51666, 19031, 63962, 19027, 51666, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40238, 9573, 42404, 9509, 40238, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 35794, 2135, 35802, 2131, 64466, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 45980, 18499, 63884, 18961, 51662, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 45982, 18499, 63902, 18947, 51678, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47570, 1171, 39070, 8339, 40082, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 48036, 8485, 41276, 8485, 39204, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 45986, 2339, 37154, 8469, 39176, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47182, 18515, 51278, 18499, 48066, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 51278, 18515, 51278, 18499, 46018, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 33904, 1169, 33904, 1105, 33936, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 48028, 16451, 45452, 2577, 63950, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 48028, 16451, 45452, 16913, 47566, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 62350, 2131, 45138, 16467, 48014, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 41550, 12883, 41550, 8771, 61826, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47694, 16979, 45646, 2627, 63874, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 47580, 1155, 39052, 8337, 40078, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 52124, 18499, 63554, 18499, 52124, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 37188, 4461, 38228, 6981, 37188, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 45532, 19011, 63948, 18513, 51278, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 45534, 19011, 63966, 18499, 51294, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 61852, 2627, 45644, 16977, 47502, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 55756, 17443, 50596, 17705, 55750, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 48028, 4163, 36940, 4177, 48014, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 48028, 4163, 37250, 4611, 47580, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 40816, 1033, 33840, 1089, 33848, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 62348, 2131, 35218, 2579, 61900, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 37176, 6985, 38200, 4361, 37128, 1, 32768, 1, 32768, 1, 43690], true), + ([21845, 32768, 1, 32768, 1, 61900, 2643, 35294, 2131, 61522, 1, 32768, 1, 32768, 1, 43690], true), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 16, 16, 124, 146, 18, 18, 146, 124, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 112, 8, 8, 8, 62, 8, 8, 8, 124, 134, 0, 0], false), + ([0, 0, 0, 0, 0, 66, 60, 36, 66, 66, 36, 60, 66, 0, 0, 0], false), + ([0, 0, 0, 0, 130, 68, 40, 16, 254, 16, 254, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 2, 60, 66, 66, 60, 64, 66, 60, 0, 0], false), + ([36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 153, 165, 133, 133, 165, 153, 66, 60, 0, 0], false), + ([0, 0, 56, 64, 120, 68, 120, 0, 124, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 72, 72, 36, 36, 18, 36, 36, 72, 72, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 64, 64, 64, 0, 0], false), + ([21845, 32768, 1, 50780, 10819, 37836, 4689, 37454, 1, 32768, 1, 33728, 1, 32768, 1, 43690], true), + ([0, 0, 0, 0, 60, 66, 157, 165, 165, 157, 149, 165, 66, 60, 0, 0], false), + ([0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 16, 16, 16, 254, 16, 16, 16, 0, 254, 0, 0, 0], false), + ([0, 0, 0, 28, 34, 32, 24, 4, 2, 62, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 28, 34, 32, 28, 32, 34, 28, 0, 0, 0, 0, 0, 0], false), + ([0, 32, 16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 66, 66, 66, 66, 66, 66, 102, 154, 2, 1], false), + ([0, 0, 0, 0, 252, 94, 94, 94, 92, 80, 80, 80, 80, 80, 80, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 12], false), + ([0, 0, 0, 8, 12, 10, 8, 8, 8, 62, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 56, 68, 68, 68, 56, 0, 124, 0, 0, 0, 0, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 18, 18, 36, 36, 72, 36, 36, 18, 18, 0, 0], false), + ([0, 0, 0, 0, 68, 70, 36, 20, 20, 72, 104, 84, 114, 66, 0, 0], false), + ([0, 0, 0, 0, 68, 70, 36, 20, 20, 40, 88, 68, 34, 114, 0, 0], false), + ([0, 0, 0, 0, 70, 72, 36, 24, 22, 72, 104, 84, 114, 66, 0, 0], false), + ([0, 0, 0, 0, 8, 8, 0, 8, 8, 4, 2, 66, 66, 60, 0, 0], false), + ([12, 48, 0, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([48, 12, 0, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([24, 36, 0, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([76, 50, 0, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([36, 36, 0, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([24, 36, 24, 0, 24, 36, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 0, 0, 248, 20, 18, 18, 254, 18, 18, 18, 18, 242, 0, 0], false), + ([0, 0, 0, 0, 60, 66, 66, 2, 2, 2, 2, 66, 66, 60, 16, 12], false), + ([12, 48, 0, 0, 126, 2, 2, 2, 62, 2, 2, 2, 2, 126, 0, 0], false), + ([48, 12, 0, 0, 126, 2, 2, 2, 62, 2, 2, 2, 2, 126, 0, 0], false), + ([24, 36, 0, 0, 126, 2, 2, 2, 62, 2, 2, 2, 2, 126, 0, 0], false), + ([36, 36, 0, 0, 126, 2, 2, 2, 62, 2, 2, 2, 2, 126, 0, 0], false), + ([24, 96, 0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([48, 12, 0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([24, 36, 0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([36, 36, 0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 0, 0, 30, 34, 66, 66, 79, 66, 66, 66, 34, 30, 0, 0], false), + ([76, 50, 0, 0, 66, 70, 70, 74, 74, 82, 82, 98, 98, 66, 0, 0], false), + ([12, 48, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([48, 12, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([24, 36, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([76, 50, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([36, 36, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 0, 66, 36, 24, 36, 66, 0, 0, 0, 0], false), + ([0, 0, 0, 64, 92, 34, 98, 82, 82, 74, 74, 70, 68, 58, 2, 0], false), + ([12, 48, 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([48, 12, 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([24, 36, 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([36, 36, 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([48, 12, 0, 0, 130, 130, 68, 68, 40, 16, 16, 16, 16, 16, 0, 0], false), + ([0, 0, 0, 2, 2, 30, 34, 66, 66, 34, 30, 2, 2, 2, 0, 0], false), + ([0, 0, 0, 0, 28, 34, 34, 18, 26, 34, 66, 66, 74, 50, 0, 0], false), + ([0, 0, 12, 48, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 48, 12, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 24, 36, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 76, 50, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 36, 36, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 24, 36, 24, 0, 0, 60, 66, 64, 124, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 124, 146, 144, 252, 18, 18, 146, 124, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 60, 66, 2, 2, 2, 2, 66, 60, 16, 12], false), + ([0, 0, 12, 48, 0, 0, 60, 66, 66, 126, 2, 2, 66, 60, 0, 0], false), + ([0, 0, 48, 12, 0, 0, 60, 66, 66, 126, 2, 2, 66, 60, 0, 0], false), + ([0, 0, 24, 36, 0, 0, 60, 66, 66, 126, 2, 2, 66, 60, 0, 0], false), + ([0, 0, 36, 36, 0, 0, 60, 66, 66, 126, 2, 2, 66, 60, 0, 0], false), + ([0, 0, 12, 48, 0, 0, 24, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 48, 12, 0, 0, 24, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 24, 36, 0, 0, 24, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 36, 36, 0, 0, 24, 16, 16, 16, 16, 16, 16, 124, 0, 0], false), + ([0, 0, 76, 48, 40, 68, 64, 124, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 76, 50, 0, 0, 58, 70, 66, 66, 66, 66, 66, 66, 0, 0], false), + ([0, 0, 12, 48, 0, 0, 60, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 48, 12, 0, 0, 60, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 24, 36, 0, 0, 60, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 76, 50, 0, 0, 60, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 36, 36, 0, 0, 60, 66, 66, 66, 66, 66, 66, 60, 0, 0], false), + ([0, 0, 0, 0, 0, 0, 24, 0, 0, 126, 0, 0, 24, 0, 0, 0], false), + ([0, 0, 0, 0, 0, 64, 60, 98, 82, 82, 74, 74, 70, 60, 2, 0], false), + ([0, 0, 12, 48, 0, 0, 66, 66, 66, 66, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 48, 12, 0, 0, 66, 66, 66, 66, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 24, 36, 0, 0, 66, 66, 66, 66, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 36, 36, 0, 0, 66, 66, 66, 66, 66, 66, 98, 92, 0, 0], false), + ([0, 0, 48, 12, 0, 0, 66, 66, 66, 66, 66, 100, 88, 64, 64, 60], false), + ([0, 0, 0, 2, 2, 2, 58, 70, 66, 66, 66, 66, 70, 58, 2, 2], false), + ([0, 0, 36, 36, 0, 0, 66, 66, 66, 66, 66, 100, 88, 64, 64, 60], false), +]; \ No newline at end of file diff --git a/src/video/framebuffer.rs b/src/video/framebuffer.rs index e26a9cb..1d6d838 100644 --- a/src/video/framebuffer.rs +++ b/src/video/framebuffer.rs @@ -1,6 +1,9 @@ use super::font::FONT; -use core::fmt; -use spin::{Mutex, Once}; +use core::{ + fmt, + ops::{Deref, DerefMut}, +}; +use spin::{Lazy, Mutex, MutexGuard, Once}; // @@ -8,9 +11,20 @@ pub static FBO: Once<Mutex<Framebuffer>> = Once::new(); // +pub fn get_fbo() -> Option<MutexGuard<'static, Framebuffer>> { + FBO.get().map(|mtx| mtx.lock()) +} + +// + pub struct Framebuffer { pub buf: &'static mut [u8], + pub info: FramebufferInfo, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub struct FramebufferInfo { pub width: usize, // not the pixels to the next row pub height: usize, pub pitch: usize, // pixels to the next row @@ -39,24 +53,51 @@ impl Framebuffer { } } - pub fn put_byte(&mut self, x: usize, y: usize, ch: u8, fg: Color, bg: Color) { - let map = FONT[ch as usize]; + pub fn put_byte(&mut self, x: usize, y: usize, ch: u8, fg: Color, bg: Color) -> bool { + let (map, double_wide) = FONT[ch as usize]; for (yd, row) in map.into_iter().enumerate() { - for xd in 0..8 { - self.set( - x + xd, - y + yd, - if (row & 1 << (7 - xd)) != 0 { fg } else { bg }, - ); + for xd in 0..if double_wide { 16 } else { 8 } { + self.set(x + xd, y + yd, if (row & 1 << xd) != 0 { fg } else { bg }); } } + + double_wide } - pub fn put_bytes(&mut self, x: usize, y: usize, s: &[u8], fg: Color, bg: Color) { - for (offs, ch) in s.iter().enumerate() { - self.put_byte(x + 12 * offs, y, *ch, fg, bg) + pub fn scroll(&mut self, h: usize) { + for y in h..self.height { + let two_rows = &mut self.buf[(y - 1) * self.info.pitch..(y + 1) * self.info.pitch]; + + self.buf.copy_within( + y * self.info.pitch..(y + 1) * self.info.pitch, + (y - h) * self.info.pitch, + ); } + + self.buf[(self.info.height - h) * self.info.pitch..].fill(0); + } + + pub fn clear(&mut self) { + self.buf.fill(0); + } + + pub fn info(&self) -> FramebufferInfo { + self.info + } +} + +impl Deref for Framebuffer { + type Target = FramebufferInfo; + + fn deref(&self) -> &Self::Target { + &self.info + } +} + +impl DerefMut for Framebuffer { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.info } } @@ -72,21 +113,56 @@ impl Color { Self { r, g, b } } - pub const fn as_u32(&self) -> u32 { - u32::from_ne_bytes([self.r, self.g, self.b, 0]) + pub const fn from_u32(code: u32) -> Self { + let [r, g, b, _] = code.to_ne_bytes(); + Self::new(r, g, b) } - pub const fn as_arr(&self) -> [u8; 4] { - [self.r, self.g, self.b, 0] + pub const fn from_hex(hex_code: &str) -> Self { + Self::from_hex_bytes(hex_code.as_bytes()) + } + + pub const fn from_hex_bytes(hex_code: &[u8]) -> Self { + match hex_code { + [r0, r1, g0, g1, b0, b1, _, _] + | [r0, r1, g0, g1, b0, b1] + | [b'#', r0, r1, g0, g1, b0, b1, _, _] + | [b'#', r0, r1, g0, g1, b0, b1] => { + Self::from_hex_bytes_2([*r0, *r1, *g0, *g1, *b0, *b1]) + } + _ => { + panic!("Invalid color hex code") + } + } + } + + pub const fn from_hex_bytes_2(hex_code: [u8; 6]) -> Self { + const fn parse_hex_char(c: u8) -> u8 { + match c { + b'0'..=b'9' => c - b'0', + b'a'..=b'f' => c - b'a' + 0xa, + _ => c, + } + } + + const fn parse_byte(str_byte: [u8; 2]) -> u8 { + parse_hex_char(str_byte[0]) | parse_hex_char(str_byte[1]) << 4 + } + + let r = parse_byte([hex_code[0], hex_code[1]]); + let g = parse_byte([hex_code[2], hex_code[3]]); + let b = parse_byte([hex_code[4], hex_code[5]]); + + Self::new(r, g, b) } -} -impl fmt::Debug for Framebuffer { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Framebuffer") - .field("width", &self.width) - .field("height", &self.height) - .field("pitch", &self.pitch) - .finish_non_exhaustive() + pub const fn as_u32(&self) -> u32 { + // self.b as u32 | (self.g as u32) << 8 | (self.r as u32) << 16 + u32::from_le_bytes([self.b, self.g, self.r, 0]) + } + + pub const fn as_arr(&self) -> [u8; 4] { + self.as_u32().to_ne_bytes() + // [self.r, self.g, self.b, 0] } } diff --git a/src/video/mod.rs b/src/video/mod.rs index 27cbe8d..7e1c0fb 100644 --- a/src/video/mod.rs +++ b/src/video/mod.rs @@ -1,2 +1,3 @@ pub mod font; pub mod framebuffer; +pub mod logger; -- GitLab