using System; public class RAM { public byte[] memory = new byte[256]; } public class CPU { // ALU OPERATIONS public byte ExecuteADD(byte regA, byte regB) { byte result = (byte)(regA + regB); if (result < regA) { flagRegister |= (byte)flags.carry; Console.WriteLine("Carry flag set on"); } else { flagRegister &= (byte)~flags.carry; } return result; } public void ExecuteSHL(byte regA, byte regB) { register[regB] = (byte)(register[regA] << 1); Console.WriteLine($"SHL Result: {register[regB]}"); } public void ExecuteSHR(byte regA, byte regB) { register[regB] = (byte)(register[regA] >> 1); Console.WriteLine($"SHR Result: {register[regB]}"); } public void ExecuteNOT(byte regA, byte regB) { register[regB] = (byte)(~regA); Console.WriteLine($"NOT Result: {register[regB]}"); } public void ExecuteAND(byte regA, byte regB) { register[regB] = (byte)(regA & regB); Console.WriteLine($"AND Result: {register[regB]}"); } public void ExecuteOR(byte regA, byte regB) { register[regB] = (byte)(regA | regB); Console.WriteLine($"OR Result: {register[regB]}"); } public void ExecuteXOR(byte regA, byte regB) { register[regB] = (byte)(regA ^ regB); Console.WriteLine($"XOR Result: {register[regB]}"); } public void ExecuteCMP(byte regA, byte regB) { flagRegister = 0; if (register[regA] > register[regB]) { flagRegister = (byte)(flagRegister | (byte)flags.greaterThan); Console.WriteLine("greaterThan flag set on"); } else if (register[regA] == register[regB]) { flagRegister = (byte)(flagRegister | (byte)flags.equal); Console.WriteLine("equal flag set on"); } else if (register[regA] < register[regB]) { flagRegister = (byte)(flagRegister | (byte)flags.zero); Console.WriteLine("zero flag set on"); } } //OTHER INSTRUCTIONS public void ExecuteLD(RAM ram, byte regA, byte regB) { register[regB] = ram.memory[register[regA]]; } public void ExecuteST(RAM ram, byte regA, byte regB) { ram.memory[register[regA]] = register[regB]; } public void ExecuteDATA(RAM ram, byte IR) { byte regB = (byte)(IR & 0b00000011); IAR++; byte data = ram.memory[IAR]; register[regB] = data; Console.WriteLine($"Loaded {data} into register {regB}."); } public void ExecuteJMPR(byte regB) { IAR = register[regB]; } public void ExecuteJMP(RAM ram, byte IR) { byte regB = (byte)(IR & 0b00000011); IAR++; IAR = ram.memory[regB]; Console.WriteLine($"Jumping to address: {IAR}"); } public void ExecuteJMPIF(byte flagBits, byte targetAddress) { flagRegister = flagBits; bool conditionMet = false; if ((flagBits & 0b1000) != 0 && (flagRegister & (byte)flags.carry) != 0) conditionMet = true; if ((flagBits & 0b0100) != 0 && (flagRegister & (byte)flags.greaterThan) != 0) conditionMet = true; if ((flagBits & 0b0010) != 0 && (flagRegister & (byte)flags.equal) != 0) conditionMet = true; if ((flagBits & 0b0001) != 0 && (flagRegister & (byte)flags.zero) != 0) conditionMet = true; if (conditionMet) { IAR = (byte)(targetAddress - 1); // -1 because the main loop will increment it after Console.WriteLine($"Condition met. Jumping to {targetAddress}"); } else { Console.WriteLine("Condition not met, no jump."); } } public void ExecuteCLF() { flagRegister = 0; } public void ExecuteHALT() { running = false; } public byte[] register = new byte[4]; public byte IAR; public byte IR; public byte MAR; public byte flagRegister; public enum flags : byte { carry = 0b1000, greaterThan = 0b0100, equal = 0b0010, zero = 0b0001 } public enum aluOp : byte { ADD = 0b000, SHL = 0b001, SHR = 0b010, NOT = 0b011, AND = 0b100, OR = 0b101, XOR = 0b110, CMP = 0b111 } public enum instructions : byte { LD = 0b000, ST = 0b001, DATA = 0b010, JMPR = 0b011, JMP = 0b100, JMPIF = 0b101, CLF = 0b110, HALT = 0b111 } bool running = true; public void Run(RAM ram) { while(running) { IR = ram.memory[IAR]; bool isALU = (IR & 0b10000000) != 0; if (isALU) { byte aluOperation = (byte)((IR >> 4) & 0b00000111); byte regA = (byte)((IR >> 2) & 0b00000011); byte regB = (byte)(IR & 0b00000011); switch ((aluOp)aluOperation) { case aluOp.ADD: register[regB] = ExecuteADD(register[regA], register[regB]); Console.WriteLine($"ADD Result: {register[regB]}"); break; case aluOp.SHL: ExecuteSHL(regA, regB); break; case aluOp.SHR: ExecuteSHR(regA, regB); break; case aluOp.NOT: ExecuteNOT(regA, regB); break; case aluOp.AND: ExecuteAND(regA, regB); break; case aluOp.OR: ExecuteOR(regA, regB); break; case aluOp.XOR: ExecuteXOR(regA, regB); break; case aluOp.CMP: ExecuteCMP(regA, regB); break; } } else { byte instr = (byte)((IR >> 4) & 0b00000111); byte regA = (byte)((IR >> 2) & 0b00000011); byte regB = (byte)(IR & 0b00000011); switch ((instructions)instr) { case instructions.LD: ExecuteLD(ram, regA, regB); Console.WriteLine($"LD Result: {register[regB]}"); break; case instructions.ST: ExecuteST(ram, regA, regB); Console.WriteLine($"ST Result: {ram.memory[regA]}"); break; case instructions.DATA: ExecuteDATA(ram, IR); break; case instructions.JMPR: ExecuteJMPR(regB); Console.WriteLine($"Jumped to adress: {regB}"); break; case instructions.JMP: ExecuteJMP(ram, IR); break; case instructions.JMPIF: byte flagBits = (byte)(IR & 0b00001111); // Extract the 4 flag bits byte targetAddress = ram.memory[++IAR]; // Fetch the next byte as the address ExecuteJMPIF(flagBits, targetAddress); break; case instructions.CLF: ExecuteCLF(); Console.WriteLine("Flags cleared"); break; case instructions.HALT: ExecuteHALT(); Console.WriteLine("CPU Halted"); break; } } IAR++; } } } public class SimulateComputer { public static void Main(string[] args) { RAM ram = new RAM(); CPU cpu = new CPU(); ram.memory[0] = 0b00100000; ram.memory[1] = 35; ram.memory[2] = 0b00100001; ram.memory[3] = 13; ram.memory[4] = 0b10000001; ram.memory[5] = 0b01110000; cpu.Run(ram); } }
Write, Run & Share C# code online using OneCompiler's C# online compiler for free. It's one of the robust, feature-rich online compilers for C# language, running on the latest version 8.0. Getting started with the OneCompiler's C# compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C#
and start coding.
OneCompiler's C# online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
using System;
namespace Sample
{
class Test
{
public static void Main(string[] args)
{
string name;
name = Console.ReadLine();
Console.WriteLine("Hello {0} ", name);
}
}
}
C# is a general purpose object-oriented programming language by Microsoft. Though initially it was developed as part of .net but later it was approved by ECMA and ISO standards.
You can use C# to create variety of applications, like web, windows, mobile, console applications and much more using Visual studio.
Data Type | Description | Range | size |
---|---|---|---|
int | To store integers | -2,147,483,648 to 2,147,483,647 | 4 bytes |
double | to store large floating point numbers with decimals | can store 15 decimal digits | 8 bytes |
float | to store floating point numbers with decimals | can store upto 7 decimal digits | 4 bytes |
char | to store single characters | - | 2 bytes |
string | to stores text | - | 2 bytes per character |
bool | to stores either true or false | - | 1 bit |
datatype variable-name = value;
When ever you want to perform a set of operations based on a condition or set of few conditions IF-ELSE is used.
if(conditional-expression) {
// code
}
else {
// code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression) {
case value1:
// code
break; // optional
case value2:
// code
break; // optional
...
default:
// code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement) {
// code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while(condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.
data-type[] array-name;
Method is a set of statements which gets executed only when they are called. Call the method name in the main function to execute the method.
static void method-name()
{
// code to be executed
}