corecpu.c 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255
  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. /* TODO: Add Inst/MemAccess breakpoints */
  15. /* Depending on the OS, one of these provide the malloc function */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <stdint.h>
  19. #include <string.h>
  20. #include <os_dependent.h>
  21. /*******************************************************************************
  22. /!\ WARNING this debug tool slow down a lot the emulator! /!\
  23. /!\ Use it only if you really need it ! /!\
  24. *******************************************************************************/
  25. //#define TRACE_INSTRUCTIONS
  26. #ifdef TRACE_INSTRUCTIONS
  27. #define TRACEi(trace) do { console_printf(Console_Debug, ">> $%04X - ", cpu->reg_PC-1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
  28. #define TRACEiE(trace) do { console_printf(Console_Debug, ">> $%04X - ", cpu->reg_PC-1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
  29. #else
  30. #define TRACEi(trace) { }
  31. //#define TRACEiE(trace) { }
  32. #define TRACEiE(trace) do { console_printf(Console_Debug, ">> $%04X - ", cpu->reg_PC-1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
  33. #endif
  34. /*
  35. * IP_ == "Instruction Parameter"
  36. * nP: No parameters
  37. * iM: Immediate
  38. * iX: Indirect by X
  39. * iY: Indirect by Y
  40. * zP: Zero Page
  41. * zX: Zero Page Indexec by X
  42. * zY: Zero Page Indexec by Y
  43. * iD: Indirect Double
  44. * aB: Absolute
  45. * aX: Absolute by X
  46. * aY: Absolute by Y
  47. * rE: Relative
  48. */
  49. #define IP_nP "N"
  50. #define IP_iM "I"
  51. #define IP_iX "X"
  52. #define IP_iY "Y"
  53. #define IP_zP "0"
  54. #define IP_zX "z"
  55. #define IP_zY "Z"
  56. #define IP_iD "D"
  57. #define IP_aB "A"
  58. #define IP_aX "x"
  59. #define IP_aY "y"
  60. #define IP_rE "R"
  61. #define IP_nPc 'N'
  62. #define IP_iMc 'I'
  63. #define IP_iXc 'X'
  64. #define IP_iYc 'Y'
  65. #define IP_zPc '0'
  66. #define IP_zXc 'z'
  67. #define IP_zYc 'Z'
  68. #define IP_iDc 'D'
  69. #define IP_aBc 'A'
  70. #define IP_aXc 'x'
  71. #define IP_aYc 'y'
  72. #define IP_rEc 'R'
  73. #define IPf_nP ""
  74. #define IPf_iM " $%02X"
  75. #define IPf_iX " ($%02X,X)"
  76. #define IPf_iY " ($%02X),Y"
  77. #define IPf_zP " $%02X"
  78. #define IPf_zX " $%02X,X"
  79. #define IPf_zY " $%02X,Y"
  80. #define IPf_iD " ($%02X%02X)"
  81. #define IPf_aB " $%02X%02X"
  82. #define IPf_aX " $%02X%02X,X"
  83. #define IPf_aY " $%02X%02X,Y"
  84. #define IPf_rE " $%02X%02X"
  85. #define _INTERNAL_QUICK6502_CORECPU_
  86. #include "corecpu.h"
  87. /*** Instructions useful macros ***/
  88. #define INSTRUCTION(s) static inline void I_##s (quick6502_cpu *cpu)
  89. #define NZ_FLAG_UPDATE(value) cpu->reg_P = (cpu->reg_P & ~(Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  90. (value & 0x80) | ((value)?0:Q6502_Z_FLAG)
  91. #define CROSS_CYCLE_UPDATE(value) if ((value) & 0x0F00) cpu->page_crossed = 1
  92. #define MEMORY_READ_ZP() cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))
  93. #define MEMORY_READ_IX() cpu->memory_read( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X ) & 0xFF) |\
  94. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X + 1) << 8) ); cpu->reg_PC++
  95. #define MEMORY_READ_IY() cpu->memory_read( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  96. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + 1) << 8) ) + cpu->reg_Y ); cpu->reg_PC++
  97. #define MEMORY_READ_ZX() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X) )
  98. #define MEMORY_READ_ZY() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y) )
  99. #define MEMORY_READ_AB() cpu->memory_read( ((cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  100. (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) )); cpu->reg_PC += 2
  101. #define MEMORY_READ_AX() cpu->memory_read( ((op1 ) |\
  102. (op2 << 8) ) + cpu->reg_X)
  103. #define MEMORY_READ_AY() cpu->memory_read( ((op1 ) |\
  104. (op2 << 8) ) + cpu->reg_Y )
  105. #define MEMORY_WRITE_ZP(val) cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), val)
  106. #define MEMORY_WRITE_IX(val) cpu->memory_write( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X ) & 0xFF) |\
  107. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X + 1) << 8) , val); cpu->reg_PC++
  108. #define MEMORY_WRITE_IY(val) cpu->memory_write( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  109. (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + 1) << 8) ) + cpu->reg_Y , val); cpu->reg_PC++
  110. #define MEMORY_WRITE_ZX(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X), val)
  111. #define MEMORY_WRITE_ZY(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y), val)
  112. #define MEMORY_WRITE_AB(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  113. (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ), val); cpu->reg_PC += 2
  114. #define MEMORY_WRITE_AX(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  115. (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ) + cpu->reg_X, val); cpu->reg_PC += 2
  116. #define MEMORY_WRITE_AY(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC ) ) |\
  117. (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ) + cpu->reg_Y, val); cpu->reg_PC += 2
  118. #define PUSH_S(value) cpu->memory_stack_write(0x100 | (cpu->reg_S--), value)
  119. #define POP_S() (cpu->memory_stack_read (0x100 | (++cpu->reg_S) ))
  120. #ifdef Q6502_NO_DECIMAL
  121. #define ADC_OPERATION(read) do {\
  122. unsigned short tmp = 0; unsigned char v = read; \
  123. tmp = cpu->reg_A + v + (cpu->reg_P & Q6502_C_FLAG); \
  124. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \
  125. (tmp & 0x80) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
  126. ((tmp & 0xFF00)?Q6502_C_FLAG:0) | \
  127. ( ( ~(cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \
  128. cpu->reg_A = tmp & 0xFF; \
  129. } while(0)
  130. #define SBC_OPERATION(read) do {\
  131. unsigned short tmp = 0; unsigned char v = read; \
  132. tmp = cpu->reg_A - v - (~cpu->reg_P & Q6502_C_FLAG); \
  133. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \
  134. (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
  135. ((tmp & 0xFF00)?0:Q6502_C_FLAG) | \
  136. ( ( (cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \
  137. cpu->reg_A = tmp & 0xFF; \
  138. } while(0)
  139. #else
  140. #error Quick6502 doesn t actually support DECIMAL mode
  141. #endif
  142. #define AND_OPERATION(read) cpu->reg_A &= read; NZ_FLAG_UPDATE(cpu->reg_A)
  143. /* CMP is like SBC but without storing the result value */
  144. #define CMP_OPERATION(register, read) do { \
  145. unsigned short tmp = 0; \
  146. tmp = register - read; \
  147. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  148. (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
  149. ((tmp & 0xFF00)?0:Q6502_C_FLAG); \
  150. } while(0)
  151. #define EOR_OPERATION(read) cpu->reg_A ^= read; NZ_FLAG_UPDATE(cpu->reg_A)
  152. #define ORA_OPERATION(read) cpu->reg_A |= read; NZ_FLAG_UPDATE(cpu->reg_A)
  153. #define BIT_OPERATION(read) do { \
  154. byte tmp = read; \
  155. cpu->reg_P = (cpu->reg_P & ~(Q6502_V_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  156. (tmp & Q6502_N_FLAG) | (tmp & Q6502_V_FLAG) | \
  157. ((tmp & cpu->reg_A)?0:Q6502_Z_FLAG); \
  158. } while(0)
  159. #define ASL_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  160. ((val&0x40)?Q6502_N_FLAG:0) | \
  161. ((val&0x80)?Q6502_C_FLAG:0) | \
  162. ((val&0x7F)?0:Q6502_Z_FLAG); \
  163. val = val << 1
  164. #define LSR_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  165. (val & Q6502_C_FLAG) | \
  166. ((val&0xFE)?0:Q6502_Z_FLAG); \
  167. val = val >> 1
  168. #define ROR_OPERATION(val) do {\
  169. unsigned short tmp = val | (cpu->reg_P & Q6502_C_FLAG) << 8; \
  170. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  171. ( tmp&Q6502_C_FLAG) | /* Set the C flag */ \
  172. ((tmp&0x100) >> 1) | /* Set the N flag */ \
  173. ((tmp&0x1FE)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \
  174. val = (tmp>>1) & 0xFF; \
  175. } while(0)
  176. #define ROL_OPERATION(val) do {\
  177. unsigned short tmp = (val << 1) | (cpu->reg_P & Q6502_C_FLAG); \
  178. cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
  179. ((tmp&0x100)?Q6502_C_FLAG:0) | /* Set the C flag */ \
  180. ((tmp&0x80)) | /* Set the N flag */ \
  181. ((tmp&0xFF)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \
  182. val = tmp & 0xFF; \
  183. } while(0)
  184. /** Function used for execution of instruction */
  185. static inline int quick6502_exec_one(quick6502_cpu *cpu);
  186. /**
  187. * Initialise the CPU
  188. *
  189. * Inputs:
  190. *
  191. * - CPU Init structure:
  192. * - Memory Read function pointer
  193. * - Memory Write function pointer
  194. * - Fast memory read function pointer (for opcodes read)
  195. * - Fast page 0 function Read/Write
  196. * - Fast page 1 function Read/Write
  197. *
  198. * Output:
  199. *
  200. * (void *): An opaque pointer to the internal structure of the CPU.
  201. * NULL if an error occured !
  202. */
  203. quick6502_cpu *quick6502_init(quick6502_cpuconfig *config)
  204. {
  205. quick6502_cpu *cpu;
  206. /* Alloc structure */
  207. cpu = (quick6502_cpu *) malloc (sizeof (quick6502_cpu));
  208. if (!cpu)
  209. return NULL;
  210. /* Initialise other variables */
  211. cpu->running = 0; /* CPU is currently NOT running */
  212. cpu->cycle_done = 0;
  213. cpu->int_pending = 0;
  214. cpu->page_crossed = 0;
  215. /* Initialise registers */
  216. cpu->reg_A = 0;
  217. cpu->reg_X = 0;
  218. cpu->reg_Y = 0;
  219. cpu->reg_S = 0xFF;
  220. cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG;
  221. if (config->memory_read != NULL)
  222. cpu->memory_read = config->memory_read;
  223. else
  224. goto init_error;
  225. if (config->memory_write != NULL)
  226. cpu->memory_write = config->memory_write;
  227. else
  228. goto init_error;
  229. if (config->memory_opcode_read != NULL)
  230. cpu->memory_opcode_read = config->memory_opcode_read;
  231. else
  232. cpu->memory_opcode_read = config->memory_read;
  233. if (config->memory_page0_read != NULL)
  234. cpu->memory_page0_read = config->memory_page0_read;
  235. else
  236. cpu->memory_page0_read = config->memory_read;
  237. if (config->memory_page0_write != NULL)
  238. cpu->memory_page0_write = config->memory_page0_write;
  239. else
  240. cpu->memory_page0_write = config->memory_write;
  241. if (config->memory_stack_read != NULL)
  242. cpu->memory_stack_read = config->memory_stack_read;
  243. else
  244. cpu->memory_stack_read = config->memory_read;
  245. if (config->memory_stack_write != NULL)
  246. cpu->memory_stack_write = config->memory_stack_write;
  247. else
  248. cpu->memory_stack_write = config->memory_write;
  249. return cpu;
  250. init_error:
  251. if (cpu)
  252. free (cpu);
  253. return NULL;
  254. }
  255. /** Reset the CPU (must be done after init) */
  256. void quick6502_reset(quick6502_cpu *cpu)
  257. {
  258. /* Initialise registers */
  259. /*cpu->reg_A = 0;
  260. cpu->reg_X = 0;
  261. cpu->reg_Y = 0;
  262. cpu->reg_S = 0xFF;*/
  263. //cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG | 0x20 | Q6502_B_FLAG;
  264. /* Set the PC to the RESET vector */
  265. cpu->reg_PC = ( cpu->memory_read(Q6502_RESET_HIGH) << 8)
  266. | cpu->memory_read(Q6502_RESET_LOW);
  267. cpu->exit_loop = 0;
  268. }
  269. /**
  270. * Run cpu for at least X cycles
  271. *
  272. * Output:
  273. *
  274. * int: (Number of cycle really done) - (Number of cycle asked)
  275. */
  276. int quick6502_run(quick6502_cpu *cpu, int cycles)
  277. {
  278. cpu->running = !0;
  279. while(cpu->cycle_done < cycles)
  280. {
  281. quick6502_exec_one(cpu);
  282. }
  283. cpu->cycle_done -= cycles;
  284. cpu->running = 0;
  285. return cycles + cpu->cycle_done;
  286. }
  287. /** Loop CPU until explicit quit */
  288. void quick6502_loop(quick6502_cpu *cpu)
  289. {
  290. cpu->running = !0;
  291. while(cpu->exit_loop)
  292. {
  293. quick6502_exec_one(cpu);
  294. }
  295. cpu->running = 0;
  296. }
  297. /** Run CPU for one instruction */
  298. void quick6502_exec(quick6502_cpu *cpu)
  299. {
  300. cpu->running = !0;
  301. quick6502_exec_one(cpu);
  302. cpu->running = 0;
  303. }
  304. /** Send IRQ/NMI/EXITLOOP signal to CPU */
  305. void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal)
  306. {
  307. switch(signal)
  308. {
  309. default:
  310. break;
  311. case Q6502_IRQ_SIGNAL:
  312. if (! (cpu->reg_P & Q6502_I_FLAG) )
  313. {
  314. TRACEi(("IRQ Triggered !"));
  315. PUSH_S((cpu->reg_PC >> 8) & 0xFF );
  316. PUSH_S((cpu->reg_PC ) & 0xFF );
  317. PUSH_S( cpu->reg_P & ~Q6502_B_FLAG );
  318. cpu->reg_P = cpu->reg_P | Q6502_I_FLAG;
  319. cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8);
  320. cpu->cycle_done += 7;
  321. }
  322. else
  323. cpu->int_pending = 1;
  324. break;
  325. case Q6502_NMI_SIGNAL:
  326. TRACEi(("NMI Triggered !"));
  327. PUSH_S((cpu->reg_PC >> 8) & 0xFF );
  328. PUSH_S((cpu->reg_PC ) & 0xFF );
  329. PUSH_S( cpu->reg_P );
  330. cpu->reg_P = (cpu->reg_P | Q6502_I_FLAG) & ~Q6502_B_FLAG;
  331. cpu->reg_PC = (cpu->memory_read(Q6502_NMI_LOW)) | (cpu->memory_read(Q6502_NMI_HIGH)<<8);
  332. cpu->cycle_done += 7;
  333. break;
  334. case Q6502_STOPLOOP_SIGNAL:
  335. cpu->exit_loop = 1;
  336. break;
  337. }
  338. }
  339. /** Dump CPU State to the given file */
  340. void quick6502_dump(quick6502_cpu *cpu, FILE * fp)
  341. {
  342. short i;
  343. char instr[100];
  344. /* Display registers */
  345. fprintf(fp,
  346. "## Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X [%c%c%c%c%c%c%c%c]\n",
  347. cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
  348. cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
  349. cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
  350. '.', /* No real flag here */
  351. cpu->reg_P&Q6502_B_FLAG ? 'B':'.',
  352. cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
  353. cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
  354. cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
  355. cpu->reg_P&Q6502_C_FLAG ? 'C':'.'
  356. );
  357. /* Display stack */
  358. fprintf(fp, "## Quick6502: Stack: [ ");
  359. for (i = cpu->reg_S+1; i < 0x100; i++)
  360. {
  361. fprintf(fp, "$%02X ", cpu->memory_read(0x100 | i));
  362. }
  363. fprintf(fp, "] Run:%c Cycle:%ld\n", cpu->running?'Y':'N', cpu->cycle_done);
  364. fprintf(fp, "## Quick6502: InstrMem: [ ");
  365. for (i = 0; i < 0x5; i++)
  366. {
  367. fprintf(fp, "$%02X ", cpu->memory_opcode_read(cpu->reg_PC + i));
  368. }
  369. fprintf(fp, "]\n");
  370. quick6502_getinstruction(cpu, (1==1), cpu->reg_PC, instr, NULL);
  371. fprintf(fp, "## $%04X: %s\n", cpu->reg_PC, instr);
  372. }
  373. typedef enum InstructionNameTag
  374. {
  375. n_ILG = 0, n_NOP,
  376. n_CLI, n_SEI, n_CLC, n_SEC, n_CLD, n_SED, n_CLV,
  377. n_LDA, n_LDX, n_LDY, n_STA, n_STX, n_STY,
  378. n_TXA, n_TAX, n_TAY, n_TYA, n_TSX, n_TXS,
  379. n_PHA, n_PLA, n_PHP, n_PLP,
  380. n_DEX, n_DEY, n_INX, n_INY, n_DEC, n_INC,
  381. n_JSR, n_RTS, n_JMP, n_BRK, n_RTI,
  382. n_BCC, n_BCS, n_BEQ, n_BNE, n_BHI, n_BPL, n_BVS, n_BVC, n_BMI,
  383. n_EOR, n_AND, n_BIT, n_ORA, n_ADC, n_SBC,
  384. n_ROL, n_ROR, n_ASL, n_LSR,
  385. n_CMP, n_CPX, n_CPY,
  386. } InstructionNameTag;
  387. char *InstructionName[] =
  388. {
  389. "ILLEGAL", "NOP",
  390. "CLI", "SEI", "CLC", "SEC", "CLD", "SED", "CLV",
  391. "LDA", "LDX", "LDY", "STA", "STX", "STY",
  392. "TXA", "TAX", "TAY", "TYA", "TSX", "TXS",
  393. "PHA", "PLA", "PHP", "PLP",
  394. "DEX", "DEY", "INX", "INY", "DEC", "INC",
  395. "JSR", "RTS", "JMP", "BRK", "RTI",
  396. "BCC", "BCS", "BEQ", "BNE", "BHI", "BPL", "BVS", "BVC", "BVS",
  397. "EOR", "AND", "BIT", "ORA", "ADC", "SBC",
  398. "ROL", "ROR", "ASL", "LSR",
  399. "CMP", "CPX", "CPY",
  400. };
  401. /**
  402. * Free the CPU
  403. *
  404. * This function will free the CPU only if it's not currently used, it will
  405. * return 0 if everything goes well and !0 if the free is impossible
  406. */
  407. int quick6502_free(quick6502_cpu *cpu)
  408. {
  409. return 0;
  410. }
  411. /*******************************************************************************
  412. *** Here start real CPU logic ***
  413. *******************************************************************************/
  414. static byte CycleTable[256] =
  415. {
  416. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  417. /* 00 */ 7, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
  418. /* 10 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  419. /* 20 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6,
  420. /* 30 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  421. /* 40 */ 6, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6,
  422. /* 50 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  423. /* 60 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6,
  424. /* 70 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  425. /* 80 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
  426. /* 90 */ 2, 6, 0, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5,
  427. /* A0 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
  428. /* B0 */ 2, 5, 0, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4,
  429. /* C0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
  430. /* D0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
  431. /* E0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
  432. /* F0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7
  433. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  434. };
  435. typedef void (*InstructionFunction)(quick6502_cpu *cpu);
  436. /*******************************************************************************
  437. * Instruction implementations
  438. *******************************************************************************/
  439. /**** Other instructions ****/
  440. INSTRUCTION(ILLEG)
  441. {
  442. TRACEiE(("Illegal instruction $%02X", cpu->memory_opcode_read(cpu->reg_PC-1)));
  443. //exit(-1);
  444. }
  445. /** 58 : CLI - CLear Interrupt **/
  446. INSTRUCTION(CLInP)
  447. {
  448. TRACEi(("CLI"));
  449. cpu->reg_P &= ~Q6502_I_FLAG;
  450. }
  451. /** 78 : SEI - SEt Interrupt **/
  452. INSTRUCTION(SEInP)
  453. {
  454. TRACEi(("SEI"));
  455. cpu->reg_P |= Q6502_I_FLAG;
  456. }
  457. /** 18 : CLC - CLear Carry **/
  458. INSTRUCTION(CLCnP)
  459. {
  460. TRACEi(("CLC"));
  461. cpu->reg_P &= ~Q6502_C_FLAG;
  462. }
  463. /** 38 : SEC - SEt Carry **/
  464. INSTRUCTION(SECnP)
  465. {
  466. TRACEi(("SEC"));
  467. cpu->reg_P |= Q6502_C_FLAG;
  468. }
  469. /** D8 : CLD - CLear Decimal **/
  470. INSTRUCTION(CLDnP)
  471. {
  472. TRACEi(("CLD"));
  473. cpu->reg_P &= ~Q6502_D_FLAG;
  474. }
  475. /** F8 : SED - SEt Decimal **/
  476. INSTRUCTION(SEDnP)
  477. {
  478. TRACEi(("SED"));
  479. cpu->reg_P |= Q6502_D_FLAG;
  480. }
  481. /** B8 : CLV - CLear oVerflo **/
  482. INSTRUCTION(CLVnP)
  483. {
  484. TRACEi(("CLV"));
  485. cpu->reg_P &= ~Q6502_V_FLAG;
  486. }
  487. /** EA : NOP - NO oPeration **/
  488. INSTRUCTION(NOPnP)
  489. {
  490. TRACEi(("NOP"));
  491. }
  492. /**** Load/Store functions ****/
  493. /** A9 : LDA #$xx - LoaD an immediate value into A */
  494. INSTRUCTION(LDAiM)
  495. {
  496. TRACEi(("LDA #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  497. cpu->reg_A = cpu->memory_opcode_read(cpu->reg_PC++);
  498. NZ_FLAG_UPDATE(cpu->reg_A);
  499. }
  500. /** A2 : LDX #$xx - LoaD an immediate value into X */
  501. INSTRUCTION(LDXiM)
  502. {
  503. TRACEi(("LDX #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  504. cpu->reg_X = cpu->memory_opcode_read(cpu->reg_PC++);
  505. NZ_FLAG_UPDATE(cpu->reg_X);
  506. }
  507. /** A0 : LDY #$xx - LoaD an immediate value into Y */
  508. INSTRUCTION(LDYiM)
  509. {
  510. TRACEi(("LDY #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  511. cpu->reg_Y = cpu->memory_opcode_read(cpu->reg_PC++);
  512. NZ_FLAG_UPDATE(cpu->reg_Y);
  513. }
  514. /** A5: LDA $xx - LoaD to A from zero page **/
  515. INSTRUCTION(LDAzP)
  516. {
  517. TRACEi(("LDA $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  518. cpu->reg_A = MEMORY_READ_ZP();
  519. NZ_FLAG_UPDATE(cpu->reg_A);
  520. }
  521. /** B5: LDA $xx,X - LoaD to A **/
  522. INSTRUCTION(LDAzX)
  523. {
  524. TRACEi(("LDA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  525. cpu->reg_A = MEMORY_READ_ZX();
  526. NZ_FLAG_UPDATE(cpu->reg_A);
  527. }
  528. /** A1: LDA ($xx,X) - LoaD to A **/
  529. INSTRUCTION(LDAiX)
  530. {
  531. TRACEi(("LDA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC)));
  532. cpu->reg_A = MEMORY_READ_IX();
  533. NZ_FLAG_UPDATE(cpu->reg_A);
  534. }
  535. /** B1: LDA ($xx),Y - LoaD to A **/
  536. INSTRUCTION(LDAiY)
  537. {
  538. TRACEi(("LDA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC)));
  539. cpu->reg_A = MEMORY_READ_IY();
  540. NZ_FLAG_UPDATE(cpu->reg_A);
  541. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  542. }
  543. /** AD: LDA $xxxx - LoaD to A **/
  544. INSTRUCTION(LDAaB)
  545. {
  546. TRACEi(("LDA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  547. cpu->reg_A = MEMORY_READ_AB();
  548. NZ_FLAG_UPDATE(cpu->reg_A);
  549. }
  550. /** DD: LDA $xxxx,X - LoaD to A **/
  551. INSTRUCTION(LDAaX)
  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(("LDA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  556. cpu->reg_A = MEMORY_READ_AX();
  557. NZ_FLAG_UPDATE(cpu->reg_A);
  558. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  559. }
  560. /** D9: LDA $xxxx,Y - LoaD to A **/
  561. INSTRUCTION(LDAaY)
  562. {
  563. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  564. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  565. cpu->reg_A = MEMORY_READ_AY();
  566. NZ_FLAG_UPDATE(cpu->reg_A);
  567. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  568. }
  569. /** 85: STA $xx - STore A to zero page **/
  570. INSTRUCTION(STAzP)
  571. {
  572. TRACEi(("STA $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  573. cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_A);
  574. }
  575. /** 95: STA $xx,X - STore A **/
  576. INSTRUCTION(STAzX)
  577. {
  578. TRACEi(("STA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  579. MEMORY_WRITE_ZX(cpu->reg_A);
  580. }
  581. /** 81: STA ($xx,X) - STore A **/
  582. INSTRUCTION(STAiX)
  583. {
  584. TRACEi(("STA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC)));
  585. MEMORY_WRITE_IX(cpu->reg_A);
  586. }
  587. /** 91: STA ($xx),Y - STore A **/
  588. INSTRUCTION(STAiY)
  589. {
  590. TRACEi(("STA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC)));
  591. MEMORY_WRITE_IY(cpu->reg_A);
  592. }
  593. /** 8D: STA $xxxx - STore A **/
  594. INSTRUCTION(STAaB)
  595. {
  596. TRACEi(("STA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  597. MEMORY_WRITE_AB(cpu->reg_A);
  598. }
  599. /** 9D: STA $xxxx,X - STore A **/
  600. INSTRUCTION(STAaX)
  601. {
  602. TRACEi(("STA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  603. MEMORY_WRITE_AX(cpu->reg_A);
  604. }
  605. /** 99: STA $xxxx,Y - STore A **/
  606. INSTRUCTION(STAaY)
  607. {
  608. TRACEi(("STA $%02X%02X,Y", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  609. MEMORY_WRITE_AY(cpu->reg_A);
  610. }
  611. /** A6: LDX $xx - LoaD to X from zero page **/
  612. INSTRUCTION(LDXzP)
  613. {
  614. TRACEi(("LDX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  615. cpu->reg_X = MEMORY_READ_ZP();
  616. NZ_FLAG_UPDATE(cpu->reg_X);
  617. }
  618. /** B6: LDX $xx,Y - LoaD to X **/
  619. INSTRUCTION(LDXzY)
  620. {
  621. TRACEi(("LDX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC)));
  622. cpu->reg_X = MEMORY_READ_ZY();
  623. NZ_FLAG_UPDATE(cpu->reg_X);
  624. }
  625. /** AE: LDX $xxxx - LoaD to X **/
  626. INSTRUCTION(LDXaB)
  627. {
  628. TRACEi(("LDX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  629. cpu->reg_X = MEMORY_READ_AB();
  630. NZ_FLAG_UPDATE(cpu->reg_X);
  631. }
  632. /** BE: LDX $xxxx,Y - LoaD to X **/
  633. INSTRUCTION(LDXaY)
  634. {
  635. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  636. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  637. TRACEi(("LDX $%02X%02X,Y", op2, op1));
  638. cpu->reg_X = MEMORY_READ_AY();
  639. NZ_FLAG_UPDATE(cpu->reg_X);
  640. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  641. }
  642. /** B6: STX $xx - STore X to zero page **/
  643. INSTRUCTION(STXzP)
  644. {
  645. TRACEi(("STX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  646. cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_X);
  647. }
  648. /** 96: STX $xx,Y - STore X **/
  649. INSTRUCTION(STXzY)
  650. {
  651. TRACEi(("STX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC)));
  652. MEMORY_WRITE_ZY(cpu->reg_X);
  653. }
  654. /** 8E: STX $xxxx - STore X **/
  655. INSTRUCTION(STXaB)
  656. {
  657. TRACEi(("STX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  658. MEMORY_WRITE_AB(cpu->reg_X);
  659. }
  660. /** A4: LDY $xx - LoaD to Y from zero page **/
  661. INSTRUCTION(LDYzP)
  662. {
  663. TRACEi(("LDY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  664. cpu->reg_Y = MEMORY_READ_ZP();
  665. NZ_FLAG_UPDATE(cpu->reg_Y);
  666. }
  667. /** B4: LDY $xx,X - LoaD to Y **/
  668. INSTRUCTION(LDYzX)
  669. {
  670. TRACEi(("LDY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  671. cpu->reg_Y = MEMORY_READ_ZX();
  672. NZ_FLAG_UPDATE(cpu->reg_Y);
  673. }
  674. /** AC: LDY $xxxx - LoaD to Y **/
  675. INSTRUCTION(LDYaB)
  676. {
  677. TRACEi(("LDY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  678. cpu->reg_Y = MEMORY_READ_AB();
  679. NZ_FLAG_UPDATE(cpu->reg_Y);
  680. }
  681. /** BC: LDY $xxxx,X - LoaD to Y **/
  682. INSTRUCTION(LDYaX)
  683. {
  684. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  685. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  686. TRACEi(("LDY $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  687. cpu->reg_Y = MEMORY_READ_AX();
  688. NZ_FLAG_UPDATE(cpu->reg_Y);
  689. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  690. }
  691. /** 84: STY $xx - STore Y to zero page **/
  692. INSTRUCTION(STYzP)
  693. {
  694. TRACEi(("STY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  695. cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_Y);
  696. }
  697. /** 94: STY $xx,X - STore Y **/
  698. INSTRUCTION(STYzX)
  699. {
  700. TRACEi(("STY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  701. MEMORY_WRITE_ZX(cpu->reg_Y);
  702. }
  703. /** 8C: STY $xxxx - STore Y **/
  704. INSTRUCTION(STYaB)
  705. {
  706. TRACEi(("STY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  707. MEMORY_WRITE_AB(cpu->reg_Y);
  708. }
  709. /**** Register functions ****/
  710. /** AA : TAX - Transfer A to X **/
  711. INSTRUCTION(TAXnP)
  712. {
  713. TRACEi(("TAX"));
  714. cpu->reg_X = cpu->reg_A;
  715. NZ_FLAG_UPDATE(cpu->reg_X);
  716. }
  717. /** 8A : TXA - Transfer X to A **/
  718. INSTRUCTION(TXAnP)
  719. {
  720. TRACEi(("TXA"));
  721. cpu->reg_A = cpu->reg_X;
  722. NZ_FLAG_UPDATE(cpu->reg_A);
  723. }
  724. /** A8 : TAY - Transfer A to Y **/
  725. INSTRUCTION(TAYnP)
  726. {
  727. TRACEi(("TAY"));
  728. cpu->reg_Y = cpu->reg_A;
  729. NZ_FLAG_UPDATE(cpu->reg_Y);
  730. }
  731. /** 98 : TYA - Transfer Y to A **/
  732. INSTRUCTION(TYAnP)
  733. {
  734. TRACEi(("TYA"));
  735. cpu->reg_A = cpu->reg_Y;
  736. NZ_FLAG_UPDATE(cpu->reg_A);
  737. }
  738. /* BA : TSX - Transfer S to X **/
  739. INSTRUCTION(TSXnP)
  740. {
  741. TRACEi(("TSX"));
  742. cpu->reg_X = cpu->reg_S;
  743. NZ_FLAG_UPDATE(cpu->reg_X);
  744. }
  745. /** 9A : TXS - Transfer X to S **/
  746. INSTRUCTION(TXSnP)
  747. {
  748. TRACEi(("TXS"));
  749. cpu->reg_S = cpu->reg_X;
  750. }
  751. /**** Simple register operation instructions ****/
  752. /** CA : DEX - DEcrement X **/
  753. INSTRUCTION(DEXnP)
  754. {
  755. TRACEi(("DEX"));
  756. cpu->reg_X --;
  757. NZ_FLAG_UPDATE(cpu->reg_X);
  758. }
  759. /** 88 : DEY - DEcrement Y **/
  760. INSTRUCTION(DEYnP)
  761. {
  762. TRACEi(("DEY"));
  763. cpu->reg_Y --;
  764. NZ_FLAG_UPDATE(cpu->reg_Y);
  765. }
  766. /** E8 : INX - INcrement X **/
  767. INSTRUCTION(INXnP)
  768. {
  769. TRACEi(("INX"));
  770. cpu->reg_X ++;
  771. NZ_FLAG_UPDATE(cpu->reg_X);
  772. }
  773. /** C8 : INY - INcrement Y **/
  774. INSTRUCTION(INYnP)
  775. {
  776. TRACEi(("INY"));
  777. cpu->reg_Y ++;
  778. NZ_FLAG_UPDATE(cpu->reg_Y);
  779. }
  780. /**** Stack related instructions ****/
  781. /** 48 : PHA - PusH A */
  782. INSTRUCTION(PHAnP)
  783. {
  784. TRACEi(("PHA"));
  785. PUSH_S(cpu->reg_A);
  786. }
  787. /** 68 : PLA - PuLl A */
  788. INSTRUCTION(PLAnP)
  789. {
  790. TRACEi(("PLA"));
  791. cpu->reg_A = POP_S();
  792. NZ_FLAG_UPDATE(cpu->reg_A);
  793. }
  794. /** 08 : PHP - PusH P */
  795. INSTRUCTION(PHPnP)
  796. {
  797. TRACEi(("PHP"));
  798. PUSH_S((cpu->reg_P | Q6502_R_FLAG | Q6502_B_FLAG));
  799. }
  800. /** 28 : PLP - PuLl P */
  801. INSTRUCTION(PLPnP)
  802. {
  803. TRACEi(("PLP"));
  804. cpu->reg_P = POP_S() & ~(Q6502_R_FLAG | Q6502_B_FLAG);
  805. if (cpu->int_pending != 0)
  806. {
  807. quick6502_int(cpu, Q6502_IRQ_SIGNAL);
  808. }
  809. }
  810. /**** Branch instructions ****/
  811. /** 20 : JSR $xxxx - Jump to SubRoutine */
  812. INSTRUCTION(JSRaB)
  813. {
  814. TRACEi(("JSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  815. cpu->reg_PC++;
  816. PUSH_S((cpu->reg_PC >> 8) & 0xFF);
  817. PUSH_S((cpu->reg_PC ) & 0xFF);
  818. cpu->reg_PC = ((cpu->memory_opcode_read(cpu->reg_PC-1) ) | (cpu->memory_opcode_read(cpu->reg_PC) << 8));
  819. }
  820. /** 60 : RTS - ReTurn from Subrutine */
  821. INSTRUCTION(RTSnP)
  822. {
  823. TRACEi(("RTS"));
  824. cpu->reg_PC = POP_S();
  825. cpu->reg_PC |= (POP_S() << 8);
  826. cpu->reg_PC ++;
  827. }
  828. /** 4C : JMP $xxxx - JuMP inconditionaly to $xxxx **/
  829. INSTRUCTION(JMPaB)
  830. {
  831. TRACEi(("JMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  832. cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC) | (cpu->memory_opcode_read(cpu->reg_PC+1) << 8);
  833. }
  834. /** 6C : JMP ($xxxx) - JuMP inconditionaly to ($xxxx) **/
  835. INSTRUCTION(JMPiD)
  836. {
  837. TRACEi(("JMP ($%02X%02X)", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  838. cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC) | (cpu->memory_opcode_read(cpu->reg_PC+1) << 8);
  839. cpu->reg_PC = cpu->memory_read(cpu->reg_PC) |
  840. (cpu->memory_read((cpu->reg_PC & 0xFF00) | ((cpu->reg_PC+1) & 0x00FF)) << 8);
  841. }
  842. /** 00 : BRK - BReaK **/
  843. INSTRUCTION(BRKnP)
  844. {
  845. TRACEi(("BRK"));
  846. cpu->reg_PC++;
  847. PUSH_S((cpu->reg_PC >> 8) & 0xFF);
  848. PUSH_S((cpu->reg_PC ) & 0xFF);
  849. PUSH_S( cpu->reg_P );
  850. cpu->reg_P = cpu->reg_P | Q6502_I_FLAG | Q6502_B_FLAG;
  851. cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8);
  852. }
  853. /** 40 : RTI - ReTurn from Interruption **/
  854. INSTRUCTION(RTInP)
  855. {
  856. TRACEi(("RTI"));
  857. cpu->reg_P = POP_S();
  858. cpu->reg_PC = POP_S();
  859. cpu->reg_PC |= (POP_S() << 8);
  860. if (cpu->int_pending != 0)
  861. {
  862. quick6502_int(cpu, Q6502_IRQ_SIGNAL);
  863. }
  864. }
  865. /** 90 : BCC - Branch if Carry Clear **/
  866. INSTRUCTION(BCCrE)
  867. {
  868. TRACEi(("BCC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  869. if (!(cpu->reg_P & Q6502_C_FLAG))
  870. {
  871. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  872. /* Need to set timing */
  873. /* +1 is same page */
  874. cpu->cycle_done += 1;
  875. /* +2 is another */
  876. }
  877. else
  878. cpu->reg_PC ++;
  879. }
  880. /** B0 : BCS - Branch if Carry Set**/
  881. INSTRUCTION(BCSrE)
  882. {
  883. TRACEi(("BCS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  884. if (cpu->reg_P & Q6502_C_FLAG)
  885. {
  886. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  887. /* Need to set timing */
  888. /* +1 is same page */
  889. cpu->cycle_done += 1;
  890. /* +2 is another */
  891. }
  892. else
  893. cpu->reg_PC ++;
  894. }
  895. /** F0 : BEQ - Branch if Equal**/
  896. INSTRUCTION(BEQrE)
  897. {
  898. TRACEi(("BEQ $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  899. if (cpu->reg_P & Q6502_Z_FLAG)
  900. {
  901. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  902. /* Need to set timing */
  903. /* +1 is same page */
  904. cpu->cycle_done += 1;
  905. /* +2 is another */
  906. }
  907. else
  908. cpu->reg_PC ++;
  909. }
  910. /** 30 : BMI - Branch if MInus**/
  911. INSTRUCTION(BMIrE)
  912. {
  913. TRACEi(("BMI $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  914. if (cpu->reg_P & Q6502_N_FLAG)
  915. {
  916. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  917. /* Need to set timing */
  918. /* +1 is same page */
  919. cpu->cycle_done += 1;
  920. /* +2 is another */
  921. }
  922. else
  923. cpu->reg_PC ++;
  924. }
  925. /** D0 : Bxx - Branch if Not Equal**/
  926. INSTRUCTION(BNErE)
  927. {
  928. TRACEi(("BNE $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  929. if (!(cpu->reg_P & Q6502_Z_FLAG))
  930. {
  931. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  932. /* Need to set timing */
  933. /* +1 is same page */
  934. cpu->cycle_done += 1;
  935. /* +2 is another */
  936. }
  937. else
  938. cpu->reg_PC ++;
  939. }
  940. /** 10 : BPL - Branch if PLus **/
  941. INSTRUCTION(BPLrE)
  942. {
  943. TRACEi(("BPL $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  944. if (!(cpu->reg_P & Q6502_N_FLAG))
  945. {
  946. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  947. /* Need to set timing */
  948. /* +1 is same page */
  949. cpu->cycle_done += 1;
  950. /* +2 is another */
  951. }
  952. else
  953. cpu->reg_PC ++;
  954. }
  955. /** 50 : BVC - Branch if oVerflow Clear**/
  956. INSTRUCTION(BVCrE)
  957. {
  958. TRACEi(("BVC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  959. if (!(cpu->reg_P & Q6502_V_FLAG))
  960. {
  961. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  962. /* Need to set timing */
  963. /* +1 is same page */
  964. cpu->cycle_done += 1;
  965. /* +2 is another */
  966. }
  967. else
  968. cpu->reg_PC ++;
  969. }
  970. /** 70 : BVS - Branch if oVerflow Set**/
  971. INSTRUCTION(BVSrE)
  972. {
  973. TRACEi(("BVS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
  974. if (cpu->reg_P & Q6502_V_FLAG)
  975. {
  976. cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
  977. /* Need to set timing */
  978. /* +1 is same page */
  979. cpu->cycle_done += 1;
  980. /* +2 is another */
  981. }
  982. else
  983. cpu->reg_PC ++;
  984. }
  985. /*** Mathematical functions ***/
  986. /** 69 : ADC - ADd with Carry **/
  987. INSTRUCTION(ADCiM)
  988. {
  989. TRACEi(("ADC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  990. ADC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  991. }
  992. /** 65 : ADC - ADd with Carry **/
  993. INSTRUCTION(ADCzP)
  994. {
  995. TRACEi(("ADC $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  996. ADC_OPERATION(MEMORY_READ_ZP());
  997. }
  998. /** 75 : ADC - ADd with Carry **/
  999. INSTRUCTION(ADCzX)
  1000. {
  1001. TRACEi(("ADC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1002. ADC_OPERATION(MEMORY_READ_ZX());
  1003. }
  1004. /** 61 : ADC - ADd with Carry **/
  1005. INSTRUCTION(ADCiX)
  1006. {
  1007. TRACEi(("ADC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1008. ADC_OPERATION(MEMORY_READ_IX());
  1009. }
  1010. /** 71 : ADC - ADd with Carry **/
  1011. INSTRUCTION(ADCiY)
  1012. {
  1013. TRACEi(("ADC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1014. ADC_OPERATION(MEMORY_READ_IY());
  1015. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1016. }
  1017. /** 6D : ADC - ADd with Carry **/
  1018. INSTRUCTION(ADCaB)
  1019. {
  1020. TRACEi(("ADC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1021. ADC_OPERATION(MEMORY_READ_AB());
  1022. }
  1023. /** 7D : ADC - ADd with Carry **/
  1024. INSTRUCTION(ADCaX)
  1025. {
  1026. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1027. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1028. TRACEi(("ADC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1029. ADC_OPERATION(MEMORY_READ_AX());
  1030. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1031. }
  1032. /** 79 : ADC - ADd with Carry **/
  1033. INSTRUCTION(ADCaY)
  1034. {
  1035. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1036. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1037. TRACEi(("ADC $%02X%02X,Y", op2, op1));
  1038. ADC_OPERATION(MEMORY_READ_AY());
  1039. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1040. }
  1041. /** E9 : SBC - SuBstract with Carry **/
  1042. INSTRUCTION(SBCiM)
  1043. {
  1044. TRACEi(("SBC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1045. SBC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1046. }
  1047. /** E5 : SBC - SuBstract with Carry **/
  1048. INSTRUCTION(SBCzP)
  1049. {
  1050. TRACEi(("SBC $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1051. SBC_OPERATION(MEMORY_READ_ZP());
  1052. }
  1053. /** F5 : SBC - SuBstract with Carry **/
  1054. INSTRUCTION(SBCzX)
  1055. {
  1056. TRACEi(("SBC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1057. SBC_OPERATION(MEMORY_READ_ZX());
  1058. }
  1059. /** E1 : SBC - SuBstract with Carry **/
  1060. INSTRUCTION(SBCiX)
  1061. {
  1062. TRACEi(("SBC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1063. SBC_OPERATION(MEMORY_READ_IX());
  1064. }
  1065. /** F1 : SBC - SuBstract with Carry **/
  1066. INSTRUCTION(SBCiY)
  1067. {
  1068. TRACEi(("SBC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1069. SBC_OPERATION(MEMORY_READ_IY());
  1070. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1071. }
  1072. /** ED : SBC - SuBstract with Carry **/
  1073. INSTRUCTION(SBCaB)
  1074. {
  1075. TRACEi(("SBC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1076. SBC_OPERATION(MEMORY_READ_AB());
  1077. }
  1078. /** FD : SBC - SuBstract with Carry **/
  1079. INSTRUCTION(SBCaX)
  1080. {
  1081. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1082. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1083. TRACEi(("SBC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1084. SBC_OPERATION(MEMORY_READ_AX());
  1085. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1086. }
  1087. /** F9 : SBC - SuBstract with Carry **/
  1088. INSTRUCTION(SBCaY)
  1089. {
  1090. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1091. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1092. TRACEi(("SBC $%02X%02X,Y", op2, op1));
  1093. SBC_OPERATION(MEMORY_READ_AY());
  1094. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1095. }
  1096. /** C9 : CMP - CoMPare **/
  1097. INSTRUCTION(CMPiM)
  1098. {
  1099. TRACEi(("CMP #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1100. CMP_OPERATION(cpu->reg_A, cpu->memory_opcode_read(cpu->reg_PC++));
  1101. }
  1102. /** C5 : CMP - CoMPare **/
  1103. INSTRUCTION(CMPzP)
  1104. {
  1105. TRACEi(("CMP $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1106. CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZP());
  1107. }
  1108. /** D5 : CMP - CoMPare **/
  1109. INSTRUCTION(CMPzX)
  1110. {
  1111. TRACEi(("CMP $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1112. CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZX());
  1113. }
  1114. /** C1 : CMP - CoMPare **/
  1115. INSTRUCTION(CMPiX)
  1116. {
  1117. TRACEi(("CMP ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1118. CMP_OPERATION(cpu->reg_A, MEMORY_READ_IX());
  1119. }
  1120. /** D1 : CMP - CoMPare **/
  1121. INSTRUCTION(CMPiY)
  1122. {
  1123. TRACEi(("CMP ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1124. CMP_OPERATION(cpu->reg_A, MEMORY_READ_IY());
  1125. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1126. }
  1127. /** CD : CMP - CoMPare **/
  1128. INSTRUCTION(CMPaB)
  1129. {
  1130. TRACEi(("CMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1131. CMP_OPERATION(cpu->reg_A, MEMORY_READ_AB());
  1132. }
  1133. /** DD : CMP - CoMPare **/
  1134. INSTRUCTION(CMPaX)
  1135. {
  1136. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1137. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1138. TRACEi(("CMP $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1139. CMP_OPERATION(cpu->reg_A, MEMORY_READ_AX());
  1140. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1141. }
  1142. /** D9 : CMP - CoMPare **/
  1143. INSTRUCTION(CMPaY)
  1144. {
  1145. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1146. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1147. TRACEi(("CMP $%02X%02X,Y", op2, op1));
  1148. CMP_OPERATION(cpu->reg_A, MEMORY_READ_AY());
  1149. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1150. }
  1151. /** E0 : CPX - ComPare with Y **/
  1152. INSTRUCTION(CPXiM)
  1153. {
  1154. TRACEi(("CPX #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1155. CMP_OPERATION(cpu->reg_X, cpu->memory_opcode_read(cpu->reg_PC++));
  1156. }
  1157. /** E4 : CPX - ComPare with X **/
  1158. INSTRUCTION(CPXzP)
  1159. {
  1160. TRACEi(("CPX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1161. CMP_OPERATION(cpu->reg_X, MEMORY_READ_ZP());
  1162. }
  1163. /** EC : CPX - ComPare with X **/
  1164. INSTRUCTION(CPXaB)
  1165. {
  1166. TRACEi(("CPX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1167. CMP_OPERATION(cpu->reg_X, MEMORY_READ_AB());
  1168. }
  1169. /** C0 : CPY - ComPare with Y **/
  1170. INSTRUCTION(CPYiM)
  1171. {
  1172. TRACEi(("CPY #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1173. CMP_OPERATION(cpu->reg_Y, cpu->memory_opcode_read(cpu->reg_PC++));
  1174. }
  1175. /** C4 : CPY - ComPare with Y **/
  1176. INSTRUCTION(CPYzP)
  1177. {
  1178. TRACEi(("CPY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1179. CMP_OPERATION(cpu->reg_Y, MEMORY_READ_ZP());
  1180. }
  1181. /** CC : CPY - ComPare with Y **/
  1182. INSTRUCTION(CPYaB)
  1183. {
  1184. TRACEi(("CPY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1185. CMP_OPERATION(cpu->reg_Y, MEMORY_READ_AB());
  1186. }
  1187. /** 09 : ORA - OR with A **/
  1188. INSTRUCTION(ORAiM)
  1189. {
  1190. TRACEi(("ORA #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1191. ORA_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1192. }
  1193. /** 405 : ORA - OR with A **/
  1194. INSTRUCTION(ORAzP)
  1195. {
  1196. TRACEi(("ORA $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1197. ORA_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
  1198. }
  1199. /** 15 : ORA - OR with A **/
  1200. INSTRUCTION(ORAzX)
  1201. {
  1202. TRACEi(("ORA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1203. ORA_OPERATION(MEMORY_READ_ZX());
  1204. }
  1205. /** 01 : ORA - OR with A **/
  1206. INSTRUCTION(ORAiX)
  1207. {
  1208. TRACEi(("ORA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1209. ORA_OPERATION(MEMORY_READ_IX());
  1210. }
  1211. /** 11 : ORA - OR with A **/
  1212. INSTRUCTION(ORAiY)
  1213. {
  1214. TRACEi(("ORA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1215. ORA_OPERATION(MEMORY_READ_IY());
  1216. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1217. }
  1218. /** 0D : ORA - OR with A **/
  1219. INSTRUCTION(ORAaB)
  1220. {
  1221. TRACEi(("ORA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1222. ORA_OPERATION(MEMORY_READ_AB());
  1223. }
  1224. /** 1D : ORA - OR with A **/
  1225. INSTRUCTION(ORAaX)
  1226. {
  1227. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1228. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1229. TRACEi(("ORA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1230. ORA_OPERATION(MEMORY_READ_AX());
  1231. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1232. }
  1233. /** 19 : ORA - OR with A **/
  1234. INSTRUCTION(ORAaY)
  1235. {
  1236. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1237. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1238. TRACEi(("ORA $%02X%02X,Y", op2, op1));
  1239. ORA_OPERATION(MEMORY_READ_AY());
  1240. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1241. }
  1242. /** 49 : EOR - Exclusive OR **/
  1243. INSTRUCTION(EORiM)
  1244. {
  1245. TRACEi(("EOR #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1246. EOR_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1247. }
  1248. /** 45 : EOR - Exclusive OR **/
  1249. INSTRUCTION(EORzP)
  1250. {
  1251. TRACEi(("EOR $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1252. EOR_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
  1253. }
  1254. /** 55 : EOR - Exclusive OR **/
  1255. INSTRUCTION(EORzX)
  1256. {
  1257. TRACEi(("EOR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1258. EOR_OPERATION(MEMORY_READ_ZX());
  1259. }
  1260. /** 41 : EOR - Exclusive OR **/
  1261. INSTRUCTION(EORiX)
  1262. {
  1263. TRACEi(("EOR ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1264. EOR_OPERATION(MEMORY_READ_IX());
  1265. }
  1266. /** 51 : EOR - Exclusive OR **/
  1267. INSTRUCTION(EORiY)
  1268. {
  1269. TRACEi(("EOR ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1270. EOR_OPERATION(MEMORY_READ_IY());
  1271. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1272. }
  1273. /** 4D : EOR - Exclusive OR **/
  1274. INSTRUCTION(EORaB)
  1275. {
  1276. TRACEi(("EOR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1277. EOR_OPERATION(MEMORY_READ_AB());
  1278. }
  1279. /** 5D : EOR - Exclusive OR **/
  1280. INSTRUCTION(EORaX)
  1281. {
  1282. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1283. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1284. TRACEi(("EOR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1285. EOR_OPERATION(MEMORY_READ_AX());
  1286. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1287. }
  1288. /** 59 : EOR - Exclusive OR **/
  1289. INSTRUCTION(EORaY)
  1290. {
  1291. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1292. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1293. TRACEi(("EOR $%02X%02X,Y", op2, op1));
  1294. EOR_OPERATION(MEMORY_READ_AY());
  1295. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1296. }
  1297. /** 29 : AND - Logical AND **/
  1298. INSTRUCTION(ANDiM)
  1299. {
  1300. TRACEi(("AND #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1301. AND_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
  1302. }
  1303. /** 25 : AND - Logical AND **/
  1304. INSTRUCTION(ANDzP)
  1305. {
  1306. TRACEi(("AND $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1307. AND_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
  1308. }
  1309. /** 35 : AND - Logical AND **/
  1310. INSTRUCTION(ANDzX)
  1311. {
  1312. TRACEi(("AND $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
  1313. AND_OPERATION(MEMORY_READ_ZX());
  1314. }
  1315. /** 21 : AND - Logical AND **/
  1316. INSTRUCTION(ANDiX)
  1317. {
  1318. TRACEi(("AND ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
  1319. AND_OPERATION(MEMORY_READ_IX());
  1320. }
  1321. /** 31 : AND - Logical AND **/
  1322. INSTRUCTION(ANDiY)
  1323. {
  1324. TRACEi(("AND ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
  1325. AND_OPERATION(MEMORY_READ_IY());
  1326. CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
  1327. }
  1328. /** 2D : AND - Logical AND **/
  1329. INSTRUCTION(ANDaB)
  1330. {
  1331. TRACEi(("AND $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1332. AND_OPERATION(MEMORY_READ_AB());
  1333. }
  1334. /** 3D : AND - Logical AND **/
  1335. INSTRUCTION(ANDaX)
  1336. {
  1337. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1338. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1339. TRACEi(("AND $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1340. AND_OPERATION(MEMORY_READ_AX());
  1341. CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
  1342. }
  1343. /** 39 : AND - Logical AND **/
  1344. INSTRUCTION(ANDaY)
  1345. {
  1346. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1347. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1348. TRACEi(("AND $%02X%02X,Y", op2, op1));
  1349. AND_OPERATION(MEMORY_READ_AY());
  1350. CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
  1351. }
  1352. /*** Misc instructions ***/
  1353. /** 24 : BIT **/
  1354. INSTRUCTION(BITzP)
  1355. {
  1356. TRACEi(("BIT $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1357. BIT_OPERATION(MEMORY_READ_ZP());
  1358. }
  1359. /** 2C : BIT **/
  1360. INSTRUCTION(BITaB)
  1361. {
  1362. TRACEi(("BIT $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1363. BIT_OPERATION(MEMORY_READ_AB());
  1364. }
  1365. /** 2A : ROL A **/
  1366. INSTRUCTION(ROLnP)
  1367. {
  1368. TRACEi(("ROL A"));
  1369. ROL_OPERATION(cpu->reg_A);
  1370. }
  1371. /** 6A : ROR A **/
  1372. INSTRUCTION(RORnP)
  1373. {
  1374. TRACEi(("ROR A"));
  1375. ROR_OPERATION(cpu->reg_A);
  1376. }
  1377. /** 0A : ASL A **/
  1378. INSTRUCTION(ASLnP)
  1379. {
  1380. TRACEi(("ASL A"));
  1381. ASL_OPERATION(cpu->reg_A);
  1382. }
  1383. /** 4A : LSR A **/
  1384. INSTRUCTION(LSRnP)
  1385. {
  1386. TRACEi(("LSR A"));
  1387. LSR_OPERATION(cpu->reg_A);
  1388. }
  1389. /** 2E : ROL **/
  1390. INSTRUCTION(ROLaB)
  1391. {
  1392. TRACEi(("ROL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1393. byte val = MEMORY_READ_AB();
  1394. cpu->reg_PC -= 2;
  1395. ROL_OPERATION(val);
  1396. MEMORY_WRITE_AB(val);
  1397. }
  1398. /** 26 : ROL **/
  1399. INSTRUCTION(ROLzP)
  1400. {
  1401. TRACEi(("ROL $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1402. byte val = MEMORY_READ_ZP();
  1403. cpu->reg_PC -= 1;
  1404. ROL_OPERATION(val);
  1405. MEMORY_WRITE_ZP(val);
  1406. }
  1407. /** 3E : ROL **/
  1408. INSTRUCTION(ROLaX)
  1409. {
  1410. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1411. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1412. TRACEi(("ROL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1413. byte val = MEMORY_READ_AX();
  1414. cpu->reg_PC -= 2;
  1415. ROL_OPERATION(val);
  1416. MEMORY_WRITE_AX(val);
  1417. }
  1418. /** 36 : ROL **/
  1419. INSTRUCTION(ROLzX)
  1420. {
  1421. TRACEi(("ROL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1422. byte val = MEMORY_READ_ZX();
  1423. cpu->reg_PC -= 1;
  1424. ROL_OPERATION(val);
  1425. MEMORY_WRITE_ZX(val);
  1426. }
  1427. /** 6E : ROR **/
  1428. INSTRUCTION(RORaB)
  1429. {
  1430. TRACEi(("ROR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1431. byte val = MEMORY_READ_AB();
  1432. cpu->reg_PC -= 2;
  1433. ROR_OPERATION(val);
  1434. MEMORY_WRITE_AB(val);
  1435. }
  1436. /** 66 : ROR **/
  1437. INSTRUCTION(RORzP)
  1438. {
  1439. TRACEi(("ROR $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1440. byte val = MEMORY_READ_ZP();
  1441. cpu->reg_PC -= 1;
  1442. ROR_OPERATION(val);
  1443. MEMORY_WRITE_ZP(val);
  1444. }
  1445. /** 7E : ROR **/
  1446. INSTRUCTION(RORaX)
  1447. {
  1448. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1449. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1450. TRACEi(("ROR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1451. byte val = MEMORY_READ_AX();
  1452. cpu->reg_PC -= 2;
  1453. ROR_OPERATION(val);
  1454. MEMORY_WRITE_AX(val);
  1455. }
  1456. /** 76 : ROR **/
  1457. INSTRUCTION(RORzX)
  1458. {
  1459. TRACEi(("ROR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1460. byte val = MEMORY_READ_ZX();
  1461. cpu->reg_PC -= 1;
  1462. ROR_OPERATION(val);
  1463. MEMORY_WRITE_ZX(val);
  1464. }
  1465. /** 0E : ASL **/
  1466. INSTRUCTION(ASLaB)
  1467. {
  1468. TRACEi(("ASL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1469. byte val = MEMORY_READ_AB();
  1470. cpu->reg_PC -= 2;
  1471. ASL_OPERATION(val);
  1472. MEMORY_WRITE_AB(val);
  1473. }
  1474. /** 06 : ASL **/
  1475. INSTRUCTION(ASLzP)
  1476. {
  1477. TRACEi(("ASL $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1478. byte val = MEMORY_READ_ZP();
  1479. cpu->reg_PC -= 1;
  1480. ASL_OPERATION(val);
  1481. MEMORY_WRITE_ZP(val);
  1482. }
  1483. /** 1E : ASL **/
  1484. INSTRUCTION(ASLaX)
  1485. {
  1486. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1487. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1488. TRACEi(("ASL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1489. byte val = MEMORY_READ_AX();
  1490. cpu->reg_PC -= 2;
  1491. ASL_OPERATION(val);
  1492. MEMORY_WRITE_AX(val);
  1493. }
  1494. /** 16 : ASL **/
  1495. INSTRUCTION(ASLzX)
  1496. {
  1497. TRACEi(("ASL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1498. byte val = MEMORY_READ_ZX();
  1499. cpu->reg_PC -= 1;
  1500. ASL_OPERATION(val);
  1501. MEMORY_WRITE_ZX(val);
  1502. }
  1503. /** 4E : LSR **/
  1504. INSTRUCTION(LSRaB)
  1505. {
  1506. TRACEi(("LSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1507. byte val = MEMORY_READ_AB();
  1508. cpu->reg_PC -= 2;
  1509. LSR_OPERATION(val);
  1510. MEMORY_WRITE_AB(val);
  1511. }
  1512. /** 46 : LSR **/
  1513. INSTRUCTION(LSRzP)
  1514. {
  1515. TRACEi(("LSR $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1516. byte val = MEMORY_READ_ZP();
  1517. cpu->reg_PC -= 1;
  1518. LSR_OPERATION(val);
  1519. MEMORY_WRITE_ZP(val);
  1520. }
  1521. /** 5E : LSR **/
  1522. INSTRUCTION(LSRaX)
  1523. {
  1524. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1525. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1526. TRACEi(("LSR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1527. byte val = MEMORY_READ_AX();
  1528. cpu->reg_PC -= 2;
  1529. LSR_OPERATION(val);
  1530. MEMORY_WRITE_AX(val);
  1531. }
  1532. /** 56 : LSR **/
  1533. INSTRUCTION(LSRzX)
  1534. {
  1535. TRACEi(("LSR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1536. byte val = MEMORY_READ_ZX();
  1537. cpu->reg_PC -= 1;
  1538. LSR_OPERATION(val);
  1539. MEMORY_WRITE_ZX(val);
  1540. }
  1541. /** CE : DEC **/
  1542. INSTRUCTION(DECaB)
  1543. {
  1544. TRACEi(("DEC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1545. byte val = MEMORY_READ_AB();
  1546. cpu->reg_PC -= 2;
  1547. MEMORY_WRITE_AB(--val);
  1548. NZ_FLAG_UPDATE(val);
  1549. }
  1550. /** C6 : DEC **/
  1551. INSTRUCTION(DECzP)
  1552. {
  1553. TRACEi(("DEC $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1554. byte val = MEMORY_READ_ZP();
  1555. cpu->reg_PC -= 1;
  1556. MEMORY_WRITE_ZP(--val);
  1557. NZ_FLAG_UPDATE(val);
  1558. }
  1559. /** DE : DEC **/
  1560. INSTRUCTION(DECaX)
  1561. {
  1562. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1563. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1564. TRACEi(("DEC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1565. byte val = MEMORY_READ_AX();
  1566. cpu->reg_PC -= 2;
  1567. MEMORY_WRITE_AX(--val);
  1568. NZ_FLAG_UPDATE(val);
  1569. }
  1570. /** D6 : DEC **/
  1571. INSTRUCTION(DECzX)
  1572. {
  1573. TRACEi(("DEC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1574. byte val = MEMORY_READ_ZX();
  1575. cpu->reg_PC -= 1;
  1576. MEMORY_WRITE_ZX(--val);
  1577. NZ_FLAG_UPDATE(val);
  1578. }
  1579. /** EE : INC **/
  1580. INSTRUCTION(INCaB)
  1581. {
  1582. TRACEi(("INC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1583. byte val = MEMORY_READ_AB();
  1584. cpu->reg_PC -= 2;
  1585. MEMORY_WRITE_AB(++val);
  1586. NZ_FLAG_UPDATE(val);
  1587. }
  1588. /** E6 : INC **/
  1589. INSTRUCTION(INCzP)
  1590. {
  1591. TRACEi(("INC $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
  1592. byte val = MEMORY_READ_ZP();
  1593. cpu->reg_PC -= 1;
  1594. MEMORY_WRITE_ZP(++val);
  1595. NZ_FLAG_UPDATE(val);
  1596. }
  1597. /** FE : INC **/
  1598. INSTRUCTION(INCaX)
  1599. {
  1600. register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
  1601. register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
  1602. TRACEi(("INC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
  1603. byte val = MEMORY_READ_AX();
  1604. cpu->reg_PC -= 2;
  1605. MEMORY_WRITE_AX(++val);
  1606. NZ_FLAG_UPDATE(val);
  1607. }
  1608. /** F6 : INC **/
  1609. INSTRUCTION(INCzX)
  1610. {
  1611. TRACEi(("INC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
  1612. byte val = MEMORY_READ_ZX();
  1613. cpu->reg_PC -= 1;
  1614. MEMORY_WRITE_ZX(++val);
  1615. NZ_FLAG_UPDATE(val);
  1616. }
  1617. /* iM: Immediate
  1618. * iX: Indirect by X
  1619. * iY: Indirect by Y
  1620. * zP: Zero Page
  1621. * zX: Zero Page Indexec by X
  1622. * zY: Zero Page Indexec by Y
  1623. * iD: Indirect Double
  1624. * aB: Absolute
  1625. * aX: Absolute by X
  1626. * aY: Absolute by Y
  1627. */
  1628. static InstructionFunction InstructionTable[256] =
  1629. {
  1630. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1631. /* 00 */ I_BRKnP, I_ORAiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzP, I_ASLzP, I_ILLEG, I_PHPnP, I_ORAiM, I_ASLnP, I_ILLEG, I_ILLEG, I_ORAaB, I_ASLaB, I_ILLEG,
  1632. /* 10 */ I_BPLrE, I_ORAiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzX, I_ASLzX, I_ILLEG, I_CLCnP, I_ORAaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAaX, I_ASLaX, I_ILLEG,
  1633. /* 20 */ I_JSRaB, I_ANDiX, I_ILLEG, I_ILLEG, I_BITzP, I_ANDzP, I_ROLzP, I_ILLEG, I_PLPnP, I_ANDiM, I_ROLnP, I_ILLEG, I_BITaB, I_ANDaB, I_ROLaB, I_ILLEG,
  1634. /* 30 */ I_BMIrE, I_ANDiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDzX, I_ROLzX, I_ILLEG, I_SECnP, I_ANDaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDaX, I_ROLaX, I_ILLEG,
  1635. /* 40 */ I_RTInP, I_EORiX, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzP, I_LSRzP, I_ILLEG, I_PHAnP, I_EORiM, I_LSRnP, I_ILLEG, I_JMPaB, I_EORaB, I_LSRaB, I_ILLEG,
  1636. /* 50 */ I_BVCrE, I_EORiY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzX, I_LSRzX, I_ILLEG, I_CLInP, I_EORaY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORaX, I_LSRaX, I_ILLEG,
  1637. /* 60 */ I_RTSnP, I_ADCiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzP, I_RORzP, I_ILLEG, I_PLAnP, I_ADCiM, I_RORnP, I_ILLEG, I_JMPiD, I_ADCaB, I_RORaB, I_ILLEG,
  1638. /* 70 */ I_BVSrE, I_ADCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzX, I_RORzX, I_ILLEG, I_SEInP, I_ADCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCaX, I_RORaX, I_ILLEG,
  1639. /* 80 */ I_ILLEG, I_STAiX, I_ILLEG, I_ILLEG, I_STYzP, I_STAzP, I_STXzP, I_ILLEG, I_DEYnP, I_ILLEG, I_TXAnP, I_ILLEG, I_STYaB, I_STAaB, I_STXaB, I_ILLEG,
  1640. /* 90 */ I_BCCrE, I_STAiY, I_ILLEG, I_ILLEG, I_STYzX, I_STAzX, I_STXzY, I_ILLEG, I_TYAnP, I_STAaY, I_TXSnP, I_ILLEG, I_ILLEG, I_STAaX, I_ILLEG, I_ILLEG,
  1641. /* A0 */ I_LDYiM, I_LDAiX, I_LDXiM, I_ILLEG, I_LDYzP, I_LDAzP, I_LDXzP, I_ILLEG, I_TAYnP, I_LDAiM, I_TAXnP, I_ILLEG, I_LDYaB, I_LDAaB, I_LDXaB, I_ILLEG,
  1642. /* B0 */ I_BCSrE, I_LDAiY, I_ILLEG, I_ILLEG, I_LDYzX, I_LDAzX, I_LDXzY, I_ILLEG, I_CLVnP, I_LDAaY, I_TSXnP, I_ILLEG, I_LDYaX, I_LDAaX, I_LDXaY, I_ILLEG,
  1643. /* C0 */ I_CPYiM, I_CMPiX, I_ILLEG, I_ILLEG, I_CPYzP, I_CMPzP, I_DECzP, I_ILLEG, I_INYnP, I_CMPiM, I_DEXnP, I_ILLEG, I_CPYaB, I_CMPaB, I_DECaB, I_ILLEG,
  1644. /* D0 */ I_BNErE, I_CMPiY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPzX, I_DECzX, I_ILLEG, I_CLDnP, I_CMPaY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPaX, I_DECaX, I_ILLEG,
  1645. /* E0 */ I_CPXiM, I_SBCiX, I_ILLEG, I_ILLEG, I_CPXzP, I_SBCzP, I_INCzP, I_ILLEG, I_INXnP, I_SBCiM, I_NOPnP, I_ILLEG, I_CPXaB, I_SBCaB, I_INCaB, I_ILLEG,
  1646. /* F0 */ I_BEQrE, I_SBCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCzX, I_INCzX, I_ILLEG, I_SEDnP, I_SBCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCaX, I_INCaX, I_ILLEG
  1647. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1648. };
  1649. #ifdef MINE
  1650. typedef enum InstructionType
  1651. {
  1652. t_IMM = 0, t_IDX, t_IDY, t_ABS,
  1653. t_REL, t_ZEP, t_ZPX, t_ZPY,
  1654. t_ABX, t_ABY, t_IND, t_NOP,
  1655. } InstructionType;
  1656. static InstructionType InstructionTypeTable[256] =
  1657. {
  1658. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1659. /* 00 */ t_NOP, t_IDX, t_IMM, t_IMM, t_IMM, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_IMM, t_ABS, t_ABS, t_IMM,
  1660. /* 10 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
  1661. /* 20 */ t_ABS, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
  1662. /* 30 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
  1663. /* 40 */ t_NOP, t_IDX, t_IMM, t_IMM, t_IMM, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
  1664. /* 50 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
  1665. /* 60 */ t_NOP, t_IDX, t_IMM, t_IMM, t_IMM, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_IND, t_ABS, t_ABS, t_IMM,
  1666. /* 70 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
  1667. /* 80 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
  1668. /* 90 */ t_REL, t_IDY, t_IMM, t_IMM, t_ZPX, t_ZPX, t_ZPY, t_IMM, t_NOP, t_ABY, t_NOP, t_IMM, t_IMM, t_ABX, t_IMM, t_IMM,
  1669. /* A0 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
  1670. /* B0 */ t_REL, t_IDY, t_IMM, t_IMM, t_ZPX, t_ZPX, t_ZPY, t_IMM, t_NOP, t_ABY, t_NOP, t_IMM, t_ABX, t_ABX, t_ABY, t_IMM,
  1671. /* C0 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
  1672. /* D0 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
  1673. /* E0 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_IMM, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
  1674. /* F0 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM
  1675. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1676. };
  1677. static InstructionNameTag InstructionNameTable[256] =
  1678. {
  1679. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1680. /* 00 */ n_BRK, n_ORA, n_ILG, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG, n_PHP, n_ORA, n_ASL, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG,
  1681. /* 10 */ n_BPL, n_ORA, n_ILG, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG, n_CLC, n_ORA, n_ILG, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG,
  1682. /* 20 */ n_JSR, n_AND, n_ILG, n_ILG, n_BIT, n_AND, n_ROL, n_ILG, n_PLP, n_AND, n_ROL, n_ILG, n_BIT, n_AND, n_ROL, n_ILG,
  1683. /* 30 */ n_BMI, n_AND, n_ILG, n_ILG, n_ILG, n_AND, n_ROL, n_ILG, n_SEC, n_AND, n_ILG, n_ILG, n_ILG, n_AND, n_ROL, n_ILG,
  1684. /* 40 */ n_RTI, n_EOR, n_ILG, n_ILG, n_ILG, n_EOR, n_LSR, n_ILG, n_PHA, n_EOR, n_LSR, n_ILG, n_JMP, n_EOR, n_LSR, n_ILG,
  1685. /* 50 */ n_BVC, n_EOR, n_ILG, n_ILG, n_ILG, n_EOR, n_LSR, n_ILG, n_CLI, n_EOR, n_ILG, n_ILG, n_ILG, n_EOR, n_LSR, n_ILG,
  1686. /* 60 */ n_RTS, n_ADC, n_ILG, n_ILG, n_ILG, n_ADC, n_ROR, n_ILG, n_PLA, n_ADC, n_ROR, n_ILG, n_JMP, n_ADC, n_ROR, n_ILG,
  1687. /* 70 */ n_BVS, n_ADC, n_ILG, n_ILG, n_ILG, n_ADC, n_ROR, n_ILG, n_SEI, n_ADC, n_ILG, n_ILG, n_ILG, n_ADC, n_ROR, n_ILG,
  1688. /* 80 */ n_ILG, n_STA, n_ILG, n_ILG, n_STY, n_STA, n_STX, n_ILG, n_DEY, n_ILG, n_TXA, n_ILG, n_STY, n_STA, n_STX, n_ILG,
  1689. /* 90 */ n_BCC, n_STA, n_ILG, n_ILG, n_STY, n_STA, n_STX, n_ILG, n_TYA, n_STA, n_TXS, n_ILG, n_ILG, n_STA, n_ILG, n_ILG,
  1690. /* A0 */ n_LDY, n_LDA, n_LDX, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG, n_TAY, n_LDA, n_TAX, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG,
  1691. /* B0 */ n_BCS, n_LDA, n_ILG, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG, n_CLV, n_LDA, n_TSX, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG,
  1692. /* C0 */ n_CPY, n_CMP, n_ILG, n_ILG, n_CPY, n_CMP, n_DEC, n_ILG, n_INY, n_CMP, n_DEX, n_ILG, n_CPY, n_CMP, n_DEC, n_ILG,
  1693. /* D0 */ n_BNE, n_CMP, n_ILG, n_ILG, n_ILG, n_CMP, n_DEC, n_ILG, n_CLD, n_CMP, n_ILG, n_ILG, n_ILG, n_CMP, n_DEC, n_ILG,
  1694. /* E0 */ n_CPX, n_SBC, n_ILG, n_ILG, n_CPX, n_SBC, n_INC, n_ILG, n_INX, n_SBC, n_NOP, n_ILG, n_CPX, n_SBC, n_INC, n_ILG,
  1695. /* F0 */ n_BEQ, n_SBC, n_ILG, n_ILG, n_ILG, n_SBC, n_INC, n_ILG, n_SED, n_SBC, n_ILG, n_ILG, n_ILG, n_SBC, n_INC, n_ILG,
  1696. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1697. };
  1698. /** Get current instruction name at specified address and put it into buffer */
  1699. int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
  1700. unsigned short addr, char *buffer, int *strlength)
  1701. {
  1702. int len = 0, curlen;
  1703. int readbyte = 1;
  1704. char *str = buffer;
  1705. uint8_t opcode = cpu->memory_opcode_read(addr);
  1706. uint8_t value_u8;
  1707. uint16_t value_u16;
  1708. curlen = sprintf(str, "%s", InstructionName[InstructionNameTable[opcode]]);
  1709. str += curlen; len += curlen;
  1710. switch(InstructionTypeTable[opcode])
  1711. {
  1712. default: /* Nothing to do */
  1713. case t_NOP:
  1714. break;
  1715. case t_IMM:
  1716. curlen = sprintf(str, " #$%02X", cpu->memory_opcode_read(addr + 1));
  1717. str += curlen; len += curlen;
  1718. /* Nothing to interpret.. Really */
  1719. readbyte += 2;
  1720. break;
  1721. case t_IDX:
  1722. curlen = sprintf(str, " ($%02X, X)", cpu->memory_opcode_read(addr + 1));
  1723. str += curlen; len += curlen;
  1724. if (interpret)
  1725. {
  1726. value_u8 = cpu->memory_opcode_read( addr + 1 );
  1727. value_u16 = value_u8 + cpu->reg_X;
  1728. curlen = sprintf(str, " ; ($%02X + $%02X) -> ($%02X) -> $%02X%02X",
  1729. value_u8, cpu->reg_X,
  1730. value_u16 & 0xFF,
  1731. cpu->memory_page0_read(value_u16),
  1732. cpu->memory_page0_read(value_u16 + 1));
  1733. str += curlen; len += curlen;
  1734. }
  1735. readbyte += 1;
  1736. break;
  1737. case t_IDY:
  1738. curlen = sprintf(str, " ($%02X), Y", cpu->memory_opcode_read(addr + 1));
  1739. str += curlen; len += curlen;
  1740. if (interpret)
  1741. {
  1742. value_u8 = cpu->memory_opcode_read( addr + 1 );
  1743. value_u16 = (cpu->memory_page0_read(value_u8 + 1) << 8) |
  1744. (cpu->memory_page0_read(value_u8) );
  1745. curlen = sprintf(str, " ; ($%02X) + $%02X -> $%04X + $%02X -> $%04X",
  1746. value_u8, cpu->reg_Y,
  1747. value_u16, cpu->reg_Y,
  1748. value_u16 + cpu->reg_Y
  1749. );
  1750. str += curlen; len += curlen;
  1751. }
  1752. readbyte += 1;
  1753. break;
  1754. case t_ABS:
  1755. curlen = sprintf(str, " $%02X%02X", cpu->memory_opcode_read(addr + 2),
  1756. cpu->memory_opcode_read(addr + 1));
  1757. str += curlen; len += curlen;
  1758. /* Nothing to interpret.. Really */
  1759. readbyte += 2;
  1760. break;
  1761. case t_REL:
  1762. value_u16 = 2 + addr + (signed char) cpu->memory_opcode_read(addr + 1);
  1763. curlen = sprintf(str, " $%04X", value_u16);
  1764. str += curlen; len += curlen;
  1765. /* Nothing to interpret.. Really */
  1766. readbyte += 1;
  1767. break;
  1768. case t_ZEP:
  1769. curlen = sprintf(str, " $%02X", cpu->memory_opcode_read(addr + 1));
  1770. str += curlen; len += curlen;
  1771. /* Nothing to interpret.. Really */
  1772. readbyte += 1;
  1773. break;
  1774. case t_ZPX:
  1775. curlen = sprintf(str, " $%02X, X", cpu->memory_opcode_read(addr + 1));
  1776. str += curlen; len += curlen;
  1777. if (interpret)
  1778. {
  1779. curlen = sprintf(str, " ; $%02X + $%02x -> $%02X",
  1780. cpu->memory_opcode_read(addr + 1), cpu->reg_X,
  1781. (cpu->memory_opcode_read(addr + 1) + cpu->reg_X) & 0xFF);
  1782. str += curlen; len += curlen;
  1783. }
  1784. readbyte += 1;
  1785. break;
  1786. case t_ZPY:
  1787. curlen = sprintf(str, " $%02X, Y", cpu->memory_opcode_read(addr + 1));
  1788. str += curlen; len += curlen;
  1789. if (interpret)
  1790. {
  1791. curlen = sprintf(str, " ; $%02X + $%02x -> $%02X",
  1792. cpu->memory_opcode_read(addr + 1), cpu->reg_Y,
  1793. (cpu->memory_opcode_read(addr + 1) + cpu->reg_Y) & 0xFF);
  1794. str += curlen; len += curlen;
  1795. }
  1796. readbyte += 1;
  1797. break;
  1798. case t_ABX:
  1799. curlen = sprintf(str, " $%02X%02X, X", cpu->memory_opcode_read(addr + 2),
  1800. cpu->memory_opcode_read(addr + 1));
  1801. str += curlen; len += curlen;
  1802. if (interpret)
  1803. {
  1804. value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) |
  1805. cpu->memory_opcode_read(addr + 1);
  1806. curlen = sprintf(str, " ; $%04X + $%02X -> $%04X", value_u16,
  1807. cpu->reg_X, value_u16 + cpu->reg_X);
  1808. str += curlen; len += curlen;
  1809. }
  1810. readbyte += 2;
  1811. break;
  1812. case t_ABY:
  1813. curlen = sprintf(str, " $%02X%02X, Y", cpu->memory_opcode_read(addr + 2),
  1814. cpu->memory_opcode_read(addr + 1));
  1815. str += curlen; len += curlen;
  1816. if (interpret)
  1817. {
  1818. value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) |
  1819. cpu->memory_opcode_read(addr + 1);
  1820. curlen = sprintf(str, " ; $%04X + $%02X -> $%04X", value_u16,
  1821. cpu->reg_Y, value_u16 + cpu->reg_Y);
  1822. str += curlen; len += curlen;
  1823. }
  1824. readbyte += 2;
  1825. break;
  1826. case t_IND:
  1827. curlen = sprintf(str, " ($%02X%02X)", cpu->memory_opcode_read(addr + 2),
  1828. cpu->memory_opcode_read(addr + 1));
  1829. str += curlen; len += curlen;
  1830. if (interpret)
  1831. {
  1832. value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) |
  1833. cpu->memory_opcode_read(addr + 1);
  1834. value_u16 = cpu->memory_read(value_u16) |
  1835. (cpu->memory_read( ( value_u16 & 0xFF00 ) |
  1836. ( ( value_u16 + 1 ) & 0x00FF ) ) << 8 );
  1837. curlen = sprintf(str, " ; ($%02X%02X) -> $%04X",
  1838. cpu->memory_opcode_read(addr + 2),
  1839. cpu->memory_opcode_read(addr + 1),
  1840. cpu->memory_opcode_read(addr));
  1841. str += curlen; len += curlen;
  1842. }
  1843. readbyte += 2;
  1844. break;
  1845. }
  1846. if (strlength != NULL)
  1847. *strlength = len;
  1848. return readbyte;
  1849. }
  1850. #else
  1851. static char InstructionParameters[256][10] =
  1852. {
  1853. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1854. /* 00 */ IP_iM "BRK", IP_iX "ORA", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zP "ORA", IP_zP "ASL", IP_iM "ILG", IP_iM "PHP", IP_iM "ORA", IP_iM "ASL", IP_iM "ILG", IP_iM "ILG", IP_aB "ORA", IP_aB "ASL", IP_iM "ILG",
  1855. /* 10 */ IP_rE "BPL", IP_iY "ORA", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "ORA", IP_zX "ASL", IP_iM "ILG", IP_iM "CLC", IP_aY "ORA", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "ORA", IP_aX "ASL", IP_iM "ILG",
  1856. /* 20 */ IP_aB "JSR", IP_iX "AND", IP_iM "ILG", IP_iM "ILG", IP_zP "BIT", IP_zP "AND", IP_zP "ROL", IP_iM "ILG", IP_iM "PLP", IP_iM "AND", IP_iM "ROL", IP_iM "ILG", IP_aB "BIT", IP_aB "AND", IP_aB "ROL", IP_iM "ILG",
  1857. /* 30 */ IP_rE "BMI", IP_iY "AND", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "AND", IP_zX "ROL", IP_iM "ILG", IP_iM "SEC", IP_aY "AND", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "AND", IP_aX "ROL", IP_iM "ILG",
  1858. /* 40 */ IP_iM "RTI", IP_iX "EOR", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zP "EOR", IP_zP "LSR", IP_iM "ILG", IP_iM "PHA", IP_iM "EOR", IP_iM "LSR", IP_iM "ILG", IP_aB "JMP", IP_aB "EOR", IP_aB "LSR", IP_iM "ILG",
  1859. /* 50 */ IP_rE "BVC", IP_iY "EOR", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "EOR", IP_zX "LSR", IP_iM "ILG", IP_iM "CLI", IP_aY "EOR", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "EOR", IP_aX "LSR", IP_iM "ILG",
  1860. /* 60 */ IP_iM "RTS", IP_iX "ADC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zP "ADC", IP_zP "ROR", IP_iM "ILG", IP_iM "PLA", IP_iM "ADC", IP_iM "ROR", IP_iM "ILG", IP_iD "JMP", IP_aB "ADC", IP_aB "ROR", IP_iM "ILG",
  1861. /* 70 */ IP_rE "BVS", IP_iY "ADC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "ADC", IP_zX "ROR", IP_iM "ILG", IP_iM "SEI", IP_aY "ADC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "ADC", IP_aX "ROR", IP_iM "ILG",
  1862. /* 80 */ IP_iM "ILG", IP_iX "STA", IP_iM "ILG", IP_iM "ILG", IP_zP "STY", IP_zP "STA", IP_zP "STX", IP_iM "ILG", IP_iM "DEY", IP_iM "ILG", IP_iM "TXA", IP_iM "ILG", IP_aB "STY", IP_aB "STA", IP_aB "STX", IP_iM "ILG",
  1863. /* 90 */ IP_rE "BCC", IP_iY "STA", IP_iM "ILG", IP_iM "ILG", IP_zX "STY", IP_zX "STA", IP_zY "STX", IP_iM "ILG", IP_iM "TYA", IP_aY "STA", IP_iM "TXS", IP_iM "ILG", IP_iM "ILG", IP_aX "STA", IP_iM "ILG", IP_iM "ILG",
  1864. /* A0 */ IP_iM "LDY", IP_iX "LDA", IP_iM "LDX", IP_iM "ILG", IP_zP "LDY", IP_zP "LDA", IP_zP "LDX", IP_iM "ILG", IP_iM "TAY", IP_iM "LDA", IP_iM "TAX", IP_iM "ILG", IP_aB "LDY", IP_aB "LDA", IP_aB "LDX", IP_iM "ILG",
  1865. /* B0 */ IP_rE "BCS", IP_iY "LDA", IP_iM "ILG", IP_iM "ILG", IP_zX "LDY", IP_zX "LDA", IP_zY "LDX", IP_iM "ILG", IP_iM "CLV", IP_aY "LDA", IP_iM "TSX", IP_iM "ILG", IP_aX "LDY", IP_aX "LDA", IP_aY "LDX", IP_iM "ILG",
  1866. /* C0 */ IP_iM "CPY", IP_iX "CMP", IP_iM "ILG", IP_iM "ILG", IP_zP "CPY", IP_zP "CMP", IP_zP "DEC", IP_iM "ILG", IP_iM "INY", IP_iM "CMP", IP_iM "DEX", IP_iM "ILG", IP_aB "CPY", IP_aB "CMP", IP_aB "DEC", IP_iM "ILG",
  1867. /* D0 */ IP_rE "BNE", IP_iY "CMP", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "CMP", IP_zX "DEC", IP_iM "ILG", IP_iM "CLD", IP_aY "CMP", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "CMP", IP_aX "DEC", IP_iM "ILG",
  1868. /* E0 */ IP_iM "CPX", IP_iX "SBC", IP_iM "ILG", IP_iM "ILG", IP_zP "CPX", IP_zP "SBC", IP_zP "INC", IP_iM "ILG", IP_iM "INX", IP_iM "SBC", IP_iM "NOP", IP_iM "ILG", IP_aB "CPX", IP_aB "SBC", IP_aB "INC", IP_iM "ILG",
  1869. /* F0 */ IP_rE "BEQ", IP_iY "SBC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "SBC", IP_zX "INC", IP_iM "ILG", IP_iM "SED", IP_aY "SBC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "SBC", IP_aX "INC", IP_iM "ILG"
  1870. /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
  1871. };
  1872. /** Get current instruction name at specified address and put it into buffer */
  1873. int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
  1874. unsigned short addr, char *buffer, int *strlength)
  1875. {
  1876. unsigned char instr = cpu->memory_opcode_read(cpu->reg_PC);
  1877. unsigned char *instrText = InstructionParameters[instr];
  1878. buffer += strlen(strcpy(buffer, instrText[1]));
  1879. switch(instrText[0])
  1880. {
  1881. case IP_nPc: default: break;
  1882. case IP_iMc: buffer += strlen(sprintf(buffer, IPf_iM, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1883. case IP_iXc: buffer += strlen(sprintf(buffer, IPf_iX, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1884. case IP_iYc: buffer += strlen(sprintf(buffer, IPf_iY, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1885. case IP_zPc: buffer += strlen(sprintf(buffer, IPf_zP, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1886. case IP_zXc: buffer += strlen(sprintf(buffer, IPf_zX, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1887. case IP_zYc: buffer += strlen(sprintf(buffer, IPf_zY, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1888. case IP_iDc: buffer += strlen(sprintf(buffer, IPf_iD, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1889. case IP_aBc: buffer += strlen(sprintf(buffer, IPf_aB, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1890. case IP_aXc: buffer += strlen(sprintf(buffer, IPf_aX, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1891. case IP_aYc: buffer += strlen(sprintf(buffer, IPf_aY, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
  1892. case IP_rEc: buffer += strlen(sprintf(buffer, IPf_rE, cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1)); break;
  1893. }
  1894. *buffer = 0;
  1895. }
  1896. #endif
  1897. static inline int quick6502_exec_one(quick6502_cpu *cpu)
  1898. {
  1899. register byte opcode = cpu->memory_opcode_read(cpu->reg_PC);
  1900. //char instr[100];
  1901. //quick6502_dump(cpu, stdout);
  1902. cpu->reg_PC++;
  1903. TRACEi(("Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]",
  1904. cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
  1905. cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
  1906. cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
  1907. cpu->reg_P&Q6502_R_FLAG ? 'R':'.',
  1908. cpu->reg_P&Q6502_B_FLAG ? 'B':'.',
  1909. cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
  1910. cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
  1911. cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
  1912. cpu->reg_P&Q6502_C_FLAG ? 'C':'.'));
  1913. InstructionTable[opcode](cpu);
  1914. //printf("--------------------------------------------------------------\n");
  1915. /*quick6502_getinstruction(cpu, (1==1), cpu->reg_PC, instr, NULL);
  1916. printf("%04X: %s\n", cpu->reg_PC, instr);*/
  1917. cpu->cycle_done += CycleTable[opcode];
  1918. if (cpu->page_crossed) { cpu->cycle_done++; cpu->page_crossed = 0; }
  1919. if (cpu->int_pending != 0)
  1920. {
  1921. quick6502_int(cpu, Q6502_IRQ_SIGNAL);
  1922. }
  1923. return 0;
  1924. }