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";
/* 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;
@ -69,7 +70,7 @@ update_display = 1;
static void
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 "};
if (!update_display)
@ -77,8 +78,9 @@ if (!update_display)
update_display = 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 (buf2, "R0:%08X R1:%08X R2:%08X R3:%08X R4:%08X R5:%08X\r\n", R0, R1, R2, R3, R4, R5);
sprintf (buf3, "R6:%08X R7:%08X R8:%08X R9:%08X R10:%08X R11:%08X\r\n", R6, R7, R8, R9, R10, R11);
sprintf (buf2, "PSL: %08X %s\r\n", PSL, "");
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 (1) {
static HANDLE out = NULL;
@ -93,6 +95,7 @@ if (1) {
WriteConsoleA(out, buf1, strlen(buf1), &written, NULL);
WriteConsoleA(out, buf2, strlen(buf2), &written, NULL);
WriteConsoleA(out, buf3, strlen(buf3), &written, NULL);
WriteConsoleA(out, buf4, strlen(buf4), &written, NULL);
SetConsoleCursorPosition (out, info.dwCursorPosition);
}
#else
@ -103,6 +106,7 @@ printf (CSI "H"); /* Position to Top of Screen (1,1) */
printf ("%s", buf1);
printf ("%s", buf2);
printf ("%s", buf3);
printf ("%s", buf4);
printf (CSI "s"); /* Restore Cursor Position */
printf ("\r\n");
#endif
@ -117,7 +121,7 @@ system ("cls");
printf (CSI "H"); /* Position to Top of Screen (1,1) */
printf (CSI "2J"); /* Clear Screen */
#endif
printf ("\n\n\n");
printf ("\n\n\n\n");
printf ("^C to Halt, Commands: BOOT, CONT, EXIT\n");
}
@ -190,8 +194,12 @@ if (!tape) {
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)) {
printf ("Unexpecdted success adding non-existent register 'ZPC'\n");
printf ("Unexpected success adding non-existent register 'ZPC'\n");
goto Done;
}
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());
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)) {
printf ("Error getting register data: %s\n", sim_panel_get_error());
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);
if (reason != SCPE_OK)
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);
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;
val_start = idx;
@ -6351,9 +6356,14 @@ for (rptr = lowr; rptr <= highr; rptr++) {
reason = ex_reg (ofile, val, flag, rptr, highs);
if (reason != SCPE_OK)
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);
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;

View file

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

View file

@ -131,6 +131,7 @@ sim_panel_destroy (PANEL *panel);
access to are described by the application by calling:
sim_panel_add_register
sim_panel_add_register_array
and
sim_panel_add_register_indirect
@ -138,6 +139,7 @@ and
device_name the device this register is part of. Defaults to
the device of the panel (in a device panel) or the
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
receive the data in the simulator's register
addr a pointer to the location of the buffer which will
@ -151,6 +153,14 @@ sim_panel_add_register (PANEL *panel,
size_t size,
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
sim_panel_add_register_indirect (PANEL *panel,
const char *name,