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