Work
This commit is contained in:
parent
1925720a71
commit
ac347f3613
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -135,6 +135,7 @@ dependencies = [
|
|||||||
"ron",
|
"ron",
|
||||||
"serde",
|
"serde",
|
||||||
"soloud",
|
"soloud",
|
||||||
|
"ux",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2632,6 +2633,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ux"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cb3ff47e36907a6267572c1e398ff32ef78ac5131de8aa272e53846592c207e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
@ -19,3 +19,4 @@ rand = "0.8.5"
|
|||||||
ron = "0.8.0"
|
ron = "0.8.0"
|
||||||
serde = { version = "1.0.171", features = ["derive"] }
|
serde = { version = "1.0.171", features = ["derive"] }
|
||||||
soloud = "1.0.2"
|
soloud = "1.0.2"
|
||||||
|
ux = "0.1.5"
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
|
use crate::ram::RamCard;
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use crate::ram::RamCard;
|
|
||||||
|
|
||||||
#[enum_dispatch(CardEnum)]
|
#[enum_dispatch(CardEnum)]
|
||||||
pub enum CardEnum {
|
pub enum CardEnum {
|
||||||
RamCard
|
RamCard,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait Card {
|
pub trait Card {
|
||||||
fn new(_settings: ron::Value) -> CardEnum;
|
fn new(_settings: ron::Value) -> CardEnum;
|
||||||
@ -28,5 +26,3 @@ pub trait Card {
|
|||||||
fn draw_settings_ui(&mut self, _ui: egui::Ui) {}
|
fn draw_settings_ui(&mut self, _ui: egui::Ui) {}
|
||||||
fn serialize_settings(&self) -> String;
|
fn serialize_settings(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
496
src/cpu.rs
496
src/cpu.rs
@ -8,8 +8,9 @@ use std::{
|
|||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use opcode_table::OPCODE_TABLE;
|
use opcode_table::OPCODE_TABLE;
|
||||||
|
use ux::{u4, u5};
|
||||||
|
|
||||||
use self::opcode::{Opcode, Register, RegisterPair};
|
use self::opcode::{Condition, Opcode, Register, RegisterPair};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
@ -188,6 +189,7 @@ pub struct I8080 {
|
|||||||
z: u8,
|
z: u8,
|
||||||
tmp: u8,
|
tmp: u8,
|
||||||
halted: bool,
|
halted: bool,
|
||||||
|
inte: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for I8080 {
|
impl Display for I8080 {
|
||||||
@ -224,12 +226,14 @@ impl I8080 {
|
|||||||
z: rand::random(),
|
z: rand::random(),
|
||||||
tmp: rand::random(),
|
tmp: rand::random(),
|
||||||
halted: rand::random(),
|
halted: rand::random(),
|
||||||
|
inte: rand::random(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.pc = 0;
|
self.pc = 0;
|
||||||
self.halted = false;
|
self.halted = false;
|
||||||
|
self.inte = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mem_cycle(&self) -> MemCycle {
|
pub fn get_mem_cycle(&self) -> MemCycle {
|
||||||
@ -250,7 +254,7 @@ impl I8080 {
|
|||||||
Opcode::Lhld => MemCycle::Read(self.pc),
|
Opcode::Lhld => MemCycle::Read(self.pc),
|
||||||
Opcode::Shld => MemCycle::Read(self.pc),
|
Opcode::Shld => MemCycle::Read(self.pc),
|
||||||
Opcode::Ldax(rp) => MemCycle::Read(self.get_pair(rp)),
|
Opcode::Ldax(rp) => MemCycle::Read(self.get_pair(rp)),
|
||||||
Opcode::Stax(rp) => MemCycle::Read(self.get_pair(rp)),
|
Opcode::Stax(rp) => MemCycle::Write(self.get_pair(rp), self.regs.a),
|
||||||
Opcode::Add(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::Add(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
Opcode::Adi => MemCycle::Read(self.pc),
|
Opcode::Adi => MemCycle::Read(self.pc),
|
||||||
Opcode::Adc(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::Adc(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
@ -259,8 +263,8 @@ impl I8080 {
|
|||||||
Opcode::Sui => MemCycle::Read(self.pc),
|
Opcode::Sui => MemCycle::Read(self.pc),
|
||||||
Opcode::Sbb(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::Sbb(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
Opcode::Sbi => MemCycle::Read(self.pc),
|
Opcode::Sbi => MemCycle::Read(self.pc),
|
||||||
Opcode::Inr(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::InrM => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
Opcode::Dcr(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::DcrM => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
Opcode::Ana(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::Ana(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
Opcode::Ani => MemCycle::Read(self.pc),
|
Opcode::Ani => MemCycle::Read(self.pc),
|
||||||
Opcode::Xra(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::Xra(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
@ -270,14 +274,13 @@ impl I8080 {
|
|||||||
Opcode::Cmp(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
Opcode::Cmp(_) => MemCycle::Read(self.get_pair(RegisterPair::HL)),
|
||||||
Opcode::Cpi => MemCycle::Read(self.pc),
|
Opcode::Cpi => MemCycle::Read(self.pc),
|
||||||
Opcode::Jmp => MemCycle::Read(self.pc),
|
Opcode::Jmp => MemCycle::Read(self.pc),
|
||||||
Opcode::Jcc(_) => MemCycle::Read(self.pc),
|
|
||||||
Opcode::Call => MemCycle::Read(self.pc),
|
Opcode::Call => MemCycle::Read(self.pc),
|
||||||
Opcode::Ccc(_) => MemCycle::Read(self.pc),
|
|
||||||
Opcode::Ret => MemCycle::Read(self.sp),
|
Opcode::Ret => MemCycle::Read(self.sp),
|
||||||
Opcode::Rcc(_) => MemCycle::StackRead(self.sp),
|
|
||||||
Opcode::Rst(_) => MemCycle::StackWrite(self.sp, (self.pc >> 8) as u8),
|
Opcode::Rst(_) => MemCycle::StackWrite(self.sp, (self.pc >> 8) as u8),
|
||||||
Opcode::Push(_) => MemCycle::StackRead(self.sp),
|
Opcode::Push(rp) => MemCycle::StackWrite(self.sp, (self.get_pair(rp) >> 8) as u8),
|
||||||
|
Opcode::PushPsw => MemCycle::StackWrite(self.sp, self.regs.a),
|
||||||
Opcode::Pop(_) => MemCycle::StackRead(self.sp),
|
Opcode::Pop(_) => MemCycle::StackRead(self.sp),
|
||||||
|
Opcode::PopPsw => MemCycle::StackRead(self.sp),
|
||||||
Opcode::Xthl => MemCycle::StackRead(self.sp),
|
Opcode::Xthl => MemCycle::StackRead(self.sp),
|
||||||
Opcode::In => MemCycle::Read(self.pc),
|
Opcode::In => MemCycle::Read(self.pc),
|
||||||
Opcode::Out => MemCycle::Read(self.pc),
|
Opcode::Out => MemCycle::Read(self.pc),
|
||||||
@ -290,15 +293,16 @@ impl I8080 {
|
|||||||
Opcode::Sta => MemCycle::Read(self.pc),
|
Opcode::Sta => MemCycle::Read(self.pc),
|
||||||
Opcode::Lhld => MemCycle::Read(self.pc),
|
Opcode::Lhld => MemCycle::Read(self.pc),
|
||||||
Opcode::Shld => MemCycle::Read(self.pc),
|
Opcode::Shld => MemCycle::Read(self.pc),
|
||||||
Opcode::Inr(_) => MemCycle::Write(self.get_pair(RegisterPair::HL), self.tmp),
|
Opcode::InrM => MemCycle::Write(self.get_pair(RegisterPair::HL), self.tmp),
|
||||||
Opcode::Dcr(_) => MemCycle::Write(self.get_pair(RegisterPair::HL), self.tmp),
|
Opcode::DcrM => MemCycle::Write(self.get_pair(RegisterPair::HL), self.tmp),
|
||||||
Opcode::Jmp => MemCycle::Read(self.pc),
|
Opcode::Jmp => MemCycle::Read(self.pc),
|
||||||
Opcode::Jcc(_) => MemCycle::Read(self.pc),
|
|
||||||
Opcode::Call => MemCycle::Read(self.pc),
|
Opcode::Call => MemCycle::Read(self.pc),
|
||||||
Opcode::Ccc(_) => MemCycle::Read(self.pc),
|
|
||||||
Opcode::Ret => MemCycle::StackRead(self.sp),
|
Opcode::Ret => MemCycle::StackRead(self.sp),
|
||||||
Opcode::Rcc(_) => MemCycle::StackRead(self.sp),
|
|
||||||
Opcode::Rst(_) => MemCycle::StackWrite(self.sp, 0),
|
Opcode::Rst(_) => MemCycle::StackWrite(self.sp, 0),
|
||||||
|
Opcode::Push(rp) => MemCycle::StackWrite(self.sp, self.get_pair(rp) as u8),
|
||||||
|
Opcode::PushPsw => MemCycle::StackWrite(self.sp, self.get_flags()),
|
||||||
|
Opcode::Pop(_) => MemCycle::StackRead(self.sp),
|
||||||
|
Opcode::PopPsw => MemCycle::StackRead(self.sp),
|
||||||
Opcode::Xthl => MemCycle::StackRead(self.sp),
|
Opcode::Xthl => MemCycle::StackRead(self.sp),
|
||||||
Opcode::In => MemCycle::In(self.get_wz()),
|
Opcode::In => MemCycle::In(self.get_wz()),
|
||||||
Opcode::Out => MemCycle::Out(self.get_wz(), self.regs.a),
|
Opcode::Out => MemCycle::Out(self.get_wz(), self.regs.a),
|
||||||
@ -310,7 +314,6 @@ impl I8080 {
|
|||||||
Opcode::Lhld => MemCycle::Read(self.get_wz()),
|
Opcode::Lhld => MemCycle::Read(self.get_wz()),
|
||||||
Opcode::Shld => MemCycle::Write(self.get_wz(), self.regs.l),
|
Opcode::Shld => MemCycle::Write(self.get_wz(), self.regs.l),
|
||||||
Opcode::Call => MemCycle::StackWrite(self.sp, (self.pc >> 8) as u8),
|
Opcode::Call => MemCycle::StackWrite(self.sp, (self.pc >> 8) as u8),
|
||||||
Opcode::Ccc(_) => MemCycle::StackWrite(self.sp, (self.pc >> 8) as u8),
|
|
||||||
Opcode::Xthl => MemCycle::StackWrite(self.sp, self.regs.h),
|
Opcode::Xthl => MemCycle::StackWrite(self.sp, self.regs.h),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
@ -335,6 +338,7 @@ impl I8080 {
|
|||||||
self.get_mem_cycle(),
|
self.get_mem_cycle(),
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
|
let mut cond_failed = false;
|
||||||
match self.cycle {
|
match self.cycle {
|
||||||
MCycle::M1 => {
|
MCycle::M1 => {
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
@ -351,7 +355,7 @@ impl I8080 {
|
|||||||
}
|
}
|
||||||
Opcode::MviM => (),
|
Opcode::MviM => (),
|
||||||
Opcode::Mvi(_) => (),
|
Opcode::Mvi(_) => (),
|
||||||
Opcode::Lxi(_) => (),
|
Opcode::Lxi(_) => {}
|
||||||
Opcode::Lda => (),
|
Opcode::Lda => (),
|
||||||
Opcode::Sta => (),
|
Opcode::Sta => (),
|
||||||
Opcode::Lhld => (),
|
Opcode::Lhld => (),
|
||||||
@ -364,30 +368,44 @@ impl I8080 {
|
|||||||
}
|
}
|
||||||
Opcode::AddM => (),
|
Opcode::AddM => (),
|
||||||
Opcode::Add(src) => {
|
Opcode::Add(src) => {
|
||||||
let a = self.regs.a;
|
let (ac, cy, res) = Self::add_8bit(self.regs.a, self.regs[src]);
|
||||||
let b = self.regs[src];
|
self.update_arith_flags(ac, cy, res);
|
||||||
let res = (a as u16) + (b as u16);
|
self.regs.a = res;
|
||||||
self.sign = ((res as u8) & 0x80) > 0;
|
|
||||||
self.zero = (res as u8) == 0;
|
|
||||||
self.aux_carry = (a & 0x0f) + (b & 0x0f) > 0x0f;
|
|
||||||
self.parity = (res as u8).count_ones() % 2 == 0;
|
|
||||||
self.carry = res > 0xff;
|
|
||||||
self.regs.a = res as u8;
|
|
||||||
}
|
}
|
||||||
Opcode::Adi => (),
|
Opcode::Adi => (),
|
||||||
Opcode::AdcM => (),
|
Opcode::AdcM => (),
|
||||||
Opcode::Adc(_) => todo!(),
|
Opcode::Adc(src) => {
|
||||||
|
let (ac, cy, res) = Self::adc_8bit(self.regs.a, self.regs[src], self.carry);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
Opcode::Aci => (),
|
Opcode::Aci => (),
|
||||||
Opcode::SubM => (),
|
Opcode::SubM => (),
|
||||||
Opcode::Sub(_) => todo!(),
|
Opcode::Sub(src) => {
|
||||||
|
let (ac, cy, res) = Self::sub_8bit(self.regs.a, self.regs[src]);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
Opcode::Sui => (),
|
Opcode::Sui => (),
|
||||||
Opcode::SbbM => (),
|
Opcode::SbbM => (),
|
||||||
Opcode::Sbb(_) => todo!(),
|
Opcode::Sbb(src) => {
|
||||||
|
let (ac, cy, res) = Self::sbb_8bit(self.regs.a, self.regs[src], self.carry);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
Opcode::Sbi => (),
|
Opcode::Sbi => (),
|
||||||
Opcode::InrM => (),
|
Opcode::InrM => (),
|
||||||
Opcode::Inr(_) => todo!(),
|
Opcode::Inr(src) => {
|
||||||
|
let (ac, _cy, res) = Self::add_8bit(self.regs[src], 1);
|
||||||
|
self.update_arith_flags(ac, self.carry, res);
|
||||||
|
self.regs[src] = res;
|
||||||
|
}
|
||||||
Opcode::DcrM => (),
|
Opcode::DcrM => (),
|
||||||
Opcode::Dcr(_) => todo!(),
|
Opcode::Dcr(src) => {
|
||||||
|
let (ac, _cy, res) = Self::sub_8bit(self.regs[src], 1);
|
||||||
|
self.update_arith_flags(ac, self.carry, res);
|
||||||
|
self.regs[src] = res;
|
||||||
|
}
|
||||||
Opcode::Inx(dst) => self.set_pair(dst, self.get_pair(dst) + 1),
|
Opcode::Inx(dst) => self.set_pair(dst, self.get_pair(dst) + 1),
|
||||||
Opcode::Dcx(dst) => self.set_pair(dst, self.get_pair(dst) + 2),
|
Opcode::Dcx(dst) => self.set_pair(dst, self.get_pair(dst) + 2),
|
||||||
Opcode::Dad(src) => {
|
Opcode::Dad(src) => {
|
||||||
@ -399,16 +417,28 @@ impl I8080 {
|
|||||||
}
|
}
|
||||||
Opcode::Daa => todo!(),
|
Opcode::Daa => todo!(),
|
||||||
Opcode::AnaM => (),
|
Opcode::AnaM => (),
|
||||||
Opcode::Ana(_) => todo!(),
|
Opcode::Ana(src) => {
|
||||||
|
self.regs.a &= self.regs[src];
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
}
|
||||||
Opcode::Ani => (),
|
Opcode::Ani => (),
|
||||||
Opcode::XraM => (),
|
Opcode::XraM => (),
|
||||||
Opcode::Xra(_) => todo!(),
|
Opcode::Xra(src) => {
|
||||||
|
self.regs.a ^= self.regs[src];
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
}
|
||||||
Opcode::Xri => (),
|
Opcode::Xri => (),
|
||||||
Opcode::OraM => (),
|
Opcode::OraM => (),
|
||||||
Opcode::Ora(_) => todo!(),
|
Opcode::Ora(src) => {
|
||||||
|
self.regs.a |= self.regs[src];
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
}
|
||||||
Opcode::Ori => (),
|
Opcode::Ori => (),
|
||||||
Opcode::CmpM => (),
|
Opcode::CmpM => (),
|
||||||
Opcode::Cmp(_) => todo!(),
|
Opcode::Cmp(src) => {
|
||||||
|
let (ac, cy, res) = Self::sub_8bit(self.regs.a, self.regs[src]);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
}
|
||||||
Opcode::Cpi => (),
|
Opcode::Cpi => (),
|
||||||
Opcode::Rlc => todo!(),
|
Opcode::Rlc => todo!(),
|
||||||
Opcode::Rrc => todo!(),
|
Opcode::Rrc => todo!(),
|
||||||
@ -418,20 +448,54 @@ impl I8080 {
|
|||||||
Opcode::Cmc => todo!(),
|
Opcode::Cmc => todo!(),
|
||||||
Opcode::Stc => todo!(),
|
Opcode::Stc => todo!(),
|
||||||
Opcode::Jmp => (),
|
Opcode::Jmp => (),
|
||||||
Opcode::Jcc(_) => todo!(),
|
Opcode::Jcc(cc) => {
|
||||||
Opcode::Call => todo!(),
|
cond_failed = !self.check_cond(cc);
|
||||||
Opcode::Ccc(_) => todo!(),
|
if cond_failed {
|
||||||
|
self.pc += 2;
|
||||||
|
}
|
||||||
|
self.opcode = Opcode::Jmp; // Identical after M1
|
||||||
|
}
|
||||||
|
Opcode::Call => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::Ccc(cc) => {
|
||||||
|
cond_failed = !self.check_cond(cc);
|
||||||
|
if cond_failed {
|
||||||
|
self.pc += 2;
|
||||||
|
} else {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
self.opcode = Opcode::Call; // Identical after M1
|
||||||
|
}
|
||||||
Opcode::Ret => (),
|
Opcode::Ret => (),
|
||||||
Opcode::Rcc(_) => todo!(),
|
Opcode::Rcc(cc) => {
|
||||||
Opcode::Rst(_) => todo!(),
|
cond_failed = !self.check_cond(cc);
|
||||||
Opcode::Pchl => todo!(),
|
self.opcode = Opcode::Ret; // Identical after M1
|
||||||
Opcode::Push(_) => todo!(),
|
}
|
||||||
|
Opcode::Rst(_) => {
|
||||||
|
self.w = 0;
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::Pchl => {
|
||||||
|
self.pc = self.get_pair(RegisterPair::HL);
|
||||||
|
}
|
||||||
|
Opcode::Push(_) => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::PushPsw => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
Opcode::Pop(_) => (),
|
Opcode::Pop(_) => (),
|
||||||
|
Opcode::PopPsw => (),
|
||||||
Opcode::Xthl => (),
|
Opcode::Xthl => (),
|
||||||
Opcode::In => (),
|
Opcode::In => (),
|
||||||
Opcode::Out => (),
|
Opcode::Out => (),
|
||||||
Opcode::Ei => todo!(),
|
Opcode::Ei => {
|
||||||
Opcode::Di => todo!(),
|
self.inte = false;
|
||||||
|
}
|
||||||
|
Opcode::Di => {
|
||||||
|
self.inte = false;
|
||||||
|
}
|
||||||
Opcode::Hlt => self.halted = true,
|
Opcode::Hlt => self.halted = true,
|
||||||
Opcode::Nop => (),
|
Opcode::Nop => (),
|
||||||
}
|
}
|
||||||
@ -446,7 +510,10 @@ impl I8080 {
|
|||||||
Opcode::Mvi(dst) => {
|
Opcode::Mvi(dst) => {
|
||||||
self.regs[dst] = data;
|
self.regs[dst] = data;
|
||||||
}
|
}
|
||||||
Opcode::Lxi(_) => todo!(),
|
Opcode::Lxi(_) => {
|
||||||
|
self.z = data;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
Opcode::Lda => {
|
Opcode::Lda => {
|
||||||
self.z = data;
|
self.z = data;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
@ -455,62 +522,159 @@ impl I8080 {
|
|||||||
self.z = data;
|
self.z = data;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
Opcode::Lhld => todo!(),
|
Opcode::Lhld => {
|
||||||
Opcode::Shld => todo!(),
|
self.z = data;
|
||||||
Opcode::Ldax(_) => todo!(),
|
self.pc += 1;
|
||||||
Opcode::Stax(_) => todo!(),
|
}
|
||||||
Opcode::AddM => {
|
Opcode::Shld => {
|
||||||
let a = self.regs.a;
|
self.z = data;
|
||||||
let b = data;
|
self.pc += 1;
|
||||||
let res = (a as u16) + (b as u16);
|
}
|
||||||
self.sign = ((res as u8) & 0x80) > 0;
|
Opcode::Ldax(_) => {
|
||||||
self.zero = (res as u8) == 0;
|
self.regs.a = data;
|
||||||
self.aux_carry = (a & 0x0f) + (b & 0x0f) > 0x0f;
|
}
|
||||||
self.parity = (res as u8).count_ones() % 2 == 0;
|
Opcode::Stax(_) => (),
|
||||||
self.carry = res > 0xff;
|
Opcode::AddM => {
|
||||||
self.regs.a = res as u8;
|
let (ac, cy, res) = Self::add_8bit(self.regs.a, data);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
|
Opcode::Adi => {
|
||||||
|
let (ac, cy, res) = Self::add_8bit(self.regs.a, data);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::AdcM => {
|
||||||
|
let (ac, cy, res) = Self::adc_8bit(self.regs.a, data, self.carry);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
|
Opcode::Aci => {
|
||||||
|
let (ac, cy, res) = Self::adc_8bit(self.regs.a, data, self.carry);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::SubM => {
|
||||||
|
let (ac, cy, res) = Self::sub_8bit(self.regs.a, data);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
|
Opcode::Sui => {
|
||||||
|
let (ac, cy, res) = Self::sub_8bit(self.regs.a, data);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::SbbM => {
|
||||||
|
let (ac, cy, res) = Self::sbb_8bit(self.regs.a, data, self.carry);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
}
|
||||||
|
Opcode::Sbi => {
|
||||||
|
let (ac, cy, res) = Self::sbb_8bit(self.regs.a, data, self.carry);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.regs.a = res;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::InrM => {
|
||||||
|
let (ac, _cy, res) = Self::add_8bit(data, 1);
|
||||||
|
self.update_arith_flags(ac, self.carry, self.tmp);
|
||||||
|
self.tmp = res;
|
||||||
|
}
|
||||||
|
Opcode::DcrM => {
|
||||||
|
let (ac, _cy, res) = Self::sub_8bit(data, 1);
|
||||||
|
self.update_arith_flags(ac, self.carry, self.tmp);
|
||||||
|
self.tmp = res;
|
||||||
|
}
|
||||||
|
Opcode::AnaM => {
|
||||||
|
self.regs.a &= data;
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
}
|
||||||
|
Opcode::Ani => {
|
||||||
|
self.regs.a &= data;
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::XraM => {
|
||||||
|
self.regs.a ^= data;
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
}
|
||||||
|
Opcode::Xri => {
|
||||||
|
self.regs.a ^= data;
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::OraM => {
|
||||||
|
self.regs.a |= data;
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
}
|
||||||
|
Opcode::Ori => {
|
||||||
|
self.regs.a ^= data;
|
||||||
|
self.update_logic_flags(self.regs.a);
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::CmpM => {
|
||||||
|
let (ac, cy, res) = Self::sub_8bit(self.regs.a, data);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
}
|
||||||
|
Opcode::Cpi => {
|
||||||
|
let (ac, cy, res) = Self::sub_8bit(self.regs.a, data);
|
||||||
|
self.update_arith_flags(ac, cy, res);
|
||||||
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
Opcode::Adi => todo!(),
|
|
||||||
Opcode::AdcM => todo!(),
|
|
||||||
Opcode::Aci => todo!(),
|
|
||||||
Opcode::SubM => todo!(),
|
|
||||||
Opcode::Sui => todo!(),
|
|
||||||
Opcode::SbbM => todo!(),
|
|
||||||
Opcode::Sbi => todo!(),
|
|
||||||
Opcode::InrM => todo!(),
|
|
||||||
Opcode::DcrM => todo!(),
|
|
||||||
Opcode::AnaM => todo!(),
|
|
||||||
Opcode::Ani => todo!(),
|
|
||||||
Opcode::XraM => todo!(),
|
|
||||||
Opcode::Xri => todo!(),
|
|
||||||
Opcode::OraM => todo!(),
|
|
||||||
Opcode::Ori => todo!(),
|
|
||||||
Opcode::CmpM => todo!(),
|
|
||||||
Opcode::Cpi => todo!(),
|
|
||||||
Opcode::Jmp => {
|
Opcode::Jmp => {
|
||||||
self.z = data;
|
self.z = data;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
Opcode::Jcc(_) => todo!(),
|
Opcode::Call => {
|
||||||
Opcode::Call => todo!(),
|
self.z = data;
|
||||||
Opcode::Ccc(_) => todo!(),
|
self.pc += 1;
|
||||||
Opcode::Ret => todo!(),
|
}
|
||||||
Opcode::Rcc(_) => todo!(),
|
Opcode::Ret => {
|
||||||
Opcode::Rst(_) => todo!(),
|
self.z = data;
|
||||||
Opcode::Push(_) => todo!(),
|
self.pc += 1;
|
||||||
Opcode::Pop(_) => todo!(),
|
}
|
||||||
|
Opcode::Rst(_) => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::Push(_) => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::PushPsw => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::Pop(_) => {
|
||||||
|
self.sp += 1;
|
||||||
|
self.z = data;
|
||||||
|
}
|
||||||
|
Opcode::PopPsw => {
|
||||||
|
self.sp += 1;
|
||||||
|
self.set_flags(data);
|
||||||
|
}
|
||||||
Opcode::Xthl => {
|
Opcode::Xthl => {
|
||||||
self.sp += 1;
|
self.sp += 1;
|
||||||
self.z = data;
|
self.z = data;
|
||||||
}
|
}
|
||||||
Opcode::In => todo!(),
|
Opcode::In => {
|
||||||
Opcode::Out => todo!(),
|
self.w = data;
|
||||||
Opcode::Hlt => todo!(),
|
self.z = data;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::Out => {
|
||||||
|
self.w = data;
|
||||||
|
self.z = data;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
MCycle::M3 => match self.opcode {
|
MCycle::M3 => match self.opcode {
|
||||||
Opcode::MviM => (),
|
Opcode::MviM => (),
|
||||||
Opcode::Lxi(_) => todo!(),
|
Opcode::Lxi(rp) => {
|
||||||
|
self.w = data;
|
||||||
|
self.set_pair(rp, self.get_wz());
|
||||||
|
}
|
||||||
Opcode::Lda => {
|
Opcode::Lda => {
|
||||||
self.w = data;
|
self.w = data;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
@ -519,22 +683,46 @@ impl I8080 {
|
|||||||
self.w = data;
|
self.w = data;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
Opcode::Lhld => todo!(),
|
Opcode::Lhld => {
|
||||||
Opcode::Shld => {
|
self.w = data;
|
||||||
self.set_wz(self.get_wz() + 1);
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
Opcode::Inr(_) => todo!(),
|
Opcode::Shld => {
|
||||||
Opcode::Dcr(_) => todo!(),
|
self.w = data;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::InrM => (),
|
||||||
|
Opcode::DcrM => (),
|
||||||
Opcode::Jmp => {
|
Opcode::Jmp => {
|
||||||
self.w = data;
|
self.w = data;
|
||||||
self.pc = self.get_wz();
|
self.pc = self.get_wz();
|
||||||
}
|
}
|
||||||
Opcode::Jcc(_) => todo!(),
|
Opcode::Call => {
|
||||||
Opcode::Call => todo!(),
|
self.w = data;
|
||||||
Opcode::Ccc(_) => todo!(),
|
self.pc += 1;
|
||||||
Opcode::Ret => todo!(),
|
}
|
||||||
Opcode::Rcc(_) => todo!(),
|
Opcode::Ret => {
|
||||||
Opcode::Rst(_) => todo!(),
|
self.w = data;
|
||||||
|
self.pc += 1;
|
||||||
|
}
|
||||||
|
Opcode::Rst(n) => {
|
||||||
|
self.z = n << 3;
|
||||||
|
self.pc = self.get_wz();
|
||||||
|
}
|
||||||
|
Opcode::Push(_) => (),
|
||||||
|
Opcode::PushPsw => (),
|
||||||
|
Opcode::Pop(rp) => {
|
||||||
|
self.sp += 1;
|
||||||
|
self.z = data;
|
||||||
|
self.set_pair(rp, self.get_wz());
|
||||||
|
}
|
||||||
|
Opcode::PopPsw => {
|
||||||
|
self.sp += 1;
|
||||||
|
self.regs.a = data;
|
||||||
|
}
|
||||||
|
Opcode::Xthl => {
|
||||||
|
self.w = data;
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
MCycle::M4 => match self.opcode {
|
MCycle::M4 => match self.opcode {
|
||||||
@ -542,21 +730,34 @@ impl I8080 {
|
|||||||
self.regs.a = data;
|
self.regs.a = data;
|
||||||
}
|
}
|
||||||
Opcode::Sta => (),
|
Opcode::Sta => (),
|
||||||
Opcode::Lhld => todo!(),
|
Opcode::Lhld => {
|
||||||
Opcode::Shld => todo!(),
|
self.set_wz(self.get_wz() + 1);
|
||||||
Opcode::Call => todo!(),
|
self.regs.l = data;
|
||||||
Opcode::Ccc(_) => todo!(),
|
}
|
||||||
Opcode::Xthl => (),
|
Opcode::Shld => {
|
||||||
|
self.set_wz(self.get_wz() + 1);
|
||||||
|
}
|
||||||
|
Opcode::Call => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
|
Opcode::Xthl => {
|
||||||
|
self.sp -= 1;
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
MCycle::M5 => match self.opcode {
|
MCycle::M5 => match self.opcode {
|
||||||
Opcode::Call => todo!(),
|
Opcode::Lhld => {
|
||||||
Opcode::Ccc(_) => todo!(),
|
self.regs.h = data;
|
||||||
Opcode::Xthl => (),
|
}
|
||||||
|
Opcode::Shld => (),
|
||||||
|
Opcode::Call => (),
|
||||||
|
Opcode::Xthl => {
|
||||||
|
self.set_pair(RegisterPair::HL, self.get_wz());
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if self.cycle == self.opcode.max_m_cycle() {
|
if self.cycle == self.opcode.max_m_cycle() || cond_failed {
|
||||||
println!("Instruction done");
|
println!("Instruction done");
|
||||||
self.cycle = MCycle::M1;
|
self.cycle = MCycle::M1;
|
||||||
} else {
|
} else {
|
||||||
@ -564,6 +765,73 @@ impl I8080 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn nibblize(n: u8) -> (u4, u4) {
|
||||||
|
(u4::new(n >> 4), u4::new(n & 0xF))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_nibbles(nh: u4, nl: u4) -> u8 {
|
||||||
|
(u8::from(nh) << 4) | u8::from(nl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_4bit(a: u4, b: u4, cy: bool) -> (bool, u4) {
|
||||||
|
let res: u5 = u5::from(a) + u5::from(b) + u5::new(cy as u8);
|
||||||
|
(
|
||||||
|
(res >> 4) > u5::new(0),
|
||||||
|
(res & u5::new(0xF)).try_into().unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_8bit(a: u8, b: u8) -> (bool, bool, u8) {
|
||||||
|
Self::adc_8bit(a, b, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adc_8bit(a: u8, b: u8, cy: bool) -> (bool, bool, u8) {
|
||||||
|
let (ah, al) = Self::nibblize(a);
|
||||||
|
let (bh, bl) = Self::nibblize(b);
|
||||||
|
let (ac, sl) = Self::add_4bit(al, bl, cy);
|
||||||
|
let (cy, sh) = Self::add_4bit(ah, bh, ac);
|
||||||
|
let sum = Self::join_nibbles(sh, sl);
|
||||||
|
(ac, cy, sum)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sub_8bit(a: u8, b: u8) -> (bool, bool, u8) {
|
||||||
|
Self::sbb_8bit(a, b, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sbb_8bit(a: u8, b: u8, cy: bool) -> (bool, bool, u8) {
|
||||||
|
let (ah, al) = Self::nibblize(a);
|
||||||
|
let (bh, bl) = Self::nibblize(!b);
|
||||||
|
let (ac, sl) = Self::add_4bit(al, bl, cy);
|
||||||
|
let (cy, sh) = Self::add_4bit(ah, bh, ac);
|
||||||
|
let sum = Self::join_nibbles(sh, sl);
|
||||||
|
(ac, cy, sum)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_logic_flags(&mut self, res: u8) {
|
||||||
|
self.update_arith_flags(false, false, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_arith_flags(&mut self, ac: bool, cy: bool, res: u8) {
|
||||||
|
self.sign = (res & 0x80) > 0;
|
||||||
|
self.zero = res == 0;
|
||||||
|
self.aux_carry = ac;
|
||||||
|
self.parity = res.count_ones() % 2 == 0;
|
||||||
|
self.carry = cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_cond(&self, cond: Condition) -> bool {
|
||||||
|
match cond {
|
||||||
|
Condition::NZ => !self.zero,
|
||||||
|
Condition::Z => self.zero,
|
||||||
|
Condition::NC => !self.carry,
|
||||||
|
Condition::C => self.carry,
|
||||||
|
Condition::PO => !self.parity,
|
||||||
|
Condition::PE => self.parity,
|
||||||
|
Condition::P => !self.sign,
|
||||||
|
Condition::M => self.sign,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_pair(&self, pair: RegisterPair) -> u16 {
|
fn get_pair(&self, pair: RegisterPair) -> u16 {
|
||||||
match pair {
|
match pair {
|
||||||
RegisterPair::BC => ((self.regs.b as u16) << 8) | (self.regs.c as u16),
|
RegisterPair::BC => ((self.regs.b as u16) << 8) | (self.regs.c as u16),
|
||||||
@ -599,4 +867,20 @@ impl I8080 {
|
|||||||
self.w = (val >> 8) as u8;
|
self.w = (val >> 8) as u8;
|
||||||
self.z = val as u8;
|
self.z = val as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_flags(&self) -> u8 {
|
||||||
|
0b10 | self.carry as u8
|
||||||
|
| (self.parity as u8) << 2
|
||||||
|
| (self.aux_carry as u8) << 4
|
||||||
|
| (self.zero as u8) << 6
|
||||||
|
| (self.sign as u8) << 7
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_flags(&mut self, flags: u8) {
|
||||||
|
self.carry = (flags & (1 << 0)) > 0;
|
||||||
|
self.parity = (flags & (1 << 2)) > 0;
|
||||||
|
self.aux_carry = (flags & (1 << 4)) > 0;
|
||||||
|
self.zero = (flags & (1 << 6)) > 0;
|
||||||
|
self.sign = (flags & (1 << 7)) > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ pub(super) enum RegisterPair {
|
|||||||
BC,
|
BC,
|
||||||
DE,
|
DE,
|
||||||
HL,
|
HL,
|
||||||
SP, // PSW for push/pop
|
SP,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
@ -95,7 +95,9 @@ pub(super) enum Opcode {
|
|||||||
Rst(u8),
|
Rst(u8),
|
||||||
Pchl,
|
Pchl,
|
||||||
Push(RegisterPair),
|
Push(RegisterPair),
|
||||||
|
PushPsw,
|
||||||
Pop(RegisterPair),
|
Pop(RegisterPair),
|
||||||
|
PopPsw,
|
||||||
Xthl,
|
Xthl,
|
||||||
In,
|
In,
|
||||||
Out,
|
Out,
|
||||||
@ -169,7 +171,9 @@ impl Opcode {
|
|||||||
Self::Rst(_) => MCycle::M3,
|
Self::Rst(_) => MCycle::M3,
|
||||||
Self::Pchl => MCycle::M1,
|
Self::Pchl => MCycle::M1,
|
||||||
Self::Push(_) => MCycle::M3,
|
Self::Push(_) => MCycle::M3,
|
||||||
|
Self::PushPsw => MCycle::M3,
|
||||||
Self::Pop(_) => MCycle::M3,
|
Self::Pop(_) => MCycle::M3,
|
||||||
|
Self::PopPsw => MCycle::M3,
|
||||||
Self::Xthl => MCycle::M5,
|
Self::Xthl => MCycle::M5,
|
||||||
Self::In => MCycle::M3,
|
Self::In => MCycle::M3,
|
||||||
Self::Out => MCycle::M3,
|
Self::Out => MCycle::M3,
|
||||||
|
@ -245,11 +245,11 @@ pub(super) static OPCODE_TABLE: [Opcode; 256] = [
|
|||||||
Xri,
|
Xri,
|
||||||
Rst(5),
|
Rst(5),
|
||||||
Rcc(Condition::P),
|
Rcc(Condition::P),
|
||||||
Pop(RegisterPair::SP), // Actually PSW
|
PopPsw,
|
||||||
Jcc(Condition::P),
|
Jcc(Condition::P),
|
||||||
Di,
|
Di,
|
||||||
Ccc(Condition::P),
|
Ccc(Condition::P),
|
||||||
Push(RegisterPair::SP), // Actually PSW
|
PushPsw,
|
||||||
Ori,
|
Ori,
|
||||||
Rst(6),
|
Rst(6),
|
||||||
Rcc(Condition::M),
|
Rcc(Condition::M),
|
||||||
|
66
src/main.rs
66
src/main.rs
@ -1,5 +1,5 @@
|
|||||||
mod cpu;
|
|
||||||
mod card;
|
mod card;
|
||||||
|
mod cpu;
|
||||||
mod ram;
|
mod ram;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@ -235,7 +235,7 @@ impl AltairEmulator {
|
|||||||
mem[0x10] = 0x4;
|
mem[0x10] = 0x4;
|
||||||
mem[0x11] = 0x5;
|
mem[0x11] = 0x5;
|
||||||
// 0: 072 020 000
|
// 0: 072 020 000
|
||||||
// 3: 107
|
// 3: 107
|
||||||
// 4: 072 021 000
|
// 4: 072 021 000
|
||||||
// 7: 200
|
// 7: 200
|
||||||
// 10: 062 022 000
|
// 10: 062 022 000
|
||||||
@ -482,6 +482,14 @@ impl eframe::App for AltairEmulator {
|
|||||||
|| pressed_keys.contains(&Keycode::U)
|
|| pressed_keys.contains(&Keycode::U)
|
||||||
|| pressed_keys.contains(&Keycode::I)
|
|| pressed_keys.contains(&Keycode::I)
|
||||||
|| pressed_keys.contains(&Keycode::O)
|
|| 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;
|
switch_clicked = true;
|
||||||
}
|
}
|
||||||
@ -541,36 +549,53 @@ impl eframe::App for AltairEmulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let newstate = if pressed_keys.contains(&Keycode::LShift)
|
|
||||||
|| pressed_keys.contains(&Keycode::RShift)
|
|
||||||
{
|
|
||||||
SwitchState::Down
|
|
||||||
} else {
|
|
||||||
SwitchState::Up
|
|
||||||
};
|
|
||||||
if pressed_keys.contains(&Keycode::W) {
|
if pressed_keys.contains(&Keycode::W) {
|
||||||
self.runstop = newstate;
|
self.runstop = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::E) {
|
if pressed_keys.contains(&Keycode::E) {
|
||||||
self.single_step = newstate;
|
self.single_step = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::R) {
|
if pressed_keys.contains(&Keycode::R) {
|
||||||
self.exam = newstate;
|
self.exam = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::T) {
|
if pressed_keys.contains(&Keycode::T) {
|
||||||
self.dep = newstate;
|
self.dep = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::Y) {
|
if pressed_keys.contains(&Keycode::Y) {
|
||||||
self.reset = newstate;
|
self.reset = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::U) {
|
if pressed_keys.contains(&Keycode::U) {
|
||||||
self.prot = newstate;
|
self.prot = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::I) {
|
if pressed_keys.contains(&Keycode::I) {
|
||||||
self.aux1 = newstate;
|
self.aux1 = SwitchState::Up;
|
||||||
}
|
}
|
||||||
if pressed_keys.contains(&Keycode::O) {
|
if pressed_keys.contains(&Keycode::O) {
|
||||||
self.aux2 = newstate;
|
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 {
|
if let Some(kbd_ad) = kbd_ad {
|
||||||
switch_clicked = true;
|
switch_clicked = true;
|
||||||
@ -688,7 +713,10 @@ enum OptionsCategory {
|
|||||||
impl OptionWindow {
|
impl OptionWindow {
|
||||||
fn new(ctx: &egui::Context, options: Options) -> Self {
|
fn new(ctx: &egui::Context, options: Options) -> Self {
|
||||||
Modal::new(ctx, "options_modal").open();
|
Modal::new(ctx, "options_modal").open();
|
||||||
Self { options, category: OptionsCategory::General }
|
Self {
|
||||||
|
options,
|
||||||
|
category: OptionsCategory::General,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn draw(&mut self, ctx: &egui::Context, options: &mut Options) -> bool {
|
fn draw(&mut self, ctx: &egui::Context, options: &mut Options) -> bool {
|
||||||
let modal = Modal::new(ctx, "options_modal");
|
let modal = Modal::new(ctx, "options_modal");
|
||||||
@ -701,7 +729,7 @@ impl OptionWindow {
|
|||||||
match self.category {
|
match self.category {
|
||||||
OptionsCategory::General => {
|
OptionsCategory::General => {
|
||||||
ui.checkbox(&mut self.options.fan_enabled, "Fan enabled");
|
ui.checkbox(&mut self.options.fan_enabled, "Fan enabled");
|
||||||
},
|
}
|
||||||
OptionsCategory::Cards => {
|
OptionsCategory::Cards => {
|
||||||
ui.heading("TODO");
|
ui.heading("TODO");
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::card::{Card, CardEnum};
|
use crate::card::{Card, CardEnum};
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ impl Card for RamCard {
|
|||||||
ram.resize(settings.size as usize, 0);
|
ram.resize(settings.size as usize, 0);
|
||||||
CardEnum::RamCard(Self {
|
CardEnum::RamCard(Self {
|
||||||
ram,
|
ram,
|
||||||
start_addr: settings.start_addr
|
start_addr: settings.start_addr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +27,7 @@ impl Card for RamCard {
|
|||||||
ron::to_string(&RamCardSettings {
|
ron::to_string(&RamCardSettings {
|
||||||
size: self.ram.len() as u16,
|
size: self.ram.len() as u16,
|
||||||
start_addr: self.start_addr,
|
start_addr: self.start_addr,
|
||||||
}).unwrap()
|
})
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user