1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#![no_std]
#![feature(const_fn)]
use x86_64::instructions::port::Port;
const CHANNEL_TWO_DATA_PORT: u16 = 0x42;
const COMMAND_REGISTER: u16 = 0x43;
const SPEAKER_POSITIONS: u16 = 0x61;
pub struct Speaker {
channel_2_data_port: Port<u8>,
command_register: Port<u8>,
speaker_positions: Port<u8>,
}
impl Speaker {
pub const fn new() -> Speaker {
Speaker {
channel_2_data_port: Port::new(CHANNEL_TWO_DATA_PORT),
command_register: Port::new(COMMAND_REGISTER),
speaker_positions: Port::new(SPEAKER_POSITIONS),
}
}
fn play_sound(&mut self, n_frequency: u32) {
let div = 1193180 / n_frequency;
unsafe {
self.command_register.write(0xb6);
self.channel_2_data_port.write(div as u8);
self.channel_2_data_port.write((div >> 8) as u8);
}
let tmp = unsafe { self.speaker_positions.read() };
if tmp != (tmp | 3) {
unsafe { self.speaker_positions.write(tmp | 3) };
}
}
fn nosound(&mut self) {
let tmp = unsafe { self.speaker_positions.read() };
unsafe { self.speaker_positions.write(tmp & 0xFC) };
}
fn timer_wait(&mut self, n: u32) {
for _i in 0..10_000 * n {}
}
pub fn beep(&mut self, frequency: u32, duration: u32) {
self.play_sound(frequency);
self.timer_wait(duration);
self.nosound();
}
}