12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342 |
- /**
- * CoreCPU - The Quick6502 Project
- * corecpu.c
- *
- * Created by Manoël Trapier on 24/02/08
- * Copyright (c) 2002-2019 986-Studio.
- *
- */
- /* TODO: Add Inst/MemAccess breakpoints */
- /* Depending on the OS, one of these provide the malloc function */
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.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
- /*
- * IP_ == "Instruction Parameter"
- * nP: No parameters
- * iM: Immediate
- * iX: Indirect by X
- * iY: Indirect by Y
- * zP: Zero Page
- * zX: Zero Page Index by X
- * zY: Zero Page Index by Y
- * iD: Indirect Double
- * aB: Absolute
- * aX: Absolute by X
- * aY: Absolute by Y
- * rE: Relative
- */
- #define IP_nP "N"
- #define IP_iM "I"
- #define IP_iX "X"
- #define IP_iY "Y"
- #define IP_zP "0"
- #define IP_zX "z"
- #define IP_zY "Z"
- #define IP_iD "D"
- #define IP_aB "A"
- #define IP_aX "x"
- #define IP_aY "y"
- #define IP_rE "R"
- #define IP_nPc 'N'
- #define IP_iMc 'I'
- #define IP_iXc 'X'
- #define IP_iYc 'Y'
- #define IP_zPc '0'
- #define IP_zXc 'z'
- #define IP_zYc 'Z'
- #define IP_iDc 'D'
- #define IP_aBc 'A'
- #define IP_aXc 'x'
- #define IP_aYc 'y'
- #define IP_rEc 'R'
- #define IPf_nP ""
- #define IPf_iM " $%02X"
- #define IPf_iX " ($%02X,X)"
- #define IPf_iY " ($%02X),Y"
- #define IPf_zP " $%02X"
- #define IPf_zX " $%02X,X"
- #define IPf_zY " $%02X,Y"
- #define IPf_iD " ($%02X%02X)"
- #define IPf_aB " $%02X%02X"
- #define IPf_aX " $%02X%02X,X"
- #define IPf_aY " $%02X%02X,Y"
- #define IPf_rE " $%02X%02X"
- #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) ); cpu->reg_PC++
- #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 ); cpu->reg_PC++
- #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+1) << 8) )); cpu->reg_PC += 2
- #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); cpu->reg_PC++
- #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); cpu->reg_PC++
- #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+1) << 8) ), val); cpu->reg_PC += 2
- #define MEMORY_WRITE_AX(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC ) ) |\
- (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ) + cpu->reg_X, val); cpu->reg_PC += 2
- #define MEMORY_WRITE_AY(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC ) ) |\
- (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ) + cpu->reg_Y, val); cpu->reg_PC += 2
- #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 Q6502_NO_DECIMAL
- #define ADC_OPERATION(read) do {\
- uint16_t tmp = 0; uint8_t 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)?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 {\
- uint16_t tmp = 0; uint8_t 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 { \
- uint16_t 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 { \
- uint8_t 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 {\
- uint16_t 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 {\
- uint16_t 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 occurred !
- */
- 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)
- */
- uint32_t quick6502_run(quick6502_cpu *cpu, uint32_t cycles)
- {
- cpu->running = true;
- while (cpu->cycle_done < cycles)
- {
- quick6502_exec_one(cpu);
- }
- cpu->cycle_done -= cycles;
- cpu->running = false;
- return cycles + cpu->cycle_done;
- }
- /** Loop CPU until explicit quit */
- void quick6502_loop(quick6502_cpu *cpu)
- {
- cpu->running = true;
- while (cpu->exit_loop)
- {
- quick6502_exec_one(cpu);
- }
- cpu->running = false;
- }
- /** Run CPU for one instruction */
- void quick6502_exec(quick6502_cpu *cpu)
- {
- cpu->running = true;
- quick6502_exec_one(cpu);
- cpu->running = false;
- }
- /** 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[100];
- /* Display registers */
- fprintf(fp,
- "## Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X [%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_read(0x100 | i));
- }
- fprintf(fp, "] Run:%c Cycle:%ld\n", cpu->running ? 'Y' : 'N', cpu->cycle_done);
- fprintf(fp, "## Quick6502: InstrMem: [ ");
- for (i = 0 ; i < 0x5 ; i++)
- {
- fprintf(fp, "$%02X ", cpu->memory_opcode_read(cpu->reg_PC + i));
- }
- fprintf(fp, "]\n");
- quick6502_getinstruction(cpu, true, cpu->reg_PC, instr, NULL);
- fprintf(fp, "## $%04X: %s\n", cpu->reg_PC, instr);
- }
- typedef enum InstructionNameTag
- {
- n_ILG = 0, n_NOP,
- n_CLI, n_SEI, n_CLC, n_SEC, n_CLD, n_SED, n_CLV,
- n_LDA, n_LDX, n_LDY, n_STA, n_STX, n_STY,
- n_TXA, n_TAX, n_TAY, n_TYA, n_TSX, n_TXS,
- n_PHA, n_PLA, n_PHP, n_PLP,
- n_DEX, n_DEY, n_INX, n_INY, n_DEC, n_INC,
- n_JSR, n_RTS, n_JMP, n_BRK, n_RTI,
- n_BCC, n_BCS, n_BEQ, n_BNE, n_BPL, n_BVS, n_BVC, n_BMI,
- n_EOR, n_AND, n_BIT, n_ORA, n_ADC, n_SBC,
- n_ROL, n_ROR, n_ASL, n_LSR,
- n_CMP, n_CPX, n_CPY,
- } InstructionNameTag;
- char *InstructionName[] =
- {
- "ILLEGAL", "NOP",
- "CLI", "SEI", "CLC", "SEC", "CLD", "SED", "CLV",
- "LDA", "LDX", "LDY", "STA", "STX", "STY",
- "TXA", "TAX", "TAY", "TYA", "TSX", "TXS",
- "PHA", "PLA", "PHP", "PLP",
- "DEX", "DEY", "INX", "INY", "DEC", "INC",
- "JSR", "RTS", "JMP", "BRK", "RTI",
- "BCC", "BCS", "BEQ", "BNE", "BPL", "BVS", "BVC", "BVS",
- "EOR", "AND", "BIT", "ORA", "ADC", "SBC",
- "ROL", "ROR", "ASL", "LSR",
- "CMP", "CPX", "CPY",
- };
- /**
- * 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 uint8_t 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(CLInP)
- {
- TRACEi(("CLI"));
- cpu->reg_P &= ~Q6502_I_FLAG;
- }
- /** 78 : SEI - SEt Interrupt **/
- INSTRUCTION(SEInP)
- {
- TRACEi(("SEI"));
- cpu->reg_P |= Q6502_I_FLAG;
- }
- /** 18 : CLC - CLear Carry **/
- INSTRUCTION(CLCnP)
- {
- TRACEi(("CLC"));
- cpu->reg_P &= ~Q6502_C_FLAG;
- }
- /** 38 : SEC - SEt Carry **/
- INSTRUCTION(SECnP)
- {
- TRACEi(("SEC"));
- cpu->reg_P |= Q6502_C_FLAG;
- }
- /** D8 : CLD - CLear Decimal **/
- INSTRUCTION(CLDnP)
- {
- TRACEi(("CLD"));
- cpu->reg_P &= ~Q6502_D_FLAG;
- }
- /** F8 : SED - SEt Decimal **/
- INSTRUCTION(SEDnP)
- {
- TRACEi(("SED"));
- cpu->reg_P |= Q6502_D_FLAG;
- }
- /** B8 : CLV - CLear oVerflow **/
- INSTRUCTION(CLVnP)
- {
- TRACEi(("CLV"));
- cpu->reg_P &= ~Q6502_V_FLAG;
- }
- /** EA : NOP - NO oPeration **/
- INSTRUCTION(NOPnP)
- {
- 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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(TAXnP)
- {
- TRACEi(("TAX"));
- cpu->reg_X = cpu->reg_A;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** 8A : TXA - Transfer X to A **/
- INSTRUCTION(TXAnP)
- {
- TRACEi(("TXA"));
- cpu->reg_A = cpu->reg_X;
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** A8 : TAY - Transfer A to Y **/
- INSTRUCTION(TAYnP)
- {
- TRACEi(("TAY"));
- cpu->reg_Y = cpu->reg_A;
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** 98 : TYA - Transfer Y to A **/
- INSTRUCTION(TYAnP)
- {
- TRACEi(("TYA"));
- cpu->reg_A = cpu->reg_Y;
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /* BA : TSX - Transfer S to X **/
- INSTRUCTION(TSXnP)
- {
- TRACEi(("TSX"));
- cpu->reg_X = cpu->reg_S;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** 9A : TXS - Transfer X to S **/
- INSTRUCTION(TXSnP)
- {
- TRACEi(("TXS"));
- cpu->reg_S = cpu->reg_X;
- }
- /**** Simple register operation instructions ****/
- /** CA : DEX - DEcrement X **/
- INSTRUCTION(DEXnP)
- {
- TRACEi(("DEX"));
- cpu->reg_X--;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** 88 : DEY - DEcrement Y **/
- INSTRUCTION(DEYnP)
- {
- TRACEi(("DEY"));
- cpu->reg_Y--;
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /** E8 : INX - INcrement X **/
- INSTRUCTION(INXnP)
- {
- TRACEi(("INX"));
- cpu->reg_X++;
- NZ_FLAG_UPDATE(cpu->reg_X);
- }
- /** C8 : INY - INcrement Y **/
- INSTRUCTION(INYnP)
- {
- TRACEi(("INY"));
- cpu->reg_Y++;
- NZ_FLAG_UPDATE(cpu->reg_Y);
- }
- /**** Stack related instructions ****/
- /** 48 : PHA - PusH A */
- INSTRUCTION(PHAnP)
- {
- TRACEi(("PHA"));
- PUSH_S(cpu->reg_A);
- }
- /** 68 : PLA - PuLl A */
- INSTRUCTION(PLAnP)
- {
- TRACEi(("PLA"));
- cpu->reg_A = POP_S();
- NZ_FLAG_UPDATE(cpu->reg_A);
- }
- /** 08 : PHP - PusH P */
- INSTRUCTION(PHPnP)
- {
- TRACEi(("PHP"));
- PUSH_S((cpu->reg_P | Q6502_R_FLAG | Q6502_B_FLAG));
- }
- /** 28 : PLP - PuLl P */
- INSTRUCTION(PLPnP)
- {
- 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 Subroutine */
- INSTRUCTION(RTSnP)
- {
- TRACEi(("RTS"));
- cpu->reg_PC = POP_S();
- cpu->reg_PC |= (POP_S() << 8);
- cpu->reg_PC++;
- }
- /** 4C : JMP $xxxx - JuMP unconditionally 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 + 1) << 8);
- }
- /** 6C : JMP ($xxxx) - JuMP unconditionally 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(BRKnP)
- {
- 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(RTInP)
- {
- TRACEi(("RTI"));
- cpu->reg_P = POP_S();
- cpu->reg_PC = POP_S();
- cpu->reg_PC |= (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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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 uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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(ROLnP)
- {
- TRACEi(("ROL A"));
- ROL_OPERATION(cpu->reg_A);
- }
- /** 6A : ROR A **/
- INSTRUCTION(RORnP)
- {
- TRACEi(("ROR A"));
- ROR_OPERATION(cpu->reg_A);
- }
- /** 0A : ASL A **/
- INSTRUCTION(ASLnP)
- {
- TRACEi(("ASL A"));
- ASL_OPERATION(cpu->reg_A);
- }
- /** 4A : LSR A **/
- INSTRUCTION(LSRnP)
- {
- 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- ROL_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 3E : ROL **/
- INSTRUCTION(ROLaX)
- {
- register uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- ROR_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 7E : ROR **/
- INSTRUCTION(RORaX)
- {
- register uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- ASL_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 1E : ASL **/
- INSTRUCTION(ASLaX)
- {
- register uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- LSR_OPERATION(val);
- MEMORY_WRITE_ZP(val);
- }
- /** 5E : LSR **/
- INSTRUCTION(LSRaX)
- {
- register uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZP(--val);
- NZ_FLAG_UPDATE(val);
- }
- /** DE : DEC **/
- INSTRUCTION(DECaX)
- {
- register uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZP();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZP(++val);
- NZ_FLAG_UPDATE(val);
- }
- /** FE : INC **/
- INSTRUCTION(INCaX)
- {
- register uint8_t op1 = cpu->memory_opcode_read(cpu->reg_PC++);
- register uint8_t 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)));
- uint8_t 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)));
- uint8_t val = MEMORY_READ_ZX();
- cpu->reg_PC -= 1;
- MEMORY_WRITE_ZX(++val);
- NZ_FLAG_UPDATE(val);
- }
- /* iM: Immediate
- * iX: Indirect by X
- * iY: Indirect by Y
- * zP: Zero Page
- * zX: Zero Page Index by X
- * zY: Zero Page Index by Y
- * iD: Indirect Double
- * aB: Absolute
- * aX: Absolute by X
- * aY: Absolute by Y
- */
- static InstructionFunction InstructionTable[256] =
- {
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- /* 00 */ I_BRKnP, I_ORAiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzP, I_ASLzP, I_ILLEG, I_PHPnP, I_ORAiM,
- I_ASLnP, I_ILLEG, I_ILLEG, I_ORAaB, I_ASLaB, I_ILLEG,
- /* 10 */ I_BPLrE, I_ORAiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzX, I_ASLzX, I_ILLEG, I_CLCnP, I_ORAaY,
- I_ILLEG, I_ILLEG, I_ILLEG, I_ORAaX, I_ASLaX, I_ILLEG,
- /* 20 */ I_JSRaB, I_ANDiX, I_ILLEG, I_ILLEG, I_BITzP, I_ANDzP, I_ROLzP, I_ILLEG, I_PLPnP, I_ANDiM,
- I_ROLnP, I_ILLEG, I_BITaB, I_ANDaB, I_ROLaB, I_ILLEG,
- /* 30 */ I_BMIrE, I_ANDiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDzX, I_ROLzX, I_ILLEG, I_SECnP, I_ANDaY,
- I_ILLEG, I_ILLEG, I_ILLEG, I_ANDaX, I_ROLaX, I_ILLEG,
- /* 40 */ I_RTInP, I_EORiX, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzP, I_LSRzP, I_ILLEG, I_PHAnP, I_EORiM,
- I_LSRnP, I_ILLEG, I_JMPaB, I_EORaB, I_LSRaB, I_ILLEG,
- /* 50 */ I_BVCrE, I_EORiY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzX, I_LSRzX, I_ILLEG, I_CLInP, I_EORaY,
- I_ILLEG, I_ILLEG, I_ILLEG, I_EORaX, I_LSRaX, I_ILLEG,
- /* 60 */ I_RTSnP, I_ADCiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzP, I_RORzP, I_ILLEG, I_PLAnP, I_ADCiM,
- I_RORnP, I_ILLEG, I_JMPiD, I_ADCaB, I_RORaB, I_ILLEG,
- /* 70 */ I_BVSrE, I_ADCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzX, I_RORzX, I_ILLEG, I_SEInP, I_ADCaY,
- I_ILLEG, I_ILLEG, I_ILLEG, I_ADCaX, I_RORaX, I_ILLEG,
- /* 80 */ I_ILLEG, I_STAiX, I_ILLEG, I_ILLEG, I_STYzP, I_STAzP, I_STXzP, I_ILLEG, I_DEYnP, I_ILLEG,
- I_TXAnP, I_ILLEG, I_STYaB, I_STAaB, I_STXaB, I_ILLEG,
- /* 90 */ I_BCCrE, I_STAiY, I_ILLEG, I_ILLEG, I_STYzX, I_STAzX, I_STXzY, I_ILLEG, I_TYAnP, I_STAaY,
- I_TXSnP, I_ILLEG, I_ILLEG, I_STAaX, I_ILLEG, I_ILLEG,
- /* A0 */ I_LDYiM, I_LDAiX, I_LDXiM, I_ILLEG, I_LDYzP, I_LDAzP, I_LDXzP, I_ILLEG, I_TAYnP, I_LDAiM,
- I_TAXnP, I_ILLEG, I_LDYaB, I_LDAaB, I_LDXaB, I_ILLEG,
- /* B0 */ I_BCSrE, I_LDAiY, I_ILLEG, I_ILLEG, I_LDYzX, I_LDAzX, I_LDXzY, I_ILLEG, I_CLVnP, I_LDAaY,
- I_TSXnP, I_ILLEG, I_LDYaX, I_LDAaX, I_LDXaY, I_ILLEG,
- /* C0 */ I_CPYiM, I_CMPiX, I_ILLEG, I_ILLEG, I_CPYzP, I_CMPzP, I_DECzP, I_ILLEG, I_INYnP, I_CMPiM,
- I_DEXnP, I_ILLEG, I_CPYaB, I_CMPaB, I_DECaB, I_ILLEG,
- /* D0 */ I_BNErE, I_CMPiY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPzX, I_DECzX, I_ILLEG, I_CLDnP, I_CMPaY,
- I_ILLEG, I_ILLEG, I_ILLEG, I_CMPaX, I_DECaX, I_ILLEG,
- /* E0 */ I_CPXiM, I_SBCiX, I_ILLEG, I_ILLEG, I_CPXzP, I_SBCzP, I_INCzP, I_ILLEG, I_INXnP, I_SBCiM,
- I_NOPnP, I_ILLEG, I_CPXaB, I_SBCaB, I_INCaB, I_ILLEG,
- /* F0 */ I_BEQrE, I_SBCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCzX, I_INCzX, I_ILLEG, I_SEDnP, I_SBCaY,
- I_ILLEG, I_ILLEG, I_ILLEG, I_SBCaX, I_INCaX, I_ILLEG
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- };
- #if 1
- typedef enum InstructionType
- {
- t_IMM = 0, t_IDX, t_IDY, t_ABS,
- t_REL, t_ZEP, t_ZPX, t_ZPY,
- t_ABX, t_ABY, t_IND, t_NOP,
- } InstructionType;
- static InstructionType InstructionTypeTable[256] =
- {
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- };
- static InstructionNameTag InstructionNameTable[256] =
- {
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 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,
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- };
- /** Get current instruction name at specified address and put it into buffer */
- int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
- uint16_t addr, char *buffer, int *strlength)
- {
- int len = 0, curlen;
- int readuint8_t = 1;
- char *str = buffer;
- uint8_t opcode = cpu->memory_opcode_read(addr);
- uint8_t value_u8;
- uint16_t value_u16;
- curlen = sprintf(str, "%s", InstructionName[InstructionNameTable[opcode]]);
- str += curlen;
- len += curlen;
- switch (InstructionTypeTable[opcode])
- {
- default: /* Nothing to do */
- case t_NOP:
- break;
- case t_IMM:
- curlen = sprintf(str, " #$%02X", cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- /* Nothing to interpret.. Really */
- readuint8_t += 2;
- break;
- case t_IDX:
- curlen = sprintf(str, " ($%02X, X)", cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- value_u8 = cpu->memory_opcode_read(addr + 1);
- value_u16 = value_u8 + cpu->reg_X;
- curlen = sprintf(str, " ; ($%02X + $%02X) -> ($%02X) -> $%02X%02X",
- value_u8, cpu->reg_X,
- value_u16 & 0xFF,
- cpu->memory_page0_read(value_u16),
- cpu->memory_page0_read(value_u16 + 1));
- str += curlen;
- len += curlen;
- }
- readuint8_t += 1;
- break;
- case t_IDY:
- curlen = sprintf(str, " ($%02X), Y", cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- value_u8 = cpu->memory_opcode_read(addr + 1);
- value_u16 = (cpu->memory_page0_read(value_u8 + 1) << 8) |
- (cpu->memory_page0_read(value_u8));
- curlen = sprintf(str, " ; ($%02X) + $%02X -> $%04X + $%02X -> $%04X",
- value_u8, cpu->reg_Y,
- value_u16, cpu->reg_Y,
- value_u16 + cpu->reg_Y
- );
- str += curlen;
- len += curlen;
- }
- readuint8_t += 1;
- break;
- case t_ABS:
- curlen = sprintf(str, " $%02X%02X", cpu->memory_opcode_read(addr + 2),
- cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- /* Nothing to interpret.. Really */
- readuint8_t += 2;
- break;
- case t_REL:
- value_u16 = 2 + addr + (signed char)cpu->memory_opcode_read(addr + 1);
- curlen = sprintf(str, " $%04X", value_u16);
- str += curlen;
- len += curlen;
- /* Nothing to interpret.. Really */
- readuint8_t += 1;
- break;
- case t_ZEP:
- curlen = sprintf(str, " $%02X", cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- /* Nothing to interpret.. Really */
- readuint8_t += 1;
- break;
- case t_ZPX:
- curlen = sprintf(str, " $%02X, X", cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- curlen = sprintf(str, " ; $%02X + $%02x -> $%02X",
- cpu->memory_opcode_read(addr + 1), cpu->reg_X,
- (cpu->memory_opcode_read(addr + 1) + cpu->reg_X) & 0xFF);
- str += curlen;
- len += curlen;
- }
- readuint8_t += 1;
- break;
- case t_ZPY:
- curlen = sprintf(str, " $%02X, Y", cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- curlen = sprintf(str, " ; $%02X + $%02x -> $%02X",
- cpu->memory_opcode_read(addr + 1), cpu->reg_Y,
- (cpu->memory_opcode_read(addr + 1) + cpu->reg_Y) & 0xFF);
- str += curlen;
- len += curlen;
- }
- readuint8_t += 1;
- break;
- case t_ABX:
- curlen = sprintf(str, " $%02X%02X, X", cpu->memory_opcode_read(addr + 2),
- cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) |
- cpu->memory_opcode_read(addr + 1);
- curlen = sprintf(str, " ; $%04X + $%02X -> $%04X", value_u16,
- cpu->reg_X, value_u16 + cpu->reg_X);
- str += curlen;
- len += curlen;
- }
- readuint8_t += 2;
- break;
- case t_ABY:
- curlen = sprintf(str, " $%02X%02X, Y", cpu->memory_opcode_read(addr + 2),
- cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) |
- cpu->memory_opcode_read(addr + 1);
- curlen = sprintf(str, " ; $%04X + $%02X -> $%04X", value_u16,
- cpu->reg_Y, value_u16 + cpu->reg_Y);
- str += curlen;
- len += curlen;
- }
- readuint8_t += 2;
- break;
- case t_IND:
- curlen = sprintf(str, " ($%02X%02X)", cpu->memory_opcode_read(addr + 2),
- cpu->memory_opcode_read(addr + 1));
- str += curlen;
- len += curlen;
- if (interpret)
- {
- value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) |
- cpu->memory_opcode_read(addr + 1);
- value_u16 = cpu->memory_read(value_u16) |
- (cpu->memory_read((value_u16 & 0xFF00) |
- ((value_u16 + 1) & 0x00FF)) << 8);
- curlen = sprintf(str, " ; ($%02X%02X) -> $%04X",
- cpu->memory_opcode_read(addr + 2),
- cpu->memory_opcode_read(addr + 1),
- cpu->memory_opcode_read(addr));
- str += curlen;
- len += curlen;
- }
- readuint8_t += 2;
- break;
- }
- if (strlength != NULL)
- {
- *strlength = len;
- }
- return readuint8_t;
- }
- #else
- static char InstructionParameters[256][10] =
- {
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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",
- /* 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"
- /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
- };
- /** Get current instruction name at specified address and put it into buffer */
- int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
- uint16_t addr, char *buffer, int *strlength)
- {
- uint8_t instr = cpu->memory_opcode_read(cpu->reg_PC);
- uint8_t *instrText = InstructionParameters[instr];
-
- buffer += strlen(strcpy(buffer, instrText[1]));
- switch(instrText[0])
- {
- case IP_nPc: default: break;
- case IP_iMc: buffer += strlen(sprintf(buffer, IPf_iM, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
- case IP_iXc: buffer += strlen(sprintf(buffer, IPf_iX, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
- case IP_iYc: buffer += strlen(sprintf(buffer, IPf_iY, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
- case IP_zPc: buffer += strlen(sprintf(buffer, IPf_zP, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
- case IP_zXc: buffer += strlen(sprintf(buffer, IPf_zX, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
- case IP_zYc: buffer += strlen(sprintf(buffer, IPf_zY, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
- 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;
- 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;
- 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;
- 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;
- case IP_rEc: buffer += strlen(sprintf(buffer, IPf_rE, 0, cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1)); break;
- }
-
- *buffer = 0;
- }
- #endif
- static inline int quick6502_exec_one(quick6502_cpu *cpu)
- {
- register uint8_t opcode = cpu->memory_opcode_read(cpu->reg_PC);
- //char instr[100];
- //quick6502_dump(cpu, stdout);
- 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);
- //printf("--------------------------------------------------------------\n");
- /*quick6502_getinstruction(cpu, (1==1), cpu->reg_PC, instr, NULL);
- printf("%04X: %s\n", cpu->reg_PC, instr);*/
- 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;
- }
|