[pcr] address checks in Program counter

This commit is contained in:
2024-02-18 09:57:10 +05:30
parent 2f0228eccb
commit 8df1da1d17
3 changed files with 42 additions and 8 deletions

View File

@@ -2,4 +2,4 @@ pub mod cpu;
pub mod mmu;
pub mod ram;
pub mod iomem;
mod program_counter;
pub mod program_counter;

View File

@@ -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<u8> {
@@ -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());
}
}

View File

@@ -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 {