MOS6502OpCode.java

1
package com.rox.cpu.mos6502;
2
3
import java.util.Arrays;
4
import java.util.Map;
5
import java.util.stream.Collectors;
6
7
import static com.rox.cpu.mos6502.MOS6502MicroOp.*;
8
9
public enum MOS6502OpCode {
10
    // NOTE: The first cycle is the FETCH cycle!!
11
12
    //XXX Possible bug, some instructions might not incremenet the pc, meaning the next instruction will read from the wrong place
13
14
    /** Stash the program counter and process status and set program counter to the interrupt vectors*/
15
    BRK_IMP(0x00, clockTicks(
16
            opsInTick(DUMMY_READ, INC_PC),
17
            opsInTick(PUSH_PCH),
18
            opsInTick(PUSH_PCL),
19
            opsInTick(PUSH_PROCESSOR_STATUS_WITH_BREAK, INTERRUPT),
20
            opsInTick(ADDRESS_IV_LOW, PCL_FROM_MEM),
21
            opsInTick(ADDRESS_IV_HIGH, PCH_FROM_MEM)
22
    )),
23
24
    /** Do nothing */
25
    NOP_IMP(0xEA, clockTicks(
26
            opsInTick() //Do nothing
27
    )),
28
29
    /** Zero Page Addressed ADC (ADd with Carry) */
30
    ADC_Z(0x65, clockTicks(
31
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
32
            opsInTick(ADDRESS_ADL, ADC, SET_FLAGS_ON_A)
33
    )),
34
35
    /** Immediate Addressed ADC (ADd with Carry) */
36
    ADC_I(0x69, clockTicks(
37
            opsInTick(ADDRESS_PC, ADC, SET_FLAGS_ON_A)
38
    )),
39
40
    /** A ← A + Memory[ADH:ADL] + Carry */
41
    ADC_ABS(0x6D, clockTicks(
42
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
43
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
44
            opsInTick(ADDRESS_AD, ADC, SET_FLAGS_ON_A)
45
    )),
46
47
    /** A ← A + Memory[$1234 + X] + Carry */
48
    ADC_ABS_X(0x7D, clockTicks(
49
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
50
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
51
            opsInTick(ADC, SET_FLAGS_ON_A))
52
    ),
53
54
    ADC_ABS_Y(0x79, clockTicks(
55
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
56
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
57
            opsInTick(ADC, SET_FLAGS_ON_A)
58
    )),
59
60
    ADC_IND_X(0x61, clockTicks(
61
            opsInTick(ADDRESS_PC), //XXX store in temporary location we can add to?
62
            opsInTick(X_OFFSET_ADDRESS),
63
            opsInTick(ADL_FROM_MEM),
64
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
65
            opsInTick(ADC, SET_FLAGS_ON_A)
66
    )),
67
68
    ADC_IND_Y(0x71, clockTicks(
69
            opsInTick(ADDRESS_PC),
70
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
71
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
72
            opsInTick(ADC, SET_FLAGS_ON_A)
73
    )),
74
75
    ADC_Z_X(0x75, clockTicks(
76
            opsInTick(ADDRESS_PC),
77
            opsInTick(X_OFFSET_ADDRESS),
78
            opsInTick(ADC, SET_FLAGS_ON_A)
79
    )),
80
81
    LDA_I(0xA9, clockTicks(
82
            opsInTick(ADDRESS_PC, A_FROM_MEM, SET_FLAGS_ON_A)
83
    )),
84
85
    LDA_Z(0xA5, clockTicks(
86
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
87
            opsInTick(ADDRESS_ADL, A_FROM_AD, SET_FLAGS_ON_A)
88
    )),
89
90
    LDA_Z_X(0xB5, clockTicks(
91
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
92
            opsInTick(ADL_PLUS_X),
93
            opsInTick(ADDRESS_ADL, A_FROM_AD, SET_FLAGS_ON_A)
94
    )),
95
96
    LDA_ABS(0xAD, clockTicks(
97
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
98
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
99
            opsInTick(ADDRESS_AD, A_FROM_AD, SET_FLAGS_ON_A)
100
    )),
101
102
    LDA_ABS_X(0xBD, clockTicks(
103
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
104
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
105
            opsInTick(A_FROM_AD, SET_FLAGS_ON_A)
106
    )),
107
108
    LDA_ABS_Y(0xB9, clockTicks(
109
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
110
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
111
            opsInTick(A_FROM_AD, SET_FLAGS_ON_A)
112
    )),
113
114
    LDA_IND_X(0xA1, clockTicks(
115
            opsInTick(ADDRESS_PC),
116
            opsInTick(X_OFFSET_ADDRESS),
117
            opsInTick(ADL_FROM_MEM),
118
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
119
            opsInTick(A_FROM_AD, SET_FLAGS_ON_A)
120
    )),
121
122
    LDA_IND_Y(0xB1, clockTicks(
123
            opsInTick(ADDRESS_PC),
124
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
125
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
126
            opsInTick(A_FROM_AD, SET_FLAGS_ON_A)
127
    )),
128
129
    LDX_I(0xA2, clockTicks(
130
            opsInTick(ADDRESS_PC, X_FROM_MEM, SET_FLAGS_ON_X)
131
    )),
132
133
    LDX_Z(0xA6, clockTicks(
134
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
135
            opsInTick(ADDRESS_ADL, X_FROM_AD, SET_FLAGS_ON_X)
136
    )),
137
138
    LDX_Z_Y(0xB6, clockTicks(
139
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
140
            opsInTick(ADL_PLUS_Y),
141
            opsInTick(ADDRESS_ADL, X_FROM_AD, SET_FLAGS_ON_X)
142
    )),
143
144
    LDX_ABS(0xAE, clockTicks(
145
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
146
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
147
            opsInTick(ADDRESS_AD, X_FROM_AD, SET_FLAGS_ON_X)
148
    )),
149
150
    LDX_ABS_Y(0xBE, clockTicks(
151
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
152
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
153
            opsInTick(X_FROM_AD, SET_FLAGS_ON_X)
154
    )),
155
156
    LDY_I(0xA0, clockTicks(
157
            opsInTick(ADDRESS_PC, Y_FROM_MEM, SET_FLAGS_ON_Y)
158
    )),
159
160
    LDY_Z(0xA4, clockTicks(
161
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
162
            opsInTick(ADDRESS_ADL, Y_FROM_AD, SET_FLAGS_ON_Y)
163
    )),
164
165
    LDY_Z_X(0xB4, clockTicks(
166
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
167
            opsInTick(ADL_PLUS_X),
168
            opsInTick(ADDRESS_ADL, Y_FROM_AD, SET_FLAGS_ON_Y)
169
    )),
170
171
    LDY_ABS(0xAC, clockTicks(
172
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
173
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
174
            opsInTick(ADDRESS_AD, Y_FROM_AD, SET_FLAGS_ON_Y)
175
    )),
176
177
    LDY_ABS_X(0xBC, clockTicks(
178
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
179
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
180
            opsInTick(Y_FROM_AD, SET_FLAGS_ON_Y)
181
    )),
182
183
    AND_I(0x29, clockTicks(
184
            opsInTick(ADDRESS_PC, AND, SET_FLAGS_ON_A)
185
    )),
186
187
    AND_Z(0x25, clockTicks(
188
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
189
            opsInTick(ADDRESS_ADL, AND, SET_FLAGS_ON_A)
190
    )),
191
192
    AND_Z_X(0x35,clockTicks(
193
            opsInTick(ADDRESS_PC),
194
            opsInTick(X_OFFSET_ADDRESS),
195
            opsInTick(AND, SET_FLAGS_ON_A)
196
    )),
197
198
    AND_ABS(0x2D,clockTicks(
199
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
200
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
201
            opsInTick(ADDRESS_AD, AND, SET_FLAGS_ON_A)
202
    )),
203
204
    AND_ABS_X(0x3D,clockTicks(
205
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
206
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
207
            opsInTick(AND, SET_FLAGS_ON_A)
208
    )),
209
210
    AND_ABS_Y(0x39,clockTicks(
211
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
212
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
213
            opsInTick(AND, SET_FLAGS_ON_A)
214
    )),
215
216
    AND_IND_X(0x21,clockTicks(
217
            opsInTick(ADDRESS_PC), //XXX store in temporary location we can add to?
218
            opsInTick(X_OFFSET_ADDRESS),
219
            opsInTick(ADL_FROM_MEM),
220
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
221
            opsInTick(AND, SET_FLAGS_ON_A)
222
    )),
223
224
    AND_IND_Y(0x31,clockTicks(
225
            opsInTick(ADDRESS_PC),
226
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
227
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
228
            opsInTick(AND, SET_FLAGS_ON_A)
229
    )),
230
231
    ORA_I(0x09, clockTicks(
232
            opsInTick(ADDRESS_PC, ORA, SET_FLAGS_ON_A)
233
    )),
234
235
    ORA_Z(0x05, clockTicks(
236
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
237
            opsInTick(ADDRESS_ADL, ORA, SET_FLAGS_ON_A)
238
    )),
239
240
    ORA_Z_X(0x15, clockTicks(
241
            opsInTick(ADDRESS_PC),
242
            opsInTick(X_OFFSET_ADDRESS),
243
            opsInTick(ORA, SET_FLAGS_ON_A)
244
    )),
245
246
    ORA_ABS(0x0D, clockTicks(
247
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
248
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
249
            opsInTick(ADDRESS_AD, ORA, SET_FLAGS_ON_A)
250
    )),
251
252
    ORA_ABS_X(0x1D, clockTicks(
253
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
254
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
255
            opsInTick(ORA, SET_FLAGS_ON_A)
256
    )),
257
258
    ORA_ABS_Y(0x19, clockTicks(
259
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
260
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
261
            opsInTick(ORA, SET_FLAGS_ON_A)
262
    )),
263
264
    ORA_IND_X(0x01, clockTicks(
265
            opsInTick(ADDRESS_PC),
266
            opsInTick(X_OFFSET_ADDRESS),
267
            opsInTick(ADL_FROM_MEM),
268
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
269
            opsInTick(ORA, SET_FLAGS_ON_A)
270
    )),
271
272
    ORA_IND_Y(0x11, clockTicks(
273
            opsInTick(ADDRESS_PC),
274
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
275
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
276
            opsInTick(ORA, SET_FLAGS_ON_A)
277
    )),
278
279
    EOR_I(0x49, clockTicks(
280
            opsInTick(ADDRESS_PC, EOR, SET_FLAGS_ON_A)
281
    )),
282
283
    EOR_Z(0x45, clockTicks(
284
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
285
            opsInTick(ADDRESS_ADL, EOR, SET_FLAGS_ON_A)
286
    )),
287
288
    EOR_Z_X(0x55, clockTicks(
289
            opsInTick(ADDRESS_PC),
290
            opsInTick(X_OFFSET_ADDRESS),
291
            opsInTick(EOR, SET_FLAGS_ON_A)
292
    )),
293
294
    EOR_ABS(0x4D, clockTicks(
295
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
296
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
297
            opsInTick(ADDRESS_AD, EOR, SET_FLAGS_ON_A)
298
    )),
299
300
    EOR_ABS_X(0x5D, clockTicks(
301
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
302
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
303
            opsInTick(EOR, SET_FLAGS_ON_A)
304
    )),
305
306
    EOR_ABS_Y(0x59, clockTicks(
307
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
308
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
309
            opsInTick(EOR, SET_FLAGS_ON_A)
310
    )),
311
312
    EOR_IND_X(0x41, clockTicks(
313
            opsInTick(ADDRESS_PC),
314
            opsInTick(X_OFFSET_ADDRESS),
315
            opsInTick(ADL_FROM_MEM),
316
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
317
            opsInTick(EOR, SET_FLAGS_ON_A)
318
    )),
319
320
    EOR_IND_Y(0x51, clockTicks(
321
            opsInTick(ADDRESS_PC),
322
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
323
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
324
            opsInTick(EOR, SET_FLAGS_ON_A)
325
    )),
326
327
    SBC_I(0xE9, clockTicks(
328
            opsInTick(ADDRESS_PC, SBC, SET_FLAGS_ON_A)
329
    )),
330
331
    SBC_Z(0xE5, clockTicks(
332
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
333
            opsInTick(ADDRESS_ADL, SBC, SET_FLAGS_ON_A)
334
    )),
335
336
    SBC_Z_X(0xF5, clockTicks(
337
            opsInTick(ADDRESS_PC),
338
            opsInTick(X_OFFSET_ADDRESS),
339
            opsInTick(SBC, SET_FLAGS_ON_A)
340
    )),
341
342
    SBC_ABS(0xED, clockTicks(
343
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
344
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
345
            opsInTick(ADDRESS_AD, SBC, SET_FLAGS_ON_A)
346
    )),
347
348
    SBC_ABS_X(0xFD, clockTicks(
349
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
350
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
351
            opsInTick(SBC, SET_FLAGS_ON_A)
352
    )),
353
354
    SBC_ABS_Y(0xF9, clockTicks(
355
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
356
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
357
            opsInTick(SBC, SET_FLAGS_ON_A)
358
    )),
359
360
    SBC_IND_X(0xE1, clockTicks(
361
            opsInTick(ADDRESS_PC),
362
            opsInTick(X_OFFSET_ADDRESS),
363
            opsInTick(ADL_FROM_MEM),
364
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
365
            opsInTick(SBC, SET_FLAGS_ON_A)
366
    )),
367
368
    SBC_IND_Y(0xF1, clockTicks(
369
            opsInTick(ADDRESS_PC),
370
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
371
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
372
            opsInTick(SBC, SET_FLAGS_ON_A)
373
    )),
374
375
    CMP_I(0xC9, clockTicks(
376
            opsInTick(ADDRESS_PC, CMP)
377
    )),
378
379
    CMP_Z(0xC5, clockTicks(
380
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
381
            opsInTick(ADDRESS_ADL, CMP)
382
    )),
383
384
    CMP_Z_X(0xD5, clockTicks(
385
            opsInTick(ADDRESS_PC),
386
            opsInTick(X_OFFSET_ADDRESS),
387
            opsInTick(CMP)
388
    )),
389
390
    CMP_ABS(0xCD, clockTicks(
391
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
392
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
393
            opsInTick(ADDRESS_AD, CMP)
394
    )),
395
396
    CMP_ABS_X(0xDD, clockTicks(
397
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
398
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X_AND_PAGE_CROSS),
399
            opsInTick(CMP)
400
    )),
