Пример #1
0
 public void draw(int x, int y, int n)
 {
     registers[0x0F] = 0;
     for (int dY = 0; dY < n; dY++)
     {
         ushort location = (ushort)(I + dY);
         byte   pixel    = Chip8Memory.memory[location];
         for (int dX = 0; dX < 8; dX++)
         {
             int offset = ((y + dY) * Chip8Display.SCREEN_WIDTH) + x + dX;
             if ((pixel & (0x80 >> dX)) != 0)
             {
                 if (Chip8Display.isWhite(offset))
                 {
                     registers[0x0F] = 1;
                 }
                 bool isWhite = Chip8Display.isWhite(offset) ^ true;
                 Chip8Display.draw(offset, isWhite);
             }
         }
     }
 }
Пример #2
0
        public void executeInstruction()
        {
            byte byte1     = Chip8Memory.memory[Chip8InstructionPointer.offset++];
            byte byte2     = Chip8Memory.memory[Chip8InstructionPointer.offset++];
            byte registerX = registers[Chip8Opcode.getX(byte1)];
            byte registerY = registers[Chip8Opcode.getY(byte2)];
            byte value;

            switch (Chip8Opcode.getCode(byte1))
            {
            case 0x00:
                switch (Chip8Opcode.getNN(byte2))
                {
                case 0xE0:
                    Chip8Display.clear();
                    break;

                case 0xEE:
                    byte returnByte1 = Chip8Memory.memory[--Chip8StackPointer.offset];
                    byte returnByte2 = Chip8Memory.memory[--Chip8StackPointer.offset];
                    Chip8InstructionPointer.offset = (ushort)((returnByte1 << 8) + returnByte2);
                    break;

                default:
                    throw new IllegalChip8OpcodeException("Illegal Opcode " + byte1.ToString("X2") + byte2.ToString("X2"));
                }
                break;

            case 0x01:
                Chip8InstructionPointer.offset = Chip8Opcode.getNNN(byte1, byte2);
                break;

            case 0x02:
                Chip8Memory.memory[Chip8StackPointer.offset++] = (byte)(Chip8InstructionPointer.offset & 0x0F);
                Chip8Memory.memory[Chip8StackPointer.offset++] = (byte)(Chip8InstructionPointer.offset >> 8);
                Chip8InstructionPointer.offset = Chip8Opcode.getNNN(byte1, byte2);
                break;

            case 0x03:
                if (registerX == Chip8Opcode.getNN(byte2))
                {
                    Chip8InstructionPointer.increment();
                }
                break;

            case 0x04:
                if (registerX != Chip8Opcode.getNN(byte2))
                {
                    Chip8InstructionPointer.increment();
                }
                break;

            case 0x05:
                if (registerX == registerY)
                {
                    Chip8InstructionPointer.increment();
                }
                break;

            case 0x06:
                registers[Chip8Opcode.getX(byte1)] = Chip8Opcode.getNN(byte2);
                break;

            case 0x07:
                value = (byte)(registerX + Chip8Opcode.getNN(byte2));
                registers[Chip8Opcode.getX(byte1)] = value;
                break;

            case 0x08:
                switch (Chip8Opcode.getN(byte2))
                {
                case 0x00:
                    registers[Chip8Opcode.getX(byte1)] = registerY;
                    break;

                case 0x01:
                    value = (byte)(registerX | registerY);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x02:
                    value = (byte)(registerX & registerY);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x03:
                    value = (byte)(registerX ^ registerY);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x04:
                    // handle VF
                    value = (byte)(registerX + registerY);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x05:
                    //handle VF
                    value = (byte)(registerX - registerY);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x06:
                    //handle VF
                    value = (byte)(registerY >> 1);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x07:
                    //handle VF
                    value = (byte)(registerY - registerX);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    break;

                case 0x0E:
                    //handle VF
                    value = (byte)(registerY << 1);
                    registers[Chip8Opcode.getX(byte1)] = value;
                    registers[Chip8Opcode.getY(byte2)] = value;
                    break;

                default:
                    throw new IllegalChip8OpcodeException("Illegal Opcode " + byte1.ToString("X2") + byte2.ToString("X2"));
                }
                break;

            case 0x09:
                if (registerX != registerY)
                {
                    Chip8InstructionPointer.increment();
                }
                break;

            case 0x0A:
                I = Chip8Opcode.getNNN(byte1, byte2);
                break;

            case 0x0B:
                ushort offset = (ushort)(registers[0] + Chip8Opcode.getNNN(byte1, byte2));
                Chip8InstructionPointer.offset = offset;
                break;

            case 0x0C:
                value = (byte)(random.Next(256) & Chip8Opcode.getNN(byte2));
                registers[Chip8Opcode.getX(byte1)] = value;
                break;

            case 0x0D:
                int x = registerX;
                int y = registerY;
                int n = Chip8Opcode.getN(byte2);
                draw(x, y, n);
                break;

            case 0x0E:
                switch (Chip8Opcode.getNN(byte2))
                {
                case 0x9E:
                    if (keyboard.keyState[Chip8Opcode.getX(byte1)])
                    {
                        Chip8InstructionPointer.increment();
                    }
                    break;

                case 0xA1:
                    if (!keyboard.keyState[Chip8Opcode.getX(byte1)])
                    {
                        Chip8InstructionPointer.increment();
                    }
                    break;

                default:
                    throw new IllegalChip8OpcodeException("Illegal Opcode " + byte1.ToString("X2") + byte2.ToString("X2"));
                }
                break;

            case 0x0F:
                switch (Chip8Opcode.getNN(byte2))
                {
                case 0x07:
                    registers[Chip8Opcode.getX(byte1)] = (byte)delayTimer.get();
                    break;

                case 0x0A:
                    // TODO: implment readkey
                    registers[Chip8Opcode.getX(byte1)] = 0;         // should be read key
                    break;

                case 0x15:
                    delayTimer.set(registerX);
                    break;

                case 0x18:
                    soundTimer.set(registerX);
                    break;

                case 0x1E:
                    I += registerX;
                    break;

                case 0x29:
                    I = (byte)(Chip8Fontset.FONT_HEIGHT * registerX);
                    break;

                case 0x33:
                    Chip8Memory.memory[I]     = (byte)(registerX / 100);
                    Chip8Memory.memory[I + 1] = (byte)((registerX % 100) / 10);
                    Chip8Memory.memory[I + 2] = (byte)(registerX % 10);
                    break;

                case 0x55:
                    for (int i = 0; i <= Chip8Opcode.getX(byte1); i++)
                    {
                        Chip8Memory.memory[I++] = registers[i];
                    }
                    break;

                case 0x65:
                    for (int i = 0; i <= Chip8Opcode.getX(byte1); i++)
                    {
                        registers[i] = Chip8Memory.memory[I++];
                    }
                    break;

                default:
                    throw new IllegalChip8OpcodeException("Illegal Opcode " + byte1.ToString("X2") + byte2.ToString("X2"));
                }
                break;

            default:
                throw new IllegalChip8OpcodeException("Illegal Opcode " + byte1.ToString("X2") + byte2.ToString("X2"));
            }
        }