Program: 5480
Project: 5480
Buggy source:
@Override public void write(int address,int data,boolean word,long cycles){
  address=address - offset;
  if (DEBUG) {
    log("String_Node_Str" + Utils.hex(address,4) + "String_Node_Str"+ data+ "String_Node_Str"+ word);
  }
switch (address) {
case MPY:
    if (DEBUG)     log("String_Node_Str" + data);
  op1=mpy=data;
signed=false;
accumulating=false;
break;
case MPYS:
op1=mpys=data;
if (DEBUG) log("String_Node_Str" + data);
signed=true;
accumulating=false;
break;
case MAC:
op1=mac=data;
if (DEBUG) log("String_Node_Str" + data);
signed=false;
accumulating=true;
break;
case MACS:
op1=macs=data;
if (DEBUG) log("String_Node_Str" + data);
signed=true;
accumulating=true;
break;
case RESLO:
resLo=data;
break;
case RESHI:
resHi=data;
break;
case OP2:
if (DEBUG) log("String_Node_Str" + data);
sumext=0;
op2=data;
if (signed) {
if (!word) {
if (op1 > 0x80) op1=op1 | 0xff00;
if (op2 > 0x80) op2=op2 | 0xff00;
}
op1=op1 > 0x8000 ? op1 - 0x10000 : op1;
op2=op2 > 0x8000 ? op2 - 0x10000 : op2;
}
long res=(long)op1 * (long)op2;
if (DEBUG) log("String_Node_Str" + op1 + "String_Node_Str"+ op2+ "String_Node_Str"+ res);
if (signed) {
sumext=res < 0 ? 0xffff : 0;
}
if (accumulating) {
res+=((long)resHi << 16) + resLo;
if (!signed) {
sumext=res > 0xffffffffL ? 1 : 0;
}
}
 else if (!signed) {
sumext=0;
}
resHi=(int)((res >> 16) & 0xffff);
resLo=(int)(res & 0xffff);
if (DEBUG) log("String_Node_Str" + res);
break;
case MPY32L:
op1=mpy32L=data;
signed=false;
accumulating=false;
break;
case MPY32H:
mpy32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case MPYS32L:
if (!word && data >= 0x80) {
data-=0x100;
}
op1=mpy32L=data;
signed=true;
accumulating=false;
break;
case MPYS32H:
if (!word & data > 0x80) {
data-=0x100;
}
mpys32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case MAC32L:
op1=mac32L=data;
signed=false;
accumulating=true;
break;
case MAC32H:
mac32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case MACS32L:
if (!word & data > 0x80) {
data-=0x100;
}
op1=macs32L=data;
signed=true;
accumulating=true;
break;
case MACS32H:
if (!word & data > 0x80) {
data-=0x100;
}
macs32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case OP2L:
if (signed && !word && data >= 0x80) {
data-=0x80;
}
op2L=op2=data;
break;
case OP2H:
{
long p;
if (signed && !word && data >= 0x80) {
data-=0x80;
}
op2=(op2 & 0xffff) | (data << 16);
if (signed) {
p=(long)op1 * (long)op2;
}
 else {
long uop1, uop2;
uop1=op1;
if (uop1 < 0) {
uop1+=0x100000000L;
}
uop2=op2;
if (uop2 < 0) {
uop2+=0x100000000L;
}
p=uop1 * uop2;
}
if (accumulating) {
res64+=p;
}
 else {
res64=p;
}
res0=(int)res64 & 0xffff;
res1=(int)(res64 >> 16) & 0xffff;
res2=(int)(res64 >> 32) & 0xffff;
res3=(int)(res64 >> 48) & 0xffff;
break;
}
default :
logw(WarningType.EMULATION_ERROR,"String_Node_Str" + Utils.hex(address,4));
break;
}
}

Fixed version (ground truth):
@Override public void write(int address,int data,boolean word,long cycles){
  address=address - offset;
  if (DEBUG) {
    log("String_Node_Str" + Utils.hex(address,4) + "String_Node_Str"+ data+ "String_Node_Str"+ word);
  }
switch (address) {
case MPY:
    if (DEBUG)     log("String_Node_Str" + data);
  op1=mpy=data;
signed=false;
accumulating=false;
break;
case MPYS:
op1=mpys=data;
if (DEBUG) log("String_Node_Str" + data);
signed=true;
accumulating=false;
break;
case MAC:
op1=mac=data;
if (DEBUG) log("String_Node_Str" + data);
signed=false;
accumulating=true;
break;
case MACS:
op1=macs=data;
if (DEBUG) log("String_Node_Str" + data);
signed=true;
accumulating=true;
break;
case RESLO:
resLo=data;
break;
case RESHI:
resHi=data;
break;
case OP2:
if (DEBUG) log("String_Node_Str" + data);
sumext=0;
op2=data;
if (signed) {
if (!word) {
if (op1 > 0x80) op1=op1 | 0xff00;
if (op2 > 0x80) op2=op2 | 0xff00;
}
op1=op1 > 0x8000 ? op1 - 0x10000 : op1;
op2=op2 > 0x8000 ? op2 - 0x10000 : op2;
}
long res=(long)op1 * (long)op2;
if (DEBUG) log("String_Node_Str" + op1 + "String_Node_Str"+ op2+ "String_Node_Str"+ res);
if (signed) {
sumext=res < 0 ? 0xffff : 0;
}
if (accumulating) {
res+=((long)resHi << 16) + resLo;
if (!signed) {
sumext=res > 0xffffffffL ? 1 : 0;
}
}
 else if (!signed) {
sumext=0;
}
resHi=(int)((res >> 16) & 0xffff);
resLo=(int)(res & 0xffff);
if (DEBUG) log("String_Node_Str" + res);
break;
case MPY32L:
op1=mpy32L=data;
signed=false;
accumulating=false;
break;
case MPY32H:
mpy32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case MPYS32L:
if (!word && data >= 0x80) {
data-=0x100;
}
op1=mpy32L=data;
signed=true;
accumulating=false;
break;
case MPYS32H:
if (!word & data > 0x80) {
data-=0x100;
}
mpys32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case MAC32L:
op1=mac32L=data;
signed=false;
accumulating=true;
break;
case MAC32H:
mac32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case MACS32L:
if (!word & data > 0x80) {
data-=0x100;
}
op1=macs32L=data;
signed=true;
accumulating=true;
break;
case MACS32H:
if (!word & data > 0x80) {
data-=0x100;
}
macs32H=data;
op1=(op1 & 0xffff) | (data << 16);
break;
case OP2L:
if (signed && !word && data >= 0x80) {
data-=0x80;
}
op2L=op2=data;
break;
case OP2H:
{
long p;
if (signed && !word && data >= 0x80) {
data-=0x80;
}
op2=(op2 & 0xffff) | (data << 16);
if (signed) {
p=(long)op1 * (long)op2;
}
 else {
long uop1, uop2;
uop1=op1;
if (uop1 < 0) {
uop1+=0x100000000L;
}
uop2=op2;
if (uop2 < 0) {
uop2+=0x100000000L;
}
p=uop1 * uop2;
}
if (accumulating) {
res64+=p;
}
 else {
res64=p;
}
resLo=res0=(int)res64 & 0xffff;
resHi=res1=(int)(res64 >> 16) & 0xffff;
res2=(int)(res64 >> 32) & 0xffff;
res3=(int)(res64 >> 48) & 0xffff;
break;
}
default :
logw(WarningType.EMULATION_ERROR,"String_Node_Str" + Utils.hex(address,4));
break;
}
}