401
402
    CMP_ABS_Y(0xD9, clockTicks(
403
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
404
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
405
            opsInTick(CMP)
406
    )),
407
408
    CMP_IND_X(0xC1, clockTicks(
409
            opsInTick(ADDRESS_PC),
410
            opsInTick(X_OFFSET_ADDRESS),
411
            opsInTick(ADL_FROM_MEM),
412
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
413
            opsInTick(CMP)
414
    )),
415
416
    CMP_IND_Y(0xD1, clockTicks(
417
            opsInTick(ADDRESS_PC),
418
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
419
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y_AND_PAGE_CROSS),
420
            opsInTick(CMP)
421
    )),
422
423
    JMP_ABS(0x4C, clockTicks(
424
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
425
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, AD_TO_PC)
426
    )),
427
428
    JMP_IND(0x6C, clockTicks(
429
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
430
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
431
            opsInTick(ADDRESS_AD, PCL_FROM_MEM),
432
            opsInTick(INC_ADL, ADDRESS_AD , PCH_FROM_MEM)
433
    )),
434
435
    STA_Z(0x85, clockTicks(
436
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
437
            opsInTick(ADDRESS_ADL, MEM_FROM_A)
438
    )),
439
440
    STA_Z_X(0x95, clockTicks(
441
            opsInTick(ADDRESS_PC),
442
            opsInTick(X_OFFSET_ADDRESS),
443
            opsInTick(MEM_FROM_A)
444
    )),
