Class: Amaterasu::Cartridge::Rom

Inherits:
Object
  • Object
show all
Defined in:
lib/amaterasu/cartridge/rom.rb

Overview

models the ROM inside the Game Boy cartridge.

Constant Summary collapse

CARTRIDGE_TYPES =
{
  0x00 => 'ROM ONLY',
  0x01 => 'MBC1',
  0x02 => 'MBC1+RAM',
  0x03 => 'MBC1+RAM+BATTERY',
  0x05 => 'MBC2'
}.freeze
ROM_SIZES =
{
  0x00 => 32 * 1024,
  0x01 => 64 * 1024,
  0x02 => 128 * 1024,
  0x03 => 256 * 1024,
  0x04 => 512 * 1024,
  0x05 => 1024 * 1024,
  0x06 => 2 * 1024 * 1024,
  0x07 => 4 * 1024 * 1024,
  0x08 => 8 * 1024 * 1024
}.freeze
RAM_SIZES =
{
  0x00 => 0,
  0x02 => 8 * 1024,
  0x03 => 32 * 1024,
  0x04 => 128 * 1024,
  0x05 => 64 * 1024
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Rom

Creates a ROM object given the bytes array and freezes it (read-only).



40
41
42
43
# File 'lib/amaterasu/cartridge/rom.rb', line 40

def initialize(data)
  @data = data
  @data.freeze
end

Class Method Details

.from_file(file_path) ⇒ Object



35
36
37
# File 'lib/amaterasu/cartridge/rom.rb', line 35

def self.from_file(file_path)
  new(File.binread(file_path).bytes)
end

Instance Method Details

#cartridge_typeObject

Returns a symbol for the cartridge type (:rom_only, :mbc1, …).



76
77
78
# File 'lib/amaterasu/cartridge/rom.rb', line 76

def cartridge_type
  CARTRIDGE_TYPES[@data[0x0147]]
end

#cgb_flagObject



63
64
65
# File 'lib/amaterasu/cartridge/rom.rb', line 63

def cgb_flag
  @data[0x0143]
end

#destination_codeObject



90
91
92
# File 'lib/amaterasu/cartridge/rom.rb', line 90

def destination_code
  @data[0x014A]
end

#headerObject



50
51
52
# File 'lib/amaterasu/cartridge/rom.rb', line 50

def header
  @data[0x0100..0x014F]
end

#header_checksumObject

Returns a 8-bit value for the header checksum.



103
104
105
# File 'lib/amaterasu/cartridge/rom.rb', line 103

def header_checksum
  @data[0x014D]
end

#manufacturer_codeObject



59
60
61
# File 'lib/amaterasu/cartridge/rom.rb', line 59

def manufacturer_code
  @data[0x013F..0x0142]
end

#mask_rom_versionObject



98
99
100
# File 'lib/amaterasu/cartridge/rom.rb', line 98

def mask_rom_version
  @data[0x014C]
end

#new_licensee_codeObject



67
68
69
# File 'lib/amaterasu/cartridge/rom.rb', line 67

def new_licensee_code
  @data[0x0144..0x0145]
end

#old_licensee_codeObject



94
95
96
# File 'lib/amaterasu/cartridge/rom.rb', line 94

def old_licensee_code
  @data[0x014B]
end

#ram_sizeObject

Returns an Integer indicating the RAM size.



86
87
88
# File 'lib/amaterasu/cartridge/rom.rb', line 86

def ram_size
  RAM_SIZES[@data[0x0149]]
end

#read_byte(offset) ⇒ Object

Returns a 8-bit value stored in the given address/offset.



46
47
48
# File 'lib/amaterasu/cartridge/rom.rb', line 46

def read_byte(offset)
  @data[offset]
end

#rom_sizeObject

Returns an Integer indicating the ROM size.



81
82
83
# File 'lib/amaterasu/cartridge/rom.rb', line 81

def rom_size
  ROM_SIZES[@data[0x0148]]
end

#sgb_flagObject



71
72
73
# File 'lib/amaterasu/cartridge/rom.rb', line 71

def sgb_flag
  @data[0x0146]
end

#titleObject

Returns a string containing the ROM title.



55
56
57
# File 'lib/amaterasu/cartridge/rom.rb', line 55

def title
  @data[0x0134..0x0143].pack('C*').strip
end

#valid_checksum?Boolean

Calculates the checksum and returns true if it matches.

Returns:

  • (Boolean)


108
109
110
111
112
113
114
115
# File 'lib/amaterasu/cartridge/rom.rb', line 108

def valid_checksum?
  checksum = 0
  (0x0134..0x014C).each do |address|
    checksum = checksum - @data[address] - 1
  end

  (checksum & 0xFF) == header_checksum
end