[pcr] Implement PC

This commit is contained in:
2024-02-18 09:46:10 +05:30
parent 0221eeedaf
commit 3ccd2006af
3 changed files with 47 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
use crate::emu::mmu::Memory; use crate::emu::mmu::Memory;
use crate::emu::program_counter::ProgramCounter;
use crate::misc::emulator_error::EmulatorError; use crate::misc::emulator_error::EmulatorError;
use crate::misc::endian::{read_big_endian_u16, read_big_endian_u24}; use crate::misc::endian::{read_big_endian_u16, read_big_endian_u24};
use crate::misc::result::EmulatorResult; use crate::misc::result::EmulatorResult;
@@ -7,13 +8,13 @@ use crate::misc::result::EmulatorResult;
pub struct MemoryMappedIO { pub struct MemoryMappedIO {
//FIXME use a keyboard //FIXME use a keyboard
keyboard_bytes: [u8; 2], keyboard_bytes: [u8; 2],
program_counter: [u8; 3], program_counter: ProgramCounter,
//FIXME use a device //FIXME use a device
pixel_reg: u8, pixel_reg: u8,
//FIXME use a device //FIXME use a device
audio_sample_address_base: [u8; 2], audio_sample_address_base: [u8; 2],
} }
/// Represents the memory mapped segment of IO. Aggregates the mapping logic.
impl MemoryMappedIO { impl MemoryMappedIO {
// 2 byte keyboard bits // 2 byte keyboard bits
pub const KEYBOARD_BIT_START: u32 = 0; pub const KEYBOARD_BIT_START: u32 = 0;
@@ -32,10 +33,10 @@ impl MemoryMappedIO {
pub const AUDIO_SAMPLE_BASE_LEN: u32 = 2; pub const AUDIO_SAMPLE_BASE_LEN: u32 = 2;
const AUDIO_SAMPLE_BASE_END: u32 = Self::AUDIO_SAMPLE_BASE_START + Self::AUDIO_SAMPLE_BASE_LEN - 1; const AUDIO_SAMPLE_BASE_END: u32 = Self::AUDIO_SAMPLE_BASE_START + Self::AUDIO_SAMPLE_BASE_LEN - 1;
pub fn new() -> MemoryMappedIO { pub fn new(program_counter: ProgramCounter) -> MemoryMappedIO {
MemoryMappedIO { MemoryMappedIO {
keyboard_bytes: [0, 0], keyboard_bytes: [0, 0],
program_counter: [0, 0, 0], program_counter,
pixel_reg: 0, pixel_reg: 0,
audio_sample_address_base: [0, 0], audio_sample_address_base: [0, 0],
} }
@@ -53,10 +54,8 @@ impl Memory for MemoryMappedIO {
keyboard_byte keyboard_byte
} }
Self::PC_START_ADDR..=Self::PC_END_ADDR => { Self::PC_START_ADDR..=Self::PC_END_ADDR => {
let pc_index = (address - Self::PC_START_ADDR) as usize; let pc_index = address - Self::PC_START_ADDR;
let pc_byte = self.program_counter[pc_index]; self.program_counter.try_get_byte(pc_index)?
log::trace!("Fetching PC({}) byte segment {} -> {}",read_big_endian_u24(&self.program_counter),pc_index,pc_byte);
pc_byte
} }
Self::PIXEL_BASE => { Self::PIXEL_BASE => {
log::trace!("Fetching pixel base reg {}",self.pixel_reg); log::trace!("Fetching pixel base reg {}",self.pixel_reg);

View File

@@ -2,3 +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;

View File

@@ -0,0 +1,38 @@
use crate::emu::mmu::Memory;
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)]
pub struct ProgramCounter {
/// 24bit location register
program_counter_register: [u8; 3],
}
impl ProgramCounter {
// 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) {
log::debug!("Setting PC as {}",address);
write_big_endian_u24(address, &mut self.program_counter_register)
}
}
/// Allow Using Program counter as mapped memory
impl Memory for ProgramCounter {
fn try_get_byte(&self, address: u32) -> EmulatorResult<u8> {
log::trace!("Fetching PC({}) byte segment index {}",read_big_endian_u24(&self.program_counter_register),address);
self.program_counter_register.get(address as usize)
.map(|e| *e)
.ok_or(EmulatorError::UnreachableMemory(PC, address))
}
/// TODO: Set a byte of PC from the memory.
fn try_set_byte(&mut self, address: u32, value: u8) -> EmulatorResult<()> {
log::error!("Unsupported Method!");
todo!()
}
}