445
446
    STA_ABS(0x8D, clockTicks(
447
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
448
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
449
            opsInTick(ADDRESS_AD, MEM_FROM_A)
450
    )),
451
452
    STA_ABS_X(0x9D, clockTicks(
453
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
454
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
455
            opsInTick(DUMMY_READ),
456
            opsInTick(MEM_FROM_A)
457
    )),
458
459
    STA_ABS_Y(0x99, clockTicks(
460
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
461
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_Y),
462
            opsInTick(DUMMY_READ),
463
            opsInTick(MEM_FROM_A)
464
    )),
465
466
    STA_IND_X(0x81, clockTicks(
467
            opsInTick(ADDRESS_PC),
468
            opsInTick(X_OFFSET_ADDRESS),
469
            opsInTick(ADL_FROM_MEM),
470
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD),
471
            opsInTick(MEM_FROM_A)
472
    )),
473
474
    STA_IND_Y(0x91, clockTicks(
475
            opsInTick(ADDRESS_PC),
476
            opsInTick(ADDRESS_MEM_POINTER, ADL_FROM_MEM),
477
            opsInTick(NEXT_MEM_TO_ADH, ADDRESS_AD_PLUS_Y),
478
            opsInTick(DUMMY_READ),
479
            opsInTick(MEM_FROM_A)
480
    )),
