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.

Parameters:
  • context – The Z80::context of the calling object.

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

Returns:

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.

Parameters:
  • context – The Z80::context of the calling object.

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

  • 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.

Parameters:
  • context – The Z80::context of the calling object.

  • 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.

Parameters:
typedef zuint8 (*Z80Illegal)(Z80 *cpu, zuint8 opcode)

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

Parameters:
  • cpu – The calling object.

  • opcode – The illegal opcode.

Returns:

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

Q factor.

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, zbool 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 completion of the ongoing emulation step.

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

Requesting interrupts

void z80_int(Z80 *self, zbool 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.