Skip to content

Commit

Permalink
Merge pull request #2 from yezzfusl/test
Browse files Browse the repository at this point in the history
Implement memory management unit for allocation and access.
  • Loading branch information
yezzfusl authored Aug 6, 2024
2 parents d704ae2 + 945bf1e commit cd857c7
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 4 deletions.
38 changes: 34 additions & 4 deletions src/cpu.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// src/cpu.rs

use std::collections::HashMap;
mod memory;
use memory::MemoryManagementUnit;

pub struct CPU {
registers: [u32; 8],
program_counter: usize,
memory: [u8; 4096],
mmu: MemoryManagementUnit,
instruction_set: HashMap<u8, fn(&mut CPU, u8, u8, u8)>,
}

Expand All @@ -12,7 +16,7 @@ impl CPU {
let mut cpu = CPU {
registers: [0; 8],
program_counter: 0,
memory: [0; 4096],
mmu: MemoryManagementUnit::new(),
instruction_set: HashMap::new(),
};
cpu.initialize_instruction_set();
Expand All @@ -24,6 +28,8 @@ impl CPU {
self.instruction_set.insert(0x01, CPU::sub);
self.instruction_set.insert(0x02, CPU::mul);
self.instruction_set.insert(0x03, CPU::div);
self.instruction_set.insert(0x04, CPU::load);
self.instruction_set.insert(0x05, CPU::store);
}

pub fn run(&mut self) {
Expand All @@ -34,7 +40,7 @@ impl CPU {
}

fn fetch(&mut self) -> u8 {
let instruction = self.memory[self.program_counter];
let instruction = self.mmu.read_byte(self.program_counter);
self.program_counter += 1;
instruction
}
Expand Down Expand Up @@ -75,6 +81,16 @@ impl CPU {
panic!("Division by zero");
}
}

fn load(&mut self, r1: u8, r2: u8, _r3: u8) {
let address = self.registers[r2 as usize] as usize;
self.registers[r1 as usize] = self.mmu.read_word(address);
}

fn store(&mut self, r1: u8, r2: u8, _r3: u8) {
let address = self.registers[r2 as usize] as usize;
self.mmu.write_word(address, self.registers[r1 as usize]);
}
}

#[cfg(test)]
Expand Down Expand Up @@ -125,5 +141,19 @@ mod tests {
cpu.registers[1] = 0;
cpu.div(0, 1, 0);
}
}

#[test]
fn test_load_and_store_instructions() {
let mut cpu = CPU::new();
cpu.registers[0] = 42;
cpu.registers[1] = 100; // memory address

// Store value 42 at memory address 100
cpu.store(0, 1, 0);

// Load value from memory address 100 into register 2
cpu.load(2, 1, 0);

assert_eq!(cpu.registers[2], 42);
}
}
61 changes: 61 additions & 0 deletions src/memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// src/memory.rs

pub struct MemoryManagementUnit {
memory: Vec<u8>,
}

impl MemoryManagementUnit {
pub fn new() -> Self {
MemoryManagementUnit {
memory: vec![0; 65536], // 64KB of memory
}
}

pub fn read_byte(&self, address: usize) -> u8 {
self.memory[address]
}

pub fn write_byte(&mut self, address: usize, value: u8) {
self.memory[address] = value;
}

pub fn read_word(&self, address: usize) -> u32 {
let bytes = &self.memory[address..address + 4];
u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
}

pub fn write_word(&mut self, address: usize, value: u32) {
let bytes = value.to_le_bytes();
self.memory[address..address + 4].copy_from_slice(&bytes);
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_read_write_byte() {
let mut mmu = MemoryManagementUnit::new();
mmu.write_byte(0, 42);
assert_eq!(mmu.read_byte(0), 42);
}

#[test]
fn test_read_write_word() {
let mut mmu = MemoryManagementUnit::new();
mmu.write_word(0, 0x12345678);
assert_eq!(mmu.read_word(0), 0x12345678);
}

#[test]
fn test_memory_persistence() {
let mut mmu = MemoryManagementUnit::new();
mmu.write_byte(100, 1);
mmu.write_byte(101, 2);
mmu.write_byte(102, 3);
mmu.write_byte(103, 4);

assert_eq!(mmu.read_word(100), 0x04030201);
}
}

0 comments on commit cd857c7

Please sign in to comment.