481
482
    STX_Z(0x86, clockTicks(
483
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
484
            opsInTick(ADDRESS_ADL, MEM_FROM_X)
485
    )),
486
487
    STX_Z_Y(0x96, clockTicks(
488
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
489
            opsInTick(ADL_PLUS_Y),
490
            opsInTick(ADDRESS_ADL, MEM_FROM_X)
491
    )),
492
493
    STX_ABS(0x8E, clockTicks(
494
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
495
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
496
            opsInTick(ADDRESS_AD, MEM_FROM_X)
497
    )),
498
499
    STY_Z(0x84, clockTicks(
500
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
501
            opsInTick(ADDRESS_ADL, MEM_FROM_Y)
502
    )),
503
504
    STY_Z_X(0x94, clockTicks(
505
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
506
            opsInTick(ADL_PLUS_X),
507
            opsInTick(ADDRESS_ADL, MEM_FROM_Y)
508
    )),
509
510
    STY_ABS(0x8C, clockTicks(
511
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
512
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
513
            opsInTick(ADDRESS_AD, MEM_FROM_Y)
514
    )),
515
516
    INX_IMP(0xE8, clockTicks(
517
            opsInTick(INX, SET_FLAGS_ON_X)
518
    )),
519
520
    PHA_IMP(0x48, clockTicks(
521
            opsInTick(DUMMY_READ),
522
            opsInTick(PUSH_A)
523
    )),
524
525
    PLA_IMP(0x68, clockTicks(
526
            opsInTick(DUMMY_READ),
527
            opsInTick(INC_SP),
528
            opsInTick(PULL_A, SET_FLAGS_ON_A)
529
    )),
