API reference#

#include <Z80.h>

Types#

Callback pointers#

typedef zuint8 (*Z80Read)(void *context, zuint16 address)#

Defines a pointer to a Z80 callback function invoked to perform a read operation.

Param context:

The Z80::context of the calling object.

Param address:

The memory address or I/O port to read from.

Return:

The byte read.

typedef void (*Z80Write)(void *context, zuint16 address, zuint8 value)#

Defines a pointer to a Z80 callback function invoked to perform a write operation.

Param context:

The Z80::context of the calling object.

Param address:

The memory address or I/O port to write to.

Param value:

The byte to write.

typedef void (*Z80Halt)(void *context, zuint8 signal)#

Defines a pointer to a Z80 callback function invoked to notify a signal change on the HALT line.

Param context:

The Z80::context of the calling object.

Param signal:

A code specifying the type of signal change.

typedef void (*Z80Notify)(void *context)#

Defines a pointer to a Z80 callback function invoked to notify an event.

Param context:

The Z80::context of the calling object.

typedef zuint8 (*Z80Illegal)(Z80 *cpu, zuint8 opcode)#

Defines a pointer to a Z80 callback function invoked to delegate the emulation of an illegal instruction.

Param cpu:

The calling object.

Param opcode:

The illegal opcode.

Return:

The number of clock cycles consumed by the instruction.

Emulator object#

struct Z80#

A Z80 CPU emulator.

A Z80 object contains the state of an emulated Z80 CPU, pointers to callback functions that interconnect the emulator with the external logic and a context that is passed to these functions.

Because no constructor function is provided, it is mandatory to directly initialize all callback pointers and Z80::options before using an object of this type. Optional callbacks must be set to Z_NULL when not in use.

Public Members

zusize cycles#

Number of clock cycles already executed.

zusize cycle_limit#

Maximum number of clock cycles to be executed.

void *context#

Pointer to pass as the first argument to all callback functions.

This member is intended to hold a reference to the context to which the object belongs. It is safe not to initialize it when this is not necessary.

Z80Read fetch_opcode#

Invoked to perform an opcode fetch.

This callback indicates the beginning of an opcode fetch M-cycle. The function must return the byte located at the memory address specified by the second argument.

Z80Read fetch#

Invoked to perform a memory read on instruction data.

This callback indicates the beginning of a memory read M-cycle during which the CPU fetches one byte of instruction data (i.e., one byte of the instruction that is neither a prefix nor an opcode). The function must return the byte located at the memory address specified by the second argument.

Z80Read read#

Invoked to perform a memory read.

This callback indicates the beginning of a memory read M-cycle. The function must return the byte located at the memory address specified by the second argument.

Z80Write write#

Invoked to perform a memory write.

This callback indicates the beginning of a memory write M-cycle. The function must write the third argument into the memory location specified by the second argument.

Z80Read in#

Invoked to perform an I/O port read.

This callback indicates the beginning of an I/O read M-cycle. The function must return the byte read from the I/O port specified by the second argument.

Z80Write out#

Invoked to perform an I/O port write.

This callback indicates the beginning of an I/O write M-cycle. The function must write the third argument to the I/O port specified by the second argument.

Z80Halt halt#

Invoked to notify a signal change on the HALT line.

This callback is optional and must be set to Z_NULL when not in use. Its invocation is always deferred until the next emulation step so that the emulator can abort the signal change if any invalidating condition occurs, such as the acceptance of an interrupt during the execution of a halt instruction.

The second parameter of the function specifies the type of signal change and can only contain a boolean value if the Z80 library has not been built with special RESET support:

  • 1 indicates that the HALT line is going low during the last clock cycle of a halt instruction, which means that the CPU is entering the HALT state.

  • 0 indicates that the HALT line is going high during the last clock cycle of an internal NOP executed during the HALT state, i.e., the CPU is exiting the HALT state due to an interrupt or normal RESET.

If the library has been built with special RESET support, the values Z80_HALT_EXIT_EARLY and Z80_HALT_CANCEL are also possible for the second parameter.

Z80Read nop#

Invoked to perform an opcode fetch that corresponds to an internal NOP.

