Exemplo n.º 1
0
 // Outputs the current Opcode data, and the function it has been translated to.
 public void displayOpCodeTranslation(OpCodeStruct data, string translation)
 {
     if (displayTranslation.Checked)
     {
         Invoke(new Action(() => { TranslationOutput.Items.Add(data.ToString() + " => " + translation); }));
     }
 }
Exemplo n.º 2
0
 private void skip_if_X_equals_NN(OpCodeStruct data)
 {
     displayOpCode(data, "Skip instruction if " + data.X + " is: " + data.NN);
     if (_registers[data.X] == data.NN)
     {
         skip_instruction();
     }
 }
Exemplo n.º 3
0
 private void skip_if_X_not_equals_Y(OpCodeStruct data)
 {
     displayOpCode(data, "Skip instruction if " + data.X + " is not: " + data.Y);
     if (_registers[data.X] != _registers[data.Y])
     {
         skip_instruction();
     }
 }
Exemplo n.º 4
0
        // Makes a beeping sound for the specified amount of time.
        private void beep(OpCodeStruct data)
        {
            int duration = (int)(_registers[data.X] * (1000f / 60));

            displayOpCode(data, "Play BEEP sound effect for: " + duration + "Seconds");
            Console.Beep(500, duration);
            Console.WriteLine("Sound was set to: {0}", _registers[data.X]);
        }
Exemplo n.º 5
0
 // Skips the next instruction if a certain key is pressed.
 private void skip_on_key(OpCodeStruct data)
 {
     displayOpCode(data, "Skip Instruction if key specified @ Register[" + data.X + "] is pressed.");
     if ((if_key_pressed(data) && _pressedKeys.Contains(_registers[data.X])) || (!if_key_pressed(data) && !_pressedKeys.Contains(_registers[data.X])))
     {
         skip_instruction();
     }
 }
Exemplo n.º 6
0
 // Loads all registers from the address register.
 private void reg_load(OpCodeStruct data)
 {
     displayOpCode(data, "Load Register values from RAM for Registers 0-" + data.X);
     for (var i = 0; i <= data.X; i++)
     {
         _registers[i] = _ram[_addressCounter + i];
     }
     updateRegistersRange(0, data.X);
 }
Exemplo n.º 7
0
 // Saves all registers to the address register.
 private void reg_dump(OpCodeStruct data)
 {
     displayOpCode(data, "Save Register values into RAM for Registers 0-" + data.X);
     for (var i = 0; i <= data.X; i++)
     {
         _ram[_addressCounter + i] = _registers[i];
     }
     updateRamRange(_addressCounter, _addressCounter + data.X);
 }
Exemplo n.º 8
0
        // Stores a binary decimal into ram
        private void set_BCD(OpCodeStruct data)
        {
            displayOpCode(data, "Store Binary Decimal " + _registers[data.X] + " into RAM @" + _addressCounter);
            _ram[_addressCounter]     = (byte)((_registers[data.X] / 100) % 10);
            _ram[_addressCounter + 1] = (byte)((_registers[data.X] / 10) % 10);
            _ram[_addressCounter + 2] = (byte)((_registers[data.X]) % 10);

            updateRamRange(_addressCounter, _addressCounter + 2);
        }
Exemplo n.º 9
0
        // Jumps to the subroutine
        private void call_subroutine_NNN(OpCodeStruct data)
        {
            // Push the current Program counter onto the stack

            push(_programCounter);
            // Changes program counter to target the subroutine.
            _programCounter = data.NNN;
            updateProgramCounter(_programCounter);
            displayOpCode(data, "Jump to subroutine: " + _programCounter);
        }
Exemplo n.º 10
0
        // Draws a specified sprite to the 'Screen' Object.
        private void draw_sprite(OpCodeStruct data)
        {
            var spriteX = _registers[data.X];
            var spriteY = _registers[data.Y];

            displayOpCode(data, "Draw Sprite to Screen at X:" + data.X + ", Y:" + data.Y);
            // Write any pending clears
            _screen.writePendingClears();

            // Clears the significant bit storage register.
            _registers[0xF] = 0;
            updateRegisters(0xF, _registers[0xF]);

            for (int i = 0; i < data.N; i++)
            {
                // Selects line of the sprite to render
                var spriteLine = _ram[_addressCounter + i];

                for (var bit = 0; bit < 8; bit++)
                {
                    int x_axis = (spriteX + bit) % _screenWidth;
                    int y_axis = (spriteY + i) % _screenHeight;

                    var spriteBit = ((spriteLine >> (7 - bit)) & 1);
                    var oldBit    = _screen.getPixel(x_axis, y_axis) ? 1 : 0;

                    if (oldBit != spriteBit)
                    {
                        _screen.setUpdateNeeded();
                    }

                    // New bit is XOR of existing and new.
                    var newBit = oldBit ^ spriteBit;

                    if (newBit != 0)
                    {
                        _screen.setPixel(x_axis, y_axis);
                    }
                    else // Otherwise write a pending clear
                    {
                        _screen.setPendingClear(x_axis, y_axis);
                    }

                    // If we wiped out a pixel, set flag for collission.
                    if (oldBit != 0 && newBit == 0)
                    {
                        _registers[0xF] = 1;
                    }
                    updateRegisters(0xF, _registers[0xF]);
                }
            }
        }
