aboutsummaryrefslogtreecommitdiff
path: root/ui/curses/ui.j2.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/curses/ui.j2.c')
-rw-r--r--ui/curses/ui.j2.c1386
1 files changed, 0 insertions, 1386 deletions
diff --git a/ui/curses/ui.j2.c b/ui/curses/ui.j2.c
deleted file mode 100644
index 2158eeb..0000000
--- a/ui/curses/ui.j2.c
+++ /dev/null
@@ -1,1386 +0,0 @@
-// Author: Paul Oliver <contact@pauloliver.dev>
-// Project: Salis
-
-// Implements a curses TUI for the Salis simulator.
-// World view renders the contents of the VM memory buffer into a 7 channel image.
-// It supports zooming in and out, condensing the state of several bytes of memory
-// into single pixels (terminal cells). When zoomed in, each pixel represents a
-// single byte in memory.
-
-{% set pane_width = 27 %}
-{% set proc_field_width = 21 %}
-{% set proc_page_lines = 12 %}
-
-{% set log_line_size = 1024 %}
-{% set log_line_count = 1024 %}
-
-{% macro ctrl(x) %}('{{ x }}' & 0x1f){% endmacro %}
-
-{% if not args.optimized %}
- {% set min_fps = 5 %}
- {% set max_fps = 10 %}
-{% else %}
- {% set min_fps = 30 %}
- {% set max_fps = 60 %}
-{% endif %}
-
-// pages
-enum {
- PAGE_CORE,
- PAGE_PROCESS,
- PAGE_WORLD,
- PAGE_IPC,
- PAGE_LOG,
- PAGE_COUNT,
-};
-
-// color pairs
-enum {
- PAIR_NOUSE,
- PAIR_NORMAL,
- PAIR_HEADER,
- PAIR_WARN,
- PAIR_LIVE_PROC,
- PAIR_SELECTED_PROC,
- PAIR_FREE_CELL,
- PAIR_ALLOC_CELL,
- PAIR_MEM_BLOCK_START,
- PAIR_SELECTED_MB1,
- PAIR_SELECTED_MB2,
- PAIR_SELECTED_IP,
- PAIR_SELECTED_SP,
-};
-
-// GFX globals
-uint64_t g_gfx_vsiz; // zoom level
-uint64_t *g_gfx_inst; // instruction channel
-uint64_t *g_gfx_mall; // allocated state channel
-uint64_t *g_gfx_mbst; // memory block start channel
-uint64_t *g_gfx_mb0s; // selected organism's memory block #1 channel
-uint64_t *g_gfx_mb1s; // selected organism's memory block #2 channel
-uint64_t *g_gfx_ipas; // selected organism's IP channel
-uint64_t *g_gfx_spas; // selected organism's SP channel
-
-// TUI globals
-bool g_exit;
-bool g_running;
-unsigned g_core;
-unsigned g_page;
-bool g_proc_genes;
-uint64_t g_proc_scroll;
-uint64_t g_proc_field_scroll;
-uint64_t g_proc_gene_scroll;
-uint64_t g_proc_selected;
-uint64_t g_wrld_pos;
-uint64_t g_wrld_zoom;
-bool g_wcursor_mode;
-int g_wcursor_x;
-int g_wcursor_y;
-uint64_t g_wcursor_pointed;
-uint64_t g_log_cnt;
-unsigned g_log_ptr;
-unsigned g_log_scroll;
-bool g_log_warns[{{ log_line_count }}];
-time_t g_log_times[{{ log_line_count }}];
-char g_logs[{{ log_line_count }}][{{ log_line_size }}];
-uint64_t g_vlin;
-uint64_t g_vsiz;
-uint64_t g_vlin_rng;
-uint64_t g_vsiz_rng;
-uint64_t g_ivpt_scroll;
-char *g_line_buff;
-uint64_t g_step_block;
-
-const wchar_t *g_zoomed_symbols = (
- L"⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟"
- L"⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿"
- L"⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟"
- L"⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿"
-);
-
-// ----------------------------------------------------------------------------
-// GFX functions
-// ----------------------------------------------------------------------------
-void gfx_init(uint64_t vsiz) {
- assert(vsiz);
-
- g_gfx_vsiz = vsiz;
-
- g_gfx_inst = calloc(g_gfx_vsiz, sizeof(uint64_t));
- g_gfx_mall = calloc(g_gfx_vsiz, sizeof(uint64_t));
- g_gfx_mbst = calloc(g_gfx_vsiz, sizeof(uint64_t));
- g_gfx_mb0s = calloc(g_gfx_vsiz, sizeof(uint64_t));
- g_gfx_mb1s = calloc(g_gfx_vsiz, sizeof(uint64_t));
- g_gfx_ipas = calloc(g_gfx_vsiz, sizeof(uint64_t));
- g_gfx_spas = calloc(g_gfx_vsiz, sizeof(uint64_t));
-
- assert(g_gfx_inst);
- assert(g_gfx_mall);
- assert(g_gfx_mbst);
- assert(g_gfx_mb0s);
- assert(g_gfx_mb1s);
- assert(g_gfx_ipas);
- assert(g_gfx_spas);
-}
-
-void gfx_free() {
- if (g_gfx_vsiz == 0) {
- return;
- }
-
- assert(g_gfx_inst);
- assert(g_gfx_mall);
- assert(g_gfx_mbst);
- assert(g_gfx_mb0s);
- assert(g_gfx_mb1s);
- assert(g_gfx_ipas);
- assert(g_gfx_spas);
-
- g_gfx_vsiz = 0;
-
- free(g_gfx_inst);
- free(g_gfx_mall);
- free(g_gfx_mbst);
- free(g_gfx_mb0s);
- free(g_gfx_mb1s);
- free(g_gfx_ipas);
- free(g_gfx_spas);
-
- g_gfx_inst = NULL;
- g_gfx_mall = NULL;
- g_gfx_mbst = NULL;
- g_gfx_mb0s = NULL;
- g_gfx_mb1s = NULL;
- g_gfx_ipas = NULL;
- g_gfx_spas = NULL;
-}
-
-void gfx_resize(uint64_t vsiz) {
- assert(vsiz);
-
- gfx_free();
- gfx_init(vsiz);
-}
-
-void gfx_render_inst(const struct Core *core, uint64_t pos, uint64_t zoom) {
- assert(core);
-
- for (uint64_t i = 0; i < g_gfx_vsiz; ++i) {
- g_gfx_inst[i] = 0;
- g_gfx_mall[i] = 0;
-
- for (uint64_t j = 0; j < zoom; ++j) {
- uint64_t addr = pos + (i * zoom) + j;
-
- g_gfx_inst[i] += mvec_get_byte(core, addr);
- g_gfx_mall[i] += mvec_is_alloc(core, addr) ? 1 : 0;
- }
- }
-}
-
-void gfx_clear_array(uint64_t *arry) {
- assert(arry);
- memset(arry, 0, g_gfx_vsiz * sizeof(uint64_t));
-}
-
-{% if arch_vars.mvec_loop %}
-void gfx_accumulate_pixel(uint64_t pos, uint64_t zoom, uint64_t pixa, uint64_t *arry) {
- assert(arry);
-
- uint64_t beg_mod = pos % {{ mvec_size }};
- uint64_t end_mod = beg_mod + (g_gfx_vsiz * zoom);
- uint64_t pix_mod = pixa % {{ mvec_size }};
-
- {% if not args.optimized %}
- uint64_t inc_cnt = 0;
- {% endif %}
-
- while (pix_mod < end_mod) {
- if (pix_mod >= beg_mod && pix_mod < end_mod) {
- uint64_t pixi = (pix_mod - beg_mod) / zoom;
- assert(pixi < g_gfx_vsiz);
- arry[pixi]++;
-
- {% if not args.optimized %}
- inc_cnt++;
- {% endif %}
- }
-
- pix_mod += {{ mvec_size }};
- }
-
- {% if not args.optimized %}
- if (zoom != 1) {
- assert(inc_cnt <= 2);
- }
- {% endif %}
-}
-{% endif %}
-
-{% if not arch_vars.mvec_loop %}
-void gfx_accumulate_pixel(uint64_t pos, uint64_t zoom, uint64_t pixa, uint64_t *arry) {
- assert(arry);
-
- uint64_t end = pos + (g_gfx_vsiz * zoom);
-
- if (pixa < pos || pixa >= end) {
- return;
- }
-
- uint64_t pixi = (pixa - pos) / zoom;
- assert(pixi < g_gfx_vsiz);
- arry[pixi]++;
-}
-{% endif %}
-
-void gfx_render_mbst(const struct Core *core, uint64_t pos, uint64_t zoom) {
- assert(core);
-
- gfx_clear_array(g_gfx_mbst);
-
- for (uint64_t pix = core->pfst; pix <= core->plst; ++pix) {
- uint64_t mb0a = arch_proc_mb0_addr(core, pix);
- uint64_t mb1a = arch_proc_mb1_addr(core, pix);
-
- gfx_accumulate_pixel(pos, zoom, mb0a, g_gfx_mbst);
- gfx_accumulate_pixel(pos, zoom, mb1a, g_gfx_mbst);
- }
-}
-
-void gfx_render_mb0s(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t psel) {
- assert(core);
-
- gfx_clear_array(g_gfx_mb0s);
-
- if (psel < core->pfst || psel > core->plst) {
- return;
- }
-
- uint64_t mb0a = arch_proc_mb0_addr(core, psel);
- uint64_t mb0s = arch_proc_mb0_size(core, psel);
-
- for (uint64_t i = 0; i < mb0s; ++i) {
- gfx_accumulate_pixel(pos, zoom, mb0a + i, g_gfx_mb0s);
- }
-}
-
-void gfx_render_mb1s(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t psel) {
- assert(core);
-
- gfx_clear_array(g_gfx_mb1s);
-
- if (psel < core->pfst || psel > core->plst) {
- return;
- }
-
- uint64_t mb1a = arch_proc_mb1_addr(core, psel);
- uint64_t mb1s = arch_proc_mb1_size(core, psel);
-
- for (uint64_t i = 0; i < mb1s; ++i) {
- gfx_accumulate_pixel(pos, zoom, mb1a + i, g_gfx_mb1s);
- }
-}
-
-void gfx_render_ipas(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t psel) {
- assert(core);
-
- gfx_clear_array(g_gfx_ipas);
-
- if (psel < core->pfst || psel > core->plst) {
- return;
- }
-
- uint64_t ipa = arch_proc_ip_addr(core, psel);
-
- gfx_accumulate_pixel(pos, zoom, ipa, g_gfx_ipas);
-}
-
-void gfx_render_spas(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t psel) {
- assert(core);
-
- gfx_clear_array(g_gfx_spas);
-
- if (psel < core->pfst || psel > core->plst) {
- return;
- }
-
- uint64_t spa = arch_proc_sp_addr(core, psel);
-
- gfx_accumulate_pixel(pos, zoom, spa, g_gfx_spas);
-}
-
-void gfx_render(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t psel) {
- assert(core);
-
- gfx_render_inst(core, pos, zoom);
- gfx_render_mbst(core, pos, zoom);
- gfx_render_mb0s(core, pos, zoom, psel);
- gfx_render_mb1s(core, pos, zoom, psel);
- gfx_render_ipas(core, pos, zoom, psel);
- gfx_render_spas(core, pos, zoom, psel);
-}
-
-// ----------------------------------------------------------------------------
-// TUI generic functions
-// ----------------------------------------------------------------------------
-void ui_line_buff_free() {
- if (g_line_buff) {
- free(g_line_buff);
- }
-
- g_line_buff = NULL;
-}
-
-void ui_line_buff_resize() {
- ui_line_buff_free();
-
- g_line_buff = calloc(COLS + 1, sizeof(char));
-}
-
-void ui_line(bool clear, int line, int color, int attr, const char *format, ...) {
- assert(line >= 0);
- assert(format);
-
- if (line >= LINES) {
- return;
- }
-
- if (clear) {
- move(line, 0);
- clrtoeol();
- }
-
- va_list args;
-
- attron(COLOR_PAIR(color) | attr);
- va_start(args, format);
-
- vsnprintf(g_line_buff, COLS, format, args);
- mvprintw(line, 1, g_line_buff);
-
- va_end(args);
- attroff(COLOR_PAIR(color) | attr);
-}
-
-void ui_clear_line(int l) {
- ui_line(true, l, PAIR_NORMAL, A_NORMAL, "");
-}
-
-void ui_field(int line, int col, int color, int attr, const char *format, ...) {
- assert(line >= 0);
- assert(col >= 0);
- assert(format);
-
- if (line >= LINES || col >= COLS) {
- return;
- }
-
- va_list args;
-
- attron(COLOR_PAIR(color) | attr);
- va_start(args, format);
-
- vsnprintf(g_line_buff, COLS - col, format, args);
- mvprintw(line, col, g_line_buff);
-
- va_end(args);
- attroff(COLOR_PAIR(color) | attr);
-}
-
-void ui_str_field(int l, const char *label, const char *value) {
- assert(label);
- assert(value);
- ui_line(false, l, PAIR_NORMAL, A_NORMAL, "%s : %18s", label, value);
-}
-
-void ui_ulx_field(int l, const char *label, uint64_t value) {
- assert(label);
- ui_line(false, l, PAIR_NORMAL, A_NORMAL, "%-4s : %#18lx", label, value);
-}
-
-// ----------------------------------------------------------------------------
-// Core page functions
-// ----------------------------------------------------------------------------
-void ui_print_core(int l) {
- ui_line(false, ++l, PAIR_HEADER, A_BOLD, "CORE [%d]", g_core);
- ui_ulx_field(++l, "cycl", g_cores[g_core].cycl);
- ui_ulx_field(++l, "mall", g_cores[g_core].mall);
- ui_ulx_field(++l, "mut0", g_cores[g_core].muta[0]);
- ui_ulx_field(++l, "mut1", g_cores[g_core].muta[1]);
- ui_ulx_field(++l, "mut2", g_cores[g_core].muta[2]);
- ui_ulx_field(++l, "mut3", g_cores[g_core].muta[3]);
- ui_ulx_field(++l, "pnum", g_cores[g_core].pnum);
- ui_ulx_field(++l, "pcap", g_cores[g_core].pcap);
- ui_ulx_field(++l, "pfst", g_cores[g_core].pfst);
- ui_ulx_field(++l, "plst", g_cores[g_core].plst);
- ui_ulx_field(++l, "pcur", g_cores[g_core].pcur);
- ui_ulx_field(++l, "psli", g_cores[g_core].psli);
- ui_ulx_field(++l, "ivpt", g_cores[g_core].ivpt);
-
- ++l;
-
- {% if arch_vars.core_fields|length %}
- ui_line(false, ++l, PAIR_HEADER, A_BOLD, "ARCH SPECIFIC");
- {% for type, name, print in arch_vars.core_fields if print %}
- {% if type == "uint64_t" %}
- ui_ulx_field(++l, "{{ name }}", g_cores[g_core].{{ name }});
- {% endif %}
- {% endfor %}
- {% endif %}
-}
-
-// ----------------------------------------------------------------------------
-// Process page functions
-// ----------------------------------------------------------------------------
-int ui_proc_pair(uint64_t pix) {
- if (pix == g_proc_selected) {
- return PAIR_SELECTED_PROC;
- } else if (mvec_proc_is_live(&g_cores[g_core], pix)) {
- return PAIR_LIVE_PROC;
- } else {
- return PAIR_NORMAL;
- }
-}
-
-const char *ui_proc_state(uint64_t pix) {
- return mvec_proc_is_live(&g_cores[g_core], pix) ? "live" : "dead";
-}
-
-void ui_print_process_genome_header(int l) {
- ui_line(false, l++, PAIR_NORMAL, A_NORMAL, "%s : %18s : %s", "stat", "pix", "genome");
-}
-
-void ui_print_process_gene(int l, int gcol, uint64_t gidx, uint64_t mba, uint64_t pix, int pair) {
- assert(gcol >= {{ pane_width }} + 2);
- assert(gcol < COLS);
- assert(mvec_proc_is_live(&g_cores[g_core], pix));
- assert(pair == PAIR_SELECTED_MB1 || pair == PAIR_SELECTED_MB2);
-
- const struct Core *core = &g_cores[g_core];
-
- uint64_t addr = mba + gidx;
- uint8_t byte = mvec_get_byte(core, addr);
-
- wchar_t gsym[2] = { arch_symbol(byte), L'\0' };
- cchar_t cchar = { 0 };
-
- int pair_cell;
-
- if (arch_proc_ip_addr(core, pix) == addr) {
- pair_cell = PAIR_SELECTED_IP;
- } else if (arch_proc_sp_addr(core, pix) == addr) {
- pair_cell = PAIR_SELECTED_SP;
- } else {
- pair_cell = pair;
- }
-
- setcchar(&cchar, gsym, 0, pair_cell, NULL);
- mvadd_wch(l, gcol, &cchar);
-}
-
-void ui_print_process_genes(int l, uint64_t pix) {
- ui_line(true, l, ui_proc_pair(pix), A_NORMAL, "%s : %#18lx :", ui_proc_state(pix), pix);
-
- if (!mvec_proc_is_live(&g_cores[g_core], pix)) {
- return;
- }
-
- const struct Core *core = &g_cores[g_core];
-
- int scol = {{ pane_width }} + 2;
- int gcol = scol - g_proc_gene_scroll;
- uint64_t mb0a = arch_proc_mb0_addr(core, pix);
- uint64_t mb0s = arch_proc_mb0_size(core, pix);
- uint64_t mb1a = arch_proc_mb1_addr(core, pix);
- uint64_t mb1s = arch_proc_mb1_size(core, pix);
-
- for (uint64_t gidx = 0; gidx < mb0s && gcol < COLS; ++gidx, ++gcol) {
- if (gcol >= scol) {
- ui_print_process_gene(l, gcol, gidx, mb0a, pix, PAIR_SELECTED_MB1);
- }
- }
-
- for (uint64_t gidx = 0; gidx < mb1s && gcol < COLS; ++gidx, ++gcol) {
- if (gcol >= scol) {
- ui_print_process_gene(l, gcol, gidx, mb1a, pix, PAIR_SELECTED_MB2);
- }
- }
-
- clrtoeol();
-}
-
-void ui_print_process_field_header_element(int l, int fidx, const char *name) {
- assert(fidx >= 0);
- assert(name);
-
- if (fidx < (int)g_proc_field_scroll) {
- return;
- }
-
- int foff = fidx - g_proc_field_scroll;
- int fcol = foff * {{ proc_field_width }} + {{ pane_width }} - 1;
-
- ui_field(l, fcol, PAIR_NORMAL, A_NORMAL, " : %18s", name);
-}
-
-void ui_print_process_field_header(int l) {
- ui_line(true, l, PAIR_NORMAL, A_NORMAL, "%s : %18s", "stat", "pix");
-
- int fidx = 0;
-
- {% for _, val in arch_vars.proc_fields %}
- ui_print_process_field_header_element(l, fidx++, "{{ val }}");
- {% endfor %}
-}
-
-void ui_print_process_field_element(int l, int fidx, int fclr, uint64_t field) {
- assert(fidx >= 0);
-
- if (fidx < (int)g_proc_field_scroll) {
- return;
- }
-
- int foff = fidx - g_proc_field_scroll;
- int fcol = foff * {{ proc_field_width }} + {{ pane_width }} - 1;
-
- ui_field(l, fcol, fclr, A_NORMAL, " : %#18lx", field);
-}
-
-void ui_print_process_fields(int l, uint64_t pix) {
- ui_line(true, l, ui_proc_pair(pix), A_NORMAL, "%s : %#18lx", ui_proc_state(pix), pix);
-
- const struct Proc *proc = proc_get(&g_cores[g_core], pix);
-
- int fidx = 0;
- int fclr = ui_proc_pair(pix);
-
- {% for _, val in arch_vars.proc_fields %}
- ui_print_process_field_element(l, fidx++, fclr, proc->{{ val }});
- {% endfor %}
-}
-
-void ui_print_process(int l) {
- l++;
-
- ui_line(true, l++, PAIR_HEADER, A_BOLD,
- "PROCESS [vs:%#lx | ps:%#lx | pf:%#lx | pl:%#lx | fs:%#lx | gs:%#lx]",
- g_proc_scroll,
- g_proc_selected,
- g_cores[g_core].pfst,
- g_cores[g_core].plst,
- g_proc_field_scroll,
- g_proc_gene_scroll
- );
-
- uint64_t pix = g_proc_scroll;
-
- if (g_proc_genes) {
- ui_print_process_genome_header(l++);
-
- while (l < LINES) {
- ui_print_process_genes(l++, pix++);
- }
- } else {
- ui_print_process_field_header(l++);
-
- while (l < LINES) {
- ui_print_process_fields(l++, pix++);
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-// World page functions
-// ----------------------------------------------------------------------------
-void ui_world_resize() {
- assert(g_wrld_zoom);
-
- g_vlin = 0;
- g_vsiz = 0;
- g_vlin_rng = 0;
- g_vsiz_rng = 0;
-
- if (COLS > {{ pane_width }}) {
- g_vlin = COLS - {{ pane_width }};
- g_vsiz = LINES * g_vlin;
- g_vlin_rng = g_vlin * g_wrld_zoom;
- g_vsiz_rng = g_vsiz * g_wrld_zoom;
-
- gfx_resize(g_vsiz);
- }
-}
-
-{% if arch_vars.mvec_loop %}
-void ui_print_cell(uint64_t i, uint64_t r, uint64_t x, uint64_t y) {
-{% else %}
-void ui_print_cell(uint64_t i, uint64_t r, uint64_t x, uint64_t y, uint64_t a) {
-{% endif %}
- wchar_t inst_nstr[2] = { L'\0', L'\0' };
- cchar_t cchar = { 0 };
- uint64_t inst_avrg = g_gfx_inst[i] / g_wrld_zoom;
-
- if (g_wrld_zoom == 1) {
- inst_nstr[0] = arch_symbol((uint8_t)inst_avrg);
- } else {
- inst_nstr[0] = g_zoomed_symbols[(uint8_t)inst_avrg];
- }
-
- int pair_cell;
-
- {% if arch_vars.mvec_loop %}
- if (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y) {
- {% else %}
- if (a >= {{ mvec_size }} || (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y)) {
- {% endif %}
- pair_cell = PAIR_NORMAL;
- } else if (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y) {
- pair_cell = PAIR_NORMAL;
- } else if (g_gfx_ipas[i] != 0) {
- pair_cell = PAIR_SELECTED_IP;
- } else if (g_gfx_spas[i] != 0) {
- pair_cell = PAIR_SELECTED_SP;
- } else if (g_gfx_mb0s[i] != 0) {
- pair_cell = PAIR_SELECTED_MB1;
- } else if (g_gfx_mb1s[i] != 0) {
- pair_cell = PAIR_SELECTED_MB2;
- } else if (g_gfx_mbst[i] != 0) {
- pair_cell = PAIR_MEM_BLOCK_START;
- } else if (g_gfx_mall[i] != 0) {
- pair_cell = PAIR_ALLOC_CELL;
- } else {
- pair_cell = PAIR_FREE_CELL;
- }
-
- setcchar(&cchar, inst_nstr, 0, pair_cell, NULL);
- mvadd_wch(y, x, &cchar);
-}
-
-void ui_print_wcursor_bar() {
- ui_clear_line(LINES - 1);
-
- const struct Core *core = &g_cores[g_core];
-
- char cownr[{{ proc_field_width }}];
-
- uint64_t cpos = g_vlin * g_wcursor_y + g_wcursor_x;
- uint64_t caddr = cpos * g_wrld_zoom + g_wrld_pos;
- uint8_t cbyte = mvec_get_byte(core, caddr);
-
- if (mvec_is_alloc(core, caddr)) {
- g_wcursor_pointed = mvec_get_owner(core, caddr);
- snprintf(cownr, {{ proc_field_width }}, "%#lx", g_wcursor_pointed);
- } else {
- g_wcursor_pointed = (uint64_t)(-1);
- snprintf(cownr, {{ proc_field_width }}, "-");
- }
-
- mvprintw(
- LINES - 1,
- 1,
- "cursor | x:%#x | y:%#x | addr:%#lx | isum:%#lx | iavr:%#lx | mall:%#lx | mbst:%#lx | mnem:<%s> | ownr:%s",
- g_wcursor_x,
- g_wcursor_y,
- caddr,
- g_gfx_inst[cpos],
- g_gfx_inst[cpos] / g_wrld_zoom,
- g_gfx_mall[cpos],
- g_gfx_mbst[cpos],
- arch_mnemonic(cbyte),
- cownr
- );
-}
-
-void ui_print_world(int l) {
- l++;
-
- ui_line(false, l++, PAIR_HEADER, A_BOLD, "WORLD");
- ui_ulx_field(l++, "wrlp", g_wrld_pos);
- ui_ulx_field(l++, "wrlz", g_wrld_zoom);
- ui_ulx_field(l++, "psel", g_proc_selected);
- ui_ulx_field(l++, "pabs", g_proc_selected % g_cores[g_core].pcap);
- ui_ulx_field(l++, "vrng", g_vsiz_rng);
- ui_str_field(l++, "curs", g_wcursor_mode ? "on" : "off");
-
- l++;
-
- ui_line(false, l++, PAIR_HEADER, A_BOLD, "SELECTED");
-
- const struct Proc *psel = proc_get(&g_cores[g_core], g_proc_selected);
-
- {% for _, val in arch_vars.proc_fields %}
- ui_ulx_field(l++, "{{ val }}", psel->{{ val }});
- {% endfor %}
-
- if (!g_vlin) {
- return;
- }
-
- gfx_render(&g_cores[g_core], g_wrld_pos, g_wrld_zoom, g_proc_selected);
-
- if (g_wcursor_mode) {
- int xmax = g_vlin - 1;
- int ymax = LINES - 2;
-
- g_wcursor_x = (g_wcursor_x < xmax) ? g_wcursor_x : xmax;
- g_wcursor_y = (g_wcursor_y < ymax) ? g_wcursor_y : ymax;
- }
-
- for (uint64_t i = 0; i < g_vsiz; ++i) {
- uint64_t r = i % g_vlin;
- uint64_t x = r + {{ pane_width }};
- uint64_t y = i / g_vlin;
-
- {% if arch_vars.mvec_loop %}
- ui_print_cell(i, r, x, y);
- {% else %}
- uint64_t a = g_wrld_pos + (i * g_wrld_zoom);
-
- ui_print_cell(i, r, x, y, a);
- {% endif %}
- }
-
- if (g_wcursor_mode) {
- ui_print_wcursor_bar();
- }
-}
-
-// ----------------------------------------------------------------------------
-// IPC page functions
-// ----------------------------------------------------------------------------
-void ui_print_ipc_field(int l, uint64_t i, int color) {
- uint8_t iinst = g_cores[g_core].iviv[i];
- uint64_t iaddr = g_cores[g_core].ivav[i];
-
- ui_field(l, {{ pane_width }}, color, A_NORMAL, "%#18x : %#18x : %#18x", i, iinst, iaddr);
-}
-
-void ui_print_ipc_data() {
- ui_field(0, {{ pane_width }}, PAIR_NORMAL, A_NORMAL, "%18s : %18s : %18s", "ipci", "inst", "addr");
-
- int l = 1 - g_ivpt_scroll;
-
- for (uint64_t i = 0; i < {{ sync_interval }}; ++i) {
- if (i == g_cores[g_core].ivpt) {
- if (l >= 1) {
- ui_print_ipc_field(l++, i, PAIR_SELECTED_PROC);
- }
-
- continue;
- }
-
- uint8_t iinst = g_cores[g_core].iviv[i];
-
- if ((iinst & {{ ipc_flag }}) != 0) {
- if (l >= 1) {
- ui_print_ipc_field(l++, i, PAIR_LIVE_PROC);
- }
-
- continue;
- }
- }
-
- for (; l < LINES; ++l) {
- if (l >= 1) {
- move(l, {{ pane_width }});
- clrtoeol();
- }
- }
-}
-
-void ui_print_ipc(int l) {
- l++;
-
- const struct Core *core = &g_cores[g_core];
-
- ui_line(true, l++, PAIR_HEADER, A_BOLD, "IPC [%#lx]", g_ivpt_scroll);
- ui_ulx_field(l++, "ivpt", core->ivpt);
- ui_ulx_field(l++, "ivpi", core->iviv[core->ivpt]);
- ui_ulx_field(l++, "ivpa", core->ivav[core->ivpt]);
-
- ui_print_ipc_data();
-}
-
-// ----------------------------------------------------------------------------
-// Log page functions
-// ----------------------------------------------------------------------------
-void ui_info_impl(const char *format, ...) {
- g_log_warns[g_log_ptr] = false;
- g_log_times[g_log_ptr] = time(NULL);
-
- va_list args;
- va_start(args, format);
- vsnprintf(g_logs[g_log_ptr], {{ log_line_size }}, format, args);
- va_end(args);
-
- g_log_cnt++;
- g_log_ptr = (g_log_ptr + 1) % {{ log_line_count }};
-}
-
-void ui_warn_impl(const char *format, ...) {
- g_log_warns[g_log_ptr] = true;
- g_log_times[g_log_ptr] = time(NULL);
-
- va_list args;
- va_start(args, format);
- vsnprintf(g_logs[g_log_ptr], {{ log_line_size }}, format, args);
- va_end(args);
-
- g_log_cnt++;
- g_log_ptr = (g_log_ptr + 1) % {{ log_line_count }};
-}
-
-void ui_clear_log_line(int line) {
- assert(line >= 0 && line < LINES);
- move(line, {{ pane_width }});
- clrtoeol();
-}
-
-void ui_print_log_line(unsigned lptr, int line) {
- assert(lptr < {{ log_line_count }});
- assert(line >= 0 && line < LINES);
- ui_clear_log_line(line);
-
- // Prints a log entry
- if (strlen(g_logs[lptr])) {
- struct tm tm = *localtime(&g_log_times[lptr]);
-
- // Timestamp
- ui_field(
- line,
- {{ pane_width }},
- PAIR_NORMAL,
- A_NORMAL,
- ": %d-%02d-%02d %02d:%02d:%02d",
- tm.tm_year + 1900,
- tm.tm_mon + 1,
- tm.tm_mday,
- tm.tm_hour,
- tm.tm_min,
- tm.tm_sec
- );
-
- // Level
- ui_field(
- line,
- {{ pane_width }} + 22,
- g_log_warns[lptr] ? PAIR_WARN : PAIR_HEADER,
- A_NORMAL,
- g_log_warns[lptr] ? "WARN:" : "INFO:"
- );
-
- // Message
- ui_field(
- line,
- {{ pane_width }} + 28,
- PAIR_NORMAL,
- A_NORMAL,
- g_logs[lptr]
- );
- }
-}
-
-void ui_print_log(int l) {
- l++;
-
- ui_line(true, l++, PAIR_HEADER, A_BOLD, "LOG");
- ui_ulx_field(l++, "lscr", g_log_scroll);
- ui_ulx_field(l++, "lcnt", g_log_cnt);
- ui_ulx_field(l++, "lptr", g_log_ptr);
-
- unsigned lptr = g_log_ptr;
- int line = LINES + g_log_scroll;
-
- while (line) {
- lptr = (lptr - 1 + {{ log_line_count }}) % {{ log_line_count }};
- line--;
-
- if (line < LINES) {
- ui_print_log_line(lptr, line);
- }
-
- if (lptr == g_log_ptr) {
- break;
- }
- }
-
- while (line) {
- line--;
- ui_clear_log_line(line);
- }
-}
-
-// ----------------------------------------------------------------------------
-// Main print function
-// ----------------------------------------------------------------------------
-void ui_print() {
- int l = 1;
-
- ui_line(false, l++, PAIR_HEADER, A_BOLD, "SALIS [%d:%d]", g_core, {{ args.cores }});
- ui_str_field(l++, "name", "{{ args.name }}");
- ui_ulx_field(l++, "seed", {{ args.seed }});
- ui_str_field(l++, "fbit", "{{ "yes" if args.muta_flip else "no" }}");
- ui_ulx_field(l++, "asav", {{ auto_save_interval }});
- ui_str_field(l++, "arch", "{{ args.arch }}");
- ui_ulx_field(l++, "size", {{ mvec_size }});
- ui_ulx_field(l++, "syni", {{ sync_interval }});
- ui_ulx_field(l++, "step", g_steps);
- ui_ulx_field(l++, "sync", g_syncs);
- ui_ulx_field(l++, "step", g_step_block);
-
- switch (g_page) {
- case PAGE_CORE:
- ui_print_core(l);
- break;
- case PAGE_PROCESS:
- ui_print_process(l);
- break;
- case PAGE_WORLD:
- ui_print_world(l);
- break;
- case PAGE_IPC:
- ui_print_ipc(l);
- break;
- case PAGE_LOG:
- ui_print_log(l);
- break;
- default:
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-// Control function
-// ----------------------------------------------------------------------------
-void ev_vscroll(int ev) {
- switch (g_page) {
- case PAGE_PROCESS:
- switch (ev) {
- case 'W':
- g_proc_scroll += (LINES > {{ proc_page_lines }}) ? LINES - {{ proc_page_lines }} : 0;
- break;
- case 'S':
- g_proc_scroll -= (LINES > {{ proc_page_lines }}) ? LINES - {{ proc_page_lines }} : 0;
- break;
- case 'w':
- g_proc_scroll += 1;
- break;
- case 's':
- g_proc_scroll -= 1;
- break;
- case 'q':
- g_proc_scroll = 0;
- break;
- default:
- break;
- }
-
- break;
- case PAGE_WORLD: {
- switch (ev) {
- case 'W':
- g_wrld_pos += g_vsiz_rng;
- break;
- case 'S':
- g_wrld_pos -= g_vsiz_rng;
- break;
- case 'w':
- g_wrld_pos += g_vlin_rng;
- break;
- case 's':
- {% if arch_vars.mvec_loop %}
- g_wrld_pos -= g_vlin_rng;
- {% else %}
- if (g_wrld_pos < g_vlin_rng) {
- g_wrld_pos = 0;
- } else {
- g_wrld_pos -= g_vlin_rng;
- }
- {% endif %}
- break;
- case 'q':
- g_wrld_pos = 0;
- break;
- default:
- break;
- }
-
- break;
- }
- case PAGE_IPC:
- switch (ev) {
- case 'W':
- g_ivpt_scroll += LINES;
- break;
- case 'S':
- g_ivpt_scroll -= g_ivpt_scroll < (uint64_t)LINES ? g_ivpt_scroll : (uint64_t)LINES;
- break;
- case 'w':
- g_ivpt_scroll += 1;
- break;
- case 's':
- g_ivpt_scroll -= g_ivpt_scroll ? 1 : 0;
- break;
- case 'q':
- g_ivpt_scroll = 0;
- break;
- }
-
- break;
- case PAGE_LOG:
- switch (ev) {
- case 'W':
- g_log_scroll += LINES;
- g_log_scroll = g_log_scroll >= {{ log_line_count }} ? {{ log_line_count }} - 1 : g_log_scroll;
- break;
- case 'S':
- g_log_scroll -= g_log_scroll < (uint64_t)LINES ? g_log_scroll : (uint64_t)LINES;
- break;
- case 'w':
- g_log_scroll += 1;
- g_log_scroll = g_log_scroll >= {{ log_line_count }} ? {{ log_line_count }} - 1 : g_log_scroll;
- break;
- case 's':
- g_log_scroll -= g_log_scroll ? 1 : 0;
- break;
- case 'q':
- g_log_scroll = 0;
- break;
- }
-
- break;
- default:
- break;
- }
-}
-
-void ev_hscroll(int ev) {
- switch (g_page) {
- case PAGE_PROCESS: {
- uint64_t *hs_var = g_proc_genes ? &g_proc_gene_scroll : &g_proc_field_scroll;
-
- switch (ev) {
- case 'A':
- *hs_var = 0;
- break;
- case 'a':
- *hs_var -= *hs_var ? 1 : 0;
- break;
- case 'd':
- (*hs_var)++;
- break;
- default:
- break;
- }
-
- break;
- }
-
- case PAGE_WORLD:
- switch (ev) {
- case 'a':
- {% if arch_vars.mvec_loop %}
- g_wrld_pos -= g_wrld_zoom;
- {% else %}
- if (g_wrld_pos < g_wrld_zoom) {
- g_wrld_pos = 0;
- } else {
- g_wrld_pos -= g_wrld_zoom;
- }
- {% endif %}
- break;
- case 'd':
- g_wrld_pos += g_wrld_zoom;
- break;
- default:
- break;
- }
-
- break;
- default:
- break;
- }
-}
-
-void ev_zoom(int ev) {
- switch (g_page) {
- case PAGE_WORLD:
- switch (ev) {
- case 'x':
- g_wrld_zoom *= (g_vlin != 0 && g_vsiz_rng < {{ mvec_size }}) ? 2 : 1;
- ui_world_resize();
- break;
- case 'z':
- g_wrld_zoom /= (g_wrld_zoom != 1) ? 2 : 1;
- ui_world_resize();
- break;
- default:
- break;
- }
-
- break;
- default:
- break;
- }
-}
-
-void ev_move_wcursor(int ev) {
- switch (ev) {
- case KEY_UP:
- g_wcursor_y -= (g_wcursor_y != 0) ? 1 : 0;
- break;
- case KEY_DOWN:
- g_wcursor_y += (g_wcursor_y < LINES - 2) ? 1 : 0;
- break;
- case KEY_LEFT:
- g_wcursor_x -= (g_wcursor_x != 0) ? 1 : 0;
- break;
- case KEY_RIGHT:
- g_wcursor_x += ((uint64_t)g_wcursor_x < g_vlin - 1) ? 1 : 0;
- break;
- default:
- break;
- }
-}
-
-void ev_sel_proc(int ev) {
- if (g_page != PAGE_PROCESS && g_page != PAGE_WORLD) {
- return;
- }
-
- switch (ev) {
- case 'o':
- g_proc_selected -= 1;
- break;
- case 'p':
- g_proc_selected += 1;
- break;
- case 'f':
- g_proc_selected = g_cores[g_core].pfst;
- break;
- case 'l':
- g_proc_selected = g_cores[g_core].plst;
- break;
- default:
- break;
- }
-}
-
-void ev_goto_sel_proc() {
- switch (g_page) {
- case PAGE_PROCESS:
- g_proc_scroll = g_proc_selected;
- break;
- case PAGE_WORLD:
- g_wrld_pos = g_cores[g_core].pvec[g_proc_selected % g_cores[g_core].pcap].mb0a;
- break;
- default:
- break;
- }
-}
-
-void ev_handle() {
- int ev = getch();
-
- if (g_page == PAGE_WORLD && g_wcursor_mode) {
- switch (ev) {
- case KEY_UP:
- case KEY_DOWN:
- case KEY_LEFT:
- case KEY_RIGHT:
- ev_move_wcursor(ev);
- return;
- case '\n':
- if (g_wcursor_pointed != (uint64_t)(-1)) {
- g_proc_selected = g_wcursor_pointed;
- }
-
- break;
- default:
- break;
- }
- }
-
- switch (ev) {
- case {{ ctrl('c') }}:
- g_exit = true;
- break;
- case KEY_SLEFT:
- clear();
- g_core = (g_core + {{ args.cores }} - 1) % {{ args.cores }};
- break;
- case KEY_SRIGHT:
- clear();
- g_core = (g_core + 1) % {{ args.cores }};
- break;
- case KEY_LEFT:
- clear();
- g_page = (g_page + PAGE_COUNT - 1) % PAGE_COUNT;
- break;
- case KEY_RIGHT:
- clear();
- g_page = (g_page + 1) % PAGE_COUNT;
- break;
- case KEY_RESIZE:
- clear();
- ui_line_buff_resize();
- ui_world_resize();
-
- if (g_vlin) {
- while (g_vsiz_rng >= {{ mvec_size }} * 2 && g_wrld_zoom != 1) {
- g_wrld_zoom /= 2;
- ui_world_resize();
- }
- }
-
- g_wcursor_mode = false;
- break;
- case 'W':
- case 'S':
- case 'w':
- case 's':
- case 'q':
- ev_vscroll(ev);
- break;
- case 'A':
- case 'a':
- case 'd':
- ev_hscroll(ev);
- break;
- case 'z':
- case 'x':
- ev_zoom(ev);
- break;
- case 'o':
- case 'p':
- case 'f':
- case 'l':
- ev_sel_proc(ev);
- break;
- case 'k':
- ev_goto_sel_proc();
- break;
- case 'g':
- if (g_page == PAGE_PROCESS) {
- clear();
- g_proc_genes = !g_proc_genes;
- }
-
- break;
- case 'c':
- if (g_page == PAGE_WORLD) {
- clear();
-
- if (g_vlin == 0) {
- g_wcursor_mode = false;
- } else {
- g_wcursor_mode = !g_wcursor_mode;
- }
- }
-
- break;
- case ' ':
- g_running = !g_running;
- nodelay(stdscr, g_running);
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '0':
- if (!g_running) {
- uint64_t cycles = 1 << (((ev - '0') ? (ev - '0') : 10) - 1);
- salis_step(cycles);
- }
-
- break;
- default:
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-// Main functions
-// ----------------------------------------------------------------------------
-void init() {
- setlocale(LC_ALL, "");
-
- initscr();
- raw();
- noecho();
- curs_set(0);
- keypad(stdscr, TRUE);
-
- start_color();
- init_color(COLOR_BLACK, 0, 0, 0);
-
- init_pair(PAIR_NORMAL, COLOR_WHITE, COLOR_BLACK );
- init_pair(PAIR_HEADER, COLOR_BLUE, COLOR_BLACK );
- init_pair(PAIR_WARN, COLOR_RED, COLOR_BLACK );
- init_pair(PAIR_LIVE_PROC, COLOR_BLUE, COLOR_BLACK );
- init_pair(PAIR_SELECTED_PROC, COLOR_YELLOW, COLOR_BLACK );
- init_pair(PAIR_FREE_CELL, COLOR_BLACK, COLOR_BLUE );
- init_pair(PAIR_ALLOC_CELL, COLOR_BLACK, COLOR_CYAN );
- init_pair(PAIR_MEM_BLOCK_START, COLOR_BLACK, COLOR_WHITE );
- init_pair(PAIR_SELECTED_MB1, COLOR_BLACK, COLOR_YELLOW );
- init_pair(PAIR_SELECTED_MB2, COLOR_BLACK, COLOR_GREEN );
- init_pair(PAIR_SELECTED_IP, COLOR_BLACK, COLOR_RED );
- init_pair(PAIR_SELECTED_SP, COLOR_BLACK, COLOR_MAGENTA);
-
- // Install loggers
- g_info = ui_info_impl;
- g_warn = ui_warn_impl;
-
- {% if args.command == "new" %}
- salis_init();
- {% elif args.command == "load" %}
- salis_load();
- {% endif %}
-
- g_wrld_zoom = 1;
- g_step_block = 1;
-
- ui_line_buff_resize();
- ui_world_resize();
-}
-
-void exec() {
- while (!g_exit) {
- if (g_running) {
- clock_t beg = clock();
- salis_step(g_step_block - (g_steps % g_step_block));
- clock_t end = clock();
-
- if ((end - beg) < (CLOCKS_PER_SEC / {{ min_fps }})) {
- g_step_block <<= 1;
- }
-
- if ((end - beg) >= (CLOCKS_PER_SEC / {{ max_fps }}) && g_step_block != 1) {
- g_step_block >>= 1;
- }
- }
-
- ui_print();
- ev_handle();
- }
-}
-
-void quit() {
- gfx_free();
- ui_line_buff_free();
- salis_save("{{ sim_path }}");
- salis_free();
- endwin();
-}
-
-int main() {
- init();
- exec();
- quit();
-
- return 0;
-}