diff --git a/src/bus.rs b/src/bus.rs index 2dac9a5..e7eda55 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -1,5 +1,6 @@ pub const DRAM_BASE: u32 = 0x80000000; +use crate::rv32; use crate::ram; pub struct Bus { @@ -10,4 +11,52 @@ impl Bus { pub fn new() -> Bus { Bus { memory: ram::RAM::new() } } + + pub fn load_8(&mut self, address: rv32::XLen) -> rv32::Byte { + match address { + DRAM_BASE.. => { + self.memory.read_8(address) + } + _ => { + println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address); + rv32::Byte::default() + }, + } + } + + pub fn load_16(&mut self, address: rv32::XLen) -> rv32::HalfWord { + match address { + DRAM_BASE.. => { + self.memory.read_16(address) + } + _ => { + println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address); + rv32::HalfWord::default() + }, + } + } + + pub fn load_32(&mut self, address: rv32::XLen) -> rv32::Word { + match address { + DRAM_BASE.. => { + self.memory.read_32(address) + } + _ => { + println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address); + rv32::Word::default() + }, + } + } + + pub fn load_64(&mut self, address: rv32::XLen) -> rv32::DoubleWord { + match address { + DRAM_BASE.. => { + self.memory.read_64(address) + } + _ => { + println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address); + rv32::DoubleWord::default() + }, + } + } } diff --git a/src/main.rs b/src/main.rs index 487dedb..67ca155 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,7 +47,7 @@ impl VMRV32I { } fn dump_prog(&mut self) { - println!("VM > Dumping program"); + println!("VM > Dumping program (virtual addresses)"); for i in 0..12 { println!("VM > 0x{:08x}: 0x{:02x}", i, self.bus.memory.0[i]); } @@ -69,8 +69,17 @@ impl VMRV32I { } fn exec(&mut self) { - let val: u8 = self.bus.memory.read::(0x80000000) - println!("VM > WORD at 0x80000000: 0x{:08x}", val); + let val: u8 = self.bus.memory.read_8(0x80000000); + println!("VM > BYTE at 0x80000000: 0x{:02x}", val); + let val = self.bus.memory.read_16(0x80000000); + println!("VM > HWORD at 0x80000000: 0x{:04x}", val); + let val = self.bus.memory.read_32(0x80000000); + println!("VM > WORD at 0x80000000: 0x{:08x}", val); + let val = self.bus.memory.read_64(0x80000000); + println!("VM > DWORD at 0x80000000: 0x{:016x}", val); + + let val = self.bus.load_8(0x7FFFFFFF); + println!("VM > BYTE at 0x80000000: 0x{:02x}", val); while self.pc > self.bus.memory.len() as u32 { let inst = self.fetch(); diff --git a/src/ram.rs b/src/ram.rs index 855d7d2..d1f9ef9 100644 --- a/src/ram.rs +++ b/src/ram.rs @@ -14,30 +14,68 @@ impl RAM { self.0.len() } - pub fn read(&mut self, address: rv32::XLen) -> T - where - T: num::Num - + num::ToPrimitive - + Default - + std::fmt::LowerHex - + std::ops::Shl - + std::ops::BitOr - + num::cast::NumCast, - { - let address: usize = (address - bus::DRAM_BASE) as usize; + pub fn read_8(&mut self, address: rv32::XLen) -> rv32::Byte { let memory = &self.0; - - (address..) - .take(core::mem::size_of::()) - .enumerate() - .fold(T::default(), |mut acc, (i, x)| { - println!("VM > Reading from 0x{:08x} to 0x{:08x}", x, acc); - println!("VM > Memory: 0x{:02x}", memory[x]); - println!("VM > Now Shift: {}", i * 8); - - acc << u32::from(i as u32 * 8) | memory[x].from() - }) + let address = (address - bus::DRAM_BASE) as usize; + memory[address] } - pub fn write(&mut self, address: rv32::XLen, data: T) {} + pub fn read_16(&mut self, address: rv32::XLen) -> rv32::HalfWord { + let memory = &self.0; + let address = (address - bus::DRAM_BASE) as usize; + let ret: rv32::HalfWord = + memory[address] as rv32::HalfWord | (memory[address + 1] as rv32::HalfWord) << 8; + ret + } + + pub fn read_32(&mut self, address: rv32::XLen) -> rv32::Word { + let memory = &self.0; + let address = (address - bus::DRAM_BASE) as usize; + let ret: rv32::Word = memory[address] as rv32::Word + | (memory[address + 1] as rv32::Word) << 8 + | (memory[address + 2] as rv32::Word) << 16 + | (memory[address + 3] as rv32::Word) << 24; + ret + } + + pub fn read_64(&mut self, address: rv32::XLen) -> rv32::DoubleWord { + let memory = &self.0; + let address = (address - bus::DRAM_BASE) as usize; + let ret: rv32::DoubleWord = memory[address] as rv32::DoubleWord + | (memory[address + 1] as rv32::DoubleWord) << 8 + | (memory[address + 2] as rv32::DoubleWord) << 16 + | (memory[address + 3] as rv32::DoubleWord) << 24 + | (memory[address + 4] as rv32::DoubleWord) << 32 + | (memory[address + 5] as rv32::DoubleWord) << 40 + | (memory[address + 6] as rv32::DoubleWord) << 48 + | (memory[address + 7] as rv32::DoubleWord) << 56; + ret + } + + //pub fn read(&mut self, address: rv32::XLen) -> T + //where + //T: num::Num + //+ num::ToPrimitive + //+ Default + //+ std::fmt::LowerHex + //+ std::ops::Shl + //+ std::ops::BitOr + //+ num::cast::NumCast, + //{ + //let address: usize = (address - bus::DRAM_BASE) as usize; + //let memory = &self.0; + + //(address..) + //.take(core::mem::size_of::()) + //.enumerate() + //.fold(T::default(), |mut acc, (i, x)| { + //println!("VM > Reading from 0x{:08x} to 0x{:08x}", x, acc); + //println!("VM > Memory: 0x{:02x}", memory[x]); + //println!("VM > Now Shift: {}", i * 8); + + //acc << u32::from(i as u32 * 8) | memory[x].from() + //}) + //} + + //pub fn write(&mut self, address: rv32::XLen, data: T) {} } diff --git a/src/rv32.rs b/src/rv32.rs index 31de689..0d99ae9 100644 --- a/src/rv32.rs +++ b/src/rv32.rs @@ -1,22 +1,15 @@ pub const XLEN: usize = 32; pub type XLen = u32; -enum Data { - QuadWord(u128), - DoubleWord(u64), - Word(u32), - HalfWord(u16), - Byte(u8), -} - // define words as byte fraction -//pub const QUADWORD: usize = 16; +pub const QUADWORD: usize = 16; pub const DOUBLEWORD: usize = 8; pub const WORD: usize = 4; pub const HALFWORD: usize = 2; pub const BYTE: usize = 1; -//pub type DoubleWord = u64; +pub type QuadWord = u128; +pub type DoubleWord = u64; pub type Word = u32; pub type HalfWord = u16; pub type Byte = u8;