private void DispatchOpcode(ParsedOpCode parsedOpCode) { switch (parsedOpCode.Instruction) { case 0x0: // 0xE0 Clear Display if (parsedOpCode.NN == 0xE0) { DisplayModel.Clear(); } // 0xEE Return from Subroutine else if (parsedOpCode.NN == 0xEE) { CPU.Ret(); } break; case 0x01: // 0x1NNN Jump to address NNN CPU.Jump(parsedOpCode.NNN); break; case 0x02: // 0x2NNN Execute subroutine at address NNN CPU.Subroutine(parsedOpCode.NNN); break; case 0x03: // 0x3XNN Skip the next instruction if regoster VX == NN CPU.SkipIfEqual(parsedOpCode.X, parsedOpCode.NN); break; case 0x04: // 0x4XNN Skip the next instruction if register VX != NN CPU.SkipIfNotEqual(parsedOpCode.X, parsedOpCode.NN); break; case 0x05: // 0x5XY0 Skip the next instruction if register VX == VY CPU.SkipIfXEqY(parsedOpCode.X, parsedOpCode.Y); break; case 0x06: // 0x6XNN Store the number NN in register VX CPU.StoreInRegister(parsedOpCode.X, parsedOpCode.NN); break; case 0x07: // 0x7XNN Add the number NN to register VX CPU.AddToRegister(parsedOpCode.X, parsedOpCode.NN); break; case 0x08: // Handle opcodes starting with 0x08 in a separate function Dispatch0x08(parsedOpCode); break; case 0x09: // 0x9XY0 Skip the next instruction if register VX != VY if (parsedOpCode.N == 0) { CPU.SkipNextInstructionIfVXneVY(parsedOpCode.X, parsedOpCode.Y); } break; case 0x0A: // 0xANNN Store memeory at address NNN in register I CPU.Index = parsedOpCode.NNN; break; case 0x0B: // 0xBNNN Jump to address NNN plus V0 CPU.JumpToAddressPlusV0(parsedOpCode.NNN); break; case 0x0C: // 0xCXNN Set VX to a random number with a mask of NN byte number = (byte)(random.Next(parsedOpCode.NN)); CPU.V[parsedOpCode.X] = number; break; case 0x0D: // 0xDXYN Draw sprite at position VX, VY with N bytes of data at the address stored in I // Set VF to 1 if any set pixels become unset. Set VF to 0 otherwise. var unsetPixels = DisplayModel.DrawSprite(CPU.V[parsedOpCode.X], CPU.V[parsedOpCode.Y], Memory, CPU.Index, parsedOpCode.N); CPU.V[0x0F] = (byte)(unsetPixels ? 1 : 0); break; case 0x0E: // Handle opcodes begining with 0xE Dispatch0x0E(parsedOpCode); break; case 0x0F: // Handle opcodes begining with 0xF Dispatch0x0F(parsedOpCode); break; } }