diff --git a/HP2100/hp2100_bugfixes.txt b/HP2100/hp2100_bugfixes.txt index 117dd525..4902bd00 100644 --- a/HP2100/hp2100_bugfixes.txt +++ b/HP2100/hp2100_bugfixes.txt @@ -1,6 +1,6 @@ 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 @@ -6305,4 +6305,48 @@ if the seek would fail, and modify "complete_read" (hp2100_di_da.c) to 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. diff --git a/HP2100/hp2100_cpu5.c b/HP2100/hp2100_cpu5.c index 31c381c6..5a72e75a 100644 --- a/HP2100/hp2100_cpu5.c +++ b/HP2100/hp2100_cpu5.c @@ -26,6 +26,7 @@ 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 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" @@ -333,8 +334,13 @@ uint32 dispatch = ReadIO(vswp,UMAP) & 01777; /* get fresh dispatch flag * t_bool swapflag = TRUE; if (dispatch == 0) { /* not yet set */ - idext = ReadIO(idx,UMAP); /* go into IDsegment extent */ - if (idext != 0) { /* is ema/vma program? */ + idext = ReadIO(idx,UMAP); /* go into ID segment extent */ + 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 */ WriteIO(vswp,dispatch,UMAP); /* move into $VSWP */ idext2 = ReadWA(idext+2); /* get swap bit */ @@ -347,7 +353,7 @@ if (dispatch) { /* some page is defined */ *ptepg = dispatch; /* return PTEPG# for later */ } -return swapflag; /* true for swap bit set */ +return swapflag; /* true for valid PTE */ } /* .LBP diff --git a/HP2100/hp2100_defs.h b/HP2100/hp2100_defs.h index d5126db4..5df86335 100644 --- a/HP2100/hp2100_defs.h +++ b/HP2100/hp2100_defs.h @@ -23,9 +23,8 @@ 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. + 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-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 28-Mar-11 JDB Tidied up signal handling 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 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_MA 045 /* 12821A Disc Interface with Amigo mag tape devices */ #define OPTDEV 002 /* start of optional devices */ #define CRSDEV 006 /* start of devices that receive CRS */ @@ -478,7 +476,6 @@ extern t_stat hp_showdev (FILE *st, UNIT *uptr, int32 val, void *desc); /* Device-specific functions */ -extern int32 sync_poll (POLLMODE poll_mode); -extern t_stat ma_boot_ext (uint32 SR); +extern int32 sync_poll (POLLMODE poll_mode); #endif diff --git a/HP2100/hp2100_dp.c b/HP2100/hp2100_dp.c index 196cbac8..40614207 100644 --- a/HP2100/hp2100_dp.c +++ b/HP2100/hp2100_dp.c @@ -26,6 +26,7 @@ DP 12557A 2871 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 10-Feb-12 JDB Deprecated DEVNO in favor of SC Added CNTLR_TYPE cast to dp_settype diff --git a/HP2100/hp2100_dq.c b/HP2100/hp2100_dq.c index 816c7bf7..11feafb7 100644 --- a/HP2100/hp2100_dq.c +++ b/HP2100/hp2100_dq.c @@ -26,6 +26,7 @@ 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 10-Feb-12 JDB Deprecated DEVNO in favor of SC 28-Mar-11 JDB Tidied up signal handling diff --git a/HP2100/hp2100_stddev.c b/HP2100/hp2100_stddev.c index 50f42081..856d1a5a 100644 --- a/HP2100/hp2100_stddev.c +++ b/HP2100/hp2100_stddev.c @@ -28,6 +28,7 @@ TTY 12531C buffered teleprinter interface 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 12-Feb-12 JDB Add TBG as a logical name for the CLK device 10-Feb-12 JDB Deprecated DEVNO in favor of SC diff --git a/HP2100/hp_disclib.c b/HP2100/hp_disclib.c index cb3fd649..2a0d3ce2 100644 --- a/HP2100/hp_disclib.c +++ b/HP2100/hp_disclib.c @@ -24,6 +24,7 @@ used in advertising or otherwise to promote the sale, use or other dealings 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 07-May-12 JDB Corrected end-of-track delay time logic 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 */ 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, */ uptr->wait = 0; /* set for no unit activation */ diff --git a/PDP10/pdp10_defs.h b/PDP10/pdp10_defs.h index ed54818d..8cbe1e7f 100644 --- a/PDP10/pdp10_defs.h +++ b/PDP10/pdp10_defs.h @@ -696,6 +696,8 @@ typedef struct pdp_dib DIB; #define INT_V_RP 6 /* RH11/RP,RM drives */ #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_DZRX 16 /* DZ11 */ #define INT_V_DZTX 17 @@ -707,6 +709,8 @@ typedef struct pdp_dib DIB; #define INT_RP (1u << INT_V_RP) #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_DZRX (1u << INT_V_DZRX) #define INT_DZTX (1u << INT_V_DZTX) @@ -718,6 +722,8 @@ typedef struct pdp_dib DIB; #define IPL_RP 6 /* int levels */ #define IPL_TU 6 +#define IPL_DMCRX 5 +#define IPL_DMCTX 5 #define IPL_XU 5 #define IPL_DZRX 5 #define IPL_DZTX 5 diff --git a/PDP10/pdp10_sys.c b/PDP10/pdp10_sys.c index 24ec2d48..4bfa6240 100644 --- a/PDP10/pdp10_sys.c +++ b/PDP10/pdp10_sys.c @@ -55,6 +55,7 @@ extern DEVICE dz_dev; extern DEVICE ry_dev; extern DEVICE cr_dev; extern DEVICE lp20_dev; +extern DEVICE dmc_dev[]; extern UNIT cpu_unit; extern REG cpu_reg[]; extern d10 *M; @@ -90,6 +91,10 @@ DEVICE *sim_devices[] = { &rp_dev, &tu_dev, &dz_dev, + &dmc_dev[0], + &dmc_dev[1], + &dmc_dev[2], + &dmc_dev[3], NULL }; diff --git a/PDP11/pdp11_dmc.c b/PDP11/pdp11_dmc.c index 4707bd88..762311d5 100644 --- a/PDP11/pdp11_dmc.c +++ b/PDP11/pdp11_dmc.c @@ -181,6 +181,7 @@ struct dmc_controller { LINE *line; BUFFER_QUEUE *receive_queue; BUFFER_QUEUE *transmit_queue; + UNIT_STATS *stats; SOCKET master_socket; int32 connect_poll_interval; 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_transmit_socket(CTLR *controller, int is_loopback, int forRead); 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[] = { {"TRACE", DBG_TRC}, @@ -253,16 +252,12 @@ DEBTAB dmc_debug[] = { {0} }; -UNIT dmc_unit[] = { - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) } -}; +UNIT dmc0_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }; +UNIT dmc1_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }; +UNIT dmc2_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }; +UNIT dmc3_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }; -UNIT dmp_unit[] = { - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) } -}; +UNIT dmpa_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }; CSRS dmc_csrs[DMC_NUMDEVICE]; @@ -362,43 +357,37 @@ MTAB dmc_mod[] = { #define IOBA_FLOAT 0 #define VEC_FLOAT 0 #endif -DIB dmc_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} }, - { IOBA_FLOAT, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} } -}; +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} }; +DIB dmc2_dib = { 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} }; #define IOLN_DMP 010 -DIB dmp_dib[] = -{ - { IOBA_FLOAT, IOLN_DMP, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint} } -}; +DIB dmp_dib = { IOBA_FLOAT, IOLN_DMP, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_FLOAT, {&dmc_rxint, &dmc_txint }}; 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, - &dmc_dib[0], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, - { "DMC1", &dmc_unit[1], dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + &dmc0_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }, + { "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, - &dmc_dib[1], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, - { "DMC2", &dmc_unit[2], dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + &dmc1_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }, + { "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, - &dmc_dib[2], DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, - { "DMC3", &dmc_unit[3], dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + &dmc2_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }, + { "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, - &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 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, - &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 @@ -421,40 +410,22 @@ LINE dmp_line[DMP_NUMDEVICE] = BUFFER_QUEUE dmp_receive_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[] = { - { &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[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[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[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[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], &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], &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], &dmc_stats[3], INVALID_SOCKET, -1, 30, DMC }, #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 }; 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) { 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); if (controller->line->transmit_host[0]) { - fprintf(st, "PEER=%s", controller->line->transmit_host); + fprintf(st, "peer=%s", controller->line->transmit_host); } else { - fprintf(st, "PEER Unspecified"); + fprintf(st, "peer Unspecified"); } 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) { 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; } @@ -602,22 +581,22 @@ t_stat dmc_showtype (FILE* st, UNIT* uptr, int32 val, void* desc) { case DMC: { - fprintf(st, "TYPE=DMC"); + fprintf(st, "type=DMC"); break; } case DMR: { - fprintf(st, "TYPE=DMR"); + fprintf(st, "type=DMR"); break; } case DMP: { - fprintf(st, "TYPE=DMP"); + fprintf(st, "type=DMP"); break; } default: { - fprintf(st, "TYPE=???"); + fprintf(st, "type=???"); 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) { CTLR *controller = dmc_get_controller_from_unit(uptr); - TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; - TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; - uint32 poll_count = dmc_get_unit_stats(uptr)->poll_count; + TIMER *poll_timer = &controller->stats->poll_timer; + TIMER *between_polls_timer = &controller->stats->between_polls_timer; + uint32 poll_count = controller->stats->poll_count; 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; 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->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) { 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; } @@ -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) { 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; } @@ -1235,9 +1214,13 @@ t_stat dmc_svc(UNIT* uptr) { CTLR *controller; int32 poll; + TIMER *poll_timer; + TIMER *between_polls_timer; - TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; - TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; + controller = dmc_get_controller_from_unit(uptr); + + poll_timer = &controller->stats->poll_timer; + between_polls_timer = &controller->stats->between_polls_timer; poll = clk_cosched (tmxr_poll); @@ -1255,8 +1238,6 @@ t_stat dmc_svc(UNIT* uptr) dmc_timer_start(poll_timer); } - controller = dmc_get_controller_from_unit(uptr); - if (dmc_isattached(controller)) { dmc_line_update_speed_stats(controller->line); @@ -1280,7 +1261,7 @@ t_stat dmc_svc(UNIT* uptr) { dmc_timer_start(between_polls_timer); } - dmc_get_unit_stats(uptr)->poll_count++; + controller->stats->poll_count++; return SCPE_OK; } @@ -2212,12 +2193,6 @@ t_stat dmc_reset (DEVICE *dptr) 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_clrtxint(controller); 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); strcpy(uptr->filename, cptr); controller->line->receive_port = uptr->filename; - //sim_activate_abs(controller->device->units, clk_cosched (tmxr_poll)); + dmc_reset_unit_stats(controller->stats); } return ans; diff --git a/PDP11/pdp11_dmc.h b/PDP11/pdp11_dmc.h index 3984960c..bfa9104b 100644 --- a/PDP11/pdp11_dmc.h +++ b/PDP11/pdp11_dmc.h @@ -40,6 +40,10 @@ #if defined (VM_VAX) /* VAX version */ #include "vax_defs.h" 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 */ #include "pdp11_defs.h" extern int32 int_req[IPL_HLVL]; diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index ddb18481..0760dfbd 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -2181,6 +2181,7 @@ for ( ;; ) { BRANCHB (brdisp); if (((PSL & PSL_IS) != 0) && /* on IS? */ (PSL_GETIPL (PSL) == 0x1F) && /* at IPL 31 */ + (mapen == 0) && /* Running from ROM */ (fault_PC == 0x2004361B)) /* Boot ROM Character Prompt */ cpu_idle(); } diff --git a/Visual Studio Projects/PDP10.vcproj b/Visual Studio Projects/PDP10.vcproj index 0b0e6fdd..39fd3950 100644 --- a/Visual Studio Projects/PDP10.vcproj +++ b/Visual Studio Projects/PDP10.vcproj @@ -235,6 +235,10 @@ RelativePath="..\PDP11\pdp11_cr.c" > + + @@ -292,6 +296,10 @@ RelativePath="..\PDP10\pdp10_defs.h" > + + diff --git a/descrip.mms b/descrip.mms index b61c3274..ee9e600a 100644 --- a/descrip.mms +++ b/descrip.mms @@ -557,7 +557,8 @@ PDP10_SOURCE = $(PDP10_DIR)PDP10_FE.C,\ $(PDP10_DIR)PDP10_RP.C,$(PDP10_DIR)PDP10_SYS.C,\ $(PDP10_DIR)PDP10_TIM.C,$(PDP10_DIR)PDP10_TU.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))\ /DEF=($(CC_DEFS),"USE_INT64=1","VM_PDP10=1"$(PCAP_DEFS)) diff --git a/makefile b/makefile index 076993b0..a27f63a4 100644 --- a/makefile +++ b/makefile @@ -296,6 +296,9 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) ifneq (binexists,$(shell if $(TEST) -e BIN; then echo binexists; fi)) MKDIRBIN = mkdir -p BIN endif + ifneq (,$(shell cat .git-commit-id)) + GIT_COMMIT_ID=$(shell cat .git-commit-id) + endif else #Win32 Environments (via MinGW32) GCC = gcc @@ -338,7 +341,11 @@ else ifneq ($(USE_NETWORK),) NETWORK_OPT += -DUSE_SHARED 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 +CFLAGS_GIT = -DSIM_GIT_COMMIT_ID=\"$(GIT_COMMIT_ID)\" ifneq ($(DEBUG),) CFLAGS_G = -g -ggdb -g3 CFLAGS_O = -O0 @@ -406,6 +413,10 @@ ifneq (clean,$(MAKECMDGOALS)) ifneq (,$(NETWORK_FEATURES)) $(info *** $(NETWORK_FEATURES).) endif + ifneq (,$(GIT_COMMIT_ID)) + $(info ***) + $(info *** git commit id is $(GIT_COMMIT_ID).) + endif $(info ***) endif ifneq ($(DONT_USE_ROMS),) @@ -419,7 +430,7 @@ endif CC_STD = -std=c99 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) # @@ -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_pag.c ${PDP10D}/pdp10_rp.c ${PDP10D}/pdp10_sys.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 PDP10_OPT = -DVM_PDP10 -DUSE_INT64 -I ${PDP10D} -I ${PDP11D} diff --git a/scp.c b/scp.c index f9043510..fb48f579 100644 --- a/scp.c +++ b/scp.c @@ -1003,9 +1003,29 @@ if (*cptr) { if (*cptr) return SCPE_2MARG; if ((cmdp = find_cmd (gbuf))) { - fputs (cmdp->help, stdout); - if (sim_log) - fputs (cmdp->help, sim_log); + if (cmdp->help) { + fputs (cmdp->help, stdout); + if (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; } @@ -1482,7 +1502,7 @@ t_stat shift_args (char *do_arg[], size_t arg_count) { size_t i; -for (i=1; iserport) { else /* Telnet connection */ if (lp->sock) { sim_close_sock (lp->sock, 0); /* close socket */ + lp->sock = 0; lp->conn = FALSE; 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)); } +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). @@ -1430,7 +1463,7 @@ while (*tptr) { if ((NULL == cptr) || ('\0' == *cptr)) return SCPE_ARG; line = (int32) get_uint (cptr, 10, mp->lines, &r); - if (r != SCPE_OK) + if ((r != SCPE_OK) || (mp->lines == 1)) return SCPE_ARG; continue; } @@ -1569,17 +1602,17 @@ while (*tptr) { } } 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 */ if (r != SCPE_OK) return r; if (sock == INVALID_SOCKET) /* open error */ 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); if (sim_log) fprintf (sim_log, "Listening on port %s\n", listen); @@ -1595,16 +1628,31 @@ while (*tptr) { tmxr_init_line (lp); /* initialize line state */ 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 (mp->lines > 1) return SCPE_ARG; /* ambiguous */ lp = &mp->ldsc[0]; - lp->destination = malloc(1+strlen(destination)); - strcpy (lp->destination, destination); - serport = sim_open_serial (lp->destination, lp, &r); + 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)); + strcpy (lp->destination, destination); lp->mp = mp; lp->serport = serport; lp->ser_connect_pending = TRUE; @@ -1621,6 +1669,9 @@ while (*tptr) { else { sock = sim_connect_sock (destination, "localhost", NULL); if (sock != INVALID_SOCKET) { + _mux_detach_line (lp, FALSE, TRUE); + lp->destination = malloc(1+strlen(destination)); + strcpy (lp->destination, destination); lp->mp = mp; lp->connecting = sock; lp->ipad = malloc (1 + strlen (lp->destination)); @@ -1671,32 +1722,12 @@ while (*tptr) { } } 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 */ if (r != SCPE_OK) return r; if (sock == INVALID_SOCKET) /* open error */ return SCPE_OPENERR; + _mux_detach_line (lp, TRUE, FALSE); printf ("Line %d Listening on port %s\n", line, listen); if (sim_log) fprintf (sim_log, "Line %d Listening on port %s\n", line, listen); @@ -1709,10 +1740,11 @@ while (*tptr) { lp->notelnet = mp->notelnet; } if (destination[0]) { - lp->destination = malloc(1+strlen(destination)); - strcpy (lp->destination, destination); - serport = sim_open_serial (lp->destination, lp, &r); + serport = sim_open_serial (destination, lp, &r); if (serport != INVALID_HANDLE) { + _mux_detach_line (lp, TRUE, TRUE); + lp->destination = malloc(1+strlen(destination)); + strcpy (lp->destination, destination); lp->serport = serport; lp->ser_connect_pending = TRUE; lp->notelnet = TRUE; @@ -1728,6 +1760,9 @@ while (*tptr) { else { sock = sim_connect_sock (destination, "localhost", NULL); if (sock != INVALID_SOCKET) { + _mux_detach_line (lp, FALSE, TRUE); + lp->destination = malloc(1+strlen(destination)); + strcpy (lp->destination, destination); lp->connecting = sock; lp->ipad = malloc (1 + strlen (lp->destination)); strcpy (lp->ipad, lp->destination);