From 6d4ad089c5b758ad8af4f68bf385a26ec4e9653a Mon Sep 17 00:00:00 2001 From: Thomas Albers Raviola Date: Thu, 21 Nov 2024 15:55:03 +0100 Subject: Initial commit --- src/tty.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/tty.c (limited to 'src/tty.c') diff --git a/src/tty.c b/src/tty.c new file mode 100644 index 0000000..f9413b4 --- /dev/null +++ b/src/tty.c @@ -0,0 +1,164 @@ +#include +#include +#include + +struct color { + uint8_t r, g, b; +}; + +static unsigned int row = 0; +static unsigned int col = 0; + +// Index of first row inside buf +static volatile uint8_t head = 0; + +// TTY's current contents +static volatile uint8_t buf[TTY_HEIGHT][TTY_WIDTH]; + +static volatile struct color bg_color = {0x00, 0x00, 0x00}; +static volatile struct color fg_color = {0xFF, 0xFB, 0x00}; + +extern const uint8_t font[97][8]; + + +static uint8_t cursor = 0; +static uint8_t timer = 0; + +void +blink_cursor(void) __critical __interrupt(3) +{ + if (++timer >= 75) { + uint8_t i; + + tft_set_area(8 * col, 8 * row, 8, 8); + tft_ram_wr(); + + if ((cursor ^= 1)) { + for (i = 0; i < 64; ++i) + tft_pixel(fg_color.r, fg_color.g, fg_color.b); + } else { + for (i = 0; i < 64; ++i) + tft_pixel(bg_color.r, bg_color.g, bg_color.b); + } + timer = 0; + } +} + +static void +draw(u8 c) +{ + u8 i, j; + const u8 *chr; + + if (c < ' ') + return; + + chr = font[c - ' ']; + + tft_ram_wr(); + + for (i = 0; i < 8; ++i) { + u8 row = chr[i]; + for (j = 0; j < 8; ++j) { + if (row & 1) + tft_pixel(fg_color.r, fg_color.g, fg_color.b); + else + tft_pixel(bg_color.r, bg_color.g, bg_color.b); + row >>= 1; + } + } +} + +static void +scroll(void) +{ + uint16_t i, j; + head = (head + 1) % TTY_HEIGHT; + + for (i = head; i < TTY_HEIGHT; ++i) { + for (j = 0; j < TTY_WIDTH; ++j) { + tft_set_area(8 * j, 8 * (i - head), 8, 8); + draw(buf[i][j]); + } + } + + for (i = 0; i < head - 1; ++i) { + for (j = 0; j < TTY_WIDTH; ++j) { + tft_set_area(8 * j, 8 * (TTY_HEIGHT - head + i), 8, 8); + draw(buf[i][j]); + } + } + + for (j = 0; j < TTY_WIDTH; ++j) { + tft_set_area(8 * j, 8 * (TTY_HEIGHT - 1), 8, 8); + draw(' '); + } +} + +static void +newline(void) +{ + if (++row >= TTY_HEIGHT) { + row = TTY_HEIGHT - 1; + scroll(); + } +} + +static void +advance(void) +{ + if (++col >= TTY_WIDTH) { + newline(); + col = 0; + } +} + +void +addch(char c) +{ + switch (c) { + case '\b': + if (col != 0) + --col; + return; + + case '\r': + col = 0; + return; + + case '\n': + newline(); + return; + } + + tft_set_area(8 * col, 8 * row, 8, 8); + + draw(c); + + buf[(head + row) % TTY_HEIGHT][col] = c; + advance(); +} + +void +setcur(unsigned int ncol, unsigned int nrow) +{ + col = ncol; + row = nrow; +} + +void +swap_colors(void) +{ + struct color tmp = {fg_color.r, fg_color.g, fg_color.b}; + fg_color = bg_color; + bg_color = tmp; +} + +void +addstr(const char *str) +{ + while (*str) { + addch(*str); + ++str; + } +} -- cgit v1.2.3