Exemplo n.º 11
0
 private void add_X(OpCodeStruct data)
 {
     displayOpCode(data, "Register[" + data.X + "] += " + data.NN);
     try
     {
         _registers[data.X] += data.NN;
         updateRegisters(data.X, data.NN);
     }
     catch (OverflowException)
     {
         Console.WriteLine("OVERFLOW EXCEPTION: {0} > Size of Register space allocated.", data.X);
     }
 }
Exemplo n.º 12
0
 // Will be called repeatedly by the game loop until the desired key is pressed to progress the program counter.
 private void get_key(OpCodeStruct data)
 {
     displayOpCode(data, "Stores pressed key in Register[" + data.X + "] if pressed, otherwise skips next instruction.");
     if (_pressedKeys.Count > 0)
     {
         _registers[data.X] = _pressedKeys.First();
         updateRegisters(data.X, _pressedKeys.First());
     }
     else
     {
         _programCounter -= 2;
         updateProgramCounter(_programCounter);
     }
 }
Exemplo n.º 13
0
        /*
         * OPCODE FUNCTIONS:
         */

        private void clear_or_return(OpCodeStruct data)
        {
            // Clears screen
            if (data.NN == 0xE0)
            {
                _screen.clear();
                displayOpCode(data, "Clear Screen");
            }
            // Returns subroutine from the stack
            else if (data.NN == 0xEE)
            {
                _programCounter = pop();
                updateProgramCounter(_programCounter);
                displayOpCode(data, "Return subroutine: " + _programCounter);
            }
        }
Exemplo n.º 14
0
        // Activate Miscilanious Opcode
        private void run_misc_op(OpCodeStruct data)
        {
            switch (data.NN)
            {
            case 0x07:
                get_delay(data);
                break;

            case 0x0A:
                get_key(data);
                break;

            case 0x15:
                set_delay_timer(data);
                break;

            case 0x18:
                Task.Factory.StartNew(() => beep(data));
                break;

            case 0x1E:
                add_x_to_address_register(data);
                break;

            case 0x29:
                set_address_register_for_char(data);
                break;

            case 0x33:
                set_BCD(data);
                break;

            case 0x55:
                reg_dump(data);
                break;

            case 0x65:
                reg_load(data);
                break;

            default:
                Console.WriteLine((string)("ERROR: NO MISC OP_CODE FOR:" + data));
                break;
            }
        }
Exemplo n.º 15
0
        private bool if_key_pressed(OpCodeStruct data)
        {
            bool key_pressed;

            if (data.NN == 0x9E)
            {
                key_pressed = true;
            }
            else if (data.NN == 0xA1)
            {
                key_pressed = false;
            }
            else
            {
                key_pressed = false;
                Console.WriteLine("ERROR: Key not pressed, but received unexpected value.");
            }

            return(key_pressed);
        }
Exemplo n.º 16
0
        public void Process_OpCode()
        {
            // Fetches OpCode
            var opCode = (ushort)(_ram[_programCounter++] << 8 | _ram[_programCounter++]);

            updateProgramCounter(_programCounter);

            // Decodes the OpCode
            var code = new OpCodeStruct()
            {
                OpCode = opCode,
                NNN    = (ushort)(opCode & 0x0FFF),
                NN     = (byte)(opCode & 0x00FF),
                N      = (byte)(opCode & 0x000F),
                X      = (byte)((opCode & 0x0F00) >> 8),
                Y      = (byte)((opCode & 0x00F0) >> 4),
            };

            // Excecutes the OpCode
            _opCodes[(byte)(opCode >> 12)](code);
        }
Exemplo n.º 17
0
 // Jumps to the localtion specified in the current OpCode's nnn byte.
 private void jump_to_NNN(OpCodeStruct data)
 {
     _programCounter = data.NNN;
     updateProgramCounter(_programCounter);
     displayOpCode(data, "Jump to instruction at: " + _programCounter);
 }
Exemplo n.º 18
0
        /*
         * MISC OPERATIONS:
         */

        // Sets register to current value of the delay timer
        private void get_delay(OpCodeStruct data)
        {
            displayOpCode(data, "Get Delay Timer: Register[" + data.X + "] = " + _delayTimer);
            _registers[data.X] = _delayTimer;
            updateRegisters(data.X, _delayTimer);
        }
Exemplo n.º 19
0
 private void set_delay_timer(OpCodeStruct data)
 {
     // TODO: Add GUI Component for tracking the delay Timer value?
     _delayTimer = _registers[data.X];
     displayOpCode(data, "Delay Timer = Register[" + data.X + "] = " + _delayTimer);
 }
Exemplo n.º 20
0
 // &s a random integer between 0 and 256with NN
 private void set_X_rand(OpCodeStruct data)
 {
     _registers[data.X] = (byte)(_random.Next(0, 256) & data.NN);
     updateRegisters(data.X, _registers[data.X]);
     displayOpCode(data, "Set Register[" + data.X + "] = randomInt(256) bitwise AND by" + data.NN);
 }
