rubyboy 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/rubyboy/cpu.rb CHANGED
@@ -1,96 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require_relative 'register'
3
+ require_relative 'registers'
4
+ require_relative 'operand'
5
5
 
6
6
  module Rubyboy
7
7
  class Cpu
8
- def initialize(bus)
9
- @a = Register.new(name: 'a', value: 0x01)
10
- @b = Register.new(name: 'b', value: 0x00)
11
- @c = Register.new(name: 'c', value: 0x13)
12
- @d = Register.new(name: 'd', value: 0x00)
13
- @e = Register.new(name: 'e', value: 0xd8)
14
- @h = Register.new(name: 'h', value: 0x01)
15
- @l = Register.new(name: 'l', value: 0x4d)
16
- @f = Register.new(name: 'f', value: 0xb0)
8
+ def initialize(bus, interrupt)
9
+ @bus = bus
10
+ @interrupt = interrupt
11
+ @registers = Registers.new
17
12
 
18
13
  @pc = 0x0100
19
14
  @sp = 0xfffe
20
15
  @ime = false
21
16
  @ime_delay = false
22
- @bus = bus
23
- @opcodes = File.open('lib/opcodes.json', 'r') { |file| JSON.parse(file.read) }
24
17
  @halted = false
25
-
26
- @cnt = 0
27
- end
28
-
29
- def af
30
- (@a.value << 8) + @f.value
31
- end
32
-
33
- def af=(value)
34
- value &= 0xffff
35
- @a.value = value >> 8
36
- @f.value = value & 0xf0
37
- end
38
-
39
- def bc
40
- (@b.value << 8) + @c.value
41
- end
42
-
43
- def bc=(value)
44
- value &= 0xffff
45
- @b.value = value >> 8
46
- @c.value = value & 0xff
47
- end
48
-
49
- def de
50
- (@d.value << 8) + @e.value
51
- end
52
-
53
- def de=(value)
54
- value &= 0xffff
55
- @d.value = value >> 8
56
- @e.value = value & 0xff
57
- end
58
-
59
- def hl
60
- (@h.value << 8) + @l.value
61
- end
62
-
63
- def hl=(value)
64
- value &= 0xffff
65
- @h.value = value >> 8
66
- @l.value = value & 0xff
67
18
  end
68
19
 
69
20
  def exec
70
21
  opcode = read_byte(@pc)
71
22
  # print_log(opcode)
72
23
 
73
- in_interrupt = false
24
+ @halted &= @interrupt.interrupts.zero?
74
25
 
75
- if @ime && @bus.interrupt.interrupts.positive?
76
- in_interrupt = true
77
- else
78
- increment_pc
79
- end
26
+ return 16 if @halted
80
27
 
81
- if in_interrupt
28
+ if @ime && @interrupt.interrupts.positive?
82
29
  pcs = [0x0040, 0x0048, 0x0050, 0x0058, 0x0060]
83
30
  5.times do |i|
84
- next if @bus.interrupt.interrupts[i].zero?
31
+ next if @interrupt.interrupts[i].zero?
85
32
 
86
- @bus.interrupt.if &= (~(1 << i)) & 0xff
33
+ @interrupt.reset_flag(i)
87
34
  @ime = false
88
35
  @sp -= 2
89
36
  @bus.write_word(@sp, @pc)
90
37
  @pc = pcs[i]
38
+
91
39
  break
92
40
  end
41
+
93
42
  return 20
43
+ else
44
+ increment_pc
94
45
  end
95
46
 
96
47
  if @ime_delay
@@ -98,1386 +49,517 @@ module Rubyboy
98
49
  @ime = true
99
50
  end
100
51
 
101
- cbprefixed = false
102
- branched = false
103
-
104
52
  case opcode
