Skip to main content

z80

Fast and flexible Z80/i8080 emulator.

Python package CI C/C++ CI PyPI Python License: MIT

Quick facts

  • Implements accurate machine cycle-level emulation.

  • Supports undocumented instructions, flags and registers.

  • Passes the well-known cputest, 8080pre, 8080exer, 8080exm, prelim and zexall tests.

  • Follows a modular event-driven design for flexible interfacing.

  • Employs compile-time polymorphism for zero performance overhead.

  • Cache-friendly implementation without large code switches and data tables.

  • Offers default modules for the breakpoint support and generic memory.

  • Supports multiple independently customised emulator instances.

  • Written in strict C++11.

  • Does not rely on implementation-defined or unspecified behaviour.

  • Single-header implementation.

  • Provides a generic Python 3 API and instruments to create custom bindings.

  • MIT license.

Contents

Hello world

#include "z80.h"

class my_emulator : public z80::z80_cpu<my_emulator> {
public:
    typedef z80::z80_cpu<my_emulator> base;

    my_emulator() {}

    void on_set_pc(z80::fast_u16 pc) {
        std::printf("pc = 0x%04x\n", static_cast<unsigned>(pc));
        base::on_set_pc(pc);
    }
};

int main() {
    my_emulator e;
    e.on_step();
    e.on_step();
    e.on_step();
}

hello.cpp

Building:

$ git clone git@github.com:kosarev/z80.git
$ cmake z80
$ make
$ make test
$ make hello  # Or 'make examples' to build all examples at once.

Running:

$ ./examples/hello
pc = 0x0000
pc = 0x0001
pc = 0x0002

In this example we derive our custom emulator class, my_emulator, from a mix-in that implements the logic and default interfaces necessary to emulate the Zilog Z80 processor. As you may guess, replacing z80_cpu with i8080_cpu would give us a similar Intel 8080 emulator.

The on_set_pc() method overrides its default counterpart to print the current value of the PC register before changing it. For this compile-time polymorphism to be able to do its job, we pass the type of the custom emulator to the processor mix-in as a parameter.

The main() function creates an instance of the emulator and asks it to execute a few instructions, thus triggering the custom version of on_set_pc(). The following section reveals what those instructions are and where the emulator gets them from.

Adding memory

Every time the CPU emulator needs to access memory, it calls on_read() and on_write() methods. Their default implementations do not really access any memory; on_read() simply returns 0x00, meaning the emulator in the example above actually executes a series of nops, and on_write() does literally nothing.

Since both the reading and writing functions are considered by the z80::z80_cpu class to be handlers, which we know because they have the on preposition in their names, we can use the same technique as with on_set_pc() above to override the default handlers to actually read and write something.

class my_emulator : public z80::z80_cpu<my_emulator> {
public:
    ...

    fast_u8 on_read(fast_u16 addr) {
        assert(addr < z80::address_space_size);
        fast_u8 n = memory[addr];
        std::printf("read 0x%02x at 0x%04x\n", static_cast<unsigned>(n),
                    static_cast<unsigned>(addr));
        return n;
    }

    void on_write(fast_u16 addr, fast_u8 n) {
        assert(addr < z80::address_space_size);
        std::printf("write 0x%02x at 0x%04x\n", static_cast<unsigned>(n),
                    static_cast<unsigned>(addr));
        memory[addr] = static_cast<least_u8>(n);
    }

private:
    least_u8 memory[z80::address_space_size] = {
        0x21, 0x34, 0x12,  // ld hl, 0x1234
        0x3e, 0x07,        // ld a, 7
        0x77,              // ld (hl), a
    };
};

adding_memory.cpp

Output:

read 0x21 at 0x0000
pc = 0x0001
read 0x34 at 0x0001
read 0x12 at 0x0002
pc = 0x0003
read 0x3e at 0x0003
pc = 0x0004
read 0x07 at 0x0004
pc = 0x0005
read 0x77 at 0x0005
pc = 0x0006
write 0x07 at 0x1234

Input and output

Aside from memory, another major way the processors use to communicate with the outside world is via input and output ports. If you read the previous sections, it's now easy to guess that there are a couple of handlers that do that. These are on_input() and on_output().

Note that the handlers have different types of parameters that store the port address, because i8080 only supports 256 ports while Z80 extends that number to 64K.

    // i8080_cpu
    fast_u8 on_input(fast_u8 port)
    void on_output(fast_u8 port, fast_u8 n)

    // z80_cpu
    fast_u8 on_input(fast_u16 port)
    void on_output(fast_u16 port, fast_u8 n)

