diff options
| author | Väinö Kauppila <vaino@vke.fi> | 2026-04-20 14:52:24 +0300 |
|---|---|---|
| committer | Väinö Kauppila <vaino@vke.fi> | 2026-04-20 14:52:24 +0300 |
| commit | d36d2c8a9f4c8e602bd8d72295bb6285c0f7f67c (patch) | |
| tree | 9ccd43aa723a4fb601e92537f569b8e615719eef /fw | |
| parent | bb879e81cf84ec74608162326fef4ac40bf70acd (diff) | |
| download | vhdl_pic-d36d2c8a9f4c8e602bd8d72295bb6285c0f7f67c.tar.gz vhdl_pic-d36d2c8a9f4c8e602bd8d72295bb6285c0f7f67c.zip | |
snake
Diffstat (limited to 'fw')
| -rw-r--r-- | fw/snake.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/fw/snake.c b/fw/snake.c new file mode 100644 index 0000000..968379e --- /dev/null +++ b/fw/snake.c @@ -0,0 +1,122 @@ +#include <pic16f84a.h> + +typedef unsigned char uint8_t; + +__sfr __at(0x70) UART_TX; +__sfr __at(0x71) UART_RX; +__sfr __at(0x72) UART_STATUS; + +/* + * how many OVF per refresh of the screen + */ +#define OVF_PER_REFRESH 80 + +#define DIR_UP 0 +#define DIR_DOWN 1 +#define DIR_LEFT 2 +#define DIR_RIGHT 3 + +uint8_t direction; +uint8_t position[2]; + +static volatile uint8_t ovf_count = 0; + +void isr(void) __interrupt(0) { + if (INTCON & 0x04) { /* T0IF = bit 2 */ + ovf_count++; + INTCON &= ~(uint8_t)0x04; + } +} + +static void uart_send(uint8_t b) { + while (UART_STATUS & 0x01); + UART_TX = b; +} + +static void uart_puts(const char *s) { + while (*s) uart_send((uint8_t)*s++); +} + +static uint8_t uart_recv(void) { + if (UART_STATUS & 0x02) + return 0; /* rx_empty: nothing to read */ + return UART_RX; /* reading pops the FIFO */ +} + +static uint8_t uart_getc(void) { + while (UART_STATUS & 0x02); + return UART_RX; +} + +static void handle_input(void) { + uint8_t c = uart_recv(); + if (c != 0x1B) + return; + if (uart_getc() != '[') + return; + switch (uart_getc()) { + case 'A': direction = DIR_UP; break; /* ESC [ A */ + case 'B': direction = DIR_DOWN; break; /* ESC [ B */ + case 'C': direction = DIR_RIGHT; break; /* ESC [ C */ + case 'D': direction = DIR_LEFT; break; /* ESC [ D */ + } +} + +static void update_position(void) { + switch (direction) { + case DIR_UP: position[1]--; break; + case DIR_DOWN: position[1]++; break; + case DIR_LEFT: position[0]--; break; + case DIR_RIGHT: position[0]++; break; + } +} + +static void print_uint8(uint8_t v) { + uint8_t started = 0; + if (v >= 200) { uart_send('2'); v -= 200; started = 1; } + else if (v >= 100) { uart_send('1'); v -= 100; started = 1; } + { + uint8_t t = '0'; + while (v >= 10) { v -= 10; t++; } + if (started || t != '0') uart_send(t); + } + uart_send(v + '0'); +} + + +static void render(void) { + uart_puts("\x1B[H"); /* cursor home */ + + uart_puts("pos: "); + print_uint8(position[0]); + uart_puts(", "); + print_uint8(position[1]); + uart_puts("\r\n"); +} + + +void main(void) { + + OPTION_REG = 0x07; + TMR0 = 0; + INTCON = 0xa0; + + direction = DIR_RIGHT; + position[0] = 10; + position[1] = 5; + + uart_puts("\x1B[2J\x1B[H"); + uart_puts("snake\r\n"); + uart_puts("-----------\r\n"); + + while (1) { + ovf_count = 0; + while (ovf_count < OVF_PER_REFRESH); + + handle_input(); + update_position(); + render(); + + PORTA ^= 0x01; + } +} |