105
- when 0x00 # NOP
106
- when 0x01 # LD BC, nn
107
- self.bc = read_word_and_advance_pc
108
- when 0x02 # LD (BC), A
109
- write_byte(bc, @a.value)
110
- when 0x03 # INC BC
111
- self.bc = bc + 1
112
- when 0x04 # INC B
113
- @b.increment
114
- update_flags(
115
- z: @b.value.zero?,
116
- n: false,
117
- h: (@b.value & 0x0f).zero?
118
- )
119
- when 0x05 # DEC B
120
- @b.decrement
121
- update_flags(
122
- z: @b.value.zero?,
123
- n: true,
124
- h: (@b.value & 0x0f) == 0x0f
125
- )
126
- when 0x06 # LD B, d8
127
- @b.value = read_byte_and_advance_pc
128
- when 0x07 # RLCA
129
- @a.value = (@a.value << 1) | (@a.value >> 7)
130
- update_flags(
131
- z: false,
132
- n: false,
133
- h: false,
134
- c: @a.value[0] == 1
135
- )
136
- when 0x08 # LD (nn), SP
137
- word = read_word_and_advance_pc
138
- write_word(word, @sp)
139
- when 0x09 # ADD HL, BC
140
- hflag = (hl & 0x0fff) + (bc & 0x0fff) > 0x0fff
141
- cflag = hl + bc > 0xffff
142
- self.hl = hl + bc
143
- update_flags(
144
- n: false,
145
- h: hflag,
146
- c: cflag
147
- )
148
- when 0x0a # LD A, (BC)
149
- @a.value = read_byte(bc)
150
- when 0x0b # DEC BC
151
- self.bc = bc - 1
152
- when 0x0c # INC C
153
- @c.increment
154
- update_flags(
155
- z: @c.value.zero?,
156
- n: false,
157
- h: (@c.value & 0x0f).zero?
158
- )
159
- when 0x0d # DEC C
160
- @c.decrement
161
- update_flags(
162
- z: @c.value.zero?,
163
- n: true,
164
- h: (@c.value & 0x0f) == 0x0f
165
- )
166
- when 0x0e # LD C, d8
167
- @c.value = read_byte_and_advance_pc
168
- when 0x0f # RRCA
169
- @a.value = (@a.value >> 1) | (@a.value << 7)
170
- update_flags(
171
- z: false,
172
- n: false,
173
- h: false,
174
- c: @a.value[7] == 1
175
- )
176
- when 0x10 # STOP
177
- when 0x11 # LD DE, nn
178
- self.de = read_word_and_advance_pc
179
- when 0x12 # LD (DE), A
180
- write_byte(de, @a.value)
181
- when 0x13 # INC DE
182
- self.de = de + 1
183
- when 0x14 # INC D
184
- @d.increment
185
- update_flags(
186
- z: @d.value.zero?,
187
- n: false,
188
- h: (@d.value & 0x0f).zero?
189
- )
190
- when 0x15 # DEC D
191
- @d.decrement
192
- update_flags(
193
- z: @d.value.zero?,
194
- n: true,
195
- h: (@d.value & 0x0f) == 0x0f
196
- )
197
- when 0x16 # LD D, d8
198
- @d.value = read_byte_and_advance_pc
199
- when 0x17 # RLA
200
- cflag = @a.value[7] == 1
201
- @a.value = (@a.value << 1) | bool_to_integer(flags[:c])
202
- update_flags(
203
- z: false,
204
- n: false,
205
- h: false,
206
- c: cflag
207
- )
208
- when 0x18 # JR r8
209
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
210
- @pc += byte
211
- when 0x19 # ADD HL, DE
212
- hflag = (hl & 0x0fff) + (de & 0x0fff) > 0x0fff
213
- cflag = hl + de > 0xffff
214
- self.hl = hl + de
215
- update_flags(
216
- n: false,
217
- h: hflag,
218
- c: cflag
219
- )
220
- when 0x1a # LD A, (DE)
221
- @a.value = read_byte(de)
222
- when 0x1b # DEC DE
223
- self.de = de - 1
224
- when 0x1c # INC E
225
- @e.increment
226
- update_flags(
227
- z: @e.value.zero?,
228
- n: false,
229
- h: (@e.value & 0x0f).zero?
230
- )
231
- when 0x1d # DEC E
232
- @e.decrement
233
- update_flags(
234
- z: @e.value.zero?,
235
- n: true,
236
- h: (@e.value & 0x0f) == 0x0f
237
- )
238
- when 0x1e # LD E, d8
239
- @e.value = read_byte_and_advance_pc
240
- when 0x1f # RRA
241
- cflag = @a.value[0] == 1
242
- @a.value = (@a.value >> 1) | (bool_to_integer(flags[:c]) << 7)
243
- update_flags(
244
- z: false,
245
- n: false,
246
- h: false,
247
- c: cflag
248
- )
249
- when 0x20 # JR NZ, r8
250
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
251
- unless flags[:z]
252
- @pc += byte
253
- branched = true
254
- end
255
- when 0x21 # LD HL, nn
256
- self.hl = read_word_and_advance_pc
257
- when 0x22 # LD (HL+), A
258
- write_byte(hl, @a.value)
259
- self.hl = hl + 1
260
- when 0x23 # INC HL
261
- self.hl = hl + 1
262
- when 0x24 # INC H
263
- @h.increment
264
- update_flags(
265
- z: @h.value.zero?,
266
- n: false,
267
- h: (@h.value & 0x0f).zero?
268
- )
269
- when 0x25 # DEC H
270
- @h.decrement
271
- update_flags(
272
- z: @h.value.zero?,
273
- n: true,
274
- h: (@h.value & 0x0f) == 0x0f
275
- )
276
- when 0x26 # LD H, d8
277
- @h.value = read_byte_and_advance_pc
278
- when 0x27 # DAA
279
- if flags[:n]
280
- @a.value -= 0x06 if flags[:h]
281
- @a.value -= 0x60 if flags[:c]
282
- else
283
- if flags[:c] || @a.value > 0x99
284
- @a.value += 0x60
285
- update_flags(c: true)
286
- end
287
- @a.value += 0x06 if flags[:h] || (@a.value & 0x0f) > 0x09
288
- end
289
- update_flags(
290
- z: @a.value.zero?,
291
- h: false
292
- )
293
- when 0x28 # JR Z, r8
294
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
295
- if flags[:z]
296
- @pc += byte
297
- branched = true
298
- end
299
- when 0x29 # ADD HL, HL
300
- hflag = (hl & 0x0fff) + (hl & 0x0fff) > 0x0fff
301
- cflag = hl + hl > 0xffff
302
- self.hl = hl + hl
303
- update_flags(
304
- n: false,
305
- h: hflag,
306
- c: cflag
307
- )
308
- when 0x2a # LD A, (HL+)
309
- @a.value = read_byte(hl)
310
- self.hl = hl + 1
311
- when 0x2b # DEC HL
312
- self.hl = hl - 1
313
- when 0x2c # INC L
314
- @l.increment
315
- update_flags(
316
- z: @l.value.zero?,
317
- n: false,
318
- h: (@l.value & 0x0f).zero?
319
- )
320
- when 0x2d # DEC L
321
- @l.decrement
322
- update_flags(
323
- z: @l.value.zero?,
324
- n: true,
325
- h: (@l.value & 0x0f) == 0x0f
326
- )
327
- when 0x2e # LD L, d8
328
- @l.value = read_byte_and_advance_pc
329
- when 0x2f # CPL
330
- @a.value = ~@a.value
331
- update_flags(
332
- n: true,
333
- h: true
334
- )
335
- when 0x30 # JR NC, r8
336
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
337
- unless flags[:c]
338
- @pc += byte
339
- branched = true
340
- end
341
- when 0x31 # LD SP, nn
342
- @sp = read_word_and_advance_pc
343
- when 0x32 # LD (HL-), A
344
- write_byte(hl, @a.value)
345
- self.hl = hl - 1
346
- when 0x33 # INC SP
347
- @sp = (@sp + 1) & 0xffff
348
- when 0x34 # INC (HL)
349
- byte = read_byte(hl)
350
- byte = (byte + 1) & 0xff
351
- write_byte(hl, byte)
352
- update_flags(
353
- z: byte.zero?,
354
- n: false,
355
- h: (byte & 0x0f).zero?
356
- )
357
- when 0x35 # DEC (HL)
358
- byte = read_byte(hl)
359
- byte = (byte - 1) & 0xff
360
- write_byte(hl, byte)
361
- update_flags(
362
- z: byte.zero?,
363
- n: true,
364
- h: (byte & 0x0f) == 0x0f
365
- )
366
- when 0x36 # LD (HL), d8
367
- byte = read_byte_and_advance_pc
368
- write_byte(hl, byte)
369
- when 0x37 # SCF
370
- update_flags(
371
- n: false,
372
- h: false,
373
- c: true
374
- )
375
- when 0x38 # JR C, r8
376
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
377
- if flags[:c]
378
- @pc += byte
379
- branched = true
380
- end
381
- when 0x39 # ADD HL, SP
382
- hflag = (hl & 0x0fff) + (@sp & 0x0fff) > 0x0fff
383
- cflag = hl + @sp > 0xffff
384
- self.hl = hl + @sp
385
- update_flags(
386
- n: false,
387
- h: hflag,
388
- c: cflag
389
- )
390
- when 0x3a # LD A, (HL-)
391
- @a.value = read_byte(hl)
392
- self.hl = hl - 1
393
- when 0x3b # DEC SP
394
- @sp = (@sp - 1) & 0xffff
395
- when 0x3c # INC A
396
- @a.increment
397
- update_flags(
398
- z: @a.value.zero?,
399
- n: false,
400
- h: (@a.value & 0x0f).zero?
401
- )
402
- when 0x3d # DEC A
403
- @a.decrement
404
- update_flags(
405
- z: @a.value.zero?,
406
- n: true,
407
- h: (@a.value & 0x0f) == 0x0f
408
- )
409
- when 0x3e # LD A, d8
410
- @a.value = read_byte_and_advance_pc
411
- when 0x3f # CCF
412
- update_flags(
413
- n: false,
414
- h: false,
415
- c: !flags[:c]
416
- )
417
- when 0x40 # LD B, B
418
- @b.value = @b.value
419
- when 0x41 # LD B, C
420
- @b.value = @c.value
421
- when 0x42 # LD B, D
422
- @b.value = @d.value
423
- when 0x43 # LD B, E
424
- @b.value = @e.value
425
- when 0x44 # LD B, H
426
- @b.value = @h.value
427
- when 0x45 # LD B, L
428
- @b.value = @l.value
429
- when 0x46 # LD B, (HL)
430
- @b.value = read_byte(hl)
431
- when 0x47 # LD B, A
432
- @b.value = @a.value
433
- when 0x48 # LD C, B
434
- @c.value = @b.value
435
- when 0x49 # LD C, C
436
- @c.value = @c.value
437
- when 0x4a # LD C, D
438
- @c.value = @d.value
439
- when 0x4b # LD C, E
440
- @c.value = @e.value
441
- when 0x4c # LD C, H
442
- @c.value = @h.value
443
- when 0x4d # LD C, L
444
- @c.value = @l.value
445
- when 0x4e # LD C, (HL)
446
- @c.value = read_byte(hl)
447
- when 0x4f # LD C, A
448
- @c.value = @a.value
449
- when 0x50 # LD D, B
450
- @d.value = @b.value
451
- when 0x51 # LD D, C
452
- @d.value = @c.value
453
- when 0x52 # LD D, D
454
- @d.value = @d.value
455
- when 0x53 # LD D, E
456
- @d.value = @e.value
457
- when 0x54 # LD D, H
458
- @d.value = @h.value
459
- when 0x55 # LD D, L
460
- @d.value = @l.value
461
- when 0x56 # LD D, (HL)
462
- @d.value = read_byte(hl)
463
- when 0x57 # LD D, A
464
- @d.value = @a.value
465
- when 0x58 # LD E, B
466
- @e.value = @b.value
467
- when 0x59 # LD E, C
468
- @e.value = @c.value
469
- when 0x5a # LD E, D
470
- @e.value = @d.value
471
- when 0x5b # LD E, E
472
- @e.value = @e.value
473
- when 0x5c # LD E, H
474
- @e.value = @h.value
475
- when 0x5d # LD E, L
476
- @e.value = @l.value
477
- when 0x5e # LD E, (HL)
478
- @e.value = read_byte(hl)
479
- when 0x5f # LD E, A
480
- @e.value = @a.value
481
- when 0x60 # LD H, B
482
- @h.value = @b.value
483
- when 0x61 # LD H, C
484
- @h.value = @c.value
485
- when 0x62 # LD H, D
486
- @h.value = @d.value
487
- when 0x63 # LD H, E
488
- @h.value = @e.value
489
- when 0x64 # LD H, H
490
- @h.value = @h.value
491
- when 0x65 # LD H, L
492
- @h.value = @l.value
493
- when 0x66 # LD H, (HL)
494
- @h.value = read_byte(hl)
495
- when 0x67 # LD H, A
496
- @h.value = @a.value
497
- when 0x68 # LD L, B
498
- @l.value = @b.value
499
- when 0x69 # LD L, C
500
- @l.value = @c.value
501
- when 0x6a # LD L, D
502
- @l.value = @d.value
503
- when 0x6b # LD L, E
504
- @l.value = @e.value
505
- when 0x6c # LD L, H
506
- @l.value = @h.value
507
- when 0x6d # LD L, L
508
- @l.value = @l.value
509
- when 0x6e # LD L, (HL)
510
- @l.value = read_byte(hl)
511
- when 0x6f # LD L, A
512
- @l.value = @a.value
513
- when 0x70 # LD (HL), B
514
- write_byte(hl, @b.value)
515
- when 0x71 # LD (HL), C
516
- write_byte(hl, @c.value)
517
- when 0x72 # LD (HL), D
518
- write_byte(hl, @d.value)
519
- when 0x73 # LD (HL), E
520
- write_byte(hl, @e.value)
521
- when 0x74 # LD (HL), H
522
- write_byte(hl, @h.value)
523
- when 0x75 # LD (HL), L
524
- write_byte(hl, @l.value)
525
- when 0x76 # HALT
526
- @pc -= 1 unless @bus.interrupt.interrupts.positive?
527
- when 0x77 # LD (HL), A
528
- write_byte(hl, @a.value)
529
- when 0x78 # LD A, B
530
- @a.value = @b.value
531
- when 0x79 # LD A, C
532
- @a.value = @c.value
533
- when 0x7a # LD A, D
534
- @a.value = @d.value
535
- when 0x7b # LD A, E
536
- @a.value = @e.value
537
- when 0x7c # LD A, H
538
- @a.value = @h.value
539
- when 0x7d # LD A, L
540
- @a.value = @l.value
541
- when 0x7e # LD A, (HL)
542
- @a.value = read_byte(hl)
543
- when 0x7f # LD A, A
544
- @a.value = @a.value
545
- when 0x80 # ADD A, B
546
- add8(@a, @b)
547
- when 0x81 # ADD A, C
548
- add8(@a, @c)
549
- when 0x82 # ADD A, D
550
- add8(@a, @d)
551
- when 0x83 # ADD A, E
552
- add8(@a, @e)
553
- when 0x84 # ADD A, H
554
- add8(@a, @h)
555
- when 0x85 # ADD A, L
556
- add8(@a, @l)
557
- when 0x86 # ADD A, (HL)
558
- add8(@a, Register.new(name: 'HL', value: read_byte(hl)))
559
- when 0x87 # ADD A, A
560
- add8(@a, @a)
561
- when 0x88 # ADC A, B
562
- adc8(@a, @b)
563
- when 0x89 # ADC A, C
564
- adc8(@a, @c)
565
- when 0x8a # ADC A, D
566
- adc8(@a, @d)
567
- when 0x8b # ADC A, E
568
- adc8(@a, @e)
569
- when 0x8c # ADC A, H
570
- adc8(@a, @h)
571
- when 0x8d # ADC A, L
572
- adc8(@a, @l)
573
- when 0x8e # ADC A, (HL)
574
- adc8(@a, Register.new(name: 'HL', value: read_byte(hl)))
575
- when 0x8f # ADC A, A
576
- adc8(@a, @a)
577
- when 0x90 # SUB B
578
- sub8(@b)
579
- when 0x91 # SUB C
580
- sub8(@c)
581
- when 0x92 # SUB D
582
- sub8(@d)
583
- when 0x93 # SUB E
584
- sub8(@e)
585
- when 0x94 # SUB H
586
- sub8(@h)
587
- when 0x95 # SUB L
588
- sub8(@l)
589
- when 0x96 # SUB (HL)
590
- sub8(Register.new(name: 'HL', value: read_byte(hl)))
591
- when 0x97 # SUB A
592
- sub8(@a)
593
- when 0x98 # SBC A, B
594
- sbc8(@b)
595
- when 0x99 # SBC A, C
596
- sbc8(@c)
597
- when 0x9a # SBC A, D
598
- sbc8(@d)
599
- when 0x9b # SBC A, E
600
- sbc8(@e)
601
- when 0x9c # SBC A, H
602
- sbc8(@h)
603
- when 0x9d # SBC A, L
604
- sbc8(@l)
605
- when 0x9e # SBC A, (HL)
606
- sbc8(Register.new(name: 'HL', value: read_byte(hl)))
607
- when 0x9f # SBC A, A
608
- sbc8(@a)
609
- when 0xa0 # AND B
610
- and8(@b)
611
- when 0xa1 # AND C
612
- and8(@c)
613
- when 0xa2 # AND D
614
- and8(@d)
615
- when 0xa3 # AND E
616
- and8(@e)
617
- when 0xa4 # AND H
618
- and8(@h)
619
- when 0xa5 # AND L
620
- and8(@l)
621
- when 0xa6 # AND (HL)
622
- and8(Register.new(name: 'HL', value: read_byte(hl)))
623
- when 0xa7 # AND A
624
- and8(@a)
625
- when 0xa8 # XOR B
626
- xor8(@b)
627
- when 0xa9 # XOR C
628
- xor8(@c)
629
- when 0xaa # XOR D
630
- xor8(@d)
631
- when 0xab # XOR E
632
- xor8(@e)
633
- when 0xac # XOR H
634
- xor8(@h)
635
- when 0xad # XOR L
636
- xor8(@l)
637
- when 0xae # XOR (HL)
638
- xor8(Register.new(name: 'HL', value: read_byte(hl)))
639
- when 0xaf # XOR A
640
- xor8(@a)
641
- when 0xb0 # OR B
642
- or8(@b)
643
- when 0xb1 # OR C
644
- or8(@c)
645
- when 0xb2 # OR D
646
- or8(@d)
647
- when 0xb3 # OR E
648
- or8(@e)
649
- when 0xb4 # OR H
650
- or8(@h)
651
- when 0xb5 # OR L
652
- or8(@l)
653
- when 0xb6 # OR (HL)
654
- or8(Register.new(name: 'HL', value: read_byte(hl)))
655
- when 0xb7 # OR A
656
- or8(@a)
657
- when 0xb8 # CP B
658
- cp8(@b)
659
- when 0xb9 # CP C
660
- cp8(@c)
661
- when 0xba # CP D
662
- cp8(@d)
663
- when 0xbb # CP E
664
- cp8(@e)
665
- when 0xbc # CP H
666
- cp8(@h)
667
- when 0xbd # CP L
668
- cp8(@l)
669
- when 0xbe # CP (HL)
670
- cp8(Register.new(name: 'HL', value: read_byte(hl)))
671
- when 0xbf # CP A
672
- cp8(@a)
673
- when 0xc0 # RET NZ
674
- unless flags[:z]
675
- @pc = read_word(@sp)
676
- @sp += 2
677
- branched = true
678
- end
679
- when 0xc1 # POP BC
680
- self.bc = read_word(@sp)
681
- @sp += 2
682
- when 0xc2 # JP NZ, nn
683
- word = read_word_and_advance_pc
684
- unless flags[:z]
685
- @pc = word
686
- branched = true
687
- end
688
- when 0xc3 # JP nn
689
- @pc = read_word_and_advance_pc
690
- when 0xc4 # CALL NZ, nn
691
- word = read_word_and_advance_pc
692
- unless flags[:z]
693
- @sp -= 2
694
- write_word(@sp, @pc)
695
- @pc = word
696
- branched = true
697
- end
698
- when 0xc5 # PUSH BC
699
- @sp -= 2
700
- write_word(@sp, bc)
701
- when 0xc6 # ADD A, d8
702
- byte = read_byte_and_advance_pc
703
- add8(@a, Register.new(name: 'd8', value: byte))
704
- when 0xc7 # RST 00H
705
- @sp -= 2
706
- write_word(@sp, @pc)
707
- @pc = 0x00
708
- when 0xc8 # RET Z
709
- if flags[:z]
710
- @pc = read_word(@sp)
711
- @sp += 2
712
- branched = true
713
- end
714
- when 0xc9 # RET
715
- @pc = read_word(@sp)
716
- @sp += 2
717
- when 0xca # JP Z, nn
718
- word = read_word_and_advance_pc
719
- if flags[:z]
720
- @pc = word
721
- branched = true
722
- end
723
- when 0xcc # CALL Z, nn
724
- word = read_word_and_advance_pc
725
- if flags[:z]
726
- @sp -= 2
727
- write_word(@sp, @pc)
728
- @pc = word
729
- branched = true
730
- end
731
- when 0xcd # CALL nn
732
- word = read_word_and_advance_pc
733
- @sp -= 2
734
- write_word(@sp, @pc)
735
- @pc = word
736
- when 0xce # ADC A, d8
737
- byte = read_byte_and_advance_pc
738
- adc8(@a, Register.new(name: 'd8', value: byte))
739
- when 0xcf # RST 08H
740
- @sp -= 2
741
- write_word(@sp, @pc)
742
- @pc = 0x08
743
- when 0xd0 # RET NC
744
- unless flags[:c]
745
- @pc = read_word(@sp)
746
- @sp += 2
747
- branched = true
748
- end
749
- when 0xd1 # POP DE
750
- self.de = read_word(@sp)
751
- @sp += 2
752
- when 0xd2 # JP NC, nn
753
- word = read_word_and_advance_pc
754
- unless flags[:c]
755
- @pc = word
756
- branched = true
757
- end
758
- when 0xd4 # CALL NC, nn
759
- word = read_word_and_advance_pc
760
- unless flags[:c]
761
- @sp -= 2
762
- write_word(@sp, @pc)
763
- @pc = word
764
- branched = true
765
- end
766
- when 0xd5 # PUSH DE
767
- @sp -= 2
768
- write_word(@sp, de)
769
- when 0xd6 # SUB d8
770
- byte = read_byte_and_advance_pc
771
- sub8(Register.new(name: 'd8', value: byte))
772
- when 0xd7 # RST 10H
773
- @sp -= 2
774
- write_word(@sp, @pc)
775
- @pc = 0x10
776
- when 0xd8 # RET C
777
- if flags[:c]
778
- @pc = read_word(@sp)
779
- @sp += 2
780
- branched = true
781
- end
782
- when 0xd9 # RETI
783
- @pc = read_word(@sp)
784
- @sp += 2
785
- @ime = true
786
- when 0xda # JP C, nn
787
- word = read_word_and_advance_pc
788
- if flags[:c]
789
- @pc = word
790
- branched = true
791
- end
792
- when 0xdc # CALL C, nn
793
- word = read_word_and_advance_pc
794
- if flags[:c]
795
- @sp -= 2
796
- write_word(@sp, @pc)
797
- @pc = word
798
- branched = true
799
- end
800
- when 0xde # SBC A, d8
801
- byte = read_byte_and_advance_pc
802
- sbc8(Register.new(name: 'd8', value: byte))
803
- when 0xdf # RST 18H
804
- @sp -= 2
805
- write_word(@sp, @pc)
806
- @pc = 0x18
807
- when 0xe0 # LDH (a8), A
808
- byte = read_byte_and_advance_pc
809
- write_byte(0xff00 + byte, @a.value)
810
- when 0xe1 # POP HL
811
- self.hl = read_word(@sp)
812
- @sp += 2
813
- when 0xe2 # LD (C), A
814
- write_byte(0xff00 + @c.value, @a.value)
815
- when 0xe5 # PUSH HL
816
- @sp -= 2
817
- write_word(@sp, hl)
818
- when 0xe6 # AND d8
819
- byte = read_byte_and_advance_pc
820
- and8(Register.new(name: 'd8', value: byte))
821
- when 0xe7 # RST 20H
822
- @sp -= 2
823
- write_word(@sp, @pc)
824
- @pc = 0x20
825
- when 0xe8 # ADD SP, r8
826
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
827
-
828
- hflag = (@sp & 0x0f) + (byte & 0x0f) > 0x0f
829
- cflag = (@sp & 0xff) + (byte & 0xff) > 0xff
830
-
831
- @sp += byte
832
- @sp &= 0xffff
833
- update_flags(
834
- z: false,
835
- n: false,
836
- h: hflag,
837
- c: cflag
838
- )
839
- when 0xe9 # JP (HL)
840
- @pc = hl
841
- when 0xea # LD (nn), A
842
- word = read_word_and_advance_pc
843
- write_byte(word, @a.value)
844
- when 0xee # XOR d8
845
- byte = read_byte_and_advance_pc
846
- xor8(Register.new(name: 'd8', value: byte))
847
- when 0xef # RST 28H
848
- @sp -= 2
849
- write_word(@sp, @pc)
850
- @pc = 0x28
851
- when 0xf0 # LDH A, (a8)
852
- byte = read_byte_and_advance_pc
853
- @a.value = read_byte(0xff00 + byte)
854
- when 0xf1 # POP AF
855
- self.af = read_word(@sp)
856
- @sp += 2
857
- when 0xf2 # LD A, (C)
858
- @a.value = read_byte(0xff00 + @c.value)
859
- when 0xf3 # DI
860
- @ime_delay = false
861
- @ime = false
862
- when 0xf5 # PUSH AF
863
- @sp -= 2
864
- write_word(@sp, af)
865
- when 0xf6 # OR d8
866
- byte = read_byte_and_advance_pc
867
- or8(Register.new(name: 'd8', value: byte))
868
- when 0xf7 # RST 30H
869
- @sp -= 2
870
- write_word(@sp, @pc)
871
- @pc = 0x30
872
- when 0xf8 # LD HL, SP+r8
873
- byte = convert_to_twos_complement(read_byte_and_advance_pc)
874
-
875
- hflag = (@sp & 0x0f) + (byte & 0x0f) > 0x0f
876
- cflag = (@sp & 0xff) + (byte & 0xff) > 0xff
877
- self.hl = @sp + byte
878
- update_flags(
879
- z: false,
880
- n: false,
881
- h: hflag,
882
- c: cflag
883
- )
884
- when 0xf9 # LD SP, HL
885
- @sp = hl
886
- when 0xfa # LD A, (nn)
887
- word = read_word_and_advance_pc
888
- @a.value = read_byte(word)
889
- when 0xfb # EI
890
- @ime_delay = true
891
- when 0xfe # CP d8
892
- byte = read_byte_and_advance_pc
893
- update_flags(
894
- z: @a.value == byte,
895
- n: true,
896
- h: (@a.value & 0x0f) < (byte & 0x0f),
897
- c: @a.value < byte
898
- )
899
- when 0xff # RST 38H
900
- @sp -= 2
901
- write_word(@sp, @pc)
902
- @pc = 0x38
53
+ when 0x00 then 4 # NOP
54
+ when 0x01 then ld16(Operand.new(type: :register16, value: :bc), Operand.new(type: :immediate16))
55
+ when 0x02 then ld8(Operand.new(type: :indirect, value: :bc), Operand.new(type: :register8, value: :a))
56
+ when 0x03 then inc16(Operand.new(type: :register16, value: :bc))
57
+ when 0x04 then inc8(Operand.new(type: :register8, value: :b))
58
+ when 0x05 then dec8(Operand.new(type: :register8, value: :b))
59
+ when 0x06 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :immediate8))
60
+ when 0x07 then rlca
61
+ when 0x08 then ld16(Operand.new(type: :direct16), Operand.new(type: :sp))
62
+ when 0x09 then add16(Operand.new(type: :register16, value: :hl), Operand.new(type: :register16, value: :bc))
63
+ when 0x0a then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :indirect, value: :bc))
64
+ when 0x0b then dec16(Operand.new(type: :register16, value: :bc))
65
+ when 0x0c then inc8(Operand.new(type: :register8, value: :c))
66
+ when 0x0d then dec8(Operand.new(type: :register8, value: :c))
67
+ when 0x0e then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :immediate8))
68
+ when 0x0f then rrca
69
+ when 0x10 then 4 # STOP
70
+ when 0x11 then ld16(Operand.new(type: :register16, value: :de), Operand.new(type: :immediate16))
71
+ when 0x12 then ld8(Operand.new(type: :indirect, value: :de), Operand.new(type: :register8, value: :a))
72
+ when 0x13 then inc16(Operand.new(type: :register16, value: :de))
73
+ when 0x14 then inc8(Operand.new(type: :register8, value: :d))
74
+ when 0x15 then dec8(Operand.new(type: :register8, value: :d))
75
+ when 0x16 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :immediate8))
76
+ when 0x17 then rla
77
+ when 0x18 then jr
78
+ when 0x19 then add16(Operand.new(type: :register16, value: :hl), Operand.new(type: :register16, value: :de))
79
+ when 0x1a then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :indirect, value: :de))
80
+ when 0x1b then dec16(Operand.new(type: :register16, value: :de))
81
+ when 0x1c then inc8(Operand.new(type: :register8, value: :e))
82
+ when 0x1d then dec8(Operand.new(type: :register8, value: :e))
83
+ when 0x1e then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :immediate8))
84
+ when 0x1f then rra
85
+ when 0x20 then jr(condition: !flags[:z])
86
+ when 0x21 then ld16(Operand.new(type: :register16, value: :hl), Operand.new(type: :immediate16))
87
+ when 0x22 then ld8(Operand.new(type: :hl_inc), Operand.new(type: :register8, value: :a))
88
+ when 0x23 then inc16(Operand.new(type: :register16, value: :hl))
89
+ when 0x24 then inc8(Operand.new(type: :register8, value: :h))
90
+ when 0x25 then dec8(Operand.new(type: :register8, value: :h))
91
+ when 0x26 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :immediate8))
92
+ when 0x27 then daa
93
+ when 0x28 then jr(condition: flags[:z])
94
+ when 0x29 then add16(Operand.new(type: :register16, value: :hl), Operand.new(type: :register16, value: :hl))
95
+ when 0x2a then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :hl_inc))
96
+ when 0x2b then dec16(Operand.new(type: :register16, value: :hl))
97
+ when 0x2c then inc8(Operand.new(type: :register8, value: :l))
98
+ when 0x2d then dec8(Operand.new(type: :register8, value: :l))
99
+ when 0x2e then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :immediate8))
100
+ when 0x2f then cpl
101
+ when 0x30 then jr(condition: !flags[:c])
102
+ when 0x31 then ld16(Operand.new(type: :sp), Operand.new(type: :immediate16))
103
+ when 0x32 then ld8(Operand.new(type: :hl_dec), Operand.new(type: :register8, value: :a))
104
+ when 0x33 then inc16(Operand.new(type: :sp))
105
+ when 0x34 then inc8(Operand.new(type: :indirect, value: :hl))
106
+ when 0x35 then dec8(Operand.new(type: :indirect, value: :hl))
107
+ when 0x36 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :immediate8))
108
+ when 0x37 then scf
109
+ when 0x38 then jr(condition: flags[:c])
110
+ when 0x39 then add16(Operand.new(type: :register16, value: :hl), Operand.new(type: :sp))
111
+ when 0x3a then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :hl_dec))
112
+ when 0x3b then dec16(Operand.new(type: :sp))
113
+ when 0x3c then inc8(Operand.new(type: :register8, value: :a))
114
+ when 0x3d then dec8(Operand.new(type: :register8, value: :a))
115
+ when 0x3e then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :immediate8))
116
+ when 0x3f then ccf
117
+ when 0x40 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :b))
118
+ when 0x41 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :c))
119
+ when 0x42 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :d))
120
+ when 0x43 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :e))
121
+ when 0x44 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :h))
122
+ when 0x45 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :l))
123
+ when 0x46 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :indirect, value: :hl))
124
+ when 0x47 then ld8(Operand.new(type: :register8, value: :b), Operand.new(type: :register8, value: :a))
125
+ when 0x48 then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :b))
126
+ when 0x49 then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :c))
127
+ when 0x4a then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :d))
128
+ when 0x4b then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :e))
129
+ when 0x4c then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :h))
130
+ when 0x4d then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :l))
131
+ when 0x4e then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :indirect, value: :hl))
132
+ when 0x4f then ld8(Operand.new(type: :register8, value: :c), Operand.new(type: :register8, value: :a))
133
+ when 0x50 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :b))
134
+ when 0x51 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :c))
135
+ when 0x52 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :d))
136
+ when 0x53 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :e))
137
+ when 0x54 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :h))
138
+ when 0x55 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :l))
139
+ when 0x56 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :indirect, value: :hl))
140
+ when 0x57 then ld8(Operand.new(type: :register8, value: :d), Operand.new(type: :register8, value: :a))
141
+ when 0x58 then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :b))
142
+ when 0x59 then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :c))
143
+ when 0x5a then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :d))
144
+ when 0x5b then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :e))
145
+ when 0x5c then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :h))
146
+ when 0x5d then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :l))
147
+ when 0x5e then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :indirect, value: :hl))
148
+ when 0x5f then ld8(Operand.new(type: :register8, value: :e), Operand.new(type: :register8, value: :a))
149
+ when 0x60 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :b))
150
+ when 0x61 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :c))
151
+ when 0x62 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :d))
152
+ when 0x63 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :e))
153
+ when 0x64 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :h))
154
+ when 0x65 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :l))
155
+ when 0x66 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :indirect, value: :hl))
156
+ when 0x67 then ld8(Operand.new(type: :register8, value: :h), Operand.new(type: :register8, value: :a))
157
+ when 0x68 then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :b))
158
+ when 0x69 then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :c))
159
+ when 0x6a then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :d))
160
+ when 0x6b then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :e))
161
+ when 0x6c then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :h))
162
+ when 0x6d then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :l))
163
+ when 0x6e then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :indirect, value: :hl))
164
+ when 0x6f then ld8(Operand.new(type: :register8, value: :l), Operand.new(type: :register8, value: :a))
165
+ when 0x70 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :b))
166
+ when 0x71 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :c))
167
+ when 0x72 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :d))
168
+ when 0x73 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :e))
169
+ when 0x74 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :h))
170
+ when 0x75 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :l))
171
+ when 0x76 then halt
172
+ when 0x77 then ld8(Operand.new(type: :indirect, value: :hl), Operand.new(type: :register8, value: :a))
173
+ when 0x78 then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :b))
174
+ when 0x79 then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :c))
175
+ when 0x7a then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :d))
176
+ when 0x7b then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :e))
177
+ when 0x7c then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :h))
178
+ when 0x7d then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :l))
179
+ when 0x7e then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :indirect, value: :hl))
180
+ when 0x7f then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :register8, value: :a))
181
+ when 0x80 then add8(Operand.new(type: :register8, value: :b))
182
+ when 0x81 then add8(Operand.new(type: :register8, value: :c))
183
+ when 0x82 then add8(Operand.new(type: :register8, value: :d))
184
+ when 0x83 then add8(Operand.new(type: :register8, value: :e))
185
+ when 0x84 then add8(Operand.new(type: :register8, value: :h))
186
+ when 0x85 then add8(Operand.new(type: :register8, value: :l))
187
+ when 0x86 then add8(Operand.new(type: :indirect, value: :hl))
188
+ when 0x87 then add8(Operand.new(type: :register8, value: :a))
189
+ when 0x88 then adc8(Operand.new(type: :register8, value: :b))
190
+ when 0x89 then adc8(Operand.new(type: :register8, value: :c))
191
+ when 0x8a then adc8(Operand.new(type: :register8, value: :d))
192
+ when 0x8b then adc8(Operand.new(type: :register8, value: :e))
193
+ when 0x8c then adc8(Operand.new(type: :register8, value: :h))
194
+ when 0x8d then adc8(Operand.new(type: :register8, value: :l))
195
+ when 0x8e then adc8(Operand.new(type: :indirect, value: :hl))
196
+ when 0x8f then adc8(Operand.new(type: :register8, value: :a))
197
+ when 0x90 then sub8(Operand.new(type: :register8, value: :b))
198
+ when 0x91 then sub8(Operand.new(type: :register8, value: :c))
199
+ when 0x92 then sub8(Operand.new(type: :register8, value: :d))
200
+ when 0x93 then sub8(Operand.new(type: :register8, value: :e))
201
+ when 0x94 then sub8(Operand.new(type: :register8, value: :h))
202
+ when 0x95 then sub8(Operand.new(type: :register8, value: :l))
203
+ when 0x96 then sub8(Operand.new(type: :indirect, value: :hl))
204
+ when 0x97 then sub8(Operand.new(type: :register8, value: :a))
205
+ when 0x98 then sbc8(Operand.new(type: :register8, value: :b))
206
+ when 0x99 then sbc8(Operand.new(type: :register8, value: :c))
207
+ when 0x9a then sbc8(Operand.new(type: :register8, value: :d))
208
+ when 0x9b then sbc8(Operand.new(type: :register8, value: :e))
209
+ when 0x9c then sbc8(Operand.new(type: :register8, value: :h))
210
+ when 0x9d then sbc8(Operand.new(type: :register8, value: :l))
211
+ when 0x9e then sbc8(Operand.new(type: :indirect, value: :hl))
212
+ when 0x9f then sbc8(Operand.new(type: :register8, value: :a))
213
+ when 0xa0 then and8(Operand.new(type: :register8, value: :b))
214
+ when 0xa1 then and8(Operand.new(type: :register8, value: :c))
215
+ when 0xa2 then and8(Operand.new(type: :register8, value: :d))
216
+ when 0xa3 then and8(Operand.new(type: :register8, value: :e))
217
+ when 0xa4 then and8(Operand.new(type: :register8, value: :h))
218
+ when 0xa5 then and8(Operand.new(type: :register8, value: :l))
219
+ when 0xa6 then and8(Operand.new(type: :indirect, value: :hl))
220
+ when 0xa7 then and8(Operand.new(type: :register8, value: :a))
221
+ when 0xa8 then xor8(Operand.new(type: :register8, value: :b))
222
+ when 0xa9 then xor8(Operand.new(type: :register8, value: :c))
223
+ when 0xaa then xor8(Operand.new(type: :register8, value: :d))
224
+ when 0xab then xor8(Operand.new(type: :register8, value: :e))
225
+ when 0xac then xor8(Operand.new(type: :register8, value: :h))
226
+ when 0xad then xor8(Operand.new(type: :register8, value: :l))
227
+ when 0xae then xor8(Operand.new(type: :indirect, value: :hl))
228
+ when 0xaf then xor8(Operand.new(type: :register8, value: :a))
229
+ when 0xb0 then or8(Operand.new(type: :register8, value: :b))
230
+ when 0xb1 then or8(Operand.new(type: :register8, value: :c))
231
+ when 0xb2 then or8(Operand.new(type: :register8, value: :d))
232
+ when 0xb3 then or8(Operand.new(type: :register8, value: :e))
233
+ when 0xb4 then or8(Operand.new(type: :register8, value: :h))
234
+ when 0xb5 then or8(Operand.new(type: :register8, value: :l))
235
+ when 0xb6 then or8(Operand.new(type: :indirect, value: :hl))
236
+ when 0xb7 then or8(Operand.new(type: :register8, value: :a))
237
+ when 0xb8 then cp8(Operand.new(type: :register8, value: :b))
238
+ when 0xb9 then cp8(Operand.new(type: :register8, value: :c))
239
+ when 0xba then cp8(Operand.new(type: :register8, value: :d))
240
+ when 0xbb then cp8(Operand.new(type: :register8, value: :e))
241
+ when 0xbc then cp8(Operand.new(type: :register8, value: :h))
242
+ when 0xbd then cp8(Operand.new(type: :register8, value: :l))
243
+ when 0xbe then cp8(Operand.new(type: :indirect, value: :hl))
244
+ when 0xbf then cp8(Operand.new(type: :register8, value: :a))
245
+ when 0xc0 then ret_if(!flags[:z])
246
+ when 0xc1 then pop16(:bc)
247
+ when 0xc2 then jp(Operand.new(type: :immediate16), condition: !flags[:z])
248
+ when 0xc3 then jp(Operand.new(type: :immediate16))
249
+ when 0xc4 then call16(Operand.new(type: :immediate16), condition: !flags[:z])
250
+ when 0xc5 then push16(:bc)
251
+ when 0xc6 then add8(Operand.new(type: :immediate8))
252
+ when 0xc7 then rst(0x00)
253
+ when 0xc8 then ret_if(flags[:z])
254
+ when 0xc9 then ret
255
+ when 0xca then jp(Operand.new(type: :immediate16), condition: flags[:z])
256
+ when 0xcc then call16(Operand.new(type: :immediate16), condition: flags[:z])
257
+ when 0xcd then call16(Operand.new(type: :immediate16))
258
+ when 0xce then adc8(Operand.new(type: :immediate8))
259
+ when 0xcf then rst(0x08)
260
+ when 0xd0 then ret_if(!flags[:c])
261
+ when 0xd1 then pop16(:de)
262
+ when 0xd2 then jp(Operand.new(type: :immediate16), condition: !flags[:c])
263
+ when 0xd4 then call16(Operand.new(type: :immediate16), condition: !flags[:c])
264
+ when 0xd5 then push16(:de)
265
+ when 0xd6 then sub8(Operand.new(type: :immediate8))
266
+ when 0xd7 then rst(0x10)
267
+ when 0xd8 then ret_if(flags[:c])
268
+ when 0xd9 then reti
269
+ when 0xda then jp(Operand.new(type: :immediate16), condition: flags[:c])
270
+ when 0xdc then call16(Operand.new(type: :immediate16), condition: flags[:c])
271
+ when 0xde then sbc8(Operand.new(type: :immediate8))
272
+ when 0xdf then rst(0x18)
273
+ when 0xe0 then ld8(Operand.new(type: :ff00), Operand.new(type: :register8, value: :a))
274
+ when 0xe1 then pop16(:hl)
275
+ when 0xe2 then ld8(Operand.new(type: :ff00_c), Operand.new(type: :register8, value: :a))
276
+ when 0xe5 then push16(:hl)
277
+ when 0xe6 then and8(Operand.new(type: :immediate8))
278
+ when 0xe7 then rst(0x20)
279
+ when 0xe8 then add_sp_r8
280
+ when 0xe9 then jp(Operand.new(type: :register16, value: :hl))
281
+ when 0xea then ld8(Operand.new(type: :direct8), Operand.new(type: :register8, value: :a))
282
+ when 0xee then xor8(Operand.new(type: :immediate8))
283
+ when 0xef then rst(0x28)
284
+ when 0xf0 then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :ff00))
285
+ when 0xf1 then pop16(:af)
286
+ when 0xf2 then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :ff00_c))
287
+ when 0xf3 then di
288
+ when 0xf5 then push16(:af)
289
+ when 0xf6 then or8(Operand.new(type: :immediate8))
290
+ when 0xf7 then rst(0x30)
291
+ when 0xf8 then ld_hl_sp_r8
292
+ when 0xf9 then ld16(Operand.new(type: :sp), Operand.new(type: :register16, value: :hl))
293
+ when 0xfa then ld8(Operand.new(type: :register8, value: :a), Operand.new(type: :direct8))
294
+ when 0xfb then ei
295
+ when 0xfe then cp8(Operand.new(type: :immediate8))
296
+ when 0xff then rst(0x38)
903
297
  when 0xcb # CB prefix
