• Stars
    star
    37
  • Rank 720,807 (Top 15 %)
  • Language
    Crystal
  • Created almost 10 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

VM emulator and assembler written in Crystal

RCPU

RCPU is a virtual machine emulator and assembler written in Crystal.

Caution
This project is very much a work in progress.

Building

You will need Crystal to build RCPU. Once you have Crystal, run make, which will generate the compiled assembler and emulator binaries in the current directory.

Usage

To assemble a file, use rcpu-assemble, passing the input filename (with the rcs extension). This will generate a corresponding rcb file. For example:

% ./rcpu-assemble samples/fib.rcs

To run a file, use rcpu-emulate, passing the input filename (with the rcb extension). For example:

% ./rcpu-emulate samples/fib.rcb

The rcs extension is used for RCPU source files, while rcb is for RCPU binary (i.e. compiled) files.

Tests

Run make spec to compile and run the tests.

Architecture

Registers

Name Code Size (bytes) Purpose

r0

0x00

4

general-purpose

r1

0x01

4

general-purpose

r2

0x02

4

general-purpose

r3

0x03

4

general-purpose

r4

0x04

4

general-purpose

r5

0x05

4

general-purpose

r6

0x06

4

general-purpose

r7

0x07

4

general-purpose

rpc

0x08

4

program counter (a.k.a instruction pointer)

rflags

0x09

1

contains result of cmp(i)

rsp

0x0a

4

stack pointer

rbp

0x0b

4

base pointer

rr

0x0c

4

return value

Instruction format

Instructions are of variable length.

The first byte is the opcode. Register arguments are one byte long, and label/immediate arguments are four bytes long.

Instruction set

Mnemonic Opcode Arguments Effect

Function handling

call(i)

0x01, 0x02

reg/imm

ret

0x03

(none)

Stack management

push(i)

0x04, 0x05

reg/imm

push a0 onto stack

pop

0x06

reg

pop into a0

Branching

j(i)

0x07, 0x08

reg/imm

pc ← a0

je(i)

0x09, 0x0a

reg/imm

if = then pc ← a0

jne(i)

0x0b, 0x0c

reg/imm

if β‰  then pc ← a0

jg(i)

0x0d, 0x0e

reg/imm

if > then pc ← a0

jge(i)

0x0f, 0x10

reg/imm

if β‰₯ then pc ← a0

jl(i)

0x11, 0x12

reg/imm

if < then pc ← a0

jle(i)

0x13, 0x14

reg/imm

if ≀ then pc ← a0

Arithmetic

cmp(i)

0x15, 0x16

reg, reg/imm

(see below)

mod(i)

0x17, 0x18

reg, reg, reg/imm

a0 ← a1 % a2

add(i)

0x19, 0x1a

reg, reg, reg/imm

a0 ← a1 + a2

sub(i)

0x1b, 0x1c

reg, reg, reg/imm

a0 ← a1 - a2

mul(i)

0x1d, 0x1e

reg, reg, reg/imm

a0 ← a1 * a2

div(i)

0x1f, 0x20

reg, reg, reg/imm

a0 ← a1 / a2

xor(i)

0x21, 0x22

reg, reg, reg/imm

a0 ← a1 ^ a2

or(i)

0x23, 0x24

reg, reg, reg/imm

a0 ← a1 | a2

and(i)

0x25, 0x26

reg, reg, reg/imm

a0 ← a1 & a2

shl(i)

0x27, 0x28

reg, reg, reg/imm

a0 ← a1 << a2

shr(i)

0x29, 0x2a

reg, reg, reg/imm

a0 ← a1 >> a2

not

0x2b

reg, reg

a0 ← ~a1

Register handling

mov

0x2c

reg, reg

a0 ← a1

li

0x2d

reg, imm

a0 ← a1

Memory handling

lw

0x2e

reg, imm

(see below)

lh

0x2f

reg, imm

(see below)

lb

0x30

reg, imm

(see below)

sw

0x31

reg, imm

(see below)

sh

0x32

reg, imm

(see below)

sb

0x33

reg, imm

(see below)

Special

sleep

0xfd

imm

sleep for a0 ms

prn

0xfe

reg

print a0

halt

0xff

(none)

stops emulation

cmp(i) updates the flags register and sets the 0x01 bit to true if the arguments are equal, and the 0x02 bit to true if the first argument is greater than the second.

lw, lh and lb load data from memory into a register. lw loads a word (4 bytes), lh loads a half word (2 bytes) and lb loads a byte. Similarly, sw, sh and sb store data from a register into memory.

