Пример #1
0
        private void Execute(Opcode param)
        {
            switch (param.Nibble)
            {
            case 0x0000:
                if (param.Value == 0x00e0)
                {
                    display.ClearDisplay();
                }
                else if (param.Value == 0x00ee)
                {
                    var address = ram.ReturnFromSubroutine();
                    register.JumpToAddress(address);
                    break;
                }
                else
                {
                    throw new InvalidOperationException("opcode not found");
                }
                break;

            case 0x1000:
                register.JumpToAddress(param.NNN);
                break;

            case 0x2000:
                ram.CallSubroutine(register.PC);
                register.JumpToAddress(param.NNN);
                break;

            case 0x3000:
                if (register[param.X] == param.NN)
                {
                    register.IncrementPC();
                }
                break;

            case 0x4000:
                if (register[param.X] != param.NN)
                {
                    register.IncrementPC();
                }
                break;

            case 0x5000:
                if (register[param.X] == register[param.Y])
                {
                    register.IncrementPC();
                }
                break;

            case 0x6000:
                register.StoreValue(param.X, param.NN);
                break;

            case 0x7000:
                register.IncrementRegisterValue(param.X, param.NN);
                break;

            case 0x8000:
                byte last = (byte)(param.Value & 0x000F);

                switch (last)
                {
                case 0: register.StoreValue(param.X, register[param.Y]); break;

                case 1: register.CalculateRegistersAndStoreValue(param.X, param.X, param.Y, BitOperationType.OR); break;

                case 2: register.CalculateRegistersAndStoreValue(param.X, param.X, param.Y, BitOperationType.AND); break;

                case 3: register.CalculateRegistersAndStoreValue(param.X, param.X, param.Y, BitOperationType.XOR); break;

                case 4:
                    register.StoreValueOnRegister0xF((byte)(register[param.X] + register[param.Y] > 255 ? 1 : 0));
                    register.StoreValue(param.X, (byte)((register[param.X] + register[param.Y]) & 0x00FF));
                    break;

                case 5:
                    register.StoreValueOnRegister0xF((byte)(register[param.X] > register[param.Y] ? 1 : 0));
                    register.StoreValue(param.X, (byte)((register[param.X] - register[param.Y]) & 0x00FF));
                    break;

                case 6:

                    register.StoreValueOnRegister0xF((byte)(register[param.X] & 0x0001));
                    register.StoreValue(param.X, (byte)(register[param.X] >> 1));
                    break;

                case 7:
                    register.StoreValueOnRegister0xF((byte)(register[param.Y] > register[param.X] ? 1 : 0));
                    register.StoreValue(param.X, (byte)((register[param.Y] - register[param.X]) & 0x00FF));
                    break;

                case 0xE:
                    register.StoreValueOnRegister0xF((byte)((register[param.X] & 0x80) == 0x80 ? 1 : 0));
                    register.StoreValue(param.X, (byte)(register[param.X] << 1));
                    break;

                default:
                    throw new InvalidOperationException("opcode not found");
                }

                break;

            case 0x9000:
                if (register[param.X] != register[param.Y])
                {
                    register.IncrementPC();
                }
                break;

            case 0xA000:
                register.SetRegisterI(param.NNN); break;

            case 0xB000:
                register.JumpToAddress((ushort)(register[0] + param.NNN)); return;

            case 0xC000:
                register.StoreValue(param.X, (byte)((byte)Random.Next(0, byte.MaxValue) & param.NN));
                break;

            case 0xE000:
                last = (byte)(param.Value & 0x000F);

                switch (last)
                {
                case 14:
                    if (register[param.X] == Keyboard)
                    {
                        register.IncrementPC();
                    }
                    break;

                case 1:
                    if (register[param.X] != Keyboard)
                    {
                        register.IncrementPC();
                    }
                    break;

                default:
                    throw new InvalidOperationException("opcode not found");
                }
                break;

            case 0xD000:
                var sprites = ram.GetValues(register.I, param.N);
                display.Draw(sprites, register[param.X], register[param.Y], out var overridePixel);
                register.StoreValueOnRegister0xF(overridePixel);
                break;

            case 0xF000:
                last = (byte)(param.Value & 0x00FF);

                switch (last)
                {
                case 0x7:         //FX07
                    register.StoreValue(param.X, timer.DelayTimer);
                    break;

                case 0x0A:
                    WaitingForKeyboardEvent.WaitOne();
                    register.StoreValue(param.X, Keyboard);
                    break;

                case 0x15:
                    timer.SetTimer(TimerType.Delay, register[param.X]);
                    break;

                case 0x18:         //FX18
                    timer.SetTimer(TimerType.Sound, register[param.X]);
                    break;

                case 0x1E:
                    register.IncreaseRegisterI(register[param.X]);
                    break;

                case 0x29:
                    register.SetRegisterI(ram.GetFontAddress(register[param.X]));
                    break;

                case 0x33:
                    var bcd = BCD.GetBytes(register[param.X]);
                    ram.CopyValuesToRam(bcd, register.I);
                    break;

                case 0x55:
                    ram.CopyValuesToRam(register.GetRegisters(0, param.X), register.I);
                    break;

                case 0x65:
                    register.CopyValuesToRegisters(ram.GetValues(register.I, param.X, inclusive: true), 0);
                    break;

                default:
                    throw new InvalidOperationException("opcode not found");
                }
                break;

            default:
                throw new Exception("opcode not found");
            }

            Thread.Sleep(1);
        }
Пример #2
0
 public void LoadProgram(byte[] program)
 {
     ram.CopyValuesToRam(program, 0x200);
     ProgramLoaded = true;
 }