From c77bdb20f1fcfef2ea320a64b1618f5073494127 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 25 Apr 2012 17:04:48 -0700 Subject: [PATCH] Added scp SHOW SERIAL command Fixed Ethernet formatting of open device names Fixed serial generic naming to accomodate for the fact that an OS list of serial devices might not include devices which are already opened. --- scp.c | 3 + sim_ether.c | 6 +- sim_serial.c | 191 +++++++++++++++++++++++++++++++++++++++++---------- sim_serial.h | 7 +- sim_tmxr.c | 11 ++- 5 files changed, 168 insertions(+), 50 deletions(-) diff --git a/scp.c b/scp.c index 54d111f6..110cec00 100644 --- a/scp.c +++ b/scp.c @@ -217,6 +217,7 @@ #include "sim_defs.h" #include "sim_rev.h" #include "sim_ether.h" +#include "sim_serial.h" #include #include #include @@ -697,6 +698,7 @@ static CTAB cmd_table[] = { "sh{ow} {arg,...} show device parameters\n" "sh{ow} {arg,...} show unit parameters\n" "sh{ow} ethernet show ethernet devices\n" + "sh{ow} serial show serial devices\n" "sh{ow} on show on condition actions\n" }, { "DO", &do_cmd, 1, "do {-V} {-O} {-E} {-Q} {arg,arg...}\b" @@ -2040,6 +2042,7 @@ static SHTAB show_glob_tab[] = { { "THROTTLE", &sim_show_throt, 0 }, { "ASYNCH", &sim_show_asynch, 0 }, { "ETHERNET", ð_show_devices, 0 }, + { "SERIAL", &sim_show_serial, 0 }, { "ON", &show_on, 0 }, { NULL, NULL, 0 } }; diff --git a/sim_ether.c b/sim_ether.c index cbb54161..8318f129 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -702,7 +702,7 @@ t_stat eth_show (FILE* st, UNIT* uptr, int32 val, void* desc) for (i=0, min=0; i min) min = len; for (i=0; iname, desc); if (d) - fprintf(st, " %-7s%s (%s)\n", eth_open_devices[i]->dptr->name, eth_open_devices[i]->name, d); + fprintf(st, " %-7s%s (%s)\n", eth_open_devices[i]->dptr->name, eth_open_devices[i]->dptr->units[0].filename, d); else - fprintf(st, " %-7s%s\n", eth_open_devices[i]->dptr->name, eth_open_devices[i]->name); + fprintf(st, " %-7s%s\n", eth_open_devices[i]->dptr->name, eth_open_devices[i]->dptr->units[0].filename); } } return SCPE_OK; diff --git a/sim_serial.c b/sim_serial.c index 2f6ad369..2b493195 100644 --- a/sim_serial.c +++ b/sim_serial.c @@ -111,7 +111,7 @@ enumerates the available host serial ports - t_stat sim_show_serial (FILE* st) + t_stat sim_show_serial (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, void* desc) --------------------------------- displays the available host serial ports @@ -121,6 +121,7 @@ #include "sim_defs.h" #include "sim_serial.h" +#include "sim_tmxr.h" #include @@ -135,6 +136,40 @@ typedef struct serial_list { static int sim_serial_os_devices (int max, SERIAL_LIST* list); static SERHANDLE sim_open_os_serial (char *name); +static void sim_close_os_serial (SERHANDLE port); + + +static struct open_serial_device { + SERHANDLE port; + TMLN *line; + char name[SER_DEV_NAME_MAX]; + char desc[SER_DEV_DESC_MAX]; + } *serial_open_devices = NULL; +static serial_open_device_count = 0; + +static void _serial_add_to_open_list (SERHANDLE port, TMLN *line, const char *name, const char *desc) +{ +serial_open_devices = realloc(serial_open_devices, (++serial_open_device_count)*sizeof(*serial_open_devices)); +memset(&serial_open_devices[serial_open_device_count-1], 0, sizeof(serial_open_devices[serial_open_device_count-1])); +serial_open_devices[serial_open_device_count-1].port = port; +serial_open_devices[serial_open_device_count-1].line = line; +strcpy(serial_open_devices[serial_open_device_count-1].name, name); +if (desc) + strcpy(serial_open_devices[serial_open_device_count-1].desc, desc); +} + +static void _serial_remove_from_open_list (SERHANDLE port) +{ +int i, j; + +for (i=0; iname, b->name); } -t_stat sim_show_serial (FILE* st) +static int sim_serial_devices(int max, SERIAL_LIST *list) { -SERIAL_LIST list[SER_MAX_DEVICE]; -int number = sim_serial_os_devices(SER_MAX_DEVICE, list); +int i, j, ports = sim_serial_os_devices(max, list); -fprintf(st, "Serial devices:\n"); -if (number == -1) - fprintf(st, " serial support not available in simulator\n"); -else -if (number == 0) - fprintf(st, " no serial devices are available\n"); -else { - size_t min, len; - int i; - for (i=0, min=0; i min) - min = len; - for (i=0; i= max) + break; + strcpy(list[ports].name, serial_open_devices[i].name); + strcpy(list[ports].desc, serial_open_devices[i].desc); + ++ports; } -return SCPE_OK; +if (ports) /* Order the list returned alphabetically by the port name */ + qsort (list, ports, sizeof(list[0]), _serial_name_compare); +return ports; } static char* sim_serial_getname(int number, char* name) { SERIAL_LIST list[SER_MAX_DEVICE]; -int count = sim_serial_os_devices(SER_MAX_DEVICE, list); +int count = sim_serial_devices(SER_MAX_DEVICE, list); if (count <= number) return NULL; @@ -196,7 +233,7 @@ return name; static char* sim_serial_getname_bydesc(char* desc, char* name) { SERIAL_LIST list[SER_MAX_DEVICE]; -int count = sim_serial_os_devices(SER_MAX_DEVICE, list); +int count = sim_serial_devices(SER_MAX_DEVICE, list); int i; size_t j=strlen(desc); @@ -246,7 +283,7 @@ return 0; static char* sim_serial_getname_byname(char* name, char* temp) { SERIAL_LIST list[SER_MAX_DEVICE]; -int count = sim_serial_os_devices(SER_MAX_DEVICE, list); +int count = sim_serial_devices(SER_MAX_DEVICE, list); size_t n; int i, found; @@ -262,10 +299,67 @@ for (i=0; i min) + min = len; + for (i=0; imp->dptr->name, (int)(serial_open_devices[i].line->mp->ldsc-serial_open_devices[i].line), serial_open_devices[i].line->sername, d); + else + fprintf(st, " %s\tLn%02d %s\n", serial_open_devices[i].line->mp->dptr->name, (int)(serial_open_devices[i].line->mp->ldsc-serial_open_devices[i].line), serial_open_devices[i].line->sername); + } + } +return SCPE_OK; +} + +SERHANDLE sim_open_serial (char *name, TMLN *lp) +{ +char temp1[1024], temp2[1024]; char *savname = name; +char *savdesc = NULL; +SERHANDLE port; /* translate name of type "serX" to real device name */ if ((strlen(name) <= 5) @@ -276,22 +370,36 @@ if ((strlen(name) <= 5) && (isdigit(name[4]) || (name[4] == '\0')) ) { int num = atoi(&name[3]); - savname = sim_serial_getname(num, temp); + savname = sim_serial_getname(num, temp1); if (savname == NULL) /* didn't translate */ return INVALID_HANDLE; + savdesc = sim_serial_getdesc_byname (savname, temp2); } else { /* are they trying to use device description? */ - savname = sim_serial_getname_bydesc(name, temp); + savname = sim_serial_getname_bydesc(name, temp1); if (savname == NULL) { /* didn't translate */ - /* probably is not ethX and has no description */ - savname = sim_serial_getname_byname(name, temp); + /* probably is not serX and has no description */ + savname = sim_serial_getname_byname(name, temp1); if (savname == NULL) /* didn't translate */ - savname = name; + savname = name; + else + savdesc = sim_serial_getdesc_byname(savname, temp2); } + else + savdesc = name; } -return sim_open_os_serial (savname); +port = sim_open_os_serial (savname); +if (port != INVALID_HANDLE) + _serial_add_to_open_list (port, lp, savname, savdesc); +return port; +} + +void sim_close_serial (SERHANDLE port) +{ +sim_close_os_serial (port); +_serial_remove_from_open_list (port); } /* Windows serial implementation */ @@ -338,8 +446,6 @@ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_ } RegCloseKey(hSERIALCOMM); } -if (ports) /* Order the list returned alphabetically by the port name */ - qsort (list, ports, sizeof(list[0]), _serial_name_compare); return ports; } @@ -619,7 +725,7 @@ else The serial port is closed. Errors are ignored. */ -void sim_close_serial (SERHANDLE port) +void sim_close_os_serial (SERHANDLE port) { CloseHandle (port); /* close the port */ return; @@ -666,8 +772,6 @@ for (i=0; (ports < max) && (i < 64); ++i) { close (port); } } -if (ports) /* Order the list returned alphabetically by the port name */ - qsort (list, ports, sizeof(list[0]), _serial_name_compare); return ports; } @@ -998,7 +1102,7 @@ return (int32) written; /* return number of The serial port is closed. Errors are ignored. */ -void sim_close_serial (SERHANDLE port) +void sim_close_os_serial (SERHANDLE port) { close (port); /* close the port */ return; @@ -1010,6 +1114,19 @@ return; #else +/* Enumerate the available serial ports. + + The serial port names are extracted from the appropriate place in the + windows registry (HKLM\HARDWARE\DEVICEMAP\SERIALCOMM\). The resulting + list is sorted alphabetically by device name (COMn). The device description + is set to the OS internal name for the COM device. + +*/ + +static int sim_serial_os_devices (int max, SERIAL_LIST* list) +{ +return -1; +} /* Open a serial port */ @@ -1053,7 +1170,7 @@ return -1; /* Close a serial port */ -void sim_close_serial (SERHANDLE port) +void sim_close_os_serial (SERHANDLE port) { return; } diff --git a/sim_serial.h b/sim_serial.h index e6a217eb..ff01ceca 100644 --- a/sim_serial.h +++ b/sim_serial.h @@ -30,7 +30,6 @@ #ifndef _SIM_SERIAL_H_ #define _SIM_SERIAL_H_ 0 - /* Windows definitions */ #if defined (_WIN32) @@ -76,7 +75,6 @@ typedef int SERHANDLE; #endif - /* Common definitions */ typedef struct serial_config { /* serial port configuration */ @@ -86,15 +84,16 @@ typedef struct serial_config { /* serial port configura uint32 stopbits; /* 0/1/2 stop bits (0 implies 1.5) */ } SERCONFIG; +typedef struct tmln TMLN; /* Global routines */ -extern SERHANDLE sim_open_serial (char *name); +extern SERHANDLE sim_open_serial (char *name, TMLN *lp); extern t_stat sim_config_serial (SERHANDLE port, SERCONFIG config); extern t_bool sim_control_serial (SERHANDLE port, t_bool connect); extern int32 sim_read_serial (SERHANDLE port, char *buffer, int32 count, char *brk); extern int32 sim_write_serial (SERHANDLE port, char *buffer, int32 count); extern void sim_close_serial (SERHANDLE port); -extern t_stat sim_show_serial (FILE* st); +extern t_stat sim_show_serial (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, void* desc); #endif diff --git a/sim_tmxr.c b/sim_tmxr.c index 3112c73b..0bb1b746 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -1299,6 +1299,8 @@ t_stat status; char portname [1024]; t_bool arg_error = FALSE; +dptr = find_dev_from_unit (uptr); /* find associated device */ + if (val) { /* explicit line? */ if (cptr == NULL) /* arguments supplied? */ return SCPE_ARG; /* report bad argument */ @@ -1350,7 +1352,7 @@ if (*pptr) { /* parameter string config.stopbits = 0; /* code request */ } -serport = sim_open_serial (portname); /* open the serial port */ +serport = sim_open_serial (portname, lp); /* open the serial port */ if (serport == INVALID_HANDLE) /* not a valid port name */ return SCPE_OPENERR; /* cannot attach */ @@ -1366,14 +1368,11 @@ else { /* good serial port */ } if (val == 0) { /* unit implies line? */ - dptr = find_dev_from_unit (uptr); /* find associated device */ - if (dptr && (dptr->flags & DEV_NET)) /* will RESTORE be inhibited? */ cptr = portname; /* yes, so save just port name */ - - if (mp->dptr == NULL) /* has device been set? */ - mp->dptr = dptr; /* no, so set device now */ } + if (mp->dptr == NULL) /* has device been set? */ + mp->dptr = dptr; /* no, so set device now */ tptr = (char *) malloc (strlen (cptr) + 1); /* get buffer for port name and maybe params */