Merge branch 'master' into AutoConfigure

This commit is contained in:
Mark Pizzolato 2012-12-23 07:22:14 -08:00
commit 3bcb6c1f3d
18 changed files with 257 additions and 136 deletions

View file

@ -1,6 +1,6 @@
HP 2100 SIMULATOR BUG FIX WRITEUPS HP 2100 SIMULATOR BUG FIX WRITEUPS
================================== ==================================
Last update: 2012-05-07 Last update: 2012-12-17
1. PROBLEM: Booting from magnetic tape reports "HALT instruction, P: 77756 1. PROBLEM: Booting from magnetic tape reports "HALT instruction, P: 77756
@ -6305,4 +6305,48 @@
if the seek would fail, and modify "complete_read" (hp2100_di_da.c) to if the seek would fail, and modify "complete_read" (hp2100_di_da.c) to
cancel the intersector delay and schedule the completion phase immediately. cancel the intersector delay and schedule the completion phase immediately.
STATUS: Patches prepared 2012-05-07. STATUS: Fixed in version 4.0-0.
248. PROBLEM: Calling a VMA routine from a non-VMA program does not MP abort.
VERSION: 3.9-0
OBSERVATION: If a virtual memory routine, such as .LBP, is called from a
non-VMA program, it should be aborted with a memory protect error.
Instead, a dynamic mapping error occurs instead:
ASMB,R
NAM MAPPR
EXT EXEC,.LBP
START CLA
CLB
JSB .LBP
NOP
JSB EXEC
DEF *+2
DEF *+1
DEC 6
END START
DM VIOL = 160377
DM INST = 105257
ABE 0 0 0
XYO 0 0 0
DM MAPPR 2014
MAPPR ABORTED
CAUSE: The page mapping routine, "cpu_vma_mapte", returns TRUE if the page
table is set up and valid and FALSE if not. If a program is not a VMA
program, then it has no page table, but "cpu_vma_mapte" is returning TRUE
erroneously. That results in a DM error when the invalid page entry is
used.
The microcode explicitly tests for a non-VMA program, i.e., one with no ID
extension, and generates an MP error in this case.
RESOLUTION: Modify "cpu_vma_mapte" (hp2100_cpu5.c) to return FALSE if
called for a non-VMA program.
STATUS: Fixed in version 4.0-0.

View file

@ -26,6 +26,7 @@
CPU5 RTE-6/VM and RTE-IV firmware option instructions CPU5 RTE-6/VM and RTE-IV firmware option instructions
17-Dec-12 JDB Fixed cpu_vma_mapte to return FALSE if not a VMA program
09-May-12 JDB Separated assignments from conditional expressions 09-May-12 JDB Separated assignments from conditional expressions
23-Mar-12 JDB Added sign extension for dim count in "cpu_ema_resolve" 23-Mar-12 JDB Added sign extension for dim count in "cpu_ema_resolve"
28-Dec-11 JDB Eliminated unused variable in "cpu_ema_vset" 28-Dec-11 JDB Eliminated unused variable in "cpu_ema_vset"
@ -333,8 +334,13 @@ uint32 dispatch = ReadIO(vswp,UMAP) & 01777; /* get fresh dispatch flag *
t_bool swapflag = TRUE; t_bool swapflag = TRUE;
if (dispatch == 0) { /* not yet set */ if (dispatch == 0) { /* not yet set */
idext = ReadIO(idx,UMAP); /* go into IDsegment extent */ idext = ReadIO(idx,UMAP); /* go into ID segment extent */
if (idext != 0) { /* is ema/vma program? */ if (idext == 0) { /* is ema/vma program? */
swapflag = FALSE; /* no, so mark PTE as invalid */
*ptepg = (uint32) -1; /* and return an invalid page number */
}
else { /* is an EMA/VMA program */
dispatch = ReadWA(idext+1) & 01777; /* get 1st ema page: new vswp */ dispatch = ReadWA(idext+1) & 01777; /* get 1st ema page: new vswp */
WriteIO(vswp,dispatch,UMAP); /* move into $VSWP */ WriteIO(vswp,dispatch,UMAP); /* move into $VSWP */
idext2 = ReadWA(idext+2); /* get swap bit */ idext2 = ReadWA(idext+2); /* get swap bit */
@ -347,7 +353,7 @@ if (dispatch) { /* some page is defined */
*ptepg = dispatch; /* return PTEPG# for later */ *ptepg = dispatch; /* return PTEPG# for later */
} }
return swapflag; /* true for swap bit set */ return swapflag; /* true for valid PTE */
} }
/* .LBP /* .LBP

View file

@ -23,9 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
14-Dec-12 JDB Added "-Wbitwise-op-parentheses" to the suppression pragmas
12-May-12 JDB Added pragmas to suppress logical operator precedence warnings 12-May-12 JDB Added pragmas to suppress logical operator precedence warnings
12-Feb-12 JDB Added MA device select code assignment
Added ma_boot_ext() declaration
10-Feb-12 JDB Added hp_setsc, hp_showsc functions to support SC modifier 10-Feb-12 JDB Added hp_setsc, hp_showsc functions to support SC modifier
28-Mar-11 JDB Tidied up signal handling 28-Mar-11 JDB Tidied up signal handling
29-Oct-10 JDB DMA channels renamed from 0,1 to 1,2 to match documentation 29-Oct-10 JDB DMA channels renamed from 0,1 to 1,2 to match documentation
@ -187,7 +186,6 @@ typedef enum { INITIAL, SERVICE } POLLMODE; /* poll synchronization
#define MUXC 042 /* 12920A control */ #define MUXC 042 /* 12920A control */
#define DI_DA 043 /* 12821A Disc Interface with Amigo disc devices */ #define DI_DA 043 /* 12821A Disc Interface with Amigo disc devices */
#define DI_DC 044 /* 12821A Disc Interface with CS/80 disc and tape devices */ #define DI_DC 044 /* 12821A Disc Interface with CS/80 disc and tape devices */
#define DI_MA 045 /* 12821A Disc Interface with Amigo mag tape devices */
#define OPTDEV 002 /* start of optional devices */ #define OPTDEV 002 /* start of optional devices */
#define CRSDEV 006 /* start of devices that receive CRS */ #define CRSDEV 006 /* start of devices that receive CRS */
@ -479,6 +477,5 @@ extern t_stat hp_showdev (FILE *st, UNIT *uptr, int32 val, void *desc);
/* Device-specific functions */ /* Device-specific functions */
extern int32 sync_poll (POLLMODE poll_mode); extern int32 sync_poll (POLLMODE poll_mode);
extern t_stat ma_boot_ext (uint32 SR);
#endif #endif

