diff --git a/SDS/sds_io.c b/SDS/sds_io.c index dea1a804..e021cf5f 100644 --- a/SDS/sds_io.c +++ b/SDS/sds_io.c @@ -439,6 +439,8 @@ switch (mod) { case 3: /* special */ dev = I_GETDEV3 (inst); /* special device */ + if (dev == DEV3_SMUX && !(cpu_unit.flags & UNIT_GENIE)) + dev = DEV3_GMUX; if (dev3_dsp[dev]) /* defined? */ return dev3_dsp[dev] (IO_CONN, inst, NULL); CRETINS; @@ -500,6 +502,8 @@ switch (mod) { case 3: /* special */ dev = I_GETDEV3 (inst); /* special device */ + if (dev == DEV3_SMUX && !(cpu_unit.flags & UNIT_GENIE)) + dev = DEV3_GMUX; if (dev3_dsp[dev]) dev3_dsp[dev] (IO_SKS, inst, dat); else CRETINS; @@ -547,9 +551,9 @@ return SCPE_OK; t_stat pot_fork (uint32 num, uint32 *dat) { uint32 igrp = SYI_GETGRP (*dat); /* get group */ -uint32 fbit = (1 << (VEC_FORK & 017)); /* bit in group */ +uint32 fbit = (0100000 >> (VEC_FORK & 017)); /* bit in group */ -if (igrp == (VEC_FORK / 020)) { /* right group? */ +if (igrp == ((VEC_FORK-0200) / 020)) { /* right group? */ if ((*dat & SYI_ARM) && (*dat & fbit)) /* arm, bit set? */ int_req = int_req | INT_FORK; if ((*dat & SYI_DIS) && !(*dat & fbit)) /* disarm, bit clr? */ diff --git a/SDS/sds_mux.c b/SDS/sds_mux.c index 2b5054ab..abc8a5d4 100644 --- a/SDS/sds_mux.c +++ b/SDS/sds_mux.c @@ -54,6 +54,7 @@ #define MUX_SETFLG(l,x) mux_flags[((l) * MUX_FLAGS) + (x)] = 1 #define MUX_SETINT(x) int_req = int_req | (INT_MUXR >> (x)) #define MUX_CLRINT(x) int_req = int_req & ~(INT_MUXR >> (x)) +#define MUX_CHKINT(x) (int_req & (INT_MUXR >> (x))) /* PIN/POT */ @@ -274,7 +275,7 @@ switch (fnc) { ((inst & SKS_DSR) && !(mux_sta[ln] & MUX_SDSR))) *dat = 0; /* no skip if fail */ } - else CRETINS; + else CRETINS; default: return SCPE_IERR; @@ -290,6 +291,8 @@ t_stat pin_mux (uint32 num, uint32 *dat) uint32 ln = mux_scan >> 2; uint32 flag = mux_scan & MUX_FLAGMASK; +if (!mux_slck) /* scanner must be locked */ + return SCPE_IERR; mux_scan = mux_scan & MUX_SCANMASK; /* mask scan */ mux_flags[mux_scan] = 0; /* clear flag */ if (flag == MUX_FRCV) { /* rcv event? */ @@ -333,6 +336,12 @@ else { /* enabled */ else mux_sta[ln] = mux_sta[ln] & ~MUX_SXIE; mux_sta[ln] = mux_sta[ln] | MUX_SLNE; /* line is enabled */ mux_ldsc[ln].rcve = 1; + if ((*dat & POT_NOX) && /* if no transmit char && */ + (mux_sta[ln] & MUX_SXIE) && /* line enabled && */ + !sim_is_active (&muxl_unit[ln])) { /* tx buffer empty */ + MUX_SETFLG (ln, MUX_FXMT); /* then set flag to request */ + mux_scan_next (); /* a tx interrupt */ + } } return SCPE_OK; } @@ -407,7 +416,23 @@ if (mux_sta[ln] & MUX_SXIE) { return SCPE_OK; } -/* Kick scanner */ +/* Kick scanner +* +* Per 940 Ref Man: +* If more than one raised flag is encountered by the scanner, only +* the one of highest priority will result in an interrupt. The others +* will be ignored until the scanner has completed scanning all other +* channels. The receive flag will be given highest priority, followed +* by the transmit flag, the carrier-on flag, and the carrier-off flag. +* +* To implement, advance mux_scan to last flag of current channel (by +* merging MUX_FLAGMASK) so scan loop commences with receive flag of next +* channel. +* +* When two or more channels are active, do not queue an interrupt +* request if the same interrupt is already requesting. To do so will +* cause an interrupt to be lost. +*/ void mux_scan_next (void) { @@ -415,9 +440,12 @@ int32 i; if (mux_slck) /* locked? */ return; +mux_scan |= MUX_FLAGMASK; /* last flag of current ch. */ + /* will be Rx flag of next ch. */ for (i = 0; i < MUX_SCANMAX; i++) { /* scan flags */ mux_scan = (mux_scan + 1) & MUX_SCANMASK; /* next flag */ - if (mux_flags[mux_scan]) { /* flag set? */ + if (mux_flags[mux_scan] && /* flag set */ + !MUX_CHKINT (mux_scan & MUX_FLAGMASK)) { /* and not requesting int? */ mux_slck = 1; /* lock scanner */ MUX_SETINT (mux_scan & MUX_FLAGMASK); /* request int */ return;