mirror of
https://github.com/mattrberry/crab.git
synced 2024-11-16 19:49:30 +01:00
direct reads of words / halfwords, improves fps ~25%
This commit is contained in:
parent
79ed746d6c
commit
190ce42ea6
4 changed files with 57 additions and 19 deletions
|
@ -22,19 +22,40 @@ class Bus
|
|||
when 0x7 then @gba.ppu.oam[index & 0x3FF]
|
||||
when 0x8, 0x9,
|
||||
0xA, 0xB,
|
||||
0xC, 0xD then @gba.cartridge[index & 0x01FFFFFF]
|
||||
0xC, 0xD then @gba.cartridge.rom[index & 0x01FFFFFF]
|
||||
when 0xE then @gba.storage[index & 0xFFFF]
|
||||
else abort "Unmapped read: #{hex_str index.to_u32}"
|
||||
end
|
||||
end
|
||||
|
||||
def read_half(index : Int) : Word
|
||||
self[index & ~1].to_u32 |
|
||||
(self[(index & ~1) + 1].to_u32 << 8)
|
||||
def read_half_slow(index : Int) : HalfWord
|
||||
self[index].to_u16 |
|
||||
(self[index + 1].to_u16 << 8)
|
||||
end
|
||||
|
||||
def read_half(index : Int) : HalfWord
|
||||
index &= ~1
|
||||
case bits(index, 24..27)
|
||||
when 0x0 then (@bios.to_unsafe + (index & 0x3FFF)).as(HalfWord*).value
|
||||
when 0x2 then (@wram_board.to_unsafe + (index & 0x3FFFF)).as(HalfWord*).value
|
||||
when 0x3 then (@wram_chip.to_unsafe + (index & 0x7FFF)).as(HalfWord*).value
|
||||
when 0x4 then read_half_slow(index)
|
||||
when 0x5 then (@gba.ppu.pram.to_unsafe + (index & 0x3FF)).as(HalfWord*).value
|
||||
when 0x6
|
||||
address = 0x1FFFF_u32 & index
|
||||
address -= 0x8000 if address > 0x17FFF
|
||||
(@gba.ppu.vram.to_unsafe + address).as(HalfWord*).value
|
||||
when 0x7 then (@gba.ppu.oam.to_unsafe + (index & 0x3FF)).as(HalfWord*).value
|
||||
when 0x8, 0x9,
|
||||
0xA, 0xB,
|
||||
0xC, 0xD then (@gba.cartridge.rom.to_unsafe + (index & 0x01FFFFFF)).as(HalfWord*).value
|
||||
when 0xE then read_half_slow(index)
|
||||
else abort "Unmapped read: #{hex_str index.to_u32}"
|
||||
end
|
||||
end
|
||||
|
||||
def read_half_rotate(index : Int) : Word
|
||||
half = read_half index
|
||||
half = read_half(index).to_u32!
|
||||
bits = (index & 1) << 3
|
||||
half >> bits | half << (32 - bits)
|
||||
end
|
||||
|
@ -50,11 +71,32 @@ class Bus
|
|||
end
|
||||
end
|
||||
|
||||
private def read_word_slow(index : Int) : Word
|
||||
self[index].to_u32 |
|
||||
(self[index + 1].to_u32 << 8) |
|
||||
(self[index + 2].to_u32 << 16) |
|
||||
(self[index + 3].to_u32 << 24)
|
||||
end
|
||||
|
||||
def read_word(index : Int) : Word
|
||||
self[index & ~3].to_u32 |
|
||||
(self[(index & ~3) + 1].to_u32 << 8) |
|
||||
(self[(index & ~3) + 2].to_u32 << 16) |
|
||||
(self[(index & ~3) + 3].to_u32 << 24)
|
||||
index &= ~3
|
||||
case bits(index, 24..27)
|
||||
when 0x0 then (@bios.to_unsafe + (index & 0x3FFF)).as(Word*).value
|
||||
when 0x2 then (@wram_board.to_unsafe + (index & 0x3FFFF)).as(Word*).value
|
||||
when 0x3 then (@wram_chip.to_unsafe + (index & 0x7FFF)).as(Word*).value
|
||||
when 0x4 then read_word_slow(index)
|
||||
when 0x5 then (@gba.ppu.pram.to_unsafe + (index & 0x3FF)).as(Word*).value
|
||||
when 0x6
|
||||
address = 0x1FFFF_u32 & index
|
||||
address -= 0x8000 if address > 0x17FFF
|
||||
(@gba.ppu.vram.to_unsafe + address).as(Word*).value
|
||||
when 0x7 then (@gba.ppu.oam.to_unsafe + (index & 0x3FF)).as(Word*).value
|
||||
when 0x8, 0x9,
|
||||
0xA, 0xB,
|
||||
0xC, 0xD then (@gba.cartridge.rom.to_unsafe + (index & 0x01FFFFFF)).as(Word*).value
|
||||
when 0xE then read_word_slow(index)
|
||||
else abort "Unmapped read: #{hex_str index.to_u32}"
|
||||
end
|
||||
end
|
||||
|
||||
def read_word_rotate(index : Int) : Word
|
||||
|
|
|
@ -15,8 +15,4 @@ class Cartridge
|
|||
def initialize(rom_path : String)
|
||||
File.open(rom_path) { |file| file.read @rom }
|
||||
end
|
||||
|
||||
def [](index : Int) : Byte
|
||||
@rom[index]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,12 +104,12 @@ class CPU
|
|||
end
|
||||
while @pipeline.size < 2
|
||||
if @cpsr.thumb
|
||||
log "Fetch pc: #{hex_str @r[15]}, instr: #{hex_str @gba.bus.read_half(@r[15]).to_u16}"
|
||||
@pipeline.push @gba.bus.read_half @r[15]
|
||||
log "Fetch pc: #{hex_str @r[15]}, instr: #{hex_str @gba.bus.read_half(@r[15])}"
|
||||
@pipeline.push(@gba.bus.read_half(@r[15]).to_u32!)
|
||||
@r[15] &+= 2
|
||||
else
|
||||
log "Fetch pc: #{hex_str @r[15]}, instr: #{hex_str @gba.bus.read_word @r[15]}"
|
||||
@pipeline.push @gba.bus.read_word @r[15]
|
||||
@pipeline.push(@gba.bus.read_word(@r[15]))
|
||||
@r[15] &+= 4
|
||||
end
|
||||
end
|
||||
|
@ -156,9 +156,9 @@ class CPU
|
|||
end
|
||||
|
||||
@[AlwaysInline]
|
||||
def set_reg(reg : Int, value : UInt32) : UInt32
|
||||
def set_reg(reg : Int, value : Int) : UInt32
|
||||
clear_pipeline if reg == 15
|
||||
@r[reg] = value
|
||||
@r[reg] = value.to_u32!
|
||||
end
|
||||
|
||||
@[AlwaysInline]
|
||||
|
|
|
@ -127,7 +127,7 @@ class DMA
|
|||
delta_dest = word_size * dest_control.delta
|
||||
|
||||
len.times do |idx|
|
||||
@gba.bus[@dst[channel]] = word_size == 4 ? @gba.bus.read_word(@src[channel]) : @gba.bus.read_half(@src[channel]).to_u16!
|
||||
@gba.bus[@dst[channel]] = word_size == 4 ? @gba.bus.read_word(@src[channel]) : @gba.bus.read_half(@src[channel])
|
||||
@src[channel] += delta_source
|
||||
@dst[channel] += delta_dest
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue