Skip to content

Commit

Permalink
Merge branch 'release/v0.3.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanpallant committed Mar 9, 2023
2 parents 4451c70 + c6c60c2 commit 2726b78
Show file tree
Hide file tree
Showing 10 changed files with 530 additions and 297 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,10 @@
# Change Log

## v0.3.1

* Add `hexdump`, `load` and `run` commands.
* Set colour attributes correctly (White on Black only currently)

## v0.3.0

* Updated to Neotron Common BIOS v0.8.0
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "neotron-os"
version = "0.3.0"
version = "0.3.1"
authors = ["Jonathan 'theJPster' Pallant <github@thejpster.org.uk>"]
edition = "2018"
description = "The Neotron Operating System"
Expand Down
92 changes: 92 additions & 0 deletions src/commands/config.rs
@@ -0,0 +1,92 @@
//! Configuration related commands for Neotron OS

use crate::{config, println, Ctx};

pub static COMMAND_ITEM: menu::Item<Ctx> = menu::Item {
item_type: menu::ItemType::Callback {
function: command,
parameters: &[
menu::Parameter::Optional {
parameter_name: "command",
help: Some("Which operation to perform (try help)"),
},
menu::Parameter::Optional {
parameter_name: "value",
help: Some("new value for the setting"),
},
],
},
command: "config",
help: Some("Handle non-volatile OS configuration"),
};

/// Called when the "config" command is executed.
fn command(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], ctx: &mut Ctx) {
let command = args.get(0).cloned().unwrap_or("print");
match command {
"reset" => match config::Config::load() {
Ok(new_config) => {
ctx.config = new_config;
println!("Loaded OK.");
}
Err(e) => {
println!("Error loading; {}", e);
}
},
"save" => match ctx.config.save() {
Ok(_) => {
println!("Saved OK.");
}
Err(e) => {
println!("Error saving: {}", e);
}
},
"vga" => match args.get(1).cloned() {
Some("on") => {
ctx.config.set_vga_console(true);
println!("VGA now on");
}
Some("off") => {
ctx.config.set_vga_console(false);
println!("VGA now off");
}
_ => {
println!("Give on or off as argument");
}
},
"serial" => match (args.get(1).cloned(), args.get(1).map(|s| s.parse::<u32>())) {
(_, Some(Ok(baud))) => {
println!("Turning serial console on at {} bps", baud);
ctx.config.set_serial_console_on(baud);
}
(Some("off"), _) => {
println!("Turning serial console off");
ctx.config.set_serial_console_off();
}
_ => {
println!("Give off or an integer as argument");
}
},
"print" => {
println!("VGA : {}", ctx.config.get_vga_console());
match ctx.config.get_serial_console() {
None => {
println!("Serial: off");
}
Some((_port, config)) => {
println!("Serial: {} bps", config.data_rate_bps);
}
}
}
_ => {
println!("config print - print the config");
println!("config help - print this help text");
println!("config reset - load config from BIOS store");
println!("config save - save config to BIOS store");
println!("config vga on - turn VGA on");
println!("config vga off - turn VGA off");
println!("config serial off - turn serial console off");
println!("config serial <baud> - turn serial console on with given baud rate");
}
}
}
104 changes: 104 additions & 0 deletions src/commands/hardware.rs
@@ -0,0 +1,104 @@
//! Hardware related commands for Neotron OS

use crate::{bios, println, Ctx, API};

pub static LSHW_ITEM: menu::Item<Ctx> = menu::Item {
item_type: menu::ItemType::Callback {
function: bioshw,
parameters: &[],
},
command: "bioshw",
help: Some("List all the BIOS hardware"),
};