This callback indicates the beginning of an opcode fetch M-cycle of 4 clock cycles that is generated in the following two cases:

  • During the HALT state, the CPU repeatedly executes an internal NOP that fetches the next opcode after the halt instruction without incrementing the PC register. This opcode is read again and again until an exit condition occurs (i.e., NMI, INT or RESET).

  • After detecting a special RESET signal, the CPU completes the ongoing instruction or interrupt response and then zeroes the PC register during the first clock cycle of the next M1 cycle. If no interrupt has been accepted at the end of the instruction or interrupt response, the CPU produces an internal NOP to allow for the fetch-execute overlap to take place, during which it fetches the next opcode and zeroes PC.

This callback is optional but note that setting it to Z_NULL is equivalent to enabling Z80_OPTION_HALT_SKIP.

Z80Read nmia#

Invoked to perform an opcode fetch that corresponds to a non-maskable interrupt acknowledge M-cycle.

This callback is optional and must be set to Z_NULL when not in use. It indicates the beginning of an NMI acknowledge M-cycle. The value returned by the function is ignored.

Z80Read inta#

Invoked to perform a data bus read that corresponds to a maskable interrupt acknowledge M-cycle.

This callback is optional and must be set to Z_NULL when not in use. It indicates the beginning of an INT acknowledge M-cycle. The function must return the byte that the interrupting I/O device supplies to the CPU via the data bus during this M-cycle.

When this callback is Z_NULL, the emulator assumes that the value read from the data bus is 0xFF.

Z80Read int_fetch#

Invoked to perform a memory read on instruction data during a maskable interrupt response in mode 0.

The role of this callback is analogous to that of Z80::fetch, but it is specific to the INT response in mode 0. Ideally, the function should return a byte of instruction data that the interrupting I/O device supplies to the CPU via the data bus, but depending on the emulated hardware, the device may not be able to do this during a memory read M-cycle because the memory is addressed instead, in which case the function must return the byte located at the memory address specified by the second parameter.

This callback will only be invoked if Z80::inta is not Z_NULL and returns an opcode that implies subsequent memory read M-cycles to fetch the non-opcode bytes of the instruction, so it is safe not to initialize it or set it to Z_NULL if such a scenario is not possible.

Z80Notify ld_i_a#

Invoked to notify that an ld i,a instruction has been fetched.

This callback is optional and must be set to Z_NULL when not in use. It is invoked before executing the instruction.

Z80Notify ld_r_a#

Invoked to notify that an ld r,a instruction has been fetched.

This callback is optional and must be set to Z_NULL when not in use. It is invoked before executing the instruction.

Z80Notify reti#

Invoked to notify that a reti instruction has been fetched.

This callback is optional and must be set to Z_NULL when not in use. It is invoked before executing the instruction.

Z80Notify retn#

Invoked to notify that a retn instruction has been fetched.

This callback is optional and must be set to Z_NULL when not in use. It is invoked before executing the instruction.

Z80Read hook#

Invoked when a trap is fetched.

This callback is optional and must be set to Z_NULL when not in use, in which case the opcode of the trap will be executed normally. The function receives the memory address of the trap as the second parameter and must return the opcode to be executed instead of the trap. If the function returns a trap (i.e., Z80_HOOK), the emulator will do nothing, so the trap will be fetched again unless the function has modified Z80::pc or replaced the trap in memory with another opcode. Also note that returning a trap does not revert the increment of Z80::r performed before each opcode fetch.

Z80Illegal illegal#

Invoked to delegate the execution of an illegal instruction.

This callback is optional and must be set to Z_NULL when not in use. Only those instructions with the 0xED prefix that behave the same as two consecutive nop instructions are considered illegal. The function receives the illegal opcode as the second parameter and must return the number of clock cycles taken by the instruction.

At the time of invoking this callback, and relative to the start of the instruction, only Z80::r has been incremented (twice), so Z80::pc still contains the memory address of the 0xED prefix.

ZInt32 data#

Temporary storage used for instruction fetch.

ZInt16 ix_iy[2]#

Index registers, IX and IY.

ZInt16 pc#

Register PC (program counter).

ZInt16 sp#

Register SP (stack pointer).

ZInt16 xy#

Temporary index register.

All instructions with the 0xDD prefix behave exactly the same as their counterparts with the 0xFD prefix, differing only in the index register: the former use IX, whereas the latter use IY. When one of these prefixes is fetched, the corresponding index register is copied into this member; the instruction logic is then executed and finally this member is copied back into the index register.

