
/* Implementation file for emulator
	by Jason Plumb */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "emulator.h"

/* Global vars */
char data[DATASIZE];
char prog[PROGSIZE];
int p[s];
int reg[8];
int i, max, pc, sign;


int main(int argc, char *argv[]){

	int n, i;

//	assign(data, 'data');
//	reset(data);
	
	sign = 0;
	intake(n);
	for(i=0;i<n;i++){
		printf("%d   %d\n", i, p[i]);
	}//for

	pc = -1;
	while(p[pc+1] != max){
		printf("%5d %5d %5d %5d %5d %5d\n", p[pc+1], opcode(pc+1), rop1(pc+1),
											rop2(pc+1), mop(pc+1), mop1(pc+1));
		printf("pc=%d sign=%d\n", pc+1, sign);
		for(i=0;i<3;i++){
			printf("reg%d=%d\n", i, reg[i]);
		}//for

		pc++;

		if((opcode(pc) >= 0) && (opcode(pc) <= 15)){
			switch(opcode(pc)){
			case 0:
				load(pc);
				break;
			case 1:
				store(pc);
				break;
			case 2:
				sub(pc);
				break;
			case 3:
				add(pc);
				break;
			case 4:
				dv(pc);
				break;
			case 5:
				mul(pc);
				break;
			case 6:
				beq(pc);
				break;
			case 7:
				bgt(pc);
				break;
			case 8:
				blt(pc);
				break;
			case 9:
				bne(pc);
				break;
			case 10:
				comp(pc);
				break;
			case 11:
				ini(pc);
				break;
			case 12:
				oc(pc);
				break;
			case 13:
				oi(pc);
				break;
			case 14:
				newline(pc);
				break;
			case 15:
				b(pc);
				break;
			}//switch
		}//if
		else{
			printf("Error: Invalid opcode at pc = %d\n", pc);
		}

	}//while



	return 1;
}//main

void intake(int &n){
	n = -1;


	


}//intake

int opcode(int i){
	return abs(p[i] / 2048);
}//opcode

int rop1(int i){
	int opcodet = opcode(i);
	return (p[i] - (opcodet*2048)) / 256;
}//rop1

int rop2(int i){
	int opcodet = opcode(i);
	int rop1t = (p[i] - (opcodet*2048))/256;
	return (p[i] - (opcodet*2048) - (rop1t*256))/32;
}//rop2

int mop1(int i){
	int opcodet = opcode(i);
	return p[i] - (opcodet * 2048);
}//mop2

int mop(int i){
	int opcodet = opcode(i);
	int ropt = (p[i] - (opcodet*2048))/256;
	return (p[i] - (ropt*256) - (opcodet*2048));
}//mop

void load(int pc){
	int r, m;
	bool indirect;

	indirect = false;
	if(p[pc] < 0){
		indirect = true;
		p[pc] = -1*p[pc];
	}//if

	r = rop1(pc);
	m = mop(pc) + reg[3];

	if(indirect)
		m = p[m];

	reg[r] = p[m];
}//load

void store(int pc){
	int r, m;
	bool indirect;

	if(p[pc] < 0){
		indirect = true;
		p[pc] = -1*p[pc];
	}

	r = rop1(pc);
	m = mop(pc) + reg[3];
	if(indirect)
		m = p[m];

	p[m] = reg[r];

}//store

void sub(int pc){

	int r1 = rop1(pc);
	int r2 = rop2(pc);

	reg[r1] = reg[r1] - reg[r2];

	if(reg[r1] < 0)
		sign = -1;
	else
		if(reg[r1] == 0)
			sign = 0;
		else
			sign = 1;

}//sub

void add(int pc){
	int r1 = rop1(pc);
	int r2 = rop2(pc);
	reg[r1] = reg[r1] + reg[r2];
}//add

void dv(int pc){
	int r1 = rop1(pc);
	int r2 = rop2(pc);
	reg[r1] = reg[r1] / reg[r2];
}//dv

void mul(int pc){
	int r1 = rop1(pc);
	int r2 = rop2(pc);
	reg[r1] = reg[r1] * reg[r2];
}//mul

void beq(int i){
	if(sign == 0)
		pc = mop1(i)-1;
}//beq

void bgt(int i){
	if(sign == 1)
		pc = mop1(i)-1;
}//bgt

void blt(int i){
	if(sign == -1)
		pc = mop1(i)-1;
}//blt

void bne(int i){
	if(sign != 0)
		pc = mop1(i)-1;
}//bne

void b(int i){
	pc = mop1(i)-1;
}//b

void ini(int pc){
	int r = rop1(pc);
//	read(data, reg[r]);
	memset(data, 0, DATASIZE);
	fgets(data, DATASIZE-1, stdin);
}//ini

void oc(int pc){
	int r = rop1(pc);
	printf("%c", reg[r]);
}//oc

void comp(int pc){
	int r = rop1(pc);
	reg[r] = -1*reg[r];
}//comp

void oi(int pc){
	int r = rop1(pc);
	printf("%d", reg[r]);
}//oi

void newline(int pc){
	if(p[pc] == 28672){
		memset(data, 0, DATASIZE);
		fgets(data, DATASIZE-1, stdin);
//		readln(data);
	}
	else
		printf("\n");
}//newline
