Example #1
0
        public void Executing_Instruction_Ex9E_WorksAsExpected()
        {
            var decodedInstruction = new DecodedInstruction(0xE19E);
            var cpu = new Cpu();

            cpu.V[1] = 0x2;

            var mockSequence = new MockSequence();
            var keyboardMock = new Mock <IKeyboard>(MockBehavior.Strict);

            keyboardMock.InSequence(mockSequence).Setup(x => x.GetPressedKey()).Returns((byte?)null);
            keyboardMock.InSequence(mockSequence).Setup(x => x.GetPressedKey()).Returns(1);
            keyboardMock.InSequence(mockSequence).Setup(x => x.GetPressedKey()).Returns(2);
            var keyboard = keyboardMock.Object;

            var instruction = new Instruction_Ex9E(decodedInstruction);

            Assert.That(instruction.Mnemonic, Is.EqualTo($"SKP V{decodedInstruction.x:X}"));

            var oldPC = cpu.PC;

            instruction.Execute(cpu, MockedDisplay, keyboard);
            Assert.That(cpu.PC, Is.EqualTo(oldPC));

            instruction.Execute(cpu, MockedDisplay, keyboard);
            Assert.That(cpu.PC, Is.EqualTo(oldPC));

            instruction.Execute(cpu, MockedDisplay, keyboard);
            Assert.That(cpu.PC, Is.EqualTo(oldPC + 2));

            keyboardMock.Verify(x => x.GetPressedKey(), Times.Exactly(3));
        }
Example #2
0
        internal static void Main(string[] args)
        {
            Console.WriteLine("Test");
            XedState state = new XedState
            {
                Mode = MachineMode.Legacy32,
                StackAddressWidth = AddressWidth.Width32
            };

            EncoderRequest enc = new EncoderRequest(state);

            enc.Class = InstClass.Push;
            enc.SetOperandOrder(0, OperandName.Reg0);
            enc.SetReg(OperandName.Reg0, Register.Eax);
            byte[] bytes = enc.Encode();

            DecodedInstruction inst = new DecodedInstruction(state);

            inst.Decode(bytes);

            enc = new EncoderRequest(inst);
            enc.SetBase0(Register.Edx);
            bytes = enc.Encode();
            inst  = new DecodedInstruction(state);
            inst.Decode(bytes);

            Console.ReadLine();
        }
Example #3
0
        public void Executing_Instruction_Fx0A_WorksAsExpected()
        {
            var decodedInstruction = new DecodedInstruction(0xF10A);
            var cpu = new Cpu {
                PC = (ushort)(Cpu.MemoryAddressOfFirstInstruction + 2)
            };
            byte pressedKey = 0x3;

            var mockSequence = new MockSequence();
            var keyboardMock = new Mock <IKeyboard>(MockBehavior.Strict);

            keyboardMock.InSequence(mockSequence).Setup(x => x.GetPressedKey()).Returns(pressedKey);
            keyboardMock.InSequence(mockSequence).Setup(x => x.GetPressedKey()).Returns((byte?)null);
            var keyboard = keyboardMock.Object;

            var instruction = new Instruction_Fx0A(decodedInstruction);

            Assert.That(instruction.Mnemonic, Is.EqualTo($"LD V{decodedInstruction.x:X}, K"));

            var oldPC = cpu.PC;

            instruction.Execute(cpu, MockedDisplay, keyboard);
            Assert.That(cpu.PC, Is.EqualTo(oldPC));
            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(pressedKey));

            instruction.Execute(cpu, MockedDisplay, keyboard);
            Assert.That(cpu.PC, Is.EqualTo(oldPC - 2));

            keyboardMock.Verify(x => x.GetPressedKey(), Times.Exactly(2));
        }
Example #4
0
    public void Executing_Instruction_Dxy0_DoesNotUseDisplay()
    {
      var cpu = new Cpu();
      var decodedInstruction = new DecodedInstruction(0xD230);

      var instruction = new Instruction_Dxyn(decodedInstruction);
      instruction.Execute(cpu, MockedDisplay, MockedKeyboard);
    }
Example #5
0
 public void OnAfter_RTS(CPU_6510 _cpu, DecodedInstruction _instr)
 {
     //  RTS
     if (JSR_Depth > 0)
     {
         CallStack.Pop();
         JSR_Depth--;
     }
 }
Example #6
0
        public void Executing_Instruction_8xy5_WithVx_SetToVF_ThrowsException()
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0x8FB5);

            var instruction = new Instruction_8xy5(decodedInstruction);

            Assert.Throws <InvalidOperationException>(() => instruction.Execute(cpu, MockedDisplay, MockedKeyboard));
        }
Example #7
0
        public void DecodedInstruction_IsEquatable()
        {
            var instruction1 = new DecodedInstruction(0x1234);
            var instruction2 = new DecodedInstruction(0x1234);
            var instruction3 = new DecodedInstruction(0x1235);

            Assert.That(instruction1, Is.EqualTo(instruction2));
            Assert.That(instruction1, Is.Not.EqualTo(instruction3));
        }
Example #8
0
        public void Executing_Instruction_Fx29_WithVxValue_GreatherThan0xF_ThrowsException()
        {
            var cpu = new Cpu();

            cpu.V[0xA] = 0x10;
            var decodedInstruction = new DecodedInstruction(0xFA29);

            var instruction = new Instruction_Fx29(decodedInstruction);

            Assert.Throws <InvalidOperationException>(() => instruction.Execute(cpu, MockedDisplay, MockedKeyboard));
        }
Example #9
0
        public void WriteToMemory_OutsideValidMemoryRange_ThrowsException(ushort initialI)
        {
            var cpu = new Cpu {
                I = initialI
            };
            var decodedInstruction = new DecodedInstruction(0xFA33);

            var instruction = new Instruction_Fx33(decodedInstruction);

            Assert.Throws <InvalidOperationException>(() => instruction.Execute(cpu, MockedDisplay, MockedKeyboard));
        }
Example #10
0
        public void Jumping_OutsideValidMemoryRange_ThrowsException(ushort instructionCode, byte v0)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(instructionCode);

            cpu.V[0] = v0;

            var instruction = new Instruction_Bnnn(decodedInstruction);

            Assert.Throws <InvalidOperationException>(() => instruction.Execute(cpu, MockedDisplay, MockedKeyboard));
        }
Example #11
0
        public void Executing_Instruction_Cxkk_WorksAsExpected(ushort instructionCode)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(instructionCode);

            var instruction = new Instruction_Cxkk(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.LessThanOrEqualTo(decodedInstruction.kk));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"RND V{decodedInstruction.x:X}, 0x{decodedInstruction.kk:X}"));
        }
Example #12
0
        public void Executing_Instruction_Annn_WorksAsExpected()
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0xA123);

            var instruction = new Instruction_Annn(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.I, Is.EqualTo(decodedInstruction.nnn));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"LD I, 0x{decodedInstruction.nnn:X}"));
        }
Example #13
0
        private static void Main(string[] args)
        {
            var decoder = new Decoder();

            if (!Status.Success(Decoder.Init(ref decoder, MachineMode.LONG_64, AddressWidth.WIDTH_64)))
            {
                throw new Exception("Failed to initialize instruction-decoder.");
            }
            if (!Status.Success(Decoder.EnableMode(ref decoder, DecoderMode.AMD_BRANCHES, false)))
            {
                throw new Exception("Failed to set decoder mode.");
            }

            var formatter = new Formatter();

            if (!Status.Success(Formatter.Init(ref formatter, FormatterStyle.INTEL)))
            {
                throw new Exception("Failed to initialize instruction-formatter.");
            }

            var data   = new byte[] { 0x48, 0x8B, 0x84, 0x8A, 0x34, 0x12, 0x00, 0x00, 0xEB, 0x00, 0x90, 0xCC };
            var buffer = new byte[Constants.MAX_INSTRUCTION_LENGTH];
            var offset = 0;

            DecodedInstruction instruction = new DecodedInstruction();
            var formatBuffer = new StringBuilder(256);

            while (true)
            {
                var size = Math.Min(Constants.MAX_INSTRUCTION_LENGTH, data.Length - offset);
                Array.Copy(data, offset, buffer, 0, size);

                var status = Decoder.DecodeBuffer(ref decoder, buffer, (UIntPtr)size, ref instruction);
                if (status == Status.NO_MORE_DATA)
                {
                    break;
                }
                if (!Status.Success(status))
                {
                    Console.WriteLine("db ");
                    continue;
                }

                Formatter.FormatInstruction(ref formatter, ref instruction, formatBuffer,
                                            (UIntPtr)formatBuffer.Capacity, 0x0000000000000000);
                Console.WriteLine(formatBuffer);

                offset += instruction.Length;
            }

            Console.ReadKey();
        }
Example #14
0
        public void Setting_IRegister_OutsideValidMemoryRange_ThrowsException(byte vxValue, ushort iValue)
        {
            var cpu = new Cpu {
                I = iValue
            };
            var decodedInstruction = new DecodedInstruction(0xFA1E);

            cpu.V[decodedInstruction.x] = vxValue;

            var instruction = new Instruction_Fx1E(decodedInstruction);

            Assert.Throws <InvalidOperationException>(() => instruction.Execute(cpu, MockedDisplay, MockedKeyboard));
        }
Example #15
0
        public void Executing_Instruction_7xkk_WorksAsExpected(ushort instructionCode, byte oldVxValue, byte expectedVxValue)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(instructionCode);

            cpu.V[decodedInstruction.x] = oldVxValue;

            var instruction = new Instruction_7xkk(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(expectedVxValue));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"ADD V{decodedInstruction.x:X}, 0x{decodedInstruction.kk:X}"));
        }
Example #16
0
        public void Executing_Instruction_Fx07_WorksAsExpected()
        {
            var cpu = new Cpu {
                DT = 0x12
            };
            var decodedInstruction = new DecodedInstruction(0xFA07);

            var instruction = new Instruction_Fx07(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(0x12));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"LD V{decodedInstruction.x:X}, DT"));
        }
Example #17
0
        public void Executing_Instruction_Bnnn_WorksAsExpected(ushort instructionCode, byte v0, ushort expectedPcValue)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(instructionCode);

            cpu.V[0] = v0;

            var instruction = new Instruction_Bnnn(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.PC, Is.EqualTo(expectedPcValue));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"JP V0, 0x{decodedInstruction.nnn:X}"));
        }
Example #18
0
        public void Executing_Instruction_Fx29_WorksAsExpected()
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0xFA29);

            cpu.V[decodedInstruction.x] = 0x3;

            var instruction = new Instruction_Fx29(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.I, Is.EqualTo(15));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"LD F, V{decodedInstruction.x:X}"));
        }
Example #19
0
        public void Executing_Instruction_1nnn_WorksAsExpected()
        {
            var cpu = new Cpu();

            cpu.Stack.Push((ushort)(Cpu.MemoryAddressOfFirstInstruction + 10));
            var decodedInstruction = new DecodedInstruction(0x1246);

            var instruction = new Instruction_1nnn(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.PC, Is.EqualTo(decodedInstruction.nnn));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"JP 0x{decodedInstruction.nnn:X}"));
        }
Example #20
0
        public void Executing_Instruction_8xyE_WorksAsExpected(byte vy, byte expectedResult, byte expectedVF)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0x8ABE);

            cpu.V[decodedInstruction.y] = vy;

            var instruction = new Instruction_8xyE(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(expectedResult));
            Assert.That(cpu.V[0xF], Is.EqualTo(expectedVF));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"SHL V{decodedInstruction.x:X}, V{decodedInstruction.y:X}"));
        }
