diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp
index 8196b53..7049c78 100644
--- a/cpu/cpu.cpp
+++ b/cpu/cpu.cpp
@@ -261,6 +261,18 @@ void Cpu::add16(u16& out, u16 lhs, u16 rhs)
   out = (u16)res32;
 }
 
+void Cpu::add16_8(u16& out, u16 lhs, s8 rhs)
+{
+  s16 rhs16 = rhs;
+  u16 res4 = (lhs & 0x0F) + (rhs & 0x0F);
+  state.halfcarry = (res4 & 0x10);
+  u16 res8 = (lhs & 0xFF) + (rhs & 0xFF);
+  state.carry = (res8 & 0x100);
+  state.subtract = false;
+  u32 res32 = lhs + rhs;
+  out = (u16)res32;
+}
+
 bool Cpu::handleInterrupts()
 {
   // Once there's an interrupt we exit halt mode
diff --git a/cpu/cpu.h b/cpu/cpu.h
index 9ef67ec..02e9f06 100644
--- a/cpu/cpu.h
+++ b/cpu/cpu.h
@@ -149,6 +149,7 @@ private:
 
   void aluop8(AluOp op, u8 lhs, u8 rhs, u8& out, bool update_carry = true);
   void add16(u16& out, u16 lhs, u16 rhs);
+  void add16_8(u16& out, u16 lhs, s8 rhs);
 
   inline
   void aluop8(AluOp op, u8 rhs, bool update_carry = true)
diff --git a/cpu/decoder.cpp b/cpu/decoder.cpp
index a208c5b..4830dc4 100644
--- a/cpu/decoder.cpp
+++ b/cpu/decoder.cpp
@@ -427,12 +427,12 @@ void Cpu::executeInstruction()
           state.stopped = true;
           break;
         case 0xE8: // ADD SP, e8
-          add16(state.SP, state.SP, (s32)((s8)readPC8()));
+          add16_8(state.SP, state.SP, readPC8());
           state.zero = false;
           mcycles = 4;
           break;
         case 0xF8: // LD HL, SP + e8
-          add16(state.HL, state.SP, (s32)((s8)readPC8()));
+          add16_8(state.SP, state.SP, readPC8());
           state.zero = false;
           mcycles = 3;
           break;