Program: 5497
Project: 5497
Buggy source:
public int emulateOP(long maxCycles) throws EmulationException {
  int pc=readRegister(PC);
  long startCycles=cycles;
  if (interruptsEnabled && servicedInterrupt == -1 && interruptMax >= 0) {
    pc=serviceInterrupt(pc);
  }
  if (cpuOff || flash.blocksCPU()) {
    while (cycles >= nextEventCycles) {
      executeEvents();
    }
    if (interruptsEnabled && interruptMax > 0) {
      return -1;
    }
    if (maxCycles >= 0 && maxCycles < nextEventCycles) {
      cycles=cycles < maxCycles ? maxCycles : cycles;
    }
 else {
      cycles=nextEventCycles;
    }
    return -1;
  }
  int pcBefore=pc;
  instruction=currentSegment.read(pc,AccessMode.WORD,AccessType.EXECUTE);
  if (isStopping) {
    return -2;
  }
  int ext3_0=0;
  int ext10_7=0;
  int extSrc=0;
  int extDst=0;
  boolean repeatsInDstReg=false;
  boolean wordx20=false;
  if ((instruction & 0xf800) == 0x1800) {
    extWord=instruction;
    ext3_0=instruction & 0xf;
    ext10_7=(instruction >> 7) & 0xf;
    extSrc=ext10_7 << 16;
    extDst=ext3_0 << 16;
    pc+=2;
    if ((instruction & 0x80) == 0x80) {
      repeatsInDstReg=true;
    }
    wordx20=(instruction & 0x40) == 0;
    instruction=currentSegment.read(pc,AccessMode.WORD,AccessType.EXECUTE);
  }
 else {
    extWord=0;
  }
  op=instruction >> 12;
  int sp=0;
  int sr=0;
  int rval=0;
  int repeats=1;
  boolean zeroCarry=false;
  boolean word=(instruction & 0x40) == 0;
  AccessMode mode=wordx20 ? AccessMode.WORD20 : (word ? AccessMode.WORD : AccessMode.BYTE);
  if (mode == AccessMode.WORD20)   System.out.println("String_Node_Str");
  int dstRegister=0;
  int dstAddress=-1;
  boolean dstRegMode=false;
  int dst=-1;
  boolean write=false;
  boolean updateStatus=true;
  pc+=2;
  writeRegister(PC,pc);
switch (op) {
case 0:
    op=instruction & 0xf0f0;
  if (!MSP430XArch)   throw new EmulationException("String_Node_Str");
int src=0;
int srcData=(instruction & 0x0f00) >> 8;
int dstData=(instruction & 0x000f);
boolean rrword=true;
mode=AccessMode.WORD20;
switch (op) {
case MOVA_IND:
writeRegister(dstData,currentSegment.read(readRegister(srcData),AccessMode.WORD20,AccessType.READ));
updateStatus=false;
cycles+=3;
break;
case MOVA_IND_AUTOINC:
if (profiler != null && instruction == 0x0110) {
profiler.profileReturn(cpuCycles);
}
writeRegister(PC,pc);
src=readRegister(srcData);
dst=currentSegment.read(src,AccessMode.WORD20,AccessType.READ);
writeRegister(srcData,src + 4);
writeRegister(dstData,dst);
updateStatus=false;
cycles+=3;
break;
case MOVA_ABS2REG:
src=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
writeRegister(PC,pc+=2);
dst=src + (srcData << 16);
dst=currentSegment.read(dst,AccessMode.WORD20,AccessType.READ);
writeRegister(dstData,dst);
updateStatus=false;
cycles+=4;
break;
case MOVA_INDX2REG:
int index=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
int indexModifier=readRegister(srcData);
if (index > 0x8000) {
index=-(0x10000 - index);
}
if (indexModifier > 0x8000) {
indexModifier=-(0x10000 - indexModifier);
}
writeRegister(dstData,currentSegment.read(indexModifier + index,AccessMode.WORD20,AccessType.READ));
writeRegister(PC,pc+=2);
updateStatus=false;
cycles+=4;
break;
case MOVA_REG2ABS:
dst=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
writeRegister(PC,pc+=2);
currentSegment.write(dst + (dstData << 16),readRegister(srcData),AccessMode.WORD20);
updateStatus=false;
cycles+=4;
break;
case MOVA_REG2INDX:
index=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
indexModifier=readRegister(dstData);
if (index > 0x8000) {
index=-(0x10000 - index);
}
if (indexModifier > 0x8000) {
indexModifier=-(0x10000 - indexModifier);
}
currentSegment.write(indexModifier + index,readRegister(srcData),AccessMode.WORD20);
writeRegister(PC,pc+=2);
updateStatus=false;
cycles+=4;
break;
case MOVA_IMM2REG:
src=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
writeRegister(PC,pc+=2);
dst=src + (srcData << 16);
dst&=0xfffff;
writeRegister(dstData,dst);
updateStatus=false;
cycles+=2;
break;
case ADDA_IMM:
int immData=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + (srcData << 16);
writeRegister(PC,pc+=2);
dst=readRegister(dstData) + immData;
dst&=0xfffff;
writeRegister(dstData,dst);
cycles+=3;
break;
case CMPA_IMM:
{
immData=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + (srcData << 16);
writeRegister(PC,pc+=2);
sr=readRegister(SR);
int destRegValue=readRegister(dstData);
sr&=~(NEGATIVE | ZERO | CARRY| OVERFLOW);
if (destRegValue >= immData) {
sr|=CARRY;
}
if (destRegValue < immData) {
sr|=NEGATIVE;
}
if (destRegValue == immData) {
sr|=ZERO;
}
int cmpTmp=destRegValue - immData;
int b=0x80000;
if (((destRegValue ^ cmpTmp) & b) == 0 && (((destRegValue ^ immData) & b) != 0)) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
updateStatus=false;
cycles+=3;
break;
}
case SUBA_IMM:
immData=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + (srcData << 16);
writeRegister(PC,pc+=2);
dst=readRegister(dstData) - immData;
writeRegister(dstData,dst);
cycles+=3;
break;
case MOVA_REG:
cycles+=1;
writeRegister(dstData,readRegisterCG(srcData,0));
break;
case CMPA_REG:
{
sr=readRegister(SR);
sr&=~(NEGATIVE | ZERO | CARRY| OVERFLOW);
int destRegValue=readRegister(dstData);
int srcRegValue=readRegisterCG(srcData,0);
if (destRegValue >= srcRegValue) {
sr|=CARRY;
}
if (destRegValue < srcRegValue) {
sr|=NEGATIVE;
}
if (destRegValue == srcRegValue) {
sr|=ZERO;
}
int cmpTmp=destRegValue - srcRegValue;
int b=0x80000;
if (((destRegValue ^ cmpTmp) & b) == 0 && (((destRegValue ^ srcRegValue) & b) != 0)) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
updateStatus=false;
cycles+=1;
break;
}
case ADDA_REG:
dst=readRegister(dstData) + readRegisterCG(srcData,2);
writeRegister(dstData,dst);
cycles+=1;
break;
case SUBA_REG:
dst=readRegister(dstData) - readRegisterCG(srcData,2);
writeRegister(dstData,dst);
cycles+=1;
break;
case RRXX_ADDR:
rrword=false;
case RRXX_WORD:
int count=((instruction >> 10) & 0x03) + 1;
dst=readRegister(dstData);
sr=readRegister(SR);
int nxtCarry=0;
int carry=(sr & CARRY) > 0 ? 1 : 0;
if (rrword) {
mode=AccessMode.WORD;
dst=dst & 0xffff;
}
cycles+=1 + count;
switch (instruction & RRMASK) {
case RRCM:
int dst_low=dst & ((1 << count) - 1);
nxtCarry=(dst & (1 << (count + 1))) > 0 ? CARRY : 0;
dst=dst >> (count);
if (rrword) {
dst|=(dst_low << (17 - count)) | (carry << (16 - count));
}
 else {
dst|=(dst_low << (21 - count)) | (carry << (20 - count));
}
break;
case RRAM:
if ((dst & (rrword ? 0x8000 : 0x80000)) > 0) {
dst=dst | (rrword ? 0xf8000 : 0xf80000);
}
dst=dst >> (count - 1);
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
break;
case RLAM:
dst=dst << (count - 1);
nxtCarry=(dst & (rrword ? 0x8000 : 0x80000)) > 0 ? CARRY : 0;
dst=dst << 1;
break;
case RRUM:
dst=dst >> (count - 1);
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
break;
}
writeRegister(SR,(sr & ~(CARRY | OVERFLOW)) | nxtCarry);
dst=dst & (rrword ? 0xffff : 0xfffff);
writeRegister(dstData,dst);
break;
default :
System.out.println("String_Node_Str" + Utils.hex16(instruction) + "String_Node_Str"+ Utils.hex16(op));
throw new EmulationException("String_Node_Str" + Utils.hex16(instruction) + "String_Node_Str"+ Utils.hex16(op));
}
break;
case 1:
{
dstRegister=instruction & 0xf;
if ((op=instruction & CALLA_MASK) > RETI) {
pc=readRegister(PC);
dst=-1;
updateStatus=false;
switch (op) {
case CALLA_REG:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dst=readRegister(dstRegister);
System.out.println("String_Node_Str" + Utils.hex20(dst));
cycles+=5;
break;
case CALLA_INDEX:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
System.out.println("String_Node_Str" + dstRegister);
dst=readRegister(dstRegister);
int v=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((v & 0x8000) != 0) {
v|=0xf0000;
}
System.out.println("String_Node_Str" + Utils.hex20(dst) + "String_Node_Str"+ v);
dst+=v;
dst&=0xfffff;
System.out.println("String_Node_Str" + Utils.hex20(dst));
dst=currentSegment.read(dst,AccessMode.WORD20,AccessType.READ);
System.out.println("String_Node_Str" + Utils.hex20(dst));
cycles+=5;
pc+=2;
break;
case CALLA_IMM:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dst=(dstRegister << 16) | currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
pc+=2;
cycles+=5;
break;
case CALLA_IND:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dstAddress=readRegister(dstRegister);
dst=currentSegment.read(dstAddress,AccessMode.WORD20,AccessType.READ);
pc+=2;
cycles+=5;
break;
case CALLA_ABS:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dst=(dstRegister << 16) | currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
dst=currentSegment.read(dst,AccessMode.WORD20,AccessType.READ);
pc+=2;
cycles+=7;
break;
default :
AccessMode type=AccessMode.WORD;
int size=2;
sp=readRegister(SP);
switch (op & 0x1f00) {
case PUSHM_A:
type=AccessMode.WORD20;
size=4;
cycles+=2;
case PUSHM_W:
int n=1 + ((instruction >> 4) & 0x0f);
int regNo=instruction & 0x0f;
for (int i=0; i < n; i++) {
sp-=size;
cycles+=2;
currentSegment.write(sp,this.reg[regNo--],type);
if (regNo < 0) regNo=15;
}
writeRegister(SP,sp);
break;
case POPM_A:
type=AccessMode.WORD20;
size=4;
cycles+=2;
case POPM_W:
n=1 + ((instruction >> 4) & 0x0f);
regNo=instruction & 0x0f;
for (int i=0; i < n; i++) {
cycles+=2;
this.reg[regNo++]=currentSegment.read(sp,type,AccessType.READ);
sp+=size;
if (regNo > 15) regNo=0;
}
writeRegister(SP,sp);
break;
default :
System.out.println("String_Node_Str");
throw new EmulationException("String_Node_Str" + Utils.hex16(instruction) + "String_Node_Str"+ Utils.hex16(op));
}
}
if (dst != -1) {
currentSegment.write(sp,(pc >> 16) & 0xf,AccessMode.WORD);
sp=sp - 2;
currentSegment.write(sp,pc & 0xffff,AccessMode.WORD);
writeRegister(SP,sp);
writeRegister(PC,dst);
if (profiler != null) {
profileCall(dst,pc);
}
}
}
 else {
int ad=(instruction >> 4) & 3;
int nxtCarry=0;
op=instruction & 0xff80;
if (op == PUSH || op == CALL) {
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:
rval=readRegisterCG(dstRegister,ad);
if (extWord != 0) {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + extDst;
dstAddress+=rval;
dstAddress&=0xfffff;
}
 else if (rval <= 0xffff) {
dstAddress=(rval + currentSegment.read(pc,AccessMode.WORD,AccessType.READ)) & 0xffff;
}
 else {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((dstAddress & 0x8000) > 0) {
dstAddress|=0xf0000;
}
dstAddress+=rval;
dstAddress&=0xfffff;
}
pc+=2;
writeRegister(PC,pc);
cycles+=4;
break;
case AM_IND_REG:
dstAddress=readRegister(dstRegister);
cycles+=3;
break;
case AM_IND_AUTOINC:
if (dstRegister == PC) {
dstAddress=pc;
dst=currentSegment.read(dstAddress,mode != AccessMode.BYTE ? AccessMode.WORD : AccessMode.BYTE,AccessType.READ);
dst+=extDst;
pc+=2;
writeRegister(PC,pc);
}
 else {
dstAddress=readRegister(dstRegister);
writeRegister(dstRegister,dstAddress + mode.bytes);
}
cycles+=3;
break;
}
}
if (dstRegMode) {
dst=readRegisterCG(dstRegister,ad);
dst&=mode.mask;
if (repeatsInDstReg) {
repeats=1 + readRegister(ext3_0);
}
 else {
repeats=1 + ext3_0;
}
zeroCarry=(extWord & EXTWORD_ZC) > 0;
}
 else if (dst == -1) {
dst=currentSegment.read(dstAddress,mode,AccessType.READ);
}
while (repeats-- > 0) {
sr=readRegister(SR);
if (repeats >= 0) {
if (zeroCarry) {
sr=sr & ~CARRY;
}
}
switch (op) {
case RRC:
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
dst|=(sr & CARRY) > 0 ? mode.msb : 0;
write=true;
writeRegister(SR,(sr & ~(CARRY | OVERFLOW)) | 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;
dst=(dst & mode.msb) | dst >> 1;
write=true;
writeRegister(SR,(sr & ~(CARRY | OVERFLOW)) | nxtCarry);
break;
case SXT:
dst=(dst & 0x80) > 0 ? dst | 0xfff00 : dst & 0x7f;
write=true;
sr=sr & ~(CARRY | OVERFLOW);
if (dst != 0) {
sr|=CARRY;
}
writeRegister(SR,sr);
break;
case PUSH:
if (mode == AccessMode.WORD20) {
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
}
currentSegment.write(sp,dst,mode);
cycles+=(ad == AM_REG || ad == AM_IND_AUTOINC) ? 2 : 1;
write=false;
updateStatus=false;
break;
case CALL:
pc=readRegister(PC);
currentSegment.write(sp,pc,AccessMode.WORD);
writeRegister(PC,dst);
cycles+=(ad == AM_REG) ? 3 : (ad == AM_IND_AUTOINC) ? 2 : 1;
if (profiler != null) {
profileCall(dst,pc);
}
write=false;
updateStatus=false;
break;
case RETI:
servicedInterrupt=-1;
sp=readRegister(SP);
sr=currentSegment.read(sp,AccessMode.WORD,AccessType.READ);
writeRegister(SR,sr & 0x0fff);
sp=sp + 2;
writeRegister(PC,currentSegment.read(sp,AccessMode.WORD,AccessType.READ) | (sr & 0xf000) << 4);
sp=sp + 2;
writeRegister(SP,sp);
write=false;
updateStatus=false;
cycles+=4;
if (debugInterrupts) {
System.out.println("String_Node_Str" + pc + "String_Node_Str"+ reg[PC]+ "String_Node_Str"+ reg[SP]);
}
if (profiler != null) {
profiler.profileRETI(cycles);
}
handlePendingInterrupts();
break;
default :
System.out.println("String_Node_Str" + Utils.hex16(instruction));
}
if (repeats > 0) {
dst&=mode.mask;
}
}
}
}
break;
case 2:
case 3:
int jmpOffset=instruction & 0x3ff;
jmpOffset=(jmpOffset & 0x200) == 0 ? 2 * jmpOffset : -(2 * (0x200 - (jmpOffset & 0x1ff)));
boolean jump=false;
cycles+=2;
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 :
logw(WarningType.EMULATION_ERROR,"String_Node_Str" + Utils.binary16(instruction));
}
if (jump) {
writeRegister(PC,pc + jmpOffset);
}
updateStatus=false;
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;
src=0;
if ((srcRegister == CG1 && as > AM_INDEX) || srcRegister == CG2) {
src=CREG_VALUES[srcRegister - 2][as];
src&=mode.mask;
cycles+=dstRegMode ? 1 : 4;
}
 else {
switch (as) {
case AM_REG:
src=readRegister(srcRegister);
src&=mode.mask;
cycles+=dstRegMode ? 1 : 4;
if (dstRegister == PC) cycles++;
if (dstRegMode) {
if (repeatsInDstReg) {
repeats=1 + readRegister(ext3_0);
}
 else {
repeats=1 + ext3_0;
}
zeroCarry=(extWord & EXTWORD_ZC) > 0;
}
break;
case AM_INDEX:
{
int sval=readRegisterCG(srcRegister,as);
if (extWord != 0) {
srcAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + extSrc;
srcAddress+=sval;
srcAddress&=0xfffff;
}
 else if (sval <= 0xffff) {
srcAddress=(sval + currentSegment.read(pc,AccessMode.WORD,AccessType.READ)) & 0xffff;
}
 else {
srcAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((srcAddress & 0x8000) > 0) {
srcAddress|=0xf0000;
}
srcAddress+=sval;
srcAddress&=0xfffff;
}
pc+=2;
writeRegister(PC,pc);
cycles+=dstRegMode ? 3 : 6;
break;
}
case AM_IND_REG:
srcAddress=readRegister(srcRegister);
cycles+=dstRegMode ? 2 : 5;
break;
case AM_IND_AUTOINC:
if (srcRegister == PC) {
src=currentSegment.read(pc,mode != AccessMode.BYTE ? AccessMode.WORD : AccessMode.BYTE,AccessType.READ);
src+=extSrc;
pc+=2;
writeRegister(PC,pc);
cycles+=dstRegMode ? 2 : 5;
}
 else {
srcAddress=readRegister(srcRegister);
incRegister(srcRegister,mode.bytes);
cycles+=dstRegMode ? 2 : 5;
}
if (dstRegister == PC) {
cycles++;
}
break;
}
}
if (dstRegMode) {
if (op != MOV) {
dst=readRegister(dstRegister);
dst&=mode.mask;
}
}
 else {
pc=readRegister(PC);
if (dstRegister == 2) {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
}
 else {
rval=readRegister(dstRegister);
if (rval <= 0xffff) {
dstAddress=(rval + currentSegment.read(pc,AccessMode.WORD,AccessType.READ)) & 0xffff;
}
 else {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((dstAddress & 0x8000) > 0) {
dstAddress|=0xf0000;
}
dstAddress+=rval;
dstAddress&=0xfffff;
}
}
if (op != MOV) {
dst=currentSegment.read(dstAddress,word ? AccessMode.WORD : AccessMode.BYTE,AccessType.READ);
}
pc+=2;
incRegister(PC,2);
}
if (srcAddress != -1) {
src=currentSegment.read(srcAddress,mode,AccessType.READ);
}
while (repeats-- > 0) {
sr=readRegister(SR);
if (repeats >= 0) {
if (zeroCarry) {
sr=sr & ~CARRY;
}
}
int tmp=0;
int tmpAdd=0;
switch (op) {
case MOV:
dst=src;
write=true;
updateStatus=false;
if (instruction == RETURN && profiler != null) {
profiler.profileReturn(cpuCycles);
}
break;
case SUB:
tmpAdd=1;
case SUBC:
src=(src ^ 0xffff) & 0xffff;
case ADDC:
if (op == ADDC || op == SUBC) tmpAdd=((sr & CARRY) > 0) ? 1 : 0;
case ADD:
sr&=~(OVERFLOW | CARRY);
int b=word ? 0x8000 : (wordx20 ? 0x80000 : 0x80);
tmp=(src ^ dst) & b;
dst=dst + src + tmpAdd;
int b2=word ? 0xffff : (wordx20 ? 0xfffff : 0xff);
if (dst > b2) {
sr|=CARRY;
}
if (tmp == 0 && ((src ^ dst) & b) != 0) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
write=true;
break;
case CMP:
b=mode.msb;
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) log("String_Node_Str");
dst=dst + src + ((sr & CARRY) > 0 ? 1 : 0);
write=true;
break;
case BIT:
dst=src & dst;
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:
sr=sr & ~(CARRY | OVERFLOW);
b=mode.msb;
if ((src & b) != 0 && (dst & b) != 0) {
sr|=OVERFLOW;
}
dst=src ^ dst;
if (dst != 0) {
sr|=CARRY;
}
write=true;
writeRegister(SR,sr);
break;
case AND:
sr=sr & ~(CARRY | OVERFLOW);
dst=src & dst;
if (dst != 0) {
sr|=CARRY;
}
write=true;
writeRegister(SR,sr);
break;
default :
String address=getAddressAsString(pc);
logw(WarningType.EMULATION_ERROR,"String_Node_Str" + Integer.toHexString(op) + "String_Node_Str"+ address);
if (EXCEPTION_ON_BAD_OPERATION) {
EmulationException ex=new EmulationException("String_Node_Str" + Integer.toHexString(op) + "String_Node_Str"+ address);
ex.initCause(new Throwable("String_Node_Str" + pc));
throw ex;
}
}
if (repeats > 0 && srcRegister == dstRegister) {
src=dst;
src&=mode.mask;
}
}
}
dst&=mode.mask;
if (write) {
if (dstRegMode) {
writeRegister(dstRegister,dst);
}
 else {
dstAddress&=0xffff;
currentSegment.write(dstAddress,dst,mode);
}
}
if (updateStatus) {
sr=readRegister(SR);
sr=(sr & ~(ZERO | NEGATIVE)) | ((dst == 0) ? ZERO : 0) | ((dst & mode.msb) > 0 ? NEGATIVE : 0);
writeRegister(SR,sr);
}
while (cycles >= nextEventCycles) {
executeEvents();
}
cpuCycles+=cycles - startCycles;
return pcBefore;
}

Fixed version (ground truth):
public int emulateOP(long maxCycles) throws EmulationException {
  int pc=readRegister(PC);
  long startCycles=cycles;
  if (interruptsEnabled && servicedInterrupt == -1 && interruptMax >= 0) {
    pc=serviceInterrupt(pc);
  }
  if (cpuOff || flash.blocksCPU()) {
    while (cycles >= nextEventCycles) {
      executeEvents();
    }
    if (interruptsEnabled && interruptMax > 0) {
      return -1;
    }
    if (maxCycles >= 0 && maxCycles < nextEventCycles) {
      cycles=cycles < maxCycles ? maxCycles : cycles;
    }
 else {
      cycles=nextEventCycles;
    }
    return -1;
  }
  int pcBefore=pc;
  instruction=currentSegment.read(pc,AccessMode.WORD,AccessType.EXECUTE);
  if (isStopping) {
    return -2;
  }
  int ext3_0=0;
  int ext10_7=0;
  int extSrc=0;
  int extDst=0;
  boolean repeatsInDstReg=false;
  boolean wordx20=false;
  if ((instruction & 0xf800) == 0x1800) {
    extWord=instruction;
    ext3_0=instruction & 0xf;
    ext10_7=(instruction >> 7) & 0xf;
    extSrc=ext10_7 << 16;
    extDst=ext3_0 << 16;
    pc+=2;
    if ((instruction & 0x80) == 0x80) {
      repeatsInDstReg=true;
    }
    wordx20=(instruction & 0x40) == 0;
    instruction=currentSegment.read(pc,AccessMode.WORD,AccessType.EXECUTE);
  }
 else {
    extWord=0;
  }
  op=instruction >> 12;
  int sp=0;
  int sr=0;
  int rval=0;
  int repeats=1;
  boolean zeroCarry=false;
  boolean word=(instruction & 0x40) == 0;
  AccessMode mode=wordx20 ? AccessMode.WORD20 : (word ? AccessMode.WORD : AccessMode.BYTE);
  if (mode == AccessMode.WORD20)   System.out.println("String_Node_Str");
  int dstRegister=0;
  int dstAddress=-1;
  boolean dstRegMode=false;
  int dst=-1;
  boolean write=false;
  boolean updateStatus=true;
  pc+=2;
  writeRegister(PC,pc);
switch (op) {
case 0:
    op=instruction & 0xf0f0;
  if (!MSP430XArch)   throw new EmulationException("String_Node_Str");
int src=0;
int srcData=(instruction & 0x0f00) >> 8;
int dstData=(instruction & 0x000f);
boolean rrword=true;
mode=AccessMode.WORD20;
switch (op) {
case MOVA_IND:
writeRegister(dstData,currentSegment.read(readRegister(srcData),AccessMode.WORD20,AccessType.READ));
updateStatus=false;
cycles+=3;
break;
case MOVA_IND_AUTOINC:
if (profiler != null && instruction == 0x0110) {
profiler.profileReturn(cpuCycles);
}
writeRegister(PC,pc);
src=readRegister(srcData);
dst=currentSegment.read(src,AccessMode.WORD20,AccessType.READ);
writeRegister(srcData,src + 4);
writeRegister(dstData,dst);
updateStatus=false;
cycles+=3;
break;
case MOVA_ABS2REG:
src=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
writeRegister(PC,pc+=2);
dst=src + (srcData << 16);
dst=currentSegment.read(dst,AccessMode.WORD20,AccessType.READ);
writeRegister(dstData,dst);
updateStatus=false;
cycles+=4;
break;
case MOVA_INDX2REG:
int index=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
int indexModifier=readRegister(srcData);
if (index > 0x8000) {
index=-(0x10000 - index);
}
writeRegister(dstData,currentSegment.read(indexModifier + index,AccessMode.WORD20,AccessType.READ));
writeRegister(PC,pc+=2);
updateStatus=false;
cycles+=4;
break;
case MOVA_REG2ABS:
dst=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
writeRegister(PC,pc+=2);
currentSegment.write(dst + (dstData << 16),readRegister(srcData),AccessMode.WORD20);
updateStatus=false;
cycles+=4;
break;
case MOVA_REG2INDX:
index=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
indexModifier=readRegister(dstData);
if (index > 0x8000) {
index=-(0x10000 - index);
}
currentSegment.write(indexModifier + index,readRegister(srcData),AccessMode.WORD20);
writeRegister(PC,pc+=2);
updateStatus=false;
cycles+=4;
break;
case MOVA_IMM2REG:
src=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
writeRegister(PC,pc+=2);
dst=src + (srcData << 16);
dst&=0xfffff;
writeRegister(dstData,dst);
updateStatus=false;
cycles+=2;
break;
case ADDA_IMM:
int immData=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + (srcData << 16);
writeRegister(PC,pc+=2);
dst=readRegister(dstData) + immData;
dst&=0xfffff;
writeRegister(dstData,dst);
cycles+=3;
break;
case CMPA_IMM:
{
immData=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + (srcData << 16);
writeRegister(PC,pc+=2);
sr=readRegister(SR);
int destRegValue=readRegister(dstData);
sr&=~(NEGATIVE | ZERO | CARRY| OVERFLOW);
if (destRegValue >= immData) {
sr|=CARRY;
}
if (destRegValue < immData) {
sr|=NEGATIVE;
}
if (destRegValue == immData) {
sr|=ZERO;
}
int cmpTmp=destRegValue - immData;
int b=0x80000;
if (((destRegValue ^ cmpTmp) & b) == 0 && (((destRegValue ^ immData) & b) != 0)) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
updateStatus=false;
cycles+=3;
break;
}
case SUBA_IMM:
immData=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + (srcData << 16);
writeRegister(PC,pc+=2);
dst=readRegister(dstData) - immData;
writeRegister(dstData,dst);
cycles+=3;
break;
case MOVA_REG:
cycles+=1;
writeRegister(dstData,readRegisterCG(srcData,0));
break;
case CMPA_REG:
{
sr=readRegister(SR);
sr&=~(NEGATIVE | ZERO | CARRY| OVERFLOW);
int destRegValue=readRegister(dstData);
int srcRegValue=readRegisterCG(srcData,0);
if (destRegValue >= srcRegValue) {
sr|=CARRY;
}
if (destRegValue < srcRegValue) {
sr|=NEGATIVE;
}
if (destRegValue == srcRegValue) {
sr|=ZERO;
}
int cmpTmp=destRegValue - srcRegValue;
int b=0x80000;
if (((destRegValue ^ cmpTmp) & b) == 0 && (((destRegValue ^ srcRegValue) & b) != 0)) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
updateStatus=false;
cycles+=1;
break;
}
case ADDA_REG:
dst=readRegister(dstData) + readRegisterCG(srcData,2);
writeRegister(dstData,dst);
cycles+=1;
break;
case SUBA_REG:
dst=readRegister(dstData) - readRegisterCG(srcData,2);
writeRegister(dstData,dst);
cycles+=1;
break;
case RRXX_ADDR:
rrword=false;
case RRXX_WORD:
int count=((instruction >> 10) & 0x03) + 1;
dst=readRegister(dstData);
sr=readRegister(SR);
int nxtCarry=0;
int carry=(sr & CARRY) > 0 ? 1 : 0;
if (rrword) {
mode=AccessMode.WORD;
dst=dst & 0xffff;
}
cycles+=1 + count;
switch (instruction & RRMASK) {
case RRCM:
int dst_low=dst & ((1 << count) - 1);
nxtCarry=(dst & (1 << (count + 1))) > 0 ? CARRY : 0;
dst=dst >> (count);
if (rrword) {
dst|=(dst_low << (17 - count)) | (carry << (16 - count));
}
 else {
dst|=(dst_low << (21 - count)) | (carry << (20 - count));
}
break;
case RRAM:
if ((dst & (rrword ? 0x8000 : 0x80000)) > 0) {
dst=dst | (rrword ? 0xf8000 : 0xf80000);
}
dst=dst >> (count - 1);
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
break;
case RLAM:
dst=dst << (count - 1);
nxtCarry=(dst & (rrword ? 0x8000 : 0x80000)) > 0 ? CARRY : 0;
dst=dst << 1;
break;
case RRUM:
dst=dst >> (count - 1);
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
break;
}
writeRegister(SR,(sr & ~(CARRY | OVERFLOW)) | nxtCarry);
dst=dst & (rrword ? 0xffff : 0xfffff);
writeRegister(dstData,dst);
break;
default :
System.out.println("String_Node_Str" + Utils.hex16(instruction) + "String_Node_Str"+ Utils.hex16(op));
throw new EmulationException("String_Node_Str" + Utils.hex16(instruction) + "String_Node_Str"+ Utils.hex16(op));
}
break;
case 1:
{
dstRegister=instruction & 0xf;
if ((op=instruction & CALLA_MASK) > RETI) {
pc=readRegister(PC);
dst=-1;
updateStatus=false;
switch (op) {
case CALLA_REG:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dst=readRegister(dstRegister);
System.out.println("String_Node_Str" + Utils.hex20(dst));
cycles+=5;
break;
case CALLA_INDEX:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
System.out.println("String_Node_Str" + dstRegister);
dst=readRegister(dstRegister);
int v=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((v & 0x8000) != 0) {
v|=0xf0000;
}
System.out.println("String_Node_Str" + Utils.hex20(dst) + "String_Node_Str"+ v);
dst+=v;
dst&=0xfffff;
System.out.println("String_Node_Str" + Utils.hex20(dst));
dst=currentSegment.read(dst,AccessMode.WORD20,AccessType.READ);
System.out.println("String_Node_Str" + Utils.hex20(dst));
cycles+=5;
pc+=2;
break;
case CALLA_IMM:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dst=(dstRegister << 16) | currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
pc+=2;
cycles+=5;
break;
case CALLA_IND:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dstAddress=readRegister(dstRegister);
dst=currentSegment.read(dstAddress,AccessMode.WORD20,AccessType.READ);
pc+=2;
cycles+=5;
break;
case CALLA_ABS:
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
dst=(dstRegister << 16) | currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
dst=currentSegment.read(dst,AccessMode.WORD20,AccessType.READ);
pc+=2;
cycles+=7;
break;
default :
AccessMode type=AccessMode.WORD;
int size=2;
sp=readRegister(SP);
switch (op & 0x1f00) {
case PUSHM_A:
type=AccessMode.WORD20;
size=4;
cycles+=2;
case PUSHM_W:
int n=1 + ((instruction >> 4) & 0x0f);
int regNo=instruction & 0x0f;
for (int i=0; i < n; i++) {
sp-=size;
cycles+=2;
currentSegment.write(sp,this.reg[regNo--],type);
if (regNo < 0) regNo=15;
}
writeRegister(SP,sp);
break;
case POPM_A:
type=AccessMode.WORD20;
size=4;
cycles+=2;
case POPM_W:
n=1 + ((instruction >> 4) & 0x0f);
regNo=instruction & 0x0f;
for (int i=0; i < n; i++) {
cycles+=2;
this.reg[regNo++]=currentSegment.read(sp,type,AccessType.READ);
sp+=size;
if (regNo > 15) regNo=0;
}
writeRegister(SP,sp);
break;
default :
System.out.println("String_Node_Str");
throw new EmulationException("String_Node_Str" + Utils.hex16(instruction) + "String_Node_Str"+ Utils.hex16(op));
}
}
if (dst != -1) {
currentSegment.write(sp,(pc >> 16) & 0xf,AccessMode.WORD);
sp=sp - 2;
currentSegment.write(sp,pc & 0xffff,AccessMode.WORD);
writeRegister(SP,sp);
writeRegister(PC,dst);
if (profiler != null) {
profileCall(dst,pc);
}
}
}
 else {
int ad=(instruction >> 4) & 3;
int nxtCarry=0;
op=instruction & 0xff80;
if (op == PUSH || op == CALL) {
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:
rval=readRegisterCG(dstRegister,ad);
if (extWord != 0) {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + extDst;
dstAddress+=rval;
dstAddress&=0xfffff;
}
 else if (rval <= 0xffff) {
dstAddress=(rval + currentSegment.read(pc,AccessMode.WORD,AccessType.READ)) & 0xffff;
}
 else {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((dstAddress & 0x8000) > 0) {
dstAddress|=0xf0000;
}
dstAddress+=rval;
dstAddress&=0xfffff;
}
pc+=2;
writeRegister(PC,pc);
cycles+=4;
break;
case AM_IND_REG:
dstAddress=readRegister(dstRegister);
cycles+=3;
break;
case AM_IND_AUTOINC:
if (dstRegister == PC) {
dstAddress=pc;
dst=currentSegment.read(dstAddress,mode != AccessMode.BYTE ? AccessMode.WORD : AccessMode.BYTE,AccessType.READ);
dst+=extDst;
pc+=2;
writeRegister(PC,pc);
}
 else {
dstAddress=readRegister(dstRegister);
writeRegister(dstRegister,dstAddress + mode.bytes);
}
cycles+=3;
break;
}
}
if (dstRegMode) {
dst=readRegisterCG(dstRegister,ad);
dst&=mode.mask;
if (repeatsInDstReg) {
repeats=1 + readRegister(ext3_0);
}
 else {
repeats=1 + ext3_0;
}
zeroCarry=(extWord & EXTWORD_ZC) > 0;
}
 else if (dst == -1) {
dst=currentSegment.read(dstAddress,mode,AccessType.READ);
}
while (repeats-- > 0) {
sr=readRegister(SR);
if (repeats >= 0) {
if (zeroCarry) {
sr=sr & ~CARRY;
}
}
switch (op) {
case RRC:
nxtCarry=(dst & 1) > 0 ? CARRY : 0;
dst=dst >> 1;
dst|=(sr & CARRY) > 0 ? mode.msb : 0;
write=true;
writeRegister(SR,(sr & ~(CARRY | OVERFLOW)) | 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;
dst=(dst & mode.msb) | dst >> 1;
write=true;
writeRegister(SR,(sr & ~(CARRY | OVERFLOW)) | nxtCarry);
break;
case SXT:
dst=(dst & 0x80) > 0 ? dst | 0xfff00 : dst & 0x7f;
write=true;
sr=sr & ~(CARRY | OVERFLOW);
if (dst != 0) {
sr|=CARRY;
}
writeRegister(SR,sr);
break;
case PUSH:
if (mode == AccessMode.WORD20) {
sp=readRegister(SP) - 2;
writeRegister(SP,sp);
}
currentSegment.write(sp,dst,mode);
cycles+=(ad == AM_REG || ad == AM_IND_AUTOINC) ? 2 : 1;
write=false;
updateStatus=false;
break;
case CALL:
pc=readRegister(PC);
currentSegment.write(sp,pc,AccessMode.WORD);
writeRegister(PC,dst);
cycles+=(ad == AM_REG) ? 3 : (ad == AM_IND_AUTOINC) ? 2 : 1;
if (profiler != null) {
profileCall(dst,pc);
}
write=false;
updateStatus=false;
break;
case RETI:
servicedInterrupt=-1;
sp=readRegister(SP);
sr=currentSegment.read(sp,AccessMode.WORD,AccessType.READ);
writeRegister(SR,sr & 0x0fff);
sp=sp + 2;
writeRegister(PC,currentSegment.read(sp,AccessMode.WORD,AccessType.READ) | (sr & 0xf000) << 4);
sp=sp + 2;
writeRegister(SP,sp);
write=false;
updateStatus=false;
cycles+=4;
if (debugInterrupts) {
System.out.println("String_Node_Str" + pc + "String_Node_Str"+ reg[PC]+ "String_Node_Str"+ reg[SP]);
}
if (profiler != null) {
profiler.profileRETI(cycles);
}
handlePendingInterrupts();
break;
default :
System.out.println("String_Node_Str" + Utils.hex16(instruction));
}
if (repeats > 0) {
dst&=mode.mask;
}
}
}
}
break;
case 2:
case 3:
int jmpOffset=instruction & 0x3ff;
jmpOffset=(jmpOffset & 0x200) == 0 ? 2 * jmpOffset : -(2 * (0x200 - (jmpOffset & 0x1ff)));
boolean jump=false;
cycles+=2;
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 :
logw(WarningType.EMULATION_ERROR,"String_Node_Str" + Utils.binary16(instruction));
}
if (jump) {
writeRegister(PC,pc + jmpOffset);
}
updateStatus=false;
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;
src=0;
if ((srcRegister == CG1 && as > AM_INDEX) || srcRegister == CG2) {
src=CREG_VALUES[srcRegister - 2][as];
src&=mode.mask;
cycles+=dstRegMode ? 1 : 4;
}
 else {
switch (as) {
case AM_REG:
src=readRegister(srcRegister);
src&=mode.mask;
cycles+=dstRegMode ? 1 : 4;
if (dstRegister == PC) cycles++;
if (dstRegMode) {
if (repeatsInDstReg) {
repeats=1 + readRegister(ext3_0);
}
 else {
repeats=1 + ext3_0;
}
zeroCarry=(extWord & EXTWORD_ZC) > 0;
}
break;
case AM_INDEX:
{
int sval=readRegisterCG(srcRegister,as);
if (extWord != 0) {
srcAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ) + extSrc;
srcAddress+=sval;
srcAddress&=0xfffff;
}
 else if (sval <= 0xffff) {
srcAddress=(sval + currentSegment.read(pc,AccessMode.WORD,AccessType.READ)) & 0xffff;
}
 else {
srcAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((srcAddress & 0x8000) > 0) {
srcAddress|=0xf0000;
}
srcAddress+=sval;
srcAddress&=0xfffff;
}
pc+=2;
writeRegister(PC,pc);
cycles+=dstRegMode ? 3 : 6;
break;
}
case AM_IND_REG:
srcAddress=readRegister(srcRegister);
cycles+=dstRegMode ? 2 : 5;
break;
case AM_IND_AUTOINC:
if (srcRegister == PC) {
src=currentSegment.read(pc,mode != AccessMode.BYTE ? AccessMode.WORD : AccessMode.BYTE,AccessType.READ);
src+=extSrc;
pc+=2;
writeRegister(PC,pc);
cycles+=dstRegMode ? 2 : 5;
}
 else {
srcAddress=readRegister(srcRegister);
incRegister(srcRegister,mode.bytes);
cycles+=dstRegMode ? 2 : 5;
}
if (dstRegister == PC) {
cycles++;
}
break;
}
}
if (dstRegMode) {
if (op != MOV) {
dst=readRegister(dstRegister);
dst&=mode.mask;
}
}
 else {
pc=readRegister(PC);
if (dstRegister == 2) {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
}
 else {
rval=readRegister(dstRegister);
if (rval <= 0xffff) {
dstAddress=(rval + currentSegment.read(pc,AccessMode.WORD,AccessType.READ)) & 0xffff;
}
 else {
dstAddress=currentSegment.read(pc,AccessMode.WORD,AccessType.READ);
if ((dstAddress & 0x8000) > 0) {
dstAddress|=0xf0000;
}
dstAddress+=rval;
dstAddress&=0xfffff;
}
}
if (op != MOV) {
dst=currentSegment.read(dstAddress,word ? AccessMode.WORD : AccessMode.BYTE,AccessType.READ);
}
pc+=2;
incRegister(PC,2);
}
if (srcAddress != -1) {
src=currentSegment.read(srcAddress,mode,AccessType.READ);
}
while (repeats-- > 0) {
sr=readRegister(SR);
if (repeats >= 0) {
if (zeroCarry) {
sr=sr & ~CARRY;
}
}
int tmp=0;
int tmpAdd=0;
switch (op) {
case MOV:
dst=src;
write=true;
updateStatus=false;
if (instruction == RETURN && profiler != null) {
profiler.profileReturn(cpuCycles);
}
break;
case SUB:
tmpAdd=1;
case SUBC:
src=(src ^ 0xffff) & 0xffff;
case ADDC:
if (op == ADDC || op == SUBC) tmpAdd=((sr & CARRY) > 0) ? 1 : 0;
case ADD:
sr&=~(OVERFLOW | CARRY);
int b=word ? 0x8000 : (wordx20 ? 0x80000 : 0x80);
tmp=(src ^ dst) & b;
dst=dst + src + tmpAdd;
int b2=word ? 0xffff : (wordx20 ? 0xfffff : 0xff);
if (dst > b2) {
sr|=CARRY;
}
if (tmp == 0 && ((src ^ dst) & b) != 0) {
sr|=OVERFLOW;
}
writeRegister(SR,sr);
write=true;
break;
case CMP:
b=mode.msb;
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) log("String_Node_Str");
dst=dst + src + ((sr & CARRY) > 0 ? 1 : 0);
write=true;
break;
case BIT:
dst=src & dst;
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:
sr=sr & ~(CARRY | OVERFLOW);
b=mode.msb;
if ((src & b) != 0 && (dst & b) != 0) {
sr|=OVERFLOW;
}
dst=src ^ dst;
if (dst != 0) {
sr|=CARRY;
}
write=true;
writeRegister(SR,sr);
break;
case AND:
sr=sr & ~(CARRY | OVERFLOW);
dst=src & dst;
if (dst != 0) {
sr|=CARRY;
}
write=true;
writeRegister(SR,sr);
break;
default :
String address=getAddressAsString(pc);
logw(WarningType.EMULATION_ERROR,"String_Node_Str" + Integer.toHexString(op) + "String_Node_Str"+ address);
if (EXCEPTION_ON_BAD_OPERATION) {
EmulationException ex=new EmulationException("String_Node_Str" + Integer.toHexString(op) + "String_Node_Str"+ address);
ex.initCause(new Throwable("String_Node_Str" + pc));
throw ex;
}
}
if (repeats > 0 && srcRegister == dstRegister) {
src=dst;
src&=mode.mask;
}
}
}
dst&=mode.mask;
if (write) {
if (dstRegMode) {
writeRegister(dstRegister,dst);
}
 else {
dstAddress&=0xffff;
currentSegment.write(dstAddress,dst,mode);
}
}
if (updateStatus) {
sr=readRegister(SR);
sr=(sr & ~(ZERO | NEGATIVE)) | ((dst == 0) ? ZERO : 0) | ((dst & mode.msb) > 0 ? NEGATIVE : 0);
writeRegister(SR,sr);
}
while (cycles >= nextEventCycles) {
executeEvents();
}
cpuCycles+=cycles - startCycles;
return pcBefore;
}