Example #21
0
    public void Executing_Instruction_Dxyn_WorksAsExpected()
    {
      const byte xCoordinate = 0x5, yCoordinate = 0x6;
      var cpu = new Cpu();
      cpu.V[2] = xCoordinate;
      cpu.V[3] = yCoordinate;
      cpu.I = 0x300;
      cpu.Memory[cpu.I] = 0x1;

      var decodedInstruction = new DecodedInstruction(0xD231);

      // Expected execution result:
      // - decodedInstruction.n bytes (1) are read from memory, starting at location I (0x300)
      // - those bytes are written to screen, starting at location (V2, V3) = 5,6
      // - since value at 0x300 is 0x1, and 1 is the least significant bit of that byte, then location where 
      //   pixel will be set is: xCoordinate + 7 (e.g. for value of 2, it would be xCoordinate + 6)
      // - re-executing the same command will reset the pixel and set VF register to 1
      var mockSequence = new MockSequence();
      var displayMock = new Mock<IDisplay>(MockBehavior.Strict);

      // First execution
      for(byte i = 0; i < 8; i++)
      {
        displayMock.InSequence(mockSequence).Setup(x => x.GetPixel(
          (byte)(xCoordinate + i), yCoordinate)).Returns(false);
      }
      displayMock.InSequence(mockSequence).Setup(x => x.SetPixel(xCoordinate + 7, yCoordinate));

      // Second execution
      for (byte i = 0; i < 8; i++)
      {
        displayMock.InSequence(mockSequence).Setup(x => x.GetPixel(
          (byte)(xCoordinate + i), yCoordinate)).Returns(i == 7);
      }
      displayMock.InSequence(mockSequence).Setup(x => x.ClearPixel(xCoordinate + 7, yCoordinate));

      var display = displayMock.Object;
      var instruction = new Instruction_Dxyn(decodedInstruction);

      instruction.Execute(cpu, display, MockedKeyboard);
      Assert.That(cpu.V[0xF], Is.EqualTo(0));

      instruction.Execute(cpu, display, MockedKeyboard);
      Assert.That(cpu.V[0xF], Is.EqualTo(1));

      displayMock.VerifyAll();
      Assert.That(instruction.Mnemonic, Is.EqualTo($"DRW V{decodedInstruction.x:X}, V{decodedInstruction.y:X}, {decodedInstruction.n:X}"));
    }
Example #22
0
        public void Executing_Instruction_Fx1E_WorksAsExpected(byte vxValue, ushort iValue, ushort expectedIValue)
        {
            var cpu = new Cpu {
                I = iValue
            };
            var decodedInstruction = new DecodedInstruction(0xFA1E);

            cpu.V[decodedInstruction.x] = vxValue;

            var instruction = new Instruction_Fx1E(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.I, Is.EqualTo(expectedIValue));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"ADD I, V{decodedInstruction.x:X}"));
        }
Example #23
0
        public void Executing_Instruction_8xy4_WorksAsExpected(byte value1, byte value2, byte expectedSum, byte expectedCarry)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0x8AB4);

            cpu.V[decodedInstruction.x] = value1;
            cpu.V[decodedInstruction.y] = value2;

            var instruction = new Instruction_8xy4(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(expectedSum));
            Assert.That(cpu.V[0xF], Is.EqualTo(expectedCarry));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"ADD V{decodedInstruction.x:X}, V{decodedInstruction.y:X}"));
        }
Example #24
0
        public void Executing_Instruction_8xy0_WorksAsExpected()
        {
            var        cpu = new Cpu();
            var        decodedInstruction = new DecodedInstruction(0x8AB0);
            const byte value = 0xAB;

            cpu.V[decodedInstruction.y] = value;

            var instruction = new Instruction_8xy0(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(value));
            Assert.That(cpu.V[decodedInstruction.y], Is.EqualTo(value));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"LD V{decodedInstruction.x:X}, V{decodedInstruction.y:X}"));
        }
Example #25
0
        public void OnNextOpcode(CPU_6510 _cpu, DecodedInstruction _instr)
        {
            ushort adr = _instr.PC;

            lastTraceIndex++;
            if (lastTraceIndex >= 64)
            {
                lastTraceIndex = 0;
            }

            Trace[lastTraceIndex] = _instr;

            ushort a0 = adr;

            if (adr == 0xBE1D)
            {
            }

            // TraceOPCodes = false;
            if (IsBreakpoint(adr))
            {
                //TraceOPCodes = true;
            }
            // TraceOPCodes = false;

            // AddBreakpoint(0xB91D);

            if (false)
            {
                string func = "";
                if (KernalFunctions.TryGetValue(adr, out func))
                {
                    Console.Out.WriteLine("${0,4:X4}: {1}", adr, func);
                }
            }

            if (TraceOPCodes)
            {
                string func = "";
                if (KernalFunctions.TryGetValue(adr, out func))
                {
                    Console.Out.WriteLine("${0,4:X4}: {1}", adr, func);
                }

                Console.Out.WriteLine(_instr.ToString());
            }
        }
