<repo_name>robertwestman/CPU-Mem<file_sep>/README.md
# CPU-Mem
A Java program that simulates the interactions between CPU and memory
<file_sep>/CPU.java
import java.io.*;

import java.util.*;



public class CPU {



	//registers

	private int PC = 0;

	private int SP = 999;

	private int IR = 0;

	private int AC = 0;

	private int X = 0;

	private int Y = 0;



	//input + output readers

	private BufferedWriter out;

	private BufferedReader in;



	//list of instructions with an operand

	private int instructionsWithOperand[] = {1,2,3,4,5,7,9,20,21,22,23};



	//Designated user memory

	final int USER_MEMORY = 1000;



	//mode

	private boolean kernalMode = false;



	//exit fetching instructions

	private boolean exit = false;



	//runtime + processes

	private static Runtime runtime;

	private static Process memory;

	private static CPU cpu;



	public static void main(String[] args) throws IOException, InterruptedException{

		try {

			runtime = Runtime.getRuntime();

			memory = runtime.exec("java Memory " + args[0]);

			cpu = new CPU(memory.getInputStream(), memory.getOutputStream());

			cpu.run();



			memory.waitFor();

			int exitVal = memory.exitValue();

			

			System.out.println("\nProcess exited: " + exitVal);

			System.exit(0);

			

		} catch (Throwable t) {

			t.printStackTrace();

		}

	}



	//constructor that sets up streams

	public CPU(InputStream input, OutputStream output) {

		this.in = new BufferedReader(new InputStreamReader(input));

		this.out = new BufferedWriter(new OutputStreamWriter(output));		

	}



	public void run() throws IOException {

		while(!exit) {

			fetch();

			this.PC++;

		}



		//close streams

		out.close();

		in.close();

	}



	//fetch instruction

	public void fetch() throws IOException {

		boolean operand = false;

		this.IR = read(PC);

		for(int i = 0; i < instructionsWithOperand.length; i++) {

			if(this.IR == instructionsWithOperand[i]) {

				operand = true;

				break;

			}

		}

		if(operand) {

			this.PC++;

			instruction(this.IR, read(this.PC));

		} else {

			instruction(this.IR, 0);

		}

	}



	//execute instruction

	private void instruction(int instruction, int operand) throws IOException {

		switch (instruction) {

			case 1:

				this.AC = operand;

				break;

			case 2:

				this.AC = this.read(operand);

				break;

			case 3:

				this.AC = this.read(this.read(operand));

				break;

			case 4:

				this.AC = this.read(operand + this.X);

				break;

			case 5:

				this.AC = this.read(operand + this.Y);

				break;

			case 6:

				this.AC = this.read(this.SP + this.X);

				break;

			case 7:

				this.write(operand, this.AC);

				break;

			case 8:

				this.AC = 1 + (int) (Math.random()*100);

				break;

			case 9:

                if (operand == 1) {

                    System.out.print((int) this.AC);

                } else if (operand == 2) {

                    System.out.print((char) this.AC);

                }

                break;

			case 10:

				this.AC += this.X;

				break;

			case 11:

				this.AC += this.Y;

				break;

			case 12:

				this.AC -= this.X;

				break;

			case 13:

				this.AC -= this.Y;

				break;

			case 14:

				this.X = this.AC;

				break;

			case 15:

				this.AC = this.X;

				break;

			case 16:

				this.Y = this.AC;

				break;

			case 17:

				this.AC = this.Y;

				break;

			case 18:

				this.SP = this.AC;

				break;

			case 19:

				this.AC = this.SP;

				break;

			case 20:

				this.PC = operand - 1;

				break;

			case 21:

				if(this.AC == 0) {

					this.PC = operand - 1;

				}

				break;

			case 22:

				if(this.AC != 0) {

					this.PC = operand - 1;

				}

				break;

			case 23:

				this.write(this.SP, this.PC);

				this.SP--;

				this.PC = operand - 1;

				break;

			case 24:

				this.SP++;

				this.PC = this.read(SP) - 1;

				break;

			case 25:

				this.X++;

				break;

			case 26:

				this.X--;

				break;

			case 27:

				this.write(this.SP, this.AC);

				this.SP--;

				break;

			case 28:

				this.SP++;

				this.AC = this.read(SP);

				break;

			case 50:

				exit = true;

				break;

			default:

				System.out.println("\nError: instruction " + instruction + " does not exist");

				break;

		}

	}



	protected int read(int address) throws IOException {

		out.write(String.format("%d\n", address));

		out.flush();

		String value = in.readLine();

		return Integer.parseInt(value);

	}



	protected void write(int address, int value) throws IOException {

		out.write(String.format("%d %d\n", address, value));

		out.flush();

	}

}
