47 #ifndef CPU_CUSTOM_INCLUDED
64 #define SP_HI CPU65.sphi
65 #define ZP_HI CPU65.bphi
66 #define ZERO_REG CPU65.z
67 #define CPU_TYPE "65CE02"
71 #ifdef CPU_6502_NMOS_ONLY
72 #define CPU_TYPE "6502"
74 #define CPU_TYPE "65C02"
79 #define A_OP(op,dat) CPU65.a = CPU65.a op dat
83 static int mega65_fastclock_1_penalty;
84 static int mega65_fastclock_2_penalty;
85 #define PREFIX_NOTHING 0
87 #define PREFIX_NEG_NEG 2
92 #define PREFIX_NEG_NEG_NOP 3
100 CPU65.
x = (val >> 8) & 0xFF;
101 CPU65.
y = (val >> 16) & 0xFF;
102 CPU65.z = (val >> 24);
110 # define OPC_65CE02(w) DEBUG("CPU: 65CE02 opcode: %s" NL, w)
112 # define OPC_65CE02(w)
116 #define TIMINGS_65CE02_ {7,5,2,2,4,3,4,4,3,2,1,1,5,4,5,4,2,5,5,3,4,3,4,4,1,4,1,1,5,4,5,4,5,5,7,7,3,3,4,4,3,2,1,1,4,4,5,4,2,5,5,3,3,3,4,4,1,4,1,1,4,4,5,4,5,5,2,2,4,3,4,4,3,2,1,1,3,4,5,4,2,5,5,3,4,3,4,4,2,4,3,1,4,4,5,4,4,5,7,5,3,3,4,4,3,2,1,1,5,4,5,4,2,5,5,3,3,3,4,4,2,4,3,1,5,4,5,4,2,5,6,3,3,3,3,4,1,2,1,4,4,4,4,4,2,5,5,3,3,3,3,4,1,4,1,4,4,4,4,4,2,5,2,2,3,3,3,4,1,2,1,4,4,4,4,4,2,5,5,3,3,3,3,4,1,4,1,4,4,4,4,4,2,5,2,6,3,3,4,4,1,2,1,7,4,4,5,4,2,5,5,3,3,3,4,4,1,4,3,3,4,4,5,4,2,5,6,6,3,3,4,4,1,2,1,7,4,4,5,4,2,5,5,3,5,3,4,4,1,4,3,3,7,4,5,4} // 65CE02 timing (my findings)
117 #define TIMINGS_65CE02 {7,5,2,2,4,3,4,4,3,2,1,1,5,4,5,4,2,5,5,3,4,3,4,4,1,4,1,1,5,4,5,4,2,5,7,7,4,3,4,4,3,2,1,1,5,4,4,4,2,5,5,3,4,3,4,4,1,4,1,1,5,4,5,4,5,5,2,2,4,3,4,4,3,2,1,1,3,4,5,4,2,5,5,3,4,3,4,4,1,4,3,3,4,4,5,4,4,5,7,5,3,3,4,4,3,2,1,1,5,4,5,4,2,5,5,3,3,3,4,4,2,4,3,1,5,4,5,4,2,5,6,3,3,3,3,4,1,2,1,4,4,4,4,4,2,5,5,3,3,3,3,4,1,4,1,4,4,4,4,4,2,5,2,2,3,3,3,4,1,2,1,4,4,4,4,4,2,5,5,3,3,3,3,4,1,4,1,4,4,4,4,4,2,5,2,6,3,3,4,4,1,2,1,7,4,4,5,4,2,5,5,3,3,3,4,4,1,4,3,3,4,4,5,4,2,5,6,6,3,3,4,4,1,2,1,6,4,4,5,4,2,5,5,3,5,3,4,4,1,4,3,3,7,4,5,4} // 65CE02 timing (from gs4510.vhdl)
118 #define TIMINGS_6502C65 {7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,2,5,5,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,7,8,3,3,5,5,4,2,2,2,4,4,6,6,2,5,5,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,2,5,5,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,7,8,3,3,5,5,4,2,2,2,5,4,6,6,2,5,5,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,6,5,6,4,4,4,4,2,5,2,5,5,5,5,5,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,5,5,5,4,4,4,4,2,4,2,4,4,4,4,4,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,5,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,5,8,4,4,6,6,2,4,2,7,4,4,7,7} // 65CE02 with "dead cycles" to mimic NMOS 6502
119 #define TIMINGS_6502MOS {7,6,0,8,3,3,5,5,3,2,2,2,4,4,6,6,2,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,0,8,3,3,5,5,4,2,2,2,4,4,6,6,2,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,0,8,3,3,5,5,3,2,2,2,3,4,6,6,2,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,0,8,3,3,5,5,4,2,2,2,5,4,6,6,2,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,6,0,6,4,4,4,4,2,5,2,5,5,5,5,5,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,5,0,5,4,4,4,4,2,4,2,4,4,4,4,4,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7} // NMOS timing
120 #define TIMINGS_65C02 {7,6,2,2,5,3,5,5,3,2,2,2,6,4,6,2,2,5,5,2,5,4,6,5,2,4,2,2,6,4,7,2,6,6,2,2,3,3,5,5,4,2,2,2,4,4,6,2,2,5,5,2,4,4,6,5,2,4,2,2,4,4,7,2,6,6,2,2,3,3,5,5,3,2,2,2,3,4,6,2,2,5,5,2,4,4,6,5,2,4,3,2,2,4,7,2,6,6,2,2,3,3,5,5,4,2,2,2,5,4,6,2,2,5,5,2,4,4,6,5,2,4,4,2,6,4,7,2,3,6,2,2,3,3,3,5,2,2,2,2,4,4,4,2,2,6,5,2,4,4,4,5,2,5,2,2,4,5,5,2,2,6,2,2,3,3,3,5,2,2,2,2,4,4,4,2,2,5,5,2,4,4,4,5,2,4,2,2,4,4,4,2,2,6,2,2,3,3,5,5,2,2,2,2,4,4,6,2,2,5,5,2,4,4,6,5,2,4,3,2,2,4,7,2,2,6,2,2,3,3,5,5,2,2,2,2,4,4,6,2,2,5,5,2,4,4,6,5,2,4,4,2,2,4,7,2} // 65C02 timing
123 # ifdef CPU65_65CE02_6502NMOS_TIMING_EMULATION
127 static const Uint8 *opcycles = opcycles_fast_mode;
129 static Uint8 opcycles_ultra_mode[0x100];
133 void cpu65_set_timing (
unsigned int mode ) {
136 opcycles = opcycles_slow_mode;
138 mega65_fastclock_1_penalty = 0;
139 mega65_fastclock_2_penalty = 0;
143 opcycles = opcycles_fast_mode;
145 mega65_fastclock_1_penalty = 0;
146 mega65_fastclock_2_penalty = 0;
151 opcycles = opcycles_fast_mode;
153 mega65_fastclock_1_penalty = 1;
154 mega65_fastclock_2_penalty = 2;
164 # ifdef CPU_6502_NMOS_ONLY
172 void cpu65_init_mega_specific (
void )
174 for (
int a = 0;
a < 0x100;
a++) {
175 opcycles_ultra_mode[
a] = opcycles_fast_mode[
a];
180 #ifndef CPU65_DISCRETE_PF_NZ
181 #define VALUE_TO_PF_ZERO(a) ((a) ? 0 : CPU65_PF_Z)
184 #ifdef CPU65_DISCRETE_PF_NZ
185 # define ASSIGN_PF_Z_BY_COND(a) CPU65.pf_z = (a)
186 # define ASSIGN_PF_N_BY_COND(a) CPU65.pf_n = (a)
188 # define ASSIGN_PF_Z_BY_COND(a) do { if (a) CPU65.pf_nz |= CPU65_PF_Z; else CPU65.pf_nz &= ~CPU65_PF_Z; } while(0)
189 # define ASSIGN_PF_N_BY_COND(a) do { if (a) CPU65.pf_nz |= CPU65_PF_N; else CPU65.pf_nz &= ~CPU65_PF_N; } while(0)
193 #define writeFlatAddressedByte(d) cpu65_write_linear_opcode_callback(d)
194 #define readFlatAddressedByte() cpu65_read_linear_opcode_callback()
196 #define writeFlatAddressedQuadWithZ(d) cpu65_write_linear_long_opcode_callback(CPU65.z, d)
197 #define readFlatAddressedQuadWithZ() cpu65_read_linear_long_opcode_callback(CPU65.z)
198 #define writeFlatAddressedQuadWithoutZ(d) cpu65_write_linear_long_opcode_callback(0, d)
199 #define readFlatAddressedQuadWithoutZ() cpu65_read_linear_long_opcode_callback(0)
200 #ifdef CPU65_NO_RMW_EMULATION
201 #define writeByteTwice(a,od,nd) cpu65_write_callback(a,nd)
203 #define writeByteTwice(a,od,nd) cpu65_write_rmw_callback(a,od,nd)
205 #define writeByte(a,d) cpu65_write_callback(a,d)
206 #define readByte(a) cpu65_read_callback(a)
214 #ifdef CPU_6502_NMOS_ONLY
217 #define IS_CPU_NMOS 1
218 #define NMOS_JAM_OPCODE() cpu65_illegal_opcode_callback()
219 #define HAS_NMOS_BUG_JMP_INDIRECT 1
220 #define HAS_NMOS_BUG_NO_PFD_RES_ON_INT 1
221 #define HAS_NMOS_BUG_BCD 1
225 #define IS_CPU_NMOS XEMU_UNLIKELY(CPU65.nmos_mode)
226 #define NMOS_JAM_OPCODE() cpu65_illegal_opcode_callback()
227 #define HAS_NMOS_BUG_JMP_INDIRECT M65_CPU_ALWAYS_BUG_JMP_INDIRECT || (M65_CPU_NMOS_ONLY_BUG_JMP_INDIRECT && CPU65.nmos_mode)
228 #define HAS_NMOS_BUG_NO_PFD_RES_ON_INT M65_CPU_ALWAYS_BUG_NO_RESET_PFD_ON_INT || (M65_CPU_NMOS_ONLY_BUG_NO_RESET_PFD_ON_INT && CPU65.nmos_mode)
231 #define HAS_NMOS_BUG_BCD 1
236 #define IS_CPU_NMOS 0
237 #define NMOS_JAM_OPCODE()
238 #define HAS_NMOS_BUG_JMP_INDIRECT 0
239 #define HAS_NMOS_BUG_NO_PFD_RES_ON_INT 0
240 #define HAS_NMOS_BUG_BCD 0
281 DEBUG(
"CPU: 65CE02: SPHI changed to $%04X" NL,
CPU65.sphi);
291 DEBUG(
"CPU: 65CE02: SPHI changed to $%04X" NL,
CPU65.sphi);
297 #define push(data) writeByte(((Uint8)(CPU65.s--)) | SP_HI, data)
298 #define pop() readByte(((Uint8)(++CPU65.s)) | SP_HI)
308 #define PUSH_FOR_PHW pushWord_rev
314 #ifdef CPU65_DISCRETE_PF_NZ
333 #ifdef CPU65_DISCRETE_PF_NZ
366 CPU65.cpu_inhibit_interrupts = 0;
370 CPU65.prefix = PREFIX_NOTHING;
381 #ifdef CPU65_DISCRETE_PF_NZ
391 #ifdef CPU65_DISCRETE_PF_NZ
401 #define BIT31 0x80000000U
402 #define BIT30 0x40000000U
404 #ifdef CPU65_DISCRETE_PF_NZ
414 #define _imm() (CPU65.pc++)
419 #define _absx() ((Uint16)(_abs() + CPU65.x))
420 #define _absy() ((Uint16)(_abs() + CPU65.y))
421 #define _absi() readWord(_abs())
422 #define _absxi() readWord(_absx())
423 #define _zp() (readByte(CPU65.pc++) | ZP_HI)
447 #define _zpx() (((readByte(CPU65.pc++) + CPU65.x) & 0xFF) | ZP_HI)
448 #define _zpy() (((readByte(CPU65.pc++) + CPU65.y) & 0xFF) | ZP_HI)
458 if (temp & 128) temp =
CPU65.
pc - (temp ^ 0xFF);
459 else temp =
CPU65.
pc + temp + 1;
467 static XEMU_INLINE void _BRA16 (
const int cond ) {
501 #ifdef CPU65_DISCRETE_PF_NZ
510 #ifdef CPU65_DISCRETE_PF_NZ
540 t = (t >> 1) | (t & 0x80);
547 #ifdef CPU65_DISCRETE_PF_NZ
562 temp = (temp & 0xF) + (
CPU65.
a & 0xF0) + (
data & 0xF0);
564 temp = (temp & 0xF) + (
CPU65.
a & 0xF0) + (
data & 0xF0) + 0x10;
568 if ((temp & 0x1F0) > 0x90)
575 unsigned int temp2 = (
CPU65.
a & 0xF0) + (
data & 0xF0);
576 if (temp > 9) { temp2 += 0x10; temp += 6; }
578 if (temp2 > 0x90) temp2 += 0x60;
580 CPU65.
a = (temp & 0x0F) + (temp2 & 0xF0);
598 temp_a = ((temp_a - 6) & 0xf) | ((
CPU65.
a & 0xf0) - (
data & 0xf0) - 0x10);
600 temp_a = (temp_a & 0xf) | ((
CPU65.
a & 0xf0) - (
data & 0xf0));
610 if ((temp & 0x0F) > (
CPU65.
a & 0x0F)) temp -= 6;
611 temp -= (
data & 0xF0);
612 if ((temp & 0xF0) > (
CPU65.
a & 0xF0)) temp -= 0x60;
651 const Uint32 q = AXYZ_GET();
652 const Uint64 result64 = (Uint64)q - (Uint64)m - (Uint64)1 + (Uint64)!!
CPU65.
pf_c;
654 const Uint32 result = result64 & 0xFFFFFFFFUL;
655 CPU65.
pf_v = ((result ^ q) & BIT31) && ((q ^ m) & BIT31);
656 SET_NZ32(AXYZ_SET(result));
659 const Uint64 result64 = (Uint64)AXYZ_GET() - (Uint64)m;
660 const Uint32 result = result64 & 0xFFFFFFFFUL;
665 const Uint32 q = AXYZ_GET();
666 const Uint64 result64 = (Uint64)q + (Uint64)m + (Uint64)!!
CPU65.
pf_c;
667 CPU65.
pf_c = (result64 >= 0x100000000UL);
668 const Uint32 result = result64 & 0xFFFFFFFFUL;
669 CPU65.
pf_v = ((result ^ q) & BIT31) && !((q ^ m) & BIT31);
670 SET_NZ32(AXYZ_SET(result));
674 #ifdef CPU65_DISCRETE_PF_NZ
675 CPU65.pf_n = (m & BIT31);
676 CPU65.pf_z = (!(AXYZ_GET() & m));
713 q = (q >> 1) | (q & BIT31);
719 const int new_carry = q & BIT31;
727 const int new_carry = q & 1;
738 SET_NZ32(AXYZ_SET(AXYZ_GET() + 1));
741 SET_NZ32(AXYZ_SET(AXYZ_GET() - 1));
760 q = (q >> 1) | (q & BIT31);
766 const int new_carry = q & BIT31;
774 const int new_carry = q & 1;
784 #define IS_NEG_NEG_OP() XEMU_UNLIKELY(CPU65.prefix == PREFIX_NEG_NEG)
785 #define IS_NOP_OP() XEMU_UNLIKELY(CPU65.prefix == PREFIX_NOP)
786 #define IS_NEG_NEG_NOP_OP() XEMU_UNLIKELY(CPU65.prefix == PREFIX_NEG_NEG_NOP)
798 const int run_for_cycles
803 #ifdef CPU_STEP_MULTI_OPS
824 #ifdef CPU_STEP_MULTI_OPS
847 #ifdef CPU_STEP_MULTI_OPS
857 DEBUG(
"CPU: WARN: PC at zero!" NL);
861 DEBUG(
"CPU: at $%04X opcode = $%02X %s %s A=%02X X=%02X Y=%02X Z=%02X SP=%02X" NL, (
CPU65.
pc - 1) & 0xFFFF,
CPU65.
op, opcode_names[
CPU65.
op], opcode_adm_names[opcode_adms[
CPU65.
op]],
867 #ifdef CPU65_TRAP_OPCODE
878 DEBUG(
"CPU: WARN: BRK is about executing at PC=$%04X" NL, (
CPU65.
pc - 1) & 0xFFFF);
899 DEBUG(
"CPU: WARN: E flag is cleared!" NL);
920 if (IS_NEG_NEG_OP()) {
922 SET_NZ32(AXYZ_SET(AXYZ_GET() | readQuad(
_zp())));
930 if (IS_NEG_NEG_OP()) {
951 if (IS_NEG_NEG_OP()) {
974 if (IS_NEG_NEG_OP()) {
976 SET_NZ32(AXYZ_SET(AXYZ_GET() | readQuad(_abs())));
984 if (IS_NEG_NEG_OP()) {
997 #ifdef CPU65_DISCRETE_PF_NZ
1015 if (IS_NEG_NEG_OP()) {
1017 SET_NZ32(AXYZ_SET(AXYZ_GET() | readQuad(_zpi_noz())));
1020 if (IS_NEG_NEG_NOP_OP()) {
1034 OPC_65CE02(
"BPL16");
1035 #ifdef CPU65_DISCRETE_PF_NZ
1036 _BRA16(!
CPU65.pf_n);
1053 if (IS_NEG_NEG_OP()) {
1074 if (IS_NEG_NEG_OP()) {
1101 if (IS_NEG_NEG_OP()) {
1123 OPC_65CE02(
"JSR (nnnn)");
1135 OPC_65CE02(
"JSR (nnnn,X)");
1143 if (IS_NEG_NEG_OP()) {
1145 _BITQ(readQuad(
_zp()));
1153 if (IS_NEG_NEG_OP()) {
1155 SET_NZ32(AXYZ_SET(AXYZ_GET() & readQuad(
_zp())));
1163 if (IS_NEG_NEG_OP()) {
1184 if (IS_NEG_NEG_OP()) {
1198 if (
CPU65.sphi != 0x100)
1199 DEBUG(
"CPU: WARN: stack page is set non-0x100: $%04X" NL,
CPU65.sphi);
1206 if (IS_NEG_NEG_OP()) {
1208 _BITQ(readQuad(_abs()));
1216 if (IS_NEG_NEG_OP()) {
1218 SET_NZ32(AXYZ_SET(AXYZ_GET() & readQuad(_abs())));
1226 if (IS_NEG_NEG_OP()) {
1239 #ifdef CPU65_DISCRETE_PF_NZ
1257 if (IS_NEG_NEG_OP()) {
1259 SET_NZ32(AXYZ_SET(AXYZ_GET() & readQuad(_zpi_noz())));
1262 if (IS_NEG_NEG_NOP_OP()) {
1276 OPC_65CE02(
"BMI16");
1277 #ifdef CPU65_DISCRETE_PF_NZ
1295 if (IS_NEG_NEG_OP()) {
1317 if (IS_NEG_NEG_OP()) {
1344 if (IS_NEG_NEG_OP()) {
1369 if (
CPU65.prefix == PREFIX_NEG ||
CPU65.prefix == PREFIX_NEG_NEG) {
1370 OPC_65CE02(
"NEG-NEG");
1371 CPU65.prefix = PREFIX_NEG_NEG;
1373 CPU65.prefix = PREFIX_NEG;
1380 goto do_not_clear_prefix;
1393 if (IS_NEG_NEG_OP()) {
1400 OPC_65CE02(
"ASR A");
1411 if (IS_NEG_NEG_OP()) {
1417 OPC_65CE02(
"ASR nn");
1426 if (IS_NEG_NEG_OP()) {
1428 SET_NZ32(AXYZ_SET(AXYZ_GET() ^ readQuad(
_zp())));
1436 if (IS_NEG_NEG_OP()) {
1457 if (IS_NEG_NEG_OP()) {
1478 if (IS_NEG_NEG_OP()) {
1480 SET_NZ32(AXYZ_SET(AXYZ_GET() ^ readQuad(_abs())));
1488 if (IS_NEG_NEG_OP()) {
1515 if (IS_NEG_NEG_OP()) {
1517 SET_NZ32(AXYZ_SET(AXYZ_GET() ^ readQuad(_zpi_noz())));
1520 if (IS_NEG_NEG_NOP_OP()) {
1534 OPC_65CE02(
"BVC16");
1542 if (IS_NEG_NEG_OP()) {
1548 OPC_65CE02(
"ASR nn,X");
1560 if (IS_NEG_NEG_OP()) {
1591 DEBUG(
"CPU: WARN base page is non-zero now with value of $%04X" NL,
CPU65.bphi);
1611 if (IS_NEG_NEG_OP()) {
1633 OPC_65CE02(
"RTS #nn");
1638 CPU65.sphi += 0x100;
1650 OPC_65CE02(
"BSR16");
1664 if (IS_NEG_NEG_OP()) {
1666 _ADCQ(readQuad(
_zp()));
1674 if (IS_NEG_NEG_OP()) {
1695 if (IS_NEG_NEG_OP()) {
1720 if (IS_NEG_NEG_OP()) {
1722 _ADCQ(readQuad(_abs()));
1730 if (IS_NEG_NEG_OP()) {
1757 if (IS_NEG_NEG_OP()) {
1759 _ADCQ(readQuad(_zpi_noz()));
1762 if (IS_NEG_NEG_NOP_OP()) {
1776 OPC_65CE02(
"BVS16");
1791 if (IS_NEG_NEG_OP()) {
1833 if (IS_NEG_NEG_OP()) {
1856 OPC_65CE02(
"STA (nn,S),Y");
1866 OPC_65CE02(
"BRA16");
1876 if (IS_NEG_NEG_OP()) {
1878 writeQuad(
_zp(), AXYZ_GET());
1898 #ifdef CPU65_DISCRETE_PF_NZ
1911 OPC_65CE02(
"STY nnnn,X");
1921 if (IS_NEG_NEG_OP()) {
1923 writeQuad(_abs(), AXYZ_GET());
1952 if (IS_NEG_NEG_OP()) {
1954 writeQuad(_zpi_noz(), AXYZ_GET());
1957 if (IS_NEG_NEG_NOP_OP()) {
1971 OPC_65CE02(
"BCC16");
2003 OPC_65CE02(
"STX nnnn,Y");
2038 OPC_65CE02(
"LDZ #nn");
2048 if (IS_NEG_NEG_OP()) {
2050 SET_NZ32(AXYZ_SET(readQuad(
_zp())));
2077 OPC_65CE02(
"LDZ nnnn");
2087 if (IS_NEG_NEG_OP()) {
2089 SET_NZ32(AXYZ_SET(readQuad(_abs())));
2118 if (IS_NEG_NEG_OP()) {
2120 SET_NZ32(AXYZ_SET(readQuad(_zpi())));
2123 if (IS_NEG_NEG_NOP_OP()) {
2137 OPC_65CE02(
"BCS16");
2169 OPC_65CE02(
"LDZ nnnn,X");
2197 OPC_65CE02(
"CPZ #nn");
2208 OPC_65CE02(
"DEW nn");
2210 int ahi = (alo & 0xFF00) | ((alo + 1) & 0xFF);
2223 if (IS_NEG_NEG_OP()) {
2225 _CMPQ(readQuad(
_zp()));
2234 if (IS_NEG_NEG_OP()) {
2263 OPC_65CE02(
"ASW nnnn");
2279 if (IS_NEG_NEG_OP()) {
2281 _CMPQ(readQuad(_abs()));
2290 if (IS_NEG_NEG_OP()) {
2295 const int addr = _abs();
2297 const Uint8 new_data = old_data - 1;
2308 #ifdef CPU65_DISCRETE_PF_NZ
2326 if (IS_NEG_NEG_OP()) {
2328 _CMPQ(readQuad(_zpi_noz()));
2331 if (IS_NEG_NEG_NOP_OP()) {
2345 OPC_65CE02(
"BNE16");
2346 #ifdef CPU65_DISCRETE_PF_NZ
2347 _BRA16( !
CPU65.pf_z);
2357 OPC_65CE02(
"CPZ nn");
2370 if (IS_NEG_NEG_OP()) {
2408 OPC_65CE02(
"CPZ nnnn");
2421 if (IS_NEG_NEG_OP()) {
2446 OPC_65CE02(
"LDA (nn,S),Y");
2459 OPC_65CE02(
"INW nn");
2461 int ahi = (alo & 0xFF00) | ((alo + 1) & 0xFF);
2475 if (IS_NEG_NEG_OP()) {
2477 _SBCQ(readQuad(
_zp()));
2486 if (IS_NEG_NEG_OP()) {
2515 if (
CPU65.prefix == PREFIX_NEG_NEG) {
2516 OPC_65CE02(
"NEG-NEG-NOP");
2517 CPU65.prefix = PREFIX_NEG_NEG_NOP;
2520 CPU65.prefix = PREFIX_NOP;
2522 goto do_not_clear_prefix;
2532 OPC_65CE02(
"ROW nnnn");
2548 if (IS_NEG_NEG_OP()) {
2550 _SBCQ(readQuad(_abs()));
2559 if (IS_NEG_NEG_OP()) {
2564 const int addr = _abs();
2566 const Uint8 new_data = old_data + 1;
2577 #ifdef CPU65_DISCRETE_PF_NZ
2595 if (IS_NEG_NEG_OP()) {
2597 _SBCQ(readQuad(_zpi_noz()));
2600 if (IS_NEG_NEG_NOP_OP()) {
2614 OPC_65CE02(
"BEQ16");
2615 #ifdef CPU65_DISCRETE_PF_NZ
2626 OPC_65CE02(
"PHW #nnnn");
2627 PUSH_FOR_PHW(readWord(
CPU65.
pc));
2640 if (IS_NEG_NEG_OP()) {
2680 OPC_65CE02(
"PHW nnnn");
2681 PUSH_FOR_PHW(readWord(readWord(
CPU65.
pc)));
2694 if (IS_NEG_NEG_OP()) {
2716 CPU65.prefix = PREFIX_NOTHING;
2717 do_not_clear_prefix:
2719 #ifdef CPU_STEP_MULTI_OPS
2725 }
while (all_cycles < run_for_cycles);
2743 #ifdef XEMU_SNAPSHOT_SUPPORT
2748 #define SNAPSHOT_CPU65_BLOCK_VERSION 0
2749 #define SNAPSHOT_CPU65_BLOCK_SIZE 256
2752 #define SNAPSHOT_CPU65_ID 2
2754 #define SNAPSHOT_CPU65_ID 1
2757 int cpu65_snapshot_load_state (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
2760 Uint8 buffer[SNAPSHOT_CPU65_BLOCK_SIZE];
2761 if (
block->sub_counter ||
block->block_version != SNAPSHOT_CPU65_BLOCK_VERSION ||
block->sub_size !=
sizeof buffer)
2762 RETURN_XSNAPERR_USER(
"Bad CPU 65xx block syntax");
2763 ret = xemusnap_read_file(buffer,
sizeof buffer);
2764 if (ret)
return ret;
2765 if (buffer[0] != SNAPSHOT_CPU65_ID)
2766 RETURN_XSNAPERR_USER(
"CPU type mismatch");
2767 CPU65.
pc = P_AS_BE16(buffer + 1);
2779 CPU65.z = buffer[64];
2782 CPU65.cpu_inhibit_interrupts = (int)P_AS_BE32(buffer + 96);
2788 int cpu65_snapshot_save_state (
const struct xemu_snapshot_definition_st *def )
2790 Uint8 buffer[SNAPSHOT_CPU65_BLOCK_SIZE];
2791 int ret = xemusnap_write_block_header(def->idstr, SNAPSHOT_CPU65_BLOCK_VERSION);
2792 if (ret)
return ret;
2793 memset(buffer, 0xFF,
sizeof buffer);
2794 buffer[0] = SNAPSHOT_CPU65_ID;
2795 U16_AS_BE(buffer + 1,
CPU65.
pc);
2806 buffer[64] =
CPU65.z;
2807 buffer[65] =
CPU65.bphi >> 8;
2808 buffer[66] =
CPU65.sphi >> 8;
2809 U32_AS_BE(buffer + 96, (
Uint32)
CPU65.cpu_inhibit_interrupts);
2811 return xemusnap_write_sub_block(buffer,
sizeof buffer);