Path: blob/master/BizHawk.Emulation.Cores/CPUs/MOS 6502X/6502XXX/Execute.cpp
2 views
//http://nesdev.parodius.com/6502_cpu.txt12#include <stdint.h>34#include "UopTable.cpp"56typedef int8_t sbyte;7typedef uint8_t byte;8typedef uint16_t ushort;910#include "TableNZ.h"1112const ushort NMIVector = 0xFFFA;13const ushort ResetVector = 0xFFFC;14const ushort BRKVector = 0xFFFE;15const ushort IRQVector = 0xFFFE;1617#ifdef __GNUC__18#define INL __attribute__((always_inline))19#else20#define INL21#endif2223template<int index> bool Bit(int b)24{25return (b & (1 << index)) != 0;26}2728template<int index> bool Bit(byte b)29{30return (b & (1 << index)) != 0;31}3233struct CPU34{35int _anchor;36int _land0;37int _land1;38int _land2;3940// interface41void *_ReadMemory_Managed;42void *_DummyReadMemory_Managed;43void *_PeekMemory_Managed;44void *_WriteMemory_Managed;45void *_OnExecFetch_Managed; // this only calls when the first byte of an instruction is fetched.46void *_TraceCallback_Managed; // TODO4748byte (*ReadMemory)(ushort addr);49byte (*DummyReadMemory)(ushort addr);50byte (*PeekMemory)(ushort addr);51void (*WriteMemory)(ushort addr, byte val);52void (*OnExecFetch)(ushort addr);5354// config55bool BCD_Enabled;56bool debug;5758// state59byte A;60byte X;61byte Y;62//byte P;63/// <summary>Carry Flag</summary>64bool FlagC;65/// <summary>Zero Flag</summary>66bool FlagZ;67/// <summary>Interrupt Disable Flag</summary>68bool FlagI;69/// <summary>Decimal Mode Flag</summary>70bool FlagD;71/// <summary>Break Flag</summary>72bool FlagB;73/// <summary>T... Flag</summary>74bool FlagT;75/// <summary>Overflow Flag</summary>76bool FlagV;77/// <summary>Negative Flag</summary>78bool FlagN;7980ushort PC;81byte S;8283bool IRQ;84bool NMI;85bool RDY;8687int TotalExecutedCycles;8889//opcode bytes.. theoretically redundant with the temp variables? who knows.90int opcode;91byte opcode2, opcode3;9293int ea, alu_temp; //cpu internal temp variables94int mi; //microcode index95bool iflag_pending; //iflag must be stored after it is checked in some cases (CLI and SEI).96bool rdy_freeze; //true if the CPU must be frozen9798//tracks whether an interrupt condition has popped up recently.99//not sure if this is real or not but it helps with the branch_irq_hack100bool interrupt_pending;101bool branch_irq_hack; //see Uop.RelBranch_Stage3 for more details102103// transient state104byte value8, temp8;105ushort value16;106bool branch_taken;107bool my_iflag;108bool booltemp;109int tempint;110int lo, hi;111112113INL byte GetP()114{115byte ret = 0;116if (FlagC) ret |= 1;117if (FlagZ) ret |= 2;118if (FlagI) ret |= 4;119if (FlagD) ret |= 8;120if (FlagB) ret |= 16;121if (FlagT) ret |= 32;122if (FlagV) ret |= 64;123if (FlagN) ret |= 128;124return ret;125}126127128INL void SetP(byte value)129{130FlagC = (value & 1) != 0;131FlagZ = (value & 2) != 0;132FlagI = (value & 4) != 0;133FlagD = (value & 8) != 0;134FlagB = (value & 16) != 0;135FlagT = (value & 32) != 0;136FlagV = (value & 64) != 0;137FlagN = (value & 128) != 0;138}139140INL void NZ_V(byte value)141{142FlagZ = value == 0;143FlagN = (value & 0x80) != 0;144}145146147/*148void InitOpcodeHandlers()149{150//delegates arent faster than the switch. pretty sure. dont use it.151//opcodeHandlers = new Action[] {152// Unsupported,Fetch1, Fetch1_Real, Fetch2, Fetch3,FetchDummy,153// NOP,JSR,IncPC,154// Abs_WRITE_STA, Abs_WRITE_STX, Abs_WRITE_STY,Abs_WRITE_SAX,Abs_READ_BIT, Abs_READ_LDA, Abs_READ_LDY, Abs_READ_ORA, Abs_READ_LDX, Abs_READ_CMP, Abs_READ_ADC, Abs_READ_CPX, Abs_READ_SBC, Abs_READ_AND, Abs_READ_EOR, Abs_READ_CPY, Abs_READ_NOP,155// Abs_READ_LAX,Abs_RMW_Stage4, Abs_RMW_Stage6,Abs_RMW_Stage5_INC, Abs_RMW_Stage5_DEC, Abs_RMW_Stage5_LSR, Abs_RMW_Stage5_ROL, Abs_RMW_Stage5_ASL, Abs_RMW_Stage5_ROR,Abs_RMW_Stage5_SLO, Abs_RMW_Stage5_RLA, Abs_RMW_Stage5_SRE, Abs_RMW_Stage5_RRA, Abs_RMW_Stage5_DCP, Abs_RMW_Stage5_ISC,156// JMP_abs,ZpIdx_Stage3_X, ZpIdx_Stage3_Y,ZpIdx_RMW_Stage4, ZpIdx_RMW_Stage6,ZP_WRITE_STA, ZP_WRITE_STX, ZP_WRITE_STY, ZP_WRITE_SAX,ZP_RMW_Stage3, ZP_RMW_Stage5,157// ZP_RMW_DEC, ZP_RMW_INC, ZP_RMW_ASL, ZP_RMW_LSR, ZP_RMW_ROR, ZP_RMW_ROL,ZP_RMW_SLO, ZP_RMW_RLA, ZP_RMW_SRE, ZP_RMW_RRA, ZP_RMW_DCP, ZP_RMW_ISC,158// ZP_READ_EOR, ZP_READ_BIT, ZP_READ_ORA, ZP_READ_LDA, ZP_READ_LDY, ZP_READ_LDX, ZP_READ_CPX, ZP_READ_SBC, ZP_READ_CPY, ZP_READ_NOP, ZP_READ_ADC, ZP_READ_AND, ZP_READ_CMP, ZP_READ_LAX,159// IdxInd_Stage3, IdxInd_Stage4, IdxInd_Stage5,IdxInd_Stage6_READ_ORA, IdxInd_Stage6_READ_SBC, IdxInd_Stage6_READ_LDA, IdxInd_Stage6_READ_EOR, IdxInd_Stage6_READ_CMP, IdxInd_Stage6_READ_ADC, IdxInd_Stage6_READ_AND,160// IdxInd_Stage6_READ_LAX,IdxInd_Stage6_WRITE_STA, IdxInd_Stage6_WRITE_SAX,IdxInd_Stage6_RMW,IdxInd_Stage7_RMW_SLO, IdxInd_Stage7_RMW_RLA, IdxInd_Stage7_RMW_SRE, IdxInd_Stage7_RMW_RRA, IdxInd_Stage7_RMW_ISC, IdxInd_Stage7_RMW_DCP,161// IdxInd_Stage8_RMW,AbsIdx_Stage3_X, AbsIdx_Stage3_Y, AbsIdx_Stage4,AbsIdx_WRITE_Stage5_STA,AbsIdx_WRITE_Stage5_SHY, AbsIdx_WRITE_Stage5_SHX,AbsIdx_WRITE_Stage5_ERROR,AbsIdx_READ_Stage4,162// AbsIdx_READ_Stage5_LDA, AbsIdx_READ_Stage5_CMP, AbsIdx_READ_Stage5_SBC, AbsIdx_READ_Stage5_ADC, AbsIdx_READ_Stage5_EOR, AbsIdx_READ_Stage5_LDX, AbsIdx_READ_Stage5_AND, AbsIdx_READ_Stage5_ORA, AbsIdx_READ_Stage5_LDY, AbsIdx_READ_Stage5_NOP,163// AbsIdx_READ_Stage5_LAX,AbsIdx_READ_Stage5_ERROR,AbsIdx_RMW_Stage5, AbsIdx_RMW_Stage7,AbsIdx_RMW_Stage6_ROR, AbsIdx_RMW_Stage6_DEC, AbsIdx_RMW_Stage6_INC, AbsIdx_RMW_Stage6_ASL, AbsIdx_RMW_Stage6_LSR, AbsIdx_RMW_Stage6_ROL,164// AbsIdx_RMW_Stage6_SLO, AbsIdx_RMW_Stage6_RLA, AbsIdx_RMW_Stage6_SRE, AbsIdx_RMW_Stage6_RRA, AbsIdx_RMW_Stage6_DCP, AbsIdx_RMW_Stage6_ISC,IncS, DecS,165// PushPCL, PushPCH, PushP, PullP, PullPCL, PullPCH_NoInc, PushA, PullA_NoInc, PullP_NoInc,PushP_BRK, PushP_NMI, PushP_IRQ, PushP_Reset, PushDummy,FetchPCLVector, FetchPCHVector,166// Imp_ASL_A, Imp_ROL_A, Imp_ROR_A, Imp_LSR_A,Imp_SEC, Imp_CLI, Imp_SEI, Imp_CLD, Imp_CLC, Imp_CLV, Imp_SED,Imp_INY, Imp_DEY, Imp_INX, Imp_DEX,Imp_TSX, Imp_TXS, Imp_TAX, Imp_TAY, Imp_TYA, Imp_TXA,167// Imm_CMP, Imm_ADC, Imm_AND, Imm_SBC, Imm_ORA, Imm_EOR, Imm_CPY, Imm_CPX, Imm_ANC, Imm_ASR, Imm_ARR, Imm_LXA, Imm_AXS,Imm_LDA, Imm_LDX, Imm_LDY,168// Imm_Unsupported,NZ_X, NZ_Y, NZ_A,RelBranch_Stage2_BNE, RelBranch_Stage2_BPL, RelBranch_Stage2_BCC, RelBranch_Stage2_BCS, RelBranch_Stage2_BEQ, RelBranch_Stage2_BMI, RelBranch_Stage2_BVC, RelBranch_Stage2_BVS,169// RelBranch_Stage2, RelBranch_Stage3, RelBranch_Stage4,_Eor, _Bit, _Cpx, _Cpy, _Cmp, _Adc, _Sbc, _Ora, _And, _Anc, _Asr, _Arr, _Lxa, _Axs,170// AbsInd_JMP_Stage4, AbsInd_JMP_Stage5,IndIdx_Stage3, IndIdx_Stage4, IndIdx_READ_Stage5, IndIdx_WRITE_Stage5,171// IndIdx_WRITE_Stage6_STA, IndIdx_WRITE_Stage6_SHA,IndIdx_READ_Stage6_LDA, IndIdx_READ_Stage6_CMP, IndIdx_READ_Stage6_ORA, IndIdx_READ_Stage6_SBC, IndIdx_READ_Stage6_ADC, IndIdx_READ_Stage6_AND, IndIdx_READ_Stage6_EOR,172// IndIdx_READ_Stage6_LAX,IndIdx_RMW_Stage5,IndIdx_RMW_Stage6, IndIdx_RMW_Stage7_SLO, IndIdx_RMW_Stage7_RLA, IndIdx_RMW_Stage7_SRE, IndIdx_RMW_Stage7_RRA, IndIdx_RMW_Stage7_ISC, IndIdx_RMW_Stage7_DCP,IndIdx_RMW_Stage8,173// End,End_ISpecial,End_BranchSpecial,End_SuppressInterrupt,174//};175}176*/177static const int VOP_Fetch1 = 256;178static const int VOP_RelativeStuff = 257;179static const int VOP_RelativeStuff2 = 258;180static const int VOP_RelativeStuff3 = 259;181static const int VOP_NMI = 260;182static const int VOP_IRQ = 261;183static const int VOP_RESET = 262;184static const int VOP_Fetch1_NoInterrupt = 263;185static const int VOP_NUM = 264;186187/*188bool Interrupted189{190get191{192return NMI || (IRQ && !FlagI);193}194}195*/196197INL void FetchDummy()198{199DummyReadMemory(PC);200}201202/*203void Execute(int cycles)204{205for (int i = 0; i < cycles; i++)206{207ExecuteOne();208}209}*/210211void Fetch1()212{213my_iflag = FlagI;214FlagI = iflag_pending;215if (!branch_irq_hack)216{217interrupt_pending = false;218if (NMI)219{220//if (TraceCallback != nullptr)221// TraceCallback("====NMI====");222ea = NMIVector;223opcode = VOP_NMI;224NMI = false;225mi = 0;226ExecuteOneRetry();227return;228}229else if (IRQ && !my_iflag)230{231//if (TraceCallback != nullptr)232// TraceCallback("====IRQ====");233ea = IRQVector;234opcode = VOP_IRQ;235mi = 0;236ExecuteOneRetry();237return;238}239}240Fetch1_Real();241}242243INL void Fetch1_Real()244{245rdy_freeze = !RDY;246if (RDY)247{248//if (debug) Console.WriteLine(State());249branch_irq_hack = false;250if (OnExecFetch != nullptr) OnExecFetch(PC);251//if (TraceCallback != nullptr)252// TraceCallback(State());253opcode = ReadMemory(PC++);254mi = -1;255}256}257INL void Fetch2()258{259rdy_freeze = !RDY;260if (RDY)261{262opcode2 = ReadMemory(PC++);263}264}265INL void Fetch3()266{267rdy_freeze = !RDY;268if (RDY)269{270opcode3 = ReadMemory(PC++);271}272}273INL void PushPCH()274{275WriteMemory((ushort)(S-- + 0x100), (byte)(PC >> 8));276}277INL void PushPCL()278{279WriteMemory((ushort)(S-- + 0x100), (byte)PC);280}281INL void PushP_BRK()282{283FlagB = true;284WriteMemory((ushort)(S-- + 0x100), GetP());285FlagI = true;286ea = BRKVector;287288}289INL void PushP_IRQ()290{291FlagB = false;292WriteMemory((ushort)(S-- + 0x100), GetP());293FlagI = true;294ea = IRQVector;295296}297INL void PushP_NMI()298{299FlagB = false;300WriteMemory((ushort)(S-- + 0x100), GetP());301FlagI = true; //is this right?302ea = NMIVector;303304}305INL void PushP_Reset()306{307ea = ResetVector;308S--;309FlagI = true;310311}312INL void PushDummy()313{314S--;315316}317INL void FetchPCLVector()318{319rdy_freeze = !RDY;320if (RDY)321{322if (ea == BRKVector && FlagB && NMI)323{324NMI = false;325ea = NMIVector;326}327if (ea == IRQVector && !FlagB && NMI)328{329NMI = false;330ea = NMIVector;331}332alu_temp = ReadMemory((ushort)ea);333}334335}336INL void FetchPCHVector()337{338rdy_freeze = !RDY;339if (RDY)340{341alu_temp += ReadMemory((ushort)(ea + 1)) << 8;342PC = (ushort)alu_temp;343}344345}346INL void Imp_INY()347{348rdy_freeze = !RDY;349if (RDY)350{351FetchDummy(); Y++; NZ_Y();352}353}354INL void Imp_DEY()355{356rdy_freeze = !RDY;357if (RDY)358{359FetchDummy(); Y--; NZ_Y();360}361}362INL void Imp_INX()363{364rdy_freeze = !RDY;365if (RDY)366{367FetchDummy(); X++; NZ_X();368}369}370INL void Imp_DEX()371{372rdy_freeze = !RDY;373if (RDY)374{375FetchDummy(); X--; NZ_X();376}377}378INL void NZ_A()379{380FlagZ = A == 0;381FlagN = (A & 0x80) != 0;382}383INL void NZ_X()384{385FlagZ = X == 0;386FlagN = (X & 0x80) != 0;387}388INL void NZ_Y()389{390FlagZ = Y == 0;391FlagN = (Y & 0x80) != 0;392}393INL void Imp_TSX()394{395rdy_freeze = !RDY;396if (RDY)397{398FetchDummy(); X = S; NZ_X();399}400}401INL void Imp_TXS()402{403rdy_freeze = !RDY;404if (RDY)405{406FetchDummy(); S = X;407}408}409INL void Imp_TAX()410{411rdy_freeze = !RDY;412if (RDY)413{414FetchDummy(); X = A; NZ_X();415}416}417INL void Imp_TAY()418{419rdy_freeze = !RDY;420if (RDY)421{422FetchDummy(); Y = A; NZ_Y();423}424}425INL void Imp_TYA()426{427rdy_freeze = !RDY;428if (RDY)429{430FetchDummy(); A = Y; NZ_A();431}432}433INL void Imp_TXA()434{435rdy_freeze = !RDY;436if (RDY)437{438FetchDummy(); A = X; NZ_A();439}440441}442INL void Imp_SEI()443{444rdy_freeze = !RDY;445if (RDY)446{447FetchDummy(); iflag_pending = true;448}449}450INL void Imp_CLI()451{452rdy_freeze = !RDY;453if (RDY)454{455FetchDummy(); iflag_pending = false;456}457}458INL void Imp_SEC()459{460rdy_freeze = !RDY;461if (RDY)462{463FetchDummy(); FlagC = true;464}465}466INL void Imp_CLC()467{468rdy_freeze = !RDY;469if (RDY)470{471FetchDummy(); FlagC = false;472}473}474INL void Imp_SED()475{476rdy_freeze = !RDY;477if (RDY)478{479FetchDummy(); FlagD = true;480}481}482INL void Imp_CLD()483{484rdy_freeze = !RDY;485if (RDY)486{487FetchDummy(); FlagD = false;488}489}490INL void Imp_CLV()491{492rdy_freeze = !RDY;493if (RDY)494{495FetchDummy(); FlagV = false;496}497498}499INL void Abs_WRITE_STA()500{501WriteMemory((ushort)((opcode3 << 8) + opcode2), A);502}503INL void Abs_WRITE_STX()504{505WriteMemory((ushort)((opcode3 << 8) + opcode2), X);506}507INL void Abs_WRITE_STY()508{509WriteMemory((ushort)((opcode3 << 8) + opcode2), Y);510}511INL void Abs_WRITE_SAX()512{513WriteMemory((ushort)((opcode3 << 8) + opcode2), (byte)(X & A));514515}516INL void ZP_WRITE_STA()517{518WriteMemory(opcode2, A);519}520INL void ZP_WRITE_STY()521{522WriteMemory(opcode2, Y);523}524INL void ZP_WRITE_STX()525{526WriteMemory(opcode2, X);527}528INL void ZP_WRITE_SAX()529{530WriteMemory(opcode2, (byte)(X & A));531532}533INL void IndIdx_Stage3()534{535rdy_freeze = !RDY;536if (RDY)537{538ea = ReadMemory(opcode2);539}540541}542INL void IndIdx_Stage4()543{544rdy_freeze = !RDY;545if (RDY)546{547alu_temp = ea + Y;548ea = (ReadMemory((byte)(opcode2 + 1)) << 8)549| ((alu_temp & 0xFF));550}551552}553INL void IndIdx_WRITE_Stage5()554{555rdy_freeze = !RDY;556if (RDY)557{558ReadMemory((ushort)ea);559ea += (alu_temp >> 8) << 8;560}561562}563void IndIdx_READ_Stage5()564{565rdy_freeze = !RDY;566if (RDY)567{568if (!Bit<8>(alu_temp))569{570mi++;571ExecuteOneRetry();572return;573}574else575{576ReadMemory((ushort)ea);577ea = (ushort)(ea + 0x100);578}579}580}581INL void IndIdx_RMW_Stage5()582{583rdy_freeze = !RDY;584if (RDY)585{586if (Bit<8>(alu_temp))587ea = (ushort)(ea + 0x100);588ReadMemory((ushort)ea);589}590591}592INL void IndIdx_WRITE_Stage6_STA()593{594WriteMemory((ushort)ea, A);595596}597INL void IndIdx_WRITE_Stage6_SHA()598{599WriteMemory((ushort)ea, (byte)(A & X & 7));600601}602INL void IndIdx_READ_Stage6_LDA()603{604rdy_freeze = !RDY;605if (RDY)606{607A = ReadMemory((ushort)ea);608NZ_A();609}610}611INL void IndIdx_READ_Stage6_CMP()612{613rdy_freeze = !RDY;614if (RDY)615{616alu_temp = ReadMemory((ushort)ea);617_Cmp();618}619}620INL void IndIdx_READ_Stage6_AND()621{622rdy_freeze = !RDY;623if (RDY)624{625alu_temp = ReadMemory((ushort)ea);626_And();627}628}629INL void IndIdx_READ_Stage6_EOR()630{631rdy_freeze = !RDY;632if (RDY)633{634alu_temp = ReadMemory((ushort)ea);635_Eor();636}637}638INL void IndIdx_READ_Stage6_LAX()639{640rdy_freeze = !RDY;641if (RDY)642{643A = X = ReadMemory((ushort)ea);644NZ_A();645}646}647INL void IndIdx_READ_Stage6_ADC()648{649rdy_freeze = !RDY;650if (RDY)651{652alu_temp = ReadMemory((ushort)ea);653_Adc();654}655}656INL void IndIdx_READ_Stage6_SBC()657{658rdy_freeze = !RDY;659if (RDY)660{661alu_temp = ReadMemory((ushort)ea);662_Sbc();663}664}665INL void IndIdx_READ_Stage6_ORA()666{667rdy_freeze = !RDY;668if (RDY)669{670alu_temp = ReadMemory((ushort)ea);671_Ora();672}673}674INL void IndIdx_RMW_Stage6()675{676rdy_freeze = !RDY;677if (RDY)678{679alu_temp = ReadMemory((ushort)ea);680}681682}683INL void IndIdx_RMW_Stage7_SLO()684{685WriteMemory((ushort)ea, (byte)alu_temp);686value8 = (byte)alu_temp;687FlagC = (value8 & 0x80) != 0;688alu_temp = value8 = (byte)((value8 << 1));689A |= value8;690NZ_A();691}692INL void IndIdx_RMW_Stage7_SRE()693{694WriteMemory((ushort)ea, (byte)alu_temp);695value8 = (byte)alu_temp;696FlagC = (value8 & 1) != 0;697alu_temp = value8 = (byte)(value8 >> 1);698A ^= value8;699NZ_A();700}701INL void IndIdx_RMW_Stage7_RRA()702{703WriteMemory((ushort)ea, (byte)alu_temp);704value8 = temp8 = (byte)alu_temp;705alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));706FlagC = (temp8 & 1) != 0;707_Adc();708}709INL void IndIdx_RMW_Stage7_ISC()710{711WriteMemory((ushort)ea, (byte)alu_temp);712value8 = temp8 = (byte)alu_temp;713alu_temp = value8 = (byte)(value8 + 1);714_Sbc();715}716INL void IndIdx_RMW_Stage7_DCP()717{718WriteMemory((ushort)ea, (byte)alu_temp);719value8 = temp8 = (byte)alu_temp;720alu_temp = value8 = (byte)(value8 - 1);721FlagC = (temp8 & 1) != 0;722_Cmp();723}724INL void IndIdx_RMW_Stage7_RLA()725{726WriteMemory((ushort)ea, (byte)alu_temp);727value8 = temp8 = (byte)alu_temp;728alu_temp = value8 = (byte)((value8 << 1) | (FlagC));729FlagC = (temp8 & 0x80) != 0;730A &= value8;731NZ_A();732}733INL void IndIdx_RMW_Stage8()734{735WriteMemory((ushort)ea, (byte)alu_temp);736737738}739INL void RelBranch_Stage2_BVS()740{741branch_taken = FlagV == true;742RelBranch_Stage2();743}744INL void RelBranch_Stage2_BVC()745{746branch_taken = FlagV == false;747RelBranch_Stage2();748}749INL void RelBranch_Stage2_BMI()750{751branch_taken = FlagN == true;752RelBranch_Stage2();753}754INL void RelBranch_Stage2_BPL()755{756branch_taken = FlagN == false;757RelBranch_Stage2();758}759INL void RelBranch_Stage2_BCS()760{761branch_taken = FlagC == true;762RelBranch_Stage2();763}764INL void RelBranch_Stage2_BCC()765{766branch_taken = FlagC == false;767RelBranch_Stage2();768}769INL void RelBranch_Stage2_BEQ()770{771branch_taken = FlagZ == true;772RelBranch_Stage2();773}774INL void RelBranch_Stage2_BNE()775{776branch_taken = FlagZ == false;777RelBranch_Stage2();778779}780INL void RelBranch_Stage2()781{782rdy_freeze = !RDY;783if (RDY)784{785opcode2 = ReadMemory(PC++);786if (branch_taken)787{788branch_taken = false;789//if the branch is taken, we enter a different bit of microcode to calculate the PC and complete the branch790opcode = VOP_RelativeStuff;791mi = -1;792}793}794795}796INL void RelBranch_Stage3()797{798FetchDummy();799alu_temp = (byte)PC + (int)(sbyte)opcode2;800PC &= 0xFF00;801PC |= (ushort)((alu_temp & 0xFF));802if (Bit<8>(alu_temp))803{804//we need to carry the add, and then we'll be ready to fetch the next instruction805opcode = VOP_RelativeStuff2;806mi = -1;807}808else809{810//to pass cpu_interrupts_v2/5-branch_delays_irq we need to handle a quirk here811//if we decide to interrupt in the next cycle, this condition will cause it to get deferred by one instruction812if (!interrupt_pending)813branch_irq_hack = true;814}815816}817INL void RelBranch_Stage4()818{819FetchDummy();820if (Bit<31>(alu_temp))821PC = (ushort)(PC - 0x100);822else PC = (ushort)(PC + 0x100);823824825}826INL void NOP()827{828}829INL void DecS()830{831S--;832}833INL void IncS()834{835S++;836}837INL void JSR()838{839rdy_freeze = !RDY;840if (RDY)841{842PC = (ushort)((ReadMemory((ushort)(PC)) << 8) + opcode2);843}844}845INL void PullP()846{847rdy_freeze = !RDY;848if (RDY)849{850SetP(ReadMemory((ushort)(S++ + 0x100)));851FlagT = true; //force T always to remain true852}853854}855INL void PullPCL()856{857rdy_freeze = !RDY;858if (RDY)859{860PC &= 0xFF00;861PC |= ReadMemory((ushort)(S++ + 0x100));862}863864}865INL void PullPCH_NoInc()866{867rdy_freeze = !RDY;868if (RDY)869{870PC &= 0xFF;871PC |= (ushort)(ReadMemory((ushort)(S + 0x100)) << 8);872}873874}875INL void Abs_READ_LDA()876{877rdy_freeze = !RDY;878if (RDY)879{880A = ReadMemory((ushort)((opcode3 << 8) + opcode2));881NZ_A();882}883}884INL void Abs_READ_LDY()885{886rdy_freeze = !RDY;887if (RDY)888{889Y = ReadMemory((ushort)((opcode3 << 8) + opcode2));890NZ_Y();891}892}893INL void Abs_READ_LDX()894{895rdy_freeze = !RDY;896if (RDY)897{898X = ReadMemory((ushort)((opcode3 << 8) + opcode2));899NZ_X();900}901}902INL void Abs_READ_BIT()903{904rdy_freeze = !RDY;905if (RDY)906{907alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));908_Bit();909}910}911INL void Abs_READ_LAX()912{913rdy_freeze = !RDY;914if (RDY)915{916alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));917A = ReadMemory((ushort)((opcode3 << 8) + opcode2));918X = A;919NZ_A();920}921}922INL void Abs_READ_AND()923{924rdy_freeze = !RDY;925if (RDY)926{927alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));928_And();929}930}931INL void Abs_READ_EOR()932{933rdy_freeze = !RDY;934if (RDY)935{936alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));937_Eor();938}939}940INL void Abs_READ_ORA()941{942rdy_freeze = !RDY;943if (RDY)944{945alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));946_Ora();947}948}949INL void Abs_READ_ADC()950{951rdy_freeze = !RDY;952if (RDY)953{954alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));955_Adc();956}957}958INL void Abs_READ_CMP()959{960rdy_freeze = !RDY;961if (RDY)962{963alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));964_Cmp();965}966}967INL void Abs_READ_CPY()968{969rdy_freeze = !RDY;970if (RDY)971{972alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));973_Cpy();974}975}976INL void Abs_READ_NOP()977{978rdy_freeze = !RDY;979if (RDY)980{981alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));982}983984}985INL void Abs_READ_CPX()986{987rdy_freeze = !RDY;988if (RDY)989{990alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));991_Cpx();992}993}994INL void Abs_READ_SBC()995{996rdy_freeze = !RDY;997if (RDY)998{999alu_temp = ReadMemory((ushort)((opcode3 << 8) + opcode2));1000_Sbc();1001}10021003}1004INL void ZpIdx_Stage3_X()1005{1006rdy_freeze = !RDY;1007if (RDY)1008{1009ReadMemory(opcode2);1010opcode2 = (byte)(opcode2 + X); //a bit sneaky to shove this into opcode2... but we can reuse all the zero page uops if we do that1011}10121013}1014INL void ZpIdx_Stage3_Y()1015{1016rdy_freeze = !RDY;1017if (RDY)1018{1019ReadMemory(opcode2);1020opcode2 = (byte)(opcode2 + Y); //a bit sneaky to shove this into opcode2... but we can reuse all the zero page uops if we do that1021}10221023}1024INL void ZpIdx_RMW_Stage4()1025{1026rdy_freeze = !RDY;1027if (RDY)1028{1029alu_temp = ReadMemory(opcode2);1030}10311032}1033INL void ZpIdx_RMW_Stage6()1034{1035WriteMemory(opcode2, (byte)alu_temp);103610371038}1039INL void ZP_READ_EOR()1040{1041rdy_freeze = !RDY;1042if (RDY)1043{1044alu_temp = ReadMemory(opcode2);1045_Eor();1046}1047}1048INL void ZP_READ_BIT()1049{1050rdy_freeze = !RDY;1051if (RDY)1052{1053alu_temp = ReadMemory(opcode2);1054_Bit();1055}1056}1057INL void ZP_READ_LDA()1058{1059rdy_freeze = !RDY;1060if (RDY)1061{1062A = ReadMemory(opcode2);1063NZ_A();1064}1065}1066INL void ZP_READ_LDY()1067{1068rdy_freeze = !RDY;1069if (RDY)1070{1071Y = ReadMemory(opcode2);1072NZ_Y();1073}1074}1075INL void ZP_READ_LDX()1076{1077rdy_freeze = !RDY;1078if (RDY)1079{1080X = ReadMemory(opcode2);1081NZ_X();1082}1083}1084INL void ZP_READ_LAX()1085{1086rdy_freeze = !RDY;1087if (RDY)1088{1089//?? is this right??1090X = ReadMemory(opcode2);1091A = X;1092NZ_A();1093}1094}1095INL void ZP_READ_CPY()1096{1097rdy_freeze = !RDY;1098if (RDY)1099{1100alu_temp = ReadMemory(opcode2);1101_Cpy();1102}1103}1104INL void ZP_READ_CMP()1105{1106rdy_freeze = !RDY;1107if (RDY)1108{1109alu_temp = ReadMemory(opcode2);1110_Cmp();1111}1112}1113INL void ZP_READ_CPX()1114{1115rdy_freeze = !RDY;1116if (RDY)1117{1118alu_temp = ReadMemory(opcode2);1119_Cpx();1120}1121}1122INL void ZP_READ_ORA()1123{1124rdy_freeze = !RDY;1125if (RDY)1126{1127alu_temp = ReadMemory(opcode2);1128_Ora();1129}1130}1131INL void ZP_READ_NOP()1132{1133rdy_freeze = !RDY;1134if (RDY)1135{1136ReadMemory(opcode2); //just a dummy1137}11381139}1140INL void ZP_READ_SBC()1141{1142rdy_freeze = !RDY;1143if (RDY)1144{1145alu_temp = ReadMemory(opcode2);1146_Sbc();1147}1148}1149INL void ZP_READ_ADC()1150{1151rdy_freeze = !RDY;1152if (RDY)1153{1154alu_temp = ReadMemory(opcode2);1155_Adc();1156}1157}1158INL void ZP_READ_AND()1159{1160rdy_freeze = !RDY;1161if (RDY)1162{1163alu_temp = ReadMemory(opcode2);1164_And();1165}11661167}1168INL void _Cpx()1169{1170value8 = (byte)alu_temp;1171value16 = (ushort)(X - value8);1172FlagC = (X >= value8);1173NZ_V((byte)value16);11741175}1176INL void _Cpy()1177{1178value8 = (byte)alu_temp;1179value16 = (ushort)(Y - value8);1180FlagC = (Y >= value8);1181NZ_V((byte)value16);11821183}1184INL void _Cmp()1185{1186value8 = (byte)alu_temp;1187value16 = (ushort)(A - value8);1188FlagC = (A >= value8);1189NZ_V((byte)value16);11901191}1192INL void _Bit()1193{1194FlagN = (alu_temp & 0x80) != 0;1195FlagV = (alu_temp & 0x40) != 0;1196FlagZ = (A & alu_temp) == 0;11971198}1199INL void _Eor()1200{1201A ^= (byte)alu_temp;1202NZ_A();1203}1204INL void _And()1205{1206A &= (byte)alu_temp;1207NZ_A();1208}1209INL void _Ora()1210{1211A |= (byte)alu_temp;1212NZ_A();1213}1214INL void _Anc()1215{1216A &= (byte)alu_temp;1217FlagC = Bit<7>(A);1218NZ_A();1219}1220INL void _Asr()1221{1222A &= (byte)alu_temp;1223FlagC = Bit<0>(A);1224A >>= 1;1225NZ_A();1226}1227INL void _Axs()1228{1229X &= A;1230alu_temp = X - (byte)alu_temp;1231X = (byte)alu_temp;1232FlagC = !Bit<8>(alu_temp);1233NZ_X();1234}1235INL void _Arr()1236{1237{1238A &= (byte)alu_temp;1239booltemp = Bit<0>(A);1240A = (byte)((A >> 1) | (FlagC ? 0x80 : 0x00));1241FlagC = booltemp;1242if (Bit<5>(A))1243if (Bit<6>(A))1244{ FlagC = true; FlagV = false; }1245else { FlagV = true; FlagC = false; }1246else if (Bit<6>(A))1247{ FlagV = true; FlagC = true; }1248else { FlagV = false; FlagC = false; }1249FlagZ = (A == 0);12501251}1252}1253INL void _Lxa()1254{1255A |= 0xFF; //there is some debate about what this should be. it may depend on the 6502 variant. this is suggested by qeed's doc for the nes and passes blargg's instruction test1256A &= (byte)alu_temp;1257X = A;1258NZ_A();1259}1260INL void _Sbc()1261{1262{1263value8 = (byte)alu_temp;1264tempint = A - value8 - (FlagC ? 0 : 1);1265if (FlagD && BCD_Enabled)1266{1267lo = (A & 0x0F) - (value8 & 0x0F) - (FlagC ? 0 : 1);1268hi = (A & 0xF0) - (value8 & 0xF0);1269if ((lo & 0xF0) != 0) lo -= 0x06;1270if ((lo & 0x80) != 0) hi -= 0x10;1271if ((hi & 0x0F00) != 0) hi -= 0x60;1272FlagV = ((A ^ value8) & (A ^ tempint) & 0x80) != 0;1273FlagC = (hi & 0xFF00) == 0;1274A = (byte)((lo & 0x0F) | (hi & 0xF0));1275}1276else1277{1278FlagV = ((A ^ value8) & (A ^ tempint) & 0x80) != 0;1279FlagC = tempint >= 0;1280A = (byte)tempint;1281}1282NZ_A();1283}1284}1285INL void _Adc()1286{1287{1288//TODO - an extra cycle penalty?1289value8 = (byte)alu_temp;1290if (FlagD && BCD_Enabled)1291{1292lo = (A & 0x0F) + (value8 & 0x0F) + (FlagC ? 1 : 0);1293hi = (A & 0xF0) + (value8 & 0xF0);1294if (lo > 0x09)1295{1296hi += 0x10;1297lo += 0x06;1298}1299if (hi > 0x90) hi += 0x60;1300FlagV = (~(A ^ value8) & (A ^ hi) & 0x80) != 0;1301FlagC = hi > 0xFF;1302A = (byte)((lo & 0x0F) | (hi & 0xF0));1303}1304else1305{1306tempint = value8 + A + (FlagC ? 1 : 0);1307FlagV = (~(A ^ value8) & (A ^ tempint) & 0x80) != 0;1308FlagC = tempint > 0xFF;1309A = (byte)tempint;1310}1311NZ_A();1312}13131314}1315INL void Unsupported()1316{131713181319}1320INL void Imm_EOR()1321{1322rdy_freeze = !RDY;1323if (RDY)1324{1325alu_temp = ReadMemory(PC++);1326_Eor();1327}1328}1329INL void Imm_ANC()1330{1331rdy_freeze = !RDY;1332if (RDY)1333{1334alu_temp = ReadMemory(PC++);1335_Anc();1336}1337}1338INL void Imm_ASR()1339{1340rdy_freeze = !RDY;1341if (RDY)1342{1343alu_temp = ReadMemory(PC++);1344_Asr();1345}1346}1347INL void Imm_AXS()1348{1349rdy_freeze = !RDY;1350if (RDY)1351{1352alu_temp = ReadMemory(PC++);1353_Axs();1354}1355}1356INL void Imm_ARR()1357{1358rdy_freeze = !RDY;1359if (RDY)1360{1361alu_temp = ReadMemory(PC++);1362_Arr();1363}1364}1365INL void Imm_LXA()1366{1367rdy_freeze = !RDY;1368if (RDY)1369{1370alu_temp = ReadMemory(PC++);1371_Lxa();1372}1373}1374INL void Imm_ORA()1375{1376rdy_freeze = !RDY;1377if (RDY)1378{1379alu_temp = ReadMemory(PC++);1380_Ora();1381}1382}1383INL void Imm_CPY()1384{1385rdy_freeze = !RDY;1386if (RDY)1387{1388alu_temp = ReadMemory(PC++);1389_Cpy();1390}1391}1392INL void Imm_CPX()1393{1394rdy_freeze = !RDY;1395if (RDY)1396{1397alu_temp = ReadMemory(PC++);1398_Cpx();1399}1400}1401INL void Imm_CMP()1402{1403rdy_freeze = !RDY;1404if (RDY)1405{1406alu_temp = ReadMemory(PC++);1407_Cmp();1408}1409}1410INL void Imm_SBC()1411{1412rdy_freeze = !RDY;1413if (RDY)1414{1415alu_temp = ReadMemory(PC++);1416_Sbc();1417}1418}1419INL void Imm_AND()1420{1421rdy_freeze = !RDY;1422if (RDY)1423{1424alu_temp = ReadMemory(PC++);1425_And();1426}1427}1428INL void Imm_ADC()1429{1430rdy_freeze = !RDY;1431if (RDY)1432{1433alu_temp = ReadMemory(PC++);1434_Adc();1435}1436}1437INL void Imm_LDA()1438{1439rdy_freeze = !RDY;1440if (RDY)1441{1442A = ReadMemory(PC++);1443NZ_A();1444}1445}1446INL void Imm_LDX()1447{1448rdy_freeze = !RDY;1449if (RDY)1450{1451X = ReadMemory(PC++);1452NZ_X();1453}1454}1455INL void Imm_LDY()1456{1457rdy_freeze = !RDY;1458if (RDY)1459{1460Y = ReadMemory(PC++);1461NZ_Y();1462}1463}1464INL void Imm_Unsupported()1465{1466rdy_freeze = !RDY;1467if (RDY)1468{1469ReadMemory(PC++);1470}14711472}1473INL void IdxInd_Stage3()1474{1475rdy_freeze = !RDY;1476if (RDY)1477{1478ReadMemory(opcode2); //dummy?1479alu_temp = (opcode2 + X) & 0xFF;1480}14811482}1483INL void IdxInd_Stage4()1484{1485rdy_freeze = !RDY;1486if (RDY)1487{1488ea = ReadMemory((ushort)alu_temp);1489}14901491}1492INL void IdxInd_Stage5()1493{1494rdy_freeze = !RDY;1495if (RDY)1496{1497ea += (ReadMemory((byte)(alu_temp + 1)) << 8);1498}14991500}1501INL void IdxInd_Stage6_READ_LDA()1502{1503rdy_freeze = !RDY;1504if (RDY)1505{1506//TODO make uniform with others1507A = ReadMemory((ushort)ea);1508NZ_A();1509}1510}1511INL void IdxInd_Stage6_READ_ORA()1512{1513rdy_freeze = !RDY;1514if (RDY)1515{1516alu_temp = ReadMemory((ushort)ea);1517_Ora();1518}1519}1520INL void IdxInd_Stage6_READ_LAX()1521{1522rdy_freeze = !RDY;1523if (RDY)1524{1525A = X = ReadMemory((ushort)ea);1526NZ_A();1527}1528}1529INL void IdxInd_Stage6_READ_CMP()1530{1531rdy_freeze = !RDY;1532if (RDY)1533{1534alu_temp = ReadMemory((ushort)ea);1535_Cmp();1536}1537}1538INL void IdxInd_Stage6_READ_ADC()1539{1540rdy_freeze = !RDY;1541if (RDY)1542{1543alu_temp = ReadMemory((ushort)ea);1544_Adc();1545}1546}1547INL void IdxInd_Stage6_READ_AND()1548{1549rdy_freeze = !RDY;1550if (RDY)1551{1552alu_temp = ReadMemory((ushort)ea);1553_And();1554}1555}1556INL void IdxInd_Stage6_READ_EOR()1557{1558rdy_freeze = !RDY;1559if (RDY)1560{1561alu_temp = ReadMemory((ushort)ea);1562_Eor();1563}1564}1565INL void IdxInd_Stage6_READ_SBC()1566{1567rdy_freeze = !RDY;1568if (RDY)1569{1570alu_temp = ReadMemory((ushort)ea);1571_Sbc();1572}1573}1574INL void IdxInd_Stage6_WRITE_STA()1575{1576WriteMemory((ushort)ea, A);15771578}1579INL void IdxInd_Stage6_WRITE_SAX()1580{1581alu_temp = A & X;1582WriteMemory((ushort)ea, (byte)alu_temp);1583//flag writing skipped on purpose15841585}1586INL void IdxInd_Stage6_RMW()1587{1588rdy_freeze = !RDY;1589if (RDY)1590{1591alu_temp = ReadMemory((ushort)ea);1592}15931594}1595INL void IdxInd_Stage7_RMW_SLO()1596{1597WriteMemory((ushort)ea, (byte)alu_temp);1598value8 = (byte)alu_temp;1599FlagC = (value8 & 0x80) != 0;1600alu_temp = value8 = (byte)((value8 << 1));1601A |= value8;1602NZ_A();1603}1604INL void IdxInd_Stage7_RMW_ISC()1605{1606WriteMemory((ushort)ea, (byte)alu_temp);1607value8 = (byte)alu_temp;1608alu_temp = value8 = (byte)(value8 + 1);1609_Sbc();1610}1611INL void IdxInd_Stage7_RMW_DCP()1612{1613WriteMemory((ushort)ea, (byte)alu_temp);1614value8 = temp8 = (byte)alu_temp;1615alu_temp = value8 = (byte)(value8 - 1);1616FlagC = (temp8 & 1) != 0;1617_Cmp();1618}1619INL void IdxInd_Stage7_RMW_SRE()1620{1621WriteMemory((ushort)ea, (byte)alu_temp);1622value8 = (byte)alu_temp;1623FlagC = (value8 & 1) != 0;1624alu_temp = value8 = (byte)(value8 >> 1);1625A ^= value8;1626NZ_A();1627}1628INL void IdxInd_Stage7_RMW_RRA()1629{1630WriteMemory((ushort)ea, (byte)alu_temp);1631value8 = (byte)alu_temp;1632value8 = temp8 = (byte)alu_temp;1633alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));1634FlagC = (temp8 & 1) != 0;1635_Adc();1636}1637INL void IdxInd_Stage7_RMW_RLA()1638{1639WriteMemory((ushort)ea, (byte)alu_temp);1640value8 = temp8 = (byte)alu_temp;1641alu_temp = value8 = (byte)((value8 << 1) | (FlagC));1642FlagC = (temp8 & 0x80) != 0;1643A &= value8;1644NZ_A();1645}1646INL void IdxInd_Stage8_RMW()1647{1648WriteMemory((ushort)ea, (byte)alu_temp);164916501651}1652INL void PushP()1653{1654FlagB = true;1655WriteMemory((ushort)(S-- + 0x100), GetP());16561657}1658INL void PushA()1659{1660WriteMemory((ushort)(S-- + 0x100), A);1661}1662INL void PullA_NoInc()1663{1664rdy_freeze = !RDY;1665if (RDY)1666{1667A = ReadMemory((ushort)(S + 0x100));1668NZ_A();1669}1670}1671INL void PullP_NoInc()1672{1673rdy_freeze = !RDY;1674if (RDY)1675{1676my_iflag = FlagI;1677SetP(ReadMemory((ushort)(S + 0x100)));1678iflag_pending = FlagI;1679FlagI = my_iflag;1680FlagT = true; //force T always to remain true16811682}16831684}1685INL void Imp_ASL_A()1686{1687FetchDummy();1688FlagC = (A & 0x80) != 0;1689A = (byte)(A << 1);1690NZ_A();1691}1692INL void Imp_ROL_A()1693{1694FetchDummy();1695temp8 = A;1696A = (byte)((A << 1) | (FlagC));1697FlagC = (temp8 & 0x80) != 0;1698NZ_A();1699}1700INL void Imp_ROR_A()1701{1702FetchDummy();1703temp8 = A;1704A = (byte)((A >> 1) | ((FlagC) << 7));1705FlagC = (temp8 & 1) != 0;1706NZ_A();1707}1708INL void Imp_LSR_A()1709{1710FetchDummy();1711FlagC = (A & 1) != 0;1712A = (byte)(A >> 1);1713NZ_A();17141715}1716INL void JMP_abs()1717{1718rdy_freeze = !RDY;1719if (RDY)1720{1721PC = (ushort)((ReadMemory(PC) << 8) + opcode2);1722}17231724}1725INL void IncPC()1726{1727PC++;172817291730}1731INL void ZP_RMW_Stage3()1732{1733rdy_freeze = !RDY;1734if (RDY)1735{1736alu_temp = ReadMemory(opcode2);1737}17381739}1740INL void ZP_RMW_Stage5()1741{1742WriteMemory(opcode2, (byte)alu_temp);17431744}1745INL void ZP_RMW_INC()1746{1747WriteMemory(opcode2, (byte)alu_temp);1748alu_temp = (byte)((alu_temp + 1) & 0xFF);1749NZ_V((byte)alu_temp);17501751}1752INL void ZP_RMW_DEC()1753{1754WriteMemory(opcode2, (byte)alu_temp);1755alu_temp = (byte)((alu_temp - 1) & 0xFF);1756NZ_V((byte)alu_temp);17571758}1759INL void ZP_RMW_ASL()1760{1761WriteMemory(opcode2, (byte)alu_temp);1762value8 = (byte)alu_temp;1763FlagC = (value8 & 0x80) != 0;1764alu_temp = value8 = (byte)(value8 << 1);1765NZ_V((byte)value8);17661767}1768INL void ZP_RMW_SRE()1769{1770WriteMemory(opcode2, (byte)alu_temp);1771value8 = (byte)alu_temp;1772FlagC = (value8 & 1) != 0;1773alu_temp = value8 = (byte)(value8 >> 1);1774A ^= value8;1775NZ_A();1776}1777INL void ZP_RMW_RRA()1778{1779WriteMemory(opcode2, (byte)alu_temp);1780value8 = temp8 = (byte)alu_temp;1781alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));1782FlagC = (temp8 & 1) != 0;1783_Adc();1784}1785INL void ZP_RMW_DCP()1786{1787WriteMemory(opcode2, (byte)alu_temp);1788value8 = temp8 = (byte)alu_temp;1789alu_temp = value8 = (byte)(value8 - 1);1790FlagC = (temp8 & 1) != 0;1791_Cmp();1792}1793INL void ZP_RMW_LSR()1794{1795WriteMemory(opcode2, (byte)alu_temp);1796value8 = (byte)alu_temp;1797FlagC = (value8 & 1) != 0;1798alu_temp = value8 = (byte)(value8 >> 1);1799NZ_V((byte)value8);18001801}1802INL void ZP_RMW_ROR()1803{1804WriteMemory(opcode2, (byte)alu_temp);1805value8 = temp8 = (byte)alu_temp;1806alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));1807FlagC = (temp8 & 1) != 0;1808NZ_V((byte)value8);18091810}1811INL void ZP_RMW_ROL()1812{1813WriteMemory(opcode2, (byte)alu_temp);1814value8 = temp8 = (byte)alu_temp;1815alu_temp = value8 = (byte)((value8 << 1) | (FlagC));1816FlagC = (temp8 & 0x80) != 0;1817NZ_V((byte)value8);18181819}1820INL void ZP_RMW_SLO()1821{1822WriteMemory(opcode2, (byte)alu_temp);1823value8 = (byte)alu_temp;1824FlagC = (value8 & 0x80) != 0;1825alu_temp = value8 = (byte)((value8 << 1));1826A |= value8;1827NZ_A();1828}1829INL void ZP_RMW_ISC()1830{1831WriteMemory(opcode2, (byte)alu_temp);1832value8 = (byte)alu_temp;1833alu_temp = value8 = (byte)(value8 + 1);1834_Sbc();1835}1836INL void ZP_RMW_RLA()1837{1838WriteMemory(opcode2, (byte)alu_temp);1839value8 = temp8 = (byte)alu_temp;1840alu_temp = value8 = (byte)((value8 << 1) | (FlagC));1841FlagC = (temp8 & 0x80) != 0;1842A &= value8;1843NZ_A();18441845}1846INL void AbsIdx_Stage3_Y()1847{1848rdy_freeze = !RDY;1849if (RDY)1850{1851opcode3 = ReadMemory(PC++);1852alu_temp = opcode2 + Y;1853ea = (opcode3 << 8) + (alu_temp & 0xFF);18541855//new Uop[] { Uop.Fetch2, Uop.AbsIdx_Stage3_Y, Uop.AbsIdx_Stage4, Uop.AbsIdx_WRITE_Stage5_STA, Uop.End },1856}1857}1858INL void AbsIdx_Stage3_X()1859{1860rdy_freeze = !RDY;1861if (RDY)1862{1863opcode3 = ReadMemory(PC++);1864alu_temp = opcode2 + X;1865ea = (opcode3 << 8) + (alu_temp & 0xFF);1866}18671868}1869void AbsIdx_READ_Stage4()1870{1871rdy_freeze = !RDY;1872if (RDY)1873{1874if (!Bit<8>(alu_temp))1875{1876mi++;1877ExecuteOneRetry();1878return;1879}1880else1881{1882alu_temp = ReadMemory((ushort)ea);1883ea = (ushort)(ea + 0x100);1884}1885}18861887}1888INL void AbsIdx_Stage4()1889{1890rdy_freeze = !RDY;1891if (RDY)1892{1893//bleh.. redundant code to make sure we dont clobber alu_temp before using it to decide whether to change ea1894if (Bit<8>(alu_temp))1895{1896alu_temp = ReadMemory((ushort)ea);1897ea = (ushort)(ea + 0x100);1898}1899else alu_temp = ReadMemory((ushort)ea);1900}19011902}1903INL void AbsIdx_WRITE_Stage5_STA()1904{1905WriteMemory((ushort)ea, A);19061907}1908INL void AbsIdx_WRITE_Stage5_SHY()1909{1910alu_temp = Y & (ea >> 8);1911ea = (ea & 0xFF) | (alu_temp << 8); //"(the bank where the value is stored may be equal to the value stored)" -- more like IS.1912WriteMemory((ushort)ea, (byte)alu_temp);19131914}1915INL void AbsIdx_WRITE_Stage5_SHX()1916{1917alu_temp = X & (ea >> 8);1918ea = (ea & 0xFF) | (alu_temp << 8); //"(the bank where the value is stored may be equal to the value stored)" -- more like IS.1919WriteMemory((ushort)ea, (byte)alu_temp);19201921}1922INL void AbsIdx_WRITE_Stage5_ERROR()1923{1924rdy_freeze = !RDY;1925if (RDY)1926{1927alu_temp = ReadMemory((ushort)ea);1928//throw new InvalidOperationException("UNSUPPORTED OPCODE [probably SHS] PLEASE REPORT");1929}19301931}1932INL void AbsIdx_RMW_Stage5()1933{1934rdy_freeze = !RDY;1935if (RDY)1936{1937alu_temp = ReadMemory((ushort)ea);1938}19391940}1941INL void AbsIdx_RMW_Stage7()1942{1943WriteMemory((ushort)ea, (byte)alu_temp);19441945}1946INL void AbsIdx_RMW_Stage6_DEC()1947{1948WriteMemory((ushort)ea, (byte)alu_temp);1949alu_temp = value8 = (byte)(alu_temp - 1);1950NZ_V((byte)value8);19511952}1953INL void AbsIdx_RMW_Stage6_DCP()1954{1955WriteMemory((ushort)ea, (byte)alu_temp);1956alu_temp = value8 = (byte)(alu_temp - 1);1957_Cmp();1958}1959INL void AbsIdx_RMW_Stage6_ISC()1960{1961WriteMemory((ushort)ea, (byte)alu_temp);1962alu_temp = value8 = (byte)(alu_temp + 1);1963_Sbc();1964}1965INL void AbsIdx_RMW_Stage6_INC()1966{1967WriteMemory((ushort)ea, (byte)alu_temp);1968alu_temp = value8 = (byte)(alu_temp + 1);1969NZ_V((byte)value8);19701971}1972INL void AbsIdx_RMW_Stage6_ROL()1973{1974WriteMemory((ushort)ea, (byte)alu_temp);1975value8 = temp8 = (byte)alu_temp;1976alu_temp = value8 = (byte)((value8 << 1) | (FlagC));1977FlagC = (temp8 & 0x80) != 0;1978NZ_V((byte)value8);19791980}1981INL void AbsIdx_RMW_Stage6_LSR()1982{1983WriteMemory((ushort)ea, (byte)alu_temp);1984value8 = (byte)alu_temp;1985FlagC = (value8 & 1) != 0;1986alu_temp = value8 = (byte)(value8 >> 1);1987NZ_V((byte)value8);19881989}1990INL void AbsIdx_RMW_Stage6_SLO()1991{1992WriteMemory((ushort)ea, (byte)alu_temp);1993value8 = (byte)alu_temp;1994FlagC = (value8 & 0x80) != 0;1995alu_temp = value8 = (byte)(value8 << 1);1996A |= value8;1997NZ_A();1998}1999INL void AbsIdx_RMW_Stage6_SRE()2000{2001WriteMemory((ushort)ea, (byte)alu_temp);2002value8 = (byte)alu_temp;2003FlagC = (value8 & 1) != 0;2004alu_temp = value8 = (byte)(value8 >> 1);2005A ^= value8;2006NZ_A();2007}2008INL void AbsIdx_RMW_Stage6_RRA()2009{2010WriteMemory((ushort)ea, (byte)alu_temp);2011value8 = temp8 = (byte)alu_temp;2012alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));2013FlagC = (temp8 & 1) != 0;2014_Adc();2015}2016INL void AbsIdx_RMW_Stage6_RLA()2017{2018WriteMemory((ushort)ea, (byte)alu_temp);2019value8 = temp8 = (byte)alu_temp;2020alu_temp = value8 = (byte)((value8 << 1) | (FlagC));2021FlagC = (temp8 & 0x80) != 0;2022A &= value8;2023NZ_A();2024}2025INL void AbsIdx_RMW_Stage6_ASL()2026{2027WriteMemory((ushort)ea, (byte)alu_temp);2028value8 = (byte)alu_temp;2029FlagC = (value8 & 0x80) != 0;2030alu_temp = value8 = (byte)(value8 << 1);2031NZ_V((byte)value8);20322033}2034INL void AbsIdx_RMW_Stage6_ROR()2035{2036WriteMemory((ushort)ea, (byte)alu_temp);2037value8 = temp8 = (byte)alu_temp;2038alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));2039FlagC = (temp8 & 1) != 0;2040NZ_V((byte)value8);204120422043}2044INL void AbsIdx_READ_Stage5_LDA()2045{2046rdy_freeze = !RDY;2047if (RDY)2048{2049A = ReadMemory((ushort)ea);2050NZ_A();2051}2052}2053INL void AbsIdx_READ_Stage5_LDX()2054{2055rdy_freeze = !RDY;2056if (RDY)2057{2058X = ReadMemory((ushort)ea);2059NZ_X();2060}2061}2062INL void AbsIdx_READ_Stage5_LAX()2063{2064rdy_freeze = !RDY;2065if (RDY)2066{2067A = ReadMemory((ushort)ea);2068X = A;2069NZ_A();2070}2071}2072INL void AbsIdx_READ_Stage5_LDY()2073{2074rdy_freeze = !RDY;2075if (RDY)2076{2077Y = ReadMemory((ushort)ea);2078NZ_Y();2079}2080}2081INL void AbsIdx_READ_Stage5_ORA()2082{2083rdy_freeze = !RDY;2084if (RDY)2085{2086alu_temp = ReadMemory((ushort)ea);2087_Ora();2088}2089}2090INL void AbsIdx_READ_Stage5_NOP()2091{2092rdy_freeze = !RDY;2093if (RDY)2094{2095alu_temp = ReadMemory((ushort)ea);2096}20972098}2099INL void AbsIdx_READ_Stage5_CMP()2100{2101rdy_freeze = !RDY;2102if (RDY)2103{2104alu_temp = ReadMemory((ushort)ea);2105_Cmp();2106}2107}2108INL void AbsIdx_READ_Stage5_SBC()2109{2110rdy_freeze = !RDY;2111if (RDY)2112{2113alu_temp = ReadMemory((ushort)ea);2114_Sbc();2115}2116}2117INL void AbsIdx_READ_Stage5_ADC()2118{2119rdy_freeze = !RDY;2120if (RDY)2121{2122alu_temp = ReadMemory((ushort)ea);2123_Adc();2124}2125}2126INL void AbsIdx_READ_Stage5_EOR()2127{2128rdy_freeze = !RDY;2129if (RDY)2130{2131alu_temp = ReadMemory((ushort)ea);2132_Eor();2133}2134}2135INL void AbsIdx_READ_Stage5_AND()2136{2137rdy_freeze = !RDY;2138if (RDY)2139{2140alu_temp = ReadMemory((ushort)ea);2141_And();2142}2143}2144INL void AbsIdx_READ_Stage5_ERROR()2145{2146rdy_freeze = !RDY;2147if (RDY)2148{2149alu_temp = ReadMemory((ushort)ea);2150//throw new InvalidOperationException("UNSUPPORTED OPCODE [probably LAS] PLEASE REPORT");2151}21522153}2154INL void AbsInd_JMP_Stage4()2155{2156rdy_freeze = !RDY;2157if (RDY)2158{2159ea = (opcode3 << 8) + opcode2;2160alu_temp = ReadMemory((ushort)ea);2161}2162}2163INL void AbsInd_JMP_Stage5()2164{2165rdy_freeze = !RDY;2166if (RDY)2167{2168ea = (opcode3 << 8) + (byte)(opcode2 + 1);2169alu_temp += ReadMemory((ushort)ea) << 8;2170PC = (ushort)alu_temp;2171}21722173}2174INL void Abs_RMW_Stage4()2175{2176rdy_freeze = !RDY;2177if (RDY)2178{2179ea = (opcode3 << 8) + opcode2;2180alu_temp = ReadMemory((ushort)ea);2181}21822183}2184INL void Abs_RMW_Stage5_INC()2185{2186WriteMemory((ushort)ea, (byte)alu_temp);2187value8 = (byte)(alu_temp + 1);2188alu_temp = value8;2189NZ_V((byte)value8);21902191}2192INL void Abs_RMW_Stage5_DEC()2193{2194WriteMemory((ushort)ea, (byte)alu_temp);2195value8 = (byte)(alu_temp - 1);2196alu_temp = value8;2197NZ_V((byte)value8);21982199}2200INL void Abs_RMW_Stage5_DCP()2201{2202WriteMemory((ushort)ea, (byte)alu_temp);2203value8 = (byte)(alu_temp - 1);2204alu_temp = value8;2205_Cmp();2206}2207INL void Abs_RMW_Stage5_ISC()2208{2209WriteMemory((ushort)ea, (byte)alu_temp);2210value8 = (byte)(alu_temp + 1);2211alu_temp = value8;2212_Sbc();2213}2214INL void Abs_RMW_Stage5_ASL()2215{2216WriteMemory((ushort)ea, (byte)alu_temp);2217value8 = (byte)alu_temp;2218FlagC = (value8 & 0x80) != 0;2219alu_temp = value8 = (byte)(value8 << 1);2220NZ_V((byte)value8);22212222}2223INL void Abs_RMW_Stage5_ROR()2224{2225WriteMemory((ushort)ea, (byte)alu_temp);2226value8 = temp8 = (byte)alu_temp;2227alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));2228FlagC = (temp8 & 1) != 0;2229NZ_V((byte)value8);22302231}2232INL void Abs_RMW_Stage5_SLO()2233{2234WriteMemory((ushort)ea, (byte)alu_temp);2235value8 = (byte)alu_temp;2236FlagC = (value8 & 0x80) != 0;2237alu_temp = value8 = (byte)(value8 << 1);2238A |= value8;2239NZ_A();2240}2241INL void Abs_RMW_Stage5_RLA()2242{2243WriteMemory((ushort)ea, (byte)alu_temp);2244value8 = temp8 = (byte)alu_temp;2245alu_temp = value8 = (byte)((value8 << 1) | (FlagC));2246FlagC = (temp8 & 0x80) != 0;2247A &= value8;2248NZ_A();2249}2250INL void Abs_RMW_Stage5_SRE()2251{2252WriteMemory((ushort)ea, (byte)alu_temp);2253value8 = (byte)alu_temp;2254FlagC = (value8 & 1) != 0;2255alu_temp = value8 = (byte)(value8 >> 1);2256A ^= value8;2257NZ_A();2258}2259INL void Abs_RMW_Stage5_RRA()2260{2261WriteMemory((ushort)ea, (byte)alu_temp);2262value8 = temp8 = (byte)alu_temp;2263alu_temp = value8 = (byte)((value8 >> 1) | ((FlagC) << 7));2264FlagC = (temp8 & 1) != 0;2265_Adc();2266}2267INL void Abs_RMW_Stage5_ROL()2268{2269WriteMemory((ushort)ea, (byte)alu_temp);2270value8 = temp8 = (byte)alu_temp;2271alu_temp = value8 = (byte)((value8 << 1) | (FlagC));2272FlagC = (temp8 & 0x80) != 0;2273NZ_V((byte)value8);22742275}2276INL void Abs_RMW_Stage5_LSR()2277{2278WriteMemory((ushort)ea, (byte)alu_temp);2279value8 = (byte)alu_temp;2280FlagC = (value8 & 1) != 0;2281alu_temp = value8 = (byte)(value8 >> 1);2282NZ_V((byte)value8);228322842285}2286INL void Abs_RMW_Stage6()2287{2288WriteMemory((ushort)ea, (byte)alu_temp);228922902291}2292void End_ISpecial()2293{2294opcode = VOP_Fetch1;2295mi = 0;2296ExecuteOneRetry();2297return;22982299}2300void End_SuppressInterrupt()2301{2302opcode = VOP_Fetch1_NoInterrupt;2303mi = 0;2304ExecuteOneRetry();2305return;23062307}2308void End()2309{2310opcode = VOP_Fetch1;2311mi = 0;2312iflag_pending = FlagI;2313ExecuteOneRetry();2314return;2315}2316void End_BranchSpecial()2317{2318End();2319}232023212322void ExecuteOneRetry()2323{2324//dont know whether this system is any faster. hard to get benchmarks someone else try it?2325//Uop uop = (Uop)CompiledMicrocode[MicrocodeIndex[opcode] + mi];2326Uop uop = Microcode[opcode][mi];2327switch (uop)2328{2329case Uop_Fetch1: Fetch1(); break;2330case Uop_Fetch1_Real: Fetch1_Real(); break;2331case Uop_Fetch2: Fetch2(); break;2332case Uop_Fetch3: Fetch3(); break;2333case Uop_FetchDummy: FetchDummy(); break;2334case Uop_PushPCH: PushPCH(); break;2335case Uop_PushPCL: PushPCL(); break;2336case Uop_PushP_BRK: PushP_BRK(); break;2337case Uop_PushP_IRQ: PushP_IRQ(); break;2338case Uop_PushP_NMI: PushP_NMI(); break;2339case Uop_PushP_Reset: PushP_Reset(); break;2340case Uop_PushDummy: PushDummy(); break;2341case Uop_FetchPCLVector: FetchPCLVector(); break;2342case Uop_FetchPCHVector: FetchPCHVector(); break;2343case Uop_Imp_INY: Imp_INY(); break;2344case Uop_Imp_DEY: Imp_DEY(); break;2345case Uop_Imp_INX: Imp_INX(); break;2346case Uop_Imp_DEX: Imp_DEX(); break;2347case Uop_NZ_A: NZ_A(); break;2348case Uop_NZ_X: NZ_X(); break;2349case Uop_NZ_Y: NZ_Y(); break;2350case Uop_Imp_TSX: Imp_TSX(); break;2351case Uop_Imp_TXS: Imp_TXS(); break;2352case Uop_Imp_TAX: Imp_TAX(); break;2353case Uop_Imp_TAY: Imp_TAY(); break;2354case Uop_Imp_TYA: Imp_TYA(); break;2355case Uop_Imp_TXA: Imp_TXA(); break;2356case Uop_Imp_SEI: Imp_SEI(); break;2357case Uop_Imp_CLI: Imp_CLI(); break;2358case Uop_Imp_SEC: Imp_SEC(); break;2359case Uop_Imp_CLC: Imp_CLC(); break;2360case Uop_Imp_SED: Imp_SED(); break;2361case Uop_Imp_CLD: Imp_CLD(); break;2362case Uop_Imp_CLV: Imp_CLV(); break;2363case Uop_Abs_WRITE_STA: Abs_WRITE_STA(); break;2364case Uop_Abs_WRITE_STX: Abs_WRITE_STX(); break;2365case Uop_Abs_WRITE_STY: Abs_WRITE_STY(); break;2366case Uop_Abs_WRITE_SAX: Abs_WRITE_SAX(); break;2367case Uop_ZP_WRITE_STA: ZP_WRITE_STA(); break;2368case Uop_ZP_WRITE_STY: ZP_WRITE_STY(); break;2369case Uop_ZP_WRITE_STX: ZP_WRITE_STX(); break;2370case Uop_ZP_WRITE_SAX: ZP_WRITE_SAX(); break;2371case Uop_IndIdx_Stage3: IndIdx_Stage3(); break;2372case Uop_IndIdx_Stage4: IndIdx_Stage4(); break;2373case Uop_IndIdx_WRITE_Stage5: IndIdx_WRITE_Stage5(); break;2374case Uop_IndIdx_READ_Stage5: IndIdx_READ_Stage5(); break;2375case Uop_IndIdx_RMW_Stage5: IndIdx_RMW_Stage5(); break;2376case Uop_IndIdx_WRITE_Stage6_STA: IndIdx_WRITE_Stage6_STA(); break;2377case Uop_IndIdx_WRITE_Stage6_SHA: IndIdx_WRITE_Stage6_SHA(); break;2378case Uop_IndIdx_READ_Stage6_LDA: IndIdx_READ_Stage6_LDA(); break;2379case Uop_IndIdx_READ_Stage6_CMP: IndIdx_READ_Stage6_CMP(); break;2380case Uop_IndIdx_READ_Stage6_AND: IndIdx_READ_Stage6_AND(); break;2381case Uop_IndIdx_READ_Stage6_EOR: IndIdx_READ_Stage6_EOR(); break;2382case Uop_IndIdx_READ_Stage6_LAX: IndIdx_READ_Stage6_LAX(); break;2383case Uop_IndIdx_READ_Stage6_ADC: IndIdx_READ_Stage6_ADC(); break;2384case Uop_IndIdx_READ_Stage6_SBC: IndIdx_READ_Stage6_SBC(); break;2385case Uop_IndIdx_READ_Stage6_ORA: IndIdx_READ_Stage6_ORA(); break;2386case Uop_IndIdx_RMW_Stage6: IndIdx_RMW_Stage6(); break;2387case Uop_IndIdx_RMW_Stage7_SLO: IndIdx_RMW_Stage7_SLO(); break;2388case Uop_IndIdx_RMW_Stage7_SRE: IndIdx_RMW_Stage7_SRE(); break;2389case Uop_IndIdx_RMW_Stage7_RRA: IndIdx_RMW_Stage7_RRA(); break;2390case Uop_IndIdx_RMW_Stage7_ISC: IndIdx_RMW_Stage7_ISC(); break;2391case Uop_IndIdx_RMW_Stage7_DCP: IndIdx_RMW_Stage7_DCP(); break;2392case Uop_IndIdx_RMW_Stage7_RLA: IndIdx_RMW_Stage7_RLA(); break;2393case Uop_IndIdx_RMW_Stage8: IndIdx_RMW_Stage8(); break;2394case Uop_RelBranch_Stage2_BVS: RelBranch_Stage2_BVS(); break;2395case Uop_RelBranch_Stage2_BVC: RelBranch_Stage2_BVC(); break;2396case Uop_RelBranch_Stage2_BMI: RelBranch_Stage2_BMI(); break;2397case Uop_RelBranch_Stage2_BPL: RelBranch_Stage2_BPL(); break;2398case Uop_RelBranch_Stage2_BCS: RelBranch_Stage2_BCS(); break;2399case Uop_RelBranch_Stage2_BCC: RelBranch_Stage2_BCC(); break;2400case Uop_RelBranch_Stage2_BEQ: RelBranch_Stage2_BEQ(); break;2401case Uop_RelBranch_Stage2_BNE: RelBranch_Stage2_BNE(); break;2402case Uop_RelBranch_Stage2: RelBranch_Stage2(); break;2403case Uop_RelBranch_Stage3: RelBranch_Stage3(); break;2404case Uop_RelBranch_Stage4: RelBranch_Stage4(); break;2405case Uop_NOP: NOP(); break;2406case Uop_DecS: DecS(); break;2407case Uop_IncS: IncS(); break;2408case Uop_JSR: JSR(); break;2409case Uop_PullP: PullP(); break;2410case Uop_PullPCL: PullPCL(); break;2411case Uop_PullPCH_NoInc: PullPCH_NoInc(); break;2412case Uop_Abs_READ_LDA: Abs_READ_LDA(); break;2413case Uop_Abs_READ_LDY: Abs_READ_LDY(); break;2414case Uop_Abs_READ_LDX: Abs_READ_LDX(); break;2415case Uop_Abs_READ_BIT: Abs_READ_BIT(); break;2416case Uop_Abs_READ_LAX: Abs_READ_LAX(); break;2417case Uop_Abs_READ_AND: Abs_READ_AND(); break;2418case Uop_Abs_READ_EOR: Abs_READ_EOR(); break;2419case Uop_Abs_READ_ORA: Abs_READ_ORA(); break;2420case Uop_Abs_READ_ADC: Abs_READ_ADC(); break;2421case Uop_Abs_READ_CMP: Abs_READ_CMP(); break;2422case Uop_Abs_READ_CPY: Abs_READ_CPY(); break;2423case Uop_Abs_READ_NOP: Abs_READ_NOP(); break;2424case Uop_Abs_READ_CPX: Abs_READ_CPX(); break;2425case Uop_Abs_READ_SBC: Abs_READ_SBC(); break;2426case Uop_ZpIdx_Stage3_X: ZpIdx_Stage3_X(); break;2427case Uop_ZpIdx_Stage3_Y: ZpIdx_Stage3_Y(); break;2428case Uop_ZpIdx_RMW_Stage4: ZpIdx_RMW_Stage4(); break;2429case Uop_ZpIdx_RMW_Stage6: ZpIdx_RMW_Stage6(); break;2430case Uop_ZP_READ_EOR: ZP_READ_EOR(); break;2431case Uop_ZP_READ_BIT: ZP_READ_BIT(); break;2432case Uop_ZP_READ_LDA: ZP_READ_LDA(); break;2433case Uop_ZP_READ_LDY: ZP_READ_LDY(); break;2434case Uop_ZP_READ_LDX: ZP_READ_LDX(); break;2435case Uop_ZP_READ_LAX: ZP_READ_LAX(); break;2436case Uop_ZP_READ_CPY: ZP_READ_CPY(); break;2437case Uop_ZP_READ_CMP: ZP_READ_CMP(); break;2438case Uop_ZP_READ_CPX: ZP_READ_CPX(); break;2439case Uop_ZP_READ_ORA: ZP_READ_ORA(); break;2440case Uop_ZP_READ_NOP: ZP_READ_NOP(); break;2441case Uop_ZP_READ_SBC: ZP_READ_SBC(); break;2442case Uop_ZP_READ_ADC: ZP_READ_ADC(); break;2443case Uop_ZP_READ_AND: ZP_READ_AND(); break;2444case Uop__Cpx: _Cpx(); break;2445case Uop__Cpy: _Cpy(); break;2446case Uop__Cmp: _Cmp(); break;2447case Uop__Eor: _Eor(); break;2448case Uop__And: _And(); break;2449case Uop__Ora: _Ora(); break;2450case Uop__Anc: _Anc(); break;2451case Uop__Asr: _Asr(); break;2452case Uop__Axs: _Axs(); break;2453case Uop__Arr: _Arr(); break;2454case Uop__Lxa: _Lxa(); break;2455case Uop__Sbc: _Sbc(); break;2456case Uop__Adc: _Adc(); break;2457case Uop_Unsupported: Unsupported(); break;2458case Uop_Imm_EOR: Imm_EOR(); break;2459case Uop_Imm_ANC: Imm_ANC(); break;2460case Uop_Imm_ASR: Imm_ASR(); break;2461case Uop_Imm_AXS: Imm_AXS(); break;2462case Uop_Imm_ARR: Imm_ARR(); break;2463case Uop_Imm_LXA: Imm_LXA(); break;2464case Uop_Imm_ORA: Imm_ORA(); break;2465case Uop_Imm_CPY: Imm_CPY(); break;2466case Uop_Imm_CPX: Imm_CPX(); break;2467case Uop_Imm_CMP: Imm_CMP(); break;2468case Uop_Imm_SBC: Imm_SBC(); break;2469case Uop_Imm_AND: Imm_AND(); break;2470case Uop_Imm_ADC: Imm_ADC(); break;2471case Uop_Imm_LDA: Imm_LDA(); break;2472case Uop_Imm_LDX: Imm_LDX(); break;2473case Uop_Imm_LDY: Imm_LDY(); break;2474case Uop_Imm_Unsupported: Imm_Unsupported(); break;2475case Uop_IdxInd_Stage3: IdxInd_Stage3(); break;2476case Uop_IdxInd_Stage4: IdxInd_Stage4(); break;2477case Uop_IdxInd_Stage5: IdxInd_Stage5(); break;2478case Uop_IdxInd_Stage6_READ_LDA: IdxInd_Stage6_READ_LDA(); break;2479case Uop_IdxInd_Stage6_READ_ORA: IdxInd_Stage6_READ_ORA(); break;2480case Uop_IdxInd_Stage6_READ_LAX: IdxInd_Stage6_READ_LAX(); break;2481case Uop_IdxInd_Stage6_READ_CMP: IdxInd_Stage6_READ_CMP(); break;2482case Uop_IdxInd_Stage6_READ_ADC: IdxInd_Stage6_READ_ADC(); break;2483case Uop_IdxInd_Stage6_READ_AND: IdxInd_Stage6_READ_AND(); break;2484case Uop_IdxInd_Stage6_READ_EOR: IdxInd_Stage6_READ_EOR(); break;2485case Uop_IdxInd_Stage6_READ_SBC: IdxInd_Stage6_READ_SBC(); break;2486case Uop_IdxInd_Stage6_WRITE_STA: IdxInd_Stage6_WRITE_STA(); break;2487case Uop_IdxInd_Stage6_WRITE_SAX: IdxInd_Stage6_WRITE_SAX(); break;2488case Uop_IdxInd_Stage6_RMW: IdxInd_Stage6_RMW(); break;2489case Uop_IdxInd_Stage7_RMW_SLO: IdxInd_Stage7_RMW_SLO(); break;2490case Uop_IdxInd_Stage7_RMW_ISC: IdxInd_Stage7_RMW_ISC(); break;2491case Uop_IdxInd_Stage7_RMW_DCP: IdxInd_Stage7_RMW_DCP(); break;2492case Uop_IdxInd_Stage7_RMW_SRE: IdxInd_Stage7_RMW_SRE(); break;2493case Uop_IdxInd_Stage7_RMW_RRA: IdxInd_Stage7_RMW_RRA(); break;2494case Uop_IdxInd_Stage7_RMW_RLA: IdxInd_Stage7_RMW_RLA(); break;2495case Uop_IdxInd_Stage8_RMW: IdxInd_Stage8_RMW(); break;2496case Uop_PushP: PushP(); break;2497case Uop_PushA: PushA(); break;2498case Uop_PullA_NoInc: PullA_NoInc(); break;2499case Uop_PullP_NoInc: PullP_NoInc(); break;2500case Uop_Imp_ASL_A: Imp_ASL_A(); break;2501case Uop_Imp_ROL_A: Imp_ROL_A(); break;2502case Uop_Imp_ROR_A: Imp_ROR_A(); break;2503case Uop_Imp_LSR_A: Imp_LSR_A(); break;2504case Uop_JMP_abs: JMP_abs(); break;2505case Uop_IncPC: IncPC(); break;2506case Uop_ZP_RMW_Stage3: ZP_RMW_Stage3(); break;2507case Uop_ZP_RMW_Stage5: ZP_RMW_Stage5(); break;2508case Uop_ZP_RMW_INC: ZP_RMW_INC(); break;2509case Uop_ZP_RMW_DEC: ZP_RMW_DEC(); break;2510case Uop_ZP_RMW_ASL: ZP_RMW_ASL(); break;2511case Uop_ZP_RMW_SRE: ZP_RMW_SRE(); break;2512case Uop_ZP_RMW_RRA: ZP_RMW_RRA(); break;2513case Uop_ZP_RMW_DCP: ZP_RMW_DCP(); break;2514case Uop_ZP_RMW_LSR: ZP_RMW_LSR(); break;2515case Uop_ZP_RMW_ROR: ZP_RMW_ROR(); break;2516case Uop_ZP_RMW_ROL: ZP_RMW_ROL(); break;2517case Uop_ZP_RMW_SLO: ZP_RMW_SLO(); break;2518case Uop_ZP_RMW_ISC: ZP_RMW_ISC(); break;2519case Uop_ZP_RMW_RLA: ZP_RMW_RLA(); break;2520case Uop_AbsIdx_Stage3_Y: AbsIdx_Stage3_Y(); break;2521case Uop_AbsIdx_Stage3_X: AbsIdx_Stage3_X(); break;2522case Uop_AbsIdx_READ_Stage4: AbsIdx_READ_Stage4(); break;2523case Uop_AbsIdx_Stage4: AbsIdx_Stage4(); break;2524case Uop_AbsIdx_WRITE_Stage5_STA: AbsIdx_WRITE_Stage5_STA(); break;2525case Uop_AbsIdx_WRITE_Stage5_SHY: AbsIdx_WRITE_Stage5_SHY(); break;2526case Uop_AbsIdx_WRITE_Stage5_SHX: AbsIdx_WRITE_Stage5_SHX(); break;2527case Uop_AbsIdx_WRITE_Stage5_ERROR: AbsIdx_WRITE_Stage5_ERROR(); break;2528case Uop_AbsIdx_RMW_Stage5: AbsIdx_RMW_Stage5(); break;2529case Uop_AbsIdx_RMW_Stage7: AbsIdx_RMW_Stage7(); break;2530case Uop_AbsIdx_RMW_Stage6_DEC: AbsIdx_RMW_Stage6_DEC(); break;2531case Uop_AbsIdx_RMW_Stage6_DCP: AbsIdx_RMW_Stage6_DCP(); break;2532case Uop_AbsIdx_RMW_Stage6_ISC: AbsIdx_RMW_Stage6_ISC(); break;2533case Uop_AbsIdx_RMW_Stage6_INC: AbsIdx_RMW_Stage6_INC(); break;2534case Uop_AbsIdx_RMW_Stage6_ROL: AbsIdx_RMW_Stage6_ROL(); break;2535case Uop_AbsIdx_RMW_Stage6_LSR: AbsIdx_RMW_Stage6_LSR(); break;2536case Uop_AbsIdx_RMW_Stage6_SLO: AbsIdx_RMW_Stage6_SLO(); break;2537case Uop_AbsIdx_RMW_Stage6_SRE: AbsIdx_RMW_Stage6_SRE(); break;2538case Uop_AbsIdx_RMW_Stage6_RRA: AbsIdx_RMW_Stage6_RRA(); break;2539case Uop_AbsIdx_RMW_Stage6_RLA: AbsIdx_RMW_Stage6_RLA(); break;2540case Uop_AbsIdx_RMW_Stage6_ASL: AbsIdx_RMW_Stage6_ASL(); break;2541case Uop_AbsIdx_RMW_Stage6_ROR: AbsIdx_RMW_Stage6_ROR(); break;2542case Uop_AbsIdx_READ_Stage5_LDA: AbsIdx_READ_Stage5_LDA(); break;2543case Uop_AbsIdx_READ_Stage5_LDX: AbsIdx_READ_Stage5_LDX(); break;2544case Uop_AbsIdx_READ_Stage5_LAX: AbsIdx_READ_Stage5_LAX(); break;2545case Uop_AbsIdx_READ_Stage5_LDY: AbsIdx_READ_Stage5_LDY(); break;2546case Uop_AbsIdx_READ_Stage5_ORA: AbsIdx_READ_Stage5_ORA(); break;2547case Uop_AbsIdx_READ_Stage5_NOP: AbsIdx_READ_Stage5_NOP(); break;2548case Uop_AbsIdx_READ_Stage5_CMP: AbsIdx_READ_Stage5_CMP(); break;2549case Uop_AbsIdx_READ_Stage5_SBC: AbsIdx_READ_Stage5_SBC(); break;2550case Uop_AbsIdx_READ_Stage5_ADC: AbsIdx_READ_Stage5_ADC(); break;2551case Uop_AbsIdx_READ_Stage5_EOR: AbsIdx_READ_Stage5_EOR(); break;2552case Uop_AbsIdx_READ_Stage5_AND: AbsIdx_READ_Stage5_AND(); break;2553case Uop_AbsIdx_READ_Stage5_ERROR: AbsIdx_READ_Stage5_ERROR(); break;2554case Uop_AbsInd_JMP_Stage4: AbsInd_JMP_Stage4(); break;2555case Uop_AbsInd_JMP_Stage5: AbsInd_JMP_Stage5(); break;2556case Uop_Abs_RMW_Stage4: Abs_RMW_Stage4(); break;2557case Uop_Abs_RMW_Stage5_INC: Abs_RMW_Stage5_INC(); break;2558case Uop_Abs_RMW_Stage5_DEC: Abs_RMW_Stage5_DEC(); break;2559case Uop_Abs_RMW_Stage5_DCP: Abs_RMW_Stage5_DCP(); break;2560case Uop_Abs_RMW_Stage5_ISC: Abs_RMW_Stage5_ISC(); break;2561case Uop_Abs_RMW_Stage5_ASL: Abs_RMW_Stage5_ASL(); break;2562case Uop_Abs_RMW_Stage5_ROR: Abs_RMW_Stage5_ROR(); break;2563case Uop_Abs_RMW_Stage5_SLO: Abs_RMW_Stage5_SLO(); break;2564case Uop_Abs_RMW_Stage5_RLA: Abs_RMW_Stage5_RLA(); break;2565case Uop_Abs_RMW_Stage5_SRE: Abs_RMW_Stage5_SRE(); break;2566case Uop_Abs_RMW_Stage5_RRA: Abs_RMW_Stage5_RRA(); break;2567case Uop_Abs_RMW_Stage5_ROL: Abs_RMW_Stage5_ROL(); break;2568case Uop_Abs_RMW_Stage5_LSR: Abs_RMW_Stage5_LSR(); break;2569case Uop_Abs_RMW_Stage6: Abs_RMW_Stage6(); break;2570case Uop_End_ISpecial: End_ISpecial(); break;2571case Uop_End_SuppressInterrupt: End_SuppressInterrupt(); break;2572case Uop_End: End(); break;2573case Uop_End_BranchSpecial: End_BranchSpecial(); break;2574}2575}25762577__declspec(dllexport) void ExecuteOne()2578{2579if (!rdy_freeze)2580{2581TotalExecutedCycles++;25822583interrupt_pending |= NMI || (IRQ && !FlagI);2584}2585rdy_freeze = false;25862587//i tried making ExecuteOneRetry not re-entrant by having it set a flag instead, then exit from the call below, check the flag, and GOTO if it was flagged, but it wasnt faster2588ExecuteOneRetry();25892590if (!rdy_freeze)2591mi++;2592} //ExecuteOne25932594}; // struct CPU259525962597