private void HandleOpcode(OpCode code) { switch (code.code & 0xF000) { case 0x0000: switch (code.code & 0x000F) { case 0x0000: ClearDisplay(); PC_I(); draw = true; break; case 0x000E: PC = stack[stackPointer--]; PC_I(); break; default: PC_I(); break; } break; case 0x1000: PC = (ushort)code.Addr(); break; case 0x2000: stack[++stackPointer] = PC; PC = code.Addr(); break; case 0x3000: if (VRegs[code.X()] == code.KK()) { PC_I(); } PC_I(); break; case 0x4000: if (VRegs[code.X()] != code.KK()) { PC_I(); } PC_I(); break; case 0x5000: if (VRegs[code.Y()] == VRegs[code.X()]) { PC_I(); } PC_I(); break; case 0x6000: VRegs[code.X()] = (byte)code.KK(); PC_I(); break; case 0x7000: VRegs[code.X()] += (byte)code.KK(); PC_I(); break; case 0x8000: switch (code.code & 0x000F) { case 0x0000: VRegs[code.X()] = VRegs[code.Y()]; PC_I(); break; case 0x0001: VRegs[code.X()] |= VRegs[code.Y()]; PC_I(); break; case 0x0002: VRegs[code.X()] &= VRegs[code.Y()]; PC_I(); break; case 0x0003: VRegs[code.X()] ^= VRegs[code.Y()]; PC_I(); break; case 0x0004: VRegs[0xF] = (byte)((VRegs[code.X()] + VRegs[code.Y()]) > 0xFF ? 1 : 0); VRegs[code.X()] += VRegs[code.Y()]; PC_I(); break; case 0x0005: VRegs[0xF] = (byte)(VRegs[code.X()] > VRegs[code.Y()] ? 1 : 0); VRegs[code.X()] -= VRegs[code.Y()]; PC_I(); break; case 0x0006: VRegs[0xf] = (byte)(VRegs[code.X()] & 0x1); VRegs[code.X()] /= 2; PC_I(); break; case 0x0007: VRegs[0xF] = (byte)(VRegs[code.Y()] > VRegs[code.X()] ? 1 : 0); VRegs[code.X()] = (byte)(VRegs[code.Y()] - VRegs[code.X()]); PC_I(); break; case 0x000E: VRegs[0xf] = (byte)((VRegs[code.X()] & 0x80) != 0 ? 1 : 0); VRegs[code.X()] *= 2; PC_I(); break; } break; case 0x9000: if (VRegs[code.X()] != VRegs[code.Y()]) { PC_I(); } PC_I(); break; case 0xA000: I = code.Addr(); PC_I(); break; case 0xB000: PC = (ushort)(code.Addr() + VRegs[0]); //PC_I(); break; case 0xC000: VRegs[code.X()] = (byte)(random.Next(255) & code.KK()); PC_I(); break; case 0xD000: VRegs[0xf] = 0; ushort x = VRegs[code.X()]; ushort y = VRegs[code.Y()]; ushort nibl = code.N(); ushort xj, yi; xj = yi = 0; byte pixel; for (int i = 0; i < nibl; ++i) { pixel = Memory[I + i]; for (int j = 0; j < 8; ++j) { if ((pixel & (0x80 >> j)) != 0) { //if(x+j >= 0 && x+j< 64 && y+i >= 0 && y+i < 32) //{ ushort pos = (ushort)(((x + j) + ((y + i) * 64)) % 2048); if (display[pos] == true) { VRegs[0xf] = 1; } display[pos] ^= true; //} //VRegs[0xf] = display[pos] == true ? (byte)1 : (byte)0; } } } draw = true; PC_I(); break; case 0xE000: switch (code.code & 0x00FF) { case 0x009E: if (key[VRegs[code.X()]]) { PC_I(); } PC_I(); break; case 0x00A1: if (!key[VRegs[code.X()]]) { PC_I(); } PC_I(); break; } //PC_I(); break; case 0xF000: switch (code.code & 0x00FF) { case 0x0007: VRegs[code.X()] = (byte)delayTimer; PC_I(); break; case 0x000A: for (int i = 0x0; i < 0xf; ++i) { if (key[i]) { VRegs[code.X()] = (byte)i; PC_I(); break; } } break; case 0x0015: delayTimer = VRegs[code.X()]; PC_I(); break; case 0x0018: soundTimer = VRegs[code.X()]; PC_I(); break; case 0x001E: I += VRegs[code.X()]; PC_I(); break; case 0x0029: I = (ushort)(VRegs[code.X()] * 5); PC_I(); break; case 0x0033: var value = VRegs[code.X()]; Memory[I + 2] = (byte)((value % 100) % 10); Memory[I + 1] = (byte)((value / 10) % 10); Memory[I] = (byte)(value / 100); PC_I(); break; case 0x0055: for (int i = 0; i < code.X(); ++i) { Memory[I + i] = VRegs[i]; } I += (ushort)(code.X() + 1); PC_I(); break; case 0x0065: for (int i = 0; i < code.X(); ++i) { VRegs[i] = Memory[I + i]; } I += (ushort)(code.X() + 1); PC_I(); break; } break; default: Console.WriteLine($"{code.code} not implemented yet."); break; } }