fill pipeline if necessary (gba-suite nes.gba #1)

This commit is contained in:
Matthew Berry 2021-02-10 22:58:41 -08:00
parent eeff849ec0
commit c986673e68
3 changed files with 25 additions and 7 deletions

View file

@ -93,7 +93,7 @@ module ARM
step_arm unless rd == 15
else raise "Unimplemented execution of data processing opcode: #{hex_str opcode}"
end
@r[15] &-= 4 if pc_reads_12_ahead
@r[15] &-= 4 if pc_reads_12_ahead # todo: this is probably borked if there's a write to r15, but it needs some more thought..
if rd == 15 && set_conditions
@r[15] &-= 4 if @spsr.thumb # writing to r15 will have already cleared the pipeline and bumped r15 for arm mode
old_spsr = @spsr.value

View file

@ -108,6 +108,7 @@ class Bus
def []=(index : Int, value : Byte) : Nil
log "write #{hex_str index.to_u32} -> #{hex_str value}"
return if bits(index, 28..31) > 0
@gba.cpu.fill_pipeline if index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4 # detect writes near pc
case bits(index, 24..27)
when 0x0 then log "Writing to bios - #{hex_str index.to_u32}: #{hex_str value}"
when 0x2 then @wram_board[index & 0x3FFFF] = value

View file

@ -55,7 +55,8 @@ class CPU
@reg_banks[Mode::USR.bank][5] = @r[13] = 0x03007F00
@reg_banks[Mode::IRQ.bank][5] = 0x03007FA0
@reg_banks[Mode::SVC.bank][5] = 0x03007FE0
@r[15] = 0x08000008
@r[15] = 0x08000000
clear_pipeline
end
def switch_mode(new_mode : Mode, caller = __FILE__) : Nil
@ -91,6 +92,18 @@ class CPU
end
end
def fill_pipeline : Nil
if @cpsr.thumb
pc = @r[15] & ~1
@pipeline.push @gba.bus.read_half(@r[15] &- 2).to_u32!
@pipeline.push @gba.bus.read_half(@r[15]).to_u32!
else
pc = @r[15] & ~3
@pipeline.push @gba.bus.read_half(@r[15] &- 4).to_u32!
@pipeline.push @gba.bus.read_half(@r[15]).to_u32!
end
end
def clear_pipeline : Nil
@pipeline.clear
if @cpsr.thumb
@ -101,12 +114,16 @@ class CPU
end
def read_instr : Word
if @cpsr.thumb
@r[15] &= ~1
@gba.bus.read_half(@r[15] &- 4).to_u32!
if @pipeline.size == 0
if @cpsr.thumb
@r[15] &= ~1
@gba.bus.read_half(@r[15] &- 4).to_u32!
else
@r[15] &= ~3
@gba.bus.read_word(@r[15] &- 8)
end
else
@r[15] &= ~3
@gba.bus.read_word(@r[15] &- 8)
@pipeline.shift
end
end