arm block data transfer

This commit is contained in:
Matthew Berry 2020-10-08 08:35:04 -07:00
parent e29bde0bcf
commit 705113eae2
2 changed files with 35 additions and 1 deletions

View file

@ -31,7 +31,7 @@ module ARM
elsif idx & 0b111000000000 == 0b101000000000
lut[idx] = ->arm_branch(Word)
elsif idx & 0b111000000000 == 0b100000000000
# block data transfer
lut[idx] = ->arm_block_data_transfer(Word)
elsif idx & 0b111000000001 == 0b011000000001
# undefined
elsif idx & 0b110000000000 == 0b010000000000

View file

@ -0,0 +1,34 @@
module ARM
def arm_block_data_transfer(instr : Word) : Nil
pre_index = bit?(instr, 24)
add = bit?(instr, 23)
s_bit = bit?(instr, 22) # todo respect this bit
write_back = bit?(instr, 21)
load = bit?(instr, 20)
rn = bits(instr, 16..19)
list = bits(instr, 0..15)
address = @r[rn]
if load
16.times do |idx|
if bit?(list, idx)
address &+= add ? 4 : -4 if pre_index
@r[idx] = @gba.bus.read_word(address)
address &+= add ? 4 : -4 unless pre_index
end
end
else
16.times do |idx|
if bit?(list, idx)
address &+= add ? 4 : -4 if pre_index
@gba.bus[address] = @r[idx]
address &+= add ? 4 : -4 unless pre_index
end
end
end
@r[rn] = address if write_back
# todo reset pipeline if r15 is written (this needs to be done in all other instrs that write to r15 as well)
end
end