summaryrefslogtreecommitdiffstats
path: root/fw/snake.c
diff options
context:
space:
mode:
authorVäinö Kauppila <vaino@vke.fi>2026-04-20 19:44:19 +0300
committerVäinö Kauppila <vaino@vke.fi>2026-04-20 19:44:19 +0300
commitc9d20884c0a71eb80340f33e58aa73ad99f45ce2 (patch)
tree31f722232c879708c88494cd776adadcf4d5ca4b /fw/snake.c
parent704261cfdd07bc7ad98c9f3144b807e279ed6fa2 (diff)
downloadvhdl_pic-c9d20884c0a71eb80340f33e58aa73ad99f45ce2.tar.gz
vhdl_pic-c9d20884c0a71eb80340f33e58aa73ad99f45ce2.zip
try fix the snake bug
Diffstat (limited to 'fw/snake.c')
-rw-r--r--fw/snake.c87
1 files changed, 61 insertions, 26 deletions
diff --git a/fw/snake.c b/fw/snake.c
index 48ee417..e99802b 100644
--- a/fw/snake.c
+++ b/fw/snake.c
@@ -24,7 +24,6 @@ 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) {
@@ -42,36 +41,72 @@ static void uart_puts(const char *s) {
while (*s) uart_send((uint8_t)*s++);
}
+// return 0 if EMPTY
static uint8_t uart_recv(void) {
- if (UART_STATUS & 0x02) // empty
+ if (UART_STATUS & 0b00000010) // empty
return 0;
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) {
+/* /\* 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; */
+/* 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; */
+/* } */
+/* } */
+/* } */
+
+static uint8_t __near esc_state = 0;
+
+/* drains UART FIFO fully each frame */
+static void handle_input(void)
+{
uint8_t c;
- for (int i = 0; i < 5; i++) {
- 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;
+
+ while (!(UART_STATUS & 0x02)) /* while not empty */
+ {
+ c = UART_RX;
+
+ if (esc_state == 0)
+ {
+ if (c == 0x1B) esc_state = 1;
+ }
+ else if (esc_state == 1)
+ {
+ esc_state = (c == '[' || c == 'O') ? 2 : 0;
+ }
+ else /* esc_state == 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;
+ }
+ esc_state = 0;
}
}
}
@@ -208,6 +243,6 @@ void main(void) {
print_uint8(score);
uart_puts("\r\npress any key\r\n");
while (uart_recv() == 0); /* wait for any byte */
- input_state = 0;
+ esc_state = 0;
}
}