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