From 33fc5c44e66588e2fde04870f44dc1cbeacce513 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Mon, 18 Dec 2017 15:05:58 -0800 Subject: [PATCH] FRONTPANEL: sim_frontpanel API release 11 - Properly digest all register data when it arrives from register queries and repeat activities. - Invoke register callback functon when transitioning to Halt state. - Add option to access instruction history with sim_panel_get_history API - More interesting testing in FrontPanelTest program --- frontpanel/FrontPanelTest.c | 118 +++++++++++++++++++++++++------- sim_frontpanel.c | 133 +++++++++++++++++++++++------------- sim_frontpanel.h | 32 ++++++++- 3 files changed, 209 insertions(+), 74 deletions(-) diff --git a/frontpanel/FrontPanelTest.c b/frontpanel/FrontPanelTest.c index 0aa80a90..44a093c1 100644 --- a/frontpanel/FrontPanelTest.c +++ b/frontpanel/FrontPanelTest.c @@ -83,9 +83,6 @@ DisplayRegisters (PANEL *panel) char buf1[100], buf2[100], buf3[100], buf4[100]; static const char *states[] = {"Halt", "Run "}; -if (!update_display) - return; -update_display = 0; buf1[sizeof(buf1)-1] = buf2[sizeof(buf2)-1] = buf3[sizeof(buf3)-1] = 0; sprintf (buf1, "%4s PC: %08X SP: %08X AP: %08X FP: %08X @PC: %08X\r\n", states[sim_panel_get_state (panel)], PC, SP, AP, FP, atPC); sprintf (buf2, "PSL: %08X Instructions Executed: %lld\r\n", PSL, simulation_time); @@ -132,7 +129,7 @@ printf (CSI "H"); /* Position to Top of Screen (1,1) */ printf (CSI "2J"); /* Clear Screen */ #endif printf ("\n\n\n\n"); -printf ("^C to Halt, Commands: BOOT, CONT, EXIT, BREAK, NOBREAK\n"); +printf ("^C to Halt, Commands: BOOT, CONT, EXIT, BREAK, NOBREAK, EXAMINE, HISTORY\n"); } volatile int halt_cpu = 0; @@ -159,6 +156,7 @@ if ((f = fopen (sim_config, "w"))) { fprintf (f, "set remote telnet=2226\n"); fprintf (f, "set rem-con debug=XMT;RCV;MODE;REPEAT;CMD\n"); fprintf (f, "set remote notelnet\n"); + fprintf (f, "set cpu history=128\n"); } fprintf (f, "set cpu autoboot\n"); fprintf (f, "set cpu 64\n"); @@ -529,6 +527,30 @@ panel = NULL; return -1; } +int +match_command (const char *command, const char *string, const char **arg) +{ +int match_chars = 0; +size_t i; + +while (isspace (*string)) + ++string; +for (i=0; i < strlen (command); i++) { + if (command[i] == (islower (string[i]) ? toupper (string[i]) : string[i])) + continue; + if (string[i] == '\0') + break; + if ((!isspace (string[i])) || (i == 0)) + return 0; + break; + } +while (isspace (string[i])) + ++i; +if (arg) + *arg = &string[i]; +return (i > 0) && (arg ? 1 : (string[i] == '\0')); +} + int main (int argc, char **argv) { @@ -586,10 +608,42 @@ sim_panel_clear_error (); InitDisplay(); if (panel_setup()) goto Done; +if (sim_panel_break_set (panel, "2004EAD3")) { + printf ("Error establishing breakpoint at test 52 failure path: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004E6EC")) { /* de_programmable_timers.lis line 228 */ + printf ("Error establishing breakpoint at test 52 failure path programmable_timers.lis line 228: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004E7F9")) { /* de_programmable_timers.lis line 228 */ + printf ("Error establishing breakpoint at test 52 failure path programmable_timers.lis line 381: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004E97C")) { /* Error clock failed to tick within at least 100 ms. - line 232 - Subtest 5 */ + printf ("Error establishing breakpoint at Error clock failed to tick within at least 100 ms. - line 232 - Subtest 5: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004E9BB")) { /* Time of year clock is not ticking - line 274 - Subtest 7 */ + printf ("Error establishing breakpoint at Time of year clock is not ticking - line 274 - Subtest 7: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004E9D3")) { /* Time of year clock is not ticking - line 295 - Subtest 8 */ + printf ("Error establishing breakpoint at Time of year clock is not ticking - line 295 - Subtest 8: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004EA2D")) { /* Running Slow - line 359 - Subtest 9 */ + printf ("Error establishing breakpoint at Running Slow - line 359 - Subtest 9: %s\n", sim_panel_get_error()); + goto Done; + } +if (sim_panel_break_set (panel, "2004EA39")) { /* Running Fast - line 366 - Subtest 10 */ + printf ("Error establishing breakpoint at the third test 53 failure path: %s\n", sim_panel_get_error()); + goto Done; + } sim_panel_debug (panel, "Testing with Command interface"); while (1) { - size_t i; char cmd[512]; + const char *arg; while (sim_panel_get_state (panel) == Halt) { DisplayRegisters (panel); @@ -598,41 +652,55 @@ while (1) { break; while (strlen(cmd) && isspace(cmd[strlen(cmd)-1])) cmd[strlen(cmd)-1] = '\0'; - while (isspace(cmd[0])) - memmove (cmd, cmd+1, strlen(cmd)); - for (i=0; iState == Error)) { + sim_panel_set_error (NULL, "Invalid Panel"); + return -1; + } +if (panel->State == Run) { + sim_panel_set_error (NULL, "Not Halted"); + return -1; + } +if (_panel_sendf (panel, &cmd_stat, &response, "SHOW HISTORY=%d", count)) { + free (response); + return -1; + } +strncpy (buffer, response, size); +free (response); +return 0; +} + /** sim_panel_gen_deposit @@ -2157,65 +2195,63 @@ while ((p->sock != INVALID_SOCKET) && if (r) continue; /* process next line */ } - if (!p->io_waiting) { - if (r) { - if (strcmp (s, r->name)) { + if (r) { + if (strcmp (s, r->name)) { + unsigned long long data; + + data = strtoull (e, NULL, 16); + if (little_endian) + memcpy (r->addr, &data, r->size); + else + memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size); + r = NULL; + } + s = eol; + while (isspace(0xFF & (*s))) + ++s; + continue; /* process next line */ + } + for (i=0; ireg_count; i++) { + if (p->regs[i].element_count == 0) { + if (!strcmp(p->regs[i].name, s)) { unsigned long long data; data = strtoull (e, NULL, 16); if (little_endian) - memcpy (r->addr, &data, r->size); + memcpy (p->regs[i].addr, &data, p->regs[i].size); else - memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size); - r = NULL; + memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size); + break; } - s = eol; - while (isspace(0xFF & (*s))) - ++s; - continue; /* process next line */ } - for (i=0; ireg_count; i++) { - if (p->regs[i].element_count == 0) { - if (!strcmp(p->regs[i].name, s)) { - unsigned long long data; + else { + size_t name_len = strlen (p->regs[i].name); - data = strtoull (e, NULL, 16); + if ((0 == memcmp (p->regs[i].name, s, name_len)) && (s[name_len] == '[')) { + size_t array_index = (size_t)atoi (s + name_len + 1); + size_t end_index = array_index; + char *end = strchr (s + name_len + 1, '['); + + if (end) + end_index = (size_t)atoi (end + 1); + if (strcmp (e, " same as above")) + p->array_element_data = strtoull (e, NULL, 16); + while (array_index <= end_index) { if (little_endian) - memcpy (p->regs[i].addr, &data, p->regs[i].size); + memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), &p->array_element_data, p->regs[i].size); else - memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size); - break; - } - } - else { - size_t name_len = strlen (p->regs[i].name); - - if ((0 == memcmp (p->regs[i].name, s, name_len)) && (s[name_len] == '[')) { - size_t array_index = (size_t)atoi (s + name_len + 1); - size_t end_index = array_index; - char *end = strchr (s + name_len + 1, '['); - - if (end) - end_index = (size_t)atoi (end + 1); - if (strcmp (e, " same as above")) - p->array_element_data = strtoull (e, NULL, 16); - while (array_index <= end_index) { - if (little_endian) - memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), &p->array_element_data, p->regs[i].size); - else - memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), ((char *)&p->array_element_data) + sizeof(p->array_element_data)-p->regs[i].size, p->regs[i].size); - ++array_index; - } - break; + memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), ((char *)&p->array_element_data) + sizeof(p->array_element_data)-p->regs[i].size, p->regs[i].size); + ++array_index; } + break; } } - if (i != p->reg_count) { - s = eol; - while (isspace(0xFF & (*s))) - ++s; - continue; - } + } + if (i != p->reg_count) { + s = eol; + while (isspace(0xFF & (*s))) + ++s; + continue; } --e; *e = ':'; @@ -2242,6 +2278,7 @@ while ((p->sock != INVALID_SOCKET) && _panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0); --p->io_reg_query_pending; p->io_waiting = 0; + processing_register_output = 0; pthread_cond_signal (&p->io_done); goto Start_Next_Line; } @@ -2435,6 +2472,8 @@ while ((p->sock != INVALID_SOCKET) && pthread_mutex_lock (&p->io_lock); break; } + if (p->callback) + p->callback (p, p->simulation_time_base + p->simulation_time, p->callback_context); pthread_mutex_lock (&p->io_lock); } } diff --git a/sim_frontpanel.h b/sim_frontpanel.h index f6a52f3a..4ce6fecb 100644 --- a/sim_frontpanel.h +++ b/sim_frontpanel.h @@ -56,7 +56,7 @@ extern "C" { #if !defined(__VAX) /* Unsupported platform */ -#define SIM_FRONTPANEL_VERSION 10 +#define SIM_FRONTPANEL_VERSION 11 /** @@ -349,6 +349,7 @@ sim_panel_gen_examine (PANEL *panel, const char *name_or_addr, size_t size, void *value); + /** sim_panel_gen_deposit @@ -444,6 +445,33 @@ sim_panel_set_register_value (PANEL *panel, const char *name, const char *value); +/** + + A front panel application might want to have access to the + instruction execution history that a simulator may be capable + of providing. If this functionality is desired, enabling of + recording instruction history should be explicitly enabled + in the sim_config file that the simulator is started with. + */ + +/** + + sim_panel_get_history + + count the number of instructions to return + size the size (in local storage) of the buffer which will + receive the data returned when examining the simulator + buffer a pointer to the buffer which will be loaded with the + instruction history returned from the simulator + */ + +int +sim_panel_get_history (PANEL *panel, + int count, + size_t size, + char *buffer); + + /** When a front panel application needs to change the media @@ -495,7 +523,7 @@ sim_panel_get_state (PANEL *panel); /** - All APIs routines which return an int return 0 for + All API routines which return an int return 0 for success and -1 for an error. An API which returns an error (-1), will not change the panel state