The example:

class my_emulator : public z80::z80_cpu<my_emulator> {
public:
    ...

    fast_u8 on_input(fast_u16 port) {
        fast_u8 n = 0xfe;
        std::printf("input 0x%02x from 0x%04x\n", static_cast<unsigned>(n),
                    static_cast<unsigned>(port));
        return n;
    }

    void on_output(fast_u16 port, fast_u8 n) {
        std::printf("output 0x%02x to 0x%04x\n", static_cast<unsigned>(n),
                    static_cast<unsigned>(port));
    }

private:
    least_u8 memory[z80::address_space_size] = {
        0xdb,        // in a, (0xfe)
        0xee, 0x07,  // xor 7
        0xd3,        // out (0xfe), a
    };
};

input_and_output.cpp

Accessing processor's state

Sometimes it's necessary to examine and/or alter the current state of the CPU emulator and do that in a way that is transparent to the custom code in overridden handlers. For this purpose the default state interface implemented in the i8080_state<> and z80_state<> classes provide a number of getters and setters for registers, register pairs, interrupt flip-flops and other fields constituting the internal state of the emulator. By convention, calling such functions does not fire up any handlers. The example below demonstrates a typical usage.

Note that there are no such accessors for memory as it is external to the processor emulators and they themselves have to use handlers, namely, the on_read() and on_write() ones, to deal with memory.

class my_emulator : public z80::z80_cpu<my_emulator> {
public:
    ...

    events_mask::type on_step() {
        std::printf("hl = %04x\n", static_cast<unsigned>(get_hl()));
        events_mask::type events = base::on_step();

        // Start over on every new instruction.
        set_pc(0x0000);

        return events;
    }

accessing_state.cpp

Modules

By overriding handlers we can extend and otherwise alter the default behaviour of CPU emulators. That's good, but what do we do if it's not enough? For example, what if the default representation of the processor's internal state doesn't fit the needs of your application? Say, you might be forced to follow a particular order of registers or you just want to control the way they are packed in a structure because there's some external binary API to be compatible with. Or, what if you don't need to emulate the whole processor's logic, and just want to check if a given sequence of bytes forms a specific instruction?

That's where modules come into play. To understand what they are and how to use them, let's take a look at the definitions of the emulator classes and see what's under the hood.

template<typename D>
class i8080_cpu : public i8080_executor<i8080_decoder<i8080_state<root<D>>>>
{};

template<typename D>
class z80_cpu : public z80_executor<z80_decoder<z80_state<root<D>>>>
{};

Each of these classes is no more than a stack of a few other mix-ins. The root<> template provides helpers that make it possible to call handlers of the most derived class in the hierarchy, D, which is why it takes that class as its type parameter. It also contains dummy implementations of the standard handlers, such as on_output(), so you don't have to define them when you don't need them.

i8080_state<> and z80_state<> have been mentioned in the previous section as classes that define transparent accessors to the processor state, e.g., set_hl(). They also define corresponding handlers, like on_set_hl(), that other modules use to inspect and modify the state.

i8080_decoder<> and z80_decoder<> modules analyse op-codes and fire up handlers for specific instructions, e.g., on_halt().

Finally, the job of i8080_executor<> and z80_executor<> is to implement handlers like on_halt() to actually execute corresponding instructions.

The convention is that modules shall communicate with each other only via handlers. Indeed, if they called the transparent accessors or referred to data fields directly, then those accessors wouldn't be transparent anymore and handlers would never be called. This also means that modules are free to define transparent accessors in a way that seems best for their purpose or even not define them at all.

All and any of the standard modules can be used and customised independently of each other. Moreover, all and any of the modules can be replaced with custom implementations. New modules can be developed and used separately or together with the standard ones. In all cases the only requirement is to implement handlers other modules rely on.

The root module

template<typename D>
class root {
public:
    typedef D derived;

    using events_mask = bitmask;

    ...

    fast_u8 on_read(fast_u16 addr) {
        unused(addr);
        return 0x00;
    }

    void on_write(fast_u16 addr, fast_u8 n) {
        unused(addr, n);
    }

