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
This commit is contained in:
parent
74a80c34bd
commit
33fc5c44e6
3 changed files with 209 additions and 74 deletions
|
@ -83,9 +83,6 @@ DisplayRegisters (PANEL *panel)
|
||||||
char buf1[100], buf2[100], buf3[100], buf4[100];
|
char buf1[100], buf2[100], buf3[100], buf4[100];
|
||||||
static const char *states[] = {"Halt", "Run "};
|
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;
|
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 (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);
|
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 */
|
printf (CSI "2J"); /* Clear Screen */
|
||||||
#endif
|
#endif
|
||||||
printf ("\n\n\n\n");
|
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;
|
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 remote telnet=2226\n");
|
||||||
fprintf (f, "set rem-con debug=XMT;RCV;MODE;REPEAT;CMD\n");
|
fprintf (f, "set rem-con debug=XMT;RCV;MODE;REPEAT;CMD\n");
|
||||||
fprintf (f, "set remote notelnet\n");
|
fprintf (f, "set remote notelnet\n");
|
||||||
|
fprintf (f, "set cpu history=128\n");
|
||||||
}
|
}
|
||||||
fprintf (f, "set cpu autoboot\n");
|
fprintf (f, "set cpu autoboot\n");
|
||||||
fprintf (f, "set cpu 64\n");
|
fprintf (f, "set cpu 64\n");
|
||||||
|
@ -529,6 +527,30 @@ panel = NULL;
|
||||||
return -1;
|
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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -586,10 +608,42 @@ sim_panel_clear_error ();
|
||||||
InitDisplay();
|
InitDisplay();
|
||||||
if (panel_setup())
|
if (panel_setup())
|
||||||
goto Done;
|
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");
|
sim_panel_debug (panel, "Testing with Command interface");
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t i;
|
|
||||||
char cmd[512];
|
char cmd[512];
|
||||||
|
const char *arg;
|
||||||
|
|
||||||
while (sim_panel_get_state (panel) == Halt) {
|
while (sim_panel_get_state (panel) == Halt) {
|
||||||
DisplayRegisters (panel);
|
DisplayRegisters (panel);
|
||||||
|
@ -598,41 +652,55 @@ while (1) {
|
||||||
break;
|
break;
|
||||||
while (strlen(cmd) && isspace(cmd[strlen(cmd)-1]))
|
while (strlen(cmd) && isspace(cmd[strlen(cmd)-1]))
|
||||||
cmd[strlen(cmd)-1] = '\0';
|
cmd[strlen(cmd)-1] = '\0';
|
||||||
while (isspace(cmd[0]))
|
if (match_command ("BOOT", cmd, &arg)) {
|
||||||
memmove (cmd, cmd+1, strlen(cmd));
|
if (sim_panel_exec_boot (panel, arg))
|
||||||
for (i=0; i<strlen(cmd); i++) {
|
|
||||||
if (islower(cmd[i]))
|
|
||||||
cmd[i] = toupper(cmd[i]);
|
|
||||||
}
|
|
||||||
if (!memcmp("BOOT", cmd, 4)) {
|
|
||||||
if (sim_panel_exec_boot (panel, cmd + 4))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!strcmp("STEP", cmd)) {
|
else if (match_command ("BREAK ", cmd, &arg)) {
|
||||||
|
if (sim_panel_break_set (panel, arg))
|
||||||
|
printf("Error Setting Breakpoint '%s': %s\n", arg, sim_panel_get_error ());
|
||||||
|
}
|
||||||
|
else if (match_command ("NOBREAK ", cmd, &arg)) {
|
||||||
|
if (sim_panel_break_clear (panel, arg))
|
||||||
|
printf("Error Clearing Breakpoint '%s': %s\n", arg, sim_panel_get_error ());
|
||||||
|
}
|
||||||
|
else if (match_command ("STEP", cmd, NULL)) {
|
||||||
if (sim_panel_exec_step (panel))
|
if (sim_panel_exec_step (panel))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!strcmp("CONT", cmd)) {
|
else if (match_command ("CONT", cmd, NULL)) {
|
||||||
if (sim_panel_exec_run (panel))
|
if (sim_panel_exec_run (panel))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!strcmp("EXIT", cmd))
|
else if (match_command ("EXAMINE ", cmd, &arg)) {
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if (sim_panel_gen_examine (panel, arg, sizeof (value), &value))
|
||||||
|
printf("Error EXAMINE %s: %s\n", arg, sim_panel_get_error ());
|
||||||
|
else
|
||||||
|
printf("%s: %08X\n", arg, value);
|
||||||
|
}
|
||||||
|
else if (match_command ("HISTORY ", cmd, &arg)) {
|
||||||
|
char history[10240];
|
||||||
|
int count = atoi (arg);
|
||||||
|
|
||||||
|
history[sizeof (history) - 1] = '\0';
|
||||||
|
if (sim_panel_get_history (panel, count, sizeof (history) -1, history))
|
||||||
|
printf("Error retrieving instruction history: %s\n", sim_panel_get_error ());
|
||||||
|
else
|
||||||
|
printf("%s\n", history);
|
||||||
|
}
|
||||||
|
else if ((match_command ("EXIT", cmd, NULL)) || (match_command ("QUIT", cmd, NULL)))
|
||||||
goto Done;
|
goto Done;
|
||||||
else if (!memcmp("BREAK ", cmd, 6)) {
|
|
||||||
if (sim_panel_break_set (panel, cmd + 6))
|
|
||||||
printf("Error Setting Breakpoint '%s': %s\n", cmd + 6, sim_panel_get_error ());
|
|
||||||
}
|
|
||||||
else if (!memcmp("NOBREAK ", cmd, 8)) {
|
|
||||||
if (sim_panel_break_clear (panel, cmd + 8))
|
|
||||||
printf("Error Clearing Breakpoint '%s': %s\n", cmd + 8, sim_panel_get_error ());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
printf ("Huh? %s\r\n", cmd);
|
printf ("Huh? %s\r\n", cmd);
|
||||||
}
|
}
|
||||||
while (sim_panel_get_state (panel) == Run) {
|
while (sim_panel_get_state (panel) == Run) {
|
||||||
usleep (100);
|
usleep (100);
|
||||||
if (update_display)
|
if (update_display) {
|
||||||
|
update_display = 0;
|
||||||
DisplayRegisters(panel);
|
DisplayRegisters(panel);
|
||||||
|
}
|
||||||
if (halt_cpu) {
|
if (halt_cpu) {
|
||||||
halt_cpu = 0;
|
halt_cpu = 0;
|
||||||
sim_panel_exec_halt (panel);
|
sim_panel_exec_halt (panel);
|
||||||
|
|
|
@ -199,7 +199,8 @@ struct PANEL {
|
||||||
* thread attempts to write to the socket.
|
* thread attempts to write to the socket.
|
||||||
* acquired and released in: _panel_send
|
* acquired and released in: _panel_send
|
||||||
* io_command_lock To serialize frontpanel application command requests
|
* io_command_lock To serialize frontpanel application command requests
|
||||||
* acquired and released in: _panel_get_registers, _panel_sendf
|
* acquired and released in: _panel_get_registers,
|
||||||
|
* _panel_sendf_completion
|
||||||
*
|
*
|
||||||
* Condition Var: Sync Mutex: Purpose & Duration:
|
* Condition Var: Sync Mutex: Purpose & Duration:
|
||||||
* io_done io_lock
|
* io_done io_lock
|
||||||
|
@ -1730,6 +1731,43 @@ free (response);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
char *response = NULL;
|
||||||
|
int cmd_stat;
|
||||||
|
|
||||||
|
if (!panel || (panel->State == 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
|
sim_panel_gen_deposit
|
||||||
|
@ -2157,7 +2195,6 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
if (r)
|
if (r)
|
||||||
continue; /* process next line */
|
continue; /* process next line */
|
||||||
}
|
}
|
||||||
if (!p->io_waiting) {
|
|
||||||
if (r) {
|
if (r) {
|
||||||
if (strcmp (s, r->name)) {
|
if (strcmp (s, r->name)) {
|
||||||
unsigned long long data;
|
unsigned long long data;
|
||||||
|
@ -2216,7 +2253,6 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
++s;
|
++s;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
--e;
|
--e;
|
||||||
*e = ':';
|
*e = ':';
|
||||||
/* Unexpected Register Data Found (or other output containing a : character) */
|
/* Unexpected Register Data Found (or other output containing a : character) */
|
||||||
|
@ -2242,6 +2278,7 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
_panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0);
|
_panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0);
|
||||||
--p->io_reg_query_pending;
|
--p->io_reg_query_pending;
|
||||||
p->io_waiting = 0;
|
p->io_waiting = 0;
|
||||||
|
processing_register_output = 0;
|
||||||
pthread_cond_signal (&p->io_done);
|
pthread_cond_signal (&p->io_done);
|
||||||
goto Start_Next_Line;
|
goto Start_Next_Line;
|
||||||
}
|
}
|
||||||
|
@ -2435,6 +2472,8 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
pthread_mutex_lock (&p->io_lock);
|
pthread_mutex_lock (&p->io_lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (p->callback)
|
||||||
|
p->callback (p, p->simulation_time_base + p->simulation_time, p->callback_context);
|
||||||
pthread_mutex_lock (&p->io_lock);
|
pthread_mutex_lock (&p->io_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ extern "C" {
|
||||||
|
|
||||||
#if !defined(__VAX) /* Unsupported platform */
|
#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,
|
const char *name_or_addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *value);
|
void *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
sim_panel_gen_deposit
|
sim_panel_gen_deposit
|
||||||
|
@ -444,6 +445,33 @@ sim_panel_set_register_value (PANEL *panel,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *value);
|
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
|
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.
|
success and -1 for an error.
|
||||||
|
|
||||||
An API which returns an error (-1), will not change the panel state
|
An API which returns an error (-1), will not change the panel state
|
||||||
|
|
Loading…
Add table
Reference in a new issue