Class: Amaterasu::GameBoy::Cpu::Instructions::Call

Inherits:
Base
  • Object
show all
Defined in:
lib/amaterasu/game_boy/cpu/instructions/call.rb,
sig/akane/game_boy/cpu/instructions/call.rbs

Overview

Holds the logic of all the CALL instructions.

Instance Attribute Summary

Attributes inherited from Base

#mnemonic

Instance Method Summary collapse

Methods inherited from Base

#execute, #format_operand

Constructor Details

#initialize(cpu:, condition: nil) ⇒ Call

Creates a Call instruction object with a mnemonic and logic to be executed.

Parameters:

  • cpu: (Cpu)
  • condition: (Symbol) (defaults to: nil)


10
11
12
13
14
15
# File 'lib/amaterasu/game_boy/cpu/instructions/call.rb', line 10

def initialize(cpu:, condition: nil)
  super(cpu:)

  @mnemonic = "CALL #{format_operand(condition)}, imm16"
  @logic    = build_logic(condition)
end

Instance Method Details

#build_logic(condition) ⇒ Proc

Returns a Proc object to be executed by the CPU at runtime.

Parameters:

  • (Symbol ?condition)

Returns:

  • (Proc)


20
21
22
23
24
25
26
27
28
# File 'lib/amaterasu/game_boy/cpu/instructions/call.rb', line 20

def build_logic(condition)
  case condition
  when :nz then -> { call(@registers.z_flag.zero?) }
  when :z  then -> { call(@registers.z_flag == 1) }
  when :nc then -> { call(@registers.c_flag.zero?) }
  when :c  then -> { call(@registers.c_flag == 1) }
  else -> { call(true) }
  end
end

#call(condition) ⇒ void

This method returns an undefined value.

M-cycle 1: Fetches opcode. M-cycle 2: Fetches next immediate byte (lsb). M-cycle 3: Fetches next immediate byte (msb). ---------- Return early if condition not met. M-cycle 4: Pushes the msb of the PC onto the stack. M-cycle 5: Pushes the lsb of the PC onto the stack. M-cycle 6: Jumps to the call address.

Parameters:

  • condition (Boolean)


37
38
39
40
41
42
43
# File 'lib/amaterasu/game_boy/cpu/instructions/call.rb', line 37

def call(condition)
  call_address = @cpu.fetch_next_word
  return unless condition

  @cpu.stack_push(value: @registers.pc)
  @cpu.jump_to(address: call_address)
end