530
531
    PHP_IMP(0x08, clockTicks(
532
            opsInTick(DUMMY_READ),
533
            opsInTick(PUSH_PROCESSOR_STATUS_WITH_BREAK)
534
    )),
535
536
    PLP_IMP(0x28, clockTicks(
537
            opsInTick(DUMMY_READ),
538
            opsInTick(INC_SP),
539
            opsInTick(PULL_PROCESSOR_STATUS)
540
    )),
541
542
    TAX_IMP(0xAA, clockTicks(
543
            opsInTick(DUMMY_READ, X_FROM_A, SET_FLAGS_ON_X)
544
    )),
545
546
    TAY_IMP(0xA8, clockTicks(
547
            opsInTick(DUMMY_READ, Y_FROM_A, SET_FLAGS_ON_Y)
548
    )),
549
550
    TXA_IMP(0x8A, clockTicks(
551
            opsInTick(DUMMY_READ, A_FROM_X, SET_FLAGS_ON_A)
552
    )),
553
554
    TYA_IMP(0x98, clockTicks(
555
            opsInTick(DUMMY_READ, A_FROM_Y, SET_FLAGS_ON_A)
556
    )),
557
558
    TSX_IMP(0xBA, clockTicks(
559
            opsInTick(DUMMY_READ, X_FROM_SP, SET_FLAGS_ON_X)
560
    )),
561
562
    TXS_IMP(0x9A, clockTicks(
563
            opsInTick(DUMMY_READ, SP_FROM_X)
564
    )),
565
566
    DEX_IMP(0xCA, clockTicks(
567
            opsInTick(DEX, SET_FLAGS_ON_X)
568
    )),
569
570
    INY_IMP(0xC8, clockTicks(
571
            opsInTick(INY, SET_FLAGS_ON_Y)
572
    )),
573
574
    DEY_IMP(0x88, clockTicks(
575
            opsInTick(DEY, SET_FLAGS_ON_Y)
576
    )),
577
578
    CLC_IMP(0x18, clockTicks(
579
            opsInTick(CLEAR_CARRY)
580
    )),
581
582
    SEC_IMP(0x38, clockTicks(
583
            opsInTick(SET_CARRY)
584
    )),
585
586
    CLI_IMP(0x58, clockTicks(
587
            opsInTick(CLEAR_INTERRUPT_DISABLE)
588
    )),
589
590
    SEI_IMP(0x78, clockTicks(
591
            opsInTick(INTERRUPT)
592
    )),
593
594
    CLV_IMP(0xB8, clockTicks(
595
            opsInTick(CLEAR_OVERFLOW)
596
    )),
597
598
    CLD_IMP(0xD8, clockTicks(
599
            opsInTick(CLEAR_DECIMAL)
600
    )),
601
602
    SED_IMP(0xF8, clockTicks(
603
            opsInTick(SET_DECIMAL)
604
    )),
605
606
    CPX_I(0xE0, clockTicks(
607
            opsInTick(ADDRESS_PC, CPX)
608
    )),
609
610
    CPX_Z(0xE4, clockTicks(
611
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
612
            opsInTick(ADDRESS_ADL, CPX)
613
    )),
614
615
    CPX_ABS(0xEC, clockTicks(
616
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
617
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
618
            opsInTick(ADDRESS_AD, CPX)
619
    )),
620
621
    CPY_I(0xC0, clockTicks(
622
            opsInTick(ADDRESS_PC, CPY)
623
    )),
624
625
    CPY_Z(0xC4, clockTicks(
626
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
627
            opsInTick(ADDRESS_ADL, CPY)
628
    )),
629
630
    CPY_ABS(0xCC, clockTicks(
631
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
632
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
633
            opsInTick(ADDRESS_AD, CPY)
634
    )),
635
636
    BIT_Z(0x24, clockTicks(
637
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
638
            opsInTick(ADDRESS_ADL, BIT_TEST)
639
    )),
640
641
    BIT_ABS(0x2C, clockTicks(
642
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
643
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
644
            opsInTick(ADDRESS_AD, BIT_TEST)
645
    )),
646
647
    INC_Z(0xE6, clockTicks(
648
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
649
            opsInTick(ADDRESS_ADL),
650
            opsInTick(DUMMY_WRITE_MEM),
651
            opsInTick(INC_MEM, SET_FLAGS_ON_MEM)
652
    )),
653
654
    INC_Z_X(0xF6, clockTicks(
655
            opsInTick(ADDRESS_PC),
656
            opsInTick(X_OFFSET_ADDRESS),
657
            opsInTick(DUMMY_READ),
658
            opsInTick(DUMMY_WRITE_MEM),
659
            opsInTick(INC_MEM, SET_FLAGS_ON_MEM)
660
    )),
