diff --git a/src/cpu.rs b/src/cpu.rs index 1d718fa..bc5a1ca 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -427,7 +427,7 @@ impl I8080 { self.update_arith_flags(ac, cy, res); self.regs.a = res; } - }, + } Opcode::AnaM => (), Opcode::Ana(src) => { self.regs.a &= self.regs[src]; @@ -455,32 +455,32 @@ impl I8080 { Opcode::Rlc => { self.regs.a = self.regs.a.rotate_left(1); self.carry = (self.regs.a & 0x1) > 0; - }, + } Opcode::Rrc => { self.regs.a = self.regs.a.rotate_right(1); self.carry = (self.regs.a & 0x80) > 0; - }, + } Opcode::Ral => { let high_bit = (self.regs.a & 0x80) > 0; self.regs.a <<= 1; self.regs.a |= u8::from(self.carry); self.carry = high_bit; - }, + } Opcode::Rar => { let low_bit = (self.regs.a & 0x1) > 0; self.regs.a >>= 1; self.regs.a |= u8::from(self.carry) << 7; self.carry = low_bit; - }, + } Opcode::Cma => { self.regs.a = !self.regs.a; - }, + } Opcode::Cmc => { self.carry = !self.carry; - }, + } Opcode::Stc => { self.carry = true; - }, + } Opcode::Jmp => (), Opcode::Jcc(cc) => { cond_failed = !self.check_cond(cc); @@ -532,7 +532,7 @@ impl I8080 { } Opcode::Hlt => { self.halted = true; - }, + } Opcode::Nop => (), } } diff --git a/src/cpu/opcode_table.rs b/src/cpu/opcode_table.rs index 2287ed4..4c813d1 100644 --- a/src/cpu/opcode_table.rs +++ b/src/cpu/opcode_table.rs @@ -1,6 +1,12 @@ use super::opcode::{ Condition, - Opcode::{self, Aci, Adc, AdcM, Add, AddM, Adi, Ana, AnaM, Ani, Call, Ccc, Cma, Cmc, Cmp, CmpM, Cpi, Daa, Dad, Dcr, DcrM, Dcx, Di, Ei, Hlt, In, Inr, InrM, Inx, Jcc, Jmp, Lda, Ldax, Lhld, Lxi, Mov, MovMR, MovRM, Mvi, MviM, Nop, Ora, OraM, Ori, Out, Pchl, Pop, PopPsw, Push, PushPsw, Ral, Rar, Rcc, Ret, Rlc, Rrc, Rst, Sbb, SbbM, Sbi, Shld, Sphl, Sta, Stax, Stc, Sub, SubM, Sui, Xchg, Xra, XraM, Xri, Xthl}, + Opcode::{ + self, Aci, Adc, AdcM, Add, AddM, Adi, Ana, AnaM, Ani, Call, Ccc, Cma, Cmc, Cmp, CmpM, Cpi, + Daa, Dad, Dcr, DcrM, Dcx, Di, Ei, Hlt, In, Inr, InrM, Inx, Jcc, Jmp, Lda, Ldax, Lhld, Lxi, + Mov, MovMR, MovRM, Mvi, MviM, Nop, Ora, OraM, Ori, Out, Pchl, Pop, PopPsw, Push, PushPsw, + Ral, Rar, Rcc, Ret, Rlc, Rrc, Rst, Sbb, SbbM, Sbi, Shld, Sphl, Sta, Stax, Stc, Sub, SubM, + Sui, Xchg, Xra, XraM, Xri, Xthl, + }, Register, RegisterPair, }; pub(super) static OPCODE_TABLE: [Opcode; 256] = [ diff --git a/src/frontpanel.rs b/src/frontpanel.rs new file mode 100644 index 0000000..5a2a8f4 --- /dev/null +++ b/src/frontpanel.rs @@ -0,0 +1 @@ +pub mod switch; diff --git a/src/frontpanel/switch.rs b/src/frontpanel/switch.rs new file mode 100644 index 0000000..2efe345 --- /dev/null +++ b/src/frontpanel/switch.rs @@ -0,0 +1,79 @@ +use eframe::{ + egui::{Id, Sense, Widget}, + epaint::{pos2, vec2, Color32, Rect, TextureHandle}, +}; + +const NULL_UV: Rect = Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)); +const NULL_TINT: Color32 = Color32::WHITE; + +pub struct Textures { + sw_up: TextureHandle, + sw_neut: TextureHandle, + sw_down: TextureHandle, +} + +impl Textures { + pub fn new(sw_up: TextureHandle, sw_neut: TextureHandle, sw_down: TextureHandle) -> Self { + Self { + sw_up, + sw_neut, + sw_down, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum SwitchState { + Up, + Neut, + Down, +} + +pub struct Switch<'a> { + state: &'a mut SwitchState, + textures: &'a Textures, +} + +impl<'a> Switch<'a> { + pub fn new(state: &'a mut SwitchState, textures: &'a Textures) -> Self { + Self { state, textures } + } +} + +impl Widget for Switch<'_> { + fn ui(self, ui: &mut eframe::egui::Ui) -> eframe::egui::Response { + let (resp, painter) = ui.allocate_painter((32.0, 32.0).into(), Sense::click()); + let id = Id::new(( + painter.clip_rect().left_top().x as u32, + painter.clip_rect().left_top().y as u32, + )); + let texture = match self.state { + SwitchState::Up => self.textures.sw_up.id(), + SwitchState::Neut => self.textures.sw_neut.id(), + SwitchState::Down => self.textures.sw_down.id(), + }; + painter.image( + texture, + Rect::from_min_size(painter.clip_rect().left_top(), vec2(32.0, 32.0)), + NULL_UV, + NULL_TINT, + ); + let pointer_state = ui.ctx().input(|inp| inp.pointer.clone()); + let interact_pos = pointer_state.interact_pos(); + dbg!(interact_pos); + let interacted = interact_pos.map(|interact_pos| { + Rect::from_center_size(interact_pos, (10.0, 24.0).into()).contains(painter.clip_rect().left_top()) + }).unwrap_or(false); + let newstate = if interacted { + if interact_pos.unwrap().y > painter.clip_rect().left_top().y { + SwitchState::Down + } else { + SwitchState::Up + } + } else { + SwitchState::Neut + }; + *self.state = newstate; + resp + } +} diff --git a/src/main.rs b/src/main.rs index 970fd62..7d1ae4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod card; mod cpu; +mod frontpanel; mod ram; use std::{ @@ -11,7 +12,10 @@ use std::{ use cpu::{MemCycle, Status, I8080}; use device_query::{DeviceState, Keycode}; -use eframe::{egui::{self, menu, Button, Pos2, Rect, TextureHandle, TextureOptions, Ui}, NativeOptions}; +use eframe::{ + egui::{self, menu, Button, Pos2, Rect, TextureHandle, TextureOptions, Ui}, + NativeOptions, +}; use egui_modal::Modal; use log::{debug, trace, warn}; use parking_lot::Mutex; @@ -20,6 +24,8 @@ use rfd::FileDialog; use serde::{Deserialize, Serialize}; use soloud::{audio, AudioExt, LoadExt, Soloud}; +use crate::frontpanel::switch; + #[derive(Clone, Debug)] enum AudioMessage { PlaySwitchClick, @@ -182,7 +188,7 @@ struct AltairEmulator { runstop: SwitchState, single_step: SwitchState, exam: SwitchState, - dep: SwitchState, + dep: switch::SwitchState, reset: SwitchState, prot: SwitchState, aux1: SwitchState, @@ -253,7 +259,7 @@ impl AltairEmulator { runstop: SwitchState::Neut, single_step: SwitchState::Neut, exam: SwitchState::Neut, - dep: SwitchState::Neut, + dep: switch::SwitchState::Neut, reset: SwitchState::Neut, prot: SwitchState::Neut, aux1: SwitchState::Neut, @@ -291,7 +297,7 @@ impl AltairEmulator { MemCycle::In(a) => { self.fp_address = a; self.fp_data = 0; - }, + } MemCycle::Inta(_) => todo!(), MemCycle::Hlta(_) => { self.fp_data = 0xff; @@ -339,11 +345,16 @@ impl eframe::App for AltairEmulator { if ui.button("Load binary file").clicked() { let ihex_exts = ["hex", "mcs", "int", "ihex", "ihe", "ihx"]; let file = FileDialog::new() - .add_filter("Binary files", &["bin", "img", "hex", "mcs", "int", "ihex", "ihe", "ihx"]) + .add_filter( + "Binary files", + &["bin", "img", "hex", "mcs", "int", "ihex", "ihe", "ihx"], + ) .add_filter("All files", &["*"]) .pick_file(); if let Some(file) = file { - if file.extension().map_or(false, |ext| ihex_exts.contains(&ext.to_str().unwrap_or(""))) { + if file.extension().map_or(false, |ext| { + ihex_exts.contains(&ext.to_str().unwrap_or("")) + }) { let data = std::fs::read_to_string(file).unwrap(); for record in ihex::Reader::new(&data) { let record = record.unwrap(); @@ -352,7 +363,7 @@ impl eframe::App for AltairEmulator { for (i, &byte) in value.iter().enumerate() { self.mem[offset as usize + i] = byte; } - }, + } ihex::Record::StartLinearAddress(_) => todo!(), _ => unimplemented!(), }; @@ -367,357 +378,364 @@ impl eframe::App for AltairEmulator { }); }); egui::CentralPanel::default().show(ctx, |ui| { - let (_, fp_rect) = ui.allocate_space((800.0, 333.0).into()); - image_topleft(fp_rect.left_top(), &self.textures.fp, ui); - for led in &LEDS { - let led_data = match led.source { - LedSource::Protect => 0x0, - LedSource::Iff => 0x0, - LedSource::Run => 0x0, - LedSource::CpuStatus => u16::from(self.fp_status.bits()), - LedSource::Data => u16::from(self.fp_data), - LedSource::Address => self.fp_address, - }; - let led_on = (led_data & led.mask) > 0; - let texture = if led_on { - &self.textures.led_on - } else { - &self.textures.led_off - }; - image_center(led.pos + fp_rect.left_top().to_vec2(), texture, ui); - } - let pointer_state = ctx.input(|inp| inp.pointer.clone()); - let interact_pos = pointer_state.interact_pos(); - let mut switch_clicked = false; - for (i, switch) in SWITCHES.iter().enumerate() { - let pos = switch.pos + fp_rect.left_top().to_vec2(); - fn bool_to_texture(state: bool, textures: &Textures) -> &TextureHandle { - if state { - &textures.sw_up - } else { - &textures.sw_down - } - } - fn state_to_texture(state: SwitchState, textures: &Textures) -> &TextureHandle { - match state { - SwitchState::Up => &textures.sw_up, - SwitchState::Neut => &textures.sw_neut, - SwitchState::Down => &textures.sw_down, - } - } - let texture = match i { - 0 => bool_to_texture(!self.power, &self.textures), - (1..=16) => { - bool_to_texture((self.ad_sws & (1 << (16 - i))) > 0, &self.textures) - } - 17 => state_to_texture(self.runstop, &self.textures), - 18 => state_to_texture(self.single_step, &self.textures), - 19 => state_to_texture(self.exam, &self.textures), - 20 => state_to_texture(self.dep, &self.textures), - 21 => state_to_texture(self.reset, &self.textures), - 22 => state_to_texture(self.prot, &self.textures), - 23 => state_to_texture(self.aux1, &self.textures), - 24 => state_to_texture(self.aux2, &self.textures), - _ => unreachable!(), - }; - image_center(pos, texture, ui); - let interacted = interact_pos.map(|interact_pos| { - Rect::from_center_size(interact_pos, (10.0, 24.0).into()).contains(pos) - && !disable_fp_sws - }); - if pointer_state.primary_clicked() && interacted.unwrap() { - match i { - 0 => { - switch_clicked = true; - self.power = !self.power; - if self.options.fan_enabled { - self.fan_audio_tx.send(self.power).unwrap(); - } - if self.power { - self.cpu = I8080::new(); - self.update_fp(); - } else { - self.running = false; - self.fp_status = Status::empty(); - self.fp_data = 0; - self.fp_address = 0; - } - } - (1..=16) => { - switch_clicked = true; - if (self.ad_sws & (1 << (16 - i))) > 0 { - self.ad_sws &= !(1 << (16 - i)); - } else { - self.ad_sws |= 1 << (16 - i); - } - } - _ => (), - } - } - if pointer_state.primary_down() && interacted.unwrap() { - if (17..=24).contains(&i) && self.mouse_newdown { - switch_clicked = true; - } - let newstate = if interact_pos.unwrap().y > pos.y { - SwitchState::Down - } else { - SwitchState::Up - }; - match i { - 17 => self.runstop = newstate, - 18 => self.single_step = newstate, - 19 => self.exam = newstate, - 20 => self.dep = newstate, - 21 => self.reset = newstate, - 22 => self.prot = newstate, - 23 => self.aux1 = newstate, - 24 => self.aux2 = newstate, - _ => (), - } - } else { - match i { - 17 => self.runstop = SwitchState::Neut, - 18 => self.single_step = SwitchState::Neut, - 19 => self.exam = SwitchState::Neut, - 20 => self.dep = SwitchState::Neut, - 21 => self.reset = SwitchState::Neut, - 22 => self.prot = SwitchState::Neut, - 23 => self.aux1 = SwitchState::Neut, - 24 => self.aux2 = SwitchState::Neut, - _ => (), - } - } - } - if !disable_fp_sws { - let mut kbd_ad = None; - let pressed_keys = self.device_state.query_keymap(); - if pressed_keys - .iter() - .filter(|&&k| k != Keycode::LShift && k != Keycode::RShift) - .count() - != 0 - { - if self.kbd_newdown { - self.kbd_olddown = true; - self.kbd_newdown = false; - } else if !self.kbd_newdown && !self.kbd_olddown { - self.kbd_newdown = true; - } - } else { - self.kbd_newdown = false; - self.kbd_olddown = false; - } - if self.kbd_newdown { - if pressed_keys.contains(&Keycode::W) - || pressed_keys.contains(&Keycode::E) - || pressed_keys.contains(&Keycode::R) - || pressed_keys.contains(&Keycode::T) - || pressed_keys.contains(&Keycode::Y) - || pressed_keys.contains(&Keycode::U) - || pressed_keys.contains(&Keycode::I) - || pressed_keys.contains(&Keycode::O) - || pressed_keys.contains(&Keycode::S) - || pressed_keys.contains(&Keycode::D) - || pressed_keys.contains(&Keycode::F) - || pressed_keys.contains(&Keycode::G) - || pressed_keys.contains(&Keycode::H) - || pressed_keys.contains(&Keycode::J) - || pressed_keys.contains(&Keycode::K) - || pressed_keys.contains(&Keycode::L) - { - switch_clicked = true; - } - if pressed_keys.contains(&Keycode::LShift) - || pressed_keys.contains(&Keycode::RShift) - { - if pressed_keys.contains(&Keycode::Key1) { - kbd_ad = Some(15); - } else if pressed_keys.contains(&Keycode::Key2) { - kbd_ad = Some(14); - } else if pressed_keys.contains(&Keycode::Key3) { - kbd_ad = Some(13); - } else if pressed_keys.contains(&Keycode::Key4) { - kbd_ad = Some(12); - } else if pressed_keys.contains(&Keycode::Key5) { - kbd_ad = Some(11); - } else if pressed_keys.contains(&Keycode::Key6) { - kbd_ad = Some(10); - } else if pressed_keys.contains(&Keycode::Key7) { - kbd_ad = Some(9); - } else if pressed_keys.contains(&Keycode::Key8) { - kbd_ad = Some(8); - } - } else { - if pressed_keys.contains(&Keycode::Key1) { - kbd_ad = Some(7); - } else if pressed_keys.contains(&Keycode::Key2) { - kbd_ad = Some(6); - } else if pressed_keys.contains(&Keycode::Key3) { - kbd_ad = Some(5); - } else if pressed_keys.contains(&Keycode::Key4) { - kbd_ad = Some(4); - } else if pressed_keys.contains(&Keycode::Key5) { - kbd_ad = Some(3); - } else if pressed_keys.contains(&Keycode::Key6) { - kbd_ad = Some(2); - } else if pressed_keys.contains(&Keycode::Key7) { - kbd_ad = Some(1); - } else if pressed_keys.contains(&Keycode::Key8) { - kbd_ad = Some(0); - } - if pressed_keys.contains(&Keycode::Q) { - switch_clicked = true; - self.power = !self.power; - if self.options.fan_enabled { - self.fan_audio_tx.send(self.power).unwrap(); - } - if self.power { - self.cpu = I8080::new(); - self.update_fp(); - } else { - self.running = false; - self.fp_status = Status::empty(); - self.fp_data = 0; - self.fp_address = 0; - } - } - } - } - if pressed_keys.contains(&Keycode::W) { - self.runstop = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::E) { - self.single_step = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::R) { - self.exam = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::T) { - self.dep = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::Y) { - self.reset = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::U) { - self.prot = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::I) { - self.aux1 = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::O) { - self.aux2 = SwitchState::Up; - } - if pressed_keys.contains(&Keycode::S) { - self.runstop = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::D) { - self.single_step = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::F) { - self.exam = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::G) { - self.dep = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::H) { - self.reset = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::J) { - self.prot = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::K) { - self.aux1 = SwitchState::Down; - } - if pressed_keys.contains(&Keycode::L) { - self.aux2 = SwitchState::Down; - } - if let Some(kbd_ad) = kbd_ad { - switch_clicked = true; - if (self.ad_sws & (1 << kbd_ad)) > 0 { - self.ad_sws &= !(1 << kbd_ad); - } else { - self.ad_sws |= 1 << kbd_ad; - } - } - } - if switch_clicked { - self.main_audio_tx - .send(AudioMessage::PlaySwitchClick) - .unwrap(); - } - if pointer_state.primary_down() { - if self.mouse_newdown { - self.mouse_olddown = true; - self.mouse_newdown = false; - } else if !self.mouse_newdown && !self.mouse_olddown { - self.mouse_newdown = true; - } - } else { - self.mouse_newdown = false; - self.mouse_olddown = false; - } - if switch_clicked && self.power { - if !self.running { - if self.exam == SwitchState::Up { - // Assume M1 - self.cpu.finish_m_cycle(0xC3); // JMP - self.cpu.finish_m_cycle(self.ad_sws as u8); - self.cpu.finish_m_cycle((self.ad_sws >> 8) as u8); - self.update_fp(); - } - if self.exam == SwitchState::Down { - // Assume M1 - self.cpu.finish_m_cycle(0x0); // NOP - self.update_fp(); - } - if self.dep == SwitchState::Up { - // Assume M1 - self.mem[self.cpu.get_mem_cycle().address() as usize] = self.ad_sws as u8; - self.update_fp(); - } - if self.dep == SwitchState::Down { - // Assume M1 - self.cpu.finish_m_cycle(0x0); // NOP - self.mem[self.cpu.get_mem_cycle().address() as usize] = self.ad_sws as u8; - self.update_fp(); - } - } - if self.runstop == SwitchState::Up { - self.running = false; - } - if self.runstop == SwitchState::Down { - self.running = true; - } - if self.reset == SwitchState::Up { - self.cpu.reset(); - self.update_fp(); - } - } - if ((switch_clicked && self.single_step != SwitchState::Neut) || self.running) - && self.power - { - let cycle = self.cpu.get_mem_cycle(); - let data = match cycle { - MemCycle::Fetch(a) | MemCycle::Read(a) | MemCycle::StackRead(a) => { - self.mem[a as usize] - } - MemCycle::Write(a, d) | MemCycle::StackWrite(a, d) => { - self.mem[a as usize] = d; - 0 - } - MemCycle::In(_) => 0, - MemCycle::Out(_, _) => 0, - MemCycle::Inta(_) => todo!(), - MemCycle::Hlta(_) => { - self.running = false; - 0 - } - MemCycle::IntaHlt(_) => todo!(), - }; - self.cpu.finish_m_cycle(data); - self.update_fp(); - } + // let (_, fp_rect) = ui.allocate_space((800.0, 333.0).into()); + // image_topleft(fp_rect.left_top(), &self.textures.fp, ui); + // for led in &LEDS { + // let led_data = match led.source { + // LedSource::Protect => 0x0, + // LedSource::Iff => 0x0, + // LedSource::Run => 0x0, + // LedSource::CpuStatus => u16::from(self.fp_status.bits()), + // LedSource::Data => u16::from(self.fp_data), + // LedSource::Address => self.fp_address, + // }; + // let led_on = (led_data & led.mask) > 0; + // let texture = if led_on { + // &self.textures.led_on + // } else { + // &self.textures.led_off + // }; + // image_center(led.pos + fp_rect.left_top().to_vec2(), texture, ui); + // } + // let pointer_state = ctx.input(|inp| inp.pointer.clone()); + // let interact_pos = pointer_state.interact_pos(); + // let mut switch_clicked = false; + // fn bool_to_texture(state: bool, textures: &Textures) -> &TextureHandle { + // if state { + // &textures.sw_up + // } else { + // &textures.sw_down + // } + // } + // fn state_to_texture(state: SwitchState, textures: &Textures) -> &TextureHandle { + // match state { + // SwitchState::Up => &textures.sw_up, + // SwitchState::Neut => &textures.sw_neut, + // SwitchState::Down => &textures.sw_down, + // } + // } + // for (i, switch) in SWITCHES.iter().enumerate() { + // let pos = switch.pos + fp_rect.left_top().to_vec2(); + // let texture = match i { + // 0 => bool_to_texture(!self.power, &self.textures), + // (1..=16) => { + // bool_to_texture((self.ad_sws & (1 << (16 - i))) > 0, &self.textures) + // } + // 17 => state_to_texture(self.runstop, &self.textures), + // 18 => state_to_texture(self.single_step, &self.textures), + // 19 => state_to_texture(self.exam, &self.textures), + // 20 => state_to_texture(self.dep, &self.textures), + // 21 => state_to_texture(self.reset, &self.textures), + // 22 => state_to_texture(self.prot, &self.textures), + // 23 => state_to_texture(self.aux1, &self.textures), + // 24 => state_to_texture(self.aux2, &self.textures), + // _ => unreachable!(), + // }; + // image_center(pos, texture, ui); + // let interacted = interact_pos.map(|interact_pos| { + // Rect::from_center_size(interact_pos, (10.0, 24.0).into()).contains(pos) + // && !disable_fp_sws + // }); + // if pointer_state.primary_clicked() && interacted.unwrap() { + // match i { + // 0 => { + // switch_clicked = true; + // self.power = !self.power; + // if self.options.fan_enabled { + // self.fan_audio_tx.send(self.power).unwrap(); + // } + // if self.power { + // self.cpu = I8080::new(); + // self.update_fp(); + // } else { + // self.running = false; + // self.fp_status = Status::empty(); + // self.fp_data = 0; + // self.fp_address = 0; + // } + // } + // (1..=16) => { + // switch_clicked = true; + // if (self.ad_sws & (1 << (16 - i))) > 0 { + // self.ad_sws &= !(1 << (16 - i)); + // } else { + // self.ad_sws |= 1 << (16 - i); + // } + // } + // _ => (), + // } + // } + // if pointer_state.primary_down() && interacted.unwrap() { + // if (17..=24).contains(&i) && self.mouse_newdown { + // switch_clicked = true; + // } + // let newstate = if interact_pos.unwrap().y > pos.y { + // SwitchState::Down + // } else { + // SwitchState::Up + // }; + // match i { + // 17 => self.runstop = newstate, + // 18 => self.single_step = newstate, + // 19 => self.exam = newstate, + // 20 => self.dep = newstate, + // 21 => self.reset = newstate, + // 22 => self.prot = newstate, + // 23 => self.aux1 = newstate, + // 24 => self.aux2 = newstate, + // _ => (), + // } + // } else { + // match i { + // 17 => self.runstop = SwitchState::Neut, + // 18 => self.single_step = SwitchState::Neut, + // 19 => self.exam = SwitchState::Neut, + // 20 => self.dep = SwitchState::Neut, + // 21 => self.reset = SwitchState::Neut, + // 22 => self.prot = SwitchState::Neut, + // 23 => self.aux1 = SwitchState::Neut, + // 24 => self.aux2 = SwitchState::Neut, + // _ => (), + // } + // } + // } + // if !disable_fp_sws { + // let mut kbd_ad = None; + // let pressed_keys = self.device_state.query_keymap(); + // if pressed_keys + // .iter() + // .filter(|&&k| k != Keycode::LShift && k != Keycode::RShift) + // .count() + // != 0 + // { + // if self.kbd_newdown { + // self.kbd_olddown = true; + // self.kbd_newdown = false; + // } else if !self.kbd_newdown && !self.kbd_olddown { + // self.kbd_newdown = true; + // } + // } else { + // self.kbd_newdown = false; + // self.kbd_olddown = false; + // } + // if self.kbd_newdown { + // if pressed_keys.contains(&Keycode::W) + // || pressed_keys.contains(&Keycode::E) + // || pressed_keys.contains(&Keycode::R) + // || pressed_keys.contains(&Keycode::T) + // || pressed_keys.contains(&Keycode::Y) + // || pressed_keys.contains(&Keycode::U) + // || pressed_keys.contains(&Keycode::I) + // || pressed_keys.contains(&Keycode::O) + // || pressed_keys.contains(&Keycode::S) + // || pressed_keys.contains(&Keycode::D) + // || pressed_keys.contains(&Keycode::F) + // || pressed_keys.contains(&Keycode::G) + // || pressed_keys.contains(&Keycode::H) + // || pressed_keys.contains(&Keycode::J) + // || pressed_keys.contains(&Keycode::K) + // || pressed_keys.contains(&Keycode::L) + // { + // switch_clicked = true; + // } + // if pressed_keys.contains(&Keycode::LShift) + // || pressed_keys.contains(&Keycode::RShift) + // { + // if pressed_keys.contains(&Keycode::Key1) { + // kbd_ad = Some(15); + // } else if pressed_keys.contains(&Keycode::Key2) { + // kbd_ad = Some(14); + // } else if pressed_keys.contains(&Keycode::Key3) { + // kbd_ad = Some(13); + // } else if pressed_keys.contains(&Keycode::Key4) { + // kbd_ad = Some(12); + // } else if pressed_keys.contains(&Keycode::Key5) { + // kbd_ad = Some(11); + // } else if pressed_keys.contains(&Keycode::Key6) { + // kbd_ad = Some(10); + // } else if pressed_keys.contains(&Keycode::Key7) { + // kbd_ad = Some(9); + // } else if pressed_keys.contains(&Keycode::Key8) { + // kbd_ad = Some(8); + // } + // } else { + // if pressed_keys.contains(&Keycode::Key1) { + // kbd_ad = Some(7); + // } else if pressed_keys.contains(&Keycode::Key2) { + // kbd_ad = Some(6); + // } else if pressed_keys.contains(&Keycode::Key3) { + // kbd_ad = Some(5); + // } else if pressed_keys.contains(&Keycode::Key4) { + // kbd_ad = Some(4); + // } else if pressed_keys.contains(&Keycode::Key5) { + // kbd_ad = Some(3); + // } else if pressed_keys.contains(&Keycode::Key6) { + // kbd_ad = Some(2); + // } else if pressed_keys.contains(&Keycode::Key7) { + // kbd_ad = Some(1); + // } else if pressed_keys.contains(&Keycode::Key8) { + // kbd_ad = Some(0); + // } + // if pressed_keys.contains(&Keycode::Q) { + // switch_clicked = true; + // self.power = !self.power; + // if self.options.fan_enabled { + // self.fan_audio_tx.send(self.power).unwrap(); + // } + // if self.power { + // self.cpu = I8080::new(); + // self.update_fp(); + // } else { + // self.running = false; + // self.fp_status = Status::empty(); + // self.fp_data = 0; + // self.fp_address = 0; + // } + // } + // } + // } + // if pressed_keys.contains(&Keycode::W) { + // self.runstop = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::E) { + // self.single_step = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::R) { + // self.exam = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::T) { + // self.dep = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::Y) { + // self.reset = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::U) { + // self.prot = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::I) { + // self.aux1 = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::O) { + // self.aux2 = SwitchState::Up; + // } + // if pressed_keys.contains(&Keycode::S) { + // self.runstop = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::D) { + // self.single_step = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::F) { + // self.exam = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::G) { + // self.dep = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::H) { + // self.reset = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::J) { + // self.prot = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::K) { + // self.aux1 = SwitchState::Down; + // } + // if pressed_keys.contains(&Keycode::L) { + // self.aux2 = SwitchState::Down; + // } + // if let Some(kbd_ad) = kbd_ad { + // switch_clicked = true; + // if (self.ad_sws & (1 << kbd_ad)) > 0 { + // self.ad_sws &= !(1 << kbd_ad); + // } else { + // self.ad_sws |= 1 << kbd_ad; + // } + // } + // } + // if switch_clicked { + // self.main_audio_tx + // .send(AudioMessage::PlaySwitchClick) + // .unwrap(); + // } + // if pointer_state.primary_down() { + // if self.mouse_newdown { + // self.mouse_olddown = true; + // self.mouse_newdown = false; + // } else if !self.mouse_newdown && !self.mouse_olddown { + // self.mouse_newdown = true; + // } + // } else { + // self.mouse_newdown = false; + // self.mouse_olddown = false; + // } + // if switch_clicked && self.power { + // if !self.running { + // if self.exam == SwitchState::Up { + // // Assume M1 + // self.cpu.finish_m_cycle(0xC3); // JMP + // self.cpu.finish_m_cycle(self.ad_sws as u8); + // self.cpu.finish_m_cycle((self.ad_sws >> 8) as u8); + // self.update_fp(); + // } + // if self.exam == SwitchState::Down { + // // Assume M1 + // self.cpu.finish_m_cycle(0x0); // NOP + // self.update_fp(); + // } + // if self.dep == SwitchState::Up { + // // Assume M1 + // self.mem[self.cpu.get_mem_cycle().address() as usize] = self.ad_sws as u8; + // self.update_fp(); + // } + // if self.dep == SwitchState::Down { + // // Assume M1 + // self.cpu.finish_m_cycle(0x0); // NOP + // self.mem[self.cpu.get_mem_cycle().address() as usize] = self.ad_sws as u8; + // self.update_fp(); + // } + // } + // if self.runstop == SwitchState::Up { + // self.running = false; + // } + // if self.runstop == SwitchState::Down { + // self.running = true; + // } + // if self.reset == SwitchState::Up { + // self.cpu.reset(); + // self.update_fp(); + // } + // } + // if ((switch_clicked && self.single_step != SwitchState::Neut) || self.running) + // && self.power + // { + // let cycle = self.cpu.get_mem_cycle(); + // let data = match cycle { + // MemCycle::Fetch(a) | MemCycle::Read(a) | MemCycle::StackRead(a) => { + // self.mem[a as usize] + // } + // MemCycle::Write(a, d) | MemCycle::StackWrite(a, d) => { + // self.mem[a as usize] = d; + // 0 + // } + // MemCycle::In(_) => 0, + // MemCycle::Out(_, _) => 0, + // MemCycle::Inta(_) => todo!(), + // MemCycle::Hlta(_) => { + // self.running = false; + // 0 + // } + // MemCycle::IntaHlt(_) => todo!(), + // }; + // self.cpu.finish_m_cycle(data); + // self.update_fp(); + // } + let sw_texts = switch::Textures::new( + self.textures.sw_up.clone(), + self.textures.sw_neut.clone(), + self.textures.sw_down.clone(), + ); + ui.add(switch::Switch::new(&mut self.dep, &sw_texts)); }); + let old_fan_enabled = self.options.fan_enabled; if let Some(option_window) = self.option_window.as_mut() { if option_window.draw(ctx, &mut self.options) {