Trait z80emu::Cpu

source ·
pub trait Cpu: Clone + Default + PartialEq + Eq {
Show 49 methods // Required methods fn reset(&mut self); fn get_pc(&self) -> u16; fn set_pc(&mut self, pc: u16); fn get_sp(&self) -> u16; fn set_sp(&mut self, sp: u16); fn get_acc(&self) -> u8; fn set_acc(&mut self, val: u8); fn get_flags(&self) -> CpuFlags; fn set_flags(&mut self, flags: CpuFlags); fn inc_r(&mut self); fn add_r(&mut self, delta: i32); fn get_r(&self) -> u8; fn set_r(&mut self, r: u8); fn get_i(&self) -> u8; fn set_i(&mut self, i: u8); fn get_ir(&self) -> u16; fn get_iffs(&self) -> (bool, bool); fn set_iffs(&mut self, iff1: bool, iff2: bool); fn halt(&mut self); fn is_halt(&self) -> bool; fn get_im(&self) -> InterruptMode; fn set_im(&mut self, im: InterruptMode); fn ex_af_af(&mut self); fn exx(&mut self); fn get_reg(&self, reg: Reg8, prefix: Option<Prefix>) -> u8; fn set_reg(&mut self, dst: Reg8, prefix: Option<Prefix>, val: u8); fn get_reg2(&self, src: StkReg16) -> (u8, u8); fn get_alt_reg2(&self, src: StkReg16) -> (u8, u8); fn get_reg16(&self, src: StkReg16) -> u16; fn get_alt_reg16(&self, src: StkReg16) -> u16; fn set_reg2(&mut self, src: StkReg16, hi: u8, lo: u8); fn set_reg16(&mut self, src: StkReg16, val: u16); fn get_index2(&self, prefix: Prefix) -> (u8, u8); fn get_index16(&self, prefix: Prefix) -> u16; fn set_index2(&mut self, prefix: Prefix, hi: u8, lo: u8); fn set_index16(&mut self, prefix: Prefix, val: u16); fn is_irq_allowed(&self) -> bool; fn is_nmi_allowed(&self) -> bool; fn restore_iff1(&mut self); fn disable_interrupts(&mut self); fn enable_interrupts(&mut self); fn is_after_ei(&self) -> bool; fn is_after_prefix(&self) -> bool; fn get_prefix(&self) -> Option<Prefix>; fn irq<M, T, F>( &mut self, control: &mut M, tsc: &mut T, debug: Option<F> ) -> Option<Result<M::WrIoBreak, M::RetiBreak>> where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock, F: FnOnce(CpuDebug); fn nmi<M, T>(&mut self, control: &mut M, tsc: &mut T) -> bool where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock; fn execute_instruction<M, T, F>( &mut self, control: &mut M, tsc: &mut T, debug: Option<F>, code: u8 ) -> Result<M::WrIoBreak, M::RetiBreak> where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock, F: FnOnce(CpuDebug); fn execute_next<M, T, F>( &mut self, control: &mut M, tsc: &mut T, debug: Option<F> ) -> Result<M::WrIoBreak, M::RetiBreak> where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock, F: FnOnce(CpuDebug); fn execute_with_limit<M, T>( &mut self, control: &mut M, tsc: &mut T, limit: T::Limit ) -> Result<M::WrIoBreak, M::RetiBreak> where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock;
}
Expand description

The Cpu trait provides means to execute and debug machine code or change the state of self at User’s will.

Required Methods§

source

fn reset(&mut self)

Instantly resets the Cpu to its initial state.

source

fn get_pc(&self) -> u16

Returns the current value of the program counter.

source

fn set_pc(&mut self, pc: u16)

Sets the current value of the program counter.

source

fn get_sp(&self) -> u16

Returns the current value of the stack pointer.

source

fn set_sp(&mut self, sp: u16)

Sets the current value of the stack pointer.

source

fn get_acc(&self) -> u8

Returns the Accumulator value as an unsigned 8-bit integer.

source

fn set_acc(&mut self, val: u8)

Sets the Accumulator value from an unsigned 8-bit integer.

source

fn get_flags(&self) -> CpuFlags

Returns the current state of the Flags register.

source

fn set_flags(&mut self, flags: CpuFlags)

Sets the current state of the Flags register.

source

fn inc_r(&mut self)

Increases the memory refresh counter.

source

fn add_r(&mut self, delta: i32)

Adds the arbitrary value to the memory refresh counter. This can be used to emulate the Cpu in the HALT state without executing the busy loop.

source

fn get_r(&self) -> u8

Returns the current value of the memory refresh register R.

source

fn set_r(&mut self, r: u8)

Sets the memory refresh register R value.

source

fn get_i(&self) -> u8

Returns the current value of the interrupt page I register.

source

fn set_i(&mut self, i: u8)

