#include 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; } }