mos6502 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2020, Robert Haines.
4
+ #
5
+ # Licensed under the BSD License. See LICENCE for details.
6
+
7
+ module Mos6502
8
+ class CpuFlags
9
+ def initialize
10
+ reset!
11
+ end
12
+
13
+ def carry=(flag)
14
+ @carry = set_flag(flag)
15
+ end
16
+
17
+ def carry?
18
+ @carry
19
+ end
20
+
21
+ def zero=(flag)
22
+ @zero = set_flag(flag)
23
+ end
24
+
25
+ def zero?
26
+ @zero
27
+ end
28
+
29
+ def interupt_disable=(flag)
30
+ @interupt_disable = set_flag(flag)
31
+ end
32
+
33
+ def interupt_disable?
34
+ @interupt_disable
35
+ end
36
+
37
+ def decimal_mode=(flag)
38
+ @decimal_mode = set_flag(flag)
39
+ end
40
+
41
+ def decimal_mode?
42
+ @decimal_mode
43
+ end
44
+
45
+ def break=(flag)
46
+ @break = set_flag(flag)
47
+ end
48
+
49
+ def break?
50
+ @break
51
+ end
52
+
53
+ def overflow=(flag)
54
+ @overflow = set_flag(flag)
55
+ end
56
+
57
+ def overflow?
58
+ @overflow
59
+ end
60
+
61
+ def negative=(flag)
62
+ @negative = set_flag(flag)
63
+ end
64
+
65
+ def negative?
66
+ @negative
67
+ end
68
+
69
+ def encode
70
+ [
71
+ @negative, @overflow, true, true, @decimal_mode,
72
+ @interupt_disable, @zero, @carry
73
+ ].reduce(0) { |acc, flag| (acc << 1) + get_flag(flag) }
74
+ end
75
+
76
+ def decode(bin)
77
+ self.carry = bin & 1
78
+ self.zero = (bin >> 1) & 1
79
+ self.interupt_disable = (bin >> 2) & 1
80
+ self.decimal_mode = (bin >> 3) & 1
81
+ self.break = (bin >> 4) & 1
82
+ self.overflow = (bin >> 6) & 1
83
+ self.negative = (bin >> 7) & 1
84
+ end
85
+
86
+ def reset!
87
+ @carry = false
88
+ @zero = false
89
+ @interupt_disable = false
90
+ @decimal_mode = false
91
+ @break = false
92
+ @overflow = false
93
+ @negative = false
94
+ end
95
+
96
+ private
97
+
98
+ def set_flag(flag) # rubocop:disable Naming/AccessorMethodName
99
+ flag == 0 ? false : !!flag # rubocop:disable Style/NumericPredicate
100
+ end
101
+
102
+ def get_flag(flag)
103
+ flag ? 1 : 0
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,861 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2020, Robert Haines.
4
+ #
5
+ # Licensed under the BSD License. See LICENCE for details.
6
+
7
+ require_relative 'cpu_ops'
8
+
9
+ module Mos6502
10
+ class Cpu
11
+ private
12
+
13
+ def instructions
14
+ {
15
+ # BRK
16
+ 0x00 => lambda {
17
+ @pc += 1
18
+ stack_push((@pc >> 8) & 0xff)
19
+ stack_push(@pc & 0xff)
20
+ stack_push(@status.encode)
21
+ @pc = @memory.get_word(0xfffe)
22
+ @status.break = true
23
+ @status.interupt_disable = true
24
+ },
25
+
26
+ # ORA (indexed indirect)
27
+ 0x01 => lambda {
28
+ @a |= @memory.get(indexed_indirect)
29
+ set_nz_flags(@a)
30
+ },
31
+
32
+ # ORA (zero page)
33
+ 0x05 => lambda {
34
+ @a |= @memory.get(zero_page)
35
+ set_nz_flags(@a)
36
+ },
37
+
38
+ # ASL (zero page)
39
+ 0x06 => lambda {
40
+ address = zero_page
41
+ @memory.set(address, asl(@memory.get(address)))
42
+ },
43
+
44
+ # PHP
45
+ 0x08 => lambda {
46
+ stack_push(@status.encode)
47
+ },
48
+
49
+ # ORA (immediate)
50
+ 0x09 => lambda {
51
+ @a |= next_byte
52
+ set_nz_flags(@a)
53
+ },
54
+
55
+ # ASL (accumulator)
56
+ 0x0a => lambda {
57
+ @a = asl(@a) & 0xff
58
+ },
59
+
60
+ # ORA (absolute)
61
+ 0x0d => lambda {
62
+ @a |= @memory.get(absolute)
63
+ set_nz_flags(@a)
64
+ },
65
+
66
+ # ASL (absolute)
67
+ 0x0e => lambda {
68
+ address = absolute
69
+ @memory.set(address, asl(@memory.get(address)))
70
+ },
71
+
72
+ # BPL
73
+ 0x10 => lambda {
74
+ offset = next_byte
75
+ @pc = branch(offset) unless @status.negative?
76
+ },
77
+
78
+ # ORA (indirect indexed)
79
+ 0x11 => lambda {
80
+ @a |= @memory.get(indirect_indexed)
81
+ set_nz_flags(@a)
82
+ },
83
+
84
+ # ORA (zero page, X)
85
+ 0x15 => lambda {
86
+ @a |= @memory.get(zero_page(@x))
87
+ set_nz_flags(@a)
88
+ },
89
+
90
+ # ASL (zero page, X)
91
+ 0x16 => lambda {
92
+ address = zero_page(@x)
93
+ @memory.set(address, asl(@memory.get(address)))
94
+ },
95
+
96
+ # CLC
97
+ 0x18 => lambda {
98
+ @status.carry = false
99
+ },
100
+
101
+ # ORA (absolute, Y)
102
+ 0x19 => lambda {
103
+ @a |= @memory.get(absolute(@y))
104
+ set_nz_flags(@a)
105
+ },
106
+
107
+ # ORA (absolute, X)
108
+ 0x1d => lambda {
109
+ @a |= @memory.get(absolute(@x))
110
+ set_nz_flags(@a)
111
+ },
112
+
113
+ # ASL (absolute, X)
114
+ 0x1e => lambda {
115
+ address = absolute(@x)
116
+ @memory.set(address, asl(@memory.get(address)))
117
+ },
118
+
119
+ # JSR
120
+ 0x20 => lambda {
121
+ jump_to = absolute
122
+ return_to = @pc - 1
123
+ stack_push((return_to >> 8) & 0xff)
124
+ stack_push(return_to & 0xff)
125
+ @pc = jump_to
126
+ },
127
+
128
+ # AND (indexed indirect)
129
+ 0x21 => lambda {
130
+ @a &= @memory.get(indexed_indirect)
131
+ set_nz_flags(@a)
132
+ },
133
+
134
+ # BIT (zero page)
135
+ 0x24 => lambda {
136
+ bit(@memory.get(zero_page))
137
+ },
138
+
139
+ # AND (zero page)
140
+ 0x25 => lambda {
141
+ @a &= @memory.get(zero_page)
142
+ set_nz_flags(@a)
143
+ },
144
+
145
+ # ROL (zero page)
146
+ 0x26 => lambda {
147
+ address = zero_page
148
+ @memory.set(address, rol(@memory.get(address)))
149
+ },
150
+
151
+ # PLP
152
+ 0x28 => lambda {
153
+ @status.decode(stack_pop)
154
+ },
155
+
156
+ # AND (immediate)
157
+ 0x29 => lambda {
158
+ @a &= next_byte
159
+ set_nz_flags(@a)
160
+ },
161
+
162
+ # ROL (accumulator)
163
+ 0x2a => lambda {
164
+ @a = rol(@a) & 0xff
165
+ },
166
+
167
+ # BIT (absolute)
168
+ 0x2c => lambda {
169
+ bit(@memory.get(absolute))
170
+ },
171
+
172
+ # AND (absolute)
173
+ 0x2d => lambda {
174
+ @a &= @memory.get(absolute)
175
+ set_nz_flags(@a)
176
+ },
177
+
178
+ # ROL (absolute)
179
+ 0x2e => lambda {
180
+ address = absolute
181
+ @memory.set(address, rol(@memory.get(address)))
182
+ },
183
+
184
+ # BMI
185
+ 0x30 => lambda {
186
+ offset = next_byte
187
+ @pc = branch(offset) if @status.negative?
188
+ },
189
+
190
+ # AND (indirect indexed)
191
+ 0x31 => lambda {
192
+ @a &= @memory.get(indirect_indexed)
193
+ set_nz_flags(@a)
194
+ },
195
+
196
+ # AND (zero page, X)
197
+ 0x35 => lambda {
198
+ @a &= @memory.get(zero_page(@x))
199
+ set_nz_flags(@a)
200
+ },
201
+
202
+ # ROL (zero page, X)
203
+ 0x36 => lambda {
204
+ address = zero_page(@x)
205
+ @memory.set(address, rol(@memory.get(address)))
206
+ },
207
+
208
+ # SEC
209
+ 0x38 => lambda {
210
+ @status.carry = true
211
+ },
212
+
213
+ # AND (absolute, Y)
214
+ 0x39 => lambda {
215
+ @a &= @memory.get(absolute(@y))
216
+ set_nz_flags(@a)
217
+ },
218
+
219
+ # AND (absolute, X)
220
+ 0x3d => lambda {
221
+ @a &= @memory.get(absolute(@x))
222
+ set_nz_flags(@a)
223
+ },
224
+
225
+ # ROL (absolute, X)
226
+ 0x3e => lambda {
227
+ address = absolute(@x)
228
+ @memory.set(address, rol(@memory.get(address)))
229
+ },
230
+
231
+ # RTI
232
+ 0x40 => lambda {
233
+ @status.decode(stack_pop)
234
+ @pc = (stack_pop | (stack_pop << 8))
235
+ },
236
+
237
+ # EOR (indexed indirect)
238
+ 0x41 => lambda {
239
+ @a ^= @memory.get(indexed_indirect)
240
+ set_nz_flags(@a)
241
+ },
242
+
243
+ # EOR (zero page)
244
+ 0x45 => lambda {
245
+ @a ^= @memory.get(zero_page)
246
+ set_nz_flags(@a)
247
+ },
248
+
249
+ # LSR (zero page)
250
+ 0x46 => lambda {
251
+ address = zero_page
252
+ @memory.set(address, lsr(@memory.get(address)))
253
+ },
254
+
255
+ # PHA
256
+ 0x48 => lambda {
257
+ stack_push(@a)
258
+ },
259
+
260
+ # EOR (immediate)
261
+ 0x49 => lambda {
262
+ @a ^= next_byte
263
+ set_nz_flags(@a)
264
+ },
265
+
266
+ # LSR (accumulator)
267
+ 0x4a => lambda {
268
+ @a = lsr(@a)
269
+ },
270
+
271
+ # JMP (absolute)
272
+ 0x4c => lambda {
273
+ @pc = absolute
274
+ },
275
+
276
+ # EOR (absolute)
277
+ 0x4d => lambda {
278
+ @a ^= @memory.get(absolute)
279
+ set_nz_flags(@a)
280
+ },
281
+
282
+ # LSR (absolute)
283
+ 0x4e => lambda {
284
+ address = absolute
285
+ @memory.set(address, lsr(@memory.get(address)))
286
+ },
287
+
288
+ # BVC
289
+ 0x50 => lambda {
290
+ offset = next_byte
291
+ @pc = branch(offset) unless @status.overflow?
292
+ },
293
+
294
+ # EOR (indirect indexed)
295
+ 0x51 => lambda {
296
+ @a ^= @memory.get(indirect_indexed)
297
+ set_nz_flags(@a)
298
+ },
299
+
300
+ # EOR (zero page, X)
301
+ 0x55 => lambda {
302
+ @a ^= @memory.get(zero_page(@x))
303
+ set_nz_flags(@a)
304
+ },
305
+
306
+ # LSR (zero page, X)
307
+ 0x56 => lambda {
308
+ address = zero_page(@x)
309
+ @memory.set(address, lsr(@memory.get(address)))
310
+ },
311
+
312
+ # CLI
313
+ 0x58 => lambda {
314
+ @status.interupt_disable = false
315
+ },
316
+
317
+ # EOR (absolute, Y)
318
+ 0x59 => lambda {
319
+ @a ^= @memory.get(absolute(@y))
320
+ set_nz_flags(@a)
321
+ },
322
+
323
+ # EOR (absolute, X)
324
+ 0x5d => lambda {
325
+ @a ^= @memory.get(absolute(@x))
326
+ set_nz_flags(@a)
327
+ },
328
+
329
+ # LSR (absolute, X)
330
+ 0x5e => lambda {
331
+ address = absolute(@x)
332
+ @memory.set(address, lsr(@memory.get(address)))
333
+ },
334
+
335
+ # RTS
336
+ 0x60 => lambda {
337
+ @pc = (stack_pop | (stack_pop << 8)) + 1
338
+ },
339
+
340
+ # ADC (indexed indirect)
341
+ 0x61 => lambda {
342
+ adc(@memory.get(indexed_indirect))
343
+ },
344
+
345
+ # ADC (zero page)
346
+ 0x65 => lambda {
347
+ adc(@memory.get(zero_page))
348
+ },
349
+
350
+ # ROR (zero page)
351
+ 0x66 => lambda {
352
+ address = zero_page
353
+ @memory.set(address, ror(@memory.get(address)))
354
+ },
355
+
356
+ # PLA
357
+ 0x68 => lambda {
358
+ @a = stack_pop
359
+ set_nz_flags(@a)
360
+ },
361
+
362
+ # ADC (immediate)
363
+ 0x69 => lambda {
364
+ adc(next_byte)
365
+ },
366
+
367
+ # ROR (accumulator)
368
+ 0x6a => lambda {
369
+ @a = ror(@a)
370
+ },
371
+
372
+ # JMP (indirect)
373
+ 0x6c => lambda {
374
+ @pc = indirect
375
+ },
376
+
377
+ # ADC (absolute)
378
+ 0x6d => lambda {
379
+ adc(@memory.get(absolute))
380
+ },
381
+
382
+ # ROR (absolute)
383
+ 0x6e => lambda {
384
+ address = absolute
385
+ @memory.set(address, ror(@memory.get(address)))
386
+ },
387
+
388
+ # BVS
389
+ 0x70 => lambda {
390
+ offset = next_byte
391
+ @pc = branch(offset) if @status.overflow?
392
+ },
393
+
394
+ # ADC (indirect indexed)
395
+ 0x71 => lambda {
396
+ adc(@memory.get(indirect_indexed))
397
+ },
398
+
399
+ # ADC (zero page, X)
400
+ 0x75 => lambda {
401
+ adc(@memory.get(zero_page(@x)))
402
+ },
403
+
404
+ # ROR (zero page, X)
405
+ 0x76 => lambda {
406
+ address = zero_page(@x)
407
+ @memory.set(address, ror(@memory.get(address)))
408
+ },
409
+
410
+ # SEI
411
+ 0x78 => lambda {
412
+ @status.interupt_disable = true
413
+ },
414
+
415
+ # ADC (absolute, Y)
416
+ 0x79 => lambda {
417
+ adc(@memory.get(absolute(@y)))
418
+ },
419
+
420
+ # ADC (absolute, X)
421
+ 0x7d => lambda {
422
+ adc(@memory.get(absolute(@x)))
423
+ },
424
+
425
+ # ROR (absolute, X)
426
+ 0x7e => lambda {
427
+ address = absolute(@x)
428
+ @memory.set(address, ror(@memory.get(address)))
429
+ },
430
+
431
+ # STA (indexed indirect)
432
+ 0x81 => lambda {
433
+ @memory.set(indexed_indirect, @a)
434
+ },
435
+
436
+ # STY (zero page)
437
+ 0x84 => lambda {
438
+ @memory.set(zero_page, @y)
439
+ },
440
+
441
+ # STA (zero page)
442
+ 0x85 => lambda {
443
+ @memory.set(zero_page, @a)
444
+ },
445
+
446
+ # STX (zero page)
447
+ 0x86 => lambda {
448
+ @memory.set(zero_page, @x)
449
+ },
450
+
451
+ # DEY
452
+ 0x88 => lambda {
453
+ @y = dec(@y) & 0xff
454
+ },
455
+
456
+ # TXA
457
+ 0x8a => lambda {
458
+ @a = @x & 0xff
459
+ set_nz_flags(@a)
460
+ },
461
+
462
+ # STY (absolute)
463
+ 0x8c => lambda {
464
+ @memory.set(absolute, @y)
465
+ },
466
+
467
+ # STA (absolute)
468
+ 0x8d => lambda {
469
+ @memory.set(absolute, @a)
470
+ },
471
+
472
+ # STX (absolute)
473
+ 0x8e => lambda {
474
+ @memory.set(absolute, @x)
475
+ },
476
+
477
+ # BCC
478
+ 0x90 => lambda {
479
+ offset = next_byte
480
+ @pc = branch(offset) unless @status.carry?
481
+ },
482
+
483
+ # STA (indirect indexed)
484
+ 0x91 => lambda {
485
+ @memory.set(indirect_indexed, @a)
486
+ },
487
+
488
+ # STY (zero page, X)
489
+ 0x94 => lambda {
490
+ @memory.set(zero_page(@x), @y)
491
+ },
492
+
493
+ # STA (zero page, X)
494
+ 0x95 => lambda {
495
+ @memory.set(zero_page(@x), @a)
496
+ },
497
+
498
+ # STX (zero page, Y)
499
+ 0x96 => lambda {
500
+ @memory.set(zero_page(@y), @x)
501
+ },
502
+
503
+ # TYA
504
+ 0x98 => lambda {
505
+ @a = @y & 0xff
506
+ set_nz_flags(@a)
507
+ },
508
+
509
+ # STA (absolute, Y)
510
+ 0x99 => lambda {
511
+ @memory.set(absolute(@y), @a)
512
+ },
513
+
514
+ # TXS
515
+ 0x9a => lambda {
516
+ @sp = @x & 0xff
517
+ },
518
+
519
+ # STA (absolute, X)
520
+ 0x9d => lambda {
521
+ @memory.set(absolute(@x), @a)
522
+ },
523
+
524
+ # LDY (immediate)
525
+ 0xa0 => lambda {
526
+ @y = next_byte
527
+ set_nz_flags(@y)
528
+ },
529
+
530
+ # LDA (indexed indirect)
531
+ 0xa1 => lambda {
532
+ @a = @memory.get(indexed_indirect)
533
+ set_nz_flags(@a)
534
+ },
535
+
536
+ # LDX (immediate)
537
+ 0xa2 => lambda {
538
+ @x = next_byte
539
+ set_nz_flags(@x)
540
+ },
541
+
542
+ # LDY (zero page)
543
+ 0xa4 => lambda {
544
+ @y = @memory.get(zero_page)
545
+ set_nz_flags(@y)
546
+ },
547
+
548
+ # LDA (zero page)
549
+ 0xa5 => lambda {
550
+ @a = @memory.get(zero_page)
551
+ set_nz_flags(@a)
552
+ },
553
+
554
+ # LDX (zero page)
555
+ 0xa6 => lambda {
556
+ @x = @memory.get(zero_page)
557
+ set_nz_flags(@x)
558
+ },
559
+
560
+ # TAY
561
+ 0xa8 => lambda {
562
+ @y = @a & 0xff
563
+ set_nz_flags(@y)
564
+ },
565
+
566
+ # LDA (immediate)
567
+ 0xa9 => lambda {
568
+ @a = next_byte
569
+ set_nz_flags(@a)
570
+ },
571
+
572
+ # TAX
573
+ 0xaa => lambda {
574
+ @x = @a & 0xff
575
+ set_nz_flags(@x)
576
+ },
577
+
578
+ # LDY (absolute)
579
+ 0xac => lambda {
580
+ @y = @memory.get(absolute)
581
+ set_nz_flags(@y)
582
+ },
583
+
584
+ # LDA (absolute)
585
+ 0xad => lambda {
586
+ @a = @memory.get(absolute)
587
+ set_nz_flags(@a)
588
+ },
589
+
590
+ # LDX (absolute)
591
+ 0xae => lambda {
592
+ @x = @memory.get(absolute)
593
+ set_nz_flags(@x)
594
+ },
595
+
596
+ # BCS
597
+ 0xb0 => lambda {
598
+ offset = next_byte
599
+ @pc = branch(offset) if @status.carry?
600
+ },
601
+
602
+ # LDA (indirect indexed)
603
+ 0xb1 => lambda {
604
+ @a = @memory.get(indirect_indexed)
605
+ set_nz_flags(@a)
606
+ },
607
+
608
+ # LDY (zero page, X)
609
+ 0xb4 => lambda {
610
+ @y = @memory.get(zero_page(@x))
611
+ set_nz_flags(@y)
612
+ },
613
+
614
+ # LDA (zero page, X)
615
+ 0xb5 => lambda {
616
+ @a = @memory.get(zero_page(@x))
617
+ set_nz_flags(@a)
618
+ },
619
+
620
+ # LDX (zero page, Y)
621
+ 0xb6 => lambda {
622
+ @x = @memory.get(zero_page(@y))
623
+ set_nz_flags(@x)
624
+ },
625
+
626
+ # CLV
627
+ 0xb8 => lambda {
628
+ @status.overflow = false
629
+ },
630
+
631
+ # LDA (absolute, Y)
632
+ 0xb9 => lambda {
633
+ @a = @memory.get(absolute(@y))
634
+ set_nz_flags(@a)
635
+ },
636
+
637
+ # TSX
638
+ 0xba => lambda {
639
+ @x = @sp & 0xff
640
+ set_nz_flags(@x)
641
+ },
642
+
643
+ # LDY (absolute, X)
644
+ 0xbc => lambda {
645
+ @y = @memory.get(absolute(@x))
646
+ set_nz_flags(@y)
647
+ },
648
+
649
+ # LDA (absolute, X)
650
+ 0xbd => lambda {
651
+ @a = @memory.get(absolute(@x))
652
+ set_nz_flags(@a)
653
+ },
654
+
655
+ # LDX (absolute, Y)
656
+ 0xbe => lambda {
657
+ @x = @memory.get(absolute(@y))
658
+ set_nz_flags(@x)
659
+ },
660
+
661
+ # CPY (immediate)
662
+ 0xc0 => lambda {
663
+ compare(@y, next_byte)
664
+ },
665
+
666
+ # CMP (indexed indirect)
667
+ 0xc1 => lambda {
668
+ compare(@a, @memory.get(indexed_indirect))
669
+ },
670
+
671
+ # CPY (zero page)
672
+ 0xc4 => lambda {
673
+ compare(@y, @memory.get(zero_page))
674
+ },
675
+
676
+ # CMP (zero page)
677
+ 0xc5 => lambda {
678
+ compare(@a, @memory.get(zero_page))
679
+ },
680
+
681
+ # DEC (zero page)
682
+ 0xc6 => lambda {
683
+ address = zero_page
684
+ @memory.set(address, dec(@memory.get(address)))
685
+ },
686
+
687
+ # INY
688
+ 0xc8 => lambda {
689
+ @y = inc(@y) & 0xff
690
+ },
691
+
692
+ # CMP (immediate)
693
+ 0xc9 => lambda {
694
+ compare(@a, next_byte)
695
+ },
696
+
697
+ # DEX
698
+ 0xca => lambda {
699
+ @x = dec(@x) & 0xff
700
+ },
701
+
702
+ # CPY (absolute)
703
+ 0xcc => lambda {
704
+ compare(@y, @memory.get(absolute))
705
+ },
706
+
707
+ # CMP (absolute)
708
+ 0xcd => lambda {
709
+ compare(@a, @memory.get(absolute))
710
+ },
711
+
712
+ # DEC (absolute)
713
+ 0xce => lambda {
714
+ address = absolute
715
+ @memory.set(address, dec(@memory.get(address)))
716
+ },
717
+
718
+ # BNE
719
+ 0xd0 => lambda {
720
+ offset = next_byte
721
+ @pc = branch(offset) unless @status.zero?
722
+ },
723
+
724
+ # CMP (indirect indexed)
725
+ 0xd1 => lambda {
726
+ compare(@a, @memory.get(indirect_indexed))
727
+ },
728
+
729
+ # CMP (zero page, X)
730
+ 0xd5 => lambda {
731
+ compare(@a, @memory.get(zero_page(@x)))
732
+ },
733
+
734
+ # DEC (zero page, X)
735
+ 0xd6 => lambda {
736
+ address = zero_page(@x)
737
+ @memory.set(address, dec(@memory.get(address)))
738
+ },
739
+
740
+ # CLD
741
+ 0xd8 => lambda {
742
+ @status.decimal_mode = false
743
+ },
744
+
745
+ # CMP (absolute, Y)
746
+ 0xd9 => lambda {
747
+ compare(@a, @memory.get(absolute(@y)))
748
+ },
749
+
750
+ # CMP (absolute, X)
751
+ 0xdd => lambda {
752
+ compare(@a, @memory.get(absolute(@x)))
753
+ },
754
+
755
+ # DEC (absolute, X)
756
+ 0xde => lambda {
757
+ address = absolute(@x)
758
+ @memory.set(address, dec(@memory.get(address)))
759
+ },
760
+
761
+ # CPX (immediate)
762
+ 0xe0 => lambda {
763
+ compare(@x, next_byte)
764
+ },
765
+
766
+ # SBC (indexed indirect)
767
+ 0xe1 => lambda {
768
+ sbc(@memory.get(indexed_indirect))
769
+ },
770
+
771
+ # CPX (zero page)
772
+ 0xe4 => lambda {
773
+ compare(@x, @memory.get(zero_page))
774
+ },
775
+
776
+ # SBC (zero page)
777
+ 0xe5 => lambda {
778
+ sbc(@memory.get(zero_page))
779
+ },
780
+
781
+ # INC (zero page)
782
+ 0xe6 => lambda {
783
+ address = zero_page
784
+ @memory.set(address, inc(@memory.get(address)))
785
+ },
786
+
787
+ # INX
788
+ 0xe8 => lambda {
789
+ @x = inc(@x) & 0xff
790
+ },
791
+
792
+ # SBC (immediate)
793
+ 0xe9 => lambda {
794
+ sbc(next_byte)
795
+ },
796
+
797
+ # NOP
798
+ 0xea => lambda {}, # rubocop:disable Style/Lambda
799
+
800
+ # CPX (absolute)
801
+ 0xec => lambda {
802
+ compare(@x, @memory.get(absolute))
803
+ },
804
+
805
+ # SBC (absolute)
806
+ 0xed => lambda {
807
+ sbc(@memory.get(absolute))
808
+ },
809
+
810
+ # INC (absolute)
811
+ 0xee => lambda {
812
+ address = absolute
813
+ @memory.set(address, inc(@memory.get(address)))
814
+ },
815
+
816
+ # BEQ
817
+ 0xf0 => lambda {
818
+ offset = next_byte
819
+ @pc = branch(offset) if @status.zero?
820
+ },
821
+
822
+ # SBC (indirect indexed)
823
+ 0xf1 => lambda {
824
+ sbc(@memory.get(indirect_indexed))
825
+ },
826
+
827
+ # SBC (zero page, X)
828
+ 0xf5 => lambda {
829
+ sbc(@memory.get(zero_page(@x)))
830
+ },
831
+
832
+ # INC (zero page, X)
833
+ 0xf6 => lambda {
834
+ address = zero_page(@x)
835
+ @memory.set(address, inc(@memory.get(address)))
836
+ },
837
+
838
+ # SED
839
+ 0xf8 => lambda {
840
+ @status.decimal_mode = true
841
+ },
842
+
843
+ # SBC (absolute, Y)
844
+ 0xf9 => lambda {
845
+ sbc(@memory.get(absolute(@y)))
846
+ },
847
+
848
+ # SBC (absolute, X)
849
+ 0xfd => lambda {
850
+ sbc(@memory.get(absolute(@x)))
851
+ },
852
+
853
+ # INC (absolute, X)
854
+ 0xfe => lambda {
855
+ address = absolute(@x)
856
+ @memory.set(address, inc(@memory.get(address)))
857
+ }
858
+ }
859
+ end
860
+ end
861
+ end