From e5f67a01f556a6b6c06ed4b118b45fd7b9cf50f1 Mon Sep 17 00:00:00 2001 From: PeronTheDuck Date: Tue, 28 Jan 2020 00:09:05 -0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=BB=E2=9C=8F=F0=9F=92=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{sixty_five => emulator}/addr | 0 .../addressing_modes.rs | 17 ++ src/emulator/error.rs | 27 +++ src/{sixty_five => emulator}/mod.rs | 9 +- src/{sixty_five => emulator}/opcodes.rs | 0 src/{sixty_five => emulator}/ops | 0 .../cpu.rs => emulator/registers.rs} | 8 +- .../emulator.rs => emulator/system.rs} | 84 +++++---- src/error.rs | 2 +- src/handler.rs | 107 +++++++++++ src/main.rs | 170 +++++++++--------- src/sixty_five/error.rs | 25 --- 12 files changed, 289 insertions(+), 160 deletions(-) rename src/{sixty_five => emulator}/addr (100%) rename src/{sixty_five => emulator}/addressing_modes.rs (66%) create mode 100644 src/emulator/error.rs rename src/{sixty_five => emulator}/mod.rs (53%) rename src/{sixty_five => emulator}/opcodes.rs (100%) rename src/{sixty_five => emulator}/ops (100%) rename src/{sixty_five/cpu.rs => emulator/registers.rs} (93%) rename src/{sixty_five/emulator.rs => emulator/system.rs} (68%) create mode 100644 src/handler.rs delete mode 100644 src/sixty_five/error.rs diff --git a/src/sixty_five/addr b/src/emulator/addr similarity index 100% rename from src/sixty_five/addr rename to src/emulator/addr diff --git a/src/sixty_five/addressing_modes.rs b/src/emulator/addressing_modes.rs similarity index 66% rename from src/sixty_five/addressing_modes.rs rename to src/emulator/addressing_modes.rs index 6228147..37a774a 100644 --- a/src/sixty_five/addressing_modes.rs +++ b/src/emulator/addressing_modes.rs @@ -1,3 +1,20 @@ +use std::convert::{From, Into}; + +struct Address(usize); +impl From for Address { + fn from(v: usize) -> Self { + if v > 0xFFFF { + panic!("Address is bigger than 0x10000 (Got 0x{:04X})", v); + } + Self(v) + } +} +impl From for Address { + fn from(v: u16) -> Self { + Self(v as usize) + } +} + pub fn get_size(addr_mode: AddressingMode) -> usize { OP_SIZES[addr_mode as usize] } diff --git a/src/emulator/error.rs b/src/emulator/error.rs new file mode 100644 index 0000000..0130e4d --- /dev/null +++ b/src/emulator/error.rs @@ -0,0 +1,27 @@ +use std::boxed::Box; +use std::error::Error; +use std::fmt::{Display, Error as FmtError, Formatter}; + +#[derive(Debug)] +pub enum CpuError { + UnknownOp(u8), + Break, + Suberror(Box), +} + +impl Display for CpuError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!( + f, + "Emulator Error: {}", + match self { + CpuError::Suberror(e) => e.description().to_string(), + CpuError::Break => "Emulator Terminated".to_string(), + CpuError::UnknownOp(code) => format!("Unknown OP with code {:02X}", code), + } + ) + } +} +impl Error for CpuError {} +unsafe impl std::marker::Send for CpuError {} +unsafe impl std::marker::Sync for CpuError {} diff --git a/src/sixty_five/mod.rs b/src/emulator/mod.rs similarity index 53% rename from src/sixty_five/mod.rs rename to src/emulator/mod.rs index b0bfa51..5239c93 100644 --- a/src/sixty_five/mod.rs +++ b/src/emulator/mod.rs @@ -1,9 +1,10 @@ -pub mod error; +mod error; +pub use error::CpuError; mod addressing_modes; use addressing_modes::AddressingMode; mod opcodes; use opcodes::OpcodeType; -mod cpu; -mod emulator; -pub use emulator::Emulator; +mod registers; +mod system; +pub use system::System; diff --git a/src/sixty_five/opcodes.rs b/src/emulator/opcodes.rs similarity index 100% rename from src/sixty_five/opcodes.rs rename to src/emulator/opcodes.rs diff --git a/src/sixty_five/ops b/src/emulator/ops similarity index 100% rename from src/sixty_five/ops rename to src/emulator/ops diff --git a/src/sixty_five/cpu.rs b/src/emulator/registers.rs similarity index 93% rename from src/sixty_five/cpu.rs rename to src/emulator/registers.rs index 094dacf..a662451 100644 --- a/src/sixty_five/cpu.rs +++ b/src/emulator/registers.rs @@ -11,14 +11,14 @@ pub enum Flags { Carry = 1, } #[allow(non_snake_case)] -pub struct Cpu { +pub struct Registers { pub A: u8, pub X: u8, pub Y: u8, pub PC: u16, pub flags: u8, } -impl Cpu { +impl Registers { pub fn test(&self, flag: Flags) -> bool { (self.flags & flag as u8) != 0 } @@ -46,7 +46,7 @@ impl Cpu { self.A = value; } } -impl std::default::Default for Cpu { +impl std::default::Default for Registers { fn default() -> Self { Self { A: 0x00, @@ -57,7 +57,7 @@ impl std::default::Default for Cpu { } } } -impl std::fmt::Debug for Cpu { +impl std::fmt::Debug for Registers { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { write!( f, diff --git a/src/sixty_five/emulator.rs b/src/emulator/system.rs similarity index 68% rename from src/sixty_five/emulator.rs rename to src/emulator/system.rs index 564912d..3463b38 100644 --- a/src/sixty_five/emulator.rs +++ b/src/emulator/system.rs @@ -1,6 +1,6 @@ -use super::cpu::{Cpu, Flags}; use super::error; use super::opcodes; +use super::registers::{Flags, Registers}; use super::OpcodeType; use super::{addressing_modes::get_size, AddressingMode}; @@ -12,7 +12,7 @@ static RESET_VEC_ADDR: usize = 0xFFFC; macro_rules! fetch { ($self:ident PC+$off:expr) => { - $self.ram[$self.cpu.PC as usize + $off] + $self.ram[$self.registers.PC as usize + $off] }; ($self:ident $addr:expr) => { $self.ram[$addr as usize] @@ -23,48 +23,48 @@ macro_rules! fetch { } macro_rules! operation { ($self:ident A+$b:expr) => { - $self.cpu.A.wrapping_add($b as u8) + $self.registers.A.wrapping_add($b as u8) }; ($self:ident X+$b:expr) => { - $self.cpu.X.wrapping_add($b as u8) + $self.registers.X.wrapping_add($b as u8) }; (unwrap $arg:ident $addr:ident) => { $arg.unwrap_or_else(|| invalid_mode($addr.addr_mode)) }; } -pub struct Emulator { +pub struct System { pub cycles: usize, pub ram: [u8; 0x10000], - pub cpu: Cpu, + pub registers: Registers, } -impl Emulator { +impl System { pub fn new() -> Self { Self { cycles: 0, ram: [0x00; 0x10000], - cpu: Cpu::default(), + registers: Registers::default(), } } - pub fn init(&mut self) -> Result<(), error::EmulatorError> { + pub fn init(&mut self) -> Result<(), error::CpuError> { let lo: u16 = self.ram[RESET_VEC_ADDR] as u16; let hi: u16 = self.ram[RESET_VEC_ADDR + 1] as u16; let addr = hi << 8 | lo; - self.cpu.PC = addr; + self.registers.PC = addr; Ok(()) } - pub fn step(&mut self) -> Result<(), error::EmulatorError> { + pub fn step(&mut self) -> Result<(), error::CpuError> { if self.cycles == 0 { println!("Initializing"); self.init()?; } - if self.cpu.test(Flags::Break) { + /* if self.registers.test(Flags::Break) { return Err(error::EmulatorError::Break); - } - println!("Step on {:04X}", self.cpu.PC); - let code = self.ram[self.cpu.PC as usize]; + } */ + println!("Step on {:04X}", self.registers.PC); + let code = self.ram[self.registers.PC as usize]; let code = match opcodes::from_code(code) { - None => return Err(error::EmulatorError::UnknownOp(code)), + None => return Err(error::CpuError::UnknownOp(code)), Some(v) => v, }; println!(" Opcode {:?}", code.name); @@ -78,12 +78,12 @@ impl Emulator { } AddressingMode::ABS => { // Next 2 bytes are an address from where to fetch the real argument - let addr = self.cpu.PC as usize + 1; + let addr = self.registers.PC as usize + 1; Some(fetch!(self D addr) as u16) } AddressingMode::ZPG => { // Next byte is an address from the range 0x0000-0x00FF - let addr = self.cpu.PC as usize + 1; + let addr = self.registers.PC as usize + 1; Some(fetch!(self addr) as u16) } AddressingMode::INDX => { @@ -99,7 +99,7 @@ impl Emulator { AddressingMode::REL => { // Add PC with the next byte let arg = fetch!(self PC+1) as u8 as i8 as isize; - let pc = self.cpu.PC as usize as isize; + let pc = self.registers.PC as usize as isize; let new_pc = (arg + pc) & 0xFFFF; Some(new_pc as u16) } @@ -112,39 +112,49 @@ impl Emulator { match code.name { OpcodeType::BRK => { println!("Stepped on break. Ending"); - println!("{:#?}", self.cpu); - return Err(error::EmulatorError::Break); + println!("{:#?}", self.registers); + /* return Err(error::EmulatorError::Break); */ } OpcodeType::NOP => {} OpcodeType::LDA => match code.addr_mode { - AddressingMode::IMM => self.cpu.set_a(operation!(unwrap arg code) as u8), - AddressingMode::ABS => self.cpu.set_a(fetch!(self operation!(unwrap arg code))), - AddressingMode::ZPG => self.cpu.set_a(fetch!(self operation!(unwrap arg code))), + AddressingMode::IMM => self.registers.set_a(operation!(unwrap arg code) as u8), + AddressingMode::ABS => self + .registers + .set_a(fetch!(self operation!(unwrap arg code))), + AddressingMode::ZPG => self + .registers + .set_a(fetch!(self operation!(unwrap arg code))), _ => panic!("Invalid addressing mode for {:?}", code.name), }, OpcodeType::STA => match code.addr_mode { - AddressingMode::ABS => self.ram[operation!(unwrap arg code) as usize] = self.cpu.A, - AddressingMode::ZPG => self.ram[operation!(unwrap arg code) as usize] = self.cpu.A, - AddressingMode::INDX => self.ram[operation!(unwrap arg code) as usize] = self.cpu.A, + AddressingMode::ABS => { + self.ram[operation!(unwrap arg code) as usize] = self.registers.A + } + AddressingMode::ZPG => { + self.ram[operation!(unwrap arg code) as usize] = self.registers.A + } + AddressingMode::INDX => { + self.ram[operation!(unwrap arg code) as usize] = self.registers.A + } _ => panic!("Invalid addressing mode for {:?}", code.name), }, OpcodeType::ADC => match code.addr_mode { - AddressingMode::IMM => self.cpu.add_a(operation!(unwrap arg code) as u8), + AddressingMode::IMM => self.registers.add_a(operation!(unwrap arg code) as u8), _ => panic!("Invalid addressing mode for {:?}", code.name), }, OpcodeType::JMP => match code.addr_mode { - AddressingMode::ABS => self.cpu.PC = operation!(unwrap arg code) as u16, + AddressingMode::ABS => self.registers.PC = operation!(unwrap arg code) as u16, _ => panic!("Invalid addressing mode for {:?}", code.name), }, OpcodeType::BEQ if code.addr_mode == AddressingMode::REL => { - if self.cpu.test(Flags::Zero) { - self.cpu.PC = operation!(unwrap arg code); + if self.registers.test(Flags::Zero) { + self.registers.PC = operation!(unwrap arg code); branch_taken = true; } } OpcodeType::BNE if code.addr_mode == AddressingMode::REL => { - if !self.cpu.test(Flags::Zero) { - self.cpu.PC = operation!(unwrap arg code); + if !self.registers.test(Flags::Zero) { + self.registers.PC = operation!(unwrap arg code); branch_taken = true; } } @@ -159,7 +169,7 @@ impl Emulator { if branch_taken || code.name == OpcodeType::JMP { println!("Don't increment PC"); } else { - self.cpu.PC += get_size(code.addr_mode) as u16; + self.registers.PC += get_size(code.addr_mode) as u16; } self.cycles += 1; Ok(()) @@ -167,15 +177,15 @@ impl Emulator { pub fn restart(&mut self) { self.cycles = 0; self.ram = [0x00; 0x10000]; - self.cpu = Cpu::default(); + self.registers = Registers::default(); } } mod test { #[test] fn test_flags() { - use super::{Cpu, Flags}; - let mut cpu: Cpu = Cpu::default(); + use super::{Flags, Registers}; + let mut cpu: Registers = Registers::default(); cpu.set_flag(Flags::Zero, true); assert_eq!(cpu.test(Flags::Zero), true); cpu.set_flag(Flags::Zero, false); diff --git a/src/error.rs b/src/error.rs index 77f35aa..0a2dc3c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,4 +21,4 @@ macro_rules! prog_err { }; } -prog_err!(glib::BoolError, crate::sixty_five::error::EmulatorError); +prog_err!(glib::BoolError); diff --git a/src/handler.rs b/src/handler.rs new file mode 100644 index 0000000..8faa36d --- /dev/null +++ b/src/handler.rs @@ -0,0 +1,107 @@ +use crate::emulator::{CpuError, System}; +use std::sync::mpsc; +use std::sync::{Arc, Mutex}; +use std::thread; + +static TEST_CODE: &'static [u8; 0x10000] = include_bytes!("color.hex"); + +/* #region Commands */ +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum Cmd { + Step, + Run, + Stop, + Get(GetType), + Reset, +} +impl std::convert::From<&str> for Cmd { + fn from(text: &str) -> Self { + match text { + "Step" => Self::Step, + "Run" => Self::Run, + "Stop" => Self::Stop, + "Reset" => Self::Reset, + _ => panic!("???"), + } + } +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum GetType { + Range(usize, usize), + Value(usize), + Flags, +} +/* #endregion */ + +pub struct ThreadedEmulator { + pub tcmd: mpsc::Sender, + pub rdata: glib::Receiver>, + pub system: Arc>, + pub thread: thread::JoinHandle>, +} +impl ThreadedEmulator { + pub fn new() -> Self { + let (tcmd, rcmd) = mpsc::channel::(); + let (tdata, rdata) = glib::MainContext::channel(glib::source::Priority::default()); + let system = Arc::from(Mutex::from(System::new())); + let thread = { + let system = system.clone(); + thread::spawn(move || Self::thread(rcmd, tdata, system)) + }; + Self { + tcmd, + rdata, + system, + thread, + } + } + + fn thread( + rcmd: mpsc::Receiver, + tdata: glib::Sender>, + system: Arc>, + ) -> Result<(), CpuError> { + loop { + if let Ok(cmd) = rcmd.recv() { + let mut system = system.lock().unwrap_or_else(|e| { + panic!("Error acquiring lock for the system. Error: {}", e) + }); + println!("Cmd: {:?}", cmd); + match cmd { + Cmd::Step => system.step()?, + Cmd::Reset => { + system.restart(); + system.ram = *TEST_CODE; + } + Cmd::Run => loop { + if let Err(e) = rcmd.recv_timeout(std::time::Duration::from_millis(1)) { + if e == std::sync::mpsc::RecvTimeoutError::Timeout { + system.step()?; + } else { + panic!("Controller mpsc disconnected: {}", e) + } + } else { + break; + } + }, + Cmd::Get(what) => match what { + GetType::Flags => {} + GetType::Range(start, end) => { + let data = &system.ram[start..end]; + tdata + .send(Vec::from(data)) + .expect("Couldn't send requested value"); + } + GetType::Value(addr) => { + tdata + .send(vec![system.ram[addr]]) + .expect("Couldn't send requested value"); + } + }, + _ => {} + }; + } + } + } +} diff --git a/src/main.rs b/src/main.rs index ed8798b..790c315 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,87 +6,81 @@ use gio::prelude::*; use gtk::prelude::*; use gtk::Builder; -mod sixty_five; -use sixty_five::Emulator; +mod emulator; mod graphic; +mod handler; use graphic::{Color, Image}; +use handler::{Cmd, ThreadedEmulator}; -#[derive(Copy, Clone, Debug, PartialEq)] -enum Cmd { - Step, - Run, - Stop, - Reset, -} -impl std::convert::From<&str> for Cmd { - fn from(text: &str) -> Self { - match text { - "Step" => Self::Step, - "Run" => Self::Run, - "Stop" => Self::Stop, - "Reset" => Self::Reset, - _ => panic!("???"), - } - } +macro_rules! gtk_rs { + ($builder:expr=>$name:expr) => { + $builder + .get_object($name) + .unwrap_or_else(|| panic!("Object {} could't be found", $name)) + }; } pub fn init(app: >k::Application) -> Result<(), ProgErr> { - let img = Image::new(); - let (img_width, img_height) = (img.width, img.height); use std::sync::{Arc, Mutex}; - let img_m = Arc::from(Mutex::from(img)); - let palette = Arc::from(Mutex::from([Color::default(); 16])); + let img_m = Arc::from(Mutex::from(Image::new())); + let palette: Arc> = Arc::from(Mutex::from([Color::default(); 16])); - // Handle emulator CMDs - let (tcmd, rcmd) = std::sync::mpsc::channel::(); - let (tdata, rdata) = glib::MainContext::channel(glib::source::Priority::default()); - let emulator = Arc::from(Mutex::from(Emulator::new())); - { - let emulator = emulator.clone(); - std::thread::spawn(move || loop { - if let Ok(cmd) = rcmd.recv() { - let mut emulator = match emulator.try_lock() { - Err(_) => continue, - Ok(v) => v, - }; - match cmd { - Cmd::Step => { - if let Err(e) = emulator.step() { - println!("{:#?}", e); - } - } - Cmd::Reset => { - emulator.restart(); - emulator.ram = *include_bytes!("color.hex"); - } - Cmd::Run => loop { - if let Ok(_) = rcmd.recv_timeout(std::time::Duration::from_millis(1)) { - break; - } else { - if let Err(e) = emulator.step() { - println!("Emulator error: {:?}", e); - break; - } - println!("Tick {}", emulator.cycles); - let page_02 = Vec::from(&emulator.ram[0x200..0x300]); - tdata.send(page_02); - } - }, - _ => {} - }; - println!("Tick {}", emulator.cycles); - let page_02 = Vec::from(&emulator.ram[0x200..0x300]); - tdata.send(page_02); - } - }); - } + let emulator = ThreadedEmulator::new(); + /* + // Handle emulator CMDs + let (tcmd, rcmd) = std::sync::mpsc::channel::(); + let (tdata, rdata) = glib::MainContext::channel(glib::source::Priority::default()); + let emulator = Arc::from(Mutex::from(System::new())); + { + let emulator = emulator.clone(); + std::thread::spawn(move || loop { + if let Ok(cmd) = rcmd.recv() { + if let Ok(mut emulator) = emulator.try_lock() { + match cmd { + Cmd::Step => { + if let Err(e) = emulator.step() { + println!("{:#?}", e); + } + } + Cmd::Reset => { + emulator.restart(); + emulator.ram = *include_bytes!("color.hex"); + } + Cmd::Run => loop { + if let Ok(_) = rcmd.recv_timeout(std::time::Duration::from_millis(1)) { + break; + } else { + if let Err(e) = emulator.step() { + println!("Emulator error: {:?}", e); + break; + } + println!("Tick {}", emulator.cycles); + let page_02 = Vec::from(&emulator.ram[0x200..0x300]); + tdata.send(page_02); + } + }, + _ => {} + }; + println!("Tick {}", emulator.cycles); + let page_02 = Vec::from(&emulator.ram[0x200..0x300]); + tdata.send(page_02); + } else { + continue; + } + } + }); + } + + + + */ let builder: Builder = Builder::new_from_string(include_str!("ui.glade")); - let window: gtk::ApplicationWindow = builder.get_object("Window").unwrap(); - let drawing_area: gtk::DrawingArea = builder.get_object("Display").unwrap(); - let drawing_area = Arc::from(drawing_area); + //let window: Option = builder.get_object("Window"); + let window: gtk::ApplicationWindow = gtk_rs!(builder=>"Window"); + let drawing_area: gtk::DrawingArea = gtk_rs!(builder=>"Display"); + //let drawing_area = Arc::from(drawing_area); { - drawing_area.set_size_request(img_width as i32, img_height as i32); let img_m = img_m.clone(); drawing_area.connect_draw( move |drawing_area: >k::DrawingArea, ctx: &cairo::Context| { @@ -102,20 +96,20 @@ pub fn init(app: >k::Application) -> Result<(), ProgErr> { } for widget_name in &["Step", "Reset", "Run", "Stop"] { - let tcmd_clone = tcmd.clone(); - let widget: gtk::Button = builder.get_object(widget_name).expect("Not found"); + let tcmd = emulator.tcmd.clone(); + let widget: gtk::Button = gtk_rs!(builder=>widget_name); // builder.get_object(widget_name).expect("Not found"); widget.connect_clicked(move |s: >k::Button| { let name = s.get_widget_name().unwrap(); let name = name.as_str(); println!("Sending from {}", name); - tcmd_clone.send(Cmd::from(name)).expect("Couldn't send cmd"); + tcmd.send(Cmd::from(name)).expect("Couldn't send cmd"); }); } // Ram Display - { - let ram_display_window: gtk::Window = builder.get_object("RamDisplayWindow").unwrap(); - let switch: gtk::Switch = builder.get_object("RamDisplay").expect("Not Found"); + /* { + let ram_display_window: gtk::Window = gtk_rs!(builder=>"RamDisplayWindow"); // builder.get_object().unwrap(); + let switch: gtk::Switch = gtk_rs!(builder=>"RamDisplay"); // builder.get_object().expect("Not Found"); switch.connect_state_set(move |switch: >k::Switch, state: bool| { if state { ram_display_window.show_all(); @@ -126,19 +120,17 @@ pub fn init(app: >k::Application) -> Result<(), ProgErr> { Inhibit(false) }); - let ram_list: gtk::Window = builder.get_object("RamList").unwrap(); - } + let ram_list: gtk::Window = gtk_rs!(builder=>"RamList"); + } */ - let registers: gtk::Label = builder.get_object("Registers").unwrap(); - let registers = Mutex::from(registers); + let registers: gtk::Label = gtk_rs!(builder=>"Registers"); // Receive GPU page { let drawing_area = drawing_area.clone(); let palette = palette.clone(); - let emulator = emulator.clone(); let img_m = img_m.clone(); - rdata.attach(None, move |data: Vec<_>| { + emulator.rdata.attach(None, move |data: Vec<_>| { println!("Received page"); for line in data.chunks(16) { println!( @@ -159,10 +151,9 @@ pub fn init(app: >k::Application) -> Result<(), ProgErr> { } } } - if let Ok(registers) = registers.try_lock() { - if let Ok(emulator) = emulator.try_lock() { - registers.set_text(&format!("{:#?}", emulator.cpu)); - } + + if let Ok(system) = emulator.system.try_lock() { + registers.set_text(&format!("{:#?}", system.registers)); } drawing_area.queue_draw(); glib::Continue(true) @@ -174,8 +165,8 @@ pub fn init(app: >k::Application) -> Result<(), ProgErr> { for i in 0..16 { let drawing_area = drawing_area.clone(); let palette = palette.clone(); - let color_button: gtk::ColorButton = - builder.get_object(&format!("ColorPalette{}", i)).unwrap(); + let color_button = &format!("ColorPalette{}", i); + let color_button: gtk::ColorButton = gtk_rs!(builder=>color_button); color_button.connect_color_set(move |s: >k::ColorButton| { let color = s.get_rgba(); let color = Color::from((color.red, color.green, color.blue)); @@ -190,13 +181,14 @@ pub fn init(app: >k::Application) -> Result<(), ProgErr> { window.set_application(Some(app)); window.show_all(); + Ok(()) } fn main() -> Result<(), ProgErr> { let app: gtk::Application = gtk::Application::new(Some("com.ducklings_corp.emulator"), Default::default())?; - app.connect_activate(move |app| init(app).expect("Init failed")); + app.connect_activate(|app| init(app).expect("Init failed")); app.run(&std::env::args().collect::>()); Ok(()) } diff --git a/src/sixty_five/error.rs b/src/sixty_five/error.rs deleted file mode 100644 index 1ea0bb6..0000000 --- a/src/sixty_five/error.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::boxed::Box; -use std::error::Error; -use std::fmt::{Display, Error as FmtError, Formatter}; - -#[derive(Debug)] -pub enum EmulatorError { - UnknownOp(u8), - Break, - Suberror(Box), -} - -impl Display for EmulatorError { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { - write!( - f, - "Emulator Error: {}", - match self { - EmulatorError::Suberror(e) => e.description().to_string(), - EmulatorError::Break => "Emulator Terminated".to_string(), - EmulatorError::UnknownOp(code) => format!("Unknown OP with code {:02X}", code), - } - ) - } -} -impl Error for EmulatorError {}