trapezoid-core 0.3.0

A PSX emulator, backed by vulkano for rendering
Documentation
use byteorder::{ByteOrder, LittleEndian};

use crate::memory::Result;

use super::BusLine;

pub struct MainRam {
    data: Vec<u8>,
}

impl Default for MainRam {
    fn default() -> Self {
        Self {
            data: vec![0; 0x200000],
        }
    }
}

impl MainRam {
    pub fn put_at_address(&mut self, block_data: &[u8], addr: u32) {
        let addr = (addr as usize) & 0x1FFFFF;
        let block_len = block_data.len();
        assert!((block_len + addr) < self.data.len());

        self.data[addr..(addr + block_len)].copy_from_slice(block_data);
    }
}

impl BusLine for MainRam {
    fn read_u32(&mut self, addr: u32) -> Result<u32> {
        let index = (addr as usize) & 0x1FFFFF;

        Ok(LittleEndian::read_u32(&self.data[index..index + 4]))
    }

    fn write_u32(&mut self, addr: u32, data: u32) -> Result<()> {
        let index = (addr as usize) & 0x1FFFFF;

        LittleEndian::write_u32(&mut self.data[index..index + 4], data);
        Ok(())
    }

    fn read_u16(&mut self, addr: u32) -> Result<u16> {
        let index = (addr as usize) & 0x1FFFFF;
        Ok(LittleEndian::read_u16(&self.data[index..index + 2]))
    }

    fn write_u16(&mut self, addr: u32, data: u16) -> Result<()> {
        let index = (addr as usize) & 0x1FFFFF;

        LittleEndian::write_u16(&mut self.data[index..index + 2], data);
        Ok(())
    }

    fn read_u8(&mut self, addr: u32) -> Result<u8> {
        Ok(self.data[(addr as usize) & 0x1FFFFF])
    }

    fn write_u8(&mut self, addr: u32, data: u8) -> Result<()> {
        self.data[(addr as usize) & 0x1FFFFF] = data;
        Ok(())
    }
}

pub struct Scratchpad {
    data: Vec<u8>,
}

impl Default for Scratchpad {
    fn default() -> Self {
        Self {
            data: vec![0; 0x400],
        }
    }
}

impl BusLine for Scratchpad {
    fn read_u32(&mut self, addr: u32) -> Result<u32> {
        let index = addr as usize;

        Ok(LittleEndian::read_u32(&self.data[index..index + 4]))
    }

    fn write_u32(&mut self, addr: u32, data: u32) -> Result<()> {
        let index = addr as usize;

        LittleEndian::write_u32(&mut self.data[index..index + 4], data);
        Ok(())
    }

    fn read_u16(&mut self, addr: u32) -> Result<u16> {
        let index = addr as usize;

        Ok(LittleEndian::read_u16(&self.data[index..index + 2]))
    }

    fn write_u16(&mut self, addr: u32, data: u16) -> Result<()> {
        let index = addr as usize;

        LittleEndian::write_u16(&mut self.data[index..index + 2], data);
        Ok(())
    }

    fn read_u8(&mut self, addr: u32) -> Result<u8> {
        Ok(self.data[addr as usize])
    }

    fn write_u8(&mut self, addr: u32, data: u8) -> Result<()> {
        self.data[addr as usize] = data;
        Ok(())
    }
}