From 493d8b74f6363b3e634f2f0130cc5238ca958af0 Mon Sep 17 00:00:00 2001 From: Matthew Berry Date: Sun, 4 Oct 2020 16:10:34 -0700 Subject: [PATCH] remove constant ranges from bus, redesign mem map lookups Turns out constants in Crystal are slow as _hell_. Thanks Ary for the help discovering that. Maybe one day Crystal will improve that, but for now this change over triples performance. --- src/crab/bus.cr | 49 +++++++++++++++++++++++++++++++++---------------- src/crab/ppu.cr | 8 +------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/crab/bus.cr b/src/crab/bus.cr index 9ba4944..7a736c6 100644 --- a/src/crab/bus.cr +++ b/src/crab/bus.cr @@ -22,14 +22,22 @@ class Bus def [](index : Int) : Byte log "read #{hex_str index.to_u32}" - case index - when WRAM_BOARD then @wram_board[index - WRAM_BOARD.begin] - when WRAM_CHIP then @wram_chip[index - WRAM_CHIP.begin] - when PPU_IO then @gba.ppu[index] - when PPU then @gba.ppu[index] - when CARTRIDGE then @gba.cartridge[index - CARTRIDGE.begin] - when UNUSED then 0xFF_u8 - else 0xFF_u8 + case bits(index, 24..27) + when 0x2 then @wram_board[index & 0x3FFFF] + when 0x3 then @wram_chip[index & 0x7FFF] + when 0x4 + io_addr = 0x0FFF_u16 & index + if io_addr <= 0x05F + @gba.ppu[index] + else + raise "Unmapped i/o read: #{hex_str index.to_u32}" + end + when 0x6 + address = 0x1FFFF_u32 & index + address &= ~0x8000 if address > 0x17FFF + @gba.ppu.vram[address] + when 0x8, 0x9 then @gba.cartridge[index & 0x7FFFFFF] + else raise "Unmapped read: #{hex_str index.to_u32}" end end @@ -47,14 +55,23 @@ class Bus def []=(index : Int, value : Byte) : Nil log "write #{hex_str index.to_u32} -> #{hex_str value}" - case index - when WRAM_BOARD then @wram_board[index - WRAM_BOARD.begin] = value - when WRAM_CHIP then @wram_chip[index - WRAM_CHIP.begin] = value - when PPU_IO then @gba.ppu[index] = value - when PPU then @gba.ppu[index] = value - when CARTRIDGE then @gba.cartridge[index - CARTRIDGE.begin] = value # todo is this meant to be writable? - when UNUSED then nil - else raise "Unimplemented write ~ addr:#{hex_str index.to_u32}, val:#{value}" + return if bits(index, 28..31) > 0 + case bits(index, 24..27) + when 0x2 then @wram_board[index & 0x3FFFF] = value + when 0x3 then @wram_chip[index & 0x7FFF] = value + when 0x4 + io_addr = 0x0FFF_u16 & index + if io_addr <= 0x05F + @gba.ppu[index] = value + else + raise "Unmapped i/o write: #{hex_str index.to_u32}" + end + when 0x6 + address = 0x1FFFF_u32 & index + address &= ~0x8000 if address > 0x17FFF + @gba.ppu.vram[address] = value + when 0x8, 0x9 then @gba.cartridge[index & 0x7FFFFFF] = value + else raise "Unmapped write: #{hex_str index.to_u32}" end end diff --git a/src/crab/ppu.cr b/src/crab/ppu.cr index 69b7c2f..5c41e7d 100644 --- a/src/crab/ppu.cr +++ b/src/crab/ppu.cr @@ -1,8 +1,4 @@ class PPU - BG_OBJ_PALETTE = 0x05000000..0x050003FF - VRAM = 0x06000000..0x06017FFF - OAM = 0x07000000..0x070003FF - # Display timings in cycles HDRAW = 960 HBLANK = 272 @@ -29,7 +25,7 @@ class PPU num bg_mode, 3 # (0-5=Video Mode 0-5, 6-7=Prohibited) end - @vram = Bytes.new VRAM.size + getter vram = Bytes.new 0x18000 @dispcnt : DISPCNT = DISPCNT.new 0 @@ -52,7 +48,6 @@ class PPU when 0x04000001 then @dispcnt.value.to_u8! when 0x04000002 then 0_u8 when 0x04000003 then 0_u8 - when VRAM then @vram[index = VRAM.begin] else raise "Unimplemented PPU read ~ addr:#{hex_str index.to_u32}" end end @@ -63,7 +58,6 @@ class PPU when 0x04000001 then @dispcnt.value = (@dispcnt.value & 0xFF00) | value when 0x04000002 when 0x04000003 - when VRAM then @vram[index - VRAM.begin] = value else raise "Unimplemented PPU write ~ addr:#{hex_str index.to_u32}, val:#{value}" end end