/// @brief Determine the ID of the cog.
        /// @param[in] caller Cog instance to determine the its ID.
        /// @returns Cog ID.
        public uint CogID(Cog caller)
        {
            for (uint i = 0; i < Cogs.Length; i++)
            {
                if (caller == Cogs[i])
                {
                    return(i);
                }
            }

            return(0);
        }
Пример #2
0
        public void Tick(ulong pins)
        {
            switch (CtrMode)
            {
            case CounterMode.DISABLED:
            case CounterMode.PLL_INTERNAL:
            case CounterMode.PLL_SINGLE_ENDED:
            case CounterMode.PLL_DIFFERENTIAL:
                break;

            case CounterMode.NCO_SINGLE_ENDED:
                PHS += FRQ;
                OutA = (PHS & 0x80000000) != 0;
                break;

            case CounterMode.NCO_DIFFERENTIAL:
                PHS += FRQ;
                OutA = (PHS & 0x80000000) != 0;
                OutB = !OutA;
                break;

            case CounterMode.DUTY_SINGLE_ENDED:
            {
                long o = (long)PHS + (long)FRQ;

                PHS  = (uint)o;
                OutA = o > 0xFFFFFFFF;
            }
            break;

            case CounterMode.DUTY_DIFFERENTIAL:
            {
                long o = (long)PHS + (long)FRQ;

                PHS  = (uint)o;
                OutA = o > 0xFFFFFFFF;
                OutB = !OutA;
            }
            break;

            case CounterMode.POS_DETECTOR:
                if (PinA)
                {
                    PHS += FRQ;
                }
                break;

            case CounterMode.POS_DETECTOR_FEEDBACK:
                if (PinA)
                {
                    PHS += FRQ;
                }
                OutB = !PinA;
                break;

            case CounterMode.POSEDGE_DETECTOR:
                if (PinA && !PinA_)
                {
                    PHS += FRQ;
                }
                break;

            case CounterMode.POSEDGE_DETECTOR_FEEDBACK:
                if (PinA && !PinA_)
                {
                    PHS += FRQ;
                }
                OutB = !PinA;
                break;

            case CounterMode.NEG_DETECTOR:
                if (!PinA)
                {
                    PHS += FRQ;
                }
                break;

            case CounterMode.NEG_DETECTOR_FEEDBACK:
                if (!PinA)
                {
                    PHS += FRQ;
                }
                OutB = !PinA;
                break;

            case CounterMode.NEGEDGE_DETECTOR:
                if (!PinA && PinA_)
                {
                    PHS += FRQ;
                }
                break;

            case CounterMode.NEGEDGE_DETECTOR_FEEDBACK:
                if (!PinA && PinA_)
                {
                    PHS += FRQ;
                }
                OutB = !PinA;
                break;

            default:
                // changed to NOT ConditionCompare(.) to repair Logic Modes Counter
                if (!Cog.ConditionCompare((Assembly.ConditionCodes)((int)CtrMode - 16), PinA, PinB))
                {
                    PHS += FRQ;
                }
                break;
            }

            // Cycle in our previous pin states

            ulong Input = Host.IN;

            PinA_ = PinA;   // Delay by 2
            PinA  = (Input & PinAMask) != 0;
            PinB  = (Input & PinBMask) != 0;
        }
        /// @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);
        }