FRONTPANEL: Added support for a register array to be returned as part of a register set

This commit is contained in:
Mark Pizzolato 2015-04-17 14:46:06 -07:00
parent 04142da99c
commit d75ec66607
4 changed files with 125 additions and 25 deletions

View file

@ -56,7 +56,8 @@ const char *sim_config =
"VAX-PANEL.ini"; "VAX-PANEL.ini";
/* Registers visible on the Front Panel */ /* Registers visible on the Front Panel */
unsigned int PC, SP, FP, AP, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, atPC; unsigned int PC, SP, FP, AP, PSL, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, atPC;
unsigned int PCQ[32];
int update_display = 1; int update_display = 1;
@ -69,7 +70,7 @@ update_display = 1;
static void static void
DisplayRegisters (PANEL *panel) DisplayRegisters (PANEL *panel)
{ {
char buf1[100], buf2[100], buf3[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) if (!update_display)
@ -77,8 +78,9 @@ if (!update_display)
update_display = 0; 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, "%s 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, "%s 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, "R0:%08X R1:%08X R2:%08X R3:%08X R4:%08X R5:%08X\r\n", R0, R1, R2, R3, R4, R5); sprintf (buf2, "PSL: %08X %s\r\n", PSL, "");
sprintf (buf3, "R6:%08X R7:%08X R8:%08X R9:%08X R10:%08X R11:%08X\r\n", R6, R7, R8, R9, R10, R11); sprintf (buf3, "R0:%08X R1:%08X R2:%08X R3:%08X R4:%08X R5:%08X\r\n", R0, R1, R2, R3, R4, R5);
sprintf (buf4, "R6:%08X R7:%08X R8:%08X R9:%08X R10:%08X R11:%08X\r\n", R6, R7, R8, R9, R10, R11);
#if defined(_WIN32) #if defined(_WIN32)
if (1) { if (1) {
static HANDLE out = NULL; static HANDLE out = NULL;
@ -93,6 +95,7 @@ if (1) {
WriteConsoleA(out, buf1, strlen(buf1), &written, NULL); WriteConsoleA(out, buf1, strlen(buf1), &written, NULL);
WriteConsoleA(out, buf2, strlen(buf2), &written, NULL); WriteConsoleA(out, buf2, strlen(buf2), &written, NULL);
WriteConsoleA(out, buf3, strlen(buf3), &written, NULL); WriteConsoleA(out, buf3, strlen(buf3), &written, NULL);
WriteConsoleA(out, buf4, strlen(buf4), &written, NULL);
SetConsoleCursorPosition (out, info.dwCursorPosition); SetConsoleCursorPosition (out, info.dwCursorPosition);
} }
#else #else
@ -103,6 +106,7 @@ printf (CSI "H"); /* Position to Top of Screen (1,1) */
printf ("%s", buf1); printf ("%s", buf1);
printf ("%s", buf2); printf ("%s", buf2);
printf ("%s", buf3); printf ("%s", buf3);
printf ("%s", buf4);
printf (CSI "s"); /* Restore Cursor Position */ printf (CSI "s"); /* Restore Cursor Position */
printf ("\r\n"); printf ("\r\n");
#endif #endif
@ -117,7 +121,7 @@ system ("cls");
printf (CSI "H"); /* Position to Top of Screen (1,1) */ 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"); printf ("\n\n\n\n");
printf ("^C to Halt, Commands: BOOT, CONT, EXIT\n"); printf ("^C to Halt, Commands: BOOT, CONT, EXIT\n");
} }
@ -190,8 +194,12 @@ if (!tape) {
goto Done; goto Done;
} }
if (sim_panel_add_register_array (panel, "PCQ", NULL, sizeof(PCQ)/sizeof(PCQ[0]), sizeof(PCQ[0]), &PCQ)) {
printf ("Error adding register array 'PCQ': %s\n", sim_panel_get_error());
goto Done;
}
if (!sim_panel_add_register (panel, "ZPC", NULL, sizeof(PC), &PC)) { if (!sim_panel_add_register (panel, "ZPC", NULL, sizeof(PC), &PC)) {
printf ("Unexpecdted success adding non-existent register 'ZPC'\n"); printf ("Unexpected success adding non-existent register 'ZPC'\n");
goto Done; goto Done;
} }
if (sim_panel_add_register (panel, "PC", NULL, sizeof(PC), &PC)) { if (sim_panel_add_register (panel, "PC", NULL, sizeof(PC), &PC)) {
@ -262,6 +270,10 @@ if (sim_panel_add_register (panel, "R11", NULL, sizeof(R11), &R11)) {
printf ("Error adding register 'R11': %s\n", sim_panel_get_error()); printf ("Error adding register 'R11': %s\n", sim_panel_get_error());
goto Done; goto Done;
} }
if (sim_panel_add_register (panel, "PSL", NULL, sizeof(PSL), &PSL)) {
printf ("Error adding register 'PSL': %s\n", sim_panel_get_error());
goto Done;
}
if (sim_panel_get_registers (panel, NULL)) { if (sim_panel_get_registers (panel, NULL)) {
printf ("Error getting register data: %s\n", sim_panel_get_error()); printf ("Error getting register data: %s\n", sim_panel_get_error());
goto Done; goto Done;

14
scp.c
View file

@ -6328,9 +6328,14 @@ for (rptr = lowr; rptr <= highr; rptr++) {
reason = ex_reg (ofile, val, flag, rptr, idx-1); reason = ex_reg (ofile, val, flag, rptr, idx-1);
if (reason != SCPE_OK) if (reason != SCPE_OK)
return reason; return reason;
if (sim_log && (ofile == stdout))
ex_reg (sim_log, val, flag, rptr, idx-1);
} }
else else {
Fprintf (ofile, "%s[%d]-%s[%d]: same as above\n", rptr->name, val_start+1, rptr->name, idx-1); Fprintf (ofile, "%s[%d]-%s[%d]: same as above\n", rptr->name, val_start+1, rptr->name, idx-1);
if (sim_log && (ofile == stdout))
Fprintf (sim_log, "%s[%d]-%s[%d]: same as above\n", rptr->name, val_start+1, rptr->name, idx-1);
}
} }
sim_last_val = last_val = val; sim_last_val = last_val = val;
val_start = idx; val_start = idx;
@ -6351,9 +6356,14 @@ for (rptr = lowr; rptr <= highr; rptr++) {
reason = ex_reg (ofile, val, flag, rptr, highs); reason = ex_reg (ofile, val, flag, rptr, highs);
if (reason != SCPE_OK) if (reason != SCPE_OK)
return reason; return reason;
if (sim_log && (ofile == stdout))
ex_reg (sim_log, val, flag, rptr, highs);
} }
else else {
Fprintf (ofile, "%s[%d]-%s[%d]: same as above\n", rptr->name, val_start+1, rptr->name, highs); Fprintf (ofile, "%s[%d]-%s[%d]: same as above\n", rptr->name, val_start+1, rptr->name, highs);
if (sim_log && (ofile == stdout))
Fprintf (sim_log, "%s[%d]-%s[%d]: same as above\n", rptr->name, val_start+1, rptr->name, highs);
}
} }
} }
return SCPE_OK; return SCPE_OK;

