1use core::num::NonZeroU16;
10use core::fmt::{self, Debug};
11use core::any::TypeId;
12use core::marker::PhantomData;
13use core::ops::{Deref, DerefMut};
14
15#[cfg(feature = "snapshot")]
16use serde::{Serialize, Deserialize};
17
18mod dynbus;
19
20use crate::clock::VFrameTs;
21
22pub use dynbus::*;
23
24impl<T: 'static> dyn NamedBusDevice<T> {
25 #[inline]
27 pub fn downcast<D: 'static>(self: Box<Self>) -> Result<Box<D>, Box<dyn NamedBusDevice<T>>>
28 where D: NamedBusDevice<T>
29 {
30 if self.is::<D>() {
31 unsafe {
32 let raw: *mut dyn NamedBusDevice<T> = Box::into_raw(self);
33 Ok(Box::from_raw(raw as *mut D))
34 }
35 } else {
36 Err(self)
37 }
38 }
39}
40
41impl<T: 'static> dyn NamedBusDevice<T> + 'static {
42 #[inline]
44 pub fn is<D: NamedBusDevice<T> + 'static>(&self) -> bool {
45 TypeId::of::<D>() == self.type_id()
46 }
47 pub fn downcast_ref<D: NamedBusDevice<T> + 'static>(&self) -> Option<&D> {
50 if self.is::<D>() {
51 unsafe {
52 Some(&*(self as *const dyn NamedBusDevice<T> as *const D))
53 }
54 } else {
55 None
56 }
57 }
58 pub fn downcast_mut<D: NamedBusDevice<T> + 'static>(&mut self) -> Option<&mut D> {
61 if self.is::<D>() {
62 unsafe {
63 Some(&mut *(self as *mut dyn NamedBusDevice<T> as *mut D))
64 }
65 } else {
66 None
67 }
68 }
69}
70
71pub trait BusDevice: Debug {
80 type Timestamp: Sized;
82 type NextDevice: BusDevice<Timestamp=Self::Timestamp>;
84
85 fn next_device_mut(&mut self) -> &mut Self::NextDevice;
87 fn next_device_ref(&self) -> &Self::NextDevice;
89 fn into_next_device(self) -> Self::NextDevice;
91 #[inline(always)]
100 fn reset(&mut self, timestamp: Self::Timestamp) {
101 self.next_device_mut().reset(timestamp)
102 }
103 #[inline(always)]
112 fn update_timestamp(&mut self, timestamp: Self::Timestamp) {
113 self.next_device_mut().update_timestamp(timestamp)
114 }
115 #[inline(always)]
129 fn next_frame(&mut self, eof_timestamp: Self::Timestamp) {
130 self.next_device_mut().next_frame(eof_timestamp)
131 }
132 #[inline(always)]
143 fn read_io(&mut self, port: u16, timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
144 self.next_device_mut().read_io(port, timestamp)
145 }
146 #[inline(always)]
157 fn write_io(&mut self, port: u16, data: u8, timestamp: Self::Timestamp) -> Option<u16> {
158 self.next_device_mut().write_io(port, data, timestamp)
159 }
160 fn type_id(&self) -> TypeId where Self: 'static {
168 TypeId::of::<Self>()
169 }
170}
171
172impl<D: BusDevice> BusDevice for Box<D> {
173 type Timestamp = D::Timestamp;
174 type NextDevice = D::NextDevice;
175
176 #[inline(always)]
177 fn next_device_mut(&mut self) -> &mut Self::NextDevice {
178 (**self).next_device_mut()
179 }
180 #[inline(always)]
181 fn next_device_ref(&self) -> &Self::NextDevice {
182 (**self).next_device_ref()
183 }
184 #[inline]
185 fn into_next_device(self) -> Self::NextDevice {
186 (*self).into_next_device()
187 }
188 #[inline]
189 fn reset(&mut self, timestamp: Self::Timestamp) {
190 (**self).reset(timestamp)
191 }
192 #[inline]
193 fn update_timestamp(&mut self, timestamp: Self::Timestamp) {
194 (**self).update_timestamp(timestamp)
195 }
196 #[inline]
197 fn next_frame(&mut self, eof_timestamp: Self::Timestamp) {
198 (**self).next_frame(eof_timestamp)
199 }
200 #[inline]
201 fn read_io(&mut self, port: u16, timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
202 (**self).read_io(port, timestamp)
203 }
204 #[inline]
205 fn write_io(&mut self, port: u16, data: u8, timestamp: Self::Timestamp) -> Option<u16> {
206 (**self).write_io(port, data, timestamp)
207 }
208}
209
210pub trait PortAddress: Debug {
212 const ADDRESS_MASK: u16;
214 const ADDRESS_BITS: u16;
216 #[inline]
218 fn match_port(address: u16) -> bool {
219 address & Self::ADDRESS_MASK == Self::ADDRESS_BITS & Self::ADDRESS_MASK
220 }
221}
222
223#[derive(Clone, PartialEq, Eq)]
227#[cfg_attr(feature = "snapshot", derive(Serialize, Deserialize))]
228pub struct NullDevice<T>(PhantomData<T>);
229
230pub type VFNullDevice<V> = NullDevice<VFrameTs<V>>;
231
232impl<T> Default for NullDevice<T> {
233 #[inline(always)]
234 fn default() -> Self {
235 NullDevice(PhantomData)
236 }
237}
238
239impl<T> BusDevice for NullDevice<T> {
240 type Timestamp = T;
241 type NextDevice = Self;
242
243 #[inline(always)]
244 fn next_device_mut(&mut self) -> &mut Self::NextDevice {
245 self
246 }
247 #[inline(always)]
248 fn next_device_ref(&self) -> &Self::NextDevice {
249 self
250 }
251 #[inline(always)]
252 fn into_next_device(self) -> Self::NextDevice {
253 self
254 }
255 #[inline(always)]
256 fn reset(&mut self, _timestamp: Self::Timestamp) {}
257
258 #[inline(always)]
259 fn update_timestamp(&mut self, _timestamp: Self::Timestamp) {}
260
261 #[inline(always)]
262 fn next_frame(&mut self, _timestamp: Self::Timestamp) {}
263
264 #[inline(always)]
265 fn read_io(&mut self, _port: u16, _timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
266 None
267 }
268
269 #[inline(always)]
270 fn write_io(&mut self, _port: u16, _data: u8, _timestamp: Self::Timestamp) -> Option<u16> {
271 None
272 }
273}
274
275impl<T> fmt::Debug for NullDevice<T> {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 f.debug_struct("NullDevice").finish()
278 }
279}
280
281impl<T> fmt::Display for NullDevice<T> {
282 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
283 Ok(())
284 }
285}
286
287#[derive(Clone, Default, Debug)]
289#[cfg_attr(feature = "snapshot", derive(Serialize, Deserialize))]
290#[cfg_attr(feature = "snapshot", serde(rename_all = "camelCase"))]
291pub struct OptionalBusDevice<D, N> {
292 #[cfg_attr(feature = "snapshot", serde(default))]
294 pub device: Option<D>,
295 #[cfg_attr(feature = "snapshot", serde(default))]
297 pub next_device: N
298}
299
300impl<D, N> OptionalBusDevice<D, N>
301 where D: BusDevice, N: BusDevice
302{
303 pub fn new(device: Option<D>, next_device: N) -> Self {
304 OptionalBusDevice { device, next_device }
305 }
306}
307
308impl<D, N> Deref for OptionalBusDevice<D, N> {
309 type Target = Option<D>;
310 fn deref(&self) -> &Self::Target {
311 &self.device
312 }
313}
314
315impl<D, N> DerefMut for OptionalBusDevice<D, N> {
316 fn deref_mut(&mut self) -> &mut Self::Target {
317 &mut self.device
318 }
319}
320
321impl<D, N> BusDevice for OptionalBusDevice<D, N>
322 where D: BusDevice,
323 N: BusDevice<Timestamp=D::Timestamp>,
324 D::Timestamp: Copy
325{
326 type Timestamp = D::Timestamp;
327 type NextDevice = N;
328
329 #[inline]
330 fn next_device_mut(&mut self) -> &mut Self::NextDevice {
331 &mut self.next_device
332 }
333 #[inline]
334 fn next_device_ref(&self) -> &Self::NextDevice {
335 &self.next_device
336 }
337 #[inline]
338 fn into_next_device(self) -> Self::NextDevice {
339 self.next_device
340 }
341 #[inline]
342 fn reset(&mut self, timestamp: Self::Timestamp) {
343 if let Some(device) = &mut self.device {
344 device.reset(timestamp);
345 }
346 self.next_device.reset(timestamp);
347 }
348 #[inline]
349 fn update_timestamp(&mut self, timestamp: Self::Timestamp) {
350 if let Some(device) = &mut self.device {
351 device.update_timestamp(timestamp);
352 }
353 self.next_device.update_timestamp(timestamp);
354 }
355 #[inline]
356 fn next_frame(&mut self, timestamp: Self::Timestamp) {
357 if let Some(device) = &mut self.device {
358 device.next_frame(timestamp);
359 }
360 self.next_device.next_frame(timestamp);
361 }
362 #[inline]
363 fn read_io(&mut self, port: u16, timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
364 let dev_data = if let Some((data, ws)) = self.device
365 .as_mut()
366 .and_then(|dev| dev.read_io(port, timestamp)) {
367 if ws.is_some() {
368 return Some((data, ws))
370 }
371 Some(data)
372 }
373 else {
374 None
375 };
376 if let Some((bus_data, ws)) = self.next_device.read_io(port, timestamp) {
377 let data = bus_data & dev_data.unwrap_or(!0);
378 return Some((data, ws))
379 }
380 dev_data.map(|data| (data, None))
381 }
382
383 #[inline]
384 fn write_io(&mut self, port: u16, data: u8, timestamp: Self::Timestamp) -> Option<u16> {
385 if let Some(device) = &mut self.device {
386 if let Some(ws) = device.write_io(port, data, timestamp) {
387 return Some(ws)
388 }
389 }
390 self.next_device.write_io(port, data, timestamp)
391 }
392}
393
394impl<D, N> fmt::Display for OptionalBusDevice<D, N>
395 where D: fmt::Display
396{
397 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
398 if let Some(ref device) = self.device {
399 device.fmt(f)
400 }
401 else {
402 Ok(())
403 }
404 }
405}