David Cantrell


CPU::Emulator::Z80 - a Z80 emulator


    # create a CPU with 64K of zeroes in RAM
    my $cpu = CPU::Emulator::Z80->new();

    # set a breakpoint
    $cpu->memory()->poke16(0xF000, 0xDDDD); # STOP instruction
    $cpu->memory()->poke(0xF002, 0x00);

    $cpu->memory()->poke(0, 0xC3);     # JP 0xC000
    $cpu->memory()->poke16(1, 0xC000);

    # run until we hit a breakpoint ie RST 1
    eval { $cpu->run(); }
    print $cpu->format_registers();


This class provides a virtual Z80 micro-processor written in pure perl. You can program it in Z80 machine code. Machine code is fast! This will make your code faster!



The constructor returns an object representing a Z80 CPU. It takes several optional parameters:


can be either an object inheriting from CPU::Emulator::Memory, or a string of data with which to initialise RAM. If a string is passed, then a CPU::Emulator::Memory::Banked is created of the appropriate size. If not specified at all, then a CPU::Emulator::Memory::Banked is created with 64K of zeroes.


can be either 256 or 65536 (no other values are permitted) and defaults to 65536. This is the number of I/O ports that can be addressed. If set to 65536, the entire address bus is used to determine what port I/O instructions tickle. If 256, then the most significant 8 bits are ignored.

init_PC, init_A, init_B ...

For each of A B C D E F R HL IX IY PC SP, an integer, the starting value for that register, defaulting to 0.

init_A_, init_B_, ...

For each of A B C D E F HL, an integer for the starting value for that register in the alternate set, defaulting to 0. Note that contrary to normal Z80 custom these are named as X_ instead of X'. This is just for quoting convenience.


Takes two named parameters, 'address' and 'function', and creates an input port at that address. Reading from the port will call the function with no parameters, returning whatever the function returns.

In 256-port mode, the port is effectively replicated 256 times.


Takes two named parameters, 'address' and 'function', and creates an output port at that address. Writing to the port simply calls that function with the byte to be written as its only parameter.

In 256-port mode, the port is effectively replicated 256 times.


Return a reference to the object that represent's the system's memory.


Return the object representing a specified register. This can be any of the real registers (eg D or D_) or a derived register (eg DE or L). For (HL) it returns the private internal DON'T TOUCH THIS 'W' register, for evil twisty internals reasons.


Return a scalar representing the entire state of the CPU or, if passed a scalar, attempt to initialise the CPU to the status it represents.


Return a hashref of all the real registers and their values.


A convenient method for getting all the registers in a nice printable format. It mostly exists to help me with debuggering, but if you promise to be good you can use it too. Just don't rely on the format remaining unchanged.


Attempt to raise an interrupt. Whether any attention is paid to it or not depends on whether you've enabled interrupts or not in your Z80 code. Because only IM 1 is implemented, this will generate a RST 0x38 if interrupts are enabled. Note that interrupts are disabled at power-on.

This returns true if the interrupt will be acted upon, false otherwise. That is, it returns true if interrupts are enabled.


Raise a non-maskable interrupt. This generates a CALL 0x0066 as the next instruction.a This also disables interrupts. Interrupts are restored to their previous state by a RETN instruction.


Start the CPU running from whatever the Program Counter (PC) is set to. This will by default run for ever. However, it takes an optional parameter telling the CPU to run that number of instructions.

This returns either when that many instructions have been executed, or when a STOP instruction executed - see 'Extra Instructions' below.

On return, the PC will point at the next instruction to execute so that you can resume where you left off.


Returns true if the CPU has STOPped, false otherwise. You can use this to easily determine why the run() method returned.


Whenever any combination of two of the 0xDD and 0xFD prefixes are met, behaviour deviates from that of a normal Z80 and instead depends on the following byte:

0x00 - STOP

The run() method stops, even if the desired number of instructions has not yet been reached.

anything else

Fatal error.


I recommend "Programming the Z80" by Rodnay Zaks. This excellent book is unfortunately out of print, but may be available through abebooks.com http://www.abebooks.com/servlet/SearchResults?an=zaks&tn=programming+the+z80.


Claims about making your code faster may not be true in all realities.

I assume you're using a twos-complement machine. I *think* that that's true of anything perl runs on.

Only interrupt mode 1 is implemented. All interrupts are serviced by a RST 0x38 instruction.

The DDFD- and FDDD-prefixed instructions (the "use this index register - no, wait, I meant the other one" prefixes) and the DDDD- and FDFD-prefixed instructions (the "use this index register, no really, I mean it, pleeeeease" prefixes) are silly, and have been replaced - see "Extra Instructions" above.


I welcome feedback about my code, including constructive criticism and bug reports. The best bug reports include files that I can add to the test suite, which fail with the current code in CVS and will pass once I've fixed the bug.

Feature requests are far more likely to get implemented if you submit a patch yourself.




The FUSE Free Unix Spectrum Emulator: http://fuse-emulator.sourceforge.net/




Copyright 2008 David Cantrell <david@cantrell.org.uk>

This software is free-as-in-speech software, and may be used, distributed, and modified under the terms of either the GNU General Public Licence version 2 or the Artistic Licence. It's up to you which one you use. The full text of the licences can be found in the files GPL2.txt and ARTISTIC.txt, respectively.


This module is also free-as-in-mason software.