    ...

protected:
    const derived &self() const{ return static_cast<const derived&>(*this); }
    derived &self() { return static_cast<derived&>(*this); }
};

The main function of the root module is to define the self() method that other modules can use to call handlers. For example, a decoder could do self().on_ret() whenever it runs into a ret instruction.

Aside from that, the module contains dummy implementations of the standard handlers that do nothing or, if they have to return something, return some default values.

The root module also seeds the events_mask type with an empty set of events. A module whose logic raises events shadows the name with an extension of its base module's mask, declaring the new bits relative to the base mask's unused_bit, so the set of events composes automatically as modules are layered: the executor declares breakpoint_hit and retry_input, the machine_state<> module declares end_of_frame, and custom modules declare their own events the same way. The composed mask is then available on the most derived class, e.g., my_emulator::events_mask::breakpoint_hit.

State modules

template<typename B>
class i8080_state : public internals::cpu_state_base<B> {
public:
    ...

    bool get_iff() const { ... }
    void set_iff(bool f) { ... }

    ...
};

template<typename B>
class z80_state : public internals::cpu_state_base<z80_decoder_state<B>> {
public:
    ...

    void exx_regs() { ... }
    void on_exx_regs() { exx_regs(); }

    ...
};

The purpose of state modules is to provide handlers to access the internal state of the emulated CPU. They also usually store the fields of the state, thus defining its layout in memory.

Regardless of the way the fields are represented and stored, the default getting and setting handlers for register pairs use access handlers for the corresponding 8-bit registers to obtain or set the 16-bit values. Furthermore, the low half of the register pair is always retrieved and set before the high half. This means that by default handlers for 8-bit registers are getting called even if originally a value of a register pair they are part of has been queried. Custom implementations of processor states, however, are not required to do so.

    fast_u16 on_get_bc() {
        // Always get the low byte first.
        fast_u8 l = self().on_get_c();
        fast_u8 h = self().on_get_b();
        return make16(h, l);

    void on_set_bc(fast_u16 n) {
        // Always set the low byte first.
        self().on_set_c(get_low8(n));
        self().on_set_b(get_high8(n));
    }

Aside from the usual getters and setters for the registers and flip-flops, both the i8080 and Z80 states have to provide an on_ex_de_hl_regs() handler that exchanges hl and de registers the same way the xchg and ex de, hl do. And the Z80 state additionally has to have an on_exx_regs() that swaps register pairs just as the exx instruction does. The default swapping handlers do their work by accessing registers directly, without relying on the getting and setting handlers, similarly to how silicon implementations of the processors toggle internal flip-flops demux'ing access to register cells without actually transferring their values.

Because the CPUs have a lot of similarities, processor-specific variants of modules usually share some common code in helper base classes that in turn are defined in the internals class. That class defines entities that are internal to the implementation of the library. The client code is therefore supposed to be written as if the module classes are derived directly from their type parameters, B.

Note that z80_state has an additional mix-in in its inheritance chain, z80_decoder_state<>, whereas i8080_state is derived directly from the generic base. This is because Z80 decoders are generally not stateless objects; they have to track which of the IX, IY or HL registers has to be used as the index register for the current instruction. The decoder state class stores and provides access to that information.

template<typename B>
class z80_decoder_state : public B {
public:
    ...

    iregp get_iregp_kind() const { ... }
    void set_iregp_kind(iregp r) { ... }

    iregp on_get_iregp_kind() const { return get_iregp_kind(); }
    void on_set_iregp_kind(iregp r) { set_iregp_kind(r); }

    ...
};

In its simplest form, a custom state module can be a structure defining the necessary state fields together with corresponding access handlers.

template<typename B>
struct my_state : public B {
    fast_u16 pc;

    ...

    fast_u16 on_get_pc() const { return pc; }
    void on_set_pc(fast_u16 n) { pc = n; }

    ...

    // These always have to be explicitly defined.
    void on_ex_de_hl_regs() {}
    void on_ex_af_alt_af_regs() {}
    void on_exx_regs() {}
};

custom_state.cpp

Using it from Python

Besides the C++ library, the emulator ships as a Python package: pip install z80 (prebuilt wheels are available, so no C++ toolchain is needed). It offers the same processors as z80.Z80Machine and z80.I8080Machine, and lets your code examine and alter the machine state directly: registers and flags are exposed as plain attributes, and memory through m.memory and m.set_memory_block().

from z80 import ADD, HALT, A, B, Code, Z80Machine

m = Z80Machine()

# A one-instruction routine that adds the B register to the
# accumulator and then halts.
code = Code()
code.add(ADD(A, B),
         HALT())
addr, image = code.encode()[0]
m.set_memory_block(addr, image)

# Alter the state: seed the operands into the registers and point
# the program counter at the routine, all from Python.
m.a = 30
m.b = 12
m.pc = 0x0000

m.run()

# Examine the state: read the result back out of the accumulator.
print(m.a)   # 42

state.py

Here we seed the operands straight into the CPU registers rather than baking them into the program, let the emulator execute a real add instruction, and then read the result back, all without leaving Python. The machine object also exposes m.bc, m.hl, m.sp, the halted flag, and handler callbacks (set_read_callback(), set_output_callback(), ...), mirroring the C++ handlers described above.

Feedback

Any notes on overall design, improving performance and testing approaches are highly appreciated. Please file an issue or use the email given at https://github.com/kosarev. Thanks!

Metadata

Release files for z80 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for z80 1.2.0
File Size Uploaded
z80-1.2.0.tar.gz 84.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for z80 1.2.0
File
z80-1.2.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
z80-1.2.0-cp313-cp313-win32.whl CPython 3.13 CPython 3.13 Windows x86-32 Details
z80-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl CPython 3.13 CPython 3.13 Linux musl 1.2+ x86-64 Details
z80-1.2.0-cp313-cp313-musllinux_1_2_i686.whl CPython 3.13 CPython 3.13 Linux musl 1.2+ x86-32 Details
z80-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details
z80-1.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-32, Linux glibc 2.5+ x86-32 Details
z80-1.2.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
z80-1.2.0-cp312-cp312-win32.whl CPython 3.12 CPython 3.12 Windows x86-32 Details
z80-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl CPython 3.12 CPython 3.12 Linux musl 1.2+ x86-64 Details
z80-1.2.0-cp312-cp312-musllinux_1_2_i686.whl CPython 3.12 CPython 3.12 Linux musl 1.2+ x86-32 Details
z80-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details
z80-1.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-32, Linux glibc 2.5+ x86-32 Details
z80-1.2.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
z80-1.2.0-cp311-cp311-win32.whl CPython 3.11 CPython 3.11 Windows x86-32 Details
z80-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl CPython 3.11 CPython 3.11 Linux musl 1.2+ x86-64 Details
z80-1.2.0-cp311-cp311-musllinux_1_2_i686.whl CPython 3.11 CPython 3.11 Linux musl 1.2+ x86-32 Details
z80-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.17+ x86-64 Details
z80-1.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl CPython 3.11 CPython 3.11 Linux glibc 2.5+ x86-32, Linux glibc 2.17+ x86-32 Details
z80-1.2.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
z80-1.2.0-cp310-cp310-win32.whl CPython 3.10 CPython 3.10 Windows x86-32 Details
z80-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl CPython 3.10 CPython 3.10 Linux musl 1.2+ x86-64 Details
z80-1.2.0-cp310-cp310-musllinux_1_2_i686.whl CPython 3.10 CPython 3.10 Linux musl 1.2+ x86-32 Details
z80-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details
z80-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl CPython 3.10 CPython 3.10 Linux glibc 2.5+ x86-32, Linux glibc 2.17+ x86-32 Details

Total release size: 7.3 MB

Release files / z80-1.2.0.tar.gz

Download URL z80-1.2.0.tar.gz
Size 84.2 kB
Tags Source
SHA-256 checksum
How to use checksums
55631c306d731564a74bd4df00c51abec0d5d72a3afc3c039c7126d7c8cb924c
BLAKE2b-256 checksum
How to use checksums
539048ad77da0b0f44dc6ad968ed0a319bb5cab99ca2a1c87423383e3c90c358
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp313-cp313-win_amd64.whl

Download URL z80-1.2.0-cp313-cp313-win_amd64.whl
Size 76.0 kB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
bec8fa1c42609dd8d7ea7915644ea99f2ea83e46817f50bb02a5dd5c7e61d775
BLAKE2b-256 checksum
How to use checksums
f2804bf896b856943ef6fa09d8fce7e51cffee89b612bc6b4c4cc6ebecb41862
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp313-cp313-win32.whl

Download URL z80-1.2.0-cp313-cp313-win32.whl
Size 74.2 kB
Tags CPython 3.13 Windows x86-32
SHA-256 checksum
How to use checksums
fcae92c6a09fad4ebdc288fd57ec0b74e626475475a75f851c700cd507d0b787
BLAKE2b-256 checksum
How to use checksums
22dfd5b9a50598709aa075ebb5aa6da3f12b919d0ab35aa275e46873cf60db3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl

Download URL z80-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl
Size 418.3 kB
Tags CPython 3.13 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
d976bcff401c35ccade5d6528bbecebec04fe56bc6a21915771c3c2e591576f8
BLAKE2b-256 checksum
How to use checksums
176d447d7a388f54efddba70cbc0a1190c44a6d55e7093e548ac024c3204e5e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp313-cp313-musllinux_1_2_i686.whl

Download URL z80-1.2.0-cp313-cp313-musllinux_1_2_i686.whl
Size 422.6 kB
Tags CPython 3.13 Linux musl 1.2+ x86-32
SHA-256 checksum
How to use checksums
d513da568ac7bf2360e97818bfcc8160a2e99644b5e9b66ebe49f3cd3c22105a
BLAKE2b-256 checksum
How to use checksums
c688047a4f041062b7a6844855bf7ba8b3b9e54a9766e06431e8fb5c78e3120b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL z80-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 418.3 kB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
ee0a841258161b2f9bcf1dc667b6e75f77e070df5a620755c01b7c4ba6df53df
BLAKE2b-256 checksum
How to use checksums
6b2b3af4e33f88d96b76f0cf6f3a22804594ec1024c0b85c623026af7cebae33
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl

Download URL z80-1.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Size 409.6 kB
Tags CPython 3.13 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32
SHA-256 checksum
How to use checksums
9824314a745dd333d96543b445f22278c8e0c9c2d547306119f2118b54ac22f1
BLAKE2b-256 checksum
How to use checksums
c28616bccc1fb2d39db9f97fa47ec058ce699fc47e2c8ee3fe4e8d7abed4545f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp312-cp312-win_amd64.whl

Download URL z80-1.2.0-cp312-cp312-win_amd64.whl
Size 76.0 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
e8c923ad83f0615c9b8f16d4335bcc644882b8addb70aeb6b9c13f16c7d7ee6f
BLAKE2b-256 checksum
How to use checksums
1745f325ee2e7c1db162b30106793802bd51c0147fe3f37c5e02c9c1810fb6d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp312-cp312-win32.whl

Download URL z80-1.2.0-cp312-cp312-win32.whl
Size 74.2 kB
Tags CPython 3.12 Windows x86-32
SHA-256 checksum
How to use checksums
5a0e9d1dfc688e761cd4df5415f1f6f9984c9ff0e177e372519c3fb9e3e1a5ee
BLAKE2b-256 checksum
How to use checksums
5cb186d05aae94a5f5066f2502c94f4938e723fdf09888a08d40c8eac9fb09ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl

Download URL z80-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl
Size 418.4 kB
Tags CPython 3.12 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
0a53089a112bd03271d1ef49dbf7f7f7274ca4ea14c0c7a223c6ffcb40a8bfca
BLAKE2b-256 checksum
How to use checksums
998757afb9d8f33c4b6a073031299d1b28260d8232dc5b4da46081287c3fb638
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp312-cp312-musllinux_1_2_i686.whl

Download URL z80-1.2.0-cp312-cp312-musllinux_1_2_i686.whl
Size 422.6 kB
Tags CPython 3.12 Linux musl 1.2+ x86-32
SHA-256 checksum
How to use checksums
c792eea7337a8fc7a4b07ac9d16edc3f123217979ed8ec5024f9306fb21b5f0e
BLAKE2b-256 checksum
How to use checksums
3f711e590babadf38bc281ce1336b98896b30051ce255369dfd242df025085e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL z80-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 418.3 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
8bf713cd6cb93bb168927789dff1f147726541693216e9815acae76c5d1a14e9
BLAKE2b-256 checksum
How to use checksums
216f6c15e0562e470981a345eb817646bd98de62fbc374489c12f7a39d7c2828
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl

Download URL z80-1.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Size 409.6 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32
SHA-256 checksum
How to use checksums
67e8c76eee31cd205a4f1bfbb9e24ec155c491b54bbb903650a8e3e6a51119e3
BLAKE2b-256 checksum
How to use checksums
9c6e13afba9bb7a966f25916fbed251f92955d731f50cb1cb6f7fde9d043f335
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp311-cp311-win_amd64.whl

Download URL z80-1.2.0-cp311-cp311-win_amd64.whl
Size 75.9 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
30034d3a6858711601c4ac673a7e5fa356bd615241a35ba284c2c6258dc6d049
BLAKE2b-256 checksum
How to use checksums
f46bddb19a5128856fba9dd87c03236bdc198888a284374e257537baf937c3ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp311-cp311-win32.whl

Download URL z80-1.2.0-cp311-cp311-win32.whl
Size 74.1 kB
Tags CPython 3.11 Windows x86-32
SHA-256 checksum
How to use checksums
2bd5c3fa9fb956d7e97f571237c160f75048541d53f8124a076e4362572afca3
BLAKE2b-256 checksum
How to use checksums
69e2c4a0d9027fc799b6d0b50456478d0c8edd1e71f3b70e0936c2aeaa9d37d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl

Download URL z80-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl
Size 416.1 kB
Tags CPython 3.11 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
71e0fd7512b18deafd3e82265bfa20644bd4c8561f012141e037de8df91881dd
BLAKE2b-256 checksum
How to use checksums
4ece63b4aa803302fb752801458fc313a60a8a252f0fd0dee55d7dc057b66195
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp311-cp311-musllinux_1_2_i686.whl

Download URL z80-1.2.0-cp311-cp311-musllinux_1_2_i686.whl
Size 417.8 kB
Tags CPython 3.11 Linux musl 1.2+ x86-32
SHA-256 checksum
How to use checksums
dd769d7792c4532b7fe5c7592b7a74a8b94f821631ffded0050c27c454768ead
BLAKE2b-256 checksum
How to use checksums
1cd6f2ca50e457bda4bc2ff84913c30f0cd4eae09233cfe8d62cde2d99b43548
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL z80-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 414.8 kB
Tags CPython 3.11 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
cf53679bc0ed7900a00644c7c29042b87f460e6fe4f7579703c4656540b61608
BLAKE2b-256 checksum
How to use checksums
36e5bd908cf49f099a628eb54e1089e854857607adc570a99a78f365239a754a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl

Download URL z80-1.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Size 407.5 kB
Tags CPython 3.11 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32
SHA-256 checksum
How to use checksums
2b7ae487c4ea81e70a4cf0a88ce8e51b23b2059acdb14f38db53b5a510192e72
BLAKE2b-256 checksum
How to use checksums
af850ca6df7495d3e867a173e3db11ea42cc6bbd3781e94cbb5a7d62a071cc8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp310-cp310-win_amd64.whl

Download URL z80-1.2.0-cp310-cp310-win_amd64.whl
Size 75.9 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
49b1ca954ab482671c4d739b2ffdd7762b11a5066238f966df2dc778405e7371
BLAKE2b-256 checksum
How to use checksums
43887ad2fe0797a455da91f5b3bbeaa1aba8aa020bcd1f4cb9a480470536baa0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp310-cp310-win32.whl

Download URL z80-1.2.0-cp310-cp310-win32.whl
Size 74.1 kB
Tags CPython 3.10 Windows x86-32
SHA-256 checksum
How to use checksums
5e0789cc46037f13e3423476597307097ecf53289010a18ab94c8bbc1ece6e09
BLAKE2b-256 checksum
How to use checksums
5d86c3e729327ddcf6bbf15684980a8388f83c92e4604dfd9556c555ac6a3acc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl

Download URL z80-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl
Size 415.0 kB
Tags CPython 3.10 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
8fe869ed3eb407939d9eadf6762907ce9157f2a440562736dfa35eb7c2631b27
BLAKE2b-256 checksum
How to use checksums
35e6cd059b54e73b3e1c6586cbe47b0fb2ddc7f34271d53109e113a229b58b20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp310-cp310-musllinux_1_2_i686.whl

Download URL z80-1.2.0-cp310-cp310-musllinux_1_2_i686.whl
Size 416.4 kB
Tags CPython 3.10 Linux musl 1.2+ x86-32
SHA-256 checksum
How to use checksums
f55d4640b1ab3fb7c52751759d58727ab71f9187a7314a6cc8e1d1fbe996cf5b
BLAKE2b-256 checksum
How to use checksums
36b05c00d466b51f71657e4280778a27a027a86c76306f62872720613ee119b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL z80-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 413.9 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
2f70a6b9c053c6e5d15f6bf6583459a855ff1cefeaff2b994788ec7088ab80ca
BLAKE2b-256 checksum
How to use checksums
8599d506e2c7b317d04fee61ab94d8a7527a71c175dce3ba4625f555fb433a1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / z80-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl

Download URL z80-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Size 406.7 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32
SHA-256 checksum
How to use checksums
4e5e13992762818e9611924a5d48017651528ffb9a5ade73fc3cd0f30fc6798e
BLAKE2b-256 checksum
How to use checksums
8daf81a938dae7e3e50af8d150de73de6dc8e927169b1e4d869369fa4ccedf9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page