pdp11_vh.c: - Added debugging support to trace register, interrupt
and data traffic (SET VH DEBUG[=REG;INT;XMT;RCV]) - Added SET LOG and SET NOLOG support for logging mux traffic - Fixed SET VH LINES=n to correctly adjust the number of lines available to be 8, 16, 24, or 32. - Fixed performance issue avoiding redundant polling in unit service routine (removed 75% of polling overhead) pdp11_dz.c: - Added debugging support to trace register, interrupt and data traffic (SET VH DEBUG[=REG;INT;XMT;RCV])
This commit is contained in:
parent
338ad5147b
commit
89a27e0816
2 changed files with 1173 additions and 1017 deletions
|
@ -160,6 +160,20 @@ int32 dz_auto = 0; /* autodiscon enabled */
|
||||||
TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { 0 }; /* line descriptors */
|
TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { 0 }; /* line descriptors */
|
||||||
TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, dz_ldsc }; /* mux descriptor */
|
TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, dz_ldsc }; /* mux descriptor */
|
||||||
|
|
||||||
|
/* debugging bitmaps */
|
||||||
|
#define DBG_REG 0x0001 /* trace read/write registers */
|
||||||
|
#define DBG_INT 0x0002 /* display transfer requests */
|
||||||
|
#define DBG_XMT TMXR_DBG_XMT /* display Transmitted Data */
|
||||||
|
#define DBG_RCV TMXR_DBG_RCV /* display Received Data */
|
||||||
|
|
||||||
|
DEBTAB dz_debug[] = {
|
||||||
|
{"REG", DBG_REG},
|
||||||
|
{"INT", DBG_INT},
|
||||||
|
{"XMT", DBG_XMT},
|
||||||
|
{"RCV", DBG_RCV},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
DEVICE dz_dev;
|
DEVICE dz_dev;
|
||||||
t_stat dz_rd (int32 *data, int32 PA, int32 access);
|
t_stat dz_rd (int32 *data, int32 PA, int32 access);
|
||||||
t_stat dz_wr (int32 data, int32 PA, int32 access);
|
t_stat dz_wr (int32 data, int32 PA, int32 access);
|
||||||
|
@ -249,9 +263,16 @@ DEVICE dz_dev = {
|
||||||
1, DEV_RDX, 8, 1, DEV_RDX, 8,
|
1, DEV_RDX, 8, 1, DEV_RDX, 8,
|
||||||
&tmxr_ex, &tmxr_dep, &dz_reset,
|
&tmxr_ex, &tmxr_dep, &dz_reset,
|
||||||
NULL, &dz_attach, &dz_detach,
|
NULL, &dz_attach, &dz_detach,
|
||||||
&dz_dib, DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_UBUS | DEV_QBUS
|
&dz_dib, DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_UBUS | DEV_QBUS | DEV_DEBUG,
|
||||||
|
0, dz_debug
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Register names for Debug tracing */
|
||||||
|
static char *dz_rd_regs[] =
|
||||||
|
{"CSR ", "RBUF", "TCR ", "MSR " };
|
||||||
|
static char *dz_wr_regs[] =
|
||||||
|
{"CSR ", "LPR ", "TCR ", "TDR "};
|
||||||
|
|
||||||
/* IO dispatch routines, I/O addresses 177601x0 - 177601x7 */
|
/* IO dispatch routines, I/O addresses 177601x0 - 177601x7 */
|
||||||
|
|
||||||
t_stat dz_rd (int32 *data, int32 PA, int32 access)
|
t_stat dz_rd (int32 *data, int32 PA, int32 access)
|
||||||
|
@ -289,6 +310,8 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sim_debug(DBG_REG, &dz_dev, "dz_rd(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, dz_rd_regs[(PA >> 1) & 03], access, *data);
|
||||||
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +321,8 @@ int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
|
||||||
int32 i, c, line;
|
int32 i, c, line;
|
||||||
TMLN *lp;
|
TMLN *lp;
|
||||||
|
|
||||||
|
sim_debug(DBG_REG, &dz_dev, "dz_wr(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, dz_wr_regs[(PA >> 1) & 03], access, data);
|
||||||
|
|
||||||
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||||
|
|
||||||
case 00: /* CSR */
|
case 00: /* CSR */
|
||||||
|
@ -517,6 +542,7 @@ int32 dz;
|
||||||
|
|
||||||
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
|
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
|
||||||
if (dz_rxi & (1 << dz)) {
|
if (dz_rxi & (1 << dz)) {
|
||||||
|
sim_debug(DBG_INT, &dz_dev, "dz_rzinta(dz=%d)\n", dz);
|
||||||
dz_clr_rxint (dz); /* clear intr */
|
dz_clr_rxint (dz); /* clear intr */
|
||||||
return (dz_dib.vec + (dz * 010)); /* return vector */
|
return (dz_dib.vec + (dz * 010)); /* return vector */
|
||||||
}
|
}
|
||||||
|
@ -546,6 +572,7 @@ int32 dz;
|
||||||
|
|
||||||
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
|
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
|
||||||
if (dz_txi & (1 << dz)) {
|
if (dz_txi & (1 << dz)) {
|
||||||
|
sim_debug(DBG_INT, &dz_dev, "dz_txinta(dz=%d)\n", dz);
|
||||||
dz_clr_txint (dz); /* clear intr */
|
dz_clr_txint (dz); /* clear intr */
|
||||||
return (dz_dib.vec + 4 + (dz * 010)); /* return vector */
|
return (dz_dib.vec + 4 + (dz * 010)); /* return vector */
|
||||||
}
|
}
|
||||||
|
|
191
PDP11/pdp11_vh.c
191
PDP11/pdp11_vh.c
|
@ -26,6 +26,13 @@
|
||||||
|
|
||||||
vh DHQ11 asynch multiplexor for SIMH
|
vh DHQ11 asynch multiplexor for SIMH
|
||||||
|
|
||||||
|
02-Jun-11 MP Added debugging support to trace register, interrupt
|
||||||
|
and data traffic (SET VH DEBUG[=REG;INT;XMT;RCV])
|
||||||
|
Added SET LOG and SET NOLOG support for logging mux
|
||||||
|
traffic
|
||||||
|
Fixed SET VH LINES=n to correctly adjust the number
|
||||||
|
of lines available to be 8, 16, 24, or 32.
|
||||||
|
Fixed performance issue avoiding redundant polling
|
||||||
03-Jan-10 JAD Eliminate gcc warnings
|
03-Jan-10 JAD Eliminate gcc warnings
|
||||||
19-Nov-08 RMS Revised for common TMXR show routines
|
19-Nov-08 RMS Revised for common TMXR show routines
|
||||||
18-Jun-07 RMS Added UNIT_IDLE flag
|
18-Jun-07 RMS Added UNIT_IDLE flag
|
||||||
|
@ -82,7 +89,6 @@ extern int32 cpu_opt;
|
||||||
extern int32 tmxr_poll, clk_tps;
|
extern int32 tmxr_poll, clk_tps;
|
||||||
/* convert ms to SIMH time units based on tmxr_poll polls per second */
|
/* convert ms to SIMH time units based on tmxr_poll polls per second */
|
||||||
#define MS2SIMH(ms) (((ms) * clk_tps) / 1000)
|
#define MS2SIMH(ms) (((ms) * clk_tps) / 1000)
|
||||||
extern FILE *sim_log;
|
|
||||||
|
|
||||||
#ifndef VH_MUXES
|
#ifndef VH_MUXES
|
||||||
#define VH_MUXES (4)
|
#define VH_MUXES (4)
|
||||||
|
@ -284,6 +290,20 @@ static TMLN vh_ldsc[VH_MUXES * VH_LINES] = { { 0 } };
|
||||||
static TMXR vh_desc = { VH_MUXES * VH_LINES, 0, 0, vh_ldsc };
|
static TMXR vh_desc = { VH_MUXES * VH_LINES, 0, 0, vh_ldsc };
|
||||||
static TMLX vh_parm[VH_MUXES * VH_LINES] = { { 0 } };
|
static TMLX vh_parm[VH_MUXES * VH_LINES] = { { 0 } };
|
||||||
|
|
||||||
|
/* debugging bitmaps */
|
||||||
|
#define DBG_REG 0x0001 /* trace read/write registers */
|
||||||
|
#define DBG_INT 0x0002 /* display transfer requests */
|
||||||
|
#define DBG_XMT TMXR_DBG_XMT /* display Transmitted Data */
|
||||||
|
#define DBG_RCV TMXR_DBG_RCV /* display Received Data */
|
||||||
|
|
||||||
|
DEBTAB vh_debug[] = {
|
||||||
|
{"REG", DBG_REG},
|
||||||
|
{"INT", DBG_INT},
|
||||||
|
{"XMT", DBG_XMT},
|
||||||
|
{"RCV", DBG_RCV},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
/* Forward references */
|
/* Forward references */
|
||||||
static t_stat vh_rd (int32 *data, int32 PA, int32 access);
|
static t_stat vh_rd (int32 *data, int32 PA, int32 access);
|
||||||
static t_stat vh_wr (int32 data, int32 PA, int32 access);
|
static t_stat vh_wr (int32 data, int32 PA, int32 access);
|
||||||
|
@ -294,11 +314,15 @@ static t_stat vh_clear (int32 vh, t_bool flag);
|
||||||
static t_stat vh_reset (DEVICE *dptr);
|
static t_stat vh_reset (DEVICE *dptr);
|
||||||
static t_stat vh_attach (UNIT *uptr, char *cptr);
|
static t_stat vh_attach (UNIT *uptr, char *cptr);
|
||||||
static t_stat vh_detach (UNIT *uptr);
|
static t_stat vh_detach (UNIT *uptr);
|
||||||
static t_stat vh_show_debug (FILE *st, UNIT *uptr, int32 val, void *desc);
|
static t_stat vh_show_detail (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
static t_stat vh_show_rbuf (FILE *st, UNIT *uptr, int32 val, void *desc);
|
static t_stat vh_show_rbuf (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
static t_stat vh_show_txq (FILE *st, UNIT *uptr, int32 val, void *desc);
|
static t_stat vh_show_txq (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
static t_stat vh_putc (int32 vh, TMLX *lp, int32 chan, int32 data);
|
static t_stat vh_putc (int32 vh, TMLX *lp, int32 chan, int32 data);
|
||||||
static void doDMA (int32 vh, int32 chan);
|
static void doDMA (int32 vh, int32 chan);
|
||||||
|
static t_stat vh_setnl (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
static t_stat vh_set_log (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
static t_stat vh_set_nolog (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
static t_stat vh_show_log (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
|
|
||||||
int32 tmxr_send_buffered_data (TMLN *lp);
|
int32 tmxr_send_buffered_data (TMLN *lp);
|
||||||
|
|
||||||
|
@ -317,9 +341,6 @@ static DIB vh_dib = {
|
||||||
|
|
||||||
static UNIT vh_unit[VH_MUXES] = {
|
static UNIT vh_unit[VH_MUXES] = {
|
||||||
{ UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) },
|
{ UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) },
|
||||||
{ UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) },
|
|
||||||
{ UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) },
|
|
||||||
{ UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const REG vh_reg[] = {
|
static const REG vh_reg[] = {
|
||||||
|
@ -344,23 +365,28 @@ static const MTAB vh_mod[] = {
|
||||||
&set_vec, &show_vec_mux, (void *) &vh_desc },
|
&set_vec, &show_vec_mux, (void *) &vh_desc },
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
|
||||||
&set_addr_flt, NULL, NULL },
|
&set_addr_flt, NULL, NULL },
|
||||||
/* this one is dangerous, don't use yet */
|
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, "LINES", "LINES",
|
{ MTAB_XTD|MTAB_VDV, 0, "LINES", "LINES",
|
||||||
NULL, &tmxr_show_lines, (void *) &vh_desc },
|
&vh_setnl, &tmxr_show_lines, (void *) &vh_desc },
|
||||||
{ UNIT_ATT, UNIT_ATT, "summary", NULL,
|
{ UNIT_ATT, UNIT_ATT, "summary", NULL,
|
||||||
NULL, &tmxr_show_summ, (void *) &vh_desc },
|
NULL, &tmxr_show_summ, (void *) &vh_desc },
|
||||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
|
{ MTAB_XTD|MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
|
||||||
NULL, &tmxr_show_cstat, (void *) &vh_desc },
|
NULL, &tmxr_show_cstat, (void *) &vh_desc },
|
||||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
|
{ MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
|
||||||
NULL, &tmxr_show_cstat, (void *) &vh_desc },
|
NULL, &tmxr_show_cstat, (void *) &vh_desc },
|
||||||
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
|
{ MTAB_XTD|MTAB_VDV, 1, NULL, "DISCONNECT",
|
||||||
&tmxr_dscln, NULL, &vh_desc },
|
&tmxr_dscln, NULL, &vh_desc },
|
||||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "DEBUG", NULL,
|
{ MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "DETAIL", NULL,
|
||||||
NULL, &vh_show_debug, NULL },
|
NULL, &vh_show_detail, NULL },
|
||||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "RBUF", NULL,
|
{ MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "RBUF", NULL,
|
||||||
NULL, &vh_show_rbuf, NULL },
|
NULL, &vh_show_rbuf, NULL },
|
||||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "TXQ", NULL,
|
{ MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "TXQ", NULL,
|
||||||
NULL, &vh_show_txq, NULL },
|
NULL, &vh_show_txq, NULL },
|
||||||
|
{ MTAB_XTD|MTAB_VDV | MTAB_NC, 0, NULL, "LOG",
|
||||||
|
&vh_set_log, NULL, &vh_desc },
|
||||||
|
{ MTAB_XTD|MTAB_VDV | MTAB_NC, 0, NULL, "NOLOG",
|
||||||
|
&vh_set_nolog, NULL, &vh_desc },
|
||||||
|
{ MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "LOG", NULL,
|
||||||
|
NULL, &vh_show_log, &vh_desc },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -381,10 +407,21 @@ DEVICE vh_dev = {
|
||||||
NULL, /* boot routine */
|
NULL, /* boot routine */
|
||||||
&vh_attach, /* attach routine */
|
&vh_attach, /* attach routine */
|
||||||
&vh_detach, /* detach routine */
|
&vh_detach, /* detach routine */
|
||||||
(void *)&vh_dib, /* context */
|
(void *)&vh_dib,/* context */
|
||||||
DEV_FLTA | DEV_DISABLE | DEV_DIS |DEV_NET | DEV_QBUS | DEV_UBUS, /* flags */
|
DEV_FLTA | DEV_DISABLE | DEV_DIS |DEV_NET | DEV_QBUS | DEV_UBUS | DEV_DEBUG, /* flags */
|
||||||
|
0, vh_debug
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Register names for Debug tracing */
|
||||||
|
static char *vh_rd_dhv_regs[] =
|
||||||
|
{"CSR ", "RBUF ", "LPR ", "STAT ", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" };
|
||||||
|
static char *vh_wr_dhv_regs[] =
|
||||||
|
{"CSR ", "TXCHAR", "LPR ", "STAT ", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" };
|
||||||
|
static char *vh_rd_dhu_regs[] =
|
||||||
|
{"CSR ", "RBUF ", "LPR ", "FIFOSZ", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" };
|
||||||
|
static char *vh_wr_dhu_regs[] =
|
||||||
|
{"CSR ", "RXTIMR", "LPR ", "FIFODT", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" };
|
||||||
|
|
||||||
/* Interrupt routines */
|
/* Interrupt routines */
|
||||||
|
|
||||||
static void vh_clr_rxint ( int32 vh )
|
static void vh_clr_rxint ( int32 vh )
|
||||||
|
@ -408,8 +445,9 @@ static int32 vh_rxinta (void)
|
||||||
{
|
{
|
||||||
int32 vh;
|
int32 vh;
|
||||||
|
|
||||||
for (vh = 0; vh < VH_MUXES; vh++) {
|
for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) {
|
||||||
if (vh_rxi & (1 << vh)) {
|
if (vh_rxi & (1 << vh)) {
|
||||||
|
sim_debug(DBG_INT, &vh_dev, "vh_rzinta(vh=%d)\n", vh);
|
||||||
vh_clr_rxint (vh);
|
vh_clr_rxint (vh);
|
||||||
return (vh_dib.vec + (vh * 010));
|
return (vh_dib.vec + (vh * 010));
|
||||||
}
|
}
|
||||||
|
@ -438,8 +476,9 @@ static int32 vh_txinta (void)
|
||||||
{
|
{
|
||||||
int32 vh;
|
int32 vh;
|
||||||
|
|
||||||
for (vh = 0; vh < VH_MUXES; vh++) {
|
for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) {
|
||||||
if (vh_txi & (1 << vh)) {
|
if (vh_txi & (1 << vh)) {
|
||||||
|
sim_debug(DBG_INT, &vh_dev, "vh_txinta(vh=%d)\n", vh);
|
||||||
vh_clr_txint (vh);
|
vh_clr_txint (vh);
|
||||||
return (vh_dib.vec + 4 + (vh * 010));
|
return (vh_dib.vec + 4 + (vh * 010));
|
||||||
}
|
}
|
||||||
|
@ -772,6 +811,10 @@ fprintf (stderr, "\rtqln %d\n", 64 - tmxr_tqln (lp->tmln));
|
||||||
/* can't happen */
|
/* can't happen */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sim_debug(DBG_REG, &vh_dev, "vh_rd(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA,
|
||||||
|
((vh_unit[vh].flags & UNIT_MODEDHU) ? vh_rd_dhu_regs : vh_rd_dhv_regs)[(PA >> 1) & 07], access, data);
|
||||||
|
|
||||||
return (SCPE_OK);
|
return (SCPE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,6 +825,9 @@ static t_stat vh_wr ( int32 data,
|
||||||
int32 vh = ((PA - vh_dib.ba) >> 4) & VH_MNOMASK, line;
|
int32 vh = ((PA - vh_dib.ba) >> 4) & VH_MNOMASK, line;
|
||||||
TMLX *lp;
|
TMLX *lp;
|
||||||
|
|
||||||
|
sim_debug(DBG_REG, &vh_dev, "vh_wr(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA,
|
||||||
|
((vh_unit[vh].flags & UNIT_MODEDHU) ? vh_wr_dhu_regs : vh_wr_dhv_regs)[(PA >> 1) & 07], access, data);
|
||||||
|
|
||||||
switch ((PA >> 1) & 7) {
|
switch ((PA >> 1) & 7) {
|
||||||
case 0: /* CSR, but no read-modify-write */
|
case 0: /* CSR, but no read-modify-write */
|
||||||
if (access == WRITEB)
|
if (access == WRITEB)
|
||||||
|
@ -791,6 +837,7 @@ static t_stat vh_wr ( int32 data,
|
||||||
if (data & CSR_MASTER_RESET) {
|
if (data & CSR_MASTER_RESET) {
|
||||||
if ((vh_unit[vh].flags & UNIT_MODEDHU) && (data & CSR_SKIP))
|
if ((vh_unit[vh].flags & UNIT_MODEDHU) && (data & CSR_SKIP))
|
||||||
data &= ~CSR_MASTER_RESET;
|
data &= ~CSR_MASTER_RESET;
|
||||||
|
if (vh == 0) /* Only start unit service on the first unit. Units are polled there */
|
||||||
sim_activate (&vh_unit[vh], clk_cosched (tmxr_poll));
|
sim_activate (&vh_unit[vh], clk_cosched (tmxr_poll));
|
||||||
/* vh_mcount[vh] = 72; */ /* 1.2 seconds */
|
/* vh_mcount[vh] = 72; */ /* 1.2 seconds */
|
||||||
vh_mcount[vh] = MS2SIMH (1200); /* 1.2 seconds */
|
vh_mcount[vh] = MS2SIMH (1200); /* 1.2 seconds */
|
||||||
|
@ -1083,7 +1130,7 @@ static t_stat vh_svc ( UNIT *uptr )
|
||||||
int32 vh, newln, i;
|
int32 vh, newln, i;
|
||||||
|
|
||||||
/* scan all muxes for countdown reset */
|
/* scan all muxes for countdown reset */
|
||||||
for (vh = 0; vh < VH_MUXES; vh++) {
|
for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) {
|
||||||
if (vh_csr[vh] & CSR_MASTER_RESET) {
|
if (vh_csr[vh] & CSR_MASTER_RESET) {
|
||||||
if (vh_mcount[vh] != 0)
|
if (vh_mcount[vh] != 0)
|
||||||
vh_mcount[vh] -= 1;
|
vh_mcount[vh] -= 1;
|
||||||
|
@ -1109,17 +1156,17 @@ static t_stat vh_svc ( UNIT *uptr )
|
||||||
/* BUG: should check for overflow above */
|
/* BUG: should check for overflow above */
|
||||||
}
|
}
|
||||||
/* scan all muxes, lines for DMA to complete; start every 3.12ms */
|
/* scan all muxes, lines for DMA to complete; start every 3.12ms */
|
||||||
for (vh = 0; vh < VH_MUXES; vh++) {
|
for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) {
|
||||||
for (i = 0; i < VH_LINES; i++)
|
for (i = 0; i < VH_LINES; i++)
|
||||||
doDMA (vh, i);
|
doDMA (vh, i);
|
||||||
}
|
}
|
||||||
/* interrupt driven in a real DHQ */
|
/* interrupt driven in a real DHQ */
|
||||||
tmxr_poll_rx (&vh_desc);
|
tmxr_poll_rx (&vh_desc);
|
||||||
for (vh = 0; vh < VH_MUXES; vh++)
|
for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++)
|
||||||
vh_getc (vh);
|
vh_getc (vh);
|
||||||
tmxr_poll_tx (&vh_desc);
|
tmxr_poll_tx (&vh_desc);
|
||||||
/* scan all DHU-mode muxes for RX FIFO timeout */
|
/* scan all DHU-mode muxes for RX FIFO timeout */
|
||||||
for (vh = 0; vh < VH_MUXES; vh++) {
|
for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) {
|
||||||
if (vh_unit[vh].flags & UNIT_MODEDHU) {
|
if (vh_unit[vh].flags & UNIT_MODEDHU) {
|
||||||
if (vh_timeo[vh] && (vh_csr[vh] & CSR_RXIE)) {
|
if (vh_timeo[vh] && (vh_csr[vh] & CSR_RXIE)) {
|
||||||
vh_timeo[vh] -= 1;
|
vh_timeo[vh] -= 1;
|
||||||
|
@ -1234,9 +1281,9 @@ static t_stat vh_reset ( DEVICE *dptr )
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
for (i = 0; i < (VH_MUXES * VH_LINES); i++)
|
for (i = 0; i < vh_desc.lines; i++)
|
||||||
vh_parm[i].tmln = &vh_ldsc[i];
|
vh_parm[i].tmln = &vh_ldsc[i];
|
||||||
for (i = 0; i < VH_MUXES; i++) {
|
for (i = 0; i < vh_desc.lines/VH_LINES; i++) {
|
||||||
#if defined (VM_PDP11)
|
#if defined (VM_PDP11)
|
||||||
/* if Unibus, force DHU mode */
|
/* if Unibus, force DHU mode */
|
||||||
if (UNIBUS)
|
if (UNIBUS)
|
||||||
|
@ -1247,9 +1294,8 @@ static t_stat vh_reset ( DEVICE *dptr )
|
||||||
vh_rxi = vh_txi = 0;
|
vh_rxi = vh_txi = 0;
|
||||||
CLR_INT (VHRX);
|
CLR_INT (VHRX);
|
||||||
CLR_INT (VHTX);
|
CLR_INT (VHTX);
|
||||||
for (i = 0; i < VH_MUXES; i++)
|
sim_cancel (&vh_unit[0]);
|
||||||
sim_cancel (&vh_unit[i]);
|
return (auto_config (dptr->name, (dptr->flags & DEV_DIS) ? 0 : vh_desc.lines/VH_LINES));
|
||||||
return (auto_config (dptr->name, (dptr->flags & DEV_DIS) ? 0 : VH_MUXES));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1266,7 +1312,7 @@ static t_stat vh_detach ( UNIT *uptr )
|
||||||
return (tmxr_detach (&vh_desc, uptr));
|
return (tmxr_detach (&vh_desc, uptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug_line ( FILE *st,
|
static void vh_detail_line ( FILE *st,
|
||||||
int32 vh,
|
int32 vh,
|
||||||
int32 chan )
|
int32 chan )
|
||||||
{
|
{
|
||||||
|
@ -1283,7 +1329,7 @@ static void debug_line ( FILE *st,
|
||||||
lp->tmln->rcve, lp->tmln->xmte);
|
lp->tmln->rcve, lp->tmln->xmte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat vh_show_debug ( FILE *st,
|
static t_stat vh_show_detail ( FILE *st,
|
||||||
UNIT *uptr,
|
UNIT *uptr,
|
||||||
int32 val,
|
int32 val,
|
||||||
void *desc )
|
void *desc )
|
||||||
|
@ -1291,14 +1337,14 @@ static t_stat vh_show_debug ( FILE *st,
|
||||||
int32 i, j;
|
int32 i, j;
|
||||||
|
|
||||||
fprintf (st, "VH:\trxi %d, txi %d\n", vh_rxi, vh_txi);
|
fprintf (st, "VH:\trxi %d, txi %d\n", vh_rxi, vh_txi);
|
||||||
for (i = 0; i < VH_MUXES; i++) {
|
for (i = 0; i < vh_desc.lines/VH_LINES; i++) {
|
||||||
fprintf (st, "VH%d:\tmode %s, crit %d\n", i,
|
fprintf (st, "VH%d:\tmode %s, crit %d\n", i,
|
||||||
vh_unit[i].flags & UNIT_MODEDHU ? "DHU" : "DHV",
|
vh_unit[i].flags & UNIT_MODEDHU ? "DHU" : "DHV",
|
||||||
vh_crit & (1 << i));
|
vh_crit & (1 << i));
|
||||||
fprintf (st, "\tCSR %06o, mcount %d, rbuf_idx %d, txq_idx %d\n",
|
fprintf (st, "\tCSR %06o, mcount %d, rbuf_idx %d, txq_idx %d\n",
|
||||||
vh_csr[i], vh_mcount[i], rbuf_idx[i], txq_idx[i]);
|
vh_csr[i], vh_mcount[i], rbuf_idx[i], txq_idx[i]);
|
||||||
for (j = 0; j < VH_LINES; j++)
|
for (j = 0; j < VH_LINES; j++)
|
||||||
debug_line (st, i, j);
|
vh_detail_line (st, i, j);
|
||||||
}
|
}
|
||||||
return (SCPE_OK);
|
return (SCPE_OK);
|
||||||
}
|
}
|
||||||
|
@ -1327,3 +1373,86 @@ static t_stat vh_show_txq ( FILE *st,
|
||||||
return (SCPE_OK);
|
return (SCPE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SET LINES processor */
|
||||||
|
|
||||||
|
static t_stat vh_setnl (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
int32 newln, i, t, ndev;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (cptr == NULL)
|
||||||
|
return SCPE_ARG;
|
||||||
|
newln = (int32) get_uint (cptr, 10, (VH_MUXES * VH_LINES), &r);
|
||||||
|
if ((r != SCPE_OK) || (newln == vh_desc.lines))
|
||||||
|
return r;
|
||||||
|
if ((newln == 0) || (newln % VH_LINES))
|
||||||
|
return SCPE_ARG;
|
||||||
|
if (newln < vh_desc.lines) {
|
||||||
|
for (i = newln, t = 0; i < vh_desc.lines; i++)
|
||||||
|
t = t | vh_ldsc[i].conn;
|
||||||
|
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
|
||||||
|
return SCPE_OK;
|
||||||
|
for (i = newln; i < vh_desc.lines; i++) {
|
||||||
|
if (vh_ldsc[i].conn) {
|
||||||
|
tmxr_linemsg (&vh_ldsc[i], "\r\nOperator disconnected line\r\n");
|
||||||
|
tmxr_reset_ln (&vh_ldsc[i]); /* reset line */
|
||||||
|
}
|
||||||
|
if ((i % VH_LINES) == (VH_LINES - 1))
|
||||||
|
vh_clear (i / VH_LINES, TRUE); /* reset mux */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vh_dib.lnt = (newln / VH_LINES) * IOLN_VH; /* set length */
|
||||||
|
vh_desc.lines = newln;
|
||||||
|
ndev = ((vh_dev.flags & DEV_DIS)? 0: (vh_desc.lines / VH_LINES));
|
||||||
|
vh_dev.numunits = (newln / VH_LINES);
|
||||||
|
return auto_config (vh_dev.name, ndev); /* auto config */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SET LOG processor */
|
||||||
|
|
||||||
|
static t_stat vh_set_log (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
char *tptr;
|
||||||
|
t_stat r;
|
||||||
|
int32 ln;
|
||||||
|
|
||||||
|
if (cptr == NULL)
|
||||||
|
return SCPE_ARG;
|
||||||
|
tptr = strchr (cptr, '=');
|
||||||
|
if ((tptr == NULL) || (*tptr == 0))
|
||||||
|
return SCPE_ARG;
|
||||||
|
*tptr++ = 0;
|
||||||
|
ln = (int32) get_uint (cptr, 10, (VH_MUXES * VH_LINES), &r);
|
||||||
|
if ((r != SCPE_OK) || (ln >= vh_desc.lines))
|
||||||
|
return SCPE_ARG;
|
||||||
|
return tmxr_set_log (NULL, ln, tptr, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SET NOLOG processor */
|
||||||
|
|
||||||
|
static t_stat vh_set_nolog (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
int32 ln;
|
||||||
|
|
||||||
|
if (cptr == NULL)
|
||||||
|
return SCPE_ARG;
|
||||||
|
ln = (int32) get_uint (cptr, 10, (VH_MUXES * VH_LINES), &r);
|
||||||
|
if ((r != SCPE_OK) || (ln >= vh_desc.lines))
|
||||||
|
return SCPE_ARG;
|
||||||
|
return tmxr_set_nolog (NULL, ln, NULL, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SHOW LOG processor */
|
||||||
|
|
||||||
|
static t_stat vh_show_log (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < vh_desc.lines; i++) {
|
||||||
|
fprintf (st, "line %d: ", i);
|
||||||
|
tmxr_show_log (st, NULL, i, desc);
|
||||||
|
fprintf (st, "\n");
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue