Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

ep128emu is an open source, portable emulator of the Enterprise 128,
ZX Spectrum 48/128, Amstrad CPC 464/664/6128 and Videoton TVC computers,
written in C++, and supporting Windows and POSIX platforms (32 and 64
bit Windows and Linux, and MacOS X have been tested).
It implements accurate, high quality hardware emulation, however, the
system requirements are higher than that of most other emulators.



  * graphical user interface using the FLTK library
  * software (FLTK based) or OpenGL video, with resizable emulator
    window, fullscreen mode, brightness, contrast, gamma, hue, and color
    saturation control; additional features in OpenGL mode only: single
    or double buffered (with synchronization to vertical refresh) mode,
    linear texture filtering, resampling video output to the monitor
    refresh rate, and some display effects: motion blur, scanline
    shading, and (if OpenGL 2.0 shaders are available) PAL TV emulation
  * real time audio output uses the PortAudio library (v18 or v19), with
    support for many native audio APIs (MME/DirectSound/WDM-KS/WASAPI on
    Windows, OSS/ALSA/JACK on Linux, and CoreAudio on MacOS X); high
    quality sample rate conversion with low aliasing; volume control,
    two first order highpass filters with configurable cutoff frequency,
    and an optional parametric equalizer can be applied to the audio
  * recording audio output to a WAV format sound file
  * recording video and sound output to an AVI format video file, with
    768x576 RLE8 or 384x288 uncompressed YV12 video at 24 to 60 frames
    per second, and 48000 Hz stereo 16-bit PCM audio
  * saving screenshots as 768x576 8-bit PNG format files
  * saving and loading snapshots of the state of the emulated machine
  * demo recording (snapshot combined with stream of keyboard and mouse
    events which can be played back with accurate timing)
  * tape emulation with playback, recording, and setting tape position;
    markers can be created for quick positioning to specific tape
    locations (useful for tapes with multiple files); uses custom file
    format which is PCM audio data with 1 to 8 bits of sample resolution
    and variable sample rate, and header including the table of markers;
    there is also limited (read only) support for EPTE format tape
    files, as well as read-write (although without markers) support for
    sound files like WAV, AIFF, etc.
  * GUI tape editor utility for copying Enterprise files from/to
    ep128emu tape images
  * GUI debugger with support for breakpoints/watchpoints, viewing the
    current state of CPU registers and memory paging, displaying memory
    dump and searching for a pattern of bytes, and disassembler with
    support for all documented and undocumented Z80 opcodes.
    A simple monitor is also included, with commands like assemble,
    disassemble (also to file), trace, memory and I/O port dump and
    modify, printing and changing CPU registers, memory compare, copy,
    fill, search, load and save, and more.
    For most operations, addresses can be 16 bit CPU (affected by
    current paging) or 22 bit physical (all ROM and RAM data can be
    accessed, regardless of memory paging) addresses. Watchpoints can
    also be set on I/O ports and physical addresses.
    The debugger supports scripting in the Lua language, to allow for
    advanced uses like breakpoints with custom defined, complex set of
  * configurable keyboard map for the emulated machine; it is also
    possible to use external game controller devices like joysticks and

Enterprise emulation

  * instruction based emulation of the Z80 CPU, supports all documented
    and undocumented opcodes, and memory wait states (including
    synchronization with the NICK chip when accessing video memory)
  * RAM size can be set in 16 kilobyte steps in the range 64 to 3712
  * ROM can be loaded from external image files to segments 0 to 7,
    16 to 19 (decimal), 32 to 35, 48 to 51, and 64 to 67
  * using external configuration files, it is also possible to define
    any memory configuration without the above limitations
  * NICK chip emulation, supporting all documented and undocumented
    video modes
  * DAVE emulation, including timers, interrupts, external ports for
    tape and keyboard/joystick, memory paging, and sound output (all
    effects are supported, and the polynomial counters generate the same
    pseudo-random "noise" pattern as on the real machine)
  * tape emulation (see general features for details)
  * WD177x (floppy drive controller) emulation for EXDOS
  * IDE hard disk emulation; supports up to 4 2 GB disks, image files
    can be in raw or VHD format
  * optional extension ROM (epfileio.rom) that implements a FILE: device
    for direct access to files on the host system in a single user
    selectable directory
  * Spectrum emulator card emulation
  * real time clock (at ports 7E, 7F)
  * external 4-channel 8-bit DAC at ports F0 to F3
  * mouse emulation, an EnterMice device with up to 5 buttons and mouse
    wheel is emulated in native mode on column K of the keyboard matrix
  * SD card (SDEXT) emulation, this is an experimental feature based on
    code from LGB's Xep128 emulator
  * SID card emulation at ports 0E (address) and 0F (data) using reSID
    1.0; NOTE: this currently breaks the external DAC emulation when

Spectrum emulation

  * instruction based emulation of the Z80 CPU, supports all documented
    and undocumented opcodes, and cycle accurate synchronization with
    the ULA chip when accessing video memory and I/O ports
  * RAM size can be 16, 48, or 128 kilobytes
  * ROM can be loaded from external image files
  * ULA, AY-3-8912, keyboard, and Kempston joystick emulation
  * tape emulation (see general features for details)
  * Spectrum tape files in .tap format can be used as tape images for
    read-only hardware level tape emulation, or loaded directly to
    memory if the "Enable virtual file I/O" option is checked in the
    machine configuration
  * it is also possible to load .tzx format tape images, although the
    support for these is not complete yet
  * loading SNA and Z80 format snapshot files created by other emulators
    is supported; however, snapshot saving and demo recording are only
    possible in the native ep128emu format

Amstrad CPC emulation

  * instruction based emulation of the Z80 CPU, supports all documented
    and undocumented opcodes, and cycle accurate synchronization with
    the CRTC and gate array when accessing video memory and I/O ports
  * RAM size can be 64, 128, 192, 320, or 576 kilobytes
  * ROM can be loaded from external image files to the lower ROM and
    expansion ROMs 0 to 7
  * 6845 CRTC (currently type 0 only), gate array, AY-3-8912, 8255 PPI
    (modes 1 and 2 are not supported yet), keyboard, and joystick
  * tape emulation (see general features for details)
  * CPC tape files in .cdt (same as Spectrum .tzx) format can be used as
    tape images for read-only hardware level tape emulation, although
    the support for this format is not complete yet
  * uPD765 (floppy drive controller) emulation; it supports standard and
    extended .DSK files, and also access to real disks (not very useful
    in practice, since only PC format disks can be used this way), as
    well as limited emulation of the timing of disk rotation, stepping,
    and data transfers. The FORMAT TRACK (0x0D) command is not
    implemented yet, and some copy protected games and .DSK files with
    unusual track formats may not work correctly
  * loading SNA snapshot files (v1 or v2; v3 is loaded, but the extra
    information about the internal state of the hardware is currently
    ignored) created by other emulators is supported; however, snapshot
    saving and demo recording are only possible in the native ep128emu

Videoton TVC emulation

  * instruction based emulation of the Z80 CPU, supports all documented
    and undocumented opcodes, and cycle level synchronization with the
    CRTC and other devices when accessing video memory and I/O ports
  * RAM size can be 48, 80 or 128 kilobytes (TVC 32, 64 or 64+)
  * ROM can be loaded from external image files to SYS, CART and EXT
  * 6845 CRTC (currently type 0 only), audio, keyboard and joystick
  * tape emulation (see general features for details)
  * WD1773/1793 (floppy drive controller) emulation for VT-DOS
  * optional extension ROM (tvcfileio.rom) that implements a FILE device
    for direct access to files on the host system in a single user
    selectable directory
  * SD card (SDEXT) emulation, this is an experimental feature based on
    code from LGB's Xep128 emulator



On Linux and other POSIX platforms, the emulator is installed from the
source code, available at the GitHub download page
or the most recent state of the code can be downloaded from Git with the
following command:
  git clone