904
298
  opcode = read_byte_and_advance_pc
905
- cbprefixed = true
906
-
907
- # p "CB #{opcode.to_s(16)}"
908
299
 
909
300
  case opcode
910
- when 0x00 # RLC B
911
- rlc8(@b)
912
- when 0x01 # RLC C
913
- rlc8(@c)
914
- when 0x02 # RLC D
915
- rlc8(@d)
916
- when 0x03 # RLC E
917
- rlc8(@e)
918
- when 0x04 # RLC H
919
- rlc8(@h)
920
- when 0x05 # RLC L
921
- rlc8(@l)
922
- when 0x06 # RLC (HL)
923
- reg = Register.new(name: 'HL', value: read_byte(hl))
924
- rlc8(reg)
925
- write_byte(hl, reg.value)
926
- when 0x07 # RLC A
927
- rlc8(@a)
928
- when 0x08 # RRC B
929
- rrc8(@b)
930
- when 0x09 # RRC C
931
- rrc8(@c)
932
- when 0x0a # RRC D
933
- rrc8(@d)
934
- when 0x0b # RRC E
935
- rrc8(@e)
936
- when 0x0c # RRC H
937
- rrc8(@h)
938
- when 0x0d # RRC L
939
- rrc8(@l)
940
- when 0x0e # RRC (HL)
941
- reg = Register.new(name: 'HL', value: read_byte(hl))
942
- rrc8(reg)
943
- write_byte(hl, reg.value)
944
- when 0x0f # RRC A
945
- rrc8(@a)
946
- when 0x10 # RL B
947
- rl8(@b)
948
- when 0x11 # RL C
949
- rl8(@c)
950
- when 0x12 # RL D
951
- rl8(@d)
952
- when 0x13 # RL E
953
- rl8(@e)
954
- when 0x14 # RL H
955
- rl8(@h)
956
- when 0x15 # RL L
957
- rl8(@l)
958
- when 0x16 # RL (HL)
959
- reg = Register.new(name: 'HL', value: read_byte(hl))
960
- rl8(reg)
961
- write_byte(hl, reg.value)
962
- when 0x17 # RL A
963
- rl8(@a)
964
- when 0x18 # RR B
965
- rr8(@b)
966
- when 0x19 # RR C
967
- rr8(@c)
968
- when 0x1a # RR D
969
- rr8(@d)
970
- when 0x1b # RR E
971
- rr8(@e)
972
- when 0x1c # RR H
973
- rr8(@h)
974
- when 0x1d # RR L
975
- rr8(@l)
976
- when 0x1e # RR (HL)
977
- reg = Register.new(name: 'HL', value: read_byte(hl))
978
- rr8(reg)
979
- write_byte(hl, reg.value)
980
- when 0x1f # RR A
981
- rr8(@a)
982
- when 0x20 # SLA B
983
- sla8(@b)
984
- when 0x21 # SLA C
985
- sla8(@c)
986
- when 0x22 # SLA D
987
- sla8(@d)
988
- when 0x23 # SLA E
989
- sla8(@e)
990
- when 0x24 # SLA H
991
- sla8(@h)
992
- when 0x25 # SLA L
993
- sla8(@l)
994
- when 0x26 # SLA (HL)
995
- reg = Register.new(name: 'HL', value: read_byte(hl))
996
- sla8(reg)
997
- write_byte(hl, reg.value)
998
- when 0x27 # SLA A
999
- sla8(@a)
1000
- when 0x28 # SRA B
1001
- sra8(@b)
1002
- when 0x29 # SRA C
1003
- sra8(@c)
1004
- when 0x2a # SRA D
1005
- sra8(@d)
1006
- when 0x2b # SRA E
1007
- sra8(@e)
1008
- when 0x2c # SRA H
1009
- sra8(@h)
1010
- when 0x2d # SRA L
1011
- sra8(@l)
1012
- when 0x2e # SRA (HL)
1013
- reg = Register.new(name: 'HL', value: read_byte(hl))
1014
- sra8(reg)
1015
- write_byte(hl, reg.value)
1016
- when 0x2f # SRA A
1017
- sra8(@a)
1018
- when 0x30 # SWAP B
1019
- swap8(@b)
1020
- when 0x31 # SWAP C
1021
- swap8(@c)
1022
- when 0x32 # SWAP D
1023
- swap8(@d)
1024
- when 0x33 # SWAP E
1025
- swap8(@e)
1026
- when 0x34 # SWAP H
1027
- swap8(@h)
1028
- when 0x35 # SWAP L
1029
- swap8(@l)
1030
- when 0x36 # SWAP (HL)
1031
- reg = Register.new(name: 'HL', value: read_byte(hl))
1032
- swap8(reg)
1033
- write_byte(hl, reg.value)
1034
- when 0x37 # SWAP A
1035
- swap8(@a)
1036
- when 0x38 # SRL B
1037
- srl8(@b)
1038
- when 0x39 # SRL C
1039
- srl8(@c)
1040
- when 0x3a # SRL D
1041
- srl8(@d)
1042
- when 0x3b # SRL E
1043
- srl8(@e)
1044
- when 0x3c # SRL H
1045
- srl8(@h)
1046
- when 0x3d # SRL L
1047
- srl8(@l)
1048
- when 0x3e # SRL (HL)
1049
- reg = Register.new(name: 'HL', value: read_byte(hl))
1050
- srl8(reg)
1051
- write_byte(hl, reg.value)
1052
- when 0x3f # SRL A
1053
- srl8(@a)
1054
- when 0x40 # BIT 0, B
1055
- bit8(0, @b)
1056
- when 0x41 # BIT 0, C
1057
- bit8(0, @c)
1058
- when 0x42 # BIT 0, D
1059
- bit8(0, @d)
1060
- when 0x43 # BIT 0, E
1061
- bit8(0, @e)
1062
- when 0x44 # BIT 0, H
1063
- bit8(0, @h)
1064
- when 0x45 # BIT 0, L
1065
- bit8(0, @l)
1066
- when 0x46 # BIT 0, (HL)
1067
- bit8(0, Register.new(name: 'HL', value: read_byte(hl)))
1068
- when 0x47 # BIT 0, A
1069
- bit8(0, @a)
1070
- when 0x48 # BIT 1, B
1071
- bit8(1, @b)
1072
- when 0x49 # BIT 1, C
1073
- bit8(1, @c)
1074
- when 0x4a # BIT 1, D
1075
- bit8(1, @d)
1076
- when 0x4b # BIT 1, E
1077
- bit8(1, @e)
1078
- when 0x4c # BIT 1, H
1079
- bit8(1, @h)
1080
- when 0x4d # BIT 1, L
1081
- bit8(1, @l)
1082
- when 0x4e # BIT 1, (HL)
1083
- bit8(1, Register.new(name: 'HL', value: read_byte(hl)))
1084
- when 0x4f # BIT 1, A
1085
- bit8(1, @a)
1086
- when 0x50 # BIT 2, B
1087
- bit8(2, @b)
1088
- when 0x51 # BIT 2, C
1089
- bit8(2, @c)
1090
- when 0x52 # BIT 2, D
1091
- bit8(2, @d)
1092
- when 0x53 # BIT 2, E
1093
- bit8(2, @e)
1094
- when 0x54 # BIT 2, H
1095
- bit8(2, @h)
1096
- when 0x55 # BIT 2, L
1097
- bit8(2, @l)
1098
- when 0x56 # BIT 2, (HL)
1099
- bit8(2, Register.new(name: 'HL', value: read_byte(hl)))
1100
- when 0x57 # BIT 2, A
1101
- bit8(2, @a)
1102
- when 0x58 # BIT 3, B
1103
- bit8(3, @b)
1104
- when 0x59 # BIT 3, C
1105
- bit8(3, @c)
1106
- when 0x5a # BIT 3, D
1107
- bit8(3, @d)
1108
- when 0x5b # BIT 3, E
1109
- bit8(3, @e)
1110
- when 0x5c # BIT 3, H
1111
- bit8(3, @h)
1112
- when 0x5d # BIT 3, L
1113
- bit8(3, @l)
1114
- when 0x5e # BIT 3, (HL)
1115
- bit8(3, Register.new(name: 'HL', value: read_byte(hl)))
1116
- when 0x5f # BIT 3, A
1117
- bit8(3, @a)
1118
- when 0x60 # BIT 4, B
1119
- bit8(4, @b)
1120
- when 0x61 # BIT 4, C
1121
- bit8(4, @c)
1122
- when 0x62 # BIT 4, D
1123
- bit8(4, @d)
1124
- when 0x63 # BIT 4, E
1125
- bit8(4, @e)
1126
- when 0x64 # BIT 4, H
1127
- bit8(4, @h)
1128
- when 0x65 # BIT 4, L
1129
- bit8(4, @l)
1130
- when 0x66 # BIT 4, (HL)
1131
- bit8(4, Register.new(name: 'HL', value: read_byte(hl)))
1132
- when 0x67 # BIT 4, A
1133
- bit8(4, @a)
1134
- when 0x68 # BIT 5, B
1135
- bit8(5, @b)
1136
- when 0x69 # BIT 5, C
1137
- bit8(5, @c)
1138
- when 0x6a # BIT 5, D
1139
- bit8(5, @d)
1140
- when 0x6b # BIT 5, E
1141
- bit8(5, @e)
1142
- when 0x6c # BIT 5, H
1143
- bit8(5, @h)
1144
- when 0x6d # BIT 5, L
1145
- bit8(5, @l)
1146
- when 0x6e # BIT 5, (HL)
1147
- bit8(5, Register.new(name: 'HL', value: read_byte(hl)))
1148
- when 0x6f # BIT 5, A
1149
- bit8(5, @a)
1150
- when 0x70 # BIT 6, B
1151
- bit8(6, @b)
1152
- when 0x71 # BIT 6, C
1153
- bit8(6, @c)
1154
- when 0x72 # BIT 6, D
1155
- bit8(6, @d)
1156
- when 0x73 # BIT 6, E
1157
- bit8(6, @e)
1158
- when 0x74 # BIT 6, H
1159
- bit8(6, @h)
1160
- when 0x75 # BIT 6, L
1161
- bit8(6, @l)
1162
- when 0x76 # BIT 6, (HL)
1163
- bit8(6, Register.new(name: 'HL', value: read_byte(hl)))
1164
- when 0x77 # BIT 6, A
1165
- bit8(6, @a)
1166
- when 0x78 # BIT 7, B
1167
- bit8(7, @b)
1168
- when 0x79 # BIT 7, C
1169
- bit8(7, @c)
1170
- when 0x7a # BIT 7, D
1171
- bit8(7, @d)
1172
- when 0x7b # BIT 7, E
1173
- bit8(7, @e)
1174
- when 0x7c # BIT 7, H
1175
- bit8(7, @h)
1176
- when 0x7d # BIT 7, L
1177
- bit8(7, @l)
1178
- when 0x7e # BIT 7, (HL)
1179
- bit8(7, Register.new(name: 'HL', value: read_byte(hl)))
1180
- when 0x7f # BIT 7, A
1181
- bit8(7, @a)
1182
- when 0x80 # RES 0, B
1183
- res8(0, @b)
1184
- when 0x81 # RES 0, C
1185
- res8(0, @c)
1186
- when 0x82 # RES 0, D
1187
- res8(0, @d)
1188
- when 0x83 # RES 0, E
1189
- res8(0, @e)
1190
- when 0x84 # RES 0, H
1191
- res8(0, @h)
1192
- when 0x85 # RES 0, L
1193
- res8(0, @l)
1194
- when 0x86 # RES 0, (HL)
1195
- reg = Register.new(name: 'HL', value: read_byte(hl))
1196
- res8(0, reg)
1197
- write_byte(hl, reg.value)
1198
- when 0x87 # RES 0, A
1199
- res8(0, @a)
1200
- when 0x88 # RES 1, B
1201
- res8(1, @b)
1202
- when 0x89 # RES 1, C
1203
- res8(1, @c)
1204
- when 0x8a # RES 1, D
1205
- res8(1, @d)
1206
- when 0x8b # RES 1, E
1207
- res8(1, @e)
1208
- when 0x8c # RES 1, H
1209
- res8(1, @h)
1210
- when 0x8d # RES 1, L
1211
- res8(1, @l)
1212
- when 0x8e # RES 1, (HL)
1213
- reg = Register.new(name: 'HL', value: read_byte(hl))
1214
- res8(1, reg)
1215
- write_byte(hl, reg.value)
1216
- when 0x8f # RES 1, A
1217
- res8(1, @a)
1218
- when 0x90 # RES 2, B
1219
- res8(2, @b)
1220
- when 0x91 # RES 2, C
1221
- res8(2, @c)
1222
- when 0x92 # RES 2, D
1223
- res8(2, @d)
1224
- when 0x93 # RES 2, E
1225
- res8(2, @e)
1226
- when 0x94 # RES 2, H
1227
- res8(2, @h)
1228
- when 0x95 # RES 2, L
1229
- res8(2, @l)
1230
- when 0x96 # RES 2, (HL)
1231
- reg = Register.new(name: 'HL', value: read_byte(hl))
1232
- res8(2, reg)
1233
- write_byte(hl, reg.value)
1234
- when 0x97 # RES 2, A
1235
- res8(2, @a)
1236
- when 0x98 # RES 3, B
1237
- res8(3, @b)
1238
- when 0x99 # RES 3, C
1239
- res8(3, @c)
1240
- when 0x9a # RES 3, D
1241
- res8(3, @d)
1242
- when 0x9b # RES 3, E
1243
- res8(3, @e)
1244
- when 0x9c # RES 3, H
1245
- res8(3, @h)
1246
- when 0x9d # RES 3, L
1247
- res8(3, @l)
1248
- when 0x9e # RES 3, (HL)
1249
- reg = Register.new(name: 'HL', value: read_byte(hl))
1250
- res8(3, reg)
1251
- write_byte(hl, reg.value)
1252
- when 0x9f # RES 3, A
1253
- res8(3, @a)
1254
- when 0xa0 # RES 4, B
1255
- res8(4, @b)
1256
- when 0xa1 # RES 4, C
1257
- res8(4, @c)
1258
- when 0xa2 # RES 4, D
1259
- res8(4, @d)
1260
- when 0xa3 # RES 4, E
1261
- res8(4, @e)
1262
- when 0xa4 # RES 4, H
1263
- res8(4, @h)
1264
- when 0xa5 # RES 4, L
1265
- res8(4, @l)
1266
- when 0xa6 # RES 4, (HL)
1267
- reg = Register.new(name: 'HL', value: read_byte(hl))
1268
- res8(4, reg)
1269
- write_byte(hl, reg.value)
1270
- when 0xa7 # RES 4, A
1271
- res8(4, @a)
1272
- when 0xa8 # RES 5, B
1273
- res8(5, @b)
1274
- when 0xa9 # RES 5, C
1275
- res8(5, @c)
1276
- when 0xaa # RES 5, D
1277
- res8(5, @d)
1278
- when 0xab # RES 5, E
1279
- res8(5, @e)
1280
- when 0xac # RES 5, H
1281
- res8(5, @h)
1282
- when 0xad # RES 5, L
1283
- res8(5, @l)
1284
- when 0xae # RES 5, (HL)
1285
- reg = Register.new(name: 'HL', value: read_byte(hl))
1286
- res8(5, reg)
1287
- write_byte(hl, reg.value)
1288
- when 0xaf # RES 5, A
1289
- res8(5, @a)
1290
- when 0xb0 # RES 6, B
1291
- res8(6, @b)
1292
- when 0xb1 # RES 6, C
1293
- res8(6, @c)
1294
- when 0xb2 # RES 6, D
1295
- res8(6, @d)
1296
- when 0xb3 # RES 6, E
1297
- res8(6, @e)
1298
- when 0xb4 # RES 6, H
1299
- res8(6, @h)
1300
- when 0xb5 # RES 6, L
1301
- res8(6, @l)
1302
- when 0xb6 # RES 6, (HL)
1303
- reg = Register.new(name: 'HL', value: read_byte(hl))
1304
- res8(6, reg)
1305
- write_byte(hl, reg.value)
1306
- when 0xb7 # RES 6, A
1307
- res8(6, @a)
1308
- when 0xb8 # RES 7, B
1309
- res8(7, @b)
1310
- when 0xb9 # RES 7, C
1311
- res8(7, @c)
1312
- when 0xba # RES 7, D
1313
- res8(7, @d)
1314
- when 0xbb # RES 7, E
1315
- res8(7, @e)
1316
- when 0xbc # RES 7, H
1317
- res8(7, @h)
1318
- when 0xbd # RES 7, L
1319
- res8(7, @l)
1320
- when 0xbe # RES 7, (HL)
1321
- reg = Register.new(name: 'HL', value: read_byte(hl))
1322
- res8(7, reg)
1323
- write_byte(hl, reg.value)
1324
- when 0xbf # RES 7, A
1325
- res8(7, @a)
1326
- when 0xc0 # SET 0, B
1327
- set8(0, @b)
1328
- when 0xc1 # SET 0, C
1329
- set8(0, @c)
1330
- when 0xc2 # SET 0, D
1331
- set8(0, @d)
1332
- when 0xc3 # SET 0, E
1333
- set8(0, @e)
1334
- when 0xc4 # SET 0, H
1335
- set8(0, @h)
1336
- when 0xc5 # SET 0, L
1337
- set8(0, @l)
1338
- when 0xc6 # SET 0, (HL)
1339
- reg = Register.new(name: 'HL', value: read_byte(hl))
1340
- set8(0, reg)
1341
- write_byte(hl, reg.value)
1342
- when 0xc7 # SET 0, A
1343
- set8(0, @a)
1344
- when 0xc8 # SET 1, B
1345
- set8(1, @b)
1346
- when 0xc9 # SET 1, C
1347
- set8(1, @c)
1348
- when 0xca # SET 1, D
1349
- set8(1, @d)
1350
- when 0xcb # SET 1, E
1351
- set8(1, @e)
1352
- when 0xcc # SET 1, H
1353
- set8(1, @h)
1354
- when 0xcd # SET 1, L
1355
- set8(1, @l)
1356
- when 0xce # SET 1, (HL)
1357
- reg = Register.new(name: 'HL', value: read_byte(hl))
1358
- set8(1, reg)
1359
- write_byte(hl, reg.value)
1360
- when 0xcf # SET 1, A
1361
- set8(1, @a)
1362
- when 0xd0 # SET 2, B
1363
- set8(2, @b)
1364
- when 0xd1 # SET 2, C
1365
- set8(2, @c)
1366
- when 0xd2 # SET 2, D
1367
- set8(2, @d)
1368
- when 0xd3 # SET 2, E
1369
- set8(2, @e)
1370
- when 0xd4 # SET 2, H
1371
- set8(2, @h)
1372
- when 0xd5 # SET 2, L
1373
- set8(2, @l)
1374
- when 0xd6 # SET 2, (HL)
1375
- reg = Register.new(name: 'HL', value: read_byte(hl))
1376
- set8(2, reg)
1377
- write_byte(hl, reg.value)
1378
- when 0xd7 # SET 2, A
1379
- set8(2, @a)
1380
- when 0xd8 # SET 3, B
1381
- set8(3, @b)
1382
- when 0xd9 # SET 3, C
1383
- set8(3, @c)
1384
- when 0xda # SET 3, D
1385
- set8(3, @d)
1386
- when 0xdb # SET 3, E
1387
- set8(3, @e)
1388
- when 0xdc # SET 3, H
1389
- set8(3, @h)
1390
- when 0xdd # SET 3, L
1391
- set8(3, @l)
1392
- when 0xde # SET 3, (HL)
1393
- reg = Register.new(name: 'HL', value: read_byte(hl))
1394
- set8(3, reg)
1395
- write_byte(hl, reg.value)
1396
- when 0xdf # SET 3, A
1397
- set8(3, @a)
1398
- when 0xe0 # SET 4, B
1399
- set8(4, @b)
1400
- when 0xe1 # SET 4, C
1401
- set8(4, @c)
1402
- when 0xe2 # SET 4, D
1403
- set8(4, @d)
1404
- when 0xe3 # SET 4, E
1405
- set8(4, @e)
1406
- when 0xe4 # SET 4, H
1407
- set8(4, @h)
1408
- when 0xe5 # SET 4, L
1409
- set8(4, @l)
1410
- when 0xe6 # SET 4, (HL)
1411
- reg = Register.new(name: 'HL', value: read_byte(hl))
1412
- set8(4, reg)
1413
- write_byte(hl, reg.value)
1414
- when 0xe7 # SET 4, A
1415
- set8(4, @a)
1416
- when 0xe8 # SET 5, B
1417
- set8(5, @b)
1418
- when 0xe9 # SET 5, C
1419
- set8(5, @c)
1420
- when 0xea # SET 5, D
1421
- set8(5, @d)
1422
- when 0xeb # SET 5, E
1423
- set8(5, @e)
1424
- when 0xec # SET 5, H
1425
- set8(5, @h)
1426
- when 0xed # SET 5, L
1427
- set8(5, @l)
1428
- when 0xee # SET 5, (HL)
1429
- reg = Register.new(name: 'HL', value: read_byte(hl))
1430
- set8(5, reg)
1431
- write_byte(hl, reg.value)
1432
- when 0xef # SET 5, A
1433
- set8(5, @a)
1434
- when 0xf0 # SET 6, B
1435
- set8(6, @b)
1436
- when 0xf1 # SET 6, C
1437
- set8(6, @c)
1438
- when 0xf2 # SET 6, D
1439
- set8(6, @d)
1440
- when 0xf3 # SET 6, E
1441
- set8(6, @e)
1442
- when 0xf4 # SET 6, H
1443
- set8(6, @h)
1444
- when 0xf5 # SET 6, L
1445
- set8(6, @l)
1446
- when 0xf6 # SET 6, (HL)
1447
- reg = Register.new(name: 'HL', value: read_byte(hl))
1448
- set8(6, reg)
1449
- write_byte(hl, reg.value)
1450
- when 0xf7 # SET 6, A
1451
- set8(6, @a)
1452
- when 0xf8 # SET 7, B
1453
- set8(7, @b)
1454
- when 0xf9 # SET 7, C
1455
- set8(7, @c)
1456
- when 0xfa # SET 7, D
1457
- set8(7, @d)
1458
- when 0xfb # SET 7, E
1459
- set8(7, @e)
1460
- when 0xfc then set8(7, @h)
1461
- when 0xfd then set8(7, @l)
1462
- when 0xfe # SET 7, (HL)
1463
- reg = Register.new(name: 'HL', value: read_byte(hl))
1464
- set8(7, reg)
1465
- write_byte(hl, reg.value)
1466
- when 0xff then set8(7, @a) # SET 7, A
301
+ when 0x00 then rlc8(Operand.new(type: :register8, value: :b))
302
+ when 0x01 then rlc8(Operand.new(type: :register8, value: :c))
303
+ when 0x02 then rlc8(Operand.new(type: :register8, value: :d))
304
+ when 0x03 then rlc8(Operand.new(type: :register8, value: :e))
305
+ when 0x04 then rlc8(Operand.new(type: :register8, value: :h))
306
+ when 0x05 then rlc8(Operand.new(type: :register8, value: :l))
307
+ when 0x06 then rlc8(Operand.new(type: :indirect, value: :hl))
308
+ when 0x07 then rlc8(Operand.new(type: :register8, value: :a))
309
+ when 0x08 then rrc8(Operand.new(type: :register8, value: :b))
310
+ when 0x09 then rrc8(Operand.new(type: :register8, value: :c))
311
+ when 0x0a then rrc8(Operand.new(type: :register8, value: :d))
312
+ when 0x0b then rrc8(Operand.new(type: :register8, value: :e))
313
+ when 0x0c then rrc8(Operand.new(type: :register8, value: :h))
314
+ when 0x0d then rrc8(Operand.new(type: :register8, value: :l))
315
+ when 0x0e then rrc8(Operand.new(type: :indirect, value: :hl))
316
+ when 0x0f then rrc8(Operand.new(type: :register8, value: :a))
317
+ when 0x10 then rl8(Operand.new(type: :register8, value: :b))
318
+ when 0x11 then rl8(Operand.new(type: :register8, value: :c))
319
+ when 0x12 then rl8(Operand.new(type: :register8, value: :d))
320
+ when 0x13 then rl8(Operand.new(type: :register8, value: :e))
321
+ when 0x14 then rl8(Operand.new(type: :register8, value: :h))
322
+ when 0x15 then rl8(Operand.new(type: :register8, value: :l))
323
+ when 0x16 then rl8(Operand.new(type: :indirect, value: :hl))
324
+ when 0x17 then rl8(Operand.new(type: :register8, value: :a))
325
+ when 0x18 then rr8(Operand.new(type: :register8, value: :b))
326
+ when 0x19 then rr8(Operand.new(type: :register8, value: :c))
327
+ when 0x1a then rr8(Operand.new(type: :register8, value: :d))
328
+ when 0x1b then rr8(Operand.new(type: :register8, value: :e))
329
+ when 0x1c then rr8(Operand.new(type: :register8, value: :h))
330
+ when 0x1d then rr8(Operand.new(type: :register8, value: :l))
331
+ when 0x1e then rr8(Operand.new(type: :indirect, value: :hl))
332
+ when 0x1f then rr8(Operand.new(type: :register8, value: :a))
333
+ when 0x20 then sla8(Operand.new(type: :register8, value: :b))
334
+ when 0x21 then sla8(Operand.new(type: :register8, value: :c))
335
+ when 0x22 then sla8(Operand.new(type: :register8, value: :d))
336
+ when 0x23 then sla8(Operand.new(type: :register8, value: :e))
337
+ when 0x24 then sla8(Operand.new(type: :register8, value: :h))
338
+ when 0x25 then sla8(Operand.new(type: :register8, value: :l))
339
+ when 0x26 then sla8(Operand.new(type: :indirect, value: :hl))
340
+ when 0x27 then sla8(Operand.new(type: :register8, value: :a))
341
+ when 0x28 then sra8(Operand.new(type: :register8, value: :b))
342
+ when 0x29 then sra8(Operand.new(type: :register8, value: :c))
343
+ when 0x2a then sra8(Operand.new(type: :register8, value: :d))
344
+ when 0x2b then sra8(Operand.new(type: :register8, value: :e))
345
+ when 0x2c then sra8(Operand.new(type: :register8, value: :h))
346
+ when 0x2d then sra8(Operand.new(type: :register8, value: :l))
347
+ when 0x2e then sra8(Operand.new(type: :indirect, value: :hl))
348
+ when 0x2f then sra8(Operand.new(type: :register8, value: :a))
349
+ when 0x30 then swap8(Operand.new(type: :register8, value: :b))
350
+ when 0x31 then swap8(Operand.new(type: :register8, value: :c))
351
+ when 0x32 then swap8(Operand.new(type: :register8, value: :d))
352
+ when 0x33 then swap8(Operand.new(type: :register8, value: :e))
353
+ when 0x34 then swap8(Operand.new(type: :register8, value: :h))
354
+ when 0x35 then swap8(Operand.new(type: :register8, value: :l))
355
+ when 0x36 then swap8(Operand.new(type: :indirect, value: :hl))
356
+ when 0x37 then swap8(Operand.new(type: :register8, value: :a))
357
+ when 0x38 then srl8(Operand.new(type: :register8, value: :b))
358
+ when 0x39 then srl8(Operand.new(type: :register8, value: :c))
359
+ when 0x3a then srl8(Operand.new(type: :register8, value: :d))
360
+ when 0x3b then srl8(Operand.new(type: :register8, value: :e))
361
+ when 0x3c then srl8(Operand.new(type: :register8, value: :h))
362
+ when 0x3d then srl8(Operand.new(type: :register8, value: :l))
363
+ when 0x3e then srl8(Operand.new(type: :indirect, value: :hl))
364
+ when 0x3f then srl8(Operand.new(type: :register8, value: :a))
365
+ when 0x40 then bit8(0, Operand.new(type: :register8, value: :b))
366
+ when 0x41 then bit8(0, Operand.new(type: :register8, value: :c))
367
+ when 0x42 then bit8(0, Operand.new(type: :register8, value: :d))
368
+ when 0x43 then bit8(0, Operand.new(type: :register8, value: :e))
369
+ when 0x44 then bit8(0, Operand.new(type: :register8, value: :h))
370
+ when 0x45 then bit8(0, Operand.new(type: :register8, value: :l))
371
+ when 0x46 then bit8(0, Operand.new(type: :indirect, value: :hl))
372
+ when 0x47 then bit8(0, Operand.new(type: :register8, value: :a))
373
+ when 0x48 then bit8(1, Operand.new(type: :register8, value: :b))
374
+ when 0x49 then bit8(1, Operand.new(type: :register8, value: :c))
375
+ when 0x4a then bit8(1, Operand.new(type: :register8, value: :d))
376
+ when 0x4b then bit8(1, Operand.new(type: :register8, value: :e))
377
+ when 0x4c then bit8(1, Operand.new(type: :register8, value: :h))
378
+ when 0x4d then bit8(1, Operand.new(type: :register8, value: :l))
379
+ when 0x4e then bit8(1, Operand.new(type: :indirect, value: :hl))
380
+ when 0x4f then bit8(1, Operand.new(type: :register8, value: :a))
381
+ when 0x50 then bit8(2, Operand.new(type: :register8, value: :b))
382
+ when 0x51 then bit8(2, Operand.new(type: :register8, value: :c))
383
+ when 0x52 then bit8(2, Operand.new(type: :register8, value: :d))
384
+ when 0x53 then bit8(2, Operand.new(type: :register8, value: :e))
385
+ when 0x54 then bit8(2, Operand.new(type: :register8, value: :h))
386
+ when 0x55 then bit8(2, Operand.new(type: :register8, value: :l))
387
+ when 0x56 then bit8(2, Operand.new(type: :indirect, value: :hl))
388
+ when 0x57 then bit8(2, Operand.new(type: :register8, value: :a))
389
+ when 0x58 then bit8(3, Operand.new(type: :register8, value: :b))
390
+ when 0x59 then bit8(3, Operand.new(type: :register8, value: :c))
391
+ when 0x5a then bit8(3, Operand.new(type: :register8, value: :d))
392
+ when 0x5b then bit8(3, Operand.new(type: :register8, value: :e))
393
+ when 0x5c then bit8(3, Operand.new(type: :register8, value: :h))
394
+ when 0x5d then bit8(3, Operand.new(type: :register8, value: :l))
395
+ when 0x5e then bit8(3, Operand.new(type: :indirect, value: :hl))
396
+ when 0x5f then bit8(3, Operand.new(type: :register8, value: :a))
397
+ when 0x60 then bit8(4, Operand.new(type: :register8, value: :b))
398
+ when 0x61 then bit8(4, Operand.new(type: :register8, value: :c))
399
+ when 0x62 then bit8(4, Operand.new(type: :register8, value: :d))
400
+ when 0x63 then bit8(4, Operand.new(type: :register8, value: :e))
401
+ when 0x64 then bit8(4, Operand.new(type: :register8, value: :h))
402
+ when 0x65 then bit8(4, Operand.new(type: :register8, value: :l))
403
+ when 0x66 then bit8(4, Operand.new(type: :indirect, value: :hl))
404
+ when 0x67 then bit8(4, Operand.new(type: :register8, value: :a))
405
+ when 0x68 then bit8(5, Operand.new(type: :register8, value: :b))
406
+ when 0x69 then bit8(5, Operand.new(type: :register8, value: :c))
407
+ when 0x6a then bit8(5, Operand.new(type: :register8, value: :d))
408
+ when 0x6b then bit8(5, Operand.new(type: :register8, value: :e))
409
+ when 0x6c then bit8(5, Operand.new(type: :register8, value: :h))
410
+ when 0x6d then bit8(5, Operand.new(type: :register8, value: :l))
411
+ when 0x6e then bit8(5, Operand.new(type: :indirect, value: :hl))
412
+ when 0x6f then bit8(5, Operand.new(type: :register8, value: :a))
413
+ when 0x70 then bit8(6, Operand.new(type: :register8, value: :b))
414
+ when 0x71 then bit8(6, Operand.new(type: :register8, value: :c))
415
+ when 0x72 then bit8(6, Operand.new(type: :register8, value: :d))
416
+ when 0x73 then bit8(6, Operand.new(type: :register8, value: :e))
417
+ when 0x74 then bit8(6, Operand.new(type: :register8, value: :h))
418
+ when 0x75 then bit8(6, Operand.new(type: :register8, value: :l))
419
+ when 0x76 then bit8(6, Operand.new(type: :indirect, value: :hl))
420
+ when 0x77 then bit8(6, Operand.new(type: :register8, value: :a))
421
+ when 0x78 then bit8(7, Operand.new(type: :register8, value: :b))
422
+ when 0x79 then bit8(7, Operand.new(type: :register8, value: :c))
423
+ when 0x7a then bit8(7, Operand.new(type: :register8, value: :d))
424
+ when 0x7b then bit8(7, Operand.new(type: :register8, value: :e))
425
+ when 0x7c then bit8(7, Operand.new(type: :register8, value: :h))
426
+ when 0x7d then bit8(7, Operand.new(type: :register8, value: :l))
427
+ when 0x7e then bit8(7, Operand.new(type: :indirect, value: :hl))
428
+ when 0x7f then bit8(7, Operand.new(type: :register8, value: :a))
429
+ when 0x80 then res8(0, Operand.new(type: :register8, value: :b))
430
+ when 0x81 then res8(0, Operand.new(type: :register8, value: :c))
431
+ when 0x82 then res8(0, Operand.new(type: :register8, value: :d))
432
+ when 0x83 then res8(0, Operand.new(type: :register8, value: :e))
433
+ when 0x84 then res8(0, Operand.new(type: :register8, value: :h))
434
+ when 0x85 then res8(0, Operand.new(type: :register8, value: :l))
435
+ when 0x86 then res8(0, Operand.new(type: :indirect, value: :hl))
436
+ when 0x87 then res8(0, Operand.new(type: :register8, value: :a))
437
+ when 0x88 then res8(1, Operand.new(type: :register8, value: :b))
438
+ when 0x89 then res8(1, Operand.new(type: :register8, value: :c))
439
+ when 0x8a then res8(1, Operand.new(type: :register8, value: :d))
440
+ when 0x8b then res8(1, Operand.new(type: :register8, value: :e))
441
+ when 0x8c then res8(1, Operand.new(type: :register8, value: :h))
442
+ when 0x8d then res8(1, Operand.new(type: :register8, value: :l))
443
+ when 0x8e then res8(1, Operand.new(type: :indirect, value: :hl))
444
+ when 0x8f then res8(1, Operand.new(type: :register8, value: :a))
445
+ when 0x90 then res8(2, Operand.new(type: :register8, value: :b))
446
+ when 0x91 then res8(2, Operand.new(type: :register8, value: :c))
447
+ when 0x92 then res8(2, Operand.new(type: :register8, value: :d))
448
+ when 0x93 then res8(2, Operand.new(type: :register8, value: :e))
449
+ when 0x94 then res8(2, Operand.new(type: :register8, value: :h))
450
+ when 0x95 then res8(2, Operand.new(type: :register8, value: :l))
451
+ when 0x96 then res8(2, Operand.new(type: :indirect, value: :hl))
452
+ when 0x97 then res8(2, Operand.new(type: :register8, value: :a))
453
+ when 0x98 then res8(3, Operand.new(type: :register8, value: :b))
454
+ when 0x99 then res8(3, Operand.new(type: :register8, value: :c))
455
+ when 0x9a then res8(3, Operand.new(type: :register8, value: :d))
456
+ when 0x9b then res8(3, Operand.new(type: :register8, value: :e))
457
+ when 0x9c then res8(3, Operand.new(type: :register8, value: :h))
458
+ when 0x9d then res8(3, Operand.new(type: :register8, value: :l))
459
+ when 0x9e then res8(3, Operand.new(type: :indirect, value: :hl))
460
+ when 0x9f then res8(3, Operand.new(type: :register8, value: :a))
461
+ when 0xa0 then res8(4, Operand.new(type: :register8, value: :b))
462
+ when 0xa1 then res8(4, Operand.new(type: :register8, value: :c))
463
+ when 0xa2 then res8(4, Operand.new(type: :register8, value: :d))
464
+ when 0xa3 then res8(4, Operand.new(type: :register8, value: :e))
465
+ when 0xa4 then res8(4, Operand.new(type: :register8, value: :h))
466
+ when 0xa5 then res8(4, Operand.new(type: :register8, value: :l))
467
+ when 0xa6 then res8(4, Operand.new(type: :indirect, value: :hl))
468
+ when 0xa7 then res8(4, Operand.new(type: :register8, value: :a))
469
+ when 0xa8 then res8(5, Operand.new(type: :register8, value: :b))
470
+ when 0xa9 then res8(5, Operand.new(type: :register8, value: :c))
471
+ when 0xaa then res8(5, Operand.new(type: :register8, value: :d))
472
+ when 0xab then res8(5, Operand.new(type: :register8, value: :e))
473
+ when 0xac then res8(5, Operand.new(type: :register8, value: :h))
474
+ when 0xad then res8(5, Operand.new(type: :register8, value: :l))
475
+ when 0xae then res8(5, Operand.new(type: :indirect, value: :hl))
476
+ when 0xaf then res8(5, Operand.new(type: :register8, value: :a))
477
+ when 0xb0 then res8(6, Operand.new(type: :register8, value: :b))
478
+ when 0xb1 then res8(6, Operand.new(type: :register8, value: :c))
479
+ when 0xb2 then res8(6, Operand.new(type: :register8, value: :d))
480
+ when 0xb3 then res8(6, Operand.new(type: :register8, value: :e))
481
+ when 0xb4 then res8(6, Operand.new(type: :register8, value: :h))
482
+ when 0xb5 then res8(6, Operand.new(type: :register8, value: :l))
483
+ when 0xb6 then res8(6, Operand.new(type: :indirect, value: :hl))
484
+ when 0xb7 then res8(6, Operand.new(type: :register8, value: :a))
485
+ when 0xb8 then res8(7, Operand.new(type: :register8, value: :b))
486
+ when 0xb9 then res8(7, Operand.new(type: :register8, value: :c))
487
+ when 0xba then res8(7, Operand.new(type: :register8, value: :d))
488
+ when 0xbb then res8(7, Operand.new(type: :register8, value: :e))
489
+ when 0xbc then res8(7, Operand.new(type: :register8, value: :h))
490
+ when 0xbd then res8(7, Operand.new(type: :register8, value: :l))
491
+ when 0xbe then res8(7, Operand.new(type: :indirect, value: :hl))
492
+ when 0xbf then res8(7, Operand.new(type: :register8, value: :a))
493
+ when 0xc0 then set8(0, Operand.new(type: :register8, value: :b))
494
+ when 0xc1 then set8(0, Operand.new(type: :register8, value: :c))
495
+ when 0xc2 then set8(0, Operand.new(type: :register8, value: :d))
496
+ when 0xc3 then set8(0, Operand.new(type: :register8, value: :e))
497
+ when 0xc4 then set8(0, Operand.new(type: :register8, value: :h))
498
+ when 0xc5 then set8(0, Operand.new(type: :register8, value: :l))
499
+ when 0xc6 then set8(0, Operand.new(type: :indirect, value: :hl))
500
+ when 0xc7 then set8(0, Operand.new(type: :register8, value: :a))
501
+ when 0xc8 then set8(1, Operand.new(type: :register8, value: :b))
502
+ when 0xc9 then set8(1, Operand.new(type: :register8, value: :c))
503
+ when 0xca then set8(1, Operand.new(type: :register8, value: :d))
504
+ when 0xcb then set8(1, Operand.new(type: :register8, value: :e))
505
+ when 0xcc then set8(1, Operand.new(type: :register8, value: :h))
506
+ when 0xcd then set8(1, Operand.new(type: :register8, value: :l))
507
+ when 0xce then set8(1, Operand.new(type: :indirect, value: :hl))
508
+ when 0xcf then set8(1, Operand.new(type: :register8, value: :a))
509
+ when 0xd0 then set8(2, Operand.new(type: :register8, value: :b))
510
+ when 0xd1 then set8(2, Operand.new(type: :register8, value: :c))
511
+ when 0xd2 then set8(2, Operand.new(type: :register8, value: :d))
512
+ when 0xd3 then set8(2, Operand.new(type: :register8, value: :e))
513
+ when 0xd4 then set8(2, Operand.new(type: :register8, value: :h))
514
+ when 0xd5 then set8(2, Operand.new(type: :register8, value: :l))
515
+ when 0xd6 then set8(2, Operand.new(type: :indirect, value: :hl))
516
+ when 0xd7 then set8(2, Operand.new(type: :register8, value: :a))
517
+ when 0xd8 then set8(3, Operand.new(type: :register8, value: :b))
518
+ when 0xd9 then set8(3, Operand.new(type: :register8, value: :c))
519
+ when 0xda then set8(3, Operand.new(type: :register8, value: :d))
520
+ when 0xdb then set8(3, Operand.new(type: :register8, value: :e))
521
+ when 0xdc then set8(3, Operand.new(type: :register8, value: :h))
522
+ when 0xdd then set8(3, Operand.new(type: :register8, value: :l))
523
+ when 0xde then set8(3, Operand.new(type: :indirect, value: :hl))
524
+ when 0xdf then set8(3, Operand.new(type: :register8, value: :a))
525
+ when 0xe0 then set8(4, Operand.new(type: :register8, value: :b))
526
+ when 0xe1 then set8(4, Operand.new(type: :register8, value: :c))
527
+ when 0xe2 then set8(4, Operand.new(type: :register8, value: :d))
528
+ when 0xe3 then set8(4, Operand.new(type: :register8, value: :e))
529
+ when 0xe4 then set8(4, Operand.new(type: :register8, value: :h))
530
+ when 0xe5 then set8(4, Operand.new(type: :register8, value: :l))
531
+ when 0xe6 then set8(4, Operand.new(type: :indirect, value: :hl))
532
+ when 0xe7 then set8(4, Operand.new(type: :register8, value: :a))
533
+ when 0xe8 then set8(5, Operand.new(type: :register8, value: :b))
534
+ when 0xe9 then set8(5, Operand.new(type: :register8, value: :c))
535
+ when 0xea then set8(5, Operand.new(type: :register8, value: :d))
536
+ when 0xeb then set8(5, Operand.new(type: :register8, value: :e))
537
+ when 0xec then set8(5, Operand.new(type: :register8, value: :h))
538
+ when 0xed then set8(5, Operand.new(type: :register8, value: :l))
539
+ when 0xee then set8(5, Operand.new(type: :indirect, value: :hl))
540
+ when 0xef then set8(5, Operand.new(type: :register8, value: :a))
541
+ when 0xf0 then set8(6, Operand.new(type: :register8, value: :b))
542
+ when 0xf1 then set8(6, Operand.new(type: :register8, value: :c))
543
+ when 0xf2 then set8(6, Operand.new(type: :register8, value: :d))
544
+ when 0xf3 then set8(6, Operand.new(type: :register8, value: :e))
545
+ when 0xf4 then set8(6, Operand.new(type: :register8, value: :h))
546
+ when 0xf5 then set8(6, Operand.new(type: :register8, value: :l))
547
+ when 0xf6 then set8(6, Operand.new(type: :indirect, value: :hl))
548
+ when 0xf7 then set8(6, Operand.new(type: :register8, value: :a))
549
+ when 0xf8 then set8(7, Operand.new(type: :register8, value: :b))
550
+ when 0xf9 then set8(7, Operand.new(type: :register8, value: :c))
551
+ when 0xfa then set8(7, Operand.new(type: :register8, value: :d))
552
+ when 0xfb then set8(7, Operand.new(type: :register8, value: :e))
553
+ when 0xfc then set8(7, Operand.new(type: :register8, value: :h))
554
+ when 0xfd then set8(7, Operand.new(type: :register8, value: :l))
555
+ when 0xfe then set8(7, Operand.new(type: :indirect, value: :hl))
556
+ when 0xff then set8(7, Operand.new(type: :register8, value: :a))
1467
557
  else
