1. interfect
  2. dcpu-emu

Overview

HTTPS SSH

DCPU-EMU

DCPU-EMU is an emulator for the DCPU-16 architecture, to be used in Notch's upcoming game about assembly programming in space (no really!), 0x10c.

Features

  • Binary program files.
  • 32x16 "video memory" area for output! IN COLOR!
  • compile time configurable keyboard: either a 16-character keyboard ring buffer or a single reset on read hardware latch at 0x9000!
  • Correct semantics for edge-case instructions like ADD PUSH, PUSH.
  • Lazy updates of memory-mapped devices make the emulator fast.

Downloading

DCPU-EMU is under active development, so it's best to work from the Mercurial repository:

anovak@hypernova:~/workspace$ hg clone https://bitbucket.org/interfect/dcpu-emu
destination directory: dcpu-emu
requesting all changes
adding changesets
adding manifests
adding file changes
added 57 changesets with 85 changes to 18 files
updating working directory
11 files updated, 0 files merged, 0 files removed, 0 files unresolved
anovak@hypernova:~/workspace$ cd dcpu-emu/
anovak@hypernova:~/workspace/dcpu-emu$

Once you have that set up, it's easy to get updates:

anovak@hypernova:~/workspace/dcpu-emu$ hg pull
pulling from https://bitbucket.org/interfect/dcpu-emu
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 2 changes to 2 files
(run 'hg update' to get a working copy)
anovak@hypernova:~/workspace/dcpu-emu$ hg update
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
anovak@hypernova:~/workspace/dcpu-emu$

Compiling

First, make sure you can compile Curses programs:

anovak@hypernova:~/workspace/dcpu-emu$ sudo apt-get install ncurses-dev

The included Makefile will compile the emulator on any system with gcc and make:

anovak@hypernova:~/workspace/dcpu-emu$ make
gcc cpu.c -std=c99 -lcurses -o cpu
anovak@hypernova:~/workspace/dcpu-emu$

Assembling Programs

The first thing you will probably want to do is assemble the included "Hello Word" program, hello.asm. To do this, you need an assembler; Chris Forbes's dcpu-asm is known to work well:

anovak@hypernova:~/workspace/dcpu-emu$ git clone https://github.com/chrisforbes/dcpu-asm.git
Cloning into dcpu-asm...
remote: Counting objects: 74, done.
remote: Compressing objects: 100% (66/66), done.
remote: Total 74 (delta 27), reused 54 (delta 7)
Unpacking objects: 100% (74/74), done.
anovak@hypernova:~/workspace/dcpu-emu$ python dcpu-asm/asm.py hello.asm -o hello.bin
anovak@hypernova:~/workspace/dcpu-emu$

Note that you need to specify both input and output filenames for the assembler.

Running Programs

Once you have a .bin file, you can run it in the emulator:

anovak@hypernova:~/workspace/dcpu-emu$ ./cpu hello.bin
Hello world!















====CYCLE 0x0094====
A:  0xbeef      B:  0x0000      C:  0x0000
X:  0x0000      Y:  0x0000      Z:  0x0000
I:  0x000c      J:  0x0000
PC: 0x0021      SP: 0x0000      O:  0x0000
Instruction: 0x85c3     Keyboard:0x0000

SYSTEM HALTED           Press any key to continue...

Although you didn't see it, the emulated system executed the entire "Hello World" program, displaying the values of the registers and the contents of video memory as it ran. When the halt instruction was encountered--in this case, a "subtract 1 from the program counter" instruction--the (trivial) infinite loop was detected and the emulator stopped.

Notes on Video Memory

Notch's original Hello World program copied data to an area starting at 0x8000, which he described as "Video ram". He has also posted an image of text output in-game, depicting what appears to be a 32-column, 16-line display. This display system has been implemented in the emulator as a block of memory from 0x8000 to 0x8400, where every word corresponds to one character. This appears to be how Notch intends his strings to work, and leaves extra bits for color (which is planned).

Under this implementation, Notch's sample "Hello World" program behaves much as one would expect it to. However, the specifications behind the implementation have not been explicitly discussed by Notch, and may change at a later time to be compatible with the actual game.

Color is currently implemented so that the high 4 bits are the foreground color, the next 4 bits are the background color, and the next bit is the blink attribute. If colors aren't showing up right for you, make sure your terminal supports at least 16 colors:

anovak@hypernova:~/workspace/dcpu-emu$ tput colors
256
anovak@hypernova:~/workspace/dcpu-emu$

An easy way to set this up on Ubuntu is by installing the ncurses-term package, and setting your TERM variable to xterm-256color:

anovak@hypernova:~/workspace/dcpu-emu$ sudo apt-get install ncurses-term
anovak@hypernova:~/workspace/dcpu-emu$ export TERM=xterm-256color

You may want to add the second line to your ~/.bashrc file.

To see colors in action, run the included hello2.asm, based on Notch's color demo.

Notes on Keyboard Input

Keyboard input is implemented as a 16-character ring buffer at 0x9000. This is compatible with deNull's web-based emulator, but not with DCPU Studio. Alternatively, you can compile the emulator to use a single address at 0x9000 as a keyboard device that is reset to 0 after each read.

A simple routine to get a character using the ring buffer is:

:getch SET B, [0x9010]
     SET A, [0x9000+B]
     IFE A, 0
       SET PC, POP
     SET [0x9000+B], 0
     ADD B, 1
     MOD B, 16
     SET [0x9010], B
     SET PC, POP

If you compile the emulator with KEYBOARD_USE_RING 0, you can get the last character pressed with:

SET A, [0x9000]

This routine returns 0 if there is no character available, and the character code otherwise. The included keycodes.asm file can be used to determine character codes.