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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use bit_field::BitField;
pub type Observer = Box<Fn(u8)>;
pub struct IoPort {
direction: u8,
input: u8,
output: u8,
observer: Option<Observer>,
}
impl IoPort {
pub fn new(direction: u8, input: u8) -> IoPort {
IoPort {
direction,
input,
output: 0,
observer: None,
}
}
#[inline]
pub fn get_direction(&self) -> u8 {
self.direction
}
#[inline]
pub fn get_value(&self) -> u8 {
(self.output & self.direction) | (self.input & !self.direction)
}
#[inline]
pub fn set_direction(&mut self, direction: u8) {
self.direction = direction;
self.notify_observer();
}
#[inline]
pub fn set_input(&mut self, value: u8) {
self.input = value;
self.notify_observer();
}
#[inline]
pub fn set_input_bit(&mut self, bit: usize, value: bool) {
self.input.set_bit(bit, value);
self.notify_observer();
}
#[inline]
pub fn set_observer(&mut self, observer: Observer) {
self.observer = Some(observer);
}
#[inline]
pub fn set_value(&mut self, value: u8) {
self.output = value;
self.notify_observer();
}
#[inline]
pub fn reset(&mut self) {
self.direction = 0x00;
self.input = 0xff;
self.output = 0x00;
self.notify_observer();
}
#[inline]
fn notify_observer(&self) {
if let Some(ref observer) = self.observer {
observer(self.get_value());
}
}
}