diff --git a/lib/waterfoul/boot_rom.rb b/lib/waterfoul/boot_rom.rb index d366222..e7ad49c 100644 --- a/lib/waterfoul/boot_rom.rb +++ b/lib/waterfoul/boot_rom.rb @@ -49,10 +49,19 @@ module Waterfoul 0x3E, 0x01, 0xE0, 0x50 ].freeze + attr_reader :cartridge + + def initialize(cartridge) + @cartridge = cartridge + end # Read bootstrap instruction given an index (memory location) - def self.[](i) - ROM[i] + def [](i) + ROM[i] || @cartridge[i] + end + + def []=(i, v) + @cartridge[i] = v end end end diff --git a/lib/waterfoul/cartridge.rb b/lib/waterfoul/cartridge.rb index 2066e3f..9ceac25 100644 --- a/lib/waterfoul/cartridge.rb +++ b/lib/waterfoul/cartridge.rb @@ -54,5 +54,9 @@ module Waterfoul MBC::MBC5 end end + + def self.empty + Array.new(0x8000, 0) + end end end diff --git a/lib/waterfoul/emulator.rb b/lib/waterfoul/emulator.rb index 7902742..ed22e9a 100644 --- a/lib/waterfoul/emulator.rb +++ b/lib/waterfoul/emulator.rb @@ -6,8 +6,8 @@ module Waterfoul # read the given file as binary and break it down into an array of bytes rom = File.binread(rom_filename).bytes # initialize emulated CPU, GPU & Scren components - $mmu = MMU.new @cartridge = Cartridge.new rom + $mmu = MMU.new(@cartridge) @cpu = CPU.new @cpu = SkipBoot.set_state(@cpu) if options.has_key?('skip_boot') @ppu = PPU.new @@ -15,7 +15,6 @@ module Waterfoul end def run - $mmu.cartridge = @cartridge loop do @cpu.step @ppu.step @cpu.m diff --git a/lib/waterfoul/mmu.rb b/lib/waterfoul/mmu.rb index 462d4dc..a513027 100644 --- a/lib/waterfoul/mmu.rb +++ b/lib/waterfoul/mmu.rb @@ -11,8 +11,6 @@ module Waterfoul MEMORY_SIZE = 65536 # bytes # unmap boot rom register address UNMAP_BOOT_ROM_MEM_LOC = 0xFF50 - # location in memory where the boot rom ends - BOOT_ROM_END_MEM_LOC = 0xFF # DMA register function address DMA_TRANSFER_MEM_LOC = 0xFF46 # DIV register memory location @@ -21,10 +19,9 @@ module Waterfoul attr_reader :memory attr_accessor :cartridge - def initialize - @cartridge = Array.new 0x8000, 0 + def initialize(cartridge = Cartridge.empty) # map the boot rom when the device starts - @map_boot_rom = true + @cartridge = BootROM.new(cartridge) # storage for usable memory (zero filled) @memory = Array.new MEMORY_SIZE, 0 end @@ -37,12 +34,7 @@ module Waterfoul when 0xFF00 Input.read_keyboard @memory[i] when 0x0000...0x8000 # ROM Bank 0 + n - # if the boot rom is enabled and the address is < 0x100 - if @map_boot_rom && i <= BOOT_ROM_END_MEM_LOC - BootROM[i] - else - @cartridge[i] - end + @cartridge[i] when 0x8000...0xA000 # Video RAM @memory[i] when 0xA000...0xC000 # RAM Bank @@ -65,7 +57,9 @@ module Waterfoul unless options[:hardware_operation] case i when UNMAP_BOOT_ROM_MEM_LOC # unmap the boot rom when 0xFF50 is wrtiten to in memory - @map_boot_rom = false if v == 0x1 && @map_boot_rom + if v == 0x1 && @cartridge.is_a?(BootROM) + @cartridge = @cartridge.cartridge + end when 0xFF00 @memory[i] = v | 0xF when 0xFF46 # DMA transfer