Example #26
0
        public void Executing_Instruction_9xy0_WorksAsExpected(bool vxEqualToVy)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0x9460);

            cpu.V[decodedInstruction.x] = 0x1;
            cpu.V[decodedInstruction.y] = vxEqualToVy ? (byte)0x1 : (byte)0x2;

            var instruction = new Instruction_9xy0(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            var pcOffset = vxEqualToVy ? 0 : 2;

            Assert.That(cpu.PC, Is.EqualTo(Cpu.MemoryAddressOfFirstInstruction + pcOffset));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"SNE V{decodedInstruction.x:X}, V{decodedInstruction.y:X}"));
        }
Example #27
0
        private void recursiveTranversal(ushort addr, byte[] rom)
        {
            while (addr >= 0 && addr <= rom.Length)
            {
                if (!addrDecodeCheck[addr])
                {
                    DecodedInstruction instruct = dissaembleInstruc((ushort)((rom[addr] << 8) | rom[addr + 1]), addr);
                    decodedRom.Add(instruct);
                    addrDecodeCheck[addr] = true;

                    byte opcode = Utli.getUpperByteHighNibble(instruct.Opcode);

                    //branch instruction check
                    if (opcode == 1) //non conditional jump
                    {
                        recursiveTranversal((ushort)((instruct.Opcode & 0x0FFF) - Chip8.ROM_BASE_ADDR), rom);
                        return;
                    }
                    else if (opcode == 2)// subroutine call,
                    {
                        //2 brances. first branch is the call, second is the return branch
                        recursiveTranversal((ushort)((instruct.Opcode & 0x0FFF) - Chip8.ROM_BASE_ADDR), rom);
                        recursiveTranversal((ushort)((instruct.AddrOfInstruc + 2)), rom);
                        return;
                    }
                    else if (instruct.Opcode == 0x00EE) //end subroutine
                    {
                        return;
                    }//3,5,4,9
                    else if (opcode == 3 || opcode == 5 || opcode == 4 || opcode == 9 || opcode == 0xE) //primitive conditional branching
                    {
                        recursiveTranversal((ushort)((instruct.AddrOfInstruc + 2)), rom);
                        recursiveTranversal((ushort)((instruct.AddrOfInstruc + 4)), rom);
                        return;
                    }
                    else
                    {
                        addr = (ushort)(addr + 2);
                    }
                }
                else
                {
                    return;
                }
            }
        }
Example #28
0
        public void Executing_Instruction_8xy2_WorksAsExpected()
        {
            var        cpu = new Cpu();
            var        decodedInstruction = new DecodedInstruction(0x8AB2);
            const byte value1             = 0xCD;
            const byte value2             = 0xEF;

            cpu.V[decodedInstruction.x] = value1;
            cpu.V[decodedInstruction.y] = value2;

            var instruction = new Instruction_8xy2(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.V[decodedInstruction.x], Is.EqualTo(value1 & value2));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"AND V{decodedInstruction.x:X}, V{decodedInstruction.y:X}"));
        }
Example #29
0
        public void Executing_Instruction_Fx33_WorksAsExpected(byte vx, ushort initialIValue, byte expectedHundreds, byte expectedTens, byte expectedOnes)
        {
            var cpu = new Cpu {
                I = initialIValue
            };
            var decodedInstruction = new DecodedInstruction(0xFA33);

            cpu.V[decodedInstruction.x] = vx;

            var instruction = new Instruction_Fx33(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            Assert.That(cpu.Memory[initialIValue], Is.EqualTo(expectedHundreds));
            Assert.That(cpu.Memory[initialIValue + 1], Is.EqualTo(expectedTens));
            Assert.That(cpu.Memory[initialIValue + 2], Is.EqualTo(expectedOnes));
            Assert.That(cpu.I, Is.EqualTo(initialIValue + 2));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"LD B, V{decodedInstruction.x:X}"));
        }