1468
558
  raise "unknown opcode: 0xcb 0x#{'%02x' % opcode}"
1469
559
  end
1470
560
  else
1471
561
  raise "unknown opcode: 0x#{'%02x' % opcode}"
1472
562
  end
1473
-
1474
- @sp &= 0xffff
1475
-
1476
- opcode_kind = cbprefixed ? 'cbprefixed' : 'unprefixed'
1477
- opcode_str = "0x#{'%02X' % opcode}"
1478
- cycles = @opcodes[opcode_kind][opcode_str]['cycles']
1479
-
1480
- branched ? cycles.max : cycles.min
1481
563
  end
1482
564
 
1483
565
  private
@@ -1511,24 +593,27 @@ module Rubyboy
1511
593
  end
1512
594
 
1513
595
  def print_log(opcode)
1514
- puts "OP: 0x#{'%02x' % opcode}, PC: 0x#{'%04x' % @pc}, SP: 0x#{'%04x' % @sp}, A: 0x#{'%02x' % @a.value}, B: 0x#{'%02x' % @b.value}, C: 0x#{'%02x' % @c.value}, D: 0x#{'%02x' % @d.value}, E: 0x#{'%02x' % @e.value}, H: 0x#{'%02x' % @h.value}, L: 0x#{'%02x' % @l.value}, F: 0x#{'%02x' % @f.value}"
596
+ puts "PC: 0x#{'%04x' % @pc}, Opcode: 0x#{'%02x' % opcode}, AF: 0x#{'%04x' % @registers.read16(:af)}, BC: 0x#{'%04x' % @registers.read16(:bc)}, HL: 0x#{'%04x' % @registers.read16(:hl)}, SP: 0x#{'%04x' % @sp}"
1515
597
  end