View file

@ -26,6 +26,7 @@
DP 12557A 2871 disk subsystem DP 12557A 2871 disk subsystem
13210A 7900 disk subsystem 13210A 7900 disk subsystem
18-Dec-12 MP Now calls sim_activate_time to get remaining seek time
09-May-12 JDB Separated assignments from conditional expressions 09-May-12 JDB Separated assignments from conditional expressions
10-Feb-12 JDB Deprecated DEVNO in favor of SC 10-Feb-12 JDB Deprecated DEVNO in favor of SC
Added CNTLR_TYPE cast to dp_settype Added CNTLR_TYPE cast to dp_settype

View file

@ -26,6 +26,7 @@
DQ 12565A 2883 disk system DQ 12565A 2883 disk system
18-Dec-12 MP Now calls sim_activate_time to get remaining seek time
09-May-12 JDB Separated assignments from conditional expressions 09-May-12 JDB Separated assignments from conditional expressions
10-Feb-12 JDB Deprecated DEVNO in favor of SC 10-Feb-12 JDB Deprecated DEVNO in favor of SC
28-Mar-11 JDB Tidied up signal handling 28-Mar-11 JDB Tidied up signal handling

View file

@ -28,6 +28,7 @@
TTY 12531C buffered teleprinter interface TTY 12531C buffered teleprinter interface
CLK 12539C time base generator CLK 12539C time base generator
18-Dec-12 MP Now calls sim_activate_time to get remaining poll time
09-May-12 JDB Separated assignments from conditional expressions 09-May-12 JDB Separated assignments from conditional expressions
12-Feb-12 JDB Add TBG as a logical name for the CLK device 12-Feb-12 JDB Add TBG as a logical name for the CLK device
10-Feb-12 JDB Deprecated DEVNO in favor of SC 10-Feb-12 JDB Deprecated DEVNO in favor of SC

View file

@ -24,6 +24,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the authors. in this Software without prior written authorization from the authors.
20-Dec-12 JDB sim_is_active() now returns t_bool
24-Oct-12 JDB Changed CNTLR_OPCODE to title case to avoid name clash 24-Oct-12 JDB Changed CNTLR_OPCODE to title case to avoid name clash
07-May-12 JDB Corrected end-of-track delay time logic 07-May-12 JDB Corrected end-of-track delay time logic
02-May-12 JDB First release 02-May-12 JDB First release
@ -773,7 +774,7 @@ else if (uptr) { /* otherwise, we have a
uptr->wait = cvptr->cmd_time; /* most commands use the command delay */ uptr->wait = cvptr->cmd_time; /* most commands use the command delay */
if (props->unit_access) { /* does the command access the unit? */ if (props->unit_access) { /* does the command access the unit? */
is_seeking = sim_activate_time (uptr) != 0; /* see if the unit is busy */ is_seeking = sim_is_active (uptr); /* see if the unit is busy */
if (is_seeking) /* if a seek is in progress, */ if (is_seeking) /* if a seek is in progress, */
uptr->wait = 0; /* set for no unit activation */ uptr->wait = 0; /* set for no unit activation */

View file

@ -696,6 +696,8 @@ typedef struct pdp_dib DIB;
#define INT_V_RP 6 /* RH11/RP,RM drives */ #define INT_V_RP 6 /* RH11/RP,RM drives */
#define INT_V_TU 7 /* RH11/TM03/TU45 */ #define INT_V_TU 7 /* RH11/TM03/TU45 */
#define INT_V_DMCRX 13
#define INT_V_DMCTX 14
#define INT_V_XU 15 /* DEUNA/DELUA */ #define INT_V_XU 15 /* DEUNA/DELUA */
#define INT_V_DZRX 16 /* DZ11 */ #define INT_V_DZRX 16 /* DZ11 */
#define INT_V_DZTX 17 #define INT_V_DZTX 17
@ -707,6 +709,8 @@ typedef struct pdp_dib DIB;
#define INT_RP (1u << INT_V_RP) #define INT_RP (1u << INT_V_RP)
#define INT_TU (1u << INT_V_TU) #define INT_TU (1u << INT_V_TU)
#define INT_DMCRX (1u << INT_V_DMCRX)
#define INT_DMCTX (1u << INT_V_DMCTX)
#define INT_XU (1u << INT_V_XU) #define INT_XU (1u << INT_V_XU)
#define INT_DZRX (1u << INT_V_DZRX) #define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX) #define INT_DZTX (1u << INT_V_DZTX)
@ -718,6 +722,8 @@ typedef struct pdp_dib DIB;
#define IPL_RP 6 /* int levels */ #define IPL_RP 6 /* int levels */
#define IPL_TU 6 #define IPL_TU 6
#define IPL_DMCRX 5
#define IPL_DMCTX 5
#define IPL_XU 5 #define IPL_XU 5
#define IPL_DZRX 5 #define IPL_DZRX 5
#define IPL_DZTX 5 #define IPL_DZTX 5

View file

@ -55,6 +55,7 @@ extern DEVICE dz_dev;
extern DEVICE ry_dev; extern DEVICE ry_dev;
extern DEVICE cr_dev; extern DEVICE cr_dev;
extern DEVICE lp20_dev; extern DEVICE lp20_dev;
extern DEVICE dmc_dev[];
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern REG cpu_reg[]; extern REG cpu_reg[];
extern d10 *M; extern d10 *M;
@ -90,6 +91,10 @@ DEVICE *sim_devices[] = {
&rp_dev, &rp_dev,
&tu_dev, &tu_dev,
&dz_dev, &dz_dev,
&dmc_dev[0],
&dmc_dev[1],
&dmc_dev[2],
&dmc_dev[3],
NULL NULL
}; };

View file

@ -181,6 +181,7 @@ struct dmc_controller {
LINE *line; LINE *line;
BUFFER_QUEUE *receive_queue; BUFFER_QUEUE *receive_queue;
BUFFER_QUEUE *transmit_queue; BUFFER_QUEUE *transmit_queue;
UNIT_STATS *stats;
SOCKET master_socket; SOCKET master_socket;
int32 connect_poll_interval; int32 connect_poll_interval;
DEVTYPE dev_type; DEVTYPE dev_type;
@ -238,8 +239,6 @@ int dmc_get_socket(CTLR *controller, int forRead);
int dmc_get_receive_socket(CTLR *controller, int forRead); int dmc_get_receive_socket(CTLR *controller, int forRead);
int dmc_get_transmit_socket(CTLR *controller, int is_loopback, int forRead); int dmc_get_transmit_socket(CTLR *controller, int is_loopback, int forRead);
void dmc_line_update_speed_stats(LINE *line); void dmc_line_update_speed_stats(LINE *line);
UNIT_STATS *dmc_get_unit_stats(UNIT *uptr);
void dmc_set_unit_stats(UNIT *uptr, UNIT_STATS *stats);
DEBTAB dmc_debug[] = { DEBTAB dmc_debug[] = {
{"TRACE", DBG_TRC}, {"TRACE", DBG_TRC},
@ -253,16 +252,12 @@ DEBTAB dmc_debug[] = {
{0} {0}
}; };
UNIT dmc_unit[] = { UNIT dmc0_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
{ UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, UNIT dmc1_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
{ UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, UNIT dmc2_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
{ UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, UNIT dmc3_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
{ UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }
};
UNIT dmp_unit[] = { UNIT dmpa_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
{ UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }
};
CSRS dmc_csrs[DMC_NUMDEVICE]; CSRS dmc_csrs[DMC_NUMDEVICE];
@ -362,43 +357,37 @@ MTAB dmc_mod[] = {
#define IOBA_FLOAT 0 #define IOBA_FLOAT 0
#define VEC_FLOAT 0 #define VEC_FLOAT 0
#endif #endif
DIB dmc_dib[] = DIB dmc0_dib = { IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} };
{ DIB dmc1_dib = { IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} };
{ IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} }, DIB dmc2_dib = { IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} };
{ IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} }, DIB dmc3_dib = { IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} };
{ IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} },
{ IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} }
};
#define IOLN_DMP 010 #define IOLN_DMP 010
DIB dmp_dib[] = DIB dmp_dib = { IOBA_FLOAT, IOLN_DMP, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint }};
{
{ IOBA_FLOAT, IOLN_DMP, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} }
};
DEVICE dmc_dev[] = DEVICE dmc_dev[] =
{ {
{ "DMC0", &dmc_unit[0], dmca_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, { "DMC0", &dmc0_unit, dmca_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc_dib[0], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, &dmc0_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug },
{ "DMC1", &dmc_unit[1], dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, { "DMC1", &dmc1_unit, dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc_dib[1], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, &dmc1_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug },
{ "DMC2", &dmc_unit[2], dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, { "DMC2", &dmc2_unit, dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc_dib[2], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, &dmc2_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug },
{ "DMC3", &dmc_unit[3], dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, { "DMC3", &dmc3_unit, dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc_dib[3], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } &dmc3_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }
}; };
#ifdef DMP #ifdef DMP
DEVICE dmp_dev[] = DEVICE dmp_dev[] =
{ {
{ "DMP", &dmp_unit[0], dmp_reg, dmc_mod, DMP_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, { "DMP", &dmp_unit, dmp_reg, dmc_mod, DMP_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmp_dib[0], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } &dmp_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }
}; };
#endif #endif
@ -421,40 +410,22 @@ LINE dmp_line[DMP_NUMDEVICE] =
BUFFER_QUEUE dmp_receive_queues[DMP_NUMDEVICE]; BUFFER_QUEUE dmp_receive_queues[DMP_NUMDEVICE];
BUFFER_QUEUE dmp_transmit_queues[DMP_NUMDEVICE]; BUFFER_QUEUE dmp_transmit_queues[DMP_NUMDEVICE];
UNIT_STATS dmc_stats[DMC_NUMDEVICE];
UNIT_STATS dmp_stats[DMP_NUMDEVICE];
CTLR dmc_ctrls[] = CTLR dmc_ctrls[] =
{ {
{ &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], INVALID_SOCKET, -1, 30, DMC }, { &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], &dmc_stats[0], INVALID_SOCKET, -1, 30, DMC },
{ &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], INVALID_SOCKET, -1, 30, DMC }, { &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], &dmc_stats[1], INVALID_SOCKET, -1, 30, DMC },
{ &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], INVALID_SOCKET, -1, 30, DMC }, { &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], &dmc_stats[2], INVALID_SOCKET, -1, 30, DMC },
{ &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], INVALID_SOCKET, -1, 30, DMC }, { &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], &dmc_stats[3], INVALID_SOCKET, -1, 30, DMC },
#ifdef DMP #ifdef DMP
{ &dmp_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], INVALID_SOCKET, -1, 30, DMP } { &dmp_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], &dmp_stats[0], INVALID_SOCKET, -1, 30, DMP }
#endif #endif
}; };
extern int32 tmxr_poll; /* calibrated delay */ extern int32 tmxr_poll; /* calibrated delay */
UNIT_STATS *dmc_get_unit_stats(UNIT *uptr)
{
UNIT_STATS *ans = NULL;
#ifdef USE_ADDR64
ans = (UNIT_STATS *)(((t_uint64)uptr->u3 << 32) | uptr->u4);
#else
ans = (UNIT_STATS *)(uptr->u3);
#endif
return ans;
}
void dmc_set_unit_stats(UNIT *uptr, UNIT_STATS *stats)
{
#ifdef USE_ADDR64
uptr->u3 = (int32)((t_uint64)stats >> 32);
uptr->u4 = (int32)((t_uint64)stats & 0xFFFFFFFF);
#else
uptr->u3 = (int32)stats;
#endif
}
void dmc_reset_unit_stats(UNIT_STATS *s) void dmc_reset_unit_stats(UNIT_STATS *s)
{ {
s->between_polls_timer.started = FALSE; s->between_polls_timer.started = FALSE;
@ -545,11 +516,11 @@ t_stat dmc_showpeer (FILE* st, UNIT* uptr, int32 val, void* desc)
CTLR *controller = dmc_get_controller_from_unit(uptr); CTLR *controller = dmc_get_controller_from_unit(uptr);
if (controller->line->transmit_host[0]) if (controller->line->transmit_host[0])
{ {
fprintf(st, "PEER=%s", controller->line->transmit_host); fprintf(st, "peer=%s", controller->line->transmit_host);
} }
else else
{ {
fprintf(st, "PEER Unspecified"); fprintf(st, "peer Unspecified");
} }
return SCPE_OK; return SCPE_OK;
@ -576,7 +547,15 @@ t_stat dmc_setpeer (UNIT* uptr, int32 val, char* cptr, void* desc)
t_stat dmc_showspeed (FILE* st, UNIT* uptr, int32 val, void* desc) t_stat dmc_showspeed (FILE* st, UNIT* uptr, int32 val, void* desc)
{ {
CTLR *controller = dmc_get_controller_from_unit(uptr); CTLR *controller = dmc_get_controller_from_unit(uptr);
fprintf(st, "SPEED=%d", controller->line->speed); if (controller->line->speed > 0)
{
fprintf(st, "speed=%d bits/sec", controller->line->speed);
}
else
{
fprintf(st, "speed=unrestricted");
}
return SCPE_OK; return SCPE_OK;
} }
@ -602,22 +581,22 @@ t_stat dmc_showtype (FILE* st, UNIT* uptr, int32 val, void* desc)
{ {
case DMC: case DMC:
{ {
fprintf(st, "TYPE=DMC"); fprintf(st, "type=DMC");
break; break;
} }
case DMR: case DMR:
{ {
fprintf(st, "TYPE=DMR"); fprintf(st, "type=DMR");
break; break;
} }
case DMP: case DMP:
{ {
fprintf(st, "TYPE=DMP"); fprintf(st, "type=DMP");
break; break;
} }
default: default:
{ {
fprintf(st, "TYPE=???"); fprintf(st, "type=???");
break; break;
} }
} }
@ -662,9 +641,9 @@ t_stat dmc_settype (UNIT* uptr, int32 val, char* cptr, void* desc)
t_stat dmc_showstats (FILE* st, UNIT* uptr, int32 val, void* desc) t_stat dmc_showstats (FILE* st, UNIT* uptr, int32 val, void* desc)
{ {
CTLR *controller = dmc_get_controller_from_unit(uptr); CTLR *controller = dmc_get_controller_from_unit(uptr);
TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; TIMER *poll_timer = &controller->stats->poll_timer;
TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; TIMER *between_polls_timer = &controller->stats->between_polls_timer;
uint32 poll_count = dmc_get_unit_stats(uptr)->poll_count; uint32 poll_count = controller->stats->poll_count;
if (dmc_timer_started(between_polls_timer) && poll_count > 0) if (dmc_timer_started(between_polls_timer) && poll_count > 0)
{ {
@ -699,7 +678,7 @@ t_stat dmc_setstats (UNIT* uptr, int32 val, char* cptr, void* desc)
t_stat status = SCPE_OK; t_stat status = SCPE_OK;
CTLR *controller = dmc_get_controller_from_unit(uptr); CTLR *controller = dmc_get_controller_from_unit(uptr);
dmc_reset_unit_stats(dmc_get_unit_stats(uptr)); dmc_reset_unit_stats(controller->stats);
controller->receive_buffer_output_transfers_completed = 0; controller->receive_buffer_output_transfers_completed = 0;
controller->transmit_buffer_output_transfers_completed = 0; controller->transmit_buffer_output_transfers_completed = 0;
@ -714,7 +693,7 @@ t_stat dmc_setstats (UNIT* uptr, int32 val, char* cptr, void* desc)
t_stat dmc_showconnectpoll (FILE* st, UNIT* uptr, int32 val, void* desc) t_stat dmc_showconnectpoll (FILE* st, UNIT* uptr, int32 val, void* desc)
{ {
CTLR *controller = dmc_get_controller_from_unit(uptr); CTLR *controller = dmc_get_controller_from_unit(uptr);
fprintf(st, "CONNECTPOLL=%d", controller->connect_poll_interval); fprintf(st, "connect poll=%d", controller->connect_poll_interval);
return SCPE_OK; return SCPE_OK;
} }
@ -735,7 +714,7 @@ t_stat dmc_setconnectpoll (UNIT* uptr, int32 val, char* cptr, void* desc)
t_stat dmc_showlinemode (FILE* st, UNIT* uptr, int32 val, void* desc) t_stat dmc_showlinemode (FILE* st, UNIT* uptr, int32 val, void* desc)
{ {
CTLR *controller = dmc_get_controller_from_unit(uptr); CTLR *controller = dmc_get_controller_from_unit(uptr);
fprintf(st, "LINEMODE=%s", controller->line->isPrimary? "PRIMARY" : "SECONDARY"); fprintf(st, "line mode=%s", controller->line->isPrimary? "PRIMARY" : "SECONDARY");
return SCPE_OK; return SCPE_OK;
} }
@ -1235,9 +1214,13 @@ t_stat dmc_svc(UNIT* uptr)
{ {
CTLR *controller; CTLR *controller;
int32 poll; int32 poll;
TIMER *poll_timer;
TIMER *between_polls_timer;
TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; controller = dmc_get_controller_from_unit(uptr);
TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer;
poll_timer = &controller->stats->poll_timer;
between_polls_timer = &controller->stats->between_polls_timer;
poll = clk_cosched (tmxr_poll); poll = clk_cosched (tmxr_poll);
@ -1255,8 +1238,6 @@ t_stat dmc_svc(UNIT* uptr)
dmc_timer_start(poll_timer); dmc_timer_start(poll_timer);
} }
controller = dmc_get_controller_from_unit(uptr);
if (dmc_isattached(controller)) if (dmc_isattached(controller))
{ {
dmc_line_update_speed_stats(controller->line); dmc_line_update_speed_stats(controller->line);
@ -1280,7 +1261,7 @@ t_stat dmc_svc(UNIT* uptr)
{ {
dmc_timer_start(between_polls_timer); dmc_timer_start(between_polls_timer);
} }
dmc_get_unit_stats(uptr)->poll_count++; controller->stats->poll_count++;
return SCPE_OK; return SCPE_OK;
} }
@ -2212,12 +2193,6 @@ t_stat dmc_reset (DEVICE *dptr)
sim_debug(DBG_TRC, dptr, "dmc_reset()\n"); sim_debug(DBG_TRC, dptr, "dmc_reset()\n");
if (dmc_get_unit_stats(dptr->units) == NULL)
{
dmc_set_unit_stats(dptr->units, (UNIT_STATS *)malloc(sizeof(UNIT_STATS)));
dmc_reset_unit_stats(dmc_get_unit_stats(dptr->units));
}
dmc_clrrxint(controller); dmc_clrrxint(controller);
dmc_clrtxint(controller); dmc_clrtxint(controller);
sim_cancel (controller->device->units); /* stop poll */ sim_cancel (controller->device->units); /* stop poll */
@ -2242,7 +2217,7 @@ t_stat dmc_attach (UNIT *uptr, char *cptr)
uptr->filename = (char *)malloc(strlen(cptr)+1); uptr->filename = (char *)malloc(strlen(cptr)+1);
strcpy(uptr->filename, cptr); strcpy(uptr->filename, cptr);
controller->line->receive_port = uptr->filename; controller->line->receive_port = uptr->filename;
//sim_activate_abs(controller->device->units, clk_cosched (tmxr_poll)); dmc_reset_unit_stats(controller->stats);
} }
return ans; return ans;

View file

@ -40,6 +40,10 @@
#if defined (VM_VAX) /* VAX version */ #if defined (VM_VAX) /* VAX version */
#include "vax_defs.h" #include "vax_defs.h"
extern int32 int_req[IPL_HLVL]; extern int32 int_req[IPL_HLVL];
#elif defined(VM_PDP10)
#include "pdp10_defs.h"
//#define IPL_HLVL 8 /* # int levels */
extern int32 int_req;
#else /* PDP-11 version */ #else /* PDP-11 version */
#include "pdp11_defs.h" #include "pdp11_defs.h"
extern int32 int_req[IPL_HLVL]; extern int32 int_req[IPL_HLVL];

View file

@ -2181,6 +2181,7 @@ for ( ;; ) {
BRANCHB (brdisp); BRANCHB (brdisp);
if (((PSL & PSL_IS) != 0) && /* on IS? */ if (((PSL & PSL_IS) != 0) && /* on IS? */
(PSL_GETIPL (PSL) == 0x1F) && /* at IPL 31 */ (PSL_GETIPL (PSL) == 0x1F) && /* at IPL 31 */
(mapen == 0) && /* Running from ROM */
(fault_PC == 0x2004361B)) /* Boot ROM Character Prompt */ (fault_PC == 0x2004361B)) /* Boot ROM Character Prompt */
cpu_idle(); cpu_idle();
} }

View file

@ -235,6 +235,10 @@
RelativePath="..\PDP11\pdp11_cr.c" RelativePath="..\PDP11\pdp11_cr.c"
> >
</File> </File>
<File
RelativePath="..\PDP11\pdp11_dmc.c"
>
</File>
<File <File
RelativePath="..\PDP11\pdp11_dz.c" RelativePath="..\PDP11\pdp11_dz.c"
> >
@ -292,6 +296,10 @@
RelativePath="..\PDP10\pdp10_defs.h" RelativePath="..\PDP10\pdp10_defs.h"
> >
</File> </File>
<File
RelativePath="..\PDP11\pdp11_dmc.h"
>
</File>
<File <File
RelativePath="..\scp.h" RelativePath="..\scp.h"
> >

View file

@ -557,7 +557,8 @@ PDP10_SOURCE = $(PDP10_DIR)PDP10_FE.C,\
$(PDP10_DIR)PDP10_RP.C,$(PDP10_DIR)PDP10_SYS.C,\ $(PDP10_DIR)PDP10_RP.C,$(PDP10_DIR)PDP10_SYS.C,\
$(PDP10_DIR)PDP10_TIM.C,$(PDP10_DIR)PDP10_TU.C,\ $(PDP10_DIR)PDP10_TIM.C,$(PDP10_DIR)PDP10_TU.C,\
$(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_DZ.C,\ $(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_DZ.C,\
$(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_CR.C $(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_CR.C,\
$(PDP11_DIR)PDP11_DMC.C
PDP10_OPTIONS = /INCL=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))\ PDP10_OPTIONS = /INCL=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))\
/DEF=($(CC_DEFS),"USE_INT64=1","VM_PDP10=1"$(PCAP_DEFS)) /DEF=($(CC_DEFS),"USE_INT64=1","VM_PDP10=1"$(PCAP_DEFS))

View file

@ -296,6 +296,9 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
ifneq (binexists,$(shell if $(TEST) -e BIN; then echo binexists; fi)) ifneq (binexists,$(shell if $(TEST) -e BIN; then echo binexists; fi))
MKDIRBIN = mkdir -p BIN MKDIRBIN = mkdir -p BIN
endif endif
ifneq (,$(shell cat .git-commit-id))
GIT_COMMIT_ID=$(shell cat .git-commit-id)
endif
else else
#Win32 Environments (via MinGW32) #Win32 Environments (via MinGW32)
GCC = gcc GCC = gcc
@ -338,7 +341,11 @@ else
ifneq ($(USE_NETWORK),) ifneq ($(USE_NETWORK),)
NETWORK_OPT += -DUSE_SHARED NETWORK_OPT += -DUSE_SHARED
endif endif
ifneq (,$(shell if exist .git-commit-id type .git-commit-id))
GIT_COMMIT_ID=$(shell if exist .git-commit-id type .git-commit-id)
endif
endif endif
CFLAGS_GIT = -DSIM_GIT_COMMIT_ID=\"$(GIT_COMMIT_ID)\"
ifneq ($(DEBUG),) ifneq ($(DEBUG),)
CFLAGS_G = -g -ggdb -g3 CFLAGS_G = -g -ggdb -g3
CFLAGS_O = -O0 CFLAGS_O = -O0
@ -406,6 +413,10 @@ ifneq (clean,$(MAKECMDGOALS))
ifneq (,$(NETWORK_FEATURES)) ifneq (,$(NETWORK_FEATURES))
$(info *** $(NETWORK_FEATURES).) $(info *** $(NETWORK_FEATURES).)
endif endif
ifneq (,$(GIT_COMMIT_ID))
$(info ***)
$(info *** git commit id is $(GIT_COMMIT_ID).)
endif
$(info ***) $(info ***)
endif endif
ifneq ($(DONT_USE_ROMS),) ifneq ($(DONT_USE_ROMS),)
@ -419,7 +430,7 @@ endif
CC_STD = -std=c99 CC_STD = -std=c99
CC_OUTSPEC = -o $@ CC_OUTSPEC = -o $@
CC = $(GCC) $(CC_STD) -U__STRICT_ANSI__ $(CFLAGS_G) $(CFLAGS_O) -I . $(OS_CCDEFS) $(ROMS_OPT) CC = $(GCC) $(CC_STD) -U__STRICT_ANSI__ $(CFLAGS_G) $(CFLAGS_O) $(CFLAGS_GIT) -I . $(OS_CCDEFS) $(ROMS_OPT)
LDFLAGS = $(OS_LDFLAGS) $(NETWORK_LDFLAGS) $(LDFLAGS_O) LDFLAGS = $(OS_LDFLAGS) $(NETWORK_LDFLAGS) $(LDFLAGS_O)
# #
@ -565,7 +576,7 @@ PDP10 = ${PDP10D}/pdp10_fe.c ${PDP11D}/pdp11_dz.c ${PDP10D}/pdp10_cpu.c \
${PDP10D}/pdp10_ksio.c ${PDP10D}/pdp10_lp20.c ${PDP10D}/pdp10_mdfp.c \ ${PDP10D}/pdp10_ksio.c ${PDP10D}/pdp10_lp20.c ${PDP10D}/pdp10_mdfp.c \
${PDP10D}/pdp10_pag.c ${PDP10D}/pdp10_rp.c ${PDP10D}/pdp10_sys.c \ ${PDP10D}/pdp10_pag.c ${PDP10D}/pdp10_rp.c ${PDP10D}/pdp10_sys.c \
${PDP10D}/pdp10_tim.c ${PDP10D}/pdp10_tu.c ${PDP10D}/pdp10_xtnd.c \ ${PDP10D}/pdp10_tim.c ${PDP10D}/pdp10_tu.c ${PDP10D}/pdp10_xtnd.c \
${PDP11D}/pdp11_pt.c ${PDP11D}/pdp11_ry.c \ ${PDP11D}/pdp11_pt.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_dmc.c \
${PDP11D}/pdp11_cr.c ${PDP11D}/pdp11_cr.c
PDP10_OPT = -DVM_PDP10 -DUSE_INT64 -I ${PDP10D} -I ${PDP11D} PDP10_OPT = -DVM_PDP10 -DUSE_INT64 -I ${PDP10D} -I ${PDP11D}

25
scp.c
View file

@ -1003,10 +1003,30 @@ if (*cptr) {
if (*cptr) if (*cptr)
return SCPE_2MARG; return SCPE_2MARG;
if ((cmdp = find_cmd (gbuf))) { if ((cmdp = find_cmd (gbuf))) {
if (cmdp->help) {
fputs (cmdp->help, stdout); fputs (cmdp->help, stdout);
if (sim_log) if (sim_log)
fputs (cmdp->help, sim_log); fputs (cmdp->help, sim_log);
} }
else { /* no help so it is likely a command alias */
CTAB *cmdpa;
for (cmdpa=cmd_table; cmdpa->name != NULL; cmdpa++)
if ((cmdpa->action == cmdp->action) && (cmdpa->help)) {
fprintf (stdout, "%s is an alias for the %s command:\n%s",
cmdp->name, cmdpa->name, cmdpa->help);
if (sim_log)
fprintf (sim_log, "%s is an alias for the %s command.\n%s",
cmdp->name, cmdpa->name, cmdpa->help);
break;
}
if (cmdpa->name == NULL) { /* not found? */
fprintf (stdout, "No help available for the %s command\n", cmdp->name);
if (sim_log)
fprintf (sim_log, "No help available for the %s command\n", cmdp->name);
}
}
}
else return SCPE_ARG; else return SCPE_ARG;
} }
else { else {
@ -1482,7 +1502,7 @@ t_stat shift_args (char *do_arg[], size_t arg_count)
{ {
size_t i; size_t i;
for (i=1; i<arg_count; ++i) for (i=1; i<arg_count-1; ++i)
do_arg[i] = do_arg[i+1]; do_arg[i] = do_arg[i+1];
return SCPE_OK; return SCPE_OK;
} }
@ -2297,6 +2317,9 @@ if (vdelt)
fprintf (st, " delta %d", vdelt); fprintf (st, " delta %d", vdelt);
if (flag) if (flag)
fprintf (st, " [%s, %s, %s]", sim_si64, sim_sa64, sim_snet); fprintf (st, " [%s, %s, %s]", sim_si64, sim_sa64, sim_snet);
#if defined(SIM_GIT_COMMIT_ID)
fprintf (st, " git commit id: %8.8s", SIM_GIT_COMMIT_ID);
#endif
fprintf (st, "\n"); fprintf (st, "\n");
return SCPE_OK; return SCPE_OK;
} }

View file

@ -569,7 +569,8 @@ char* eth_getname(int number, char* name)
ETH_LIST list[ETH_MAX_DEVICE]; ETH_LIST list[ETH_MAX_DEVICE];
int count = eth_devices(ETH_MAX_DEVICE, list); int count = eth_devices(ETH_MAX_DEVICE, list);
if (count <= number) return NULL; if ((number < 0) || (count <= number))
return NULL;
strcpy(name, list[number].name); strcpy(name, list[number].name);
return name; return name;
} }

View file

@ -891,6 +891,7 @@ if (lp->serport) {
else /* Telnet connection */ else /* Telnet connection */
if (lp->sock) { if (lp->sock) {
sim_close_sock (lp->sock, 0); /* close socket */ sim_close_sock (lp->sock, 0); /* close socket */
lp->sock = 0;
lp->conn = FALSE; lp->conn = FALSE;
lp->rcve = lp->xmte = 0; lp->rcve = lp->xmte = 0;
} }
@ -1380,6 +1381,38 @@ int32 tmxr_tqln (TMLN *lp)
return (lp->txbpi - lp->txbpr + ((lp->txbpi < lp->txbpr)? lp->txbsz: 0)); return (lp->txbpi - lp->txbpr + ((lp->txbpi < lp->txbpr)? lp->txbsz: 0));
} }
static void _mux_detach_line (TMLN *lp, t_bool close_listener, t_bool close_connecting)
{
if (close_listener && lp->master) {
sim_close_sock (lp->master, 1);
lp->master = 0;
free (lp->port);
lp->port = NULL;
}
if (lp->sock) { /* if existing tcp, drop it */
tmxr_report_disconnection (lp); /* report disconnection */
tmxr_reset_ln (lp);
}
if (close_connecting) {
free (lp->destination);
lp->destination = NULL;
if (lp->connecting) { /* if existing outgoing tcp, drop it */
lp->sock = lp->connecting;
lp->connecting = 0;
tmxr_reset_ln (lp);
}
}
if (lp->serport) { /* close current serial connection */
tmxr_reset_ln (lp);
sim_control_serial (lp->serport, 0, TMXR_MDM_DTR|TMXR_MDM_RTS, NULL);/* drop DTR and RTS */
sim_close_serial (lp->serport);
lp->serport = 0;
free (lp->serconfig);
lp->serconfig = NULL;
free (lp->destination);
lp->destination = NULL;
}
}
/* Open a master listening socket (and all of the other variances of connections). /* Open a master listening socket (and all of the other variances of connections).
@ -1430,7 +1463,7 @@ while (*tptr) {
if ((NULL == cptr) || ('\0' == *cptr)) if ((NULL == cptr) || ('\0' == *cptr))
return SCPE_ARG; return SCPE_ARG;
line = (int32) get_uint (cptr, 10, mp->lines, &r); line = (int32) get_uint (cptr, 10, mp->lines, &r);
if (r != SCPE_OK) if ((r != SCPE_OK) || (mp->lines == 1))
return SCPE_ARG; return SCPE_ARG;
continue; continue;
} }
@ -1569,17 +1602,17 @@ while (*tptr) {
} }
} }
if (listen[0]) { if (listen[0]) {
if (mp->port && (0 != strcmp (listen, mp->port))) {
sim_close_sock (mp->master, 1);
mp->master = 0;
free (mp->port);
mp->port = NULL;
}
sock = sim_master_sock (listen, &r); /* make master socket */ sock = sim_master_sock (listen, &r); /* make master socket */
if (r != SCPE_OK) if (r != SCPE_OK)
return r; return r;
if (sock == INVALID_SOCKET) /* open error */ if (sock == INVALID_SOCKET) /* open error */
return SCPE_OPENERR; return SCPE_OPENERR;
if (mp->port) { /* close prior listener */
sim_close_sock (mp->master, 1);
mp->master = 0;
free (mp->port);
mp->port = NULL;
}
printf ("Listening on port %s\n", listen); printf ("Listening on port %s\n", listen);
if (sim_log) if (sim_log)
fprintf (sim_log, "Listening on port %s\n", listen); fprintf (sim_log, "Listening on port %s\n", listen);
@ -1595,16 +1628,31 @@ while (*tptr) {
tmxr_init_line (lp); /* initialize line state */ tmxr_init_line (lp); /* initialize line state */
lp->sock = 0; /* clear the socket */ lp->sock = 0; /* clear the socket */
} }
else { /* close current serial connection */
tmxr_reset_ln (lp);
sim_control_serial (lp->serport, 0, TMXR_MDM_DTR|TMXR_MDM_RTS, NULL);/* drop DTR and RTS */
sim_close_serial (lp->serport);
lp->serport = 0;
free (lp->serconfig);
lp->serconfig = NULL;
}
} }
} }
if (destination[0]) { if (destination[0]) {
if (mp->lines > 1) if (mp->lines > 1)
return SCPE_ARG; /* ambiguous */ return SCPE_ARG; /* ambiguous */
lp = &mp->ldsc[0]; lp = &mp->ldsc[0];
serport = sim_open_serial (destination, lp, &r);
if (serport != INVALID_HANDLE) {
_mux_detach_line (lp, TRUE, TRUE);
if (lp->mp->master) { /* if existing listener, close it */
sim_close_sock (lp->mp->master, 1);
lp->mp->master = 0;
free (lp->mp->port);
lp->mp->port = NULL;
}
lp->destination = malloc(1+strlen(destination)); lp->destination = malloc(1+strlen(destination));
strcpy (lp->destination, destination); strcpy (lp->destination, destination);
serport = sim_open_serial (lp->destination, lp, &r);
if (serport != INVALID_HANDLE) {
lp->mp = mp; lp->mp = mp;
lp->serport = serport; lp->serport = serport;
lp->ser_connect_pending = TRUE; lp->ser_connect_pending = TRUE;
@ -1621,6 +1669,9 @@ while (*tptr) {
else { else {
sock = sim_connect_sock (destination, "localhost", NULL); sock = sim_connect_sock (destination, "localhost", NULL);
if (sock != INVALID_SOCKET) { if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE);
lp->destination = malloc(1+strlen(destination));
strcpy (lp->destination, destination);
lp->mp = mp; lp->mp = mp;
lp->connecting = sock; lp->connecting = sock;
lp->ipad = malloc (1 + strlen (lp->destination)); lp->ipad = malloc (1 + strlen (lp->destination));
@ -1671,32 +1722,12 @@ while (*tptr) {
} }
} }
if (listen[0]) { if (listen[0]) {
if (lp->master) {
sim_close_sock (lp->master, 1);
lp->master = 0;
}
if (lp->sock) {
sim_close_sock (lp->sock, 1);
lp->sock = 0;
}
if (lp->connecting) {
sim_close_sock (lp->connecting, 1);
lp->connecting = 0;
}
if (lp->serport) {
sim_close_serial (lp->serport);
lp->serport = 0;
free (lp->serconfig);
lp->serconfig = NULL;
}
free (lp->destination);
lp->conn = FALSE;
lp->destination = NULL;
sock = sim_master_sock (listen, &r); /* make master socket */ sock = sim_master_sock (listen, &r); /* make master socket */
if (r != SCPE_OK) if (r != SCPE_OK)
return r; return r;
if (sock == INVALID_SOCKET) /* open error */ if (sock == INVALID_SOCKET) /* open error */
return SCPE_OPENERR; return SCPE_OPENERR;
_mux_detach_line (lp, TRUE, FALSE);
printf ("Line %d Listening on port %s\n", line, listen); printf ("Line %d Listening on port %s\n", line, listen);
if (sim_log) if (sim_log)
fprintf (sim_log, "Line %d Listening on port %s\n", line, listen); fprintf (sim_log, "Line %d Listening on port %s\n", line, listen);
@ -1709,10 +1740,11 @@ while (*tptr) {
lp->notelnet = mp->notelnet; lp->notelnet = mp->notelnet;
} }
if (destination[0]) { if (destination[0]) {
serport = sim_open_serial (destination, lp, &r);
if (serport != INVALID_HANDLE) {
_mux_detach_line (lp, TRUE, TRUE);
lp->destination = malloc(1+strlen(destination)); lp->destination = malloc(1+strlen(destination));
strcpy (lp->destination, destination); strcpy (lp->destination, destination);
serport = sim_open_serial (lp->destination, lp, &r);
if (serport != INVALID_HANDLE) {
lp->serport = serport; lp->serport = serport;
lp->ser_connect_pending = TRUE; lp->ser_connect_pending = TRUE;
lp->notelnet = TRUE; lp->notelnet = TRUE;
@ -1728,6 +1760,9 @@ while (*tptr) {
else { else {
sock = sim_connect_sock (destination, "localhost", NULL); sock = sim_connect_sock (destination, "localhost", NULL);
if (sock != INVALID_SOCKET) { if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE);
lp->destination = malloc(1+strlen(destination));
strcpy (lp->destination, destination);
lp->connecting = sock; lp->connecting = sock;
lp->ipad = malloc (1 + strlen (lp->destination)); lp->ipad = malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination); strcpy (lp->ipad, lp->destination);