[ref] format and use methods to get references
Plus, add setting keyboard support
This commit is contained in:
@@ -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() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@@ -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 {}
|
||||||
|
|
||||||
}
|
|
@@ -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;
|
||||||
|
@@ -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> {
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
Reference in New Issue
Block a user