1
0
Fork 0
mirror of https://github.com/pnx/m16vm synced 2026-06-16 03:44:55 +02:00
No description
Find a file
2019-04-23 11:12:37 +02:00
as as/lexer/number.c: should not stop parsing if we overflow. 2019-04-03 16:45:53 +02:00
examples examples/asm/hello_world.as: fix movl with 7+ offsets. 2019-01-04 21:15:30 +01:00
lib lib/error.c: minor fix. 2019-03-13 10:13:18 +01:00
vm vm/mm.c: convert check_bounds to a macro. 2019-04-23 11:12:37 +02:00
.gitignore Makefile: call "as" "m16as" 2018-12-10 23:21:58 +01:00
.gitlab-ci.yml .gitlab-ci.yml: adding m16as as artifact 2019-01-04 21:13:45 +01:00
LICENSE Add LICENSE 2018-10-26 12:47:02 +00:00
Makefile as/lexer.c: move hex/dec parse functions to as/lexer/number.c 2019-03-29 16:01:59 +01:00
README.md README.md: addr of Type-J is unsigned. 2018-11-25 11:23:11 +01:00

m16vm - 16 bit processor virtual machine

This is a virtual machine for a RISC-processor designed for educational purposes.

The design is taken from the real world and tries to mimic existing RISC-architectures. So it should in theory be possible to construct actual hardware based on the instruction set. Maybe not build a transistor-chip (it's hard, unless you know someone working at Intel/Amd or something) but by putting together a bunch of gate-chips on a breadboard.

The instruction set is by no means designed to be "fast" or "optimal" but focus more on being easy to understand and modify/play with.

Specification

The cpu has 16 general purpose registers, r0 - r15. Each register is 16-bit.

Memory addresses are aligned by 2 bytes (16 bit) and the machine has a total of 65536 bytes of memory (per default, can be changed at compile time).

instruction set overview

There are 16 different instructions.

opcode Name Type Description
0000 noop - No operation
0001 add R Addition
0010 movl I move value to register (lowest 8-bits)
0011 movh I move value to register (highest 8-bits)
0100 ld RI load word
0101 sw RI store word
0110 beq RI Branch on equal
0111 jmp J Jump
1000 jr I Jump (register)
1001 - - Reserved
1010 - - Reserved
1011 - - Reserved
1100 - - Reserved
1101 - - Reserved
1110 - - Reserved
1111 int I Interrupt

NOTE: Subtraction can be implemented via add and negative register values, so no special opcode is needed.

Instruction set format

Register operation (R):

opcode (4) | rs (4)  | r0 (4) | r1 (4)

r0,r1      - Operand registers.
rs         - save register

Register operation offset (RI):

opcode (4) | rs (4)  | r0 (4) | offset (signed 4)

r0 	- Operand registers.
offset  - constant offset from r0 value.
rs   	- save register

Constant operation format (I):

opcode (4) | reg (4) | data (signed 8)

reg - Register
data - Constant data to insert into reg.

Jump format (J):

opcode (4) | addr (12)

Interrupts

There can be a total of 16 Interrupts and the instruction uses the I-format.

The interrupt number is stored in reg (note that for interrupts this is a constant and not a register).

The data field can be used as an argument to the interrupt.

Number Name data Description
10 I/O Write format Outputs a value to the screen, value are stored in r15

I/O Write - int 10

The formatting of the output can be controlled by the number in data as follows:

Argument Datatype
0 Integer (16 bit signed)
1 Integer (8 bit signed)
2 Character

Example programs.

in the programs directory, there is some example programs to run.