[−][src]Trait z80emu::Cpu
The Cpu trait provides means to execute and debug machine code or change the state of self
at User's will.
Required methods
fn reset(&mut self)
Instantly resets the Cpu to its initial state.
fn get_pc(&self) -> u16
Returns the current value of the program counter.
fn set_pc(&mut self, pc: u16)
Sets the current value of the program counter.
fn get_sp(&self) -> u16
Returns the current value of the stack pointer.
fn set_sp(&mut self, sp: u16)
Sets the current value of the stack pointer.
fn get_acc(&self) -> u8
Returns the Accumulator value as an unsigned 8-bit integer.
fn set_acc(&mut self, val: u8)
Sets the Accumulator value from an unsigned 8-bit integer.
fn get_flags(&self) -> CpuFlags
Returns the current state of the Flags register.
fn set_flags(&mut self, flags: CpuFlags)
Sets the current state of the Flags register.
fn inc_r(&mut self)
Increases the memory refresh counter.
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.
fn get_r(&self) -> u8
Returns the current value of the memory refresh register R
.
fn set_r(&mut self, r: u8)
Sets the memory refresh register R
value.
fn get_i(&self) -> u8
Returns the current value of the interrupt page I
register.
fn set_i(&mut self, i: u8)
Sets the current value of the interrupt page I
register.
fn get_ir(&self) -> u16
Returns the current memory refresh address.
fn get_iffs(&self) -> (bool, bool)
Returns values of interrupt flip-flops (iff1, iff2)
.
fn set_iffs(&mut self, iff1: bool, iff2: bool)
Sets the values of interrupt flip-flops.
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.
fn is_halt(&self) -> bool
Returns true
if the Cpu is in the HALT state.
fn get_im(&self) -> InterruptMode
Returns the current interrupt mode.
fn set_im(&mut self, im: InterruptMode)
Sets the interrupt mode.
fn ex_af_af(&mut self)
Swaps the AF
register with its alternative counterpart AF'
.
fn exx(&mut self)
Swaps the BC
, DE
and HL
registers with their alternative counterparts BC'
, DE'
and HL'
.
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.
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.
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.
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.
fn get_reg16(&self, src: StkReg16) -> u16
Returns the content of the selected pair of registers as an unsigned 16-bit integer.
fn get_alt_reg16(&self, src: StkReg16) -> u16
Returns the content of the selected pair of alternative registers as an unsigned 16-bit integer.
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
.
fn set_reg16(&mut self, src: StkReg16, val: u16)
Sets the content of the selected pair of registers as an unsigned 16-bit integer.
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:
- Prefix::Xdd -
(IXh, IXl)
- Prefix::Yfd -
(IYh, IYl)
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:
- Prefix::Xdd -
IX
- Prefix::Yfd -
IY
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:
- Prefix::Xdd -
IXh=hi, IXl=lo
- Prefix::Yfd -
IYh=hi, IYl=lo
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:
- Prefix::Xdd -
IX
- Prefix::Yfd -
IY
fn is_irq_allowed(&self) -> bool
Returns true if the Cpu will accept the interrupt request before executing the next opcode.
fn is_nmi_allowed(&self) -> bool
Returns true if the Cpu will accept the non-maskable interrupt before executing the next opcode.
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.
fn disable_interrupts(&mut self)
Disables the maskable interrupts by resetting both interrupt flip-flops
to Off.
This is what DI
instruction usually does.
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.
fn is_after_ei(&self) -> bool
Returns true
if the last command executed was EI
.
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.
fn get_prefix(&self) -> Option<Prefix>
Returns the prefix value after executing the last command.
See Cpu::execute_instruction for more information.
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),
&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:
- InterruptMode::Mode0 an instruction provided via Io::irq_data.
- InterruptMode::Mode1 a
RST 38h
instruction. - InterruptMode::Mode2 a hypothetical
PUSH pc + JP <vector address>
instruction. A debugger will see theJP
command in this instance.
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.
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,
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.
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),
&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.
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),
&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.
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,
&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 theHALT
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.
Implementors
impl Cpu for Z80Any
[src]
fn reset(&mut self)
[src]
fn get_pc(&self) -> u16
[src]
fn set_pc(&mut self, pc: u16)
[src]
fn get_sp(&self) -> u16
[src]
fn set_sp(&mut self, sp: u16)
[src]
fn get_acc(&self) -> u8
[src]
fn set_acc(&mut self, val: u8)
[src]
fn get_flags(&self) -> CpuFlags
[src]
fn set_flags(&mut self, flags: CpuFlags)
[src]
fn inc_r(&mut self)
[src]
fn add_r(&mut self, delta: i32)
[src]
fn get_r(&self) -> u8
[src]
fn set_r(&mut self, r: u8)
[src]
fn get_i(&self) -> u8
[src]
fn set_i(&mut self, i: u8)
[src]
fn get_ir(&self) -> u16
[src]
fn get_iffs(&self) -> (bool, bool)
[src]
fn set_iffs(&mut self, iff1: bool, iff2: bool)
[src]
fn halt(&mut self)
[src]
fn is_halt(&self) -> bool
[src]
fn get_im(&self) -> InterruptMode
[src]
fn set_im(&mut self, im: InterruptMode)
[src]
fn ex_af_af(&mut self)
[src]
fn exx(&mut self)
[src]
fn get_reg(&self, reg: Reg8, prefix: Option<Prefix>) -> u8
[src]
fn set_reg(&mut self, dst: Reg8, prefix: Option<Prefix>, val: u8)
[src]
fn get_reg2(&self, src: StkReg16) -> (u8, u8)
[src]
fn get_alt_reg2(&self, src: StkReg16) -> (u8, u8)
[src]
fn get_reg16(&self, src: StkReg16) -> u16
[src]
fn get_alt_reg16(&self, src: StkReg16) -> u16
[src]
fn set_reg2(&mut self, src: StkReg16, hi: u8, lo: u8)
[src]
fn set_reg16(&mut self, src: StkReg16, val: u16)
[src]
fn get_index2(&self, prefix: Prefix) -> (u8, u8)
[src]
fn get_index16(&self, prefix: Prefix) -> u16
[src]
fn set_index2(&mut self, prefix: Prefix, hi: u8, lo: u8)
[src]
fn set_index16(&mut self, prefix: Prefix, val: u16)
[src]
fn is_irq_allowed(&self) -> bool
[src]
fn is_nmi_allowed(&self) -> bool
[src]
fn restore_iff1(&mut self)
[src]
fn disable_interrupts(&mut self)
[src]
fn enable_interrupts(&mut self)
[src]
fn is_after_ei(&self) -> bool
[src]
fn is_after_prefix(&self) -> bool
[src]
fn get_prefix(&self) -> Option<Prefix>
[src]
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),
[src]
&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,
[src]
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),
[src]
&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),
[src]
&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,
vc_limit: T::Limit
) -> Result<M::WrIoBreak, M::RetiBreak> where
M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>,
T: Clock,
[src]
&mut self,
control: &mut M,
tsc: &mut T,
vc_limit: T::Limit
) -> Result<M::WrIoBreak, M::RetiBreak> where
M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>,
T: Clock,
impl<Q: Flavour> Cpu for Z80<Q>
[src]
fn reset(&mut self)
[src]
fn get_pc(&self) -> u16
[src]
fn set_pc(&mut self, pc: u16)
[src]
fn get_sp(&self) -> u16
[src]
fn set_sp(&mut self, sp: u16)
[src]
fn get_acc(&self) -> u8
[src]
fn set_acc(&mut self, val: u8)
[src]
fn get_flags(&self) -> CpuFlags
[src]
fn set_flags(&mut self, flags: CpuFlags)
[src]
fn inc_r(&mut self)
[src]
fn add_r(&mut self, delta: i32)
[src]
fn get_r(&self) -> u8
[src]
fn set_r(&mut self, r: u8)
[src]
fn get_i(&self) -> u8
[src]
fn set_i(&mut self, i: u8)
[src]
fn get_ir(&self) -> u16
[src]
fn get_iffs(&self) -> (bool, bool)
[src]
fn set_iffs(&mut self, iff1: bool, iff2: bool)
[src]
fn halt(&mut self)
[src]
fn is_halt(&self) -> bool
[src]
fn get_im(&self) -> InterruptMode
[src]
fn set_im(&mut self, im: InterruptMode)
[src]
fn ex_af_af(&mut self)
[src]
fn exx(&mut self)
[src]
fn get_reg(&self, reg: Reg8, prefix: Option<Prefix>) -> u8
[src]
fn set_reg(&mut self, dst: Reg8, prefix: Option<Prefix>, val: u8)
[src]
fn get_reg2(&self, src: StkReg16) -> (u8, u8)
[src]
fn get_alt_reg2(&self, src: StkReg16) -> (u8, u8)
[src]
fn get_reg16(&self, src: StkReg16) -> u16
[src]
fn get_alt_reg16(&self, src: StkReg16) -> u16
[src]
fn set_reg2(&mut self, src: StkReg16, hi: u8, lo: u8)
[src]
fn set_reg16(&mut self, src: StkReg16, val: u16)
[src]
fn get_index2(&self, prefix: Prefix) -> (u8, u8)
[src]
fn get_index16(&self, prefix: Prefix) -> u16
[src]
fn set_index2(&mut self, prefix: Prefix, hi: u8, lo: u8)
[src]
fn set_index16(&mut self, prefix: Prefix, val: u16)
[src]
fn is_irq_allowed(&self) -> bool
[src]
fn is_nmi_allowed(&self) -> bool
[src]
fn restore_iff1(&mut self)
[src]
fn disable_interrupts(&mut self)
[src]
fn enable_interrupts(&mut self)
[src]
fn is_after_ei(&self) -> bool
[src]
fn is_after_prefix(&self) -> bool
[src]
fn get_prefix(&self) -> Option<Prefix>
[src]
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),
[src]
&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,
[src]
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),
[src]
&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),
[src]
&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,
vc_limit: T::Limit
) -> Result<M::WrIoBreak, M::RetiBreak> where
M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>,
T: Clock,
[src]
&mut self,
control: &mut M,
tsc: &mut T,
vc_limit: T::Limit
) -> Result<M::WrIoBreak, M::RetiBreak> where
M: Memory<Timestamp = T::Timestamp> + Io<Timestamp = T::Timestamp>,
T: Clock,