Several opcodes have an (i) variant. These variants take a four-byte immediate argument (meaning the data is encoded in the instruction) rather than a register name. For opcodes that have immediate variants, the Opcode column contains the non-immediate variant followed by the immediate variant.

Label arguments are identical to immediate arguments.

Memory layout

Range Use

0x00 – …

Program code

… – 0xffff

Stack (grows downward, word-aligned)

0x00010000 - 0x00014b00

Video memory (160 by 120 pixels, 1 byte per pixel)

Assembly language syntax

A lines can be an instruction line, a label line, or a data directive line. Blank lines are ignored.

Comments start with the # character and can appear anywhere on a line, including a blank line. For example:

	# load coords
	li r2, 0                 # x (in px)
	li r3, 0                 # y (in px)

An instruction line starts with a tab character, followed by the instruction mnemonic, and arguments separated by commas. For example:

	li r3, 0                 # y (in px)
	jei @print-string-done
	addi rsp, rsp, 12

Register arguments are indicated with an r prefix (e.g. rsp or r0).

Immediate values can be given in decimal (e.g. 123), in hexadecimal (starting with 0x, e.g. 0xfe), or in binary (starting with 0b, e.g. 0b10010000).

Label arguments start with the @ character.

A label line starts with an identifier, followed by a colon. For example:

print-string-loop:

A data directive line starts with a period, followed by the directive name, followed by optional arguments. For example:

.byte 0x73 # s
.byte 0x6c # l
.byte 0x65 # e
.byte 0x65 # e
.byte 0x70 # p

.word @char-left-parenthesis  # (
.word @char-right-parenthesis # )
.word @char-question-mark     # * - TODO
.word @char-question-mark     # + - TODO
.word @char-comma             # ,
.word @char-dash              # -
.word @char-period            # .
.word @char-slash             # /

The supported data directives are .byte, .half and .word; they insert a byte, a half word (two bytes) or a word (four bytes), respectively.

See the examples in the samples directory for inspiration.

To do

  • Finish implementing all opcodes

  • Tests

  • Line/column numbers in parser error messages

  • RCPU prefix in binaries

More Repositories

1

cri

A tool for building commandline applications
Ruby
117
star
2

adsf

Web server that you can launch instantly in any directory
Ruby
88
star
3

glove

Crystal framework for making games
Crystal
69
star
4

fast-aleck

Fast Aleck is a fast HTML-aware typographical enhancement library that lets your text use proper ellipses, smart quotes, proper dashes and more.
C
18
star
5

d-mark

Semantic markup language
Ruby
18
star
6

inari

A collection of games written in Crystal
Crystal
14
star
7

d-parse

A parser combinator library for Ruby
Ruby
10
star
8

ddmemoize

Memoization for Ruby
Ruby
9
star
9

cobject

A library that adds support for object-orientation with inheritance, polymorphism, virtual destructors and reference counting to C.
C
6
star
10

rcpu-lang

Language that compiles to RCPU assembly
Crystal
6
star
11

slow_enumerator_tools

provides tools for transforming Ruby enumerators that produce data slowly and unpredictably
Ruby
5
star
12

ecs-sample

A sample game built using an Entity/Component/System architecture
Ruby
5
star
13

ddplugin

Plugin management library
Ruby
4
star
14

ddmetrics

In-memory, non-timeseries telemetry for Ruby
Ruby
4
star
15

ddbencode

bencode library written in C
C
3
star
16

yonce

β™« All the single ladies β™ͺ
Ruby
3
star
17

d-stream

Ruby
3
star
18

til

Today I Learned β€” sharing the things I learn
Ruby
3
star
19

d-mark-rust

Dβ˜…Mark implementation in Rust
Rust
2
star
20

neps

ARCHIVED - Contains all nanoc enhancement proposals (NEPs)
2
star
21

game-ai.cr

Some board games + common AI
Crystal
1
star
22

d-tech

2D game engine
Lua
1
star
23

nanoc-mermaid-example

HTML
1
star
24

myst-online-site

Source for the Myst Online: Uru Live web site
Ruby
1
star
25

monet

A MVC library for writing hardware-accelerated 2D games.
C
1
star
26

dotfiles-2013

Shell
1
star
27

breakout.lua

A Breakout clone written in Lua
Lua
1
star
28

scrobscrob

Automatically exported from code.google.com/p/scrobscrob
Objective-C
1
star
29

released

Experimental release pipeline
Ruby
1
star
30

fast-aleck-ruby

Ruby bindings for the Fast Aleck typographical enhancement library
Ruby
1
star
31

markbook

A vocabulary for Dβ˜…Mark for general technical writing
Ruby
1
star
32

d-tune

Experimental music player
TypeScript
1
star