pub enum Microcode {
Show 56 variants Yield, ReadReg { reg: Reg8, }, WriteReg { reg: Reg8, }, ReadReg16 { reg: Reg16, }, WriteReg16 { reg: Reg16, }, ReadMem, WriteMem, GetFlagsMasked { mask: Flags, }, SetFlagsMasked { mask: Flags, }, Append { val: u8, }, Dup16, Discard8, Discard16, Swap816, Intersperse, Not, Add, Adc, Sub, Sbc, And, Or, Xor, RotateLeft8, RotateLeft9, RotateRight8, RotateRight9, Compliment, ShiftLeft, ShiftRight, ShiftRightSignExt, Swap, DecimalAdjust, TestBit { bit: u8, }, SetBit { bit: u8, }, ResetBit { bit: u8, }, Inc16, Dec16, Add16, OffsetAddr, Stop, Halt, EnableInterrupts { immediate: bool, }, DisableInterrupts, CheckHalt, ClearHalt, CheckIme, GetActiveInterrupts, PopInterrupt, PopHaltBug, TickImeOnEnd, Skip { steps: usize, }, SkipIf { steps: usize, }, FetchNextInstruction, ParseOpcode, ParseCBOpcode,
}
Expand description

Microcode is a set of simple instructions designed specifically for implementing the opcodes on the gbz80 processor used on the gameboy. These instructions operate on a stack of bytes called the microcode stack, which is separate from the gameboy’s stack. Each microcode operation pops some values off of the stack, computes a result, and pushes its results onto the stack.

Most microcode operations are pure functions, meaning they only operate on the microcode stack. The functionality of those operations is defined directly in this crate. For operations which are not-pure, such as skips which execute part of the microcode only conditionally or operations which act directly on the gbz80 CPU in some way, the behavior of those operations is defined externally.

Variants§

§

Yield

Delays execution for 1m cycle.

This instruction is an extern.

Signature: fn r#yield()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

ReadReg

Fields

§reg: Reg8

The register to read from.

Read an 8-bit value from a register.

This instruction is an extern.

Signature: fn read_reg(reg : Reg8,) -> u8

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u8
§

WriteReg

Fields

§reg: Reg8

The register to write to.

Write an 8-bit value to a register.

This instruction is an extern.

Signature: fn write_reg(reg : Reg8, val : u8,)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Does not push any results onto the stack.

§

ReadReg16

Fields

§reg: Reg16

The register to read from.

Read an 8-bit value from a register.

This instruction is an extern.

Signature: fn read_reg(reg : Reg16,) -> u16

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
§

WriteReg16

Fields

§reg: Reg16

The register to write to.

Write an 8-bit value to a register.

This instruction is an extern.

Signature: fn write_reg(reg : Reg16, val : u16,)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u16

Does not push any results onto the stack.

§

ReadMem

Pop a 16 bit value from the stack and use it to read an 8 bit value onto the stack.

This instruction is an extern.

Signature: fn read_mem(addr : u16) -> u8

Pops these values off of the stack: (in order from top of the stack to the bottom)

addr : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u8
§

WriteMem

Pop a 16 bit value from the stack and use it as the address, then pop an 8 bit value from the stack and wite it to that address.

This instruction is an extern.

Signature: fn write_mem(addr : u16, val : u8)

Pops these values off of the stack: (in order from top of the stack to the bottom)

addr : u16
val : u8

Does not push any results onto the stack.

§

GetFlagsMasked

Fields

§mask: Flags

Fetches the flags register onto the microcode stack,

This instruction is an extern.

Signature: fn get_flags_masked(mask : Flags) -> Flags

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
§

SetFlagsMasked

Fields

§mask: Flags

Pops flags off the microcode stack, masks them, and applies them to the flags register.

This instruction is an extern.

