wm: 5551

Download patch

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;
 }