Class: GBRb::BaseCartridge

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

Direct Known Subclasses

MBC1

Constant Summary collapse

HEADER_START =
0x0100
HEADER_END =
0x014f
TITLE_OFFSET =
0x34
TITLE_LENGTH =
0xf
TYPE_OFFSET =
0x47
DESTINATION_OFFSET =
0x4a
RAM_BANK_SIZE =
0x2000

Instance Method Summary collapse

Constructor Details

#initialize(raw_data) ⇒ BaseCartridge

Returns a new instance of BaseCartridge.



14
15
16
17
18
19
20
# File 'lib/gbrb/cartridge/cartridge.rb', line 14

def initialize raw_data
  @rom_banks = raw_data.read.each_byte.each_slice(MEMORY_BANK_SIZE).to_a
  @header = rom_bank(0)[HEADER_START..HEADER_END]
  @current_rom_bank = rom_bank 1
  @rom_bank_number = 1
  post_initialize
end

Instance Method Details

#destinationObject



129
130
131
132
133
134
135
136
137
138
# File 'lib/gbrb/cartridge/cartridge.rb', line 129

def destination
  case header_field DESTINATION_OFFSET
  when 0x00
    "Japanese"
  when 0x01
    "Non-Japanese"
  else
    "Unknown"
  end
end

#header_field(offset, length = 1) ⇒ Object



140
141
142
143
144
145
146
# File 'lib/gbrb/cartridge/cartridge.rb', line 140

def header_field offset, length=1
  if length == 1
    @header[offset]
  else
    @header.slice offset, length
  end
end

#infoObject



51
52
53
54
55
56
# File 'lib/gbrb/cartridge/cartridge.rb', line 51

def info
  "Title:        #{title}\n"        <<
  "Type:         #{type}\n"         <<
  "Destination:  #{destination}\n"  <<
  ""
end

#post_initializeObject



22
# File 'lib/gbrb/cartridge/cartridge.rb', line 22

def post_initialize; end

#ram_bank(number = 0) ⇒ Object



28
29
30
# File 'lib/gbrb/cartridge/cartridge.rb', line 28

def ram_bank number=0
  @ram_banks.fetch(number) { Array.new 0x1fff, 0 }
end

#read_byte(addr) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/gbrb/cartridge/cartridge.rb', line 32

def read_byte addr
  case addr
  when 0x0000..0x3fff
    @rom_banks[0][addr & (MEMORY_BANK_SIZE - 1)]
  when 0x4000..0x7fff
    rom_bank(@rom_bank_number)[addr & (MEMORY_BANK_SIZE - 1)]
  when 0xa000..0xbfff
    if @current_ram_bank
      @current_ram_bank[addr & (RAM_BANK_SIZE - 1)]
    else
      0
    end
  end
end

#rom_bank(number = 0) ⇒ Object



24
25
26
# File 'lib/gbrb/cartridge/cartridge.rb', line 24

def rom_bank number=0
  @rom_banks.fetch(number) { Array.new MEMORY_BANK_SIZE, 0 }
end

#titleObject



58
59
60
61
62
# File 'lib/gbrb/cartridge/cartridge.rb', line 58

def title
  header_field(TITLE_OFFSET, TITLE_LENGTH).select{|el| (0x20..0x7e).cover? el}
                                          .map(&:chr)
                                          .join
end

#typeObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/gbrb/cartridge/cartridge.rb', line 64

def type
  case header_field TYPE_OFFSET
  when 0x00
    "ROM ONLY"
  when 0x01
    "MBC1"
  when 0x02
    "MBC1+RAM"
  when 0x03
    "MBC1+RAM+BATTERY"
  when 0x05
    "MBC2"
  when 0x06
    "MBC2+BATTERY"
  when 0x08
    "ROM+RAM"
  when 0x09
    "ROM+RAM+BATTERY"
  when 0x0b
    "MMM01"
  when 0x0c
    "MMM01+RAM"
  when 0x0d
    "MMM01+RAM+BATTERY"
  when 0x0f
    "MBC3+TIMER+BATTERY"
  when 0x10
    "MBC3+TIMER+RAM+BATTERY"
  when 0x11
    "MBC3"
  when 0x12
    "MBC3+RAM"
  when 0x13
    "MBC3+RAM+BATTERY"
  when 0x15
    "MBC4"
  when 0x16
    "MBC4+RAM"
  when 0x17
    "MBC4+RAM+BATTERY"
  when 0x19
    "MBC5"
  when 0x1a
    "MBC5+RAM"
  when 0x1b
    "MBC5+RAM+BATTERY"
  when 0x1c
    "MBC5+RUMBLE"
  when 0x1d
    "MBC5+RUMBLE+RAM"
  when 0x1e
    "MBC5+RUMBLE+RAM+BATTERY"
  when 0xfc
    "POCKET CAMERA"
  when 0xfd
    "BANDAI TAMA5"
  when 0xfe
    "HuC3"
  when 0xff
    "HuC1+RAM+BATTERY"
  else
    "INVALID"
  end
end

#write_byte(addr, value) ⇒ Object



47
48
49
# File 'lib/gbrb/cartridge/cartridge.rb', line 47

def write_byte addr, value
  @current_ram_bank[addr & (ram_bank_size - 1)] = value if (0xa000..0xbfff).cover? addr
end