Example #30
0
        public void Executing_Instruction_4xkk_WorksAsExpected(bool vxEqualToKk)
        {
            var cpu = new Cpu();
            var decodedInstruction = new DecodedInstruction(0x4468);

            if (vxEqualToKk)
            {
                cpu.V[decodedInstruction.x] = decodedInstruction.kk;
            }

            var instruction = new Instruction_4xkk(decodedInstruction);

            instruction.Execute(cpu, MockedDisplay, MockedKeyboard);

            var pcOffset = (vxEqualToKk == true) ? 0 : 2;

            Assert.That(cpu.PC, Is.EqualTo(Cpu.MemoryAddressOfFirstInstruction + pcOffset));
            Assert.That(instruction.Mnemonic, Is.EqualTo($"SNE V{decodedInstruction.x:X}, 0x{decodedInstruction.kk:X}"));
        }
Example #31
0
 private static void TestInstructionsManaged(DecodedInstruction[] insts)
 {
     Assert.That(insts, Has.Length.EqualTo(3));
       Assert.That(insts[0].Offset.ToInt32(), Is.EqualTo(0x1000));
       Assert.That(insts[0].Mnemonic, Is.EqualTo("RET"));
       Assert.That(insts[1].Offset.ToInt32(), Is.EqualTo(0x1001));
       Assert.That(insts[1].Mnemonic, Is.EqualTo("XOR"));
       Assert.That(insts[2].Offset.ToInt32(), Is.EqualTo(0x1003));
       Assert.That(insts[2].Mnemonic, Is.EqualTo("RET"));
 }
Example #32
0
        public void PerformDecode()
        {
            while (!areWeDone)
            {
                decodeEvent.WaitOne();
                Console.WriteLine("In Decode");
                if (fetched_instructions.Count > 0)
                {
                    FetchedInstruction instr = fetched_instructions.Dequeue();
                    
                    Console.WriteLine("Decode counter is: " + Decode_Counter);
                    DecodedInstruction decodedInstr = new DecodedInstruction(instr.binary, instr.index);
                    decoded_instructions.Enqueue(decodedInstr);
                    Decode_IR = decodedInstr;
                    //If Branch, then add to table.
                    if (decodedInstr.opcode == "100")
                    {
                        currBranchInstr = Memory.getAssemblyInstructions().ElementAt(decodedInstr.index);
                        branches.Add(new branchClass(decodedInstr.index));
                    }
                    else
                    {
                        currBranchInstr = "";

                    }

                    Console.WriteLine("Just decoded: " + decodedInstr.binary);

                    if (OnDecodeDone != null)
                    {
                        OnDecodeDone(this, new DecodeEventArgs(decodedInstr));
                        //OnDecodeDone(this, new StageDoneEventArgs(instr.index, StageType.Decode));
                    }
                    /*if (OnStageDone != null)
                    {
                        OnStageDone(this, new StageDoneEventArgs(StageType.Decode));
                    }*/
                    Decode_Counter++;
                }
                CPU_OnStageDone(StageType.Decode);                
            }
        }