View file

@ -118,6 +118,7 @@ typedef struct {
void *addr; void *addr;
size_t size; size_t size;
int indirect; int indirect;
size_t element_count;
} REG; } REG;
struct PANEL { struct PANEL {
@ -134,6 +135,7 @@ struct PANEL {
REG *regs; REG *regs;
char *reg_query; char *reg_query;
size_t reg_query_size; size_t reg_query_size;
unsigned long long array_element_data;
OperationalState State; OperationalState State;
unsigned long long simulation_time; unsigned long long simulation_time;
pthread_mutex_t lock; pthread_mutex_t lock;
@ -358,6 +360,8 @@ pthread_mutex_lock (&panel->io_lock);
buf_needed = 2 + strlen (register_get_prefix); /* SHOW TIME */ buf_needed = 2 + strlen (register_get_prefix); /* SHOW TIME */
for (i=0; i<panel->reg_count; i++) { for (i=0; i<panel->reg_count; i++) {
buf_needed += 9 + strlen (panel->regs[i].name) + (panel->regs[i].device_name ? strlen (panel->regs[i].device_name) : 0); buf_needed += 9 + strlen (panel->regs[i].name) + (panel->regs[i].device_name ? strlen (panel->regs[i].device_name) : 0);
if (panel->regs[i].element_count > 0)
buf_needed += 4 + 6 /* 6 digit register array index */;
if (panel->regs[i].indirect) if (panel->regs[i].indirect)
buf_needed += 12 + strlen (register_ind_echo) + strlen (panel->regs[i].name); buf_needed += 12 + strlen (register_ind_echo) + strlen (panel->regs[i].name);
} }
@ -400,10 +404,18 @@ for (i=j=0; i<panel->reg_count; i++) {
j = 0; j = 0;
*buf_size = buf_needed; *buf_size = buf_needed;
} }
if (panel->regs[i].element_count == 0) {
if (j == 0) if (j == 0)
sprintf (*buf + buf_data, "E -H %s %s", dev, panel->regs[i].name); sprintf (*buf + buf_data, "E -H %s %s", dev, panel->regs[i].name);
else else
sprintf (*buf + buf_data, ",%s", panel->regs[i].name); sprintf (*buf + buf_data, ",%s", panel->regs[i].name);
}
else {
if (j == 0)
sprintf (*buf + buf_data, "E -H %s %s[0:%d]", dev, panel->regs[i].name, panel->regs[i].element_count-1);
else
sprintf (*buf + buf_data, ",%s[0:%d]", panel->regs[i].name, panel->regs[i].element_count-1);
}
++j; ++j;
buf_data += strlen (*buf + buf_data); buf_data += strlen (*buf + buf_data);
} }
@ -863,7 +875,8 @@ _panel_add_register (PANEL *panel,
const char *device_name, const char *device_name,
size_t size, size_t size,
void *addr, void *addr,
int indirect) int indirect,
size_t element_count)
{ {
REG *regs, *reg; REG *regs, *reg;
char *response = NULL; char *response = NULL;
@ -937,9 +950,10 @@ for (i=0; i<panel->reg_count; i++) {
} }
reg->addr = addr; reg->addr = addr;
reg->size = size; reg->size = size;
reg->element_count = element_count;
pthread_mutex_unlock (&panel->io_lock); pthread_mutex_unlock (&panel->io_lock);
/* Validate existence of requested register */ /* Validate existence of requested register/array */
if (_panel_sendf (panel, 1, &response, "EXAMINE %s %s\r", device_name? device_name : "", name)) { if (_panel_sendf (panel, 1, &response, "EXAMINE %s %s%s\r", device_name? device_name : "", name, (element_count > 0) ? "[0]" : "")) {
free (reg->name); free (reg->name);
free (reg->device_name); free (reg->device_name);
free (regs); free (regs);
@ -954,6 +968,23 @@ if (!strcmp ("Invalid argument\r\n", response)) {
return -1; return -1;
} }
free (response); free (response);
if (element_count > 0) {
if (_panel_sendf (panel, 1, &response, "EXAMINE %s %s[%d]\r", device_name? device_name : "", name, element_count-1)) {
free (reg->name);
free (reg->device_name);
free (regs);
return -1;
}
if (!strcmp ("Subscript out of range\r\n", response)) {
sim_panel_set_error ("Invalid Register Array Dimension: %s %s[%d]", device_name? device_name : "", name, element_count-1);
free (response);
free (reg->name);
free (reg->device_name);
free (regs);
return -1;
}
free (response);
}
pthread_mutex_lock (&panel->io_lock); pthread_mutex_lock (&panel->io_lock);
++panel->reg_count; ++panel->reg_count;
free (panel->regs); free (panel->regs);
@ -972,9 +1003,21 @@ sim_panel_add_register (PANEL *panel,
size_t size, size_t size,
void *addr) void *addr)
{ {
return _panel_add_register (panel, name, device_name, size, addr, 0); return _panel_add_register (panel, name, device_name, size, addr, 0, 0);
} }
int
sim_panel_add_register_array (PANEL *panel,
const char *name,
const char *device_name,
size_t element_count,
size_t size,
void *addr)
{
return _panel_add_register (panel, name, device_name, size, addr, 0, element_count);
}
int int
sim_panel_add_register_indirect (PANEL *panel, sim_panel_add_register_indirect (PANEL *panel,
const char *name, const char *name,
@ -982,7 +1025,7 @@ sim_panel_add_register_indirect (PANEL *panel,
size_t size, size_t size,
void *addr) void *addr)
{ {
return _panel_add_register (panel, name, device_name, size, addr, 1); return _panel_add_register (panel, name, device_name, size, addr, 1, 0);
} }
int int
@ -1541,6 +1584,7 @@ while ((p->sock != INVALID_SOCKET) &&
continue; continue;
} }
for (i=0; i<p->reg_count; i++) { for (i=0; i<p->reg_count; i++) {
if (p->regs[i].element_count == 0) {
if (!strcmp(p->regs[i].name, s)) { if (!strcmp(p->regs[i].name, s)) {
unsigned long long data; unsigned long long data;
@ -1552,6 +1596,30 @@ while ((p->sock != INVALID_SOCKET) &&
break; break;
} }
} }
else {
size_t name_len = strlen (p->regs[i].name);
if ((0 == memcmp (p->regs[i].name, s, name_len), s) &&
(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;
}
}
}
if (i != p->reg_count) { if (i != p->reg_count) {
s = eol; s = eol;
while (isspace(0xFF & (*s))) while (isspace(0xFF & (*s)))

View file

@ -131,6 +131,7 @@ sim_panel_destroy (PANEL *panel);
access to are described by the application by calling: access to are described by the application by calling:
sim_panel_add_register sim_panel_add_register
sim_panel_add_register_array
and and
sim_panel_add_register_indirect sim_panel_add_register_indirect
@ -138,6 +139,7 @@ and
device_name the device this register is part of. Defaults to device_name the device this register is part of. Defaults to
the device of the panel (in a device panel) or the the device of the panel (in a device panel) or the
default device in the simulator (usually the CPU). default device in the simulator (usually the CPU).
element_count number of elements in the register array
size the size (in local storage) of the buffer which will size the size (in local storage) of the buffer which will
receive the data in the simulator's register receive the data in the simulator's register
addr a pointer to the location of the buffer which will addr a pointer to the location of the buffer which will
@ -151,6 +153,14 @@ sim_panel_add_register (PANEL *panel,
size_t size, size_t size,
void *addr); void *addr);
int
sim_panel_add_register_array (PANEL *panel,
const char *name,
const char *device_name,
size_t element_count,
size_t size,
void *addr);
int int
sim_panel_add_register_indirect (PANEL *panel, sim_panel_add_register_indirect (PANEL *panel,
const char *name, const char *name,