[pcr] Implement PC
This commit is contained in:
@@ -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);
|
||||||
|
@@ -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;
|
38
src/emu/program_counter.rs
Normal file
38
src/emu/program_counter.rs
Normal 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!()
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user