diff --git a/src/crab/thumb/conditional_branch.cr b/src/crab/thumb/conditional_branch.cr index 685e449..b6c9ce6 100644 --- a/src/crab/thumb/conditional_branch.cr +++ b/src/crab/thumb/conditional_branch.cr @@ -1,7 +1,7 @@ module THUMB def thumb_conditional_branch(instr : Word) : Nil cond = bits(instr, 8..11) - offset = bits(instr, 0..8).to_i8! + offset = bits(instr, 0..7).to_i8! if cond @r[15] &+= (offset * 2) clear_pipeline diff --git a/src/crab/thumb/move_compare_add_subtract.cr b/src/crab/thumb/move_compare_add_subtract.cr new file mode 100644 index 0000000..3bbfa9c --- /dev/null +++ b/src/crab/thumb/move_compare_add_subtract.cr @@ -0,0 +1,17 @@ +module THUMB + def thumb_move_compare_add_subtract(instr : Word) : Nil + op = bits(instr, 11..12) + rd = bits(instr, 8..10) + offset = bits(instr, 0..7) + # todo handle carry flag on all ops + case op + when 0b00 then res = @r[rd] = offset + when 0b01 then res = @r[rd] &- offset + when 0b10 then res = @r[rd] &+= offset + when 0b11 then res = @r[rd] &-= offset + else raise "Invalid move/compare/add/subtract op: #{op}" + end + @cpsr.zero = res == 0 + @cpsr.negative = bit?(res, 31) + end +end diff --git a/src/crab/thumb/thumb.cr b/src/crab/thumb/thumb.cr index b7d588c..cceb1d2 100644 --- a/src/crab/thumb/thumb.cr +++ b/src/crab/thumb/thumb.cr @@ -39,7 +39,7 @@ module THUMB elsif idx & 0b11111100 == 0b01000000 # alu operations elsif idx & 0b11100000 == 0b00100000 - # move/compare/add/subtract immediate + lut[idx] = ->thumb_move_compare_add_subtract(Word) elsif idx & 0b11111100 == 0b00011000 # add/subtract elsif idx & 0b11100000 == 0b00000000