FRONTPANEL: Added support for a register array to be returned as part of a register set
This commit is contained in:
parent
04142da99c
commit
d75ec66607
4 changed files with 125 additions and 25 deletions
|
@ -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
14
scp.c
|
@ -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;
|
||||||
|
|
102
sim_frontpanel.c
102
sim_frontpanel.c
|
@ -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 (j == 0)
|
if (panel->regs[i].element_count == 0) {
|
||||||
sprintf (*buf + buf_data, "E -H %s %s", dev, panel->regs[i].name);
|
if (j == 0)
|
||||||
else
|
sprintf (*buf + buf_data, "E -H %s %s", dev, panel->regs[i].name);
|
||||||
sprintf (*buf + buf_data, ",%s", 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;
|
++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,15 +1584,40 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (i=0; i<p->reg_count; i++) {
|
for (i=0; i<p->reg_count; i++) {
|
||||||
if (!strcmp(p->regs[i].name, s)) {
|
if (p->regs[i].element_count == 0) {
|
||||||
unsigned long long data;
|
if (!strcmp(p->regs[i].name, s)) {
|
||||||
|
unsigned long long data;
|
||||||
|
|
||||||
data = strtoull (e, NULL, 16);
|
data = strtoull (e, NULL, 16);
|
||||||
if (little_endian)
|
if (little_endian)
|
||||||
memcpy (p->regs[i].addr, &data, p->regs[i].size);
|
memcpy (p->regs[i].addr, &data, p->regs[i].size);
|
||||||
else
|
else
|
||||||
memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size);
|
memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size);
|
||||||
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) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue