[−][src]Enum pir_8_emu::micro::MicroOp
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
Do nothing
Also to pad out the returned instruction
Halt
Load the top of the stack into INS
Write the address specified by the top two bytes of the μstack into ADR
Read both bytes of ADR onto the μstack
Push a byte from the top of the μstack to the stack
Pop a byte from the stack to the μstack
Alu(AluOperation)
Perform an ALU operation
Read a byte from the port specified at the top of the μstack
Write to the port specified at the top of the μstack a byte from the next byte on the μstack
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
Read a 1-byte immediate from memory at PC to the top of the μstack, incrementing PC
Read the value from memory at ADR
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
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]
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>
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]
&'s self,
registers: &'r GeneralPurposeRegisterBank
) -> DisplayMicroOp<'r>
Get proxy object implementing Display
for printing μOps in human-readable format
Examples
assert_eq!(MicroOp::WriteRegister(registers[1].address()).display(®isters).to_string(), "WriteRegister S"); assert_eq!(MicroOp::Alu(AluOperation::Or).display(®isters).to_string(), "Alu OR"); assert_eq!(MicroOp::CheckJumpCondition(InstructionJumpCondition::Jmpz).display(®isters).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]
fn hash<__H: Hasher>(&self, state: &mut __H)
[src]
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl Ord for MicroOp
[src]
fn cmp(&self, other: &MicroOp) -> Ordering
[src]
fn max(self, other: Self) -> Self
1.21.0[src]
fn min(self, other: Self) -> Self
1.21.0[src]
fn clamp(self, min: Self, max: Self) -> Self
[src]
impl PartialEq<MicroOp> for MicroOp
[src]
impl PartialOrd<MicroOp> for MicroOp
[src]
fn partial_cmp(&self, other: &MicroOp) -> Option<Ordering>
[src]
fn lt(&self, other: &MicroOp) -> bool
[src]
fn le(&self, other: &MicroOp) -> bool
[src]
fn gt(&self, other: &MicroOp) -> bool
[src]
fn ge(&self, other: &MicroOp) -> bool
[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]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Downcast for T where
T: Any,
[src]
T: Any,
fn into_any(self: Box<T>) -> Box<dyn Any + 'static>
[src]
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any + 'static>
[src]
fn as_any(&self) -> &(dyn Any + 'static)
[src]
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
[src]
impl<T> DowncastSync for T where
T: Send + Sync + Any,
[src]
T: Send + Sync + Any,
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,