1
0
mirror of https://github.com/simh/simh.git synced 2026-01-11 23:52:58 +00:00

FRONTPANEL: Merged simulator panel and device panel constructors.

This commit is contained in:
Mark Pizzolato 2015-02-26 12:13:56 -08:00
parent 71fe58b33a
commit 8c0fc33b2e

View File

@ -445,108 +445,125 @@ for (i=0; i<panel_count; i++) {
}
PANEL *
sim_panel_start_simulator (const char *sim_path,
const char *sim_config,
size_t device_panel_count)
{
return sim_panel_start_simulator_debug (sim_path, sim_config, device_panel_count, NULL);
}
PANEL *
sim_panel_start_simulator_debug (const char *sim_path,
const char *sim_config,
size_t device_panel_count,
const char *debug_file)
static PANEL *
_sim_panel_create (const char *sim_path,
const char *sim_config,
size_t device_panel_count,
PANEL *simulator_panel,
const char *device_name,
const char *debug_file)
{
PANEL *p = NULL;
FILE *fIn = NULL;
FILE *fOut = NULL;
struct stat statb;
char *buf = NULL;
int port, i;
int port;
size_t i, device_num;
char hostport[64];
union {int i; char c[sizeof (int)]; } end_test;
end_test.i = 1; /* test endian-ness */
little_endian = (end_test.c[0] != 0);
sim_init_sock ();
for (port=1024; port < 2048; port++) {
SOCKET sock;
sprintf (hostport, "%d", port);
sock = sim_connect_sock_ex (NULL, hostport, NULL, NULL, SIM_SOCK_OPT_NODELAY | SIM_SOCK_OPT_BLOCKING);
if (sock != INVALID_SOCKET) {
int sta = 0;
while (!sta) {
msleep (10);
sta = sim_check_conn (sock, 1);
}
sim_close_sock (sock);
if (sta == -1)
if (simulator_panel) {
for (device_num=0; device_num < simulator_panel->device_count; ++device_num)
if (simulator_panel->devices[device_num] == NULL)
break;
if (device_num == simulator_panel->device_count) {
sim_panel_set_error ("No free panel devices slots available %s simulator. All %d slots are used.", simulator_panel->path, (int)simulator_panel->device_count);
return NULL;
}
else
break;
p = (PANEL *)_panel_malloc (sizeof(*p));
if (p == NULL)
goto Error_Return;
memset (p, 0, sizeof(*p));
p->device_name = (char *)_panel_malloc (1 + strlen (device_name));
if (p->device_name == NULL)
goto Error_Return;
strcpy (p->device_name, device_name);
p->parent = simulator_panel;
strcpy (p->hostport, simulator_panel->hostport);
p->sock = INVALID_SOCKET;
}
if (stat (sim_config, &statb) < 0) {
sim_panel_set_error ("Can't stat simulator configuration '%s': %s", sim_config, strerror(errno));
goto Error_Return;
else {
end_test.i = 1; /* test endian-ness */
little_endian = (end_test.c[0] != 0);
sim_init_sock ();
for (port=1024; port < 2048; port++) {
SOCKET sock;
sprintf (hostport, "%d", port);
sock = sim_connect_sock_ex (NULL, hostport, NULL, NULL, SIM_SOCK_OPT_NODELAY | SIM_SOCK_OPT_BLOCKING);
if (sock != INVALID_SOCKET) {
int sta = 0;
while (!sta) {
msleep (10);
sta = sim_check_conn (sock, 1);
}
sim_close_sock (sock);
if (sta == -1)
break;
}
else
break;
}
if (stat (sim_config, &statb) < 0) {
sim_panel_set_error ("Can't stat simulator configuration '%s': %s", sim_config, strerror(errno));
goto Error_Return;
}
buf = (char *)_panel_malloc (statb.st_size+1);
if (buf == NULL)
goto Error_Return;
buf[statb.st_size] = '\0';
p = (PANEL *)_panel_malloc (sizeof(*p));
if (p == NULL)
goto Error_Return;
memset (p, 0, sizeof(*p));
p->sock = INVALID_SOCKET;
p->path = (char *)_panel_malloc (strlen (sim_path) + 1);
if (p->path == NULL)
goto Error_Return;
strcpy (p->path, sim_path);
p->config = (char *)_panel_malloc (strlen (sim_config) + 1);
if (p->config == NULL)
goto Error_Return;
strcpy (p->config, sim_config);
fIn = fopen (sim_config, "r");
if (fIn == NULL) {
sim_panel_set_error ("Can't open configuration file '%s': %s", sim_config, strerror(errno));
goto Error_Return;
}
p->temp_config = (char *)_panel_malloc (strlen (sim_config) + 40);
if (p->temp_config == NULL)
goto Error_Return;
sprintf (p->temp_config, "%s-Panel-%d", sim_config, getpid());
fOut = fopen (p->temp_config, "w");
if (fOut == NULL) {
sim_panel_set_error ("Can't create temporary configuration file '%s': %s", p->temp_config, strerror(errno));
goto Error_Return;
}
fprintf (fOut, "# Temporary FrontPanel generated simh configuration file\n");
fprintf (fOut, "# Original Configuration File: %s\n", p->config);
fprintf (fOut, "# Simulator Path: %s\n", sim_path);
while (fgets (buf, statb.st_size, fIn))
fputs (buf, fOut);
free (buf);
buf = NULL;
fclose (fIn);
fIn = NULL;
fprintf (fOut, "set remote notelnet\n");
if (device_panel_count)
fprintf (fOut, "set remote connections=%d\n", (int)device_panel_count+1);
fprintf (fOut, "set remote -u telnet=%s\n", hostport);
fprintf (fOut, "set remote master\n");
fclose (fOut);
fOut = NULL;
}
buf = (char *)_panel_malloc (statb.st_size+1);
if (buf == NULL)
goto Error_Return;
buf[statb.st_size] = '\0';
p = (PANEL *)_panel_malloc (sizeof(*p));
if (p == NULL)
goto Error_Return;
memset (p, 0, sizeof(*p));
p->sock = INVALID_SOCKET;
p->path = (char *)_panel_malloc (strlen (sim_path) + 1);
if (p->path == NULL)
goto Error_Return;
strcpy (p->path, sim_path);
p->config = (char *)_panel_malloc (strlen (sim_config) + 1);
if (p->config == NULL)
goto Error_Return;
strcpy (p->config, sim_config);
fIn = fopen (sim_config, "r");
if (fIn == NULL) {
sim_panel_set_error ("Can't open configuration file '%s': %s", sim_config, strerror(errno));
goto Error_Return;
}
p->temp_config = (char *)_panel_malloc (strlen (sim_config) + 40);
if (p->temp_config == NULL)
goto Error_Return;
sprintf (p->temp_config, "%s-Panel-%d", sim_config, getpid());
fOut = fopen (p->temp_config, "w");
if (fOut == NULL) {
sim_panel_set_error ("Can't create temporary configuration file '%s': %s", p->temp_config, strerror(errno));
goto Error_Return;
}
fprintf (fOut, "# Temporary FrontPanel generated simh configuration file\n");
fprintf (fOut, "# Original Configuration File: %s\n", p->config);
fprintf (fOut, "# Simulator Path: %s\n", sim_path);
while (fgets (buf, statb.st_size, fIn))
fputs (buf, fOut);
free (buf);
buf = NULL;
fclose (fIn);
fIn = NULL;
fprintf (fOut, "set remote notelnet\n");
if (device_panel_count)
fprintf (fOut, "set remote connections=%d\n", (int)device_panel_count+1);
fprintf (fOut, "set remote -u telnet=%s\n", hostport);
fprintf (fOut, "set remote master\n");
fclose (fOut);
fOut = NULL;
if (debug_file) {
sim_panel_set_debug_file (p, debug_file);
sim_panel_set_debug_mode (p, DBG_XMT|DBG_RCV);
_panel_debug (p, DBG_XMT|DBG_RCV, "Creating Simulator Process %s\n", NULL, 0, sim_path);
}
if (1) {
if (!simulator_panel) {
#if defined(_WIN32)
char cmd[2048];
PROCESS_INFORMATION ProcessInfo;
@ -584,23 +601,28 @@ if (1) {
goto Error_Return;
}
#endif
strcpy (p->hostport, hostport);
}
for (i=0; i<100; i++) { /* Allow up to 10 seconds waiting for simulator to start up */
p->sock = sim_connect_sock_ex (NULL, hostport, NULL, NULL, SIM_SOCK_OPT_NODELAY | SIM_SOCK_OPT_BLOCKING);
p->sock = sim_connect_sock_ex (NULL, p->hostport, NULL, NULL, SIM_SOCK_OPT_NODELAY | SIM_SOCK_OPT_BLOCKING);
if (p->sock == INVALID_SOCKET)
msleep (100);
else
break;
}
if (p->sock == INVALID_SOCKET) {
if (stat (sim_path, &statb) < 0)
sim_panel_set_error ("Can't stat simulator '%s': %s", sim_path, strerror(errno));
else
sim_panel_set_error ("Can't connect to simulator Remote Console on port %s", hostport);
if (simulator_panel) {
sim_panel_set_error ("Can't connect to simulator Remote Console on port %s", p->hostport);
}
else {
if (stat (sim_path, &statb) < 0)
sim_panel_set_error ("Can't stat simulator '%s': %s", sim_path, strerror(errno));
else
sim_panel_set_error ("Can't connect to simulator Remote Console on port %s", p->hostport);
}
goto Error_Return;
}
strcpy (p->hostport, hostport);
_panel_debug (p, DBG_XMT|DBG_RCV, "Connected to simulator at %s after %dms\n", NULL, 0, hostport, i*100);
_panel_debug (p, DBG_XMT|DBG_RCV, "Connected to simulator at %s after %dms\n", NULL, 0, p->hostport, i*100);
pthread_mutex_init (&p->io_lock, NULL);
pthread_mutex_init (&p->io_send_lock, NULL);
pthread_cond_init (&p->io_done, NULL);
@ -622,26 +644,30 @@ if (1) {
pthread_mutex_unlock (&p->io_lock);
pthread_cond_destroy (&p->startup_cond);
}
if (device_panel_count) {
p->devices = (PANEL **)_panel_malloc (device_panel_count*sizeof(*p->devices));
if (p->devices == NULL)
if (simulator_panel) {
simulator_panel->devices[device_num] = p;
}
else {
if (device_panel_count) {
p->devices = (PANEL **)_panel_malloc (device_panel_count*sizeof(*p->devices));
if (p->devices == NULL)
goto Error_Return;
memset (p->devices, 0, device_panel_count*sizeof(*p->devices));
p->device_count = device_panel_count;
}
/* Validate sim_frontpanel API version */
if (_panel_sendf (p, 1, &p->simulator_version, "SHOW VERSION\r"))
goto Error_Return;
memset (p->devices, 0, device_panel_count*sizeof(*p->devices));
p->device_count = device_panel_count;
}
/* Validate sim_frontpanel API version */
if (_panel_sendf (p, 1, &p->simulator_version, "SHOW VERSION\r")) {
goto Error_Return;
}
if (1) {
int api_version = 0;
char *c = strstr (p->simulator_version, "FrontPanel API Version");
if (1) {
int api_version = 0;
char *c = strstr (p->simulator_version, "FrontPanel API Version");
if ((!c) ||
(1 != sscanf (c, "FrontPanel API Version %d", &api_version)) ||
(api_version != SIM_FRONTPANEL_VERSION)) {
sim_panel_set_error ("Inconsistent sim_frontpanel API version %d in simulator. Version %d needed.-", api_version, SIM_FRONTPANEL_VERSION);
goto Error_Return;
if ((!c) ||
(1 != sscanf (c, "FrontPanel API Version %d", &api_version)) ||
(api_version != SIM_FRONTPANEL_VERSION)) {
sim_panel_set_error ("Inconsistent sim_frontpanel API version %d in simulator. Version %d needed.-", api_version, SIM_FRONTPANEL_VERSION);
goto Error_Return;
}
}
}
_panel_register_panel (p);
@ -668,74 +694,36 @@ if (1) {
return NULL;
}
PANEL *
sim_panel_start_simulator_debug (const char *sim_path,
const char *sim_config,
size_t device_panel_count,
const char *debug_file)
{
return _sim_panel_create (sim_path, sim_config, device_panel_count, NULL, NULL, debug_file);
}
PANEL *
sim_panel_start_simulator (const char *sim_path,
const char *sim_config,
size_t device_panel_count)
{
return sim_panel_start_simulator_debug (sim_path, sim_config, device_panel_count, NULL);
}
PANEL *
sim_panel_add_device_panel_debug (PANEL *simulator_panel,
const char *device_name,
const char *debug_file)
{
return _sim_panel_create (NULL, NULL, 0, simulator_panel, device_name, debug_file);
}
PANEL *
sim_panel_add_device_panel (PANEL *simulator_panel,
const char *device_name)
{
size_t i, device_num;
PANEL *p = NULL;
if (!simulator_panel) {
sim_panel_set_error ("Invalid Panel");
return NULL;
}
for (device_num=0; device_num < simulator_panel->device_count; ++device_num)
if (simulator_panel->devices[device_num] == NULL)
break;
if (device_num == simulator_panel->device_count) {
sim_panel_set_error ("No free panel devices slots available %s simulator. All %d slots are used.", simulator_panel->path, (int)simulator_panel->device_count);
return NULL;
}
p = (PANEL *)_panel_malloc (sizeof(*p));
if (p == NULL)
goto Error_Return;
memset (p, 0, sizeof(*p));
p->device_name = (char *)_panel_malloc (1 + strlen (device_name));
if (p->device_name == NULL)
goto Error_Return;
strcpy (p->device_name, device_name);
p->parent = simulator_panel;
p->sock = INVALID_SOCKET;
for (i=0; i<100; i++) {
p->sock = sim_connect_sock_ex (NULL, simulator_panel->hostport, NULL, NULL, SIM_SOCK_OPT_NODELAY | SIM_SOCK_OPT_BLOCKING);
if (p->sock == INVALID_SOCKET)
msleep (100);
else
break;
}
if (p->sock == INVALID_SOCKET) {
sim_panel_set_error ("Can't connect to simulator Remote Console on port %s", simulator_panel->hostport);
goto Error_Return;
}
strcpy (p->hostport, simulator_panel->hostport);
pthread_mutex_init (&p->io_lock, NULL);
pthread_mutex_init (&p->io_send_lock, NULL);
pthread_cond_init (&p->io_done, NULL);
pthread_cond_init (&p->startup_cond, NULL);
if (sizeof(mantra) != _panel_send (p, (char *)mantra, sizeof(mantra))) {
sim_panel_set_error ("Error sending Telnet mantra (options): %s", sim_get_err_sock ("send"));
goto Error_Return;
}
if (1) {
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_mutex_lock (&p->io_lock);
pthread_create (&p->io_thread, &attr, _panel_reader, (void *)p);
pthread_attr_destroy(&attr);
while (!p->io_thread_running)
pthread_cond_wait (&p->startup_cond, &p->io_lock); /* Wait for thread to stabilize */
pthread_mutex_unlock (&p->io_lock);
pthread_cond_destroy (&p->startup_cond);
}
simulator_panel->devices[device_num] = p;
_panel_register_panel (p);
return p;
Error_Return:
sim_panel_destroy (p);
return NULL;
return sim_panel_add_device_panel_debug (simulator_panel, device_name, NULL);
}
int