summaryrefslogtreecommitdiffstats
path: root/tis-curses.c
diff options
context:
space:
mode:
Diffstat (limited to 'tis-curses.c')
-rw-r--r--tis-curses.c565
1 files changed, 0 insertions, 565 deletions
diff --git a/tis-curses.c b/tis-curses.c
deleted file mode 100644
index 157b102..0000000
--- a/tis-curses.c
+++ /dev/null
@@ -1,565 +0,0 @@
-#define NCURSES_WIDECHAR 1
-
-#include "tpu.h"
-#include "util.h"
-#include "asm.h"
-
-#include <curses.h>
-#include <sys/inotify.h>
-#include <unistd.h>
-#include <locale.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#define KEY_ESC 0x1b
-#define KEY_CTRL(c) ((c) & ~0x60)
-
-#define TPU_INPUT_ROWS 14
-#define TPU_INPUT_COLS 20
-#define TPU_INFO_W 6
-#define TPU_INFO_H 4
-#define TPU_CNT 6
-#define TPU_W (TPU_INPUT_COLS + 2 + 6)
-#define TPU_H (TPU_INPUT_ROWS + 2)
-
-#define TIMEOUT 50
-
-enum input_mode {
- MAIN,
- TPU_NAV
-};
-
-enum {
- NONE, MIN, MAX, MID
-};
-
-enum {
- COLOR_HEADING,
- COLOR_VAL
-};
-
-static const char *mode_repr[] = {
- "IDL", "RUN", "REA", "WRI"
-};
-
-static int scrx = 0;
-static int scry = 0;
-static int scrw = 80;
-static int scrh = 40;
-
-static struct tis tis;
-static FILE *tis_stdin = NULL;
-static FILE *tis_stdout = NULL;
-
-static int show_reloaded = 0;
-
-static enum input_mode input_mode = MAIN;
-
-static struct tpu *tpu_sel = NULL;
-
-int (*cleanup)(void) = endwin;
-const char *progname = "tis-curses";
-
-static enum tpu_port_dir
-key_to_dir(int key)
-{
- switch (key) {
- case KEY_LEFT:
- return DIR_LEFT;
- case KEY_RIGHT:
- return DIR_RIGHT;
- case KEY_UP:
- return DIR_UP;
- case KEY_DOWN:
- return DIR_DOWN;
- default:
- abort();
- }
-}
-
-static const cchar_t *
-dir_to_arrow(enum tpu_port_dir dir)
-{
- switch (dir) {
- case DIR_UP:
- return WACS_UARROW;
- case DIR_DOWN:
- return WACS_DARROW;
- case DIR_LEFT:
- return WACS_LARROW;
- case DIR_RIGHT:
- return WACS_RARROW;
- }
-}
-
-static int
-tpu_pos_x(struct tpu *tpu)
-{
- return 2 + (int) tpu->x * (TPU_W + 4);
-}
-
-static int
-tpu_pos_y(struct tpu *tpu)
-{
- return 2 + (int) tpu->y * (TPU_H + 2);
-}
-
-static void
-tui_draw_box(int sx, int sy, int w, int h, attr_t attr,
- const cchar_t *ul, const cchar_t *ur,
- const cchar_t *ll, const cchar_t *lr)
-{
- int x, y;
-
- if (sx + w < scrx || sx >= scrx + scrw) return;
- if (sy + h < scry || sy >= scry + scrh) return;
-
- sx -= scrx;
- sy -= scry;
-
- attron(attr);
- mvadd_wch(sy, sx, ul);
- mvadd_wch(sy, sx + w - 1, ur);
- mvadd_wch(sy + h - 1, sx, ll);
- mvadd_wch(sy + h - 1, sx + w - 1, lr);
- for (x = sx + 1; x < sx + w - 1; x++)
- mvadd_wch(sy, x, WACS_D_HLINE);
- for (x = sx + 1; x < sx + w - 1; x++)
- mvadd_wch(sy + h - 1, x, WACS_D_HLINE);
- for (y = sy + 1; y < sy + h - 1; y++)
- mvadd_wch(y, sx, WACS_D_VLINE);
- for (y = sy + 1; y < sy + h - 1; y++)
- mvadd_wch(y, sx + w - 1, WACS_D_VLINE);
- attroff(attr);
-}
-
-static void
-__attribute__((format(printf, 4, 5)))
-tui_draw_text(int x, int y, attr_t attr, const char *fmt, ...)
-{
- char buf[256];
- va_list ap;
- int i;
-
- va_start(ap, fmt);
- vsnprintf(buf, 256, fmt, ap);
- va_end(ap);
-
- attron(attr);
- for (i = 0; i < strlen(buf) && x + i < scrx + scrw; i++)
- mvaddch(y - scry, x + i - scrx, (chtype) buf[i]);
- attroff(attr);
-}
-
-static void
-tui_draw_wch(int x, int y, attr_t attr, const cchar_t *c)
-{
- attron(attr);
- mvadd_wch(y - scry, x - scrx, c);
- attroff(attr);
-}
-
-static void
-tui_draw_tpu(struct tpu *tpu)
-{
- char linebuf[TPU_INPUT_COLS + 1];
- struct tpu_port *port;
- int sx, sy, x, y, w, h;
- int off, start, inst;
- size_t len;
- attr_t attr;
- int idle;
-
- attr = (tpu_sel == tpu && input_mode == TPU_NAV) ? A_BOLD : 0;
-
- sx = tpu_pos_x(tpu);
- sy = tpu_pos_y(tpu);
- tui_draw_box(sx, sy, TPU_W, TPU_H, attr,
- WACS_D_ULCORNER, WACS_D_URCORNER,
- WACS_D_LLCORNER, WACS_D_LRCORNER);
-
- if (tpu->inst_cnt > 0) {
- start = MAX(0, MIN(tpu->pc - 4, (int) tpu->inst_cnt - TPU_INPUT_ROWS));
- inst = start;
- for (off = 0; off < TPU_INPUT_ROWS && inst < tpu->inst_cnt; ) {
- if (tpu->label_map.labels[inst]) {
- len = strlen(tpu->label_map.labels[inst]);
- if (len > TPU_INPUT_COLS - 1) {
- tui_draw_text(sx + 2, sy + 1 + off, A_DIM,
- "%.*s..:", TPU_INPUT_COLS - 3,
- tpu->label_map.labels[inst]);
- } else {
- tui_draw_text(sx + 2, sy + 1 + off, A_DIM,
- "%s:", tpu->label_map.labels[inst]);
- }
- off++;
- }
- asm_print_inst(linebuf, sizeof(linebuf), &tpu->insts[inst]);
- tui_draw_text(sx + 2, sy + 1 + off,
- inst == tpu->pc ? A_STANDOUT : 0, "%-*.*s",
- TPU_INPUT_COLS, TPU_INPUT_COLS, linebuf);
- inst++; off++;
- }
- }
-
- x = sx + TPU_W - TPU_INFO_W;
- y = sy;
- w = TPU_INFO_W;
- h = TPU_INFO_H;
- tui_draw_box(x, y, w, h, attr,
- WACS_D_TTEE, WACS_D_URCORNER, WACS_D_LTEE, WACS_D_RTEE);
- tui_draw_text(x + 2, y + 1, A_BOLD, "ACC");
- tui_draw_text(x + 2, y + 2, 0, "%03i", tpu->acc);
-
- tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
- WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE);
- tui_draw_text(x + 2, y + 1, A_BOLD, "BAK");
- tui_draw_text(x + 2, y + 2, 0, "%03i", tpu->bak);
-
- tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
- WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE);
- tui_draw_text(x + 2, y + 1, A_BOLD, "LST");
- if (tpu->last < 0) {
- tui_draw_text(x + 2, y + 2, 0, "N/A");
- } else {
- tui_draw_wch(x + 2, y + 2, 0,
- dir_to_arrow((enum tpu_port_dir) tpu->last));
- tui_draw_wch(x + 3, y + 2, 0,
- dir_to_arrow((enum tpu_port_dir) tpu->last));
- tui_draw_wch(x + 4, y + 2, 0,
- dir_to_arrow((enum tpu_port_dir) tpu->last));
- }
-
- tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
- WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE);
- tui_draw_text(x + 2, y + 1, A_BOLD, "MOD");
- tui_draw_text(x + 2, y + 2, 0, "%s", mode_repr[tpu->status]);
-
- tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
- WACS_D_LTEE, WACS_D_RTEE, WACS_D_BTEE, WACS_D_LRCORNER);
- tui_draw_text(x + 2, y + 1, A_BOLD, "IDL");
- if (tpu->steps > 0)
- idle = (int) ((double) tpu->idle_steps * 100 / (double) tpu->steps);
- else
- idle = 100;
- tui_draw_text(x + 2, y + 2, 0, "%03i", idle);
-
- if (tpu->ports[DIR_LEFT].attached) {
- port = &tpu->ports[DIR_LEFT];
- if (port->in >= 0)
- tui_draw_text(sx - 3, sy + 6,
- A_BOLD, "%03i", port->in);
- if (port->type & PORT_IN)
- tui_draw_wch(sx - 1, sy + 7,
- port->in >= 0 ? A_BOLD : 0, WACS_RARROW);
- if (port->type & PORT_OUT)
- tui_draw_wch(sx - 1, sy + 8,
- port->out >= 0 ? A_BOLD : 0, WACS_LARROW);
- if (port->out >= 0)
- tui_draw_text(sx - 3, sy + 10,
- A_BOLD, "%03i", port->out);
- }
-
- if (tpu->ports[DIR_RIGHT].attached) {
- port = &tpu->ports[DIR_RIGHT];
- if (port->out >= 0)
- tui_draw_text(sx + TPU_W + 1, sy + 5,
- A_BOLD, "%03i", port->out);
- if (port->type & PORT_OUT)
- tui_draw_wch(sx + TPU_W + 1, sy + 7,
- port->out >= 0 ? A_BOLD : 0, WACS_RARROW);
- if (port->type & PORT_IN)
- tui_draw_wch(sx + TPU_W + 1, sy + 8,
- port->in >= 0 ? A_BOLD : 0, WACS_LARROW);
- if (port->in >= 0)
- tui_draw_text(sx + TPU_W + 1, sy + 9,
- A_BOLD, "%03i", port->in);
- }
-
- if (tpu->ports[DIR_UP].attached) {
- port = &tpu->ports[DIR_UP];
- if (port->out >= 0)
- tui_draw_text(sx + 9, sy - 1,
- A_BOLD, "%03i", port->out);
- if (port->type & PORT_OUT)
- tui_draw_wch(sx + 13, sy - 1,
- port->out >= 0 ? A_BOLD : 0, WACS_UARROW);
- if (port->type & PORT_IN)
- tui_draw_wch(sx + 15, sy - 1,
- port->in >= 0 ? A_BOLD : 0, WACS_DARROW);
- if (port->in >= 0)
- tui_draw_text(sx + 17, sy - 1,
- A_BOLD, "%03i", port->in);
- }
-
- if (tpu->ports[DIR_DOWN].attached) {
- port = &tpu->ports[DIR_DOWN];
- if (port->in >= 0)
- tui_draw_text(sx + 9, sy + TPU_H,
- A_BOLD, "%03i", port->in);
- if (port->type & PORT_IN)
- tui_draw_wch(sx + 13, sy + TPU_H,
- port->in >= 0 ? A_BOLD : 0, WACS_UARROW);
- if (port->type & PORT_OUT)
- tui_draw_wch(sx + 15, sy + TPU_H,
- port->out >= 0 ? A_BOLD : 0, WACS_DARROW);
- if (port->out >= 0)
- tui_draw_text(sx + 17, sy + TPU_H,
- A_BOLD, "%03i", port->out);
- }
-}
-
-static void
-tui_draw(void)
-{
- struct tpu_map_link *link;
- size_t i;
- int tx;
-
- clear();
- for (i = 0; i < TPU_MAP_BUCKETS; i++) {
- for (link = tis.tpu_map.buckets[i]; link; link = link->next)
- tui_draw_tpu(link->tpu);
- }
- if (show_reloaded > 0) {
- tx = MAX(0, scrx + scrw / 2 - 4);
- tui_draw_text(scrx, scry, A_STANDOUT, "%-*s", scrw, "");
- tui_draw_text(tx, scry, A_STANDOUT, "RELOADED");
- show_reloaded--;
- }
- refresh();
-}
-
-static void
-tui_resize(void)
-{
- scrw = getmaxx(stdscr);
- scrh = getmaxy(stdscr);
-}
-
-static void
-tui_seek(struct tpu *tpu, int dx, int dy)
-{
- struct tpu_map_link *link;
- int minx, miny, maxx, maxy;
- int x, y;
- size_t i;
-
- if (tpu) {
- minx = maxx = tpu_pos_x(tpu);
- miny = maxy = tpu_pos_y(tpu);
- } else {
- minx = miny = maxx = maxy = -1;
- for (i = 0; i < TPU_MAP_BUCKETS; i++) {
- link = tis.tpu_map.buckets[i];
- for (; link; link = link->next) {
- if (tpu && tpu != link->tpu)
- continue;
- x = tpu_pos_x(link->tpu);
- if (minx == -1 || x < minx) minx = x;
- if (maxx == -1 || x > maxx) maxx = x;
- y = tpu_pos_y(link->tpu);
- if (miny == -1 || y < miny) miny = y;
- if (maxy == -1 || y > maxy) maxy = y;
- }
- }
- if (minx == -1 || miny == -1) return;
- }
-
- if (dx == MIN) scrx = minx - 2;
- else if (dx == MAX) scrx = maxx + TPU_W + 2 - scrw;
- else if (dx == MID) scrx = (minx + maxx + TPU_W - scrw) / 2;
-
- if (dy == MIN) scry = miny - 2;
- else if (dy == MAX) scry = maxy + TPU_H + 2 - scrh;
- else if (dy == MID) scry = (miny + maxy + TPU_H - scrh) / 2;
-}
-
-static void
-handlekey(int key)
-{
- enum tpu_port_dir dir;
- int c;
-
- if (input_mode == MAIN) {
- switch (key) {
- case 'I':
- input_mode = TPU_NAV;
- break;
- case KEY_UP:
- scry -= 2;
- break;
- case KEY_DOWN:
- scry += 2;
- break;
- case KEY_LEFT:
- scrx -= 4;
- break;
- case KEY_RIGHT:
- scrx += 4;
- break;
- case 's':
- if (tis_stdin && tis.stdin_port.attached
- && tis.stdin_port.out < 0) {
- c = getc(tis_stdin);
- if (c >= 0) tis.stdin_port.out = c;
- }
-
- if (tis.stdout_port.attached && tis.stdout_port.in >= 0) {
- if (tis_stdout)
- putc(tis.stdout_port.in, tis_stdout);
- tis.stdout_port.in = -1;
- }
-
- tis_step(&tis);
- break;
- }
- } else {
- switch (key) {
- case KEY_ESC:
- input_mode = MAIN;
- break;
- case KEY_UP:
- case KEY_DOWN:
- case KEY_LEFT:
- case KEY_RIGHT:
- dir = key_to_dir(key);
- if (tpu_sel && tpu_sel->ports[dir].dst_tpu)
- tpu_sel = tpu_sel->ports[dir].dst_tpu;
- tui_seek(tpu_sel, MID, MID);
- break;
- }
- }
-}
-
-static struct tpu *
-first_tpu(void)
-{
- size_t i;
-
- for (i = 0; i < TPU_MAP_BUCKETS; i++) {
- if (tis.tpu_map.buckets[i])
- return tis.tpu_map.buckets[i]->tpu;
- }
-
- return NULL;
-}
-
-static void
-reset(int ifd, int argc, char **argv, bool watch)
-{
- tis_load(&tis, argv[1]);
-
- if (watch)
- if (inotify_add_watch(ifd, argv[1], IN_MODIFY) < 0)
- die("inotify_add_watch '%s':", argv[1]);
-
- if (argc >= 3) {
- if (tis_stdin) fclose(tis_stdin);
- tis_stdin = fopen(argv[2], "r");
- if (!tis_stdin) die("fopen '%s':", argv[2]);
- }
-
- if (argc >= 4) {
- if (tis_stdout) fclose(tis_stdout);
- tis_stdout = fopen(argv[3], "w+");
- if (!tis_stdout) die("fopen '%s':", argv[3]);
- }
-
- if (tis.stdin_port.attached) {
- tpu_sel = tis.stdin_port.dst_tpu;
- } else {
- tpu_sel = first_tpu();
- }
- tui_seek(NULL, MID, MID);
-
-}
-
-int
-main(int argc, char **argv)
-{
- struct inotify_event event;
- ssize_t len;
- bool quit;
- int key;
- int ifd;
-
- if (argc < 2 || argc > 4) {
- fprintf(stderr, "Usage: tis-curses FILE [STDIN] [STDOUT]\n");
- exit(1);
- }
-
- setlocale(LC_ALL, "");
-
- initscr();
-
- raw();
- noecho();
- keypad(stdscr, TRUE);
- start_color();
- curs_set(0);
- tui_resize();
- timeout(TIMEOUT);
- ESCDELAY = 0;
-
- tis_init(&tis);
-
- ifd = inotify_init1(IN_NONBLOCK);
-
- reset(ifd, argc, argv, true);
-
- quit = false;
- while (!quit) {
- len = read(ifd, &event, sizeof(event));
- if (len < 0 && errno != EAGAIN)
- die("inotify_read:");
- if (len >= 0) {
- reset(ifd, argc, argv, true);
- show_reloaded = 1000 / TIMEOUT;
- }
-
- tui_draw();
- key = getch();
- switch (key) {
- case KEY_RESIZE:
- tui_resize();
- break;
- case 'g':
- tui_seek(tpu_sel, MID, MID);
- break;
- case 'h':
- tui_seek(NULL, MID, MID);
- break;
- case 'i':
- if (tis.stdin_port.attached)
- tui_seek(tis.stdin_port.dst_tpu, MID, MID);
- break;
- case 'o':
- if (tis.stdout_port.attached)
- tui_seek(tis.stdout_port.dst_tpu, MID, MID);
- break;
- case 'r':
- reset(ifd, argc, argv, false);
- break;
- case KEY_CTRL('c'):
- quit = true;
- break;
- default:
- handlekey(key);
- break;
- }
- }
-
- tis_deinit(&tis);
-
- close(ifd);
-
- if (tis_stdin) fclose(tis_stdin);
- if (tis_stdout) fclose(tis_stdout);
-
- endwin();
-}