spectrusty_peripherals/joystick/
kempston.rs

1/*
2    Copyright (C) 2020-2022  Rafal Michalski
3
4    This file is part of SPECTRUSTY, a Rust library for building emulators.
5
6    For the full copyright notice, see the lib.rs file.
7*/
8//! Kempston Joystick implementation.
9use super::{JoystickDevice, Directions, JoystickInterface};
10                      // 000F_UDLR
11const FIRE_MASK:  u8 = 0b0001_0000;
12const RIGHT_MASK: u8 = 0b0000_0001;
13const LEFT_MASK:  u8 = 0b0000_0010;
14const DOWN_MASK:  u8 = 0b0000_0100;
15const UP_MASK:    u8 = 0b0000_1000;
16
17/// The Kempston Joystick device implements [JoystickDevice] and [JoystickInterface].
18#[derive(Clone, Copy, Default, Debug)]
19pub struct KempstonJoystickDevice {
20    data: u8,
21    directions: Directions
22}
23
24impl JoystickDevice for KempstonJoystickDevice {
25    #[inline]
26    fn port_read(&self, _port: u16) -> u8 {
27        self.data
28    }
29}
30
31impl JoystickInterface for KempstonJoystickDevice {
32    fn fire(&mut self, _btn: u8, pressed: bool) {
33        if pressed {
34            self.data |= FIRE_MASK;
35        }
36        else {
37            self.data &= !FIRE_MASK;
38        }
39    }
40
41    fn get_fire(&self, _btn: u8) -> bool {
42        self.data & FIRE_MASK == FIRE_MASK
43    }
44
45    fn set_directions(&mut self, dir: Directions) {
46        self.directions = dir;
47        self.data = (self.data & FIRE_MASK) | 
48            if dir.intersects(Directions::UP)    { UP_MASK    } else { 0 } |
49            if dir.intersects(Directions::RIGHT) { RIGHT_MASK } else { 0 } |
50            if dir.intersects(Directions::DOWN)  { DOWN_MASK  } else { 0 } |
51            if dir.intersects(Directions::LEFT)  { LEFT_MASK  } else { 0 };
52    }
53    fn get_directions(&self) -> Directions {
54        self.directions
55    }
56}