fixed breaking specs for jump instructions

This commit is contained in:
Colby Swandale 2016-09-25 22:46:12 +10:00
parent c37d0d9b02
commit e175b5bdf8

View file

@ -1,21 +1,20 @@
require 'spec_helper' require 'spec_helper'
describe Waterfoul::CPU do describe Waterfoul::CPU do
before { $mmu = Waterfoul::MMU.new }
subject { Waterfoul::CPU.new } subject { Waterfoul::CPU.new }
before :each do before { subject.set_register :pc, 0x100 }
$mmu = double :mmu before { subject.set_register :sp, 0x200 }
end
describe '#jr_nz_r8' do describe '#jr_nz_r8' do
let(:jump_to) { 0x54 } before { $mmu.write_byte 0x100, 0x54 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) }
context 'when Z flag is set' do context 'when Z flag is set' do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'increments the pc' do it 'increments the pc' do
subject.jr_nz_r8 subject.jr_nz_r8
expect(subject.pc).to eq 0x1 expect(subject.pc).to eq 0x101
end end
end end
@ -23,20 +22,19 @@ describe Waterfoul::CPU do
before { subject.reset_z_flag } before { subject.reset_z_flag }
it 'adds immediate value from memory and 1 to pc' do it 'adds immediate value from memory and 1 to pc' do
subject.jr_nz_r8 subject.jr_nz_r8
expect(subject.pc).to eq (1 + jump_to) expect(subject.pc).to eq 0x155
end end
end end
end end
describe '#jr_nc_r8' do describe '#jr_nc_r8' do
let(:jump_to) { 0x55 } before { $mmu.write_byte 0x100, 0x72 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) }
context 'when C flag is set' do context 'when C flag is set' do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'increments the pc' do it 'increments the pc' do
subject.jr_nc_r8 subject.jr_nc_r8
expect(subject.pc).to eq 1 expect(subject.pc).to eq 0x101
end end
end end
@ -44,30 +42,28 @@ describe Waterfoul::CPU do
before { subject.reset_c_flag } before { subject.reset_c_flag }
it 'adds immediate value from memory and 1 to pc' do it 'adds immediate value from memory and 1 to pc' do
subject.jr_nc_r8 subject.jr_nc_r8
expect(subject.pc).to eq (1 + jump_to) expect(subject.pc).to eq 0x173
end end
end end
end end
describe '#jr_r8' do describe '#jr_r8' do
let(:jump_to) { 0x56 } before { $mmu.write_byte 0x100, 0x56 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) }
it 'increments pc by 1 and the value fetched from memory' do it 'increments pc by 1 and the value fetched from memory' do
subject.jr_r8 subject.jr_r8
expect(subject.pc).to eq (1 + jump_to) expect(subject.pc).to eq 0x157
end end
end end
describe '#jr_z_r8' do describe '#jr_z_r8' do
let(:jump_to) { 0x57 } before { $mmu.write_byte 0x100, 0x59 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) }
context 'when Z flag is set' do context 'when Z flag is set' do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'adds immediate value from memory and 1 to pc' do it 'adds immediate value from memory and 1 to pc' do
subject.jr_z_r8 subject.jr_z_r8
expect(subject.pc).to eq (1 + jump_to) expect(subject.pc).to eq 0x15A
end end
end end
@ -75,20 +71,19 @@ describe Waterfoul::CPU do
before { subject.reset_z_flag } before { subject.reset_z_flag }
it 'increments the pc' do it 'increments the pc' do
subject.jr_z_r8 subject.jr_z_r8
expect(subject.pc).to eq 1 expect(subject.pc).to eq 0x101
end end
end end
end end
describe '#jr_c_r8' do describe '#jr_c_r8' do
let(:jump_to) { 0x58 } before { $mmu.write_byte 0x100, 0x43 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) }
context 'when C flag is set' do context 'when C flag is set' do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'adds immediate value from memory and 1 to pc' do it 'adds immediate value from memory and 1 to pc' do
subject.jr_c_r8 subject.jr_c_r8
expect(subject.pc).to eq (1 + jump_to) expect(subject.pc).to eq 0x144
end end
end end
@ -96,25 +91,25 @@ describe Waterfoul::CPU do
before { subject.reset_c_flag } before { subject.reset_c_flag }
it 'increments pc by 1' do it 'increments pc by 1' do
subject.jr_c_r8 subject.jr_c_r8
expect(subject.pc).to eq 1 expect(subject.pc).to eq 0x101
end end
end end
end end
describe '#ret_nz' do describe '#ret_nz' do
let(:jump_to) { 0x59 } before { $mmu.write_byte 0x200, 0x30 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) } before { $mmu.write_byte 0x201, 0x40 }
context 'when Z flag reset' do context 'when Z flag reset' do
before { subject.reset_z_flag } before { subject.reset_z_flag }
it 'sets pc to immediate value from memory' do it 'sets pc to the immediate value from memory' do
subject.ret_nz subject.ret_nz
expect(subject.pc).to eq 0x5959 expect(subject.pc).to eq 0x4030
end end
it 'increments the stack pointer by 2' do it 'decrements the stack pointer by 2 addreses' do
subject.ret_nz subject.ret_nz
expect(subject.sp).to eq 2 expect(subject.sp).to eq 0x202
end end
end end
@ -122,25 +117,25 @@ describe Waterfoul::CPU do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'does not increment the pc' do it 'does not increment the pc' do
subject.ret_nz subject.ret_nz
expect(subject.pc).to eq 0 expect(subject.pc).to eq 0x100
end end
end end
end end
describe '#ret_nc' do describe '#ret_nc' do
let(:jump_to) { 0x60 } before { $mmu.write_byte 0x200, 0x40 }
before { allow($mmu).to receive(:read_byte).and_return(jump_to) } before { $mmu.write_byte 0x201, 0x30 }
context 'when C flag is reset' do context 'when C flag is reset' do
before { subject.reset_c_flag } before { subject.reset_c_flag }
it 'sets pc to immediate value from memory' do it 'sets pc to immediate value from memory' do
subject.ret_nz subject.ret_nz
expect(subject.pc).to eq 0x6060 expect(subject.pc).to eq 0x3040
end end
it 'increments the stack pointer by 2' do it 'decrements the stack pointer by 2 addresses' do
subject.ret_nz subject.ret_nz
expect(subject.sp).to eq 2 expect(subject.sp).to eq 0x202
end end
end end
@ -148,20 +143,19 @@ describe Waterfoul::CPU do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'does not increment the pc' do it 'does not increment the pc' do
subject.ret_nc subject.ret_nc
expect(subject.pc).to eq 0 expect(subject.pc).to eq 0x100
end end
end end
end end
describe '#jp_nz_a16' do describe '#jp_nz_a16' do
let(:jump_to) { 0x61 } before { $mmu.write_byte 0x100, 0x30 }
before { allow($mmu).to receive(:read_word).and_return(jump_to) }
context 'when Z flag is reset' do context 'when Z flag is reset' do
before { subject.reset_z_flag } before { subject.reset_z_flag }
it 'sets pc to immediate value from memory' do it 'sets pc to immediate value from memory' do
subject.jp_nz_a16 subject.jp_nz_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x30
end end
end end
@ -169,20 +163,19 @@ describe Waterfoul::CPU do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'increments the pc by 2' do it 'increments the pc by 2' do
subject.jp_nz_a16 subject.jp_nz_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
end end
describe '#jp_nc_a16' do describe '#jp_nc_a16' do
let(:jump_to) { 0x62 } before { $mmu.write_byte 0x100, 0x40 }
before { allow($mmu).to receive(:read_word).and_return(jump_to) }
context 'when C flag is reset' do context 'when C flag is reset' do
before { subject.reset_c_flag } before { subject.reset_c_flag }
it 'sets pc to immediate value from memory' do it 'sets pc to immediate value from memory' do
subject.jp_nc_a16 subject.jp_nc_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x40
end end
end end
@ -190,20 +183,16 @@ describe Waterfoul::CPU do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'increments the pc by 2' do it 'increments the pc by 2' do
subject.jp_nc_a16 subject.jp_nc_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
end end
%w(rst_00h rst_10h rst_20h rst_30h rst_08h rst_18h rst_28h rst_38h).each do |m| %w(rst_00h rst_10h rst_20h rst_30h rst_08h rst_18h rst_28h rst_38h).each do |m|
describe "##{m}" do describe "##{m}" do
let(:sp_pointer) { 0xFFDF } it 'increments the sp by 2 addresses' do
before { subject.set_stack_pointer sp_pointer }
before { allow($mmu).to receive(:write_byte) }
it 'deincrements the sp by -2' do
subject.public_send m subject.public_send m
expect(subject.sp).to eq (sp_pointer - 2) expect(subject.sp).to eq 0x1FE
end end
hex = /rst\_(\d+)h/.match(m) hex = /rst\_(\d+)h/.match(m)
@ -215,177 +204,158 @@ describe Waterfoul::CPU do
end end
describe '#jp_a16' do describe '#jp_a16' do
let(:jump_to) { 0x63 } before { $mmu.write_byte 0x100, 0x70 }
before { allow($mmu).to receive(:read_word).and_return(jump_to) }
it 'jumps to immediate value from memory' do it 'jumps to immediate value from memory' do
subject.jp_a16 subject.jp_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x70
end end
end end
describe '#call_nz_a16' do describe '#call_nz_a16' do
before { allow($mmu).to receive(:write_byte) } before { $mmu.write_byte 0x100, 0x80 }
before { allow($mmu).to receive(:read_word).and_return jump_to }
let(:jump_to) { 0x64 }
let(:stack_pointer) { 0xFFDF }
context 'when Z flag is set' do context 'when Z flag is set' do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'increments the pc' do it 'increments the pc by 2' do
subject.call_nz_a16 subject.call_nz_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
context 'when Z flag is reset' do context 'when Z flag is reset' do
before { subject.reset_z_flag } before { subject.reset_z_flag }
before { subject.set_register :sp, stack_pointer }
before { subject.set_register :pc, jump_to }
xit 'pushes the value of PC into the stack' do
subject.call_nz_a16
end
it 'sets PC to immediate value from memory' do it 'sets PC to immediate value from memory' do
subject.call_nz_a16 subject.call_nz_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x80
end end
it 'decrements the sp' do it 'increments the stack pointer by 2 addresses' do
subject.call_nz_a16 subject.call_nz_a16
expect(subject.sp).to eq (stack_pointer - 2) expect(subject.sp).to eq 0x1FE
end end
end end
end end
describe '#call_nc_a16' do describe '#call_nc_a16' do
before { allow($mmu).to receive(:write_byte) } before { $mmu.write_byte 0x100, 0x104 }
before { allow($mmu).to receive(:read_word).and_return jump_to }
let(:jump_to) { 0x64 }
let(:stack_pointer) { 0xFFDF }
context 'when C flag is set' do context 'when C flag is set' do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'increments the pc' do it 'increments the pc' do
subject.call_nc_a16 subject.call_nc_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
context 'when C flag is reset' do context 'when C flag is reset' do
before { subject.reset_c_flag } before { subject.reset_c_flag }
before { subject.set_register :sp, stack_pointer }
before { subject.set_register :pc, jump_to }
xit 'pushes the value of PC into the stack' do
subject.call_nc_a16
end
it 'sets PC to immediate value from memory' do it 'sets PC to immediate value from memory' do
subject.call_nc_a16 subject.call_nc_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x104
end end
it 'decrements the sp' do it 'decrements the sp' do
subject.call_nc_a16 subject.call_nc_a16
expect(subject.sp).to eq (stack_pointer - 2) expect(subject.sp).to eq 0x1FE
end end
end end
end end
describe '#ret_z' do describe '#ret_z' do
let(:jump_to) { 0x65 } before { $mmu.write_byte 0x200, 0x7A }
before { allow($mmu).to receive(:read_byte).and_return jump_to } before { $mmu.write_byte 0x201, 0xE }
context 'when Z flag set' do context 'when Z flag set' do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'jumps to instruction at immediate value from memory' do it 'jumps to value from the stack' do
subject.ret_z subject.ret_z
expect(subject.pc).to eq 0x6565 expect(subject.pc).to eq 0xE7A
end end
it 'increments stack pointer' do it 'decrements stack pointer by 2 addresses' do
subject.ret_z subject.ret_z
expect(subject.sp).to eq 2 expect(subject.sp).to eq 0x202
end end
end end
end end
describe '#ret_c' do describe '#ret_c' do
let(:jump_to) { 0x66 } before { $mmu.write_byte 0x200, 0xFF }
before { allow($mmu).to receive(:read_byte).and_return jump_to } before { $mmu.write_byte 0x201, 0x12 }
context 'when C flag set' do context 'when C flag set' do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'jumps to value from memory' do it 'jumps to value from the stack' do
subject.ret_c subject.ret_c
expect(subject.pc).to eq 0x6666 expect(subject.pc).to eq 0x12FF
end end
it 'increments stack pointer' do it 'decrements stack pointer by 2 addresses' do
subject.ret_c subject.ret_c
expect(subject.sp).to eq 2 expect(subject.sp).to eq 0x202
end end
end end
end end
describe '#ret' do describe '#ret' do
let(:jump_to) { 0x67 } before { $mmu.write_byte 0x200, 0xA }
before { allow($mmu).to receive(:read_byte).and_return jump_to } before { $mmu.write_byte 0x201, 0xF }
it 'increments the stack pointer' do it 'decrements the stack pointer by 2 addresses' do
subject.ret subject.ret
expect(subject.sp).to eq 2 expect(subject.sp).to eq 0x202
end end
it 'jumps to value from memory' do it 'jumps to value from from the sack' do
subject.ret subject.ret
expect(subject.pc).to eq 0x6767 expect(subject.pc).to eq 0xF0A
end end
end end
describe '#reti' do describe '#reti' do
let(:jump_to) { 0x68 } before { $mmu.write_byte 0x200, 0x1A }
before { allow($mmu).to receive(:read_byte).and_return jump_to } before { $mmu.write_byte 0x201, 0xF }
it 'sets the ime flag' do it 'sets the ime flag' do
subject.reti subject.reti
expect(subject.ime).to eq 1 expect(subject.ime).to eq true
end end
it 'increments the stack pointer' do it 'decrements the stack pointer by 2 addresses' do
subject.reti subject.reti
expect(subject.sp).to eq 2 expect(subject.sp).to eq 0x202
end end
it 'jumps to value from memory' do it 'jumps to value from the stack' do
subject.reti subject.reti
expect(subject.pc).to eq 0x6868 expect(subject.pc).to eq 0xF1A
end end
end end
describe '#jp_dhl' do describe '#jp_dhl' do
let(:jump_to) { 0x69 } before { subject.set_register :hl, 0x1FA5 }
before { subject.set_register :hl, jump_to }
it 'jumps to value from hl register' do it 'jumps to value from hl register' do
subject.jp_dhl subject.jp_dhl
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x1FA5
end end
end end
describe '#jp_z_a16' do describe '#jp_z_a16' do
let(:jump_to) { 0x70 } before { $mmu.write_byte 0x100, 0x56 }
before { $mmu.write_byte 0x101, 0x64 }
context 'when Z flag is set' do context 'when Z flag is set' do
before { subject.set_z_flag } before { subject.set_z_flag }
before { expect($mmu).to receive(:read_word).and_return jump_to }
it 'jumps to instruction from immediate value in memory' do it 'jumps to instruction from immediate value in memory' do
subject.jp_z_a16 subject.jp_z_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x6456
end end
end end
@ -393,20 +363,20 @@ describe Waterfoul::CPU do
before { subject.reset_z_flag } before { subject.reset_z_flag }
it 'increments pc' do it 'increments pc' do
subject.jp_z_a16 subject.jp_z_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
end end
describe '#jp_c_a16' do describe '#jp_c_a16' do
let(:jump_to) { 0x71 } before { $mmu.write_byte 0x100, 0x51 }
before { allow($mmu).to receive(:read_word).and_return jump_to } before { $mmu.write_byte 0x101, 0x65 }
context 'when C flag is set' do context 'when C flag is set' do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'jumps to instruction at immediate value from memory' do it 'jumps to instruction at immediate value from memory' do
subject.jp_c_a16 subject.jp_c_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x6551
end end
end end
@ -414,54 +384,50 @@ describe Waterfoul::CPU do
before { subject.reset_c_flag } before { subject.reset_c_flag }
it 'increments pc' do it 'increments pc' do
subject.jp_c_a16 subject.jp_c_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
end end
describe '#call_z_a16' do describe '#call_z_a16' do
let(:jump_to) { 0x72 } before { $mmu.write_byte 0x100, 0x54 }
before { subject.set_register :sp, 2 } before { $mmu.write_byte 0x101, 0xFF }
before { allow($mmu).to receive(:read_word).and_return jump_to }
before { allow($mmu).to receive(:write_byte) }
context 'when Z flag is set' do context 'when Z flag is set' do
before { subject.set_z_flag } before { subject.set_z_flag }
it 'jumps to instruction at immediate value from memory' do it 'jumps to instruction at immediate value from memory' do
subject.call_z_a16 subject.call_z_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0xFF54
end end
it 'decrements the stack pointer' do it 'increments the stack pointer by 2 addresses' do
subject.call_z_a16 subject.call_z_a16
expect(subject.sp).to eq 0 expect(subject.sp).to eq 0x1FE
end end
end end
context 'when Z flag is reset' do context 'when Z flag is reset' do
it 'increments pc' do it 'increments pc' do
subject.call_z_a16 subject.call_z_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
end end
describe '#call_c_a16' do describe '#call_c_a16' do
let(:jump_to) { 0x73 } before { $mmu.write_byte 0x100, 0x65 }
before { subject.set_register :sp, 2 } before { $mmu.write_byte 0x101, 0x1C }
before { allow($mmu).to receive(:read_word).and_return jump_to }
before { allow($mmu).to receive(:write_byte) }
context 'when C flag is set' do context 'when C flag is set' do
before { subject.set_c_flag } before { subject.set_c_flag }
it 'jumps to instruction at immediate value from memory' do it 'jumps to instruction at immediate value from memory' do
subject.call_c_a16 subject.call_c_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0x1C65
end end
it 'decrements the stack pointer' do it 'increments the stack pointer by 2 addresses' do
subject.call_c_a16 subject.call_c_a16
expect(subject.sp).to eq 0 expect(subject.sp).to eq 0x1FE
end end
end end
@ -469,25 +435,23 @@ describe Waterfoul::CPU do
before { subject.reset_c_flag } before { subject.reset_c_flag }
it 'increments the program counter' do it 'increments the program counter' do
subject.call_c_a16 subject.call_c_a16
expect(subject.pc).to eq 2 expect(subject.pc).to eq 0x102
end end
end end
end end
describe '#call_a16' do describe '#call_a16' do
let(:jump_to) { 0x74 } before { $mmu.write_byte 0x100, 0x10 }
before { subject.set_register :sp, 2 } before { $mmu.write_byte 0x101, 0xC2 }
before { allow($mmu).to receive(:read_word).and_return jump_to }
before { allow($mmu).to receive(:write_byte) }
it 'jumps to instruction at immediate value from memory' do it 'jumps to instruction at immediate value from memory' do
subject.call_a16 subject.call_a16
expect(subject.pc).to eq jump_to expect(subject.pc).to eq 0xC210
end end
it 'decrements the stack pointer' do it 'inccrements the stack pointer by 2 addresses' do
subject.call_a16 subject.call_a16
expect(subject.sp).to eq 0 expect(subject.sp).to eq 0x1FE
end end
end end
end end