A Note on this Project's Origin
This project is primarily the result of a series of experiments using Gemini Code Assist for code generation and error handling. Rather than using it on academic examples, it seemed more interesting to apply it to a project that could meet a real practical need.
This, therefore, is the reason for
Z80 Python Wrapper's existence: you can dissect the code to see how Gemini (with my guidance) went about building it, or you can ignore all that and just use this library for your own needs!
This project is a Python wrapper for the Zilog Z80 CPU Emulator C library. It uses ctypes to interface with the compiled C library, allowing you to control a Z80 emulator from Python.
- Provides a high-level
EmulatorPython class to interact with the Z80 CPU. - Exposes main CPU functions like
run,reset, andpower. - Allows direct access to CPU registers and state via helper methods.
- Includes a basic memory implementation that can be extended.
- Handles the compilation of the C source code into a Python extension module using
setuptools.
There are two ways to install this package, depending on your needs.
This is the easiest method if you just want to use the z80_wrapper library in your own project. It uses a pre-compiled "wheel" file (.whl) and does not require a C compiler on your system.
-
Download the Wheel File: Download the appropriate
.whlfile for your operating system and Python version from the project's GitHub Releases page. -
Install the Wheel File: Open a terminal, navigate to the directory where you downloaded the file, and run the installation command:
# If you use pip pip install z80_wrapper-0.1.0-....whl # If you use uv uv pip install z80_wrapper-0.1.0-....whl
(Note: Replace
z80_wrapper-0.1.0-....whlwith the exact name of the file you downloaded.)
This method is for those who want to modify the wrapper's code, run tests, or contribute to the project. This method requires a C compiler.
-
Prerequisites: Ensure you have a C compiler installed and configured.
- On Windows: Install the Microsoft C++ Build Tools. You can get them from this link by selecting the "Desktop development with C++" workload.
- On macOS: Run
xcode-select --install. - On Linux: Install
build-essential(e.g.,sudo apt-get install build-essential).
-
Clone the Repositories: This project requires the source code for the emulator and its dependency,
Zeta. Crucially, the directory paths must not contain spaces.git clone https://github.com/devfred78/z80-python-wrapper.git Z80 cd Z80 git clone https://github.com/redcode/z80.git Zilog_Z80_CPU_Emulator git clone https://github.com/redcode/Zeta.git Zeta -
Install in Editable Mode: This command compiles the C code and installs the package in a way that allows you to edit the source files and have the changes immediately reflected.
# To install the base package uv pip install -e . # To also install development tools (like pytest) for testing uv pip install -e .[dev]
Here is a simple example of how to use the emulator:
from z80_wrapper import Emulator
# 1. Create an emulator instance
emu = Emulator()
# 2. Power on the CPU
emu.power(True)
# 3. Load a program into memory (e.g., at address 0x0000)
# This program is a series of NOPs (0x00) followed by a HALT (0x76)
program = bytes([0x00, 0x00, 0x00, 0x76])
emu.load_program(program)
# 4. Reset the CPU. This sets the program counter (PC) to 0x0000.
emu.reset()
print(f"Initial PC: {emu.get_reg('PC'):04X}")
# 5. Run the emulator for a few cycles
executed_cycles = emu.run(20)
print(f"Executed {executed_cycles} cycles.")
print(f"PC is now at: {emu.get_reg('PC'):04X}")This project uses pytest for running tests.
-
Install testing dependencies: Make sure you have installed the package with the
[dev]option as described in the developer installation section. -
Run the tests: Once
pytestis installed, you can run the entire test suite with this simple command:uv run pytest
This project is licensed under the terms of the LGPL-3.0-or-later license. The underlying C libraries (Zilog Z80 CPU Emulator and Zeta) are also licensed under the LGPL-3.0 (or later), which allows them to be used as libraries in both open-source and proprietary software, provided that any modifications to the libraries themselves are shared.
You can find the full license text in the LICENSE file.
.
├── Zeta/ # Clone of the Zeta dependency
│ └── API/
│ └── Z/ # Header files for Zeta
├── Zilog_Z80_CPU_Emulator/ # Clone of the original C emulator (no spaces in name)
│ ├── API/
│ │ └── Z80.h # Header file for the C library
│ └── sources/
│ └── Z80.c # C source of the emulator
├── tests/
│ └── test_emulator.py # Unit tests
├── z80_wrapper/
│ ├── __init__.py # The Python wrapper code
│ ├── __main__.py # Example usage script
│ └── z80_module.c # C shim for the Python extension
├── LICENSE # The full license text
├── pyproject.toml # Project metadata and build system configuration
└── setup.py # Build script for the C extension
This project would not have been possible without the excellent Zilog Z80 CPU Emulator and Zeta libraries by Manuel Sainz de Baranda y Goñi.