summaryrefslogtreecommitdiffstats
path: root/fw
diff options
context:
space:
mode:
Diffstat (limited to 'fw')
-rw-r--r--fw/snake.c122
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;
+ }
+}