Enum feo3boy_opcodes::microcode::Microcode
source · 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)
u8
WriteReg
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
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
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
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
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
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
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
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
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
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
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 : 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
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.