Exemplo n.º 1
0
        protected uint ReadInner()
        {
            foreach (var registerField in registerFields)
            {
                UnderlyingValue = registerField.CallValueProviderHandler(UnderlyingValue);
            }
            var baseValue     = UnderlyingValue;
            var valueToRead   = UnderlyingValue;
            var changedFields = new List <RegisterField>();

            foreach (var registerField in registerFields)
            {
                if (!registerField.fieldMode.IsReadable())
                {
                    BitHelper.ClearBits(ref valueToRead, registerField.position, registerField.width);
                }
                if (registerField.fieldMode.IsFlagSet(FieldMode.ReadToClear) &&
                    BitHelper.AreAnyBitsSet(UnderlyingValue, registerField.position, registerField.width))
                {
                    BitHelper.ClearBits(ref UnderlyingValue, registerField.position, registerField.width);
                    changedFields.Add(registerField);
                }
            }
            foreach (var registerField in registerFields)
            {
                registerField.CallReadHandler(baseValue, UnderlyingValue);
            }
            foreach (var changedRegister in changedFields.Distinct())
            {
                changedRegister.CallChangeHandler(baseValue, UnderlyingValue);
            }
            return(valueToRead);
        }
Exemplo n.º 2
0
        protected void WriteInner(long offset, uint value)
        {
            var baseValue        = UnderlyingValue;
            var difference       = UnderlyingValue ^ value;
            var setRegisters     = value & (~UnderlyingValue);
            var changedRegisters = new List <RegisterField>();

            foreach (var registerField in registerFields)
            {
                //switch is OK, because write modes are exclusive.
                switch (registerField.fieldMode.WriteBits())
                {
                case FieldMode.Write:
                    if (BitHelper.AreAnyBitsSet(difference, registerField.position, registerField.width))
                    {
                        BitHelper.UpdateWith(ref UnderlyingValue, value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.Set:
                    if (BitHelper.AreAnyBitsSet(setRegisters, registerField.position, registerField.width))
                    {
                        BitHelper.OrWith(ref UnderlyingValue, setRegisters, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.Toggle:
                    if (BitHelper.AreAnyBitsSet(value, registerField.position, registerField.width))
                    {
                        BitHelper.XorWith(ref UnderlyingValue, value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.WriteOneToClear:
                    if (BitHelper.AreAnyBitsSet(value, registerField.position, registerField.width))
                    {
                        BitHelper.AndWithNot(ref UnderlyingValue, value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.WriteZeroToClear:
                    if (BitHelper.AreAnyBitsSet(~value, registerField.position, registerField.width))
                    {
                        BitHelper.AndWithNot(ref UnderlyingValue, ~value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;
                }
            }
            foreach (var registerField in registerFields)
            {
                registerField.CallWriteHandler(baseValue, value);
            }
            foreach (var changedRegister in changedRegisters.Distinct())
            {
                changedRegister.CallChangeHandler(baseValue, UnderlyingValue);
            }

            CallWriteHandlers(baseValue, value);
            if (changedRegisters.Any())
            {
                CallChangeHandlers(baseValue, UnderlyingValue);
            }

            var unhandledWrites = difference & ~definedFieldsMask;

            if (unhandledWrites != 0)
            {
                parent.Log(LogLevel.Warning, TagLogger(offset, unhandledWrites, value));
            }
        }