From d808070d24d4c59afbfa09f04d24f2e75c77253c Mon Sep 17 00:00:00 2001 From: Matthew Berry Date: Mon, 5 Oct 2020 00:14:19 -0700 Subject: [PATCH] custom/minimal pipeline implementation in favor of Deque also removed constants from Bus class, which seems to have improved performance for some reason as well --- src/crab/bus.cr | 19 ++----------------- src/crab/cpu.cr | 7 ++++--- src/crab/pipeline.cr | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 src/crab/pipeline.cr diff --git a/src/crab/bus.cr b/src/crab/bus.cr index 7a736c6..5c75e56 100644 --- a/src/crab/bus.cr +++ b/src/crab/bus.cr @@ -1,21 +1,6 @@ class Bus - BIOS = 0x00000000..0x00003FFF - WRAM_BOARD = 0x02000000..0x0203FFFF - WRAM_CHIP = 0x03000000..0x03007FFF - PPU_IO = 0x04000000..0x0400005F - SOUND_IO = 0x04000060..0x040000AF - DMA_IO = 0x040000B0..0x040000FF - TIMER_IO = 0x04000100..0x0400011F - SERIAL_IO_1 = 0x04000120..0x0400012F - KEYPAD_IO = 0x04000130..0x04000133 - SERIAL_IO_2 = 0x04000134..0x040001FF - INTERRUPT_IO = 0x04000200..0x0400FFFF - PPU = 0x05000000..0x07FFFFFF - CARTRIDGE = 0x08000000..0x0FFFFFFF - UNUSED = 0x10000000..0xFFFFFFFF - - @wram_board = Bytes.new Bus::WRAM_BOARD.size - @wram_chip = Bytes.new Bus::WRAM_CHIP.size + @wram_board = Bytes.new 0x40000 + @wram_chip = Bytes.new 0x08000 def initialize(@gba : GBA) end diff --git a/src/crab/cpu.cr b/src/crab/cpu.cr index 4595221..9046780 100644 --- a/src/crab/cpu.cr +++ b/src/crab/cpu.cr @@ -1,5 +1,6 @@ require "./arm/*" require "./thumb/*" +require "./pipeline" class CPU include ARM @@ -19,7 +20,7 @@ class CPU @r = Slice(Word).new 16 @cpsr : PSR - @pipeline = Deque(Word).new 2 + @pipeline = Pipeline.new getter lut : Slice(Proc(Word, Nil)) { fill_lut } getter thumb_lut : Slice(Proc(Word, Nil)) { fill_thumb_lut } @@ -35,11 +36,11 @@ class CPU 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 << @gba.bus.read_half @r[15] + @pipeline.push @gba.bus.read_half @r[15] @r[15] &+= 2 else log "Fetch pc: #{hex_str @r[15]}, instr: #{hex_str @gba.bus.read_word @r[15]}" - @pipeline << @gba.bus.read_word @r[15] + @pipeline.push @gba.bus.read_word @r[15] @r[15] &+= 4 end end diff --git a/src/crab/pipeline.cr b/src/crab/pipeline.cr new file mode 100644 index 0000000..41cb04e --- /dev/null +++ b/src/crab/pipeline.cr @@ -0,0 +1,29 @@ +# A super minimalistic FIFO queue implementation optimized for +# use as an ARM instruction pipeline. +class Pipeline + @buffer = Slice(Word).new 2 + @pos = 0 + @size = 0 + + def push(instr : Word) : Nil + raise "Pushing to full pipeline" if @size == 2 + index = (@pos + @size) & 1 + @buffer[index] = instr + @size += 1 + end + + def shift : Word + @size -= 1 + val = @buffer[@pos] + @pos = (@pos + 1) & 1 + val + end + + def clear : Nil + @size = 0 + end + + def size : Int32 + @size + end +end