GBRb 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/README.md +9 -1
- data/bin/gbrb +3 -3
- data/doc/images/blargg_cpu.png +0 -0
- data/doc/images/cpu_01.png +0 -0
- data/doc/images/cpu_03.png +0 -0
- data/doc/images/cpu_04.png +0 -0
- data/doc/images/cpu_05.png +0 -0
- data/doc/images/cpu_06.png +0 -0
- data/doc/images/cpu_07.png +0 -0
- data/doc/images/cpu_08.png +0 -0
- data/doc/images/cpu_09.png +0 -0
- data/doc/images/cpu_10.png +0 -0
- data/doc/images/cpu_11.png +0 -0
- data/doc/images/nintendo_logo.png +0 -0
- data/doc/images/opus5.png +0 -0
- data/doc/images/test.gb.png +0 -0
- data/doc/images/ttt.png +0 -0
- data/lib/gbrb.rb +7 -0
- data/lib/gbrb/cartridge.rb +21 -8
- data/lib/gbrb/cartridge/cartridge.rb +187 -0
- data/lib/gbrb/cpu/concatenated_register.rb +1 -1
- data/lib/gbrb/cpu/z80.rb +575 -498
- data/lib/gbrb/gb.rb +102 -32
- data/lib/gbrb/graphics.rb +1 -1
- data/lib/gbrb/graphics/gpu.rb +38 -30
- data/lib/gbrb/graphics/mode_clock.rb +31 -30
- data/lib/gbrb/graphics/screen_client.rb +3 -2
- data/lib/gbrb/instruction_set.rb +16 -0
- data/lib/gbrb/instruction_set/arithmetic.rb +238 -0
- data/lib/gbrb/instruction_set/bitwise.rb +64 -0
- data/lib/gbrb/instruction_set/boolean.rb +61 -0
- data/lib/gbrb/instruction_set/call.rb +40 -0
- data/lib/gbrb/instruction_set/carry.rb +23 -0
- data/lib/gbrb/instruction_set/cpl.rb +12 -0
- data/lib/gbrb/instruction_set/daa.rb +33 -0
- data/lib/gbrb/instruction_set/instruction.rb +23 -0
- data/lib/gbrb/instruction_set/jump.rb +47 -0
- data/lib/gbrb/instruction_set/ld.rb +241 -0
- data/lib/gbrb/instruction_set/return.rb +43 -0
- data/lib/gbrb/instruction_set/rotate.rb +178 -0
- data/lib/gbrb/instruction_set/rst.rb +16 -0
- data/lib/gbrb/instruction_set/special.rb +37 -0
- data/lib/gbrb/instruction_set/stack.rb +34 -0
- data/lib/gbrb/instruction_set/swap.rb +32 -0
- data/lib/gbrb/mmu.rb +60 -35
- data/lib/gbrb/options.rb +54 -0
- data/lib/gbrb/timer.rb +114 -0
- data/lib/gbrb/version.rb +1 -1
- data/misc/dump_diff +133 -0
- data/perf/cpu_perf_spec.rb +2 -2
- data/spec/gbrb/cartridge/cartridge_spec.rb +19 -0
- data/spec/gbrb/cartridge/mbc1_spec.rb +83 -0
- data/spec/gbrb/cpu/z80_spec.rb +92 -2
- data/spec/gbrb/{cpu/instruction_spec.rb → instruction_set/arithmetic_spec.rb} +21 -100
- data/spec/gbrb/instruction_set/boolean_spec.rb +50 -0
- data/spec/gbrb/instruction_set/instruction_spec.rb +22 -0
- data/spec/gbrb/instruction_set/ld_spec.rb +21 -0
- data/spec/gbrb/instruction_set/special_spec.rb +22 -0
- data/spec/gbrb/mmu_spec.rb +1 -1
- data/spec/gbrb/timer_spec.rb +26 -0
- metadata +53 -9
- data/lib/gbrb/cpu/instruction.rb +0 -648
- data/spec/gbrb/cartridge_spec.rb +0 -19
- data/spec/gbrb/graphics/mode_clock_spec.rb +0 -82
data/perf/cpu_perf_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'benchmark'
|
|
3
3
|
|
4
4
|
module GBRb::CPU
|
5
5
|
describe Z80 do
|
6
|
-
|
6
|
+
it "full speed" do
|
7
7
|
n = 1_000_000
|
8
8
|
class Z80
|
9
9
|
def fetch
|
@@ -14,7 +14,7 @@ module GBRb::CPU
|
|
14
14
|
|
15
15
|
@cpu = Z80.new
|
16
16
|
elapsed_time = Benchmark.realtime do
|
17
|
-
n.times { @cpu.
|
17
|
+
n.times { @cpu.step }
|
18
18
|
end
|
19
19
|
|
20
20
|
elapsed_time.should be < 1.0
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../../spec_helper.rb'
|
2
|
+
|
3
|
+
require_relative '../../../lib/gbrb/cartridge/cartridge'
|
4
|
+
|
5
|
+
module GBRb
|
6
|
+
describe BaseCartridge do
|
7
|
+
it "is initialized with an IO object" do
|
8
|
+
c = BaseCartridge.new StringIO.new ""
|
9
|
+
end
|
10
|
+
|
11
|
+
it "separates data into banks" do
|
12
|
+
raw_data = StringIO.new(0x01.chr * MEMORY_BANK_SIZE + 0x02.chr * MEMORY_BANK_SIZE)
|
13
|
+
c = BaseCartridge.new raw_data
|
14
|
+
c.rom_bank(0).each {|b| b.should eq 0x01}
|
15
|
+
c.rom_bank(1).each {|b| b.should eq 0x02}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require_relative '../../../lib/gbrb/cartridge'
|
3
|
+
|
4
|
+
module GBRb
|
5
|
+
describe MBC1 do
|
6
|
+
context 'post_initialize' do
|
7
|
+
let(:m) { MBC1.new StringIO.new '' }
|
8
|
+
|
9
|
+
it 'sets the mode' do
|
10
|
+
m.instance_eval('@mode').should eq :rom
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'sets the rom bank number' do
|
14
|
+
m.instance_eval('@rom_bank_number').should eq 1
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets the ram bank number' do
|
18
|
+
m.instance_eval('@ram_bank_number').should eq 0
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'sets the ram status' do
|
22
|
+
m.instance_eval('@ram_status').should eq :disabled
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'write_byte' do
|
27
|
+
let(:m) { MBC1.new StringIO.new '' }
|
28
|
+
|
29
|
+
context 'Swap current ROM bank' do
|
30
|
+
it 'changes rom bank' do
|
31
|
+
m.write_byte 0x2345, 7
|
32
|
+
m.instance_eval('@rom_bank_number').should eq 7
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'maps 0 to bank 1' do
|
36
|
+
m.write_byte 0x2941, 0
|
37
|
+
m.instance_eval('@rom_bank_number').should eq 1
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'only sets the lowest 5 bits' do
|
41
|
+
m.write_byte 0x3456, 0x33
|
42
|
+
m.instance_eval('@rom_bank_number').should eq 0x13
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'sets the upper 2 bits when in rom mode' do
|
46
|
+
m.instance_eval('@mode = :rom')
|
47
|
+
m.write_byte 0x4567, 3
|
48
|
+
m.instance_eval('@rom_bank_number').should eq 0x61
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'sets the ram bank when in ram mode' do
|
52
|
+
m.instance_eval('@mode = :ram')
|
53
|
+
m.write_byte 0x5678, 2
|
54
|
+
m.instance_eval('@ram_bank_number').should eq 0x02
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'Change operating mode' do
|
59
|
+
it '0x01 is RAM' do
|
60
|
+
m.write_byte 0x6820, 0x01
|
61
|
+
m.instance_eval('@mode').should eq :ram
|
62
|
+
end
|
63
|
+
|
64
|
+
it '0x00 is ROM' do
|
65
|
+
m.write_byte 0x7481, 0x00
|
66
|
+
m.instance_eval('@mode').should eq :rom
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'Enable/disable ram' do
|
71
|
+
it 'disables ram with 0x00' do
|
72
|
+
m.write_byte 0x1234, 0x00
|
73
|
+
m.instance_eval('@ram_status').should eq :disabled
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'enables ram with 0x0a' do
|
77
|
+
m.write_byte 0x0123, 0x0a
|
78
|
+
m.instance_eval('@ram_status').should eq :enabled
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/gbrb/cpu/z80_spec.rb
CHANGED
@@ -80,7 +80,11 @@ module GBRb
|
|
80
80
|
reg.clear
|
81
81
|
reg.read.should eq 0x00
|
82
82
|
run pop_opcode
|
83
|
-
|
83
|
+
if register == :af
|
84
|
+
reg.read.should eq value & 0xfff0
|
85
|
+
else
|
86
|
+
reg.read.should eq value
|
87
|
+
end
|
84
88
|
end
|
85
89
|
|
86
90
|
it "push/pop bc" do
|
@@ -455,6 +459,13 @@ module GBRb
|
|
455
459
|
run 0x28
|
456
460
|
@z.r.pc.read.should eq 0xff96
|
457
461
|
end
|
462
|
+
|
463
|
+
it "jr a16" do
|
464
|
+
@z.r.pc.store 0x0002
|
465
|
+
@z.mmu.write_word 0x0002, 0x4231
|
466
|
+
run 0xc3
|
467
|
+
@z.r.pc.read.should eq 0x4231
|
468
|
+
end
|
458
469
|
end
|
459
470
|
|
460
471
|
context "ld (immediate value)" do
|
@@ -623,6 +634,13 @@ module GBRb
|
|
623
634
|
@z.mmu.read_byte(address).should eq @z.r.a.read
|
624
635
|
@z.r.hl.read.should eq address + 1
|
625
636
|
end
|
637
|
+
|
638
|
+
it "ld a hl+" do
|
639
|
+
address = @z.r.hl.read
|
640
|
+
run 0x2a
|
641
|
+
@z.mmu.read_byte(address).should eq @z.r.a.read
|
642
|
+
@z.r.hl.read.should eq address +1
|
643
|
+
end
|
626
644
|
end
|
627
645
|
|
628
646
|
context "ld decrement" do
|
@@ -633,6 +651,14 @@ module GBRb
|
|
633
651
|
@z.mmu.read_byte(address).should eq @z.r.a.read
|
634
652
|
@z.r.hl.read.should eq address - 1
|
635
653
|
end
|
654
|
+
|
655
|
+
it "ld a hl-" do
|
656
|
+
@z.r.hl.store 0x4c
|
657
|
+
address = @z.r.hl.read
|
658
|
+
run 0x3a
|
659
|
+
@z.mmu.read_byte(address).should eq @z.r.a.read
|
660
|
+
@z.r.hl.read.should eq address - 1
|
661
|
+
end
|
636
662
|
end
|
637
663
|
|
638
664
|
context "ld (indirect destination)" do
|
@@ -1300,8 +1326,9 @@ module GBRb
|
|
1300
1326
|
before(:each) { @z.reset }
|
1301
1327
|
|
1302
1328
|
def run op
|
1329
|
+
@z.r.pc.store 7
|
1330
|
+
@z.mmu.write_byte 7, op.to_i
|
1303
1331
|
@z.dispatch @z.decode 0xcb
|
1304
|
-
@z.dispatch @z.decode op.to_i
|
1305
1332
|
end
|
1306
1333
|
|
1307
1334
|
context "#reset" do
|
@@ -2475,6 +2502,69 @@ module GBRb
|
|
2475
2502
|
end
|
2476
2503
|
end
|
2477
2504
|
|
2505
|
+
context "srl" do
|
2506
|
+
it "srl b" do
|
2507
|
+
@z.r.b.store 0b10101010
|
2508
|
+
run 0x38
|
2509
|
+
@z.r.b.read.should eq 0b01010101
|
2510
|
+
@z.r.carry_flag?.should be_false
|
2511
|
+
end
|
2512
|
+
|
2513
|
+
it "srl c" do
|
2514
|
+
@z.r.c.store 0b00000001
|
2515
|
+
run 0x39
|
2516
|
+
@z.r.c.read.should eq 0b00000000
|
2517
|
+
@z.r.carry_flag?.should be_true
|
2518
|
+
@z.r.zero_flag?.should be_true
|
2519
|
+
end
|
2520
|
+
|
2521
|
+
it "srl d" do
|
2522
|
+
@z.r.d.store 0b00000000
|
2523
|
+
@z.r.set_carry_flag
|
2524
|
+
run 0x3a
|
2525
|
+
@z.r.d.read.should eq 0b00000000
|
2526
|
+
@z.r.carry_flag?.should be_false
|
2527
|
+
@z.r.zero_flag?.should be_true
|
2528
|
+
end
|
2529
|
+
|
2530
|
+
it "srl e" do
|
2531
|
+
@z.r.e.store 0b10011001
|
2532
|
+
run 0x3b
|
2533
|
+
@z.r.e.read.should eq 0b01001100
|
2534
|
+
@z.r.carry_flag?.should be_true
|
2535
|
+
end
|
2536
|
+
|
2537
|
+
it "srl h" do
|
2538
|
+
@z.r.h.store 0b11111111
|
2539
|
+
run 0x3c
|
2540
|
+
@z.r.h.read.should eq 0b01111111
|
2541
|
+
@z.r.carry_flag?.should be_true
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
it "srl l" do
|
2545
|
+
@z.r.l.store 0b11111110
|
2546
|
+
run 0x3d
|
2547
|
+
@z.r.l.read.should eq 0b01111111
|
2548
|
+
@z.r.carry_flag?.should be_false
|
2549
|
+
end
|
2550
|
+
|
2551
|
+
it "srl (hl)" do
|
2552
|
+
@z.mmu.write_byte 0x1d3b, 0b01010101
|
2553
|
+
@z.r.hl.store 0x1d3b
|
2554
|
+
run 0x3e
|
2555
|
+
@z.mmu.read_byte(0x1d3b).should eq 0b00101010
|
2556
|
+
@z.r.carry_flag?.should be_true
|
2557
|
+
@z.r.hl.read.should eq 0x1d3b
|
2558
|
+
end
|
2559
|
+
|
2560
|
+
it "srl a" do
|
2561
|
+
@z.r.a.store 0b00100110
|
2562
|
+
run 0x3f
|
2563
|
+
@z.r.a.read.should eq 0b0010011
|
2564
|
+
@z.r.carry_flag?.should be_false
|
2565
|
+
end
|
2566
|
+
end
|
2567
|
+
|
2478
2568
|
context "swap" do
|
2479
2569
|
it "swap b" do
|
2480
2570
|
@z.r.b.store 0b10101010
|
@@ -1,26 +1,8 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
|
-
require_relative '../../../lib/gbrb/
|
2
|
+
require_relative '../../../lib/gbrb/instruction_set/arithmetic.rb'
|
3
3
|
require_relative '../../../lib/gbrb/cpu/register.rb'
|
4
4
|
|
5
|
-
module GBRb::
|
6
|
-
describe Instruction do
|
7
|
-
it "has a m time" do
|
8
|
-
i = Instruction.new
|
9
|
-
i.m.should be_true
|
10
|
-
end
|
11
|
-
|
12
|
-
it "has a t time" do
|
13
|
-
i = Instruction.new
|
14
|
-
i.t.should be_true
|
15
|
-
end
|
16
|
-
|
17
|
-
it "is callable" do
|
18
|
-
i = Instruction.new
|
19
|
-
world = double
|
20
|
-
i.call world, nil
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
5
|
+
module GBRb::InstructionSet
|
24
6
|
describe Inc do
|
25
7
|
it "clears the add sub flag" do
|
26
8
|
fake_register = double.as_null_object
|
@@ -34,7 +16,7 @@ module GBRb::CPU
|
|
34
16
|
end
|
35
17
|
|
36
18
|
it "sets the zero flag when zero" do
|
37
|
-
a = Register.new 0xff
|
19
|
+
a = GBRb::CPU::Register.new 0xff
|
38
20
|
world = double.as_null_object
|
39
21
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
40
22
|
world.should_receive(:set_zero_flag)
|
@@ -43,7 +25,7 @@ module GBRb::CPU
|
|
43
25
|
end
|
44
26
|
|
45
27
|
it "does not set the carry flag when value overflows register" do
|
46
|
-
a = Register.new 0xff
|
28
|
+
a = GBRb::CPU::Register.new 0xff
|
47
29
|
world = double.as_null_object
|
48
30
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
49
31
|
world.should_not_receive(:set_carry_flag)
|
@@ -52,7 +34,7 @@ module GBRb::CPU
|
|
52
34
|
end
|
53
35
|
|
54
36
|
it "sets the half carry flag when low nibble overflows" do
|
55
|
-
a = Register.new 0x0f
|
37
|
+
a = GBRb::CPU::Register.new 0x0f
|
56
38
|
world = double.as_null_object
|
57
39
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
58
40
|
world.should_receive(:set_half_carry_flag)
|
@@ -62,7 +44,7 @@ module GBRb::CPU
|
|
62
44
|
end
|
63
45
|
|
64
46
|
it "does not touch the flags if initialized with false" do
|
65
|
-
a = Register.new 0xff
|
47
|
+
a = GBRb::CPU::Register.new 0xff
|
66
48
|
world = double.as_null_object
|
67
49
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
68
50
|
world.should_not_receive(:set_carry_flag)
|
@@ -86,7 +68,7 @@ module GBRb::CPU
|
|
86
68
|
end
|
87
69
|
|
88
70
|
it "sets the zero flag when zero" do
|
89
|
-
a = Register.new 0x01
|
71
|
+
a = GBRb::CPU::Register.new 0x01
|
90
72
|
world = double.as_null_object
|
91
73
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
92
74
|
world.should_not_receive(:set_half_carry_flag)
|
@@ -96,7 +78,7 @@ module GBRb::CPU
|
|
96
78
|
end
|
97
79
|
|
98
80
|
it "does not set the carry flag when value underflows register" do
|
99
|
-
a = Register.new 0x00
|
81
|
+
a = GBRb::CPU::Register.new 0x00
|
100
82
|
world = double.as_null_object
|
101
83
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
102
84
|
world.should_not_receive(:set_carry_flag)
|
@@ -105,7 +87,7 @@ module GBRb::CPU
|
|
105
87
|
end
|
106
88
|
|
107
89
|
it "sets the half carry flag when borrowing from high nibble" do
|
108
|
-
a = Register.new 0x10
|
90
|
+
a = GBRb::CPU::Register.new 0x10
|
109
91
|
world = double.as_null_object
|
110
92
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
111
93
|
world.should_receive(:set_half_carry_flag)
|
@@ -115,7 +97,7 @@ module GBRb::CPU
|
|
115
97
|
end
|
116
98
|
|
117
99
|
it "does not touch the flags if initialized with false" do
|
118
|
-
a = Register.new 0xff
|
100
|
+
a = GBRb::CPU::Register.new 0xff
|
119
101
|
world = double.as_null_object
|
120
102
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
121
103
|
world.should_not_receive(:set_half_carry_flag)
|
@@ -125,25 +107,9 @@ module GBRb::CPU
|
|
125
107
|
end
|
126
108
|
end
|
127
109
|
|
128
|
-
describe Ld do
|
129
|
-
it "does not set any flags" do
|
130
|
-
b = Register.new
|
131
|
-
c = Register.new 0x34
|
132
|
-
world = double.as_null_object
|
133
|
-
world.should_receive(:b).at_least(1).times.and_return(b)
|
134
|
-
world.should_receive(:c).at_least(1).times.and_return(c)
|
135
|
-
world.should_not_receive(:set_half_carry_flag)
|
136
|
-
world.should_not_receive(:set_carry_flag)
|
137
|
-
world.should_not_receive(:set_add_sub_flag)
|
138
|
-
world.should_not_receive(:set_zero_flag)
|
139
|
-
i = Ld.new :b, :c
|
140
|
-
i.call world, nil
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
110
|
describe Add do
|
145
111
|
it "clears the add sub flag" do
|
146
|
-
a = Register.new 0x34
|
112
|
+
a = GBRb::CPU::Register.new 0x34
|
147
113
|
world = double.as_null_object
|
148
114
|
world.should_receive(:clear_add_sub_flag)
|
149
115
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
@@ -152,7 +118,7 @@ module GBRb::CPU
|
|
152
118
|
end
|
153
119
|
|
154
120
|
it "sets the zero flag when zero" do
|
155
|
-
a = Register.new 0x80
|
121
|
+
a = GBRb::CPU::Register.new 0x80
|
156
122
|
world = double.as_null_object
|
157
123
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
158
124
|
world.should_receive(:set_zero_flag)
|
@@ -162,7 +128,7 @@ module GBRb::CPU
|
|
162
128
|
end
|
163
129
|
|
164
130
|
it "sets the carry flag when value overflows register" do
|
165
|
-
a = Register.new 0xff
|
131
|
+
a = GBRb::CPU::Register.new 0xff
|
166
132
|
world = double.as_null_object
|
167
133
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
168
134
|
i = Add.new :a
|
@@ -171,7 +137,7 @@ module GBRb::CPU
|
|
171
137
|
end
|
172
138
|
|
173
139
|
it "sets the half carry flag when low nibble overflows" do
|
174
|
-
a = Register.new 0x0d
|
140
|
+
a = GBRb::CPU::Register.new 0x0d
|
175
141
|
world = double.as_null_object
|
176
142
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
177
143
|
world.should_receive(:set_half_carry_flag)
|
@@ -183,7 +149,7 @@ module GBRb::CPU
|
|
183
149
|
|
184
150
|
describe Sub do
|
185
151
|
it "sets the add sub flag" do
|
186
|
-
a = Register.new 0x34
|
152
|
+
a = GBRb::CPU::Register.new 0x34
|
187
153
|
world = double.as_null_object
|
188
154
|
world.should_receive(:set_add_sub_flag)
|
189
155
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
@@ -192,7 +158,7 @@ module GBRb::CPU
|
|
192
158
|
end
|
193
159
|
|
194
160
|
it "sets the zero flag when zero" do
|
195
|
-
a = Register.new 0x80
|
161
|
+
a = GBRb::CPU::Register.new 0x80
|
196
162
|
world = double.as_null_object
|
197
163
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
198
164
|
world.should_receive(:set_zero_flag)
|
@@ -202,7 +168,7 @@ module GBRb::CPU
|
|
202
168
|
end
|
203
169
|
|
204
170
|
it "sets the carry flag when value underflows register" do
|
205
|
-
a = Register.new 0x00
|
171
|
+
a = GBRb::CPU::Register.new 0x00
|
206
172
|
world = double.as_null_object
|
207
173
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
208
174
|
i = Sub.new :a
|
@@ -210,8 +176,8 @@ module GBRb::CPU
|
|
210
176
|
end
|
211
177
|
|
212
178
|
it "sets the half carry flag when borrowing from high nibble" do
|
213
|
-
a = Register.new 0x10
|
214
|
-
b = Register.new 0x01
|
179
|
+
a = GBRb::CPU::Register.new 0x10
|
180
|
+
b = GBRb::CPU::Register.new 0x01
|
215
181
|
world = double.as_null_object
|
216
182
|
world.should_receive(:a).at_least(1).times.and_return(a)
|
217
183
|
world.should_receive(:b).at_least(1).times.and_return(b)
|
@@ -224,8 +190,8 @@ module GBRb::CPU
|
|
224
190
|
|
225
191
|
describe Cp do
|
226
192
|
it "does not modify the accumulator" do
|
227
|
-
a = Register.new 0x1f
|
228
|
-
b = Register.new 0x3b
|
193
|
+
a = GBRb::CPU::Register.new 0x1f
|
194
|
+
b = GBRb::CPU::Register.new 0x3b
|
229
195
|
world = double.as_null_object
|
230
196
|
world.stub(a: a)
|
231
197
|
world.stub(b: b)
|
@@ -235,49 +201,4 @@ module GBRb::CPU
|
|
235
201
|
i.call world, nil
|
236
202
|
end
|
237
203
|
end
|
238
|
-
|
239
|
-
describe And do
|
240
|
-
it "sets the correct flags" do
|
241
|
-
a = Register.new 0x73
|
242
|
-
b = Register.new 0xd2
|
243
|
-
world = double.as_null_object
|
244
|
-
world.stub(:a).and_return(a)
|
245
|
-
world.stub(:b).and_return(b)
|
246
|
-
world.should_receive :clear_add_sub_flag
|
247
|
-
world.should_receive :set_half_carry_flag
|
248
|
-
world.should_receive :clear_carry_flag
|
249
|
-
i = And.new :a, :b
|
250
|
-
i.call world, nil
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
describe Or do
|
255
|
-
it "sets the correct flags" do
|
256
|
-
a = Register.new 0x81
|
257
|
-
b = Register.new 0xaf
|
258
|
-
world = double.as_null_object
|
259
|
-
world.stub(:a).and_return(a)
|
260
|
-
world.stub(:b).and_return(b)
|
261
|
-
world.should_receive :clear_add_sub_flag
|
262
|
-
world.should_receive :clear_half_carry_flag
|
263
|
-
world.should_receive :clear_carry_flag
|
264
|
-
i= Or.new :a, :b
|
265
|
-
i.call world, nil
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
describe Xor do
|
270
|
-
it "sets the correct flags" do
|
271
|
-
a = Register.new 0x81
|
272
|
-
b = Register.new 0xaf
|
273
|
-
world = double.as_null_object
|
274
|
-
world.stub(:a).and_return(a)
|
275
|
-
world.stub(:b).and_return(b)
|
276
|
-
world.should_receive :clear_add_sub_flag
|
277
|
-
world.should_receive :clear_half_carry_flag
|
278
|
-
world.should_receive :clear_carry_flag
|
279
|
-
i= Xor.new :a, :b
|
280
|
-
i.call world, nil
|
281
|
-
end
|
282
|
-
end
|
283
204
|
end
|