661
662
    INC_ABS(0xEE, clockTicks(
663
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
664
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
665
            opsInTick(ADDRESS_AD),
666
            opsInTick(DUMMY_WRITE_MEM),
667
            opsInTick(INC_MEM, SET_FLAGS_ON_MEM)
668
    )),
669
670
    INC_ABS_X(0xFE, clockTicks(
671
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
672
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
673
            opsInTick(DUMMY_READ),
674
            opsInTick(DUMMY_READ),
675
            opsInTick(DUMMY_WRITE_MEM),
676
            opsInTick(INC_MEM, SET_FLAGS_ON_MEM)
677
    )),
678
679
    DEC_Z(0xC6, clockTicks(
680
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
681
            opsInTick(ADDRESS_ADL),
682
            opsInTick(DUMMY_WRITE_MEM),
683
            opsInTick(DEC_MEM, SET_FLAGS_ON_MEM)
684
    )),
685
686
    DEC_Z_X(0xD6, clockTicks(
687
            opsInTick(ADDRESS_PC),
688
            opsInTick(X_OFFSET_ADDRESS),
689
            opsInTick(DUMMY_READ),
690
            opsInTick(DUMMY_WRITE_MEM),
691
            opsInTick(DEC_MEM, SET_FLAGS_ON_MEM)
692
    )),
693
694
    DEC_ABS(0xCE, clockTicks(
695
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
696
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
697
            opsInTick(ADDRESS_AD),
698
            opsInTick(DUMMY_WRITE_MEM),
699
            opsInTick(DEC_MEM, SET_FLAGS_ON_MEM)
700
    )),
701
702
    DEC_ABS_X(0xDE, clockTicks(
703
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
704
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
705
            opsInTick(DUMMY_READ),
706
            opsInTick(DUMMY_READ),
707
            opsInTick(DUMMY_WRITE_MEM),
708
            opsInTick(DEC_MEM, SET_FLAGS_ON_MEM)
709
    )),
710
711
    ASL_A(0x0A, clockTicks(
712
            opsInTick(ASL_ACC, SET_FLAGS_ON_A)
713
    )),
714
715
    ASL_Z(0x06, clockTicks(
716
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
717
            opsInTick(ADDRESS_ADL),
718
            opsInTick(DUMMY_WRITE_MEM),
719
            opsInTick(ASL_MEM, SET_FLAGS_ON_MEM)
720
    )),
721
722
    ASL_Z_X(0x16, clockTicks(
723
            opsInTick(ADDRESS_PC),
724
            opsInTick(X_OFFSET_ADDRESS),
725
            opsInTick(DUMMY_READ),
726
            opsInTick(DUMMY_WRITE_MEM),
727
            opsInTick(ASL_MEM, SET_FLAGS_ON_MEM)
728
    )),
729
730
    ASL_ABS(0x0E, clockTicks(
731
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
732
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
733
            opsInTick(ADDRESS_AD),
734
            opsInTick(DUMMY_WRITE_MEM),
735
            opsInTick(ASL_MEM, SET_FLAGS_ON_MEM)
736
    )),
737
738
    ASL_ABS_X(0x1E, clockTicks(
739
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
740
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
741
            opsInTick(DUMMY_READ),
742
            opsInTick(DUMMY_READ),
743
            opsInTick(DUMMY_WRITE_MEM),
744
            opsInTick(ASL_MEM, SET_FLAGS_ON_MEM)
745
    )),
746
747
    LSR_A(0x4A, clockTicks(
748
            opsInTick(LSR_ACC, SET_FLAGS_ON_A)
749
    )),
750
751
    LSR_Z(0x46, clockTicks(
752
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
753
            opsInTick(ADDRESS_ADL),
754
            opsInTick(DUMMY_WRITE_MEM),
755
            opsInTick(LSR_MEM, SET_FLAGS_ON_MEM)
756
    )),
757
758
    LSR_Z_X(0x56, clockTicks(
759
            opsInTick(ADDRESS_PC),
760
            opsInTick(X_OFFSET_ADDRESS),
761
            opsInTick(DUMMY_READ),
762
            opsInTick(DUMMY_WRITE_MEM),
763
            opsInTick(LSR_MEM, SET_FLAGS_ON_MEM)
764
    )),
765
766
    LSR_ABS(0x4E, clockTicks(
767
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
768
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
769
            opsInTick(ADDRESS_AD),
770
            opsInTick(DUMMY_WRITE_MEM),
771
            opsInTick(LSR_MEM, SET_FLAGS_ON_MEM)
772
    )),
773
774
    LSR_ABS_X(0x5E, clockTicks(
775
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
776
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
777
            opsInTick(DUMMY_READ),
778
            opsInTick(DUMMY_READ),
779
            opsInTick(DUMMY_WRITE_MEM),
780
            opsInTick(LSR_MEM, SET_FLAGS_ON_MEM)
781
    )),
