/// @brief Reset the propeller CPU to initial state.
        /// @details Release cog instances, clock sources, clear locks and pins, and reset plugins.
        /// @version 15.03.26 - Separate reset loops for clock sources, cogs and locks.
        public void Reset()
        {
            ResetMemory.CopyTo(Memory, 0);

            SystemCounter = 0;
            Time          = 0;
            RingPosition  = 0;
            for (int i = 0; i < ClockSources.Length; i++)   //clear clock source references
            {
                ClockSources[i] = null;
            }
            for (int i = 0; i < TOTAL_COGS; i++)    //clear cog references
            {
                Cogs[i] = null;
            }
            CogsRunning = 0;

            for (int i = 0; i < TOTAL_LOCKS; i++)    //clear locks state
            {
                LocksAvailable[i] = true;
                LocksState[i]     = false;
            }

            PinChanged();   //update situation of pins

            foreach (PluginCommon plugin in PlugIns)
            {
                plugin.OnReset();
            }

            SetClockMode((byte)(ClockMode & 0x7F));

            // Start the runtime in interpreted mode (fake boot)

            // Pushes the 3 primary offsets (local offset, var offset, and object offset)
            // Stack -1 is the boot parameter

            uint InitFrame = ReadWord(10);

            WriteWord(InitFrame - 8, ReadWord(6));  // Object
            WriteWord(InitFrame - 6, ReadWord(8));  // Var
            WriteWord(InitFrame - 4, ReadWord(12)); // Local
            WriteWord(InitFrame - 2, ReadWord(14)); // Stack

            // Boot parameter is Initial PC in the lo word, and the stack frame in the hi word
            ClockSources[0] = new PLLGroup();

            Cogs[0]     = new InterpretedCog(this, InitFrame, CoreFreq, (PLLGroup)ClockSources[0]);
            CogsRunning = 1;
        }
Exemplo n.º 2
0
        private void Repaint(bool tick, InterpretedCog host)
        {
            Graphics g = Graphics.FromImage((Image)BackBuffer);
            Brush    brush;

            g.Clear(SystemColors.Control);

            String display;
            uint   topLine, bottomLine;

            topLine    = 5;
            bottomLine = (uint)((ClientRectangle.Height / MonoFont.Height) - 5);

            zeroFlagLabel.Text   = "";
            carryFlagLabel.Text  = "";
            OpcodeSize.Visible   = true;
            DisplayUnits.Visible = true;

            if (memoryViewButton.Checked)
            {
                for (uint i = (uint)positionScroll.Value, y = 0;
                     y < ClientRectangle.Height;
                     y += (uint)MonoFont.Height, i++)
                {
                    if ((i > 0xFFFF) || (i < 0))
                    {
                        continue;
                    }

                    uint mem = host[(int)i];

                    string binary = Convert.ToString((long)mem, 2);

                    while (binary.Length < 32)
                    {
                        binary = "0" + binary;
                    }

                    display = String.Format("{0:X4}:  {1:X8}   {2}   ",
                                            i, mem, binary);
                    if (displayAsHexadecimal)
                    {
                        display = display + String.Format("{0:X8}", mem);
                    }
                    else
                    {
                        display = display + String.Format("{0}", mem);
                    }

                    g.FillRectangle(SystemBrushes.Control, 0, y, assemblyPanel.Width, y + MonoFont.Height);

                    g.DrawString(
                        display,
                        (host.ProgramCursor == i) ? MonoFontBold : MonoFont,
                        SystemBrushes.ControlText, 0, y);
                }
            }
            else
            {
                uint y = 0;

                for (uint i = (uint)positionScroll.Value, line = 1; y < ClientRectangle.Height; y += (uint)MonoFont.Height, line++)
                {
                    if (i > 0xFFFF)
                    {
                        continue;
                    }

                    uint start = i;

                    Propeller.MemoryManager mem = new Propeller.MemoryManager(Chip, i);
                    string inst = InstructionDisassembler.InterpreterText(mem, displayAsHexadecimal, useShortOpcodes);
                    i                   = mem.Address;
                    display             = String.Format("{0:X4}: ", start);
                    InterpAddress[line] = start;

                    for (uint q = start; q < start + 4; q++)
                    {
                        if (q < i)
                        {
                            byte b = Chip.DirectReadByte(q);
                            display += String.Format(" {0:X2}", b);
                        }
                        else
                        {
                            display += "   ";
                        }
                    }


                    display += "  " + inst;

                    if (InterpAddress[line] == host.BreakPoint)
                    {
                        brush = System.Drawing.Brushes.Pink;
                    }
                    else if ((!followPCButton.Checked) || (line <= topLine) || (line >= bottomLine))
                    {
                        brush = SystemBrushes.Control;
                    }
                    else
                    {
                        brush = SystemBrushes.Window;
                    }
                    g.FillRectangle(brush, 0, y, assemblyPanel.Width, y + MonoFont.Height);

                    g.DrawString(
                        display,
                        (host.ProgramCursor == start) ? MonoFontBold : MonoFont,
                        SystemBrushes.ControlText, 0, y);
                }

                StringBrush = SystemBrushes.ControlText;
                StringY     = 0;
                StringX     = (uint)(assemblyPanel.Width - StackMargin);

                DrawString(g, String.Format("@Stk[0] = ${0:X4} {0}", host.Stack));
                DrawString(g, String.Format("@Obj[0] = ${0:X4} {0}", host.Object));
                DrawString(g, String.Format("@Loc[0] = ${0:X4} {0}", host.Local));
                DrawString(g, String.Format("@Var[0] = ${0:X4} {0}", host.Variable));
                g.DrawLine(Pens.Black, assemblyPanel.Width - StackMargin, StringY, assemblyPanel.Width, StringY);
                DrawString(g, String.Format("Caller& = ${0:X4} {0}", Chip.DirectReadWord(host.Local - 8)));
                DrawString(g, String.Format("          ${0:X4} {0}", Chip.DirectReadWord(host.Local - 6)));
                DrawString(g, String.Format("          ${0:X4} {0}", Chip.DirectReadWord(host.Local - 4)));
                DrawString(g, String.Format("Return& = ${0:X4}", Chip.DirectReadWord(host.Local - 2)));
                g.DrawLine(Pens.Black, assemblyPanel.Width - StackMargin, StringY, assemblyPanel.Width, StringY);

                for (uint i = host.Local; i < host.Stack && StringY < ClientRectangle.Height; i += 4)
                {
                    DrawString(g, String.Format("${0:X8}  {0}", (int)Chip.DirectReadLong(i)));
                }
            }
        }
        /// @brief Execute the hub operations.
        /// @details This method is called from a cog to do the operations related to all the CPU.
        /// @version 15.03.26 - corrected problem in COGSTOP return.
        /// @param[in] caller Reference to the caller Cog of this method.
        /// @param[in] operation Hub operation to execute.
        /// @param[in] argument Parameter given to the opcode (destination field in PASM).
        /// @param[in,out] carry Carry flag that could be affected by the operation.
        /// @param[in,out] zero Zero flag that could be affected by the operation.
        /// @returns Value depending on operation.
        /// @note Reference of supported Operations, based in Propeller Manual v1.2:
        /// @arg HUBOP_CLKSET - page 271.
        /// @arg HUBOP_COGID - page 283.
        /// @arg HUBOP_COGINIT - page 284.
        /// @arg HUBOP_COGSTOP - page 286.
        /// @arg HUBOP_LOCKNEW - page 304.
        /// @arg HUBOP_LOCKRET - page 305.
        /// @arg HUBOP_LOCKSET - page 306.
        /// @arg HUBOP_LOCKCLR - page 303.
        public uint HubOp(Cog caller, uint operation, uint argument, ref bool carry, ref bool zero)
        {
            uint maskedArg = (argument & 0x7);
            uint cog       = (uint)Cogs.Length;

            switch ((HubOperationCodes)operation)
            {
            case HubOperationCodes.HUBOP_CLKSET:
                zero  = false;
                carry = false;
                SetClockMode((byte)argument);
                break;

            case HubOperationCodes.HUBOP_COGID:
                carry = false;
                cog   = CogID(caller);
                zero  = (cog == 0) ? true : false;
                return(cog);

            case HubOperationCodes.HUBOP_COGINIT:
                //determine witch cog start
                if ((argument & 0x8) != 0)                 //if free cog should be started (bit 3 is set)
                {
                    for (uint i = 0; i < Cogs.Length; i++) //assign the first free cog
                    {
                        if (Cogs[i] == null)
                        {
                            cog = i;
                            break;
                        }
                    }
                    if (cog >= Cogs.Length)
                    {
                        carry = true;       //no free cog
                        return(0xFFFFFFFF);
                    }
                    else
                    {
                        carry = false;
                    }
                }
                else      // instead specific cog should be started
                {
                    cog = maskedArg;
                }

                zero = (cog == 0) ? true : false;

                PLLGroup pll = new PLLGroup();
                ClockSources[cog] = (ClockSource)pll;
                uint param = (argument >> 16) & 0xFFFC;       //decode param value
                uint progm = (argument >> 2) & 0xFFFC;        //decode program address to load to
                if (progm == 0xF004)
                {
                    Cogs[cog] = new InterpretedCog(this, param, CoreFreq, pll);
                }
                else
                {
                    Cogs[cog] = new NativeCog(this, progm, param, CoreFreq, pll);
                }
                CogsRunning++;
                return((uint)cog);

            case HubOperationCodes.HUBOP_COGSTOP:
                zero  = (maskedArg == 0) ? true: false;
                carry = (CogsRunning < TOTAL_COGS) ? false : true;
                Stop((int)maskedArg);
                CogsRunning--;
                return(maskedArg);

            case HubOperationCodes.HUBOP_LOCKCLR:
                zero  = (maskedArg == 0) ? true : false;
                carry = LocksState[maskedArg];
                LocksState[maskedArg] = false;
                return(argument);

            case HubOperationCodes.HUBOP_LOCKNEW:
                zero  = false;      // initial value if no Locks available
                carry = true;       // initial value if no Locks available
                for (uint i = 0; i < LocksAvailable.Length; i++)
                {
                    if (LocksAvailable[i])
                    {
                        LocksAvailable[i] = false;
                        carry             = false;
                        if (i == 0)
                        {
                            zero = true;
                        }
                        return(i);
                    }
                }
                return(7);      // if all are occupied, return a 7, but carry is true

            case HubOperationCodes.HUBOP_LOCKRET:
                zero  = (maskedArg == 0) ? true : false;
                carry = true;       // initial value if no Locks available
                for (uint i = 0; i < LocksAvailable.Length; i++)
                {
                    if (LocksAvailable[i])
                    {
                        carry = false;
                    }
                }
                LocksAvailable[maskedArg] = true;
                return(maskedArg);

            case HubOperationCodes.HUBOP_LOCKSET:
                zero  = (maskedArg == 0) ? true : false;
                carry = LocksState[maskedArg];
                LocksState[maskedArg] = true;
                return(maskedArg);

            default:
                // TODO: RAISE EXCEPTION
                break;
            }

            return(0);
        }