spectrusty_peripherals/bus/
mouse.rs1use core::num::NonZeroU16;
10use core::fmt::{self, Debug};
11use core::marker::PhantomData;
12use core::ops::{Deref, DerefMut};
13
14#[cfg(feature = "snapshot")]
15use serde::{Serialize, Deserialize};
16
17use spectrusty_core::{
18 bus::{BusDevice, PortAddress}
19};
20
21use super::ay::PassByAyAudioBusDevice;
22
23pub use crate::mouse::{
24 MouseDevice, MouseInterface, NullMouseDevice,
25 kempston::*
26};
27
28pub type KempstonMouse<D> = MouseBusDevice<
30 KempstonMousePortAddress,
31 KempstonMouseDevice,
32 D>;
33
34impl<D> fmt::Display for KempstonMouse<D> {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 f.write_str("Kempston Mouse")
37 }
38}
39#[derive(Clone, Default, Debug)]
41#[cfg_attr(feature = "snapshot", derive(Serialize, Deserialize))]
42pub struct MouseBusDevice<P, M, D> {
43 #[cfg_attr(feature = "snapshot", serde(default))]
46 pub mouse: M,
47 #[cfg_attr(feature = "snapshot", serde(default))]
48 bus: D,
49 #[cfg_attr(feature = "snapshot", serde(skip))]
50 _port_decode: PhantomData<P>,
51}
52
53#[derive(Clone, Copy, Default, Debug)]
55pub struct KempstonMousePortAddress;
56impl PortAddress for KempstonMousePortAddress {
57 const ADDRESS_MASK: u16 = 0b0000_0000_0010_0000;
58 const ADDRESS_BITS: u16 = 0b1111_1010_1101_1111;
59}
60
61impl<P, M: MouseInterface, D> Deref for MouseBusDevice<P, M, D> {
62 type Target = M;
63 fn deref(&self) -> &Self::Target {
64 &self.mouse
65 }
66}
67
68impl<P, M: MouseInterface, D> DerefMut for MouseBusDevice<P, M, D> {
69 fn deref_mut(&mut self) -> &mut Self::Target {
70 &mut self.mouse
71 }
72}
73
74impl<P, M, D> PassByAyAudioBusDevice for MouseBusDevice<P, M, D> {}
75
76impl<P, M, D> BusDevice for MouseBusDevice<P, M, D>
77 where P: PortAddress,
78 D: BusDevice,
79 M: MouseDevice
80{
81 type Timestamp = D::Timestamp;
82 type NextDevice = D;
83
84 #[inline]
85 fn next_device_mut(&mut self) -> &mut Self::NextDevice {
86 &mut self.bus
87 }
88
89 #[inline]
90 fn next_device_ref(&self) -> &Self::NextDevice {
91 &self.bus
92 }
93
94 #[inline]
95 fn into_next_device(self) -> Self::NextDevice {
96 self.bus
97 }
98
99 #[inline]
100 fn read_io(&mut self, port: u16, timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
101 let bus_data = self.bus.read_io(port, timestamp);
102 if P::match_port(port) {
103 let mouse_data = self.mouse.port_read(port);
104 if let Some((data, ws)) = bus_data {
105 return Some((data & mouse_data, ws))
106 }
107 return Some((mouse_data, None))
108 }
109 bus_data
110 }
111
112 #[inline]
113 fn write_io(&mut self, port: u16, data: u8, timestamp: Self::Timestamp) -> Option<u16> {
114 if P::match_port(port) && self.mouse.port_write(port, data) {
115 return Some(0);
116 }
117 self.bus.write_io(port, data, timestamp)
118 }
119}