[ create a new paste ] login | about

Link: http://codepad.org/bR3LZS5E    [ raw code | output | fork ]

arachneng - C, pasted on Apr 5:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

typedef uint16_t word;
typedef uint32_t xword;

#define CASEx8(x) \
	case (x)+0: case (x)+1: case (x)+2: case (x)+3: \
	case (x)+4: case (x)+5: case (x)+6: case (x)+7

int wc;
word pc, sp, of, reg[8], mem[1<<16];

void init(void)
{
	wc = 0;
	pc = 0x0000;
	sp = 0xffff;
	of = 0x0000;
	memset(reg, 0, sizeof reg);
}

word *get(word v, word *sink)
{
	switch (v) {
	CASEx8(0x00):		return &reg[v];
	CASEx8(0x08):		return &mem[reg[v-0x08]];
	CASEx8(0x10):	++wc;	return &mem[reg[v-0x10] + mem[pc++]];
	case 0x18:		return &mem[sp++];
	case 0x19:		return &mem[sp];
	case 0x1a:		return &mem[--sp];
	case 0x1b:		return &sp;
	case 0x1c:		return &pc;
	case 0x1d:		return &of;
	case 0x1e:	++wc;	return &mem[mem[pc++]];
	case 0x1f:	++wc;	return &mem[pc++];
	CASEx8(0x20):
	CASEx8(0x28):
	CASEx8(0x30):
	CASEx8(0x3f):		*sink = v-0x20; return sink; // OOPS!
	default:		abort();
	}
}

void tick(void)
{
	word c = mem[pc++];
	word op = c & 15, aa = (c >> 4) & 63, bb = c >> 10;

	if (op) { // typical opcodes
		word a0, b0;
		xword tmp;
		word *a = get(aa, &a0);
		word *b = get(bb, &b0);

		switch (op) {
		case 0x01: // SET
			*a = *b;
			wc += 1;
			break;

		case 0x02: // ADD
			tmp = (xword)*a + (xword)*b;
			of = (tmp >= 0x10000 ? 1 : 0);
			*a = (word)(tmp & 0xffff);
			wc += 2;
			break;

		case 0x03: // SUB
			tmp = (xword)*a + (xword)~*b + 1;
			of = (tmp >= 0x10000 ? 0xffff : 0);
			*a = (word)(tmp & 0xffff);
			wc += 2;
			break;

		case 0x04: // MUL
			tmp = (xword)*a * (xword)*b;
			of = (word)(tmp >> 16);
			*a = (word)(tmp & 0xffff);
			wc += 2;
			break;

		case 0x05: // DIV
			tmp = (*b ? ((xword)*a << 16) / (xword)*b : 0);
			of = (word)(tmp & 0xffff);
			*a = (word)(tmp >> 16);
			wc += 3;
			break;

		case 0x06: // MOD
			*a = (*b ? *a % *b : 0);
			wc += 3;
			break;

		case 0x07: // SHL
			tmp = (*b >= 32 ? 0 : (xword)*a << (xword)*b);
			of = (word)(tmp >> 16);
			*a = (word)(tmp & 0xffff);
			wc += 2;
			break;

		case 0x08: // SHR
			tmp = (*b >= 32 ? 0 : ((xword)*a << 16) >> (xword)*b);
			of = (word)(tmp & 0xffff);
			*a = (word)(tmp >> 16);
			wc += 2;
			break;

		case 0x09: // AND
			*a = *a & *b;
			wc += 1;
			break;

		case 0x0a: // BOR
			*a = *a | *b;
			wc += 1;
			break;

		case 0x0b: // XOR
			*a = *a ^ *b;
			wc += 1;
			break;

		case 0x0c: // IFE
			if (*a == *b) {
				wc += 1;
			} else {
				pc += 1;
				wc += 2;
			}
			break;

		case 0x0d: // IFN
			if (*a != *b) {
				wc += 1;
			} else {
				pc += 1;
				wc += 2;
			}
			break;

		case 0x0e: // IFG
			if (*a > *b) {
				wc += 1;
			} else {
				pc += 1;
				wc += 2;
			}
			break;

		case 0x0f: // IFB
			if (*a & *b) {
				wc += 1;
			} else {
				pc += 1;
				wc += 2;
			}
			break;

		default:
			abort();
		}
	} else if (aa) {
		word b0;
		switch (aa) {
		case 0x01: // JSR
			mem[--sp] = pc;
			pc = *get(bb, &b0);
			wc += 2;
			break;

		default:
			if (aa >= 0x02 && aa <= 0x3f) {
				fprintf(stderr, "Reserved opcode %d:0\n", (int)aa);
				wc += 1;
				break;
			}
			abort();
		}
	} else {
		fprintf(stderr, "Reserved opcode %d:0:0\n", (int)bb);
		wc += 1;
	}
}

