diff --git a/src/main/scala/millfork/compiler/m6809/M6809Buitins.scala b/src/main/scala/millfork/compiler/m6809/M6809Buitins.scala
index 279ac573..7b4f4c73 100644
--- a/src/main/scala/millfork/compiler/m6809/M6809Buitins.scala
+++ b/src/main/scala/millfork/compiler/m6809/M6809Buitins.scala
@@ -88,7 +88,7 @@ object M6809Buitins {
               case (false, false) => MathOperator.Plus
               case (true, false) => MathOperator.Minus
               case (false, true) => MathOperator.DecimalPlus
-              case (false, true) => MathOperator.DecimalMinus
+              case (true, true) => MathOperator.DecimalMinus
             },
             constant, c
           ).quickSimplify
@@ -133,27 +133,51 @@ object M6809Buitins {
     val result = ListBuffer[MLine]()
     for ((neg, load) <- addendReads) {
       if (result.isEmpty && fromScratch) {
-        result ++= load
-        if (neg) result += MLine.inherentB(NEG)
+        if (expr.decimal) {
+          if (load.nonEmpty && load.last.opcode == LDB) {
+            result ++= load.init
+            result += load.last.copy(opcode = LDA)
+          } else {
+            result ++= load
+            result += MLine.tfr(M6809Register.B, M6809Register.A)
+          }
+          if (neg) ???
+        } else {
+          result ++= load
+          if (neg) result += MLine.inherentB(NEG)
+        }
       } else {
         load match {
           case List(l@MLine0(LDB, _, _)) =>
             if (neg) {
-              result += l.copy(opcode = sub)
-              if (expr.decimal) ???
+              if (expr.decimal) {
+                result += MLine.pp(PSHS, M6809Register.A)
+                result += MLine.immediate(LDA, 0x9a)
+                result += l.copy(opcode = SUBA)
+                result += MLine.accessAndPullS(ADDA)
+                result += MLine.inherent(DAA)
+              } else {
+                result += l.copy(opcode = sub)
+              }
             } else {
               result += l.copy(opcode = add)
               if (expr.decimal) result += MLine.inherent(DAA)
             }
           case _ =>
             if (expr.decimal) {
-              result += MLine.pp(PSHS, M6809Register.A)
-              result ++= load
-              result += MLine.pp(PULS, M6809Register.A)
               if (neg) {
-                ???
-                if (expr.decimal) ???
+                result += MLine.pp(PSHS, M6809Register.A)
+                result ++= load
+                result += MLine.pp(PSHS, M6809Register.B)
+                result += MLine.immediate(LDA, 0x9a)
+                result += MLine.accessAndPullS(SUBA)
+                result += MLine.accessAndPullS(ADDA)
+                result += MLine.inherent(DAA)
               } else {
+                result += MLine.pp(PSHS, M6809Register.A)
+                result ++= load
+                result += MLine.pp(PULS, M6809Register.A)
+                result += MLine.pp(PSHS, M6809Register.B)
                 result += MLine.accessAndPullS(ADDA)
                 result += MLine.inherent(DAA)
               }
diff --git a/src/main/scala/millfork/compiler/m6809/M6809DecimalBuiltins.scala b/src/main/scala/millfork/compiler/m6809/M6809DecimalBuiltins.scala
new file mode 100644
index 00000000..e1f06d81
--- /dev/null
+++ b/src/main/scala/millfork/compiler/m6809/M6809DecimalBuiltins.scala
@@ -0,0 +1,48 @@
+package millfork.compiler.m6809
+
+import millfork.assembly.m6809.MLine
+import millfork.compiler.CompilationContext
+import millfork.node.Expression
+import millfork.assembly.m6809.MOpcode._
+import millfork.env.NumericConstant
+import millfork.node.M6809Register._
+
+/**
+  * @author Karol Stasiak
+  */
+object M6809DecimalBuiltins {
+
+  def compileByteDecimalShiftLeft(ctx: CompilationContext, lhs: Option[Expression], rhs: Expression): List[MLine] = {
+    val load = lhs match {
+      case None => List(MLine.indexedX(LDA, 0))
+      case Some(l) => M6809ExpressionCompiler.compileToA(ctx, l)
+    }
+    val loop = ctx.env.eval(rhs) match {
+      case Some(NumericConstant(0, _)) => Nil
+      case Some(NumericConstant(1, _)) => List(
+        MLine.pp(PSHS, A),
+        MLine.accessAndPullS(ADDA),
+        MLine.inherent(DAA)
+      )
+      case _ =>
+        val labelSkip = ctx.nextLabel("ss")
+        val labelRepeat = ctx.nextLabel("sr")
+        M6809ExpressionCompiler.stashAIfNeeded(ctx, M6809ExpressionCompiler.compileToB(ctx, rhs)) ++ List(
+          MLine.label(labelRepeat),
+          MLine.immediate(CMPB, 0),
+          MLine.shortBranch(BEQ, labelSkip),
+          MLine.pp(PSHS, A),
+          MLine.accessAndPullS(ADDA),
+          MLine.inherent(DAA),
+          MLine.inherentB(DEC),
+          MLine.shortBranch(BRA, labelRepeat),
+          MLine.label(labelSkip)
+        )
+    }
+    val store = lhs match {
+      case None => List(MLine.indexedX(STA, 0))
+      case Some(l) => Nil
+    }
+    load ++ loop ++ store
+  }
+}
diff --git a/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala b/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala
index babed652..9c502070 100644
--- a/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala
+++ b/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala
@@ -345,7 +345,12 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
                 M6809Buitins.compileWordShiftForD(ctx, params(1), left = false) ++
                 targetifyB(ctx, target, isSigned = false)
             }
-          case "<<'" => ???
+          case "<<'" =>
+            assertArithmeticBinary(ctx, params) match {
+              case (l, r, 1) => M6809DecimalBuiltins.compileByteDecimalShiftLeft(ctx, Some(l), r) ++ targetifyA(ctx, target, isSigned = false)
+              case (l, r, 2) => ???
+              case (l, r, _) => ???
+            }
           case ">>'" => ???
           case "+=" =>
             val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
@@ -354,7 +359,22 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
               case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ADDD, commutative = true)
               case _ => ctx.log.error("Long addition not implemented yet", fce.position); Nil
             }
-          case "+'=" => ???
+          case "+'=" =>
+            val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
+            size match {
+              case 1 =>
+                val lc = compileAddressToX(ctx, l)
+                val rc = compileToA(ctx, r)
+                val add = List(MLine.indexedX(ADDA, 0), MLine.inherent(DAA), MLine.indexedX(STA, 0))
+                (lc.exists(_.changesRegister(M6809Register.A)), rc.exists(_.changesRegister(M6809Register.X))) match {
+                  case (false, false) => rc ++ lc ++ add
+                  case (false, true) => rc ++ lc ++ add
+                  case (true, false) => lc ++ rc ++ add
+                  case (true, true) => rc ++ stashAIfNeeded(ctx, lc) ++ add
+                }
+              case 2 => ???
+              case _ => ???
+            }
           case "-=" =>
             val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
             size match {
@@ -362,7 +382,17 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
               case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, SUBD, commutative = false)
               case _ => ???
             }
-          case "-'=" => ???
+          case "-'=" =>
+            val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
+            size match {
+              case 1 =>
+                val lc = compileAddressToX(ctx, l)
+                val rc = compileToB(ctx, r)
+                lc ++ List(MLine.pp(PSHS, M6809Register.B)) ++
+                  rc ++ List(MLine.pp(PSHS, M6809Register.B), MLine.immediate(LDA, 0x9a), MLine.accessAndPullS(SUBA), MLine.accessAndPullS(ADDA), MLine.inherent(DAA), MLine.indexedX(STA, 0))
+              case 2 => ???
+              case _ => ???
+            }
           case "*=" =>
             val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
             size match {
@@ -412,7 +442,13 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
               case 2 =>
                 handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = true))
             }
-          case "<<'=" => ???
+          case "<<'=" =>
+            val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
+            size match {
+              case 1 =>
+                compileAddressToX(ctx, l) ++ M6809DecimalBuiltins.compileByteDecimalShiftLeft(ctx, None, r)
+              case 2 => ???
+            }
           case ">>=" =>
             val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
             // TODO: optimize shifts directly in memory
diff --git a/src/test/scala/millfork/test/ByteDecimalMathSuite.scala b/src/test/scala/millfork/test/ByteDecimalMathSuite.scala
index 86c771e5..5bccdd50 100644
--- a/src/test/scala/millfork/test/ByteDecimalMathSuite.scala
+++ b/src/test/scala/millfork/test/ByteDecimalMathSuite.scala
@@ -10,7 +10,7 @@ import org.scalatest.{FunSuite, Matchers}
 class ByteDecimalMathSuite extends FunSuite with Matchers {
 
   test("Decimal byte addition") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | byte a
@@ -22,7 +22,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Decimal byte addition 2") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | byte a
@@ -62,7 +62,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Decimal byte subtraction") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | byte a
@@ -74,7 +74,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("In-place decimal byte addition") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | array output[3] @$c000
         | byte a
@@ -88,7 +88,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("In-place decimal byte addition 2") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | array output[3] @$c000
         | void main () {
@@ -108,7 +108,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("In-place decimal byte subtraction") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | byte a
@@ -181,7 +181,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Flag switching test") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | void main () {
@@ -192,7 +192,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Flag switching test 2") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | void main () {
@@ -203,7 +203,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Flag switching test 3") {
-    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | void main () {
@@ -214,7 +214,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Decimal left shift test") {
-    EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | void main () {
@@ -229,7 +229,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
   }
 
   test("Decimal left shift test 2") {
-    EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
+    EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
       """
         | byte output @$c000
         | void main () {
diff --git a/src/test/scala/millfork/test/emu/M6809Memory.scala b/src/test/scala/millfork/test/emu/M6809Memory.scala
index 99274395..31f7a1b2 100644
--- a/src/test/scala/millfork/test/emu/M6809Memory.scala
+++ b/src/test/scala/millfork/test/emu/M6809Memory.scala
@@ -22,6 +22,8 @@ class M6809Memory(memoryBank: MemoryBank, resetVector: Int) extends MemorySegmen
 
   override def load(addr: Int): Int = {
     if (!memoryBank.readable(addr)) {
+      val start = addr & 0xff00
+      (0 until 0x100).grouped(16).map(range => (start + range.head).toHexString + range.map(i => memoryBank.output(start + i)).map(v => f" $v%02X").mkString("")).foreach(println)
       println(s"Accessing memory for read at $$${addr.toHexString}")
       ???
     }