diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..102b75c --- /dev/null +++ b/src/args.rs @@ -0,0 +1,6 @@ +use clap::Parser; + +#[derive(Debug,Parser)] +pub struct BytePusherArgs{ + +} \ No newline at end of file diff --git a/src/emu/cpu.rs b/src/emu/cpu.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/emu/endian.rs b/src/emu/endian.rs new file mode 100644 index 0000000..fea9654 --- /dev/null +++ b/src/emu/endian.rs @@ -0,0 +1,15 @@ + +/// read a 24bit endian value, and place it in a u32 num +pub fn read_big_endian_tribyte(input:&[u8;3]) ->u32{ + todo!() +} + +pub fn read_big_endian_byte_array(input:&[u8]) ->u32{ + todo!() +} + + +/// Get 24 bit big endian slice +pub fn get_big_endian(input:u32)->[u8;3]{ + todo!() +} \ No newline at end of file diff --git a/src/emu/iomem.rs b/src/emu/iomem.rs new file mode 100644 index 0000000..ca9127c --- /dev/null +++ b/src/emu/iomem.rs @@ -0,0 +1,60 @@ + +use crate::emu::mmu::Memory; + +#[derive(Debug, Copy, Clone)] +pub struct MemoryMappedIO { + keyboard_bits: [u8;2], + program_counter: [u8; 3], + pixel_reg: u8, + audio_sample_address_base: [u8; 2], +} + +impl MemoryMappedIO { + pub fn new() -> MemoryMappedIO { + MemoryMappedIO { + keyboard_bits: [0,0], + program_counter: [0, 0, 0], + pixel_reg: 0, + audio_sample_address_base: [0, 0], + } + } +} + +const KEYBOARD_BIT_START: u32 = 0; +const KEYBOARD_BIT_END: u32 = 1; +const PC_START_ADDR: u32 = 2; +const PC_LEN: u32 = 3; +const PC_END_ADDR: u32 = PC_START_ADDR + PC_LEN - 1; + +const PIXEL_BASE: u32 = 5; +const AUDIO_SAMPLE_BASE_START: u32 = 6; +const AUDIO_SAMPLE_BASE_LEN: u32 = 2; +const AUDIO_SAMPLE_BASE_END: u32 = AUDIO_SAMPLE_BASE_START + AUDIO_SAMPLE_BASE_LEN - 1; + +impl Memory for MemoryMappedIO { + fn get_byte(&self, address: u32) -> u8 { + match address { + KEYBOARD_BIT_START..=KEYBOARD_BIT_END => { + let addr_usize = address as usize; + log::trace!("Fetching keyboard bits segment {}",addr_usize); + self.keyboard_bits[addr_usize] + }, + PC_START_ADDR..=PC_END_ADDR => { + let pc_index = (address - PC_START_ADDR) as usize; + log::trace!("Fetching PC {:?} bit segment {}",self.program_counter,pc_index); + self.program_counter[pc_index] + }, + PIXEL_BASE => { + log::trace!("Fetching pixel base reg {}",self.pixel_reg); + self.pixel_reg + }, + AUDIO_SAMPLE_BASE_START => self.audio_sample_address_base[0], + AUDIO_SAMPLE_BASE_END => self.audio_sample_address_base[1], + _ => { panic!("Unreachable code") } + } + } + + fn set_byte(&mut self, address: u32, val: u8) { + todo!() + } +} diff --git a/src/emu/mem.rs b/src/emu/mem.rs new file mode 100644 index 0000000..de153ee --- /dev/null +++ b/src/emu/mem.rs @@ -0,0 +1,28 @@ +use crate::emu::mmu::Memory; + +const MEM_LENGTH: usize = 2 << 24; + +#[derive(Clone, Debug)] +pub struct RamMemory { + data: Box<[u8; MEM_LENGTH]>, +} + +impl RamMemory { + pub fn new() -> RamMemory { + RamMemory { + data: vec![0; MEM_LENGTH].into_boxed_slice().try_into().expect("Incorrect ram allocation") + } + } +} + +impl Memory for RamMemory { + fn get_byte(&self, address: u32) -> u8 { + log::trace!("Fetch RAM memory at address {}",address); + let x = *self.data.get(address as usize).expect("Unchecked address fetch"); + x + } + + fn set_byte(&mut self, address: u32, val: u8) { + self.data[address as usize] = val; + } +} \ No newline at end of file diff --git a/src/emu/mmu.rs b/src/emu/mmu.rs new file mode 100644 index 0000000..e29485e --- /dev/null +++ b/src/emu/mmu.rs @@ -0,0 +1,46 @@ +use crate::emu::iomem::MemoryMappedIO; +use crate::emu::mem::RamMemory; + +pub const MMAPPEDIO_END: u32 = RAM_MEM_START-1; +pub const RAM_MEM_START:u32 = 8; +pub const RAM_MEM_END: u32 = 2<<24 - 1; + +/// +/// mapped I/O + RAM. +pub trait Memory { + /// Get the value (24bit) at the address(24bit) + fn get_byte(&self, address: u32) -> u8; + /// Set the value at the 24bit address + fn set_byte(&mut self, address: u32, value: u8); +} +#[derive(Debug,Clone)] +pub struct MappedMemory { + memory_mapped_io: MemoryMappedIO, + ram_memory: RamMemory, +} +impl MappedMemory { + pub fn new(memory_mapped_io: MemoryMappedIO, ram_memory: RamMemory)-> MappedMemory { + MappedMemory { + memory_mapped_io, + ram_memory + } + } +} + +impl Memory for MappedMemory { + fn get_byte(&self, address: u32) -> u8 { + match address { + 0..=MMAPPEDIO_END => { + self.memory_mapped_io.get_byte(address) + }, + RAM_MEM_START..=RAM_MEM_END =>{ + self.ram_memory.get_byte(address) + } + _ => { panic!("Invalid address") } + } + } + fn set_byte(&mut self, address: u32, value: u8) { + todo!() + } +} + diff --git a/src/emu/mod.rs b/src/emu/mod.rs new file mode 100644 index 0000000..6dae1b1 --- /dev/null +++ b/src/emu/mod.rs @@ -0,0 +1,5 @@ +pub mod cpu; +pub mod mmu; +pub mod mem; +mod endian; +pub mod iomem; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..697edd9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,19 @@ +use simple_logger::SimpleLogger; +use crate::emu::iomem::MemoryMappedIO; +use crate::emu::mem::RamMemory; +use crate::emu::mmu::{Memory, MappedMemory}; + +mod emu; +mod args; + +fn main() { + SimpleLogger::new().init().unwrap(); + + let mmio = MemoryMappedIO::new(); + let ram = RamMemory::new(); + let mmu = MappedMemory::new(mmio, ram); + for i in 0..10 { + log::info!("Memory at {} is {}",i,mmu.get_byte(i)); + } + +}