782
783
    ROL_A(0x2A, clockTicks(
784
            opsInTick(ROL_ACC, SET_FLAGS_ON_A)
785
    )),
786
787
    ROL_Z(0x26, clockTicks(
788
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
789
            opsInTick(ADDRESS_ADL),
790
            opsInTick(DUMMY_WRITE_MEM),
791
            opsInTick(ROL_MEM, SET_FLAGS_ON_MEM)
792
    )),
793
794
    ROL_Z_X(0x36, clockTicks(
795
            opsInTick(ADDRESS_PC),
796
            opsInTick(X_OFFSET_ADDRESS),
797
            opsInTick(DUMMY_READ),
798
            opsInTick(DUMMY_WRITE_MEM),
799
            opsInTick(ROL_MEM, SET_FLAGS_ON_MEM)
800
    )),
801
802
    ROL_ABS(0x2E, clockTicks(
803
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
804
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
805
            opsInTick(ADDRESS_AD),
806
            opsInTick(DUMMY_WRITE_MEM),
807
            opsInTick(ROL_MEM, SET_FLAGS_ON_MEM)
808
    )),
809
810
    ROL_ABS_X(0x3E, clockTicks(
811
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
812
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
813
            opsInTick(DUMMY_READ),
814
            opsInTick(DUMMY_READ),
815
            opsInTick(DUMMY_WRITE_MEM),
816
            opsInTick(ROL_MEM, SET_FLAGS_ON_MEM)
817
    )),
818
819
    ROR_A(0x6A, clockTicks(
820
            opsInTick(ROR_ACC, SET_FLAGS_ON_A)
821
    )),
822
823
    ROR_Z(0x66, clockTicks(
824
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
825
            opsInTick(ADDRESS_ADL),
826
            opsInTick(DUMMY_WRITE_MEM),
827
            opsInTick(ROR_MEM, SET_FLAGS_ON_MEM)
828
    )),
829
830
    ROR_Z_X(0x76, clockTicks(
831
            opsInTick(ADDRESS_PC),
832
            opsInTick(X_OFFSET_ADDRESS),
833
            opsInTick(DUMMY_READ),
834
            opsInTick(DUMMY_WRITE_MEM),
835
            opsInTick(ROR_MEM, SET_FLAGS_ON_MEM)
836
    )),
837
838
    ROR_ABS(0x6E, clockTicks(
839
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
840
            opsInTick(ADDRESS_PC, ADH_FROM_MEM),
841
            opsInTick(ADDRESS_AD),
842
            opsInTick(DUMMY_WRITE_MEM),
843
            opsInTick(ROR_MEM, SET_FLAGS_ON_MEM)
844
    )),
845
846
    ROR_ABS_X(0x7E, clockTicks(
847
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
848
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, ADDRESS_AD_PLUS_X),
849
            opsInTick(DUMMY_READ),
850
            opsInTick(DUMMY_READ),
851
            opsInTick(DUMMY_WRITE_MEM),
852
            opsInTick(ROR_MEM, SET_FLAGS_ON_MEM)
853
    )),
854
855
    BPL_REL(0x10, clockTicks(
856
            opsInTick(ADDRESS_PC, BRANCH_IF_POSITIVE)
857
    )),
858
859
    BMI_REL(0x30, clockTicks(
860
            opsInTick(ADDRESS_PC, BRANCH_IF_NEGATIVE)
861
    )),
862
863
    BVC_REL(0x50, clockTicks(
864
            opsInTick(ADDRESS_PC, BRANCH_IF_OVERFLOW_CLEAR)
865
    )),
866
867
    BVS_REL(0x70, clockTicks(
868
            opsInTick(ADDRESS_PC, BRANCH_IF_OVERFLOW_SET)
869
    )),
870
871
    BCC_REL(0x90, clockTicks(
872
            opsInTick(ADDRESS_PC, BRANCH_IF_CARRY_CLEAR)
873
    )),
874
875
    BCS_REL(0xB0, clockTicks(
876
            opsInTick(ADDRESS_PC, BRANCH_IF_CARRY_SET)
877
    )),
878
879
    BNE_REL(0xD0, clockTicks(
880
            opsInTick(ADDRESS_PC, BRANCH_IF_NOT_EQUAL)
881
    )),
882
883
    BEQ_REL(0xF0, clockTicks(
884
            opsInTick(ADDRESS_PC, BRANCH_IF_EQUAL)
885
    )),
886
887
    /** Push the return address onto the stack and jump to the addressed subroutine */
888
    JSR_ABS(0x20, clockTicks(
889
            opsInTick(ADDRESS_PC, ADL_FROM_MEM),
890
            opsInTick(DUMMY_READ),
891
            opsInTick(PUSH_PCH),
892
            opsInTick(PUSH_PCL),
893
            opsInTick(ADDRESS_PC, ADH_FROM_MEM, AD_TO_PC)
894
    )),
