1 module ben_eater; 2 3 import std.stdio; 4 5 class BenEaterEmulator { 6 public this(ubyte[16] program) { 7 memory[]= program; 8 } 9 10 public void run() { 11 while (true) { 12 ubyte instruction = memory[pc++]; 13 ubyte opcode = instruction >> 4; 14 ubyte argument = instruction & 0x0f; 15 16 switch (opcode) with (Opcodes) { 17 case LDA: 18 regA = memory[argument]; 19 break; 20 case ADD: 21 ubyte temp = regA; 22 regA += memory[argument]; 23 if (regA < temp) carryFlag = true; 24 break; 25 case SUB: 26 ubyte temp = regA; 27 regA -= memory[argument]; 28 if (regA > temp) carryFlag = true; 29 break; 30 case STA: 31 memory[argument] = regA; 32 break; 33 case OUT: 34 writeln(regA); 35 break; 36 case JMP: 37 pc = argument; 38 break; 39 case LDI: 40 regA = argument; 41 break; 42 case JC: 43 if (carryFlag) pc = argument; 44 break; 45 case NOP: 46 break; 47 case HLT: 48 writeln("Done"); 49 return; 50 default: 51 writefln("Invalid.\nOpcode: %08b\nArgument: %08b", opcode, argument); 52 break; 53 } 54 //writefln("%08b", instruction); 55 } 56 } 57 58 private ubyte[16] memory; // Both the program and the variables it uses 59 private ubyte pc = 0; // Program counter 60 private ubyte regA; // Register A 61 private ubyte regB; // Register B 62 private bool carryFlag; // When there was an overflow or underflow in the last operation 63 64 enum Opcodes { 65 LDA = 0b0001, 66 ADD = 0b0010, 67 SUB = 0b0011, 68 STA = 0b0100, 69 OUT = 0b0101, 70 JMP = 0b0110, 71 LDI = 0b0111, 72 JC = 0b1000, 73 NOP = 0b1001, 74 HLT = 0b1111 75 } 76 }