riscii

An emulator for the RISC II
Log | Files | Refs | LICENSE

commit 7d9d33974dbd996748f727e512e9d9f0b7a4bd31
parent 698dca6504826f2ade27436f7e14b3db965b8daa
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date:   Sun,  9 Oct 2022 19:50:24 -0700

Basic windowing system

Diffstat:
Msrc/config.rs | 18++++++++++++++++++
Msrc/instruction.rs | 4++--
Msrc/main.rs | 31++++++++++++++++++++++++++++---
Msrc/sdl.rs | 16+++++++++-------
Asrc/windows.rs | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 163 insertions(+), 12 deletions(-)

diff --git a/src/config.rs b/src/config.rs @@ -50,6 +50,12 @@ pub struct Config { /// Height of the window. #[serde(default = "default_height")] win_height: u32, + /// Width of the window. + #[serde(default = "default_width")] + debug_win_width: u32, + /// Height of the window. + #[serde(default = "default_height")] + debug_win_height: u32, } // Struct impls. @@ -74,6 +80,8 @@ impl Config { cache_path: String::new(), win_width: 0, win_height: 0, + debug_win_width: 0, + debug_win_height: 0, }) } @@ -195,6 +203,16 @@ impl Config { // Getters. /// Get the user's configured window width. + pub fn get_debug_win_width(&self) -> u32 { + self.debug_win_width + } + + /// Get the user's configured window height. + pub fn get_debug_win_height(&self) -> u32 { + self.debug_win_height + } + + /// Get the user's configured window width. pub fn get_win_width(&self) -> u32 { self.win_width } diff --git a/src/instruction.rs b/src/instruction.rs @@ -366,7 +366,7 @@ impl ShortSource { pub fn new(opcode: u32, signed: bool) -> Self { // Short source immediate-mode bottom 13 bits <12-0> or rs1 <4-0>. if opcode & 0x2000 != 0 { - let mut tmp = Self::Imm13(opcode & 0x1fff); + let tmp = Self::Imm13(opcode & 0x1fff); if signed { tmp.uimm_to_simm() } else { @@ -389,7 +389,7 @@ impl ShortSource { Self::Imm13(u) } } - Self::Reg(r) => *self, + Self::Reg(_) => *self, } } } diff --git a/src/main.rs b/src/main.rs @@ -33,6 +33,7 @@ pub mod memory; pub mod sdl; pub mod system; pub mod util; +pub mod windows; use decode::decode_file; use std::fs; @@ -41,14 +42,13 @@ use config::Config; use std::boxed::Box; use std::error::Error; use system::System; - +use windows::{DebugWindow, Drawable, MainWindow}; // Struct/enum declarations. fn main() -> Result<(), Box<dyn Error>> { let config = Config::init()?; - let context = sdl::Context::new(&config)?; - let system = System::new(&config); + let system = System::new(&config)?; println!( "Running emulator with the following configuration: \n{}\n", config @@ -56,5 +56,30 @@ fn main() -> Result<(), Box<dyn Error>> { //println!("Opening binary file {}.", path); //let program = fs::read(path)?; + let mut debug_window = Some(DebugWindow::new(&config, &system)?); + let mut main_window = MainWindow::new(&config, &system)?; + + 'running: loop { + if main_window.handle_events() { + break 'running; + } + debug_window = if let Some(mut win) = debug_window { + if win.handle_events() { + None + } else { + Some(win) + } + } else { + None + }; + + debug_window = if let Some(mut win) = debug_window { + win.draw(); + Some(win) + } else { + None + }; + main_window.draw(); + } Ok(()) } diff --git a/src/sdl.rs b/src/sdl.rs @@ -1,4 +1,4 @@ -// RISC II emulator window and I/O. +// RISC II emulator SDL layer. // (C) Ryan Jeffrey <ryan@ryanmj.xyz>, 2022 // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -27,30 +27,32 @@ use sdl2::video::Window; use sdl2::EventPump; use sdl2::Sdl; use sdl2::VideoSubsystem; +use system::System; use util::Result; // Struct definitions. + /// SDL context structs. pub struct Context { /// SDL context. - context: Sdl, + pub context: Sdl, /// Video context. - video_system: VideoSubsystem, + pub video_system: VideoSubsystem, /// Window canvas. - canvas: Canvas<Window>, + pub canvas: Canvas<Window>, /// Event queue. - event_pump: EventPump, + pub event_pump: EventPump, } // Struct impls. impl Context { /// Create a new SDL window/context. Return context on success and a /// string on error. - pub fn new(config: &Config) -> Result<Self> { + pub fn new(width: u32, height: u32, name: String) -> Result<Self> { let sdl_context = sdl2::init()?; let video_subsystem = sdl_context.video()?; let window = video_subsystem - .window("RISC II", config.get_win_width(), config.get_win_height()) + .window(name.as_str(), width, height) .position_centered() .opengl() .build() diff --git a/src/windows.rs b/src/windows.rs @@ -0,0 +1,106 @@ +// RISC II emulator windows. +// (C) Ryan Jeffrey <ryan@ryanmj.xyz>, 2022 +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. + +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// 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/>. + +// Struct definitions. + +use config::Config; +use sdl::Context; +use sdl2::event::Event; +use sdl2::pixels::*; +use system::System; +use util::Result; + +pub trait Drawable { + fn draw(&mut self); + fn handle_events(&mut self) -> bool; +} + +pub struct DebugWindow<'a> { + context: Context, + system: &'a System, + config: &'a Config, +} + +pub struct MainWindow<'a> { + context: Context, + system: &'a System, + config: &'a Config, +} + +// Struct impls. + +impl<'a> Drawable for MainWindow<'a> { + fn draw(&mut self) {} + + fn handle_events(&mut self) -> bool { + false + } +} + +impl<'a> MainWindow<'a> { + pub fn new(config: &'a Config, system: &'a System) -> Result<Self> { + Ok(Self { + context: Context::new( + config.get_win_width(), + config.get_debug_win_height(), + format!("RISC II"), + )?, + system: system, + config: config, + }) + } +} + +impl<'a> DebugWindow<'a> { + pub fn new(config: &'a Config, system: &'a System) -> Result<Self> { + Ok(Self { + context: Context::new( + config.get_debug_win_width(), + config.get_debug_win_height(), + format!("Debug"), + )?, + system: system, + config: config, + }) + } +} + +impl<'a> Drawable for DebugWindow<'a> { + fn draw(&mut self) { + self.context.canvas.set_draw_color(Color::RGB(0, 0, 0)); + self.context.canvas.clear(); + + // + self.context.canvas.present(); + } + fn handle_events(&mut self) -> bool { + let event_pump = &mut self.context.event_pump; + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } => { + return true; + } + Event::KeyDown { + keycode: Some(kc), .. + } => {} + Event::KeyUp { + keycode: Some(kc), .. + } => {} + _ => {} + } + } + return false; + } +}