GBRb 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -0
- data/Rakefile +6 -0
- data/bin/display +9 -0
- data/bin/gbrb +12 -0
- data/gbrb.gemspec +26 -0
- data/lib/gbrb.rb +9 -0
- data/lib/gbrb/bios +256 -0
- data/lib/gbrb/cartridge.rb +15 -0
- data/lib/gbrb/cpu.rb +7 -0
- data/lib/gbrb/cpu/concatenated_register.rb +44 -0
- data/lib/gbrb/cpu/flags_register.rb +42 -0
- data/lib/gbrb/cpu/instruction.rb +648 -0
- data/lib/gbrb/cpu/register.rb +44 -0
- data/lib/gbrb/cpu/register_ensemble.rb +59 -0
- data/lib/gbrb/cpu/z80.rb +584 -0
- data/lib/gbrb/gb.rb +125 -0
- data/lib/gbrb/graphics.rb +14 -0
- data/lib/gbrb/graphics/gpu.rb +196 -0
- data/lib/gbrb/graphics/mode_clock.rb +51 -0
- data/lib/gbrb/graphics/screen_client.rb +31 -0
- data/lib/gbrb/graphics/screen_server.rb +90 -0
- data/lib/gbrb/mmu.rb +96 -0
- data/lib/gbrb/version.rb +3 -0
- data/misc/parse_tiles +27 -0
- data/perf/cpu_perf_spec.rb +23 -0
- data/spec/gbrb/cartridge_spec.rb +19 -0
- data/spec/gbrb/cpu/concatenated_register_spec.rb +36 -0
- data/spec/gbrb/cpu/flags_register_spec.rb +91 -0
- data/spec/gbrb/cpu/instruction_spec.rb +283 -0
- data/spec/gbrb/cpu/register_ensemble_spec.rb +84 -0
- data/spec/gbrb/cpu/register_spec.rb +86 -0
- data/spec/gbrb/cpu/z80_spec.rb +2534 -0
- data/spec/gbrb/graphics/mode_clock_spec.rb +82 -0
- data/spec/gbrb/mmu_spec.rb +61 -0
- data/spec/gbrb/version_spec.rb +10 -0
- data/spec/spec_helper.rb +4 -0
- metadata +154 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require_relative '../../spec_helper.rb'
|
2
|
+
require_relative '../../../lib/gbrb/cpu/register_ensemble'
|
3
|
+
|
4
|
+
module GBRb::CPU
|
5
|
+
describe RegisterEnsemble do
|
6
|
+
def register_bit_count label
|
7
|
+
@re.public_send(label.to_sym).instance_eval("@bits")
|
8
|
+
end
|
9
|
+
|
10
|
+
before {@re = RegisterEnsemble.new }
|
11
|
+
it "has an a register" do
|
12
|
+
register_bit_count(:a).should eq 8
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has an 8-bit b register" do
|
16
|
+
register_bit_count(:b).should eq 8
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has an 8-bit c register" do
|
20
|
+
register_bit_count(:c).should eq 8
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has an 8-bit d register" do
|
24
|
+
register_bit_count(:d).should eq 8
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has an 8-bit e register" do
|
28
|
+
register_bit_count(:e).should eq 8
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has an 8-bit h register" do
|
32
|
+
register_bit_count(:h).should eq 8
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has an 8-bit l register" do
|
36
|
+
register_bit_count(:l).should eq 8
|
37
|
+
end
|
38
|
+
|
39
|
+
it "has an 8-bit f register" do
|
40
|
+
register_bit_count(:f).should eq 8
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has a 16-bit pc register" do
|
44
|
+
register_bit_count(:pc).should eq 16
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has a 16-bit sp register" do
|
48
|
+
register_bit_count(:sp).should eq 16
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has an 8-bit m register" do
|
52
|
+
register_bit_count(:m).should eq 8
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has an 8-bit t register" do
|
56
|
+
register_bit_count(:t).should eq 8
|
57
|
+
end
|
58
|
+
|
59
|
+
it "provides access to bc as one 16-bit register" do
|
60
|
+
register_bit_count(:bc).should eq 16
|
61
|
+
end
|
62
|
+
|
63
|
+
it "provides access to de as one 16-bit register" do
|
64
|
+
register_bit_count(:de).should eq 16
|
65
|
+
end
|
66
|
+
|
67
|
+
it "provides access to hl as one 16-bit register" do
|
68
|
+
register_bit_count(:hl).should eq 16
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#==" do
|
72
|
+
it "is true if all registers are equal" do
|
73
|
+
se = RegisterEnsemble.new
|
74
|
+
@re.should eq se
|
75
|
+
end
|
76
|
+
|
77
|
+
it "is false if a register is different" do
|
78
|
+
se = RegisterEnsemble.new
|
79
|
+
se.d.store(0xAA)
|
80
|
+
@re.should_not eq se
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative '../../spec_helper.rb'
|
2
|
+
require_relative '../../../lib/gbrb/cpu/register.rb'
|
3
|
+
|
4
|
+
module GBRb::CPU
|
5
|
+
describe Register do
|
6
|
+
context "8bit" do
|
7
|
+
let(:r) { Register.new }
|
8
|
+
|
9
|
+
it "returns a value" do
|
10
|
+
r.read.should eq 0x0
|
11
|
+
end
|
12
|
+
|
13
|
+
it "stores a value" do
|
14
|
+
r.store 0xFF
|
15
|
+
r.read.should eq 0xFF
|
16
|
+
end
|
17
|
+
|
18
|
+
it "only stores one byte" do
|
19
|
+
r.store 0x1FD
|
20
|
+
r.read.should eq 0xFD
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has the correct mask value" do
|
24
|
+
r.mask.should eq 0x100
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has the correct half mask value" do
|
28
|
+
r.half_mask.should eq 0x10
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "16bit" do
|
33
|
+
let(:r) { Register.new 0x0, 16 }
|
34
|
+
|
35
|
+
it "stores two bytes" do
|
36
|
+
r.store 0xD
|
37
|
+
r.read.should eq 0xD
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has the correct mask value" do
|
41
|
+
r.mask.should eq 0x10000
|
42
|
+
end
|
43
|
+
|
44
|
+
it "has the correct half mask value" do
|
45
|
+
r.half_mask.should eq 0x100
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "raises an error if invalid bits are specified" do
|
50
|
+
expect {Register.new 0x0, 5}.to raise_error ArgumentError
|
51
|
+
end
|
52
|
+
|
53
|
+
it "clears the bits" do
|
54
|
+
r = Register.new 0x3
|
55
|
+
r.clear
|
56
|
+
r.read.should eq 0x0
|
57
|
+
end
|
58
|
+
|
59
|
+
it "knows if it is zero" do
|
60
|
+
r = Register.new
|
61
|
+
r.zero?.should be_true
|
62
|
+
r.store 0x1
|
63
|
+
r.zero?.should be_false
|
64
|
+
end
|
65
|
+
|
66
|
+
context "#==" do
|
67
|
+
it "is true if both registers have the same value and the same bit count" do
|
68
|
+
r = Register.new
|
69
|
+
s = Register.new
|
70
|
+
r.should eq s
|
71
|
+
end
|
72
|
+
|
73
|
+
it "is false if registers have different values" do
|
74
|
+
r = Register.new 0x05
|
75
|
+
s = Register.new 0xF0
|
76
|
+
r.should_not eq s
|
77
|
+
end
|
78
|
+
|
79
|
+
it "is false if registers have different bit counts" do
|
80
|
+
r = Register.new 0, 8
|
81
|
+
s = Register.new 0, 16
|
82
|
+
r.should_not eq s
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,2534 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require_relative '../../../lib/gbrb/cpu/z80'
|
3
|
+
|
4
|
+
module GBRb
|
5
|
+
module CPU
|
6
|
+
describe Z80 do
|
7
|
+
context "#clock" do
|
8
|
+
let(:z) { Z80.new }
|
9
|
+
it "has two clock values" do
|
10
|
+
z.clock.keys.should eq %i[m t]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "#dispatch" do
|
15
|
+
let(:z) { Z80.new }
|
16
|
+
it "updates the accumulated clock" do
|
17
|
+
initial_clock = z.clock.dup
|
18
|
+
z.dispatch z.decode 0x00
|
19
|
+
z.clock.should_not eq initial_clock
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#instructions" do
|
24
|
+
before(:all) { @z = Z80.new }
|
25
|
+
before(:each) { @z.reset }
|
26
|
+
|
27
|
+
def run op
|
28
|
+
@z.dispatch @z.decode op.to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
it "nop" do
|
32
|
+
initial_registers = Marshal.load Marshal.dump @z.registers
|
33
|
+
run 0x00
|
34
|
+
@z.registers.should eq initial_registers
|
35
|
+
end
|
36
|
+
|
37
|
+
it "rla" do
|
38
|
+
@z.r.a.store 0b10100101
|
39
|
+
run 0x17
|
40
|
+
@z.r.a.read.should eq 0b01001010
|
41
|
+
@z.r.carry_flag?.should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "rlca" do
|
45
|
+
@z.r.a.store 0b10100101
|
46
|
+
@z.r.set_carry_flag
|
47
|
+
run 0x07
|
48
|
+
@z.r.a.read.should eq 0b01001011
|
49
|
+
@z.r.carry_flag?.should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "scf" do
|
53
|
+
@z.r.should_receive(:clear_half_carry_flag)
|
54
|
+
@z.r.should_receive(:clear_add_sub_flag)
|
55
|
+
@z.r.should_receive(:set_carry_flag)
|
56
|
+
run 0x37
|
57
|
+
end
|
58
|
+
|
59
|
+
it "cpl" do
|
60
|
+
@z.r.should_receive(:set_half_carry_flag)
|
61
|
+
@z.r.should_receive(:set_add_sub_flag)
|
62
|
+
run 0x2f
|
63
|
+
@z.r.a.read.should eq 0xFF
|
64
|
+
end
|
65
|
+
|
66
|
+
it "ccf" do
|
67
|
+
@z.r.carry_flag?.should be_false
|
68
|
+
run 0x3f
|
69
|
+
@z.r.carry_flag?.should be_true
|
70
|
+
run 0x3f
|
71
|
+
@z.r.carry_flag?.should be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
context "push and pop (round-trip)" do
|
75
|
+
def common register, push_opcode, pop_opcode
|
76
|
+
value = 0x835b
|
77
|
+
reg = @z.r.public_send(register.to_sym)
|
78
|
+
reg.store value
|
79
|
+
run push_opcode
|
80
|
+
reg.clear
|
81
|
+
reg.read.should eq 0x00
|
82
|
+
run pop_opcode
|
83
|
+
reg.read.should eq value
|
84
|
+
end
|
85
|
+
|
86
|
+
it "push/pop bc" do
|
87
|
+
common :bc, 0xc5, 0xc1
|
88
|
+
end
|
89
|
+
|
90
|
+
it "push/pop de" do
|
91
|
+
common :de, 0xd5, 0xd1
|
92
|
+
end
|
93
|
+
|
94
|
+
it "push/pop hl" do
|
95
|
+
common :hl, 0xe5, 0xe1
|
96
|
+
end
|
97
|
+
|
98
|
+
it "push/pop af" do
|
99
|
+
common :af, 0xf5, 0xf1
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
context "inc" do
|
105
|
+
it "inc_a" do
|
106
|
+
a = @z.r.a.read
|
107
|
+
run 0x3c
|
108
|
+
@z.registers.a.read.should eq a + 1
|
109
|
+
end
|
110
|
+
|
111
|
+
it "inc_b" do
|
112
|
+
b = @z.r.b.read
|
113
|
+
run 0x04
|
114
|
+
@z.registers.b.read.should eq b + 1
|
115
|
+
end
|
116
|
+
|
117
|
+
it "inc_c" do
|
118
|
+
c = @z.r.c.read
|
119
|
+
run 0x0c
|
120
|
+
@z.registers.c.read.should eq c + 1
|
121
|
+
end
|
122
|
+
|
123
|
+
it "inc_d" do
|
124
|
+
d = @z.r.d.read
|
125
|
+
run 0x14
|
126
|
+
@z.registers.d.read.should eq d + 1
|
127
|
+
end
|
128
|
+
|
129
|
+
it "inc_e" do
|
130
|
+
e = @z.r.e.read
|
131
|
+
run 0x1c
|
132
|
+
@z.registers.e.read.should eq e + 1
|
133
|
+
end
|
134
|
+
|
135
|
+
it "inc_h" do
|
136
|
+
h = @z.r.h.read
|
137
|
+
run 0x24
|
138
|
+
@z.registers.h.read.should eq h + 1
|
139
|
+
end
|
140
|
+
|
141
|
+
it "inc_l" do
|
142
|
+
l = @z.r.l.read
|
143
|
+
run 0x2c
|
144
|
+
@z.registers.l.read.should eq l + 1
|
145
|
+
end
|
146
|
+
|
147
|
+
it "inc_bc" do
|
148
|
+
bc = @z.r.bc.read
|
149
|
+
run 0x03
|
150
|
+
@z.registers.bc.read.should eq bc + 1
|
151
|
+
end
|
152
|
+
|
153
|
+
it "inc_de" do
|
154
|
+
de = @z.r.de.read
|
155
|
+
run 0x13
|
156
|
+
@z.registers.de.read.should eq de + 1
|
157
|
+
end
|
158
|
+
|
159
|
+
it "inc_hl" do
|
160
|
+
hl = @z.r.hl.read
|
161
|
+
run 0x23
|
162
|
+
@z.registers.hl.read.should eq hl + 1
|
163
|
+
end
|
164
|
+
|
165
|
+
it "inc_sp" do
|
166
|
+
sp = @z.r.sp.read
|
167
|
+
run 0x33
|
168
|
+
@z.registers.sp.read.should eq (sp + 1)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "dec" do
|
173
|
+
def common register, opcode
|
174
|
+
r = @z.r.public_send(register.to_sym)
|
175
|
+
v = r.read
|
176
|
+
run opcode
|
177
|
+
r.read.should eq (v - 1) % r.mask
|
178
|
+
end
|
179
|
+
|
180
|
+
it "dec_a" do
|
181
|
+
common :a, 0x3d
|
182
|
+
end
|
183
|
+
|
184
|
+
it "dec_b" do
|
185
|
+
common :b, 0x05
|
186
|
+
end
|
187
|
+
|
188
|
+
it "dec_c" do
|
189
|
+
common :c, 0x0d
|
190
|
+
end
|
191
|
+
|
192
|
+
it "dec_d" do
|
193
|
+
common :d, 0x15
|
194
|
+
end
|
195
|
+
|
196
|
+
it "dec_e" do
|
197
|
+
common :e, 0x1d
|
198
|
+
end
|
199
|
+
|
200
|
+
it "dec_h" do
|
201
|
+
common :h, 0x25
|
202
|
+
end
|
203
|
+
|
204
|
+
it "dec_l" do
|
205
|
+
common :l, 0x2d
|
206
|
+
end
|
207
|
+
|
208
|
+
it "dec_bc" do
|
209
|
+
common :bc, 0x0b
|
210
|
+
end
|
211
|
+
|
212
|
+
it "dec_de" do
|
213
|
+
common :de, 0x1b
|
214
|
+
end
|
215
|
+
|
216
|
+
it "dec_hl" do
|
217
|
+
common :hl, 0x2b
|
218
|
+
end
|
219
|
+
|
220
|
+
it "dec_sp" do
|
221
|
+
common :sp, 0x3b
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "ld" do
|
226
|
+
before(:each) do
|
227
|
+
@z.r.a.store 0x01
|
228
|
+
@z.r.b.store 0x02
|
229
|
+
@z.r.c.store 0x03
|
230
|
+
@z.r.d.store 0x04
|
231
|
+
@z.r.e.store 0x05
|
232
|
+
@z.r.h.store 0x06
|
233
|
+
@z.r.l.store 0x07
|
234
|
+
end
|
235
|
+
|
236
|
+
def common destination, target, opcode
|
237
|
+
v = @z.r.public_send(target.to_sym).read
|
238
|
+
run opcode
|
239
|
+
@z.r.public_send(destination.to_sym).read.should eq v
|
240
|
+
end
|
241
|
+
|
242
|
+
it "ld_b_b" do
|
243
|
+
common :b, :b, 0x40
|
244
|
+
end
|
245
|
+
|
246
|
+
it "ld_b_c" do
|
247
|
+
common :b, :c, 0x41
|
248
|
+
end
|
249
|
+
|
250
|
+
it "ld_b_d" do
|
251
|
+
common :b, :d, 0x42
|
252
|
+
end
|
253
|
+
|
254
|
+
it "ld_b_e" do
|
255
|
+
common :b, :e, 0x43
|
256
|
+
end
|
257
|
+
|
258
|
+
it "ld_b_h" do
|
259
|
+
common :b, :h, 0x44
|
260
|
+
end
|
261
|
+
|
262
|
+
it "ld_b_l" do
|
263
|
+
common :b, :l, 0x45
|
264
|
+
end
|
265
|
+
|
266
|
+
it "ld_b_a" do
|
267
|
+
common :b, :a, 0x47
|
268
|
+
end
|
269
|
+
|
270
|
+
it "ld_c_b" do
|
271
|
+
common :c, :b, 0x48
|
272
|
+
end
|
273
|
+
|
274
|
+
it "ld_c_c" do
|
275
|
+
common :c, :c, 0x49
|
276
|
+
end
|
277
|
+
|
278
|
+
it "ld_c_d" do
|
279
|
+
common :c, :d, 0x4a
|
280
|
+
end
|
281
|
+
|
282
|
+
it "ld_c_e" do
|
283
|
+
common :c, :e, 0x4b
|
284
|
+
end
|
285
|
+
|
286
|
+
it "ld_c_h" do
|
287
|
+
common :c, :h, 0x4c
|
288
|
+
end
|
289
|
+
|
290
|
+
it "ld_c_l" do
|
291
|
+
common :c, :l, 0x4d
|
292
|
+
end
|
293
|
+
|
294
|
+
it "ld_c_a" do
|
295
|
+
common :c, :a, 0x4f
|
296
|
+
end
|
297
|
+
|
298
|
+
it "ld_d_b" do
|
299
|
+
common :d, :b, 0x50
|
300
|
+
end
|
301
|
+
|
302
|
+
it "ld_d_c" do
|
303
|
+
common :d, :c, 0x51
|
304
|
+
end
|
305
|
+
|
306
|
+
it "ld_d_d" do
|
307
|
+
common :d, :d, 0x52
|
308
|
+
end
|
309
|
+
|
310
|
+
it "ld_d_e" do
|
311
|
+
common :d, :e, 0x53
|
312
|
+
end
|
313
|
+
|
314
|
+
it "ld_d_h" do
|
315
|
+
common :d, :h, 0x54
|
316
|
+
end
|
317
|
+
|
318
|
+
it "ld_d_l" do
|
319
|
+
common :d, :l, 0x55
|
320
|
+
end
|
321
|
+
|
322
|
+
it "ld_d_a" do
|
323
|
+
common :d, :a, 0x57
|
324
|
+
end
|
325
|
+
|
326
|
+
it "ld_e_b" do
|
327
|
+
common :e, :b, 0x58
|
328
|
+
end
|
329
|
+
|
330
|
+
it "ld_e_c" do
|
331
|
+
common :e, :c, 0x59
|
332
|
+
end
|
333
|
+
|
334
|
+
it "ld_e_d" do
|
335
|
+
common :e, :d, 0x5a
|
336
|
+
end
|
337
|
+
|
338
|
+
it "ld_e_e" do
|
339
|
+
common :e, :e, 0x5b
|
340
|
+
end
|
341
|
+
|
342
|
+
it "ld_e_h" do
|
343
|
+
common :e, :h, 0x5c
|
344
|
+
end
|
345
|
+
|
346
|
+
it "ld_e_l" do
|
347
|
+
common :e, :l, 0x5d
|
348
|
+
end
|
349
|
+
|
350
|
+
it "ld_e_a" do
|
351
|
+
common :e, :a, 0x5f
|
352
|
+
end
|
353
|
+
|
354
|
+
it "ld_h_b" do
|
355
|
+
common :h, :b, 0x60
|
356
|
+
end
|
357
|
+
|
358
|
+
it "ld_h_c" do
|
359
|
+
common :h, :c, 0x61
|
360
|
+
end
|
361
|
+
|
362
|
+
it "ld_h_d" do
|
363
|
+
common :h, :d, 0x62
|
364
|
+
end
|
365
|
+
|
366
|
+
it "ld_h_e" do
|
367
|
+
common :h, :e, 0x63
|
368
|
+
end
|
369
|
+
|
370
|
+
it "ld_h_h" do
|
371
|
+
common :h, :h, 0x64
|
372
|
+
end
|
373
|
+
|
374
|
+
it "ld_h_l" do
|
375
|
+
common :h, :l, 0x65
|
376
|
+
end
|
377
|
+
|
378
|
+
it "ld_h_a" do
|
379
|
+
common :h, :a, 0x67
|
380
|
+
end
|
381
|
+
|
382
|
+
it "ld_l_b" do
|
383
|
+
common :l, :b, 0x68
|
384
|
+
end
|
385
|
+
|
386
|
+
it "ld_l_c" do
|
387
|
+
common :l, :c, 0x69
|
388
|
+
end
|
389
|
+
|
390
|
+
it "ld_l_d" do
|
391
|
+
common :l, :d, 0x6a
|
392
|
+
end
|
393
|
+
|
394
|
+
it "ld_l_e" do
|
395
|
+
common :l, :e, 0x6b
|
396
|
+
end
|
397
|
+
|
398
|
+
it "ld_l_h" do
|
399
|
+
common :l, :h, 0x6c
|
400
|
+
end
|
401
|
+
|
402
|
+
it "ld_l_l" do
|
403
|
+
common :l, :l, 0x6d
|
404
|
+
end
|
405
|
+
|
406
|
+
it "ld_l_a" do
|
407
|
+
common :l, :a, 0x6f
|
408
|
+
end
|
409
|
+
|
410
|
+
it "ld_a_b" do
|
411
|
+
common :a, :b, 0x78
|
412
|
+
end
|
413
|
+
|
414
|
+
it "ld_a_c" do
|
415
|
+
common :a, :c, 0x79
|
416
|
+
end
|
417
|
+
|
418
|
+
it "ld_a_d" do
|
419
|
+
common :a, :d, 0x7a
|
420
|
+
end
|
421
|
+
|
422
|
+
it "ld_a_e" do
|
423
|
+
common :a, :e, 0x7b
|
424
|
+
end
|
425
|
+
|
426
|
+
it "ld_a_h" do
|
427
|
+
common :a, :h, 0x7c
|
428
|
+
end
|
429
|
+
|
430
|
+
it "ld_a_l" do
|
431
|
+
common :a, :l, 0x7d
|
432
|
+
end
|
433
|
+
|
434
|
+
it "ld_a_a" do
|
435
|
+
common :a, :a, 0x7f
|
436
|
+
end
|
437
|
+
|
438
|
+
it "ld_sp_hl" do
|
439
|
+
common :sp, :hl, 0xf9
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
context "jr" do
|
444
|
+
it "jr nz r8" do
|
445
|
+
@z.r.pc.store 0x0001
|
446
|
+
@z.mmu.write_byte(0x0001, 0xab)
|
447
|
+
run 0x20
|
448
|
+
@z.r.pc.read.should eq 0xffad
|
449
|
+
end
|
450
|
+
|
451
|
+
it "jr z r8" do
|
452
|
+
@z.r.pc.store 0x0001
|
453
|
+
@z.mmu.write_byte 0x0001, 0x94
|
454
|
+
@z.r.set_zero_flag
|
455
|
+
run 0x28
|
456
|
+
@z.r.pc.read.should eq 0xff96
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
context "ld (immediate value)" do
|
461
|
+
before(:each) do
|
462
|
+
@z.r.pc.store 0x0003
|
463
|
+
@z.mmu.write_byte(0x0003, 0xcb)
|
464
|
+
@z.mmu.write_byte(0x0004, 0xf1)
|
465
|
+
end
|
466
|
+
|
467
|
+
def common destination, opcode, num_bytes=1, indirect=false
|
468
|
+
run opcode
|
469
|
+
if num_bytes == 1
|
470
|
+
expected = 0xcb
|
471
|
+
else
|
472
|
+
expected = 0xf1cb
|
473
|
+
end
|
474
|
+
result = @z.r.public_send(destination.to_sym).read
|
475
|
+
result = @z.mmu.read_byte result if indirect
|
476
|
+
result.should eq expected
|
477
|
+
end
|
478
|
+
|
479
|
+
it "ld bc d16" do
|
480
|
+
common :bc, 0x01, 2
|
481
|
+
end
|
482
|
+
|
483
|
+
it "ld de d16" do
|
484
|
+
common :de, 0x11, 2
|
485
|
+
end
|
486
|
+
|
487
|
+
it "ld hl d16" do
|
488
|
+
common :hl, 0x21, 2
|
489
|
+
end
|
490
|
+
|
491
|
+
it "ld sp d16" do
|
492
|
+
common :sp, 0x31, 2
|
493
|
+
end
|
494
|
+
|
495
|
+
it "ld b d8" do
|
496
|
+
common :b, 0x06
|
497
|
+
end
|
498
|
+
|
499
|
+
it "ld c d8" do
|
500
|
+
common :c, 0x0e
|
501
|
+
end
|
502
|
+
|
503
|
+
it "ld d d8" do
|
504
|
+
common :d, 0x16
|
505
|
+
end
|
506
|
+
|
507
|
+
it "ld e d8" do
|
508
|
+
common :e, 0x1e
|
509
|
+
end
|
510
|
+
|
511
|
+
it "ld h d8" do
|
512
|
+
common :h, 0x26
|
513
|
+
end
|
514
|
+
|
515
|
+
it "ld l d8" do
|
516
|
+
common :l, 0x2e
|
517
|
+
end
|
518
|
+
|
519
|
+
it "ld (hl) d8" do
|
520
|
+
common :hl, 0x36, 1, true
|
521
|
+
end
|
522
|
+
|
523
|
+
it "ld a d8" do
|
524
|
+
common :a, 0x3e
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
context "ld (indirect target)" do
|
529
|
+
before(:each) do
|
530
|
+
@z.r.a.store 0x01
|
531
|
+
@z.r.b.store 0x02
|
532
|
+
@z.r.c.store 0x03
|
533
|
+
@z.r.d.store 0x04
|
534
|
+
@z.r.e.store 0x05
|
535
|
+
@z.r.h.store 0x06
|
536
|
+
@z.r.l.store 0x07
|
537
|
+
end
|
538
|
+
|
539
|
+
def common destination, target, opcode
|
540
|
+
@z.r.public_send(target.to_sym).store 0x39
|
541
|
+
@z.mmu.write_byte 0x39, 0xb6
|
542
|
+
run opcode
|
543
|
+
@z.r.public_send(destination.to_sym).read.should eq 0xb6
|
544
|
+
end
|
545
|
+
|
546
|
+
it "ldi_a_bc" do
|
547
|
+
common :a, :bc, 0x0a
|
548
|
+
end
|
549
|
+
|
550
|
+
it "ldi_a_de" do
|
551
|
+
common :a, :de, 0x1a
|
552
|
+
end
|
553
|
+
|
554
|
+
it "ldi_a_hl" do
|
555
|
+
common :a, :hl, 0x7e
|
556
|
+
end
|
557
|
+
|
558
|
+
it "ldi_l_hl" do
|
559
|
+
common :l, :hl, 0x6e
|
560
|
+
end
|
561
|
+
|
562
|
+
it "ldi_e_hl" do
|
563
|
+
common :e, :hl, 0x5e
|
564
|
+
end
|
565
|
+
|
566
|
+
it "ldi_c_hl" do
|
567
|
+
common :c, :hl, 0x4e
|
568
|
+
end
|
569
|
+
|
570
|
+
it "ldi_h_hl" do
|
571
|
+
common :h, :hl, 0x66
|
572
|
+
end
|
573
|
+
|
574
|
+
it "ldi_d_hl" do
|
575
|
+
common :d, :hl, 0x56
|
576
|
+
end
|
577
|
+
|
578
|
+
it "ldi_b_hl" do
|
579
|
+
common :b, :hl, 0x46
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
context "indirect ld with immediate value" do
|
584
|
+
it "ld (a16) a" do
|
585
|
+
@z.r.a.store 0x4b
|
586
|
+
@z.mmu.write_byte 0x0000, 0xc6
|
587
|
+
@z.mmu.write_byte 0x0001, 0x9b
|
588
|
+
run 0xea
|
589
|
+
@z.mmu.read_byte(0x9bc6).should eq 0x4b
|
590
|
+
end
|
591
|
+
|
592
|
+
it "ld a (a16)" do
|
593
|
+
@z.mmu.write_byte 0x0000, 0xc6
|
594
|
+
@z.mmu.write_byte 0x0001, 0x9b
|
595
|
+
@z.mmu.write_byte 0x9bc6, 0x5e
|
596
|
+
run 0xfa
|
597
|
+
@z.r.a.read.should eq 0x5e
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
context "indirect inc" do
|
602
|
+
it "inc_i_hl" do
|
603
|
+
address = @z.r.hl.read
|
604
|
+
expected = @z.mmu.read_byte(address) + 1
|
605
|
+
run 0x34
|
606
|
+
@z.mmu.read_byte(address).should eq expected
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
610
|
+
context "indirect dec" do
|
611
|
+
it "dec_i_hl" do
|
612
|
+
address = @z.r.hl.read
|
613
|
+
expected = @z.mmu.read_byte(address) - 1
|
614
|
+
run 0x35
|
615
|
+
@z.mmu.read_byte(address).should eq expected
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
context "ld increment" do
|
620
|
+
it "ld hl+ a" do
|
621
|
+
address = @z.r.hl.read
|
622
|
+
run 0x22
|
623
|
+
@z.mmu.read_byte(address).should eq @z.r.a.read
|
624
|
+
@z.r.hl.read.should eq address + 1
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
context "ld decrement" do
|
629
|
+
it "ld hl- a" do
|
630
|
+
@z.r.hl.store 0x4c
|
631
|
+
address = @z.r.hl.read
|
632
|
+
run 0x32
|
633
|
+
@z.mmu.read_byte(address).should eq @z.r.a.read
|
634
|
+
@z.r.hl.read.should eq address - 1
|
635
|
+
end
|
636
|
+
end
|
637
|
+
|
638
|
+
context "ld (indirect destination)" do
|
639
|
+
before(:each) do
|
640
|
+
@z.reset
|
641
|
+
@z.r.a.store 0x01
|
642
|
+
@z.r.b.store 0x02
|
643
|
+
@z.r.c.store 0x03
|
644
|
+
@z.r.d.store 0x04
|
645
|
+
@z.r.e.store 0x05
|
646
|
+
@z.r.h.store 0x06
|
647
|
+
@z.r.l.store 0x07
|
648
|
+
end
|
649
|
+
|
650
|
+
def common destination, target, opcode
|
651
|
+
expected = @z.r.public_send(target.to_sym).read
|
652
|
+
run opcode
|
653
|
+
@z.mmu.read_byte(@z.r.public_send(destination.to_sym).read).should eq expected
|
654
|
+
end
|
655
|
+
|
656
|
+
it "ldi_bc_a" do
|
657
|
+
common :bc, :a, 0x02
|
658
|
+
end
|
659
|
+
|
660
|
+
it "ldi_de_a" do
|
661
|
+
common :de, :a, 0x12
|
662
|
+
end
|
663
|
+
|
664
|
+
it "ldi_hl_b" do
|
665
|
+
common :hl, :b, 0x70
|
666
|
+
end
|
667
|
+
|
668
|
+
it "ldi_hl_c" do
|
669
|
+
common :hl, :c, 0x71
|
670
|
+
end
|
671
|
+
|
672
|
+
it "ldi_hl_d" do
|
673
|
+
common :hl, :d, 0x72
|
674
|
+
end
|
675
|
+
|
676
|
+
it "ldi_hl_e" do
|
677
|
+
common :hl, :e, 0x73
|
678
|
+
end
|
679
|
+
|
680
|
+
it "ldi_hl_h" do
|
681
|
+
common :hl, :h, 0x74
|
682
|
+
end
|
683
|
+
|
684
|
+
it "ldi_hl_l" do
|
685
|
+
common :hl, :l, 0x75
|
686
|
+
end
|
687
|
+
|
688
|
+
it "ldi_hl_a" do
|
689
|
+
common :hl, :a, 0x77
|
690
|
+
end
|
691
|
+
|
692
|
+
it "ld (c) a" do
|
693
|
+
expected = @z.r.a.read
|
694
|
+
address = @z.r.c.read + 0xff00
|
695
|
+
run 0xe2
|
696
|
+
@z.mmu.read_byte(address).should eq expected
|
697
|
+
end
|
698
|
+
|
699
|
+
it "ld (a8) a" do
|
700
|
+
expected = @z.r.a.read
|
701
|
+
address = 0xff35
|
702
|
+
@z.mmu.write_byte(0x00, address)
|
703
|
+
run 0xe0
|
704
|
+
@z.mmu.read_byte(0xff35).should eq expected
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
context "call" do
|
709
|
+
it "call a16" do
|
710
|
+
@z.r.pc.store 0x1234
|
711
|
+
@z.mmu.write_byte 0x1234, 0x34
|
712
|
+
@z.mmu.write_byte 0x1235, 0x84
|
713
|
+
run 0xcd
|
714
|
+
@z.r.pc.read.should eq 0x8434
|
715
|
+
@z.mmu.read_byte(@z.r.sp.read).should eq 0x36
|
716
|
+
@z.mmu.read_byte(@z.r.sp.read + 1).should eq 0x12
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
context "return" do
|
721
|
+
it "ret" do
|
722
|
+
@z.r.pc.store 0x1234
|
723
|
+
@z.mmu.write_byte 0x1234, 0x34
|
724
|
+
@z.mmu.write_byte 0x1235, 0x84
|
725
|
+
run 0xcd
|
726
|
+
run 0xc9
|
727
|
+
@z.r.pc.read.should eq 0x1236
|
728
|
+
end
|
729
|
+
end
|
730
|
+
|
731
|
+
context "add_a" do
|
732
|
+
before(:each) do
|
733
|
+
@z.r.a.store 0xfb
|
734
|
+
@z.r.b.store 0x02
|
735
|
+
@z.r.c.store 0x03
|
736
|
+
@z.r.d.store 0x04
|
737
|
+
@z.r.e.store 0xd5
|
738
|
+
@z.r.h.store 0x06
|
739
|
+
@z.r.l.store 0x07
|
740
|
+
end
|
741
|
+
|
742
|
+
def common destination, target, opcode, mask=0xff
|
743
|
+
v = @z.r.public_send(target.to_sym).read + @z.r.public_send(destination.to_sym).read
|
744
|
+
run opcode
|
745
|
+
@z.r.public_send(destination.to_sym).read.should eq v & mask
|
746
|
+
end
|
747
|
+
|
748
|
+
it "add_a_b" do
|
749
|
+
common :a, :b, 0x80
|
750
|
+
end
|
751
|
+
|
752
|
+
it "add_a_c" do
|
753
|
+
common :a, :c, 0x81
|
754
|
+
end
|
755
|
+
|
756
|
+
it "add_a_d" do
|
757
|
+
common :a, :d, 0x82
|
758
|
+
end
|
759
|
+
|
760
|
+
it "add_a_e" do
|
761
|
+
common :a, :e, 0x83
|
762
|
+
end
|
763
|
+
|
764
|
+
it "add_a_h" do
|
765
|
+
common :a, :h, 0x84
|
766
|
+
end
|
767
|
+
|
768
|
+
it "add_a_l" do
|
769
|
+
common :a, :l, 0x85
|
770
|
+
end
|
771
|
+
|
772
|
+
it "add_a_a" do
|
773
|
+
common :a, :a, 0x87
|
774
|
+
end
|
775
|
+
|
776
|
+
it "add_hl_bc" do
|
777
|
+
common :hl, :bc, 0x09, 0xffff
|
778
|
+
end
|
779
|
+
|
780
|
+
it "add_hl_de" do
|
781
|
+
common :hl, :de, 0x19, 0xffff
|
782
|
+
end
|
783
|
+
|
784
|
+
it "add_hl_hl" do
|
785
|
+
common :hl, :hl, 0x29, 0xffff
|
786
|
+
end
|
787
|
+
|
788
|
+
it "add_hl_sp" do
|
789
|
+
common :hl, :sp, 0x39, 0xffff
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
793
|
+
context "sub_a" do
|
794
|
+
before(:each) do
|
795
|
+
@z.r.a.store 0xfb
|
796
|
+
@z.r.b.store 0x02
|
797
|
+
@z.r.c.store 0x03
|
798
|
+
@z.r.d.store 0x04
|
799
|
+
@z.r.e.store 0xd5
|
800
|
+
@z.r.h.store 0x06
|
801
|
+
@z.r.l.store 0x07
|
802
|
+
end
|
803
|
+
|
804
|
+
def common target, opcode
|
805
|
+
v = @z.r.a.read - @z.r.public_send(target.to_sym).read
|
806
|
+
run opcode
|
807
|
+
@z.r.a.read.should eq (v & 0xFF)
|
808
|
+
end
|
809
|
+
|
810
|
+
it "sub_a_b" do
|
811
|
+
common :b, 0x90
|
812
|
+
end
|
813
|
+
|
814
|
+
it "sub_a_c" do
|
815
|
+
common :c, 0x91
|
816
|
+
end
|
817
|
+
|
818
|
+
it "sub_a_d" do
|
819
|
+
common :d, 0x92
|
820
|
+
end
|
821
|
+
|
822
|
+
it "sub_a_e" do
|
823
|
+
common :e, 0x93
|
824
|
+
end
|
825
|
+
|
826
|
+
it "sub_a_h" do
|
827
|
+
common :h, 0x94
|
828
|
+
end
|
829
|
+
|
830
|
+
it "sub_a_l" do
|
831
|
+
common :l, 0x95
|
832
|
+
end
|
833
|
+
|
834
|
+
it "sub_a_a" do
|
835
|
+
common :a, 0x97
|
836
|
+
end
|
837
|
+
end
|
838
|
+
|
839
|
+
context "indirect add" do
|
840
|
+
it "add a (hl)" do
|
841
|
+
@z.r.hl.store 0x9e
|
842
|
+
@z.mmu.write_byte(@z.r.hl.read, 0x43)
|
843
|
+
@z.r.a.store 0x8b
|
844
|
+
expected = @z.r.a.read + @z.mmu.read_byte(@z.r.hl.read)
|
845
|
+
run 0x86
|
846
|
+
@z.r.a.read.should eq (expected & 0xff)
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
context "indirect sub" do
|
851
|
+
it "sub a (hl)" do
|
852
|
+
@z.r.hl.store 0x9e
|
853
|
+
@z.mmu.write_byte(@z.r.hl.read, 0x43)
|
854
|
+
@z.r.a.store 0x8b
|
855
|
+
expected = @z.r.a.read - @z.mmu.read_byte(@z.r.hl.read)
|
856
|
+
run 0x96
|
857
|
+
@z.r.a.read.should eq (expected & 0xff)
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
context "cp" do
|
862
|
+
before(:each) do
|
863
|
+
@z.r.a.store 0xfb
|
864
|
+
@z.r.b.store 0x02
|
865
|
+
@z.r.c.store 0x03
|
866
|
+
@z.r.d.store 0x04
|
867
|
+
@z.r.e.store 0xd5
|
868
|
+
@z.r.h.store 0x06
|
869
|
+
@z.r.l.store 0x07
|
870
|
+
end
|
871
|
+
|
872
|
+
def common target, opcode
|
873
|
+
v = @z.r.a.read
|
874
|
+
run opcode
|
875
|
+
@z.r.a.read.should eq (v & 0xFF)
|
876
|
+
end
|
877
|
+
|
878
|
+
it "cp_b" do
|
879
|
+
common :b, 0xb8
|
880
|
+
end
|
881
|
+
|
882
|
+
it "cp_c" do
|
883
|
+
common :c, 0xb9
|
884
|
+
end
|
885
|
+
|
886
|
+
it "cp_d" do
|
887
|
+
common :d, 0xba
|
888
|
+
end
|
889
|
+
|
890
|
+
it "cp_e" do
|
891
|
+
common :e, 0xbb
|
892
|
+
end
|
893
|
+
|
894
|
+
it "cp_h" do
|
895
|
+
common :h, 0xbc
|
896
|
+
end
|
897
|
+
|
898
|
+
it "cp_l" do
|
899
|
+
common :l, 0xbd
|
900
|
+
end
|
901
|
+
|
902
|
+
it "cp_a" do
|
903
|
+
common :a, 0xbf
|
904
|
+
end
|
905
|
+
|
906
|
+
it "cp d8" do
|
907
|
+
common nil, 0xfe
|
908
|
+
end
|
909
|
+
end
|
910
|
+
|
911
|
+
context "adc" do
|
912
|
+
before(:each) do
|
913
|
+
@z.r.a.store 0xfb
|
914
|
+
@z.r.b.store 0x02
|
915
|
+
@z.r.c.store 0x03
|
916
|
+
@z.r.d.store 0x04
|
917
|
+
@z.r.e.store 0xd5
|
918
|
+
@z.r.h.store 0x06
|
919
|
+
@z.r.l.store 0x07
|
920
|
+
end
|
921
|
+
|
922
|
+
context "no carrry set" do
|
923
|
+
def common target, opcode
|
924
|
+
v = @z.r.a.read + @z.r.public_send(target.to_sym).read
|
925
|
+
run opcode
|
926
|
+
@z.r.a.read.should eq (v & 0xff)
|
927
|
+
end
|
928
|
+
|
929
|
+
before(:each) { @z.r.clear_carry_flag }
|
930
|
+
it "adc_b" do
|
931
|
+
common :b, 0x88
|
932
|
+
end
|
933
|
+
|
934
|
+
it "adc_c" do
|
935
|
+
common :c, 0x89
|
936
|
+
end
|
937
|
+
|
938
|
+
it "adc_d" do
|
939
|
+
common :d, 0x8a
|
940
|
+
end
|
941
|
+
|
942
|
+
it "adc_e" do
|
943
|
+
common :e, 0x8b
|
944
|
+
end
|
945
|
+
|
946
|
+
it "adc_h" do
|
947
|
+
common :h, 0x8c
|
948
|
+
end
|
949
|
+
|
950
|
+
it "adc_l" do
|
951
|
+
common :l, 0x8d
|
952
|
+
end
|
953
|
+
|
954
|
+
it "adc_a" do
|
955
|
+
common :a, 0x8f
|
956
|
+
end
|
957
|
+
end
|
958
|
+
|
959
|
+
context "carrry set" do
|
960
|
+
def common target, opcode
|
961
|
+
v = @z.r.a.read + @z.r.public_send(target.to_sym).read + 1
|
962
|
+
run opcode
|
963
|
+
@z.r.a.read.should eq (v & 0xff)
|
964
|
+
end
|
965
|
+
|
966
|
+
before(:each) { @z.r.set_carry_flag }
|
967
|
+
it "adc_b" do
|
968
|
+
common :b, 0x88
|
969
|
+
end
|
970
|
+
|
971
|
+
it "adc_c" do
|
972
|
+
common :c, 0x89
|
973
|
+
end
|
974
|
+
|
975
|
+
it "adc_d" do
|
976
|
+
common :d, 0x8a
|
977
|
+
end
|
978
|
+
|
979
|
+
it "adc_e" do
|
980
|
+
common :e, 0x8b
|
981
|
+
end
|
982
|
+
|
983
|
+
it "adc_h" do
|
984
|
+
common :h, 0x8c
|
985
|
+
end
|
986
|
+
|
987
|
+
it "adc_l" do
|
988
|
+
common :l, 0x8d
|
989
|
+
end
|
990
|
+
|
991
|
+
it "adc_a" do
|
992
|
+
common :a, 0x8f
|
993
|
+
end
|
994
|
+
end
|
995
|
+
end
|
996
|
+
|
997
|
+
context "sbc" do
|
998
|
+
before(:each) do
|
999
|
+
@z.r.a.store 0xfb
|
1000
|
+
@z.r.b.store 0x02
|
1001
|
+
@z.r.c.store 0x03
|
1002
|
+
@z.r.d.store 0x04
|
1003
|
+
@z.r.e.store 0xd5
|
1004
|
+
@z.r.h.store 0x06
|
1005
|
+
@z.r.l.store 0x07
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
context "no carrry set" do
|
1009
|
+
def common target, opcode
|
1010
|
+
v = @z.r.a.read - @z.r.public_send(target.to_sym).read
|
1011
|
+
run opcode
|
1012
|
+
@z.r.a.read.should eq (v & 0xff)
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
before(:each) { @z.r.clear_carry_flag }
|
1016
|
+
it "sbc_b" do
|
1017
|
+
common :b, 0x98
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
it "sbc_c" do
|
1021
|
+
common :c, 0x99
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
it "sbc_d" do
|
1025
|
+
common :d, 0x9a
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
it "sbc_e" do
|
1029
|
+
common :e, 0x9b
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
it "sbc_h" do
|
1033
|
+
common :h, 0x9c
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
it "sbc_l" do
|
1037
|
+
common :l, 0x9d
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
it "sbc_a" do
|
1041
|
+
common :a, 0x9f
|
1042
|
+
end
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
context "carrry set" do
|
1046
|
+
def common target, opcode
|
1047
|
+
v = @z.r.a.read - @z.r.public_send(target.to_sym).read - 1
|
1048
|
+
run opcode
|
1049
|
+
@z.r.a.read.should eq (v & 0xff)
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
before(:each) { @z.r.set_carry_flag }
|
1053
|
+
it "sbc_b" do
|
1054
|
+
common :b, 0x98
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
it "sbc_c" do
|
1058
|
+
common :c, 0x99
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
it "sbc_d" do
|
1062
|
+
common :d, 0x9a
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
it "sbc_e" do
|
1066
|
+
common :e, 0x9b
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
it "sbc_h" do
|
1070
|
+
common :h, 0x9c
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
it "sbc_l" do
|
1074
|
+
common :l, 0x9d
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
it "sbc_a" do
|
1078
|
+
common :a, 0x9f
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
|
1084
|
+
context "and" do
|
1085
|
+
before(:each) do
|
1086
|
+
@z.r.a.store 0xfb
|
1087
|
+
@z.r.b.store 0x02
|
1088
|
+
@z.r.c.store 0x03
|
1089
|
+
@z.r.d.store 0x04
|
1090
|
+
@z.r.e.store 0xd5
|
1091
|
+
@z.r.h.store 0x06
|
1092
|
+
@z.r.l.store 0x07
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
def common target, opcode
|
1096
|
+
v = @z.r.public_send(target.to_sym).read & @z.r.a.read
|
1097
|
+
run opcode
|
1098
|
+
@z.r.a.read.should eq (v & 0xFF)
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
it "and_b" do
|
1102
|
+
common :b, 0xa0
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
it "and_c" do
|
1106
|
+
common :c, 0xa1
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
it "and_d" do
|
1110
|
+
common :d, 0xa2
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
it "and_e" do
|
1114
|
+
common :e, 0xa3
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
it "and_h" do
|
1118
|
+
common :h, 0xa4
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
it "and_l" do
|
1122
|
+
common :l, 0xa5
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
it "and_a" do
|
1126
|
+
common :a, 0xa7
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
context "indirect and" do
|
1131
|
+
it "and hl" do
|
1132
|
+
@z.r.a.store 0x31
|
1133
|
+
@z.r.hl.store 0x77
|
1134
|
+
@z.mmu.write_byte(@z.r.hl.read, 0xb7)
|
1135
|
+
expected = @z.r.a.read & @z.mmu.read_byte(@z.r.hl.read)
|
1136
|
+
run 0xa6
|
1137
|
+
@z.r.a.read.should eq expected
|
1138
|
+
end
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
context "or" do
|
1142
|
+
before(:each) do
|
1143
|
+
@z.r.a.store 0xfb
|
1144
|
+
@z.r.b.store 0x02
|
1145
|
+
@z.r.c.store 0x03
|
1146
|
+
@z.r.d.store 0x04
|
1147
|
+
@z.r.e.store 0xd5
|
1148
|
+
@z.r.h.store 0x06
|
1149
|
+
@z.r.l.store 0x07
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
def common target, opcode
|
1153
|
+
v = @z.r.public_send(target.to_sym).read | @z.r.a.read
|
1154
|
+
run opcode
|
1155
|
+
@z.r.a.read.should eq (v & 0xFF)
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
it "or_b" do
|
1159
|
+
common :b, 0xb0
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
it "or_c" do
|
1163
|
+
common :c, 0xb1
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
it "or_d" do
|
1167
|
+
common :d, 0xb2
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
it "or_e" do
|
1171
|
+
common :e, 0xb3
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
it "or_h" do
|
1175
|
+
common :h, 0xb4
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
it "or_l" do
|
1179
|
+
common :l, 0xb5
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
it "or_a" do
|
1183
|
+
common :a, 0xb7
|
1184
|
+
end
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
context "indirect or" do
|
1188
|
+
it "or hl" do
|
1189
|
+
@z.r.a.store 0x31
|
1190
|
+
@z.r.hl.store 0x77
|
1191
|
+
@z.mmu.write_byte(@z.r.hl.read, 0xb7)
|
1192
|
+
expected = @z.r.a.read | @z.mmu.read_byte(@z.r.hl.read)
|
1193
|
+
run 0xb6
|
1194
|
+
@z.r.a.read.should eq expected
|
1195
|
+
end
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
context "xor" do
|
1199
|
+
before(:each) do
|
1200
|
+
@z.r.a.store 0xfb
|
1201
|
+
@z.r.b.store 0x02
|
1202
|
+
@z.r.c.store 0x03
|
1203
|
+
@z.r.d.store 0x04
|
1204
|
+
@z.r.e.store 0xd5
|
1205
|
+
@z.r.h.store 0x06
|
1206
|
+
@z.r.l.store 0x07
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
def common target, opcode
|
1210
|
+
v = @z.r.public_send(target.to_sym).read ^ @z.r.a.read
|
1211
|
+
run opcode
|
1212
|
+
@z.r.a.read.should eq (v & 0xFF)
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
it "xor_b" do
|
1216
|
+
common :b, 0xa8
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
it "xor_c" do
|
1220
|
+
common :c, 0xa9
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
it "xor_d" do
|
1224
|
+
common :d, 0xaa
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
it "xor_e" do
|
1228
|
+
common :e, 0xab
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
it "xor_h" do
|
1232
|
+
common :h, 0xac
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
it "xor_l" do
|
1236
|
+
common :l, 0xad
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
it "xor_a" do
|
1240
|
+
common :a, 0xaf
|
1241
|
+
end
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
context "indirect xor" do
|
1245
|
+
it "xor hl" do
|
1246
|
+
@z.r.a.store 0x31
|
1247
|
+
@z.r.hl.store 0x77
|
1248
|
+
@z.mmu.write_byte(@z.r.hl.read, 0xb7)
|
1249
|
+
expected = @z.r.a.read ^ @z.mmu.read_byte(@z.r.hl.read)
|
1250
|
+
run 0xae
|
1251
|
+
@z.r.a.read.should eq expected
|
1252
|
+
end
|
1253
|
+
end
|
1254
|
+
|
1255
|
+
context "rst" do
|
1256
|
+
def common opcode, offset
|
1257
|
+
original_address = @z.r.pc.read
|
1258
|
+
run opcode
|
1259
|
+
@z.r.pc.read.should eq offset
|
1260
|
+
sp = @z.r.sp.read
|
1261
|
+
((@z.mmu.read_byte(sp) << 4) + @z.mmu.read_byte(sp+1)).should eq original_address
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
it "rst 0x00" do
|
1265
|
+
common 0xc7, 0x00
|
1266
|
+
end
|
1267
|
+
|
1268
|
+
it "rst 0x08" do
|
1269
|
+
common 0xcf, 0x08
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
it "rst 0x10" do
|
1273
|
+
common 0xd7, 0x10
|
1274
|
+
end
|
1275
|
+
|
1276
|
+
it "rst 0x18" do
|
1277
|
+
common 0xdf, 0x18
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
it "rst 0x20" do
|
1281
|
+
common 0xe7, 0x20
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
it "rst 0x28" do
|
1285
|
+
common 0xef, 0x28
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
it "rst 0x30" do
|
1289
|
+
common 0xf7, 0x30
|
1290
|
+
end
|
1291
|
+
|
1292
|
+
it "rst 0x38" do
|
1293
|
+
common 0xff, 0x38
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
context "#cb_instructions" do
|
1299
|
+
before(:all) { @z = Z80.new }
|
1300
|
+
before(:each) { @z.reset }
|
1301
|
+
|
1302
|
+
def run op
|
1303
|
+
@z.dispatch @z.decode 0xcb
|
1304
|
+
@z.dispatch @z.decode op.to_i
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
context "#reset" do
|
1308
|
+
def common register, op
|
1309
|
+
if register == :hl
|
1310
|
+
@z.mmu.write_byte 0x43, 0xff
|
1311
|
+
@z.r.hl.store 0x43
|
1312
|
+
else
|
1313
|
+
@z.r.public_send(register.to_sym).store 0xff
|
1314
|
+
end
|
1315
|
+
run op
|
1316
|
+
|
1317
|
+
if register == :hl
|
1318
|
+
@z.mmu.read_byte(@z.r.hl.read).should eq @exp
|
1319
|
+
else
|
1320
|
+
@z.r.public_send(register.to_sym).read.should eq @exp
|
1321
|
+
end
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
context "0" do
|
1325
|
+
before(:all) { @exp = 0xfe }
|
1326
|
+
|
1327
|
+
it "res 0 b" do
|
1328
|
+
common :b, 0x80
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
it "res 0 c" do
|
1332
|
+
common :c, 0x81
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
it "res 0 d" do
|
1336
|
+
common :d, 0x82
|
1337
|
+
end
|
1338
|
+
|
1339
|
+
it "res 0 e" do
|
1340
|
+
common :e, 0x83
|
1341
|
+
end
|
1342
|
+
|
1343
|
+
it "res 0 h" do
|
1344
|
+
common :h, 0x84
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
it "res 0 l" do
|
1348
|
+
common :l, 0x85
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
it "res 0 hl" do
|
1352
|
+
common :hl, 0x86
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
it "res 0 a" do
|
1356
|
+
common :a, 0x87
|
1357
|
+
end
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
context "1" do
|
1361
|
+
before(:all) { @exp = 0xfd }
|
1362
|
+
|
1363
|
+
it "res 1 b" do
|
1364
|
+
common :b, 0x88
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
it "res 1 c" do
|
1368
|
+
common :c, 0x89
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
it "res 1 d" do
|
1372
|
+
common :d, 0x8a
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
it "res 1 e" do
|
1376
|
+
common :e, 0x8b
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
it "res 1 h" do
|
1380
|
+
common :h, 0x8c
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
it "res 1 l" do
|
1384
|
+
common :l, 0x8d
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
it "res 1 hl" do
|
1388
|
+
common :hl, 0x8e
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
it "res 1 a" do
|
1392
|
+
common :a, 0x8f
|
1393
|
+
end
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
context "2" do
|
1397
|
+
before(:all) { @exp = 0xfb }
|
1398
|
+
|
1399
|
+
it "res 2 b" do
|
1400
|
+
common :b, 0x90
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
it "res 2 c" do
|
1404
|
+
common :c, 0x91
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
it "res 2 d" do
|
1408
|
+
common :d, 0x92
|
1409
|
+
end
|
1410
|
+
|
1411
|
+
it "res 2 e" do
|
1412
|
+
common :e, 0x93
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
it "res 2 h" do
|
1416
|
+
common :h, 0x94
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
it "res 2 l" do
|
1420
|
+
common :l, 0x95
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
it "res 2 hl" do
|
1424
|
+
common :hl, 0x96
|
1425
|
+
end
|
1426
|
+
|
1427
|
+
it "res 2 a" do
|
1428
|
+
common :a, 0x97
|
1429
|
+
end
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
context "3" do
|
1433
|
+
before(:all) { @exp = 0xf7 }
|
1434
|
+
|
1435
|
+
it "res 3 b" do
|
1436
|
+
common :b, 0x98
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
it "res 3 c" do
|
1440
|
+
common :c, 0x99
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
it "res 3 d" do
|
1444
|
+
common :d, 0x9a
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
it "res 3 e" do
|
1448
|
+
common :e, 0x9b
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
it "res 3 h" do
|
1452
|
+
common :h, 0x9c
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
it "res 3 l" do
|
1456
|
+
common :l, 0x9d
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
it "res 3 hl" do
|
1460
|
+
common :hl, 0x9e
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
it "res 3 a" do
|
1464
|
+
common :a, 0x9f
|
1465
|
+
end
|
1466
|
+
end
|
1467
|
+
|
1468
|
+
context "4" do
|
1469
|
+
before(:all) { @exp = 0xef }
|
1470
|
+
|
1471
|
+
it "res 4 b" do
|
1472
|
+
common :b, 0xa0
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
it "res 4 c" do
|
1476
|
+
common :c, 0xa1
|
1477
|
+
end
|
1478
|
+
|
1479
|
+
it "res 4 d" do
|
1480
|
+
common :d, 0xa2
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
it "res 4 e" do
|
1484
|
+
common :e, 0xa3
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
it "res 4 h" do
|
1488
|
+
common :h, 0xa4
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
it "res 4 l" do
|
1492
|
+
common :l, 0xa5
|
1493
|
+
end
|
1494
|
+
|
1495
|
+
it "res 4 hl" do
|
1496
|
+
common :hl, 0xa6
|
1497
|
+
end
|
1498
|
+
|
1499
|
+
it "res 4 a" do
|
1500
|
+
common :a, 0xa7
|
1501
|
+
end
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
context "5" do
|
1505
|
+
before(:all) { @exp = 0xdf }
|
1506
|
+
|
1507
|
+
it "res 5 b" do
|
1508
|
+
common :b, 0xa8
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
it "res 5 c" do
|
1512
|
+
common :c, 0xa9
|
1513
|
+
end
|
1514
|
+
|
1515
|
+
it "res 5 d" do
|
1516
|
+
common :d, 0xaa
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
it "res 5 e" do
|
1520
|
+
common :e, 0xab
|
1521
|
+
end
|
1522
|
+
|
1523
|
+
it "res 5 h" do
|
1524
|
+
common :h, 0xac
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
it "res 5 l" do
|
1528
|
+
common :l, 0xad
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
it "res 5 hl" do
|
1532
|
+
common :hl, 0xae
|
1533
|
+
end
|
1534
|
+
|
1535
|
+
it "res 5 a" do
|
1536
|
+
common :a, 0xaf
|
1537
|
+
end
|
1538
|
+
end
|
1539
|
+
|
1540
|
+
context "6" do
|
1541
|
+
before(:all) { @exp = 0xbf }
|
1542
|
+
|
1543
|
+
it "res 6 b" do
|
1544
|
+
common :b, 0xb0
|
1545
|
+
end
|
1546
|
+
|
1547
|
+
it "res 6 c" do
|
1548
|
+
common :c, 0xb1
|
1549
|
+
end
|
1550
|
+
|
1551
|
+
it "res 6 d" do
|
1552
|
+
common :d, 0xb2
|
1553
|
+
end
|
1554
|
+
|
1555
|
+
it "res 6 e" do
|
1556
|
+
common :e, 0xb3
|
1557
|
+
end
|
1558
|
+
|
1559
|
+
it "res 6 h" do
|
1560
|
+
common :h, 0xb4
|
1561
|
+
end
|
1562
|
+
|
1563
|
+
it "res 6 l" do
|
1564
|
+
common :l, 0xb5
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
it "res 6 hl" do
|
1568
|
+
common :hl, 0xb6
|
1569
|
+
end
|
1570
|
+
|
1571
|
+
it "res 6 a" do
|
1572
|
+
common :a, 0xb7
|
1573
|
+
end
|
1574
|
+
end
|
1575
|
+
|
1576
|
+
context "7" do
|
1577
|
+
before(:all) { @exp = 0x7f }
|
1578
|
+
|
1579
|
+
it "res 7 b" do
|
1580
|
+
common :b, 0xb8
|
1581
|
+
end
|
1582
|
+
|
1583
|
+
it "res 7 c" do
|
1584
|
+
common :c, 0xb9
|
1585
|
+
end
|
1586
|
+
|
1587
|
+
it "res 7 d" do
|
1588
|
+
common :d, 0xba
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
it "res 7 e" do
|
1592
|
+
common :e, 0xbb
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
it "res 7 h" do
|
1596
|
+
common :h, 0xbc
|
1597
|
+
end
|
1598
|
+
|
1599
|
+
it "res 7 l" do
|
1600
|
+
common :l, 0xbd
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
it "res 7 hl" do
|
1604
|
+
common :hl, 0xbe
|
1605
|
+
end
|
1606
|
+
|
1607
|
+
it "res 7 a" do
|
1608
|
+
common :a, 0xbf
|
1609
|
+
end
|
1610
|
+
end
|
1611
|
+
end
|
1612
|
+
context "#set" do
|
1613
|
+
def common register, op
|
1614
|
+
if register == :hl
|
1615
|
+
@z.mmu.write_byte 0x43, 0x00
|
1616
|
+
@z.r.hl.store 0x43
|
1617
|
+
else
|
1618
|
+
@z.r.public_send(register.to_sym).store 0x00
|
1619
|
+
end
|
1620
|
+
run op
|
1621
|
+
|
1622
|
+
if register == :hl
|
1623
|
+
@z.mmu.read_byte(@z.r.hl.read).should eq @exp
|
1624
|
+
else
|
1625
|
+
@z.r.public_send(register.to_sym).read.should eq @exp
|
1626
|
+
end
|
1627
|
+
end
|
1628
|
+
|
1629
|
+
context "0" do
|
1630
|
+
before(:all) { @exp = 0x01 }
|
1631
|
+
|
1632
|
+
it "set 0 b" do
|
1633
|
+
common :b, 0xc0
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
it "set 0 c" do
|
1637
|
+
common :c, 0xc1
|
1638
|
+
end
|
1639
|
+
|
1640
|
+
it "set 0 d" do
|
1641
|
+
common :d, 0xc2
|
1642
|
+
end
|
1643
|
+
|
1644
|
+
it "set 0 e" do
|
1645
|
+
common :e, 0xc3
|
1646
|
+
end
|
1647
|
+
|
1648
|
+
it "set 0 h" do
|
1649
|
+
common :h, 0xc4
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
it "set 0 l" do
|
1653
|
+
common :l, 0xc5
|
1654
|
+
end
|
1655
|
+
|
1656
|
+
it "set 0 hl" do
|
1657
|
+
common :hl, 0xc6
|
1658
|
+
end
|
1659
|
+
|
1660
|
+
it "set 0 a" do
|
1661
|
+
common :a, 0xc7
|
1662
|
+
end
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
context "1" do
|
1666
|
+
before(:all) { @exp = 0x02 }
|
1667
|
+
|
1668
|
+
it "set 1 b" do
|
1669
|
+
common :b, 0xc8
|
1670
|
+
end
|
1671
|
+
|
1672
|
+
it "set 1 c" do
|
1673
|
+
common :c, 0xc9
|
1674
|
+
end
|
1675
|
+
|
1676
|
+
it "set 1 d" do
|
1677
|
+
common :d, 0xca
|
1678
|
+
end
|
1679
|
+
|
1680
|
+
it "set 1 e" do
|
1681
|
+
common :e, 0xcb
|
1682
|
+
end
|
1683
|
+
|
1684
|
+
it "set 1 h" do
|
1685
|
+
common :h, 0xcc
|
1686
|
+
end
|
1687
|
+
|
1688
|
+
it "set 1 l" do
|
1689
|
+
common :l, 0xcd
|
1690
|
+
end
|
1691
|
+
|
1692
|
+
it "set 1 hl" do
|
1693
|
+
common :hl, 0xce
|
1694
|
+
end
|
1695
|
+
|
1696
|
+
it "set 1 a" do
|
1697
|
+
common :a, 0xcf
|
1698
|
+
end
|
1699
|
+
end
|
1700
|
+
|
1701
|
+
context "2" do
|
1702
|
+
before(:all) { @exp = 0x04 }
|
1703
|
+
|
1704
|
+
it "set 2 b" do
|
1705
|
+
common :b, 0xd0
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
it "set 2 c" do
|
1709
|
+
common :c, 0xd1
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
it "set 2 d" do
|
1713
|
+
common :d, 0xd2
|
1714
|
+
end
|
1715
|
+
|
1716
|
+
it "set 2 e" do
|
1717
|
+
common :e, 0xd3
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
it "set 2 h" do
|
1721
|
+
common :h, 0xd4
|
1722
|
+
end
|
1723
|
+
|
1724
|
+
it "set 2 l" do
|
1725
|
+
common :l, 0xd5
|
1726
|
+
end
|
1727
|
+
|
1728
|
+
it "set 2 hl" do
|
1729
|
+
common :hl, 0xd6
|
1730
|
+
end
|
1731
|
+
|
1732
|
+
it "set 2 a" do
|
1733
|
+
common :a, 0xd7
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
context "3" do
|
1738
|
+
before(:all) { @exp = 0x08 }
|
1739
|
+
|
1740
|
+
it "set 3 b" do
|
1741
|
+
common :b, 0xd8
|
1742
|
+
end
|
1743
|
+
|
1744
|
+
it "set 3 c" do
|
1745
|
+
common :c, 0xd9
|
1746
|
+
end
|
1747
|
+
|
1748
|
+
it "set 3 d" do
|
1749
|
+
common :d, 0xda
|
1750
|
+
end
|
1751
|
+
|
1752
|
+
it "set 3 e" do
|
1753
|
+
common :e, 0xdb
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
it "set 3 h" do
|
1757
|
+
common :h, 0xdc
|
1758
|
+
end
|
1759
|
+
|
1760
|
+
it "set 3 l" do
|
1761
|
+
common :l, 0xdd
|
1762
|
+
end
|
1763
|
+
|
1764
|
+
it "set 3 hl" do
|
1765
|
+
common :hl, 0xde
|
1766
|
+
end
|
1767
|
+
|
1768
|
+
it "set 3 a" do
|
1769
|
+
common :a, 0xdf
|
1770
|
+
end
|
1771
|
+
end
|
1772
|
+
|
1773
|
+
context "4" do
|
1774
|
+
before(:all) { @exp = 0x10 }
|
1775
|
+
|
1776
|
+
it "set 4 b" do
|
1777
|
+
common :b, 0xe0
|
1778
|
+
end
|
1779
|
+
|
1780
|
+
it "set 4 c" do
|
1781
|
+
common :c, 0xe1
|
1782
|
+
end
|
1783
|
+
|
1784
|
+
it "set 4 d" do
|
1785
|
+
common :d, 0xe2
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
it "set 4 e" do
|
1789
|
+
common :e, 0xe3
|
1790
|
+
end
|
1791
|
+
|
1792
|
+
it "set 4 h" do
|
1793
|
+
common :h, 0xe4
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
it "set 4 l" do
|
1797
|
+
common :l, 0xe5
|
1798
|
+
end
|
1799
|
+
|
1800
|
+
it "set 4 hl" do
|
1801
|
+
common :hl, 0xe6
|
1802
|
+
end
|
1803
|
+
|
1804
|
+
it "set 4 a" do
|
1805
|
+
common :a, 0xe7
|
1806
|
+
end
|
1807
|
+
end
|
1808
|
+
|
1809
|
+
context "5" do
|
1810
|
+
before(:all) { @exp = 0x20 }
|
1811
|
+
|
1812
|
+
it "set 5 b" do
|
1813
|
+
common :b, 0xe8
|
1814
|
+
end
|
1815
|
+
|
1816
|
+
it "set 5 c" do
|
1817
|
+
common :c, 0xe9
|
1818
|
+
end
|
1819
|
+
|
1820
|
+
it "set 5 d" do
|
1821
|
+
common :d, 0xea
|
1822
|
+
end
|
1823
|
+
|
1824
|
+
it "set 5 e" do
|
1825
|
+
common :e, 0xeb
|
1826
|
+
end
|
1827
|
+
|
1828
|
+
it "set 5 h" do
|
1829
|
+
common :h, 0xec
|
1830
|
+
end
|
1831
|
+
|
1832
|
+
it "set 5 l" do
|
1833
|
+
common :l, 0xed
|
1834
|
+
end
|
1835
|
+
|
1836
|
+
it "set 5 hl" do
|
1837
|
+
common :hl, 0xee
|
1838
|
+
end
|
1839
|
+
|
1840
|
+
it "set 5 a" do
|
1841
|
+
common :a, 0xef
|
1842
|
+
end
|
1843
|
+
end
|
1844
|
+
|
1845
|
+
context "6" do
|
1846
|
+
before(:all) { @exp = 0x40 }
|
1847
|
+
|
1848
|
+
it "set 6 b" do
|
1849
|
+
common :b, 0xf0
|
1850
|
+
end
|
1851
|
+
|
1852
|
+
it "set 6 c" do
|
1853
|
+
common :c, 0xf1
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
it "set 6 d" do
|
1857
|
+
common :d, 0xf2
|
1858
|
+
end
|
1859
|
+
|
1860
|
+
it "set 6 e" do
|
1861
|
+
common :e, 0xf3
|
1862
|
+
end
|
1863
|
+
|
1864
|
+
it "set 6 h" do
|
1865
|
+
common :h, 0xf4
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
it "set 6 l" do
|
1869
|
+
common :l, 0xf5
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
it "set 6 hl" do
|
1873
|
+
common :hl, 0xf6
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
it "set 6 a" do
|
1877
|
+
common :a, 0xf7
|
1878
|
+
end
|
1879
|
+
end
|
1880
|
+
|
1881
|
+
context "7" do
|
1882
|
+
before(:all) { @exp = 0x80 }
|
1883
|
+
|
1884
|
+
it "set 7 b" do
|
1885
|
+
common :b, 0xf8
|
1886
|
+
end
|
1887
|
+
|
1888
|
+
it "set 7 c" do
|
1889
|
+
common :c, 0xf9
|
1890
|
+
end
|
1891
|
+
|
1892
|
+
it "set 7 d" do
|
1893
|
+
common :d, 0xfa
|
1894
|
+
end
|
1895
|
+
|
1896
|
+
it "set 7 e" do
|
1897
|
+
common :e, 0xfb
|
1898
|
+
end
|
1899
|
+
|
1900
|
+
it "set 7 h" do
|
1901
|
+
common :h, 0xfc
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
it "set 7 l" do
|
1905
|
+
common :l, 0xfd
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
it "set 7 hl" do
|
1909
|
+
common :hl, 0xfe
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
it "set 7 a" do
|
1913
|
+
common :a, 0xff
|
1914
|
+
end
|
1915
|
+
end
|
1916
|
+
end
|
1917
|
+
|
1918
|
+
context "#bit" do
|
1919
|
+
def common register, op
|
1920
|
+
if register == :hl
|
1921
|
+
@z.mmu.write_byte 0x43, 0xab
|
1922
|
+
@z.r.hl.store 0x43
|
1923
|
+
else
|
1924
|
+
@z.r.public_send(register.to_sym).store 0xab
|
1925
|
+
end
|
1926
|
+
run op
|
1927
|
+
|
1928
|
+
@z.r.zero_flag?.should eq @exp
|
1929
|
+
end
|
1930
|
+
|
1931
|
+
context "0" do
|
1932
|
+
before(:all) { @exp = false }
|
1933
|
+
|
1934
|
+
it "bit 0 b" do
|
1935
|
+
common :b, 0x40
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
it "bit 0 c" do
|
1939
|
+
common :c, 0x41
|
1940
|
+
end
|
1941
|
+
|
1942
|
+
it "bit 0 d" do
|
1943
|
+
common :d, 0x42
|
1944
|
+
end
|
1945
|
+
|
1946
|
+
it "bit 0 e" do
|
1947
|
+
common :e, 0x43
|
1948
|
+
end
|
1949
|
+
|
1950
|
+
it "bit 0 h" do
|
1951
|
+
common :h, 0x44
|
1952
|
+
end
|
1953
|
+
|
1954
|
+
it "bit 0 l" do
|
1955
|
+
common :l, 0x45
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
it "bit 0 hl" do
|
1959
|
+
common :hl, 0x46
|
1960
|
+
end
|
1961
|
+
|
1962
|
+
it "bit 0 a" do
|
1963
|
+
common :a, 0x47
|
1964
|
+
end
|
1965
|
+
end
|
1966
|
+
|
1967
|
+
context "1" do
|
1968
|
+
before(:all) { @exp = false }
|
1969
|
+
|
1970
|
+
it "bit 1 b" do
|
1971
|
+
common :b, 0x48
|
1972
|
+
end
|
1973
|
+
|
1974
|
+
it "bit 1 c" do
|
1975
|
+
common :c, 0x49
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
it "bit 1 d" do
|
1979
|
+
common :d, 0x4a
|
1980
|
+
end
|
1981
|
+
|
1982
|
+
it "bit 1 e" do
|
1983
|
+
common :e, 0x4b
|
1984
|
+
end
|
1985
|
+
|
1986
|
+
it "bit 1 h" do
|
1987
|
+
common :h, 0x4c
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
it "bit 1 l" do
|
1991
|
+
common :l, 0x4d
|
1992
|
+
end
|
1993
|
+
|
1994
|
+
it "bit 1 hl" do
|
1995
|
+
common :hl, 0x4e
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
it "bit 1 a" do
|
1999
|
+
common :a, 0x4f
|
2000
|
+
end
|
2001
|
+
end
|
2002
|
+
|
2003
|
+
context "2" do
|
2004
|
+
before(:all) { @exp = true }
|
2005
|
+
|
2006
|
+
it "bit 2 b" do
|
2007
|
+
common :b, 0x50
|
2008
|
+
end
|
2009
|
+
|
2010
|
+
it "bit 2 c" do
|
2011
|
+
common :c, 0x51
|
2012
|
+
end
|
2013
|
+
|
2014
|
+
it "bit 2 d" do
|
2015
|
+
common :d, 0x52
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
it "bit 2 e" do
|
2019
|
+
common :e, 0x53
|
2020
|
+
end
|
2021
|
+
|
2022
|
+
it "bit 2 h" do
|
2023
|
+
common :h, 0x54
|
2024
|
+
end
|
2025
|
+
|
2026
|
+
it "bit 2 l" do
|
2027
|
+
common :l, 0x55
|
2028
|
+
end
|
2029
|
+
|
2030
|
+
it "bit 2 hl" do
|
2031
|
+
common :hl, 0x56
|
2032
|
+
end
|
2033
|
+
|
2034
|
+
it "bit 2 a" do
|
2035
|
+
common :a, 0x57
|
2036
|
+
end
|
2037
|
+
end
|
2038
|
+
|
2039
|
+
context "3" do
|
2040
|
+
before(:all) { @exp = false }
|
2041
|
+
|
2042
|
+
it "bit 3 b" do
|
2043
|
+
common :b, 0x58
|
2044
|
+
end
|
2045
|
+
|
2046
|
+
it "bit 3 c" do
|
2047
|
+
common :c, 0x59
|
2048
|
+
end
|
2049
|
+
|
2050
|
+
it "bit 3 d" do
|
2051
|
+
common :d, 0x5a
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
it "bit 3 e" do
|
2055
|
+
common :e, 0x5b
|
2056
|
+
end
|
2057
|
+
|
2058
|
+
it "bit 3 h" do
|
2059
|
+
common :h, 0x5c
|
2060
|
+
end
|
2061
|
+
|
2062
|
+
it "bit 3 l" do
|
2063
|
+
common :l, 0x5d
|
2064
|
+
end
|
2065
|
+
|
2066
|
+
it "bit 3 hl" do
|
2067
|
+
common :hl, 0x5e
|
2068
|
+
end
|
2069
|
+
|
2070
|
+
it "bit 3 a" do
|
2071
|
+
common :a, 0x5f
|
2072
|
+
end
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
context "4" do
|
2076
|
+
before(:all) { @exp = true }
|
2077
|
+
|
2078
|
+
it "bit 4 b" do
|
2079
|
+
common :b, 0x60
|
2080
|
+
end
|
2081
|
+
|
2082
|
+
it "bit 4 c" do
|
2083
|
+
common :c, 0x61
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
it "bit 4 d" do
|
2087
|
+
common :d, 0x62
|
2088
|
+
end
|
2089
|
+
|
2090
|
+
it "bit 4 e" do
|
2091
|
+
common :e, 0x63
|
2092
|
+
end
|
2093
|
+
|
2094
|
+
it "bit 4 h" do
|
2095
|
+
common :h, 0x64
|
2096
|
+
end
|
2097
|
+
|
2098
|
+
it "bit 4 l" do
|
2099
|
+
common :l, 0x65
|
2100
|
+
end
|
2101
|
+
|
2102
|
+
it "bit 4 hl" do
|
2103
|
+
common :hl, 0x66
|
2104
|
+
end
|
2105
|
+
|
2106
|
+
it "bit 4 a" do
|
2107
|
+
common :a, 0x67
|
2108
|
+
end
|
2109
|
+
end
|
2110
|
+
|
2111
|
+
context "5" do
|
2112
|
+
before(:all) { @exp = false }
|
2113
|
+
|
2114
|
+
it "bit 5 b" do
|
2115
|
+
common :b, 0x68
|
2116
|
+
end
|
2117
|
+
|
2118
|
+
it "bit 5 c" do
|
2119
|
+
common :c, 0x69
|
2120
|
+
end
|
2121
|
+
|
2122
|
+
it "bit 5 d" do
|
2123
|
+
common :d, 0x6a
|
2124
|
+
end
|
2125
|
+
|
2126
|
+
it "bit 5 e" do
|
2127
|
+
common :e, 0x6b
|
2128
|
+
end
|
2129
|
+
|
2130
|
+
it "bit 5 h" do
|
2131
|
+
common :h, 0x6c
|
2132
|
+
end
|
2133
|
+
|
2134
|
+
it "bit 5 l" do
|
2135
|
+
common :l, 0x6d
|
2136
|
+
end
|
2137
|
+
|
2138
|
+
it "bit 5 hl" do
|
2139
|
+
common :hl, 0x6e
|
2140
|
+
end
|
2141
|
+
|
2142
|
+
it "bit 5 a" do
|
2143
|
+
common :a, 0x6f
|
2144
|
+
end
|
2145
|
+
end
|
2146
|
+
|
2147
|
+
context "6" do
|
2148
|
+
before(:all) { @exp = true }
|
2149
|
+
|
2150
|
+
it "bit 6 b" do
|
2151
|
+
common :b, 0x70
|
2152
|
+
end
|
2153
|
+
|
2154
|
+
it "bit 6 c" do
|
2155
|
+
common :c, 0x71
|
2156
|
+
end
|
2157
|
+
|
2158
|
+
it "bit 6 d" do
|
2159
|
+
common :d, 0x72
|
2160
|
+
end
|
2161
|
+
|
2162
|
+
it "bit 6 e" do
|
2163
|
+
common :e, 0x73
|
2164
|
+
end
|
2165
|
+
|
2166
|
+
it "bit 6 h" do
|
2167
|
+
common :h, 0x74
|
2168
|
+
end
|
2169
|
+
|
2170
|
+
it "bit 6 l" do
|
2171
|
+
common :l, 0x75
|
2172
|
+
end
|
2173
|
+
|
2174
|
+
it "bit 6 hl" do
|
2175
|
+
common :hl, 0x76
|
2176
|
+
end
|
2177
|
+
|
2178
|
+
it "bit 6 a" do
|
2179
|
+
common :a, 0x77
|
2180
|
+
end
|
2181
|
+
end
|
2182
|
+
|
2183
|
+
context "7" do
|
2184
|
+
before(:all) { @exp = false }
|
2185
|
+
|
2186
|
+
it "bit 7 b" do
|
2187
|
+
common :b, 0x78
|
2188
|
+
end
|
2189
|
+
|
2190
|
+
it "bit 7 c" do
|
2191
|
+
common :c, 0x79
|
2192
|
+
end
|
2193
|
+
|
2194
|
+
it "bit 7 d" do
|
2195
|
+
common :d, 0x7a
|
2196
|
+
end
|
2197
|
+
|
2198
|
+
it "bit 7 e" do
|
2199
|
+
common :e, 0x7b
|
2200
|
+
end
|
2201
|
+
|
2202
|
+
it "bit 7 h" do
|
2203
|
+
common :h, 0x7c
|
2204
|
+
end
|
2205
|
+
|
2206
|
+
it "bit 7 l" do
|
2207
|
+
common :l, 0x7d
|
2208
|
+
end
|
2209
|
+
|
2210
|
+
it "bit 7 hl" do
|
2211
|
+
common :hl, 0x7e
|
2212
|
+
end
|
2213
|
+
|
2214
|
+
it "bit 7 a" do
|
2215
|
+
common :a, 0x7f
|
2216
|
+
end
|
2217
|
+
end
|
2218
|
+
end
|
2219
|
+
|
2220
|
+
context "rl" do
|
2221
|
+
it "rl b" do
|
2222
|
+
@z.r.b.store 0b10101010
|
2223
|
+
run 0x10
|
2224
|
+
@z.r.b.read.should eq 0b01010100
|
2225
|
+
@z.r.carry_flag?.should be_true
|
2226
|
+
end
|
2227
|
+
|
2228
|
+
it "rl c" do
|
2229
|
+
@z.r.c.store 0b10000000
|
2230
|
+
run 0x11
|
2231
|
+
@z.r.c.read.should eq 0b00000000
|
2232
|
+
@z.r.carry_flag?.should be_true
|
2233
|
+
@z.r.zero_flag?.should be_true
|
2234
|
+
end
|
2235
|
+
|
2236
|
+
it "rl d" do
|
2237
|
+
@z.r.d.store 0b00000000
|
2238
|
+
@z.r.set_carry_flag
|
2239
|
+
run 0x12
|
2240
|
+
@z.r.d.read.should eq 0b00000001
|
2241
|
+
@z.r.carry_flag?.should be_false
|
2242
|
+
@z.r.zero_flag?.should be_false
|
2243
|
+
end
|
2244
|
+
|
2245
|
+
it "rl e" do
|
2246
|
+
@z.r.e.store 0b10011001
|
2247
|
+
@z.r.set_carry_flag
|
2248
|
+
run 0x13
|
2249
|
+
@z.r.e.read.should eq 0b00110011
|
2250
|
+
@z.r.carry_flag?.should be_true
|
2251
|
+
end
|
2252
|
+
|
2253
|
+
it "rl h" do
|
2254
|
+
@z.r.h.store 0b11111111
|
2255
|
+
run 0x14
|
2256
|
+
@z.r.h.read.should eq 0b11111110
|
2257
|
+
@z.r.carry_flag?.should be_true
|
2258
|
+
end
|
2259
|
+
|
2260
|
+
it "rl l" do
|
2261
|
+
@z.r.l.store 0b01111111
|
2262
|
+
@z.r.set_carry_flag
|
2263
|
+
run 0x15
|
2264
|
+
@z.r.l.read.should eq 0b11111111
|
2265
|
+
@z.r.carry_flag?.should be_false
|
2266
|
+
end
|
2267
|
+
|
2268
|
+
it "rl (hl)" do
|
2269
|
+
@z.mmu.write_byte 0x1d3b, 0b01010101
|
2270
|
+
@z.r.hl.store 0x1d3b
|
2271
|
+
run 0x16
|
2272
|
+
@z.mmu.read_byte(0x1d3b).should eq 0b10101010
|
2273
|
+
@z.r.hl.read.should eq 0x1d3b
|
2274
|
+
end
|
2275
|
+
|
2276
|
+
it "rl a" do
|
2277
|
+
@z.r.a.store 0b00100110
|
2278
|
+
run 0x17
|
2279
|
+
@z.r.a.read.should eq 0b01001100
|
2280
|
+
@z.r.carry_flag?.should be_false
|
2281
|
+
end
|
2282
|
+
end
|
2283
|
+
|
2284
|
+
context "rlc" do
|
2285
|
+
it "rlc b" do
|
2286
|
+
@z.r.b.store 0b10101010
|
2287
|
+
run 0x00
|
2288
|
+
@z.r.b.read.should eq 0b01010101
|
2289
|
+
@z.r.carry_flag?.should be_true
|
2290
|
+
end
|
2291
|
+
|
2292
|
+
it "rlc c" do
|
2293
|
+
@z.r.c.store 0b10000000
|
2294
|
+
run 0x01
|
2295
|
+
@z.r.c.read.should eq 0b00000001
|
2296
|
+
@z.r.carry_flag?.should be_true
|
2297
|
+
@z.r.zero_flag?.should be_false
|
2298
|
+
end
|
2299
|
+
|
2300
|
+
it "rlc d" do
|
2301
|
+
@z.r.d.store 0b00000000
|
2302
|
+
@z.r.set_carry_flag
|
2303
|
+
run 0x02
|
2304
|
+
@z.r.d.read.should eq 0b00000000
|
2305
|
+
@z.r.carry_flag?.should be_false
|
2306
|
+
@z.r.zero_flag?.should be_true
|
2307
|
+
end
|
2308
|
+
|
2309
|
+
it "rlc e" do
|
2310
|
+
@z.r.e.store 0b10011001
|
2311
|
+
@z.r.set_carry_flag
|
2312
|
+
run 0x03
|
2313
|
+
@z.r.e.read.should eq 0b00110011
|
2314
|
+
@z.r.carry_flag?.should be_true
|
2315
|
+
end
|
2316
|
+
|
2317
|
+
it "rlc h" do
|
2318
|
+
@z.r.h.store 0b11111111
|
2319
|
+
run 0x04
|
2320
|
+
@z.r.h.read.should eq 0b11111111
|
2321
|
+
@z.r.carry_flag?.should be_true
|
2322
|
+
end
|
2323
|
+
|
2324
|
+
it "rlc l" do
|
2325
|
+
@z.r.l.store 0b01111111
|
2326
|
+
@z.r.set_carry_flag
|
2327
|
+
run 0x05
|
2328
|
+
@z.r.l.read.should eq 0b11111110
|
2329
|
+
@z.r.carry_flag?.should be_false
|
2330
|
+
end
|
2331
|
+
|
2332
|
+
it "rlc (hl)" do
|
2333
|
+
@z.mmu.write_byte 0x1d3b, 0b01010101
|
2334
|
+
@z.r.hl.store 0x1d3b
|
2335
|
+
run 0x06
|
2336
|
+
@z.mmu.read_byte(0x1d3b).should eq 0b10101010
|
2337
|
+
@z.r.carry_flag?.should be_false
|
2338
|
+
@z.r.hl.read.should eq 0x1d3b
|
2339
|
+
end
|
2340
|
+
|
2341
|
+
it "rlc a" do
|
2342
|
+
@z.r.a.store 0b00100110
|
2343
|
+
run 0x07
|
2344
|
+
@z.r.a.read.should eq 0b01001100
|
2345
|
+
@z.r.carry_flag?.should be_false
|
2346
|
+
end
|
2347
|
+
end
|
2348
|
+
|
2349
|
+
context "rr" do
|
2350
|
+
it "rr b" do
|
2351
|
+
@z.r.b.store 0b10101010
|
2352
|
+
run 0x18
|
2353
|
+
@z.r.b.read.should eq 0b01010101
|
2354
|
+
@z.r.carry_flag?.should be_false
|
2355
|
+
end
|
2356
|
+
|
2357
|
+
it "rr c" do
|
2358
|
+
@z.r.c.store 0b10000001
|
2359
|
+
run 0x19
|
2360
|
+
@z.r.c.read.should eq 0b01000000
|
2361
|
+
@z.r.carry_flag?.should be_true
|
2362
|
+
@z.r.zero_flag?.should be_false
|
2363
|
+
end
|
2364
|
+
|
2365
|
+
it "rr d" do
|
2366
|
+
@z.r.d.store 0b00000000
|
2367
|
+
@z.r.set_carry_flag
|
2368
|
+
run 0x1a
|
2369
|
+
@z.r.d.read.should eq 0b10000000
|
2370
|
+
@z.r.carry_flag?.should be_false
|
2371
|
+
@z.r.zero_flag?.should be_false
|
2372
|
+
end
|
2373
|
+
|
2374
|
+
it "rr e" do
|
2375
|
+
@z.r.e.store 0b10011001
|
2376
|
+
@z.r.set_carry_flag
|
2377
|
+
run 0x1b
|
2378
|
+
@z.r.e.read.should eq 0b11001100
|
2379
|
+
@z.r.carry_flag?.should be_true
|
2380
|
+
end
|
2381
|
+
|
2382
|
+
it "rr h" do
|
2383
|
+
@z.r.h.store 0b11111111
|
2384
|
+
run 0x1c
|
2385
|
+
@z.r.h.read.should eq 0b01111111
|
2386
|
+
@z.r.carry_flag?.should be_true
|
2387
|
+
end
|
2388
|
+
|
2389
|
+
it "rr l" do
|
2390
|
+
@z.r.l.store 0b11111110
|
2391
|
+
@z.r.set_carry_flag
|
2392
|
+
run 0x1d
|
2393
|
+
@z.r.l.read.should eq 0b11111111
|
2394
|
+
@z.r.carry_flag?.should be_false
|
2395
|
+
end
|
2396
|
+
|
2397
|
+
it "rr (hl)" do
|
2398
|
+
@z.mmu.write_byte 0x1d3b, 0b01010101
|
2399
|
+
@z.r.hl.store 0x1d3b
|
2400
|
+
run 0x1e
|
2401
|
+
@z.mmu.read_byte(0x1d3b).should eq 0b00101010
|
2402
|
+
@z.r.hl.read.should eq 0x1d3b
|
2403
|
+
@z.r.carry_flag?.should be_true
|
2404
|
+
end
|
2405
|
+
|
2406
|
+
it "rr a" do
|
2407
|
+
@z.r.a.store 0b00100110
|
2408
|
+
run 0x1f
|
2409
|
+
@z.r.a.read.should eq 0b00010011
|
2410
|
+
@z.r.carry_flag?.should be_false
|
2411
|
+
end
|
2412
|
+
end
|
2413
|
+
|
2414
|
+
context "rrc" do
|
2415
|
+
it "rrc b" do
|
2416
|
+
@z.r.b.store 0b10101010
|
2417
|
+
run 0x08
|
2418
|
+
@z.r.b.read.should eq 0b01010101
|
2419
|
+
@z.r.carry_flag?.should be_false
|
2420
|
+
end
|
2421
|
+
|
2422
|
+
it "rrc c" do
|
2423
|
+
@z.r.c.store 0b00000001
|
2424
|
+
run 0x09
|
2425
|
+
@z.r.c.read.should eq 0b10000000
|
2426
|
+
@z.r.carry_flag?.should be_true
|
2427
|
+
@z.r.zero_flag?.should be_false
|
2428
|
+
end
|
2429
|
+
|
2430
|
+
it "rrc d" do
|
2431
|
+
@z.r.d.store 0b00000000
|
2432
|
+
@z.r.set_carry_flag
|
2433
|
+
run 0x0a
|
2434
|
+
@z.r.d.read.should eq 0b00000000
|
2435
|
+
@z.r.carry_flag?.should be_false
|
2436
|
+
@z.r.zero_flag?.should be_true
|
2437
|
+
end
|
2438
|
+
|
2439
|
+
it "rrc e" do
|
2440
|
+
@z.r.e.store 0b10011001
|
2441
|
+
@z.r.set_carry_flag
|
2442
|
+
run 0x0b
|
2443
|
+
@z.r.e.read.should eq 0b11001100
|
2444
|
+
@z.r.carry_flag?.should be_true
|
2445
|
+
end
|
2446
|
+
|
2447
|
+
it "rrc h" do
|
2448
|
+
@z.r.h.store 0b11111111
|
2449
|
+
run 0x0c
|
2450
|
+
@z.r.h.read.should eq 0b11111111
|
2451
|
+
@z.r.carry_flag?.should be_true
|
2452
|
+
end
|
2453
|
+
|
2454
|
+
it "rrc l" do
|
2455
|
+
@z.r.l.store 0b11111110
|
2456
|
+
@z.r.set_carry_flag
|
2457
|
+
run 0x0d
|
2458
|
+
@z.r.l.read.should eq 0b01111111
|
2459
|
+
@z.r.carry_flag?.should be_false
|
2460
|
+
end
|
2461
|
+
|
2462
|
+
it "rrc (hl)" do
|
2463
|
+
@z.mmu.write_byte 0x1d3b, 0b01010101
|
2464
|
+
@z.r.hl.store 0x1d3b
|
2465
|
+
run 0x0e
|
2466
|
+
@z.mmu.read_byte(0x1d3b).should eq 0b10101010
|
2467
|
+
@z.r.hl.read.should eq 0x1d3b
|
2468
|
+
end
|
2469
|
+
|
2470
|
+
it "rrc a" do
|
2471
|
+
@z.r.a.store 0b00100110
|
2472
|
+
run 0x0f
|
2473
|
+
@z.r.a.read.should eq 0b0010011
|
2474
|
+
@z.r.carry_flag?.should be_false
|
2475
|
+
end
|
2476
|
+
end
|
2477
|
+
|
2478
|
+
context "swap" do
|
2479
|
+
it "swap b" do
|
2480
|
+
@z.r.b.store 0b10101010
|
2481
|
+
run 0x30
|
2482
|
+
@z.r.b.read.should eq 0b10101010
|
2483
|
+
end
|
2484
|
+
|
2485
|
+
it "swap c" do
|
2486
|
+
@z.r.c.store 0b00000000
|
2487
|
+
run 0x31
|
2488
|
+
@z.r.c.read.should eq 0b00000000
|
2489
|
+
@z.r.zero_flag?.should be_true
|
2490
|
+
end
|
2491
|
+
|
2492
|
+
it "swap d" do
|
2493
|
+
@z.r.d.store 0b00010000
|
2494
|
+
run 0x32
|
2495
|
+
@z.r.d.read.should eq 0b00000001
|
2496
|
+
@z.r.zero_flag?.should be_false
|
2497
|
+
end
|
2498
|
+
|
2499
|
+
it "swap e" do
|
2500
|
+
@z.r.e.store 0b10011011
|
2501
|
+
run 0x33
|
2502
|
+
@z.r.e.read.should eq 0b10111001
|
2503
|
+
end
|
2504
|
+
|
2505
|
+
it "swap h" do
|
2506
|
+
@z.r.h.store 0b01011010
|
2507
|
+
run 0x34
|
2508
|
+
@z.r.h.read.should eq 0b10100101
|
2509
|
+
end
|
2510
|
+
|
2511
|
+
it "swap l" do
|
2512
|
+
@z.r.l.store 0b11111101
|
2513
|
+
run 0x35
|
2514
|
+
@z.r.l.read.should eq 0b11011111
|
2515
|
+
end
|
2516
|
+
|
2517
|
+
it "swap (hl)" do
|
2518
|
+
@z.mmu.write_byte 0x1d3b, 0b01010111
|
2519
|
+
@z.r.hl.store 0x1d3b
|
2520
|
+
run 0x36
|
2521
|
+
@z.mmu.read_byte(0x1d3b).should eq 0b01110101
|
2522
|
+
@z.r.hl.read.should eq 0x1d3b
|
2523
|
+
end
|
2524
|
+
|
2525
|
+
it "swap a" do
|
2526
|
+
@z.r.a.store 0b00100110
|
2527
|
+
run 0x37
|
2528
|
+
@z.r.a.read.should eq 0b01100010
|
2529
|
+
end
|
2530
|
+
end
|
2531
|
+
end
|
2532
|
+
end
|
2533
|
+
end
|
2534
|
+
end
|