1516
598
 
1517
599
  def flags
600
+ f_value = @registers.read8(:f)
1518
601
  {
1519
- z: @f.value[7] == 1,
1520
- n: @f.value[6] == 1,
1521
- h: @f.value[5] == 1,
1522
- c: @f.value[4] == 1
602
+ z: f_value[7] == 1,
603
+ n: f_value[6] == 1,
604
+ h: f_value[5] == 1,
605
+ c: f_value[4] == 1
1523
606
  }
1524
607
  end
1525
608
 
1526
609
  def update_flags(z: flags[:z], n: flags[:n], h: flags[:h], c: flags[:c])
1527
- @f.value = 0x00
1528
- @f.value |= 0x80 if z
1529
- @f.value |= 0x40 if n
1530
- @f.value |= 0x20 if h
1531
- @f.value |= 0x10 if c
610
+ f_value = 0x00
611
+ f_value |= 0x80 if z
612
+ f_value |= 0x40 if n
613
+ f_value |= 0x20 if h
614
+ f_value |= 0x10 if c
615
+
616
+ @registers.write8(:f, f_value)
1532
617
  end
1533
618
 
1534
619
  def bool_to_integer(bool)
@@ -1543,205 +628,635 @@ module Rubyboy
1543
628
  @pc += byte
