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
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)
u8WriteReg
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 : u8Does not push any results onto the stack.
ReadReg16
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)
u16WriteReg16
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 : u16Does 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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
u8WriteMem
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 : u8Does not push any results onto the stack.
GetFlagsMasked
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)
FlagsSetFlagsMasked
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 : FlagsDoes not push any results onto the stack.
Append
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)
u8Dup16
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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
u16
u16Discard8
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)
u8Does 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)
u16Does 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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
u16
u8Intersperse
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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
u16
u8
u16
u8Not
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 : boolPushes these values onto the stack: (in order from top of the stack to the bottom)
boolAdd
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Adc
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Sub
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Sbc
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8And
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Or
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Xor
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8RotateLeft8
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8RotateLeft9
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8RotateRight8
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8RotateRight9
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Compliment
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8ShiftLeft
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8ShiftRight
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8ShiftRightSignExt
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8Swap
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8DecimalAdjust
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u8TestBit
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
FlagsSetBit
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
u8ResetBit
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
u8Inc16
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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
u16Dec16
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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
u16Add16
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 : u16Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u16OffsetAddr
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 : u8Pushes these values onto the stack: (in order from top of the stack to the bottom)
Flags
u16Stop
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
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)
boolClearHalt
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)
boolGetActiveInterrupts
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)
u8PopInterrupt
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)
u16PopHaltBug
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)
boolTickImeOnEnd
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
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
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 : boolDoes 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 : u8Does 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 : u8Does not push any results onto the stack.
Implementations§
Source§impl Microcode
impl Microcode
Sourcepub fn is_terminal(self) -> bool
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
impl Microcode
Sourcepub fn descriptor(self) -> MicrocodeDescriptor
pub fn descriptor(self) -> MicrocodeDescriptor
Get the MicrocodeDescriptor for this operation.