logicsim 0.1.7

composable, modular, digital logic simulation
Documentation
use num_enum::TryFromPrimitive;
pub const OPCODE_LENGTH: u32 = 8;
pub const DATA_LENGTH: u32 = 8;
#[repr(u8)]
#[derive(
    Debug, Eq, PartialEq, EnumIter, Copy, Clone, TryFromPrimitive, EnumCount, Ord, PartialOrd, Hash,
)]
pub enum InstructionType {
    // Do nothing
    NOP = 0,
    // Load register A from ram address.
    LDA,
    // Load register B from ram address.
    LDB,
    // Load register A with immediate value.
    LIA,
    // Load register B with immediate value.
    LIB,
    // Load register A with the contents of ram pointed to by register B.
    LDR,
    // Store register A at the address in register B.
    STR,
    // Store register A at the immediate address.
    STI,
    // Swap the contents of register A and B.
    SWP,
    // Add the contents of register A and B and save the result in register A.
    ADD,
    // Subtracts the contents of register B from A and save the result in register A.
    SUB,
    // Load the result of the alu to the output register.
    OUT,
    // If there is new content in the input register, load it into register A and jump to the immediate address.
    // otherwise NOP
    IN,
    // Set the program counter to address.
    JMP,
    // Set the program counter to the contents of register B.
    JMR,
    // Set the program counter to address if register A is zero.
    JZ,
}
impl InstructionType {
    pub fn with_data(&self, data: u8) -> Instruction {
        Instruction { ty: *self, data }
    }
    pub fn with_0(&self) -> Instruction {
        Instruction { ty: *self, data: 0 }
    }
}
impl Into<u16> for InstructionType {
    fn into(self) -> u16 {
        self.with_0().into()
    }
}

#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
pub struct Instruction {
    pub ty: InstructionType,
    pub data: u8,
}
impl Into<u16> for Instruction {
    fn into(self) -> u16 {
        self.ty as u16 | ((self.data as u16) << OPCODE_LENGTH)
    }
}