1544
629
  end
1545
630
 
1546
- def convert_to_twos_complement(byte)
631
+ def to_signed_byte(byte)
1547
632
  byte &= 0xff
1548
633
  byte > 127 ? byte - 256 : byte
1549
634
  end
1550
635
 
1551
- def ld8(x, y)
1552
- x.value = y.value
636
+ def rlca
637
+ a_value = @registers.read8(:a)
638
+ a_value = ((a_value << 1) | (a_value >> 7)) & 0xff
639
+ @registers.write8(:a, a_value)
640
+ update_flags(
641
+ z: false,
642
+ n: false,
643
+ h: false,
644
+ c: a_value[0] == 1
645
+ )
646
+
647
+ 4
648
+ end
649
+
650
+ def rrca
651
+ a_value = @registers.read8(:a)
652
+ a_value = ((a_value >> 1) | (a_value << 7)) & 0xff
653
+ @registers.write8(:a, a_value)
654
+ update_flags(
655
+ z: false,
656
+ n: false,
657
+ h: false,
658
+ c: a_value[7] == 1
659
+ )
660
+
661
+ 4
662
+ end
663
+
664
+ def rra
665
+ a_value = @registers.read8(:a)
666
+ cflag = a_value[0] == 1
667
+ a_value = ((a_value >> 1) | (bool_to_integer(flags[:c]) << 7)) & 0xff
668
+ @registers.write8(:a, a_value)
669
+ update_flags(
670
+ z: false,
671
+ n: false,
672
+ h: false,
673
+ c: cflag
674
+ )
675
+
676
+ 4
677
+ end
678
+
679
+ def rla
680
+ a_value = @registers.read8(:a)
681
+ cflag = a_value[7] == 1
682
+ a_value = ((a_value << 1) | bool_to_integer(flags[:c])) & 0xff
683
+ @registers.write8(:a, a_value)
684
+ update_flags(
685
+ z: false,
686
+ n: false,
687
+ h: false,
688
+ c: cflag
689
+ )
690
+
691
+ 4
692
+ end
693
+
694
+ def daa
695
+ a_value = @registers.read8(:a)
696
+ if flags[:n]
697
+ a_value -= 0x06 if flags[:h]
698
+ a_value -= 0x60 if flags[:c]
699
+ else
700
+ if flags[:c] || a_value > 0x99
701
+ a_value += 0x60
702
+ update_flags(c: true)
703
+ end
704
+ a_value += 0x06 if flags[:h] || (a_value & 0x0f) > 0x09
705
+ end
706
+
707
+ @registers.write8(:a, a_value)
708
+ update_flags(
709
+ z: @registers.read8(:a).zero?,
710
+ h: false
711
+ )
712
+
713
+ 4
714
+ end
715
+
716
+ def cpl
717
+ @registers.write8(:a, ~@registers.read8(:a))
718
+ update_flags(
719
+ n: true,
720
+ h: true
721
+ )
722
+
723
+ 4
1553
724
  end