895
896
    /** Pull the return address from the stack (incrementing past the JSR operand) and resume there */
897
    RTS_IMP(0x60, clockTicks(
898
            opsInTick(DUMMY_READ),
899
            opsInTick(INC_SP),
900
            opsInTick(PULL_PCL, INC_SP),
901
            opsInTick(PULL_PCH),
902
            opsInTick(INC_PC)
903
    )),
904
905
    /** Pull the processor status and return address from the stack, resuming exactly where BRK left off */
906
    RTI_IMP(0x40, clockTicks(
907
            opsInTick(DUMMY_READ),
908
            opsInTick(INC_SP),
909
            opsInTick(PULL_PROCESSOR_STATUS, INC_SP),
910
            opsInTick(PULL_PCL, INC_SP),
911
            opsInTick(PULL_PCH)
912
    ));
913
914
    /*
915
    For sample program: INX (done), CPX (done), BNE (done), BRK (done)
916
     */
917
918
    /** 6502 code for this OpCode */
919
    private final int id;
920
    /** [tick][operation] */
921
    private final MOS6502Operation[][] ops;
922
923
    /** Helper method to make setting up enum arguments cleaner */
924
    private static MOS6502Operation[] opsInTick(final MOS6502Operation... ops) {
925
        return ops;
926
    }
927
928
    /** Helper method to make setting up enum arguments cleaner */
929
    private static MOS6502Operation[][] clockTicks(final MOS6502Operation[]... ticks) {
930
        return ticks;
931
    }
932
933
    /** Helper method for turning an ID into an enum */
934
    private static final Map<Integer, MOS6502OpCode> BY_ID =
935
            Arrays.stream(values())
936
                    .collect(Collectors.toMap(op -> op.id, op -> op));
937
938
    MOS6502OpCode(final int id, final MOS6502Operation[][] ops) {
939
        this.id = id;
940
        this.ops = ops;
941
    }
942
943
    /**
944
     * @return the list of {@link MOS6502Operation}s that make up this opcode arranged as a 2d array where
945
     * [clock tick][operation in that clock tick]
946
     */
947
    public MOS6502Operation[][] getOperations(){
948 1 1. getOperations : replaced return value with null for com/rox/cpu/mos6502/MOS6502OpCode::getOperations → KILLED
        return ops.clone();
949
    }
950
951
    /**
952
     * @param id for a MOS6502 opcode
953
     * @return the {@link MOS6502OpCode} associated with the given ID
954
     * @throws IllegalArgumentException if the ID is unknown
955
     */
956
    public static MOS6502OpCode from(final int id) {
957
        final MOS6502OpCode opCode = BY_ID.get(id);
958
959 1 1. from : negated conditional → KILLED
        if (opCode == null) {
960
            throw new IllegalArgumentException(String.format("Unknown opcode: 0x%02X", id));
961
        }
962
963 1 1. from : replaced return value with null for com/rox/cpu/mos6502/MOS6502OpCode::from → KILLED
        return opCode;
964
    }
965
966
    public Integer getId() {
967 1 1. getId : replaced Integer return value with 0 for com/rox/cpu/mos6502/MOS6502OpCode::getId → KILLED
        return id;
968
    }
969
}

Mutations

948

1.1
Location : getOperations
Killed by : com.rox.cpu.mos6502.MOS6502OpCodeTest.[engine:junit-jupiter]/[class:com.rox.cpu.mos6502.MOS6502OpCodeTest]/[nested-class:CLC]/[method:clcClearsCarryFlag()]
replaced return value with null for com/rox/cpu/mos6502/MOS6502OpCode::getOperations → KILLED

959

1.1
Location : from
Killed by : com.rox.cpu.mos6502.MOS6502OpCodeTest.[engine:junit-jupiter]/[class:com.rox.cpu.mos6502.MOS6502OpCodeTest]/[nested-class:CLC]/[method:clcClearsCarryFlag()]
negated conditional → KILLED

963

1.1
Location : from
Killed by : com.rox.cpu.mos6502.MOS6502OpCodeTest.[engine:junit-jupiter]/[class:com.rox.cpu.mos6502.MOS6502OpCodeTest]/[nested-class:CLC]/[method:clcClearsCarryFlag()]
replaced return value with null for com/rox/cpu/mos6502/MOS6502OpCode::from → KILLED

967

1.1
Location : getId
Killed by : com.rox.cpu.mos6502.MOS6502OpCodeTest.[engine:junit-jupiter]/[class:com.rox.cpu.mos6502.MOS6502OpCodeTest]/[nested-class:CLC]/[method:clcClearsCarryFlag()]
replaced Integer return value with 0 for com/rox/cpu/mos6502/MOS6502OpCode::getId → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1