Exemplo n.º 21
0
 // Just to the value in the register offset by NNN value
 private void jump_offset_by_NNN(OpCodeStruct data)
 {
     displayOpCode(data, "Jump to Register[" + data.NNN + "]");
     _programCounter = (ushort)(_registers[0] + data.NNN);
     updateProgramCounter(_programCounter);
 }
Exemplo n.º 22
0
 private void set_adress_counter(OpCodeStruct data)
 {
     displayOpCode(data, "Address Counter = " + data.NNN);
     _addressCounter = data.NNN;
     updateAddressCounter(_addressCounter);
 }
Exemplo n.º 23
0
 private void add_x_to_address_register(OpCodeStruct data)
 {
     displayOpCode(data, "Address Counter += Register[" + data.X + "]");
     _addressCounter += _registers[data.X];
     updateAddressCounter(_addressCounter);
 }
Exemplo n.º 24
0
        private void math_operation(OpCodeStruct data)
        {
            // Use the opcode's N byte to determine which mathematic operation to perform with X & Y.
            switch (data.N)
            {
            case 0x0:       //Assign: Set X to Y
                displayOpCode(data, "Register[" + data.X + "] = Register[" + data.NN + "]");
                _registers[data.X] = _registers[data.Y];

                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x1:       // BitOp: Set X = X | Y (bitwise OR)
                displayOpCode(data, "Register[" + data.X + "] = Bitwise OR of Register[" + data.NN + "] and Register[" + data.Y + "]");
                _registers[data.X] |= _registers[data.Y];

                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x2:       // BitOp: Sets X = X & Y (bitwise AND)
                displayOpCode(data, "Register[" + data.X + "] = Bitwise AND of Register[" + data.NN + "] and Register[" + data.Y + "]");
                _registers[data.X] &= _registers[data.Y];

                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x3:       // BitOP: Sets X = X xor Y
                displayOpCode(data, "Register[" + data.X + "] = Bitwise XOR of Register[" + data.NN + "] and Register[" + data.Y + "]");
                _registers[data.X] ^= _registers[data.Y];

                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x4:       // Math: Sets X += Y
                displayOpCode(data, "Register[" + data.X + "] += " + data.Y);
                _registers[0xF]     = (byte)(_registers[data.X] + _registers[data.Y] > 0xFF ? 1 : 0);
                _registers[data.X] += _registers[data.Y];

                updateRegisters(0xF, _registers[0xF]);
                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x5:       // Math: X -= Y
                displayOpCode(data, "Register[" + data.X + "] -= " + data.Y);
                _registers[0xF]     = (byte)(_registers[data.X] > _registers[data.Y] ? 1 : 0);
                _registers[data.X] -= _registers[data.Y];

                updateRegisters(0xF, _registers[0xF]);
                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x6:       // BitOp: Stores the least significant bit of the value of register position X at position 0xF in ram, then shifts value of register @ position X to the right by 1.
                displayOpCode(data, "Bit shift value of Register[" + data.X + "] to the Right & store lsb in Register[0xF]");
                _registers[0xF]     = (byte)((_registers[data.X] & 0x1) != 0 ? 1 : 0);
                _registers[data.X] /= 2;     // Bit shift right.

                updateRegisters(0xF, _registers[0xF]);
                updateRegisters(data.X, _registers[data.X]);
                break;

            case 0x7:       //Math: Y = Y - X
                displayOpCode(data, "Register[" + data.X + "] = " + data.Y + " - " + data.X);
                _registers[0xF]     = (byte)(_registers[data.Y] > _registers[data.X] ? 1 : 0);
                _registers[data.Y] -= _registers[data.X];

                updateRegisters(0xF, _registers[0xF]);
                updateRegisters(data.Y, _registers[data.Y]);
                break;

            case 0xE:       // BitOp: Stores the least significant bit of the value of register position X at position 0xF in ram, then shifts value of register @ position X to the left by 1.
                displayOpCode(data, "Bit shift value of Register[" + data.X + "] to the Left & store lsb in Register[0xF]");
                _registers[0xF]     = (byte)((_registers[data.X] & 0xF) != 0 ? 1 : 0);
                _registers[data.X] *= 2;     // Bit shift left.

                updateRegisters(0xF, _registers[0xF]);
                updateRegisters(data.X, _registers[data.X]);
                break;

            default:
                Console.WriteLine("ERROR: No valid Math Operation for case: {0}", data.N);
                break;
            }
        }
Exemplo n.º 25
0
 // Sets the address register to the current location of the 'font' sprite for the sepcified character.
 private void set_address_register_for_char(OpCodeStruct data)
 {
     displayOpCode(data, "Set Address Counter to location of font sprite: " + _registers[data.X]);
     _addressCounter = (ushort)(_registers[data.X] * 5);
     updateAddressCounter(_addressCounter);
 }
Exemplo n.º 26
0
 private void set_X(OpCodeStruct data)
 {
     _registers[data.X] = data.NN;
     updateRegisters(data.X, data.NN);
     displayOpCode(data, "Set Register[" + data.X + "] = " + data.NN);
 }