📄 65816emu.cpp
字号:
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 1; cycles -= 2; DOBREAK;
case 0x1B: // "TAS", 1, 2,
//(*((ATYPE*)®.A)) = ACCUM;
S = ACCUM_16BIT;
// No effect on flags
PC += 1; cycles -= 2; DOBREAK;
case 0x1C: // "TRB %w", 3, 6,
amem = (ATYPE*)ABS;
SETZERO (*amem & ACCUM);
*amem &= ~ACCUM;
TRAPWRITE ((byte*)amem);
PC += 3; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x1D: // "ORA %w,X", 3, 4,
mem = ABS_INDEX_X;
ACCUM |= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x1E: // "SHL %w,X", 3, 7,
if (*(amem = (ATYPE*)ABS_INDEX_X) & SIGN_BIT) P |= CARRY;
else P &= ~CARRY;
*amem <<= 1;
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
SETNEGATIVE (*amem);
PC += 3; cycles -= 7+A_IS16BIT; DOBREAK;
case 0x1F: // "ORA %L,X", 4, 5,
mem = ABS_LONG_INDEX_X;
ACCUM |= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x20: // "JSR %w", 3, 6,
PUSHWORD ((word)(PC + 2)); // TEST
PC = (PC & 0xFFFF0000) | OPWORD;
cycles -= 6; DOBREAK;
case 0x21: // "AND (<%b,X)", 2, 6,
mem = DIR_INDEX_INDIR_X;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x22: // "JSL %L", 4, 8,
PUSHBYTE ((PC+3) >> 16);
PUSHWORD ((word)PC + 3 ); // 3??
PC = OPLONG;
cycles -= 8; DOBREAK;
case 0x23: // "AND <%b,s", 2, 4,
mem = S_REL;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x24: // "BIT <%b", 2, 3,
mem = DIR;
if (*(amem = (ATYPE*)TRAPREAD(mem)) & ACCUM)
P &= ~ZERO; else P |= ZERO;
P = (P & ~(NEGATIVE | OVERFLOW)) | ((byte)(*amem >> NV_SHIFT) & (NEGATIVE | OVERFLOW));
PC += 2; cycles -= 3+A_IS16BIT; DOBREAK;
case 0x25: // "AND <%b", 2, 3,
mem = DIR;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 3+A_IS16BIT; DOBREAK;
case 0x26: // "ROL <%b", 2, 5,
amem = (ATYPE*)DIR;
_tmp = *amem & SIGN_BIT;
*amem = (ATYPE)((*amem << 1) | (P&1));
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
SETNEGATIVE (*amem);
if (_tmp) P |= CARRY; else P &= ~CARRY;
PC += 2; cycles -= 5; DOBREAK;
case 0x27: // "AND [<%b]", 2, 6,
mem = DIR_INDIR_LONG;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x28: // "PUL P", 1, 4, // PLP
PC += 1; cycles -= 4;
_tmp2 = P;
PULLBYTE (P);
if ((P & (MEMORY | INDEX)) != (_tmp2 & (MEMORY | INDEX))) {
if (P & INDEX) { // if indexes are now 8-bit
INDEX_X_16BIT &= 0xFF; // clear high byte
INDEX_Y_16BIT &= 0xFF;
}
goto saveregs_andexit;
}
DOBREAK;
case 0x29: // "AND %#", 2, 2,
ACCUM &= IMM_ACCUM;
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2+A_IS16BIT; cycles -= 2+A_IS16BIT; DOBREAK;
case 0x2A: // "ROL A", 1, 2,
//debug0 ("ROLA: Accum&SIGN_BIT %d signbit %d", ACCUM & SIGN_BIT, SIGN_BIT);
//ACCUM = (ATYPE)opdata;
_tmp = ACCUM & SIGN_BIT;
ACCUM = (ATYPE)((ACCUM << 1) | (P&1));
SETZERO (ACCUM);
SETNEGATIVE (ACCUM);
if (_tmp) P |= CARRY; else P &= ~CARRY;
PC += 1; cycles -= 2; DOBREAK;
case 0x2B: // "PUL D", 1, 5, // PLD Pull Direct
PULLWORD (D);
SETZERO (D);
if (D & 0x8000) P |= NEGATIVE;
else P &= ~NEGATIVE; // Don't use SETNEGATIVE
PC += 1; cycles -= 5; DOBREAK;
case 0x2C: // "BIT %w", 3, 4,
mem = ABS;
if (*(amem = (ATYPE*)TRAPREAD(mem)) & ACCUM)
P &= ~ZERO; else P |= ZERO;
P = (P & ~(NEGATIVE | OVERFLOW)) | ((byte)(*amem >> NV_SHIFT) & (NEGATIVE | OVERFLOW));
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x2D: // "AND %w", 3, 4,
mem = ABS;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x2E: // "ROL %w", 3, 6,
amem = (ATYPE*)ABS;
_tmp = *amem & SIGN_BIT;
*amem = (ATYPE)((*amem << 1) | (P&1));
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
SETNEGATIVE (*amem);
if (_tmp) P |= CARRY; else P &= ~CARRY;
PC += 3; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x2F: // "AND %L", 4, 5,
mem = ABS_LONG;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x30: // "BMI @%b", 2, 2,
if (!(P & NEGATIVE)) { // False
PC += 2; cycles -= 2; DOBREAK;
}
PC += 2 + ((signed char) opdata);
cycles -= 3; DOBREAK;
case 0x31: // "AND (<%b),Y", 2, 5,
mem = DIR_INDIR_INDEX_Y;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x32: // "AND (<%b)", 2, 5,
mem = DIR_INDIR;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x33: // "AND (<%b,S),Y", 2, 7,
mem = S_REL_INDIR_INDEX_Y;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 7+A_IS16BIT; DOBREAK;
case 0x34: // "BIT <%b,X", 2, 4,
mem = DIR_INDEX_X;
if (*(amem = (ATYPE*)TRAPREAD(mem)) & ACCUM)
P &= ~ZERO; else P |= ZERO;
P = (P & ~(NEGATIVE | OVERFLOW)) | ((byte)(*amem >> NV_SHIFT) & (NEGATIVE | OVERFLOW));
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x35: // "AND <%b,X", 2, 4,
mem = DIR_INDEX_X;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x36: // "ROL <%b,X", 2, 6,
amem = (ATYPE*)DIR_INDEX_X;
_tmp = *amem & SIGN_BIT;
*amem = (ATYPE)((*amem << 1) | (P&1));
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
SETNEGATIVE (*amem);
if (_tmp) P |= CARRY; else P &= ~CARRY;
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x37: // "AND [<%b],Y", 2, 6,
mem = DIR_INDIR_LONG_INDEX_Y;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM);
SETNEGATIVE (ACCUM);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x38: // "SEC", 1, 2,
P |= CARRY;
PC += 1; cycles -= 2; DOBREAK;
case 0x39: // "AND %w,Y", 3, 4,
mem = ABS_INDEX_Y;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x3A: // "DEC A", 1, 2,
ACCUM--;
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 1; cycles -= 2; DOBREAK;
case 0x3B: // "TSA", 1, 2,
/*ACCUM = (ATYPE)*/ (ACCUM_16BIT = (word)S);
SETZERO (ACCUM); // Flags should change
SETNEGATIVE (ACCUM);
PC += 1; cycles -= 2; DOBREAK;
case 0x3C: // "BIT %w,X", 3, 4,
mem = ABS_INDEX_X;
if (*(amem = (ATYPE*)TRAPREAD(mem)) & ACCUM)
P &= ~ZERO; else P |= ZERO;
P = (P & ~(NEGATIVE | OVERFLOW)) | ((byte)(*amem >> NV_SHIFT) & (NEGATIVE | OVERFLOW));
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x3D: // "AND %w,X", 3, 4,
mem = ABS_INDEX_X;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x3E: // "ROL %w,X", 3, 7,
mem = ABS_INDEX_X;
amem = (ATYPE*)TRAPREAD(mem);
_tmp = *amem & SIGN_BIT;
*amem = (ATYPE)((*amem << 1) | (P&1));
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
SETNEGATIVE (*amem);
if (_tmp) P |= CARRY; else P &= ~CARRY;
PC += 3; cycles -= 7+A_IS16BIT; DOBREAK;
case 0x3F: // "AND %L,X", 4, 5,
mem = ABS_LONG_INDEX_X;
ACCUM &= *(ATYPE *)TRAPREAD(mem);
SETZERO (ACCUM);
SETNEGATIVE (ACCUM);
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x40: // "RTI", 1, 7,
_tmp = P;
PULLBYTE (P);
PULLWORD (PC);
PULLBYTE (_tmp2);
PC |= (_tmp2 << 16);
cycles -= 7;
if ((P & (MEMORY | INDEX)) != (_tmp & (MEMORY | INDEX))) {
if (P & INDEX) { // if indexes are now 8-bit
INDEX_X_16BIT &= 0xFF; // clear high byte
INDEX_Y_16BIT &= 0xFF;
}
goto saveregs_andexit;
}
DOBREAK;
case 0x41: // "XOR (<%b,X)", 2, 6,
mem = DIR_INDEX_INDIR_X;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x42: // "???", 2, 2,
addmessage ("ERROR: INVALID OPCODE $42(WDM) AT $%LX", PC);
PC += 1; cycles -= 2; DOBREAK;
case 0x43: // "XOR <%b,S", 2, 4,
mem = S_REL;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x44: // "MVP XYA", 3, 7,
cycles -= 7;
DBR = OPBYTE;
_tmp = DBR << 16;
_tmp2 = (opdata << 8) & 0x00FF0000;
*(byte*)SNESMEM (_tmp + INDEX_Y) = *(byte*)SNESMEM (_tmp2 + INDEX_X);
INDEX_Y--;
INDEX_X--;
ACCUM--;
if (ACCUM == (ATYPE) -1)
PC += 3;
DOBREAK;
case 0x45: // "XOR <%b", 2, 3,
mem = DIR;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 3+A_IS16BIT; DOBREAK;
case 0x46: // "SHR <%b", 2, 5,
if (*(amem = (ATYPE*)DIR) & 1) P |= CARRY;
else P &= ~CARRY;
*amem >>= 1;
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
P &= ~NEGATIVE;
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x47: // "XOR [<%b]", 2, 6,
mem = DIR_INDIR_LONG;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x48: // "PSH A", 1, 3, // PHA
#ifdef A_16BIT
PUSHWORD (ACCUM);
#else
PUSHBYTE (ACCUM);
#endif
PC += 1; cycles -= 3+A_IS16BIT; DOBREAK;
case 0x49: // "XOR %#", 2, 2,
ACCUM ^= IMM_ACCUM;
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2+A_IS16BIT; cycles -= 2+A_IS16BIT; DOBREAK;
case 0x4A: // "SHR A", 1, 2,
if (ACCUM & 1) P |= CARRY;
else P &= ~CARRY;
ACCUM >>= 1;
SETZERO (ACCUM);
P &= ~NEGATIVE;
PC += 1; cycles -= 2; DOBREAK;
case 0x4B: // "PSH PBR", 1, 3, // PHK
PUSHBYTE (PC >> 16);
PC += 1; cycles -= 3; DOBREAK;
case 0x4C: // "JMP %w", 3, 3,
PC = (PC & 0xFF0000) | OPWORD;
cycles -= 3; DOBREAK;
case 0x4D: // "XOR %w", 3, 4,
mem = ABS;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM);
SETNEGATIVE (ACCUM);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x4E: // "SHR %w", 3, 6,
if (*(amem = (ATYPE*)ABS) & 1) P |= CARRY;
else P &= ~CARRY;
*amem >>= 1;
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
P &= ~NEGATIVE;
PC += 3; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x4F: // "XOR %L", 4, 5,
mem = ABS_LONG;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x50: // "BVC @%b", 2, 2,
if (P & OVERFLOW) { // False
PC += 2; cycles -= 2; DOBREAK;
}
PC += 2 + ((signed char) opdata);
cycles -= 3; DOBREAK;
case 0x51: // "XOR (<%b),Y", 2, 5,
mem = DIR_INDIR_INDEX_Y;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x52: // "XOR (<%b)", 2, 5,
mem = DIR_INDIR;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0x53: // "XOR (<%b,S),Y", 2, 7,
mem = S_REL_INDIR_INDEX_Y;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 7+A_IS16BIT; DOBREAK;
case 0x54: // "MVN %w", 3, 7,
cycles -= 7;
DBR = OPBYTE;
_tmp = DBR << 16;
_tmp2 = (opdata << 8) & 0x00FF0000;
*(byte*)SNESMEM (_tmp + INDEX_Y) = *(byte*)SNESMEM (_tmp2 + INDEX_X);
INDEX_Y++;
INDEX_X++;
ACCUM--;
if (ACCUM == (ATYPE) -1)
PC += 3;
DOBREAK;
case 0x55: // "XOR <%b,X", 2, 4,
mem = DIR_INDEX_X;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0x56: // "SHR <%b,X", 2, 6,
mem = DIR_INDEX_X;
if (*(amem = (ATYPE*)TRAPREAD(mem)) & 1) P |= CARRY;
else P &= ~CARRY;
*amem >>= 1;
TRAPWRITE ((byte*)amem);
SETZERO (*amem);
P &= ~NEGATIVE;
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x57: // "XOR [<%b],Y", 2, 6,
mem = DIR_INDIR_LONG_INDEX_Y;
ACCUM ^= *(ATYPE*)TRAPREAD(mem);
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0x58: // "CLI", 1, 2,
P &= ~INT_DISABLE;
PC += 1; cycles -= 2; DOBREAK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -