diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-02-24 01:33:45 +0100 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-02-24 01:33:45 +0100 |
| commit | 9f7e70904e6c0fa650323ac5e50ebf6003da333c (patch) | |
| tree | 3015be498d36e8d5c960cf55667c6c825f7de493 /ui/curses/ui.j2.c | |
| parent | 0fb1497a62332e0db45f94b4f195cb37183678cb (diff) | |
Removes usage of Jinja templates
Use CPP to pre-process C files instead
Diffstat (limited to 'ui/curses/ui.j2.c')
| -rw-r--r-- | ui/curses/ui.j2.c | 1386 |
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; -} |
