mirror of https://github.com/vinc/moros.git
93 lines
2.7 KiB
Rust
93 lines
2.7 KiB
Rust
use crate::{api, sys};
|
|
use crate::api::process::ExitCode;
|
|
use crate::api::console::Style;
|
|
|
|
use x86_64::instructions::port::Port;
|
|
|
|
// See: https://wiki.osdev.org/PC_Speaker
|
|
|
|
const SPEAKER_PORT: u16 = 0x61;
|
|
|
|
fn start_sound(freq: f64) {
|
|
let divider = (sys::time::PIT_FREQUENCY / freq) as u16;
|
|
let channel = 2;
|
|
sys::time::set_pit_frequency_divider(divider, channel);
|
|
|
|
let mut speaker: Port<u8> = Port::new(SPEAKER_PORT);
|
|
let tmp = unsafe { speaker.read() };
|
|
if tmp != (tmp | 3) {
|
|
unsafe { speaker.write(tmp | 3) };
|
|
}
|
|
}
|
|
|
|
fn stop_sound() {
|
|
let mut speaker: Port<u8> = Port::new(SPEAKER_PORT);
|
|
let tmp = unsafe { speaker.read() } & 0xFC;
|
|
unsafe { speaker.write(tmp) };
|
|
}
|
|
|
|
fn beep(freq: f64, len: f64) {
|
|
start_sound(freq);
|
|
api::syscall::sleep(len);
|
|
stop_sound();
|
|
}
|
|
|
|
pub fn main(args: &[&str]) -> Result<(), ExitCode> {
|
|
let mut freq = 440.0;
|
|
let mut len = 200.0;
|
|
let mut i = 1;
|
|
let n = args.len();
|
|
while i < n {
|
|
match args[i] {
|
|
"-h" | "--help" => {
|
|
return help();
|
|
}
|
|
"-f" | "--freq" => {
|
|
if i + 1 < n {
|
|
if let Ok(value) = args[i + 1].parse() {
|
|
freq = value;
|
|
} else {
|
|
error!("Could not parse freq");
|
|
return Err(ExitCode::Failure);
|
|
}
|
|
i += 1;
|
|
} else {
|
|
error!("Missing freq");
|
|
return Err(ExitCode::UsageError);
|
|
}
|
|
},
|
|
"-l" | "--len" => {
|
|
if i + 1 < n {
|
|
if let Ok(value) = args[i + 1].parse() {
|
|
len = value;
|
|
} else {
|
|
error!("Could not parse len");
|
|
return Err(ExitCode::Failure);
|
|
}
|
|
i += 1;
|
|
} else {
|
|
error!("Missing len");
|
|
return Err(ExitCode::UsageError);
|
|
}
|
|
},
|
|
_ => {},
|
|
}
|
|
i += 1;
|
|
}
|
|
|
|
beep(freq, len / 1000.0);
|
|
Ok(())
|
|
}
|
|
|
|
fn help() -> Result<(), ExitCode> {
|
|
let csi_option = Style::color("LightCyan");
|
|
let csi_title = Style::color("Yellow");
|
|
let csi_reset = Style::reset();
|
|
println!("{}Usage:{} beep {}<options>{1}", csi_title, csi_reset, csi_option);
|
|
println!();
|
|
println!("{}Options:{}", csi_title, csi_reset);
|
|
println!(" {0}-f{1}, {0}--freq <hertz>{1} Tone frequency", csi_option, csi_reset);
|
|
println!(" {0}-l{1}, {0}--len <milliseconds>{1} Tone length", csi_option, csi_reset);
|
|
Ok(())
|
|
}
|