Emulating the CoCo on a GNU/Linux system

By Pierre Sarrazin
Last update: 2022-11-11
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.

Contents


The MAME emulator

This section is partly obsolete, since MESS has been part of MAME for a good while.

Source Code

Recent versions of MAME require SDL2, for which there are apparently no precompiled packages for some versions of Ubuntu, so one may need to compile SDL2 from sources, as explained below.

Compilation under GNU/Linux

GCC

The minimum GCC version to compile MESS is 5.0. If gcc --version reports 5.0 or later, you can skip this section.

When I was using Ubuntu 14.04, it only came with GCC 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.

Installing SDL2

If your system has files /usr/include/SDL2/SDL.h and /usr/include/SDL2/SDL_ttf.h, then you have the SDL2 and SDL2_ttf development files, and you can skip this section.

Otherwise, on an Ubuntu system, you should be able to install those files with this command:

sudo apt install libsdl2-dev libsdl2-ttf-dev

If this installation works, you can skip the rest of this section.

In 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:

Patching the MESS sources re: SDL2 header files

Skip this section if you did not need to install SDL2 from the sources.

The following 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:

src/osd/sdl/sdlmain.cpp
src/osd/sdl/window.cpp
src/osd/sdl/video.cpp
src/osd/modules/sound/sdl_sound.cpp
src/osd/modules/sound/direct_sound.cpp
src/osd/modules/render/drawsdl.cpp
src/osd/modules/render/draw13.h
src/osd/modules/render/sdlglcontext.h
src/osd/modules/render/drawbgfx.cpp
src/osd/modules/render/drawsdl.h
src/osd/modules/render/drawogl.cpp
src/osd/modules/monitor/monitor_sdl.cpp
src/osd/modules/lib/osdlib_unix.cpp
src/osd/modules/opengl/osd_opengl.h
src/osd/modules/input/input_x11.cpp
src/osd/modules/input/input_sdl.cpp
src/osd/modules/input/input_sdlcommon.cpp
src/osd/modules/input/input_common.cpp
src/osd/modules/font/font_sdl.cpp
src/osd/osdcore.cpp

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

In the simple case, the compilation is launched with this command:

make SUBTARGET=mess -j4

But if it was necessary to install and use an alternate version of GCC, then the following arguments must be added to that command line (in the case of GCC 7.2.0):

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

The argument to the -j option is the number of jobs that make is allowed to launch at the same time. For a shorter build time, this should be the number of cores on the machine.

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:

~/roms/coco3/coco3.rom
~/roms/coco3/disk11.rom

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

Skip this section if the system GCC was used to compile MESS.

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

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

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 the following command to run the CoCo 3 emulator on a 64-bit system (omit LD_LIBRARY_PATH if the system GCC was used to compile MESS):

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

MESS 0.199 named the executable mess instead of mamemess.

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 available 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:
Generated
ASCII
code:
" 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 ↓ 91
] Shift → 93
94
Shift 95
CLEAR Home 12
BREAK End 3
kill line Shift 21
pause Shift Left Alt 19
unpause Most keys

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 the 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

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

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

NitrOS-9

Booting

NitrOS-9 command reference

Goal Command example Remarks
General file manipulations dir, chd (or cd), copy, del, rename, pwd, makdir, deldir
Show contents of file list filename
Hex dump of file dump filename
Create text file build filename Type non empty lines, then end with empty line.
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

Typing special characters

Here are some of the keys listed in the Special Keys section of Getting Started With NitrOS-9.

Character to produce Appearance CoCo keys to use
Underscore _ Ctrl-Hyphen
Left bracket [ Ctrl-8
Right bracket ] Ctrl-9
Left brace { Ctrl-Comma
Right brace } Ctrl-Period
Backslash \ Ctrl-Slash
Tilde ~ Ctrl-3
Vertical bar (pipe) | Ctrl-1
Caret ^ Ctrl-7

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 an Ubuntu system, it should be possible to install them this way:

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

Give this command to prepare the compilation:

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

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.

If the GTK+ interface is wanted, these lines should have appeared:

checking for gtk+-2.0... yes
checking if GTK+ 2 is usable... yes
checking for gtkglext-1.0... yes
checking if GtkGLExt is usable... yes

To compile XRoar, give the make command. The executable should appear in src/xroar.

To confirm 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. The GTK+ interface should appear, if it has been compiled.

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. This requires using the GTK+ interface.

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.

Collecting the output of the serial port

Pass -lp-file host_file to send the CoCo's serial port output to the given host file. The emulator must be closed before the characters will appear in the host file.


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