use bitflags::bitflags;
use core::mem::size_of;
use static_assertions::const_assert;
use volatile_register::RW;
#[repr(C, packed)]
pub struct TimeOfDay {
pub deci_seconds: RW<u8>, pub seconds: RW<u8>, pub minutes: RW<u8>, pub hours: RW<u8>, }
const_assert!(size_of::<TimeOfDay>() == 4);
#[repr(C, packed)]
pub struct MOSComplexInterfaceAdapter6526 {
pub port_a: RW<GameController>, pub port_b: RW<GameController>, pub data_direction_port_a: RW<u8>, pub data_direction_port_b: RW<u8>, pub timer_a: RW<u16>, pub timer_b: RW<u16>, pub time_of_day: TimeOfDay, pub serial_shift: RW<u8>, pub interrupt: RW<u8>, pub control_a: RW<u8>, pub control_b: RW<u8>, }
const_assert!(size_of::<MOSComplexInterfaceAdapter6526>() == 16);
pub enum JoystickPosition {
Up,
Down,
Left,
Right,
UpLeft,
DownLeft,
UpRight,
DownRight,
Middle,
}
impl JoystickPosition {
pub const fn new(value: GameController) -> JoystickPosition {
let complement = value.complement(); if complement.contains(GameController::UP_LEFT) {
JoystickPosition::UpLeft
} else if complement.contains(GameController::UP_RIGHT) {
JoystickPosition::UpRight
} else if complement.contains(GameController::DOWN_LEFT) {
JoystickPosition::DownLeft
} else if complement.contains(GameController::DOWN_RIGHT) {
JoystickPosition::DownRight
} else if complement.contains(GameController::UP) {
JoystickPosition::Up
} else if complement.contains(GameController::DOWN) {
JoystickPosition::Down
} else if complement.contains(GameController::LEFT) {
JoystickPosition::Left
} else if complement.contains(GameController::RIGHT) {
JoystickPosition::Right
} else {
JoystickPosition::Middle
}
}
}
bitflags! {
pub struct GameController: u8 {
const UP = 0b0000_0001; const DOWN = 0b0000_0010; const LEFT = 0b0000_0100; const RIGHT = 0b0000_1000; const FIRE = 0b0001_0000;
const UP_FIRE = Self::UP.bits | Self::FIRE.bits;
const DOWN_FIRE = Self::DOWN.bits | Self::FIRE.bits;
const LEFT_FIRE = Self::LEFT.bits | Self::FIRE.bits;
const RIGHT_FIRE = Self::RIGHT.bits | Self::FIRE.bits;
const UP_LEFT = Self::UP.bits | Self::LEFT.bits;
const UP_RIGHT = Self::UP.bits | Self::RIGHT.bits;
const DOWN_LEFT = Self::DOWN.bits | Self::LEFT.bits;
const DOWN_RIGHT = Self::DOWN.bits | Self::RIGHT.bits;
const UP_LEFT_FIRE = Self::UP.bits | Self::LEFT.bits | Self::FIRE.bits;
const UP_RIGHT_FIRE = Self::UP.bits | Self::RIGHT.bits | Self::FIRE.bits;
const DOWN_LEFT_FIRE = Self::DOWN.bits | Self::LEFT.bits | Self::FIRE.bits;
const DOWN_RIGHT_FIRE = Self::DOWN.bits | Self::RIGHT.bits | Self::FIRE.bits;
}
}
impl GameController {
pub const fn read_joystick(&self) -> (JoystickPosition, bool) {
let position = JoystickPosition::new(*self);
let fire = self.complement().contains(Self::FIRE);
(position, fire)
}
}