Integration

As an external dependency in CMake-based projects

The Z80 library includes a config-file package for integration into CMake-based projects that must be installed for development. Use find_package to find the Z80 package. This creates the Z80 imported library target, which carries the necessary transitive link dependencies. Optionally, the linking method can be selected by specifying either the Shared or Static component.

Example:

find_package(Z80 REQUIRED Shared)
target_link_libraries(your-target Z80)

When not specified as a component, the linking method is selected according to Z80_SHARED_LIBS. If this option is not defined, the config-file uses the type of library that is installed on the system and, if it finds both the shared and the static versions, BUILD_SHARED_LIBS determines which one to link against.

As a CMake subproject

To embed the Z80 library as a CMake subproject, extract the source code tarballs of Zeta and Z80 (or clone their respective repositories) into a subdirectory of another project. Then use add_subdirectory in the parent project to add the Z80 source code tree to the build process (N.B., the Z80 subproject will automatically find Zeta and import it as an interface library).

It is advisable to configure the Z80 library in the CMakeLists.txt of the parent project. This will eliminate the need for the user to specify configuration options for the Z80 subproject through the command line when building the main project.

Example:

set(Z80_SHARED_LIBS                 NO  CACHE BOOL "")
set(Z80_WITH_Q                      YES CACHE BOOL "")
set(Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG YES CACHE BOOL "")

add_subdirectory(dependencies/Z80)
target_link_libraries(your-target Z80)

It is important to set the Z80_SHARED_LIBS option. Otherwise, CMake will build the library type indicated by BUILD_SHARED_LIBS, which may not be the desired one.

Non-CMake-based projects

The source code of the emulator can be configured at compile time by predefining a series of macros. Both Z80.h and Z80.c obey the first two explained below. The rest of the macros are only relevant when compiling Z80.c:

Z80_EXTERNAL_HEADER

Specifies the only external header to #include, replacing all others.

Predefine this macro to provide a header file that defines the external types and macros used by the emulator, thus preventing your project from depending on Zeta:

  • Macros: Z_ALWAYS_INLINE, Z_API_EXPORT, Z_API_IMPORT, Z_CAST, Z_EMPTY, Z_EXTERN_C_BEGIN, Z_EXTERN_C_END, Z_MEMBER_OFFSET, Z_NULL, Z_UINT8_ROTATE_LEFT, Z_UINT8_ROTATE_RIGHT, Z_UINT16, Z_UINT16_BIG_ENDIAN, Z_UINT32, Z_UINT32_BIG_ENDIAN, Z_UNUSED, Z_USIZE and Z_USIZE_MAXIMUM.

  • Types: zbool, zchar, zsint, zsint8, zuint, zuint8, zuint16, zuint32, zusize, ZInt16 and ZInt32.

You can use this macro when compiling Z80.c within your project or (if your types do not break the binary compatibility) when including <Z80.h> and linking against a pre-built Z80 library.

Z80_STATIC

Indicates that the emulator is a static library.

This macro must be predefined when building Z80.c as a static library. Additionally, if you compile Z80.c directly within your project or link your program against the static version of the Z80 library, ensure that this macro is defined before including "Z80.h" or <Z80.h>.

Z80_WITH_LOCAL_HEADER

Tells Z80.c to #include "Z80.h" instead of <Z80.h>.

The optional features of the emulator mentioned in the “Configure” section of “Installation from source code” are disabled by default. If you compile Z80.c within your project, enable those features you need by predefining their respective activation macros. They have the same name as their CMake equivalents:

Z80_WITH_EXECUTE

Enables the implementation of the z80_execute() function.

Z80_WITH_FULL_IM0

Enables the full implementation of the interrupt mode 0.

Z80_WITH_IM0_RETX_NOTIFICATIONS

Enables optional notifications for any reti or retn instruction executed during the interrupt mode 0 response.

Z80_WITH_PARITY_COMPUTATION

Enables actual parity calculation for the P/V flag instead of using a table of precomputed values.

Z80_WITH_PRECOMPUTED_DAA

Enables the use of a table of precomputed values to emulate the daa instruction.

Z80_WITH_Q

Enables the implementation of Q.

Z80_WITH_SPECIAL_RESET

Enables the implementation of the special RESET.

Z80_WITH_UNOFFICIAL_RETI

Configures the undocumented instructions ED5Dh, ED6Dh and ED7Dh as reti instead of retn.

Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG

Enables the implementation 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.

Except for Z80_EXTERNAL_HEADER, the above macros can be empty; the source code only checks whether they are defined.