From 9c166aca9068902242bbbd781c95c49f00113122 Mon Sep 17 00:00:00 2001 From: Matthew Berry Date: Tue, 6 Oct 2020 21:13:07 -0700 Subject: [PATCH] thumb halfword data transfer immediate, pram read/write --- src/crab/arm/arm.cr | 1 + src/crab/arm/halfword_data_transfer_imm.cr | 49 ++++++++++++++++++++++ src/crab/bus.cr | 2 + src/crab/ppu.cr | 1 + 4 files changed, 53 insertions(+) create mode 100644 src/crab/arm/halfword_data_transfer_imm.cr diff --git a/src/crab/arm/arm.cr b/src/crab/arm/arm.cr index f0a6d3b..bb27456 100644 --- a/src/crab/arm/arm.cr +++ b/src/crab/arm/arm.cr @@ -38,6 +38,7 @@ module ARM lut[idx] = ->arm_single_data_transfer(Word) elsif idx & 0b111001001001 == 0b000001001001 # halfword data transfer immediate offset + lut[idx] = ->arm_halfword_data_transfer_immediate(Word) elsif idx & 0b111001001001 == 0b000000001001 # halfword data transfer register offset elsif idx & 0b111111111111 == 0b000100100001 diff --git a/src/crab/arm/halfword_data_transfer_imm.cr b/src/crab/arm/halfword_data_transfer_imm.cr new file mode 100644 index 0000000..bdebf91 --- /dev/null +++ b/src/crab/arm/halfword_data_transfer_imm.cr @@ -0,0 +1,49 @@ +module ARM + def arm_halfword_data_transfer_immediate(instr : Word) : Nil + pre_index = bit?(instr, 24) + add = bit?(instr, 23) + write_back = bit?(instr, 21) + load = bit?(instr, 20) + rn = bits(instr, 16..19) + rd = bits(instr, 12..15) + offset_high = bits(instr, 8..11) + sh = bits(instr, 5..6) + offset_low = bits(instr, 0..3) + + address = @r[rn] + offset = offset_high << 4 | offset_low + + if pre_index + if add + address &+= offset + else + address &-= offset + end + end + + case sh + when 0b00 # swp, no docs on this? + when 0b01 # ldrh/strh + if load + @r[rd] = @gba.bus.read_half address + else + @gba.bus[address] = @r[rd] + end + when 0b10 # ldrsb + @r[rd] = @gba.bus[address].to_i8!.to_u32 + when 0b11 # ldrsh + @r[rd] = @gba.bus.read_half(address).to_i16!.to_u32 + else raise "Invalid halfword data transfer imm op: #{sh}" + end + + if !pre_index + if add + @r[rn] &+= offset + else + @r[rn] &-= offset + end + elsif write_back + @r[rn] = address + end + end +end diff --git a/src/crab/bus.cr b/src/crab/bus.cr index 5c75e56..3edcfa4 100644 --- a/src/crab/bus.cr +++ b/src/crab/bus.cr @@ -17,6 +17,7 @@ class Bus else raise "Unmapped i/o read: #{hex_str index.to_u32}" end + when 0x5 then @gba.ppu.pram[index] when 0x6 address = 0x1FFFF_u32 & index address &= ~0x8000 if address > 0x17FFF @@ -51,6 +52,7 @@ class Bus else raise "Unmapped i/o write: #{hex_str index.to_u32}" end + when 0x5 then @gba.ppu.pram[index & 0x3FF] = value when 0x6 address = 0x1FFFF_u32 & index address &= ~0x8000 if address > 0x17FFF diff --git a/src/crab/ppu.cr b/src/crab/ppu.cr index 5c41e7d..aae63ad 100644 --- a/src/crab/ppu.cr +++ b/src/crab/ppu.cr @@ -25,6 +25,7 @@ class PPU num bg_mode, 3 # (0-5=Video Mode 0-5, 6-7=Prohibited) end + getter pram = Bytes.new 0x400 getter vram = Bytes.new 0x18000 @dispcnt : DISPCNT = DISPCNT.new 0