Signature: fn set_flags_masked(mask : Flags, flags : Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

flags : Flags

Does not push any results onto the stack.

§

Append

Fields

§val: u8

The value to place on the stack.

Append an 8-bit value to the microcode stack. (Essentially provides a constant value).

This instruction is defined by the function defs::append.

Signature: fn append(val : u8,) -> u8

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u8
§

Dup16

Takes one u16 from the stack and pushes 2 copies of it onto the stack.

This instruction is defined by the function defs::dup.

Signature: fn dup(v : u16) -> (u16, u16)

Pops these values off of the stack: (in order from top of the stack to the bottom)

v : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
u16
§

Discard8

Discard an 8 bit value from the microcode stack.

This instruction is defined by the function defs::discard8.

Signature: fn discard8(_ : u8)

Pops these values off of the stack: (in order from top of the stack to the bottom)

u8

Does not push any results onto the stack.

§

Discard16

Discard a 16 bit value from the microcode stack.

This instruction is defined by the function defs::discard16.

Signature: fn discard16(_ : u16)

Pops these values off of the stack: (in order from top of the stack to the bottom)

u16

Does not push any results onto the stack.

§

Swap816

Pop a u8 and a u16 off the microcode stack and push them in reverse order (u16 on top, u8 below it).

This instruction is defined by the function defs::swap816.

Signature: fn swap816(top : u8, second : u16) -> (u8, u16)

Pops these values off of the stack: (in order from top of the stack to the bottom)

top : u8
second : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
u8
§

Intersperse

Takes a u16 address off the stack followed by a u16 value, then splits the value into separate bytes and pushes them on the stack in the order: u8 high, u16 addr, u8 low, u16 addr. This is useful for performing a 16 bit write where the low byte is written first.

This instruction is defined by the function defs::intersperse.

Signature: fn intersperse(addr : u16, val : u16) -> (u8, u16, u8, u16)

Pops these values off of the stack: (in order from top of the stack to the bottom)

addr : u16
val : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
u8
u16
u8
§

Not

Boolean not. Note this is an interanl microcode operation, not a gameboy ALU operation.

This instruction is defined by the function defs::not.

Signature: fn not(val : bool) -> bool

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : bool

Pushes these values onto the stack: (in order from top of the stack to the bottom)

bool
§

Add

Perform an 8 bit add.

This instruction is defined by the function defs::add.

Signature: fn add(lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Adc

Perform an 8 bit add-carry.

This instruction is defined by the function defs::adc.

Signature: fn adc(prevflags : Flags, lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

prevflags : Flags
lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Sub

Perform an 8 bit sub.

This instruction is defined by the function defs::sub.

Signature: fn sub(lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Sbc

Perform an 8 bit sub-carry.

This instruction is defined by the function defs::sbc.

Signature: fn sbc(prevflags : Flags, lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

prevflags : Flags
lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

And

Perform a microcode and.

This instruction is defined by the function defs::and.

Signature: fn and(lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Or

Perform a microcde or

This instruction is defined by the function defs::or.

Signature: fn or(lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Xor

Perform a microcde xor

This instruction is defined by the function defs::xor.

Signature: fn xor(lhs : u8, rhs : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

lhs : u8
rhs : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

RotateLeft8

Rotate the value left by 8 bits.

This instruction is defined by the function defs::rotate_left8.

Signature: fn rotate_left8(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

RotateLeft9

Rotate the value left by 9 bits, rotating through the carry flag.

This instruction is defined by the function defs::rotate_left9.

Signature: fn rotate_left9(prevflags : Flags, val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

prevflags : Flags
val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

RotateRight8

Rotate the value right by 8 bits.

This instruction is defined by the function defs::rotate_right8.

Signature: fn rotate_right8(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

RotateRight9

Rotate the value right by 9 bits, rotating through the carry flag.

This instruction is defined by the function defs::rotate_right9.

Signature: fn rotate_right9(prevflags : Flags, val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

prevflags : Flags
val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Compliment

Complement the value on top of the stack.

This instruction is defined by the function defs::compliment.

Signature: fn compliment(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

ShiftLeft

Shift the value left by one bit.

This instruction is defined by the function defs::shift_left.

Signature: fn shift_left(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

ShiftRight

Shift the value right by one bit.

This instruction is defined by the function defs::shift_right.

Signature: fn shift_right(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

ShiftRightSignExt

Shift the value right by one bit, performing sign-extension.

This instruction is defined by the function defs::shift_right_sign_ext.

Signature: fn shift_right_sign_ext(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

Swap

Swaps the lower and upper nybble of the byte.

This instruction is defined by the function defs::swap.

Signature: fn swap(val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

DecimalAdjust

Helper for doing binary-coded-decimal. Adjusts the hex didgits to keep both nybbles in range 0..=9 by adding 0x06 and/or 0x60 to push the digit to the next nybble. Depends on the carry/halfcarry flags.

This instruction is defined by the function defs::decmial_adjust.

Signature: fn decmial_adjust(prevflags : Flags, val : u8) -> (u8, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

prevflags : Flags
val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u8
§

TestBit

Fields

§bit: u8

The index of the bit to test.

Tests if a particular bit is set in the output.

This instruction is defined by the function defs::test_bit.

Signature: fn test_bit(bit : u8, val : u8,) -> Flags

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
§

SetBit

Fields

§bit: u8

The index of the bit to set.

Sets a paricular bit in the output.

This instruction is defined by the function defs::set_bit.

Signature: fn set_bit(bit : u8, val : u8,) -> u8

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u8
§

ResetBit

Fields

§bit: u8

The index of the bit to clear..

Clears a paricular bit in the output.

This instruction is defined by the function defs::reset_bit.

Signature: fn reset_bit(bit : u8, val : u8,) -> u8

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u8
§

Inc16

Increments a 16 bit value.

This instruction is defined by the function defs::inc16.

Signature: fn inc16(val : u16) -> u16

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
§

Dec16

Decrements a 16 bit value.

This instruction is defined by the function defs::dec16.

Signature: fn dec16(val : u16) -> u16

Pops these values off of the stack: (in order from top of the stack to the bottom)

val : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
§

Add16

Performs a 16 bit add with flags. Pops two 16 bit args off the stack (lhs on top, rhs below it), adds them, and pushes the result followed by the flags on top. The returned flags will have 00HC set based on the upper byte of the operation (as if it was performed by running the pseudo-instructions add l,<arg-low>; adc h,<arg-high>.

This instruction is defined by the function defs::add16.

Signature: fn add16(lhs : u16, rhs : u16) -> (u16, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

lhs : u16
rhs : u16

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u16
§

OffsetAddr

Pops a 16 bit address off the stack followed by an 8 bit offset below it. Applies address offsetting and pushes the new address followed by the flags on top.

This instruction is defined by the function defs::offset_addr.

Signature: fn offset_addr(addr : u16, offset : u8) -> (u16, Flags)

Pops these values off of the stack: (in order from top of the stack to the bottom)

addr : u16
offset : u8

Pushes these values onto the stack: (in order from top of the stack to the bottom)

Flags
u16
§

Stop

Panics if the stop instruction is reached. This should probably become an extern if stop is ever implemented.

This instruction is defined by the function defs::stop.

Signature: fn stop()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

Halt

Puts the CPU into the halted state.

This instruction is an extern.

Signature: fn halt()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

EnableInterrupts

Fields

§immediate: bool

If true, enable interrupts immediately, otherwise after the next instruction.

Enables interrupts, either immediately or after the next instruction.

This instruction is an extern.

Signature: fn enable_interrupts(immediate : bool,)

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

DisableInterrupts

Disables interrupts immediately.

This instruction is an extern.

Signature: fn disable_interrupts()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

CheckHalt

Retrieves the value of the halted flag from the CPU.

This instruction is an extern.

Signature: fn check_halt() -> bool

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

bool
§

ClearHalt

Sets the CPU to not be halted.

This instruction is an extern.

Signature: fn clear_halt()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

CheckIme

Gets a bool indicating if IME is set.

This instruction is an extern.

Signature: fn check_ime() -> bool

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

bool
§

GetActiveInterrupts

Gets the set of currently active and enabled interrupts.

This instruction is an extern.

Signature: fn get_active_interrupts() -> u8

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u8
§

PopInterrupt

Gets the address of the interrupt handler for the next active and enabled interrupt from the interupt vector and clears that interrupt from the interrupt vector. Does not disable interrupts.

This instruction is an extern.

Signature: fn pop_interrupt() -> u16

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

u16
§

PopHaltBug

Pushes the value of the Halt Bug flag onto the microcode stack, clearing the value to false.

This instruction is an extern.

Signature: fn pop_halt_bug() -> bool

Does not pop any values off of the stack.

Pushes these values onto the stack: (in order from top of the stack to the bottom)

bool
§

TickImeOnEnd

Tells the CPU that interrupt_master_enable.tick should be run when the current instruction finishes. This will happen on FetchNextInstruction, whether that is triggered explicitly or by reaching the end of the current instruction.

This instruction is an extern.

Signature: fn tick_ime_on_end()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

Skip

Fields

§steps: usize

Number of steps in the microcode to skip over.

Unconditionally skip the given number of microcode steps.

Skips the microcode pc forward by this number of steps. Note that the microcode pc is already incremented for the skip instruction, so that is not counted when figuring out how many steps to skip.

This instruction is an extern.

Signature: fn skip(steps : usize,)

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

SkipIf

Fields

§steps: usize

Number of steps in the microcode to skip over.

Conditionally skip the given number of microcode steps.

Pops an 8 bit value off the microcode stack, and if it is non-zero, skips the microcode pc forward by this number of steps. Note that the microcode pc is already incremented for the skip instruction, so that is not counted when figuring out how many steps to skip.

This instruction is an extern.

Signature: fn skip_if(steps : usize, cond : bool,)

Pops these values off of the stack: (in order from top of the stack to the bottom)

cond : bool

Does not push any results onto the stack.

§

FetchNextInstruction

Replace the currently executing instruction with the microcode for the CPU’s internal halt check, interrupt handler, and instruction fetch.

Executing this instruction also checks if previous_ime is set, and if so, ticks the IME state forward.

It is not necessary to include this in every instruction, as the CPU will perform this automatically if it runs out of steps in the currently executing instruction. This can be useful as a ‘break’ or ‘return’ from within an instruction.

This instruction is an extern.

Signature: fn fetch_next_instruction()

Does not pop any values off of the stack.

Does not push any results onto the stack.

§

ParseOpcode

This instruction is an extern.

Signature: fn parse_opcode(opcode : u8)

Pops these values off of the stack: (in order from top of the stack to the bottom)

opcode : u8

Does not push any results onto the stack.

§

ParseCBOpcode

This instruction is an extern.

Signature: fn parse_cb_opcode(opcode : u8)

Pops these values off of the stack: (in order from top of the stack to the bottom)

opcode : u8

Does not push any results onto the stack.

Implementations§

source§

impl Microcode

source

pub fn is_terminal(self) -> bool

Returns true if this microcode operation causes the currently executing instruction to terminate. True for FetchNextInstruction ParseOpcode, and ParseCBOpcode.

source§

impl Microcode

source

pub fn descriptor(self) -> MicrocodeDescriptor

Get the MicrocodeDescriptor for this operation.

Trait Implementations§

source§

impl Clone for Microcode

source§

fn clone(&self) -> Microcode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Microcode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<Microcode> for InstrBuilder

source§

fn from(value: Microcode) -> Self

Converts to this type from the input type.
source§

impl Hash for Microcode

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Microcode> for Microcode

source§

fn eq(&self, other: &Microcode) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Copy for Microcode

source§

impl Eq for Microcode

source§

impl StructuralEq for Microcode

source§

impl StructuralPartialEq for Microcode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.