Esempio n. 1
0
        void CPU_BreakpointHit(object sender, BreakpointEventArgs e)
        {
            if (stepOverEnabled)
            {
                CPU.Breakpoints.Remove(CPU.Breakpoints.Where(b => b.Address == CPU.PC).First());
                e.ContinueExecution = false;
                (sender as DCPU).IsRunning = false;
                disassemblyDisplay1.EnableUpdates = true;
                ResetLayout();
                stepOverEnabled = false;
                return;
            }

            (sender as DCPU).IsRunning = false;
            ResetLayout();
        }
Esempio n. 2
0
 static void CPU_BreakpointHit(object sender, BreakpointEventArgs e)
 {
     e.ContinueExecution = false;
     CPU.IsRunning = false;
     Console.WriteLine("Breakpoint hit: 0x" + e.Breakpoint.Address.ToString("X4"));
     ParseInput("dasm"); ParseInput("list registers"); Console.Write(">");
 }
Esempio n. 3
0
        public void Execute(int CyclesToExecute)
        {
            if (!IsRunning && CyclesToExecute != -1)
                return;
            int oldCycles = Cycles;
            if (CyclesToExecute == -1)
                Cycles = 1;
            else
                Cycles += CyclesToExecute;
            while (Cycles > 0)
            {
                if (IsOnFire)
                    Memory[Random.Next(0xFFFF)] = (ushort)Random.Next(0xFFFF);
                if (!InterruptQueueEnabled && InterruptQueue.Count > 0 && IA != 0)
                {
                    Memory[--SP] = PC;
                    Memory[--SP] = A;
                    PC = IA;
                    A = InterruptQueue.Dequeue();
                    InterruptQueueEnabled = true;
                }
                if (BreakpointHit != null)
                {
                    foreach (var breakpoint in Breakpoints)
                    {
                        if (breakpoint.Address == PC)
                        {
                            if (breakpointHandled || (CyclesToExecute == -1))
                            {
                                breakpointHandled = false;
                            }
                            else
                            {
                                var bea = new BreakpointEventArgs(breakpoint);
                                BreakpointHit(this, bea);
                                if (!bea.ContinueExecution)
                                {
                                    breakpointHandled = true;
                                    return;
                                }
                            }
                            break;
                        }
                    }
                }

                ushort PCBeforeExecution = PC;
                ushort instruction = Memory[PC++];
                byte opcode = (byte)(instruction & 0x1F);
                byte valueB = (byte)((instruction & 0x3E0) >> 5);
                byte valueA = (byte)((instruction & 0xFC00) >> 10);
                ushort opA = 0, opB = 0;
                opA = Get(valueA);
                if (opcode != 0)
                {
                    ushort pc_old = PC, sp_old = SP;
                    opB = Get(valueB);
                    PC = pc_old;
                    SP = sp_old;
                }
                short opB_s = (short)opB;
                short opA_s = (short)opA;
                Cycles--;
                unchecked
                {
                    switch (opcode)
                    {
                        case 0x00: // (nonbasic)
                            switch (valueB)
                            {
                                case 0x01: // JSR a
                                    Cycles -= 2;
                                    Memory[--SP] = PC;
                                    PC = opA;
                                    break;
                                case 0x08: // INT a
                                    Cycles -= 3;
                                    FireInterrupt(opA);
                                    break;
                                case 0x09: // IAG a
                                    Set(valueA, IA);
                                    break;
                                case 0x0A: // IAS a
                                    IA = opA;
                                    break;
                                case 0x0B: // RFI a
                                    A = Memory[SP++];
                                    PC = Memory[SP++];
                                    InterruptQueueEnabled = false;
                                    break;
                                case 0x0C: // IAQ a
                                    Cycles--;
                                    InterruptQueueEnabled = opA != 0;
                                    break;
                                case 0x10: // HWN a
                                    Cycles--;
                                    Set(valueA, (ushort)Devices.Count);
                                    break;
                                case 0x11: // HWQ a
                                    Cycles -= 3;
                                    if (opA < Devices.Count)
                                    {
                                        Device d = Devices[opA];
                                        A = (ushort)(d.DeviceID & 0xFFFF);
                                        B = (ushort)((d.DeviceID & 0xFFFF0000) >> 16);
                                        C = d.Version;
                                        X = (ushort)(d.ManufacturerID & 0xFFFF);
                                        Y = (ushort)((d.ManufacturerID & 0xFFFF0000) >> 16);
                                    }
                                    break;
                                case 0x12: // HWI a
                                    Cycles -= 3;
                                    if (opA < Devices.Count)
                                        Cycles -= Devices[opA].DoInterrupt();
                                    break;
                                default:
                                    if (InvalidInstruction != null)
                                    {
                                        var eventArgs = new InvalidInstructionEventArgs(instruction, PCBeforeExecution);
                                        PC = PCBeforeExecution;
                                        InvalidInstruction(this, eventArgs);
                                        if (!eventArgs.ContinueExecution)
                                            return;
                                    }
                                    break;
                            }
                            break;
                        case 0x01: // SET b, a
                            Set(valueB, opA);
                            break;
                        case 0x02: // ADD b, a
                            Cycles--;
                            if (opB + opA > 0xFFFF)
                                EX = 0x0001;
                            else
                                EX = 0;
                            Set(valueB, (ushort)(opB + opA));
                            break;
                        case 0x03: // SUB b, a
                            Cycles--;
                            if (opB - opA < 0)
                                EX = 0xFFFF;
                            else
                                EX = 0;
                            Set(valueB, (ushort)(opB - opA));
                            break;
                        case 0x04: // MUL b, a
                            Cycles--;
                            EX = (ushort)(((opB * opA) >> 16) & 0xffff);
                            Set(valueB, (ushort)(opB * opA));
                            break;
                        case 0x05: // MLI b, a
                            Cycles--;
                            EX = (ushort)(((opB_s * opA_s) >> 16) & 0xffff);
                            Set(valueB, (ushort)(opB_s * opA_s));
                            break;
                        case 0x06: // DIV b, a
                            Cycles -= 2;
                            if (opA == 0)
                            {
                                EX = 0;
                                Set(valueB, 0);
                            }
                            else
                            {
                                EX = (ushort)(((opB << 16) / opA) & 0xffff);
                                Set(valueB, (ushort)(opB / opA));
                            }
                            break;
                        case 0x07: // DVI b, a
                            Cycles -= 2;
                            if (opA_s == 0)
                            {
                                EX = 0;
                                Set(valueB, 0);
                            }
                            else
                            {
                                EX = (ushort)(((opB_s << 16) / opA_s) & 0xffff);
                                Set(valueB, (ushort)(opB_s / opA_s));
                            }
                            break;
                        case 0x08: // MOD b, a
                            Cycles -= 2;
                            if (opA == 0)
                                Set(valueB, 0);
                            else
                                Set(valueB, (ushort)(opB % opA));
                            break;
                        case 0x09: // MDI b, a
                            Cycles -= 2;
                            if (opA_s == 0)
                                Set(valueB, 0);
                            else
                                Set(valueB, (ushort)(opB_s % opA_s));
                            break;
                        case 0x0A: // AND b, a
                            Set(valueB, (ushort)(opB & opA));
                            break;
                        case 0x0B: // BOR b, a
                            Set(valueB, (ushort)(opB | opA));
                            break;
                        case 0x0C: // XOR b, a
                            Set(valueB, (ushort)(opB ^ opA));
                            break;
                        case 0x0D: // SHR b, a
                            EX = (ushort)(((opB << 16) >> opA) & 0xffff);
                            Set(valueB, (ushort)(opB >> opA));
                            break;
                        case 0x0E: // ASR b, a
                            EX = (ushort)(((opB_s << 16) >> opA) & 0xffff);
                            Set(valueB, (ushort)(opB_s >> opA));
                            break;
                        case 0x0F: // SHL b, a
                            EX = (ushort)(((opB << opA) >> 16) & 0xffff);
                            Set(valueB, (ushort)(opB << opA));
                            break;
                        case 0x10: // IFB b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!((ushort)(opB & opA) != 0))
                                SkipIfChain();
                            break;
                        case 0x11: // IFC b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!((ushort)(opB & opA) == 0))
                                SkipIfChain();
                            break;
                        case 0x12: // IFE b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!(opB == opA))
                                SkipIfChain();
                            break;
                        case 0x13: // IFN b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!(opB != opA))
                                SkipIfChain();
                            break;
                        case 0x14: // IFG b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!(opB > opA))
                                SkipIfChain();
                            break;
                        case 0x15: // IFA b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!(opB_s > opA_s))
                                SkipIfChain();
                            break;
                        case 0x16: // IFL b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!(opB < opA))
                                SkipIfChain();
                            break;
                        case 0x17: // IFU b, a
                            Cycles -= 2;
                            Get(valueB);
                            if (!(opB_s < opA_s))
                                SkipIfChain();
                            break;
                        case 0x1A: // ADX b, a
                            Cycles -= 2;
                            uint resADX = (uint)(opB + opA + (short)EX);
                            EX = (ushort)((resADX >> 16) & 0xFFFF);
                            Set(valueB, (ushort)resADX);
                            break;
                        case 0x1B: // SBX b, a
                            Cycles -= 2;
                            uint resSBX = (uint)(opB - opA + (short)EX);
                            EX = (ushort)((resSBX >> 16) & 0xFFFF);
                            Set(valueB, (ushort)resSBX);
                            break;
                        case 0x1E: // STI b, a
                            Cycles--;
                            Set(valueB, opA);
                            I++;
                            J++;
                            break;
                        case 0x1F: // STD b, a
                            Cycles--;
                            Set(valueB, opA);
                            I--;
                            J--;
                            break;
                        default:
                            // According to spec, should take zero cycles
                            // For sanity, all NOPs take one cycle
                            if (InvalidInstruction != null)
                            {
                                var eventArgs = new InvalidInstructionEventArgs(instruction, PCBeforeExecution);
                                PC = PCBeforeExecution;
                                InvalidInstruction(this, eventArgs);
                                if (!eventArgs.ContinueExecution)
                                    return;
                            }
                            break;
                    }
                }
                if (!IsRunning && CyclesToExecute != -1)
                    return;
            }
            if (CyclesToExecute == -1)
            {
                TotalCycles += -(Cycles - 1);
                Cycles = oldCycles;
            }
            else
                TotalCycles += CyclesToExecute;
        }