ZInt16 memptr#

Register MEMPTR, also known as WZ.

ZInt16 af#

Register pair AF (accumulator and flags).

ZInt16 bc#

Register pair BC.

ZInt16 de#

Register pair DE.

ZInt16 hl#

Register pair HL.

ZInt16 af_#

Register pair AF’.

ZInt16 bc_#

Register pair BC’.

ZInt16 de_#

Register pair DE’.

ZInt16 hl_#

Register pair HL’.

zuint8 r#

Register R (memory refresh).

zuint8 i#

Register I (interrupt vector base).

zuint8 r7#

Backup of bit 7 of the R register.

The Z80 CPU increments the R register during each M1 cycle without altering its most significant bit, commonly known as R7. However, the emulator only performs normal full-byte increments for speed reasons, which eventually corrupts R7.

Before entering the execution loop, both z80_execute and z80_run copy Z80::r into this member to preserve the value of R7, so that they can restore it before returning. The emulation of the ld r, a instruction also updates the value of this member.

zuint8 im#

Maskable interrupt mode.

Contains the number of the maskable interrupt mode in use: 0, 1 or 2.

zuint8 request#

Requests pending to be responded.

zuint8 resume#

Type of unfinished operation to be resumed.

zuint8 iff1#

Interrupt enable flip-flop #1 (IFF1).

zuint8 iff2#

Interrupt enable flip-flop #2 (IFF2).

zuint8 q#

Pseudo-register Q.

zuint8 options#

Emulation options.

This member specifies the different emulation options that are enabled. It is mandatory to initialize it before using the emulator. Setting it to 0 disables all options.

zuint8 int_line#

State of the INT line.

The value of this member is 1 if the INT line is low; otherwise, 0.

zuint8 halt_line#

State of the HALT line.

The value of this member is 1 if the HALT line is low; otherwise, 0. The emulator updates this member before invoking Z80::halt, not after.

Functions#

Powering the CPU#

void z80_power(Z80 *self, zboolean state)#

Sets the power state of a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

  • stateZ_TRUE = power on; Z_FALSE = power off.

Running the emulation#

zusize z80_execute(Z80 *self, zusize cycles)#

Runs a Z80 for a given number of clock cycles, executing only instructions without responding to signals.

Parameters:
  • self – Pointer to the object on which the function is called.

  • cycles – Number of clock cycles to be emulated.

Returns:

The actual number of clock cycles emulated.

zusize z80_run(Z80 *self, zusize cycles)#

Runs a Z80 for a given number of clock cycles.

Parameters:
  • self – Pointer to the object on which the function is called.

  • cycles – Number of clock cycles to be emulated.

Returns:

The actual number of clock cycles emulated.

Stopping the emulation#

static inline void z80_break(Z80 *self)#

Ends the emulation loop of z80_execute or z80_run.

This function should only be used inside callback functions. It zeroes Z80::cycle_limit, thus breaking the emulation loop after the ongoing emulation step has finished executing.

Parameters:
  • self – Pointer to the object on which the function is called.

Requesting interrupts#

void z80_int(Z80 *self, zboolean state)#

Sets the state of the INT line of a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

  • stateZ_TRUE = set line low; Z_FALSE = set line high.

void z80_nmi(Z80 *self)#

Triggers the NMI line of a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

void z80_instant_reset(Z80 *self)#

Performs an instantaneous normal RESET on a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

void z80_special_reset(Z80 *self)#

Sends a special RESET signal to a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

Obtaining information#

static inline zuint8 z80_in_cycle(Z80 const *self)#

Obtains the clock cycle, relative to the start of the instruction, at which the I/O read M-cycle being executed by a Z80 begins.

Parameters:
  • self – Pointer to the object on which the function is called.

Returns:

The clock cycle at which the I/O read M-cycle begins.

static inline zuint8 z80_out_cycle(Z80 const *self)#

Obtains the clock cycle, relative to the start of the instruction, at which the I/O write M-cycle being executed by a Z80 begins.

Parameters:
  • self – Pointer to the object on which the function is called.

Returns:

The clock cycle at which the I/O write M-cycle begins.

static inline zuint8 z80_r(Z80 const *self)#

