From 5d591cb128c098e59b1c5979ff0f996ce7031ce4 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 25 Feb 2024 18:40:56 +0000 Subject: [PATCH 1/7] Add some demo slides. These need pushing out to a demo application really, but I haven't done the API yet. Note I had to give the OS more RAM so there was room for the slides. --- Cargo.lock | 163 ++++++++++++++++++---------- Cargo.toml | 1 - neotron-os/Cargo.toml | 2 + neotron-os/neotron-flash-0002.ld | 2 +- neotron-os/neotron-flash-0802.ld | 2 +- neotron-os/neotron-flash-1002.ld | 2 +- neotron-os/src/commands/mod.rs | 1 + neotron-os/src/commands/screen.rs | 123 +++++++++++++++++++++ neotron-os/src/slide_bios.bmp | Bin 0 -> 19720 bytes neotron-os/src/slide_links.bmp | Bin 0 -> 24090 bytes neotron-os/src/slide_os.bmp | Bin 0 -> 26982 bytes neotron-os/src/slide_oss.bmp | Bin 0 -> 24106 bytes neotron-os/src/slide_pico_audio.bmp | Bin 0 -> 20466 bytes neotron-os/src/slide_pico_vga.bmp | Bin 0 -> 29838 bytes neotron-os/src/slide_px3.bmp | Bin 0 -> 34650 bytes neotron-os/src/slide_sdk.bmp | Bin 0 -> 16792 bytes neotron-os/src/slide_stars.bmp | Bin 0 -> 6354 bytes 17 files changed, 237 insertions(+), 59 deletions(-) create mode 100644 neotron-os/src/slide_bios.bmp create mode 100644 neotron-os/src/slide_links.bmp create mode 100644 neotron-os/src/slide_os.bmp create mode 100644 neotron-os/src/slide_oss.bmp create mode 100644 neotron-os/src/slide_pico_audio.bmp create mode 100644 neotron-os/src/slide_pico_vga.bmp create mode 100644 neotron-os/src/slide_px3.bmp create mode 100644 neotron-os/src/slide_sdk.bmp create mode 100644 neotron-os/src/slide_stars.bmp diff --git a/Cargo.lock b/Cargo.lock index 29b287c..c184a15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "atomic-polyfill" @@ -23,6 +23,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + [[package]] name = "bitflags" version = "1.3.2" @@ -31,9 +37,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "byteorder" @@ -93,6 +99,29 @@ dependencies = [ "winapi", ] +[[package]] +name = "embedded-graphics" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" +dependencies = [ + "az", + "byteorder", +] + [[package]] name = "embedded-hal" version = "1.0.0" @@ -117,6 +146,15 @@ dependencies = [ "neotron-sdk", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "hash32" version = "0.2.1" @@ -142,9 +180,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "lock_api" @@ -158,9 +196,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "menu" @@ -168,6 +206,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b03d7f798bfe97329ad6df937951142eec93886b37d87010502dd25e8cc75fd5" +[[package]] +name = "micromath" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" + [[package]] name = "mio" version = "0.8.11" @@ -186,7 +230,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82c00f842e7006421002e67a53866b90ddd6f7d86137b52d2147f5e38b35e82f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "neotron-ffi", ] @@ -196,7 +240,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67d6c96706b6f3ec069abfb042cadfd2d701980fa4940f407c0bc28ee1e1c493" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "neotron-ffi", ] @@ -228,6 +272,7 @@ name = "neotron-os" version = "0.8.1" dependencies = [ "chrono", + "embedded-graphics", "embedded-sdmmc", "heapless", "menu", @@ -239,6 +284,7 @@ dependencies = [ "postcard", "r0", "serde", + "tinybmp", "vte", ] @@ -291,7 +337,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -302,9 +348,9 @@ checksum = "ed089a1fbffe3337a1a345501c981f1eb1e47e69de5a40e852433e12953c3174" [[package]] name = "postcard" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +checksum = "20ee10b999a00ca189ac2cb99f5db1ca71fb7371e3d5f493b879ca95d2a67220" dependencies = [ "cobs", "heapless", @@ -313,9 +359,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -337,11 +383,11 @@ checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -367,18 +413,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", @@ -397,9 +443,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio", @@ -438,15 +484,22 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tinybmp" +version = "0.5.0" +dependencies = [ + "embedded-graphics", +] + [[package]] name = "unicode-ident" version = "1.0.12" @@ -455,9 +508,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vte" @@ -472,9 +525,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -534,18 +587,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -556,9 +609,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -568,9 +621,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -580,15 +633,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -598,9 +651,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -610,9 +663,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -622,9 +675,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -634,6 +687,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 9fca006..505e645 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,3 @@ panic = "abort" [profile.dev] panic = "abort" - diff --git a/neotron-os/Cargo.toml b/neotron-os/Cargo.toml index ab7dc16..82c02ba 100644 --- a/neotron-os/Cargo.toml +++ b/neotron-os/Cargo.toml @@ -32,6 +32,7 @@ required-features = ["native-log"] [dependencies] chrono = { version = "0.4", default-features = false } +embedded-graphics = "0.8.1" embedded-sdmmc = { version = "0.7", default-features = false } heapless = "0.7" menu = "0.3" @@ -43,6 +44,7 @@ pc-keyboard = "0.7" postcard = "1.0" r0 = "1.0" serde = { version = "1.0", default-features = false } +tinybmp = { path = "../../tinybmp" } vte = "0.12" [features] diff --git a/neotron-os/neotron-flash-0002.ld b/neotron-os/neotron-flash-0002.ld index 59626d9..0ff3547 100644 --- a/neotron-os/neotron-flash-0002.ld +++ b/neotron-os/neotron-flash-0002.ld @@ -22,7 +22,7 @@ MEMORY { /* The first 128 KiB is for the BIOS. We get the rest. */ - FLASH (rx) : ORIGIN = 0x00020000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x00020000, LENGTH = 512K /* * We get the bottom 4KB of RAM. Anything above that is for applications * (up to wherever the BIOS tells us we can use.) diff --git a/neotron-os/neotron-flash-0802.ld b/neotron-os/neotron-flash-0802.ld index 3a961ab..b982b79 100644 --- a/neotron-os/neotron-flash-0802.ld +++ b/neotron-os/neotron-flash-0802.ld @@ -22,7 +22,7 @@ MEMORY { /* The first 128 KiB is for the BIOS. We get the rest. */ - FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 512K /* * We get the bottom 4KB of RAM. Anything above that is for applications * (up to wherever the BIOS tells us we can use.) diff --git a/neotron-os/neotron-flash-1002.ld b/neotron-os/neotron-flash-1002.ld index 0ba14c0..e7ff580 100644 --- a/neotron-os/neotron-flash-1002.ld +++ b/neotron-os/neotron-flash-1002.ld @@ -22,7 +22,7 @@ MEMORY { /* The first 128 KiB is for the BIOS. We get the rest. */ - FLASH (rx) : ORIGIN = 0x10020000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x10020000, LENGTH = 512K /* * The RAM reserved for the OS. Above this is the Transient Program Area. diff --git a/neotron-os/src/commands/mod.rs b/neotron-os/src/commands/mod.rs index 3c3324e..ae1d8e4 100644 --- a/neotron-os/src/commands/mod.rs +++ b/neotron-os/src/commands/mod.rs @@ -36,6 +36,7 @@ pub static OS_MENU: menu::Menu = menu::Menu { &screen::CLS_ITEM, &screen::MODE_ITEM, &screen::GFX_ITEM, + &screen::DEMO_ITEM, &input::KBTEST_ITEM, &hardware::SHUTDOWN_ITEM, &sound::MIXER_ITEM, diff --git a/neotron-os/src/commands/screen.rs b/neotron-os/src/commands/screen.rs index f64b8e8..620c754 100644 --- a/neotron-os/src/commands/screen.rs +++ b/neotron-os/src/commands/screen.rs @@ -1,5 +1,18 @@ //! Screen-related commands for Neotron OS +static SLIDES: [&[u8]; 8] = [ + include_bytes!("../slide_pico_vga.bmp"), + include_bytes!("../slide_pico_audio.bmp"), + include_bytes!("../slide_bios.bmp"), + include_bytes!("../slide_os.bmp"), + include_bytes!("../slide_oss.bmp"), + include_bytes!("../slide_links.bmp"), + include_bytes!("../slide_stars.bmp"), + include_bytes!("../slide_px3.bmp"), +]; + +use pc_keyboard::DecodedKey; + use crate::{ bios::{ video::{Format, Mode}, @@ -47,6 +60,15 @@ pub static GFX_ITEM: menu::Item = menu::Item { help: Some("Test a graphics mode"), }; +pub static DEMO_ITEM: menu::Item = menu::Item { + item_type: menu::ItemType::Callback { + function: demo_cmd, + parameters: &[], + }, + command: "demo", + help: Some("Run demo"), +}; + /// Called when the "cls" command is executed. fn cls_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], _ctx: &mut Ctx) { // Reset SGR, go home, clear screen, @@ -221,4 +243,105 @@ fn print_modes() { } } +/// Called when the "demo" command is executed. +fn demo_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], ctx: &mut Ctx) { + let api = crate::API.get(); + let old_mode = (api.video_get_mode)(); + let old_ptr = (api.video_get_framebuffer)(); + let buffer = ctx.tpa.as_slice_u8(); + let buffer_ptr = buffer.as_mut_ptr() as *mut u32; + let old_palette = [ + (api.video_get_palette)(0), + (api.video_get_palette)(1), + (api.video_get_palette)(2), + (api.video_get_palette)(3), + ]; + if let neotron_common_bios::FfiResult::Err(e) = + unsafe { (api.video_set_mode)(Mode::from_u8(6), buffer_ptr) } + { + osprintln!("Couldn't set mode 6: {:?}", e); + return; + } + + 'slides: for slide_bytes in SLIDES.iter().cycle().cloned() { + if let Err(_e) = show_slide(slide_bytes, api, buffer) { + break; + } + // Now wait for user input - Q to quit, ' ' to skip + 'wait: for _ in 0..300 { + // 300 frames = 5 seconds + (api.video_wait_for_line)(478); + (api.video_wait_for_line)(479); + let keyin = crate::STD_INPUT.lock().get_raw(); + if let Some(DecodedKey::Unicode('Q') | DecodedKey::Unicode('q')) = keyin { + break 'slides; + } + if let Some(DecodedKey::Unicode(' ')) = keyin { + break 'wait; + } + } + } + + // Put it back as it was + unsafe { + (api.video_set_mode)(old_mode, old_ptr); + for (idx, colour) in old_palette.iter().enumerate() { + if let neotron_common_bios::FfiOption::Some(colour) = colour { + (api.video_set_palette)(idx as u8, *colour); + } + } + } +} + +enum SlideError { + Unspecified, +} + +fn show_slide( + data: &[u8], + api: &neotron_common_bios::Api, + buffer: &mut [u8], +) -> Result<(), SlideError> { + use embedded_graphics::pixelcolor::RgbColor; + + let raw_bmp = tinybmp::RawBmp::from_slice(data).map_err(|_| SlideError::Unspecified)?; + let header = raw_bmp.header(); + if header.image_size.width > 640 || header.image_size.height > 480 { + return Err(SlideError::Unspecified); + } + + // Program palette + if let Some(table) = raw_bmp.color_table() { + for entry in 0..4 { + if let Some(rgb) = table.get(entry) { + let rgb666 = + neotron_common_bios::video::RGBColour::from_rgb(rgb.r(), rgb.g(), rgb.b()); + (api.video_set_palette)(entry as u8, rgb666); + } + } + } + + // Copy bitmap + for px in raw_bmp.pixels() { + let offset_px = (px.position.y * 640) + px.position.x; + let offset_byte = (offset_px / 4) as usize; + match offset_px % 4 { + 0 => { + buffer[offset_byte] = (px.color << 6) as u8; + } + 1 => { + buffer[offset_byte] |= (px.color << 4) as u8; + } + 2 => { + buffer[offset_byte] |= (px.color << 2) as u8; + } + _ => { + buffer[offset_byte] |= px.color as u8; + } + } + } + + Ok(()) +} + // End of file diff --git a/neotron-os/src/slide_bios.bmp b/neotron-os/src/slide_bios.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2b72a90c4c8302c28ba8022b8cfa0b73cfbbb219 GIT binary patch literal 19720 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 Lr}h7%^WXRn<;NP| literal 0 HcmV?d00001 diff --git a/neotron-os/src/slide_links.bmp b/neotron-os/src/slide_links.bmp new file mode 100644 index 0000000000000000000000000000000000000000..08432093d4b9aac3f9fac03e56927c5e0cbb2343 GIT binary patch literal 24090 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 literal 0 HcmV?d00001 diff --git a/neotron-os/src/slide_os.bmp b/neotron-os/src/slide_os.bmp new file mode 100644 index 0000000000000000000000000000000000000000..36f974082005c730bde9fdde5af756dba2add697 GIT binary patch literal 26982 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

2%YY?%Mq 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 Q`@I2w*SqVtJpa-E16AcaCjbBd literal 0 HcmV?d00001 diff --git a/neotron-os/src/slide_pico_vga.bmp b/neotron-os/src/slide_pico_vga.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9c803c08d11b4f41f30a7a52dc2a0c2b7f9763b7 GIT binary patch literal 29838 zcmeI4&ue7ab;sY7j1WSIiV#8w(G-|4()L>+fId;URwT55sVHd%Kap{F}Vy@n?Un z`3JYR!+(_Tk2@;9w;6s?cziUvx42#0{xoK7hW?ILR8aK2+nIZt;b#N0ne}owy*)1U zkA~q)ST@4|qQgQ*-$z_Ml%Ru#+}`TSDZ}_XD{~pmIirsCcUngu4~v7t+r{Q+IJ)gd zFBuJ^HZ%En{JAJ}_d=$2esp_La3y-~fxGb&0rB`Sq+H$#dO^52IAYjT$`hmXC@}L78FtBcuoUlQkFVP8P-aCca{=LLk!GrExPhFOnyX&U-9%<#S%JefxE!z7~Sc38l>&7mrh2$aYyky+%`1uHlp%IatoIwq% zJ}0&&Wo9LRg zji&Imq_Y-9FIr60u$ELcuxyh&%dSSisDHffn#BFlu=0FMjkr*n&qHD-rts)@U#>xt zbCb5vxinILdXzGGL>%)R*B!2c%_BsNiTDtnM%C_0PPP}CA!@o-cXFiFh0L|a?2oBZ zLwcx1MW%!y(^}rn`@~gJM)d`NHp|k&2U^X8O{cFkb4>CZ%V}GA{(%ZM%Y7}Hu`?4# z?0%|3#FF&;0v$&r-MKU9yo+^m67-3^#h1$c+!6RHBPCII@`tg;!U}Pok~XA4S7<$p zU7Dz92M7)JW@Jhvxd-WJUq-&)hqc#C)6*7W?+Ie%2Hsd98$3sd^eKc;A`9SQTydPn zrHEfMe96N!2mr)`RBV_d$eukYq2?(JaMh?R?LlA;uf@;FZEpizIfWZWfYzVd0S#Lyj|`m6?I-m)L6Z(OVd*$ zQr}Olb(N?NIKv;9JEj#2GxZbe1C*PXk=VS8_>+S8qgXp-r4?Nv$dYn;?mrfe?+wEh$Za32o%CK7y4lTw68KGt^_DV>X%&YGuh~WGj|%sXCGQ^; zx=H2LjBHaZ8vFmYcl}aoOwGlPLndkcL9IDDaK1l%?2h&s8wdwdlB{7Q>H?YR=XLZ*sNwhF(e~ zHk`Yf4i6qn(8a;v5;02N-R)PR>lYe~x~q8DXmnWYpC$^bsIK*`BL%X3*kcxbDPfP}d>Sx|J7XiGV~>RTao!OqtoyKd z!l5OE&y2@Tk$JZ_gUy{+2(TQdYp2I1t^bQG{BoE<_D;+<71F+r3aqXpG?F2Fw{*ob zI+RS!z9zizc~3PFM*O%baJ}~Q$+?VM_ay&Xk;-OK^Ek&3JCH&^S+gJ6Jqc$2ExmVF zi1?$}-#RDnmk8g1?+!H&oCUuyFAlm&AhaS*wFjY`?7SY&nTBN%m5Q!DMVlEds@|zZ zzK%26O@SjMMZb*cdmk;gwxi$})5P&CT!eHxOfe&es~sa&Z6U0d+cU#NrOG&@){tDW z+h<2x`VKue?n99pk^aTBVqqn7pJ?9K&DlGUqGQkMHLtqsIPmCHc+jK3VF+wK9&4^b z6%|IJ(=3%SmMC!reql@5iCxg6%G-^P(Xz3;9dc2DEF%xbSVO{!sc{GHLXlucm5J$iKp_1-wGRECvH3^n2e0v%AP(tsBvaL ziceXSJF4atandt@jeTP;5^DlZ_^hu^cN*G}#tQjviHq-)@9&iBznJ*K>yH1^*h#+| zpZC#z%-B1vY?QeRXMg`kMW+7RuiiUZUOT)`W6OLd3)~Ua)cN?&VjW+j>yPDs9{1Wc zEdKK{TQX}lCDiS$bfmnn8MyW>5yx+-QkI>6YGC9JJcd0l9%k=xY{pA9KF08!-sP-M z^wZVwR6i|rP0rF2*tkyQH=dM~ogp)m_Y6KqagAXP)bgns@ge7t`;e)u+7U)}%B)-O z;gISqA^}H@rq{LNK+H{iUhg5HY_N^aH6W`YUqydhEP7EOGYDA zhlaS8nHpJT6lJx3B>4evV^khB&hjN}79$c(lf(98A7ahvTj*?~sIS7_P|fa;=+*tU z{5+&Zis9hw)^F43SQjMSb1o2L94Z;4Xgj z>ZC0!h8~hO(x_(;6h;yh&0ZEh0?*}*7b6c&E>b@Lp%fD?_*V((R+!9daucMMEN}6Hq68@EhsWU#N60j zv^SV0YvuvAp)U3_4Jcz9WLWC2;h&GLLRTYdAAPUF0$>lU4SRWqjl4+T)%jtESG8C* zv)b`~=a%MCMs3YIitR+*`U1g)b#KgaKfN8{$WVNwzIW$51#<8Ub=df!(Y5sl6e%LQ zrKZ7p58fCrj~+#;9bMNY=(zE&507}Wz1bv)&0s}P}>0}uA!Dou*$ zJ@S`GAv%FGbb2OMZNJ?1nDKsTjL`hLck3mPrwC=Fkl@+6Gn!HGQ@fn)tk!h1L(E!m zW$Ej92YB(urdO&-BAbNM{W0F~unwy&a1}JDF$ZD{EKv=4ulAEtMy|`Ngk!$u?GY!k z9k}UsiCkvWWkErt*@s`YPOZo4avU^z`9p_ZBkR*NTL|>mJ9ZLy0h8??VL66}2Ge)Y z`1=u6jDZ?a_X3CTSIt6;$$n=cS5=PGU1FmC(@`e_RgJPwT`R*4cr?uR&?kr2!9S~% zibL66_Uk23Rwz*_DglrDQTU8IAd7>@fr&omUKiwP6|@oAt01N#C9aY~kT4Lx7y-1y z>n3wQDC2mN&3O2K5WBmq>UjcVxjaJW&KO$RnLS-q(!pY+-xG0%1pSv4U$R`Tc4B{Y zur}|GFnCA(fn*?lu}4b;vY;>$d8iKP4?2oF_qn%~xzqY@`!00ETI+d%6?tFDs_2aS zV_uZ!jn`>p*%P^u-}MJe^6{P%yeFX*qIKg1jnBl1{B|rHnUyWk?eIkNP8BE7$x`%n zq#5a#REeqS6CF3ozh5+G+G%m9TokMI9QOj^8?ZI5q173!aa_7|JG^8Jafy(+p$fACJvtIeORX5^;! za`k(mpyb`4&!x{8q4*toeF!Zy-&5l^R%GhM=3}8^W%{WL_5gpzEHGh95aH?U@R;lV z0iMcpI=^*=PcZ-Dfz(_f&rvkLrRad}r8v-WF?Fv6aIqN_E~=Nn#~u1HWpwC9(L!%j zIeT&)-GLF*525MRJx9~JCmNm9-_v>hLf;XB2t`$r7IQbBbqM0kur7#soB@bsBb{o8s5f*NHH$E-<`aIhNN5dTg1)pc8kyIZ;cLu(0M93-5)W1G=1C0VZbmPV zBi~Kw5w+{{Jc%K6Dfi2Wc2bJhm9BEyD;b<5Q^XKyyx3qWQ}jQg;_mI{(e8bROwB7h zdw7(rr`?Tp%<7Wo5Y~e4SVE6a>G9t=`_1r<+G&o~9Pg|kn#`s+wq@|HdjxRcZ@8U~ zLsv*I8nN498S1*b72!v1oG|G3LdYLWhoy-RrTmk=8PelrMf!&zsBgGLLL9>)5N&!jBwiZsZtD}FM{JEV`0|6UC7+z}h>(ZCjl zT+dT2yf3X}4$zMV#oUo|YWt`UB)yqBf9AZ2>=M719nG~T&dmnB?UT~I2(~-h+tx?+ z5r$m%#IVGQ2fQBK*}TtjCh=$TC04^E z_6U(-k@+6pnfq*TJam`T>2<=8E5FBTsi{6iW7_>HF_CzRym&FVs9Srl+4Arruc(ez zLX-4C{NfGm(1SiA*Uih=R@Pn_t!1iUOIosC=K<)YuFD#E*x$Kx(Y#<@;+V@5#4V}O zT*mbWBZ#LSkCz{m4XN!5GWuz<;mt5D`;V4r%n1y!Soz^6I7J6}vV6~9#C0<7JlwDFN z)8xX`H?<@&z%)9YkL7+4cRh22&aU{q&07)+v2iBCV(ZX^?oT^@rEe%77jWik9yIh{ zc)q6SFg}tZmg5p{3>Aq>tV(_Rn_L1I5q>T1o-M95rtU(Z?nGa41h=W&(q(7{X+pBm z@8D%?Wpm&29-@jJqa|}x+q`YROX}#!Zb|$)d>v6ixy|=NS1FZJ4&-!KnBDEDpI9Oz zvCUn)=-@||V0v<~p2Z2fi!kwyb+0R-$^1t9%u2g*o%6?WP2{_{D$RBEgGX6Lo<2!F zer+A-S+{h$kV=?Wrrhqa;=q^wC%jQ#>Ac&GWyM36{d96EyQLK$SDhJ-JtN9+h z-m|SFQJlptyj=%7)&M&)ERkFW(DRNuw;{iugX0%ZOWOP?5A~I5MQe26|3K@U9lsFE zk4|sbQH@aX&~rJBt`K>j{;8i5TtxR^xpQ9jFxVM0lV{s{=2G5?{3v)*T{NyfYn-#M z!x%a`R1S1|K*hD}Rzi6f9WohNyr)r+#Cwoj2g@rdr9CO5M|KmqnMn^zZ(l@LMpEkv z_vHu0X1iv(!`$Z5sde?^&eykej=pn+(Jg#dJi;|2-ugs7!5?>drh~uaTdwmn?f*G9 zHHQs;SCW2x-PUgw^mpoLgX8Nxr>o9;ovakCzla$bJB|uceG{b!p<31PFK@&+-rdpI zdQao1rL_354u5E08ARa$yWR1|lza?(<9+SDT~?es_>HGxK>3wfTLI@n%Fcs0sJJa& z-i?%euB-8OPI!lV6L-{Jg(sfvx6wceqA|}xtI!p?@{TZFWB)#xsK7gU#3r6(FoP$O zu8+sO@ZBl5s6PYU^cPwr^`evDnk&S-^6j=UAFnKF;v%w}^p5hCE^8D8q1Q@8LceDo z^ktWLCry(yT>G(N6US;x&T-cLBFn$!RL3U0$g-}(^bEkdCRRj6StG2hT0F}V2-O<@ zDESL>1P)gC^t@ilHB0e?nxQ@VwfGqrbc&^OPGMd*y~d96$vFO6{R zr(v33{5)~_TR8igVvMc$USAXJM92Owgg|l~;8`Pl0-?)2zj=Iqx?)Y#Xu-T0Y(0g& z$imkdF+s(z&jK~(2%8Xqip8_v>dlO8^XBqpa)zv0tO~$X|V%%4O?*n;O zU<&{9>hOxD(@|WORU7ZjjA4CwS`(^nm!lOewfmP_*fZ;Wt$?;)>vm>yxUA)gMZ@^> z7S+|RDjxfp_7~my8KY}==*|v$NL`&QR)3sJt@Z%$3yB@V#=lgNY{1azu17b# zoAzxO)82s5wCEax&g5#W)q;YDMvT|zJ#meFS(#VkK6};RATF}!)^02_Pyf6wdnj8u zsl7Wg!sY6b&(!jkJwx}pTXCss4G%>4F1~kOsmvXDlDfZU=7zu-Pqnc1A8#cUE@Vyr zy2<%4_p9OCa#8dlz4ZJ`9G5lAQ!#2I??9+6sDG$HkgsTX!r!CqWANF9AiUlX^aLC4 zfu1ZgK|t-)>MOrN!838HuUQn9%l)+-deAe@%%h+eig?qaWI5K8R(9<<$_cB6s3xe5 zcrO%>(YVwD$LHGEgID+<4-WLpSBku$~-L){1?+ znetj^Z)&|iA5PYbl`8PX@%p(wk979oaIDXN*PW+v^g{Ub9^&F;eLbA%?_#aK+v04k zj*LF_?#cQ_*B2}GLNsQv(i^V2avJnFzZ}kE=3=FFQYh)IQq5(?Rhen37wcoqd@3G` zm3k_(^e%==&18gDd8KzQJuVhcbQN7*iQ{F^S`TpG+8nm?;d*@@BlNz@h}K%yuQd~l zrnJ%#qvt7|4e-|fSz{V4W}j=$)AiY~()|nZLP9jS(zSV7P=T7Fi$<+0GE-yL(=}t( zk~!(EHJ)p8QZ9q{>A;v(N9{rgZba#+u0z$du(j#W(K4pRO7B2v)R-Flp?4FK_0%lO zJUvjE+G6#jqQjaOA?3{)o@1Ifn#0w76dBXgyA-waweo~!oes}*cPR^F4ZQJLaG9eA zHZUsUYt)z`7?y$MNb@<;yC34?qs4kr=`Vvb*P*wI&smIO6~e8}xvqM_|1JaTsYa2b z1WtSK#e(x=aaLudql=JhDgM5*n=5O0I1-hZo#VGTE?KV{3%%s0-yZ5J8ic31NpWXh zI*@^OHK22k?zvn^Dy|bdux@@rAJ0E6Qty_88Tj#HrH)t~-+0)^q5MpLxmxtE%xPY7 z;TR3>;$r;}3v%R?e$FJSnhVGq4^Y}h(Bk?uVkVC^@~YaOvC>_|2bZKV=7O}`*~f+Z zD^bj`Up*hJAc>?O>+RW>Bu~!=`@g={(Eq&7Y*ou*AIof^f00qM@UhHldgn9NX4WVFvc~j5O2`dSHeTyb27ZWJ`#d2UXIiCa3~qW?vLj|_D>D%)7G1Dc@mkyYiO56 z@LISGuPuw~f?TU#9v^a8+HtqesON?w<@MLJe%2EEwdM%tT>LsdMsCmey<3(yX>e;bAF(67*O_X}le@MAHCWFRI+n*=UHQY+)O(($oN`igqAOGO zjNM$Vo1AMMF%uf*yi&d!SIyWvN0Oz-wOb-r4IQ;Dcye^Z;fR`5WlG?4?-kfJGz8uU z)sm|ycLD6o@+ zO4|(`M>ZeA{z>0^v}d7>p0=+q7B5Csxc#EhW>oIAOkMwiR*50ln>>RaZ#w$ICfSd* z|Mb1aAy=8NuS91b{j=Dw!vR#rp0smsOmxXzM5FGVHX3MqW7Zqk&D${>nyf49v2pNf zB2yz{%v3+YoQU12CGNUIz*uGL=v_=Xoy(dRvG)g2$3=Gc6)+^1=c3>9pkslCTL;1; zGd596fX#guORl#KO7(!eC(#qBJfhD67tl9Zxc@}gkSBW`=7g^?_C!)#s}`gC!YH_~ zBFw`*B+wko?=ROcwm2{gI&^}vHv&5+!|mJvzvK6ddU2yj^&JFl|CF z##ZfnQ&%MeUn!EV^+&IPapu8V0|_Xyhjtt*aJk;h@Nfr+Pex}yEqOdq1bH4&gbD(> z`dyzsUG=>aTKlb_isbL=$oU~Ve3!b4HBQ!_l=+`)jHA_J^*6=Kc8wwiwK3-T{on}| zqSD_M3g~Bi|HbS*_ai@#Oy1^t2lag+L^j_Qwbc(R_3aVpm(f2cW6pK#QJ;o}J}>>C zlXV+`mQU90zCC5J`n1v*k07E<$D~b9)_21nmcAH1lQhQnvvxieSFh-^vIAju*6;Io zSJ5NsX=4w(&AhMV-}Yx{-wppYI{T%(2FdS+U+Q{l>TdY&(i!^8xcBvR%HOodJ(>U3 F{{cQT&T9Yw literal 0 HcmV?d00001 diff --git a/neotron-os/src/slide_px3.bmp b/neotron-os/src/slide_px3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d4f5611bde3190b87c581121e42e253ce71935e8 GIT binary patch literal 34650 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 D>WFdo literal 0 HcmV?d00001 diff --git a/neotron-os/src/slide_stars.bmp b/neotron-os/src/slide_stars.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73e2d392234ceb97b4e92025a8733fcdd0318237 GIT binary patch literal 6354 zcmeI0Z%bT96o=2w4Y!NPaz|v5Wm%S~NC`!@nG!+>BFkb$w#%}Jh=_=Yhy)QUBC;$Z z5=10~5JDP4K2Kky6#5DJN!mVVX4N*V)>7!JRp;E9-+ktsx&LO)SpWXl2?;;%v0ciE z5&11Al9LBQRi1GE%jsAi(AFaI$JJkG)xYcf5Gwz|sPE5ze);AL`B8qB^wTH#o!>Kn z;c<8$hVQ}fI~dLb_nQYkigBj;K}^nAY-0RJX3;xT_dz7h*-Tgg(!|$}_C8O;@4!VvL^2Th;UaZgqrsZ-_TyvB`*!9`3I) z0yFB~$SBcX%P7&_F^1dJ0?}R(tzfZ9!AJJ~D%WW;_ewINy_Ae-Z;5uBI!3fhqK#Q> zGUg*YNafm1)W>1R1F71$qeZL>G*f#+tlQKgvCfHAwAiHRBRfcajo+wGz)l2GwFyUy zSTE2_?KQD(Q%mjzk(50n)(u@^3@EvhRlVfZ2lv@Ty^LDE*2<0+9!}9r?Ny%~q*mN1 zK9xPe>kVBY8cMEWRj+vU@sem!ucB73wW_0qhaQ@#y$qytJ$kF!rT=|&Q-#bqtGx5- zh3Cp=ruro6^akTh$}_|C4?uHMa*p4ZjONjh_qr>=Us`#E!Hq z#rM!Q<;W6`ZDaPtH>#OSx!+m`s$?{mrK+!xkOz?T@lqx?joorxwzJi zId>Csj$V{=)D`GeJfAU&lDx1KzlyddXReF~jaFh58ZYX`oWSZhD1HrgU3w^0=$^$U zJ-;4QW4dlqx_EHXrN62h#5#hWl4DEpdJUU$;w(+q8 z{am*2@dO`R7MpDO=Rq}Q(>;?-*r&1ytLm<7z&?ZBu-Ih7@1pL>x|>B?gPlQLgO0i} ztF9rd=yh2|)u+5KEBI)@uUKrd;`f7U%(9!8W!O1chE?@ImSE>$mn=3}@&`dRri0#; zMN9FAXouYOwrfk9{w-JwS03vwY9`YW-9#U(cNvwQsWaA9srScvm#Wv>;A$J;S|j2zdy-Hey+_k-X-qjyu~K*nIFr) zQ5Rh7Z!&$8<{6j1OGk`$(rH-=v#rjpi($sq+4YJb4N8T*u!C||(u|%ikj_h5)7D?; zDq~IiY|5B*eOQE`9@dEHRjCnC+X>7_u+(9wW3RY^=z6471y7^ls9c4Zv^Ykx;xewL z+-G&Q%cQ~#A6Go;eXgvtbXZZVbp+yc8J&r?7iQ33A-_s+KI`@zFInAFQidyBynE%x(H|D8h zqrVJ-b%2nO% Date: Thu, 11 Apr 2024 22:25:51 +0100 Subject: [PATCH 2/7] Change the demo slides and make it render faster --- neotron-os/src/commands/screen.rs | 46 ++++++++++++++++-------------- neotron-os/src/slide_links.bmp | Bin 24090 -> 0 bytes neotron-os/src/slide_pi.bmp | Bin 0 -> 13756 bytes neotron-os/src/slide_win30.bmp | Bin 0 -> 14306 bytes 4 files changed, 24 insertions(+), 22 deletions(-) delete mode 100644 neotron-os/src/slide_links.bmp create mode 100644 neotron-os/src/slide_pi.bmp create mode 100644 neotron-os/src/slide_win30.bmp diff --git a/neotron-os/src/commands/screen.rs b/neotron-os/src/commands/screen.rs index 620c754..067f942 100644 --- a/neotron-os/src/commands/screen.rs +++ b/neotron-os/src/commands/screen.rs @@ -1,16 +1,18 @@ //! Screen-related commands for Neotron OS -static SLIDES: [&[u8]; 8] = [ +static SLIDES: [&[u8]; 10] = [ include_bytes!("../slide_pico_vga.bmp"), include_bytes!("../slide_pico_audio.bmp"), include_bytes!("../slide_bios.bmp"), include_bytes!("../slide_os.bmp"), include_bytes!("../slide_oss.bmp"), - include_bytes!("../slide_links.bmp"), + include_bytes!("../slide_sdk.bmp"), include_bytes!("../slide_stars.bmp"), include_bytes!("../slide_px3.bmp"), + include_bytes!("../slide_pi.bmp"), + include_bytes!("../slide_win30.bmp"), ]; - + use pc_keyboard::DecodedKey; use crate::{ @@ -248,8 +250,8 @@ fn demo_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], ct let api = crate::API.get(); let old_mode = (api.video_get_mode)(); let old_ptr = (api.video_get_framebuffer)(); - let buffer = ctx.tpa.as_slice_u8(); - let buffer_ptr = buffer.as_mut_ptr() as *mut u32; + let buffer = ctx.tpa.as_slice_u32(); + let buffer_ptr = buffer.as_mut_ptr(); let old_palette = [ (api.video_get_palette)(0), (api.video_get_palette)(1), @@ -264,12 +266,12 @@ fn demo_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], ct } 'slides: for slide_bytes in SLIDES.iter().cycle().cloned() { - if let Err(_e) = show_slide(slide_bytes, api, buffer) { + if let Err(_e) = show_slide(slide_bytes, api, buffer_ptr) { break; } // Now wait for user input - Q to quit, ' ' to skip - 'wait: for _ in 0..300 { - // 300 frames = 5 seconds + 'wait: for _ in 0..450 { + // 450 frames = 7.5 seconds (api.video_wait_for_line)(478); (api.video_wait_for_line)(479); let keyin = crate::STD_INPUT.lock().get_raw(); @@ -300,7 +302,7 @@ enum SlideError { fn show_slide( data: &[u8], api: &neotron_common_bios::Api, - buffer: &mut [u8], + buffer: *mut u32, ) -> Result<(), SlideError> { use embedded_graphics::pixelcolor::RgbColor; @@ -322,21 +324,21 @@ fn show_slide( } // Copy bitmap + let mut pixel_word = 0; for px in raw_bmp.pixels() { let offset_px = (px.position.y * 640) + px.position.x; - let offset_byte = (offset_px / 4) as usize; - match offset_px % 4 { - 0 => { - buffer[offset_byte] = (px.color << 6) as u8; - } - 1 => { - buffer[offset_byte] |= (px.color << 4) as u8; - } - 2 => { - buffer[offset_byte] |= (px.color << 2) as u8; - } - _ => { - buffer[offset_byte] |= px.color as u8; + let offset_word = (offset_px / 16) as usize; + let shift = 30 - ((offset_px % 16) * 2); + if shift == 30 { + pixel_word = 0; + } else { + pixel_word <<= 2; + } + pixel_word |= px.color & 0x03; + if shift == 0 { + pixel_word = pixel_word.to_be(); + unsafe { + buffer.add(offset_word).write_volatile(pixel_word); } } } diff --git a/neotron-os/src/slide_links.bmp b/neotron-os/src/slide_links.bmp deleted file mode 100644 index 08432093d4b9aac3f9fac03e56927c5e0cbb2343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24090 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 diff --git a/neotron-os/src/slide_pi.bmp b/neotron-os/src/slide_pi.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e81f4448dbf43a02ef1188ac11aa06ac81689a1c GIT binary patch literal 13756 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 VnJn{#7~e=XsZ)shn16>-`9BD{gMa`4 literal 0 HcmV?d00001 diff --git a/neotron-os/src/slide_win30.bmp b/neotron-os/src/slide_win30.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6a66f60bfe5496d51ad39ef7b209a14fb91ce451 GIT binary patch literal 14306 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 literal 0 HcmV?d00001 From c6fd84e325676726553a9de3f0e0760938e2ed82 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Tue, 20 Aug 2024 16:48:06 +0100 Subject: [PATCH 3/7] Use git version of tinybmp --- Cargo.lock | 13 ++----------- neotron-os/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c184a15..7c1b983 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,10 +276,9 @@ dependencies = [ "embedded-sdmmc", "heapless", "menu", - "neotron-api 0.2.0", + "neotron-api 0.1.0", "neotron-common-bios", "neotron-loader", - "neotron-romfs", "pc-keyboard", "postcard", "r0", @@ -288,15 +287,6 @@ dependencies = [ "vte", ] -[[package]] -name = "neotron-romfs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5758cc14dd6e15def81e3a12d36a35b2779ac568e30b96501cdaba2571c4b1e2" -dependencies = [ - "neotron-api 0.1.0", -] - [[package]] name = "neotron-sdk" version = "0.2.0" @@ -496,6 +486,7 @@ dependencies = [ [[package]] name = "tinybmp" version = "0.5.0" +source = "git+https://github.com/embedded-graphics/tinybmp?rev=247718592bb7a1904f4846e5f1adef87d33e1781#247718592bb7a1904f4846e5f1adef87d33e1781" dependencies = [ "embedded-graphics", ] diff --git a/neotron-os/Cargo.toml b/neotron-os/Cargo.toml index 82c02ba..232f9ce 100644 --- a/neotron-os/Cargo.toml +++ b/neotron-os/Cargo.toml @@ -44,7 +44,7 @@ pc-keyboard = "0.7" postcard = "1.0" r0 = "1.0" serde = { version = "1.0", default-features = false } -tinybmp = { path = "../../tinybmp" } +tinybmp = { git = "https://github.com/embedded-graphics/tinybmp", rev="247718592bb7a1904f4846e5f1adef87d33e1781" } vte = "0.12" [features] From 5646a641590f1aa1798cfac47e43833a819a0319 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Tue, 20 Aug 2024 17:14:50 +0100 Subject: [PATCH 4/7] Update Cargo.lock --- Cargo.lock | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 7c1b983..32fe98d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,9 +276,10 @@ dependencies = [ "embedded-sdmmc", "heapless", "menu", - "neotron-api 0.1.0", + "neotron-api 0.2.0", "neotron-common-bios", "neotron-loader", + "neotron-romfs", "pc-keyboard", "postcard", "r0", @@ -287,6 +288,15 @@ dependencies = [ "vte", ] +[[package]] +name = "neotron-romfs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5758cc14dd6e15def81e3a12d36a35b2779ac568e30b96501cdaba2571c4b1e2" +dependencies = [ + "neotron-api 0.1.0", +] + [[package]] name = "neotron-sdk" version = "0.2.0" From 8ae875516fb5cf18100608cdf0c1ef7b0a076249 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Tue, 20 Aug 2024 20:20:30 +0100 Subject: [PATCH 5/7] Add 16-colour bitmap. Sets the correct mode based on the bitmap colour depth. --- neotron-os/src/commands/screen.rs | 102 ++++++++++++++++++++++-------- neotron-os/src/slide_win31.bmp | Bin 0 -> 153802 bytes 2 files changed, 76 insertions(+), 26 deletions(-) create mode 100644 neotron-os/src/slide_win31.bmp diff --git a/neotron-os/src/commands/screen.rs b/neotron-os/src/commands/screen.rs index 067f942..4e70d08 100644 --- a/neotron-os/src/commands/screen.rs +++ b/neotron-os/src/commands/screen.rs @@ -1,6 +1,6 @@ //! Screen-related commands for Neotron OS -static SLIDES: [&[u8]; 10] = [ +static SLIDES: [&[u8]; 11] = [ include_bytes!("../slide_pico_vga.bmp"), include_bytes!("../slide_pico_audio.bmp"), include_bytes!("../slide_bios.bmp"), @@ -11,8 +11,10 @@ static SLIDES: [&[u8]; 10] = [ include_bytes!("../slide_px3.bmp"), include_bytes!("../slide_pi.bmp"), include_bytes!("../slide_win30.bmp"), + include_bytes!("../slide_win31.bmp"), ]; - + +use neotron_common_bios::video::Timing; use pc_keyboard::DecodedKey; use crate::{ @@ -257,13 +259,19 @@ fn demo_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], ct (api.video_get_palette)(1), (api.video_get_palette)(2), (api.video_get_palette)(3), + (api.video_get_palette)(4), + (api.video_get_palette)(5), + (api.video_get_palette)(6), + (api.video_get_palette)(7), + (api.video_get_palette)(8), + (api.video_get_palette)(9), + (api.video_get_palette)(10), + (api.video_get_palette)(11), + (api.video_get_palette)(12), + (api.video_get_palette)(13), + (api.video_get_palette)(14), + (api.video_get_palette)(15), ]; - if let neotron_common_bios::FfiResult::Err(e) = - unsafe { (api.video_set_mode)(Mode::from_u8(6), buffer_ptr) } - { - osprintln!("Couldn't set mode 6: {:?}", e); - return; - } 'slides: for slide_bytes in SLIDES.iter().cycle().cloned() { if let Err(_e) = show_slide(slide_bytes, api, buffer_ptr) { @@ -302,7 +310,7 @@ enum SlideError { fn show_slide( data: &[u8], api: &neotron_common_bios::Api, - buffer: *mut u32, + buffer_ptr: *mut u32, ) -> Result<(), SlideError> { use embedded_graphics::pixelcolor::RgbColor; @@ -312,34 +320,76 @@ fn show_slide( return Err(SlideError::Unspecified); } - // Program palette - if let Some(table) = raw_bmp.color_table() { - for entry in 0..4 { - if let Some(rgb) = table.get(entry) { - let rgb666 = - neotron_common_bios::video::RGBColour::from_rgb(rgb.r(), rgb.g(), rgb.b()); - (api.video_set_palette)(entry as u8, rgb666); - } + let Some(table) = raw_bmp.color_table() else { + // can only do palettised images + return Err(SlideError::Unspecified); + }; + + // Set palette to black + for entry in 0..table.len() { + (api.video_set_palette)(entry as u8, neotron_common_bios::video::RGBColour::BLACK); + } + + let (mode, bpp, px_per_word_shift) = match (header.bpp, table.len() <= 4) { + (tinybmp::Bpp::Bits4, true) => (Mode::new(Timing::T640x480, Format::Chunky2), 2, 4), + (tinybmp::Bpp::Bits4, false) => (Mode::new(Timing::T640x480, Format::Chunky4), 4, 3), + b => { + // can't display it + osprintln!("Couldn't handle {:?}", b); + return Err(SlideError::Unspecified); } + }; + + if let neotron_common_bios::FfiResult::Err(e) = + unsafe { (api.video_set_mode)(mode, buffer_ptr) } + { + osprintln!("Couldn't set mode {:?}: {:?}", mode, e); + return Err(SlideError::Unspecified); } // Copy bitmap let mut pixel_word = 0; + let mut offset_word = 0; + let mut left_in_word = 1 << px_per_word_shift; + let mut y = 0; + let mut x = 0; + // annoyingly bitmaps aren't always top-left to bottom-right. for px in raw_bmp.pixels() { - let offset_px = (px.position.y * 640) + px.position.x; - let offset_word = (offset_px / 16) as usize; - let shift = 30 - ((offset_px % 16) * 2); - if shift == 30 { + if y != px.position.y || x != px.position.x { + // we assume discontinuities only happen at line breaks + y = px.position.y; + x = px.position.x; + offset_word = (((y * 640) + x) >> px_per_word_shift) as usize; + left_in_word = 1 << px_per_word_shift; pixel_word = 0; - } else { - pixel_word <<= 2; } - pixel_word |= px.color & 0x03; - if shift == 0 { + + pixel_word <<= bpp; + pixel_word |= px.color; + + left_in_word -= 1; + if left_in_word == 0 { pixel_word = pixel_word.to_be(); unsafe { - buffer.add(offset_word).write_volatile(pixel_word); + buffer_ptr.add(offset_word).write_volatile(pixel_word); } + pixel_word = 0; + left_in_word = 1 << px_per_word_shift; + offset_word += 1; + } + + x += 1; + if x == 640 { + x = 0; + y += 1; + } + } + + // Set palette to correct colours now picture is drawn + for entry in 0..table.len() { + if let Some(rgb) = table.get(entry as u32) { + let rgb666 = neotron_common_bios::video::RGBColour::from_rgb(rgb.r(), rgb.g(), rgb.b()); + (api.video_set_palette)(entry as u8, rgb666); } } diff --git a/neotron-os/src/slide_win31.bmp b/neotron-os/src/slide_win31.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2f3bc7eb31d2920e549a1166e2564c87edb1da88 GIT binary patch literal 153802 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 D+?ue- literal 0 HcmV?d00001 From 9f601573aa12d2ec80bb259b30176a42d6f34a25 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Tue, 20 Aug 2024 20:20:35 +0100 Subject: [PATCH 6/7] Clippy fixes. --- neotron-os/src/commands/fs.rs | 16 +++++++--------- neotron-os/src/lib.rs | 4 ++-- neotron-os/src/program.rs | 1 + 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/neotron-os/src/commands/fs.rs b/neotron-os/src/commands/fs.rs index 56728b2..194cf03 100644 --- a/neotron-os/src/commands/fs.rs +++ b/neotron-os/src/commands/fs.rs @@ -190,7 +190,7 @@ fn romfn(_menu: &menu::Menu, _item: &menu::Item, args: &[&str], ctx: & osprintln!("No ROM available"); return; }; - if let Some(arg) = args.get(0) { + if let Some(arg) = args.first() { let Some(entry) = romfs.find(arg) else { osprintln!("Couldn't find {} in ROM", arg); return; @@ -199,14 +199,12 @@ fn romfn(_menu: &menu::Menu, _item: &menu::Item, args: &[&str], ctx: & osprintln!("Error: {:?}", e); } } else { - for entry in romfs.into_iter() { - if let Ok(entry) = entry { - osprintln!( - "{} ({} bytes)", - entry.metadata.file_name, - entry.metadata.file_size - ); - } + for entry in romfs.into_iter().flatten() { + osprintln!( + "{} ({} bytes)", + entry.metadata.file_name, + entry.metadata.file_size + ); } } } diff --git a/neotron-os/src/lib.rs b/neotron-os/src/lib.rs index 69307c5..a63c2e4 100644 --- a/neotron-os/src/lib.rs +++ b/neotron-os/src/lib.rs @@ -62,10 +62,10 @@ static STD_INPUT: CsRefCell = CsRefCell::new(StdInput::new()); static FILESYSTEM: fs::Filesystem = fs::Filesystem::new(); #[cfg(romfs_enabled = "yes")] -static ROMFS: &'static [u8] = include_bytes!(env!("ROMFS_PATH")); +static ROMFS: &[u8] = include_bytes!(env!("ROMFS_PATH")); #[cfg(not(romfs_enabled = "yes"))] -static ROMFS: &'static [u8] = &[]; +static ROMFS: &[u8] = &[]; // =========================================================================== // Macros diff --git a/neotron-os/src/program.rs b/neotron-os/src/program.rs index 404b3ce..7cc1878 100644 --- a/neotron-os/src/program.rs +++ b/neotron-os/src/program.rs @@ -310,6 +310,7 @@ impl TransientProgramArea { // We support a maximum of four arguments. #[allow(clippy::get_first)] let ffi_args = [ + #[allow(clippy::get_first)] neotron_api::FfiString::new(args.get(0).unwrap_or(&"")), neotron_api::FfiString::new(args.get(1).unwrap_or(&"")), neotron_api::FfiString::new(args.get(2).unwrap_or(&"")), From 29aeb0e6c6d80ca57891a4e1dda6b78fe05d9458 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Tue, 20 Aug 2024 20:22:19 +0100 Subject: [PATCH 7/7] More clippy fixes. --- neotron-os/build.rs | 2 +- utilities/flames/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/neotron-os/build.rs b/neotron-os/build.rs index 1a31183..a91e548 100644 --- a/neotron-os/build.rs +++ b/neotron-os/build.rs @@ -37,9 +37,9 @@ fn main() { if option_env!("ROMFS_PATH").is_some() { println!("cargo::rustc-cfg=romfs_enabled=\"yes\""); - println!("cargo::rustc-check-cfg=cfg(romfs_enabled, values(\"yes\"))"); println!("cargo::rerun-if-env-changed=ROMFS_PATH"); } + println!("cargo::rustc-check-cfg=cfg(romfs_enabled, values(\"yes\"))"); } /// Put the given script in our output directory and ensure it's on the linker diff --git a/utilities/flames/src/lib.rs b/utilities/flames/src/lib.rs index 4cc4a63..0c9a7b9 100644 --- a/utilities/flames/src/lib.rs +++ b/utilities/flames/src/lib.rs @@ -136,7 +136,7 @@ impl App { /// Generates a number in the range [0, limit) fn random_up_to(&mut self, limit: usize) -> usize { - let buckets = ::core::usize::MAX / limit; + let buckets = usize::MAX / limit; let upper_edge = buckets * limit; loop { let attempt = self.random();