cpu.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:50k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * cpu.c - 6502 CPU emulation
  3.  *
  4.  * Copyright (C) 1995-1998 David Firth
  5.  * Copyright (C) 1998-2005 Atari800 development team (see DOC/CREDITS)
  6.  *
  7.  * This file is part of the Atari800 emulator project which emulates
  8.  * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
  9.  *
  10.  * Atari800 is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * Atari800 is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with Atari800; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23. */
  24. /*
  25. Configuration symbols
  26. =====================
  27. Define CPU65C02 if you don't want 6502 JMP() bug emulation.
  28. Define CYCLES_PER_OPCODE to update xpos in each opcode's emulation.
  29. Define MONITOR_BREAK if you want code breakpoints and execution history.
  30. Define MONITOR_BREAKPOINTS if you want user-defined breakpoints.
  31. Define MONITOR_PROFILE if you want 6502 opcode profiling.
  32. Define MONITOR_TRACE if you want the code to be disassembled while it is executed.
  33. Define NO_GOTO if you compile with GCC, but want switch() rather than goto *.
  34. Define NO_V_FLAG_VARIABLE to don't use local (static) variable V for the V flag.
  35. Define PC_PTR to emulate 6502 Program Counter using UBYTE *.
  36. Define PREFETCH_CODE to always fetch 2 bytes after the opcode.
  37. Define WRAP_64K to correctly emulate instructions that wrap at 64K.
  38. Define WRAP_ZPAGE to prevent incorrect access to the address 0x0100 in zeropage
  39. indirect mode.
  40. Limitations & Known bugs
  41. ========================
  42. There is no emulation of the bug in the BRK instruction executed simultaneously
  43. with another interrupt.
  44. The 6502 emulation ignores memory attributes for instruction fetch.
  45. This is because the instruction must come from either RAM or ROM.
  46. A program that executes instructions from within hardware addresses will fail
  47. since there is never any usable code there.
  48. The 6502 emulation also ignores memory attributes for accesses to page 0 and page 1.
  49.  */
  50. #include "config.h"
  51. #include <stdio.h>
  52. #include <stdlib.h> /* exit() */
  53. #include "cpu.h"
  54. #ifdef ASAP /* external project, see http://asap.sf.net */
  55. #include "asap_internal.h"
  56. #else
  57. #include "antic.h"
  58. #include "atari.h"
  59. #include "memory.h"
  60. #include "monitor.h"
  61. #ifndef BASIC
  62. #include "statesav.h"
  63. #ifndef __PLUS
  64. #include "ui.h"
  65. #endif
  66. #endif /* BASIC */
  67. #endif /* ASAP */
  68. #ifdef FALCON_CPUASM
  69. extern UBYTE IRQ;
  70. #ifdef PAGED_MEM
  71. #error cpu_m68k.asm cannot work with paged memory
  72. #endif
  73. void CPU_Initialise(void)
  74. {
  75. CPU_INIT();
  76. }
  77. void CPU_GetStatus(void)
  78. {
  79. CPUGET();
  80. }
  81. void CPU_PutStatus(void)
  82. {
  83. CPUPUT();
  84. }
  85. #else /* FALCON_CPUASM */
  86. /* Windows headers define it */
  87. #undef ABSOLUTE
  88. #ifndef __GNUC__
  89. #define NO_GOTO
  90. #endif
  91. /* #define CYCLES_PER_OPCODE */
  92. /* #define MONITOR_PROFILE */
  93. /* #define NO_V_FLAG_VARIABLE */
  94. /* If PC_PTR is defined, local PC is "const UBYTE *", otherwise it's UWORD. */
  95. /* #define PC_PTR */
  96. /* If PREFETCH_CODE is defined, 2 bytes after the opcode are always fetched. */
  97. /* #define PREFETCH_CODE */
  98. /* 6502 stack handling */
  99. #define PL                  dGetByte(0x0100 + ++S)
  100. #define PH(x)               dPutByte(0x0100 + S--, x)
  101. #define PHW(x)              PH((x) >> 8); PH((x) & 0xff)
  102. /* 6502 code fetching */
  103. #ifdef PC_PTR
  104. #define GET_PC()            (PC - memory)
  105. #define SET_PC(newpc)       (PC = memory + (newpc))
  106. #define PHPC                { UWORD tmp = PC - memory; PHW(tmp); }
  107. #define GET_CODE_BYTE()     (*PC++)
  108. #define PEEK_CODE_BYTE()    (*PC)
  109. #if !defined(WORDS_BIGENDIAN) && defined(WORDS_UNALIGNED_OK)
  110. #define PEEK_CODE_WORD()    (*(const UWORD *) PC)
  111. #else
  112. #define PEEK_CODE_WORD()    (*PC + (PC[1] << 8))
  113. #endif
  114. #else /* PC_PTR */
  115. #define GET_PC()            PC
  116. #define SET_PC(newpc)       (PC = (newpc))
  117. #define PHPC                PHW(PC)
  118. #define GET_CODE_BYTE()     dGetByte(PC++)
  119. #define PEEK_CODE_BYTE()    dGetByte(PC)
  120. #define PEEK_CODE_WORD()    dGetWord(PC)
  121. #endif /* PC_PTR */
  122. /* Cycle-exact Read-Modify-Write instructions.
  123.    RMW instructions: ASL, LSR, ROL, ROR, INC, DEC
  124.    (+ some undocumented) write to the specified address
  125.    *twice*: first the unmodified value, then the modified value.
  126.    This can be observed only with some hardware registers. */
  127. /* XXX: we do this only for GTIA, because NEW_CYCLE_EXACT does not correctly
  128.    emulate INC $D400 (and INC $D40A wasn't tested) */
  129. #ifdef NEW_CYCLE_EXACT
  130. #ifndef PAGED_ATTRIB
  131. #define RMW_GetByte(x, addr) 
  132. if (attrib[addr] == HARDWARE) { 
  133. x = Atari800_GetByte(addr); 
  134. if ((addr & 0xef00) == 0xc000) { 
  135. xpos--; 
  136. Atari800_PutByte(addr, x); 
  137. xpos++; 
  138. } else 
  139. x = dGetByte(addr);
  140. #else /* PAGED_ATTRIB */
  141. #define RMW_GetByte(x, addr) 
  142. x = GetByte(addr); 
  143. if ((addr & 0xef00) == 0xc000) { 
  144. xpos--; 
  145. PutByte(addr, x); 
  146. xpos++; 
  147. }
  148. #endif /* PAGED_ATTRIB */
  149. #else /* NEW_CYCLE_EXACT */
  150. /* Don't emulate the first write */
  151. #define RMW_GetByte(x, addr) x = GetByte(addr);
  152. #endif /* NEW_CYCLE_EXACT */
  153. /* 6502 registers. */
  154. UWORD regPC;
  155. UBYTE regA;
  156. UBYTE regX;
  157. UBYTE regY;
  158. UBYTE regP; /* Processor Status Byte (Partial) */
  159. UBYTE regS;
  160. UBYTE IRQ;
  161. /* Transfer 6502 registers between global variables and local variables inside GO() */
  162. #define UPDATE_GLOBAL_REGS  regPC = GET_PC(); regS = S; regA = A; regX = X; regY = Y
  163. #define UPDATE_LOCAL_REGS   SET_PC(regPC); S = regS; A = regA; X = regX; Y = regY
  164. /* 6502 flags local to this module */
  165. static UBYTE N; /* bit7 set => N flag set */
  166. #ifndef NO_V_FLAG_VARIABLE
  167. static UBYTE V;                 /* non-zero => V flag set */
  168. #endif
  169. static UBYTE Z; /* zero     => Z flag set */
  170. static UBYTE C; /* must be 0 or 1 */
  171. /* B, D, I are always in regP */
  172. void CPU_GetStatus(void)
  173. {
  174. #ifndef NO_V_FLAG_VARIABLE
  175. regP = (N & 0x80) + (V ? 0x40 : 0) + (regP & 0x3c) + ((Z == 0) ? 0x02 : 0) + C;
  176. #else
  177. regP = (N & 0x80) + (regP & 0x7c) + ((Z == 0) ? 0x02 : 0) + C;
  178. #endif
  179. }
  180. void CPU_PutStatus(void)
  181. {
  182. N = regP;
  183. #ifndef NO_V_FLAG_VARIABLE
  184. V = (regP & 0x40);
  185. #endif
  186. Z = (regP & 0x02) ^ 0x02;
  187. C = (regP & 0x01);
  188. }
  189. /* For Atari Basic loader */
  190. void (*rts_handler)(void) = NULL;
  191. /* 6502 instruction profiling */
  192. #ifdef MONITOR_PROFILE
  193. int instruction_count[256];
  194. #endif
  195. UBYTE cim_encountered = FALSE;
  196. /* Execution history */
  197. #ifdef MONITOR_BREAK
  198. UWORD remember_PC[REMEMBER_PC_STEPS];
  199. unsigned int remember_PC_curpos = 0;
  200. int remember_xpos[REMEMBER_PC_STEPS];
  201. UWORD remember_JMP[REMEMBER_JMP_STEPS];
  202. unsigned int remember_jmp_curpos = 0;
  203. #define INC_RET_NESTING ret_nesting++
  204. #else /* MONITOR_BREAK */
  205. #define INC_RET_NESTING
  206. #endif /* MONITOR_BREAK */
  207. /* Addressing modes */
  208. #ifdef WRAP_ZPAGE
  209. #define zGetWord(x) (dGetByte(x) + (dGetByte((UBYTE) ((x) + 1)) << 8))
  210. #else
  211. #define zGetWord(x) dGetWord(x)
  212. #endif
  213. #ifdef PREFETCH_CODE
  214. #if defined(WORDS_BIGENDIAN) || !defined(WORDS_UNALIGNED_OK)
  215. #warning PREFETCH_CODE is efficient only on little-endian machines with WORDS_UNALIGNED_OK
  216. #endif
  217. #define OP_BYTE     ((UBYTE) addr)
  218. #define OP_WORD     addr
  219. #define IMMEDIATE   (PC++, (UBYTE) addr)
  220. #define ABSOLUTE    PC += 2
  221. #define ZPAGE       PC++; addr &= 0xff
  222. #define ABSOLUTE_X  addr += X; PC += 2
  223. #define ABSOLUTE_Y  addr += Y; PC += 2
  224. #define INDIRECT_X  PC++; addr = (UBYTE) (addr + X); addr = zGetWord(addr)
  225. #define INDIRECT_Y  PC++; addr &= 0xff; addr = zGetWord(addr) + Y
  226. #define ZPAGE_X     PC++; addr = (UBYTE) (addr + X)
  227. #define ZPAGE_Y     PC++; addr = (UBYTE) (addr + Y)
  228. #else /* PREFETCH_CODE */
  229. #define OP_BYTE     PEEK_CODE_BYTE()
  230. #define OP_WORD     PEEK_CODE_WORD()
  231. #define IMMEDIATE   GET_CODE_BYTE()
  232. #define ABSOLUTE    addr = PEEK_CODE_WORD(); PC += 2
  233. #define ZPAGE       addr = GET_CODE_BYTE()
  234. #define ABSOLUTE_X  addr = PEEK_CODE_WORD() + X; PC += 2
  235. #define ABSOLUTE_Y  addr = PEEK_CODE_WORD() + Y; PC += 2
  236. #define INDIRECT_X  addr = (UBYTE) (GET_CODE_BYTE() + X); addr = zGetWord(addr)
  237. #define INDIRECT_Y  addr = GET_CODE_BYTE(); addr = zGetWord(addr) + Y
  238. #define ZPAGE_X     addr = (UBYTE) (GET_CODE_BYTE() + X)
  239. #define ZPAGE_Y     addr = (UBYTE) (GET_CODE_BYTE() + Y)
  240. #endif /* PREFETCH_CODE */
  241. /* Instructions */
  242. #define AND(t_data) Z = N = A &= t_data
  243. #define CMP(t_data) data = t_data; Z = N = A - data; C = (A >= data)
  244. #define CPX(t_data) data = t_data; Z = N = X - data; C = (X >= data)
  245. #define CPY(t_data) data = t_data; Z = N = Y - data; C = (Y >= data)
  246. #define EOR(t_data) Z = N = A ^= t_data
  247. #define LDA(t_data) Z = N = A = t_data
  248. #define LDX(t_data) Z = N = X = t_data
  249. #define LDY(t_data) Z = N = Y = t_data
  250. #define ORA(t_data) Z = N = A |= t_data
  251. #ifndef NO_V_FLAG_VARIABLE
  252. #define PHP(x)      data = (N & 0x80) + (V ? 0x40 : 0) + (regP & (x)) + ((Z == 0) ? 0x02 : 0) + C; PH(data)
  253. #define PHPB0       PHP(0x2c)  /* push flags with B flag clear (NMI, IRQ) */
  254. #define PHPB1       PHP(0x3c)  /* push flags with B flag set (PHP, BRK) */
  255. #define PLP         data = PL; N = data; V = (data & 0x40); Z = (data & 0x02) ^ 0x02; C = (data & 0x01); regP = (data & 0x0c) + 0x30
  256. #else /* NO_V_FLAG_VARIABLE */
  257. #define PHP(x)      data = (N & 0x80) + (regP & (x)) + ((Z == 0) ? 0x02 : 0) + C; PH(data)
  258. #define PHPB0       PHP(0x6c)  /* push flags with B flag clear (NMI, IRQ) */
  259. #define PHPB1       PHP(0x7c)  /* push flags with B flag set (PHP, BRK) */
  260. #define PLP         data = PL; N = data; Z = (data & 0x02) ^ 0x02; C = (data & 0x01); regP = (data & 0x4c) + 0x30
  261. #endif /* NO_V_FLAG_VARIABLE */
  262. /* 1 or 2 extra cycles for conditional jumps */
  263. #if 0
  264. /* old, less efficient version */
  265. #define BRANCH(cond) 
  266. if (cond) { 
  267. SWORD sdata = (SBYTE) GET_CODE_BYTE(); 
  268. if ((sdata + (UBYTE) GET_PC()) & 0xff00) 
  269. xpos++; 
  270. xpos++; 
  271. PC += sdata; 
  272. DONE 
  273. PC++; 
  274. DONE
  275. #else
  276. #define BRANCH(cond) 
  277. if (cond) { 
  278. addr = (UWORD) (SBYTE) IMMEDIATE; 
  279. addr += GET_PC(); 
  280. if ((addr ^ GET_PC()) & 0xff00) 
  281. xpos++; 
  282. xpos++; 
  283. SET_PC(addr); 
  284. DONE 
  285. PC++; 
  286. DONE
  287. #endif
  288. /* 1 extra cycle for X (or Y) index overflow */
  289. #define NCYCLES_X   if ((UBYTE) addr < X) xpos++
  290. #define NCYCLES_Y   if ((UBYTE) addr < Y) xpos++
  291. /* Triggers a Non-Maskable Interrupt */
  292. void NMI(void)
  293. {
  294. UBYTE S = regS;
  295. UBYTE data;
  296. PHW(regPC);
  297. PHPB0;
  298. SetI;
  299. regPC = dGetWordAligned(0xfffa);
  300. regS = S;
  301. xpos += 7; /* handling an interrupt by 6502 takes 7 cycles */
  302. INC_RET_NESTING;
  303. }
  304. /* Check pending IRQ, helps in (not only) Lucasfilm games */
  305. #define CPUCHECKIRQ 
  306. if (IRQ && !(regP & I_FLAG) && xpos < xpos_limit) { 
  307. PHPC; 
  308. PHPB0; 
  309. SetI; 
  310. SET_PC(dGetWordAligned(0xfffe)); 
  311. xpos += 7; 
  312. INC_RET_NESTING; 
  313. }
  314. /* Enter monitor */
  315. #ifdef __PLUS
  316. #define ENTER_MONITOR  Atari800_Exit(TRUE)
  317. #else
  318. #define ENTER_MONITOR  if (!Atari800_Exit(TRUE)) exit(0)
  319. #endif
  320. #define DO_BREAK 
  321. UPDATE_GLOBAL_REGS; 
  322. CPU_GetStatus(); 
  323. ENTER_MONITOR; 
  324. CPU_PutStatus(); 
  325. UPDATE_LOCAL_REGS;
  326. /* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
  327. static const int cycles[256] =
  328. {
  329. 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, /* 0x */
  330. 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 1x */
  331. 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, /* 2x */
  332. 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 3x */
  333. 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, /* 4x */
  334. 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 5x */
  335. 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, /* 6x */
  336. 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 7x */
  337. 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* 8x */
  338. 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, /* 9x */
  339. 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* Ax */
  340. 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, /* Bx */
  341. 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* Cx */
  342. 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* Dx */
  343. 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* Ex */
  344. 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 /* Fx */
  345. };
  346. /* 6502 emulation routine */
  347. void GO(int limit)
  348. {
  349. #ifdef NO_GOTO
  350. #define OPCODE_ALIAS(code) case 0x##code:
  351. #define DONE break;
  352. #else
  353. #define OPCODE_ALIAS(code) opcode_##code:
  354. #define DONE goto next;
  355. static const void *opcode[256] =
  356. {
  357. &&opcode_00, &&opcode_01, &&opcode_02, &&opcode_03,
  358. &&opcode_04, &&opcode_05, &&opcode_06, &&opcode_07,
  359. &&opcode_08, &&opcode_09, &&opcode_0a, &&opcode_0b,
  360. &&opcode_0c, &&opcode_0d, &&opcode_0e, &&opcode_0f,
  361. &&opcode_10, &&opcode_11, &&opcode_12, &&opcode_13,
  362. &&opcode_14, &&opcode_15, &&opcode_16, &&opcode_17,
  363. &&opcode_18, &&opcode_19, &&opcode_1a, &&opcode_1b,
  364. &&opcode_1c, &&opcode_1d, &&opcode_1e, &&opcode_1f,
  365. &&opcode_20, &&opcode_21, &&opcode_22, &&opcode_23,
  366. &&opcode_24, &&opcode_25, &&opcode_26, &&opcode_27,
  367. &&opcode_28, &&opcode_29, &&opcode_2a, &&opcode_2b,
  368. &&opcode_2c, &&opcode_2d, &&opcode_2e, &&opcode_2f,
  369. &&opcode_30, &&opcode_31, &&opcode_32, &&opcode_33,
  370. &&opcode_34, &&opcode_35, &&opcode_36, &&opcode_37,
  371. &&opcode_38, &&opcode_39, &&opcode_3a, &&opcode_3b,
  372. &&opcode_3c, &&opcode_3d, &&opcode_3e, &&opcode_3f,
  373. &&opcode_40, &&opcode_41, &&opcode_42, &&opcode_43,
  374. &&opcode_44, &&opcode_45, &&opcode_46, &&opcode_47,
  375. &&opcode_48, &&opcode_49, &&opcode_4a, &&opcode_4b,
  376. &&opcode_4c, &&opcode_4d, &&opcode_4e, &&opcode_4f,
  377. &&opcode_50, &&opcode_51, &&opcode_52, &&opcode_53,
  378. &&opcode_54, &&opcode_55, &&opcode_56, &&opcode_57,
  379. &&opcode_58, &&opcode_59, &&opcode_5a, &&opcode_5b,
  380. &&opcode_5c, &&opcode_5d, &&opcode_5e, &&opcode_5f,
  381. &&opcode_60, &&opcode_61, &&opcode_62, &&opcode_63,
  382. &&opcode_64, &&opcode_65, &&opcode_66, &&opcode_67,
  383. &&opcode_68, &&opcode_69, &&opcode_6a, &&opcode_6b,
  384. &&opcode_6c, &&opcode_6d, &&opcode_6e, &&opcode_6f,
  385. &&opcode_70, &&opcode_71, &&opcode_72, &&opcode_73,
  386. &&opcode_74, &&opcode_75, &&opcode_76, &&opcode_77,
  387. &&opcode_78, &&opcode_79, &&opcode_7a, &&opcode_7b,
  388. &&opcode_7c, &&opcode_7d, &&opcode_7e, &&opcode_7f,
  389. &&opcode_80, &&opcode_81, &&opcode_82, &&opcode_83,
  390. &&opcode_84, &&opcode_85, &&opcode_86, &&opcode_87,
  391. &&opcode_88, &&opcode_89, &&opcode_8a, &&opcode_8b,
  392. &&opcode_8c, &&opcode_8d, &&opcode_8e, &&opcode_8f,
  393. &&opcode_90, &&opcode_91, &&opcode_92, &&opcode_93,
  394. &&opcode_94, &&opcode_95, &&opcode_96, &&opcode_97,
  395. &&opcode_98, &&opcode_99, &&opcode_9a, &&opcode_9b,
  396. &&opcode_9c, &&opcode_9d, &&opcode_9e, &&opcode_9f,
  397. &&opcode_a0, &&opcode_a1, &&opcode_a2, &&opcode_a3,
  398. &&opcode_a4, &&opcode_a5, &&opcode_a6, &&opcode_a7,
  399. &&opcode_a8, &&opcode_a9, &&opcode_aa, &&opcode_ab,
  400. &&opcode_ac, &&opcode_ad, &&opcode_ae, &&opcode_af,
  401. &&opcode_b0, &&opcode_b1, &&opcode_b2, &&opcode_b3,
  402. &&opcode_b4, &&opcode_b5, &&opcode_b6, &&opcode_b7,
  403. &&opcode_b8, &&opcode_b9, &&opcode_ba, &&opcode_bb,
  404. &&opcode_bc, &&opcode_bd, &&opcode_be, &&opcode_bf,
  405. &&opcode_c0, &&opcode_c1, &&opcode_c2, &&opcode_c3,
  406. &&opcode_c4, &&opcode_c5, &&opcode_c6, &&opcode_c7,
  407. &&opcode_c8, &&opcode_c9, &&opcode_ca, &&opcode_cb,
  408. &&opcode_cc, &&opcode_cd, &&opcode_ce, &&opcode_cf,
  409. &&opcode_d0, &&opcode_d1, &&opcode_d2, &&opcode_d3,
  410. &&opcode_d4, &&opcode_d5, &&opcode_d6, &&opcode_d7,
  411. &&opcode_d8, &&opcode_d9, &&opcode_da, &&opcode_db,
  412. &&opcode_dc, &&opcode_dd, &&opcode_de, &&opcode_df,
  413. &&opcode_e0, &&opcode_e1, &&opcode_e2, &&opcode_e3,
  414. &&opcode_e4, &&opcode_e5, &&opcode_e6, &&opcode_e7,
  415. &&opcode_e8, &&opcode_e9, &&opcode_ea, &&opcode_eb,
  416. &&opcode_ec, &&opcode_ed, &&opcode_ee, &&opcode_ef,
  417. &&opcode_f0, &&opcode_f1, &&opcode_f2, &&opcode_f3,
  418. &&opcode_f4, &&opcode_f5, &&opcode_f6, &&opcode_f7,
  419. &&opcode_f8, &&opcode_f9, &&opcode_fa, &&opcode_fb,
  420. &&opcode_fc, &&opcode_fd, &&opcode_fe, &&opcode_ff,
  421. };
  422. #endif /* NO_GOTO */
  423. #ifdef CYCLES_PER_OPCODE
  424. #define OPCODE(code) OPCODE_ALIAS(code) xpos += cycles[0x##code];
  425. #else
  426. #define OPCODE(code) OPCODE_ALIAS(code)
  427. #endif
  428. #ifdef PC_PTR
  429. const UBYTE *PC;
  430. #else
  431. UWORD PC;
  432. #endif
  433. UBYTE A;
  434. UBYTE X;
  435. UBYTE Y;
  436. UBYTE S;
  437. UWORD addr;
  438. UBYTE data;
  439. #define insn data
  440. /*
  441.    This used to be in the main loop but has been removed to improve
  442.    execution speed. It does not seem to have any adverse effect on
  443.    the emulation for two reasons:
  444.    1. NMI's will can only be raised in antic.c - there is
  445.       no way an NMI can be generated whilst in this routine.
  446.    2. The timing of the IRQs are not that critical. */
  447. if (wsync_halt) {
  448. #ifdef NEW_CYCLE_EXACT
  449. if (DRAWING_SCREEN) {
  450. /* if WSYNC_C is a stolen cycle, antic2cpu_ptr will convert that to the nearest
  451.    cpu cycle before that cycle.  The CPU will see this cycle, if WSYNC is not
  452.    delayed. (Actually this cycle is the first cycle of the instruction after
  453.    STA WSYNC, which was really executed one cycle after STA WSYNC because
  454.    of an internal antic delay ).   delayed_wsync is added to this cycle to form
  455.    the limit in the case that WSYNC is not early (does not allow this extra cycle) */
  456. if (limit < antic2cpu_ptr[WSYNC_C] + delayed_wsync)
  457. return;
  458. xpos = antic2cpu_ptr[WSYNC_C] + delayed_wsync;
  459. }
  460. else {
  461. if (limit < (WSYNC_C + delayed_wsync))
  462. return;
  463. xpos = WSYNC_C;
  464. }
  465. delayed_wsync = 0;
  466. #else /* NEW_CYCLE_EXACT */
  467. if (limit < WSYNC_C)
  468. return;
  469. xpos = WSYNC_C;
  470. #endif /* NEW_CYCLE_EXACT */
  471. wsync_halt = 0;
  472. }
  473. xpos_limit = limit; /* needed for WSYNC store inside ANTIC */
  474. UPDATE_LOCAL_REGS;
  475. CPUCHECKIRQ;
  476. while (xpos < limit) {
  477. #ifdef MONITOR_BREAKPOINTS
  478. breakpoint_return:
  479. #endif
  480. #ifdef PC_PTR
  481. /* must handle 64k wrapping */
  482. if (PC >= memory + 0xfffe) {
  483. if (PC >= memory + 0x10000)
  484. PC -= 0x10000;
  485. else {
  486. /* the opcode is before 0x10000, but the operand is past */
  487. #ifdef WORDS_UNALIGNED_OK
  488. *(UWORD *) (memory + 0x10000) = *(UWORD *) memory;
  489. #else
  490. memory[0x10000] = memory[0];
  491. memory[0x10001] = memory[1];
  492. #endif /* WORDS_UNALIGNED_OK */
  493. }
  494. }
  495. #endif /* PC_PTR */
  496. #ifdef MONITOR_TRACE
  497. if (trace_file != NULL) {
  498. show_state(trace_file, GET_PC(), A, X, Y, S,
  499. (N & 0x80) ? 'N' : '-',
  500. #ifndef NO_V_FLAG_VARIABLE
  501. V ? 'V' : '-',
  502. #else
  503. (regP & V_FLAG) ? 'V' : '-',
  504. #endif
  505. (Z == 0) ? 'Z' : '-',
  506. (C != 0) ? 'C' : '-');
  507. }
  508. #endif
  509. #ifdef MONITOR_BREAK
  510. remember_PC[remember_PC_curpos] = GET_PC();
  511. #ifdef NEW_CYCLE_EXACT
  512. if (DRAWING_SCREEN)
  513. remember_xpos[remember_PC_curpos] = cpu2antic_ptr[xpos] + (ypos << 8);
  514. else
  515. #endif
  516. remember_xpos[remember_PC_curpos] = xpos + (ypos << 8);
  517. remember_PC_curpos = (remember_PC_curpos + 1) % REMEMBER_PC_STEPS;
  518. if (break_addr == GET_PC() || break_ypos == ypos) {
  519. DO_BREAK;
  520. }
  521. #endif /* MONITOR_BREAK */
  522. #if defined(WRAP_64K) && !defined(PC_PTR)
  523. memory[0x10000] = memory[0];
  524. #endif
  525. insn = GET_CODE_BYTE();
  526. #ifdef MONITOR_BREAKPOINTS
  527. if (breakpoint_table_size > 0 && breakpoints_enabled) {
  528. UBYTE optype = optype6502[insn];
  529. int i;
  530. switch (optype >> 4) {
  531. case 1:
  532. addr = PEEK_CODE_WORD();
  533. break;
  534. case 2:
  535. addr = PEEK_CODE_BYTE();
  536. break;
  537. case 3:
  538. addr = PEEK_CODE_WORD() + X;
  539. break;
  540. case 4:
  541. addr = PEEK_CODE_WORD() + Y;
  542. break;
  543. case 5:
  544. addr = (UBYTE) (PEEK_CODE_BYTE() + X);
  545. addr = zGetWord(addr);
  546. break;
  547. case 6:
  548. addr = PEEK_CODE_BYTE();
  549. addr = zGetWord(addr) + Y;
  550. break;
  551. case 7:
  552. addr = (UBYTE) (PEEK_CODE_BYTE() + X);
  553. break;
  554. case 8:
  555. addr = (UBYTE) (PEEK_CODE_BYTE() + Y);
  556. break;
  557. /* XXX: case 13 */
  558. default:
  559. addr = 0;
  560. break;
  561. }
  562. for (i = 0; i < breakpoint_table_size; i++) {
  563. int cond;
  564. int value;
  565. if (!breakpoint_table[i].enabled)
  566. continue; /* skip */
  567. cond = breakpoint_table[i].condition;
  568. if (cond == BREAKPOINT_OR)
  569. break; /* fire */
  570. value = breakpoint_table[i].value;
  571. if (cond == BREAKPOINT_FLAG_CLEAR) {
  572. switch (value) {
  573. case N_FLAG:
  574. if ((N & 0x80) == 0)
  575. continue;
  576. break;
  577. #ifndef NO_V_FLAG_VARIABLE
  578. case V_FLAG:
  579. if (V == 0)
  580. continue;
  581. break;
  582. #endif
  583. case Z_FLAG:
  584. if (Z != 0)
  585. continue;
  586. break;
  587. case C_FLAG:
  588. if (C == 0)
  589. continue;
  590. break;
  591. default:
  592. if ((regP & value) == 0)
  593. continue;
  594. break;
  595. }
  596. }
  597. else if (cond == BREAKPOINT_FLAG_SET) {
  598. switch (value) {
  599. case N_FLAG:
  600. if ((N & 0x80) != 0)
  601. continue;
  602. break;
  603. #ifndef NO_V_FLAG_VARIABLE
  604. case V_FLAG:
  605. if (V != 0)
  606. continue;
  607. break;
  608. #endif
  609. case Z_FLAG:
  610. if (Z == 0)
  611. continue;
  612. break;
  613. case C_FLAG:
  614. if (C != 0)
  615. continue;
  616. break;
  617. default:
  618. if ((regP & value) != 0)
  619. continue;
  620. break;
  621. }
  622. }
  623. else {
  624. int val;
  625. switch (cond >> 3) {
  626. case BREAKPOINT_PC >> 3:
  627. val = GET_PC() - 1;
  628. break;
  629. case BREAKPOINT_A >> 3:
  630. val = A;
  631. break;
  632. case BREAKPOINT_X >> 3:
  633. val = X;
  634. break;
  635. case BREAKPOINT_Y >> 3:
  636. val = Y;
  637. break;
  638. case BREAKPOINT_S >> 3:
  639. val = S;
  640. break;
  641. case BREAKPOINT_READ >> 3:
  642. if ((optype & 4) == 0)
  643. goto cond_failed;
  644. val = addr;
  645. break;
  646. case BREAKPOINT_WRITE >> 3:
  647. if ((optype & 8) == 0)
  648. goto cond_failed;
  649. val = addr;
  650. break;
  651. case BREAKPOINT_ACCESS >> 3:
  652. if ((optype & 12) == 0)
  653. goto cond_failed;
  654. val = addr;
  655. break;
  656. default:
  657. /* shouldn't happen */
  658. continue;
  659. }
  660. if ((cond & BREAKPOINT_LESS) != 0 && val < value)
  661. continue;
  662. if ((cond & BREAKPOINT_EQUAL) != 0 && val == value)
  663. continue;
  664. if ((cond & BREAKPOINT_GREATER) != 0 && val > value)
  665. continue;
  666. cond_failed:
  667. ;
  668. }
  669. /* a condition failed */
  670. /* quickly skip AND-connected conditions */
  671. do {
  672. if (++i >= breakpoint_table_size)
  673. goto no_breakpoint;
  674. } while (breakpoint_table[i].condition != BREAKPOINT_OR || !breakpoint_table[i].enabled);
  675. }
  676. /* fire breakpoint */
  677. PC--;
  678. DO_BREAK;
  679. goto breakpoint_return;
  680. no_breakpoint:
  681. ;
  682. }
  683. #endif /* MONITOR_BREAKPOINTS */
  684. #ifndef CYCLES_PER_OPCODE
  685. xpos += cycles[insn];
  686. #endif
  687. #ifdef MONITOR_PROFILE
  688. instruction_count[insn]++;
  689. #endif
  690. #ifdef PREFETCH_CODE
  691. addr = PEEK_CODE_WORD();
  692. #endif
  693. #ifdef NO_GOTO
  694. switch (insn) {
  695. #else
  696. goto *opcode[insn];
  697. #endif
  698. OPCODE(00) /* BRK */
  699. #ifdef MONITOR_BREAK
  700. if (break_brk) {
  701. DO_BREAK;
  702. }
  703. else
  704. #endif
  705. {
  706. PC++;
  707. PHPC;
  708. PHPB1;
  709. SetI;
  710. SET_PC(dGetWordAligned(0xfffe));
  711. INC_RET_NESTING;
  712. }
  713. DONE
  714. OPCODE(01) /* ORA (ab,x) */
  715. INDIRECT_X;
  716. ORA(GetByte(addr));
  717. DONE
  718. OPCODE(03) /* ASO (ab,x) [unofficial - ASL then ORA with Acc] */
  719. INDIRECT_X;
  720. aso:
  721. RMW_GetByte(data, addr);
  722. C = (data & 0x80) ? 1 : 0;
  723. data <<= 1;
  724. PutByte(addr, data);
  725. Z = N = A |= data;
  726. DONE
  727. OPCODE_ALIAS(04) /* NOP ab [unofficial - skip byte] */
  728. OPCODE_ALIAS(44)
  729. OPCODE(64)
  730. PC++;
  731. DONE
  732. OPCODE_ALIAS(14) /* NOP ab,x [unofficial - skip byte] */
  733. OPCODE_ALIAS(34)
  734. OPCODE_ALIAS(54)
  735. OPCODE_ALIAS(74)
  736. OPCODE_ALIAS(d4)
  737. OPCODE(f4)
  738. PC++;
  739. DONE
  740. OPCODE_ALIAS(80) /* NOP #ab [unofficial - skip byte] */
  741. OPCODE_ALIAS(82)
  742. OPCODE_ALIAS(89)
  743. OPCODE_ALIAS(c2)
  744. OPCODE(e2)
  745. PC++;
  746. DONE
  747. OPCODE(05) /* ORA ab */
  748. ZPAGE;
  749. ORA(dGetByte(addr));
  750. DONE
  751. OPCODE(06) /* ASL ab */
  752. ZPAGE;
  753. data = dGetByte(addr);
  754. C = (data & 0x80) ? 1 : 0;
  755. Z = N = data << 1;
  756. dPutByte(addr, Z);
  757. DONE
  758. OPCODE(07) /* ASO ab [unofficial - ASL then ORA with Acc] */
  759. ZPAGE;
  760. aso_zpage:
  761. data = dGetByte(addr);
  762. C = (data & 0x80) ? 1 : 0;
  763. data <<= 1;
  764. dPutByte(addr, data);
  765. Z = N = A |= data;
  766. DONE
  767. OPCODE(08) /* PHP */
  768. PHPB1;
  769. DONE
  770. OPCODE(09) /* ORA #ab */
  771. ORA(IMMEDIATE);
  772. DONE
  773. OPCODE(0a) /* ASL */
  774. C = (A & 0x80) ? 1 : 0;
  775. Z = N = A <<= 1;
  776. DONE
  777. OPCODE_ALIAS(0b) /* ANC #ab [unofficial - AND then copy N to C (Fox) */
  778. OPCODE(2b)
  779. AND(IMMEDIATE);
  780. C = N >= 0x80;
  781. DONE
  782. OPCODE(0c) /* NOP abcd [unofficial - skip word] */
  783. PC += 2;
  784. DONE
  785. OPCODE(0d) /* ORA abcd */
  786. ABSOLUTE;
  787. ORA(GetByte(addr));
  788. DONE
  789. OPCODE(0e) /* ASL abcd */
  790. ABSOLUTE;
  791. RMW_GetByte(data, addr);
  792. C = (data & 0x80) ? 1 : 0;
  793. Z = N = data << 1;
  794. PutByte(addr, Z);
  795. DONE
  796. OPCODE(0f) /* ASO abcd [unofficial - ASL then ORA with Acc] */
  797. ABSOLUTE;
  798. goto aso;
  799. OPCODE(10) /* BPL */
  800. BRANCH(!(N & 0x80))
  801. OPCODE(11) /* ORA (ab),y */
  802. INDIRECT_Y;
  803. NCYCLES_Y;
  804. ORA(GetByte(addr));
  805. DONE
  806. OPCODE(13) /* ASO (ab),y [unofficial - ASL then ORA with Acc] */
  807. INDIRECT_Y;
  808. goto aso;
  809. OPCODE(15) /* ORA ab,x */
  810. ZPAGE_X;
  811. ORA(dGetByte(addr));
  812. DONE
  813. OPCODE(16) /* ASL ab,x */
  814. ZPAGE_X;
  815. data = dGetByte(addr);
  816. C = (data & 0x80) ? 1 : 0;
  817. Z = N = data << 1;
  818. dPutByte(addr, Z);
  819. DONE
  820. OPCODE(17) /* ASO ab,x [unofficial - ASL then ORA with Acc] */
  821. ZPAGE_X;
  822. goto aso_zpage;
  823. OPCODE(18) /* CLC */
  824. C = 0;
  825. DONE
  826. OPCODE(19) /* ORA abcd,y */
  827. ABSOLUTE_Y;
  828. NCYCLES_Y;
  829. ORA(GetByte(addr));
  830. DONE
  831. OPCODE(1b) /* ASO abcd,y [unofficial - ASL then ORA with Acc] */
  832. ABSOLUTE_Y;
  833. goto aso;
  834. OPCODE_ALIAS(1c) /* NOP abcd,x [unofficial - skip word] */
  835. OPCODE_ALIAS(3c)
  836. OPCODE_ALIAS(5c)
  837. OPCODE_ALIAS(7c)
  838. OPCODE_ALIAS(dc)
  839. OPCODE(fc)
  840. if (OP_BYTE + X >= 0x100)
  841. xpos++;
  842. PC += 2;
  843. DONE
  844. OPCODE(1d) /* ORA abcd,x */
  845. ABSOLUTE_X;
  846. NCYCLES_X;
  847. ORA(GetByte(addr));
  848. DONE
  849. OPCODE(1e) /* ASL abcd,x */
  850. ABSOLUTE_X;
  851. RMW_GetByte(data, addr);
  852. C = (data & 0x80) ? 1 : 0;
  853. Z = N = data << 1;
  854. PutByte(addr, Z);
  855. DONE
  856. OPCODE(1f) /* ASO abcd,x [unofficial - ASL then ORA with Acc] */
  857. ABSOLUTE_X;
  858. goto aso;
  859. OPCODE(20) /* JSR abcd */
  860. {
  861. UWORD retaddr = GET_PC() + 1;
  862. #ifdef MONITOR_BREAK
  863. remember_JMP[remember_jmp_curpos] = GET_PC() - 1;
  864. remember_jmp_curpos = (remember_jmp_curpos + 1) % REMEMBER_JMP_STEPS;
  865. ret_nesting++;
  866. #endif
  867. PHW(retaddr);
  868. }
  869. SET_PC(OP_WORD);
  870. DONE
  871. OPCODE(21) /* AND (ab,x) */
  872. INDIRECT_X;
  873. AND(GetByte(addr));
  874. DONE
  875. OPCODE(23) /* RLA (ab,x) [unofficial - ROL Mem, then AND with A] */
  876. INDIRECT_X;
  877. rla:
  878. RMW_GetByte(data, addr);
  879. if (C) {
  880. C = (data & 0x80) ? 1 : 0;
  881. data = (data << 1) + 1;
  882. }
  883. else {
  884. C = (data & 0x80) ? 1 : 0;
  885. data = (data << 1);
  886. }
  887. PutByte(addr, data);
  888. Z = N = A &= data;
  889. DONE
  890. OPCODE(24) /* BIT ab */
  891. ZPAGE;
  892. N = dGetByte(addr);
  893. #ifndef NO_V_FLAG_VARIABLE
  894. V = N & 0x40;
  895. #else
  896. regP = (regP & 0xbf) + (N & 0x40);
  897. #endif
  898. Z = (A & N);
  899. DONE
  900. OPCODE(25) /* AND ab */
  901. ZPAGE;
  902. AND(dGetByte(addr));
  903. DONE
  904. OPCODE(26) /* ROL ab */
  905. ZPAGE;
  906. data = dGetByte(addr);
  907. Z = N = (data << 1) + C;
  908. C = (data & 0x80) ? 1 : 0;
  909. dPutByte(addr, Z);
  910. DONE
  911. OPCODE(27) /* RLA ab [unofficial - ROL Mem, then AND with A] */
  912. ZPAGE;
  913. rla_zpage:
  914. data = dGetByte(addr);
  915. if (C) {
  916. C = (data & 0x80) ? 1 : 0;
  917. data = (data << 1) + 1;
  918. }
  919. else {
  920. C = (data & 0x80) ? 1 : 0;
  921. data = (data << 1);
  922. }
  923. dPutByte(addr, data);
  924. Z = N = A &= data;
  925. DONE
  926. OPCODE(28) /* PLP */
  927. PLP;
  928. CPUCHECKIRQ;
  929. DONE
  930. OPCODE(29) /* AND #ab */
  931. AND(IMMEDIATE);
  932. DONE
  933. OPCODE(2a) /* ROL */
  934. Z = N = (A << 1) + C;
  935. C = (A & 0x80) ? 1 : 0;
  936. A = Z;
  937. DONE
  938. OPCODE(2c) /* BIT abcd */
  939. ABSOLUTE;
  940. N = GetByte(addr);
  941. #ifndef NO_V_FLAG_VARIABLE
  942. V = N & 0x40;
  943. #else
  944. regP = (regP & 0xbf) + (N & 0x40);
  945. #endif
  946. Z = (A & N);
  947. DONE
  948. OPCODE(2d) /* AND abcd */
  949. ABSOLUTE;
  950. AND(GetByte(addr));
  951. DONE
  952. OPCODE(2e) /* ROL abcd */
  953. ABSOLUTE;
  954. RMW_GetByte(data, addr);
  955. Z = N = (data << 1) + C;
  956. C = (data & 0x80) ? 1 : 0;
  957. PutByte(addr, Z);
  958. DONE
  959. OPCODE(2f) /* RLA abcd [unofficial - ROL Mem, then AND with A] */
  960. ABSOLUTE;
  961. goto rla;
  962. OPCODE(30) /* BMI */
  963. BRANCH(N & 0x80)
  964. OPCODE(31) /* AND (ab),y */
  965. INDIRECT_Y;
  966. NCYCLES_Y;
  967. AND(GetByte(addr));
  968. DONE
  969. OPCODE(33) /* RLA (ab),y [unofficial - ROL Mem, then AND with A] */
  970. INDIRECT_Y;
  971. goto rla;
  972. OPCODE(35) /* AND ab,x */
  973. ZPAGE_X;
  974. AND(dGetByte(addr));
  975. DONE
  976. OPCODE(36) /* ROL ab,x */
  977. ZPAGE_X;
  978. data = dGetByte(addr);
  979. Z = N = (data << 1) + C;
  980. C = (data & 0x80) ? 1 : 0;
  981. dPutByte(addr, Z);
  982. DONE
  983. OPCODE(37) /* RLA ab,x [unofficial - ROL Mem, then AND with A] */
  984. ZPAGE_X;
  985. goto rla_zpage;
  986. OPCODE(38) /* SEC */
  987. C = 1;
  988. DONE
  989. OPCODE(39) /* AND abcd,y */
  990. ABSOLUTE_Y;
  991. NCYCLES_Y;
  992. AND(GetByte(addr));
  993. DONE
  994. OPCODE(3b) /* RLA abcd,y [unofficial - ROL Mem, then AND with A] */
  995. ABSOLUTE_Y;
  996. goto rla;
  997. OPCODE(3d) /* AND abcd,x */
  998. ABSOLUTE_X;
  999. NCYCLES_X;
  1000. AND(GetByte(addr));
  1001. DONE
  1002. OPCODE(3e) /* ROL abcd,x */
  1003. ABSOLUTE_X;
  1004. RMW_GetByte(data, addr);
  1005. Z = N = (data << 1) + C;
  1006. C = (data & 0x80) ? 1 : 0;
  1007. PutByte(addr, Z);
  1008. DONE
  1009. OPCODE(3f) /* RLA abcd,x [unofficial - ROL Mem, then AND with A] */
  1010. ABSOLUTE_X;
  1011. goto rla;
  1012. OPCODE(40) /* RTI */
  1013. PLP;
  1014. data = PL;
  1015. SET_PC((PL << 8) + data);
  1016. CPUCHECKIRQ;
  1017. #ifdef MONITOR_BREAK
  1018. if (break_ret && --ret_nesting <= 0)
  1019. break_step = TRUE;
  1020. #endif
  1021. DONE
  1022. OPCODE(41) /* EOR (ab,x) */
  1023. INDIRECT_X;
  1024. EOR(GetByte(addr));
  1025. DONE
  1026. OPCODE(43) /* LSE (ab,x) [unofficial - LSR then EOR result with A] */
  1027. INDIRECT_X;
  1028. lse:
  1029. RMW_GetByte(data, addr);
  1030. C = data & 1;
  1031. data >>= 1;
  1032. PutByte(addr, data);
  1033. Z = N = A ^= data;
  1034. DONE
  1035. OPCODE(45) /* EOR ab */
  1036. ZPAGE;
  1037. EOR(dGetByte(addr));
  1038. DONE
  1039. OPCODE(46) /* LSR ab */
  1040. ZPAGE;
  1041. data = dGetByte(addr);
  1042. C = data & 1;
  1043. Z = data >> 1;
  1044. N = 0;
  1045. dPutByte(addr, Z);
  1046. DONE
  1047. OPCODE(47) /* LSE ab [unofficial - LSR then EOR result with A] */
  1048. ZPAGE;
  1049. lse_zpage:
  1050. data = dGetByte(addr);
  1051. C = data & 1;
  1052. data >>= 1;
  1053. dPutByte(addr, data);
  1054. Z = N = A ^= data;
  1055. DONE
  1056. OPCODE(48) /* PHA */
  1057. PH(A);
  1058. DONE
  1059. OPCODE(49) /* EOR #ab */
  1060. EOR(IMMEDIATE);
  1061. DONE
  1062. OPCODE(4a) /* LSR */
  1063. C = A & 1;
  1064. Z = N = A >>= 1;
  1065. DONE
  1066. OPCODE(4b) /* ALR #ab [unofficial - Acc AND Data, LSR result] */
  1067. data = A & IMMEDIATE;
  1068. C = data & 1;
  1069. Z = N = A = (data >> 1);
  1070. DONE
  1071. OPCODE(4c) /* JMP abcd */
  1072. #ifdef MONITOR_BREAK
  1073. remember_JMP[remember_jmp_curpos] = GET_PC() - 1;
  1074. remember_jmp_curpos = (remember_jmp_curpos + 1) % REMEMBER_JMP_STEPS;
  1075. #endif
  1076. SET_PC(OP_WORD);
  1077. DONE
  1078. OPCODE(4d) /* EOR abcd */
  1079. ABSOLUTE;
  1080. EOR(GetByte(addr));
  1081. DONE
  1082. OPCODE(4e) /* LSR abcd */
  1083. ABSOLUTE;
  1084. RMW_GetByte(data, addr);
  1085. C = data & 1;
  1086. Z = data >> 1;
  1087. N = 0;
  1088. PutByte(addr, Z);
  1089. DONE
  1090. OPCODE(4f) /* LSE abcd [unofficial - LSR then EOR result with A] */
  1091. ABSOLUTE;
  1092. goto lse;
  1093. OPCODE(50) /* BVC */
  1094. #ifndef NO_V_FLAG_VARIABLE
  1095. BRANCH(!V)
  1096. #else
  1097. BRANCH(!(regP & 0x40))
  1098. #endif
  1099. OPCODE(51) /* EOR (ab),y */
  1100. INDIRECT_Y;
  1101. NCYCLES_Y;
  1102. EOR(GetByte(addr));
  1103. DONE
  1104. OPCODE(53) /* LSE (ab),y [unofficial - LSR then EOR result with A] */
  1105. INDIRECT_Y;
  1106. goto lse;
  1107. OPCODE(55) /* EOR ab,x */
  1108. ZPAGE_X;
  1109. EOR(dGetByte(addr));
  1110. DONE
  1111. OPCODE(56) /* LSR ab,x */
  1112. ZPAGE_X;
  1113. data = dGetByte(addr);
  1114. C = data & 1;
  1115. Z = data >> 1;
  1116. N = 0;
  1117. dPutByte(addr, Z);
  1118. DONE
  1119. OPCODE(57) /* LSE ab,x [unofficial - LSR then EOR result with A] */
  1120. ZPAGE_X;
  1121. goto lse_zpage;
  1122. OPCODE(58) /* CLI */
  1123. ClrI;
  1124. CPUCHECKIRQ;
  1125. DONE
  1126. OPCODE(59) /* EOR abcd,y */
  1127. ABSOLUTE_Y;
  1128. NCYCLES_Y;
  1129. EOR(GetByte(addr));
  1130. DONE
  1131. OPCODE(5b) /* LSE abcd,y [unofficial - LSR then EOR result with A] */
  1132. ABSOLUTE_Y;
  1133. goto lse;
  1134. OPCODE(5d) /* EOR abcd,x */
  1135. ABSOLUTE_X;
  1136. NCYCLES_X;
  1137. EOR(GetByte(addr));
  1138. DONE
  1139. OPCODE(5e) /* LSR abcd,x */
  1140. ABSOLUTE_X;
  1141. RMW_GetByte(data, addr);
  1142. C = data & 1;
  1143. Z = data >> 1;
  1144. N = 0;
  1145. PutByte(addr, Z);
  1146. DONE
  1147. OPCODE(5f) /* LSE abcd,x [unofficial - LSR then EOR result with A] */
  1148. ABSOLUTE_X;
  1149. goto lse;
  1150. OPCODE(60) /* RTS */
  1151. data = PL;
  1152. SET_PC((PL << 8) + data + 1);
  1153. #ifdef MONITOR_BREAK
  1154. if (break_ret && --ret_nesting <= 0)
  1155. break_step = TRUE;
  1156. #endif
  1157. if (rts_handler != NULL) {
  1158. rts_handler();
  1159. rts_handler = NULL;
  1160. }
  1161. DONE
  1162. OPCODE(61) /* ADC (ab,x) */
  1163. INDIRECT_X;
  1164. data = GetByte(addr);
  1165. goto adc;
  1166. OPCODE(63) /* RRA (ab,x) [unofficial - ROR Mem, then ADC to Acc] */
  1167. INDIRECT_X;
  1168. rra:
  1169. RMW_GetByte(data, addr);
  1170. if (C) {
  1171. C = data & 1;
  1172. data = (data >> 1) + 0x80;
  1173. }
  1174. else {
  1175. C = data & 1;
  1176. data >>= 1;
  1177. }
  1178. PutByte(addr, data);
  1179. goto adc;
  1180. OPCODE(65) /* ADC ab */
  1181. ZPAGE;
  1182. data = dGetByte(addr);
  1183. goto adc;
  1184. OPCODE(66) /* ROR ab */
  1185. ZPAGE;
  1186. data = dGetByte(addr);
  1187. Z = N = (C << 7) + (data >> 1);
  1188. C = data & 1;
  1189. dPutByte(addr, Z);
  1190. DONE
  1191. OPCODE(67) /* RRA ab [unofficial - ROR Mem, then ADC to Acc] */
  1192. ZPAGE;
  1193. rra_zpage:
  1194. data = dGetByte(addr);
  1195. if (C) {
  1196. C = data & 1;
  1197. data = (data >> 1) + 0x80;
  1198. }
  1199. else {
  1200. C = data & 1;
  1201. data >>= 1;
  1202. }
  1203. dPutByte(addr, data);
  1204. goto adc;
  1205. OPCODE(68) /* PLA */
  1206. Z = N = A = PL;
  1207. DONE
  1208. OPCODE(69) /* ADC #ab */
  1209. data = IMMEDIATE;
  1210. goto adc;
  1211. OPCODE(6a) /* ROR */
  1212. Z = N = (C << 7) + (A >> 1);
  1213. C = A & 1;
  1214. A = Z;
  1215. DONE
  1216. OPCODE(6b) /* ARR #ab [unofficial - Acc AND Data, ROR result] */
  1217. /* It does some 'BCD fixup' if D flag is set */
  1218. /* MPC 05/24/00 */
  1219. data = A & IMMEDIATE;
  1220. if (regP & D_FLAG) {
  1221. UBYTE temp = (data >> 1) + (C << 7);
  1222. Z = N = temp;
  1223. #ifndef NO_V_FLAG_VARIABLE
  1224. V = ((temp ^ data) & 0x40);
  1225. #else
  1226. regP = (regP & 0xbf) + ((temp ^ data) & 0x40);
  1227. #endif
  1228. if ((data & 0x0F) + (data & 0x01) > 5)
  1229. temp = (temp & 0xF0) + ((temp + 0x6) & 0x0F);
  1230. if (data + (data & 0x10) >= 0x60) {
  1231. temp += 0x60;
  1232. C = 1;
  1233. }
  1234. else
  1235. C = 0;
  1236. A = (UBYTE) temp;
  1237. }
  1238. else {
  1239. Z = N = A = (data >> 1) + (C << 7);
  1240. C = data >> 7;
  1241. #ifndef NO_V_FLAG_VARIABLE
  1242. V = C ^ ((A >> 5) & 1);
  1243. #else
  1244. regP = (regP & 0xbf) + ((A ^ data) & 0x40);
  1245. #endif
  1246. }
  1247. DONE
  1248. OPCODE(6c) /* JMP (abcd) */
  1249. #ifdef MONITOR_BREAK
  1250. remember_JMP[remember_jmp_curpos] = GET_PC() - 1;
  1251. remember_jmp_curpos = (remember_jmp_curpos + 1) % REMEMBER_JMP_STEPS;
  1252. #endif
  1253. ABSOLUTE;
  1254. #ifdef CPU65C02
  1255. /* XXX: if ((UBYTE) addr == 0xff) xpos++; */
  1256. SET_PC(dGetWord(addr));
  1257. #else
  1258. /* original 6502 had a bug in JMP (addr) when addr crossed page boundary */
  1259. if ((UBYTE) addr == 0xff)
  1260. SET_PC((dGetByte(addr - 0xff) << 8) + dGetByte(addr));
  1261. else
  1262. SET_PC(dGetWord(addr));
  1263. #endif
  1264. DONE
  1265. OPCODE(6d) /* ADC abcd */
  1266. ABSOLUTE;
  1267. data = GetByte(addr);
  1268. goto adc;
  1269. OPCODE(6e) /* ROR abcd */
  1270. ABSOLUTE;
  1271. RMW_GetByte(data, addr);
  1272. Z = N = (C << 7) + (data >> 1);
  1273. C = data & 1;
  1274. PutByte(addr, Z);
  1275. DONE
  1276. OPCODE(6f) /* RRA abcd [unofficial - ROR Mem, then ADC to Acc] */
  1277. ABSOLUTE;
  1278. goto rra;
  1279. OPCODE(70) /* BVS */
  1280. #ifndef NO_V_FLAG_VARIABLE
  1281. BRANCH(V)
  1282. #else
  1283. BRANCH(regP & 0x40)
  1284. #endif
  1285. OPCODE(71) /* ADC (ab),y */
  1286. INDIRECT_Y;
  1287. NCYCLES_Y;
  1288. data = GetByte(addr);
  1289. goto adc;
  1290. OPCODE(73) /* RRA (ab),y [unofficial - ROR Mem, then ADC to Acc] */
  1291. INDIRECT_Y;
  1292. goto rra;
  1293. OPCODE(75) /* ADC ab,x */
  1294. ZPAGE_X;
  1295. data = dGetByte(addr);
  1296. goto adc;
  1297. OPCODE(76) /* ROR ab,x */
  1298. ZPAGE_X;
  1299. data = dGetByte(addr);
  1300. Z = N = (C << 7) + (data >> 1);
  1301. C = data & 1;
  1302. dPutByte(addr, Z);
  1303. DONE
  1304. OPCODE(77) /* RRA ab,x [unofficial - ROR Mem, then ADC to Acc] */
  1305. ZPAGE_X;
  1306. goto rra_zpage;
  1307. OPCODE(78) /* SEI */
  1308. SetI;
  1309. DONE
  1310. OPCODE(79) /* ADC abcd,y */
  1311. ABSOLUTE_Y;
  1312. NCYCLES_Y;
  1313. data = GetByte(addr);
  1314. goto adc;
  1315. OPCODE(7b) /* RRA abcd,y [unofficial - ROR Mem, then ADC to Acc] */
  1316. ABSOLUTE_Y;
  1317. goto rra;
  1318. OPCODE(7d) /* ADC abcd,x */
  1319. ABSOLUTE_X;
  1320. NCYCLES_X;
  1321. data = GetByte(addr);
  1322. goto adc;
  1323. OPCODE(7e) /* ROR abcd,x */
  1324. ABSOLUTE_X;
  1325. RMW_GetByte(data, addr);
  1326. Z = N = (C << 7) + (data >> 1);
  1327. C = data & 1;
  1328. PutByte(addr, Z);
  1329. DONE
  1330. OPCODE(7f) /* RRA abcd,x [unofficial - ROR Mem, then ADC to Acc] */
  1331. ABSOLUTE_X;
  1332. goto rra;
  1333. OPCODE(81) /* STA (ab,x) */
  1334. INDIRECT_X;
  1335. PutByte(addr, A);
  1336. DONE
  1337. /* AXS doesn't change flags and SAX is better name for it (Fox) */
  1338. OPCODE(83) /* SAX (ab,x) [unofficial - Store result A AND X */
  1339. INDIRECT_X;
  1340. data = A & X;
  1341. PutByte(addr, data);
  1342. DONE
  1343. OPCODE(84) /* STY ab */
  1344. ZPAGE;
  1345. dPutByte(addr, Y);
  1346. DONE
  1347. OPCODE(85) /* STA ab */
  1348. ZPAGE;
  1349. dPutByte(addr, A);
  1350. DONE
  1351. OPCODE(86) /* STX ab */
  1352. ZPAGE;
  1353. dPutByte(addr, X);
  1354. DONE
  1355. OPCODE(87) /* SAX ab [unofficial - Store result A AND X] */
  1356. ZPAGE;
  1357. data = A & X;
  1358. dPutByte(addr, data);
  1359. DONE
  1360. OPCODE(88) /* DEY */
  1361. Z = N = --Y;
  1362. DONE
  1363. OPCODE(8a) /* TXA */
  1364. Z = N = A = X;
  1365. DONE
  1366. OPCODE(8b) /* ANE #ab [unofficial - A AND X AND (Mem OR $EF) to Acc] (Fox) */
  1367. data = IMMEDIATE;
  1368. N = Z = A & X & data;
  1369. A &= X & (data | 0xef);
  1370. DONE
  1371. OPCODE(8c) /* STY abcd */
  1372. ABSOLUTE;
  1373. PutByte(addr, Y);
  1374. DONE
  1375. OPCODE(8d) /* STA abcd */
  1376. ABSOLUTE;
  1377. PutByte(addr, A);
  1378. DONE
  1379. OPCODE(8e) /* STX abcd */
  1380. ABSOLUTE;
  1381. PutByte(addr, X);
  1382. DONE
  1383. OPCODE(8f) /* SAX abcd [unofficial - Store result A AND X] */
  1384. ABSOLUTE;
  1385. data = A & X;
  1386. PutByte(addr, data);
  1387. DONE
  1388. OPCODE(90) /* BCC */
  1389. BRANCH(!C)
  1390. OPCODE(91) /* STA (ab),y */
  1391. INDIRECT_Y;
  1392. PutByte(addr, A);
  1393. DONE
  1394. OPCODE(93) /* SHA (ab),y [unofficial, UNSTABLE - Store A AND X AND (H+1) ?] (Fox) */
  1395. /* It seems previous memory value is important - also in 9f */
  1396. ZPAGE;
  1397. data = dGetByte((UBYTE) (addr + 1)); /* Get high byte from zpage */
  1398. data = A & X & (data + 1);
  1399. addr = dGetWord(addr) + Y;
  1400. PutByte(addr, data);
  1401. DONE
  1402. OPCODE(94) /* STY ab,x */
  1403. ZPAGE_X;
  1404. dPutByte(addr, Y);
  1405. DONE
  1406. OPCODE(95) /* STA ab,x */
  1407. ZPAGE_X;
  1408. dPutByte(addr, A);
  1409. DONE
  1410. OPCODE(96) /* STX ab,y */
  1411. ZPAGE_Y;
  1412. PutByte(addr, X);
  1413. DONE
  1414. OPCODE(97) /* SAX ab,y [unofficial - Store result A AND X] */
  1415. ZPAGE_Y;
  1416. data = A & X;
  1417. dPutByte(addr, data);
  1418. DONE
  1419. OPCODE(98) /* TYA */
  1420. Z = N = A = Y;
  1421. DONE
  1422. OPCODE(99) /* STA abcd,y */
  1423. ABSOLUTE_Y;
  1424. PutByte(addr, A);
  1425. DONE
  1426. OPCODE(9a) /* TXS */
  1427. S = X;
  1428. DONE
  1429. OPCODE(9b) /* SHS abcd,y [unofficial, UNSTABLE] (Fox) */
  1430. /* Transfer A AND X to S, then store S AND (H+1)] */
  1431. /* S seems to be stable, only memory values vary */
  1432. ABSOLUTE;
  1433. S = A & X;
  1434. data = S & ((addr >> 8) + 1);
  1435. addr += Y;
  1436. PutByte(addr, data);
  1437. DONE
  1438. OPCODE(9c) /* SHY abcd,x [unofficial - Store Y and (H+1)] (Fox) */
  1439. /* Seems to be stable */
  1440. ABSOLUTE;
  1441. /* MPC 05/24/00 */
  1442. data = Y & ((UBYTE) ((addr >> 8) + 1));
  1443. addr += X;
  1444. PutByte(addr, data);
  1445. DONE
  1446. OPCODE(9d) /* STA abcd,x */
  1447. ABSOLUTE_X;
  1448. PutByte(addr, A);
  1449. DONE
  1450. OPCODE(9e) /* SHX abcd,y [unofficial - Store X and (H+1)] (Fox) */
  1451. /* Seems to be stable */
  1452. ABSOLUTE;
  1453. /* MPC 05/24/00 */
  1454. data = X & ((UBYTE) ((addr >> 8) + 1));
  1455. addr += Y;
  1456. PutByte(addr, data);
  1457. DONE
  1458. OPCODE(9f) /* SHA abcd,y [unofficial, UNSTABLE - Store A AND X AND (H+1) ?] (Fox) */
  1459. ABSOLUTE;
  1460. data = A & X & ((addr >> 8) + 1);
  1461. addr += Y;
  1462. PutByte(addr, data);
  1463. DONE
  1464. OPCODE(a0) /* LDY #ab */
  1465. LDY(IMMEDIATE);
  1466. DONE
  1467. OPCODE(a1) /* LDA (ab,x) */
  1468. INDIRECT_X;
  1469. LDA(GetByte(addr));
  1470. DONE
  1471. OPCODE(a2) /* LDX #ab */
  1472. LDX(IMMEDIATE);
  1473. DONE
  1474. OPCODE(a3) /* LAX (ab,x) [unofficial] */
  1475. INDIRECT_X;
  1476. Z = N = X = A = GetByte(addr);
  1477. DONE
  1478. OPCODE(a4) /* LDY ab */
  1479. ZPAGE;
  1480. LDY(dGetByte(addr));
  1481. DONE
  1482. OPCODE(a5) /* LDA ab */
  1483. ZPAGE;
  1484. LDA(dGetByte(addr));
  1485. DONE
  1486. OPCODE(a6) /* LDX ab */
  1487. ZPAGE;
  1488. LDX(dGetByte(addr));
  1489. DONE
  1490. OPCODE(a7) /* LAX ab [unofficial] */
  1491. ZPAGE;
  1492. Z = N = X = A = GetByte(addr);
  1493. DONE
  1494. OPCODE(a8) /* TAY */
  1495. Z = N = Y = A;
  1496. DONE
  1497. OPCODE(a9) /* LDA #ab */
  1498. LDA(IMMEDIATE);
  1499. DONE
  1500. OPCODE(aa) /* TAX */
  1501. Z = N = X = A;
  1502. DONE
  1503. OPCODE(ab) /* ANX #ab [unofficial - AND #ab, then TAX] */
  1504. Z = N = X = A &= IMMEDIATE;
  1505. DONE
  1506. OPCODE(ac) /* LDY abcd */
  1507. ABSOLUTE;
  1508. LDY(GetByte(addr));
  1509. DONE
  1510. OPCODE(ad) /* LDA abcd */
  1511. ABSOLUTE;
  1512. LDA(GetByte(addr));
  1513. DONE
  1514. OPCODE(ae) /* LDX abcd */
  1515. ABSOLUTE;
  1516. LDX(GetByte(addr));
  1517. DONE
  1518. OPCODE(af) /* LAX abcd [unofficial] */
  1519. ABSOLUTE;
  1520. Z = N = X = A = GetByte(addr);
  1521. DONE
  1522. OPCODE(b0) /* BCS */
  1523. BRANCH(C)
  1524. OPCODE(b1) /* LDA (ab),y */
  1525. INDIRECT_Y;
  1526. NCYCLES_Y;
  1527. LDA(GetByte(addr));
  1528. DONE
  1529. OPCODE(b3) /* LAX (ab),y [unofficial] */
  1530. INDIRECT_Y;
  1531. NCYCLES_Y;
  1532. Z = N = X = A = GetByte(addr);
  1533. DONE
  1534. OPCODE(b4) /* LDY ab,x */
  1535. ZPAGE_X;
  1536. LDY(dGetByte(addr));
  1537. DONE
  1538. OPCODE(b5) /* LDA ab,x */
  1539. ZPAGE_X;
  1540. LDA(dGetByte(addr));
  1541. DONE
  1542. OPCODE(b6) /* LDX ab,y */
  1543. ZPAGE_Y;
  1544. LDX(GetByte(addr));
  1545. DONE
  1546. OPCODE(b7) /* LAX ab,y [unofficial] */
  1547. ZPAGE_Y;
  1548. Z = N = X = A = GetByte(addr);
  1549. DONE
  1550. OPCODE(b8) /* CLV */
  1551. #ifndef NO_V_FLAG_VARIABLE
  1552. V = 0;
  1553. #else
  1554. ClrV;
  1555. #endif
  1556. DONE
  1557. OPCODE(b9) /* LDA abcd,y */
  1558. ABSOLUTE_Y;
  1559. NCYCLES_Y;
  1560. LDA(GetByte(addr));
  1561. DONE
  1562. OPCODE(ba) /* TSX */
  1563. Z = N = X = S;
  1564. DONE
  1565. /* AXA [unofficial - original decode by R.Sterba and R.Petruzela 15.1.1998 :-)]
  1566.    AXA - this is our new imaginative name for instruction with opcode hex BB.
  1567.    AXA - Store Mem AND #$FD to Acc and X, then set stackpoint to value (Acc - 4)
  1568.    It's cool! :-)
  1569.    LAS - this is better name for this :) (Fox)
  1570.    It simply ANDs stack pointer with Mem, then transfers result to A and X
  1571.  */
  1572. OPCODE(bb) /* LAS abcd,y [unofficial - AND S with Mem, transfer to A and X (Fox) */
  1573. ABSOLUTE_Y;
  1574. NCYCLES_Y;
  1575. Z = N = A = X = S &= GetByte(addr);
  1576. DONE
  1577. OPCODE(bc) /* LDY abcd,x */
  1578. ABSOLUTE_X;
  1579. NCYCLES_X;
  1580. LDY(GetByte(addr));
  1581. DONE
  1582. OPCODE(bd) /* LDA abcd,x */
  1583. ABSOLUTE_X;
  1584. NCYCLES_X;
  1585. LDA(GetByte(addr));
  1586. DONE
  1587. OPCODE(be) /* LDX abcd,y */
  1588. ABSOLUTE_Y;
  1589. NCYCLES_Y;
  1590. LDX(GetByte(addr));
  1591. DONE
  1592. OPCODE(bf) /* LAX abcd,y [unofficial] */
  1593. ABSOLUTE_Y;
  1594. NCYCLES_Y;
  1595. Z = N = X = A = GetByte(addr);
  1596. DONE
  1597. OPCODE(c0) /* CPY #ab */
  1598. CPY(IMMEDIATE);
  1599. DONE
  1600. OPCODE(c1) /* CMP (ab,x) */
  1601. INDIRECT_X;
  1602. CMP(GetByte(addr));
  1603. DONE
  1604. OPCODE(c3) /* DCM (ab,x) [unofficial - DEC Mem then CMP with Acc] */
  1605. INDIRECT_X;
  1606. dcm:
  1607. RMW_GetByte(data, addr);
  1608. data--;
  1609. PutByte(addr, data);
  1610. CMP(data);
  1611. DONE
  1612. OPCODE(c4) /* CPY ab */
  1613. ZPAGE;
  1614. CPY(dGetByte(addr));
  1615. DONE
  1616. OPCODE(c5) /* CMP ab */
  1617. ZPAGE;
  1618. CMP(dGetByte(addr));
  1619. DONE
  1620. OPCODE(c6) /* DEC ab */
  1621. ZPAGE;
  1622. Z = N = dGetByte(addr) - 1;
  1623. dPutByte(addr, Z);
  1624. DONE
  1625. OPCODE(c7) /* DCM ab [unofficial - DEC Mem then CMP with Acc] */
  1626. ZPAGE;
  1627. dcm_zpage:
  1628. data = dGetByte(addr) - 1;
  1629. dPutByte(addr, data);
  1630. CMP(data);
  1631. DONE
  1632. OPCODE(c8) /* INY */
  1633. Z = N = ++Y;
  1634. DONE
  1635. OPCODE(c9) /* CMP #ab */
  1636. CMP(IMMEDIATE);
  1637. DONE
  1638. OPCODE(ca) /* DEX */
  1639. Z = N = --X;
  1640. DONE
  1641. OPCODE(cb) /* SBX #ab [unofficial - store ((A AND X) - Mem) in X] (Fox) */
  1642. X &= A;
  1643. data = IMMEDIATE;
  1644. C = X >= data;
  1645. /* MPC 05/24/00 */
  1646. Z = N = X -= data;
  1647. DONE
  1648. OPCODE(cc) /* CPY abcd */
  1649. ABSOLUTE;
  1650. CPY(GetByte(addr));
  1651. DONE
  1652. OPCODE(cd) /* CMP abcd */
  1653. ABSOLUTE;
  1654. CMP(GetByte(addr));
  1655. DONE
  1656. OPCODE(ce) /* DEC abcd */
  1657. ABSOLUTE;
  1658. RMW_GetByte(Z, addr);
  1659. N = --Z;
  1660. PutByte(addr, Z);
  1661. DONE
  1662. OPCODE(cf) /* DCM abcd [unofficial - DEC Mem then CMP with Acc] */
  1663. ABSOLUTE;
  1664. goto dcm;
  1665. OPCODE(d0) /* BNE */
  1666. BRANCH(Z)
  1667. OPCODE(d1) /* CMP (ab),y */
  1668. INDIRECT_Y;
  1669. NCYCLES_Y;
  1670. CMP(GetByte(addr));
  1671. DONE
  1672. OPCODE(d3) /* DCM (ab),y [unofficial - DEC Mem then CMP with Acc] */
  1673. INDIRECT_Y;
  1674. goto dcm;
  1675. OPCODE(d5) /* CMP ab,x */
  1676. ZPAGE_X;
  1677. CMP(dGetByte(addr));
  1678. Z = N = A - data;
  1679. C = (A >= data);
  1680. DONE
  1681. OPCODE(d6) /* DEC ab,x */
  1682. ZPAGE_X;
  1683. Z = N = dGetByte(addr) - 1;
  1684. dPutByte(addr, Z);
  1685. DONE
  1686. OPCODE(d7) /* DCM ab,x [unofficial - DEC Mem then CMP with Acc] */
  1687. ZPAGE_X;
  1688. goto dcm_zpage;
  1689. OPCODE(d8) /* CLD */
  1690. ClrD;
  1691. DONE
  1692. OPCODE(d9) /* CMP abcd,y */
  1693. ABSOLUTE_Y;
  1694. NCYCLES_Y;
  1695. CMP(GetByte(addr));
  1696. DONE
  1697. OPCODE(db) /* DCM abcd,y [unofficial - DEC Mem then CMP with Acc] */
  1698. ABSOLUTE_Y;
  1699. goto dcm;
  1700. OPCODE(dd) /* CMP abcd,x */
  1701. ABSOLUTE_X;
  1702. NCYCLES_X;
  1703. CMP(GetByte(addr));
  1704. DONE
  1705. OPCODE(de) /* DEC abcd,x */
  1706. ABSOLUTE_X;
  1707. RMW_GetByte(Z, addr);
  1708. N = --Z;
  1709. PutByte(addr, Z);
  1710. DONE
  1711. OPCODE(df) /* DCM abcd,x [unofficial - DEC Mem then CMP with Acc] */
  1712. ABSOLUTE_X;
  1713. goto dcm;
  1714. OPCODE(e0) /* CPX #ab */
  1715. CPX(IMMEDIATE);
  1716. DONE
  1717. OPCODE(e1) /* SBC (ab,x) */
  1718. INDIRECT_X;
  1719. data = GetByte(addr);
  1720. goto sbc;
  1721. OPCODE(e3) /* INS (ab,x) [unofficial - INC Mem then SBC with Acc] */
  1722. INDIRECT_X;
  1723. ins:
  1724. RMW_GetByte(data, addr);
  1725. ++data;
  1726. PutByte(addr, data);
  1727. goto sbc;
  1728. OPCODE(e4) /* CPX ab */
  1729. ZPAGE;
  1730. CPX(dGetByte(addr));
  1731. DONE
  1732. OPCODE(e5) /* SBC ab */
  1733. ZPAGE;
  1734. data = dGetByte(addr);
  1735. goto sbc;
  1736. OPCODE(e6) /* INC ab */
  1737. ZPAGE;
  1738. Z = N = dGetByte(addr) + 1;
  1739. dPutByte(addr, Z);
  1740. DONE
  1741. OPCODE(e7) /* INS ab [unofficial - INC Mem then SBC with Acc] */
  1742. ZPAGE;
  1743. ins_zpage:
  1744. data = dGetByte(addr) + 1;
  1745. dPutByte(addr, data);
  1746. goto sbc;
  1747. OPCODE(e8) /* INX */
  1748. Z = N = ++X;
  1749. DONE
  1750. OPCODE_ALIAS(e9) /* SBC #ab */
  1751. OPCODE(eb) /* SBC #ab [unofficial] */
  1752. data = IMMEDIATE;
  1753. goto sbc;
  1754. OPCODE_ALIAS(ea) /* NOP */
  1755. OPCODE_ALIAS(1a) /* NOP [unofficial] */
  1756. OPCODE_ALIAS(3a)
  1757. OPCODE_ALIAS(5a)
  1758. OPCODE_ALIAS(7a)
  1759. OPCODE_ALIAS(da)
  1760. OPCODE(fa)
  1761. DONE
  1762. OPCODE(ec) /* CPX abcd */
  1763. ABSOLUTE;
  1764. CPX(GetByte(addr));
  1765. DONE
  1766. OPCODE(ed) /* SBC abcd */
  1767. ABSOLUTE;
  1768. data = GetByte(addr);
  1769. goto sbc;
  1770. OPCODE(ee) /* INC abcd */
  1771. ABSOLUTE;
  1772. RMW_GetByte(Z, addr);
  1773. N = ++Z;
  1774. PutByte(addr, Z);
  1775. DONE
  1776. OPCODE(ef) /* INS abcd [unofficial - INC Mem then SBC with Acc] */
  1777. ABSOLUTE;
  1778. goto ins;
  1779. OPCODE(f0) /* BEQ */
  1780. BRANCH(!Z)
  1781. OPCODE(f1) /* SBC (ab),y */
  1782. INDIRECT_Y;
  1783. NCYCLES_Y;
  1784. data = GetByte(addr);
  1785. goto sbc;
  1786. OPCODE(f3) /* INS (ab),y [unofficial - INC Mem then SBC with Acc] */
  1787. INDIRECT_Y;
  1788. goto ins;
  1789. OPCODE(f5) /* SBC ab,x */
  1790. ZPAGE_X;
  1791. data = dGetByte(addr);
  1792. goto sbc;
  1793. OPCODE(f6) /* INC ab,x */
  1794. ZPAGE_X;
  1795. Z = N = dGetByte(addr) + 1;
  1796. dPutByte(addr, Z);
  1797. DONE
  1798. OPCODE(f7) /* INS ab,x [unofficial - INC Mem then SBC with Acc] */
  1799. ZPAGE_X;
  1800. goto ins_zpage;
  1801. OPCODE(f8) /* SED */
  1802. SetD;
  1803. DONE
  1804. OPCODE(f9) /* SBC abcd,y */
  1805. ABSOLUTE_Y;
  1806. NCYCLES_Y;
  1807. data = GetByte(addr);
  1808. goto sbc;
  1809. OPCODE(fb) /* INS abcd,y [unofficial - INC Mem then SBC with Acc] */
  1810. ABSOLUTE_Y;
  1811. goto ins;
  1812. OPCODE(fd) /* SBC abcd,x */
  1813. ABSOLUTE_X;
  1814. NCYCLES_X;
  1815. data = GetByte(addr);
  1816. goto sbc;
  1817. OPCODE(fe) /* INC abcd,x */
  1818. ABSOLUTE_X;
  1819. RMW_GetByte(Z, addr);
  1820. N = ++Z;
  1821. PutByte(addr, Z);
  1822. DONE
  1823. OPCODE(ff) /* INS abcd,x [unofficial - INC Mem then SBC with Acc] */
  1824. ABSOLUTE_X;
  1825. goto ins;
  1826. #ifdef ASAP
  1827. OPCODE_ALIAS(d2)
  1828. OPCODE_ALIAS(f2)
  1829. #else
  1830. OPCODE(d2) /* ESCRTS #ab (CIM) - on Atari is here instruction CIM [unofficial] !RS! */
  1831. data = IMMEDIATE;
  1832. UPDATE_GLOBAL_REGS;
  1833. CPU_GetStatus();
  1834. Atari800_RunEsc(data);
  1835. CPU_PutStatus();
  1836. UPDATE_LOCAL_REGS;
  1837. data = PL;
  1838. SET_PC((PL << 8) + data + 1);
  1839. #ifdef MONITOR_BREAK
  1840. if (break_ret && --ret_nesting <= 0)
  1841. break_step = TRUE;
  1842. #endif
  1843. DONE
  1844. OPCODE(f2) /* ESC #ab (CIM) - on Atari is here instruction CIM [unofficial] !RS! */
  1845. /* OPCODE(ff: ESC #ab - opcode FF is now used for INS [unofficial] instruction !RS! */
  1846. data = IMMEDIATE;
  1847. UPDATE_GLOBAL_REGS;
  1848. CPU_GetStatus();
  1849. Atari800_RunEsc(data);
  1850. CPU_PutStatus();
  1851. UPDATE_LOCAL_REGS;
  1852. DONE
  1853. #endif /* ASAP */
  1854. OPCODE_ALIAS(02) /* CIM [unofficial - crash intermediate] */
  1855. OPCODE_ALIAS(12)
  1856. OPCODE_ALIAS(22)
  1857. OPCODE_ALIAS(32)
  1858. OPCODE_ALIAS(42)
  1859. OPCODE_ALIAS(52)
  1860. OPCODE_ALIAS(62)
  1861. OPCODE_ALIAS(72)
  1862. OPCODE_ALIAS(92)
  1863. OPCODE(b2)
  1864. #ifdef ASAP
  1865. ASAP_CIM();
  1866. DONE
  1867. #else
  1868. /* OPCODE(d2) Used for ESCRTS #ab (CIM) */
  1869. /* OPCODE(f2) Used for ESC #ab (CIM) */
  1870. PC--;
  1871. UPDATE_GLOBAL_REGS;
  1872. CPU_GetStatus();
  1873. #ifdef CRASH_MENU
  1874. crash_address = GET_PC();
  1875. crash_afterCIM = GET_PC() + 1;
  1876. crash_code = insn;
  1877. ui();
  1878. #else
  1879. cim_encountered = TRUE;
  1880. ENTER_MONITOR;
  1881. #endif /* CRASH_MENU */
  1882. CPU_PutStatus();
  1883. UPDATE_LOCAL_REGS;
  1884. DONE
  1885. #endif /* ASAP */
  1886. /* ---------------------------------------------- */
  1887. /* ADC and SBC routines */
  1888. adc:
  1889. if (!(regP & D_FLAG)) {
  1890. /* Binary mode */
  1891. unsigned int tmp;
  1892. tmp = A + data + C;
  1893. C = tmp > 0xff;
  1894. /* C = tmp >> 8; */
  1895. #ifndef NO_V_FLAG_VARIABLE
  1896. V = !((A ^ data) & 0x80) && ((data ^ tmp) & 0x80);
  1897. #else
  1898. ClrV;
  1899. if (!((A ^ data) & 0x80) && ((data ^ tmp) & 0x80))
  1900. SetV;
  1901. #endif
  1902. Z = N = A = (UBYTE) tmp;
  1903.     }
  1904. else {
  1905. /* Decimal mode */
  1906. unsigned int tmp;
  1907. tmp = (A & 0x0f) + (data & 0x0f) + C;
  1908. if (tmp >= 10)
  1909. tmp = (tmp - 10) | 0x10;
  1910. tmp += (A & 0xf0) + (data & 0xf0);
  1911. Z = A + data + C;
  1912. N = (UBYTE) tmp;
  1913. #ifndef NO_V_FLAG_VARIABLE
  1914. V = !((A ^ data) & 0x80) && ((data ^ tmp) & 0x80);
  1915. #else
  1916. ClrV;
  1917. if (!((A ^ data) & 0x80) && ((data ^ tmp) & 0x80))
  1918. SetV;
  1919. #endif
  1920. if (tmp > 0x9f)
  1921. tmp += 0x60;
  1922. C = tmp > 0xff;
  1923. A = (UBYTE) tmp;
  1924. }
  1925. DONE
  1926. sbc:
  1927. if (!(regP & D_FLAG)) {
  1928. /* Binary mode */
  1929. unsigned int tmp;
  1930. /* tmp = A - data - !C; */
  1931. tmp = A - data - 1 + C;
  1932. C = tmp < 0x100;
  1933. #ifndef NO_V_FLAG_VARIABLE
  1934. V = ((A ^ tmp) & 0x80) && ((A ^ data) & 0x80);
  1935. #else
  1936. ClrV;
  1937. if (((A ^ tmp) & 0x80) && ((A ^ data) & 0x80))
  1938. SetV;
  1939. #endif
  1940. Z = N = A = (UBYTE) tmp;
  1941. }
  1942. else {
  1943. /* Decimal mode */
  1944. unsigned int al, ah, tmp;
  1945. /* tmp = A - data - !C; */
  1946. tmp = A - data - 1 + C;
  1947. /* al = (A & 0x0f) - (data & 0x0f) - !C; */
  1948. al = (A & 0x0f) - (data & 0x0f) - 1 + C; /* Calculate lower nybble */
  1949. ah = (A >> 4) - (data >> 4); /* Calculate upper nybble */
  1950. if (al & 0x10) {
  1951. al -= 6; /* BCD fixup for lower nybble */
  1952. ah--;
  1953. }
  1954. if (ah & 0x10)
  1955. ah -= 6; /* BCD fixup for upper nybble */
  1956. C = tmp < 0x100; /* Set flags */
  1957. #ifndef NO_V_FLAG_VARIABLE
  1958. V = ((A ^ tmp) & 0x80) && ((A ^ data) & 0x80);
  1959. #else
  1960. ClrV;
  1961. if (((A ^ tmp) & 0x80) && ((A ^ data) & 0x80))
  1962. SetV;
  1963. #endif
  1964. Z = N = (UBYTE) tmp;
  1965. A = (ah << 4) + (al & 0x0f); /* Compose result */
  1966. }
  1967. DONE
  1968. #ifdef NO_GOTO
  1969. }
  1970. #else
  1971. next:
  1972. #endif
  1973. #ifdef MONITOR_BREAK
  1974. if (break_step) {
  1975. DO_BREAK;
  1976. }
  1977. #endif
  1978. /* This "continue" does nothing here.
  1979.    But it is necessary because, if we're not using NO_GOTO nor MONITOR_BREAK,
  1980.    gcc can complain: "error: label at end of compound statement". */
  1981. continue;
  1982. }
  1983. UPDATE_GLOBAL_REGS;
  1984. }
  1985. void CPU_Initialise(void)
  1986. {
  1987. }
  1988. #endif /* FALCON_CPUASM */
  1989. void CPU_Reset(void)
  1990. {
  1991. #ifdef MONITOR_PROFILE
  1992. memset(instruction_count, 0, sizeof(instruction_count));
  1993. #endif
  1994. IRQ = 0;
  1995. regP = 0x34; /* The unused bit is always 1, I flag set! */
  1996. CPU_PutStatus(); /* Make sure flags are all updated */
  1997. regS = 0xff;
  1998. regPC = dGetWordAligned(0xfffc);
  1999. }
  2000. #if !defined(BASIC) && !defined(ASAP)
  2001. void CpuStateSave(UBYTE SaveVerbose)
  2002. {
  2003. SaveUBYTE(&regA, 1);
  2004. CPU_GetStatus(); /* Make sure flags are all updated */
  2005. SaveUBYTE(&regP, 1);
  2006. SaveUBYTE(&regS, 1);
  2007. SaveUBYTE(&regX, 1);
  2008. SaveUBYTE(&regY, 1);
  2009. SaveUBYTE(&IRQ, 1);
  2010. MemStateSave(SaveVerbose);
  2011. SaveUWORD(&regPC, 1);
  2012. }
  2013. void CpuStateRead(UBYTE SaveVerbose)
  2014. {
  2015. ReadUBYTE(&regA, 1);
  2016. ReadUBYTE(&regP, 1);
  2017. CPU_PutStatus(); /* Make sure flags are all updated */
  2018. ReadUBYTE(&regS, 1);
  2019. ReadUBYTE(&regX, 1);
  2020. ReadUBYTE(&regY, 1);
  2021. ReadUBYTE(&IRQ, 1);
  2022. MemStateRead( SaveVerbose );
  2023. ReadUWORD(&regPC, 1);
  2024. }
  2025. #endif