[pcr] address checks in Program counter
This commit is contained in:
@@ -2,4 +2,4 @@ pub mod cpu;
|
||||
pub mod mmu;
|
||||
pub mod ram;
|
||||
pub mod iomem;
|
||||
mod program_counter;
|
||||
pub mod program_counter;
|
@@ -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());
|
||||
}
|
||||
}
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user