Last active
May 25, 2018 13:13
-
-
Save native-m/086207e9fb651079b1dd7f57c98867dd to your computer and use it in GitHub Desktop.
Simple CPU Emulator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| // Instruction | |
| /* | |
| NOP : No Operation | |
| LOADI dest, imm : Load immidiate to 'dest' register | |
| LOADA dest, addr : Load address to 'dest' register | |
| ADD dest, op1, op2 : Add 'op1' and 'op2' and save to 'dest' register | |
| SUB dest, op1, op2 : Subtract 'op1' and 'op2' and save to 'dest' register | |
| PRINT registers : Print registers | |
| */ | |
| // Sample program, add two numbers | |
| int program[] = { | |
| // Data | |
| 12, | |
| 13, | |
| // Main program | |
| 0x00000000, // NOP | |
| 0x00000002, // LOADA R0, 0x00 | |
| 0x00040102, // LOADA R1, 0x04 | |
| 0x01000203, // ADD R2, R0, R1 | |
| 0x00000205, // PRINT R2 | |
| }; | |
| // ------------ Registers ------------ | |
| int registers[32] = {0}; | |
| // ------------ Instruction implementation ------------ | |
| void nop(int code) | |
| { | |
| // No operation | |
| return; | |
| } | |
| void loadi(int code) | |
| { | |
| int dest = (code & 0x0000FF00) >> 8; | |
| int imm = (code & 0xFFFF0000) >> 16; | |
| registers[dest] = imm; | |
| return; | |
| } | |
| void loada(int code) | |
| { | |
| int dest = (code & 0x0000FF00) >> 8; | |
| int addr = (code & 0xFFFF0000) >> 16; | |
| void* memAddr = (void*)&program[0] + addr; | |
| registers[dest] = *(int*)memAddr; | |
| return; | |
| } | |
| void add(int code) | |
| { | |
| int dest = (code & 0x0000FF00) >> 8; | |
| int op1 = (code & 0x00FF0000) >> 16; | |
| int op2 = (code & 0xFF000000) >> 24; | |
| registers[dest] = registers[op1] + registers[op2]; | |
| return; | |
| } | |
| void sub(int code) | |
| { | |
| int dest = (code & 0x0000FF00) >> 8; | |
| int op1 = (code & 0x00FF0000) >> 16; | |
| int op2 = (code & 0xFF000000) >> 24; | |
| registers[dest] = registers[op1] + registers[op2]; | |
| return; | |
| } | |
| void print(int code) | |
| { | |
| int reg = (code & 0x0000FF00) >> 8; | |
| std::cout << registers[reg] << std::endl; | |
| return; | |
| } | |
| typedef void (*instr)(int); | |
| int main() | |
| { | |
| instr instrFun[6] = { | |
| &nop, | |
| &loadi, | |
| &loada, | |
| &add, | |
| &sub, | |
| }; | |
| int instrCount = (sizeof(program) / sizeof(int)); | |
| int startPoint = 2; // Start at index 2 of the program array (as seen in the program above) | |
| // Execute all instructions in the program | |
| for(int pc = startPoint; pc < instrCount; pc++) | |
| { | |
| // Decode the opcode | |
| int code = program[pc] & 0x000000FF; | |
| // Call the opcode | |
| (*instrFun[code])(program[pc]); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment