summaryrefslogtreecommitdiffstats
path: root/fw
diff options
context:
space:
mode:
authorVäinö Kauppila <vaino@vke.fi>2026-04-20 15:24:16 +0300
committerVäinö Kauppila <vaino@vke.fi>2026-04-20 15:24:16 +0300
commit681bd85b0e3144e0dcc77a8cbe00747e8d4716de (patch)
tree149fa408691c8963a1c59ff2a81b664161575702 /fw
parente98cf5fe63ccadce28885208bd917568a0e9658d (diff)
downloadvhdl_pic-681bd85b0e3144e0dcc77a8cbe00747e8d4716de.tar.gz
vhdl_pic-681bd85b0e3144e0dcc77a8cbe00747e8d4716de.zip
snake uart recv SM
Diffstat (limited to 'fw')
-rw-r--r--fw/snake.c41
1 files changed, 27 insertions, 14 deletions
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;
}
}