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
mod banked;
mod block;
mod branch;
mod logging;
mod mos6510;
/// The various interface adapters (6520, 6522, 6526) for the MOS 6502 CPU.
pub mod mos652x;
mod null;
mod ports;

pub use banked::BankedMemory;
pub use block::BlockMemory;
pub use branch::BranchMemory;
pub use logging::LoggingMemory;
pub use mos6510::Mos6510Port;
pub use null::NullMemory;
pub use ports::{NullPort, Port};

/// Represents the state of the interrupts on the system.
#[derive(Debug, PartialEq, Eq)]
pub enum ActiveInterrupt {
  /// No interrupts are active.
  None,
  /// An NMI (non-maskable interrupt) is active.
  NMI,
  /// An IRQ (maskable interrupt request) is active.
  IRQ,
}

/// Represents a contiguous block of memory which can be read, written,
/// reset, and polled to see if an interrupt has been triggered.
pub trait Memory {
  /// Read a byte from this memory at the given address.
  /// Implementations may trigger side effects as a result of this read.
  fn read(&mut self, address: u16) -> u8;

  /// Write a byte to this memory at the given address.
  fn write(&mut self, address: u16, value: u8);

  /// Reset this memory to its initial state, e.g. after a system reboot.
  /// Sometimes this will clear the contents of the memory, like with RAM.
  /// Other times this is a no-op, e.g. for ROM.
  fn reset(&mut self);

  /// Poll this memory to see if an interrupt has been triggered.
  /// Implementations may trigger an NMI or IRQ for any
  /// implementation-dependent reason.
  fn poll(&mut self, cycles_since_poll: u64, total_cycle_count: u64) -> ActiveInterrupt;
}