Gets the full value of the R register of a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

Returns:

The value of the R register.

static inline zuint16 z80_refresh_address(Z80 const *self)#

Obtains the refresh address of the M1 cycle being executed by a Z80.

Parameters:
  • self – Pointer to the object on which the function is called.

Returns:

The refresh address.

Macros#

Library version#

Z80_LIBRARY_VERSION_MAJOR#

Major version number of the Z80 library.

Z80_LIBRARY_VERSION_MINOR#

Minor version number of the Z80 library.

Z80_LIBRARY_VERSION_MICRO#

Micro version number of the Z80 library.

Z80_LIBRARY_VERSION_STRING#

String literal with the version number of the Z80 library.

Limits#

Z80_MAXIMUM_CYCLES#

Maximum number of clock cycles that z80_run and z80_execute can emulate.

Z80_MAXIMUM_CYCLES_PER_STEP#

Maximum number of clock cycles that z80_run will emulate if instructed to execute 1 clock cycle.

This is the number of clock cycles it takes to execute the longest instruction through interrupt mode 0, not counting the M-cycle used to fetch a 0xDD or 0xFD prefix. For z80_execute, subtract 4 clock cycles from this value.

Z80_MINIMUM_CYCLES_PER_STEP#

Minimum number of clock cycles that z80_run or z80_execute will emulate if instructed to execute 1 clock cycle.

Opcodes#

Z80_HOOK#

Opcode interpreted as a trap by the Z80 library. It corresponds to the ld h,h instruction in the Z80 ISA.

Flags#

Z80_SF#

Bitmask of the Z80 S flag.

Z80_ZF#

Bitmask of the Z80 Z flag.

Z80_YF#

Bitmask of the Z80 Y flag.

Z80_HF#

Bitmask of the Z80 H flag.

Z80_XF#

Bitmask of the Z80 X flag.

Z80_PF#

Bitmask of the Z80 P/V flag.

Z80_NF#

Bitmask of the Z80 N flag.

Z80_CF#

Bitmask of the Z80 C flag.

Configuration#

Z80_OPTION_HALT_SKIP#

Z80::options bitmask that enables the HALTskip optimization.

Z80_OPTION_IM0_RETX_NOTIFICATIONS#

Z80::options bitmask that enables notifications for any reti or retn instruction executed during the interrupt mode 0 response.

Z80_OPTION_LD_A_IR_BUG#

Z80::options bitmask that enables emulation of the bug affecting the Zilog Z80 NMOS, which causes the P/V flag to be reset when a maskable interrupt is accepted during the execution of the ld a,{i|r} instructions.

Z80_OPTION_OUT_VC_255#

Z80::options bitmask that enables emulation of the out (c),255 instruction, specific to the Zilog Z80 CMOS.

Z80_OPTION_XQ#

Z80::options bitmask that enables the XQ factor in the emulation of the ccf and scf instructions.

Z80_OPTION_YQ#

Z80::options bitmask that enables the YQ factor in the emulation of the ccf and scf instructions.

Z80_MODEL_ZILOG_NMOS#

Z80::options bitmask that enables full emulation of the Zilog NMOS models.

Z80_MODEL_ZILOG_CMOS#

Z80::options bitmask that enables full emulation of the Zilog CMOS models.

Z80_MODEL_NEC_NMOS#

Z80::options bitmask that enables full emulation of the NEC NMOS models.

Z80_MODEL_ST_CMOS#

Z80::options bitmask that enables full emulation of the ST CMOS models.

Requests#

Z80_REQUEST_INT#

Z80::request bitmask indicating that the INT line is low and interrupts are enabled.

Z80_REQUEST_NMI#

Z80::request bitmask indicating that an NMI signal has been received.

Z80_REQUEST_REJECT_NMI#

Z80::request bitmask that prevents the NMI signal from being accepted.

Z80_REQUEST_SPECIAL_RESET#

Z80::request bitmask indicating that a special RESET signal has been received.

Resume codes#

Sometimes the emulator runs out of clock cycles while performing long tasks that can exceed Z80_MAXIMUM_CYCLES_PER_STEP. In these cases, the emulation stops and Z80::resume is set to one of the following values:

Z80_RESUME_HALT#

Z80::resume value indicating that the emulator ran out of clock cycles during the HALT state.

