예제 #1
0
        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;
            }
        }