Sets the current value of the interrupt page I register.

source

fn get_ir(&self) -> u16

Returns the current memory refresh address.

source

fn get_iffs(&self) -> (bool, bool)

Returns values of interrupt flip-flops (iff1, iff2).

source

fn set_iffs(&mut self, iff1: bool, iff2: bool)

Sets the values of interrupt flip-flops.

source

fn halt(&mut self)

Forces Cpu to enter the HALT state. This doesn’t involve Clock and happens instantly. This also can be done by executing HALT instruction with Cpu::execute_instruction.

source

fn is_halt(&self) -> bool

Returns true if the Cpu is in the HALT state.

source

fn get_im(&self) -> InterruptMode

Returns the current interrupt mode.

source

fn set_im(&mut self, im: InterruptMode)

Sets the interrupt mode.

source

fn ex_af_af(&mut self)

Swaps the AF register with its alternative counterpart AF'.

source

fn exx(&mut self)

Swaps the BC, DE and HL registers with their alternative counterparts BC', DE' and HL'.

source

fn get_reg(&self, reg: Reg8, prefix: Option<Prefix>) -> u8

Returns the content of the selected 8-bit register.

The reg argument specifies the register. If the prefix argument is one of Prefix::Xdd or Prefix::Yfd and the reg is Reg8::H or Reg8::L the content of the IXh, IXl or IYh, IYl will be returned instead.

source

fn set_reg(&mut self, dst: Reg8, prefix: Option<Prefix>, val: u8)

Sets the content of the selected 8-bit register.

The reg argument specifies the register. If the prefix argument is one of Prefix::Xdd or Prefix::Yfd and the reg is Reg8::H or Reg8::L the content of the IXh, IXl or IYh, IYl will be set instead.

source

fn get_reg2(&self, src: StkReg16) -> (u8, u8)

Returns the content of the selected pair of registers as a tuple of 8-bit unsigned integers.

E.g. for StkReg16::BC the content of (B, C) will be returned.

source

fn get_alt_reg2(&self, src: StkReg16) -> (u8, u8)

Returns the content of the selected pair of alternative registers as a tuple of 8-bit unsigned integers.

E.g. for StkReg16::AF the content of (A', F') will be returned.

source

fn get_reg16(&self, src: StkReg16) -> u16

Returns the content of the selected pair of registers as an unsigned 16-bit integer.

source

fn get_alt_reg16(&self, src: StkReg16) -> u16

Returns the content of the selected pair of alternative registers as an unsigned 16-bit integer.

source

fn set_reg2(&mut self, src: StkReg16, hi: u8, lo: u8)

Sets the content of the selected pair of registers.

E.g. for StkReg16::BC register B will be set to hi and C to lo.

source

fn set_reg16(&mut self, src: StkReg16, val: u16)

Sets the content of the selected pair of registers as an unsigned 16-bit integer.

source

fn get_index2(&self, prefix: Prefix) -> (u8, u8)

Returns the content of one of the index registers as a tuple of 8-bit unsigned integers.

Depending on prefix this will be:

source

fn get_index16(&self, prefix: Prefix) -> u16

Returns the content of one of the index registers as a 16-bit unsigned integer.

Depending on prefix this will be:

source

fn set_index2(&mut self, prefix: Prefix, hi: u8, lo: u8)

Sets the content of one of the index registers.

Depending on prefix this will be:

source

fn set_index16(&mut self, prefix: Prefix, val: u16)

Sets the content of one of the index registers as a 16-bit unsigned integer.

Depending on prefix this will be:

source

fn is_irq_allowed(&self) -> bool

Returns true if the Cpu will accept the interrupt request before executing the next opcode.

source

fn is_nmi_allowed(&self) -> bool

Returns true if the Cpu will accept the non-maskable interrupt before executing the next opcode.

source

fn restore_iff1(&mut self)

Restores the content of the interrupt flip-flop 1 from the content of the interrupt flip-flop 2. This is what RETN instruction usually does.

source

fn disable_interrupts(&mut self)

Disables the maskable interrupts by resetting both interrupt flip-flops to Off.

This is what DI instruction usually does.

source

fn enable_interrupts(&mut self)

Enabes the maskable interrupts by setting both interrupt flip-flops to On.

Prevents the interrupts to be allowed before the next command. This is what EI instruction usually does.

source

fn is_after_ei(&self) -> bool

Returns true if the last command executed was EI.

source

fn is_after_prefix(&self) -> bool

Returns true if the last command executed was a 0xDD or a 0xFD prefix.

See Cpu::execute_instruction for more information.

source

fn get_prefix(&self) -> Option<Prefix>

Returns the prefix value after executing the last command.

See Cpu::execute_instruction for more information.

source

fn irq<M, T, F>( &mut self, control: &mut M, tsc: &mut T, debug: Option<F> ) -> Option<Result<M::WrIoBreak, M::RetiBreak>>
where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock, F: FnOnce(CpuDebug),

Requests a maskable interrupt.

This is the alternative method to invoke the maskable interrupt. Usually while instructions are being executed the Cpu checks via Io::is_irq method if the interrrupt from any device is being requested.

Returns None if the interrupt could not be accepted at this time. In this instance the method performs no operation.

Returns Some(Ok(())) if an interrupt was accepted and no break was requested by the executed instruction. In this instance at least one instruction will be executed. Depending on the interrupt mode this would be:

The Clock is advanced by the IRQ:6 cycle + optional wait states + cycles specific to the executed instruction (minus the M1:4 cycle).

Some(Err(BreakCause)) indicates that an instruction requested a break. Currently this may be possible in the interrupt mode 0 when the HALT, OUT or RETI instruction was executed and the Io::write_io or Io::reti requested to break the execution.

See Cpu::execute_instruction for the debug argument description.

§Note

If the interrupt is being accepted this method resets the HALT state before everything else.

source

fn nmi<M, T>(&mut self, control: &mut M, tsc: &mut T) -> bool
where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock,

Attempts to trigger a non-maskable interrupt.

Returns false if the interrupt could not be accepted at this time. The non-maskable interrupt is not being accepted in some situations, e.g. right after executing the EI instruction or after one of the 0xDD and 0xFD opcode prefixes. In this instance the method performs no operation.

Returns true on success. In this instance no instruction will be executed but the program counter will be set to 0x0066 and the previous program counter will be pushed on the machine stack. The interrupt flip-flop 1 is being set to false, while preserving the value of iff 2 and the Clock advances according to the Z80 NMI cycles: M1:4 + IR:1 + SP-1:3 + SP-2:3.

§Note

If the interrupt is being accepted this method resets the HALT state before everything else.

source

fn execute_instruction<M, T, F>( &mut self, control: &mut M, tsc: &mut T, debug: Option<F>, code: u8 ) -> Result<M::WrIoBreak, M::RetiBreak>
where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock, F: FnOnce(CpuDebug),

Executes a single instruction given as code. If the instruction is a first byte of the multi-byte instruction the rest of the instruction body will be fetched via calls to Memory::read_opcode.

The return value Err(BreakCause) indicates that an instruction requested a break. Currently this may be possible when the HALT instruction was executed or when the OUT family instruction was executed and the Io::write_io requested a break or the RETI instruction was executed and the Io::reti requested a break. See also BreakCause.

If debug argument is Some(F), a closure F may be called with CpuDebug argument during the instruction execution. It won’t be called if code is one of the 0xDD or 0xFD prefixes.

There is no limit of how many of these prefixes can be present before an actual instruction, so the execution is finished each time one of them is being encountered to prevent the overfeeding the Clock with a huge amount of T-states and to allow for the better synchronization with the emulated side effects. The user can check with Cpu::is_after_prefix method if this is the case after calling one of the execution methods.

§Note

This method resets the HALT state and after EI state before the instruction is being executed.

source

fn execute_next<M, T, F>( &mut self, control: &mut M, tsc: &mut T, debug: Option<F> ) -> Result<M::WrIoBreak, M::RetiBreak>
where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock, F: FnOnce(CpuDebug),

Executes the next instruction present in the Memory at the program counter fetched via Memory::read_opcode.

If interrupts are allowed, before fetching the instruction, checks if the interrupt request is present via Io::is_irq and enters the interrupted state, instead of fetching and executing the next instruction.

If the Cpu is in the HALT state, increases the memory refresh register and advances the Clock only. If debug closure is given, it will not be called in this instance.

See Cpu::execute_instruction and Cpu::irq for the returned value and debug argument descriptions.

source

fn execute_with_limit<M, T>( &mut self, control: &mut M, tsc: &mut T, limit: T::Limit ) -> Result<M::WrIoBreak, M::RetiBreak>
where M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>, T: Clock,

Executes instructions until Clock reaches the given limit or when other conditions are met.

Returns Ok(()) only when limit has been reached and the last executed instruction didn’t request a break.

Returns Err(BreakCause) when:

  • The HALT instruction was encountered. This also implies that the Cpu has entered the HALT state.
  • An instruction requested a break via Io::write_io or Io::reti.

See also BreakCause.

When interrupts are enabled, before fetching each next instruction, this method checks if the interrupt has been requested via Io::is_irq and executes the interrupt routine without breaking the execution.

When called while the Cpu was already in the HALT state, increases the memory refresh register and advances the Clock until the limit has been reached. If interrupts were enabled and an interrupt was requested via Io::is_irq, the HALT state is being reset and the regular execution of commands will be resumed.

Object Safety§

This trait is not object safe.

Implementors§

source§

impl Cpu for Z80Any

source§

impl<Q: Flavour> Cpu for Z80<Q>