Skip to content

Commit 796afd6

Browse files
authored
Merge pull request #30 from Neotron-Compute/add-screen-benchmark
2 parents c975de8 + 0d0b20c commit 796afd6

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

src/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ pub static OS_MENU: menu::Menu<Ctx> = menu::Menu {
2222
#[cfg(target_os = "none")]
2323
&ram::RUN_ITEM,
2424
&screen::CLEAR_ITEM,
25+
&screen::BENCH_ITEM,
2526
&screen::FILL_ITEM,
27+
&screen::MANDEL_ITEM,
2628
&input::KBTEST_ITEM,
2729
],
2830
entry: None,

src/commands/screen.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use neotron_common_bios::video::{Attr, TextBackgroundColour, TextForegroundColour};
44

5-
use crate::{println, Ctx, API, VGA_CONSOLE};
5+
use crate::{print, println, Ctx, API, VGA_CONSOLE};
66

77
pub static CLEAR_ITEM: menu::Item<Ctx> = menu::Item {
88
item_type: menu::ItemType::Callback {
@@ -22,6 +22,24 @@ pub static FILL_ITEM: menu::Item<Ctx> = menu::Item {
2222
help: Some("Fill the screen with characters"),
2323
};
2424

25+
pub static BENCH_ITEM: menu::Item<Ctx> = menu::Item {
26+
item_type: menu::ItemType::Callback {
27+
function: bench,
28+
parameters: &[],
29+
},
30+
command: "screen_bench",
31+
help: Some("Time how long to put 1,000,000 characters on the screen, with scrolling."),
32+
};
33+
34+
pub static MANDEL_ITEM: menu::Item<Ctx> = menu::Item {
35+
item_type: menu::ItemType::Callback {
36+
function: mandel,
37+
parameters: &[],
38+
},
39+
command: "screen_mandel",
40+
help: Some("Calculate the Mandelbrot set"),
41+
};
42+
2543
/// Called when the "clear" command is executed.
2644
fn clear(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
2745
if let Some(ref mut console) = unsafe { &mut VGA_CONSOLE } {
@@ -69,3 +87,61 @@ fn fill(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx:
6987
console.set_attr(attr);
7088
}
7189
}
90+
91+
/// Called when the "bench" command is executed.
92+
fn bench(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
93+
const NUM_CHARS: u64 = 1_000_000;
94+
if let Some(ref mut console) = unsafe { &mut VGA_CONSOLE } {
95+
let api = API.get();
96+
let start = (api.time_ticks_get)();
97+
console.clear();
98+
let glyphs = &[b'x'];
99+
for _idx in 0..NUM_CHARS {
100+
console.write_bstr(glyphs);
101+
}
102+
let end = (api.time_ticks_get)();
103+
let delta = end.0 - start.0;
104+
let chars_per_second = (NUM_CHARS * (api.time_ticks_per_second)().0) / delta;
105+
println!(
106+
"{} chars in {} ticks, or {} chars per second",
107+
NUM_CHARS, delta, chars_per_second
108+
);
109+
}
110+
}
111+
112+
/// Called when the "mandel" command is executed.
113+
fn mandel(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
114+
fn mandelbrot(cx: f64, cy: f64, max_loops: u32) -> u32 {
115+
let mut x = cx;
116+
let mut y = cy;
117+
for i in 1..max_loops {
118+
let x_squared = x * x;
119+
let y_squared = y * y;
120+
if x_squared + y_squared > 4.0 {
121+
return i;
122+
}
123+
let x1 = x_squared - y_squared + cx;
124+
let y1 = (2.0 * x * y) + cy;
125+
x = x1;
126+
y = y1;
127+
}
128+
0
129+
}
130+
131+
let api = API.get();
132+
let mode = (api.video_get_mode)();
133+
let (Some(width), Some(height)) = (mode.text_width(), mode.text_height()) else {
134+
println!("Unable to get screen size");
135+
return;
136+
};
137+
138+
let glyphs = b" .,'~!^:;[/<&?oxOX# ";
139+
for y_pos in 0..height - 2 {
140+
let y = (f64::from(y_pos) * 4.0 / f64::from(height)) - 2.0;
141+
for x_pos in 0..width {
142+
let x = (f64::from(x_pos) * 4.0 / f64::from(width)) - 2.0;
143+
let result = mandelbrot(x, y, 20);
144+
print!("{}", glyphs[result as usize] as char);
145+
}
146+
}
147+
}

0 commit comments

Comments
 (0)