ref: f1addc2feef11d34311a9baa77ea0bda2bdf928b
parent: 8e9d7d65c2d1374e5676f63e23bed794f1c00e45
author: mkf <mkf@cloud9p.org>
date: Wed Jul 3 08:03:44 EDT 2024
5552e: import
--- /dev/null
+++ b/5552e.c
@@ -1,0 +1,421 @@
+/* 5552 cpu emulator */
+#include "5552.h"
+
+struct mach
+{
+ word reg[REGS];
+
+
+ /* both are nibbles currently, but for convience */
+ word op;
+ word mode;
+
+ word arg1;
+ word arg2;
+
+ byte mem[MMAX];
+};
+
+/*
+int
+btoi(int b[], int len)
+{
+ char arr[10];
+ int res = 0, i = 0, j = len;
+ while (i <= len)
+ {
+ arr[i] = b[j] ? '1' : '0';
+ i++;
+ j--;
+ }
+ sscanf(arr, "%d", &res);
+ return res;
+}
+*/
+int
+mach_drd(word dev, word src, word dst)
+{
+ switch(dev)
+ {
+ case REG:
+ regs[dst] = regs[src];
+ break;
+ case MEM:
+ regs[dst] = mem[src];
+ break;
+ case GPIO:
+ switch(src)
+ {
+ case SERIAL:
+ read(0, regs+dst, sizeof(Word));
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+int
+mach_dwr(word dev, word src, word dst)
+{
+ switch(dev)
+ {
+ case REG:
+ regs[src] = regs[dst];
+ break;
+ case MEM:
+ regs[src] = mem[dst];
+ break;
+ case GPIO:
+ switch(dst)
+ {
+ case SERIAL:
+ write(0, regs+src, sizeof(Word));
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+int
+mach_dwr(word dev, word src, word dst)
+{
+ switch(dev)
+ {
+ case REG:
+ regs[src] = regs[dst];
+ break;
+ case MEM:
+ regs[src] = mem[dst];
+ break;
+ case GPIO:
+ switch(dst)
+ {
+ case SERIAL:
+ write(0, regs+src, sizeof(Word));
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+int
+mach_not(word mode, word arg1, word arg2)
+{
+ switch(mode)
+ {
+ case REG:
+ regs[RES] = ~regs[arg1];
+ break;
+ case INLINE:
+ regs[RES] = ~((arg1 << (sizeof Word) * 8) & arg2);
+ break;
+ case DIRECT:
+ default:
+ break;
+ }
+}
+
+int
+mach_and(Word mode, Word arg1, Word arg2)
+{
+ switch(mode)
+ {
+ case REG:
+ regs[RES] = regs[arg1] & regs[arg2];
+ break;
+ case INLINE:
+ regs[RES] = arg1 & arg2;
+ break;
+ case DIRECT:
+ regs[RES] = regs[arg1] & arg2;
+ break;
+ default:
+ break;
+ }
+}
+
+int
+mach_nor(Word mode, Word arg1, Word arg2)
+{
+ switch(mode)
+ {
+ case REG:
+ regs[RES] = !(regs[arg1] | regs[arg2]);
+ break;
+ case INLINE:
+ regs[RES] = !(arg1 | arg2);
+ break;
+ case DIRECT:
+ regs[RES] = !(regs[arg1] & arg2);
+ break;
+ default:
+ break;
+ }
+}
+
+int
+mach_xor(Word mode, Word arg1, Word arg2)
+{
+ switch(mode)
+ {
+ case REG:
+ regs[RES] = regs[arg1] ^ regs[arg2];
+ break;
+ case INLINE:
+ regs[RES] = arg1 ^ arg2;
+ break;
+ case DIRECT:
+ regs[RES] = regs[arg1] ^ arg2;
+ break;
+ default:
+ break;
+ }
+}
+
+int
+mach_add(Word mode, Word arg1, Word arg2)
+{
+ int result;
+
+ switch(mode)
+ {
+ case REG:
+ result = (int)regs[arg1] + (int)regs[arg2];
+ break;
+ case INLINE:
+ result = (int)arg1 + (int)arg2;
+ break;
+ case DIRECT:
+ result = (int)regs[arg1] + (int)arg2;
+ break;
+ default:
+ break;
+ }
+ if(intsize(result) > sizeof Word)
+ regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
+ regs[RES] = (Word)result;
+}
+
+int
+mach_sub(Word mode, Word arg1, Word arg2)
+{
+ int result;
+
+ switch(mode)
+ {
+ case REG:
+ result = (int)regs[arg1] - (int)regs[arg2];
+ break;
+ case INLINE:
+ result = (int)arg1 - (int)arg2;
+ break;
+ case DIRECT:
+ result = (int)regs[arg1] - (int)arg2;
+ break;
+ default:
+ break;
+ }
+ if(intsize(result) > sizeof Word * 8)
+ regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
+ regs[RES] = (Word)result;
+}
+
+int
+mach_mul(Word mode, Word arg1, Word arg2)
+{
+ int result;
+
+ switch(mode)
+ {
+ case REG:
+ result = (int)regs[arg1] * (int)regs[arg2];
+ break;
+ case INLINE:
+ result = (int)arg1 * (int)arg2;
+ break;
+ case DIRECT:
+ result = (int)regs[arg1] * (int)arg2;
+ break;
+ default:
+ break;
+ }
+ if(intsize(result) > sizeof Word * 8)
+ regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
+ regs[RES] = (Word)result;
+}
+
+int
+mach_div(Word mode, Word arg1, Word arg2)
+{
+ int result;
+
+ switch(mode)
+ {
+ case REG:
+ result = (int)regs[arg1] / (int)regs[arg2];
+ break;
+ case INLINE:
+ result = (int)arg1 / (int)arg2;
+ break;
+ case DIRECT:
+ result = (int)regs[arg1] / (int)arg2;
+ break;
+ default:
+ break;
+ }
+ regs[RES] = (Word)result;
+}
+
+int
+mach_mul(Word mode, Word arg1, Word arg2)
+{
+ int result;
+
+ switch(mode)
+ {
+ case REG:
+ result = (int)regs[arg1] * (int)regs[arg2];
+ break;
+ case INLINE:
+ result = (int)arg1 * (int)arg2;
+ break;
+ case DIRECT:
+ result = (int)regs[arg1] * (int)arg2;
+ break;
+ default:
+ break;
+ }
+ if(intsize(result) > sizeof Word * 8)
+ regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
+ regs[RES] = (Word)result;
+}
+
+void
+main(void)
+{
+ char *input;
+ void *buf;
+ int arg, prev;
+
+ input = malloc(OPLEN);
+ if(input < 0)
+ panic("Not enough memory\n");
+
+ mach.reg[STATE] = ON;
+
+ while(mach.state == ON)
+ {
+ if(read(1, buf, 3) < 3)
+ {
+ panic("EOF?\n");
+ }
+
+ mach.op = buf[0] >> 4;
+ mach.mode = buf[0] & (1 << 4) - 1;
+ mach.arg1 = buf[1];
+ mach.arg2 = buf[2];
+
+ for(int i = 0; i < sizeof(optab) ; i++)
+ {
+ if(mach.op == operators[i].op)
+ {
+ operators[i].exec(mach.mode, mach.arg1, mach.arg2);
+ break;
+ }
+
+ }
+ }
+}
+
+int
+main(void)
+{
+ char string[16];
+ r.flags[ON] = 1;
+ r.flags[NSIGN] = false;
+ unsigned int op, a, b, c, ind = 0;
+ bool barr[10];
+
+ /* there is no space between op and args
+ since some can have no args */
+ while(r.flags[ON] && scanf("%u %[^\n]", &op, string))
+ {
+ sscanf(string, "%u %u %u", &a, &b, &c);
+ switch(op)
+ {
+ case DIE:
+ r.flags[ON] = 0;
+ break;
+ case OUT:
+ /* just in case output is "manfi" */
+ if(r.flags[NSIGN])
+ printf("-%u\n", r.regs[a]);
+ else
+ printf("%u\n", r.regs[a]);
+ break;
+ case NOT:
+ r.regs[b] = !a;
+ break;
+ case AND:
+ r.regs[c] = a & b;
+ break;
+ case NOR:
+ r.regs[c] = !(a | b);
+ break;
+ case XOR:
+ r.regs[c] = a ^ b;
+ break;
+ case SUB:
+ b = ~b;
+ r.regs[CARRY] = 1;
+ r.flags[NSIGN] = (a < b);
+ r.regs[c] = r.flags[NSIGN] ? b - a : a - b;
+ case ADD:
+ r.flags[NSIGN] = false;
+ r.regs[c] = a + b;
+ break;
+ r.flags[NSIGN] = false;
+ r.regs[b] = a + 1;
+ break;
+ case DEC:
+ r.regs[b] = a - 1;
+ r.flags[NSIGN] = (r.regs[b] < 0);
+ break;
+ case SHR:
+ r.regs[c] = a >> b;
+ break;
+ case SHL:
+ r.regs[c] = a << b;
+ break;
+ case PUT:
+ memory[b] = a;
+ case MOV:
+ memory[b] = r.regs[a];
+ break;
+ case LDM:
+ r.regs[b] = memory[a];
+ break;
+ case NTH:
+ r.regs[c] = a >> b;
+ break;
+ default:
+ fprintf(stderr, "unknown op\n");
+ return 1;
+ }
+ /* clear them */
+ a = 0;
+ b = 0;
+ op = 0;
+ string[0] = '\0';
+ }
+ return 0;
+}