1554
725
 
1555
- def add8(x, y)
1556
- hflag = (x.value & 0x0f) + (y.value & 0x0f) > 0x0f
1557
- cflag = x.value + y.value > 0xff
1558
- x.value += y.value
726
+ def scf
1559
727
  update_flags(
1560
- z: x.value.zero?,
728
+ n: false,
729
+ h: false,
730
+ c: true
731
+ )
732
+
733
+ 4
734
+ end
735
+
736
+ def ccf
737
+ update_flags(
738
+ n: false,
739
+ h: false,
740
+ c: !flags[:c]
741
+ )
742
+
743
+ 4
744
+ end
745
+
746
+ def inc8(x)
747
+ value = (get_value(x) + 1) & 0xff
748
+ set_value(x, value)
749
+ update_flags(
750
+ z: value.zero?,
751
+ n: false,
752
+ h: (value & 0x0f).zero?
753
+ )
754
+
755
+ x.type == :register8 ? 4 : 12
756
+ end
757
+
758
+ def inc16(x)
759
+ set_value(x, get_value(x) + 1)
760
+
761
+ 8
762
+ end
763
+
764
+ def dec8(x)
765
+ value = (get_value(x) - 1) & 0xff
766
+ set_value(x, value)
767
+ update_flags(
768
+ z: value.zero?,
769
+ n: true,
770
+ h: (value & 0x0f) == 0x0f
771
+ )
772
+
773
+ x.type == :register8 ? 4 : 12
774
+ end
775
+
776
+ def dec16(x)
777
+ set_value(x, get_value(x) - 1)
778
+
779
+ 8
780
+ end
781
+
782
+ def add8(x)
783
+ a_value = @registers.read8(:a)
784
+ x_value = get_value(x)
785
+
786
+ hflag = (a_value & 0x0f) + (x_value & 0x0f) > 0x0f
787
+ cflag = a_value + x_value > 0xff
788
+
789
+ a_value += x_value
790
+ @registers.write8(:a, a_value)
791
+ update_flags(
792
+ z: @registers.read8(:a).zero?,
1561
793
  n: false,
1562
794
  h: hflag,
1563
795
  c: cflag
1564
796
  )
797
+
798
+ x.type == :register8 ? 4 : 8
1565
799
  end
1566
800
 
1567
- def adc8(x, y)
1568
- c_value = bool_to_integer(flags[:c])
1569
- hflag = (x.value & 0x0f) + (y.value & 0x0f) + c_value > 0x0f
1570
- cflag = x.value + y.value + c_value > 0xff
1571
- x.value += y.value + c_value
801
+ def add16(x, y)
802
+ x_value = get_value(x)
803
+ y_value = get_value(y)
804
+
805
+ hflag = (x_value & 0x0fff) + (y_value & 0x0fff) > 0x0fff
806
+ cflag = x_value + y_value > 0xffff
807
+
808
+ set_value(x, x_value + y_value)
809
+ update_flags(
810
+ n: false,
811
+ h: hflag,
812
+ c: cflag
813
+ )
814
+
815
+ 8
816
+ end
817
+
818
+ def add_sp_r8
819
+ byte = to_signed_byte(read_byte_and_advance_pc)
820
+
821
+ hflag = (@sp & 0x0f) + (byte & 0x0f) > 0x0f
822
+ cflag = (@sp & 0xff) + (byte & 0xff) > 0xff
823
+
824
+ @sp += byte
825
+ @sp &= 0xffff
1572
826
  update_flags(
1573
- z: x.value.zero?,
827
+ z: false,
1574
828
  n: false,
1575
829
  h: hflag,
1576
830
  c: cflag
1577
831
  )
832
+
833
+ 16
1578
834
  end
1579
835
 
1580
836
  def sub8(x)
1581
- hflag = (x.value & 0x0f) > (@a.value & 0x0f)
1582
- cflag = x.value > @a.value
1583
- @a.value -= x.value
837
+ a_value = @registers.read8(:a)
838
+ x_value = get_value(x)
839
+
840
+ hflag = (x_value & 0x0f) > (a_value & 0x0f)
841
+ cflag = x_value > a_value
842
+ a_value -= x_value
843
+ @registers.write8(:a, a_value)
1584
844
  update_flags(
1585
- z: @a.value.zero?,
845
+ z: a_value.zero?,
1586
846
  n: true,
1587
847
  h: hflag,
1588
848
  c: cflag
1589
849
  )
850
+
851
+ x.type == :register8 ? 4 : 8
852
+ end
853
+
854
+ def adc8(x)
855
+ a_value = @registers.read8(:a)
856
+ x_value = get_value(x)
857
+ c_value = bool_to_integer(flags[:c])
858
+
859
+ hflag = (a_value & 0x0f) + (x_value & 0x0f) + c_value > 0x0f
860
+ cflag = a_value + x_value + c_value > 0xff
861
+ a_value += x_value + c_value
862
+ @registers.write8(:a, a_value)
863
+ update_flags(
864
+ z: @registers.read8(:a).zero?,
865
+ n: false,
866
+ h: hflag,
867
+ c: cflag
868
+ )
869
+
870
+ x.type == :register8 ? 4 : 8
1590
871
  end
