ref: a7be9c155a2bd5fae1b795c69695e3448d1778e9
parent: eb8d04c749099a24090a693f7b8226b66fffc630
author: mkf <mkf@d510>
date: Fri May 5 13:28:43 EDT 2023
add new instructions, fix a lots of problems, etc etc remove SET, it's useless. fix registers (thanks jm!), fix DIE, make proper memory handling(?) fix sub
--- a/5551a.c
+++ b/5551a.c
@@ -1,49 +1,97 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
-#include <fcntl.h>
+/* ops */
enum
{
- NOT = 1,
+ DIE, /* drop dead */
+ OUT,
+ NOT,
AND,
+ NOR,
XOR,
+ SUB,
ADD,
- RST, /* reset the machine state */
- CPY, /* copy stuff from a reg or addr to another */
- SET, /* sets mode to bool and int */
- OUT
+ SHR,
+ SHL,
+ PUT, /* stores something in memory */
+ MOV, /* move stuff from a reg to memory */
+ CPY, /* copy from a memory address to another */
+ LDM, /* load from memory into register */
+ NTH, /* returns the Nth bit */
};
-void main(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- unsigned int a, b;
- char string[16], *op;
- FILE *fd = open("5551.out", O_WRONLY);
- if(fd < 0)
+ unsigned int inst, a, b, c;
+ char string[32], *op;
+ while(scanf("%s %[^\n;]%*c", op, string) > 0)
{
- fprintf(stderr, "unable to open file\n");
- return;
- }
- while(scanf("%s %[^\n]", op, string) > 0) /* %s removes spaces, what did i expected? */
- {
- sscanf(string, "%u %u", &a, &b);
+ sscanf(string, " %u %u %u", &a, &b, &c);
+ if(!strcmp(op, "DIE"))
+ inst = DIE;
+ if(!strcmp(op, "OUT"))
+ inst = OUT;
if(!strcmp(op, "NOT"))
- printf("%u %u\n", NOT, a);
+ inst = NOT;
if(!strcmp(op, "AND"))
- printf("%u %u %u\n", AND, a, b);
+ inst = AND;
+ if(!strcmp(op, "NOR"))
+ inst = NOR;
if(!strcmp(op, "XOR"))
- printf("%u %u %u\n", XOR, a, b);
-// if(!strcmp(op, "RST"))
- // reset():
- if(!strcmp(op, "CPY"))
- printf("%u %u %u\n", CPY, a, b);
- if(!strcmp(op, "SET"))
- printf("%u %u\n", SET, a);
- if(!strcmp(op, "OUT"))
- printf("%u %u\n", OUT, a);
- if(!strcmp(op, "DIE"))
- return;
+ inst = XOR;
+ if(!strcmp(op, "SUB"))
+ inst = SUB;
+ if(!strcmp(op, "ADD"))
+ inst = ADD;
+ if(!strcmp(op, "SHR"))
+ inst = SHR;
+ if(!strcmp(op, "SHL"))
+ inst = SHL;
+ if(!strcmp(op, "PUT"))
+ inst = PUT;
+ if(!strcmp(op, "MOV"))
+ inst = MOV;
+ if(!strcmp(op, "LDM"))
+ inst = LDM;
+ if(!strcmp(op, "NTH"))
+ inst = NTH;
}
- return;
+ switch(inst)
+ {
+ /* no args */
+ case DIE:
+ printf("%u\n", inst);
+ break;
+ /* one arg */
+ case NOT:
+ case OUT:
+ printf("%u %u\n", inst, a);
+ break;
+ /* two args */
+ case PUT:
+ case MOV:
+ case LDM:
+ printf("%u %u %u\n", inst, a, b);
+ break;
+ /* three args */
+ case AND:
+ case NOR:
+ case XOR:
+ case SUB:
+ case SHL:
+ case SHR:
+ case ADD:
+ case NTH:
+ printf("%u %u %u %u\n", inst, a, b, c);
+ break;
+ /* should this ever happen? */
+ default:
+ {
+ fprintf(stderr, "unkown instr.\n");
+ return -1;
+ }
+ }
+ return 0;
}
--- a/5551e.c
+++ b/5551e.c
@@ -1,94 +1,98 @@
+/* 5551 cpu emulator */
+
#include <stdbool.h>
#include <stdio.h>
-#define MMAX ( 1 << 8 )
-unsigned int reg[8];
+#include "5551.h"
+
typedef struct
{
- bool carry, overflow, nsign, sub, parity;
- bool mode; /* 0 bool, 1 int */
-}flag_t;
+ bool flags[8];
+ int regs[8];
+}reg_t;
-enum
+bool add_bit(bool a, bool b, bool &carry)
{
- /* logical num */
- NOT = 1,
- AND,
- XOR,
- ADD,
- RST, /* reset the machine state */
- CPY, /* copy stuff from a reg or addr to another */
- SET,
- OUT,
-
-};
-
-bool add_bit(bool a, bool b, bool cin, bool *cout)
-{
- bool out, temp;
+ bool out, temp, tcarry = carry;
temp = a & b;
- out = ((a ^ b) | (temp & cin));
+ out = ((a ^ b) | (temp & tcarry));
temp = a ^ b;
- cout = ((a & b) | (temp & cin));
+ carry = ((a & b) | (temp & tcarry));
return temp;
}
-/*
-bool* add_int(bool* a, bool* b)
+
+int main()
{
- bool cout, t[;
- while(i > 8)
- {
- t *= 2;
- }
-}
-*/
-void main()
-{
- flag_t flags;
+
+ reg_t r;
+ unsigned int memory[MMAX];
+ memory[MMAX-1] = -1;
+
char string[16];
- unsigned int memory[MMAX], op, a, b, def = 0;
- memory[0] = 0;
- memory[MMAX-1] = -1;
- while(scanf("%u %[^\n]", &op, string))
+
+ unsigned int op, a, b, c;
+
+ /* there is no space between op and args
+ since some can have no args */
+ while(scanf(r.flags[ON] && "%u%[^\n]", &op, string))
{
- sscanf(string, "%u %u", &a, &b);
+
+ sscanf(string, " %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.reg[a]);
+ else
+ printf("%u\n" r.reg[a]);
+ break;
case NOT:
- reg[def] = !a;
+ r.reg[b] = !a;
break;
case AND:
- reg[def] = a & b;
+ r.reg[c] = a & b;
break;
+ case NOR:
+ r.reg[c] = !(a | b)
case XOR:
- reg[def] = a ^ b;
+ r.reg[c] = a ^ b;
break;
+ case SUB:
+ b = ~b;
+ r.carry = 1;
case ADD:
- reg[def] = add_bit(a, b, 0, &flags.carry);
+ r.reg[c] = add_bit(a, b, &r.flags[carry]);
break;
- case RST:
- // reset():
+ case SHR:
+ r.reg[c] = reg[a] >> b;
break;
- case CPY:
- reg[b] = reg[a];
+ case SHL:
+ r.reg[c] = reg[a] << b;
break;
- case SET:
- if((a < 0) || (a > 8))
- {
- fprintf(stderr, "out of regs\n");
- return;
- }
- def = a;
+ case PUT:
+ memory[b] = a;
+ case MOV:
+ memory[b] = reg[a];
break;
- case OUT:
- printf("%u\n", reg[a]);
+ case LDM:
+ r.reg[b] = memory[a];
break;
+ case NTH:
+ r.reg[c] = a >> n;
+ break;
default:
fprintf(stderr, "unkown op\n");
- return;
+ return 1;
}
/* clear them */
- // a = NULL, b = NULL, op = NULL;
- // string = "\0";
+ a = 0
+ b = 0
+ op = 0;
+ string = "";
}
+ return 0;
}