1use bincode::{Decode, Encode}; 2 3#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)] 4pub enum MemoryCycle { 5 N, // Non-sequential 6 S, // Sequential 7} 8 9pub struct OpSize; 10 11impl OpSize { 12 pub const BYTE: u8 = 0; 13 pub const HALFWORD: u8 = 1; 14 pub const WORD: u8 = 2; 15 16 #[must_use] 17 pub const fn display(size: u8) -> &'static str { 18 match size { 19 Self::BYTE => "Byte", 20 Self::HALFWORD => "Halfword", 21 Self::WORD => "Word", 22 _ => "(invalid)", 23 } 24 } 25} 26 27pub trait BusInterface {
8-bit / 16-bit / 32-bit read instruction
29 fn read<const SIZE: u8>(&mut self, address: u32, cycle: MemoryCycle) -> u32;
16-bit (Thumb) / 32-bit (ARM) opcode fetch Implementations can override this to adjust behavior based on PC location or whether a read is for instruction fetch
8-bit / 16-bit / 32-bit write instruction
39 fn write<const SIZE: u8>(&mut self, address: u32, value: u32, cycle: MemoryCycle);
8-bit read instruction
16-bit read instruction
32-bit read instruction
Opcode fetch in Thumb mode Implementations can override this to adjust behavior based on PC location
Opcode fetch in ARM mode Implementations can override this to adjust behavior based on PC location
8-bit write instruction
16-bit write instruction
32-bit write instruction
IRQ line
84 fn irq(&self) -> bool;
Called when instructions have internal cycles
87 fn internal_cycles(&mut self, cycles: u32);
Lock the bus (used by SWAP instruction)
90 fn lock(&mut self) {}