Some improvements for custom debug output.
diff --git a/sdk/include/debug.hh b/sdk/include/debug.hh
index a3dda60..6c6bfa7 100644
--- a/sdk/include/debug.hh
+++ b/sdk/include/debug.hh
@@ -79,6 +79,44 @@
 	 * Write a 64-bit signed integer.
 	 */
 	virtual void write(int64_t) = 0;
+	/**
+	 * Write a single byte as hex with no leading 0x.
+	 */
+	virtual void write_hex_byte(uint8_t) = 0;
+	/**
+	 * Write an integer as hex.
+	 */
+	template<typename T>
+	__always_inline void write_hex(T x)
+	    requires(std::integral<T>)
+	{
+		if constexpr (sizeof(T) <= 4)
+		{
+			write(static_cast<uint32_t>(x));
+		}
+		else
+		{
+			write(static_cast<uint64_t>(x));
+		}
+	}
+	/**
+	 * Write an integer as decimal.
+	 */
+	template<typename T>
+	__always_inline void write_decimal(T x)
+	    requires(std::integral<T>)
+	{
+		if constexpr (sizeof(T) <= 4)
+		{
+			write(
+			  static_cast<int32_t>(static_cast<std::make_unsigned_t<T>>(x)));
+		}
+		else
+		{
+			write(
+			  static_cast<int64_t>(static_cast<std::make_unsigned_t<T>>(x)));
+		}
+	}
 };
 
 /**
diff --git a/sdk/lib/debug/debug.cc b/sdk/lib/debug/debug.cc
index 2643db1..d855a3f 100644
--- a/sdk/lib/debug/debug.cc
+++ b/sdk/lib/debug/debug.cc
@@ -168,6 +168,14 @@
 		}
 
 		/**
+		 * Write a single byte with no prefix.
+		 */
+		void write_hex_byte(uint8_t byte) override
+		{
+			append_hex_word(byte);
+		}
+
+		/**
 		 * Write a 32-bit unsigned integer to the buffer as hex with no prefix.
 		 */
 		void append_hex_word(uint32_t s)