Skip to content

Commit c6d7e89

Browse files
committed
Add some mode demos, and a palette IOCTL.
1 parent 6303664 commit c6d7e89

File tree

14 files changed

+810
-0
lines changed

14 files changed

+810
-0
lines changed

nbuild/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,20 @@ fn packages() -> Vec<nbuild::Package> {
6363
kind: nbuild::PackageKind::Utility,
6464
testable: nbuild::Testable::No,
6565
},
66+
nbuild::Package {
67+
name: "logo",
68+
path: std::path::Path::new("./utilities/logo/Cargo.toml"),
69+
output_template: Some("./target/{target}/{profile}/logo"),
70+
kind: nbuild::PackageKind::Utility,
71+
testable: nbuild::Testable::No,
72+
},
73+
nbuild::Package {
74+
name: "desktop",
75+
path: std::path::Path::new("./utilities/desktop/Cargo.toml"),
76+
output_template: Some("./target/{target}/{profile}/desktop"),
77+
kind: nbuild::PackageKind::Utility,
78+
testable: nbuild::Testable::No,
79+
},
6680
nbuild::Package {
6781
name: "Neotron OS",
6882
path: std::path::Path::new("./neotron-os/Cargo.toml"),

neotron-os/src/program.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,16 @@ pub const GFX_COMMAND_MOVE_CURSOR: u64 = 3;
850850
/// The start position is the cursor position. The cursor is updated to the final position.
851851
pub const GFX_COMMAND_DRAW_LINE: u64 = 4;
852852

853+
/// Set a palette entry
854+
///
855+
/// The command contains [ <padding> | II | RR | GG | BB ]
856+
///
857+
/// II, RR, GG and BB are 8-bit values where II is the index into the 256 long
858+
/// palette, and RR, GG and BB are the 24-bit RGB colour for that index.
859+
///
860+
/// Use [`set_palette_value`] to construct a value.
861+
pub const GFX_COMMAND_SET_PALETTE: u64 = 5;
862+
853863
/// Handle framebuffer-specific ioctls
854864
fn ioctl_gfx(state: &mut GfxState, command: u64, value: u64) -> neotron_api::Result<u64> {
855865
let mut lock = crate::VGA_CONSOLE.lock();
@@ -1003,6 +1013,14 @@ fn ioctl_gfx(state: &mut GfxState, command: u64, value: u64) -> neotron_api::Res
10031013
state.cursor_y = new_y;
10041014
neotron_api::Result::Ok(0)
10051015
}
1016+
GFX_COMMAND_SET_PALETTE => {
1017+
let index = (value >> 24) as u8;
1018+
let rgb_packed = (value & 0xFFFFFF) as u32;
1019+
let api = crate::API.get();
1020+
let rgb_colour = neotron_common_bios::video::RGBColour::from_packed(rgb_packed);
1021+
(api.video_set_palette)(index, rgb_colour);
1022+
neotron_api::Result::Ok(0)
1023+
}
10061024
_ => neotron_api::Result::Err(neotron_api::Error::InvalidArg),
10071025
}
10081026
}

utilities/desktop/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "desktop"
3+
version = "0.1.0"
4+
edition = "2021"
5+
license = "MIT OR Apache-2.0"
6+
authors = ["Jonathan 'theJPster' Pallant <neotron@thejpster.org.uk>"]
7+
description = "Shows the Windows 95 desktop"
8+
9+
[dependencies]
10+
neotron-sdk = { workspace = true }
11+
12+
# See workspace for profile settings

utilities/desktop/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Desktop
2+
3+
Displays a raw 640x480 bitmap in 16 colour mode.

utilities/desktop/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("cargo:rustc-link-arg-bin=desktop=-Tneotron-cortex-m.ld");
3+
}

utilities/desktop/src/desktop.raw

150 KB
Binary file not shown.

utilities/desktop/src/lib.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//! Logic for the vidtest utility
2+
3+
#![no_std]
4+
#![deny(missing_docs)]
5+
6+
use core::{cell::UnsafeCell, fmt::Write};
7+
8+
// Big enough for our Mode 5 (640 x 480 @ 4bpp) logo
9+
struct RacyBuffer {
10+
inner: UnsafeCell<[u8; 320 * 480]>,
11+
}
12+
13+
unsafe impl Sync for RacyBuffer {}
14+
15+
static FRAMEBUFFER: RacyBuffer = RacyBuffer {
16+
inner: UnsafeCell::new(*include_bytes!("desktop.raw")),
17+
};
18+
19+
/// Entry point to the program
20+
pub fn main() -> i32 {
21+
let mut stdout = neotron_sdk::stdout();
22+
23+
let Some(mode) = neotron_sdk::VideoMode::try_from_u8(5) else {
24+
_ = writeln!(stdout, "Invalid mode");
25+
return -1;
26+
};
27+
28+
let handle: Result<_, _> = neotron_sdk::File::open(
29+
neotron_sdk::path::Path::new("GFX:").unwrap(),
30+
neotron_sdk::Flags::WRITE,
31+
);
32+
let Ok(handle) = handle else {
33+
return -1;
34+
};
35+
unsafe {
36+
// point at our canned data
37+
if handle
38+
.ioctl(
39+
neotron_sdk::ioctls::gfx::COMMAND_CHANGE_MODE,
40+
neotron_sdk::ioctls::gfx::change_mode_value(
41+
mode,
42+
FRAMEBUFFER.inner.get() as *mut u32,
43+
),
44+
)
45+
.is_err()
46+
{
47+
return -2;
48+
}
49+
}
50+
51+
for (index, entry) in PALETTE.iter().enumerate() {
52+
unsafe {
53+
// load the palette
54+
if handle
55+
.ioctl(
56+
neotron_sdk::ioctls::gfx::COMMAND_SET_PALETTE,
57+
neotron_sdk::ioctls::gfx::set_palette_value(
58+
index as u8,
59+
entry.0,
60+
entry.1,
61+
entry.2,
62+
),
63+
)
64+
.is_err()
65+
{
66+
return -2;
67+
}
68+
}
69+
}
70+
71+
wait_for_key();
72+
73+
0
74+
}
75+
76+
fn wait_for_key() {
77+
let stdin = neotron_sdk::stdin();
78+
let mut buffer = [0u8; 1];
79+
while let Ok(0) = stdin.read(&mut buffer) {
80+
// spin
81+
}
82+
}
83+
84+
static PALETTE: [(u8, u8, u8); 16] = [
85+
(0, 0, 0),
86+
(136, 0, 0),
87+
(255, 0, 0),
88+
(0, 136, 0),
89+
(0, 255, 0),
90+
(136, 136, 0),
91+
(255, 255, 0),
92+
(0, 0, 136),
93+
(0, 0, 255),
94+
(0, 136, 136),
95+
(0, 255, 255),
96+
(136, 136, 136),
97+
(187, 187, 187),
98+
(255, 255, 255),
99+
(0, 0, 0),
100+
(0, 0, 0),
101+
];
102+
103+
// End of file

utilities/desktop/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![cfg_attr(target_os = "none", no_std)]
2+
#![cfg_attr(target_os = "none", no_main)]
3+
4+
#[cfg(not(target_os = "none"))]
5+
fn main() {
6+
neotron_sdk::init();
7+
}
8+
9+
#[no_mangle]
10+
extern "C" fn neotron_main() -> i32 {
11+
desktop::main()
12+
}
13+
14+
// End of file

utilities/logo/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "logo"
3+
version = "0.1.0"
4+
edition = "2021"
5+
license = "MIT OR Apache-2.0"
6+
authors = ["Jonathan 'theJPster' Pallant <neotron@thejpster.org.uk>"]
7+
description = "Shows the Windows 95 boot-up logo"
8+
9+
[dependencies]
10+
neotron-sdk = { workspace = true }
11+
12+
# See workspace for profile settings

utilities/logo/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Logo
2+
3+
Displays a raw 320x480 bitmap in 256 colour mode and rolls the palette.

0 commit comments

Comments
 (0)