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 prevent the user from having 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_DEPENDENCIES_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: zboolean, zchar, zsint, zsint8, zuint, zuint8, zuint16, zuint32, zusize, ZInt16 and ZInt32.

You can use this macro when compiling Z80.c as a part of 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#

Restricts the visibility of public symbols.

This macro is required if you are building Z80.c as a static library, compiling it directly as a part of your project, or linking your program against the static version of the Z80 library. In either of these cases, make sure 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 “Installation” section are disabled by default. If you compile Z80.c as a part of 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_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_DEPENDENCIES_HEADER, the above macros can be empty; the source code only checks whether they are defined.