1591
872
 
1592
873
  def sbc8(x)
874
+ a_value = @registers.read8(:a)
875
+ x_value = get_value(x)
1593
876
  c_value = bool_to_integer(flags[:c])
1594
- hflag = (x.value & 0x0f) + c_value > (@a.value & 0x0f)
1595
- cflag = x.value + c_value > @a.value
1596
- @a.value -= x.value + c_value
877
+
878
+ hflag = (x_value & 0x0f) + c_value > (a_value & 0x0f)
879
+ cflag = x_value + c_value > a_value
880
+ a_value -= x_value + c_value
881
+ @registers.write8(:a, a_value)
1597
882
  update_flags(
1598
- z: @a.value.zero?,
883
+ z: @registers.read8(:a).zero?,
1599
884
  n: true,
1600
885
  h: hflag,
1601
886
  c: cflag
1602
887
  )
888
+
889
+ x.type == :register8 ? 4 : 8
1603
890
  end
1604
891
 
1605
892
  def and8(x)
1606
- @a.value &= x.value
893
+ a_value = @registers.read8(:a) & get_value(x)
894
+ @registers.write8(:a, a_value)
1607
895
  update_flags(
1608
- z: @a.value.zero?,
896
+ z: a_value.zero?,
1609
897
  n: false,
1610
898
  h: true,
1611
899
  c: false
1612
900
  )
901
+
902
+ x.type == :register8 ? 4 : 8
1613
903
  end
1614
904
 
1615
905
  def or8(x)
1616
- @a.value |= x.value
906
+ a_value = @registers.read8(:a) | get_value(x)
907
+ @registers.write8(:a, a_value)
1617
908
  update_flags(
1618
- z: @a.value.zero?,
909
+ z: a_value.zero?,
1619
910
  n: false,
1620
911
  h: false,
1621
912
  c: false
1622
913
  )
914
+
915
+ x.type == :register8 ? 4 : 8
1623
916
  end
1624
917
 
1625
918
  def xor8(x)
1626
- @a.value ^= x.value
919
+ a_value = @registers.read8(:a) ^ get_value(x)
920
+ @registers.write8(:a, a_value)
1627
921
  update_flags(
1628
- z: @a.value.zero?,
922
+ z: a_value.zero?,
1629
923
  n: false,
1630
924
  h: false,
1631
925
  c: false
1632
926
  )
927
+
928
+ x.type == :register8 ? 4 : 8
929
+ end
930
+
931
+ def push16(register16)
932
+ value = @registers.read16(register16)
933
+ @sp -= 2
934
+ write_word(@sp, value)
935
+
936
+ 16
937
+ end
938
+
939
+ def pop16(register16)
940
+ @registers.write16(register16, read_word(@sp))
941
+ @sp += 2
942
+
943
+ 12
944
+ end
945
+
946
+ def halt
947
+ @halted = true
948
+
949
+ 4
950
+ end
951
+
952
+ def ld8(x, y)
953
+ value = get_value(y)
954
+ set_value(x, value)
955
+
956
+ return 4 if x.type == :register8 && y.type == :register8
957
+ return 12 if x.type == :indirect && y.type == :immediate8
958
+ return 12 if x.type == :ff00 || y.type == :ff00
959
+ return 16 if x.type == :direct8 || y.type == :direct8
960
+
961
+ 8
962
+ end
963
+
964
+ def ld16(x, y)
965
+ value = get_value(y)
966
+ set_value(x, value)
967
+
968
+ return 8 if y.type == :register16
969
+ return 20 if y.type == :sp
970
+
971
+ 12
972
+ end
973
+
974
+ def ld_hl_sp_r8
975
+ byte = to_signed_byte(read_byte_and_advance_pc)
976
+
977
+ hflag = (@sp & 0x0f) + (byte & 0x0f) > 0x0f
978
+ cflag = (@sp & 0xff) + (byte & 0xff) > 0xff
979
+ @registers.write16(:hl, @sp + byte)
980
+ update_flags(
981
+ z: false,
982
+ n: false,
983
+ h: hflag,
984
+ c: cflag
985
+ )
986
+
987
+ 12
988
+ end
989
+
990
+ def ei
991
+ @ime_delay = true
992
+
993
+ 4
994
+ end
995
+
996
+ def di
997
+ @ime_delay = false
998
+ @ime = false
999
+
1000
+ 4
1633
1001
  end
1634
1002
 
1635
1003
  def cp8(x)
1636
- hflag = (x.value & 0x0f) > (@a.value & 0x0f)
1637
- cflag = x.value > @a.value
1004
+ a_value = @registers.read8(:a)
1005
+ x_value = get_value(x)
1006
+
1007
+ hflag = (x_value & 0x0f) > (a_value & 0x0f)
1008
+ cflag = x_value > a_value
1638
1009
  update_flags(
1639
- z: @a.value == x.value,
1010
+ z: a_value == x_value,
1640
1011
  n: true,
1641
1012
  h: hflag,
1642
1013
  c: cflag
1643
1014
  )
1015
+
1016
+ x.type == :register8 ? 4 : 8
1017
+ end
1018
+
1019
+ def rst(addr)
1020
+ @sp -= 2
1021
+ write_word(@sp, @pc)
1022
+ @pc = addr
1023
+
1024
+ 16
1025
+ end
1026
+
1027
+ def jr(condition: true)
1028
+ value = to_signed_byte(read_byte_and_advance_pc)
1029
+ @pc += value if condition
1030
+
1031
+ condition ? 12 : 8
1032
+ end
1033
+
1034
+ def jp(x, condition: true)
1035
+ addr = get_value(x)
1036
+ @pc = addr if condition
1037
+
1038
+ return 4 if x.type == :register16
1039
+
1040
+ condition ? 16 : 12
1041
+ end
1042
+
1043
+ def call16(x, condition: true)
1044
+ addr = get_value(x)
1045
+ if condition
1046
+ @sp -= 2
1047
+ write_word(@sp, @pc)
1048
+ @pc = addr
1049
+ end
1050
+
1051
+ condition ? 24 : 12
1052
+ end
1053
+
1054
+ def ret
1055
+ @pc = read_word(@sp)
1056
+ @sp += 2
1057
+
1058
+ 16
1059
+ end
1060
+
1061
+ def ret_if(condition)
1062
+ ret if condition
1063
+
1064
+ condition ? 20 : 8
1065
+ end
1066
+
1067
+ def reti
1068
+ @ime = true
1069
+ ret
1644
1070
  end
1645
1071
 
1646
1072
  def rlc8(x)
1647
- x.value = (x.value << 1) | (x.value >> 7)
1073
+ value = get_value(x)
1074
+ value = (value << 1) | (value >> 7)
1075
+ set_value(x, value)
1648
1076
  update_flags(
1649
- z: x.value.zero?,
1077
+ z: value.zero?,
1650
1078
  n: false,
1651
1079
  h: false,
1652
- c: x.value[0] == 1
1080
+ c: value[0] == 1
1653
1081
  )
1082
+
1083
+ x.type == :register8 ? 8 : 16
1654
1084
  end
1655
1085
 
1656
1086
  def rrc8(x)
1657
- x.value = (x.value >> 1) | (x.value << 7)
1087
+ value = get_value(x)
1088
+ value = (value >> 1) | (value << 7)
1089
+ set_value(x, value)
1658
1090
  update_flags(
1659
- z: x.value.zero?,
1091
+ z: value.zero?,
1660
1092
  n: false,
1661
1093
  h: false,
1662
- c: x.value[7] == 1
1094
+ c: value[7] == 1
1663
1095
  )
1096
+
1097
+ x.type == :register8 ? 8 : 16
1664
1098
  end
1665
1099
 
1666
1100
  def rl8(x)
1667
- cflag = x.value[7] == 1
1668
- x.value = (x.value << 1) | bool_to_integer(flags[:c])
1101
+ value = get_value(x)
1102
+ cflag = value[7] == 1
1103
+ value = ((value << 1) | bool_to_integer(flags[:c])) & 0xff
1104
+ set_value(x, value)
1669
1105
  update_flags(
1670
- z: x.value.zero?,
1106
+ z: value.zero?,
1671
1107
  n: false,
1672
1108
  h: false,
1673
1109
  c: cflag
1674
1110
  )
1111
+
1112
+ x.type == :register8 ? 8 : 16
1675
1113
  end
1676
1114
 
1677
1115
  def rr8(x)
1678
- cflag = x.value[0] == 1
1679
- x.value = (x.value >> 1) | (bool_to_integer(flags[:c]) << 7)
1116
+ value = get_value(x)
1117
+ cflag = value[0] == 1
1118
+ value = (value >> 1) | (bool_to_integer(flags[:c]) << 7)
1119
+ set_value(x, value)
1680
1120
  update_flags(
1681
- z: x.value.zero?,
1121
+ z: value.zero?,
1682
1122
  n: false,
1683
1123
  h: false,
1684
1124
  c: cflag
1685
1125
  )
1126
+
1127
+ x.type == :register8 ? 8 : 16
1686
1128
  end
1687
1129
 
1688
1130
  def sla8(x)
1689
- cflag = x.value[7] == 1
1690
- x.value <<= 1
1131
+ value = get_value(x)
1132
+ cflag = value[7] == 1
1133
+ value <<= 1
1134
+ value &= 0xff
1135
+ set_value(x, value)
1691
1136
  update_flags(
1692
- z: x.value.zero?,
1137
+ z: value.zero?,
1693
1138
  n: false,
1694
1139
  h: false,
1695
1140
  c: cflag
1696
1141
  )
1142
+
1143
+ x.type == :register8 ? 8 : 16
1697
1144
  end
1698
1145
 
1699
1146
  def sra8(x)
1700
- cflag = x.value[0] == 1
1701
- x.value = (x.value >> 1) | (x.value[7] << 7)
1147
+ value = get_value(x)
1148
+ cflag = value[0] == 1
1149
+ value = (value >> 1) | (value[7] << 7)
1150
+ set_value(x, value)
1702
1151
  update_flags(
1703
- z: x.value.zero?,
1152
+ z: value.zero?,
1704
1153
  n: false,
1705
1154
  h: false,
1706
1155
  c: cflag
1707
1156
  )
1157
+
1158
+ x.type == :register8 ? 8 : 16
1708
1159
  end
1709
1160
 
1710
1161
  def swap8(x)
1711
- x.value = ((x.value & 0x0f) << 4) | ((x.value & 0xf0) >> 4)
1162
+ value = get_value(x)
1163
+ value = ((value & 0x0f) << 4) | ((value & 0xf0) >> 4)
1164
+ set_value(x, value)
1712
1165
  update_flags(
1713
- z: x.value.zero?,
1166
+ z: value.zero?,
1714
1167
  n: false,
1715
1168
  h: false,
1716
1169
  c: false
1717
1170
  )
1171
+
1172
+ x.type == :register8 ? 8 : 16
1718
1173
  end
1719
1174
 
1720
1175
  def srl8(x)
1721
- cflag = x.value[0] == 1
1722
- x.value >>= 1
1176
+ value = get_value(x)
1177
+ cflag = value[0] == 1
1178
+ value >>= 1
1179
+ set_value(x, value)
1723
1180
  update_flags(
1724
- z: x.value.zero?,
1181
+ z: value.zero?,
1725
1182
  n: false,
1726
1183
  h: false,
1727
1184
  c: cflag
1728
1185
  )
1186
+
1187
+ x.type == :register8 ? 8 : 16
1729
1188
  end
1730
1189
 
1731
1190
  def bit8(n, x)
1191
+ value = get_value(x)
1732
1192
  update_flags(
1733
- z: x.value[n].zero?,
1193
+ z: value[n].zero?,
1734
1194
  n: false,
1735
1195
  h: true
1736
1196
  )
1197
+
1198
+ x.type == :register8 ? 8 : 12
1199
+ end
1200
+
1201
+ def res8(n, x)
1202
+ value = get_value(x)
1203
+ value &= ((~(1 << n)) & 0xff)
1204
+ set_value(x, value)
1205
+
1206
+ x.type == :register8 ? 8 : 16
1737
1207
  end
1738
1208
 
1739
1209
  def set8(n, x)
1740
- x.value |= (1 << n)
1210
+ value = get_value(x)
1211
+ value |= (1 << n)
1212
+ set_value(x, value)
1213
+
1214
+ x.type == :register8 ? 8 : 16
1741
1215
  end
1742
1216
 
1743
- def res8(n, x)
1744
- x.value &= ((~(1 << n)) & 0xff)
1217
+ def get_value(operand)
1218
+ case operand.type
1219
+ when :register8 then @registers.read8(operand.value)
1220
+ when :register16 then @registers.read16(operand.value)
1221
+ when :sp then @sp
1222
+ when :immediate8 then read_byte_and_advance_pc
1223
+ when :immediate16 then read_word_and_advance_pc
1224
+ when :direct8 then read_byte(read_word_and_advance_pc)
1225
+ when :direct16 then read_word(read_word_and_advance_pc)
1226
+ when :indirect then read_byte(@registers.read16(operand.value))
1227
+ when :ff00 then read_byte(0xff00 + read_byte_and_advance_pc)
1228
+ when :ff00_c then read_byte(0xff00 + @registers.read8(:c))
1229
+ when :hl_inc
1230
+ value = read_byte(@registers.read16(:hl))
1231
+ @registers.increment16(:hl)
1232
+ value
1233
+ when :hl_dec
1234
+ value = read_byte(@registers.read16(:hl))
1235
+ @registers.decrement16(:hl)
1236
+ value
1237
+ else raise "unknown operand: #{operand}"
1238
+ end
1239
+ end
1240
+
1241
+ def set_value(operand, value)
1242
+ case operand.type
1243
+ when :register8 then @registers.write8(operand.value, value)
1244
+ when :register16 then @registers.write16(operand.value, value)
1245
+ when :sp then @sp = value & 0xffff
1246
+ when :direct8 then write_byte(read_word_and_advance_pc, value)
1247
+ when :direct16 then write_word(read_word_and_advance_pc, value)
1248
+ when :indirect then write_byte(@registers.read16(operand.value), value)
1249
+ when :ff00 then write_byte(0xff00 + read_byte_and_advance_pc, value)
1250
+ when :ff00_c then write_byte(0xff00 + @registers.read8(:c), value)
1251
+ when :hl_inc
1252
+ write_byte(@registers.read16(:hl), value)
1253
+ @registers.increment16(:hl)
1254
+ when :hl_dec
1255
+ write_byte(@registers.read16(:hl), value)
1256
+ @registers.decrement16(:hl)
1257
+ when :immediate8, :immediate16 then raise 'immediate type is read only'
1258
+ else raise "unknown operand: #{operand}"
1259
+ end
1745
1260
  end
1746
1261
  end
1747
1262
  end