[][src]Enum pir_8_emu::micro::MicroOp

[]
pub enum MicroOp {
    Nop,
    Halt,
    LoadInstruction,
    AdrWrite,
    AdrRead,
    StackPush,
    StackPop,
    Alu(AluOperation),
    PortIn,
    PortOut,
    Compare,
    MakeImmediate(u8),
    LoadImmediate,
    FetchAddress,
    WriteAddress,
    CheckJumpCondition(InstructionJumpCondition),
    Jump,
    ReadRegister(u8),
    WriteRegister(u8),
}
[]

Actual μOps executable by the CPU

The approach is stack-based (think ComputerCraft or FORTH): bytes are individually pushed and popped onto the μstack (separate from the actual program stack), and there is no other storage.

Each high-level instruction deconstructs losslessly into up to six μOps, with the exception of reserved instructions, which are converted into 6 NOPs.

Variants

Nop
[]

Do nothing

Also to pad out the returned instruction

Halt
[]

Halt

LoadInstruction
[]

Load the top of the stack into INS

AdrWrite
[]

Write the address specified by the top two bytes of the μstack into ADR

AdrRead
[]

Read both bytes of ADR onto the μstack

StackPush
[]

Push a byte from the top of the μstack to the stack

StackPop
[]

Pop a byte from the stack to the μstack

Alu(AluOperation)
[]

Perform an ALU operation

PortIn
[]

Read a byte from the port specified at the top of the μstack

PortOut
[]

Write to the port specified at the top of the μstack a byte from the next byte on the μstack

Compare
[]

Execute the compare instruction with S at the top and the specified register as the next byte on the μstack

MakeImmediate(u8)
[]

Create an immediate value at the top of the μstack

LoadImmediate
[]

Read a 1-byte immediate from memory at PC to the top of the μstack, incrementing PC

FetchAddress
[]

Read the value from memory at ADR

WriteAddress
[]

Write to memory at ADR the byte on top of the μstack

CheckJumpCondition(InstructionJumpCondition)
[]

Check if the specified jump condition is satisfied by the top of the μstack

Jump
[]

If the top of the μstack is 1, set PC to ADR. If it's 0, do nothing. Otherwise, error out.

ReadRegister(u8)
[]

Read the specified register into the top of the μstack.

WriteRegister(u8)
[]

Write the top of the μstack to the specified register.

Methods

impl MicroOp[src][]

pub fn from_instruction(instr: Instruction) -> (MicroOpBlock, usize)[src][]

Get μOps corresponding to the given instruction

The return type is (ops, len), where &ops[..len] are the actual μOps and the rest is padding. This was done to reduce allocations.

Examples

let ops = MicroOp::from_instruction(Instruction::Move { qqq: 0b100, rrr: 0b101 });
let ops = &ops.0[..ops.1];

assert_eq!(ops, &[MicroOp::ReadRegister(0b100), MicroOp::WriteRegister(0b101)]);

impl MicroOp[src][]

pub fn perform(
    self,
    stack: &mut Vec<u8>,
    memory: &mut Memory,
    ports: &mut Ports,
    registers: &mut GeneralPurposeRegisterBank,
    pc: &mut SpecialPurposeRegister<u16>,
    sp: &mut SpecialPurposeRegister<u16>,
    adr: &mut SpecialPurposeRegister<u16>,
    ins: &mut SpecialPurposeRegister<u8>
) -> Result<bool, MicroOpPerformError>
[src][]

Perform this μOp

The Ok(..) return value indicates whether to continue execution (i.e. not halt)

Examples

memory[0x1A00] = 0x69;

let mut stack = vec![0x1A, 0x00];
assert_eq!(MicroOp::AdrWrite.perform(&mut stack, &mut memory, &mut ports, &mut registers,
                                     &mut pc, &mut sp, &mut adr, &mut ins),
           Ok(true));
assert_eq!(*adr, 0x1A00);
assert_eq!(stack, &[]);

assert_eq!(MicroOp::FetchAddress.perform(&mut stack, &mut memory, &mut ports, &mut registers,
                                         &mut pc, &mut sp, &mut adr, &mut ins),
           Ok(true));
assert_eq!(stack, &[0x69]);

assert_eq!(MicroOp::LoadInstruction.perform(&mut stack, &mut memory, &mut ports, &mut registers,
                                            &mut pc, &mut sp, &mut adr, &mut ins),
           Ok(true));
assert_eq!(stack, &[]);
assert_eq!(*ins, 0x69);

impl MicroOp[src][]

pub fn display<'r, 's: 'r>(
    &'s self,
    registers: &'r GeneralPurposeRegisterBank
) -> DisplayMicroOp<'r>
[src][]

Get proxy object implementing Display for printing μOps in human-readable format

Examples

assert_eq!(MicroOp::WriteRegister(registers[1].address()).display(&registers).to_string(),
           "WriteRegister S");

assert_eq!(MicroOp::Alu(AluOperation::Or).display(&registers).to_string(),
           "Alu OR");

assert_eq!(MicroOp::CheckJumpCondition(InstructionJumpCondition::Jmpz).display(&registers).to_string(),
           "CheckJumpCondition JMPZ");

Trait Implementations

impl Clone for MicroOp[src][+]

impl Copy for MicroOp[src]

impl Debug for MicroOp[src][+]

impl Eq for MicroOp[src]

impl Hash for MicroOp[src][+]

impl Ord for MicroOp[src][+]

impl PartialEq<MicroOp> for MicroOp[src][+]

impl PartialOrd<MicroOp> for MicroOp[src][+]

impl StructuralEq for MicroOp[src]

impl StructuralPartialEq for MicroOp[src]

Auto Trait Implementations

impl RefUnwindSafe for MicroOp

impl Send for MicroOp

impl Sync for MicroOp

impl Unpin for MicroOp

impl UnwindSafe for MicroOp

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src][+]

impl<T> Borrow<T> for T where
    T: ?Sized
[src][+]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src][+]

impl<T> Downcast for T where
    T: Any
[src][+]

impl<T> DowncastSync for T where
    T: Send + Sync + Any
[src][+]

impl<T> From<T> for T[src][+]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src][+]

impl<T> ToOwned for T where
    T: Clone
[src][+]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src][+]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src][+]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.