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