# The Z80 emulator that emulates the undocumented flags too

> redcode's Z80 is an ANSI C emulator of the Zilog Z80 that covers MEMPTR, the Q flag, the special RESET behaviour and interrupt mode 0, validated against the three major CPU test suites. It is a library, not a machine, and the output is a mesh of triangles rather than a playable system.

**redcode/Z80** — Highly portable Zilog Z80 CPU emulator written in ANSI C

- Repository: https://github.com/redcode/Z80
- Website: https://zxe.io/software/Z80
- Stars: 565 · Forks: 57
- Language: C
- License: LGPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/redcode-z80

## It emulates the parts Zilog never documented

The Z80 library implements a fast, small and accurate emulator of the Zilog Z80, and the README is explicit that it emulates all that is known to date about this CPU. That includes the undocumented behaviours, and it names three of them: MEMPTR, the Q flag, and the special RESET behaviour.

Those three are the reason this library is not interchangeable with a generic 8-bit CPU core. MEMPTR is the internal bus address latch, and some undocumented instructions leak it into flags, so an emulator that does not model it produces wrong results for exactly the instructions that clever software uses. The Q flag is the undocumented flag that carries the parity of the number of bits set in the status register. The special RESET behaviour is a different reset vector mode that some boot roms depend on.

The library also claims the honor of having been the first open source project to provide full emulation of interrupt mode 0, which is the mode where a device places a byte on the bus and the CPU executes it as an instruction, and which is famously the source of ROP-era exploits on real hardware.

The source is written in ANSI C for maximum portability and is extensively commented, with the stated aim of a well-structured, easy to understand piece of software that can stand the test of time with no need for major changes. The homepage is zxe.io/software/Z80 and the licence is LGPL-3.0.

## Instruction-level granularity, and what that costs in precision

The Accuracy section is where the design trade-off is spelled out, and it is the part to read before you use the library.

The emulator has a classic design with instruction-level granularity that delivers high performance whilst offering reasonable flexibility to achieve precision down to the T-state level.

What instruction-level granularity means in practice is spelled out next. Except in a few well-defined cases, the execution of a given instruction cannot stop until all its internal M-cycles have been processed, that is, instructions are not divided into micro-operations. Registers are modified only once per instruction, and the T-state counter is normally updated after a full instruction has been executed.

So the timing is exact at instruction boundaries and approximate within them. A cycle counter that needs to know precisely when a memory access happened inside an instruction will not get it from the counter, though the README links to a separate project that does T-state level instruction clocking, which suggests the authors know the boundary.

The parts that matter most are accurate. Instructions, flags, memory accesses, interrupts and clock cycles are emulated according to the available technical documentation, the findings made after decades of research on the Z80, and electronic simulations. That last phrase is worth pausing on: the specification of this CPU is partly a body of folklore recovered from measured hardware behaviour, not a document.

The repository keeps the source of that knowledge in a wiki, with a technical literature page and a simulators page, which is unusual and useful. The evidence base is part of the project.

## The three test suites, and the four ways they slice the CPU

The README says the emulator passes the most exhaustive tests written to date, including all three major test suites. The first is the Zilog Z80 CPU Test Suite by Patrik Rak, and its stated purpose is to help emulator authors reach the desired level of CPU emulation authenticity. Each program in it performs an exhaustive computation using each of the tested Z80 instructions, compares the results with values obtained from a real Sinclair ZX Spectrum 48K with a Zilog Z80 CPU, and reports any deviations detected.

That comparison against real hardware is the key methodological point. The tests are not checking against a specification, they are checking against a physical machine, which is the only oracle available for undocumented behaviour.

The suite is offered in four variants that slice the CPU differently, and the variants tell you what the emulator is claiming.

z80full.tap tests all flags and registers. z80doc.tap tests all registers but only officially documented flags. z80flags.tap tests all flags and ignores registers. And z80docflags.tap tests documented flags only and ignores registers.

Then two more specific ones. z80ccf.tap tests all flags after executing ccf after each instruction tested, which checks the complement-carry-flag behaviour in isolation. And z80memptr.tap tests all flags after executing bit N,(hl) after each instruction tested, which is the MEMPTR leak in isolation.

So the suite covers the documented behaviour, the undocumented behaviour, and the interactions, in the combinations a consumer of the library might actually care about.

## Getting the library: CMake, an API directory and a documentation site

There is no install command in the README, and for a library written in ANSI C that is normal. The project points at the documentation site at zxe.io/software/Z80/documentation/latest, and the repository itself tells you what you are getting: a CMake based build, an API directory, and a documentation directory.

The repository layout makes the scope clear. There is an API/ directory, a CMake/ directory and a CMakeLists.txt at the top, a sources/ directory, a support/ directory, a documentation/ directory, and a set of project files including HISTORY, THANKS, AUTHORS, CITATION.cff and a COPYING file alongside COPYING.LESSER.

Two things follow. First, the project is built with CMake rather than a plain Makefile, which is the portable choice for something that has to compile on several systems. Second, the presence of both a COPYING and a COPYING.LESSER, together with the LGPL-3.0 licence, points to a library rather than an application, and the API/ directory is the public surface.

