[ref] format and use methods to get references

Plus, add setting keyboard support
This commit is contained in:
2024-02-19 14:25:57 +05:30
parent a6c95eccaf
commit 09dc9bd473
6 changed files with 86 additions and 77 deletions

View File

@@ -6,13 +6,13 @@ use crate::misc::result::EmulatorResult;
#[derive(Debug)] #[derive(Debug)]
pub enum CpuState { pub enum CpuState {
Running, Running,
Paused Paused,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Cpu<'a> { pub struct Cpu<'a> {
pub memory: &'a RamMemory, memory: &'a RamMemory,
pub graphics_processor: &'a GraphicsProcessor<'a> graphics_processor: &'a GraphicsProcessor<'a>,
} }
impl<'a> Cpu<'a> { impl<'a> Cpu<'a> {
@@ -22,16 +22,16 @@ impl <'a> Cpu<'a>{
pub fn new(memory: &'a RamMemory, graphics_processor: &'a GraphicsProcessor<'a>) -> Cpu<'a> { pub fn new(memory: &'a RamMemory, graphics_processor: &'a GraphicsProcessor<'a>) -> Cpu<'a> {
Cpu { Cpu {
graphics_processor, graphics_processor,
memory memory,
} }
} }
pub fn get_pc(&self) -> u32 { pub fn get_pc(&self) -> u32 {
let memory_slice = self.memory.data.borrow(); let memory_slice = self.memory.get_data_ref();
let data = memory_slice.get(Self::PC_START..(Self::PC_START + Self::PC_LEN)).unwrap(); let data = memory_slice.get(Self::PC_START..(Self::PC_START + Self::PC_LEN)).unwrap();
read_big_endian_u24(data.try_into().unwrap()) read_big_endian_u24(data.try_into().unwrap())
} }
pub fn set_pc(&self, address: u32) { pub fn set_pc(&self, address: u32) {
let mut memory_slice = self.memory.data.borrow_mut(); let mut memory_slice = self.memory.get_data_ref_mut();
let mut pc_big_endian_slice = Self::PC_ZERO; let mut pc_big_endian_slice = Self::PC_ZERO;
write_big_endian_u24(address, &mut pc_big_endian_slice); write_big_endian_u24(address, &mut pc_big_endian_slice);
@@ -82,13 +82,8 @@ impl <'a> Cpu<'a>{
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#[test] #[test]
pub fn construct(){ pub fn construct() {}
}
} }

View File

@@ -26,11 +26,11 @@ impl <'a> GraphicsProcessor<'a> {
frame_buffer: RefCell::new(framebuffer), frame_buffer: RefCell::new(framebuffer),
}) })
} }
/// take a copy of FB and /// Draw the pixels.
/// Since this is a VM, we just copy and store it in a buffer.
/// take a copy of FB and store it
pub fn draw(&self) -> EmulatorResult<()> { pub fn draw(&self) -> EmulatorResult<()> {
self.copy_indicated_pixel_data_block()?; self.copy_indicated_pixel_data_block()
let fb_immut = self.frame_buffer.borrow();
Ok(())
} }
fn copy_indicated_pixel_data_block(&self) -> Result<(), EmulatorError> { fn copy_indicated_pixel_data_block(&self) -> Result<(), EmulatorError> {
@@ -50,6 +50,4 @@ impl <'a> GraphicsProcessor<'a> {
} }
#[cfg(test)] #[cfg(test)]
mod test{ mod test {}
}

View File

@@ -1,8 +1,8 @@
use std::cell::RefCell; use std::cell::{Ref, RefCell, RefMut};
use crate::misc::emulator_error::DeviceType::RAM; use crate::misc::emulator_error::DeviceType::RAM;
use crate::misc::emulator_error::EmulatorError; use crate::misc::emulator_error::EmulatorError;
use crate::misc::endian::read_big_endian_u24; use crate::misc::endian::{read_big_endian_u24, write_big_endian_u16};
use crate::misc::result::EmulatorResult; use crate::misc::result::EmulatorResult;
pub const MEM_LENGTH: usize = 2 << 23; pub const MEM_LENGTH: usize = 2 << 23;
@@ -17,7 +17,7 @@ pub trait Memory {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RamMemory { pub struct RamMemory {
pub data: RefCell<Box<[u8; MEM_LENGTH]>>, data: RefCell<Box<[u8; MEM_LENGTH]>>,
} }
impl RamMemory { impl RamMemory {
@@ -58,8 +58,20 @@ impl RamMemory {
Ok(()) Ok(())
} }
pub fn get_data_ref(&self) -> Ref<Box<[u8; MEM_LENGTH]>> {
self.data.borrow()
} }
pub fn get_data_ref_mut(&self) -> RefMut<Box<[u8; MEM_LENGTH]>> {
self.data.borrow_mut()
}
/// set keyboard bits
pub fn set_keyboard(&self,keyboard_bits: u16) {
let mut keyboard_slice_ref = self.data.borrow_mut();
let keyboard_slice = keyboard_slice_ref.get_mut(0..2).unwrap();
write_big_endian_u16(keyboard_bits,keyboard_slice.try_into().unwrap());
}
}
impl Memory for RamMemory { impl Memory for RamMemory {
fn try_get_byte(&self, address: u32) -> EmulatorResult<u8> { fn try_get_byte(&self, address: u32) -> EmulatorResult<u8> {
log::trace!("Fetch RAM memory at address {}",address); log::trace!("Fetch RAM memory at address {}",address);
@@ -70,7 +82,7 @@ impl Memory for RamMemory {
fn try_set_byte(&self, address: u32, value: u8) -> EmulatorResult<()> { fn try_set_byte(&self, address: u32, value: u8) -> EmulatorResult<()> {
if address >= MEM_LENGTH as u32 { if address >= MEM_LENGTH as u32 {
return Err(EmulatorError::UnreachableMemory(RAM, address)) return Err(EmulatorError::UnreachableMemory(RAM, address));
} }
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
data[address as usize] = value; data[address as usize] = value;
@@ -79,12 +91,11 @@ impl Memory for RamMemory {
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::emu::memory::RamMemory; use crate::emu::memory::RamMemory;
use crate::emu::memory::Memory; use crate::emu::memory::Memory;
const EXAMPLE_ADDRESS: u32 = 0x24; const EXAMPLE_ADDRESS: u32 = 0x24;
#[test] #[test]
@@ -92,6 +103,7 @@ mod tests{
let ram_result = RamMemory::try_new(); let ram_result = RamMemory::try_new();
assert!(ram_result.is_ok()) assert!(ram_result.is_ok())
} }
#[test] #[test]
pub fn get_set_memory() { pub fn get_set_memory() {
const EXAMPLE_DATA: u8 = 0xa5; const EXAMPLE_DATA: u8 = 0xa5;

View File

@@ -9,7 +9,7 @@ use crate::misc::result::EmulatorResult;
#[derive(Clone)] #[derive(Clone)]
pub struct SDLGraphicsAdapter<'a> { pub struct SDLGraphicsAdapter<'a> {
pub graphics_processor: &'a GraphicsProcessor<'a>, graphics_processor: &'a GraphicsProcessor<'a>,
} }
impl<'a> Debug for SDLGraphicsAdapter<'a> { impl<'a> Debug for SDLGraphicsAdapter<'a> {

View File

@@ -18,11 +18,11 @@ pub enum EmulatorError {
UnreachableMemory(DeviceType, u32), UnreachableMemory(DeviceType, u32),
InvalidColor(u8), InvalidColor(u8),
EmulatorIOError(Error), EmulatorIOError(Error),
OtherError(String) OtherError(String),
} }
impl From<TryFromSliceError> for EmulatorError { impl From<TryFromSliceError> for EmulatorError {
fn from(value: TryFromSliceError) -> Self { fn from(_: TryFromSliceError) -> Self {
EmulatorError::UnreachableMemory(DeviceType::RAM, 0x5a5a) EmulatorError::UnreachableMemory(DeviceType::RAM, 0x5a5a)
} }
} }

View File

@@ -11,3 +11,7 @@ pub fn read_big_endian_u16(input: &[u8; 2]) -> u16 {
pub fn write_big_endian_u24(input: u32, output_slice: &mut [u8; 3]) { pub fn write_big_endian_u24(input: u32, output_slice: &mut [u8; 3]) {
BigEndian::write_u24(output_slice, input); BigEndian::write_u24(output_slice, input);
} }
pub fn write_big_endian_u16(input: u16, output_slice: &mut [u8; 2]) {
BigEndian::write_u16(output_slice, input);
}