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";
|
||||
|
||||
/* 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
14
scp.c
|
@ -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;
|
||||
|
|
102
sim_frontpanel.c
102
sim_frontpanel.c
|
@ -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 (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);
|
||||
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,15 +1584,40 @@ while ((p->sock != INVALID_SOCKET) &&
|
|||
continue;
|
||||
}
|
||||
for (i=0; i<p->reg_count; i++) {
|
||||
if (!strcmp(p->regs[i].name, s)) {
|
||||
unsigned long long data;
|
||||
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 (p->regs[i].addr, &data, p->regs[i].size);
|
||||
else
|
||||
memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size);
|
||||
break;
|
||||
data = strtoull (e, NULL, 16);
|
||||
if (little_endian)
|
||||
memcpy (p->regs[i].addr, &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) &&
|
||||
(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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue