📄 65816emu.cpp
字号:
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0xD3: // "CMP (<%b,S),Y", 2, 7,
mem = S_REL_INDIR_INDEX_Y;
oldA = ACCUM - *(ATYPE*)TRAPREAD(mem);
SETNEGATIVE (oldA); SETZERO (oldA);
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 2; cycles -= 7+A_IS16BIT; DOBREAK;
case 0xD4: // "PSH <%b", 2, 6, // PEI
PUSHWORD (*(word*)DIR);
PC += 2; cycles -= 6; DOBREAK;
case 0xD5: // "CMP <%b,X", 2, 4,
mem = DIR_INDEX_X;
oldA = ACCUM - *(ATYPE*)TRAPREAD(mem);
SETNEGATIVE (oldA); SETZERO (oldA);
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xD6: // "DEC <%b,X", 2, 6,
mem = DIR_INDEX_X;
(*(amem = (ATYPE*)TRAPREAD(mem)))--;
SETZERO (*amem); SETNEGATIVE (*amem);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xD7: // "CMP [<%b],Y", 2, 6,
mem = DIR_INDIR_LONG_INDEX_Y;
oldA = ACCUM - *(ATYPE*)TRAPREAD(mem);
SETNEGATIVE (oldA); SETZERO (oldA);
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xD8: // "CLD", 1, 2,
P &= ~BCD;
PC += 1; cycles -= 2; DOBREAK;
case 0xD9: // "CMP %w,Y", 3, 4,
mem = ABS_INDEX_Y;
oldA = ACCUM - *(ATYPE*)TRAPREAD(mem);
SETNEGATIVE (oldA); SETZERO (oldA);
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xDA: // "PSH X", 1, 3, // PHX
#ifdef XY_16BIT
PUSHWORD (INDEX_X);
#else
PUSHBYTE (INDEX_X);
#endif
PC += 1; cycles -= 3+XY_IS16BIT; DOBREAK;
case 0xDB: // "HLT", 1, 3, // STP
addmessage ("Warning: SNES HALTED (Clock stopped)!");
//PC += 1; cycles -= 3;
cycles = -1;
DOBREAK;
case 0xDC: // "JML (%w)", 3, 6,
PC = *(long*)ABS_INDIR & 0xFFFFFF;
cycles -= 6; DOBREAK;
case 0xDD: // "CMP %w,X", 3, 4,
mem = ABS_INDEX_X;
oldA = ACCUM - *(ATYPE*)TRAPREAD(mem);
SETNEGATIVE (oldA); SETZERO (oldA);
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xDE: // "DEC %w,X", 3, 7,
mem = ABS_INDEX_X;
(*(amem = (ATYPE*)TRAPREAD(mem)))--;
SETZERO (*amem); SETNEGATIVE (*amem);
PC += 3; cycles -= 7+A_IS16BIT; DOBREAK;
case 0xDF: // "CMP %L,X", 4, 5,
mem = ABS_LONG_INDEX_X;
oldA = ACCUM - *(ATYPE*)TRAPREAD(mem);
SETNEGATIVE (oldA); SETZERO (oldA);
if (oldA > ACCUM)
P &= ~CARRY; else P |= CARRY;
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
case 0xE0: // "CPX %#i", 2, 2,
oldXY = INDEX_X - IMM_INDEX;
SETNEGATIVEXY (oldXY); SETZERO (oldXY);
if (oldXY > INDEX_X)
P &= ~CARRY; else P |= CARRY;
PC += 2+XY_IS16BIT; cycles -= 2+XY_IS16BIT; DOBREAK;
case 0xE1: // "SBC (<%b,X)", 2, 6,
SAVE(ACCUM);
mem = DIR_INDEX_INDIR_X;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xE2: // "SEP %#b", 2, 3,
PC += 2; cycles -= 3;
if (((P | IMM_BYTE) & (MEMORY | INDEX)) != (P & (MEMORY | INDEX))) { // Change
P |= IMM_BYTE;
if (IMM_BYTE & INDEX) { // if switching from 16-bit to 8-bit indeXes,
INDEX_X_16BIT &= 0xFF; // clear high byte
INDEX_Y_16BIT &= 0xFF;
}
goto saveregs_andexit;
}
P |= IMM_BYTE;
DOBREAK;
case 0xE3: // "SBC <%b,S", 2, 4,
SAVE(ACCUM);
mem = S_REL;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xE4: // "CPX <%b", 2, 3,
mem = DIR;
oldXY = INDEX_X - *(XYTYPE*)TRAPREAD(mem);
SETNEGATIVEXY (oldXY); SETZERO (oldXY);
if (oldXY > INDEX_X)
P &= ~CARRY; else P |= CARRY;
PC += 2; cycles -= 3+XY_IS16BIT; DOBREAK;
case 0xE5: // "SBC <%b", 2, 3,
SAVE(ACCUM);
mem = DIR;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 3+A_IS16BIT; DOBREAK;
case 0xE6: // "INC <%b", 2, 5,
mem = DIR;
(*(amem = (ATYPE*)TRAPREAD(mem)))++;
SETZERO (*amem); SETNEGATIVE (*amem);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0xE7: // "SBC [<%b]", 2, 6,
SAVE(ACCUM);
mem = DIR_INDIR_LONG;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xE8: // "INX", 1, 2,
INDEX_X++;
SETZERO (INDEX_X); SETNEGATIVEXY (INDEX_X);
PC += 1; cycles -= 2; DOBREAK;
case 0xE9: // "SBC %#", 2, 2,
SAVE(ACCUM);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + IMM_ACCUM);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2+A_IS16BIT; cycles -= 2+A_IS16BIT; DOBREAK;
case 0xEA: // "NOP", 1, 2,
PC += 1; cycles -= 2; DOBREAK;
case 0xEB: // "SWA", 1, 3,
//(*((ATYPE*)®.A)) = ACCUM;
_tmp = ACCUM_16BIT & 0xFF;
ACCUM_16BIT >>= 8;
ACCUM_16BIT |= _tmp << 8;
//ACCUM = (ATYPE) reg.A;
SETZERO (ACCUM); SETNEGATIVE (ACCUM);
PC += 1; cycles -= 3; DOBREAK;
case 0xEC: // "CPX %w", 3, 4,
mem = ABS;
oldXY = INDEX_X - *(XYTYPE*)TRAPREAD(mem);
SETNEGATIVEXY (oldXY); SETZERO (oldXY);
if (oldXY > INDEX_X)
P &= ~CARRY; else P |= CARRY;
PC += 3; cycles -= 4+XY_IS16BIT; DOBREAK;
case 0xED: // "SBC %w", 3, 4,
SAVE(ACCUM);
mem = ABS;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xEE: // "INC %w", 3, 6,
mem = ABS;
(*(amem = (ATYPE*)TRAPREAD(mem)))++;
SETZERO (*amem); SETNEGATIVE (*amem);
PC += 3; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xEF: // "SBC %L", 4, 5,
SAVE(ACCUM);
mem = ABS_LONG;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
case 0xF0: // "BEQ @%b", 2, 2,
if (!(P & ZERO)) { // False
PC += 2; cycles -= 2; DOBREAK;
}
PC += 2 + ((signed char) opdata);
cycles -= 3; DOBREAK;
case 0xF1: // "SBC (<%b),Y", 2, 5,
SAVE(ACCUM);
mem = DIR_INDIR_INDEX_Y;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0xF2: // "SBC (<%b)", 2, 5,
SAVE(ACCUM);
mem = DIR_INDIR;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 5+A_IS16BIT; DOBREAK;
case 0xF3: // "SBC (<%b,S),Y", 2, 7,
SAVE(ACCUM);
mem = S_REL_INDIR_INDEX_Y;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 7+A_IS16BIT; DOBREAK;
case 0xF4: // "PSH %#w", 3, 5, // PEA
PUSHWORD (OPWORD);
PC += 3; cycles -= 5; DOBREAK;
case 0xF5: // "SBC <%b,X", 2, 4,
SAVE(ACCUM);
mem = DIR_INDEX_X;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xF6: // "INC <%b,X", 2, 6,
mem = DIR_INDEX_X;
(*(amem = (ATYPE*)TRAPREAD(mem)))++;
SETZERO (*amem); SETNEGATIVE (*amem);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xF7: // "SBC [<%b],Y", 2, 6,
SAVE(ACCUM);
mem = DIR_INDIR_LONG_INDEX_Y;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 2; cycles -= 6+A_IS16BIT; DOBREAK;
case 0xF8: // "SED", 1, 2,
P |= BCD;
PC += 1; cycles -= 2; DOBREAK;
case 0xF9: // "SBC %w,Y", 3, 4,
SAVE(ACCUM);
mem = ABS_INDEX_Y;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xFA: // "PUL X", 1, 4, // PLX
#ifdef XY_16BIT
PULLWORD (INDEX_X);
#else
PULLBYTE (INDEX_X);
#endif
SETZERO (INDEX_X); SETNEGATIVEXY (INDEX_X);
PC += 1; cycles -= 4+XY_IS16BIT; DOBREAK;
case 0xFB: // "XCE", 1, 2,
PC += 1; cycles -= 2;
_tmp2 = P & CARRY;
if (E) P |= CARRY; else P &= ~CARRY;
E = _tmp2;
if (E) {
P |= INDEX | MEMORY;
S = (S & 0xFF) | 0x100;
INDEX_X_16BIT &= 0xFF;
INDEX_Y_16BIT &= 0xFF;
D = 0;
goto saveregs_andexit;
}
DOBREAK;
case 0xFC: // "JSR (%w,X)", 3, 6,
PUSHWORD ((word)(PC + 2)); // TEST
PC = ABS_INDEX_INDIR_X_JMP;
cycles -= 6; DOBREAK;
case 0xFD: // "SBC %w,X", 3, 4,
SAVE(ACCUM);
mem = ABS_INDEX_X;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 3; cycles -= 4+A_IS16BIT; DOBREAK;
case 0xFE: // "INC %w,X", 3, 7,
mem = ABS_INDEX_X;
(*(amem = (ATYPE*)TRAPREAD(mem)))++;
SETZERO (*amem); SETNEGATIVE (*amem);
PC += 3; cycles -= 7+A_IS16BIT; DOBREAK;
case 0xFF: // "SBC %L,X", 4, 5
SAVE(ACCUM);
mem = ABS_LONG_INDEX_X;
amem = (ATYPE*)TRAPREAD(mem);
_tmpc = (dword)ACCUM - ((P&CARRY ? 0 : 1) + *amem);
SBCSETCARRY(_tmpc);
ACCUM = _tmpc;
if (P & BCD) BCDSUBADJUST (ACCUM);
SETZERO(ACCUM);
SETNEGATIVE(ACCUM); SETOVERFLOW(ACCUM, oldA);
PC += 4; cycles -= 5+A_IS16BIT; DOBREAK;
}
}
saveregs_andexit:
//reg.PC = PC;
//reg.P = P;
//debug0 ("reg.P set to %X", reg.P);
//(*((XYTYPE*)®.X)) = INDEX_X;
//(*((XYTYPE*)®.Y)) = INDEX_Y;
//(*((ATYPE*)®.A)) = ACCUM;
//reg.S = S;
//reg.D = D;
//reg.DBR = DBR;
//reg.E = E;
//return cycles;
return;
}
#undef DOBREAK
#undef P
#undef S
#undef D
#undef E
#undef DBR
#undef PC
#undef ACCUM_16BIT
#undef INDEX_X_16BIT
#undef INDEX_Y_16BIT
#undef cycles
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -