public int Execute() { int SaveC; int Operand = 0, Temp = 0; int FetchCode; int NOPS, TempPC; if (Breakpoint.Contains(PC) || debug) { // Do something for a hardware breaskpoint // Log stuff //if (!((PC >= 0xFE3A) && (PC <= 0xFE4F))) // Ignore OUTCH //{ // System.Diagnostics.Debug.WriteLine(string.Format("PC:{0,4:X} A:{1,2:X} B:{2,2:X} IX:{3,4:X} SP:{4,4:X}", PC, A, B, IX, SP)); //} } if (!((PC >= 0xFE3A) && (PC <= 0xFE4F))) // Ignore OUTCH { System.Diagnostics.Debug.WriteLine(string.Format("PC:{0,4:X} A:{1,2:X} B:{2,2:X} IX:{3,4:X} SP:{4,4:X} CC:{5,6}", PC, A, B, IX, SP, Convert.ToString(Flags.H * 32 + Flags.I * 16 + Flags.N * 8 + Flags.Z * 4 + Flags.V * 2 + Flags.C, 2))); } FetchCode = ReadMem(PC); Clock = Clock + Cycles[FetchCode]; switch (AddrMode[FetchCode]) { case IMMEDIATE: Operand = ReadMem(PC + 1); break; case DIRECT: Operand = ReadMem(ReadMem(PC + 1)); break; case INDEXED: Operand = ReadMem(IX + ReadMem(PC + 1)); break; case EXTENDED: Operand = ReadMem((ReadMem(PC + 1) << 8) + ReadMem(PC + 2)); break; case INHERENT: // break; case RELATIVE: Operand = ReadMem(PC + 1); if (Operand > 0x80) { Operand = (0 - Operand) & 0xFF; Operand = -Operand; } break; } ; switch (FetchCode) { //============ LOGIC OPCODES ========== //ADDA case 0x8B: case 0x9B: case 0xAB: case 0xBB: Temp = A; Temp += Operand; TestH(A, Operand, Temp); TestC(A, Operand, Temp); TestV(A, Operand, Temp); A = Temp & 0xFF; TestN(A); TestZ(A); break; //ADDB case 0xCB: case 0xDB: case 0xEB: case 0xFB: Temp = B; Temp += Operand; TestH(B, Operand, Temp); TestC(B, Operand, Temp); TestV(B, Operand, Temp); B = Temp & 0xFF; TestN(B); TestZ(B); break; //ABA case 0x1B: Temp = A; Temp += B; TestH(A, B, Temp); TestC(A, B, Temp); TestV(A, B, Temp); A = Temp & 0xFF; TestN(A); TestZ(A); break; //ADCA case 0x89: case 0x99: case 0xA9: case 0xB9: Temp = A; Temp += Operand + Flags.C; TestH(A, Operand, Temp); TestC(A, Operand, Temp); TestV(A, Operand, Temp); A = Temp & 0xFF; TestN(A); TestZ(A); break; //ADCB case 0xC9: case 0xD9: case 0xE9: case 0xF9: Temp = B; Temp += Operand + Flags.C; TestH(B, Operand, Temp); TestC(B, Operand, Temp); TestV(B, Operand, Temp); B = Temp & 0xFF; TestN(B); TestZ(B); break; //ANDA case 0x84: case 0x94: case 0xA4: case 0xB4: A &= Operand; TestN(A); TestZ(A); Flags.V = 0; break; //ANDB case 0xC4: case 0xD4: case 0xE4: case 0xF4: B &= Operand; TestN(B); TestZ(B); Flags.V = 0; break; //BITA case 0x85: case 0x95: case 0xA5: case 0xB5: Temp = A & Operand; TestN(Temp); TestZ(Temp); Flags.V = 0; break; //BITB case 0xC5: case 0xD5: case 0xE5: case 0xF5: Temp = B & Operand; TestN(Temp); TestZ(Temp); Flags.V = 0; break; //CLR case 0x6F: WriteMem(IX + ReadMem(PC + 1), 0); Flags.N = 0; Flags.Z = 1; Flags.V = 0; Flags.C = 0; break; case 0x7F: WriteMem((ReadMem(PC + 1) << 8) + ReadMem(PC + 2), 0); Flags.N = 0; Flags.Z = 1; Flags.V = 0; Flags.C = 0; break; //CLRA case 0x4F: A = 0; Flags.N = 0; Flags.Z = 1; Flags.V = 0; Flags.C = 0; break; //CLRB case 0x5F: B = 0; Flags.N = 0; Flags.Z = 1; Flags.V = 0; Flags.C = 0; break; //CMPA case 0x81: case 0x91: case 0xA1: case 0xB1: Temp = A - Operand; if (Temp < 0) { Flags.C = 1; } else { Flags.C = 0; } TestV(A, Operand, Temp); TestN(Temp); TestZ(Temp); break; //CMPB case 0xC1: case 0xD1: case 0xE1: case 0xF1: Temp = B - Operand; if (Temp < 0) { Flags.C = 1; } else { Flags.C = 0; } TestV(B, Operand, Temp); TestN(Temp); TestZ(Temp); break; //CBA case 0x11: Temp = A; Temp -= B; if (Temp < 0) { Flags.C = 1; } else { Flags.C = 0; } TestV(A, B, Temp); TestN(Temp); TestZ(Temp); break; //COM case 0x63: TempPC = IX + ReadMem(PC + 1); Temp = ~ReadMem(TempPC) & 0xFF; WriteMem(TempPC, Temp); TestN(Temp); TestZ(Temp); Flags.V = 0; Flags.C = 1; break; case 0x73: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); Temp = ~ReadMem(TempPC) & 0xFF; WriteMem(TempPC, Temp); TestN(Temp); TestZ(Temp); Flags.V = 0; Flags.C = 1; break; //COMA case 0x43: A = ~A & 0xFF; TestN(A); TestZ(A); Flags.V = 0; Flags.C = 1; break; //COMB case 0x53: B = ~B & 0xFF; TestN(B); TestZ(B); Flags.V = 0; Flags.C = 1; break; //NEG case 0x60: TempPC = IX + ReadMem(PC + 1); Temp = (0 - ReadMem(TempPC)) & 0xFF; WriteMem(TempPC, Temp); TestN(Temp); Bit7V(Temp); TestZC(Temp); break; case 0x70: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); Temp = (0 - ReadMem(TempPC)) & 0xFF; WriteMem(TempPC, Temp); TestN(Temp); Bit7V(Temp); TestZC(Temp); break; //NEGA case 0x40: Temp = A; Temp = 0 - Temp; A = Temp & 0xFF; TestN(A); Bit7V(A); TestZC(A); break; //NEGB case 0x50: Temp = B; Temp = 0 - Temp; B = Temp & 0xFF; TestN(B); Bit7V(B); TestZC(B); break; //DAA case 0x19: Temp = A; if (((A & 0xF) > 9) | (Flags.H == 1)) { A += 0x06; TestV(Temp, 0x06, A); } if ((((A & 0xF0) >> 8) > 9) | (Flags.C == 1)) { A += 0x60; TestV(Temp, 0x60, A); } if (((A & 0xF) > 9) & ((A & 0xF0) == 0x90)) { A += 0x60; TestV(Temp, 0x60, A); } if (((A & 0xF0) >> 8) > 9) { Flags.C = 1; } TestN(A); TestZ(A); break; //DEC case 0x6A: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); Bit7V(Temp); WriteMem(TempPC, (Temp - 1) & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); break; case 0x7A: TempPC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); Temp = ReadMem(TempPC); Bit7V(Temp); WriteMem(TempPC, (Temp - 1) & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); break; //DECA case 0x4A: Temp = A; Bit7V(Temp); Temp = Temp - 1; A = Temp & 0xFF; TestN(A); TestZ(A); break; //DECB case 0x5A: Temp = B; Bit7V(Temp); Temp = Temp - 1; B = Temp & 0xFF; TestN(B); TestZ(B); break; //EORA case 0x88: case 0x98: case 0xA8: case 0xB8: A ^= Operand; TestN(A); TestZ(A); Flags.V = 0; break; //EORB case 0xC8: case 0xD8: case 0xE8: case 0xF8: B ^= Operand; TestN(B); TestZ(B); Flags.V = 0; break; //INC case 0x6C: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); if (Temp == 0x7F) { Flags.V = 1; } else { Flags.V = 0; } Temp = Temp + 1; WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); break; case 0x7C: TempPC = ReadMem(PC + 1); TempPC = TempPC * 0x100 + ReadMem(PC + 2); Temp = ReadMem(TempPC); if (Temp == 0x7F) { Flags.V = 1; } else { Flags.V = 0; } Temp++; WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); break; //INCA case 0x4C: Temp = A; if (Temp == 0x7F) { Flags.V = 1; } else { Flags.V = 0; } Temp++; A = Temp & 0xFF; TestN(A); TestZ(A); break; //INCB case 0x5C: Temp = B; if (Temp == 0x7F) { Flags.V = 1; } else { Flags.V = 0; } Temp++; B = Temp & 0xFF; TestN(B); TestZ(B); break; //LDAA case 0x86: case 0x96: case 0xA6: case 0xB6: A = Operand; TestN(A); TestZ(A); Flags.V = 0; break; //LDAB case 0xC6: case 0xD6: case 0xE6: case 0xF6: B = Operand; TestN(B); TestZ(B); Flags.V = 0; break; //ORA case 0x8A: case 0x9A: case 0xAA: case 0xBA: A |= Operand; TestN(A); TestZ(A); Flags.V = 0; break; //ORB case 0xCA: case 0xDA: case 0xEA: case 0xFA: B |= Operand; TestN(B); TestZ(B); Flags.V = 0; break; //PSHA case 0x36: WriteMem(SP--, A); break; //PSHB case 0x37: WriteMem(SP--, B); break; //PULA case 0x32: A = ReadMem(++SP); break; //PULB case 0x33: B = ReadMem(++SP); break; //ROL case 0x69: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); SaveC = Flags.C; Bit7C(Temp); Temp = (Temp << 1) + SaveC; WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; case 0x79: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); Temp = ReadMem(TempPC); SaveC = Flags.C; Bit7C(Temp); Temp = (Temp << 1) + SaveC; WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; //ROLA case 0x49: Temp = A; SaveC = Flags.C; Bit7C(A); Temp = (Temp << 1) + SaveC; A = Temp & 0xFF; TestN(A); TestZ(A); Flags.V = Flags.N ^ Flags.C; break; //ROLB case 0x59: Temp = B; SaveC = Flags.C; Bit7C(B); Temp = (Temp << 1) + SaveC; B = Temp & 0xFF; TestN(B); TestZ(B); Flags.V = Flags.N ^ Flags.C; break; //ROR case 0x66: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); SaveC = Flags.C; Flags.C = Temp & 1; Temp = (Temp >> 1) + (SaveC << 7); WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; case 0x76: TempPC = ReadMem(PC + 1); TempPC = (Temp << 8) + ReadMem(PC + 2); Temp = ReadMem(TempPC); SaveC = Flags.C; Flags.C = Temp & 1; Temp = (Temp >> 1) + (SaveC << 7); WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; //RORA case 0x46: Temp = A; SaveC = Flags.C; Flags.C = Temp & 1; Temp = (Temp >> 1) + (SaveC << 7); A = Temp & 0xFF; TestN(A); TestZ(A); Flags.V = Flags.N ^ Flags.C; break; //RORB case 0x56: Temp = B; SaveC = Flags.C; Flags.C = Temp & 1; Temp = (Temp >> 1) + (SaveC << 7); B = Temp & 0xFF; TestN(B); TestZ(B); Flags.V = Flags.N ^ Flags.C; break; //ASL case 0x68: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); Flags.C = (Temp >> 7) & 1; Temp = (Temp << 1); WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; case 0x78: TempPC = ReadMem(PC + 1); TempPC = TempPC * 0x100 + ReadMem(PC + 2); Temp = ReadMem(TempPC); Flags.C = (Temp >> 7) & 1; Temp = (Temp << 1); WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; //ASLA case 0x48: Temp = A; Flags.C = (Temp >> 7) & 1; Temp = (Temp << 1); A = Temp & 0xFF; TestN(A); TestZ(A); Flags.V = Flags.N ^ Flags.C; break; //ASLB case 0x58: Temp = B; Flags.C = (Temp >> 7) & 1; Temp = (Temp << 1); B = Temp & 0xFF; TestN(B); TestZ(B); Flags.V = Flags.N ^ Flags.C; break; //ASR case 0x67: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); Flags.C = Temp & 1; Temp = (Temp >> 1) + (Temp & 0x80); WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; case 0x77: TempPC = ReadMem(PC + 1); TempPC = TempPC * 0x100 + ReadMem(PC + 2); Temp = ReadMem(TempPC); Flags.C = Temp & 1; Temp = (Temp >> 1) + (Temp & 0x80); WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; //ASRA case 0x47: Temp = A; Flags.C = Temp & 1; Temp = (Temp >> 1) + (Temp & 0x80); A = Temp & 0xFF; TestN(A); TestZ(A); Flags.V = Flags.N ^ Flags.C; break; //ASRB case 0x57: Temp = B; Flags.C = Temp & 1; Temp = (Temp >> 1) + (Temp & 0x80); B = Temp & 0xFF; TestN(B); TestZ(B); Flags.V = Flags.N ^ Flags.C; break; //LSR case 0x64: TempPC = IX + ReadMem(PC + 1); Temp = ReadMem(TempPC); Flags.C = Temp & 1; Temp = Temp >> 1; WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; case 0x74: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); Temp = ReadMem(TempPC); Flags.C = Temp & 1; Temp = Temp >> 1; WriteMem(TempPC, Temp & 0xFF); TestN(ReadMem(TempPC)); TestZ(ReadMem(TempPC)); Flags.V = Flags.N ^ Flags.C; break; //LSRA case 0x44: Temp = A; Flags.C = Temp & 1; Temp = Temp >> 1; A = Temp & 0xFF; TestN(A); TestZ(A); Flags.V = Flags.N ^ Flags.C; break; //LSRB case 0x54: Temp = B; Flags.C = Temp & 1; Temp = Temp >> 1; B = Temp & 0xFF; TestN(B); TestZ(B); Flags.V = Flags.N ^ Flags.C; break; //STAA case 0x97: WriteMem(Memory[PC + 1], A); TestN(A); TestZ(A); Flags.V = 0; break; case 0xA7: TempPC = IX + ReadMem(PC + 1); WriteMem(TempPC, A); TestN(A); TestZ(A); Flags.V = 0; //if(((TempPC <= 0xC16F) && (TempPC >= 0xC110)) && ((TempPC & 0xF)== 0)) Render(TempPC / 0x10 & 0xF, A); //if((TempPC <= 0xC16F) && (TempPC >= 0xC110)) Render(TempPC / 0x10 & 0xF, A); break; case 0xB7: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); WriteMem(TempPC, A); TestN(A); TestZ(A); Flags.V = 0; //if((TempPC <= 0xC16F) && (TempPC >= 0xC110)) Render(TempPC / 0x10 & 0xF, A); break; //STAB case 0xD7: WriteMem(ReadMem(PC + 1), B); TestN(B); TestZ(B); Flags.V = 0; break; case 0xE7: TempPC = IX + ReadMem(PC + 1); WriteMem(TempPC, B); TestN(B); TestZ(B); Flags.V = 0; //if((TempPC <= 0xC16F) && (TempPC >= 0xC110)) Render(TempPC / 0x10 & 0xF, B); break; case 0xF7: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); WriteMem(TempPC, B); TestN(B); TestZ(B); Flags.V = 0; // if((TempPC <= 0xC16F) && (TempPC >= 0xC110)) Render(TempPC / 0x10 & 0xF, B); break; //SUBA case 0x80: case 0x90: case 0xA0: case 0xB0: Temp = A; Temp -= Operand; if (Operand > A) { Flags.C = 1; } else { Flags.C = 0; } //TestC(A, Operand); TestV(A, Operand, Temp); A = Temp & 0xFF; TestN(A); TestZ(A); break; //SUBB case 0xC0: case 0xD0: case 0xE0: case 0xF0: Temp = B; Temp = Temp - Operand; if (Operand > B) { Flags.C = 1; } else { Flags.C = 0; } // TestC(B, Operand); TestV(B, Operand, Temp); B = Temp & 0xFF; TestN(B); TestZ(B); break; //SBA case 0x10: Temp = A; Temp = Temp - B; TestC(A, B, Temp); TestV(A, B, Temp); A = Temp & 0xFF; TestN(A); TestZ(A); break; //SBCA case 0x82: case 0x92: case 0xA2: case 0xB2: Temp = A; Temp -= Operand; Temp -= Flags.C; if (Operand > A) { Flags.C = 1; } else { Flags.C = 0; } //TestC(A, Operand); TestV(A, Operand, Temp); A = Temp & 0xFF; TestN(A); TestZ(A); break; //SBCB case 0xC2: case 0xD2: case 0xE2: case 0xF2: Temp = B; Temp = Temp - Operand; Temp -= Flags.C; if (Operand > B) { Flags.C = 1; } else { Flags.C = 0; } // TestC(B, Operand); TestV(B, Operand, Temp); B = Temp & 0xFF; TestN(B); TestZ(B); break; //TAB case 0x16: B = A; TestN(B); TestZ(B); Flags.V = 0; break; //TBA case 0x17: A = B; TestN(A); TestZ(A); Flags.V = 0; break; //TST case 0x6D: Temp = ReadMem(IX + ReadMem(PC + 1)); TestN(Temp); TestZ(Temp); Flags.V = 0; Flags.C = 0; break; case 0x7D: TempPC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); Temp = ReadMem(TempPC); TestN(Temp); TestZ(Temp); Flags.V = 0; Flags.C = 0; break; //TSTA case 0x4D: TestN(A); TestZ(A); Flags.V = 0; Flags.C = 0; break; //TSTB case 0x5D: TestN(B); TestZ(B); Flags.V = 0; Flags.C = 0; break; //============ INDEX REGISTER AND STACK OPCODES ========== //CPX case 0x8C: Temp = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); Operand = Temp; Temp = IX - Temp; TestV(IX, Operand, Temp); TestN(Temp >> 8); TestZ(Temp); break; case 0x9C: Temp = (ReadMem(PC + 1) << 8) + ReadMem(ReadMem(PC + 1) + 1); Operand = Temp; Temp = IX - Temp; TestV(IX, Operand, Temp); TestN(Temp >> 8); TestZ(Temp); break; case 0xAC: Temp = (ReadMem(IX + ReadMem(PC + 1)) << 8) + ReadMem(IX + ReadMem(PC + 1) + 1); Operand = Temp; Temp = IX - Temp; TestV(IX, Operand, Temp); TestN(Temp >> 8); TestZ(Temp); break; case 0xBC: TempPC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); Temp = ReadMem(TempPC); Temp = (Temp << 8) + ReadMem(TempPC + 1); Operand = Temp; Temp = IX - Temp; TestV(IX, Operand, Temp); TestN(Temp >> 8); TestZ(Temp); break; //DEX case 0x09: IX--; TestZ(IX); break; //DES case 0x34: SP--; break; //INX case 0x8: IX++; TestZ(IX); break; //INS case 0x31: SP++; break; //LDX case 0xCE: //FOROPT IX = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); TestN(IX >> 8); TestZ(IX); Flags.V = 0; break; case 0xDE: //FOROPT IX = (ReadMem(ReadMem(PC + 1)) << 8) + ReadMem(ReadMem(PC + 1) + 1); TestN(IX >> 8); TestZ(IX); Flags.V = 0; break; case 0xEE: TempPC = IX + ReadMem(PC + 1); IX = (ReadMem(TempPC) << 8) + ReadMem(TempPC + 1); TestN(IX >> 8); TestZ(IX); Flags.V = 0; break; case 0xFE: TempPC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); IX = (ReadMem(TempPC) << 8) + ReadMem(TempPC + 1); TestN(IX >> 8); TestZ(IX); Flags.V = 0; //LDS break; case 0x8E: SP = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; case 0x9E: TempPC = ReadMem(PC + 1); SP = (ReadMem(TempPC) << 8) + ReadMem(TempPC + 1); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; case 0xAE: TempPC = IX + ReadMem(PC + 1); SP = ReadMem(TempPC); SP = (SP << 8) + ReadMem(TempPC + 1); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; case 0xBE: TempPC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); SP = (ReadMem(TempPC) << 8) + ReadMem(TempPC + 1); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; //STX case 0xDF: TempPC = ReadMem(PC + 1); WriteMem(TempPC, (IX >> 8) & 0xFF); WriteMem(TempPC + 1, IX & 0xFF); TestN(IX >> 8); TestZ(IX); Flags.V = 0; break; case 0xEF: TempPC = IX + ReadMem(PC + 1); WriteMem(TempPC, (IX >> 8) & 0xFF); WriteMem(TempPC + 1, IX & 0xFF); TestN(IX >> 8); TestZ(IX); Flags.V = 0; break; case 0xFF: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); WriteMem(TempPC, (IX >> 8) & 0xFF); WriteMem(TempPC + 1, IX & 0xFF); TestN(IX >> 8); TestZ(IX); Flags.V = 0; break; //STS case 0x9F: TempPC = ReadMem(PC + 1); WriteMem(TempPC, (SP / 0x100) & 0xFF); WriteMem(TempPC + 1, SP & 0xFF); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; case 0xAF: TempPC = IX + ReadMem(PC + 1); WriteMem(TempPC, (SP >> 8) & 0xFF); WriteMem(TempPC + 1, SP & 0xFF); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; case 0xBF: TempPC = ReadMem(PC + 1); TempPC = (TempPC << 8) + ReadMem(PC + 2); WriteMem(TempPC, (SP >> 8) & 0xFF); WriteMem(TempPC + 1, SP & 0xFF); TestN(SP >> 8); TestZ(SP); Flags.V = 0; break; //TXS case 0x35: SP = IX - 1; break; //TSX case 0x30: IX = SP + 1; break; //============ JUMP AND BRANCH OPCODES ========== //BRA case 0x20: PC += Operand; break; //BCC case 0x24: if (Flags.C == 0) { PC += Operand; } break; //BCS case 0x25: if (Flags.C == 1) { PC += Operand; } break; //BEQ case 0x27: if (Flags.Z == 1) { PC += Operand; } break; //BGE case 0x2C: if ((Flags.N ^ Flags.V) == 0) { PC += Operand; } break; //BGT case 0x2E: if ((Flags.Z | (Flags.N ^ Flags.V)) == 0) { PC += Operand; } break; //BHI case 0x22: if ((Flags.C | Flags.Z) == 0) { PC += Operand; } break; //BLE case 0x2F: if ((Flags.Z | (Flags.N ^ Flags.V)) == 1) { PC += Operand; } break; //BLS case 0x23: if ((Flags.C | Flags.Z) == 1) { PC += Operand; } break; //BLT case 0x2D: if ((Flags.N ^ Flags.V) == 1) { PC += Operand; } break; //BMI case 0x2B: if (Flags.N == 1) { PC += Operand; } break; //BNE case 0x26: if (Flags.Z == 0) { PC += Operand; } break; //BVC case 0x28: if (Flags.V == 0) { PC += Operand; } break; //BVS case 0x29: if (Flags.V == 1) { PC += Operand; } break; //BPL case 0x2A: if (Flags.N == 0) { PC += Operand; } break; //BSR case 0x8D: PC += 2; WriteMem(SP--, PC & 0xFF); WriteMem(SP--, (PC >> 8) & 0xFF); PC += Operand; break; //JMP case 0x6E: PC = IX + ReadMem(PC + 1); break; case 0x7E: PC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); break; //JSR case 0xAD: TempPC = PC; PC += 3; WriteMem(SP--, PC & 0xFF); WriteMem(SP--, (PC >> 8) & 0xFF); PC = IX + ReadMem(TempPC + 1); break; case 0xBD: TempPC = (ReadMem(PC + 1) << 8) + ReadMem(PC + 2); PC += 3; WriteMem(SP--, PC & 0xFF); WriteMem(SP--, (PC >> 8) & 0xFF); PC = TempPC; break; //NOP case 0x1: PC = PC + 1; break; //RTI case 0x3B: SP++; Flags.H = (ReadMem(SP) >> 6) & 1; Flags.I = (ReadMem(SP) >> 5) & 1; Flags.N = (ReadMem(SP) >> 4) & 1; Flags.Z = (ReadMem(SP) >> 3) & 1; Flags.V = (ReadMem(SP) >> 2) & 1; Flags.C = (ReadMem(SP) >> 1) & 1; SP++; B = ReadMem(SP); SP++; A = ReadMem(SP); SP += 2; IX = (ReadMem(SP - 1) << 8) + ReadMem(SP); SP += 2; PC = (ReadMem(SP - 1) << 8) + ReadMem(SP); break; //RTS case 0x39: SP += 2; PC = (ReadMem(SP - 1) << 8) + ReadMem(SP); break; //SWI case 0x3F: //erp! WriteMem(SP--, PC & 0xFF); WriteMem(SP--, (PC >> 8) & 0xFF); WriteMem(SP--, IX & 0xFF); WriteMem(SP--, (IX >> 8) & 0xFF); WriteMem(SP--, A); WriteMem(SP--, B); WriteMem(SP--, Flags.H * 32 + Flags.I * 16 + Flags.N * 8 + Flags.Z * 4 + Flags.V * 2 + Flags.C); Flags.I = 1; //SP = SP - 7; PC = (ReadMem(0xFFFA) << 8) + ReadMem(0xFFFB); break; //WAI case 0x3E: //if Flags.I = 1; // Paused = False //Else // Paused = True //End if break; //============ CONDITIONS CODE REGISTER OPCODES ========== //CLC case 0xC: Flags.C = 0; break; //CLI case 0xE: Flags.I = 0; break; //CLV case 0xA: Flags.V = 0; break; //SEC case 0xD: Flags.C = 1; break; //SEI case 0xF: Flags.I = 1; break; //SEV case 0xB: Flags.Z = 1; break; //TAP case 0x6: Flags.H = A / 32 & 1; Flags.I = A / 16 & 1; Flags.N = A / 8 & 1; Flags.Z = A / 4 & 1; Flags.V = A / 2 & 1; Flags.C = A & 1; break; //TPA case 0x7: A += Flags.H * 32; A += Flags.I * 16; A += Flags.N * 8; A += Flags.Z * 4; A += Flags.V * 2; A += Flags.C; break; //INVALID default: break; } NOPS = CalcNOPs(FetchCode); switch (FetchCode) { case 0x8D: case 0x6E: case 0x7E: case 0xAD: case 0xBD: case 0x39: case 0x3F: case 0x3B: // PC already calculated break; default: PC += NOPS; break; } //Safety check lastpc = PC; //Interrupt handlers if ((NMI == 0) || ((IRQ == 0) && (Flags.I == 0))) { WriteMem(SP, PC & 0xFF); WriteMem(SP - 1, PC / 0x100 & 0xFF); WriteMem(SP - 2, IX & 0xFF); WriteMem(SP - 3, IX / 0x100 & 0xFF); WriteMem(SP - 4, A); WriteMem(SP - 5, B); WriteMem(SP - 6, Flags.H * 32 + Flags.I * 16 + Flags.N * 8 + Flags.Z * 4 + Flags.V * 2 + Flags.C); SP = SP - 7; Flags.I = 1; PC = (ReadMem(0xFFFC) << 8) + ReadMem(0xFFFD); } return(Cycles[FetchCode]); }