Example #33
0
        public void executeInstruction(DecodedInstruction instr)
        {

            //PC++;
            string binaryString = Convert.ToString(instr.binary, 2).PadLeft(16, '0');
            String opcode = instr.opcode;
            String command = instr.command;
            String flag = instr.flag;
            short value = instr.value;
            int instrIndex = instr.index;
            //Defaults to none for things like NOP and branches
            ExecutedInstruction executedInstr = new ExecutedInstruction(0, StoreType.None, instrIndex);           

            Console.WriteLine("Executing ---->" + binaryString + " O " + opcode + " C " + command + " F " + flag + " V " + value);

            switch (opcode)
            {
                case "000":// --------------GROUP1
                    if(command == "0000"){ // NOP
                        Debug.WriteLine("NOP has been reached");
                        //return;
                    }
                    else{ // HLT
                        //DO HLT 
                        Debug.WriteLine("HLT has been reached");
                        //return;
                    }
                    break;
                case "001":// ------------GROUP2
                    if(command == "0001"){ //LDA
                        //Maybe signal to the GUI here that there was a load-use delay
                        if (!bypassing)
                        {
                            //penalty for a load-use delay is 1 cycle
                            cycle_penalties++;
                        }
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("LDA# has been reached");
                            //ACC = value;
                            executedInstr = new ExecutedInstruction(value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("LDA$ has been reached");
                            //ACC = Memory.stack[value];
                            //ACC = memory[value];
                            executedInstr = new ExecutedInstruction(memory[value], StoreType.Accumulator, instrIndex);
                        }
                    }
                    if(command == "0010"){ //STA
                        Debug.WriteLine("STA has been reached");
                        //Memory.stack[value] = ACC;
                        //memory[value] = ACC;
                        executedInstr = new ExecutedInstruction(ACC, StoreType.Memory, instrIndex, value);
                        Debug.Write("Stored the value " + ACC + " into stack at index " + value);
                    }
                    else if(command == "1010"){
                        Debug.WriteLine("STA special has been reached");
                        TEMP = ACC;
                        Debug.WriteLine("TEMP = " + TEMP);
                    }
                    break;
                case "010":// --------------GROUP3
                    if(command == "0001"){ //ADD
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("ADD# has been reached");
                            Debug.Write("Value is " + value);
                            //ACC += value;
                            executedInstr = new ExecutedInstruction(ACC + value, StoreType.Accumulator, instrIndex);
                            Debug.Write(" ACC is " + ACC);
                        }
                        else{
                            //$
                            Debug.WriteLine("ADD$ has been reached");
                            //ACC += Memory.stack[value];
                            //ACC += memory[value];
                            executedInstr = new ExecutedInstruction(ACC + memory[value], StoreType.Accumulator, instrIndex);
                        }
                        break;
                    }
                    if (command == "1001")//Special add
                    {
                        Debug.WriteLine("Special ADD has been reached");
                        ACC += TEMP;
                    }
                    if(command == "0010"){ // SUB
                      if(flag == "1"){
                            //#
                          Debug.WriteLine("SUB# has been reached");
                          Debug.WriteLine("ACC is " + ACC + " and value is " + value);
                          //ACC -= value;
                          executedInstr = new ExecutedInstruction(ACC - value, StoreType.Accumulator, instrIndex);
                          Debug.WriteLine("ACC is now " + ACC);
                        }
                        else{
                           //$
                            //int temp = Memory.stack[value];
                            //int temp1 = memory[value];
                            Debug.WriteLine("SUB$ has been reached");
                            //Debug.WriteLine("ACC is " + ACC + " and value is " + temp1);
                            //ACC -= temp;
                            executedInstr = new ExecutedInstruction(ACC - memory[value], StoreType.Accumulator, instrIndex);
                            Debug.WriteLine("ACC is now " + ACC);
                        }
                    }
                    if(command == "0011"){//MUL
                        //maybe signal to the GUI that there was a hazard
                        cycle_penalties = cycle_penalties + 4;
                        mdHazard = true;
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("MUL# has been reached");
                            //ACC = ACC * value;
                            executedInstr = new ExecutedInstruction(ACC * value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("MUL$ has been reached");
                            //ACC = ACC * Memory.stack[value];
                            //ACC = ACC * memory[value];
                            executedInstr = new ExecutedInstruction(ACC * memory[value], StoreType.Accumulator, instrIndex);
                        }
                    }
                    if(command == "0100"){//DIV
                        //maybe signal to the GUI that there was a hazard
                        cycle_penalties = cycle_penalties + 4;
                        mdHazard = true;
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("DIV# has been reached");
                            //ACC = ACC / value;
                            executedInstr = new ExecutedInstruction(ACC / value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("DIV$ has been reached");
                            //ACC = ACC / Memory.stack[value];
                            //ACC = ACC / memory[value];
                            executedInstr = new ExecutedInstruction(ACC / memory[value], StoreType.Accumulator, instrIndex);

                        }
                    }
                    if(command == "0101"){//SHL
                      //SHL things
                        Debug.WriteLine("SHL has been reached");
                        ACC = ACC << value;
                    }
                    break;
                case "011": //-----------------GROUP4
                    if(command == "0001"){//AND
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("AND# has been reached");
                            //ACC = ACC & value;
                            executedInstr = new ExecutedInstruction(ACC & value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            //int temp = Memory.stack[value];
                            //int temp = memory[value];
                            Debug.WriteLine("AND$ has been reached");
                            //Debug.WriteLine("ACC is " + ACC + " and value is " + temp);
                            //ACC = ACC & temp;
                            executedInstr = new ExecutedInstruction(ACC & memory[value], StoreType.Accumulator, instrIndex);
                            Debug.WriteLine("ACC is now " + ACC);
                        }
                    }
                    if(command == "0010"){//OR
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("OR# has been reached");
                            //ACC = ACC | (ushort)value; // Do we need to cast here? perhaps
                            executedInstr = new ExecutedInstruction(ACC | (ushort)value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("OR$ has been reached");
                            //ACC = ACC | Memory.stack[value];
                            //ACC = ACC | memory[value];
                            executedInstr = new ExecutedInstruction(ACC | memory[value], StoreType.Accumulator, instrIndex);
                        }
                    }
                    if(command == "0011"){//NOTA
                      //NOTA things
                        Debug.WriteLine("NOTA# has been reached");
                        Debug.WriteLine("!" + ACC + " is " + ~ACC);
                        //ACC = ~ACC; // I think ~ is a bitwise not
                        executedInstr = new ExecutedInstruction(~ACC, StoreType.Accumulator, instrIndex);
                    }
                    break;
                case "100": // ------------------GROUP5
                    tookBranch = false;
                    if (command == "0001"){//BA
                        Debug.WriteLine("BA has been reached");
                        
                        tookBranch = true;
                    } 
                    if(command == "0010"){//BE
                        Debug.WriteLine("BE has been reached");
                        if (CC == 0)
                        {
                            
                            tookBranch = true;
                        }
                    } 
                    if(command == "0011"){//BL
                        Debug.WriteLine("BL has been reached");
                        if (CC < 0)
                        {
                            
                            tookBranch = true;
                        }
                    }
                    if (command == "0100"){//BG
                        Debug.WriteLine("BG has been reached");
                        if (CC > 0)
                        {
                            
                            tookBranch = true;
                        }
                    }

                    foreach (var branch in branches)
                    {
                        if (branch.branchlabel.CompareTo(Memory.getAssemblyInstructions().ElementAt(instrIndex)) == 0)
                        {
                            branch.numTaken++;
                            branch.updateChoice(tookBranch);
                        }
                    }

                    if (tookBranch)
                    {

                        //Normal branching code
                        PC = (short)(value-1);//think it was -1 due to the PC incrementing after// PC = (short)(value - 1);
                        Fetch_Counter = PC+1;
                        Decode_Counter = -1;//PC
                        Execute_Counter = -1;//PC
                        fetched_instructions.Clear();
                        decoded_instructions.Clear();
                        executed_instructions.Clear();
                        //penalty for a taken branch is 1 cycle
                        cycle_penalties++;
                        //gotta call something here to flush out pipeline queue in GUI
                        //moved to execute thread
                        if (OnBranch != null)
                        {
                            OnBranch(this, new BranchEventArgs(instr, instrIndex, true));
                            //OnFetchDone(this, new FetchEventArgs(0, -1));
                            //OnDecodeDone(this, new DecodeEventArgs(null, -1));
                            //OnExecuteDone(this, new ExecuteEventArgs(0, -1));

                        }
                    }
                    else
                    {
                        if (OnBranch != null)
                        {
                            OnBranch(this, new BranchEventArgs(instr, instrIndex, false));
                        }
                    }
                    break;
            }

            //This is to avoid the next instruction being a branch and depending on the
            //cc to be updated from the previous instruction when it goes to store
            if (executedInstr.type == StoreType.Accumulator)
            {
                if (executedInstr.result > 0)
                {
                    CC = 1;
                }
                else if (executedInstr.result < 0)
                {
                    CC = -1;
                }
                else CC = 0;
            }
            //Passes the result of execute to the store stage, to be stored next cycle
            executed_instructions.Enqueue(executedInstr);

            return;
        }