int dumpv(word v, word pc)
{
	static const char ops[8] = "ABCXYZIJ";

	switch (v) {
	CASEx8(0x00):	putchar(ops[v]); return 0;
	CASEx8(0x08):	printf("[%c]", ops[v-0x08]); return 0;
	CASEx8(0x10):	printf("[%c%+d]", ops[v-0x10], (int)(int16_t)mem[pc]); return 1;
	case 0x18:	printf("[SP++]"); return 0;
	case 0x19:	printf("[SP]"); return 0;
	case 0x1a:	printf("[--SP]"); return 0;
	case 0x1b:	printf("SP"); return 0;
	case 0x1c:	printf("PC"); return 0;
	case 0x1d:	putchar('O'); return 0;
	case 0x1e:	printf("[%#x]", (int)(int16_t)mem[pc]); return 1;
	case 0x1f:	printf("%#x", (int)(int16_t)mem[pc]); return 1;
	CASEx8(0x20):
	CASEx8(0x28):
	CASEx8(0x30):
	CASEx8(0x3f):	printf("%d", (int)(v-0x20)); return 0;
	default:	abort();
	}
}

word dump(word pc)
{
	word oldpc = pc;
	word c = mem[pc++];
	word op = c & 15, a = (c >> 4) & 63, b = c >> 10;

	printf("%04x: ", oldpc);
	if (op) {
		static const char opcodes[16][4] = {
			"???", "SET", "ADD", "SUB", "MUL", "DIV", "MOV", "SHL",
			"SHR", "AND", "BOR", "XOR", "IFE", "IFN", "IFG", "IFB",
		};
		printf("%s ", opcodes[op]);
		pc += dumpv(a, pc);
		printf(", ");
		pc += dumpv(b, pc);
		printf("\n");
	} else {
		switch (a) {
		case 0x00:
			printf("; Reserved opcode %d:0:0\n", (int)b);
			break;
		case 0x01:
			printf("JSR ");
			pc += dumpv(b, pc);
			printf("\n");
			break;
		default:
			if (a >= 0x02 && a <= 0x3f) {
				printf("; Reserved opcode %d:0\n", (int)a);
				break;
			}
			abort();
		}
	}
	return pc - oldpc;
}

void stat(void)
{
	printf("PC=%04x SP=%04x O=%04x Reg=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x (t=%d)\n",
		pc, sp, of, reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7], wc);
	dump(pc);
}

int main(void) {
	word initmem[] = {
		0x7c01,0x0030,0x7de1,0x1000,0x0020,0x7803,0x1000,0xc00d,
		0x7dc1,0x001a,0xa861,0x7c01,0x2000,0x2161,0x2000,0x8463,
		0x806d,0x7dc1,0x000d,0x9031,0x7c10,0x0018,0x7dc1,0x001a,
		0x9037,0x61c1,0x7dc1,0x001a,0x0000,0x0000,0x0000,0x0000,
	};
	int i;

	for (i = 0; i < 32; ++i) mem[i] = initmem[i];

	init();
	while (wc < 100) {
		stat();
		tick();
	}

	return 0;
}


Output:
PC=0000 SP=ffff O=0000 Reg=0000:0000:0000:0000:0000:0000:0000:0000 (t=0)
0000: SET A, 0x30
PC=0002 SP=ffff O=0000 Reg=0030:0000:0000:0000:0000:0000:0000:0000 (t=2)
0002: SET [0x1000], 0x20
PC=0005 SP=ffff O=0000 Reg=0030:0000:0000:0000:0000:0000:0000:0000 (t=5)
0005: SUB A, [0x1000]
PC=0007 SP=ffff O=0000 Reg=0010:0000:0000:0000:0000:0000:0000:0000 (t=8)
0007: IFN A, 16
PC=0009 SP=ffff O=0000 Reg=0010:0000:0000:0000:0000:0000:0000:0000 (t=10)
0009: BOR B, A
PC=000a SP=ffff O=0000 Reg=0010:0010:0000:0000:0000:0000:0000:0000 (t=11)
000a: SET I, 10
PC=000b SP=ffff O=0000 Reg=0010:0010:0000:0000:0000:0000:000a:0000 (t=12)
000b: SET A, 0x2000
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:000a:0000 (t=14)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:000a:0000 (t=16)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0009:0000 (t=18)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0009:0000 (t=19)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0009:0000 (t=21)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0009:0000 (t=23)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0008:0000 (t=25)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0008:0000 (t=26)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0008:0000 (t=28)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0008:0000 (t=30)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0007:0000 (t=32)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0007:0000 (t=33)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0007:0000 (t=35)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0007:0000 (t=37)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0006:0000 (t=39)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0006:0000 (t=40)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0006:0000 (t=42)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0006:0000 (t=44)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0005:0000 (t=46)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0005:0000 (t=47)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0005:0000 (t=49)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0005:0000 (t=51)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0004:0000 (t=53)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0004:0000 (t=54)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0004:0000 (t=56)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0004:0000 (t=58)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0003:0000 (t=60)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0003:0000 (t=61)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0003:0000 (t=63)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0003:0000 (t=65)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0002:0000 (t=67)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0002:0000 (t=68)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0002:0000 (t=70)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0002:0000 (t=72)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0001:0000 (t=74)
0010: IFN I, 0
PC=0011 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0001:0000 (t=75)
0011: SET PC, 0xd
PC=000d SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0001:0000 (t=77)
000d: SET [I+8192], [A]
PC=000f SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0001:0000 (t=79)
000f: SUB I, 1
PC=0010 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0000:0000 (t=81)
0010: IFN I, 0
PC=0012 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0000:0000 (t=83)
0012: IFN A, A
PC=0014 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0000:0000 (t=85)
0014: JSR 0x18
PC=0018 SP=fffe O=0000 Reg=2000:0010:0000:0000:0000:0000:0000:0000 (t=88)
0018: SHL X, 4
PC=0019 SP=fffe O=0000 Reg=2000:0010:0000:0000:0000:0000:0000:0000 (t=90)
0019: SET PC, [SP++]
PC=0015 SP=ffff O=0000 Reg=2000:0010:0000:0000:0000:0000:0000:0000 (t=91)
0015: SHR B, A
PC=0016 SP=ffff O=0000 Reg=2000:0000:0000:0000:0000:0000:0000:0000 (t=93)
0016: SET PC, 0x1a
PC=001a SP=ffff O=0000 Reg=2000:0000:0000:0000:0000:0000:0000:0000 (t=95)
001a: SET PC, 0x1a
PC=001a SP=ffff O=0000 Reg=2000:0000:0000:0000:0000:0000:0000:0000 (t=97)
001a: SET PC, 0x1a
PC=001a SP=ffff O=0000 Reg=2000:0000:0000:0000:0000:0000:0000:0000 (t=99)
001a: SET PC, 0x1a


Create a new paste based on this one


Comments: