diff --git a/source/tools/juggler.exe b/source/tools/juggler.exe
index 52a0542..6690d9f 100644
Binary files a/source/tools/juggler.exe and b/source/tools/juggler.exe differ
diff --git a/tools/platostools/src/nativeMain/kotlin/de/platon42/demoscene/tools/juggler/main.kt b/tools/platostools/src/nativeMain/kotlin/de/platon42/demoscene/tools/juggler/main.kt
index cdf4cf2..288562d 100644
--- a/tools/platostools/src/nativeMain/kotlin/de/platon42/demoscene/tools/juggler/main.kt
+++ b/tools/platostools/src/nativeMain/kotlin/de/platon42/demoscene/tools/juggler/main.kt
@@ -218,9 +218,200 @@ private fun parseLayoutLine(
             }
             println("Reorganized data to ${newData.size} bytes.")
         }
-
     }
-    lineParser.subcommands(ClearCommand(), LoadCommand(), SaveCommand(), ExtractCommand(), ReorganizeCommand())
+
+    class PlanarToChunkyCommand :
+        Subcommand("P2C", "Planar to chunky conversion") {
+        val width by argument(ArgType.Int, "width", description = "Width of image")
+        val height by argument(ArgType.Int, "height", description = "Height of image")
+        val planes by argument(ArgType.Int, "planes", description = "Number of planes")
+        val isInterleaved by option(ArgType.Boolean, "interleaved", "i", description = "Data is interleaved")
+        val startOffOption by option(ArgType.Int, "start", "s", description = "Start offset in bytes (default: 0)")
+
+        override fun execute() {
+            newData = UByteArray(width * height)
+            var inPos = startOffOption ?: 0
+            var outPos = 0
+            if ((width / 8) * height * planes + inPos > data.size) {
+                println("Input data not big enough!")
+                return
+            }
+            val planeOffset = if (isInterleaved == true) (width / 8) else (width / 8) * height
+            for (y in 0 until height) {
+                for (x in 0 until width step 8) {
+                    var mask = 0x80
+                    for (xx in 0..7) {
+                        var v = 0
+                        for (p in 0 until planes) {
+                            if ((data[inPos + p * planeOffset].toInt() and mask) != 0) {
+                                v += 1 shl p
+                            }
+                        }
+                        newData[outPos++] = v.toUByte()
+                        mask = mask shr 1
+                    }
+                    inPos++
+                }
+                if (isInterleaved == true) {
+                    inPos += planeOffset * (planes - 1)
+                }
+            }
+            println("Planar to chunky to ${newData.size} bytes.")
+        }
+    }
+
+    class ArithmeticCommand :
+        Subcommand("ALU", "Arithmetic operations") {
+        val length by argument(ArgType.Int, "length", description = "Amount of operations")
+        val operation by argument(
+            ArgType.Choice(
+                listOf("add", "sub", "neg", "mulu", "muls", "divu", "divs", "and", "or", "xor", "not"),
+                { it }), description = "Operation"
+        )
+        val operand by option(ArgType.Int, "const", "c", description = "Constant operand for operations")
+        val width by option(
+            ArgType.Choice(listOf("byte", "word", "long"), { it }),
+            shortName = "w",
+            description = "Width of operation (default: byte)"
+        )
+        val startOffOption by option(ArgType.Int, "start", "s", description = "Start offset in bytes (default: 0)")
+        val targetOffOption by option(
+            ArgType.Int,
+            "dest",
+            "d",
+            description = "Destination offset in bytes (default: 0)"
+        )
+        val operandOffOption by option(
+            ArgType.Int,
+            "operand",
+            "o",
+            description = "Operand offset in bytes (default: 0)"
+        )
+
+        override fun execute() {
+            val opWidth = when (width) {
+                "byte" -> 1
+                "word" -> 2
+                "long" -> 4
+                else -> 1
+            }
+            if ((operation != "neg") && (operation != "not") && (operand == null) && (operandOffOption == null)) {
+                println("Missing operand for operation '$operation!'")
+                return
+            }
+            var inPos = startOffOption ?: 0
+            var outPos = targetOffOption ?: 0
+            var opPos = operandOffOption ?: 0
+            if (inPos + length * opWidth > data.size) {
+                println("Input data not big enough!")
+                return
+            }
+            if (outPos + length * opWidth > data.size) {
+                println("Output data not big enough!")
+                return
+            }
+            if (opPos + length * opWidth > data.size) {
+                println("Operand data not big enough!")
+                return
+            }
+            for (p in 1..length) {
+                val value = when (opWidth) {
+                    1 -> data[inPos++].toInt()
+                    2 -> {
+                        var v = data[inPos++].toInt() shl 8
+                        v += data[inPos++].toInt()
+                        v
+                    }
+
+                    4 -> {
+                        var v = data[inPos++].toInt() shl 24
+                        v += data[inPos++].toInt() shl 16
+                        v += data[inPos++].toInt() shl 8
+                        v += data[inPos++].toInt()
+                        v
+                    }
+
+                    else -> 0
+                }
+                val opValue = if (operandOffOption != null) {
+                    when (opWidth) {
+                        1 -> data[opPos++].toInt()
+                        2 -> {
+                            var v = data[opPos++].toInt() shl 8
+                            v += data[opPos++].toInt()
+                            v
+                        }
+
+                        4 -> {
+                            var v = data[opPos++].toInt() shl 24
+                            v += data[opPos++].toInt() shl 16
+                            v += data[opPos++].toInt() shl 8
+                            v += data[opPos++].toInt()
+                            v
+                        }
+
+                        else -> 0
+                    }
+                } else {
+                    operand ?: 0
+                }
+                val result = when (operation) {
+                    "add" -> value + opValue
+                    "sub" -> value - opValue
+                    "neg" -> -value
+
+                    "and" -> value and opValue
+                    "or" -> value or opValue
+                    "xor" -> value xor opValue
+                    "not" -> value.inv()
+
+                    "mulu" -> value * opValue
+                    "muls" -> when (opWidth) {
+                        1 -> value.toByte().toInt() * opValue.toByte().toInt()
+                        2 -> value.toShort().toInt() * opValue.toShort().toInt()
+                        4 -> value * opValue
+                        else -> 0
+                    }
+
+                    "divu" -> value / opValue
+                    "divs" -> when (opWidth) {
+                        1 -> value.toByte().toInt() / opValue.toByte().toInt()
+                        2 -> value.toShort().toInt() / opValue.toShort().toInt()
+                        4 -> value / opValue
+                        else -> 0
+                    }
+
+                    else -> 0
+                }
+
+                when (opWidth) {
+                    1 -> data[outPos++] = result.toUByte()
+                    2 -> {
+                        data[outPos++] = (result ushr 8).toUByte()
+                        data[outPos++] = result.toUByte()
+                    }
+
+                    4 -> {
+                        data[outPos++] = (result ushr 24).toUByte()
+                        data[outPos++] = (result ushr 16).toUByte()
+                        data[outPos++] = (result ushr 8).toUByte()
+                        data[outPos++] = result.toUByte()
+                    }
+                }
+            }
+            println("ALU done.")
+        }
+    }
+
+    lineParser.subcommands(
+        ClearCommand(),
+        LoadCommand(),
+        SaveCommand(),
+        ExtractCommand(),
+        ReorganizeCommand(),
+        PlanarToChunkyCommand(),
+        ArithmeticCommand()
+    )
     println(line)
     lineParser.parse(line.split(" ").toTypedArray())
     return newData