Skip to content

Commit

Permalink
Make ioctls unsafe, and add some defines.
Browse files Browse the repository at this point in the history
  • Loading branch information
thejpster committed Dec 27, 2024
1 parent 88b28f0 commit 49509fc
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ authors = ["Jonathan 'theJPster' Pallant <[email protected]>"]
[dependencies]
neotron-ffi = "0.1"
neotron-api = "0.2"
neotron-common-bios = "0.12"

[target.'cfg(unix)'.dependencies]
crossterm = "0.26"
Expand Down
44 changes: 44 additions & 0 deletions src/ioctls/gfx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! Graphics ioctl constants
/// Clear the screen
///
/// The corresponding value is the fill colour, which is taken modulo the number of on-screen colours.
pub const COMMAND_CLEAR_SCREEN: u64 = 0;

/// Plot a chunky pixel
///
/// The command contains [ x | y | mode | colour ].
///
/// * `x` is 16 bits and marks the horizontal position (0 is left)
/// * `y` is 16 bits and marks the vertical position (0 is top)
/// * `mode` is 8 bits and is currently ignored
/// * `colour` is 24 bits, and is taken modulo the number of on-screen colours
///
/// Use [`chunky_plot_value`] to create a suitable value for this ioctl command.
pub const COMMAND_CHUNKY_PLOT: u64 = 1;

/// Change graphics mode
///
/// The command contains the video mode in the upper 32 bits and a pointer to a
/// framebuffer in the lower 32 bits.
///
/// The framebuffer pointer must point to a 32-bit aligned region of memory
/// that is large enough for the selected mode. If you pass `null`, then the OS
/// will attempt to allocate a framebuffer for you.
///
/// Use [`change_mode_value`] to construct a value.
pub const COMMAND_CHANGE_MODE: u64 = 2;

/// Calculate a 64-bit value argument for a gfx ioctl
pub fn chunky_plot_value(x: u16, y: u16, colour: u32) -> u64 {
(x as u64) << 48 | (y as u64) << 32 | (colour & 0xFFFFFF) as u64
}

/// Calculate a 64-bit value argument for a gfx ioctl
pub fn change_mode_value(mode: crate::VideoMode, fb_ptr: *mut u32) -> u64 {
let fb_ptr = fb_ptr as usize as u64;
let mode = mode.as_u8() as u64;
mode << 32 | fb_ptr
}

// End of file
3 changes: 3 additions & 0 deletions src/ioctls/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! A collection of ioctl constants
pub mod gfx;
14 changes: 12 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ pub use neotron_ffi::{FfiBuffer, FfiByteSlice, FfiString};

pub use neotron_api::{file::Flags, path, Api, Error};

pub use neotron_common_bios::video::Mode as VideoMode;

use neotron_api as api;

pub mod console;

pub mod ioctls;

#[cfg(not(target_os = "none"))]
mod fake_os_api;

Expand Down Expand Up @@ -204,8 +208,14 @@ impl File {

/// Perform a special I/O control operation.
///
/// The allowed values of `command` and `value` are TBD.
pub fn ioctl(&self, command: u64, value: u64) -> Result<u64> {
/// The allowed values of `command` and `value` are defined in the
/// [`ioctls`] module.
///
/// # Safety
///
/// Refer to the documentation for the ioctl you are using. Raw pointers may
/// be involved.
pub unsafe fn ioctl(&self, command: u64, value: u64) -> Result<u64> {
let api = get_api();
match (api.ioctl)(self.0, command, value) {
neotron_ffi::FfiResult::Ok(output) => Ok(output),
Expand Down

0 comments on commit 49509fc

Please sign in to comment.