Skip to content

Commit

Permalink
feat: Initialize the basic implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
howjmay committed Feb 3, 2024
1 parent 65f4c3c commit 86fe631
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 9 deletions.
14 changes: 5 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb


# Added by cargo

/target
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "emurv"
version = "0.1.0"
edition = "2021"

[dependencies]
55 changes: 55 additions & 0 deletions src/cpu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use core::fmt;

use crate::memory;

#[derive(Debug)]
pub struct CPU {
// integer registers
xregs: [u64; 32],
pc: u64,
bus: memory::BUS,
}

const DEFAULT_RSTVEC: u64 = 0x00001000;

impl CPU {
fn new() -> Self {
let mut cpu: CPU = CPU {
xregs: [0; 32],
pc: memory::MEM_BASE,
bus: memory::BUS {},
};
(cpu).xregs[2] = memory::MEM_BASE + memory::MEM_SIZE; // Set stack pointer
(cpu).pc = memory::MEM_BASE;
return cpu;
}

fn fetch() {}

fn execute() {}
}

pub struct XREGS([u64; 32]);

impl fmt::Debug for XREGS {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = f.debug_struct("xregs");
for i in 0..32 {
s.field(format!("xreg[{i}]").as_str(), &self.0[i]);
}
s.finish()
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn xregs_debug() {
let mut xregs: XREGS = XREGS([0; 32]);
for i in 0..32 {
xregs.0[i] = (i * 11) as u64;
}
println!("{xregs:#?}")
}
}
6 changes: 6 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod cpu;
pub mod memory;

fn main() {
println!("Hello, world!");
}
86 changes: 86 additions & 0 deletions src/memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
pub const MEM_BASE: u64 = 0x80000000; // defined in QEMU
pub const MEM_SIZE: u64 = 1024 * 1024 * 1;

#[derive(Debug)]
pub struct BUS {}

pub struct MEMORY {
mem: [u8; MEM_SIZE as usize],
}

impl MEMORY {
fn load(self, addr: u64, size: u64) -> u64 {
match size {
8 => return self.load8(addr),
16 => return self.load16(addr),
32 => return self.load32(addr),
64 => return self.load64(addr),
_ => panic!("wrong load size"),
}
}
fn store(&mut self, addr: u64, size: u64, value: u64) {
match size {
8 => self.store8(addr, value),
16 => self.store16(addr, value),
32 => self.store32(addr, value),
64 => self.store64(addr, value),
_ => panic!("wrong store size"),
}
}

// load funcs
fn load8(self, addr: u64) -> u64 {
let index = (addr - MEM_BASE) as usize;
return self.mem[index] as u64;
}
fn load16(self, addr: u64) -> u64 {
let index = (addr - MEM_BASE) as usize;
return self.mem[index] as u64 | ((self.mem[index + 1] as u64) << 8);
}
fn load32(self, addr: u64) -> u64 {
let index = (addr - MEM_BASE) as usize;
return self.mem[index] as u64
| ((self.mem[index + 1] as u64) << 8)
| ((self.mem[index + 2] as u64) << 16)
| ((self.mem[index + 3] as u64) << 24);
}
fn load64(self, addr: u64) -> u64 {
let index = (addr - MEM_BASE) as usize;
return self.mem[index] as u64
| ((self.mem[index + 1] as u64) << 8)
| ((self.mem[index + 2] as u64) << 16)
| ((self.mem[index + 3] as u64) << 24)
| ((self.mem[index + 4] as u64) << 32)
| ((self.mem[index + 5] as u64) << 40)
| ((self.mem[index + 6] as u64) << 48)
| ((self.mem[index + 7] as u64) << 56);
}

// store funcs
fn store8(&mut self, addr: u64, value: u64) {
let index = (addr - MEM_BASE) as usize;
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
}
fn store16(&mut self, addr: u64, value: u64) {
let index = (addr - MEM_BASE) as usize;
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u64)) as u8;
}
fn store32(&mut self, addr: u64, value: u64) {
let index = (addr - MEM_BASE) as usize;
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u64)) as u8;
self.mem[index + 2] = ((value >> 16) & (std::u8::MAX as u64)) as u8;
}
fn store64(&mut self, addr: u64, value: u64) {
let index = (addr - MEM_BASE) as usize;
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u64)) as u8;
self.mem[index + 2] = ((value >> 16) & (std::u8::MAX as u64)) as u8;
self.mem[index + 3] = ((value >> 24) & (std::u8::MAX as u64)) as u8;
self.mem[index + 4] = ((value >> 32) & (std::u8::MAX as u64)) as u8;
self.mem[index + 5] = ((value >> 40) & (std::u8::MAX as u64)) as u8;
self.mem[index + 6] = ((value >> 48) & (std::u8::MAX as u64)) as u8;
self.mem[index + 7] = ((value >> 56) & (std::u8::MAX as u64)) as u8;
}
}
Empty file added src/opcode.rs
Empty file.

0 comments on commit 86fe631

Please sign in to comment.