diff --git a/esp8266/esp_mphal.h b/esp8266/esp_mphal.h
index 28f2ed53a780f0e4b1c3d333e2512d65d99b773b..617a0f8c1119544833db4027417910dc135797b0 100644
--- a/esp8266/esp_mphal.h
+++ b/esp8266/esp_mphal.h
@@ -27,6 +27,9 @@
 #ifndef _INCLUDED_MPHAL_H_
 #define _INCLUDED_MPHAL_H_
 
+// SDK functions not declared in SDK itself
+void ets_isr_mask(unsigned);
+
 void mp_hal_init(void);
 void mp_hal_feed_watchdog(void);
 void mp_hal_udelay(uint32_t);
diff --git a/esp8266/uart.c b/esp8266/uart.c
index 69c2f40fa8464cbcbad7dc50d6732be29fa824f7..55841fe39678e0ed466c9d05591ccec13a5a6683 100644
--- a/esp8266/uart.c
+++ b/esp8266/uart.c
@@ -20,6 +20,7 @@
 #include "esp_mphal.h"
 
 #define RX_BUF_SIZE (256)
+#define UART_REPL UART0
 
 // UartDev is defined and initialized in rom code.
 extern UartDevice UartDev;
@@ -135,8 +136,7 @@ static void uart0_rx_intr_handler(void *para) {
     * uart1 and uart0 respectively
     */
 
-    uint8 RcvChar;
-    uint8 uart_no = UART0;
+    uint8 uart_no = UART_REPL;
 
     if (UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) {
         // frame error
@@ -145,23 +145,22 @@ static void uart0_rx_intr_handler(void *para) {
 
     if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) {
         // fifo full
-        WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
         goto read_chars;
     } else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) {
-        WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_TOUT_INT_CLR);
         read_chars:
-        while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
-            RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
 #if 1 //MICROPY_REPL_EVENT_DRIVEN is not available here
-            system_os_post(UART_TASK_ID, 0, RcvChar);
+        ETS_UART_INTR_DISABLE();
+        system_os_post(UART_TASK_ID, 0, 0);
 #else
+        while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
+            uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
             uint16_t rx_buf_in_next = (rx_buf_in + 1) % RX_BUF_SIZE;
             if (rx_buf_in_next != rx_buf_out) {
                 rx_buf[rx_buf_in] = RcvChar;
                 rx_buf_in = rx_buf_in_next;
             }
-#endif
         }
+#endif
     }
 }
 
@@ -175,6 +174,13 @@ int uart0_rx(void) {
   }
 }
 
+int uart_rx_one_char(uint8 uart_no) {
+    if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
+        return READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
+    }
+    return -1;
+}
+
 /******************************************************************************
  * FunctionName : uart_init
  * Description  : user interface for init uart
@@ -206,7 +212,19 @@ void ICACHE_FLASH_ATTR uart_reattach() {
 void soft_reset(void);
 
 void uart_task_handler(os_event_t *evt) {
-    int ret = pyexec_event_repl_process_char(evt->par);
+    int c, ret = 0;
+    while ((c = uart_rx_one_char(UART_REPL)) >= 0) {
+        ret = pyexec_event_repl_process_char(c);
+        if (ret & PYEXEC_FORCED_EXIT) {
+            break;
+        }
+    }
+
+    // Clear pending FIFO interrupts
+    WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST);
+    // Enable UART interrupts, so our task will receive events again from IRQ handler
+    ETS_UART_INTR_ENABLE();
+
     if (ret & PYEXEC_FORCED_EXIT) {
         soft_reset();
     }