Пример #1
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));
            }
        }