private void WaitForKeyPress(object sender, EventArgs e) { WaitingForKey?.Invoke(this, e); HideCaret(this.Handle); this.BackColor = SystemColors.ControlDark; this.KeyDown += SetKey; this.LostFocus += TapToSetTextBox_LostFocus; this.DoubleClick += TapToSetTextBox_LostFocus; }
/// <summary> /// It takes from _memory the instruction indicated by the program counter and executes it /// </summary> private void ExecuteNext() { ushort opcode = (ushort)(_memory[_PC & 0xFFF] * 0x100 + _memory[(_PC + 1) & 0xFFF]); _PC += 2; byte u = (byte)((opcode >> 12) & 0xF); byte p = (byte)((opcode >> 0) & 0xF); byte y = (byte)((opcode >> 4) & 0xF); byte x = (byte)((opcode >> 8) & 0xF); byte kk = (byte)((opcode >> 0) & 0xFF); ushort nnn = (ushort)((opcode >> 0) & 0xFFF); switch (u) { case 0: if (opcode == 0x0E0) { Array.Clear(_screen, 0, _screen.Length); } else if (opcode == 0x0EE) { _PC = _stack.Pop(); } else { throw new UnsupportedInstructionException(opcode.ToString("X4")); } break; case 1: _PC = nnn; break; case 2: _stack.Push(_PC); _PC = nnn; break; case 3: if (_V[x] == kk) { _PC += 2; } break; case 4: if (_V[x] != kk) { _PC += 2; } break; case 5: if (_V[x] == _V[y]) { _PC += 2; } break; case 6: _V[x] = kk; break; case 7: _V[x] += kk; break; case 8: switch (p) { case 0: _V[x] = _V[y]; break; case 1: _V[x] |= _V[y]; break; case 2: _V[x] &= _V[y]; break; case 3: _V[x] ^= _V[y]; break; case 4: _V[0xF] = (byte)(_V[x] + _V[y] > byte.MaxValue ? 1 : 0); _V[x] += _V[y]; break; case 5: _V[0xF] = (byte)(_V[x] > _V[y] ? 1 : 0); _V[x] -= _V[y]; break; case 6: _V[0xF] = (byte)(_V[x] & 0x0001); _V[x] >>= 1; break; case 7: _V[0xF] = (byte)(_V[y] > _V[x] ? 1 : 0); _V[x] = (byte)(_V[y] - _V[x]); break; case 0xE: _V[0xF] = (byte)((_V[x] & 0x80) == 0x80 ? 1 : 0); _V[x] <<= 1; break; default: throw new UnsupportedInstructionException(opcode.ToString("X4")); break; } break; case 9: if (_V[x] != _V[y]) { _PC += 2; } break; case 0xA: _I = nnn; break; case 0xB: _PC = (ushort)(nnn + _V[0]); break; case 0xC: _V[x] = (byte)(_random.Next(byte.MaxValue + 1) & kk); break; case 0xD: int x1 = _V[x]; int y1 = _V[y]; _V[15] = 0; for (int i = 0; i < p; i++) { byte mem = _memory[_I + i]; for (int j = 0; j < 8; j++) { byte pixel = (byte)((mem >> (7 - j)) & 0x01); int index = x1 + j + (y1 + i) * ScreenWidth; index %= 2048; if (pixel == 1 && _screen[index] != 0) { _V[15] = 1; } _screen[index] = (byte)(_screen[index] ^ pixel); } } break; case 0xE: if (kk == 0x9E) { if ((_currentKey == _keyboardMapper.Convert(_V[x]))) { _PC += 2; } } else if (kk == 0xA1) { if ((_currentKey != _keyboardMapper.Convert(_V[x]))) { _PC += 2; } } else { throw new UnsupportedInstructionException(opcode.ToString("X4")); } break; case 0xF: switch (kk) { case 0x07: _V[x] = _delayTimer; break; case 0x0A: while (_currentKey != _keyboardMapper.Convert(_V[x])) { WaitingForKey?.Invoke(this, EventArgs.Empty); autoEvent.WaitOne(); } break; case 0x15: _delayTimer = _V[x]; break; case 0x18: _soundTimer = _V[x]; break; case 0x1E: _I += _V[x]; break; case 0x29: _I = (ushort)(_V[x] * 5); break; case 0x33: _memory[_I] = (byte)(_V[x] / 100); _memory[_I + 1] = (byte)((_V[x] % 100) / 10); _memory[_I + 2] = (byte)(_V[x] % 10); break; case 0x55: Array.Copy(_V, 0, _memory, _I, x + 1); break; case 0x65: Array.Copy(_memory, _I, _V, 0, x + 1); break; default: throw new UnsupportedInstructionException(opcode.ToString("X4")); break; } break; default: throw new UnsupportedInstructionException(opcode.ToString("X4")); break; } }