MEMU - Memotech EMUlator

Contents

Introduction

The Memotech MTX series of computers were superior 8-bit computers of the 1980s. Although initially supplied with a ROM BASIC later addons included disk drives of various formats, which could be accessed from extensions to the ROM BASIC or the system could boot CP/M 2.2. The definitive source of information about Memotech computers is Dave Stevenson's site.

MEMU is a full featured emulator of the MTX systems originally written by Andy Key. Andy's version of MEMU is available for Microsoft Windows or Linux from here. Discussion of MEMU can be found here.

This code is a fork of Andy's original to include some additional features and support different patforms. This release currently supports:

The full (Linux) version of MEMU provides just about complete emulation of the original hardware, including:

It provides emulation of some modern hardware add-ons:

There are also features to assist Z80 software development and debugging:

Discussion of MEMU can be found here.

Building

Raspberry Pi Pico Build

Hardware Requirements:

It is recommended that the code be compiled on a Raspberry Pi. This is the only build that has been tested.


        wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
        chmod +x pico_setup.sh
        ./pico_setup.sh
    

Reboot to complete setup. Log back in, then:


        cd pico
        git clone https://github.com/Memotech-Bill/MEMU.git
        cd MEMU
        mkdir build-pico
        cd build-pico
        cmake -DTARGET=Pico ..
        make
    

The MEMU folder should be at the same level as the pico-sdk and pico-extras folders:

The resulting memu-pico.uf2 file can then be copied onto the Pico, or the memu-pico.elf file loaded using the debug connector on the Pico. See "Getting Started with Raspberry Pi Pico".

The hardware is configured as follows:

Linux Builds

The following pre-requisites are required when building on a Raspberry Pi:

To build the X-Window version of MEMU (for use with GUI):


        git clone https://github.com/Memotech-Bill/MEMU.git
        cd MEMU
        mkdir build-x
        cd build-x
        cmake -DTARGET=XWin ..
        make
    

To build the Framebuffer version of MEMU (for use without a GUI):


        git clone https://github.com/Memotech-Bill/MEMU.git
        cd MEMU
        mkdir build-fb
        cd build-fb
        cmake -DTARGET=FBuf ..
        make
    

Note: The framebuffer version is intended for use from the console keyboard and screen. It will not work over an SSH connection.

The executables "memu-x" or "memu-fb" should be in the ../run_time folder. For older versions of CMake, they may either be in the root of the build folder, or in the "src/memu" sub-folder. Copy the executable into the root of the "run_time" folder.

The Linux version of MEMU will run on many single-board computers such as the Raspberry Pi. On such systems, the use of GPIO to connect to real hardware is potentially useful, so this has been re-implemented as an optional feature of the Linux builds, using standard Linux software interfaces. To enable this feature, add the following switches to the cmake line of the Linux build instructions:

To use GPIO attached hardware, it is necessary to use the switch -hw-config when starting MEMU to give the name of a file specifying the hardware attached.

Obsolete Raspberry Pi Build

The Linux builds of MEMU (documented above) will compile and run on any version of Raspberry Pi. The original Raspberry Pi build (documented below) had two additional features:

The software interfaces used to implement these features have been obsoleted by recent versions of Raspberry Pi OS, and are not available at all for the Raspberry Pi 5.

The GPIO interface as been re-implemented using standard Linux system calls (see above) which should work on all models of Raspberry Pi with a recent operating system.

This build is intended to be run from an operating system, typically "Raspberry Pi OS". It does not require a GUI, instead it uses the VideoCore IV GPU to display full screen.

This build must be done on a Raspberry Pi, as the VideoCore libraries are required. To build this version of MEMU:


        git clone https://github.com/Memotech-Bill/MEMU.git
        cd MEMU
        mkdir build-rpi
        cd build-rpi
        cmake -DTARGET=RPi ..
        make
    

The "memu-pi" executable should be in the ../run_time folder. For older versions of CMake, it may either be in the root of the build-rpi folder, or in the "src/memu" sub-folder. Copy the executable into the root of the "run_time" folder.

Notes:

  1. This build uses the VideoCore GPU to compose the display. It therefore requires use of the old FKMS driver, not the new KMS driver. Therefore edit the file "/config.txt"

  2. The display must be connected to one of the outputs controlled by the VideoCore (e.g. HDMI), and the keyboard attached to a USB port. This version will not work over an SSH connection. Use memu-x for that.

Bare-Metal Raspberry Pi Build

The bare-metal version of MEMU relies upon the Circle bare-metal programming environment for the Raspberry Pi. It has been tested with release 43.3 of Circle.

It is necessary to build a version of MEMU specific to the type of Raspberry Pi it is to run on as outlined in the following table:

RPIExecutableModelsOptimized for
1kernel.imgA, B, A+, B+, Zero, (CM)ARM1176JZF-S
2kernel7.img2, 3, (CM3)Cortex-A7
3kernel8-32.img3, (CM3)Cortex-A53
4kernel7l.img4B, 400, CM4Cortex-A72

To build a Circle version of MEMU, run the following commands, where the ? is replaced by a number (1 to 4) from the first column of the above table, according to the Raspberry Pi version required:


        git clone https://github.com/Memotech-Bill/MEMU.git
        git clone --depth 1 --branch Step43.3 https://github.com/rsta2/circle.git
        cd MEMU
        mkdir build-circle
        cd build-circle
        cmake -DTARGET=Circle -DRPI=? ..
        make
    

If required it is possible to create multiple build folders (e.g. "build-circle1" to "build-circle4") and build programs for each version of Raspberry Pi.

Installation requires an SD or SDHC card formatted with a FAT partition as the first or only partition. Copy into this partition:

Windows Build

Requirements:

Download and configure the portaudio code:


        git clone https://github.com/PortAudio/portaudio.git
        cd portaudio
        git checkout tags/v19.7.0
        cd ..
    

Download and build the MEMU source code:


        git clone https://github.com/Memotech-Bill/MEMU.git
        cd MEMU
        mkdir build-win
        cd build-win
        cmake -DTARGET=Win ..
        cmake --build . --config Release
    

Copy the "Release\memu-win.exe" and "portaudio\Release\portaudioXXX.dll" files into the "run-time" folder

Usage

Basic Usage

If MEMU is started without any command line arguments, it will usually start in whichever emulation mode it was last used in. When first installed that will be emulating a Memotech MTX512 running ROM BASIC.

For instructions on using MEMU as a Memotech, please read the Memotech manuals, copies of which can be found here.

For versions of MEMU (FBuf, RPi, Circle) which use the full screen to display each MTX screen (VDP, CP/M ...) use keys <Ctrl+F1>, <Ctrl+F2> etc. to switch between each screen.

To configure MEMU for different emulation modes, open the configuration screen or window. Because different operating environments capture different keys, a number of different key presses may be used to open this screen:

Configuration Screen

Use the arrow keys to navigate the options and either <space> or <Enter> to select an option. The <Esc> key can be used to exit sub-menus.

The top row of the screen is used to select the basic emulation mode:

MTX500
32K RAM, ROM BASIC, 40 column VDP display, Tape interface
MTX512
64K RAM, ROM BASIC, 40 column VDP display, Tape interface
SDX
512K RAM, ROM BASIC, 40 column VDP display, Single disk drive (type07, 640KB)
CPM MONO
576K RAM, CP/M & ROM BASIC, 40 column VDP display, 80 column monochrome display, Two type07 disk drives, Four Silicon Drives (optional)
CPM COLR
576K RAM, CP/M & ROM BASIC, 40 column VDP display, 80 column colour display, Two type07 disk drives, Four Silicon Drives (optional)
MFX
576K RAM, CP/M & ROM BASIC, 40 column VDP display, 80 column VGA display, SD Card emulation (up to 8 CPM drive images), Four Silicon Drives (optional).
Note: This does not include emulation of the WizNet network interface on the real MFX card. The windows version of MEMU cannot currently emulate this. While the Linux version can emulate the WizNet, either the program would need to be run as root to be able to open the ports for FTP or HTTP, or the port numbers would need to be re-mapped to high (unprivilaged) values. Command line switches may be ussed to enable this emulation for the Linux version.

The body of the screen is used to provide details:

Keyboard Remapping
Remapping adjusts for differences between the Memotech keyboard layout and modern keyboards. It is usually most convenient to have remapping enabled, but this will not work for programs with their own keyboard drivers. See the section Keyboard for more details.
Sound
Generation of sound may be turned on or off.
Tapes
For the emulator, most program tapes are supplied in a binary format (*.mtx). These will load quickly. However for use with real hardware, tapes may be in the format of audio files (*.wav). These can also be loaded into the emulator and will take a realistic time to load. To prevent accidental overwriting of existing programs, overwriting can be disabled. The file names for tapes to be loaded or saved can be selected.
Silicon Disks
In real hardware, silicon disks loose their contents when turned off. To emulate this, saving the contents of silicon disks on exiting MEMU can be disabled. For the real hardware, silicon disks were limited to a maximum of 8MB. However, one modern game by Andy Key requires more storage. Therefore to enable this to be run in MEMU, he extended the simulated silicon disk interface to support much larger capacities.

The lowest line on the screen provides some brief help. The line above is used to exit the configuration:

Apply
Makes the requested changes and returns to the existing emulation. Only changes to the tape or floppy disks may be made.
Cancel
Returns to the existing emulation without making any changes.
Restart
Restarts the emulation in the requested mode. The new configuration is written to the configuration file so that MEMU will start in the new mode next time it is used.
Exit
Exits MEMU. In bare-metal versions it will be necessary to reset the processor to restart the program.

In order to be used by MEMU, disk images should be placed in the "disks" sub-folder below the folder containing MEMU and the configuration files. Similarly, tapes should be placed in the "tapes" sub-folder. This repository only contains a few example tape and disk image files. Many more can be obtained from:

Typical configuration for SDX emulation

The image below shows a typical configuration for SDX emulation, with a tape file ready for loading with the command LOAD "", and a disk of games available for USER LOAD "game". Any user programs can be saved with USER SAVE "name"

SDX Selected, Keyboard: Remapped, Sound: Yes, Audio tapes: No, Overwrite tapes: No, Tape file selected, Floppy drive B file selected

Typical configuration for CP/M emulation

A typical configuration for CP/M emulation, with two floppy disks, is shown below.

CP/M Colour Selected, Keyboard: Remapped, Sound: Yes, Files for floppy drives B and C selected

Disk Images

MEMU is not able to directly access files stored by the operating system. Instead the program reads files that are are binary copies of the contents of CP/M disks. To access the CP/M files on a modern PC you need to use a program which understands the CP/M disk format.

The traditional set of programs for that is cpmtools. For most Linux distributions they can be installed using the distribution's package manager. Versions for Microsoft Windows can be downloaded from here. Cpmtools requires a disk definition file which defines the exact layout of the disk image. Andy Key's website provides a disk definition file for all the Memotech disk formats.

The two most commonly used formats with the MEMU emulator are:

Cpmtools are traditional command line utilities. To make the CP/M images more accessible on modern machines, Andy has also developed software whicch enables the CP/M image to be mounted and accessed using standard GUI file managers. These are:

An empty disk image can be preduced by creating an empty file, mounting it as a disk in MEMU, then using one of the Memotech utilities to format the drive. Once formatted, close MEMU and use one of the above tools to copy files into the image.

For the real CFX-II or MFX interfaces, the CF or SD media can store up to eight images of 8MB CP/M disks. With MEMU, eight separate image files may be specified, one for each of the 8MB CP/M disks. Alternately, a single large file containing a complete image of the storage media may be given as the first file name. The media image may optionally include data for HexTrain beyond the CP/M disk images, and / or include an MBR partition table. With Linux it is even possible to specify a media device containing physical media from a Memotech

Advanced Usage

MEMU configuration is controlled by a large number of option flags or switches. These may be either in configuration files or specified on the command line.

For bare-metal systems the configuration will be specified in files "memu0.cfg" and "memu.cfg" in the root of the storage media.

For systems with an operating system, if MEMU is started without any command line options, then it will read the configuration from two files "memu0.cfg" and "memu.cfg".

MEMU now looks first for "memu.cfg" in the current folder. If found, it will read configuration from "memu0.cfg" (if it exists) and "memu.cfg" in the current folder. This allows for folder specific customisation if required. If there is no "memu.cfg" in the current folder, then "memu0.cfg" and "memu.cfg" from the same folder as the program executable is used.

The contents of the "memu0.cfg" file remain constant, while the "memu.cfg" file is re-written by the interactive configuration screen.

If there are any options specified on the command line, then the above configuration files will not be read automatically. Command line options may be used to read these (or other) configuration files.

When specifying file or folder path names, the following special macros may be used to specify the starting folder for a path;

By default, relative paths are taken from the folder containing the configuration.

The following options are supported on all versions of MEMU:

-help
Show a short summary of the options and then exit MEMU.
-ignore
Ignore options for features that are not implemented. It allows versions with fewer features (such as the Pico version) to use a configuration file intended for a more fully featured version. The options must still be syntacticly correct.
-config-file file
Read configuration options from the specified file. The option may be repeated to read multiple configuration files. The last configuration file specified is used to save changes made from the configuration screen.
-no-ignore-faults
In order to make the program more robust, reading from a configuration file disables checking for a couple of faults in Z80 programs being run (accessing invalid I/O ports, and incompletely initialised file control block). This option re-enables those checks.
-mem-blocks n
Number of 16KB memory blocks emulated (default 4)
-mem-mtx500
equivalent to -mem-blocks 2
-vid-win
Enable emulating VDP and TV using a graphical window
-mon-win
Emulate the 80 column card display using a graphical window
-mon-win-mono
Emulate the 80-column display as green screen monochrome (instead of colour)
-mon-no-ignore-init
don't ignore writes to non-emulated registers
-kbd-remap
Enables remapping of keyboard
-kbd-country n
sets the country code switches to n (default 0)
-snd-portaudio,-s
Emulate sound chip (using portaudio on Linux & Windows)
-snd-latency value
Instruct portaudio to use a given latency
-disk-dir dir
Specify the directory containing disk images
-tape-dir dir
Specify the directory containing tape files
-tape-overwrite
SAVE can overwrite an existing file
-tape-disable
Disable rapid loading of binary (*.mtx) tape files. This enables loading of audio (*.wav) files. Binary (*.mtx) files are loaded by converting them back to audio.
-cassette-in
MTX or WAV file to load
-cassette-out
MTX or WAV file to save
-sdx-mfloppy file
specify .mfloppy file in SDX first drive
-sdx-mfloppy2 file
specify .mfloppy file in SDX second drive
-rom-enable rom_bits
Bit flags to enable (1) or disable (0) the Z80 accessing the ROMS in each of the ROM banks in the address range 0x2000 to 0x3FFF.
-sdx-tracks n
specify tracks of first drive (default 80)
-sdx-tracks2 n
specify tracks of second drive (default 80)
-prn-file file
specify file to receive printer output
-speed hz
set CPU speed (default is 4000000, ie: 4MHz. Pico default: 4.8MHz)
file.mtx
subsequent LOAD/SAVE/VERIFY "" will use this file

The following options are supported on the Linux and Microsoft Windows versions:

-romX file
Load banked ROM X image from an 8MB file
-rompairX file
Load banked ROM X and ROM X+1 a 16MB file
-largerom selector file
Optionally load the system ROM (0-8K) and / or any of the banked ROMS (8-16K) specified by the characters (S,0-7) in the selector string from a single 32KB file.
-vid-win-hw-palette
-mfx
Show the emulated MFX display.
Use an alternate palette for the emulation of the VDP display.
-sidisc-huge
enable Silicon Disk huge mode
-sidisc-no-save
don't save Silicon Disk content on termination
-sidisc-file n file
specify Silicon Disk content for a drive
-cfx2 rom_file
enable CFX-II emulation and specify ROM image file
-vga
emulate Propeller VGA display (enabled by default for CFX-II)
-cf-image c:p file
specify data image for partition (p) on card (c)
-sd-type type
set the type of SD card to emulate (SDv1, SDv2, SDHC)
-sd-image p file
specify image for CP/M drive (p) on SD card
-no-cfx2 rom_file
Disable CFX-II emulation but remember the ROM image file name.
-iobyte iobyte
Specify the MTX memory mapping (IOBYTE, initially 0x00)
-addr addr
Set the address for loading data or starting execution (initially 0x0000)
-n-subpages rom n
The banked ROMS may also have sub-pages. Set number of subpages for a bank
-subpage subpage
Set ROM subpage for loading memory (initially 0)
-mem file
Load file into memory at address
-rompairX file
load a file into an adjacent pair of ROM banks X and X+1. If the file is more than 16KB, then load it into successive sub-pages.
-vid-ntsc
refresh at 60Hz (instead of 50Hz)
-mon-console,-mc
emulate 80 column card using console only
-mon-console-nokey
keyboard status shows no keys pressed
-kbd-type string
auto type keys in this string
-kbd-type-file fn
auto type keys in this file
-joy,-j
enable joystick support
-joy-buttons string
define left,right,up,down and fire buttons
-joy-central n
percentage off-centre to press direction
-tap-file fn
specify ZX tape file (default memu.tap)
-sna-file fn
specify ZX snapshot file (default memu.sna)
-cpm
emulate CP/M BDOS
-cpm-drive-a path
where CP/M BDOS finds A: files (default: .)
-cpm-invert-case
invert between CP/M and host filenames
-cpm-tail tail
construct CP/M command tail
-cpm-open-hack
don't insist on EX,S1,S2,RC being 0
-sdx
SDX support in ROM 5 (or -sdx3 for ROM 3)
-fdxb
FDXB CP/M support
-fast
don't limit speed, run as fast as possible
-run-no-interrupts
Disable interrupts when loading a RUN file via the command line option. This was default on Andy's MEMU but is not consistent with USER RUN on a real MTX. Only has any effect if SDX is not being emulated (loading a game into memory of an emulated MTX). If SDX emulation is enabled, then the effect of typing a USER RUN command is explicitly emulated.
file.com tail ...
-cpm -iobyte 0x80 -addr 0x0100 -mem file.com
file.run
-iobyte 0x00 -addr 0xAAAA (from header)

The following options only have any effect for resizeable windows (X-Window or Microsoft Windows):

-vid-win-big,-v
Increase the size of the VDP window. Repeat to further enlarge.
-vid-win-max
VDP window the largest size that will fit on the screen.
-mon-win-big,-mw
Increase the size of the 80-column display. Repeat to further enlarge.
-mon-size N
Sets the size of the 80-column display (but does not enable it).
-mon-win-max
Maximises the size of the 80-column display (but does not enable it).
-mfx-size
Sets the size of the MFX display. Negative values remember the size without enabling the display.
-mfx-max
Show the emulated MFX display using a maximum size window.
-vid-win-title
set title for VDP window
-vid-win-display
set display to use for VDP window
-mon-win-title
set title for 80 column window
-mon-win-display
set display to use for 80 column window

The following options are currently for the Linux versions only:

-serial1-dev dev
serial 1 in/out from device
-serial1-in fn
serial 1 input from file/pipe
-serial1-out fn
serial 1 output to file/pipe
-serial2-dev dev
serial 2 in/out from device
-serial2-in fn
serial 2 input from file/pipe
-serial2-out fn
serial 2 output to file/pipe
-nfx-port-offset off
offset to add to NFX port numbers

The Raspberry Pi versions of MEMU (either the with OS or bare-metal versions) may be attached to real hardware: a Memotech keyboard, a Kempston style joystick, or a Centronics printer via the Raspberry Pi GPIO connections. The following option is used to enable this:

-hw-config filename
Specifies a separate filename describing the hardware configuration. The format of this file differs from the other configuration options and is described here.

The Raspberry Pi build has one further option to control the use of the GPU:

-gpu-mode mode
Specifies the display upscaling mode to use:
  1. Perform upscaling in software (on the ARM CPU)
  2. GPU upscaling with interpolation. This can result in a blurred display
  3. GPU upscaling without interpolation. This is the default mode

Keyboard

MTX Keyboard layout

The layout of the MTX keyboard (illustrated above) differs somewhat from that of typical modern keyboards.

The two unlabelled keys either side of the space bar are reset keys. Pressing both simultaneously resets the MTX. In MEMU this is emulated by simultaneously pressing the <Alt> and <Alt Gr> keys to reset the emulated MTX.

One difference that causes a few problems is that there are a few symbols which have different shift states compared to modern keyboards. MEMU translates each key press into pressing the corresponding key on the emulated MTX keyboard. However, for these symbols the wrong shift state will be selected.

The original solution to this was to require typing a different key to produce the required symbol, as follows:

To produce symbolType the following key
^=
:#
@' (quote)
=^ (shift 6)
' (quote)@ (shift quote)
#£ (shift 3)
` (back quote)(shift back quote)

To improve on this, the emulation is modified slightly compared to the original hardware. The MTX keyboard is wired as an 8x10 matrix. However the keyboard only has 77 keys (plus the two reset keys). Thus there are three gaps in the matrix. The emulation fills these three spaces with three new keys which have most of the above symbols at shift states corresponding to modern keyboards. These new pseudo keys are:

Drive LineSense LineUnshifted symbolShifted Symbol
48=^
58'@
68#:

If keyboard remapping is enabled, and <Shift Lock> is set on the keyboard then pressing one of these symbols on the keyboard activates one of these new keys in the emulation rather than the original keys. The BASIC and CP/M ROMs are patched to recognise these new keys. However any programs with their own keyboard drivers will not know about these new keys and so will not work properly. Turning off <Scroll Lock> reverts to using the original MTX key mapping.

It is still necessary to press <Shift> to produce a back-quote symbol, but this is rarely needed.

The cursor keys on the keyboard are mapped onto the MTX cursor keys as expected, and the other navigation keys are:

KeyboardMTX Key
InsertIns
DeleteDel
HomeHome
EndEOL
Page UpPage
Page DownCls

For game playing, the physical layout of the keys is often important. For this reason, by default MEMU maps the top left portion of the keypad onto the MTX keypad as shown.

Keypad overlay illustration
PC KeypadMTX Keypad
NormalShiftedNormalShifted
Num Lock Page7
/ EOL8
* Break9
Home7Tab4
Up8Up5
Page Up9Del6
Left4Left1
 5Home2
Right6Right3
End1Ins0
Down2Down. (Decimal)
Page Down3ClsEnt

However this again results in some of the keys not having the effect indicated by the keycap. The <F12> key toggles the "Num Lock" LED. If this is illuminated then the the key mapping is changed to correspond to the labels on the keycaps. In particular the keys produce the expected numbers when the shift key is pressed. The <Num Lock> key can not be used for the toggle as it is part of the keypad mapping.

On versions of MEMU where each display is shown full screen, ideally use the combination of the <Alt> key and a function key to select the different displays. Unfortunately in some environments the operating system grabs those key combinations. In that case use the left <Ctrl> key in combination with a function key. To send a <Ctrl> and function key to a program running on MEMU, use the right <Ctrl> key.

MEMU Visual Debugger

MEMU Visual Debugger screenshot

The MEMU Visual Debugger is a machine code inspector and debugger similar to the MTX PANEL command or the CP/M VDEB utility. However it offers a number of advantages over those tools:

To open the Visual Debugger, press and hold the <F9> key and press the "h" key.

Visual Debugger commands are invoked by pressing the key corresponding to the capital letter of the command.

Break

Sets an address at which program execution will halt. Enter the required address as a hex number, and type <Return>. It is now possible to specify a specific ROM number or RAM page for the break. To do this type the two hex digit PAGE port selector (e.g. 40 for ROM 4, or 01 for RAM page 1), followed by a colon and then the address within that page. For example, to set a break at the start of the CRSPR routine enter 10:3E09. The page selector does not have to exactly match that specified for the break to occur, as long as they both point to the same location. Thus within the ROM region the RAM bits are ignored, while within RAM the ROM bits are ignored. If no page selector is specified, the current PAGE value is assumed.

When prompted for the Break Condition (COND>) there are a number of options:

Note that the Break command can only set one break condition at each address. However there may be breaks set for a number of different addresses.

Clear

Clears a break condition set at a specified address.

Display

Displays a block of memory starting at the specified address. The values starting at this location may then be changed by typing two digit hex values followed by <Return>. Use <Esc> to stop editing values.

Go

Starts program execution at specified address. If no address is specified (just <Return>) then start at the current value of the program counter (i.e continue execution). Optionally ("TO>" prompt) specify an address where execution is to halt again. The halt address may include a page specifier, as for the Break command.

Invert

Toggle between displaying memory in hex or ASCII.

List

List machine code starting at a specified address. If an address is specified, then the listing will remain fixed, starting at this address. If no address is given, then the listing will start at the location of the program counter, and will be updated whenever the program counter leaves the displayed listing.

Next

Sets a temporary break point at the next instruction, and then starts execution.

Profile

Toggles on and off collection of an execution profile.

When turned on, all the counts are reset to zero, and a count of the number of instructions executed is shown to the right of the prompt line.

When turned off, the number of times each instruction was executed since profiling was turned on is saved to a file with the name "Profile_<date>_<time>.txt" in the current folder, with the format:

Address    	     Count
DBFD - DC00	      1920
FC65 - FC6D	      1542
FC6F - FC71	      1536
FE1D - FE1E	       450
DD20 - DD22	       290
DE53 - DE55	       241
DE58 - DE61	       228
DE64 - DE67	       227
      

Quit

Quits the Visual Debugger. The window will be closed and all breakpoints will be inactive until the Visual Debugger is re-opened.

Register

Updates the value of the register pair pointed to by the register cursor. This cursor is moved by the stop "." key. Note that there is one step in the cycle when no register is selected.

Step

Executes a single machine code instruction then updates the display.

Trace

For most machine code instructions, this is the same as "Step". For a subroutine call (one that is taken for a conditional call), execute until a return statement brings the stack pointer back to the current value. For most subroutines, this will execute the routine as a single step, even if the call is followed by parameter bytes. It will fail if the routine does not finish with a return statement (e.g. finishes with "JP (HL)").

eXit

Attempts to exit the current subroutine. Works by running until a return statement is executed with the stack pointer at the current value. This will usually work if you have just mistakenly stepped into a routine you are not interested in. It will fail if there have been mis-matched PUSH and POP statements since the subroutine call.

Diagnostics

Diagnostic Options

MEMU includes many diagnostic features to assist developing and debugging Z80 code. Most of these are activated by the following additional options on the command line or in a configuration file:

-diag-console
Log diagnostic information to the console. Cannot be used with -mon-th as this would cause the diagnostic information to interfere with the text mode screen output.
-diag-file
Append diagnostic information to a file called memu.log.
-diag-file=filename
As above, but to file of your choice.
-diag-ring
Log diagnostic information to a ring buffer in memory. When MEMU terminates, dump this to memu.ring. A great way to avoid filling the disk with memu.log when all you care about is recent activity prior to failure.
-diag-ring=filename
As above, but to file of your choice.
-diag-time
Precede all diagnostic messages by a timestamp.
-diag-win-unknown-key
Displays host operating system specific keycodes typed in the windows which are not recognised by MEMUs window handling code. These will be X Window KeySym values or Windows virtual keycodes. Recognised values are passed on to the emulation of the MTX keyboard.
-diag-win-hw
Show communication with low-level devices.
-diag-win
Turn on all diagnostic options with names starting with -diag-win
-diag-mem-iobyte
Show when the IOBYTE is written to.
-diag-mem-subpage
Show when the ROM subpage register is written to.
-diag-mem-dump
When the program terminates, write the Z80 address space to a file called memu.mem.
-diag-mem
Turn on all diagnostic options with names starting with -diag-mem.
-diag-vid-status
Show when the VDP status register is read.
-diag-vid-registers
Show when VDP registers are written to.
-diag-vid-address
Show when the VDP address register is set, and whether for read or write.
-diag-vid-data
Show all data transferred to/from the VDP memory. Tries to log the data in formats allowing you to recognise which graphics data is being uploaded. Will cause a lot of logging.
-diag-vid-refresh
Show when the VDP screen is repainted to the Window on the host screen. This is the point at which the VDP interrupt bit becomes set.
-diag-vid-markers
Show additional markers on the Window. One is a line which moves down the screen, one pixel per frame, which can be observed to see if time is progressing smoothly in the emulation. Another shows on which scan lines there are >=5 sprites.
-vid-time-check parm
Set the parameters for performing timing checks on VDP access. The parameter consists of three values, separated by commas, giving:
-diag-vid-time-check
Perform VDP timing sanity checks.
-diag-vid-time-check-abort
Terminate if timing check fails.
-diag-vid-time-check-drop
Fail to store the data in VRAM, or return 0xff, if timing check fails.
-diag-vid
Turn on all diagnostic options with names starting with -diag-vid.
-diag-kbd-win-key
Show recognised key presses and releases in the VDP window which are not understood.
-diag-kbd-drive
Show keyboard drive values returned.
-diag-kbd-sense
Show keyboard drive and sense values returned.
-diag-kbd-auto-type
Show the workings of the auto-type mechanism.
-diag-kbd-remap
Show diagnostics relating to the keyboard remapping feature.
-diag-kbd-hw
Show communication with low-level device.
-diag-kbd
Turn on all diagnostic options with names starting with -diag-kbd.
-diag-joy-init
Show joystick initialisation messages.
-diag-joy-usage
Show joystick messages generated as joystick data is read.
-diag-joy
Turn on all diagnostics options with names starting with -diag-joy.
-diag-dart-ports
Show accesses to DART ports.
-diag-dart-config
Show DART configuration.
-diag-dart-data
Show DART data transfer.
-diag-dart-hw
Show communication with low-level hardware.
-diag-dart
Turn on all diagnostics options with names starting with -diag-dart.
-diag-snd-registers
Show accesses to the sound chip registers.
-diag-snd-latency
Show information relating to the latency parameters passed to PortAudio.
-diag-snd-init
Don't suppress stderr during Pa_Initialize() call.
-diag-snd
Turn on all diagnostic options with names starting with -diag-snd.
-diag-ctc-registers
Show when CTC registers are written to.
-diag-ctc-pending
Show when an interrupt becomes pending on a channel.
-diag-ctc-interrupt
Show when the fact the interrupt is pending is communicated to the Z80 chip.
-diag-ctc
Turn on all diagnostic options with names starting with -diag-ctc.
-diag-mon-hw
Show diagnostics relating to the hardware level emulation of the 6845 CRTC card and underlying memory.
-diag-mon-kbd-win-key
Show recognised key presses and releases sent to 80-column window. Only applies if -mon-win is being used.
-diag-mon-kbd-map-th
Show keycodes read from TH. Only applies if -mon-th is being used.
-diag-mon
Turn on all diagnostic options with names starting with -diag-mon.
-diag-sdxfdc-port
Turn on all diagnostic relating to SDX FDC port access.
-diag-sdxfdc-hw
Turn on all diagnostic relating to SDX FDC hardware.
-diag-sdxfdc-data
Turn on all diagnostic relating to SDX FDC data.
-diag-sdxfdc-status
Turn on all diagnostic relating to SDX FDC status.
-diag-sdxfdc
Turn on all diagnostic options with names starting with -diag-sdxfdc.
-diag-sidisc-file
Turn on all diagnostic relating to Silicon Disc file reading and writing.
-diag-sidisc-address
Turn on all diagnostic relating to Silicon Disc sector address control.
-diag-sidisc-data
Turn on all diagnostic relating to Silicon Disc data transfer.
-diag-sidisc
Turn on all diagnostic options with names starting with -diag-sidisc.
-diag-print
Show characters that are printed.
-diag-spec-ports
Log accesses to Speculator ports.
-diag-spec-interrupts
Log things relating to Speculator interrupts.
-diag-spec
Turn on all diagnostic options with names starting with -diag-spec.
-diag-cpm-driver
Log all calls to driver code in high memory.
-diag-cpm-cbios
Log all calls to CBIOS routines.
-diag-cpm-bdos-file
Log all calls to CP/M BDOS relating to file access.
-diag-cpm-bdos-other
Log other calls to CP/M BDOS.
-diag-cpm-bdos
Turn on all diagnostic options with names starting with -diag-cpm-bdos.
-diag-cpm
Turn on all diagnostic options with names starting with -diag-cpm.
-diag-z80-instructions
Log CPU registers and disassemble instruction prior to executing each instruction. Will cause a lot of logging.
-diag-z80-instructions-exclude from-to
Turn off logging CPU registers and disassemble instructions for instructions at addresses between from and to (eg: 0x0000-0x3fff).
-diag-z80-instructions-include from-to
Turn on logging CPU registers and disassemble instructions for instructions at addresses between from and to.
-diag-z80-interrupts
Log when the Z80 takes an interrupt, and show the peripheral supplied low byte of the vector table address.
-diag-z80-time
Include timing information in the Z80 instructions logged.
-diag-z80
Turn on all diagnostic options with names starting with -diag-z80 (except -diag-z80-instructions-exclude).
-diag-bad-port-display
Display when unemulated ports are accessed.
-diag-bad-port-ignore
Do not halt MEMU when certain unemulated ports are accessed. By default, termination happens for ports which are known to be used by particular hardware.
-diag-bad-port
Turn on all diagnostic options with names starting with -diag-bad-port.
-diag-tape
Diagnostics relating to the MTX BASIC LOAD/SAVE/VERIFY commands. It also shows diagnostics relating to the Z ZX Spectrum LOAD/SAVE/VERIFY commands.
-diag-speed
Every second, output an estimate of the emulated chip speed. If running with -fast this could be much higher than 4MHz. If running with -mon-console and the program waits for keyboard input, because the simulation is suspended this could to drop to near zero.
-diag-vga-mode
Report configuration of the emulated Propeller VGA display for different modes.
-diag-vga-port
Report access of ports used by the Propeller VGA display.
-diag-vga-refresh
Report refresh of the VGA display screen.
-diag-vga
Enable all the -diag-vga options.
-diag-node-pkt-tx
Log all NODE network packets transmitted.
-diag-node-pkt-rx
Log all NODE network packets received.
-diag-node
Enable all NODE network logging.
-diag-log-type
Log text entered into MEMU.
-diag-chip-log
Log diagnostic messages from programs running on MEMU.
-diag-nfx_port
Log data written to or read from Z80 ports on NFX board.
-diag-nfx_reg
Log data written to or read from Wiznet registers.
-diag-nfx_event
Log events on network connection sockets.
-diag-nfx_data
Log data sent or received over network.
-diag-nfx
Enable all NFX diagnostics.
-diag-init
Log MEMU initialisation
-diag-exit
Display the reason for the termination of MEMU.
-diag-all
Turn on all of the above (except -diag-console and -diag-file).

Run Time Diagnostics

A number of these diagnostics (and other features) may be turned on or off at run-time by pressing the <F9> key and a letter (the <F9> acting as a kind of shift key) as follows:

F9+a
Toggles accelerated mode
F9+b
Toggles -diag-mem-iobyte
F9+c
Toggles -diag-console
F9+d
Dump memory to memu.mem
F9+f
Toggles -diag-cpm-bdos-file
F9+h
Opens the Visual Debugger
F9+i
Toggles -diag-z80-interrupts
F9+k
Toggles -diag-kbd-sense
F9+l
Loads ZX snapshot file, as specified by -sna-file
F9+m
Toggles -diag-speed
F9+p
Toggles -diag-bad-port-display
F9+q
Toggles -diag-bad-port-ignore
F9+r
Dumps a snapshot of the Z80 registers
F9+s
Saves ZX snapshot file, as specified by -sna-file
F9+t
Rewinds to the start of a ZX tape file
F9+v
Dumps a snapshot of the VDP registers
F9+n
Dumps the VDP to "memuNNNNNN.vdp". This writes 16KB VRAM, 8 register bytes, and 1 status register byte.
F9+o
Toggles auto VDP dump mode on or off
F9+w
Snapshots the VDP screen to "memuNNNNNN.bmp"
F9+x
Toggles auto VDP snapshot mode on or off
F9+y
Toggles -diag-spec-ports
F9+z
Toggles -diag-z80-instructions

Diagnostic Windows

In addition to the above, MEMU supports three diagnostic windows:

-diag-ui-mem
The Memu Memory Inspector window allows you to specify an IOBYTE (and ROM subpage) and then to show what the Z80 processor sees at various addresses.
-diag-ui-vram
The Memu VRAM Inspector window allows you to show the contents of VRAM.
-diag-ui-dis
The Memu Disassembly Inspector window allows you to specify an IOBYTE (and ROM subpage) and disassemble the code seen by the Z80 at various addresses. When an instruction references (ie: jumps or calls) another address, an indication is given to the right of the instruction where the jump or call will go.

MEMU has a special RAM snapshot feature. First, you tell MEMU how many of the RAM pages are to be included in the snapshot using the -mem-blocks-snapshot N command line argument. N is the number of 16KB RAM pages. This number is normally 0, but might reasonably be 4 when debugging. MEMU takes a snapshot just before the Z80 is started, and if you're running a RUN file from the MEMU command line, just before it is given control. In the Memu Memory Inspector window colours communicate the following:

Pressing o takes a new snapshot. Pressing v toggles whether you are looking at the current value, or the value in the snapshot.

Hardware Configuration

If the optional feature of using GPIO to attach real hardware to MEMU is enabled, then it is necessary to provide a hardware configuration file to describe the attachments.

The hardware configuration file consists of blocks defining a particular interface, introduced by a name in square brackets, followed by the definition of that interface.

Pin Definitions

Most of the hardware definition file is defining which digital I/O pins connected to what hardware. These may be built in GPIO pins, or there is also support for one or more MCP23017 I2C port expanders.

These pin definitions take the form:

          GPIO, <gpiochip device>, <GPIO number>
          MCP23017, <I2C device>, <I2C address>, <MPC pin number>
      

Where:

<gpiochip device&>
The device name of the gpiochip device used, for example /dev/gpiochip0.
<GPIO number>
The number of the GPIO on the device.
<I2C device>
The device name of the I2C bus used. This will typically be “/dev/i2c-1” on more recent Raspberry Pis
<I2C address>
The I2C address of the port expander. This will typically be 0x20, although up to 8 simultaneous port expanders on different addresses are supported.
<MPC pin number>
he number of the pin on the port expander. This may either be a number in the range 0-15, or a letter and number in the ranges A0-A7 or B0-B7.

Keyboard

This block of the configuration file is used to define the connection of a MTX matrix keyboard or equivalent. It takes the form:

          [keyboard]
          kb0 = <pin definition>
	        :
          kb9 = <pin definition>
          dr0 = <pin definition>
            :
          dr7 = <pin definition>
          reset = <pin definition>
          reset2 = <pin definition>
          dr_reset = <gnd | dr0-dr7>
      

The lines kb0 – kb9 define the 10 keyboard sense lines, and the lines dr0-dr7 define the 8 keyboard drive lines.

For an unmodified MTX keyboard, the reset line defines the I/O pin that one of the keyboard reset lines is connected to. The other reset line should be connected to ground (0v). In that case the reset2 and dr_reset lines would be omitted.

The MTX keyboard may be modified by soldering an additional connection to the track joining the two reset keys. In that case both the existing keyboard reset lines should be connected to IO pins, and defined by the reset and reset2 lines. The additional connection between the reset keys should either be connected to ground (0v) or to one of the keyboard drive lines. The dr_reset line specifies how this is connected (gnd is the default).

Joysticks

If a matrix keyboard is fitted, then Atari style joysticks may be connected to the drive and sense lines, in parallel with the keyboard, as per the MTX. In that case no joystick definition is required. Alternately, the separate joystick switches may be connected to I/O pins, and the common connection to ground, as per earlier versions of MEMU-Pi. In that case, the joystick connections are defined by a block of the form:

        [joystick_1]
        left = <pin definition>
        right = <pin definition>
        up = <pin definition>
        down = <pin definition>
        fire = <pin definition>
    

The second joystick, if fitted, is defined similarly in a [joystick_2] block.

Printer

A Centronics style printer port may be provided. It should be noted that the Centronics connector uses 5v logic, while the Raspberry Pi GPIO connections are only 3.3v and are not 5v tolerant. Therefore some form of level shifting is required, Probably the simplest solution is to use an MCP23017 powered from 5v, but the I2C pullup resistors taken to 3.3v. The printer hardware block takes the form:

        [printer]
        d0 = <pin definition>
	      :
        d7 = <pin definition>
        strobe = <pin definition>
        busy = <pin definition>
        error = <pin definition>
        pe = <pin definition>
        slct = <pin definition>
    

Parallel Input/Output Port

ote that the MTX PIO port is 5v logic while the Raspberry Pi GPIO connections are only 3.3v tolerant. Also it is not practical to implement the INSTB and OTSTB lines in software. HCT244, HCT245 or HCT373 are examples of devices that could provide an OTSTB function and 3.3v to 5v step-up (not HC chips). A HC373 or HCT373 are examples that could provide INSTB, but the outputs would need resistor dividers to connect to the Raspberry Pi GPIO. The PIO hardware definition block takes the form:

        [pio]
        pot0 = <pin definition>
	      :
        pot0 = <pin definition>
        pin0 = <pin definition>
	      :
        pin7 = <pin definition>