/// Called when the "bioshw" command is executed.
fn bioshw(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
let api = API.get();
let mut found = false;

println!("Memory regions:");
for region_idx in 0..=255u8 {
if let bios::Option::Some(region) = (api.memory_get_region)(region_idx) {
println!(" {}: {}", region_idx, region);
found = true;
}
}
if !found {
println!(" None");
}

found = false;

println!("Serial Devices:");
for dev_idx in 0..=255u8 {
if let bios::Option::Some(device_info) = (api.serial_get_info)(dev_idx) {
println!(
" {}: {} {:?}",
dev_idx, device_info.name, device_info.device_type
);
found = true;
}
}
if !found {
println!(" None");
}

found = false;

println!("Block Devices:");
for dev_idx in 0..=255u8 {
if let bios::Option::Some(device_info) = (api.block_dev_get_info)(dev_idx) {
println!(
" {}: {} {:?} bs={} size={} MiB",
dev_idx,
device_info.name,
device_info.device_type,
device_info.block_size,
(device_info.num_blocks * u64::from(device_info.block_size)) / (1024 * 1024)
);
found = true;
}
}
if !found {
println!(" None");
}

found = false;

println!("I2C Buses:");
for dev_idx in 0..=255u8 {
if let bios::Option::Some(device_info) = (api.i2c_bus_get_info)(dev_idx) {
println!(" {}: {:?}", dev_idx, device_info);
found = true;
}
}
if !found {
println!(" None");
}

found = false;

println!("Neotron Bus Devices:");
for dev_idx in 0..=255u8 {
if let bios::Option::Some(device_info) = (api.bus_get_info)(dev_idx) {
println!(" {}: {:?}", dev_idx, device_info);
found = true;
}
}
if !found {
println!(" None");
}

found = false;

println!("Audio Mixers:");
for dev_idx in 0..=255u8 {
if let bios::Option::Some(device_info) = (api.audio_mixer_channel_get_info)(dev_idx) {
println!(" {}: {:?}", dev_idx, device_info);
found = true;
}
}
if !found {
println!(" None");
}
}
53 changes: 53 additions & 0 deletions src/commands/input.rs
@@ -0,0 +1,53 @@
//! Input related commands for Neotron OS

use crate::{bios, println, Ctx, API};

pub static KBTEST_ITEM: menu::Item<Ctx> = menu::Item {
item_type: menu::ItemType::Callback {
function: kbtest,
parameters: &[],
},
command: "input_kbtest",
help: Some("Test the keyboard (press ESC to quit)"),
};

/// Called when the "kbtest" command is executed.
fn kbtest(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], ctx: &mut Ctx) {
let api = API.get();
loop {
match (api.hid_get_event)() {
bios::Result::Ok(bios::Option::Some(bios::hid::HidEvent::KeyPress(code))) => {
let pckb_ev = pc_keyboard::KeyEvent {
code,
state: pc_keyboard::KeyState::Down,
};
if let Some(ev) = ctx.keyboard.process_keyevent(pckb_ev) {
println!("Code={code:?} State=Down Decoded={ev:?}");
} else {
println!("Code={code:?} State=Down Decoded=None");
}
if code == pc_keyboard::KeyCode::Escape {
break;
}
}
bios::Result::Ok(bios::Option::Some(bios::hid::HidEvent::KeyRelease(code))) => {
let pckb_ev = pc_keyboard::KeyEvent {
code,
state: pc_keyboard::KeyState::Up,
};
if let Some(ev) = ctx.keyboard.process_keyevent(pckb_ev) {
println!("Code={code:?} State=Up Decoded={ev:?}");
} else {
println!("Code={code:?} State=Up Decoded=None");
}
}
bios::Result::Ok(bios::Option::Some(bios::hid::HidEvent::MouseInput(_ignore))) => {}
bios::Result::Ok(bios::Option::None) => {
// Do nothing
}
bios::Result::Err(e) => {
println!("Failed to get HID events: {:?}", e);
}
}
}
}
28 changes: 28 additions & 0 deletions src/commands/mod.rs
@@ -0,0 +1,28 @@
//! Commands for Neotron OS
//!
//! Defines the top-level menu, and the commands it can call.

pub use super::Ctx;

mod config;
mod hardware;
mod input;
mod ram;
mod screen;

pub static OS_MENU: menu::Menu<Ctx> = menu::Menu {
label: "root",
items: &[
&config::COMMAND_ITEM,
&hardware::LSHW_ITEM,
&ram::HEXDUMP_ITEM,
&ram::LOAD_ITEM,
#[cfg(target_os = "none")]
&ram::RUN_ITEM,
&screen::CLEAR_ITEM,
&screen::FILL_ITEM,
&input::KBTEST_ITEM,
],
entry: None,
exit: None,
};

0 comments on commit 2726b78

Please sign in to comment.