corecpu.c 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850
  1. /**
  2. * CoreCPU - The Quick6502 Project
  3. * corecpu.c
  4. *
  5. * Created by Manoel Trapier on 24/02/08
  6. * Copyright 2008 986 Corp. All rights reserved.
  7. *
  8. * $LastChangedDate$
  9. * $Author$
  10. * $HeadURL$
  11. * $Revision$
  12. *
  13. */
  14. /* Depending on the OS, one of these provide the malloc function */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <os_dependent.h>
  19. /*******************************************************************************
  20. /!\ WARNING this debug tool slow down a lot the emulator! /!\
  21. /!\ Use it only if you really need it ! /!\
  22. *******************************************************************************/
  23. //#define TRACE_INSTRUCTIONS
  24. #ifdef TRACE_INSTRUCTIONS
  25. #define TRACEi(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
  26. #define TRACEiE(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
  27. #else
  28. #define TRACEi(trace) { }
  29. //#define TRACEiE(trace) { }
  30. #define TRACEiE(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
  31. #endif
  32. #define _INTERNAL_QUICK6502_CORECPU_
  33. #include "corecpu.h"
  34. /*** Instructions useful macros ***/
  35. #define INSTRUCTION(s) static inline void I_##s (quick6502_cpu *cpu)
  36. #define NZ_FLAG_UPDATE(value) cpu->reg_P = (cpu->reg_P & ~(Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  37. (value & 0x80) | ((value)?0:Q6502_Z_FLAG)
  38. #define CROSS_CYCLE_UPDATE(value) if ((value) & 0x0F00) cpu->page_crossed = 1
  39. #define MEMORY_READ_ZP() cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))
  40. #define MEMORY_READ_IX() cpu->memory_read( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X ) & 0xFF) |\
  41. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X + 1) << 8) )
  42. #define MEMORY_READ_IY() cpu->memory_read( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  43. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + 1) << 8) ) + cpu->reg_Y )
  44. #define MEMORY_READ_ZX() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X) )
  45. #define MEMORY_READ_ZY() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y) )
  46. #define MEMORY_READ_AB() cpu->memory_read( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
  47. (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ))
  48. #define MEMORY_READ_AX() cpu->memory_read( ((op1 ) |\
  49. (op2 << 8) ) + cpu->reg_X)
  50. #define MEMORY_READ_AY() cpu->memory_read( ((op1 ) |\
  51. (op2 << 8) ) + cpu->reg_Y )
  52. #define MEMORY_WRITE_ZP(val) cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), val)
  53. #define MEMORY_WRITE_IX(val) cpu->memory_write( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X ) & 0xFF) |\
  54. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X + 1) << 8) , val)
  55. #define MEMORY_WRITE_IY(val) cpu->memory_write( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  56. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + 1) << 8) ) + cpu->reg_Y , val)
  57. #define MEMORY_WRITE_ZX(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X), val)
  58. #define MEMORY_WRITE_ZY(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y), val)
  59. #define MEMORY_WRITE_AB(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
  60. (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ), val)
  61. #define MEMORY_WRITE_AX(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
  62. (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ) + cpu->reg_X, val)
  63. #define MEMORY_WRITE_AY(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
  64. (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ) + cpu->reg_Y, val)
  65. #define PUSH_S(value) cpu->memory_stack_write(0x100 | (cpu->reg_S--), value)
  66. #define POP_S() (cpu->memory_stack_read (0x100 | (++cpu->reg_S) ))
  67. #ifdef NO_DECIMAL
  68. #define ADC_OPERATION(read) do {\
  69. unsigned short tmp = 0; unsigned char v = read; \
  70. tmp = cpu->reg_A + v + (cpu->reg_P & Q6502_C_FLAG); \
  71. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \
  72. (tmp & 0x80) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
  73. ((tmp & 0xFF00)?Q6502_C_FLAG:0) | \
  74. ( ( ~(cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \
  75. cpu->reg_A = tmp & 0xFF; \
  76. } while(0)
  77. #define SBC_OPERATION(read) do {\
  78. unsigned short tmp = 0; unsigned char v = read; \
  79. tmp = cpu->reg_A - v - (~cpu->reg_P & Q6502_C_FLAG); \
  80. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \
  81. (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
  82. ((tmp & 0xFF00)?0:Q6502_C_FLAG) | \
  83. ( ( (cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \
  84. cpu->reg_A = tmp & 0xFF; \
  85. } while(0)
  86. #else
  87. #error Quick6502 doesn't actually support DECIMAL mode
  88. #endif
  89. #define AND_OPERATION(read) cpu->reg_A &= read; NZ_FLAG_UPDATE(cpu->reg_A)
  90. /* CMP is like SBC but without storing the result value */
  91. #define CMP_OPERATION(register, read) do { \
  92. unsigned short tmp = 0; \
  93. tmp = register - read; \
  94. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  95. (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
  96. ((tmp & 0xFF00)?0:Q6502_C_FLAG); \
  97. } while(0)
  98. #define EOR_OPERATION(read) cpu->reg_A ^= read; NZ_FLAG_UPDATE(cpu->reg_A)
  99. #define ORA_OPERATION(read) cpu->reg_A |= read; NZ_FLAG_UPDATE(cpu->reg_A)
  100. #define BIT_OPERATION(read) do { \
  101. byte tmp = read; \
  102. cpu->reg_P = (cpu->reg_P & ~(Q6502_V_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  103. (tmp & Q6502_N_FLAG) | (tmp & Q6502_V_FLAG) | \
  104. ((tmp & cpu->reg_A)?0:Q6502_Z_FLAG); \
  105. } while(0)
  106. #define ASL_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  107. ((val&0x40)?Q6502_N_FLAG:0) | \
  108. ((val&0x80)?Q6502_C_FLAG:0) | \
  109. ((val&0x7F)?0:Q6502_Z_FLAG); \
  110. val = val << 1
  111. #define LSR_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  112. (val & Q6502_C_FLAG) | \
  113. ((val&0xFE)?0:Q6502_Z_FLAG); \
  114. val = val >> 1
  115. #define ROR_OPERATION(val) do {\
  116. unsigned short tmp = val | (cpu->reg_P & Q6502_C_FLAG) << 8; \
  117. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  118. ( tmp&Q6502_C_FLAG) | /* Set the C flag */ \
  119. ((tmp&0x100) >> 1) | /* Set the N flag */ \
  120. ((tmp&0x1FE)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \
  121. val = (tmp>>1) & 0xFF; \
  122. } while(0)
  123. #define ROL_OPERATION(val) do {\
  124. unsigned short tmp = (val << 1) | (cpu->reg_P & Q6502_C_FLAG); \
  125. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  126. ((tmp&0x100)?Q6502_C_FLAG:0) | /* Set the C flag */ \
  127. ((tmp&0x80)) | /* Set the N flag */ \
  128. ((tmp&0xFF)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \
  129. val = tmp & 0xFF; \
  130. } while(0)
  131. /** Function used for execution of instruction */
  132. static inline int quick6502_exec_one(quick6502_cpu *cpu);
  133. /**
  134. * Initialise the CPU
  135. *
  136. * Inputs:
  137. *
  138. * - CPU Init structure:
  139. * - Memory Read function pointer
  140. * - Memory Write function pointer
  141. * - Fast memory read function pointer (for opcodes read)
  142. * - Fast page 0 function Read/Write
  143. * - Fast page 1 function Read/Write
  144. *
  145. * Output:
  146. *
  147. * (void *): An opaque pointer to the internal structure of the CPU.
  148. * NULL if an error occured !
  149. */
  150. quick6502_cpu *quick6502_init(quick6502_cpuconfig *config)
  151. {
  152. quick6502_cpu *cpu;
  153. /* Alloc structure */
  154. cpu = (quick6502_cpu *) malloc (sizeof (quick6502_cpu));
  155. if (!cpu)
  156. return NULL;
  157. /* Initialise other variables */
  158. cpu->running = 0; /* CPU is currently NOT running */
  159. cpu->cycle_done = 0;
  160. cpu->int_pending = 0;
  161. cpu->page_crossed = 0;
  162. /* Initialise registers */
  163. cpu->reg_A = 0;
  164. cpu->reg_X = 0;
  165. cpu->reg_Y = 0;
  166. cpu->reg_S = 0xFF;
  167. cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG;
  168. if (config->memory_read != NULL)
  169. cpu->memory_read = config->memory_read;
  170. else
  171. goto init_error;
  172. if (config->memory_write != NULL)
  173. cpu->memory_write = config->memory_write;
  174. else
  175. goto init_error;
  176. if (config->memory_opcode_read != NULL)
  177. cpu->memory_opcode_read = config->memory_opcode_read;
  178. else
  179. cpu->memory_opcode_read = config->memory_read;
  180. if (config->memory_page0_read != NULL)
  181. cpu->memory_page0_read = config->memory_page0_read;
  182. else
  183. cpu->memory_page0_read = config->memory_read;
  184. if (config->memory_page0_write != NULL)
  185. cpu->memory_page0_write = config->memory_page0_write;
  186. else
  187. cpu->memory_page0_write = config->memory_write;
  188. if (config->memory_stack_read != NULL)
  189. cpu->memory_stack_read = config->memory_stack_read;
  190. else
  191. cpu->memory_stack_read = config->memory_read;
  192. if (config->memory_stack_write != NULL)
  193. cpu->memory_stack_write = config->memory_stack_write;
  194. else
  195. cpu->memory_stack_write = config->memory_write;
  196. return cpu;
  197. init_error:
  198. if (cpu)
  199. free (cpu);
  200. return NULL;
  201. }
  202. /** Reset the CPU (must be done after init) */
  203. void quick6502_reset(quick6502_cpu *cpu)
  204. {
  205. /* Initialise registers */
  206. /*cpu->reg_A = 0;
  207. cpu->reg_X = 0;
  208. cpu->reg_Y = 0;
  209. cpu->reg_S = 0xFF;*/
  210. //cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG | 0x20 | Q6502_B_FLAG;
  211. /* Set the PC to the RESET vector */
  212. cpu->reg_PC = ( cpu->memory_read(Q6502_RESET_HIGH) << 8)
  213. | cpu->memory_read(Q6502_RESET_LOW);
  214. cpu->exit_loop = 0;
  215. }
  216. /**
  217. * Run cpu for at least X cycles
  218. *
  219. * Output:
  220. *
  221. * int: (Number of cycle really done) - (Number of cycle asked)
  222. */
  223. int quick6502_run(quick6502_cpu *cpu, int cycles)
  224. {
  225. cpu->running = !0;
  226. while(cpu->cycle_done < cycles)
  227. {
  228. quick6502_exec_one(cpu);
  229. }
  230. cpu->cycle_done -= cycles;
  231. cpu->running = 0;
  232. return cycles + cpu->cycle_done;
  233. }
  234. /** Loop CPU until explicit quit */
  235. void quick6502_loop(quick6502_cpu *cpu)
  236. {
  237. cpu->running = !0;
  238. while(cpu->exit_loop)
  239. {
  240. quick6502_exec_one(cpu);
  241. }
  242. cpu->running = 0;
  243. }
  244. /** Run CPU for one instruction */
  245. void quick6502_exec(quick6502_cpu *cpu)
  246. {
  247. cpu->running = !0;
  248. quick6502_exec_one(cpu);
  249. cpu->running = 0;
  250. }
  251. /** Send IRQ/NMI/EXITLOOP signal to CPU */
  252. void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal)
  253. {
  254. switch(signal)
  255. {
  256. default:
  257. break;
  258. case Q6502_IRQ_SIGNAL:
  259. if (! (cpu->reg_P & Q6502_I_FLAG) )
  260. {
  261. TRACEi(("IRQ Triggered !"));
  262. PUSH_S((cpu->reg_PC >> 8) & 0xFF );
  263. PUSH_S((cpu->reg_PC ) & 0xFF );
  264. PUSH_S( cpu->reg_P & ~Q6502_B_FLAG );
  265. cpu->reg_P = cpu->reg_P | Q6502_I_FLAG;
  266. cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8);
  267. cpu->cycle_done += 7;
  268. }
  269. else
  270. cpu->int_pending = 1;
  271. break;
  272. case Q6502_NMI_SIGNAL:
  273. TRACEi(("NMI Triggered !"));
  274. PUSH_S((cpu->reg_PC >> 8) & 0xFF );
  275. PUSH_S((cpu->reg_PC ) & 0xFF );
  276. PUSH_S( cpu->reg_P );
  277. cpu->reg_P = cpu->reg_P | Q6502_I_FLAG & ~Q6502_B_FLAG;
  278. cpu->reg_PC = (cpu->memory_read(Q6502_NMI_LOW)) | (cpu->memory_read(Q6502_NMI_HIGH)<<8);
  279. cpu->cycle_done += 7;
  280. break;
  281. case Q6502_STOPLOOP_SIGNAL:
  282. cpu->exit_loop = 1;
  283. break;
  284. }
  285. }
  286. /** Dump CPU State to the given file */
  287. void quick6502_dump(quick6502_cpu *cpu, FILE * fp)
  288. {
  289. short i;
  290. char instr[20];
  291. /* Display registers */
  292. fprintf(fp,
  293. "Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]\n",
  294. cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
  295. cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
  296. cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
  297. '.', /* No real flag here */
  298. cpu->reg_P&Q6502_B_FLAG ? 'B':'.',
  299. cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
  300. cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
  301. cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
  302. cpu->reg_P&Q6502_C_FLAG ? 'C':'.'
  303. );
  304. /* Display stack */
  305. fprintf(fp, "Quick6502: Stack: [ ");
  306. for (i = cpu->reg_S+1; i < 0x100; i++)
  307. {
  308. fprintf(fp, "$%02X ", cpu->memory_opcode_read(0x100 | i));
  309. }
  310. fprintf(fp, "] Run:%c Cycle:%ld\n", cpu->running?'Y':'N', cpu->cycle_done);
  311. quick6502_getinstruction(cpu, cpu->reg_PC, instr);
  312. fprintf(fp, "Quick6502: Instruction at PC: %s\n", instr);
  313. }
  314. /** Get current instruction name at specified address and put it into buffer */
  315. void quick6502_getinstruction(quick6502_cpu *cpu, unsigned short addr, char *buffer)
  316. {
  317. buffer[0] = 0;
  318. }
  319. /**
  320. * Free the CPU
  321. *
  322. * This function will free the CPU only if it's not currently used, it will
  323. * return !0 if everything goes well and 0 if the free is impossible
  324. */
  325. int quick6502_free(quick6502_cpu *cpu)
  326. {
  327. return 0;
  328. }
  329. /*******************************************************************************
  330. *** Here start real CPU logic ***
  331. *******************************************************************************/
  332. static byte CycleTable[256] =
  333. {
  334. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  335. /* 00 */ 7, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
  336. /* 10 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  337. /* 20 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6,
  338. /* 30 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  339. /* 40 */ 6, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6,
  340. /* 50 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  341. /* 60 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6,
  342. /* 70 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  343. /* 80 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
  344. /* 90 */ 2, 6, 0, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5,
  345. /* A0 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
  346. /* B0 */ 2, 5, 0, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4,
  347. /* C0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
  348. /* D0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  349. /* E0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
  350. /* F0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7
  351. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  352. };
  353. typedef void (*InstructionFunction)(quick6502_cpu *cpu);
  354. /*******************************************************************************
  355. * Instruction implementations
  356. *******************************************************************************/
  357. /**** Other instructions ****/
  358. INSTRUCTION(ILLEG)
  359. {
  360. TRACEiE(("Illegal instruction $%02X", cpu->memory_opcode_read(cpu->reg_PC-1)));
  361. //exit(-1);
  362. }
  363. /** 58 : CLI - CLear Interrupt **/
  364. INSTRUCTION(CLIiM)
  365. {
  366. TRACEi(("CLC"));
  367. cpu->reg_P &= ~Q6502_I_FLAG;
  368. }
  369. /** 78 : SEI - SEt Interrupt **/
  370. INSTRUCTION(SEIiM)
  371. {
  372. TRACEi(("SEI"));
  373. cpu->reg_P |= Q6502_I_FLAG;
  374. }
  375. /** 18 : CLC - CLear Carry **/
  376. INSTRUCTION(CLCiM)
  377. {
  378. TRACEi(("CLC"));
  379. cpu->reg_P &= ~Q6502_C_FLAG;
  380. }
  381. /** 38 : SEC - SEt Carry **/
  382. INSTRUCTION(SECiM)
  383. {
  384. TRACEi(("SEC"));
  385. cpu->reg_P |= Q6502_C_FLAG;
  386. }
  387. /** D8 : CLD - CLear Decimal **/
  388. INSTRUCTION(CLDiM)
  389. {
  390. TRACEi(("CLD"));
  391. cpu->reg_P &= ~Q6502_D_FLAG;
  392. }
  393. /** F8 : SED - SEt Decimal **/
  394. INSTRUCTION(SEDiM)
  395. {
  396. TRACEi(("SED"));
  397. cpu->reg_P |= Q6502_D_FLAG;
  398. }
  399. /** B8 : CLV - CLear oVerflo **/
  400. INSTRUCTION(CLViM)
  401. {
  402. TRACEi(("CLV"));
  403. cpu->reg_P &= ~Q6502_V_FLAG;
  404. }
  405. /** EA : NOP - NO oPeration **/
  406. INSTRUCTION(NOPiM)
  407. {
  408. TRACEi(("NOP"));
  409. }
  410. /**** Load/Store functions ****/
  411. /** A9 : LDA #$xx - LoaD an immediate value into A */
  412. INSTRUCTION(LDAiM)
  413. {
  414. TRACEi(("LDA #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  415. cpu->reg_A = cpu->memory_opcode_read(cpu->reg_PC++);
  416. NZ_FLAG_UPDATE(cpu->reg_A);
  417. }
  418. /** A2 : LDX #$xx - LoaD an immediate value into X */
  419. INSTRUCTION(LDXiM)
  420. {
  421. TRACEi(("LDX #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  422. cpu->reg_X = cpu->memory_opcode_read(cpu->reg_PC++);
  423. NZ_FLAG_UPDATE(cpu->reg_X);
  424. }
  425. /** A0 : LDY #$xx - LoaD an immediate value into Y */
  426. INSTRUCTION(LDYiM)
  427. {
  428. TRACEi(("LDY #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  429. cpu->reg_Y = cpu->memory_opcode_read(cpu->reg_PC++);
  430. NZ_FLAG_UPDATE(cpu->reg_Y);
  431. }
  432. /** A5: LDA $xx - LoaD to A from zero page **/
  433. INSTRUCTION(LDAzP)
  434. {
  435. TRACEi(("LDA $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  436. cpu->reg_A = MEMORY_READ_ZP();
  437. NZ_FLAG_UPDATE(cpu->reg_A);
  438. }
  439. /** B5: LDA $xx,X - LoaD to A **/
  440. INSTRUCTION(LDAzX)
  441. {
  442. TRACEi(("LDA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  443. cpu->reg_A = MEMORY_READ_ZX();
  444. NZ_FLAG_UPDATE(cpu->reg_A);
  445. }
  446. /** A1: LDA ($xx,X) - LoaD to A **/
  447. INSTRUCTION(LDAiX)
  448. {
  449. TRACEi(("LDA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC)));
  450. cpu->reg_A = MEMORY_READ_IX();
  451. NZ_FLAG_UPDATE(cpu->reg_A);
  452. }
  453. /** B1: LDA ($xx),Y - LoaD to A **/
  454. INSTRUCTION(LDAiY)
  455. {
  456. TRACEi(("LDA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC)));
  457. cpu->reg_A = MEMORY_READ_IY();
  458. NZ_FLAG_UPDATE(cpu->reg_A);
  459. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  460. }
  461. /** AD: LDA $xxxx - LoaD to A **/
  462. INSTRUCTION(LDAaB)
  463. {
  464. TRACEi(("LDA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  465. cpu->reg_A = MEMORY_READ_AB();
  466. NZ_FLAG_UPDATE(cpu->reg_A);
  467. }
  468. /** DD: LDA $xxxx,X - LoaD to A **/
  469. INSTRUCTION(LDAaX)
  470. {
  471. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  472. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  473. TRACEi(("LDA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  474. cpu->reg_A = MEMORY_READ_AX();
  475. NZ_FLAG_UPDATE(cpu->reg_A);
  476. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  477. }
  478. /** D9: LDA $xxxx,Y - LoaD to A **/
  479. INSTRUCTION(LDAaY)
  480. {
  481. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  482. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  483. cpu->reg_A = MEMORY_READ_AY();
  484. NZ_FLAG_UPDATE(cpu->reg_A);
  485. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  486. }
  487. /** 85: STA $xx - STore A to zero page **/
  488. INSTRUCTION(STAzP)
  489. {
  490. TRACEi(("STA $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  491. cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_A);
  492. }
  493. /** 95: STA $xx,X - STore A **/
  494. INSTRUCTION(STAzX)
  495. {
  496. TRACEi(("STA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  497. MEMORY_WRITE_ZX(cpu->reg_A);
  498. }
  499. /** 81: STA ($xx,X) - STore A **/
  500. INSTRUCTION(STAiX)
  501. {
  502. TRACEi(("STA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC)));
  503. MEMORY_WRITE_IX(cpu->reg_A);
  504. }
  505. /** 91: STA ($xx),Y - STore A **/
  506. INSTRUCTION(STAiY)
  507. {
  508. TRACEi(("STA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC)));
  509. MEMORY_WRITE_IY(cpu->reg_A);
  510. }
  511. /** 8D: STA $xxxx - STore A **/
  512. INSTRUCTION(STAaB)
  513. {
  514. TRACEi(("STA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  515. MEMORY_WRITE_AB(cpu->reg_A);
  516. }
  517. /** 9D: STA $xxxx,X - STore A **/
  518. INSTRUCTION(STAaX)
  519. {
  520. TRACEi(("STA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  521. MEMORY_WRITE_AX(cpu->reg_A);
  522. }
  523. /** 99: STA $xxxx,Y - STore A **/
  524. INSTRUCTION(STAaY)
  525. {
  526. TRACEi(("STA $%02X%02X,Y", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  527. MEMORY_WRITE_AY(cpu->reg_A);
  528. }
  529. /** A6: LDX $xx - LoaD to X from zero page **/
  530. INSTRUCTION(LDXzP)
  531. {
  532. TRACEi(("LDX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  533. cpu->reg_X = MEMORY_READ_ZP();
  534. NZ_FLAG_UPDATE(cpu->reg_X);
  535. }
  536. /** B6: LDX $xx,Y - LoaD to X **/
  537. INSTRUCTION(LDXzY)
  538. {
  539. TRACEi(("LDX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC)));
  540. cpu->reg_X = MEMORY_READ_ZY();
  541. NZ_FLAG_UPDATE(cpu->reg_X);
  542. }
  543. /** AE: LDX $xxxx - LoaD to X **/
  544. INSTRUCTION(LDXaB)
  545. {
  546. TRACEi(("LDX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  547. cpu->reg_X = MEMORY_READ_AB();
  548. NZ_FLAG_UPDATE(cpu->reg_X);
  549. }
  550. /** BE: LDX $xxxx,Y - LoaD to X **/
  551. INSTRUCTION(LDXaY)
  552. {
  553. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  554. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  555. TRACEi(("LDX $%02X%02X,Y", op2, op1));
  556. cpu->reg_X = MEMORY_READ_AY();
  557. NZ_FLAG_UPDATE(cpu->reg_X);
  558. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  559. }
  560. /** B6: STX $xx - STore X to zero page **/
  561. INSTRUCTION(STXzP)
  562. {
  563. TRACEi(("STX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  564. cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_X);
  565. }
  566. /** 96: STX $xx,Y - STore X **/
  567. INSTRUCTION(STXzY)
  568. {
  569. TRACEi(("STX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC)));
  570. MEMORY_WRITE_ZY(cpu->reg_X);
  571. }
  572. /** 8E: STX $xxxx - STore X **/
  573. INSTRUCTION(STXaB)
  574. {
  575. TRACEi(("STX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  576. MEMORY_WRITE_AB(cpu->reg_X);
  577. }
  578. /** A4: LDY $xx - LoaD to Y from zero page **/
  579. INSTRUCTION(LDYzP)
  580. {
  581. TRACEi(("LDY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  582. cpu->reg_Y = MEMORY_READ_ZP();
  583. NZ_FLAG_UPDATE(cpu->reg_Y);
  584. }
  585. /** B4: LDY $xx,X - LoaD to Y **/
  586. INSTRUCTION(LDYzX)
  587. {
  588. TRACEi(("LDY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  589. cpu->reg_Y = MEMORY_READ_ZX();
  590. NZ_FLAG_UPDATE(cpu->reg_Y);
  591. }
  592. /** AC: LDY $xxxx - LoaD to Y **/
  593. INSTRUCTION(LDYaB)
  594. {
  595. TRACEi(("LDY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  596. cpu->reg_Y = MEMORY_READ_AB();
  597. NZ_FLAG_UPDATE(cpu->reg_Y);
  598. }
  599. /** BC: LDY $xxxx,X - LoaD to Y **/
  600. INSTRUCTION(LDYaX)
  601. {
  602. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  603. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  604. TRACEi(("LDY $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  605. cpu->reg_Y = MEMORY_READ_AX();
  606. NZ_FLAG_UPDATE(cpu->reg_Y);
  607. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  608. }
  609. /** 84: STY $xx - STore Y to zero page **/
  610. INSTRUCTION(STYzP)
  611. {
  612. TRACEi(("STY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  613. cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_Y);
  614. }
  615. /** 94: STY $xx,X - STore Y **/
  616. INSTRUCTION(STYzX)
  617. {
  618. TRACEi(("STY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  619. MEMORY_WRITE_ZX(cpu->reg_Y);
  620. }
  621. /** 8C: STY $xxxx - STore Y **/
  622. INSTRUCTION(STYaB)
  623. {
  624. TRACEi(("STY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  625. MEMORY_WRITE_AB(cpu->reg_Y);
  626. }
  627. /**** Register functions ****/
  628. /** AA : TAX - Transfer A to X **/
  629. INSTRUCTION(TAXiM)
  630. {
  631. TRACEi(("TAX"));
  632. cpu->reg_X = cpu->reg_A;
  633. NZ_FLAG_UPDATE(cpu->reg_X);
  634. }
  635. /** 8A : TXA - Transfer X to A **/
  636. INSTRUCTION(TXAiM)
  637. {
  638. TRACEi(("TXA"));
  639. cpu->reg_A = cpu->reg_X;
  640. NZ_FLAG_UPDATE(cpu->reg_A);
  641. }
  642. /** A8 : TAY - Transfer A to Y **/
  643. INSTRUCTION(TAYiM)
  644. {
  645. TRACEi(("TAY"));
  646. cpu->reg_Y = cpu->reg_A;
  647. NZ_FLAG_UPDATE(cpu->reg_Y);
  648. }
  649. /** 98 : TYA - Transfer Y to A **/
  650. INSTRUCTION(TYAiM)
  651. {
  652. TRACEi(("TYA"));
  653. cpu->reg_A = cpu->reg_Y;
  654. NZ_FLAG_UPDATE(cpu->reg_A);
  655. }
  656. /* BA : TSX - Transfer S to X **/
  657. INSTRUCTION(TSXiM)
  658. {
  659. TRACEi(("TSX"));
  660. cpu->reg_X = cpu->reg_S;
  661. NZ_FLAG_UPDATE(cpu->reg_X);
  662. }
  663. /** 9A : TXS - Transfer X to S **/
  664. INSTRUCTION(TXSiM)
  665. {
  666. TRACEi(("TXS"));
  667. cpu->reg_S = cpu->reg_X;
  668. }
  669. /**** Simple register operation instructions ****/
  670. /** CA : DEX - DEcrement X **/
  671. INSTRUCTION(DEXiM)
  672. {
  673. TRACEi(("DEX"));
  674. cpu->reg_X --;
  675. NZ_FLAG_UPDATE(cpu->reg_X);
  676. }
  677. /** 88 : DEY - DEcrement Y **/
  678. INSTRUCTION(DEYiM)
  679. {
  680. TRACEi(("DEY"));
  681. cpu->reg_Y --;
  682. NZ_FLAG_UPDATE(cpu->reg_Y);
  683. }
  684. /** E8 : INX - INcrement X **/
  685. INSTRUCTION(INXiM)
  686. {
  687. TRACEi(("INX"));
  688. cpu->reg_X ++;
  689. NZ_FLAG_UPDATE(cpu->reg_X);
  690. }
  691. /** C8 : INY - INcrement Y **/
  692. INSTRUCTION(INYiM)
  693. {
  694. TRACEi(("INY"));
  695. cpu->reg_Y ++;
  696. NZ_FLAG_UPDATE(cpu->reg_Y);
  697. }
  698. /**** Stack related instructions ****/
  699. /** 48 : PHA - PusH A */
  700. INSTRUCTION(PHAiM)
  701. {
  702. TRACEi(("PHA"));
  703. PUSH_S(cpu->reg_A);
  704. }
  705. /** 68 : PLA - PuLl A */
  706. INSTRUCTION(PLAiM)
  707. {
  708. TRACEi(("PLA"));
  709. cpu->reg_A = POP_S();
  710. NZ_FLAG_UPDATE(cpu->reg_A);
  711. }
  712. /** 08 : PHP - PusH P */
  713. INSTRUCTION(PHPiM)
  714. {
  715. TRACEi(("PHP"));
  716. PUSH_S((cpu->reg_P | Q6502_R_FLAG | Q6502_B_FLAG));
  717. }
  718. /** 28 : PLP - PuLl P */
  719. INSTRUCTION(PLPiM)
  720. {
  721. TRACEi(("PLP"));
  722. cpu->reg_P = POP_S() & ~(Q6502_R_FLAG | Q6502_B_FLAG);
  723. if (cpu->int_pending != 0)
  724. {
  725. quick6502_int(cpu, Q6502_IRQ_SIGNAL);
  726. }
  727. }
  728. /**** Branch instructions ****/
  729. /** 20 : JSR $xxxx - Jump to SubRoutine */
  730. INSTRUCTION(JSRaB)
  731. {
  732. TRACEi(("JSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  733. cpu->reg_PC++;
  734. PUSH_S((cpu->reg_PC >> 8) & 0xFF);
  735. PUSH_S((cpu->reg_PC ) & 0xFF);
  736. cpu->reg_PC = ((cpu->memory_opcode_read(cpu->reg_PC-1) ) | (cpu->memory_opcode_read(cpu->reg_PC) << 8));
  737. }
  738. /** 60 : RTS - ReTurn from Subrutine */
  739. INSTRUCTION(RTSiM)
  740. {
  741. TRACEi(("RTS"));
  742. cpu->reg_PC = POP_S() | (POP_S() << 8);
  743. cpu->reg_PC ++;
  744. }
  745. /** 4C : JMP $xxxx - JuMP inconditionaly to $xxxx **/
  746. INSTRUCTION(JMPaB)
  747. {
  748. TRACEi(("JMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  749. cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC++) | (cpu->memory_opcode_read(cpu->reg_PC) << 8);
  750. }
  751. /** 6C : JMP ($xxxx) - JuMP inconditionaly to ($xxxx) **/
  752. INSTRUCTION(JMPiD)
  753. {
  754. TRACEi(("JMP ($%02X%02X)", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  755. cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC) | (cpu->memory_opcode_read(cpu->reg_PC+1) << 8);
  756. cpu->reg_PC = cpu->memory_read(cpu->reg_PC) |
  757. (cpu->memory_read((cpu->reg_PC & 0xFF00) | ((cpu->reg_PC+1) & 0x00FF)) << 8);
  758. }
  759. /** 00 : BRK - BReaK **/
  760. INSTRUCTION(BRKiM)
  761. {
  762. TRACEi(("BRK"));
  763. cpu->reg_PC++;
  764. PUSH_S((cpu->reg_PC >> 8) & 0xFF);
  765. PUSH_S((cpu->reg_PC ) & 0xFF);
  766. PUSH_S( cpu->reg_P );
  767. cpu->reg_P = cpu->reg_P | Q6502_I_FLAG | Q6502_B_FLAG;
  768. cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8);
  769. }
  770. /** 40 : RTI - ReTurn from Interruption **/
  771. INSTRUCTION(RTIiM)
  772. {
  773. TRACEi(("RTI"));
  774. cpu->reg_P = POP_S();
  775. cpu->reg_PC = POP_S() | (POP_S() << 8);
  776. if (cpu->int_pending != 0)
  777. {
  778. quick6502_int(cpu, Q6502_IRQ_SIGNAL);
  779. }
  780. }
  781. /** 90 : BCC - Branch if Carry Clear **/
  782. INSTRUCTION(BCCrE)
  783. {
  784. TRACEi(("BCC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  785. if (!(cpu->reg_P & Q6502_C_FLAG))
  786. {
  787. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC++) + 1;
  788. /* Need to set timing */
  789. /* +1 is same page */
  790. cpu->cycle_done += 1;
  791. /* +2 is another */
  792. }
  793. else
  794. cpu->reg_PC ++;
  795. }
  796. /** B0 : BCS - Branch if Carry Set**/
  797. INSTRUCTION(BCSrE)
  798. {
  799. TRACEi(("BCS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  800. if (cpu->reg_P & Q6502_C_FLAG)
  801. {
  802. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  803. /* Need to set timing */
  804. /* +1 is same page */
  805. cpu->cycle_done += 1;
  806. /* +2 is another */
  807. }
  808. else
  809. cpu->reg_PC ++;
  810. }
  811. /** F0 : BEQ - Branch if Equal**/
  812. INSTRUCTION(BEQrE)
  813. {
  814. TRACEi(("BEQ $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  815. if (cpu->reg_P & Q6502_Z_FLAG)
  816. {
  817. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  818. /* Need to set timing */
  819. /* +1 is same page */
  820. cpu->cycle_done += 1;
  821. /* +2 is another */
  822. }
  823. else
  824. cpu->reg_PC ++;
  825. }
  826. /** 30 : BMI - Branch if MInus**/
  827. INSTRUCTION(BMIrE)
  828. {
  829. TRACEi(("BMI $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  830. if (cpu->reg_P & Q6502_N_FLAG)
  831. {
  832. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  833. /* Need to set timing */
  834. /* +1 is same page */
  835. cpu->cycle_done += 1;
  836. /* +2 is another */
  837. }
  838. else
  839. cpu->reg_PC ++;
  840. }
  841. /** D0 : Bxx - Branch if Not Equal**/
  842. INSTRUCTION(BNErE)
  843. {
  844. TRACEi(("BNE $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  845. if (!(cpu->reg_P & Q6502_Z_FLAG))
  846. {
  847. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  848. /* Need to set timing */
  849. /* +1 is same page */
  850. cpu->cycle_done += 1;
  851. /* +2 is another */
  852. }
  853. else
  854. cpu->reg_PC ++;
  855. }
  856. /** 10 : BPL - Branch if PLus **/
  857. INSTRUCTION(BPLrE)
  858. {
  859. TRACEi(("BPL $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  860. if (!(cpu->reg_P & Q6502_N_FLAG))
  861. {
  862. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  863. /* Need to set timing */
  864. /* +1 is same page */
  865. cpu->cycle_done += 1;
  866. /* +2 is another */
  867. }
  868. else
  869. cpu->reg_PC ++;
  870. }
  871. /** 50 : BVC - Branch if oVerflow Clear**/
  872. INSTRUCTION(BVCrE)
  873. {
  874. TRACEi(("BVC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  875. if (!(cpu->reg_P & Q6502_V_FLAG))
  876. {
  877. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  878. /* Need to set timing */
  879. /* +1 is same page */
  880. cpu->cycle_done += 1;
  881. /* +2 is another */
  882. }
  883. else
  884. cpu->reg_PC ++;
  885. }
  886. /** 70 : BVS - Branch if oVerflow Set**/
  887. INSTRUCTION(BVSrE)
  888. {
  889. TRACEi(("BVS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  890. if (cpu->reg_P & Q6502_V_FLAG)
  891. {
  892. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
  893. /* Need to set timing */
  894. /* +1 is same page */
  895. cpu->cycle_done += 1;
  896. /* +2 is another */
  897. }
  898. else
  899. cpu->reg_PC ++;
  900. }
  901. /*** Mathematical functions ***/
  902. /** 69 : ADC - ADd with Carry **/
  903. INSTRUCTION(ADCiM)
  904. {
  905. TRACEi(("ADC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  906. ADC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  907. }
  908. /** 65 : ADC - ADd with Carry **/
  909. INSTRUCTION(ADCzP)
  910. {
  911. TRACEi(("ADC $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  912. ADC_OPERATION(MEMORY_READ_ZP());
  913. }
  914. /** 75 : ADC - ADd with Carry **/
  915. INSTRUCTION(ADCzX)
  916. {
  917. TRACEi(("ADC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  918. ADC_OPERATION(MEMORY_READ_ZX());
  919. }
  920. /** 61 : ADC - ADd with Carry **/
  921. INSTRUCTION(ADCiX)
  922. {
  923. TRACEi(("ADC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  924. ADC_OPERATION(MEMORY_READ_IX());
  925. }
  926. /** 71 : ADC - ADd with Carry **/
  927. INSTRUCTION(ADCiY)
  928. {
  929. TRACEi(("ADC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  930. ADC_OPERATION(MEMORY_READ_IY());
  931. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  932. }
  933. /** 6D : ADC - ADd with Carry **/
  934. INSTRUCTION(ADCaB)
  935. {
  936. TRACEi(("ADC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  937. ADC_OPERATION(MEMORY_READ_AB());
  938. }
  939. /** 7D : ADC - ADd with Carry **/
  940. INSTRUCTION(ADCaX)
  941. {
  942. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  943. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  944. TRACEi(("ADC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  945. ADC_OPERATION(MEMORY_READ_AX());
  946. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  947. }
  948. /** 79 : ADC - ADd with Carry **/
  949. INSTRUCTION(ADCaY)
  950. {
  951. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  952. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  953. TRACEi(("ADC $%02X%02X,Y", op2, op1));
  954. ADC_OPERATION(MEMORY_READ_AY());
  955. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  956. }
  957. /** E9 : SBC - SuBstract with Carry **/
  958. INSTRUCTION(SBCiM)
  959. {
  960. TRACEi(("SBC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  961. SBC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  962. }
  963. /** E5 : SBC - SuBstract with Carry **/
  964. INSTRUCTION(SBCzP)
  965. {
  966. TRACEi(("SBC $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  967. SBC_OPERATION(MEMORY_READ_ZP());
  968. }
  969. /** F5 : SBC - SuBstract with Carry **/
  970. INSTRUCTION(SBCzX)
  971. {
  972. TRACEi(("SBC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  973. SBC_OPERATION(MEMORY_READ_ZX());
  974. }
  975. /** E1 : SBC - SuBstract with Carry **/
  976. INSTRUCTION(SBCiX)
  977. {
  978. TRACEi(("SBC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  979. SBC_OPERATION(MEMORY_READ_IX());
  980. }
  981. /** F1 : SBC - SuBstract with Carry **/
  982. INSTRUCTION(SBCiY)
  983. {
  984. TRACEi(("SBC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  985. SBC_OPERATION(MEMORY_READ_IY());
  986. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  987. }
  988. /** ED : SBC - SuBstract with Carry **/
  989. INSTRUCTION(SBCaB)
  990. {
  991. TRACEi(("SBC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  992. SBC_OPERATION(MEMORY_READ_AB());
  993. }
  994. /** FD : SBC - SuBstract with Carry **/
  995. INSTRUCTION(SBCaX)
  996. {
  997. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  998. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  999. TRACEi(("SBC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1000. SBC_OPERATION(MEMORY_READ_AX());
  1001. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1002. }
  1003. /** F9 : SBC - SuBstract with Carry **/
  1004. INSTRUCTION(SBCaY)
  1005. {
  1006. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1007. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1008. TRACEi(("SBC $%02X%02X,Y", op2, op1));
  1009. SBC_OPERATION(MEMORY_READ_AY());
  1010. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1011. }
  1012. /** C9 : CMP - CoMPare **/
  1013. INSTRUCTION(CMPiM)
  1014. {
  1015. TRACEi(("CMP #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1016. CMP_OPERATION(cpu->reg_A, cpu->memory_opcode_read(cpu->reg_PC++));
  1017. }
  1018. /** C5 : CMP - CoMPare **/
  1019. INSTRUCTION(CMPzP)
  1020. {
  1021. TRACEi(("CMP $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1022. CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZP());
  1023. }
  1024. /** D5 : CMP - CoMPare **/
  1025. INSTRUCTION(CMPzX)
  1026. {
  1027. TRACEi(("CMP $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1028. CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZX());
  1029. }
  1030. /** C1 : CMP - CoMPare **/
  1031. INSTRUCTION(CMPiX)
  1032. {
  1033. TRACEi(("CMP ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1034. CMP_OPERATION(cpu->reg_A, MEMORY_READ_IX());
  1035. }
  1036. /** D1 : CMP - CoMPare **/
  1037. INSTRUCTION(CMPiY)
  1038. {
  1039. TRACEi(("CMP ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1040. CMP_OPERATION(cpu->reg_A, MEMORY_READ_IY());
  1041. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1042. }
  1043. /** CD : CMP - CoMPare **/
  1044. INSTRUCTION(CMPaB)
  1045. {
  1046. TRACEi(("CMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1047. CMP_OPERATION(cpu->reg_A, MEMORY_READ_AB());
  1048. }
  1049. /** DD : CMP - CoMPare **/
  1050. INSTRUCTION(CMPaX)
  1051. {
  1052. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1053. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1054. TRACEi(("CMP $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1055. CMP_OPERATION(cpu->reg_A, MEMORY_READ_AX());
  1056. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1057. }
  1058. /** D9 : CMP - CoMPare **/
  1059. INSTRUCTION(CMPaY)
  1060. {
  1061. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1062. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1063. TRACEi(("CMP $%02X%02X,Y", op2, op1));
  1064. CMP_OPERATION(cpu->reg_A, MEMORY_READ_AY());
  1065. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1066. }
  1067. /** E0 : CPX - ComPare with Y **/
  1068. INSTRUCTION(CPXiM)
  1069. {
  1070. TRACEi(("CPX #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1071. CMP_OPERATION(cpu->reg_X, cpu->memory_opcode_read(cpu->reg_PC++));
  1072. }
  1073. /** E4 : CPX - ComPare with X **/
  1074. INSTRUCTION(CPXzP)
  1075. {
  1076. TRACEi(("CPX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1077. CMP_OPERATION(cpu->reg_X, MEMORY_READ_ZP());
  1078. }
  1079. /** EC : CPX - ComPare with X **/
  1080. INSTRUCTION(CPXaB)
  1081. {
  1082. TRACEi(("CPX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1083. CMP_OPERATION(cpu->reg_X, MEMORY_READ_AB());
  1084. }
  1085. /** C0 : CPY - ComPare with Y **/
  1086. INSTRUCTION(CPYiM)
  1087. {
  1088. TRACEi(("CPY #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1089. CMP_OPERATION(cpu->reg_Y, cpu->memory_opcode_read(cpu->reg_PC++));
  1090. }
  1091. /** C4 : CPY - ComPare with Y **/
  1092. INSTRUCTION(CPYzP)
  1093. {
  1094. TRACEi(("CPY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1095. CMP_OPERATION(cpu->reg_Y, MEMORY_READ_ZP());
  1096. }
  1097. /** CC : CPY - ComPare with Y **/
  1098. INSTRUCTION(CPYaB)
  1099. {
  1100. TRACEi(("CPY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1101. CMP_OPERATION(cpu->reg_Y, MEMORY_READ_AB());
  1102. }
  1103. /** 09 : ORA - OR with A **/
  1104. INSTRUCTION(ORAiM)
  1105. {
  1106. TRACEi(("ORA #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1107. ORA_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1108. }
  1109. /** 405 : ORA - OR with A **/
  1110. INSTRUCTION(ORAzP)
  1111. {
  1112. TRACEi(("ORA $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1113. ORA_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
  1114. }
  1115. /** 15 : ORA - OR with A **/
  1116. INSTRUCTION(ORAzX)
  1117. {
  1118. TRACEi(("ORA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1119. ORA_OPERATION(MEMORY_READ_ZX());
  1120. }
  1121. /** 01 : ORA - OR with A **/
  1122. INSTRUCTION(ORAiX)
  1123. {
  1124. TRACEi(("ORA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1125. ORA_OPERATION(MEMORY_READ_IX());
  1126. }
  1127. /** 11 : ORA - OR with A **/
  1128. INSTRUCTION(ORAiY)
  1129. {
  1130. TRACEi(("ORA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1131. ORA_OPERATION(MEMORY_READ_IY());
  1132. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1133. }
  1134. /** 0D : ORA - OR with A **/
  1135. INSTRUCTION(ORAaB)
  1136. {
  1137. TRACEi(("ORA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1138. ORA_OPERATION(MEMORY_READ_AB());
  1139. }
  1140. /** 1D : ORA - OR with A **/
  1141. INSTRUCTION(ORAaX)
  1142. {
  1143. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1144. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1145. TRACEi(("ORA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1146. ORA_OPERATION(MEMORY_READ_AX());
  1147. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1148. }
  1149. /** 19 : ORA - OR with A **/
  1150. INSTRUCTION(ORAaY)
  1151. {
  1152. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1153. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1154. TRACEi(("ORA $%02X%02X,Y", op2, op1));
  1155. ORA_OPERATION(MEMORY_READ_AY());
  1156. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1157. }
  1158. /** 49 : EOR - Exclusive OR **/
  1159. INSTRUCTION(EORiM)
  1160. {
  1161. TRACEi(("EOR #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1162. EOR_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1163. }
  1164. /** 45 : EOR - Exclusive OR **/
  1165. INSTRUCTION(EORzP)
  1166. {
  1167. TRACEi(("EOR $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1168. EOR_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
  1169. }
  1170. /** 55 : EOR - Exclusive OR **/
  1171. INSTRUCTION(EORzX)
  1172. {
  1173. TRACEi(("EOR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1174. EOR_OPERATION(MEMORY_READ_ZX());
  1175. }
  1176. /** 41 : EOR - Exclusive OR **/
  1177. INSTRUCTION(EORiX)
  1178. {
  1179. TRACEi(("EOR ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1180. EOR_OPERATION(MEMORY_READ_IX());
  1181. }
  1182. /** 51 : EOR - Exclusive OR **/
  1183. INSTRUCTION(EORiY)
  1184. {
  1185. TRACEi(("EOR ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1186. EOR_OPERATION(MEMORY_READ_IY());
  1187. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1188. }
  1189. /** 4D : EOR - Exclusive OR **/
  1190. INSTRUCTION(EORaB)
  1191. {
  1192. TRACEi(("EOR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1193. EOR_OPERATION(MEMORY_READ_AB());
  1194. }
  1195. /** 5D : EOR - Exclusive OR **/
  1196. INSTRUCTION(EORaX)
  1197. {
  1198. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1199. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1200. TRACEi(("EOR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1201. EOR_OPERATION(MEMORY_READ_AX());
  1202. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1203. }
  1204. /** 59 : EOR - Exclusive OR **/
  1205. INSTRUCTION(EORaY)
  1206. {
  1207. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1208. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1209. TRACEi(("EOR $%02X%02X,Y", op2, op1));
  1210. EOR_OPERATION(MEMORY_READ_AY());
  1211. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1212. }
  1213. /** 29 : AND - Logical AND **/
  1214. INSTRUCTION(ANDiM)
  1215. {
  1216. TRACEi(("AND #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1217. AND_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1218. }
  1219. /** 25 : AND - Logical AND **/
  1220. INSTRUCTION(ANDzP)
  1221. {
  1222. TRACEi(("AND $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1223. AND_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
  1224. }
  1225. /** 35 : AND - Logical AND **/
  1226. INSTRUCTION(ANDzX)
  1227. {
  1228. TRACEi(("AND $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1229. AND_OPERATION(MEMORY_READ_ZX());
  1230. }
  1231. /** 21 : AND - Logical AND **/
  1232. INSTRUCTION(ANDiX)
  1233. {
  1234. TRACEi(("AND ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1235. AND_OPERATION(MEMORY_READ_IX());
  1236. }
  1237. /** 31 : AND - Logical AND **/
  1238. INSTRUCTION(ANDiY)
  1239. {
  1240. TRACEi(("AND ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1241. AND_OPERATION(MEMORY_READ_IY());
  1242. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1243. }
  1244. /** 2D : AND - Logical AND **/
  1245. INSTRUCTION(ANDaB)
  1246. {
  1247. TRACEi(("AND $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1248. AND_OPERATION(MEMORY_READ_AB());
  1249. }
  1250. /** 3D : AND - Logical AND **/
  1251. INSTRUCTION(ANDaX)
  1252. {
  1253. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1254. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1255. TRACEi(("AND $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1256. AND_OPERATION(MEMORY_READ_AX());
  1257. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1258. }
  1259. /** 39 : AND - Logical AND **/
  1260. INSTRUCTION(ANDaY)
  1261. {
  1262. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1263. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1264. TRACEi(("AND $%02X%02X,Y", op2, op1));
  1265. AND_OPERATION(MEMORY_READ_AY());
  1266. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1267. }
  1268. /*** Misc instructions ***/
  1269. /** 24 : BIT **/
  1270. INSTRUCTION(BITzP)
  1271. {
  1272. TRACEi(("BIT $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1273. BIT_OPERATION(MEMORY_READ_ZP());
  1274. }
  1275. /** 2C : BIT **/
  1276. INSTRUCTION(BITaB)
  1277. {
  1278. TRACEi(("BIT $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1279. BIT_OPERATION(MEMORY_READ_AB());
  1280. }
  1281. /** 2A : ROL A **/
  1282. INSTRUCTION(ROLiM)
  1283. {
  1284. TRACEi(("ROL A"));
  1285. ROL_OPERATION(cpu->reg_A);
  1286. }
  1287. /** 6A : ROR A **/
  1288. INSTRUCTION(RORiM)
  1289. {
  1290. TRACEi(("ROR A"));
  1291. ROR_OPERATION(cpu->reg_A);
  1292. }
  1293. /** 0A : ASL A **/
  1294. INSTRUCTION(ASLiM)
  1295. {
  1296. TRACEi(("ASL A"));
  1297. ASL_OPERATION(cpu->reg_A);
  1298. }
  1299. /** 4A : LSR A **/
  1300. INSTRUCTION(LSRiM)
  1301. {
  1302. TRACEi(("LSR A"));
  1303. LSR_OPERATION(cpu->reg_A);
  1304. }
  1305. /** 2E : ROL **/
  1306. INSTRUCTION(ROLaB)
  1307. {
  1308. TRACEi(("ROL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1309. byte val = MEMORY_READ_AB();
  1310. cpu->reg_PC -= 2;
  1311. ROL_OPERATION(val);
  1312. MEMORY_WRITE_AB(val);
  1313. }
  1314. /** 26 : ROL **/
  1315. INSTRUCTION(ROLzP)
  1316. {
  1317. TRACEi(("ROL $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1318. byte val = MEMORY_READ_ZP();
  1319. cpu->reg_PC -= 1;
  1320. ROL_OPERATION(val);
  1321. MEMORY_WRITE_ZP(val);
  1322. }
  1323. /** 3E : ROL **/
  1324. INSTRUCTION(ROLaX)
  1325. {
  1326. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1327. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1328. TRACEi(("ROL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1329. byte val = MEMORY_READ_AX();
  1330. cpu->reg_PC -= 2;
  1331. ROL_OPERATION(val);
  1332. MEMORY_WRITE_AX(val);
  1333. }
  1334. /** 36 : ROL **/
  1335. INSTRUCTION(ROLzX)
  1336. {
  1337. TRACEi(("ROL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1338. byte val = MEMORY_READ_ZX();
  1339. cpu->reg_PC -= 1;
  1340. ROL_OPERATION(val);
  1341. MEMORY_WRITE_ZX(val);
  1342. }
  1343. /** 6E : ROR **/
  1344. INSTRUCTION(RORaB)
  1345. {
  1346. TRACEi(("ROR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1347. byte val = MEMORY_READ_AB();
  1348. cpu->reg_PC -= 2;
  1349. ROR_OPERATION(val);
  1350. MEMORY_WRITE_AB(val);
  1351. }
  1352. /** 66 : ROR **/
  1353. INSTRUCTION(RORzP)
  1354. {
  1355. TRACEi(("ROR $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1356. byte val = MEMORY_READ_ZP();
  1357. cpu->reg_PC -= 1;
  1358. ROR_OPERATION(val);
  1359. MEMORY_WRITE_ZP(val);
  1360. }
  1361. /** 7E : ROR **/
  1362. INSTRUCTION(RORaX)
  1363. {
  1364. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1365. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1366. TRACEi(("ROR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1367. byte val = MEMORY_READ_AX();
  1368. cpu->reg_PC -= 2;
  1369. ROR_OPERATION(val);
  1370. MEMORY_WRITE_AX(val);
  1371. }
  1372. /** 76 : ROR **/
  1373. INSTRUCTION(RORzX)
  1374. {
  1375. TRACEi(("ROR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1376. byte val = MEMORY_READ_ZX();
  1377. cpu->reg_PC -= 1;
  1378. ROR_OPERATION(val);
  1379. MEMORY_WRITE_ZX(val);
  1380. }
  1381. /** 0E : ASL **/
  1382. INSTRUCTION(ASLaB)
  1383. {
  1384. TRACEi(("ASL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1385. byte val = MEMORY_READ_AB();
  1386. cpu->reg_PC -= 2;
  1387. ASL_OPERATION(val);
  1388. MEMORY_WRITE_AB(val);
  1389. }
  1390. /** 06 : ASL **/
  1391. INSTRUCTION(ASLzP)
  1392. {
  1393. TRACEi(("ASL $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1394. byte val = MEMORY_READ_ZP();
  1395. cpu->reg_PC -= 1;
  1396. ASL_OPERATION(val);
  1397. MEMORY_WRITE_ZP(val);
  1398. }
  1399. /** 1E : ASL **/
  1400. INSTRUCTION(ASLaX)
  1401. {
  1402. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1403. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1404. TRACEi(("ASL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1405. byte val = MEMORY_READ_AX();
  1406. cpu->reg_PC -= 2;
  1407. ASL_OPERATION(val);
  1408. MEMORY_WRITE_AX(val);
  1409. }
  1410. /** 16 : ASL **/
  1411. INSTRUCTION(ASLzX)
  1412. {
  1413. TRACEi(("ASL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1414. byte val = MEMORY_READ_ZX();
  1415. cpu->reg_PC -= 1;
  1416. ASL_OPERATION(val);
  1417. MEMORY_WRITE_ZX(val);
  1418. }
  1419. /** 4E : LSR **/
  1420. INSTRUCTION(LSRaB)
  1421. {
  1422. TRACEi(("LSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1423. byte val = MEMORY_READ_AB();
  1424. cpu->reg_PC -= 2;
  1425. LSR_OPERATION(val);
  1426. MEMORY_WRITE_AB(val);
  1427. }
  1428. /** 46 : LSR **/
  1429. INSTRUCTION(LSRzP)
  1430. {
  1431. TRACEi(("LSR $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1432. byte val = MEMORY_READ_ZP();
  1433. cpu->reg_PC -= 1;
  1434. LSR_OPERATION(val);
  1435. MEMORY_WRITE_ZP(val);
  1436. }
  1437. /** 5E : LSR **/
  1438. INSTRUCTION(LSRaX)
  1439. {
  1440. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1441. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1442. TRACEi(("LSR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1443. byte val = MEMORY_READ_AX();
  1444. cpu->reg_PC -= 2;
  1445. LSR_OPERATION(val);
  1446. MEMORY_WRITE_AX(val);
  1447. }
  1448. /** 56 : LSR **/
  1449. INSTRUCTION(LSRzX)
  1450. {
  1451. TRACEi(("LSR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1452. byte val = MEMORY_READ_ZX();
  1453. cpu->reg_PC -= 1;
  1454. LSR_OPERATION(val);
  1455. MEMORY_WRITE_ZX(val);
  1456. }
  1457. /** CE : DEC **/
  1458. INSTRUCTION(DECaB)
  1459. {
  1460. TRACEi(("DEC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1461. byte val = MEMORY_READ_AB();
  1462. cpu->reg_PC -= 2;
  1463. MEMORY_WRITE_AB(--val);
  1464. NZ_FLAG_UPDATE(val);
  1465. }
  1466. /** C6 : DEC **/
  1467. INSTRUCTION(DECzP)
  1468. {
  1469. TRACEi(("DEC $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1470. byte val = MEMORY_READ_ZP();
  1471. cpu->reg_PC -= 1;
  1472. MEMORY_WRITE_ZP(--val);
  1473. NZ_FLAG_UPDATE(val);
  1474. }
  1475. /** DE : DEC **/
  1476. INSTRUCTION(DECaX)
  1477. {
  1478. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1479. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1480. TRACEi(("DEC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1481. byte val = MEMORY_READ_AX();
  1482. cpu->reg_PC -= 2;
  1483. MEMORY_WRITE_AX(--val);
  1484. NZ_FLAG_UPDATE(val);
  1485. }
  1486. /** D6 : DEC **/
  1487. INSTRUCTION(DECzX)
  1488. {
  1489. TRACEi(("DEC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1490. byte val = MEMORY_READ_ZX();
  1491. cpu->reg_PC -= 1;
  1492. MEMORY_WRITE_ZX(--val);
  1493. NZ_FLAG_UPDATE(val);
  1494. }
  1495. /** EE : INC **/
  1496. INSTRUCTION(INCaB)
  1497. {
  1498. TRACEi(("INC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1499. byte val = MEMORY_READ_AB();
  1500. cpu->reg_PC -= 2;
  1501. MEMORY_WRITE_AB(++val);
  1502. NZ_FLAG_UPDATE(val);
  1503. }
  1504. /** E6 : INC **/
  1505. INSTRUCTION(INCzP)
  1506. {
  1507. TRACEi(("INC $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1508. byte val = MEMORY_READ_ZP();
  1509. cpu->reg_PC -= 1;
  1510. MEMORY_WRITE_ZP(++val);
  1511. NZ_FLAG_UPDATE(val);
  1512. }
  1513. /** FE : INC **/
  1514. INSTRUCTION(INCaX)
  1515. {
  1516. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1517. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1518. TRACEi(("INC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1519. byte val = MEMORY_READ_AX();
  1520. cpu->reg_PC -= 2;
  1521. MEMORY_WRITE_AX(++val);
  1522. NZ_FLAG_UPDATE(val);
  1523. }
  1524. /** F6 : INC **/
  1525. INSTRUCTION(INCzX)
  1526. {
  1527. TRACEi(("INC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1528. byte val = MEMORY_READ_ZX();
  1529. cpu->reg_PC -= 1;
  1530. MEMORY_WRITE_ZX(++val);
  1531. NZ_FLAG_UPDATE(val);
  1532. }
  1533. /* */
  1534. static InstructionFunction InstructionTable[256] =
  1535. {
  1536. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1537. /* 00 */ I_BRKiM, I_ORAiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzP, I_ASLzP, I_ILLEG, I_PHPiM, I_ORAiM, I_ASLiM, I_ILLEG, I_ILLEG, I_ORAaB, I_ASLaB, I_ILLEG,
  1538. /* 10 */ I_BPLrE, I_ORAiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzX, I_ASLzX, I_ILLEG, I_CLCiM, I_ORAaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAaX, I_ASLaX, I_ILLEG,
  1539. /* 20 */ I_JSRaB, I_ANDiX, I_ILLEG, I_ILLEG, I_BITzP, I_ANDzP, I_ROLzP, I_ILLEG, I_PLPiM, I_ANDiM, I_ROLiM, I_ILLEG, I_BITaB, I_ANDaB, I_ROLaB, I_ILLEG,
  1540. /* 30 */ I_BMIrE, I_ANDiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDzX, I_ROLzX, I_ILLEG, I_SECiM, I_ANDaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDaX, I_ROLaX, I_ILLEG,
  1541. /* 40 */ I_RTIiM, I_EORiX, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzP, I_LSRzP, I_ILLEG, I_PHAiM, I_EORiM, I_LSRiM, I_ILLEG, I_JMPaB, I_EORaB, I_LSRaB, I_ILLEG,
  1542. /* 50 */ I_BVCrE, I_EORiY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzX, I_LSRzX, I_ILLEG, I_CLIiM, I_EORaY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORaX, I_LSRaX, I_ILLEG,
  1543. /* 60 */ I_RTSiM, I_ADCiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzP, I_RORzP, I_ILLEG, I_PLAiM, I_ADCiM, I_RORiM, I_ILLEG, I_JMPiD, I_ADCaB, I_RORaB, I_ILLEG,
  1544. /* 70 */ I_BVSrE, I_ADCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzX, I_RORzX, I_ILLEG, I_SEIiM, I_ADCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCaX, I_RORaX, I_ILLEG,
  1545. /* 80 */ I_ILLEG, I_STAiX, I_ILLEG, I_ILLEG, I_STYzP, I_STAzP, I_STXzP, I_ILLEG, I_DEYiM, I_ILLEG, I_TXAiM, I_ILLEG, I_STYaB, I_STAaB, I_STXaB, I_ILLEG,
  1546. /* 90 */ I_BCCrE, I_STAiY, I_ILLEG, I_ILLEG, I_STYzX, I_STAzX, I_STXzY, I_ILLEG, I_TYAiM, I_STAaY, I_TXSiM, I_ILLEG, I_ILLEG, I_STAaX, I_ILLEG, I_ILLEG,
  1547. /* A0 */ I_LDYiM, I_LDAiX, I_LDXiM, I_ILLEG, I_LDYzP, I_LDAzP, I_LDXzP, I_ILLEG, I_TAYiM, I_LDAiM, I_TAXiM, I_ILLEG, I_LDYaB, I_LDAaB, I_LDXaB, I_ILLEG,
  1548. /* B0 */ I_BCSrE, I_LDAiY, I_ILLEG, I_ILLEG, I_LDYzX, I_LDAzX, I_LDXzY, I_ILLEG, I_CLViM, I_LDAaY, I_TSXiM, I_ILLEG, I_LDYaX, I_LDAaX, I_LDXaY, I_ILLEG,
  1549. /* C0 */ I_CPYiM, I_CMPiX, I_ILLEG, I_ILLEG, I_CPYzP, I_CMPzP, I_DECzP, I_ILLEG, I_INYiM, I_CMPiM, I_DEXiM, I_ILLEG, I_CPYaB, I_CMPaB, I_DECaB, I_ILLEG,
  1550. /* D0 */ I_BNErE, I_CMPiY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPzX, I_DECzX, I_ILLEG, I_CLDiM, I_CMPaY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPaX, I_DECaX, I_ILLEG,
  1551. /* E0 */ I_CPXiM, I_SBCiX, I_ILLEG, I_ILLEG, I_CPXzP, I_SBCzP, I_INCzP, I_ILLEG, I_INXiM, I_SBCiM, I_NOPiM, I_ILLEG, I_CPXaB, I_SBCaB, I_INCaB, I_ILLEG,
  1552. /* F0 */ I_BEQrE, I_SBCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCzX, I_INCzX, I_ILLEG, I_SEDiM, I_SBCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCaX, I_INCaX, I_ILLEG
  1553. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1554. };
  1555. static inline int quick6502_exec_one(quick6502_cpu *cpu)
  1556. {
  1557. register byte opcode = cpu->memory_opcode_read(cpu->reg_PC++);
  1558. TRACEi(("Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]",
  1559. cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
  1560. cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
  1561. cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
  1562. cpu->reg_P&Q6502_R_FLAG ? 'R':'.',
  1563. cpu->reg_P&Q6502_B_FLAG ? 'B':'.',
  1564. cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
  1565. cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
  1566. cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
  1567. cpu->reg_P&Q6502_C_FLAG ? 'C':'.'));
  1568. InstructionTable[opcode](cpu);
  1569. cpu->cycle_done += CycleTable[opcode];
  1570. if (cpu->page_crossed) { cpu->cycle_done++; cpu->page_crossed = 0; }
  1571. if (cpu->int_pending != 0)
  1572. {
  1573. quick6502_int(cpu, Q6502_IRQ_SIGNAL);
  1574. }
  1575. return 0;
  1576. }