This is an emulator for the Commander X16 computer system. It only depends on SDL2 and should compile on all modern operating systems.
Binary releases for macOS, Windows and x86_64 Linux are available on the releases page.
The emulator itself is dependent only on SDL2. However, to run the
emulated system you will also need a compatible rom.bin
ROM
image. This will be loaded from the directory containing the emulator
binary, or you can use the -rom .../path/to/rom.bin
option.
WARNING: Older versions of the ROM might not work in newer versions of the emulator, and vice versa.
You can build a ROM image yourself using the build
instructions in the [x16-rom] repo. The rom.bin
included in the latest
release of the emulator may also work with the HEAD of this repo,
but this is not guaranteed.
Install SDL2 using brew install sdl2
.
The SDL2 development package is available as a distribution package with most major versions of Linux:
yum install SDL2-devel
apt-get install libsdl2-dev
Type make
to build the source. The output will be
x16emu
in the current directory. Remember you will also
need a rom.bin
as described above.
Steps for compiling WebAssembly/HTML5 can be found here.
Currently macOS/Linux/MSYS2 is needed to build for Windows. Install mingw-w64 toolchain and mingw32 version of SDL. Type the following command to build the source:
CROSS_COMPILE_WINDOWS=1 MINGW32=/usr/x86_64-w64-mingw32 WIN_SDL2=/usr/x86_64-w64-mingw32 make
Paths to those libraries can be changed to your installation directory if they aren't located there.
The output will be x16emu.exe
in the current directory.
Remember you will also need a rom.bin
as described above
and SDL2.dll
in SDL2's binary folder.
You can start x16emu
/x16emu.exe
either by
double-clicking it, or from the command line. The latter allows you to
specify additional arguments.
x16emu
without arguments, it will pick up
the system ROM (rom.bin
) from the executable's
directory.-rom
command line argument.-ram <ramsize>
specifies banked RAM size in KB
(8, 16, 32, ..., 2048). The default is 512.-nvram
lets you specify a 64 byte file for the system's
non-volatile RAM. If it does not exist, it will be created once the
NVRAM is modified.-keymap
tells the KERNAL to switch to a specific
keyboard layout. Use it without an argument to view the supported
layouts.-sdcard
lets you specify an SD card image (partition
table + FAT32). Without this option, drive 8 will interface to the
current directory on the host.-serial
makes accesses to the host filesystem go
through the Serial Bus [experimental].-nohostieee
disables IEEE API interception to access
the host fs.-prg
lets you specify a .prg
file that
gets loaded after start. It is fetched from the host filesystem, even if
an SD card is attached!-bas
lets you specify a BASIC program in ASCII format
that automatically typed in (and tokenized).-run
executes the application specified through
-prg
or -bas
using RUN
or
SYS
, depending on the load address.-geos
launches GEOS at startup.-scale
scales video output to an integer multiple of
640x480-echo [{iso|raw}]
causes all KERNAL/BASIC output to be
printed to the host's terminal. Enable this and use the BASIC command
"LIST" to convert a BASIC program to ASCII (detokenize).-warp
causes the emulator to run as fast as possible,
possibly faster than a real X16.-gif <filename>[,wait]
to record the screen into
a GIF. See below for more info.-wav <filename>[{,wait|,auto}]
to record audio
into a WAV. See below for more info.-quality
change image scaling algorithm quality
nearest
: nearest pixel samplinglinear
: linear filteringbest
: (default) anisotropic filtering-log
enables one or more types of logging (e.g.
-log KS
):
K
: keyboard (key-up and key-down events)S
: speed (CPU load, frame misses)V
: video I/O reads and writes-debug
enables the debugger.-dump
configure system dump (e.g.
-dump CB
):
C
: CPU registers (7 B: A,X,Y,SP,STATUS,PC)R
: RAM (40 KiB)B
: Banked RAM (2 MiB)V
: Video RAM and registers (128 KiB VRAM, 32 B composer
registers, 512 B palette, 16 B layer0 registers, 16 B layer1 registers,
16 B sprite registers, 2 KiB sprite attributes)-joy1
, -joy2
, -joy3
,
-joy4
enables binding a gamepad to that SNES controller
port-sound
can be used to specify the output sound
device.-abufs
can be used to specify the number of audio
buffers (defaults to 8). If you're experiencing stuttering in the audio
try to increase this number. This will result in additional audio
latency though.-rtc
causes the real-time-clock set to the system's
time and date.-version
prints additional version information of the
emulator and ROM.#define TRACE
, -trace
will enable an instruction trace on stdout.Run x16emu -h
to see all command line options.
The X16 uses a PS/2 keyboard, and the ROM currently supports several different layouts. The following table shows their names, and what keys produce different characters than expected:
Name | Description | Differences |
---|---|---|
en-us | US | [`] ⇒ [←], [~] ⇒ [π], [\] ⇒ [£] |
en-gb | United Kingdom | [`] ⇒ [←], [~] ⇒ [π] |
de | German | [§] ⇒ [£], [´] ⇒ [^], [^] ⇒ [←], [°] ⇒ [π] |
nordic | Nordic | key left of [1] ⇒ [←],[π] |
it | Italian | [\] ⇒ [←], [|] ⇒ [π] |
pl | Polish (Programmers) | [`] ⇒ [←], [~] ⇒ [π], [\] ⇒ [£] |
hu | Hungarian | [\] ⇒ [←], [|] ⇒ [π], [§] ⇒ [£] |
es | Spanish | [|] ⇒ π, \ ⇒ [←], Alt + [<] ⇒ [£] |
fr | French | [²] ⇒ [←], [§] ⇒ [£] |
de-ch | Swiss German | [^] ⇒ [←], [°] ⇒ [π] |
fr-be | Belgian French | [²] ⇒ [←], [³] ⇒ [π] |
fi | Finnish | [§] ⇒ [←], [½] ⇒ [π] |
pt-br | Portuguese (Brazil ABNT) | [\] ⇒ [←], [|] ⇒ [π] |
Keys that produce international characters (like [ä] or [ç]) will not produce any character.
Since the emulator tells the computer the position of keys that are pressed, you need to configure the layout for the computer independently of the keyboard layout you have configured on the host.
Use the F9 key to cycle through the layouts, or set the
keyboard layout at startup using the -keymap
command line
argument.
The following keys can be used for controlling games:
Keyboard Key | SNES Equivalent |
---|---|
Ctrl | B |
Alt | Y |
Space | SELECT |
Enter | START |
Cursor Up | UP |
Cursor Down | DOWN |
Cursor Left | LEFT |
Cursor Right | RIGHT |
Ctrl
+ R
will reset the computer.Ctrl
+ V
will paste the clipboard by
injecting key presses.Ctrl
+ S
will save a system dump
(configurable with -dump
) to disk.Ctrl
+ F
and Ctrl
+
Return
will toggle full screen mode.Ctrl
+ =
and Ctrl
+
+
will toggle warp mode.On the Mac, use the Cmd
key instead.
With the argument -gif
, followed by a filename, a screen
recording will be saved into the given GIF file. Please exit the
emulator before reading the GIF file.
If the option ,wait
is specified after the filename, it
will start recording on POKE $9FB5,2
. It will capture a
single frame on POKE $9FB5,1
and pause recording on
POKE $9FB5,0
. PEEK($9FB5)
returns a 128 if
recording is enabled but not active.
With the argument -wav
, followed by a filename, an audio
recording will be saved into the given WAV file. Please exit the
emulator before reading the WAV file.
If the option ,wait
is specified after the filename, it
will start recording on POKE $9FB6,1
. If the option
,auto
is specified after the filename, it will start
recording on the first non-zero audio signal. It will pause recording on
POKE $9FB6,0
. PEEK($9FB6)
returns a 1 if
recording is enabled but not active.
On startup, the X16 presents direct mode of BASIC V2. You can enter
BASIC statements, or line numbers with BASIC statements and
RUN
the program, just like on Commodore computers.
RUN/STOP
key (Esc
in the emulator), or Ctrl + C
.Shift + Backspaces
, then type over those spaces.Shift + Home
.STOP + RESTORE
function.The command line argument -sdcard
lets you attach an
image file for the emulated SD card. Using an emulated SD card makes
filesystem operations go through the X16's DOS implementation, so it
supports all filesystem operations (including directory listing though
DOS"$
command channel commands using the DOS
statement) and guarantees full compatibility with the real device.
Images must be greater than 32 MB in size and contain an MBR
partition table and a FAT32 filesystem. The file
sdcard.img.zip
in this repository is an empty 100 MB image
in this format.
On macOS, you can just double-click an image to mount it, or use the command line:
# hdiutil attach sdcard.img
/dev/disk2 FDisk_partition_scheme
/dev/disk2s1 Windows_FAT_32 /Volumes/X16 DISK
# [do something with the filesystem]
# hdiutil detach /dev/disk[n] # [n] = number of device as printed above
On Linux, you can use the command line:
# sudo losetup -P /dev/loop21 disk.img
# sudo mount /dev/loop21p1 /mnt # pick a location to mount it to, like /mnt
# [do something with the filesystem]
# sudo umount /mnt
# sudo losetup -d /dev/loop21
On Windows, you can use the OSFMount tool.
If the system ROM contains any version of the KERNAL, and there is no SD card image attached, all accesses to the ("IEEE") Commodore Bus are intercepted by the emulator for device 8 (the default). So the BASIC statements will target the host computer's local filesystem:
DOS"$
LOAD"FOO.PRG
LOAD"IMAGE.PRG",8,1
SAVE"BAR.PRG
OPEN2,8,2,"FOO,S,R"
The emulator will interpret filenames relative to the directory it was started in. On macOS, when double-clicking the executable, this is the home directory.
To avoid incompatibility problems between the PETSCII and ASCII encodings, you can
Ctrl+O
to switch to the X16 to ISO mode for ASCII
compatibility.Ctrl+N
to switch to the upper/lower character set
for a workaround.BASIC programs are encoded in a tokenized form, they are not simply ASCII files. If you want to edit BASIC programs on the host's text editor, you need to convert it between tokenized BASIC form and ASCII.
Ctrl + V
(Mac: Cmd + V
). You can
now run the program, or use the SAVE
BASIC command to write
the tokenized version to disk.-echo
argument, LOAD
the BASIC file, and type LIST
.
Now copy the ASCII version from the terminal.Please see the KERNAL/BASIC documentation.
The debugger requires -debug
to start. Without it it is
effectively disabled.
There are 2 panels you can control. The code panel, the top left half, and the data panel, the bottom half of the screen. You can also edit the contents of the registers PC, A, X, Y, and SP.
The debugger uses its own command line with the following syntax:
Statement | Description |
---|---|
d %x | Change the code panel to view disassembly starting from the address %x. |
m %x | Change the data panel to view memory starting from the address %x. |
v %x | Display VERA RAM (VRAM) starting from address %x. |
b %s %d | Changes the current memory bank for disassembly and data. The %s param can be either 'ram' or 'rom', the %d is the memory bank to display (but see NOTE below!). |
r %s %x | Changes the value in the specified register. Valid registers in the %s param are 'pc', 'a', 'x', 'y', and 'sp'. %x is the value to store in that register. |
NOTE. To disassemble or dump memory locations in banked RAM or ROM, prepend the bank number to the address; for example, "m 4a300" displays memory contents of BANK 4, starting at address $a300. This also works for the 'd' command.
The debugger keys are similar to the Microsoft Debugger shortcut keys, and work as follows
Key | Description |
---|---|
F1 | resets the shown code position to the current PC |
F2 | resets the 65C02 CPU but not any of the hardware. |
F5 | is used to return to Run mode, the emulator should run as normal. |
F9 | sets the breakpoint to the currently code position. |
F10 | steps 'over' routines - if the next instruction is JSR it will break on return. |
F11 | steps 'into' routines. |
F12 | is used to break back into the debugger. This does not happen if you do not have -debug |
PAGE UP | is used to scroll up in the debugger. |
PAGE DOWN | is used to scroll down in the debugger. |
TAB | when stopped, or single stepping, hides the debug information when pressed |
When -debug
is selected the STP instruction (opcode $DB)
will break into the debugger automatically.
Effectively keyboard routines only work when the debugger is running normally. Single stepping through keyboard code will not work at present.
https://www.commanderx16.com/forum/
https://github.com/commanderx16/x16-emulator/wiki
Copyright (c) 2019-2020 Michael Steil <mist64@mac.com>, www.pagetable.com, et al. All rights reserved. License: 2-clause BSD
-prg
with -sdcard
MACPTR
on EOI)-warp
)-abufs
to specify number of audio buffers-uart-in
,
-uart-out
)-test
to auto-run
test-geos
to launch GEOS on startup-test
to launch (graphics) unit test on
startupnumpad +
and
numpad -
[Kobrasadetin]-joy1
and
-joy2
[John J Bliss]-echo
will now encode non-printable characters like
this: \X93 for CHR$(93), -bas
as well as pasting accepts
this convention again-echo raw
for the original behavior-echo iso
for correct character encoding in ISO
mode-ram
to specify RAM size; now defaults to 512-dump
option to allow writing RAM, CPU state or
VERA state to disk [Nils Hasenbanck]-quality
option to change scaling algorithm; now
defaults to "best" [Maurizio Porrato]-echo
can now be fed into UNIX pipes
[Anonymous Maarten]-char
(character ROM is now part of
rom.bin
)-gif
[Neil Forbes-Richardson]-debug
allows specifying a breakpoint [Frank Buss]rom.txt
Emulator:
-keymap
for setting the keyboard layout-scale
for integer scaling of the window [Stephen
Horn]-log
to enable various logging features (can also
be enabled at runtime (POKE $9FB0+) [Randall Bohn])-run
to be an option to -prg
and
-bas
-prg
and -run
no longer corrupt BASIC
programs.LOAD,1
into RAM bank [Stephen Horn]-debug
will enable the new debugger [Paul Robson]Ctrl + F/R/S/V
Ctrl + V
pastes the clipboard as keypresses-bas file.txt
loads a BASIC program in ASCII
encoding-echo
prints all BASIC/KERNAL output to the terminal,
use it with LIST to convert a BASIC program to ASCII-run
acts like -prg
, but also autostarts
the programJMP $FFFF
and SYS 65535
exit the emulator
and save memory into the host's storage-rom
,
-char
, -sdcard
and -prg
.LOAD"$"
LOAD,x,1
to load to the correct
addressgDOS
command. Without argument: print disk
status; with "$" argument: show directory; with "8" or "9" argument:
switch default drive; otherwise: send DOS command; also accessible
through F7/F8SYS65375 (SWAPPER) now also clears the screen, avoid ing side effects.
Cmd + F
or
Cmd + return
MON
: enter monitor; no more SYS65280 requiredVPEEK(bank, address)
VPOKE bank, address, value
example:
VPOKE4,0,VPEEK(4,0) OR 32
[for 256 color BASIC]rom.bin
is now
3*8 KB:
updated KERNAL with proper power-on message
LOAD and SAVE commands are intercepted by the emulator, can be used to access local file system, like this:
LOAD"TETRIS.PRG
SAVE"TETRIS.PRG
No device number is necessary. Loading absolute works like this:
LOAD"FILE.PRG",1,1
New optional override load address for PRG files:
./x64emu rom.bin chargen.bin basic.prg,0401
POKE40801,n
to switch the RAM bank at
$A000. POKE40800,n
to switch the ROM bank at $C000. The ROM
file at the command line can be up to 72 KB now (layout: 0: bank 0, 1:
KERNAL, 2: bank 1, 3: bank 2 etc.), and the RAM that
Cmd + S
saves is 2088KB ($0000-$9F00: regular RAM,
$9F00-$9FFF: unused, $A000+: extra banks)Cmd + S
now saves all of memory (linear 64 KB for now,
including ROM) to memory.bin
, memory-1.bin
,
memory-2.bin
, etc. You can extract parts of it with Unix
"dd", like:
dd if=memory.bin of=basic.bin bs=1 skip=2049 count=38655