diff --git a/pycardium/main.c b/pycardium/main.c
index 3aec04919f1cbe3b6858f07697878897424ede7b..947f072c119d36c8c77e453bc7f7da6c8619ca05 100644
--- a/pycardium/main.c
+++ b/pycardium/main.c
@@ -32,54 +32,71 @@ int main(void)
 
 	pycardium_hal_init();
 
+	epic_uart_write_str(header, sizeof(header));
+
 	if (cnt < 0) {
 		printf("pycardium: Error fetching args: %d\n", cnt);
-	} else if (cnt > 0) {
-		epic_uart_write_str(header, sizeof(header));
+
+		/* Go to REPL instead. */
+		cnt = 0;
+	}
+
+	if (cnt > 0) {
 		printf("  Loading %s ...\n", script_name);
+	} else {
+		printf("  Entering REPL ...\n\n");
 	}
 
 	mp_stack_set_top(&__StackTop);
 	mp_stack_set_limit((mp_int_t)&__StackLimit);
 
-	while (1) {
-		gc_init(&__HeapBase + 1024 * 10, &__HeapLimit);
+	gc_init(&__HeapBase + 1024 * 10, &__HeapLimit);
 
-		mp_init();
+	mp_init();
 
-		readline_init0();
-		interrupt_init0();
+	readline_init0();
+	interrupt_init0();
 
-		/* request by badge.team */
-		mp_obj_list_init(mp_sys_path, 0);
-		mp_obj_list_append(mp_sys_path, MP_ROM_QSTR(MP_QSTR_));
-		mp_obj_list_append(
-			mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)
-		);
-		mp_obj_list_append(
-			mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_apps)
-		);
+	/* request by badge.team */
+	mp_obj_list_init(mp_sys_path, 0);
+	mp_obj_list_append(mp_sys_path, MP_ROM_QSTR(MP_QSTR_));
+	mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
+	mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_apps));
 
-		if (cnt > 0) {
-			pyexec_file_if_exists(script_name);
+	if (cnt > 0) {
+		int ret = pyexec_file_if_exists(script_name);
+
+		if (ret == 0) {
+			/*
+			 * The script was aborted via uncaught exception; Sadly
+			 * we can't find out what happened so let's hope it was
+			 * a KeyboardInterrupt and drop to REPL.
+			 *
+			 * In the future it might be interesting to rework this
+			 * so any other exception will lead to epic_exit(1).
+			 */
+			epic_exec("");
 		}
 
-		epic_uart_write_str(header, sizeof(header));
-
-		for (;;) {
-			if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
-				if (pyexec_raw_repl() != 0) {
-					break;
-				}
-			} else {
-				if (pyexec_friendly_repl() != 0) {
-					break;
-				}
+		/* The script ended execution normally; return to menu */
+		epic_exit(0);
+	}
+
+	for (;;) {
+		if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
+			if (pyexec_raw_repl() != 0) {
+				break;
+			}
+		} else {
+			if (pyexec_friendly_repl() != 0) {
+				break;
 			}
 		}
-
-		mp_deinit();
 	}
+
+	mp_deinit();
+
+	epic_exit(0);
 }
 
 void HardFault_Handler(void)
@@ -87,6 +104,11 @@ void HardFault_Handler(void)
 	epic_exit(255);
 }
 
+void _exit(void)
+{
+	epic_exit(254);
+}
+
 void gc_collect(void)
 {
 	void *sp = (void *)__get_MSP();
diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c
index 4dc043f7d8a130974d1cddc1994e2a6c2634172d..0c5c5b2cc84135584aa74df1253dc9b9f5f15c8c 100644
--- a/pycardium/mphalport.c
+++ b/pycardium/mphalport.c
@@ -283,14 +283,12 @@ mp_uint_t mp_hal_ticks_us(void)
  * Fatal Errors
  */
 
-extern NORETURN void *Reset_Handler(void);
-
 void NORETURN nlr_jump_fail(void *val)
 {
 	char msg[] = " >>> nlr_jump_fail <<<\r\n";
 	epic_uart_write_str(msg, sizeof(msg));
 
-	Reset_Handler();
+	epic_exit(253);
 }
 
 /******************************************************************************
diff --git a/tools/pycard10.py b/tools/pycard10.py
index a0ce74190e58efef07ac94e4858166cef845d350..5f0a870c2db5e5bf92f6b96a3e5531da63f9f95a 100755
--- a/tools/pycard10.py
+++ b/tools/pycard10.py
@@ -130,10 +130,12 @@ class PyCard10(Pyboard):
         None
         """
 
-        self.soft_reset()
-
         self.serial.write(b"\x03\x03")  # ctrl-C twice: interrupt any running program
 
+        self.serial.write(b"\x02")  # ctrl-B: ensue it's the normal mode
+
+        self.serial.write(b'__import__("os").exec("")\r')  # Reset to REPL
+
         # flush input (without relying on serial.flushInput())
         n = self.serial.inWaiting()
         while n > 0:
@@ -176,8 +178,6 @@ class PyCard10(Pyboard):
 
         self.serial.write(b"\x04")  # ctrl-D: do the reset
 
-        time.sleep(1)  # Give epicardium some time to cycle pycardium
-
         n = self.serial.inWaiting()
         while n > 0:
             self.serial.read(n)