Program: 5795
Project: 5795
Buggy source:
public void emulateOP(){
  int pc=readRegister(PC);
  if (interruptsEnabled && servicedInterrupt == -1 && interruptMax >= 0) {
    pc=serviceInterrupt(pc);
  }
  if (breakPoints[pc] != null) {
    if (breakpointActive) {
      breakPoints[pc].cpuAction(CPUMonitor.BREAK,pc,0);
      breakpointActive=false;
      return;
    }
 else {
      breakpointActive=true;
    }
  }
  instruction=memory[pc] + (memory[pc + 1] << 8);
  op=instruction >> 12;
  int sp=0;
  int sr=0;
  boolean word=(instruction & 0x40) == 0;
  int dstRegister=0;
  int dstAddress=-1;
  boolean dstRegMode=false;
  int dst=0;
  boolean write=false;
  boolean updateStatus=true;
  if (cycles > nextIOTickCycles) {
    handleIO();
  }
  pc+=2;
  writeRegister(PC,pc);
switch (op) {
case 1:
{
      dstRegister=instruction & 0xf;
      int ad=(instruction >> 4) & 3;
      int nxtCarry=0;
      op=instruction & 0xff80;
      if (op == PUSH) {
        sp=readRegister(SP) - 2;
        writeRegister(SP,sp);
      }
      if ((dstRegister == CG1 && ad != AM_INDEX) || dstRegister == CG2) {
        dstRegMode=true;
        cycles++;
      }
 else {
switch (ad) {
case AM_REG:
          dstRegMode=true;
        cycles++;
      break;
case AM_INDEX:
    dstAddress=readRegisterCG(dstRegister,ad) + memory[pc] + (memory[pc + 1] << 8);
  pc+=2;
writeRegister(PC,pc);
cycles+=4;
break;
case AM_IND_REG:
dstAddress=readRegister(dstRegister);
cycles+=3;
break;
case AM_IND_AUTOINC:
dstAddress=readRegister(dstRegister);
writeRegister(dstRegister,dstAddress + (word ? 2 : 1));
cycles+=3;
break;
}
}
if (dstRegMode) {
dst=readRegisterCG(dstRegister,ad);
if (!word) {
dst&=0xff;
}
}
 else {
dst=read(dstAddress,word);
}
switch (op) {
case RRC:
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
if (word) {
dst|=(readRegister(SR) & CARRY) > 0 ? 0x8000 : 0;
}
 else {
dst|=(readRegister(SR) & CARRY) > 0 ? 0x80 : 0;
}
write=true;
writeRegister(SR,(readRegister(SR) & ~CARRY) | nxtCarry);
break;
case SWPB:
int tmp=dst;
dst=((tmp >> 8) & 0xff) + ((tmp << 8) & 0xff00);
write=true;
break;
case RRA:
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
if (word) {
dst=(dst & 0x8000) | (dst >> 1);
}
 else {
dst=(dst & 0x80) | (dst >> 1);
}
write=true;
writeRegister(SR,(readRegister(SR) & ~CARRY) | nxtCarry);
break;
case SXT:
dst=(dst & 0x80) > 0 ? dst | 0xff00 : dst & 0x7f;
write=true;
break;
case PUSH:
if (word) {
memory[sp]=dst & 0xff;
memory[sp + 1]=dst >> 8;
}
 else {
memory[sp]=dst & 0xff;
memory[sp + 1]=0;
}
write=false;
updateStatus=false;
break;
case CALL:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
pc=readRegister(PC);
memory[sp]=pc & 0xff;
memory[sp + 1]=pc >> 8;
writeRegister(PC,dst);
write=false;
updateStatus=false;
break;
case RETI:
sp=readRegister(SP);
writeRegister(SR,memory[sp++] + (memory[sp++] << 8));
writeRegister(PC,memory[sp++] + (memory[sp++] << 8));
writeRegister(SP,sp);
write=false;
updateStatus=false;
if (debugInterrupts) {
System.out.println("String_Node_Str" + pc + "String_Node_Str"+ reg[PC]+ "String_Node_Str"+ reg[SP]);
}
handlePendingInterrupts();
break;
default :
System.out.println("String_Node_Str" + instruction);
}
}
break;
case 2:
case 3:
int jmpOffset=instruction & 0x3ff;
jmpOffset=(jmpOffset & 0x200) == 0 ? 2 * jmpOffset : -(2 * (0x200 - (jmpOffset & 0x1ff)));
boolean jump=false;
cycles++;
sr=readRegister(SR);
switch (instruction & 0xfc00) {
case JNE:
jump=(sr & ZERO) == 0;
break;
case JEQ:
jump=(sr & ZERO) > 0;
break;
case JNC:
jump=(sr & CARRY) == 0;
break;
case JC:
jump=(sr & CARRY) > 0;
break;
case JN:
jump=(sr & NEGATIVE) > 0;
break;
case JGE:
jump=(sr & NEGATIVE) > 0 == (sr & OVERFLOW) > 0;
break;
case JL:
jump=(sr & NEGATIVE) > 0 != (sr & OVERFLOW) > 0;
break;
case JMP:
jump=true;
break;
default :
System.out.println("String_Node_Str" + Utils.binary16(instruction));
}
if (jump) {
writeRegister(PC,pc + jmpOffset);
}
break;
default :
dstRegister=instruction & 0xf;
int srcRegister=(instruction >> 8) & 0xf;
int as=(instruction >> 4) & 3;
dstRegMode=((instruction >> 7) & 1) == 0;
dstAddress=-1;
int srcAddress=-1;
int src=0;
if ((srcRegister == CG1 && as != AM_INDEX) || srcRegister == CG2) {
src=CREG_VALUES[srcRegister - 2][as];
if (!word) {
src&=0xff;
}
}
 else {
switch (as) {
case AM_REG:
src=readRegister(srcRegister);
if (!word) {
src&=0xff;
}
break;
case AM_INDEX:
srcAddress=readRegisterCG(srcRegister,as) + memory[pc] + (memory[pc + 1] << 8);
incRegister(PC,2);
cycles+=dstRegMode ? 3 : 6;
break;
case AM_IND_REG:
srcAddress=readRegister(srcRegister);
cycles+=dstRegMode ? 2 : 5;
break;
case AM_IND_AUTOINC:
if (srcRegister == PC) {
srcAddress=readRegister(PC);
pc+=2;
incRegister(PC,2);
cycles+=3;
}
 else {
srcAddress=readRegister(srcRegister);
incRegister(srcRegister,word ? 2 : 1);
cycles+=dstRegMode ? 2 : 5;
}
break;
}
}
if (dstRegMode) {
dst=readRegister(dstRegister);
if (!word) {
dst&=0xff;
}
}
 else {
pc=readRegister(PC);
if (dstRegister == 2) {
dstAddress=memory[pc] + (memory[pc + 1] << 8);
}
 else {
dstAddress=readRegister(dstRegister) + memory[pc] + (memory[pc + 1] << 8);
}
dst=read(dstAddress,word);
pc+=2;
incRegister(PC,2);
}
if (srcAddress != -1) {
srcAddress=srcAddress & 0xffff;
src=read(srcAddress,word);
}
int tmp=0;
int tmpAdd=0;
switch (op) {
case MOV:
dst=src;
write=true;
break;
case SUB:
tmpAdd=1;
case SUBC:
src=(src ^ 0xffff) & 0xffff;
case ADDC:
if (op == ADDC || op == SUBC) tmpAdd=((readRegister(SR) & CARRY) > 0) ? 1 : 0;
case ADD:
sr=readRegister(SR);
sr&=~(OVERFLOW | CARRY);
tmp=(src ^ dst) & (word ? 0x8000 : 0x80);
dst=dst + src + tmpAdd;
if (dst > (word ? 0xffff : 0xff)) {
sr|=CARRY;
}
if (tmp == 0 && ((src ^ dst) & (word ? 0x8000 : 0x80)) != 0) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
write=true;
break;
case CMP:
int b=word ? 0x8000 : 0x80;
sr=readRegister(SR);
sr=(sr & ~(CARRY | OVERFLOW)) | (dst >= src ? CARRY : 0);
tmp=dst - src;
if (((src ^ tmp) & b) == 0 && (((src ^ dst) & b) != 0)) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
dst=tmp;
break;
case DADD:
if (DEBUG) System.out.println("String_Node_Str");
dst=dst + src + ((readRegister(SR) & CARRY) > 0 ? 1 : 0);
write=true;
break;
case BIT:
dst=src & dst;
sr=readRegister(SR);
if (dst != 0) {
sr|=CARRY;
}
sr&=~OVERFLOW;
writeRegister(SR,sr);
break;
case BIC:
dst=(~src) & dst;
write=true;
updateStatus=false;
break;
case BIS:
dst=src | dst;
write=true;
updateStatus=false;
break;
case XOR:
dst=src ^ dst;
write=true;
break;
case AND:
dst=src & dst;
write=true;
break;
default :
System.out.println("String_Node_Str" + op + "String_Node_Str"+ pc);
}
}
dst&=0xffff;
if (write) {
if (dstRegMode) {
writeRegister(dstRegister,dst);
}
 else {
dstAddress&=0xffff;
write(dstAddress,dst,word);
}
}
if (updateStatus) {
sr=readRegister(SR);
sr=(sr & ~(ZERO | NEGATIVE)) | ((dst == 0) ? ZERO : 0) | (word ? ((dst & 0x8000) > 0 ? NEGATIVE : 0) : ((dst & 0x80) > 0 ? NEGATIVE : 0));
writeRegister(SR,sr);
}
}

