12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850 |
- /**
- * CoreCPU - The Quick6502 Project
- * corecpu.c
- *
- * Created by Manoel Trapier on 24/02/08
- * Copyright 2008 986 Corp. All rights reserved.
- *
- * $LastChangedDate$
- * $Author$
- * $HeadURL$
- * $Revision$
- *
- */
- /* Depending on the OS, one of these provide the malloc function */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <os_dependent.h>
- /*******************************************************************************
- /!\ WARNING this debug tool slow down a lot the emulator! /!\
- /!\ Use it only if you really need it ! /!\
- *******************************************************************************/
- //#define TRACE_INSTRUCTIONS
- #ifdef TRACE_INSTRUCTIONS
- #define TRACEi(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
- #define TRACEiE(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
- #else
- #define TRACEi(trace) { }
- //#define TRACEiE(trace) { }
- #define TRACEiE(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
- #endif
- #define _INTERNAL_QUICK6502_CORECPU_
- #include "corecpu.h"
- /*** Instructions useful macros ***/
- #define INSTRUCTION(s) static inline void I_##s (quick6502_cpu *cpu)
- #define NZ_FLAG_UPDATE(value) cpu->reg_P = (cpu->reg_P & ~(Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- (value & 0x80) | ((value)?0:Q6502_Z_FLAG)
- #define CROSS_CYCLE_UPDATE(value) if ((value) & 0x0F00) cpu->page_crossed = 1
- #define MEMORY_READ_ZP() cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))
- #define MEMORY_READ_IX() cpu->memory_read( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X ) & 0xFF) |\
- (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X + 1) << 8) )
- #define MEMORY_READ_IY() cpu->memory_read( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) ) |\
- (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + 1) << 8) ) + cpu->reg_Y )
- #define MEMORY_READ_ZX() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X) )
- #define MEMORY_READ_ZY() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y) )
- #define MEMORY_READ_AB() cpu->memory_read( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
- (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ))
- #define MEMORY_READ_AX() cpu->memory_read( ((op1 ) |\
- (op2 << 8) ) + cpu->reg_X)
- #define MEMORY_READ_AY() cpu->memory_read( ((op1 ) |\
- (op2 << 8) ) + cpu->reg_Y )
- #define MEMORY_WRITE_ZP(val) cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), val)
- #define MEMORY_WRITE_IX(val) cpu->memory_write( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) + cpu->reg_X ) & 0xFF) |\
- (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X + 1) << 8) , val)
- #define MEMORY_WRITE_IY(val) cpu->memory_write( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC ) ) |\
- (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + 1) << 8) ) + cpu->reg_Y , val)
- #define MEMORY_WRITE_ZX(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X), val)
- #define MEMORY_WRITE_ZY(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y), val)
- #define MEMORY_WRITE_AB(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
- (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ), val)
- #define MEMORY_WRITE_AX(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
- (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ) + cpu->reg_X, val)
- #define MEMORY_WRITE_AY(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++) ) |\
- (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ) + cpu->reg_Y, val)
- #define PUSH_S(value) cpu->memory_stack_write(0x100 | (cpu->reg_S--), value)
- #define POP_S() (cpu->memory_stack_read (0x100 | (++cpu->reg_S) ))
- #ifdef NO_DECIMAL
- #define ADC_OPERATION(read) do {\
- unsigned short tmp = 0; unsigned char v = read; \
- tmp = cpu->reg_A + v + (cpu->reg_P & Q6502_C_FLAG); \
- cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \
- (tmp & 0x80) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
- ((tmp & 0xFF00)?Q6502_C_FLAG:0) | \
- ( ( ~(cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \
- cpu->reg_A = tmp & 0xFF; \
- } while(0)
- #define SBC_OPERATION(read) do {\
- unsigned short tmp = 0; unsigned char v = read; \
- tmp = cpu->reg_A - v - (~cpu->reg_P & Q6502_C_FLAG); \
- cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \
- (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
- ((tmp & 0xFF00)?0:Q6502_C_FLAG) | \
- ( ( (cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \
- cpu->reg_A = tmp & 0xFF; \
- } while(0)
- #else
- #error Quick6502 doesn't actually support DECIMAL mode
- #endif
- #define AND_OPERATION(read) cpu->reg_A &= read; NZ_FLAG_UPDATE(cpu->reg_A)
- /* CMP is like SBC but without storing the result value */
- #define CMP_OPERATION(register, read) do { \
- unsigned short tmp = 0; \
- tmp = register - read; \
- cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \
- ((tmp & 0xFF00)?0:Q6502_C_FLAG); \
- } while(0)
- #define EOR_OPERATION(read) cpu->reg_A ^= read; NZ_FLAG_UPDATE(cpu->reg_A)
- #define ORA_OPERATION(read) cpu->reg_A |= read; NZ_FLAG_UPDATE(cpu->reg_A)
- #define BIT_OPERATION(read) do { \
- byte tmp = read; \
- cpu->reg_P = (cpu->reg_P & ~(Q6502_V_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- (tmp & Q6502_N_FLAG) | (tmp & Q6502_V_FLAG) | \
- ((tmp & cpu->reg_A)?0:Q6502_Z_FLAG); \
- } while(0)
- #define ASL_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- ((val&0x40)?Q6502_N_FLAG:0) | \
- ((val&0x80)?Q6502_C_FLAG:0) | \
- ((val&0x7F)?0:Q6502_Z_FLAG); \
- val = val << 1
- #define LSR_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- (val & Q6502_C_FLAG) | \
- ((val&0xFE)?0:Q6502_Z_FLAG); \
- val = val >> 1
- #define ROR_OPERATION(val) do {\
- unsigned short tmp = val | (cpu->reg_P & Q6502_C_FLAG) << 8; \
- cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- ( tmp&Q6502_C_FLAG) | /* Set the C flag */ \
- ((tmp&0x100) >> 1) | /* Set the N flag */ \
- ((tmp&0x1FE)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \
- val = (tmp>>1) & 0xFF; \
- } while(0)
- #define ROL_OPERATION(val) do {\
- unsigned short tmp = (val << 1) | (cpu->reg_P & Q6502_C_FLAG); \
- cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \
- ((tmp&0x100)?Q6502_C_FLAG:0) | /* Set the C flag */ \
- ((tmp&0x80)) | /* Set the N flag */ \
- ((tmp&0xFF)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \
- val = tmp & 0xFF; \
- } while(0)
- /** Function used for execution of instruction */
- static inline int quick6502_exec_one(quick6502_cpu *cpu);
- /**
- * Initialise the CPU
- *
- * Inputs:
- *
- * - CPU Init structure:
- * - Memory Read function pointer
- * - Memory Write function pointer
- * - Fast memory read function pointer (for opcodes read)
- * - Fast page 0 function Read/Write
- * - Fast page 1 function Read/Write
- *
- * Output:
- *
- * (void *): An opaque pointer to the internal structure of the CPU.
- * NULL if an error occured !
- */
- quick6502_cpu *quick6502_init(quick6502_cpuconfig *config)
- {
- quick6502_cpu *cpu;
- /* Alloc structure */
- cpu = (quick6502_cpu *) malloc (sizeof (quick6502_cpu));
- if (!cpu)
- return NULL;
- /* Initialise other variables */
- cpu->running = 0; /* CPU is currently NOT running */
- cpu->cycle_done = 0;
- cpu->int_pending = 0;
-
- cpu->page_crossed = 0;
-
- /* Initialise registers */
- cpu->reg_A = 0;
- cpu->reg_X = 0;
- cpu->reg_Y = 0;
- cpu->reg_S = 0xFF;
-
- cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG;
-
- if (config->memory_read != NULL)
- cpu->memory_read = config->memory_read;
- else
- goto init_error;
- if (config->memory_write != NULL)
- cpu->memory_write = config->memory_write;
- else
- goto init_error;
- if (config->memory_opcode_read != NULL)
- cpu->memory_opcode_read = config->memory_opcode_read;
- else
- cpu->memory_opcode_read = config->memory_read;
- if (config->memory_page0_read != NULL)
- cpu->memory_page0_read = config->memory_page0_read;
- else
- cpu->memory_page0_read = config->memory_read;
- if (config->memory_page0_write != NULL)
- cpu->memory_page0_write = config->memory_page0_write;
- else
- cpu->memory_page0_write = config->memory_write;
- if (config->memory_stack_read != NULL)
- cpu->memory_stack_read = config->memory_stack_read;
- else
- cpu->memory_stack_read = config->memory_read;
- if (config->memory_stack_write != NULL)
- cpu->memory_stack_write = config->memory_stack_write;
- else
- cpu->memory_stack_write = config->memory_write;
-
- return cpu;
- init_error:
- if (cpu)
- free (cpu);
- return NULL;
- }
- /** Reset the CPU (must be done after init) */
- void quick6502_reset(quick6502_cpu *cpu)
- {
- /* Initialise registers */
- /*cpu->reg_A = 0;
- cpu->reg_X = 0;
- cpu->reg_Y = 0;
- cpu->reg_S = 0xFF;*/
- //cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG | 0x20 | Q6502_B_FLAG;
- /* Set the PC to the RESET vector */
- cpu->reg_PC = ( cpu->memory_read(Q6502_RESET_HIGH) << 8)
- | cpu->memory_read(Q6502_RESET_LOW);
- cpu->exit_loop = 0;
- }
- /**
- * Run cpu for at least X cycles
- *
- * Output:
- *
- * int: (Number of cycle really done) - (Number of cycle asked)
- */
- int quick6502_run(quick6502_cpu *cpu, int cycles)
- {
- cpu->running = !0;
- while(cpu->cycle_done < cycles)
- {
- quick6502_exec_one(cpu);
- }
- cpu->cycle_done -= cycles;
- cpu->running = 0;
- return cycles + cpu->cycle_done;
- }
- /** Loop CPU until explicit quit */
- void quick6502_loop(quick6502_cpu *cpu)
- {
- cpu->running = !0;
- while(cpu->exit_loop)
- {
- quick6502_exec_one(cpu);
- }
- cpu->running = 0;
- }
- /** Run CPU for one instruction */
- void quick6502_exec(quick6502_cpu *cpu)
- {
- cpu->running = !0;
- quick6502_exec_one(cpu);
- cpu->running = 0;
- }
- /** Send IRQ/NMI/EXITLOOP signal to CPU */
- void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal)
- {
- switch(signal)
- {
- default:
- break;
- case Q6502_IRQ_SIGNAL:
- if (! (cpu->reg_P & Q6502_I_FLAG) )
- {
- TRACEi(("IRQ Triggered !"));
- PUSH_S((cpu->reg_PC >> 8) & 0xFF );
- PUSH_S((cpu->reg_PC ) & 0xFF );
- PUSH_S( cpu->reg_P & ~Q6502_B_FLAG );
- cpu->reg_P = cpu->reg_P | Q6502_I_FLAG;
- cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8);
-
- cpu->cycle_done += 7;
- }
- else
- cpu->int_pending = 1;
- break;
- case Q6502_NMI_SIGNAL:
- TRACEi(("NMI Triggered !"));
- PUSH_S((cpu->reg_PC >> 8) & 0xFF );
- PUSH_S((cpu->reg_PC ) & 0xFF );
- PUSH_S( cpu->reg_P );
- cpu->reg_P = cpu->reg_P | Q6502_I_FLAG & ~Q6502_B_FLAG;
- cpu->reg_PC = (cpu->memory_read(Q6502_NMI_LOW)) | (cpu->memory_read(Q6502_NMI_HIGH)<<8);
-
- cpu->cycle_done += 7;
- break;
- case Q6502_STOPLOOP_SIGNAL:
- cpu->exit_loop = 1;
- break;
- }
- }
- /** Dump CPU State to the given file */
- void quick6502_dump(quick6502_cpu *cpu, FILE * fp)
- {
- short i;
- char instr[20];
- /* Display registers */
- fprintf(fp,
- "Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]\n",
- cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
- cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
- cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
- '.', /* No real flag here */
- cpu->reg_P&Q6502_B_FLAG ? 'B':'.',
- cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
- cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
- cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
- cpu->reg_P&Q6502_C_FLAG ? 'C':'.'
- );
- /* Display stack */
- fprintf(fp, "Quick6502: Stack: [ ");
- for (i = cpu->reg_S+1; i < 0x100; i++)
- {
- fprintf(fp, "$%02X ", cpu->memory_opcode_read(0x100 | i));
- }
- fprintf(fp, "] Run:%c Cycle:%ld\n", cpu->running?'Y':'N', cpu->cycle_done);
- quick6502_getinstruction(cpu, cpu->reg_PC, instr);
- fprintf(fp, "Quick6502: Instruction at PC: %s\n", instr);
- }
- /** Get current instruction name at specified address and put it into buffer */
- void quick6502_getinstruction(quick6502_cpu *cpu, unsigned short addr, char *buffer)
- {
- buffer[0] = 0;
- }
- /**
- * Free the CPU
- *
- * This function will free the CPU only if it's not currently used, it will
- * return !0 if everything goes well and 0 if the free is impossible
- */
- int quick6502_free(quick6502_cpu *cpu)
- {
- return 0;
- }
- /*******************************************************************************
- *** Here start real CPU logic ***
- *******************************************************************************/
- static byte CycleTable[256] =
- {
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- /* 00 */ 7, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
- /* 10 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
- /* 20 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6,
- /* 30 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
- /* 40 */ 6, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6,
- /* 50 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
- /* 60 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6,
- /* 70 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
- /* 80 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
- /* 90 */ 2, 6, 0, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5,
- /* A0 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
- /* B0 */ 2, 5, 0, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4,
- /* C0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
- /* D0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
- /* E0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
- /* F0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- };
- typedef void (*InstructionFunction)(quick6502_cpu *cpu);
- /*******************************************************************************
- * Instruction implementations
- *******************************************************************************/
- /**** Other instructions ****/
- INSTRUCTION(ILLEG)
- {
- TRACEiE(("Illegal instruction $%02X", cpu->memory_opcode_read(cpu->reg_PC-1)));
- //exit(-1);
- }
- /** 58 : CLI - CLear Interrupt **/
- INSTRUCTION(CLIiM)
- {
- TRACEi(("CLC"));
- cpu->reg_P &= ~Q6502_I_FLAG;
- }
- /** 78 : SEI - SEt Interrupt **/
- INSTRUCTION(SEIiM)
- {
- TRACEi(("SEI"));
- cpu->reg_P |= Q6502_I_FLAG;
- }
- /** 18 : CLC - CLear Carry **/
- INSTRUCTION(CLCiM)
- {
- TRACEi(("CLC"));
- cpu->reg_P &= ~Q6502_C_FLAG;
- }
- /** 38 : SEC - SEt Carry **/
- INSTRUCTION(SECiM)
- {
- TRACEi(("SEC"));
- cpu->reg_P |= Q6502_C_FLAG;
- }
- /** D8 : CLD - CLear Decimal **/
- INSTRUCTION(CLDiM)
- {
- TRACEi(("CLD"));
- cpu->reg_P &= ~Q6502_D_FLAG;
- }
- /** F8 : SED - SEt Decimal **/
- INSTRUCTION(SEDiM)
- {
- TRACEi(("SED"));
- cpu->reg_P |= Q6502_D_FLAG;
- }
- /** B8 : CLV - CLear oVerflo **/
- INSTRUCTION(CLViM)
- {
- TRACEi(("CLV"));
- cpu->reg_P &= ~Q6502_V_FLAG;
- }
- /** EA : NOP - NO oPeration **/
- INSTRUCTION(NOPiM)
- {
- TRACEi(("NOP"));
- }
- /**** Load/Store functions ****/
- /** A9 : LDA #$xx - LoaD an immediate value into A */
- INSTRUCTION(LDAiM)
- {
- TRACEi(("LDA #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = cpu->memory_opcode_read(cpu->reg_PC++);
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** A2 : LDX #$xx - LoaD an immediate value into X */
- INSTRUCTION(LDXiM)
- {
- TRACEi(("LDX #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_X = cpu->memory_opcode_read(cpu->reg_PC++);
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** A0 : LDY #$xx - LoaD an immediate value into Y */
- INSTRUCTION(LDYiM)
- {
- TRACEi(("LDY #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_Y = cpu->memory_opcode_read(cpu->reg_PC++);
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** A5: LDA $xx - LoaD to A from zero page **/
- INSTRUCTION(LDAzP)
- {
- TRACEi(("LDA $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = MEMORY_READ_ZP();
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** B5: LDA $xx,X - LoaD to A **/
- INSTRUCTION(LDAzX)
- {
- TRACEi(("LDA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = MEMORY_READ_ZX();
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** A1: LDA ($xx,X) - LoaD to A **/
- INSTRUCTION(LDAiX)
- {
- TRACEi(("LDA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = MEMORY_READ_IX();
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** B1: LDA ($xx),Y - LoaD to A **/
- INSTRUCTION(LDAiY)
- {
- TRACEi(("LDA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = MEMORY_READ_IY();
- NZ_FLAG_UPDATE(cpu->reg_A);
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** AD: LDA $xxxx - LoaD to A **/
- INSTRUCTION(LDAaB)
- {
- TRACEi(("LDA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = MEMORY_READ_AB();
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** DD: LDA $xxxx,X - LoaD to A **/
- INSTRUCTION(LDAaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("LDA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_A = MEMORY_READ_AX();
- NZ_FLAG_UPDATE(cpu->reg_A);
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** D9: LDA $xxxx,Y - LoaD to A **/
- INSTRUCTION(LDAaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- cpu->reg_A = MEMORY_READ_AY();
- NZ_FLAG_UPDATE(cpu->reg_A);
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** 85: STA $xx - STore A to zero page **/
- INSTRUCTION(STAzP)
- {
- TRACEi(("STA $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_A);
- }
- /** 95: STA $xx,X - STore A **/
- INSTRUCTION(STAzX)
- {
- TRACEi(("STA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_ZX(cpu->reg_A);
- }
- /** 81: STA ($xx,X) - STore A **/
- INSTRUCTION(STAiX)
- {
- TRACEi(("STA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_IX(cpu->reg_A);
- }
- /** 91: STA ($xx),Y - STore A **/
- INSTRUCTION(STAiY)
- {
- TRACEi(("STA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_IY(cpu->reg_A);
- }
- /** 8D: STA $xxxx - STore A **/
- INSTRUCTION(STAaB)
- {
- TRACEi(("STA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_AB(cpu->reg_A);
- }
- /** 9D: STA $xxxx,X - STore A **/
- INSTRUCTION(STAaX)
- {
- TRACEi(("STA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_AX(cpu->reg_A);
- }
- /** 99: STA $xxxx,Y - STore A **/
- INSTRUCTION(STAaY)
- {
- TRACEi(("STA $%02X%02X,Y", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_AY(cpu->reg_A);
- }
- /** A6: LDX $xx - LoaD to X from zero page **/
- INSTRUCTION(LDXzP)
- {
- TRACEi(("LDX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_X = MEMORY_READ_ZP();
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** B6: LDX $xx,Y - LoaD to X **/
- INSTRUCTION(LDXzY)
- {
- TRACEi(("LDX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_X = MEMORY_READ_ZY();
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** AE: LDX $xxxx - LoaD to X **/
- INSTRUCTION(LDXaB)
- {
- TRACEi(("LDX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_X = MEMORY_READ_AB();
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** BE: LDX $xxxx,Y - LoaD to X **/
- INSTRUCTION(LDXaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- TRACEi(("LDX $%02X%02X,Y", op2, op1));
- cpu->reg_X = MEMORY_READ_AY();
- NZ_FLAG_UPDATE(cpu->reg_X);
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** B6: STX $xx - STore X to zero page **/
- INSTRUCTION(STXzP)
- {
- TRACEi(("STX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_X);
- }
- /** 96: STX $xx,Y - STore X **/
- INSTRUCTION(STXzY)
- {
- TRACEi(("STX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_ZY(cpu->reg_X);
- }
- /** 8E: STX $xxxx - STore X **/
- INSTRUCTION(STXaB)
- {
- TRACEi(("STX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_AB(cpu->reg_X);
- }
- /** A4: LDY $xx - LoaD to Y from zero page **/
- INSTRUCTION(LDYzP)
- {
- TRACEi(("LDY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_Y = MEMORY_READ_ZP();
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** B4: LDY $xx,X - LoaD to Y **/
- INSTRUCTION(LDYzX)
- {
- TRACEi(("LDY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_Y = MEMORY_READ_ZX();
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** AC: LDY $xxxx - LoaD to Y **/
- INSTRUCTION(LDYaB)
- {
- TRACEi(("LDY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_Y = MEMORY_READ_AB();
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** BC: LDY $xxxx,X - LoaD to Y **/
- INSTRUCTION(LDYaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("LDY $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_Y = MEMORY_READ_AX();
- NZ_FLAG_UPDATE(cpu->reg_Y);
-
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** 84: STY $xx - STore Y to zero page **/
- INSTRUCTION(STYzP)
- {
- TRACEi(("STY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_Y);
- }
- /** 94: STY $xx,X - STore Y **/
- INSTRUCTION(STYzX)
- {
- TRACEi(("STY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_ZX(cpu->reg_Y);
- }
- /** 8C: STY $xxxx - STore Y **/
- INSTRUCTION(STYaB)
- {
- TRACEi(("STY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- MEMORY_WRITE_AB(cpu->reg_Y);
- }
- /**** Register functions ****/
- /** AA : TAX - Transfer A to X **/
- INSTRUCTION(TAXiM)
- {
- TRACEi(("TAX"));
- cpu->reg_X = cpu->reg_A;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** 8A : TXA - Transfer X to A **/
- INSTRUCTION(TXAiM)
- {
- TRACEi(("TXA"));
- cpu->reg_A = cpu->reg_X;
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** A8 : TAY - Transfer A to Y **/
- INSTRUCTION(TAYiM)
- {
- TRACEi(("TAY"));
- cpu->reg_Y = cpu->reg_A;
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** 98 : TYA - Transfer Y to A **/
- INSTRUCTION(TYAiM)
- {
- TRACEi(("TYA"));
- cpu->reg_A = cpu->reg_Y;
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /* BA : TSX - Transfer S to X **/
- INSTRUCTION(TSXiM)
- {
- TRACEi(("TSX"));
- cpu->reg_X = cpu->reg_S;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** 9A : TXS - Transfer X to S **/
- INSTRUCTION(TXSiM)
- {
- TRACEi(("TXS"));
- cpu->reg_S = cpu->reg_X;
- }
- /**** Simple register operation instructions ****/
- /** CA : DEX - DEcrement X **/
- INSTRUCTION(DEXiM)
- {
- TRACEi(("DEX"));
- cpu->reg_X --;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** 88 : DEY - DEcrement Y **/
- INSTRUCTION(DEYiM)
- {
- TRACEi(("DEY"));
- cpu->reg_Y --;
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** E8 : INX - INcrement X **/
- INSTRUCTION(INXiM)
- {
- TRACEi(("INX"));
- cpu->reg_X ++;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** C8 : INY - INcrement Y **/
- INSTRUCTION(INYiM)
- {
- TRACEi(("INY"));
- cpu->reg_Y ++;
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /**** Stack related instructions ****/
- /** 48 : PHA - PusH A */
- INSTRUCTION(PHAiM)
- {
- TRACEi(("PHA"));
- PUSH_S(cpu->reg_A);
- }
- /** 68 : PLA - PuLl A */
- INSTRUCTION(PLAiM)
- {
- TRACEi(("PLA"));
- cpu->reg_A = POP_S();
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** 08 : PHP - PusH P */
- INSTRUCTION(PHPiM)
- {
- TRACEi(("PHP"));
- PUSH_S((cpu->reg_P | Q6502_R_FLAG | Q6502_B_FLAG));
- }
- /** 28 : PLP - PuLl P */
- INSTRUCTION(PLPiM)
- {
- TRACEi(("PLP"));
- cpu->reg_P = POP_S() & ~(Q6502_R_FLAG | Q6502_B_FLAG);
- if (cpu->int_pending != 0)
- {
- quick6502_int(cpu, Q6502_IRQ_SIGNAL);
- }
- }
- /**** Branch instructions ****/
- /** 20 : JSR $xxxx - Jump to SubRoutine */
- INSTRUCTION(JSRaB)
- {
- TRACEi(("JSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_PC++;
- PUSH_S((cpu->reg_PC >> 8) & 0xFF);
- PUSH_S((cpu->reg_PC ) & 0xFF);
- cpu->reg_PC = ((cpu->memory_opcode_read(cpu->reg_PC-1) ) | (cpu->memory_opcode_read(cpu->reg_PC) << 8));
- }
- /** 60 : RTS - ReTurn from Subrutine */
- INSTRUCTION(RTSiM)
- {
- TRACEi(("RTS"));
- cpu->reg_PC = POP_S() | (POP_S() << 8);
- cpu->reg_PC ++;
- }
- /** 4C : JMP $xxxx - JuMP inconditionaly to $xxxx **/
- INSTRUCTION(JMPaB)
- {
- TRACEi(("JMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC++) | (cpu->memory_opcode_read(cpu->reg_PC) << 8);
- }
- /** 6C : JMP ($xxxx) - JuMP inconditionaly to ($xxxx) **/
- INSTRUCTION(JMPiD)
- {
- TRACEi(("JMP ($%02X%02X)", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC) | (cpu->memory_opcode_read(cpu->reg_PC+1) << 8);
- cpu->reg_PC = cpu->memory_read(cpu->reg_PC) |
- (cpu->memory_read((cpu->reg_PC & 0xFF00) | ((cpu->reg_PC+1) & 0x00FF)) << 8);
- }
- /** 00 : BRK - BReaK **/
- INSTRUCTION(BRKiM)
- {
- TRACEi(("BRK"));
- cpu->reg_PC++;
- PUSH_S((cpu->reg_PC >> 8) & 0xFF);
- PUSH_S((cpu->reg_PC ) & 0xFF);
- PUSH_S( cpu->reg_P );
- cpu->reg_P = cpu->reg_P | Q6502_I_FLAG | Q6502_B_FLAG;
- cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8);
- }
- /** 40 : RTI - ReTurn from Interruption **/
- INSTRUCTION(RTIiM)
- {
- TRACEi(("RTI"));
- cpu->reg_P = POP_S();
- cpu->reg_PC = POP_S() | (POP_S() << 8);
- if (cpu->int_pending != 0)
- {
- quick6502_int(cpu, Q6502_IRQ_SIGNAL);
- }
- }
- /** 90 : BCC - Branch if Carry Clear **/
- INSTRUCTION(BCCrE)
- {
- TRACEi(("BCC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (!(cpu->reg_P & Q6502_C_FLAG))
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** B0 : BCS - Branch if Carry Set**/
- INSTRUCTION(BCSrE)
- {
- TRACEi(("BCS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (cpu->reg_P & Q6502_C_FLAG)
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** F0 : BEQ - Branch if Equal**/
- INSTRUCTION(BEQrE)
- {
- TRACEi(("BEQ $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (cpu->reg_P & Q6502_Z_FLAG)
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** 30 : BMI - Branch if MInus**/
- INSTRUCTION(BMIrE)
- {
- TRACEi(("BMI $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (cpu->reg_P & Q6502_N_FLAG)
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** D0 : Bxx - Branch if Not Equal**/
- INSTRUCTION(BNErE)
- {
- TRACEi(("BNE $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (!(cpu->reg_P & Q6502_Z_FLAG))
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** 10 : BPL - Branch if PLus **/
- INSTRUCTION(BPLrE)
- {
- TRACEi(("BPL $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (!(cpu->reg_P & Q6502_N_FLAG))
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** 50 : BVC - Branch if oVerflow Clear**/
- INSTRUCTION(BVCrE)
- {
- TRACEi(("BVC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (!(cpu->reg_P & Q6502_V_FLAG))
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /** 70 : BVS - Branch if oVerflow Set**/
- INSTRUCTION(BVSrE)
- {
- TRACEi(("BVS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
- if (cpu->reg_P & Q6502_V_FLAG)
- {
- cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
- /* Need to set timing */
- /* +1 is same page */
- cpu->cycle_done += 1;
- /* +2 is another */
- }
- else
- cpu->reg_PC ++;
- }
- /*** Mathematical functions ***/
- /** 69 : ADC - ADd with Carry **/
- INSTRUCTION(ADCiM)
- {
- TRACEi(("ADC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- ADC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** 65 : ADC - ADd with Carry **/
- INSTRUCTION(ADCzP)
- {
- TRACEi(("ADC $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- ADC_OPERATION(MEMORY_READ_ZP());
- }
- /** 75 : ADC - ADd with Carry **/
- INSTRUCTION(ADCzX)
- {
- TRACEi(("ADC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
- ADC_OPERATION(MEMORY_READ_ZX());
- }
- /** 61 : ADC - ADd with Carry **/
- INSTRUCTION(ADCiX)
- {
- TRACEi(("ADC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
- ADC_OPERATION(MEMORY_READ_IX());
- }
- /** 71 : ADC - ADd with Carry **/
- INSTRUCTION(ADCiY)
- {
- TRACEi(("ADC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
- ADC_OPERATION(MEMORY_READ_IY());
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** 6D : ADC - ADd with Carry **/
- INSTRUCTION(ADCaB)
- {
- TRACEi(("ADC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- ADC_OPERATION(MEMORY_READ_AB());
- }
- /** 7D : ADC - ADd with Carry **/
- INSTRUCTION(ADCaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("ADC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- ADC_OPERATION(MEMORY_READ_AX());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** 79 : ADC - ADd with Carry **/
- INSTRUCTION(ADCaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- TRACEi(("ADC $%02X%02X,Y", op2, op1));
- ADC_OPERATION(MEMORY_READ_AY());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** E9 : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCiM)
- {
- TRACEi(("SBC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- SBC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** E5 : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCzP)
- {
- TRACEi(("SBC $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- SBC_OPERATION(MEMORY_READ_ZP());
- }
- /** F5 : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCzX)
- {
- TRACEi(("SBC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
- SBC_OPERATION(MEMORY_READ_ZX());
- }
- /** E1 : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCiX)
- {
- TRACEi(("SBC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
- SBC_OPERATION(MEMORY_READ_IX());
- }
- /** F1 : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCiY)
- {
- TRACEi(("SBC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
- SBC_OPERATION(MEMORY_READ_IY());
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** ED : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCaB)
- {
- TRACEi(("SBC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- SBC_OPERATION(MEMORY_READ_AB());
- }
- /** FD : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("SBC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- SBC_OPERATION(MEMORY_READ_AX());
-
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** F9 : SBC - SuBstract with Carry **/
- INSTRUCTION(SBCaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- TRACEi(("SBC $%02X%02X,Y", op2, op1));
- SBC_OPERATION(MEMORY_READ_AY());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** C9 : CMP - CoMPare **/
- INSTRUCTION(CMPiM)
- {
- TRACEi(("CMP #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- CMP_OPERATION(cpu->reg_A, cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** C5 : CMP - CoMPare **/
- INSTRUCTION(CMPzP)
- {
- TRACEi(("CMP $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZP());
- }
- /** D5 : CMP - CoMPare **/
- INSTRUCTION(CMPzX)
- {
- TRACEi(("CMP $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZX());
- }
- /** C1 : CMP - CoMPare **/
- INSTRUCTION(CMPiX)
- {
- TRACEi(("CMP ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_IX());
- }
- /** D1 : CMP - CoMPare **/
- INSTRUCTION(CMPiY)
- {
- TRACEi(("CMP ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_IY());
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** CD : CMP - CoMPare **/
- INSTRUCTION(CMPaB)
- {
- TRACEi(("CMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_AB());
- }
- /** DD : CMP - CoMPare **/
- INSTRUCTION(CMPaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("CMP $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_AX());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** D9 : CMP - CoMPare **/
- INSTRUCTION(CMPaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- TRACEi(("CMP $%02X%02X,Y", op2, op1));
- CMP_OPERATION(cpu->reg_A, MEMORY_READ_AY());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** E0 : CPX - ComPare with Y **/
- INSTRUCTION(CPXiM)
- {
- TRACEi(("CPX #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_X, cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** E4 : CPX - ComPare with X **/
- INSTRUCTION(CPXzP)
- {
- TRACEi(("CPX $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_X, MEMORY_READ_ZP());
- }
- /** EC : CPX - ComPare with X **/
- INSTRUCTION(CPXaB)
- {
- TRACEi(("CPX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_X, MEMORY_READ_AB());
- }
- /** C0 : CPY - ComPare with Y **/
- INSTRUCTION(CPYiM)
- {
- TRACEi(("CPY #$%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_Y, cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** C4 : CPY - ComPare with Y **/
- INSTRUCTION(CPYzP)
- {
- TRACEi(("CPY $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_Y, MEMORY_READ_ZP());
- }
- /** CC : CPY - ComPare with Y **/
- INSTRUCTION(CPYaB)
- {
- TRACEi(("CPY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- CMP_OPERATION(cpu->reg_Y, MEMORY_READ_AB());
- }
- /** 09 : ORA - OR with A **/
- INSTRUCTION(ORAiM)
- {
- TRACEi(("ORA #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- ORA_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** 405 : ORA - OR with A **/
- INSTRUCTION(ORAzP)
- {
- TRACEi(("ORA $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- ORA_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
- }
- /** 15 : ORA - OR with A **/
- INSTRUCTION(ORAzX)
- {
- TRACEi(("ORA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
- ORA_OPERATION(MEMORY_READ_ZX());
- }
- /** 01 : ORA - OR with A **/
- INSTRUCTION(ORAiX)
- {
- TRACEi(("ORA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
- ORA_OPERATION(MEMORY_READ_IX());
- }
- /** 11 : ORA - OR with A **/
- INSTRUCTION(ORAiY)
- {
- TRACEi(("ORA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
- ORA_OPERATION(MEMORY_READ_IY());
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** 0D : ORA - OR with A **/
- INSTRUCTION(ORAaB)
- {
- TRACEi(("ORA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- ORA_OPERATION(MEMORY_READ_AB());
- }
- /** 1D : ORA - OR with A **/
- INSTRUCTION(ORAaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("ORA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- ORA_OPERATION(MEMORY_READ_AX());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** 19 : ORA - OR with A **/
- INSTRUCTION(ORAaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("ORA $%02X%02X,Y", op2, op1));
- ORA_OPERATION(MEMORY_READ_AY());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** 49 : EOR - Exclusive OR **/
- INSTRUCTION(EORiM)
- {
- TRACEi(("EOR #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- EOR_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** 45 : EOR - Exclusive OR **/
- INSTRUCTION(EORzP)
- {
- TRACEi(("EOR $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- EOR_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
- }
- /** 55 : EOR - Exclusive OR **/
- INSTRUCTION(EORzX)
- {
- TRACEi(("EOR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
- EOR_OPERATION(MEMORY_READ_ZX());
- }
- /** 41 : EOR - Exclusive OR **/
- INSTRUCTION(EORiX)
- {
- TRACEi(("EOR ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
- EOR_OPERATION(MEMORY_READ_IX());
- }
- /** 51 : EOR - Exclusive OR **/
- INSTRUCTION(EORiY)
- {
- TRACEi(("EOR ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
- EOR_OPERATION(MEMORY_READ_IY());
-
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** 4D : EOR - Exclusive OR **/
- INSTRUCTION(EORaB)
- {
- TRACEi(("EOR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- EOR_OPERATION(MEMORY_READ_AB());
- }
- /** 5D : EOR - Exclusive OR **/
- INSTRUCTION(EORaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("EOR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- EOR_OPERATION(MEMORY_READ_AX());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** 59 : EOR - Exclusive OR **/
- INSTRUCTION(EORaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- TRACEi(("EOR $%02X%02X,Y", op2, op1));
- EOR_OPERATION(MEMORY_READ_AY());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /** 29 : AND - Logical AND **/
- INSTRUCTION(ANDiM)
- {
- TRACEi(("AND #$%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- AND_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++));
- }
- /** 25 : AND - Logical AND **/
- INSTRUCTION(ANDzP)
- {
- TRACEi(("AND $%02X", cpu->memory_opcode_read(cpu->reg_PC) ));
- AND_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++)));
- }
- /** 35 : AND - Logical AND **/
- INSTRUCTION(ANDzX)
- {
- TRACEi(("AND $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) ));
- AND_OPERATION(MEMORY_READ_ZX());
- }
- /** 21 : AND - Logical AND **/
- INSTRUCTION(ANDiX)
- {
- TRACEi(("AND ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) ));
- AND_OPERATION(MEMORY_READ_IX());
- }
- /** 31 : AND - Logical AND **/
- INSTRUCTION(ANDiY)
- {
- TRACEi(("AND ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) ));
- AND_OPERATION(MEMORY_READ_IY());
-
- CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y);
- }
- /** 2D : AND - Logical AND **/
- INSTRUCTION(ANDaB)
- {
- TRACEi(("AND $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- AND_OPERATION(MEMORY_READ_AB());
- }
- /** 3D : AND - Logical AND **/
- INSTRUCTION(ANDaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("AND $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- AND_OPERATION(MEMORY_READ_AX());
-
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_X);
- }
- /** 39 : AND - Logical AND **/
- INSTRUCTION(ANDaY)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
- TRACEi(("AND $%02X%02X,Y", op2, op1));
- AND_OPERATION(MEMORY_READ_AY());
- CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y);
- }
- /*** Misc instructions ***/
- /** 24 : BIT **/
- INSTRUCTION(BITzP)
- {
- TRACEi(("BIT $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- BIT_OPERATION(MEMORY_READ_ZP());
- }
- /** 2C : BIT **/
- INSTRUCTION(BITaB)
- {
- TRACEi(("BIT $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- BIT_OPERATION(MEMORY_READ_AB());
- }
- /** 2A : ROL A **/
- INSTRUCTION(ROLiM)
- {
- TRACEi(("ROL A"));
- ROL_OPERATION(cpu->reg_A);
- }
- /** 6A : ROR A **/
- INSTRUCTION(RORiM)
- {
- TRACEi(("ROR A"));
- ROR_OPERATION(cpu->reg_A);
- }
- /** 0A : ASL A **/
- INSTRUCTION(ASLiM)
- {
- TRACEi(("ASL A"));
- ASL_OPERATION(cpu->reg_A);
- }
- /** 4A : LSR A **/
- INSTRUCTION(LSRiM)
- {
- TRACEi(("LSR A"));
- LSR_OPERATION(cpu->reg_A);
- }
- /** 2E : ROL **/
- INSTRUCTION(ROLaB)
- {
- TRACEi(("ROL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AB();
- cpu->reg_PC -= 2;
- ROL_OPERATION(val);
- MEMORY_WRITE_AB(val);
- }
- /** 26 : ROL **/
- INSTRUCTION(ROLzP)
- {
- TRACEi(("ROL $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- ROL_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 3E : ROL **/
- INSTRUCTION(ROLaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("ROL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AX();
- cpu->reg_PC -= 2;
- ROL_OPERATION(val);
- MEMORY_WRITE_AX(val);
- }
- /** 36 : ROL **/
- INSTRUCTION(ROLzX)
- {
- TRACEi(("ROL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- ROL_OPERATION(val);
- MEMORY_WRITE_ZX(val);
- }
- /** 6E : ROR **/
- INSTRUCTION(RORaB)
- {
- TRACEi(("ROR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AB();
- cpu->reg_PC -= 2;
- ROR_OPERATION(val);
- MEMORY_WRITE_AB(val);
- }
- /** 66 : ROR **/
- INSTRUCTION(RORzP)
- {
- TRACEi(("ROR $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- ROR_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 7E : ROR **/
- INSTRUCTION(RORaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("ROR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AX();
- cpu->reg_PC -= 2;
- ROR_OPERATION(val);
- MEMORY_WRITE_AX(val);
- }
- /** 76 : ROR **/
- INSTRUCTION(RORzX)
- {
- TRACEi(("ROR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- ROR_OPERATION(val);
- MEMORY_WRITE_ZX(val);
- }
- /** 0E : ASL **/
- INSTRUCTION(ASLaB)
- {
- TRACEi(("ASL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AB();
- cpu->reg_PC -= 2;
- ASL_OPERATION(val);
- MEMORY_WRITE_AB(val);
- }
- /** 06 : ASL **/
- INSTRUCTION(ASLzP)
- {
- TRACEi(("ASL $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- ASL_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 1E : ASL **/
- INSTRUCTION(ASLaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("ASL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AX();
- cpu->reg_PC -= 2;
- ASL_OPERATION(val);
- MEMORY_WRITE_AX(val);
- }
- /** 16 : ASL **/
- INSTRUCTION(ASLzX)
- {
- TRACEi(("ASL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- ASL_OPERATION(val);
- MEMORY_WRITE_ZX(val);
- }
- /** 4E : LSR **/
- INSTRUCTION(LSRaB)
- {
- TRACEi(("LSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AB();
- cpu->reg_PC -= 2;
- LSR_OPERATION(val);
- MEMORY_WRITE_AB(val);
- }
- /** 46 : LSR **/
- INSTRUCTION(LSRzP)
- {
- TRACEi(("LSR $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- LSR_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 5E : LSR **/
- INSTRUCTION(LSRaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("LSR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AX();
- cpu->reg_PC -= 2;
- LSR_OPERATION(val);
- MEMORY_WRITE_AX(val);
- }
- /** 56 : LSR **/
- INSTRUCTION(LSRzX)
- {
- TRACEi(("LSR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- LSR_OPERATION(val);
- MEMORY_WRITE_ZX(val);
- }
- /** CE : DEC **/
- INSTRUCTION(DECaB)
- {
- TRACEi(("DEC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AB();
- cpu->reg_PC -= 2;
- MEMORY_WRITE_AB(--val);
- NZ_FLAG_UPDATE(val);
- }
- /** C6 : DEC **/
- INSTRUCTION(DECzP)
- {
- TRACEi(("DEC $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZP(--val);
- NZ_FLAG_UPDATE(val);
- }
- /** DE : DEC **/
- INSTRUCTION(DECaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("DEC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AX();
- cpu->reg_PC -= 2;
- MEMORY_WRITE_AX(--val);
- NZ_FLAG_UPDATE(val);
- }
- /** D6 : DEC **/
- INSTRUCTION(DECzX)
- {
- TRACEi(("DEC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZX(--val);
- NZ_FLAG_UPDATE(val);
- }
- /** EE : INC **/
- INSTRUCTION(INCaB)
- {
- TRACEi(("INC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AB();
- cpu->reg_PC -= 2;
- MEMORY_WRITE_AB(++val);
- NZ_FLAG_UPDATE(val);
- }
- /** E6 : INC **/
- INSTRUCTION(INCzP)
- {
- TRACEi(("INC $%02X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZP(++val);
- NZ_FLAG_UPDATE(val);
- }
- /** FE : INC **/
- INSTRUCTION(INCaX)
- {
- register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("INC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_AX();
- cpu->reg_PC -= 2;
- MEMORY_WRITE_AX(++val);
- NZ_FLAG_UPDATE(val);
- }
-
- /** F6 : INC **/
- INSTRUCTION(INCzX)
- {
- TRACEi(("INC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC)));
- byte val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZX(++val);
- NZ_FLAG_UPDATE(val);
- }
- /* */
- static InstructionFunction InstructionTable[256] =
- {
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- /* 00 */ I_BRKiM, I_ORAiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzP, I_ASLzP, I_ILLEG, I_PHPiM, I_ORAiM, I_ASLiM, I_ILLEG, I_ILLEG, I_ORAaB, I_ASLaB, I_ILLEG,
- /* 10 */ I_BPLrE, I_ORAiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzX, I_ASLzX, I_ILLEG, I_CLCiM, I_ORAaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAaX, I_ASLaX, I_ILLEG,
- /* 20 */ I_JSRaB, I_ANDiX, I_ILLEG, I_ILLEG, I_BITzP, I_ANDzP, I_ROLzP, I_ILLEG, I_PLPiM, I_ANDiM, I_ROLiM, I_ILLEG, I_BITaB, I_ANDaB, I_ROLaB, I_ILLEG,
- /* 30 */ I_BMIrE, I_ANDiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDzX, I_ROLzX, I_ILLEG, I_SECiM, I_ANDaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDaX, I_ROLaX, I_ILLEG,
- /* 40 */ I_RTIiM, I_EORiX, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzP, I_LSRzP, I_ILLEG, I_PHAiM, I_EORiM, I_LSRiM, I_ILLEG, I_JMPaB, I_EORaB, I_LSRaB, I_ILLEG,
- /* 50 */ I_BVCrE, I_EORiY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzX, I_LSRzX, I_ILLEG, I_CLIiM, I_EORaY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORaX, I_LSRaX, I_ILLEG,
- /* 60 */ I_RTSiM, I_ADCiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzP, I_RORzP, I_ILLEG, I_PLAiM, I_ADCiM, I_RORiM, I_ILLEG, I_JMPiD, I_ADCaB, I_RORaB, I_ILLEG,
- /* 70 */ I_BVSrE, I_ADCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzX, I_RORzX, I_ILLEG, I_SEIiM, I_ADCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCaX, I_RORaX, I_ILLEG,
- /* 80 */ I_ILLEG, I_STAiX, I_ILLEG, I_ILLEG, I_STYzP, I_STAzP, I_STXzP, I_ILLEG, I_DEYiM, I_ILLEG, I_TXAiM, I_ILLEG, I_STYaB, I_STAaB, I_STXaB, I_ILLEG,
- /* 90 */ I_BCCrE, I_STAiY, I_ILLEG, I_ILLEG, I_STYzX, I_STAzX, I_STXzY, I_ILLEG, I_TYAiM, I_STAaY, I_TXSiM, I_ILLEG, I_ILLEG, I_STAaX, I_ILLEG, I_ILLEG,
- /* A0 */ I_LDYiM, I_LDAiX, I_LDXiM, I_ILLEG, I_LDYzP, I_LDAzP, I_LDXzP, I_ILLEG, I_TAYiM, I_LDAiM, I_TAXiM, I_ILLEG, I_LDYaB, I_LDAaB, I_LDXaB, I_ILLEG,
- /* B0 */ I_BCSrE, I_LDAiY, I_ILLEG, I_ILLEG, I_LDYzX, I_LDAzX, I_LDXzY, I_ILLEG, I_CLViM, I_LDAaY, I_TSXiM, I_ILLEG, I_LDYaX, I_LDAaX, I_LDXaY, I_ILLEG,
- /* C0 */ I_CPYiM, I_CMPiX, I_ILLEG, I_ILLEG, I_CPYzP, I_CMPzP, I_DECzP, I_ILLEG, I_INYiM, I_CMPiM, I_DEXiM, I_ILLEG, I_CPYaB, I_CMPaB, I_DECaB, I_ILLEG,
- /* D0 */ I_BNErE, I_CMPiY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPzX, I_DECzX, I_ILLEG, I_CLDiM, I_CMPaY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPaX, I_DECaX, I_ILLEG,
- /* E0 */ I_CPXiM, I_SBCiX, I_ILLEG, I_ILLEG, I_CPXzP, I_SBCzP, I_INCzP, I_ILLEG, I_INXiM, I_SBCiM, I_NOPiM, I_ILLEG, I_CPXaB, I_SBCaB, I_INCaB, I_ILLEG,
- /* F0 */ I_BEQrE, I_SBCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCzX, I_INCzX, I_ILLEG, I_SEDiM, I_SBCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCaX, I_INCaX, I_ILLEG
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- };
- static inline int quick6502_exec_one(quick6502_cpu *cpu)
- {
- register byte opcode = cpu->memory_opcode_read(cpu->reg_PC++);
-
- TRACEi(("Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]",
- cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
- cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
- cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
- cpu->reg_P&Q6502_R_FLAG ? 'R':'.',
- cpu->reg_P&Q6502_B_FLAG ? 'B':'.',
- cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
- cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
- cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
- cpu->reg_P&Q6502_C_FLAG ? 'C':'.'));
-
- InstructionTable[opcode](cpu);
- cpu->cycle_done += CycleTable[opcode];
- if (cpu->page_crossed) { cpu->cycle_done++; cpu->page_crossed = 0; }
- if (cpu->int_pending != 0)
- {
- quick6502_int(cpu, Q6502_IRQ_SIGNAL);
- }
- return 0;
- }
|