diff --git a/src/crab/cpu.cr b/src/crab/cpu.cr index 7ae1260..e6317b8 100644 --- a/src/crab/cpu.cr +++ b/src/crab/cpu.cr @@ -138,6 +138,19 @@ class CPU res end + # Add two values with carry + def adc(operand_1 : Word, operand_2 : Word, set_conditions) : Word + log "adc - operand_1:#{hex_str operand_1}, operand_2:#{hex_str operand_2}" + res = operand_1 &+ operand_2 &+ @cpsr.carry.to_unsafe + if set_conditions + @cpsr.overflow = bit?(~(operand_1 ^ operand_2) & (operand_2 ^ res), 31) + @cpsr.carry = res < operand_1 + @cpsr.zero = res == 0 + @cpsr.negative = bit?(res, 31) + end + res + end + def print_state(instr : Word) : Nil {% if flag? :trace %} @r.each do |reg| diff --git a/src/crab/thumb/alu_operations.cr b/src/crab/thumb/alu_operations.cr index 72dea36..63c377f 100644 --- a/src/crab/thumb/alu_operations.cr +++ b/src/crab/thumb/alu_operations.cr @@ -10,7 +10,7 @@ module THUMB when 0b0010 then res = @r[rd] = lsl(@r[rd], @r[rs], true) when 0b0011 then res = @r[rd] = lsr(@r[rd], @r[rs], true) when 0b0100 then res = @r[rd] = asr(@r[rd], @r[rs], true) - when 0b0101 then res = @r[rd] = @r[rd] &+ @r[rs] &+ @cpsr.carry.to_unsafe + when 0b0101 then res = @r[rd] = adc(@r[rd], @r[rs], true) when 0b0110 then res = @r[rd] = @r[rd] &- @r[rs] &- ~@cpsr.carry.to_unsafe when 0b0111 then res = @r[rd] = ror(@r[rd], @r[rs], true) when 0b1000 then res = @r[rd] & @r[rs]