diff --git a/src/emu/mod.rs b/src/emu/mod.rs index 6c70821..65a67c0 100644 --- a/src/emu/mod.rs +++ b/src/emu/mod.rs @@ -2,4 +2,4 @@ pub mod cpu; pub mod mmu; pub mod ram; pub mod iomem; -mod program_counter; \ No newline at end of file +pub mod program_counter; \ No newline at end of file diff --git a/src/emu/program_counter.rs b/src/emu/program_counter.rs index 4af8327..cb58860 100644 --- a/src/emu/program_counter.rs +++ b/src/emu/program_counter.rs @@ -1,27 +1,37 @@ -use crate::emu::mmu::Memory; +use crate::emu::mmu::{Memory, RAM_MEM_END}; use crate::misc::emulator_error::DeviceType::PC; use crate::misc::emulator_error::EmulatorError; use crate::misc::endian::{read_big_endian_u24, write_big_endian_u24}; use crate::misc::result::EmulatorResult; -#[derive(Debug,Default, Copy, Clone)] +#[derive(Debug, Default, Copy, Clone)] pub struct ProgramCounter { /// 24bit location register program_counter_register: [u8; 3], } impl ProgramCounter { + pub fn new() -> ProgramCounter { + ProgramCounter { + program_counter_register: [0; 3] + } + } // get the current program counter as an address pub fn get_pc_value(&self) -> u32 { read_big_endian_u24(&self.program_counter_register) } // assign a value of PC to start execution - pub fn set_address(&mut self, address: u32) { + pub fn set_address(&mut self, address: u32) -> EmulatorResult<()> { log::debug!("Setting PC as {}",address); - write_big_endian_u24(address, &mut self.program_counter_register) + if address >= (2 << 24) { + return Err(EmulatorError::UnreachableMemory(PC, address)); + } + write_big_endian_u24(address, &mut self.program_counter_register); + Ok(()) } } + /// Allow Using Program counter as mapped memory impl Memory for ProgramCounter { fn try_get_byte(&self, address: u32) -> EmulatorResult { @@ -35,4 +45,27 @@ impl Memory for ProgramCounter { log::error!("Unsupported Method!"); todo!() } +} + + +#[cfg(test)] +mod test { + use crate::emu::program_counter::ProgramCounter; + + #[test] + pub fn setting_address_works() { + const ADDRESS: u32 = 4; + let mut pc = ProgramCounter::new(); + let res = pc.set_address(ADDRESS); + assert!(res.is_ok()); + assert_eq!(ADDRESS, pc.get_pc_value()); + } + + #[test] + pub fn set_invalid_addr_returns_error() { + const ADDRESS: u32 = 2 << 24; + let mut pc = ProgramCounter::new(); + let res = pc.set_address(ADDRESS); + assert!(res.is_err()); + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2d557e4..ccf087a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,8 @@ use simple_logger::SimpleLogger; use crate::emu::iomem::MemoryMappedIO; use crate::emu::ram::RamMemory; use crate::emu::mmu::{Memory, MappedMemory}; -use crate::misc::emulator_error::EmulatorError; +use crate::emu::program_counter::ProgramCounter; + use crate::misc::result::EmulatorResult; mod emu; @@ -12,8 +13,8 @@ mod graphics; fn main() -> EmulatorResult<()> { SimpleLogger::new().env().init().unwrap(); - - let mmio = MemoryMappedIO::new(); + let program_counter = ProgramCounter::new(); + let mmio = MemoryMappedIO::new(program_counter); let ram = RamMemory::try_new()?; let mmu = MappedMemory::new(mmio, ram); for i in 0..10 {