working emulator UI - just need to implement the instruction set

This commit is contained in:
2025-06-15 00:39:08 +01:00
parent 68c8da4271
commit 4e9cc2849e
16 changed files with 5219 additions and 56 deletions
+187 -52
View File
@@ -1,7 +1,138 @@
type Offset = u16;
type Immediate = u16;
pub enum Interrupt {
Software(u8),
}
pub type Address = u32;
impl Interrupt {
fn as_u8(&self) -> u8 {
match self {
Interrupt::Software(code) => *code,
}
}
}
impl From<u8> for Interrupt {
fn from(_code: u8) -> Self {
todo!("implement this once a hardware interrupt convention is established");
#[allow(unreachable_code)]
Interrupt::Software(_code)
}
}
pub enum Register {
// general purpose registers
Rg0,
Rg1,
Rg2,
Rg3,
Rg4,
Rg5,
Rg6,
Rg7,
Rg8,
Rg9,
Rga,
Rgb,
Rgc,
Rgd,
Rge,
Rgf,
// special purpose registers
Acc,
Spr,
Bpr,
Ret,
Idr,
Mmr,
Zero,
None,
// system registers - can't be written to by instructions.
Mar,
Mdr,
Sts,
Cir,
Pcx,
}
impl From<u8> for Register {
fn from(idx: u8) -> Register {
match idx {
// system registers are not indexable in the reg file so they cannot be modified by instructions.
0x0 => Register::Rg0,
0x1 => Register::Rg1,
0x2 => Register::Rg2,
0x3 => Register::Rg3,
0x4 => Register::Rg4,
0x5 => Register::Rg5,
0x6 => Register::Rg6,
0x7 => Register::Rg7,
0x8 => Register::Rg8,
0x9 => Register::Rg9,
0xA => Register::Rga,
0xB => Register::Rgb,
0xC => Register::Rgc,
0xD => Register::Rgd,
0xE => Register::Rge,
0xF => Register::Rgf,
0x10 => Register::Acc,
0x11 => Register::Spr,
0x12 => Register::Bpr,
0x13 => Register::Ret,
0x14 => Register::Idr,
0x15 => Register::Mmr,
0x16 => Register::Zero,
0x17 => Register::None,
_ => panic!("invalid register"),
}
}
}
impl std::fmt::Display for Register {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Register::Rg0 => write!(f, "Rg0"),
Register::Rg1 => write!(f, "Rg1"),
Register::Rg2 => write!(f, "Rg2"),
Register::Rg3 => write!(f, "Rg3"),
Register::Rg4 => write!(f, "Rg4"),
Register::Rg5 => write!(f, "Rg5"),
Register::Rg6 => write!(f, "Rg6"),
Register::Rg7 => write!(f, "Rg7"),
Register::Rg8 => write!(f, "Rg8"),
Register::Rg9 => write!(f, "Rg9"),
Register::Rga => write!(f, "Rga"),
Register::Rgb => write!(f, "Rgb"),
Register::Rgc => write!(f, "Rgc"),
Register::Rgd => write!(f, "Rgd"),
Register::Rge => write!(f, "Rge"),
Register::Rgf => write!(f, "Rgf"),
Register::Acc => write!(f, "Acc"),
Register::Spr => write!(f, "Spr"),
Register::Bpr => write!(f, "Bpr"),
Register::Ret => write!(f, "Ret"),
Register::Idr => write!(f, "Idr"),
Register::Mmr => write!(f, "Mmr"),
Register::Zero => write!(f, "Zero"),
Register::None => write!(f, "None"),
Register::Mar => write!(f, "Mar"),
Register::Mdr => write!(f, "Mdr"),
Register::Sts => write!(f, "Sts"),
Register::Cir => write!(f, "Cir"),
Register::Pcx => write!(f, "Pcx"),
}
}
}
pub enum Instruction {
// No-op
Nop,
// Data transfer instructions
Mov(Register, Register),
MovSigned(Register, Register),
@@ -55,61 +186,65 @@ pub enum Instruction {
Halt,
}
type Offset = u16;
type Immediate = u16;
impl Instruction {
pub fn encode(&self) -> u32 {
todo!("imlement instruction encoding")
}
pub enum Interrupt {
Software(u8)
pub fn decode(data: u32) -> Self {
// TODO: this needs to actually decode something
Instruction::Nop
}
}
impl Into<u8> for Interrupt {
fn into(self) -> u8 {
impl std::fmt::Display for Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Interrupt::Software(code) => code,
Instruction::Nop => write!(f, "No Operation"),
Instruction::Mov(a, b) => write!(f, "MOV {}, {}", a, b),
Instruction::MovSigned(a, b) => write!(f, "MOVS {}, {}", a, b),
Instruction::LoadByte(a, b, c) => write!(f, "LDB {}, {}, {}", a, b, c),
Instruction::LoadByteSigned(a, b, c) => write!(f, "LDBS {}, {}, {}", a, b, c),
Instruction::LoadHalfword(a, b, c) => write!(f, "LDH {}, {}, {}", a, b, c),
Instruction::LoadHalfwordSigned(a, b, c) => write!(f, "LDHS {}, {}, {}", a, b, c),
Instruction::LoadWord(a, b, c) => write!(f, "LDW {}, {}, {}", a, b, c),
Instruction::LoadWordSigned(a, b, c) => write!(f, "LDWS {}, {}, {}", a, b, c),
Instruction::StoreByte(a, b, c) => write!(f, "STB {}, {}, {}", a, b, c),
Instruction::StoreHalfword(a, b, c) => write!(f, "STH {}, {}, {}", a, b, c),
Instruction::StoreWord(a, b, c) => write!(f, "STW {}, {}, {}", a, b, c),
Instruction::LoadLowerImmediate(a, b) => write!(f, "LLI {}, {}", a, b),
Instruction::LoadUpperImmediate(a, b) => write!(f, "LUI {}, {}", a, b),
Instruction::Jump(a, b) => write!(f, "JMP {}, {}", a, b),
Instruction::JumpEq(a, b) => write!(f, "JEQ {}, {}", a, b),
Instruction::JumpNeq(a, b) => write!(f, "JNEQ {}, {}", a, b),
Instruction::JumpGt(a, b) => write!(f, "JGT {}, {}", a, b),
Instruction::JumpGe(a, b) => write!(f, "JGE {}, {}", a, b),
Instruction::JumpLt(a, b) => write!(f, "JLT {}, {}", a, b),
Instruction::JumpLe(a, b) => write!(f, "JLE {}, {}", a, b),
Instruction::Compare(a, b) => write!(f, "CMP {}, {}", a, b),
Instruction::Add(a, b, c) => write!(f, "ADD {}, {}, {}", a, b, c),
Instruction::Sub(a, b, c) => write!(f, "SUB {}, {}, {}", a, b, c),
Instruction::Increment(a) => write!(f, "INC {}", a),
Instruction::Decrement(a) => write!(f, "DEC {}", a),
Instruction::ShiftLeft(a, b, c) => write!(f, "SHL {}, {}, {}", a, b, c),
Instruction::ShiftRight(a, b, c) => write!(f, "SHR {}, {}, {}", a, b, c),
Instruction::And(a, b, c) => write!(f, "AND {}, {}, {}", a, b, c),
Instruction::Or(a, b, c) => write!(f, "OR {}, {}, {}", a, b, c),
Instruction::Not(a, b) => write!(f, "NOT {}, {}", a, b),
Instruction::Xor(a, b, c) => write!(f, "XOR {}, {}, {}", a, b, c),
Instruction::Nand(a, b, c) => write!(f, "NAND {}, {}, {}", a, b, c),
Instruction::Nor(a, b, c) => write!(f, "NOR {}, {}, {}", a, b, c),
Instruction::Xnor(a, b, c) => write!(f, "XNOR {}, {}, {}", a, b, c),
Instruction::Interrupt(a) => write!(f, "INT {}", a.as_u8()),
Instruction::IntReturn => write!(f, "INTR"),
Instruction::Halt => write!(f, "HALT"),
}
}
}
impl From<u8> for Interrupt {
fn from(code: u8) -> Self {
todo!("implement this once a hardware interrupt convention is established");
Interrupt::Software(code)
}
}
pub enum Register {
// general purpose registers
Rg0,
Rg1,
Rg2,
Rg3,
Rg4,
Rg5,
Rg6,
Rg7,
Rg8,
Rg9,
Rg10,
Rg11,
Rg12,
Rg13,
Rg14,
Rg15,
// special purpose registers
Acc,
Spr,
Bpr,
Ret,
Idr,
Mmr,
Zero,
None,
// system registers - can't be written to by instructions.
Mar,
Mdr,
Sts,
Cir,
Pcx,
}