//============================================================================ // // MM MM 6666 555555 0000 2222 // MMMM MMMM 66 66 55 00 00 22 22 // MM MMM MM 66 55 00 00 22 // MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator" // MM MM 66 66 55 00 00 22 // MM MM 66 66 55 55 00 00 22 // MM MM 6666 5555 0000 222222 // // Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony // and the Stella Team // // See the file "License.txt" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ /** Code and cases to emulate each of the 6502 instructions. Recompile with the following: 'm4 M6502.m4 > M6502.ins' @author Bradford W. Mott and Stephen Anthony */ #ifndef NOTSAMEPAGE #define NOTSAMEPAGE(_addr1, _addr2) (((_addr1) ^ (_addr2)) & 0xff00) #endif #ifndef SET_LAST_PEEK #ifdef DEBUGGER_SUPPORT #define SET_LAST_PEEK(_addr1, _addr2) _addr1 = _addr2; #else #define SET_LAST_PEEK(_addr1, _addr2) #endif #endif #ifndef CLEAR_LAST_PEEK #ifdef DEBUGGER_SUPPORT #define CLEAR_LAST_PEEK(_addr) _addr = -1; #else #define CLEAR_LAST_PEEK(_addr) #endif #endif #ifndef SET_LAST_POKE #ifdef DEBUGGER_SUPPORT #define SET_LAST_POKE(_addr) myDataAddressForPoke = _addr; #else #define SET_LAST_POKE(_addr) #endif #endif ////////////////////////////////////////////////// // ADC case 0x69: { operand = peek(PC++, DISASM_CODE); } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x65: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x75: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x6d: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x7d: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x79: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x61: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x71: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; ////////////////////////////////////////////////// // ASR case 0x4b: { operand = peek(PC++, DISASM_CODE); } { A &= operand; // Set carry flag according to the right-most bit C = A & 0x01; A >>= 1; notZ = A; N = false; } break; ////////////////////////////////////////////////// // ANC case 0x0b: case 0x2b: { operand = peek(PC++, DISASM_CODE); } { A &= operand; notZ = A; N = A & 0x80; C = N; } break; ////////////////////////////////////////////////// // AND case 0x29: { operand = peek(PC++, DISASM_CODE); } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x25: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x35: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x2d: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x3d: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x39: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x21: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { A &= operand; notZ = A; N = A & 0x80; } break; case 0x31: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A &= operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // ANE case 0x8b: { operand = peek(PC++, DISASM_CODE); } { // NOTE: The implementation of this instruction is based on // information from the 64doc.txt file. This instruction is // reported to be unstable! A = (A | 0xee) & X & operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // ARR case 0x6b: { operand = peek(PC++, DISASM_CODE); } { // NOTE: The implementation of this instruction is based on // information from the 64doc.txt file. There are mixed // reports on its operation! if(!D) { A &= operand; A = ((A >> 1) & 0x7f) | (C ? 0x80 : 0x00); C = A & 0x40; V = (A & 0x40) ^ ((A & 0x20) << 1); notZ = A; N = A & 0x80; } else { uInt8 value = A & operand; A = ((value >> 1) & 0x7f) | (C ? 0x80 : 0x00); N = C; notZ = A; V = (value ^ A) & 0x40; if(((value & 0x0f) + (value & 0x01)) > 0x05) { A = (A & 0xf0) | ((A + 0x06) & 0x0f); } if(((value & 0xf0) + (value & 0x10)) > 0x50) { A += 0x60; C = true; } else { C = false; } } } break; ////////////////////////////////////////////////// // ASL case 0x0a: { peek(PC, DISASM_NONE); } { // Set carry flag according to the left-most bit in A C = A & 0x80; A <<= 1; notZ = A; N = A & 0x80; } break; case 0x06: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x16: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x0e: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x1e: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; ////////////////////////////////////////////////// // BIT case 0x24: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { notZ = (A & operand); N = operand & 0x80; V = operand & 0x40; } break; case 0x2C: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { notZ = (A & operand); N = operand & 0x80; V = operand & 0x40; } break; ////////////////////////////////////////////////// // Branches case 0x90: { operand = peek(PC++, DISASM_CODE); } { if(!C) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0xb0: { operand = peek(PC++, DISASM_CODE); } { if(C) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0xf0: { operand = peek(PC++, DISASM_CODE); } { if(!notZ) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0x30: { operand = peek(PC++, DISASM_CODE); } { if(N) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0xD0: { operand = peek(PC++, DISASM_CODE); } { if(notZ) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0x10: { operand = peek(PC++, DISASM_CODE); } { if(!N) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0x50: { operand = peek(PC++, DISASM_CODE); } { if(!V) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; case 0x70: { operand = peek(PC++, DISASM_CODE); } { if(V) { peek(PC, DISASM_NONE); uInt16 address = PC + Int8(operand); if(NOTSAMEPAGE(PC, address)) peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE); PC = address; } } break; ////////////////////////////////////////////////// // BRK case 0x00: { peek(PC++, DISASM_NONE); B = true; poke(0x0100 + SP--, PC >> 8, DISASM_WRITE); poke(0x0100 + SP--, PC & 0x00ff, DISASM_WRITE); poke(0x0100 + SP--, PS(), DISASM_WRITE); I = true; PC = peek(0xfffe, DISASM_DATA); PC |= (uInt16(peek(0xffff, DISASM_DATA)) << 8); } break; ////////////////////////////////////////////////// // CLC case 0x18: { peek(PC, DISASM_NONE); } { C = false; } break; ////////////////////////////////////////////////// // CLD case 0xd8: { peek(PC, DISASM_NONE); } { D = false; } break; ////////////////////////////////////////////////// // CLI case 0x58: { peek(PC, DISASM_NONE); } { I = false; } break; ////////////////////////////////////////////////// // CLV case 0xb8: { peek(PC, DISASM_NONE); } { V = false; } break; ////////////////////////////////////////////////// // CMP case 0xc9: { operand = peek(PC++, DISASM_CODE); } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xc5: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xd5: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xcd: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xdd: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xd9: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xc1: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xd1: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { uInt16 value = uInt16(A) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; ////////////////////////////////////////////////// // CPX case 0xe0: { operand = peek(PC++, DISASM_CODE); } { uInt16 value = uInt16(X) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xe4: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(X) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xec: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(X) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; ////////////////////////////////////////////////// // CPY case 0xc0: { operand = peek(PC++, DISASM_CODE); } { uInt16 value = uInt16(Y) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xc4: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(Y) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; case 0xcc: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { uInt16 value = uInt16(Y) - uInt16(operand); notZ = value; N = value & 0x0080; C = !(value & 0x0100); } break; ////////////////////////////////////////////////// // DCP case 0xcf: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; case 0xdf: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; case 0xdb: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; case 0xc7: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; case 0xd7: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; case 0xc3: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; case 0xd3: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); uInt16 value2 = uInt16(A) - uInt16(value); notZ = value2; N = value2 & 0x0080; C = !(value2 & 0x0100); } break; ////////////////////////////////////////////////// // DEC case 0xc6: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; case 0xd6: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; case 0xce: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; case 0xde: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand - 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; ////////////////////////////////////////////////// // DEX case 0xca: { peek(PC, DISASM_NONE); } { X--; notZ = X; N = X & 0x80; } break; ////////////////////////////////////////////////// // DEY case 0x88: { peek(PC, DISASM_NONE); } { Y--; notZ = Y; N = Y & 0x80; } break; ////////////////////////////////////////////////// // EOR case 0x49: { operand = peek(PC++, DISASM_CODE); } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x45: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x55: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x4d: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x5d: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x59: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x41: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { A ^= operand; notZ = A; N = A & 0x80; } break; case 0x51: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A ^= operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // INC case 0xe6: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand + 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; case 0xf6: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand + 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; case 0xee: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand + 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; case 0xfe: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = operand + 1; poke(operandAddress, value, DISASM_WRITE); notZ = value; N = value & 0x80; } break; ////////////////////////////////////////////////// // INX case 0xe8: { peek(PC, DISASM_NONE); } { X++; notZ = X; N = X & 0x80; } break; ////////////////////////////////////////////////// // INY case 0xc8: { peek(PC, DISASM_NONE); } { Y++; notZ = Y; N = Y & 0x80; } break; ////////////////////////////////////////////////// // ISB case 0xef: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xff: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xfb: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xe7: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xf7: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xe3: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xf3: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { operand = operand + 1; poke(operandAddress, operand, DISASM_WRITE); // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; ////////////////////////////////////////////////// // JMP case 0x4c: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); } { PC = operandAddress; } break; case 0x6c: { uInt16 addr = peek(PC++, DISASM_CODE); addr |= (uInt16(peek(PC++, DISASM_CODE)) << 8); // Simulate the error in the indirect addressing mode! uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1); operandAddress = peek(addr, DISASM_DATA); operandAddress |= (uInt16(peek(high, DISASM_DATA)) << 8); } { PC = operandAddress; } break; ////////////////////////////////////////////////// // JSR case 0x20: { uInt8 low = peek(PC++, DISASM_CODE); peek(0x0100 + SP, DISASM_NONE); // It seems that the 650x does not push the address of the next instruction // on the stack it actually pushes the address of the next instruction // minus one. This is compensated for in the RTS instruction poke(0x0100 + SP--, PC >> 8, DISASM_WRITE); poke(0x0100 + SP--, PC & 0xff, DISASM_WRITE); PC = (low | (uInt16(peek(PC, DISASM_CODE)) << 8)); } break; ////////////////////////////////////////////////// // LAS case 0xbb: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { A = X = SP = SP & operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // LAX case 0xaf: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { A = operand; X = operand; notZ = A; N = A & 0x80; } break; case 0xbf: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { A = operand; X = operand; notZ = A; N = A & 0x80; } break; case 0xa7: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { A = operand; X = operand; notZ = A; N = A & 0x80; } break; case 0xb7: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += Y; operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) // TODO - check this SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { A = operand; X = operand; notZ = A; N = A & 0x80; } break; case 0xa3: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) // TODO - check this { A = operand; X = operand; notZ = A; N = A & 0x80; } break; case 0xb3: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) // TODO - check this { A = operand; X = operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // LDA case 0xa9: { operand = peek(PC++, DISASM_CODE); } CLEAR_LAST_PEEK(myLastSrcAddressA) { A = operand; notZ = A; N = A & 0x80; } break; case 0xa5: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; case 0xb5: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; case 0xad: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; case 0xbd: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; case 0xb9: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; case 0xa1: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; case 0xb1: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A = operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // LDX case 0xa2: { operand = peek(PC++, DISASM_CODE); } CLEAR_LAST_PEEK(myLastSrcAddressX) { X = operand; notZ = X; N = X & 0x80; } break; case 0xa6: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { X = operand; notZ = X; N = X & 0x80; } break; case 0xb6: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += Y; operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { X = operand; notZ = X; N = X & 0x80; } break; case 0xae: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { X = operand; notZ = X; N = X & 0x80; } break; case 0xbe: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) { X = operand; notZ = X; N = X & 0x80; } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // LDY case 0xa0: { operand = peek(PC++, DISASM_CODE); } CLEAR_LAST_PEEK(myLastSrcAddressY) { Y = operand; notZ = Y; N = Y & 0x80; } break; case 0xa4: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress) { Y = operand; notZ = Y; N = Y & 0x80; } break; case 0xb4: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress) { Y = operand; notZ = Y; N = Y & 0x80; } break; case 0xac: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress) { Y = operand; notZ = Y; N = Y & 0x80; } break; case 0xbc: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress) { Y = operand; notZ = Y; N = Y & 0x80; } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // LSR case 0x4a: { peek(PC, DISASM_NONE); } { // Set carry flag according to the right-most bit C = A & 0x01; A >>= 1; notZ = A; N = false; } break; case 0x46: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand >>= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = false; } break; case 0x56: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand >>= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = false; } break; case 0x4e: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand >>= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = false; } break; case 0x5e: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand >>= 1; poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = false; } break; ////////////////////////////////////////////////// // LXA case 0xab: { operand = peek(PC++, DISASM_CODE); } { // NOTE: The implementation of this instruction is based on // information from the 64doc.txt file. This instruction is // reported to be very unstable! A = X = (A | 0xee) & operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // NOP case 0x1a: case 0x3a: case 0x5a: case 0x7a: case 0xda: case 0xea: case 0xfa: { peek(PC, DISASM_NONE); } { } break; case 0x80: case 0x82: case 0x89: case 0xc2: case 0xe2: { peek(PC++, DISASM_CODE); } { } break; case 0x04: case 0x44: case 0x64: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_DATA); } { } break; case 0x14: case 0x34: case 0x54: case 0x74: case 0xd4: case 0xf4: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; peek(intermediateAddress, DISASM_DATA); } { } break; case 0x0c: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(intermediateAddress, DISASM_DATA); } { } break; case 0x1c: case 0x3c: case 0x5c: case 0x7c: case 0xdc: case 0xfc: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; peek(intermediateAddress, DISASM_DATA); } else { peek(intermediateAddress, DISASM_DATA); } } { } break; ////////////////////////////////////////////////// // ORA case 0x09: { operand = peek(PC++, DISASM_CODE); } CLEAR_LAST_PEEK(myLastSrcAddressA) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x05: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x15: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x0d: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x1d: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x19: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x01: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; case 0x11: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) { A |= operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // PHA case 0x48: { peek(PC, DISASM_NONE); } SET_LAST_POKE(myLastSrcAddressA) { poke(0x0100 + SP--, A, DISASM_WRITE); } break; ////////////////////////////////////////////////// // PHP case 0x08: { peek(PC, DISASM_NONE); } // TODO - add tracking for this opcode { poke(0x0100 + SP--, PS(), DISASM_WRITE); } break; ////////////////////////////////////////////////// // PLA case 0x68: { peek(PC, DISASM_NONE); } // TODO - add tracking for this opcode { peek(0x0100 + SP++, DISASM_NONE); A = peek(0x0100 + SP, DISASM_DATA); notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // PLP case 0x28: { peek(PC, DISASM_NONE); } // TODO - add tracking for this opcode { peek(0x0100 + SP++, DISASM_NONE); PS(peek(0x0100 + SP, DISASM_DATA)); } break; ////////////////////////////////////////////////// // RLA case 0x2f: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; case 0x3f: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; case 0x3b: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; case 0x27: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; case 0x37: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; case 0x23: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; case 0x33: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { uInt8 value = (operand << 1) | (C ? 1 : 0); poke(operandAddress, value, DISASM_WRITE); A &= value; C = operand & 0x80; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // ROL case 0x2a: { peek(PC, DISASM_NONE); } { bool oldC = C; // Set carry flag according to the left-most bit C = A & 0x80; A = (A << 1) | (oldC ? 1 : 0); notZ = A; N = A & 0x80; } break; case 0x26: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the left-most bit in operand C = operand & 0x80; operand = (operand << 1) | (oldC ? 1 : 0); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x36: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the left-most bit in operand C = operand & 0x80; operand = (operand << 1) | (oldC ? 1 : 0); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x2e: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the left-most bit in operand C = operand & 0x80; operand = (operand << 1) | (oldC ? 1 : 0); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x3e: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the left-most bit in operand C = operand & 0x80; operand = (operand << 1) | (oldC ? 1 : 0); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; ////////////////////////////////////////////////// // ROR case 0x6a: { peek(PC, DISASM_NONE); } { bool oldC = C; // Set carry flag according to the right-most bit C = A & 0x01; A = ((A >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); notZ = A; N = A & 0x80; } break; case 0x66: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x76: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x6e: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; case 0x7e: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); notZ = operand; N = operand & 0x80; } break; ////////////////////////////////////////////////// // RRA case 0x6f: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x7f: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x7b: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x67: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x77: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x63: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; case 0x73: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { bool oldC = C; // Set carry flag according to the right-most bit C = operand & 0x01; operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); poke(operandAddress, operand, DISASM_WRITE); if(!D) { Int32 sum = A + operand + (C ? 1 : 0); N = sum & 0x80; V = ~(A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; C = sum & 0xff00; A = uInt8(sum); } else { Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0); Int32 hi = (A & 0xf0) + (operand & 0xf0); notZ = (lo+hi) & 0xff; if(lo > 0x09) { hi += 0x10; lo += 0x06; } N = hi & 0x80; V = ~(A ^ operand) & (A ^ hi) & 0x80; if(hi > 0x90) hi += 0x60; C = hi & 0xff00; A = (lo & 0x0f) + (hi & 0xf0); } } break; ////////////////////////////////////////////////// // RTI case 0x40: { peek(PC, DISASM_NONE); } { peek(0x0100 + SP++, DISASM_NONE); PS(peek(0x0100 + SP++, DISASM_NONE)); PC = peek(0x0100 + SP++, DISASM_NONE); PC |= (uInt16(peek(0x0100 + SP, DISASM_NONE)) << 8); } break; ////////////////////////////////////////////////// // RTS case 0x60: { peek(PC, DISASM_NONE); } { peek(0x0100 + SP++, DISASM_NONE); PC = peek(0x0100 + SP++, DISASM_NONE); PC |= (uInt16(peek(0x0100 + SP, DISASM_NONE)) << 8); peek(PC++, DISASM_NONE); } break; ////////////////////////////////////////////////// // SAX case 0x8f: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); } { poke(operandAddress, A & X, DISASM_WRITE); } break; case 0x87: { operandAddress = peek(PC++, DISASM_CODE); } { poke(operandAddress, A & X, DISASM_WRITE); } break; case 0x97: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + Y) & 0xFF; } { poke(operandAddress, A & X, DISASM_WRITE); } break; case 0x83: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); } { poke(operandAddress, A & X, DISASM_WRITE); } break; ////////////////////////////////////////////////// // SBC case 0xe9: case 0xeb: { operand = peek(PC++, DISASM_CODE); } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xe5: { intermediateAddress = peek(PC++, DISASM_CODE); operand = peek(intermediateAddress, DISASM_DATA); } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xf5: { intermediateAddress = peek(PC++, DISASM_CODE); peek(intermediateAddress, DISASM_NONE); intermediateAddress += X; operand = peek(intermediateAddress, DISASM_DATA); } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xed: { intermediateAddress = peek(PC++, DISASM_CODE); intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xfd: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + X); if((low + X) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + X; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xf9: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xe1: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; intermediateAddress = peek(pointer++, DISASM_DATA); intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(intermediateAddress, DISASM_DATA); } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; case 0xf1: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); intermediateAddress = high | uInt8(low + Y); if((low + Y) > 0xFF) { peek(intermediateAddress, DISASM_NONE); intermediateAddress = (high | low) + Y; operand = peek(intermediateAddress, DISASM_DATA); } else { operand = peek(intermediateAddress, DISASM_DATA); } } { // N, V, Z, C flags are the same in either mode (C calculated at the end) Int32 sum = A - operand - (C ? 0 : 1); N = sum & 0x80; V = (A ^ operand) & (A ^ sum) & 0x80; notZ = sum & 0xff; if(!D) { A = uInt8(sum); } else { Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1); Int32 hi = (A & 0xf0) - (operand & 0xf0); if(lo & 0x10) { lo -= 6; hi--; } if(hi & 0x0100) hi -= 0x60; A = (lo & 0x0f) | (hi & 0xf0); } C = (sum & 0xff00) == 0; } break; ////////////////////////////////////////////////// // SBX case 0xcb: { operand = peek(PC++, DISASM_CODE); } { uInt16 value = uInt16(X & A) - uInt16(operand); X = (value & 0xff); notZ = X; N = X & 0x80; C = !(value & 0x0100); } break; ////////////////////////////////////////////////// // SEC case 0x38: { peek(PC, DISASM_NONE); } { C = true; } break; ////////////////////////////////////////////////// // SED case 0xf8: { peek(PC, DISASM_NONE); } { D = true; } break; ////////////////////////////////////////////////// // SEI case 0x78: { peek(PC, DISASM_NONE); } { I = true; } break; ////////////////////////////////////////////////// // SHA case 0x9f: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; } { // NOTE: There are mixed reports on the actual operation // of this instruction! poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE); } break; case 0x93: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; } { // NOTE: There are mixed reports on the actual operation // of this instruction! poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE); } break; ////////////////////////////////////////////////// // SHS case 0x9b: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; } { // NOTE: There are mixed reports on the actual operation // of this instruction! SP = A & X; poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE); } break; ////////////////////////////////////////////////// // SHX case 0x9e: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; } { // NOTE: There are mixed reports on the actual operation // of this instruction! poke(operandAddress, X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE); } break; ////////////////////////////////////////////////// // SHY case 0x9c: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; } { // NOTE: There are mixed reports on the actual operation // of this instruction! poke(operandAddress, Y & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE); } break; ////////////////////////////////////////////////// // SLO case 0x0f: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; case 0x1f: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; case 0x1b: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; case 0x07: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; case 0x17: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; case 0x03: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; case 0x13: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the left-most bit in value C = operand & 0x80; operand <<= 1; poke(operandAddress, operand, DISASM_WRITE); A |= operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // SRE case 0x4f: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; case 0x5f: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; case 0x5b: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; case 0x47: { operandAddress = peek(PC++, DISASM_CODE); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; case 0x57: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; case 0x43: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; case 0x53: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; operand = peek(operandAddress, DISASM_DATA); poke(operandAddress, operand, DISASM_WRITE); } { // Set carry flag according to the right-most bit in value C = operand & 0x01; operand = (operand >> 1) & 0x7f; poke(operandAddress, operand, DISASM_WRITE); A ^= operand; notZ = A; N = A & 0x80; } break; ////////////////////////////////////////////////// // STA case 0x85: { operandAddress = peek(PC++, DISASM_CODE); } SET_LAST_POKE(myLastSrcAddressA) { poke(operandAddress, A, DISASM_WRITE); } break; case 0x95: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; } { poke(operandAddress, A, DISASM_WRITE); } break; case 0x8d: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); } SET_LAST_POKE(myLastSrcAddressA) { poke(operandAddress, A, DISASM_WRITE); } break; case 0x9d: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + X), DISASM_NONE); operandAddress = (high | low) + X; } { poke(operandAddress, A, DISASM_WRITE); } break; case 0x99: { uInt16 low = peek(PC++, DISASM_CODE); uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; } { poke(operandAddress, A, DISASM_WRITE); } break; case 0x81: { uInt8 pointer = peek(PC++, DISASM_CODE); peek(pointer, DISASM_NONE); pointer += X; operandAddress = peek(pointer++, DISASM_DATA); operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8); } { poke(operandAddress, A, DISASM_WRITE); } break; case 0x91: { uInt8 pointer = peek(PC++, DISASM_CODE); uInt16 low = peek(pointer++, DISASM_DATA); uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8); peek(high | uInt8(low + Y), DISASM_NONE); operandAddress = (high | low) + Y; } { poke(operandAddress, A, DISASM_WRITE); } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // STX case 0x86: { operandAddress = peek(PC++, DISASM_CODE); } SET_LAST_POKE(myLastSrcAddressX) { poke(operandAddress, X, DISASM_WRITE); } break; case 0x96: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + Y) & 0xFF; } { poke(operandAddress, X, DISASM_WRITE); } break; case 0x8e: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); } SET_LAST_POKE(myLastSrcAddressX) { poke(operandAddress, X, DISASM_WRITE); } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // STY case 0x84: { operandAddress = peek(PC++, DISASM_CODE); } SET_LAST_POKE(myLastSrcAddressY) { poke(operandAddress, Y, DISASM_WRITE); } break; case 0x94: { operandAddress = peek(PC++, DISASM_CODE); peek(operandAddress, DISASM_NONE); operandAddress = (operandAddress + X) & 0xFF; } { poke(operandAddress, Y, DISASM_WRITE); } break; case 0x8c: { operandAddress = peek(PC++, DISASM_CODE); operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8); } SET_LAST_POKE(myLastSrcAddressY) { poke(operandAddress, Y, DISASM_WRITE); } break; ////////////////////////////////////////////////// ////////////////////////////////////////////////// // Remaining MOVE opcodes case 0xaa: { peek(PC, DISASM_NONE); } SET_LAST_PEEK(myLastSrcAddressX, myLastSrcAddressA) { X = A; notZ = X; N = X & 0x80; } break; case 0xa8: { peek(PC, DISASM_NONE); } SET_LAST_PEEK(myLastSrcAddressY, myLastSrcAddressA) { Y = A; notZ = Y; N = Y & 0x80; } break; case 0xba: { peek(PC, DISASM_NONE); } SET_LAST_PEEK(myLastSrcAddressX, myLastSrcAddressS) { X = SP; notZ = X; N = X & 0x80; } break; case 0x8a: { peek(PC, DISASM_NONE); } SET_LAST_PEEK(myLastSrcAddressA, myLastSrcAddressX) { A = X; notZ = A; N = A & 0x80; } break; case 0x9a: { peek(PC, DISASM_NONE); } SET_LAST_PEEK(myLastSrcAddressS, myLastSrcAddressX) { SP = X; } break; case 0x98: { peek(PC, DISASM_NONE); } SET_LAST_PEEK(myLastSrcAddressA, myLastSrcAddressY) { A = Y; notZ = A; N = A & 0x80; } break; //////////////////////////////////////////////////