Simulator Example Synacor Port

The Synacor Challenge is a fun programming exercise with a number of puzzles built into it.

The first puzzle is writing an interpreter for their custom ISA. The CPU is quite basic: it's 16-bit with only 8 registers and a limited set of instructions. This means the port will never grow new features.

Implementing it here ends up being quite useful: it acts as a simple constrained "real world" example for people who want to implement a new simulator for their own architecture. We demonstrate all the basic fundamentals (registers, memory, branches, and tracing) that all ports should have.

This port does not use CGEN, so it is not a good reference for that.

Source Layout

Take note that example-synacor is the unique port name and is used everywhere for indexing. Normally this would be the common architecture name that is being simulated (e.g. arm).

This represents the barest skeleton of a functional port. Only the default Virtual Environment is supported.

* sim/

Synacor Architecture

This section is not required to write a new port. It is provided as a reference to help better understand the example-synacor internals if needed.

* Architecture

* Binary Format

* Execution

* Hints

Instructions

This section is not required to write a new port. It is provided as a reference to help better understand the example-synacor internals if needed.

These are the supported instructions and their encodings. It's the instruction name followed by its opcode (encoding), followed by its arguments (if any).

Name

Encoding

Description

halt

0

Stop execution and terminate the program.

set

1 A B

Set register A to the value of B.

push

2 A

Push A onto the stack.

pop

3 A

Remove the top element from the stack and write it into A; empty stack = error.

eq

4 A B C

Set A to 1 if B is equal to C; set it to 0 otherwise.

gt

5 A B C

Set A to 1 if B is greater than C; set it to 0 otherwise.

jmp

6 A

Jump to A.

jt

7 A B

If A is nonzero, jump to B.

jf

8 A B

If A is zero, jump to B.

add

9 A B C

Assign into A the sum of B and C (modulo 32768).

mult

10 A B C

Store into @var{A} the product of @var{B} and @var{C} (modulo 32768).

mod

11 A B C

Store into A the remainder of B divided by C.

and

12 A B C

Stores into A the bitwise and of B and C.

or

13 A B C

Stores into A the bitwise or of B and C.

not

14 A B

Stores 15-bit bitwise inverse of B in A.

rmem

15 A B

Read memory at address B and write it to A.

wmem

16 A B

Write the value from B into memory at address A.

call

17 A

Write the address of the next instruction to the stack and jump to A.

ret

18

Remove the top element from the stack and jump to it; empty stack = halt.

out

19 A

Write the character represented by ascii code A to the terminal.

in

20 A

Read a character from the terminal and write its ascii code to A; it can be assumed that once input starts, it will continue until a newline is encountered; this means that you can safely read whole lines from the keyboard and trust that they will be fully read.

noop

21

No operation.

None: Sim/Porting/Synacor (last edited 2021-11-18 05:46:05 by MikeFrysinger)

All content (C) 2008 Free Software Foundation. For terms of use, redistribution, and modification, please see the WikiLicense page.