Class: Amaterasu::GameBoy::Cpu::Instructions::Rotate

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

Overview

Holds the logic of all the Rotate instructions.

  • RLCA: Rotate Left Circular A.
  • RRCA: Rotate Right Circular A.
  • RLA: Rotate Left Through Carry A.
  • RRA: Rotate Right Through Carry A.

Instance Attribute Summary

Attributes inherited from Base

#mnemonic

Instance Method Summary collapse

Methods included from Utils::BitOps

bit, clear_bit, #self?.bit, #self?.clear_bit, #self?.set_bit, set_bit

Methods inherited from Base

#execute, #format_operand

Constructor Details

#initialize(cpu:, operation:) ⇒ Rotate

Returns a new instance of Rotate.

Parameters:

  • cpu: (Cpu)
  • operation: (Symbol)


16
17
18
19
20
21
# File 'lib/amaterasu/game_boy/cpu/instructions/rotate.rb', line 16

def initialize(cpu:, operation:)
  super(cpu:)

  @mnemonic = format_operand(operation).to_s
  @logic    = build_logic(operation)
end

Instance Method Details

#build_logic(operation) ⇒ Proc

Returns a lambda object containing the instruction logic.

Parameters:

  • operation (Symbol)

Returns:

  • (Proc)


26
27
28
29
30
31
32
33
34
35
# File 'lib/amaterasu/game_boy/cpu/instructions/rotate.rb', line 26

def build_logic(operation)
  case operation
  when :rlca then -> { rlca }
  when :rrca then -> { rrca }
  when :rla  then -> { rla }
  when :rra  then -> { rra }
  else
    raise ArgumentError, 'Unknown Rotate operation'
  end
end

#rlavoid

This method returns an undefined value.

Rotate Left Through Carry.

  • Rotate all bits from the A register to the left.
  • Bit 7 falls off the left side and becomes the Carry flag.
  • The value of Carry flag becomes the new Bit 0.

Before: [C] <- [7][6][5][4][3][2][1][0] After : [7] [6][5][4][3][2][1][0][C] <-

M-cycle 1: Fetches the opcode and performs the rotate.



87
88
89
90
91
92
93
94
95
# File 'lib/amaterasu/game_boy/cpu/instructions/rotate.rb', line 87

def rla
  carry_in = @registers.c_flag
  old_bit7 = bit(@registers.a, 7)

  @registers.clear_flags
  @registers.c_flag = old_bit7 == 1

  @registers.a = (@registers.a << 1) | carry_in
end

#rlcavoid

This method returns an undefined value.

Rotate Left Circular. Rotate all bits from the A register to the left. Bit 7 falls off the left and at the same time:

  • Either sets or clears the Carry flag depending on it's value.
  • Wraps around the A register and becomes Bit 0.

Before: [C] <- [7][6][5][4][3][2][1][0] After : [C=7] [6][5][4][3][2][1][0][7] <-

M-cycle 1: Fetches the opcode and performs the rotate.



48
49
50
51
52
53
54
55
# File 'lib/amaterasu/game_boy/cpu/instructions/rotate.rb', line 48

def rlca
  old_bit7 = bit(@registers.a, 7)

  @registers.clear_flags
  @registers.c_flag = old_bit7 == 1

  @registers.a = (@registers.a << 1) | old_bit7
end

#rravoid

This method returns an undefined value.

Rotate Right Through Carry.

  • Rotate all bits from the A register to the right.
  • Bit 0 falls off the right side and becomes the Carry flag.
  • The previous value of Carry flag becomes the new Bit 0.

Before: [7][6][5][4][3][2][1][0] -> [C] After : -> [C][7][6][5][4][3][2][1]

M-cycle 1: Fetches the opcode and performs the rotate.



107
108
109
110
111
112
113
114
115
# File 'lib/amaterasu/game_boy/cpu/instructions/rotate.rb', line 107

def rra
  carry_in = @registers.c_flag
  old_bit0 = bit(@registers.a, 0)

  @registers.clear_flags
  @registers.c_flag = old_bit0 == 1

  @registers.a = (carry_in << 7) | (@registers.a >> 1)
end

#rrcavoid

This method returns an undefined value.

Rotate Right Circular. Rotate all bits from the A register to the right. Bit 0 falls off the right side and at the same time:

  • Either sets or clears the Carry flag depending on it's value.
  • Wraps around the A register and becomes Bit 7.

Before: [7][6][5][4][3][2][1][0] -> [C] After : -> [0][7][6][5][4][3][2][1] [C=0]

M-cycle 1: Fetches the opcode and performs the rotate.



68
69
70
71
72
73
74
75
# File 'lib/amaterasu/game_boy/cpu/instructions/rotate.rb', line 68

def rrca
  old_bit0 = bit(@registers.a, 0)

  @registers.clear_flags
  @registers.c_flag = old_bit0 == 1

  @registers.a = (old_bit0 << 7) | (@registers.a >> 1)
end