diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp
index 12a9136..8021826 100644
--- a/cpu/cpu.cpp
+++ b/cpu/cpu.cpp
@@ -84,20 +84,35 @@ void Cpu::reset()
   state.IF = 0;
 
   state.halted = false;
+  state.haltbug = false;
   state.stopped = false;
 }
 
 u8 Cpu::readPC8()
 {
   u8 data = bus->read8(state.PC);
-  state.PC++;
+  if(!state.haltbug)
+    state.PC++;
+  else
+    state.haltbug = false;
   return data;
 }
 
 u16 Cpu::readPC16()
 {
-  u16 data = bus->read16(state.PC);
-  state.PC+=2;
+  u16 data;
+  if(state.haltbug)
+    {
+      data = bus->read8(state.PC);
+      data |= data << 8; // Same byte twice
+      state.PC++;
+      state.haltbug = false;
+    }
+  else
+    {
+      data = bus->read16(state.PC);
+      state.PC+=2;
+    }
   return data;
 }
 
@@ -230,11 +245,8 @@ void Cpu::aluop8(AluOp op, u8 lhs, u8 rhs, u8& out, bool update_carry)
 
 bool Cpu::handleInterrupts()
 {
-  // servicable interrupts (assuming IME is on)
-  u8 si = state.IE & state.IF & INT_MASK;
-
   // Once there's an interrupt we exit halt mode
-  if (si)
+  if (state.SI())
     state.halted = false;
 
   if (state.IME == IME_SCHEDULED)
diff --git a/cpu/cpu.h b/cpu/cpu.h
index 15f0b52..a44017d 100644
--- a/cpu/cpu.h
+++ b/cpu/cpu.h
@@ -116,7 +116,12 @@ struct Cpu_state {
   u8 IE;
   u8 IF;
 
+  // servicable interrupts
+  inline u8 SI() const
+  { return INT_MASK & IE & IF; }
+
   bool halted;
+  bool haltbug;
   bool stopped;
 
   void setAF(u16 v);
diff --git a/cpu/decoder.cpp b/cpu/decoder.cpp
index cbc9b6b..6c21e1d 100644
--- a/cpu/decoder.cpp
+++ b/cpu/decoder.cpp
@@ -443,6 +443,8 @@ void Cpu::executeInstruction()
           break;
         case 0x76: // HALT
           state.halted = true;
+          if(state.IME != IME_ON && state.SI())
+            state.haltbug = true;
           break;
         case 0x10: // STOP n8
           (void)readPC8();