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
//! Definitions for components that can preform memory read or write operations
//! from an memory address.

/// A component that can either read or write a byte from a memory address.
pub trait MemoryAccessByte<T> {
    /// Returns a byte from the memory address.
    fn read_byte(addr: u32, state: &T) -> u8;
    /// Writes a byte to the memory address.
    fn write_byte(addr: u32, data: u8, state: &mut T);
}

/// A component that can either read or write a halfword from a memory address.
pub trait MemoryAccessHalfword<T> {
    /// Returns a halfword from the memory address.
    fn read_halfword(addr: u32, state: &T) -> u16;
    /// Writes a halfword to the memory address.
    fn write_halfword(addr: u32, data: u16, state: &mut T);
}

/// A component that can either read or write a word from a memory address.
pub trait MemoryAccessWord<T> {
    /// Returns a word from the memory address.
    fn read_word(addr: u32, state: &T) -> u32;
    /// Writes a word to the memory address.
    fn write_word(addr: u32, data: u32, state: &mut T);
}

/// Writes a halfword to the memory array at the specified offset in little
/// endian order.
pub fn write_little_endian_halfword(mem: &mut [u8], offset: usize, data: u16) {
    let byte_0 = (data & 0xFF) as u8;
    let byte_1 = ((data >> 8) & 0xFF) as u8;

    mem[offset] = byte_0;
    mem[offset + 1] = byte_1;
}

/// Writes a word to the memory array at the specified offset in little endian
/// order.
pub fn write_little_endian_word(mem: &mut [u8], offset: usize, data: u32) {
    let byte_0 = (data & 0xFF) as u8;
    let byte_1 = ((data >> 8) & 0xFF) as u8;
    let byte_2 = ((data >> 16) & 0xFF) as u8;
    let byte_3 = ((data >> 24) & 0xFF) as u8;

    mem[offset] = byte_0;
    mem[offset + 1] = byte_1;
    mem[offset + 2] = byte_2;
    mem[offset + 3] = byte_3;
}