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