In addition to the standard development tools (a recent version of the
GNU C/C++ compiler, binutils, etc.), you need the following packages:

  * SCons (
  * Python interpreter for running SCons
  * FLTK 1.3.x ( or
    1.1.x (
      * this library should be compiled with the --enable-threads
        'configure' option - many Linux distributions include binaries
        of FLTK 1.1 built without --enable-threads, so you may need to
        compile it from sources
      * on MacOS X, FLTK 1.1.7 needs to be patched with the included
        fltk-1.1.7-MacOSX.patch file
  * PortAudio (, version 18 and
    19 are supported, but v19 is recommended
  * libsndfile (

The following packages are optional:

  * OpenGL for improved video display and effects
  * SDL ( 1.2 for joystick input; NOTE: on Linux,
    versions 1.2.10 and newer do not work if they are statically linked
    and were built with video support (--enable-video)
  * Lua ( or for scripting in
    the debugger; version 5.1 or newer is recommended, but 5.0 is also
  * libcurl ( for ROM download support in

Once these are installed, you can edit the file 'SConstruct' in the top
level source directory for setting compiler flags etc., and run the
command 'scons -j 2' for building the emulator. The following options
can be passed to scons:

  -j N
      Maximum number of parallel jobs to be run by scons. It is
      recommended to set N to the number of logical cores of your CPU
      Cross-compile Windows x86_64 binaries using Wine
      ( and MinGW; complete pacakges of MinGW for
      building the emulator can be downloaded from:
      Cross-compile Windows i686 binaries using Wine and MinGW
      Build 32-bit Linux binaries on a 64-bit system without using
      Disable the use of SDL and joystick support. This option may be
      needed on Linux with statically linked SDL versions 1.2.10 and
      newer that were built with video support enabled
      Build without support for Lua scripting
      Do not build the optional utilities (epimgconv and epcompress)
      Disable the use of OpenGL shaders
      Compile binaries for debugging: no optimization and more warnings
      Do not build a release version: binaries are not stripped and are
      compiled with less optimization. Implied by debug=1
      Use LuaJIT (installed as Lua 5.1) on Windows
      Emulate the CMOS version of the Z80 CPU
      Disable SD card (SDEXT) emulation
      Disable SID card emulation
      Do not use libcurl in epmakecfg for downloading the ROM package
      Additional flags to be passed to the compiler or linker
      Disable the use of pkg-config and fltk-config to automatically
      configure libraries
      Enable the use of scons build cache in '.build_cache'

An 'install' target is also supported by SConstruct, this will install
the emulator binaries under ~/bin, and the configuration and data files
under ~/.local/share/ep128emu. Running 'scons -c install' will remove
most of the installed files.
Alternatively, you can copy the executables (ep128emu, epcompress,
epimgconv, epmakecfg and tapeedit) to any directory that is in the PATH;
on MacOS X, an .app package is created in ''.

When installing the first time, you also need to set up configuration
files and ROM images. If epmakecfg was built with libcurl support, the
following steps can be skipped, the configuration utility is run
automatically by ep128emu when needed, and it can download and install
the ROM images.
Before installation, download ep128emu_roms-2.0.11.bin from
and copy it to:
  ~/.local/share/ep128emu/roms                (for 'scons install')
  ~/.ep128emu/roms                            (for manual installation)
  ~/Library/Application Support/ep128emu/roms (on Mac OS X)
If not using 'scons install', run 'epmakecfg' and click OK to the
windows that pop up asking for the base directory of configuration and
data files, and if configuration files should be installed.

It is possible to reinstall configuration files later by running the
'epmakecfg' utility. ROM images can be installed manually by downloading
ep128emu_roms- from the above location and extracting it in the
correct directory. The .bin format ROM package can be unpacked with the
command 'epcompress -x -a ep128emu_roms-2.0.11.bin' in the current
directory, 'epmakecfg' does this automatically if it finds the package
where the ROM images need to be installed.


A binary package with an installer is available at the GitHub download
Older (pre-2.0.10) versions can be downloaded from SourceForge:
To install, just run the executable, and follow the instructions. The
installer can automatically download the ROM images needed for running
the emulator, but these can also be installed manually by downloading
ep128emu_roms- from
and extracting it to roms\ under the selected installation folder.
When asked if configuration files should be reinstalled, click 'OK'
when installing the first time, but this step can be skipped in later
installations to preserve the configuration.

WARNING: on Windows, there may be timing problems when using some dual
core CPUs, or power management features that change the clock frequency
of the CPU while the emulator is running. These issues can result in
slow or erratic emulation speed, not running at 100% speed in real-time
mode, or temporary lockups. If you encounter such problems, forcing the
emulator to run on a single core (by setting the CPU affinity for
ep128emu.exe), and/or disabling dynamic changes to the CPU clock
frequency by power management could fix the timing issues. Installing
and using an utility like AMD Dual Core Optimizer may also solve the
Note that bad emulation performance might also be caused by display or
audio drivers, so it is recommended to check (and upgrade, if necessary)
those as well.


Command line options

    print the list of available command line options
    select the type of machine (Enterprise, ZX Spectrum, CPC or TVC) to
    be emulated
  -cfg <FILENAME>
    load an ASCII format configuration file on startup, and apply
  -snapshot <FILENAME>
    load snapshot or demo file on startup
    use OpenGL video driver (this is the default, and is recommended
    when hardware accelerated OpenGL is available)
    use software video driver; this is slower than OpenGL when used at
    high resolutions, and also disables many display effects, but should
    work on all machines; however, it will use a color depth of 24 bits,
    while in OpenGL mode the textures are 16 bit (R5G6B5) only, to
    improve performance
  -colorscheme <N>
    select GUI color scheme N (0, 1, 2, or 3)
    set configuration variable 'OPTION' to 'VALUE'; the available
    variable names are the same as those used in ASCII format
    configuration files
    set boolean configuration variable 'OPTION' to true

'File' menu

Configuration / Load from ASCII file (Alt + Q)

  Select and load an ASCII format configuration file and apply the new
  settings. If the configuration file does not include all the supported
  options, those that are omitted are left unchanged.

Configuration / Load from binary file (Alt + L)

  Load an ep128emu format binary file, which may be a previously saved
  snapshot, demo, or a binary format configuration file.

Configuration / Save as ASCII file

  Save the current emulator configuration to an ASCII text file, which
  can be edited with any text editor, and can be loaded at a later time.

Configuration / Save

  Save the current emulator configuration in binary format to the
  default file (~/.ep128emu/ep128cfg.dat). This is also automatically
  done when exiting the emulator.

Configuration / Revert

  Reload emulator configuration from ~/.ep128emu/ep128cfg.dat, and apply
  the original settings.

Save snapshot (Alt + S)

  Save a snapshot of the current state of the emulated machine to the
  selected file. The snapshot will also include the current memory
  configuration and ROM images, but clock frequency and timing settings
  are not restored when loading a snapshot. The file format may be
  subject to changes between different releases of the emulator, but new
  versions of the emulator can still load old snapshots. Note that the
  state of any disk drives is currently not saved, and the drives are
  reset on loading a snapshot.
  Starting from version 2.0.10 of ep128emu, snapshot and demo files can
  optionally be saved in a compressed format, if this feature is enabled
  in the machine configuration. Compressing a large snapshot can take a
  few seconds on a slow PC, but the loading time is not affected

Load snapshot (Alt + L)

  Load an ep128emu format binary file, which may be a previously saved
  snapshot, demo, or a binary format configuration file.

Quick snapshot / Set file name

  Select file name for quick snapshots. The default is
  ~/.ep128emu/qs_ep128.dat. This setting is not saved on exit, and quick
  snapshots are always saved in uncompressed format.

Quick snapshot / Save (Ctrl + F9)

  Save snapshot to the quick snapshot file (see notes above).

Quick snapshot / Load (Ctrl + F10)

  Load the quick snapshot file if it exists.

Record demo

  Save snapshot (including clock frequency and timing settings) and
  record keyboard events to the selected file until the recording is
  stopped. The events can be replayed with accurate timing when the
  file is loaded later. Note that the file format may change between
  different releases of the emulator, and the timing may also be
  incorrect when using a different version to play a demo file.

Stop demo (Alt + K)

  Stop any currently running demo playback or recording.

Load demo (Alt + L)

  Load an ep128emu format binary file, which may be a previously saved
  snapshot, demo, or a binary format configuration file.

Record audio / Start...

  Write 16 bit signed PCM sound output to a WAV format sound file.

Record audio / Stop

  Close sound output file if it is currently being written.

Record video / Start...

  Open new AVI file for video recording. This increases the CPU usage
  significantly, and since the data is written without compression, it
  will take up a lot of disk space. If the size of the output file
  reaches 2 GB, it is automatically closed, and the emulator asks for
  a new file to continue the recording.
  NOTE: the video and audio streams in the AVI file are not affected by
  any of the display or sound configuration settings. There are two
  options in the machine configuration that affect the video capture:
  the frame rate and the codec. It is recommended to use the defaults
  (RLE8 768x576 at 50 fps) when possible, but RLE8 is not always
  supported by other software, in those cases it may be necessary to use
  the YV12 codec, which decreases the quality while usually increasing
  the output file size and CPU usage.

Record video / Stop

  Stop video capture, and close any AVI file that is currently being

Save screenshot (F12, Alt + C)

  Save a screenshot in 8 bit PNG format. The video output is captured
  immediately after activating this menu item, and is saved at a
  resolution of 768x576 without any processing (color correction,
  effects, etc.).

Quit (Shift + F12)

  Exit the emulator.

'Machine' menu

Reset / Reset (F11)

  This has the same effect as using the reset button on the real

Reset / Force reset (Ctrl + F11)

  In addition to a normal reset, make sure that the emulated machine is
  really restarted using the standard ROM reset routines, and do not
  allow programs to disable reset by setting custom (RAM) handlers.

Reset / Reset clock frequencies

  Reset clock frequency and timing settings to those specified in the
  machine configuration; this is normally only useful after demo
  playback, which may override the settings.

Reset / Reset machine configuration (Shift + F11)

  Reset memory configuration (RAM size, ROM images), clock frequency,
  and timing settings according to the machine configuration, and clear
  all RAM data. Implies 'Force reset' and 'Reset clock frequencies'.
  Reverting the configuration can be useful after snapshot loading or
  demo playback, as these may change the settings.

Quick configuration / Load config 1 (PageDown)

  Load the configuration file ~/.ep128emu/epvmcfg1.cfg, and apply the
  new settings.

Quick configuration / Load config 2 (PageUp)

  Load the configuration file ~/.ep128emu/epvmcfg2.cfg, and apply the
  new settings.

Quick configuration / Save config 1

  Save the current clock frequency and timing settings to

Quick configuration / Save config 2

  Save the current clock frequency and timing settings to

'Options' menu

Display / Set size to 384x288
Display / Set size to 768x576
Display / Set size to 1152x864

  Resize the emulator window to predefined width/height values; this has
  no effect in fullscreen mode. While the window can also be resized
  using the window manager, sizes that are integer multiples of the
  actual screen resolution of the emulated machine may look better,
  particularly when texture filtering is not used, and are also slightly
  faster when using the software video driver.

Display / Cycle display mode (F9)

  Cycle between these four display modes:
    window with no menu bar
    window with menu bar (this is the default)
    fullscreen with menu bar
    fullscreen with no menu bar (recommended for mouse emulation)

Sound / Increase volume

  Increase sound output volume by about 2 dB.

Sound / Decrease volume

  Decrease sound output volume by about 2 dB.

Disk / Configure... (Alt + D)

  Opens a dialog for setting up floppy, IDE and SD card emulation.

  For each floppy drive, an image file can be selected, and disk
  geometry parameters can be specified. If the file name is left empty,
  that means having no disk in that particular drive. It may also be
  possible to directly access a real disk by using the /dev/fd* devices
  (on Linux) or \\.\A: (on Windows) as the image file.
  Any of the geometry parameters can be zero or negative to have the
  value calculated automatically from the others (if available), the
  image file size, and the file system header.

  The IDE and SD card emulation support image files in raw and VHD
  format (the latter should have a .vhd extension), with a file size of
  up to 2 GB. In the case of VHD files, the disk geometry is determined
  by the VHD footer, while the geometry of raw images is calculated from
  the file size. Depending on the image format, the model number string
  of the emulated drive will include "(VHD)" or the automatically
  assigned geometry.
  The emulator package includes a 126 MB VHD format IDE disk image in
  disk/ide126m.vhd.bz2, with 4 FAT12 formatted 31.5 MB partitions.
  Note that with the current version of IDE.ROM, after changing IDE disk
  images, a cold reset is required for the changes to be detected, and
  the disk change flag is also set on snapshot or demo loading.

  All data storage devices are disabled while recording or playing a

Disk / Remove floppy / Drive A
Disk / Remove floppy / Drive B
Disk / Remove floppy / Drive C
Disk / Remove floppy / Drive D
Disk / Remove floppy / All drives

  These are just shortcuts for setting the image file name for a
  specific floppy drive to an empty string.

Disk / Replace floppy / Drive A (Alt + H)
Disk / Replace floppy / Drive B
Disk / Replace floppy / Drive C
Disk / Replace floppy / Drive D
Disk / Replace floppy / All drives

  Set the image file name for a specific (or all) floppy drive to an
  empty string, and then set the original file name again. This is
  mostly useful when accessing real floppy disks, and should be used
  after the disk is changed.

Set working directory (Alt + F)

  Set the directory to be accessed by the optional file I/O ROM
  extension modules.

Memory configuration files

While the GUI based memory configuration is easy to use, and is
sufficient for creating the most commonly used configurations, it does
have a number of limitations. Using a configuration file - which is a
simple text file with a format described below - makes it possible to
have RAM, ROM, or no memory at any segment, and image files can also be
loaded to RAM (e.g. for emulating static RAM).
NOTE: if a memory configuration file is specified, the RAM/ROM settings
in the "Machine configuration" GUI are ignored.

A memory configuration file may contain any number of segment range
definitions, each being a line in one of the following formats for RAM
or ROM:
  0xNN RAM "fileName" nSegments
  0xNN ROM "fileName" nSegments
where 'NN' is the number of the first segment (hexadecimal), 'fileName'
is the name of the file to be loaded (with full path; backslash or
double quote characters in the name should be escaped with a backslash),
and 'nSegments' is the number of segments to be defined as RAM or ROM
(decimal). If 'nSegments' is not specified, then it defaults to 1 for an
empty file name, otherwise it is determined by the size of the image
file. If 'fileName' is also omitted, then it means a single empty
The configuration file may also include comments and empty lines.
A comment can begin with the semicolon or '#' character, and the rest of
the line is ignored.
Similarly to images loaded in the GUI ROM configuration, it is not
necessary for the files to have a size that is an integer multiple of
16384 bytes: the last segment is padded with FFh bytes. An empty file
name will initialize RAM segments to FFh bytes, while in the case of
ROM, it means that the segments will be empty. If the file is longer
than the size defined by 'nSegments', the data is truncated; if it is
too short, then the segments are repeated.
By default, segments 00h..FBh are empty, and FCh..FFh are RAM. The type
of the last four segments (the video memory) cannot be changed to ROM.

A simple example file, assuming that the emulator is installed to
"C:\Program Files\ep128emu2":

  ; EXOS 2.1 at segments 0, 1 (and repeated at segments 2, 3)
  0x00 ROM "C:\\Program Files\\ep128emu2\\roms\\exos21.rom" 4
  ; IS-BASIC 2.1 at segment 4
  0x04 ROM "C:\\Program Files\\ep128emu2\\roms\\basic21.rom"
  ; 128K RAM at segments F8h..FFh
  0xF8 RAM "" 8

Reading I/O ports in the debugger

Write-only I/O ports are readable in the monitor and Lua scripts, and
return the last value written to the port. There are also some changes
to the address decoding compared to what is seen by the emulated Z80
code, depending on the machine type:
  - Spectrum:
    - below port address 20H, the Kempston joystick state is read from
      all addresses
    - the last value written to the ULA is read from any other even
      address that is less than 100H
    - in Spectrum 128 mode, if the address is less than 100H, and the
      lowest two bits are 01B, the memory paging register is returned
    - reading any other I/O port below 100H returns FFH
    - reading from ports 0xxxxxxxxxxxxx0xB does not write the data bus
      state to the memory paging register
  - CPC:
    - when reading the gate array/RAM configuration port, the function
      (pen/color/video mode/memory configuration) can be selected in
      bits 6 and 7 of the address; for example, reading port 7F40H
      returns the color of the currently selected pen
    - in the address range 0 to 9FH, many I/O registers can be read
      - 00H-1FH: 6845 CRTC registers
      - 20H-2FH: gate array palette
      - 30H-3FH: gate array border color
      - 40H-4FH: AY-3-8912 registers
      - 50H-5FH: 8255 PPI registers
          0101x000B: port A current state (input or output)
          0101x001B: port B current state (input or output)
          0101x010B: port C current state (input or output)
          0101xx11B: control register
          0101x100B: last value written to port A register
          0101x101B: last value written to port B register
          0101x110B: last value written to port C register
      - 60H-6FH: keyboard matrix state
      - 70H:     currently selected CRTC register
      - 71H:     CRTC flags
          bit 0: 1 if the "display enabled" output is active
          bit 1: 1 if the HSYNC output is active
          bit 2: 1 if the VSYNC output is active
          bit 3: 1 if the current field is odd in interlaced modes
          bit 4: 1 if the "cursor enabled" output is active
      - 72H:     current video memory address / low
      - 73H:     current video memory address / high
      - 74H:     video mode (0 to 3)
      - 75H:     currently selected pen number
      - 76H:     gate array IRQ counter (0 to 51)
      - 77H:     AY-3-8912 register selected
      - 78H:     RAM configuration (bits 6 and 7 are RAM enable flags
                 for page 0 and page 3)
      - 79H:     currently selected expansion ROM bank
      - 7AH-7FH: unused, FFH is returned
      - 80H-9FH: uPD765 floppy drive controller registers and state
          80H: FDC phase (0: idle, 1: command, 2: execution, 3: result)
          81H: last command code
          82H: motor state (last byte written to 0FA7EH & 01H)
          83H: currently selected physical head (0 or 1) * 4 + drive
          84H: CPU<->FDC data transfer position LSB
          85H: CPU<->FDC data transfer position MSB
          86H: CPU<->FDC data transfer size LSB
          87H: CPU<->FDC data transfer size MSB
          88H: logical cylinder ID
          89H: logical head ID
          8AH: logical sector ID
          8BH: sector size code
          8CH: last sector ID (EOT), or sector count for format track
          8DH: gap length
          8EH: sector data length (DTL), or STP for scan commands
          8FH: filler byte (format track only)
          90H: first byte in command/data/result buffer
          91H: second byte in command/data/result buffer
          92H: third byte in command/data/result buffer
          93H: fourth byte in command/data/result buffer
          94H: ST1 for read/write commands
          95H: ST2 for read/write commands
          96H: specify parameter 1 (step rate / head unload time)
          97H: specify parameter 2 (head load time)
          98H: ST3 for sense drive status on drive 0
          99H: ST3 for sense drive status on drive 1
          9AH: ST3 for sense drive status on drive 2
          9BH: ST3 for sense drive status on drive 3
          9CH: drive 0 cylinder number (PCN0)
          9DH: drive 1 cylinder number (PCN1)
          9EH: drive 2 cylinder number (PCN2)
          9FH: drive 3 cylinder number (PCN3)
    - unlike the other machine types, I/O watchpoints are set on the
      upper 8 bits of the address
  - Enterprise: when the SD card emulation is enabled, segment 07H is
    handled in a special way, and its original contents cannot be
    - 0000H-1FFFH: a 8 KB page of the 64 KB flash ROM
    - 2000H-3BFFH: 7 KB static RAM
    - 3C00H-3FFFH: memory mapped I/O, 4 registers are repeated 256 times
    Reading the I/O area in the debugger ignores the high speed mode
    bit, and some of the registers have additional readable bits:
    - xxxxxxxxxxxx01B (status):
        bit 0: 1 if CS0 is active
        bit 1: 1 if CS1 is active
        bit 2: 1 if the card is in idle state
    - xxxxxxxxxxxx10B (ROM page) is readable in the debugger
    - xxxxxxxxxxxx11B (high speed read configuration):
        bit 7: 1 if high speed reading is enabled

Lua scripting

Starting from version 2.0.5, it is possible to run scripts written in
Lua from the debugger. This document only describes the use of scripts
in the emulator, and the new API functions added; for general
information about programming in Lua, see

Clicking the 'Run' button will run the script, and also enable the
breakpoint callback function (see below) if it is defined. If there are
any syntax or runtime errors, the script is terminated, and the
breakpoint callback is disabled. After making any changes to the script,
you need to click 'Run' and restart the script for the changes to take

It is possible to define a breakpoint callback function in the script,
which will be automatically called whenever a breakpoint is triggered,
and the debugger window would be shown. This function has the following

  function breakPointCallback(bpType, addr, value)
    return showWindow

where 'showWindow' is a boolean value, which, if true, will allow the
debugger window to be shown like normal, or have the emulated program
continue without any break if it is false. The four parameters passed to
the function are as follows:


    The type of break, one of the following:
      0: breakpoint at opcode read by the CPU
      1: data read from memory
      2: data written to memory
      3: opcode read in single step mode; this happens when 'Step' or
         'Step over' are being used, and if the breakpoint callback
         function returns false, breaks will continue to occur until
         true is returned
      5: I/O port read
      6: I/O port write


    This is the 16 bit address where the break occured.


    The value or CPU opcode read from or written to memory or I/O port.

The breakpoint callback function will remain active until either a new
script is run which does not define one, or the 'Stop' button is

NOTE: an infinite loop in the script will hang the emulator, and a very
frequently called and/or complex breakpoint callback may slow down the

The following new functions are defined by the emulator for use in the

  AND(...)    OR(...)    XOR(...)    SHL(a, b)    SHR(a, b)

    These simple helper functions implement bitwise operations that are
    not available in versions 5.2 and older of the Lua language by
    default. If the emulator is built with Lua 5.3 or newer, then using
    the operators &, |, ~, <<, and >> is recommended.
    AND, OR, and XOR can take any number of integer arguments, and
    return the bitwise AND, OR, and XOR of the values, respectively. In
    the case of zero arguments, OR and XOR return zero, while AND
    returns -1.
    SHL returns 'a' shifted to the left by 'b' bits, and SHR returns 'a'
    shifted to the right by 'b' bits. If 'b' is zero, the value is not
    changed, while a negative 'b' will reverse the direction of
    shifting. The result of shifting negative values to the right is

  setBreakPoint(bptype, addr, priority)

    Set a breakpoint or watchpoint at address 'addr' (0-0xFFFF), with
    priority 'priority' (0 to 3). 'bptype' can be one of the following

      0: any memory access (read, write, or Z80 opcode read)
      1: memory read
      2: memory write
      3: any memory access, same as bptype == 0
      4: Z80 opcode read
      5: I/O port read
      6: I/O port write
      7: I/O port read or write

    For memory breakpoints, it is possible to add 8 to 'bpType' to
    interpret the address as a 22 bit value in the range 0 to 0x3FFFFF,
    with the segment number determined by the most significant 8 bits.
    If the address is greater than 0xFFFF, it is also automatically
    assumed to be in 22 bit format.
    An "ignore" breakpoint can be defined by adding 16 to 'bpType', this
    will disable other breakpoints when the program counter is at the
    address to be ignored. It is still possible to have a normal read or
    write breakpoint as well at the same address, by setting the lowest
    three bits of 'bpType' to 1, 2, or 3.
    A 'priority' value of -1 will delete an existing breakpoint at the
    specified address.
    The read, write, execute, and ignore flags are combined (bitwise OR)
    if multiple breakpoints are set at the same address, while the
    priority will be the highest value specified.

    NOTE: the changes made to the breakpoint list by the script are not
    reflected in the breakpoint editor. To restore the previously
    defined breakpoints, click the 'Apply' button.


    Deletes all previously defined breakpoints.


    Returns the segment selected for page 'n' (0 to 3).
    In Spectrum or CPC emulation mode, RAM is mapped starting from
    segment 00H. For the CPC, segments 00H to 03H are the internal RAM,
    the lower ROM is at segment 80H, and expansion ROM 'n' is at segment
    C0H + 'n'; this function returns the number of the segment for read
    access (i.e. ROM if it is enabled). In the case of ZX Spectrum, the
    ROM is at segment 80H (Spectrum 16 and 48), or segments 80H and 81H
    (Spectrum 128).


    Read a byte from 'addr' (0 to 0xFFFF) in the address space of the

  writeMemory(addr, value)

    Write 'value' to 'addr' (0 to 0xFFFF) in the address space of the


    Read a byte from 'addr' (0 to 0x3FFFFF) in the "physical" address
    space; the most significant 8 bits of 'addr' select the segment

  writeMemoryRaw(addr, value)

    Write 'value' to 'addr' (0 to 0x3FFFFF) in the "physical" address
    space; the most significant 8 bits of 'addr' select the segment

  writeROM(addr, value)

    This function is similar to writeMemoryRaw(), but it can write to
    any valid segment, even if it is ROM.

  writeWord(addr, value)
  writeWordRaw(addr, value)
  writeWordROM(addr, value)

    These are similar to the memory read/write functions above, but read
    and write 16-bit LSB-first words instead of single bytes.


    Read a byte from I/O port 'addr' (0 to 0xFFFF).

  writeIOPort(addr, value)

    Write 'value' to I/O port 'addr' (0 to 0xFFFF).

  getPC()    getA()     getF()     getAF()    getB()     getC()
  getBC()    getD()     getE()     getDE()    getH()     getL()
  getHL()    getSP()    getIX()    getIY()    getAF_()   getBC_()
  getDE_()   getHL_()   getIM()    getI()     getR()     getIFF1()

    These functions return the registers of the CPU.

  setPC(n)   setA(n)    setF(n)    setAF(n)   setB(n)    setC(n)
  setBC(n)   setD(n)    setE(n)    setDE(n)   setH(n)    setL(n)
  setHL(n)   setSP(n)   setIX(n)   setIY(n)   setAF_(n)  setBC_(n)
  setDE_(n)  setHL_(n)  setIM(n)   setI(n)    setR(n)    setIFF1(n)

    Set CPU registers. Note that changing the program counter only takes
    effect after the execution of one instruction is completed.

  getNextOpcodeAddr(addr[, cpuAddressMode])

    Returns the address of the next Z80 instruction after the
    instruction at 'addr'. 'cpuAddressMode' selects the use of 16 bit
    CPU (if true or not specified) or 22 bit physical (if false)


    Returns the current video position as two values (horizontal and

    In the case of Spectrum emulation, both values are in pixels, in the
    range 0 to 447 and 0 to 311 for the Spectrum 48, or 0 to 455 and 0
    to 310 for the Spectrum 128.
    The upper left corner of the screen is at 0,0 (it is the cycle when
    the byte read from 4000H appears on the floating bus), and the lower
    right corner is at 255,191.
    The line number is incremented 64 pixels before X=0 (X=384 or X=392
    in 48K or 128K mode, respectively), but this may possibly change in
    future versions.

    For the Enterprise, the horizontal position is in characters, in the
    range 0 to 56. The vertical position is the sum of the 8-bit line
    counter within the current line parameter block (LPB), which counts
    up to 255, and the video memory address of the LPB multiplied by 16.

    In CPC emulation mode, the horizontal position is in characters, and
    the vertical position is in raster lines, i.e. 0 to 63 and 0 to 311
    with the default CRTC settings. Position 0,0 is the upper left
    corner of the screen, this is the CRTC cycle when the first two
    bytes of the screen memory are read. In the case of interlaced video
    mode (CRTC register 8 = 3), the vertical position is in frame lines,
    and is incremented by two each line (it is even or odd depending on
    the current field).

  getRawAddress(segment, offset)

    Calculates a 22-bit physical address from the specified segment and
    offset; only the 14 least significant bits of 'offset' are used.


    Calculates a 22-bit physical address from a 16-bit CPU address,
    using the current memory paging.

  loadMemory(fname, asciiMode, cpuAddressMode, startAddr[, endAddr])

    Loads a file to the memory area at 'startAddr' to 'endAddr' (the
    byte at 'endAddr' is still loaded). If no end address is specified,
    all data is read into memory. The file is searched in the working
    directory set for file I/O, and if the name is an empty string, a
    file selection dialog is shown. The expected file format is binary
    if 'asciiMode' is false, and hexadecimal dump (as written by
    saveMemory() or the 'S' monitor command) if 'asciiMode' is true.
    'cpuAddressMode' selects the use of 16 bit CPU (if true) or 22 bit
    physical (if false) addresses.
    The return value is the number of bytes actually read.

  saveMemory(fname, asciiMode, cpuAddressMode, startAddr, endAddr)

    Save the memory area at 'startAddr' to 'endAddr' (the byte at
    'endAddr' is still written) to a file, in binary (if 'asciiMode' is
    false) or hexadecimal dump (if 'asciiMode' is true) format.
    'cpuAddressMode' selects the use of 16 bit CPU (if true) or 22 bit
    physical (if false) addresses.

  loadROMSegment(segment, fname, offset)

    Load a file to the specified segment as ROM, skipping 'offset' bytes
    at the beginning of the file. An empty file name deletes the


    Prints any number of strings or numbers to the monitor.
    No separator characters are inserted between the arguments being
    printed, and a newline character is automatically added at the end
    of the message.


  mprint("Running Lua script example...")
  setBreakPoint(4, 0x0040, 2)   -- break on reading Z80 opcode at 0x0040
  function breakPointCallback(t, a, v)
    if t == 3 then              -- allow stepping
      return true
    -- check for EXOS 1 call with A=102
    if getPC() ~= 0x0040 or getA() ~= 1 or readMemory(0x005A) ~= 102 then
      return false
    -- read name parameter from memory
    s = ""
    n = readMemory(getDE())
    for i = 1, n do
      s = s..string.char(readMemory(getDE() + i))
    mprint("Channel #102 is opened with name '", s, "'")
    return true

This will break when channel 102 is opened, and print the name parameter
passed to the EXOS call.



ep128emu is copyright © 2003-2017 by Istvan Varga
<>. Z80 emulation copyright © 1999-2003 by
Kevin Thacker and Vincze Béla György. dotconf 1.3 is copyright by Lukas
Schröder and William Hubbs. reSID 1.0 copyright © 2010 by Dag Lem.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA  02111-1307 USA


Thanks to:

Zozosoft      - hardware testing and information, ROM packages
MrPrise       - web site
Attus         - Linux fixes and binary packages for the UHU distribution
Martin Bantz  - PCLinuxOS RPM spec file
LGB           - GitHub import from SourceForge, Linux testing and fixes,
                SD card emulation