Z80_RESUME_XY#

Z80::resume value indicating that the emulator ran out of clock cycles by fetching a prefix 0xDD or 0xFD.

Z80_RESUME_IM0_XY#

Z80::resume value indicating that the emulator ran out of clock cycles by fetching a prefix 0xDD or 0xFD, during a maskable interrupt response in mode 0.

HALT state codes#

Z80_HALT_EXIT_EARLY#

Value of the second parameter of Z80::halt when the HALT line goes high due to a special RESET signal.

Z80_HALT_CANCEL#

Value of the second paratemer of Z80::halt when the HALT line goes low and then high due to a special RESET signal during the execution of a halt instruction.

Register accessors#

Z80_MEMPTR(object)#

Accesses the MEMPTR register of a Z80 object.

Z80_WZ#

Same as Z80_MEMPTR.

Z80_PC(object)#

Accesses the PC register of a Z80 object.

Z80_SP(object)#

Accesses the SP register of a Z80 object.

Z80_XY(object)#

Accesses the temporary index register of a Z80 object.

Z80_IX(object)#

Accesses the IX register of a Z80 object.

Z80_IY(object)#

Accesses the IY register of a Z80 object.

Z80_AF(object)#

Accesses the AF register of a Z80 object.

Z80_BC(object)#

Accesses the BC register of a Z80 object.

Z80_DE(object)#

Accesses the DE register of a Z80 object.

Z80_HL(object)#

Accesses the HL register of a Z80 object.

Z80_AF_(object)#

Accesses the AF’ register of a Z80 object.

Z80_BC_(object)#

Accesses the BC’ register of a Z80 object.

Z80_DE_(object)#

Accesses the DE’ register of a Z80 object.

Z80_HL_(object)#

Accesses the HL’ register of a Z80 object.

Z80_MEMPTRH(object)#

Accesses the most significant byte of the MEMPTR register of a Z80 object.

Z80_MEMPTRL(object)#

Accesses the least significant byte of the MEMPTR register of a Z80 object.

Z80_WZH#

Same as Z80_MEMPTRH.

Z80_WZL#

Same as Z80_MEMPTRL.

Z80_PCH(object)#

Accesses the most significant byte of the PC register of a Z80 object.

Z80_PCL(object)#

Accesses the least significant byte of the PC register of a Z80 object.

Z80_SPH(object)#

Accesses the most significant byte of the SP register of a Z80 object.

Z80_SPL(object)#

Accesses the least significant byte of the SP register of a Z80 object.

Z80_XYH(object)#

Accesses the most significant byte of the temporary index register of a Z80 object.

Z80_XYL(object)#

Accesses the least significant byte of the temporary index register of a Z80 object.

Z80_IXH(object)#

Accesses the IXH register of a Z80 object.

Z80_IXL(object)#

Accesses the IXL register of a Z80 object.

Z80_IYH(object)#

Accesses the IYH register of a Z80 object.

Z80_IYL(object)#

Accesses the IYL register of a Z80 object.

Z80_A(object)#

Accesses the A register of a Z80 object.

Z80_F(object)#

Accesses the F register of a Z80 object.

Z80_B(object)#

Accesses the B register of a Z80 object.

Z80_C(object)#

Accesses the C register of a Z80 object.

Z80_D(object)#

Accesses the D register of a Z80 object.

Z80_E(object)#

Accesses the E register of a Z80 object.

Z80_H(object)#

Accesses the H register of a Z80 object.

Z80_L(object)#

Accesses the L register of a Z80 object.

Z80_A_(object)#

Accesses the most significant byte of the AF’ register of a Z80 object.

Z80_F_(object)#

Accesses the least significant byte of the AF’ register of a Z80 object.

Z80_B_(object)#

Accesses the most significant byte of the BC’ register of a Z80 object.

Z80_C_(object)#

Accesses the least significant byte of the BC’ register of a Z80 object.

Z80_D_(object)#

Accesses the most significant byte of the DE’ register of a Z80 object.

Z80_E_(object)#

Accesses the least significant byte of the DE’ register of a Z80 object.

Z80_H_(object)#

Accesses the most significant byte of the HL’ register of a Z80 object.

Z80_L_(object)#

Accesses the least significant byte of the HL’ register of a Z80 object.