Class: Amaterasu::GameBoy::Serial

Inherits:
Object
  • Object
show all
Defined in:
lib/amaterasu/game_boy/serial.rb,
sig/akane/game_boy/serial.rbs

Overview

Models the Serial Port present in the Game Boy.

  • Very useful for performing community accuracy tests, they use the serial to output results.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(interrupts, trace_serial: false) ⇒ Serial

Creates a serial port instance.

  • Needs to hold an instance of interrupts to request a :serial interrupt.
  • Holds the state of the Transfer Data and Control registers.


19
20
21
22
23
24
25
26
27
# File 'lib/amaterasu/game_boy/serial.rb', line 19

def initialize(interrupts, trace_serial: false)
  @interrupts = interrupts
  @trace_serial = trace_serial

  @sb = 0x00
  @sc = 0xFF

  @message_buffer = Array.new
end

Instance Attribute Details

#message_bufferArray[Integer] (readonly)

Returns an Array with all the bytes from the serial transfer.



13
14
15
# File 'lib/amaterasu/game_boy/serial.rb', line 13

def message_buffer
  @message_buffer
end

#sbInteger

Returns the 8-bit value stored in the SB (Serial Transfer Data) register.



10
11
12
# File 'lib/amaterasu/game_boy/serial.rb', line 10

def sb
  @sb
end

Instance Method Details

#clock_bitInteger

Bit 0 from the SC register determines which clock controls the transfer.

  • If Bit 0 is set, the internal clock from the receiving Game Boy controls the transfer.
  • If Bit 0 is cleared, the Game Boy waits for an external clock pulse.


63
64
65
# File 'lib/amaterasu/game_boy/serial.rb', line 63

def clock_bit
  @sc & 1
end

#complete_transfervoid

This method returns an undefined value.

Completes the transfer immediately after.

  • Transfer enable flag (Bit 7) is cleared.
  • Requests a :serial interrupt.


84
85
86
87
88
# File 'lib/amaterasu/game_boy/serial.rb', line 84

def complete_transfer
  @sc &= 0b01111111
  puts @message_buffer.pack('C*') if @trace_serial
  @interrupts.request(:serial)
end

#scInteger

Returns the 8-bit value stored in the SC (Serial Transfer Control) register.

  • In the actual hardware only Bit 7 and Bit 0 are wired.
  • Bits 6-1 always return 1 when read.


33
34
35
# File 'lib/amaterasu/game_boy/serial.rb', line 33

def sc
  @sc | 0b01111110
end

#sc=(value) ⇒ void

This method returns an undefined value.

Sets a 8-bit value into the SC register.

  • Bits 6-1 are ignored since they are not wired to anything.
  • If bit 7 goes from 0 -> 1, a transfer is started.


46
47
48
49
50
# File 'lib/amaterasu/game_boy/serial.rb', line 46

def sc=(value)
  @sc = value & 0b10000001

  start_transfer if transfer_enabled?
end

#start_transfervoid

This method returns an undefined value.

Transfers the byte from the SB register.

  • For the transfer to actually begin bits 7 and 0 need to be set.
  • Internal clock must be selected, otherwise it just waits.


71
72
73
74
75
76
77
78
# File 'lib/amaterasu/game_boy/serial.rb', line 71

def start_transfer
  return if clock_bit.zero?

  @message_buffer << @sb
  @sb = 0xFF

  complete_transfer
end

#transfer_enabled?Boolean

Bit 7 from the SC register determines if the transfer is enabled.



55
56
57
# File 'lib/amaterasu/game_boy/serial.rb', line 55

def transfer_enabled?
  (@sc >> 7).allbits?(1)
end