private void PinChanged(Topic src, TopicChanged tc) {
DVar<bool> pin=src as DVar<bool>;
int idx=-1;
if(pin==null || tc.Initiator==_mnt) {
return;
}
if(tc.Art==TopicChanged.ChangeArt.Remove) {
for(idx=0; idx<_pins.Length; idx++) {
if(_pins[idx]==pin) {
_pins[idx]=null;
ushort n_ipol=_ipol, n_iodir=_iodir;
n_iodir&=(ushort)(~(1<<idx));
_inps&=(ushort)(~(1<<idx));
if(_iodir!=n_iodir) {
_iodir=n_iodir;
_flags|=4;
}
n_ipol&=(ushort)(~(1<<idx));
if(_ipol!=n_ipol) {
_ipol=n_ipol;
_flags|=2;
}
break;
}
}
} else {
for(int i=0; i<_pins.Length; i++) {
if(_pins[i]==pin) {
idx=i;
break;
}
}
if(idx==-1) {
ushort n_ipol=_ipol, n_iodir=_iodir;
if(pin.name.Length==3
&& (pin.name[0]=='I' || pin.name[0]=='O')
&& (pin.name[1]=='p' || pin.name[1]=='n')
&& ((pin.name[2]>='0' && pin.name[2]<='9') || (pin.name[2]>='A' && pin.name[2]<='F'))) {
idx=pin.name[2]-'0';
if(idx>9) {
idx-=7;
}
if(pin.name[0]=='I') {
n_iodir|=(ushort)(1<<idx);
_inps|=(ushort)(1<<idx);
} else {
n_iodir&=(ushort)(~(1<<idx));
}
if(_iodir!=n_iodir) {
_iodir=n_iodir;
_flags|=4;
}
if(pin.name[1]=='p') {
n_ipol&=(ushort)(~(1<<idx));
} else {
n_ipol|=(ushort)(1<<idx);
}
if(_ipol!=n_ipol) {
_ipol=n_ipol;
_flags|=2;
}
} else if(pin.name=="IRQ") {
if(pin.value && !_busy && _flags==0) {
_pt=DateTime.Now.AddMilliseconds(1);
}
return;
} else {
return; // unknown variable
}
if(_pins[idx]!=pin) {
if(_pins[idx]!=null) {
_pins[idx].Remove(tc.Initiator);
}
_pins[idx]=pin;
}
}
}
if(pin.name[0]=='O') {
ushort n_gpo=_gpo;
bool val=((_ipol & (1<<idx))==0)?pin.value:!pin.value;
if(val) {
n_gpo|=(ushort)(1<<idx);
} else {
n_gpo&=(ushort)(~(1<<idx));
}
if(_gpo!=n_gpo) {
_gpo=n_gpo;
_flags|=1;
}
}
if(!_busy && _flags!=0) {
_pt=DateTime.Now.AddMilliseconds(1);
}
}
}