lc3_ensemble/sim/device/
keyboard.rs1use std::collections::VecDeque;
2use std::sync::{Arc, RwLock, RwLockWriteGuard, TryLockError};
3
4use super::{DevWrapper, ExternalDevice, Interrupt, KBDR, KBSR, KB_INTP, KB_INTV};
5
6trait KeyboardDevice: Send + Sync + 'static {
8 fn interrupts_enabled(&self) -> bool;
10 fn set_interrupts_enabled(&mut self, value: bool);
12
13 fn ready(&self) -> bool;
15 fn get_input(&self) -> Option<u8>;
17 fn pop_input(&mut self) -> Option<u8>;
19 fn clear_input(&mut self);
21}
22
23impl<K: KeyboardDevice> ExternalDevice for DevWrapper<K, dyn KeyboardDevice> {
24 fn io_read(&mut self, addr: u16, effectful: bool) -> Option<u16> {
25 match addr {
26 KBSR => {
27 Some((u16::from(self.ready()) << 15) | (u16::from(self.interrupts_enabled()) << 14))
28 },
29 KBDR if effectful => self.pop_input().map(u16::from),
30 KBDR => self.get_input().map(u16::from),
31 _ => None
32 }
33 }
34
35 fn io_write(&mut self, addr: u16, data: u16) -> bool {
36 match addr {
37 KBSR => {
38 let ie = (data >> 14) & 1 != 0;
39 self.set_interrupts_enabled(ie);
40 true
41 },
42 _ => false
43 }
44 }
45
46 fn io_reset(&mut self) {
47 self.clear_input();
48 self.set_interrupts_enabled(false);
49 }
50
51 fn poll_interrupt(&mut self) -> Option<Interrupt> {
52 match self.ready() && self.interrupts_enabled() {
53 true => Some(Interrupt::vectored(KB_INTV, KB_INTP)),
54 false => None,
55 }
56 }
57}
58
59#[derive(Default, Clone)]
61pub struct BufferedKeyboard {
62 buffer: Arc<RwLock<VecDeque<u8>>>,
63 interrupts_enabled: bool
64}
65impl BufferedKeyboard {
66 pub fn new(buffer: Arc<RwLock<VecDeque<u8>>>) -> Self {
68 Self { buffer, interrupts_enabled: false }
69 }
70
71 pub fn get_buffer(&self) -> &Arc<RwLock<VecDeque<u8>>> {
73 &self.buffer
74 }
75
76 fn try_input(&self) -> Option<RwLockWriteGuard<'_, VecDeque<u8>>> {
77 match self.buffer.try_write() {
78 Ok(g) => Some(g),
79 Err(TryLockError::Poisoned(e)) => Some(e.into_inner()),
80 Err(TryLockError::WouldBlock) => None,
81 }
82 }
83}
84impl KeyboardDevice for BufferedKeyboard {
85 fn interrupts_enabled(&self) -> bool {
86 self.interrupts_enabled
87 }
88
89 fn set_interrupts_enabled(&mut self, value: bool) {
90 self.interrupts_enabled = value;
91 }
92
93 fn ready(&self) -> bool {
94 self.try_input().is_some_and(|buf| !buf.is_empty())
95 }
96
97 fn get_input(&self) -> Option<u8> {
98 self.try_input()?.front().copied()
99 }
100
101 fn pop_input(&mut self) -> Option<u8> {
102 self.try_input()?.pop_front()
103 }
104
105 fn clear_input(&mut self) {
106 if let Some(mut inp) = self.try_input() {
107 inp.clear();
108 }
109 }
110}
111impl ExternalDevice for BufferedKeyboard {
112 fn io_read(&mut self, addr: u16, effectful: bool) -> Option<u16> {
113 DevWrapper::wrap(self).io_read(addr, effectful)
114 }
115
116 fn io_write(&mut self, addr: u16, data: u16) -> bool {
117 DevWrapper::wrap(self).io_write(addr, data)
118 }
119
120 fn io_reset(&mut self) {
121 DevWrapper::wrap(self).io_reset()
122 }
123
124 fn poll_interrupt(&mut self) -> Option<Interrupt> {
125 DevWrapper::wrap(self).poll_interrupt()
126 }
127
128 fn _to_sim_device(self, _: super::internals::ToSimDeviceToken) -> super::internals::SimDevice
129 where Self: Sized
130 {
131 super::internals::SimDevice::Keyboard(self)
132 }
133}