Emulating the CoCo on a GNU/Linux system

By Pierre Sarrazin
Last update: 2019-05-16
The information on this page can be republished elsewhere without restriction.

This page gives practical procedures to install and run an emulator for the Tandy Color Computer (1, 2 or 3) under a GNU/Linux operating system.


The MESS emulator

Source Code

MESS is part of MAME, the arcade emulator. Recent versions require SDL2, for which there are apparently no precompiled packages for my version of Ubuntu, so I compiled it from sources, as explained below.

Compilation under GNU/Linux

Installing SDL2

While MESS 0.152 used version 1.x of SDL, versions 0.158 and later use SDL2 and SDL2_ttf.

If your GNU/Linux distribution provides precompiled SDL2 and SDL2_ttf packages, you should try them first. As of February 2015, I had not found such packages for Ubuntu 12.04, so I installed them from the sources. Here is what worked for me:


The minimum GCC version to compile MESS is 5.0. My Ubuntu 14.04 installation only comes with 4.8. I compiled 7.2 myself and installed it under /usr/local/gcc-7.2.0. See the "Installing GCC" page on the GCC site for details.

Patching the MESS sources re: SDL2 header files

This command should be given before launching make, so that the compilation can find the SDL2 header files and libraries:

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/SDL2-2.0.3/lib/pkgconfig

However, for some reason, the compilation still fails to find SDL2 header files. After trying to fight the makefile generator, I resorted to change all #include directives that targeted SDL2 files to make them specify a full absolute path. For example, in src/osd/sdl/sdlmain.cpp, I changed this line:

#include <SDL2/SDL.h>

to that line:

#include </usr/local/SDL2-2.0.3/include/SDL2/SDL.h>

Here is the list of files where I had to make that substitution:


I made the substitution with Perl commands like this one:

perl -i.bak -pe 's!(#include <)(SDL2/)!$1/usr/local/SDL2-2.0.3/include/$2!' src/osd/sdl/*.cpp

Patching the MESS sources to force RGB mode

(New as of 2019-01-31.) My installation of MESS 0.199 uses composite (CMP) mode by default and I failed to find how to tell it to use RGB mode from the command line. I resorted to replacing method coco3_state::screen_update() in src/mame/machine/coco3.cpp with this version:

uint32_t coco3_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
    return m_gime->update_rgb(bitmap, cliprect);

Compiling MESS itself

The following command compiles MESS with the version of GCC that I installed myself, instead of the system's GCC:

make OVERRIDE_CC=/usr/local/gcc-7.2.0/bin/gcc-7.2.0 OVERRIDE_CXX=/usr/local/gcc-7.2.0/bin/g++-7.2.0 SUBTARGET=mess

Preparing the ROM files

You need to find the coco3.rom file, and optionally the disk11.rom, which provides Disk Basic. They must be put in a directory called coco3, which itself must be put in a general MESS roms directory, for example ~/roms. In this instance, there would be these two files:


Here are the MD5 sums for the files I use (using the md5sum command):

7233c6c429f3ce1c7392f28a933e0b6f coco3.rom
8cab28f4b7311b8df63c07bb3b59bfd5 disk11.rom

Running MESS

Specifying the stdc++ directory

Executing MESS requires specifying the lib64 directory of the newly installed GCC so that mess64 can find the correct version of libstdc++:

LD_LIBRARY_PATH=/usr/local/gcc-7.2.0/lib64 ./mess64

Without this, expect errors of this kind:

mess: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by mess)
mess: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by mess)
mess: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by mess)
mess: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by mess)
mess: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by mess)

Specifying MESS arguments

Assuming that MESS should be allowed to use the ~/coco directory to write its configuration files, and that the ROM files are stored in a directory called ~/roms, then give this command to run the CoCo 3 emulator on a 64-bit system:

LD_LIBRARY_PATH=/usr/local/gcc-7.2.0/lib64 ./mess64 -window -cfg_directory ~/coco -biospath ~/roms coco3

On a 32-bit system, replace ./mess64 with ./mess.

If you have .dsk disk image files, you can tell the emulator to use them by adding "-flop1 foo.dsk" to the previous command line, where foo.dsk is the actual name of your image file.

Read the docs/config.txt in the MESS source directory to learn the keyboard commands that control the emulation.

Configuring MESS

Configuration menus are avaiable while running the emulation. To bring up the main menu, type Scroll Lock, then Tab.

The Scroll Lock key switches between the "full" and "partial" keyboard emulation modes. The idea here is to switch to partial mode, because it is the mode where MESS interprets Tab as the menu command. Otherwise, in full mode, the Tab key gets sent to the emulated machine. In the CoCo 3 case, that does nothing. To produce a tab character (ASCII 9) on the emulated CoCo, use the right arrow key instead.

The MESS documentation explains how to tell MESS to use a key other than Scroll Lock, which is useful on laptops that do not have that key. An alternative is to start MESS with -ui_active, which starts the emulation in the partial mode.

Using the PC keyboard

To obtain
this on
the CoCo:
Type this
on a PC
US keyboard:
" Shift 2 34
& Shift 6 38
' Shift 7 39
( Shift 8 40
) Shift 9 41
* _ 42
+ Shift NumPad+ 43
/ NumPad/ 47
\ Shift Home 92
: - 58
; NumPad+ 59
= +/ 61
? Shift NumPad/ 63
@ Left Alt 64
[ Shift down arrow 91
] Shift right arrow 93
Shift 95
CLEAR Home 12
kill line Shift 21
pause Shift Left Alt 19
unpause Left Alt

Other notes:

Connecting the emulated CoCo 3 with DriveWire 3

Support for the Becker Port

Versions 0.158 and later of MESS support the Becker port. The "Becker Port" entry in the System Configuration should say "On", and the "Drivewire Server TCP Port" entry should say 65504. See the DW4 Installation Guide for more on this.

Setting up DriveWire

DriveWire4 should be installed following the DW4 Installation Guide.

After the installation, go to the directory that contains DW4UI.sh and give the command sh DW4UI.sh. The main DriveWire window should appear after a few seconds.

Go to Config menu and use the Simple Config Wizard. Choose Emulator or other TCP/IP, server mode, port 65504, MIDI and printer options do not matter (to me at least), then Finish.

Choose a 35-track disk image that you want to access through DriveWire. Mount it in DriveWire by taking the context menu of row 0 of the upper grid, then choose Insert disk for drive 0. After choosing a .dsk file, the path of this file should appear in row 0 of the grid and the Filesystem column should say DECB.


HDB-DOS is a version of DECB that supports DriveWire and the Becker port. (This guide does not cover NitrOS-9.)

See the general HDB-DOS and DriveWire documentation for more details.



NitrOS-9 command reference

Goal Command example Remarks
General file manipulations dir, chd (or cd), copy, del, rename, pwd, makdir, deldir
Dump contents of file list filename
Create text file build filename Type non empty lines, then end with empty line.
Full screen editor scred Details in manual. To exit, type ex, Enter.
Start 32x16 terminal shell i=/v1 Then press Clear until found.
Quit shell ex
Write control codes to terminal display XX XX XX ... XX must be a hex code

ToolShed command reference

To be used from the host system. See the ToolShed manual for details.

Goal Command example Remarks
Format new disk image os9 format somename.dsk -ds -t80 -e -9
Copy host file to disk image os9 copy somefile somename.dsk, Comma is necessary. Pass -r after copy to overwrite existing file.
Make disk image file executable os9 attr -q -epe somename.dsk,/somefile Note comma and slash.
List files on disk image os9 dir somename.dsk, Comma is necessary.

To use a floppy image as /d1 from MAME, append -flop2 somename.dsk to the MAME command line.

Common error codes

Screen control characters

Some control characters can be used to clear the text screen, position the cursor, etc. in an OS-9 text terminal. Those control codes, which can be sent to the terminal with the display command, are documented in Appendix B (page B-2) of the OS-9 Operating System User's Guide (411 kB PDF).

That appendix also documents how to switch to a 256x192 or 128x192 graphics mode and issue drawing commands (lines, circles, floodfills) with control codes.

Switching to VDG graphics modes only works if the program is running in a VDG terminal (see shell i=/v1 above).

VDG graphics screen address

After setting up a VDG screen mode, the address of the 6 kB screen buffer can be obtained in register X with the following code, as documented in section B.4 of the Guide:

        lda     #1
        ldb     #$12        ; SS.DSTAT (Get Display Status)
        os9     $8D         ; I$GSTT

Editing the startup file

The /dd/startup file is the script that is run when the system boots. To make the boot sequence create a 32x16 VDG terminal at /v1, add the line "shell i=/v1" in that script, normally after the other "shell i=" lines.

The XRoar emulator

XRoar is another CoCo emulator, but as of 2019, it only emulates the CoCo 1 and 2, not the CoCo 3. It also emulates the Dragon, which was a clone of the Color Computer.

It is a much smaller program which also has the advantage of being free software distributed under the GNU General Public License.

Compilation under GNU/Linux

If you want the GTK+ interface, the GTK+ and GtkGLExt libraries are needed. On my Ubuntu 11.04 system, I installed them this way:

sudo apt-get install libgtkgl2.0-dev libgtkglext1-dev

Give this command to prepare the compilation:

./configure --prefix=/usr/local/xroar-0.32

The --prefix option is only needed if one wants to properly install the program, which is not needed to run it. The path prefix used here is just an example.

To have the GTK+ interface, these lines should have appeared:

Checking for GTK+-2 ... yes
Checking for GtkGLExt ... yes

Also, these two lines should appear in config.h:

#define HAVE_GTK2
#define HAVE_GTKGL

To compile the program under my Fedora 16 GNU/Linux system, I had to give this command to (1) avoid a linking error concerning "powf@@GLIBC_2.0" and (2) to avoid a makeinfo error ("xroar.texi:607: warning: unlikely character [ in @var") when compiling the documentation:

make LDLIBS=-lm SUBDIRS="portalib src"

The SUBDIRS makefile variable normally lists "doc" as its last element. The command above just avoids compiling the documentation. On my Ubuntu 12.04 system, no arguments were needed for the make command. The compilation should take around 20 seconds.

To check that the GTK+ interface has been compiled in, run src/xroar -ui help and check that a "gtk2" line is printed. (If the "xroar" executable is not in "src", it may be in the top directory.)

ROM files

Three ROM files are needed to boot into Disk Extended Color Basic. Their MD5 sums are the following:

c2fc43556eb6b7b25bdf5955bd9df825 bas13.rom
21070aa0496142b886c562bf76d7c113 extbas11.rom
8cab28f4b7311b8df63c07bb3b59bfd5 disk11.rom

The disk11.rom file here is the same one used under MESS.

These files should go in directory ~/.xroar/roms (create it if not already done).

Running XRoar

I start XRoar with the following command, assuming the "xroar" executable and the ROM files are in the current directory:

./xroar -machine cocous -ao sdl

The "-ao sdl" option tells XRoar to use SDL for the sound.

If the ROM files are not in the standard directory (~/.xroar/roms), their path can be specified on the command line like in the following example, where the files are in the current directory:

./xroar -machine cocous -ao sdl -bas ./bas13.rom -extbas ./extbas11.rom -cart ./disk11.rom

If XRoar starts with a screen containing mostly orange rectangles and "@" characters, it is typically because it has not found the ROM files. Check the contents of ~/.xroar/roms, and/or the -bas, -extbas and -cart options and their arguments.

Holding F12 in XRoar will cause it to run the emulation at the maximum possible speed. The XRoar manual specifies other keyboard commands.

To emulate the CoCo PMODE 4 artifact colors, pass the -tv-type ntsc command-line option.

To use the French Canadian keyboard, pass the -keymap fr_CA option.

To avoid using Disk Basic, do not pass any -cart disk*.rom option and remove the disk*.rom files from the ROM directory. Note that the -run option to automatically launch a .BIN file still works in this situation.

Emulating an original 4K RAM CoCo 1

Find the bas10.rom file, put it in the same directory as bas13.rom, then add these options to XRoar:

-noextbas -nodos -bas bas10.rom -ram 4

Here is the MD5 sum of the Color Basic 1.0 ROM file:

a74f3d95b395dad7cdca19d560eeea74 /home/ps/.xroar/roms/bas10.rom

Running a machine language program as a cartridge ROM

The following instructions work with XRoar 0.34.7:

Expect a delay of about 3 seconds before the program starts running. This is due to Color Basic testing the RAM one byte at a time to find the end of the available RAM. (This delay also occurs without a cartridge.)

Enabling the Becker Port

Pass the -cart-becker option to XRoar. See the section on the Becker port for programming details.

Disk image files

To create a Disk Basic 35 track disk image file in raw format, use this command in a shell:

perl -e 'print chr(255) x (35*18*256)' > somename.dsk

Such an image file is usable in MESS with the "-flop1 somename.dsk" option, and in XRoar with the "-disk-write-back -load somename.dsk" options.

In both emulators, write operations to the emulated disk are reflected in the .dsk file.

Communicating with the Becker Port

MESS and XRoar can both connect to a program that listens for TCP/IP connections on port 65504 or the machine the emulator runs on. They make that connection when started, so the TCP/IP server must be started before the emulator.

On the emulated CoCo, a byte written to $FF42 will be sent to the TCP/IP server. This server can send data on the connection: the CoCo must first check bit 1 of $FF41 to check if any data is present. If it is set, reading $FF42 gets the next available byte.

The DynoSprite game engine

In late 2014, Richard Goedeken published DynoSprite, a full-featured video game engine for the CoCo 3.

By following the README file, I was able to compile it and run the demo, but at first, the compilation failed. The options passed to ffmpeg were not accepted by that command: I got an "Unrecognized option 'af'" error message. My system at that time (early Dec. 2014) had version 0.8.16-4:0.8.16-0ubuntu0.12.04.1 of ffmpeg.

The command aimed to convert a 44100 Hz 16-bit .wav file into a 6000 Hz 8-bit .raw file. Because my system has the sox command, I edited makefile to replace this line:

ffmpeg -v warning -i $< -acodec pcm_u8 -f u8 -ac 1 -ar $(AUDIORATE) -af aresample=$(AUDIORATE):filter_size=256:cutoff=1.0 $@

with this one:

sox $< -r $(AUDIORATE) -c 1 -u -1 $@

Then the make all command succeeded and produced a .dsk image that ran correctly in MESS 0.152, with sound.

BadWindow errors

After allowing Ubuntu's Update Manager to update from packages, I started getting errors of the following type from MESS 0.158 and MAME 0.145 (but not from MESS 0.152):

X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  137 (NV-GLX)
  Minor opcode of failed request:  4 ()
  Resource id in failed request:  0x4800002
  Serial number of failed request:  90
  Current serial number in output stream:  90

Similarly, XRoar 0.32 started giving me this error (when using the GTK+ interface):

The error was 'BadWindow (invalid Window parameter)'.
  (Details: serial 237 error_code 3 request_code 137 minor_code 4)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)

What resolved this was to reinstall the Nvidia driver (which are unfortunately required to get a 1280x1024 desktop instead of just 1024x768). I did this:

My original mistake was to choose a graphics card without checking if it would force me to use a fragile, proprietary driver to use the card's maximum resolution. I have had other problems with this driver after a kernel update. They are discussed in this Ask Ubuntu thread.

This is under Ubuntu 12.04 in March 2015. I ended up with kernel 3.8.0-44-generic. The PC is an x86_64. Its graphics card is a GeForce GT 630 Rev. 2 purchased in Fall 2013.

External links

Also by me for the CoCo

Other CoCo resources