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
//! The input module handles, as the name suggests, input devices //! for the NES. There are a number of redundancies in this module //! that are a remnant of an old input system but I haven't gotten //! around to reworking it. /// Enum for representing a NES input port #[derive(Debug)] pub(crate) enum NesInput { /// State representing no connected controller Disconnected, /// State wrapping a controller implementation Connected(NesInputDevice), } impl NesInput { /// The lower three bits of the data byte will be held and control input device behaviour. /// On a standard NES controller, this will load the shift registers so that they can be polled pub(crate) fn latch(&mut self, latch: u8) { if let NesInput::Connected(input_device) = self { input_device.latch(latch) } } /// Polls a single bit from the controller. /// On a standard NES controller, this will return the next bit in the controller's shift register. /// /// The bus parameter is used for simulating open bus behaviour. It should be ORed with the three /// bits that were polled. pub(crate) fn poll(&mut self, bus: u8) -> u8 { match self { NesInput::Disconnected => bus & 0xf4, NesInput::Connected(controller) => controller.poll(bus), } } } #[derive(Debug)] pub(crate) struct NesInputDevice { /// Shift register that stores the button information shift_register: u8, /// Controller latch that reloads shift register when true reload_latch: bool, /// Stores the actual state of the controller input_state: u8, } impl NesInputDevice { /// Creates a new instance of a NesInputDevice with the starting input state pub(crate) fn new(input_state: u8) -> Self { NesInputDevice { shift_register: 0x00, reload_latch: false, input_state, } } /// Updates the internal state of the device pub(crate) fn update_state(&mut self, input_state: u8) { self.input_state = input_state; } /// The lower three bits of the data byte will be held and control input device behaviour. /// On a standard NES controller, this will load the shift registers so that they can be polled fn latch(&mut self, latch: u8) { self.reload_latch = latch & 0x01 == 0x01; self.reload_shift_register() } /// Polls a single bit from the controller. /// On a standard NES controller, this will return the next bit in the controller's shift register. /// /// The bus parameter is used for simulating open bus behaviour. It should be ORed with the three /// bits that were polled. fn poll(&mut self, bus: u8) -> u8 { self.reload_shift_register(); // Select only the last bit of the let result = self.shift_register & 0x01; // Get the next bit in the shift register self.shift_register >>= 1; // Set the new bit to 1, which is returned after 8 polls on official NES controllers self.shift_register |= 0x80; // Return the result bit with the top 5 bits as the previous byte on the bus return result | (bus & 0xf8); } /// Reloads the shift register to the input state fn reload_shift_register(&mut self) { if self.reload_latch { self.shift_register = self.input_state; } } }