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

View File

@@ -2,3 +2,4 @@ pub mod cpu;
pub mod mmu;
pub mod ram;
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!()
}
}