corecpu.c 73 KB

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