Fixed version (ground truth):
public void emulateOP(){
  int pc=readRegister(PC);
  if (interruptsEnabled && servicedInterrupt == -1 && interruptMax >= 0) {
    pc=serviceInterrupt(pc);
  }
  if (breakPoints[pc] != null) {
    if (breakpointActive) {
      breakPoints[pc].cpuAction(CPUMonitor.BREAK,pc,0);
      breakpointActive=false;
      return;
    }
 else {
      breakpointActive=true;
    }
  }
  instruction=memory[pc] + (memory[pc + 1] << 8);
  op=instruction >> 12;
  int sp=0;
  int sr=0;
  boolean word=(instruction & 0x40) == 0;
  int dstRegister=0;
  int dstAddress=-1;
  boolean dstRegMode=false;
  int dst=0;
  boolean write=false;
  boolean updateStatus=true;
  if (cycles > nextIOTickCycles) {
    handleIO();
  }
  pc+=2;
  writeRegister(PC,pc);
switch (op) {
case 1:
{
      dstRegister=instruction & 0xf;
      int ad=(instruction >> 4) & 3;
      int nxtCarry=0;
      op=instruction & 0xff80;
      if (op == PUSH) {
        sp=readRegister(SP) - 2;
        writeRegister(SP,sp);
      }
      if ((dstRegister == CG1 && ad != AM_INDEX) || dstRegister == CG2) {
        dstRegMode=true;
        cycles++;
      }
 else {
switch (ad) {
case AM_REG:
          dstRegMode=true;
        cycles++;
      break;
case AM_INDEX:
    dstAddress=readRegisterCG(dstRegister,ad) + memory[pc] + (memory[pc + 1] << 8);
  pc+=2;
writeRegister(PC,pc);
cycles+=4;
break;
case AM_IND_REG:
dstAddress=readRegister(dstRegister);
cycles+=3;
break;
case AM_IND_AUTOINC:
dstAddress=readRegister(dstRegister);
writeRegister(dstRegister,dstAddress + (word ? 2 : 1));
cycles+=3;
break;
}
}
if (dstRegMode) {
dst=readRegisterCG(dstRegister,ad);
if (!word) {
dst&=0xff;
}
}
 else {
dst=read(dstAddress,word);
}
switch (op) {
case RRC:
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
if (word) {
dst|=(readRegister(SR) & CARRY) > 0 ? 0x8000 : 0;
}
 else {
dst|=(readRegister(SR) & CARRY) > 0 ? 0x80 : 0;
}
write=true;
writeRegister(SR,(readRegister(SR) & ~CARRY) | nxtCarry);
break;
case SWPB:
int tmp=dst;
dst=((tmp >> 8) & 0xff) + ((tmp << 8) & 0xff00);
write=true;
break;
case RRA:
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
if (word) {
dst=(dst & 0x8000) | (dst >> 1);
}
 else {
dst=(dst & 0x80) | (dst >> 1);
}
write=true;
writeRegister(SR,(readRegister(SR) & ~CARRY) | nxtCarry);
break;
case SXT:
dst=(dst & 0x80) > 0 ? dst | 0xff00 : dst & 0x7f;
write=true;
break;
case PUSH:
if (word) {
memory[sp]=dst & 0xff;
memory[sp + 1]=dst >> 8;
}
 else {
memory[sp]=dst & 0xff;
memory[sp + 1]=0;
}
write=false;
updateStatus=false;
break;
case CALL:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
pc=readRegister(PC);
memory[sp]=pc & 0xff;
memory[sp + 1]=pc >> 8;
writeRegister(PC,dst);
write=false;
updateStatus=false;
break;
case RETI:
sp=readRegister(SP);
writeRegister(SR,memory[sp++] + (memory[sp++] << 8));
writeRegister(PC,memory[sp++] + (memory[sp++] << 8));
writeRegister(SP,sp);
write=false;
updateStatus=false;
if (debugInterrupts) {
System.out.println("String_Node_Str" + pc + "String_Node_Str"+ reg[PC]+ "String_Node_Str"+ reg[SP]);
}
handlePendingInterrupts();
break;
default :
System.out.println("String_Node_Str" + instruction);
}
}
break;
case 2:
case 3:
int jmpOffset=instruction & 0x3ff;
jmpOffset=(jmpOffset & 0x200) == 0 ? 2 * jmpOffset : -(2 * (0x200 - (jmpOffset & 0x1ff)));
boolean jump=false;
cycles++;
sr=readRegister(SR);
switch (instruction & 0xfc00) {
case JNE:
jump=(sr & ZERO) == 0;
break;
case JEQ:
jump=(sr & ZERO) > 0;
break;
case JNC:
jump=(sr & CARRY) == 0;
break;
case JC:
jump=(sr & CARRY) > 0;
break;
case JN:
jump=(sr & NEGATIVE) > 0;
break;
case JGE:
jump=(sr & NEGATIVE) > 0 == (sr & OVERFLOW) > 0;
break;
case JL:
jump=(sr & NEGATIVE) > 0 != (sr & OVERFLOW) > 0;
break;
case JMP:
jump=true;
break;
default :
System.out.println("String_Node_Str" + Utils.binary16(instruction));
}
if (jump) {
writeRegister(PC,pc + jmpOffset);
}
break;
default :
dstRegister=instruction & 0xf;
int srcRegister=(instruction >> 8) & 0xf;
int as=(instruction >> 4) & 3;
dstRegMode=((instruction >> 7) & 1) == 0;
dstAddress=-1;
int srcAddress=-1;
int src=0;
if ((srcRegister == CG1 && as != AM_INDEX) || srcRegister == CG2) {
src=CREG_VALUES[srcRegister - 2][as];
if (!word) {
src&=0xff;
}
}
 else {
switch (as) {
case AM_REG:
src=readRegister(srcRegister);
if (!word) {
src&=0xff;
}
break;
case AM_INDEX:
srcAddress=readRegisterCG(srcRegister,as) + memory[pc] + (memory[pc + 1] << 8);
incRegister(PC,2);
cycles+=dstRegMode ? 3 : 6;
break;
case AM_IND_REG:
srcAddress=readRegister(srcRegister);
cycles+=dstRegMode ? 2 : 5;
break;
case AM_IND_AUTOINC:
if (srcRegister == PC) {
srcAddress=readRegister(PC);
pc+=2;
incRegister(PC,2);
cycles+=3;
}
 else {
srcAddress=readRegister(srcRegister);
incRegister(srcRegister,word ? 2 : 1);
cycles+=dstRegMode ? 2 : 5;
}
break;
}
}
if (dstRegMode) {
dst=readRegister(dstRegister);
if (!word) {
dst&=0xff;
}
}
 else {
pc=readRegister(PC);
if (dstRegister == 2) {
dstAddress=memory[pc] + (memory[pc + 1] << 8);
}
 else {
dstAddress=readRegister(dstRegister) + memory[pc] + (memory[pc + 1] << 8);
}
dst=read(dstAddress,word);
pc+=2;
incRegister(PC,2);
}
if (srcAddress != -1) {
srcAddress=srcAddress & 0xffff;
src=read(srcAddress,word);
}
int tmp=0;
int tmpAdd=0;
switch (op) {
case MOV:
dst=src;
write=true;
break;
case SUB:
tmpAdd=1;
case SUBC:
src=(src ^ 0xffff) & 0xffff;
case ADDC:
if (op == ADDC || op == SUBC) tmpAdd=((readRegister(SR) & CARRY) > 0) ? 1 : 0;
case ADD:
sr=readRegister(SR);
sr&=~(OVERFLOW | CARRY);
tmp=(src ^ dst) & (word ? 0x8000 : 0x80);
dst=dst + src + tmpAdd;
if (dst > (word ? 0xffff : 0xff)) {
sr|=CARRY;
}
if (tmp == 0 && ((src ^ dst) & (word ? 0x8000 : 0x80)) != 0) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
write=true;
break;
case CMP:
int b=word ? 0x8000 : 0x80;
sr=readRegister(SR);
sr=(sr & ~(CARRY | OVERFLOW)) | (dst >= src ? CARRY : 0);
tmp=dst - src;
if (((src ^ tmp) & b) == 0 && (((src ^ dst) & b) != 0)) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
dst=tmp;
break;
case DADD:
if (DEBUG) System.out.println("String_Node_Str");
dst=dst + src + ((readRegister(SR) & CARRY) > 0 ? 1 : 0);
write=true;
break;
case BIT:
dst=src & dst;
sr=readRegister(SR);
sr=sr & ~(CARRY | OVERFLOW);
if (dst != 0) {
sr|=CARRY;
}
writeRegister(SR,sr);
break;
case BIC:
dst=(~src) & dst;
write=true;
updateStatus=false;
break;
case BIS:
dst=src | dst;
write=true;
updateStatus=false;
break;
case XOR:
dst=src ^ dst;
write=true;
break;
case AND:
dst=src & dst;
write=true;
break;
default :
System.out.println("String_Node_Str" + op + "String_Node_Str"+ pc);
}
}
dst&=0xffff;
if (write) {
if (dstRegMode) {
writeRegister(dstRegister,dst);
}
 else {
dstAddress&=0xffff;
write(dstAddress,dst,word);
}
}
if (updateStatus) {
sr=readRegister(SR);
sr=(sr & ~(ZERO | NEGATIVE)) | ((dst == 0) ? ZERO : 0) | (word ? ((dst & 0x8000) > 0 ? NEGATIVE : 0) : ((dst & 0x80) > 0 ? NEGATIVE : 0));
writeRegister(SR,sr);
}
}