From 681bd85b0e3144e0dcc77a8cbe00747e8d4716de Mon Sep 17 00:00:00 2001 From: Väinö Kauppila Date: Mon, 20 Apr 2026 15:24:16 +0300 Subject: snake uart recv SM --- fw/snake.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'fw') diff --git a/fw/snake.c b/fw/snake.c index 879acf0..c875b1e 100644 --- a/fw/snake.c +++ b/fw/snake.c @@ -24,6 +24,7 @@ static __near uint8_t food_x; static __near uint8_t food_y; static __near uint8_t score; static volatile __near uint8_t ovf_count; +static __near uint8_t input_state; /* 0=idle, 1=got ESC, 2=got ESC+[ */ void isr(void) __interrupt(0) { if (INTCON & 0x04) { @@ -47,20 +48,31 @@ static uint8_t uart_recv(void) { return UART_RX; } -static uint8_t uart_getc(void) { - while (UART_STATUS & 0x02); - return UART_RX; -} - +/* Non-blocking state machine — drains the whole FIFO each frame. + * Handles both ESC [ x (CSI) and ESC O x (SS3) cursor key modes. + * Never blocks, so a stray ESC can't freeze the game. */ static void handle_input(void) { - uint8_t c = uart_recv(); - if (c != 0x1B) return; - if (uart_getc() != '[') return; - switch (uart_getc()) { - case 'A': if (direction != DIR_DOWN) direction = DIR_UP; break; - case 'B': if (direction != DIR_UP) direction = DIR_DOWN; break; - case 'C': if (direction != DIR_LEFT) direction = DIR_RIGHT; break; - case 'D': if (direction != DIR_RIGHT) direction = DIR_LEFT; break; + uint8_t c; + while (1) { + c = uart_recv(); + if (c == 0) return; + switch (input_state) { + case 0: + input_state = (c == 0x1B) ? 1 : 0; + break; + case 1: + input_state = (c == '[' || c == 'O') ? 2 : 0; + break; + case 2: + switch (c) { + case 'A': if (direction != DIR_DOWN) direction = DIR_UP; break; + case 'B': if (direction != DIR_UP) direction = DIR_DOWN; break; + case 'C': if (direction != DIR_LEFT) direction = DIR_RIGHT; break; + case 'D': if (direction != DIR_RIGHT) direction = DIR_LEFT; break; + } + input_state = 0; + break; + } } } @@ -195,6 +207,7 @@ void main(void) { uart_puts("GAME OVER score: "); print_uint8(score); uart_puts("\r\npress any key\r\n"); - uart_getc(); + while (uart_recv() == 0); /* wait for any byte */ + input_state = 0; } } -- cgit v1.3