dcpu16

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 5f7046b6897415957c6759c755d470ff138bd494
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed,  4 Apr 2012 03:33:47 -0700

It compiles but is otherwise untested.

Diffstat:
Adcpu.c | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+), 0 deletions(-)

diff --git a/dcpu.c b/dcpu.c @@ -0,0 +1,143 @@ +/* Copyright 2012, Brian Swetland. BSD Licensed. Share and Enjoy! */ +/* A DCPU-16 Implementation */ + +/* DCPU-16 Spec is Copyright 2012 Mojang */ +/* http://0x10c.com/doc/dcpu-16.txt */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +typedef uint16_t u16; +typedef uint32_t u32; + +struct dcpu { + u16 r[8]; + u16 pc; + u16 sp; + u16 ov; + u16 skip; + u16 m[65536]; +}; + +static u16 lit[0x20] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +u16 *dcpu_opr(struct dcpu *d, u16 code) { + switch (code) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + return d->r + code; + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + return d->m + d->r[code & 7]; + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + return d->m + ((d->r[code & 7] + d->m[d->pc++]) & 0xffff); + case 0x18: + return d->m + d->sp++; + case 0x19: + return d->m + d->sp; + case 0x1a: + return d->m + (--(d->sp)); + case 0x1b: + return &d->sp; + case 0x1c: + return &d->pc; + case 0x1d: + return &d->ov; + case 0x1e: + return d->m + d->m[d->pc++]; + case 0x1f: + return d->m + d->pc++; + default: + return lit + (code & 0x1F); + } +} + +void dcpu_step(struct dcpu *d) { + u16 op = d->m[d->pc++]; + u16 dst; + u32 res; + u16 a, b, *aa; + + if ((op & 0xF) == 0) { + switch ((op >> 4) & 0x3F) { + case 0x01: + a = *dcpu_opr(d, op >> 10); + if (d->skip) { + d->skip = 0; + } else { + d->m[--(d->sp)] = d->pc; + d->pc = a; + } + return; + default: + return; + } + } + + aa = dcpu_opr(d, dst = (op >> 4) & 0x3F); + a = *aa; + b = *dcpu_opr(d, op >> 10); + + switch (op & 0xF) { + case 0x1: res = b; + break; + case 0x2: res = a + b; + break; + case 0x3: res = a - b; + break; + case 0x4: res = a * b; + break; + case 0x5: if (b) { res = a / b; } else { res = 0; } + break; + case 0x6: if (b) { res = a % b; } else { res = 0; } + break; + case 0x7: res = a << b; + break; + case 0x8: res = a >> b; + break; + case 0x9: res = a & b; + break; + case 0xA: res = a | b; + break; + case 0xB: res = a ^ b; + break; + case 0xC: res = (a==b); + goto cond; + case 0xD: res = (a!=b); + goto cond; + case 0xE: res = (a>b); + goto cond; + case 0xF: res = ((a&b)!=0); + goto cond; + } + + if (d->skip) { + d->skip = 0; + return; + } + if (dst < 0x1f) { + *aa = res; + d->ov = res >> 16; + } + return; + +cond: + if (d->skip) { + d->skip = 0; + return; + } + d->skip = res; +} + +int main(int argc, char **argv) { + struct dcpu d; + return 0; +} +