What is not here is equally informative. There is no firmware directory, no memory map, no video circuit, no keyboard handling, no operating system, and no assembler. A ZX Spectrum emulator built on this library would need all of those, and the README's insistence on the CPU only is not a limitation being hidden.

The two COPYING files are worth a note for anyone embedding it. The double licensing arrangement of a LGPL library, with one licence for the code and one for the accompanying material, is a common pattern, and the exact split is in those two files. This is a description of where to look, not a reading of the terms.

The continuous integration badges tell you the shape of the work. There is a build-and-test-library workflow, a build-documentation workflow and a step-tests workflow, so the library, the generated API documentation and the step-by-step test suite are all built and checked separately. The CITATION.cff file is a small sign that the project is treated as a citable piece of work, which for a CPU emulator it plainly is.

For a first real use, the order of work is the same as the order of the directories. Build the library with CMake, read the API reference for the entry points, in particular the T-state counter, and then bring in one of the example objects from the API directory. There is also a chat link and a wiki in the repository, and a step-tests workflow in the continuous integration, so the same tests the project relies on are the ones you can run.

## The release naming says pre-release, and the tags are dated

The version tags are the most informative thing in the repository metadata, and they need reading carefully.

The recent releases are v0.2-pre-2025-07-02, v0.2-pre-2025-05-02 and v0.2-pre-2024-09-21. Every one of them carries a pre marker and a date. There is no 1.0 tag, and there is no plain v0.2.

That naming scheme is a deliberate signal. It tells you that the author considers the 0.2 line to be a pre-release, and it makes the tag sortable by date so you can tell which snapshot you have without looking inside it. For a library whose entire value proposition is that it stands the test of time, a versioning scheme that refuses to claim stability until it is there is a coherent choice.

The repository is not archived and the last push was on 2026-10-18, so the work is current even though the newest tag is from July 2025. There is a HISTORY file at the top level, which is where the change log lives for a project of this vintage.

For a user, the practical question is which snapshot to vendor. The dated pre-release tags make that a choice you can make deliberately, and the step-tests workflow suggests the test suite is run as part of the build rather than being a separate manual effort.

## Where the Z80 library is the wrong tool

Two clear cases and one that is a matter of degree.

The first is when you want a working machine. This is a CPU core. There is no firmware, no memory map, no video, no keyboard, no sound and no operating system in this repository, and no assembler to produce the code you would run on it. If you want to play Spectrum software, there are complete emulators built on top of this kind of core, and the README points to a simulators page in the wiki for exactly that kind of reference. Using the library directly means building the machine yourself.

The second is when you need a different architecture. There is one CPU here, the Z80. The repository topics list z80 and zilog, and the licence and structure are those of a single core library. A project needing a 6502 or an 68000 alongside would be combining two unrelated libraries, and the effort in matching their timing semantics is on you.

The third is about timing precision, and it is a matter of degree rather than kind. Instruction-level granularity means the T-state counter is normally updated after a full instruction has executed, and registers are modified once per instruction. For software that only cares about instruction timing, that is exactly right, and it is why the design is described as delivering high performance. But for software that depends on exact intra-instruction timing, such as code that depends on when a memory access lands relative to a flag change, the counter will not give you that, and the README links to a separate project that does instruction-level clocking.

The other limit is the licence rather than the software. LGPL-3.0 on a library you link into a larger program imposes obligations on how you distribute the combined work, and that is a conversation to have before you vendor it rather than after.

## Conclusion

Adopt the Z80 library if you are writing a Z80 emulator, a homebrew system, a game engine for 8-bit hardware or a test harness and you need cycle and flag accuracy that includes the undocumented behaviours. Do not adopt it if you want a runnable ZX Spectrum or a finished machine, because the project is a CPU core with no memory map, no video and no firmware. Before you build against it, read the API reference for the T-state counter and the technical literature wiki, and check the test results section to see which of the three test suites your use case actually depends on.

## FAQ

### What does the redcode Z80 library emulate?

It emulates the Zilog Z80 including the undocumented behaviours, specifically MEMPTR, the Q flag and the special RESET behaviour, and the README says it was the first open source project to provide full emulation of interrupt mode 0.

### How is the Z80 emulator validated?

The README says it passes the most exhaustive tests written to date, including the Zilog Z80 CPU Test Suite by Patrik Rak, whose programs compare exhaustive computations against values obtained from a real Sinclair ZX Spectrum 48K and report any deviations.

### What does instruction-level granularity mean for timing?

Except in a few well-defined cases, an instruction cannot stop until all its internal M-cycles have been processed, registers are modified only once per instruction, and the T-state counter is normally updated after a full instruction has been executed. The library offers precision down to the T-state level for most uses.

### What language and build system does the Z80 library use?

The source is written in ANSI C for maximum portability and is extensively commented, and the repository is built with CMake, with a CMake/ directory and a CMakeLists.txt at the top level. The project is licensed LGPL-3.0.

## Sources

- [License: LGPL-3.0](https://github.com/redcode/Z80/blob/master/LICENSE)
- [Project website](https://zxe.io/software/Z80)
- [README](https://github.com/redcode/Z80/blob/master/README.md)
- [redcode/Z80 on GitHub](https://github.com/redcode/Z80)
- [Releases](https://github.com/redcode/Z80/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/redcode-z80
