Class: GBRb::MMU

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

Constant Summary collapse

SIZE =
0x10000
WORKING_RAM_ADDRESS =
0xc000
WORKING_RAM_LENGTH =
0x2000
WORKING_RAM_SHADOW_ADDRESS =
0xe000
WORKING_RAM_SHADOW_LENGTH =
0x1e00
ROM_BANK_0_ADDRESS =
0x0000
ROM_BANK_1_ADDRESS =
0x4000
BIOS_STATUS_ADDRESS =
0xff50

Instance Method Summary collapse

Constructor Details

#initialize(bios = []) ⇒ MMU

Returns a new instance of MMU.



14
15
16
17
18
# File 'lib/gbrb/mmu.rb', line 14

def initialize bios=[]
  @storage     = Array.new SIZE, 0
  @peripherals = Array.new SIZE, nil
  load_bios bios
end

Instance Method Details

#connect(peripheral, *locations) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/gbrb/mmu.rb', line 57

def connect peripheral, *locations
  locations.map! do |location|
    if location.class == Range
      STDOUT.puts "Connecting #{peripheral.class.to_s.split('::').last} at [#{location.first.to_s 16}, #{location.last.to_s 16}]..."
      location.to_a
    else
      STDOUT.puts "Connecting #{peripheral.class.to_s.split('::').last} at #{Array(location).map{|l| l.to_s 16}.join ", "}..."
      Array(location).map &:to_i
    end
  end

  locations.flatten.each do |l|
    @peripherals[l.to_i] = peripheral
  end
end

#dump(start = 0, stop = SIZE) ⇒ Object



73
74
75
76
77
# File 'lib/gbrb/mmu.rb', line 73

def dump start=0, stop=SIZE
  debug_indicies(start, stop).zip(debug_hex(start, stop), debug_ascii(start, stop))
                .map{|row| row.join("  ")}
                .join("\n")
end

#irq(i) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/gbrb/mmu.rb', line 86

def irq i
  old_value = read_byte INTERRUPT_FLAG_ADDR
  case i
  when TIMER_OVERFLOW_IRQ
    write_byte INTERRUPT_FLAG_ADDR, old_value | TIMER_OVERFLOW_IRQ
  end
end

#read_byte(addr) ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/gbrb/mmu.rb', line 20

def read_byte addr
  raise unless (0..SIZE).cover? addr
  return @bios[addr] if addr < @bios.length and @in_bios

  if (p = @peripherals[addr])
    p.read_byte addr
  else
    @storage[addr]
  end
end

#read_word(addr) ⇒ Object



31
32
33
# File 'lib/gbrb/mmu.rb', line 31

def read_word addr
  (read_byte(addr+1) << 8) + read_byte(addr)
end

#resetObject



79
80
# File 'lib/gbrb/mmu.rb', line 79

def reset
end

#unload_biosObject



82
83
84
# File 'lib/gbrb/mmu.rb', line 82

def unload_bios
  @in_bios = false
end

#write_byte(addr, value) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/gbrb/mmu.rb', line 35

def write_byte addr, value
  if BIOS_STATUS_ADDRESS == addr
    value == 0x00 ? load_bios(@bios) : unload_bios
    return
  end

  if (p = @peripherals[addr])
    p.write_byte addr, value
  else
    @storage[addr] = value & 0xff
    if (WORKING_RAM_ADDRESS..WORKING_RAM_ADDRESS + WORKING_RAM_SHADOW_LENGTH).cover? addr
      copy_address = addr + WORKING_RAM_SHADOW_ADDRESS - WORKING_RAM_ADDRESS
      @storage[copy_address] = value & 0xff
    end
  end
end

#write_word(addr, value) ⇒ Object



52
53
54
55
# File 'lib/gbrb/mmu.rb', line 52

def write_word addr, value
  write_byte addr, value
  write_byte addr+1, value >> 8
end