A simulation of the way a processor loads and executes instructions from main memory. The program uses forking to divide the program into two processes, which self-identify based on their process ID. One process becomes Main Memory, and reads in machine code instructions from a text file, provided as a command-line argument, and stores them in memory. The other process becomes the Central Processing Unit and, through the use of two one-way pipes established between the processes, reads in instructions from memory and executes the machine code instructions.
##How to Run This program was designed to run in a UNIX environment. To run it in such an environment, move ProcessorSimulation.cpp, as well as any files of programs you want to run in the simulation, into a directory, then compile.
The program accepts two command-line arguments, the name of the text file containing the machine code to be performed, and the number of instructions that should be executed between each timer-driven interrupt (see below).
##General Procedure The initial steps of the program are to establish two pipes, representing lines of communication between the CPU and main memory (in a real system, these lines of communication would probably be a binary circuit). Then, a fork instruction copies the process, and the two processes self-distinguish into main memory and a CPU.
Memory begins by opening up the file and reading each line, storing it in a 2000 integer array, which represents a 2000 word storage device. 1000 words of memory are reserved for user code, and another 1000 are reserved for system code. User instructions begin from 0 and go up, and the user stack goes from 999 and goes down. System instructions begin at 1000 and go up, and the system stack goes from 1999 and goes down.
The system operates in two modes: user mode (the default) and system mode, which the system enters upon interrupts. Interrupts in this system simply happen on a timer, set through the second system argument.
Normal operation involves the CPU making a request for the next instruction, with "next" defined by the number given at the program counter register. Memory retrieves the memory word (int, in this case) requested and sends it to the CPU. Some instructions also demand an argument saved immediately after the instruction in memory, in which case another memory read is performed. Then, the CPU executes the instruction, writing to the registers and memory as needed.
There are 6 registers in this simulation: a Program Counter (denoting the next instruction in memory to read), the Stack Pointer (pointing to the top of the stack), the Instruction Register (which contains the instruction to be performed by the CPU), and 3 registers for the point of arithmatic, called the Accumulator, X, and Y.
When an interrupt occurs, the CPU enters system mode, and the stack pointer is switched to the top of the system stack. The user stack pointer, as well as the program counter, are pushed onto the system stack. The instructions in system memory are performed, and then, once those are complete, the stack pointer and program counter are restored, and the system returns to user mode.
##Machine Code Instruction Set 1 = Load value given in the next memory word into the Accumulator
2 = Load the value in the address given in the next memory word into the Accumulator
3 = Read an address from the address given in the next memory word, then read the value at that address (that is, if the next memory word is 200, and address 200 holds the value 50, the accumulator will be filled with the value at memory location 50)
4 = Load the value at (address + X) into the AC
5 = Load the value at (address + Y) into the AC
6 = Load the value at (SP + X) into the AC
7 = Store the value of the AC into the given address
8 = Get a random number 1-100, and store it into the AC
9 = If the argument is 1, write AC as an integer to the screen. If the argument is 2, write the AC as a character to the screen.
10 = Add the value of X to the AC
11 = Add the value of Y to the AC
12 = Subtract the value of X from the AC
13 = Subtrack the value of Y from the AC
14 = Copy the value in the AC to X
15 = Copy the value in X to the AC
16 = Copy the value in the AC to Y
17 = Copy the value in Y to the AC
18 = Copy the value in AC to the SP
19 = Copy the value in SP to the AC
20 = Jump the PC to the given address
21 = Jump the PC to the given address if the AC contains a 0
22 = Jump the PC to the given address if the AC doesn't contain a 0
23 = Push the return address onto the stack, then jump to the given address
24 = Pop a return address from the stack, then jump to that location
25 = Increment the value of X
26 = Decrement the value of X
27 = Push the value of AC onto the stack
28 = Pop the value of the AC, and save in the AC
29 = Manually perform a system interrupt
30 = Return to user code from an interrupt
50 = End
##Credit Original assignment, as well as the machine code instruction set, given by Greg Ozbirn.