diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c
index f8370ff11de1bbb0ff62c0631aa058ac81d48965..f3b3348d536d21877546a29e3de37094ed81bc3f 100644
--- a/pycardium/mphalport.c
+++ b/pycardium/mphalport.c
@@ -17,6 +17,7 @@
 #include "py/mpprint.h"
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -86,6 +87,68 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len)
 	epic_uart_write_str(str, len);
 }
 
+static char exception_lines[2][80];
+static bool exception;
+static size_t exception_line_index;
+
+static void exception_feed(char c)
+{
+	if (c == '\n') {
+		exception_lines[1][exception_line_index] = 0;
+		if (exception_lines[1][0] == ' ') {
+			memcpy(exception_lines[0],
+			       exception_lines[1],
+			       sizeof(exception_lines[0]));
+			exception_line_index = 0;
+		} else {
+			exception = false;
+			epic_disp_open();
+			epic_disp_clear(0);
+			epic_disp_print_adv(
+				1, 0, 0, "Exception:", 0xF800, 0x0000
+			);
+			char buf               = exception_lines[0][26];
+			exception_lines[0][26] = 0;
+			epic_disp_print_adv(
+				1, 0, 12, exception_lines[0], 0xFFFF, 0x0000
+			);
+			exception_lines[0][26] = buf;
+			if (strlen(exception_lines[0]) > 26) {
+				epic_disp_print_adv(
+					1,
+					0,
+					24,
+					exception_lines[0] + 26,
+					0xFFFF,
+					0x0000
+				);
+			}
+
+			buf                    = exception_lines[1][26];
+			exception_lines[1][26] = 0;
+			epic_disp_print_adv(
+				1, 0, 40, exception_lines[1], 0xF800, 0x0000
+			);
+			exception_lines[1][26] = buf;
+			if (strlen(exception_lines[1]) > 26) {
+				epic_disp_print_adv(
+					1,
+					0,
+					52,
+					exception_lines[1] + 26,
+					0xF800,
+					0x0000
+				);
+			}
+			epic_disp_update();
+		}
+	} else {
+		if (exception_line_index < sizeof(exception_lines[0]) - 1) {
+			exception_lines[1][exception_line_index++] = c;
+		}
+	}
+}
+
 /* Send a string, but replace \n with \n\r */
 void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len)
 {
@@ -93,6 +156,16 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len)
 	 * Only print one line at a time.  Insert `\r` between lines so
 	 * they are properly displayed on the serial console.
 	 */
+
+	if (strncmp(str, "Traceback (most recent call last):\n", len) == 0) {
+		exception            = true;
+		exception_line_index = 0;
+	} else if (exception) {
+		for (size_t i = 0; i < len; i++) {
+			exception_feed(str[i]);
+		}
+	}
+
 	size_t i, last = 0;
 	for (i = 0; i < len; i++) {
 		if (str[i] == '\n') {