[pcr] address checks in Program counter
This commit is contained in:
@@ -2,4 +2,4 @@ pub mod cpu;
|
|||||||
pub mod mmu;
|
pub mod mmu;
|
||||||
pub mod ram;
|
pub mod ram;
|
||||||
pub mod iomem;
|
pub mod iomem;
|
||||||
mod program_counter;
|
pub mod program_counter;
|
@@ -1,4 +1,4 @@
|
|||||||
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::DeviceType::PC;
|
||||||
use crate::misc::emulator_error::EmulatorError;
|
use crate::misc::emulator_error::EmulatorError;
|
||||||
use crate::misc::endian::{read_big_endian_u24, write_big_endian_u24};
|
use crate::misc::endian::{read_big_endian_u24, write_big_endian_u24};
|
||||||
@@ -12,16 +12,26 @@ pub struct ProgramCounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProgramCounter {
|
impl ProgramCounter {
|
||||||
|
pub fn new() -> ProgramCounter {
|
||||||
|
ProgramCounter {
|
||||||
|
program_counter_register: [0; 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
// get the current program counter as an address
|
// get the current program counter as an address
|
||||||
pub fn get_pc_value(&self) -> u32 {
|
pub fn get_pc_value(&self) -> u32 {
|
||||||
read_big_endian_u24(&self.program_counter_register)
|
read_big_endian_u24(&self.program_counter_register)
|
||||||
}
|
}
|
||||||
// assign a value of PC to start execution
|
// 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);
|
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
|
/// Allow Using Program counter as mapped memory
|
||||||
impl Memory for ProgramCounter {
|
impl Memory for ProgramCounter {
|
||||||
fn try_get_byte(&self, address: u32) -> EmulatorResult<u8> {
|
fn try_get_byte(&self, address: u32) -> EmulatorResult<u8> {
|
||||||
@@ -36,3 +46,26 @@ impl Memory for ProgramCounter {
|
|||||||
todo!()
|
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::iomem::MemoryMappedIO;
|
||||||
use crate::emu::ram::RamMemory;
|
use crate::emu::ram::RamMemory;
|
||||||
use crate::emu::mmu::{Memory, MappedMemory};
|
use crate::emu::mmu::{Memory, MappedMemory};
|
||||||
use crate::misc::emulator_error::EmulatorError;
|
use crate::emu::program_counter::ProgramCounter;
|
||||||
|
|
||||||
use crate::misc::result::EmulatorResult;
|
use crate::misc::result::EmulatorResult;
|
||||||
|
|
||||||
mod emu;
|
mod emu;
|
||||||
@@ -12,8 +13,8 @@ mod graphics;
|
|||||||
|
|
||||||
fn main() -> EmulatorResult<()> {
|
fn main() -> EmulatorResult<()> {
|
||||||
SimpleLogger::new().env().init().unwrap();
|
SimpleLogger::new().env().init().unwrap();
|
||||||
|
let program_counter = ProgramCounter::new();
|
||||||
let mmio = MemoryMappedIO::new();
|
let mmio = MemoryMappedIO::new(program_counter);
|
||||||
let ram = RamMemory::try_new()?;
|
let ram = RamMemory::try_new()?;
|
||||||
let mmu = MappedMemory::new(mmio, ram);
|
let mmu = MappedMemory::new(mmio, ram);
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
|
Reference in New Issue
Block a user