commit 528a2619207271d315330e34958f280110f0e84f
parent 1f5de190da64b59496c50a2c9a2f69b825cc78b6
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date: Fri, 10 Jun 2022 16:39:20 -0700
Fix compile errors
Diffstat:
6 files changed, 80 insertions(+), 45 deletions(-)
diff --git a/src/config.rs b/src/config.rs
@@ -149,6 +149,7 @@ impl Config {
self.cache_path = args_get_next_arg(&args, i, &format!("cache_path"))?.clone();
skips += 1;
}
+ // Skip this argument since it is special.
"--config_path" => {
args_get_next_arg(&args, i, &format!("config_path"))?;
skips += 1;
@@ -177,6 +178,8 @@ impl Config {
Ok(())
}
+ // Getters.
+
pub fn get_win_width(&self) -> u32 {
self.win_width
}
@@ -184,6 +187,10 @@ impl Config {
pub fn get_win_height(&self) -> u32 {
self.win_height
}
+
+ pub fn get_mem_size(&self) -> u32 {
+ self.mem
+ }
}
// Local functions.
diff --git a/src/decode.rs b/src/decode.rs
@@ -215,6 +215,7 @@ pub enum Instruction {
Strb(bool, u8, u32),
}
+/// Opcode errors.
pub enum DecodeError {
/// Indicates an invalid instruction. The first u32 indicates which bits are invalid,
/// the final u32 is the whole opcode.
@@ -250,6 +251,8 @@ fn get_cond_from_opcode(opcode: u32) -> Result<Conditional, DecodeError> {
})
}
+// Public function declarations.
+
pub fn decode(opcode: u32) -> Result<Instruction, DecodeError> {
type I = Instruction;
// SCC flag (<24>).
diff --git a/src/main.rs b/src/main.rs
@@ -20,12 +20,25 @@ mod main_test;
mod config;
mod decode;
+mod memory;
+mod register;
mod sdl;
mod util;
use decode::decode_file;
use std::fs;
+use config::Config;
+use memory::Memory;
+use register::State;
+
+// Struct/enum declarations.
+
+struct System {
+ regs: register::State,
+ mem: memory::Memory,
+}
+
fn get_program(path: &String) -> Result<Vec<u8>, String> {
println!("Opening binary file {}.", path);
@@ -36,9 +49,10 @@ fn get_program(path: &String) -> Result<Vec<u8>, String> {
}
fn main() -> Result<(), String> {
- let config = config::Config::init()?;
+ let config = Config::init()?;
let context = sdl::Context::new(&config)?;
+ let system = System::new(&config);
println!(
"Running emulator with the following configuration: \n{}\n",
config
@@ -47,3 +61,14 @@ fn main() -> Result<(), String> {
Ok(())
}
+
+// Impls.
+
+impl System {
+ pub fn new(config: &Config) -> Result<Self, String> {
+ Ok(Self {
+ regs: State::new(),
+ mem: Memory::new(config),
+ })
+ }
+}
diff --git a/src/memory.rs b/src/memory.rs
@@ -17,8 +17,10 @@
use util::File;
+use config::Config;
+
/// The real memory of the RISC II emulator.
-struct Memory(Vec<u8>);
+pub struct Memory(Vec<u8>);
// Struct impls.
@@ -29,15 +31,15 @@ impl Memory {
/// the memory object.
pub fn new(config: &Config) -> Self {
Self {
- 0: vec![0u8; config.mem],
+ 0: vec![0u8; config.get_mem_size() as usize],
}
}
- pub fn from_vec(memory: &Vec<u8>) {
- Self { 0: memory }
+ pub fn from_vec(memory: &Vec<u8>) -> Self {
+ Self { 0: memory.clone() }
}
- fn write_to_file(&mut self, file: &mut File) -> Result<(), String> {
+ pub fn write_to_file(&mut self, file: &mut File) -> Result<(), String> {
file.write_vec(&self.0)?;
Ok(())
}
diff --git a/src/register.rs b/src/register.rs
@@ -12,6 +12,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
+use std::convert::TryInto;
/// The number of register window_regs the RISCII supports.
pub const NUM_WINDOW_REGS: usize = 6;
@@ -36,10 +37,11 @@ pub const SIZEOF_STATE: usize = TOTAL_NUM_REGISTERS * 4;
// Struct definitions.
/// A RISC II 32bit register.
-struct Register(u32);
+type Register = u32;
/// The CPU's register state.
-struct State {
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct State {
/// Current window pointer, index of the currently active window.
cwp: Register,
/// Saved window pointer, the index of the youngest window saved in memory.
@@ -80,7 +82,7 @@ impl State {
swp: u32::from_be_bytes(buf[4..8].try_into().unwrap()),
globals: {
let mut result = [0u32; NUM_GLOBALS];
- for _ in NUM_GLOBALS {
+ for i in 0..result.len() {
result[i] =
u32::from_be_bytes(buf[cur_offset..cur_offset + 4].try_into().unwrap());
cur_offset += 4;
@@ -89,7 +91,7 @@ impl State {
},
window_regs: {
let mut result = [0u32; NUM_WINDOW_REGISTERS];
- for _ in NUM_WINDOW_REGISTERS {
+ for i in 0..result.len() {
result[i] =
u32::from_be_bytes(buf[cur_offset..cur_offset + 4].try_into().unwrap());
cur_offset += 4;
@@ -99,37 +101,33 @@ impl State {
}
}
- fn to_buf(&self) -> [u8; SIZEOF_STATE] {
- let mut result: [u8; SIZEOF_STATE] = [
- self.cwp.to_be_bytes(),
- self.swp.to_be_bytes(),
- {
- let mut tmp = [u8; NUM_GLOBALS * 4];
- for i in NUM_GLOBALS {
- let bytes = self.globals[i].to_be_bytes();
- tmp[i] = bytes[0];
- tmp[i + 1] = bytes[1];
- tmp[i + 1] = bytes[2];
- tmp[i + 1] = bytes[3];
- }
- tmp
- },
- {
- let mut tmp = [u8; NUM_WINDOW_REGISTERS * 4];
- for i in NUM_WINDOW_REGISTERS {
- let bytes = self.window_regs[i].to_be_bytes();
- tmp[i] = bytes[0];
- tmp[i + 1] = bytes[1];
- tmp[i + 1] = bytes[2];
- tmp[i + 1] = bytes[3];
- }
- tmp
- },
- ];
+ pub fn to_buf(&self) -> [u8; SIZEOF_STATE] {
+ let mut result = [0u8; SIZEOF_STATE];
+ result[0..4].copy_from_slice(&self.cwp.to_be_bytes());
+ result[4..8].copy_from_slice(&self.swp.to_be_bytes());
+ let globals = {
+ let mut tmp = [0u8; NUM_GLOBALS * 4];
+ for i in 0..NUM_GLOBALS {
+ tmp[i * 4..i * 4 + 4].copy_from_slice(&self.globals[i].to_be_bytes());
+ }
+ tmp
+ };
+
+ const GLOBAL_OFFSET: usize = 8 + NUM_GLOBALS * 4;
+ result[8..GLOBAL_OFFSET].copy_from_slice(&globals);
+ let win_regs = {
+ let mut tmp = [0u8; NUM_WINDOW_REGISTERS * 4];
+ for i in 0..NUM_WINDOW_REGISTERS {
+ tmp[i * 4..i * 4 + 4].copy_from_slice(&self.window_regs[i].to_be_bytes());
+ }
+ tmp
+ };
+
+ result[GLOBAL_OFFSET..].copy_from_slice(&win_regs);
result
}
- fn push_reg_window(&mut self) {
+ pub fn push_reg_window(&mut self) {
self.cwp += 1;
while self.cwp >= self.swp {
// TODO save the top window_regs into memory.
@@ -137,7 +135,7 @@ impl State {
}
}
- fn pop_reg_window(&mut self) {
+ pub fn pop_reg_window(&mut self) {
self.cwp -= 1;
while self.swp >= self.cwp {
// TODO load window_regs from memory.
diff --git a/src/util.rs b/src/util.rs
@@ -104,14 +104,14 @@ impl File {
}
}
- fn read_into_vec(&mut self, buf: &mut Vec<u8>) -> Result<(), String> {
+ pub fn read_into_vec(&mut self, buf: &mut Vec<u8>) -> Result<(), String> {
match self.file.read_exact(&mut buf[..]) {
Ok(r) => Ok(()),
Err(e) => Err(format!("Failed to read file {}, {}", self.path, e)),
}
}
- fn read_file(&mut self) -> Result<Vec<u8>, String> {
+ pub fn read_file(&mut self) -> Result<Vec<u8>, String> {
let metadata = self.get_metadata()?;
let mut result = vec![0u8; metadata.len() as usize];
self.read_into_vec(&mut result)?;
@@ -119,21 +119,21 @@ impl File {
Ok(result)
}
- fn get_metadata(&mut self) -> Result<Metadata, String> {
+ pub fn get_metadata(&mut self) -> Result<Metadata, String> {
match self.file.metadata() {
Ok(r) => Ok(r),
Err(e) => Err(format!("Could not read metadata for {}: {}", self.path, e)),
}
}
- fn read(&mut self, buf: &mut [u8]) -> Result<(), String> {
+ pub fn read(&mut self, buf: &mut [u8]) -> Result<(), String> {
match self.file.read_exact(buf) {
Ok(r) => Ok(()),
Err(e) => Err(format!("Could not read buffer from {}: {}", self.path, e)),
}
}
- fn write_buf(&mut self, buf: &[u8]) -> Result<(), String> {
+ pub fn write_buf(&mut self, buf: &[u8]) -> Result<(), String> {
match self.file.write_all(buf) {
Ok(r) => Ok(()),
Err(e) => Err(format!(
@@ -143,7 +143,7 @@ impl File {
}
}
- fn write_vec(&mut self, buf: &Vec<u8>) -> Result<(), String> {
+ pub fn write_vec(&mut self, buf: &Vec<u8>) -> Result<(), String> {
match self.file.write_all(&buf[..]) {
Ok(r) => Ok(()),
Err(e) => Err(format!(