/// @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); }
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); }