diff options
| author | Väinö Kauppila <vaino@vke.fi> | 2026-04-20 15:24:16 +0300 |
|---|---|---|
| committer | Väinö Kauppila <vaino@vke.fi> | 2026-04-20 15:24:16 +0300 |
| commit | 681bd85b0e3144e0dcc77a8cbe00747e8d4716de (patch) | |
| tree | 149fa408691c8963a1c59ff2a81b664161575702 /fw | |
| parent | e98cf5fe63ccadce28885208bd917568a0e9658d (diff) | |
| download | vhdl_pic-681bd85b0e3144e0dcc77a8cbe00747e8d4716de.tar.gz vhdl_pic-681bd85b0e3144e0dcc77a8cbe00747e8d4716de.zip | |
snake uart recv SM
Diffstat (limited to 'fw')
| -rw-r--r-- | fw/snake.c | 41 |
1 files changed, 27 insertions, 14 deletions
@@ -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; } } |
