Merge remote-tracking branch 'origin/master'

This commit is contained in:
Mark Pizzolato 2014-03-03 08:10:31 -08:00
commit 0c56397289
7 changed files with 157 additions and 57 deletions

View file

@ -428,9 +428,31 @@ while (reason == 0) { /* loop until halted */
int_reqhi = api_findreq (); /* recalc int req */ int_reqhi = api_findreq (); /* recalc int req */
} }
else { /* normal instr */ else { /* normal instr */
if (sim_brk_summ && sim_brk_test (P, SWMASK ('E'))) { /* breakpoint? */ if (sim_brk_summ) {
uint32 btyp = SWMASK ('E');
if (nml_mode)
btyp = SWMASK ('E') | SWMASK ('N');
else
btyp = usr_mode ? SWMASK ('E') | SWMASK ('U')
: SWMASK ('E') | SWMASK ('M');
btyp = sim_brk_test (P, btyp);
if (btyp) {
if (btyp & SWMASK ('E')) /* unqualified breakpoint? */
reason = STOP_IBKPT; /* stop simulation */ reason = STOP_IBKPT; /* stop simulation */
else switch (btyp) { /* qualified breakpoint */
case SWMASK ('M'): /* monitor mode */
reason = STOP_MBKPT; /* stop simulation */
break; break;
case SWMASK ('N'): /* normal (SDS 930) mode */
reason = STOP_NBKPT; /* stop simulation */
break;
case SWMASK ('U'): /* user mode */
reason = STOP_UBKPT; /* stop simulation */
break;
}
break;
}
} }
reason = Read (save_P = P, &inst); /* get instr */ reason = Read (save_P = P, &inst); /* get instr */
P = (P + 1) & VA_MASK; /* incr PC */ P = (P + 1) & VA_MASK; /* incr PC */
@ -448,6 +470,8 @@ while (reason == 0) { /* loop until halted */
} /* end if r == 0 */ } /* end if r == 0 */
if (reason < 0) { /* mm (fet or ex)? */ if (reason < 0) { /* mm (fet or ex)? */
pa = -reason; /* get vector */ pa = -reason; /* get vector */
if (reason == MM_MONUSR) /* record P of user-mode */
save_P = P; /* transition point */
reason = 0; /* defang */ reason = 0; /* defang */
tinst = ReadP (pa); /* get inst */ tinst = ReadP (pa); /* get inst */
if (I_GETOP (tinst) != BRM) { /* not BRM? */ if (I_GETOP (tinst) != BRM) { /* not BRM? */
@ -785,6 +809,11 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = va & VA_MASK; /* branch */ P = va & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
break; break;
case BRX: case BRX:
@ -796,6 +825,11 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = va & VA_MASK; /* branch */ P = va & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
} }
break; break;
@ -810,6 +844,11 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = (va + 1) & VA_MASK; /* branch */ P = (va + 1) & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
break; break;
case BRR: case BRR:
@ -1456,7 +1495,8 @@ pcq_r = find_reg ("PCQ", NULL, dptr);
if (pcq_r) if (pcq_r)
pcq_r->qptr = 0; pcq_r->qptr = 0;
else return SCPE_IERR; else return SCPE_IERR;
sim_brk_types = sim_brk_dflt = SWMASK ('E'); sim_brk_dflt = SWMASK ('E');
sim_brk_types = SWMASK ('E') | SWMASK ('M') | SWMASK ('N') | SWMASK ('U');
return SCPE_OK; return SCPE_OK;
} }
@ -1542,13 +1582,17 @@ return SCPE_OK;
a unit service routine and a reset routine. The service routine a unit service routine and a reset routine. The service routine
sets an interrupt that invokes the clock counter. The clock counter sets an interrupt that invokes the clock counter. The clock counter
is a "one instruction interrupt", and only MIN/SKR are valid. is a "one instruction interrupt", and only MIN/SKR are valid.
Temporarily divide rtc_tps by 2 because clock is running twice as
fast as it should. Eventually have to find problem in the clock
calibration or setup code.
*/ */
t_stat rtc_svc (UNIT *uptr) t_stat rtc_svc (UNIT *uptr)
{ {
if (rtc_pie) /* set pulse intr */ if (rtc_pie) /* set pulse intr */
int_req = int_req | INT_RTCP; int_req = int_req | INT_RTCP;
sim_activate (&rtc_unit, sim_rtcn_calb (rtc_tps, TMR_RTC)); /* reactivate */ sim_activate (&rtc_unit, sim_rtcn_calb (rtc_tps/2, TMR_RTC)); /* reactivate */
return SCPE_OK; return SCPE_OK;
} }
@ -1572,7 +1616,7 @@ if ((r = Read (va, &dat))) /* get operand */
dat = AddM24 (dat, val); /* mem +/- 1 */ dat = AddM24 (dat, val); /* mem +/- 1 */
if ((r = Write (va, dat))) /* rewrite */ if ((r = Write (va, dat))) /* rewrite */
return r; return r;
if (dat == 0) /* set clk sync int */ if ((op == MIN && dat == 0) || (dat & SIGN)) /* set clk sync int */
int_req = int_req | INT_RTCS; int_req = int_req | INT_RTCS;
return SCPE_OK; return SCPE_OK;
} }

View file

@ -52,6 +52,9 @@
#define STOP_RTCINS 12 /* rtc inst not MIN/SKR */ #define STOP_RTCINS 12 /* rtc inst not MIN/SKR */
#define STOP_ILLVEC 13 /* zero vector */ #define STOP_ILLVEC 13 /* zero vector */
#define STOP_CCT 14 /* runaway CCT */ #define STOP_CCT 14 /* runaway CCT */
#define STOP_MBKPT 15 /* monitor-mode breakpoint */
#define STOP_NBKPT 16 /* normal-mode breakpoint */
#define STOP_UBKPT 17 /* user-mode breakpoint */
/* Trap codes */ /* Trap codes */

View file

@ -330,16 +330,23 @@ switch (mod) {
if (INV_DEV (dev, ch)) /* inv dev? err */ if (INV_DEV (dev, ch)) /* inv dev? err */
CRETDEV; CRETDEV;
chan_war[ch] = chan_cnt[ch] = 0; /* init chan */ chan_war[ch] = chan_cnt[ch] = 0; /* init chan */
chan_flag[ch] = chan_dcr[ch] = 0; chan_dcr[ch] = 0;
chan_mode[ch] = chan_uar[ch] = 0; chan_uar[ch] = 0;
if (!(chan_flag[ch] & CHF_ILCE) && /* ignore if ilc */
!QAILCE (alert)) { /* already alerted */
chan_flag[ch] = chan_mode[ch] = 0;
if (ch >= CHAN_E) if (ch >= CHAN_E)
chan_mode[ch] = CHM_CE; chan_mode[ch] = CHM_CE;
}
if ((r = dev_dsp[dev][ch] (IO_CONN, inst, NULL)))/* connect */ if ((r = dev_dsp[dev][ch] (IO_CONN, inst, NULL)))/* connect */
return r; return r;
if (!(chan_flag[ch] & CHF_ILCE) && /* ignore if ilc */
!QAILCE (alert)) { /* already alerted */
if ((inst & I_IND) || (ch >= CHAN_C)) { /* C-H? alert ilc */ if ((inst & I_IND) || (ch >= CHAN_C)) { /* C-H? alert ilc */
alert = POT_ILCY + ch; alert = POT_ILCY + ch;
chan_mar[ch] = chan_wcr[ch] = 0; chan_mar[ch] = chan_wcr[ch] = 0;
} }
}
if (chan_flag[ch] & CHF_24B) /* 24B? 1 ch/wd */ if (chan_flag[ch] & CHF_24B) /* 24B? 1 ch/wd */
chan_cpw[ch] = 0; chan_cpw[ch] = 0;
else if (chan_flag[ch] & CHF_12B) /* 12B? 2 ch/wd */ else if (chan_flag[ch] & CHF_12B) /* 12B? 2 ch/wd */
@ -432,6 +439,8 @@ switch (mod) {
case 3: /* special */ case 3: /* special */
dev = I_GETDEV3 (inst); /* special device */ dev = I_GETDEV3 (inst); /* special device */
if (dev == DEV3_SMUX && !(cpu_unit.flags & UNIT_GENIE))
dev = DEV3_GMUX;
if (dev3_dsp[dev]) /* defined? */ if (dev3_dsp[dev]) /* defined? */
return dev3_dsp[dev] (IO_CONN, inst, NULL); return dev3_dsp[dev] (IO_CONN, inst, NULL);
CRETINS; CRETINS;
@ -493,6 +502,8 @@ switch (mod) {
case 3: /* special */ case 3: /* special */
dev = I_GETDEV3 (inst); /* special device */ dev = I_GETDEV3 (inst); /* special device */
if (dev == DEV3_SMUX && !(cpu_unit.flags & UNIT_GENIE))
dev = DEV3_GMUX;
if (dev3_dsp[dev]) if (dev3_dsp[dev])
dev3_dsp[dev] (IO_SKS, inst, dat); dev3_dsp[dev] (IO_SKS, inst, dat);
else CRETINS; else CRETINS;
@ -540,9 +551,9 @@ return SCPE_OK;
t_stat pot_fork (uint32 num, uint32 *dat) t_stat pot_fork (uint32 num, uint32 *dat)
{ {
uint32 igrp = SYI_GETGRP (*dat); /* get group */ 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? */ if ((*dat & SYI_ARM) && (*dat & fbit)) /* arm, bit set? */
int_req = int_req | INT_FORK; int_req = int_req | INT_FORK;
if ((*dat & SYI_DIS) && !(*dat & fbit)) /* disarm, bit clr? */ if ((*dat & SYI_DIS) && !(*dat & fbit)) /* disarm, bit clr? */

View file

@ -54,6 +54,7 @@
#define MUX_SETFLG(l,x) mux_flags[((l) * MUX_FLAGS) + (x)] = 1 #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_SETINT(x) int_req = int_req | (INT_MUXR >> (x))
#define MUX_CLRINT(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 */ /* PIN/POT */
@ -290,6 +291,8 @@ t_stat pin_mux (uint32 num, uint32 *dat)
uint32 ln = mux_scan >> 2; uint32 ln = mux_scan >> 2;
uint32 flag = mux_scan & MUX_FLAGMASK; 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_scan = mux_scan & MUX_SCANMASK; /* mask scan */
mux_flags[mux_scan] = 0; /* clear flag */ mux_flags[mux_scan] = 0; /* clear flag */
if (flag == MUX_FRCV) { /* rcv event? */ if (flag == MUX_FRCV) { /* rcv event? */
@ -333,6 +336,12 @@ else { /* enabled */
else mux_sta[ln] = mux_sta[ln] & ~MUX_SXIE; else mux_sta[ln] = mux_sta[ln] & ~MUX_SXIE;
mux_sta[ln] = mux_sta[ln] | MUX_SLNE; /* line is enabled */ mux_sta[ln] = mux_sta[ln] | MUX_SLNE; /* line is enabled */
mux_ldsc[ln].rcve = 1; 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; return SCPE_OK;
} }
@ -407,7 +416,23 @@ if (mux_sta[ln] & MUX_SXIE) {
return SCPE_OK; 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) void mux_scan_next (void)
{ {
@ -415,9 +440,12 @@ int32 i;
if (mux_slck) /* locked? */ if (mux_slck) /* locked? */
return; 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 */ for (i = 0; i < MUX_SCANMAX; i++) { /* scan flags */
mux_scan = (mux_scan + 1) & MUX_SCANMASK; /* next flag */ 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_slck = 1; /* lock scanner */
MUX_SETINT (mux_scan & MUX_FLAGMASK); /* request int */ MUX_SETINT (mux_scan & MUX_FLAGMASK); /* request int */
return; return;

View file

@ -287,7 +287,7 @@ if (rad_sba >= (RAD_NUMWD * 2)) { /* next sector? */
((rad_da + 1) & RAD_SCMASK); ((rad_da + 1) & RAD_SCMASK);
else rad_da = (rad_da & ~RAD_TRSCMASK) + /* cross band */ else rad_da = (rad_da & ~RAD_TRSCMASK) + /* cross band */
((rad_da + 1) & RAD_TRSCMASK); ((rad_da + 1) & RAD_TRSCMASK);
sba = 0; /* start new sec */ sba = 1; /* start new sec */
} }
return sba; return sba;
} }

View file

@ -96,7 +96,10 @@ const char *sim_stop_messages[] = {
"Trap instruction not BRM", "Trap instruction not BRM",
"RTC instruction not MIN or SKR", "RTC instruction not MIN or SKR",
"Interrupt vector zero", "Interrupt vector zero",
"Runaway carriage control tape" "Runaway carriage control tape",
"Monitor-mode Breakpoint",
"Normal-mode Breakpoint",
"User-mode Breakpoint"
}; };
/* Character conversion tables */ /* Character conversion tables */
@ -430,17 +433,17 @@ va = inst & VA_MASK;
shf = inst & I_SHFMSK; shf = inst & I_SHFMSK;
nonop = inst & 077777; nonop = inst & 077777;
if (sw & SWMASK ('A')) { /* ASCII? */ if (sw & SWMASK ('A')) { /* SDS internal ASCII? */
if (inst > 0377) for (i = 16; i >= 0; i -= 8) {
return SCPE_ARG; ch = (inst >> i) & 0377; /* map printable chars */
fprintf (of, FMTASC (inst & 0177)); ch = ch <= 0137 ? ch += 040 : '.'; /* from int. to ext. ASCII */
fprintf (of, "%c", ch);
}
return SCPE_OK; return SCPE_OK;
} }
if (sw & SWMASK ('C')) { /* character? */ if (sw & SWMASK ('C')) { /* six-bit character? */
fprintf (of, "%c", sds_to_ascii[(inst >> 18) & 077]); for (i = 18; i >= 0; i -= 6)
fprintf (of, "%c", sds_to_ascii[(inst >> 12) & 077]); fprintf (of, "%c", sds_to_ascii[(inst >> i) & 077]);
fprintf (of, "%c", sds_to_ascii[(inst >> 6) & 077]);
fprintf (of, "%c", sds_to_ascii[inst & 077]);
return SCPE_OK; return SCPE_OK;
} }
if (!(sw & SWMASK ('M'))) return SCPE_ARG; if (!(sw & SWMASK ('M'))) return SCPE_ARG;
@ -539,7 +542,7 @@ return cptr; /* no change */
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
{ {
int32 i, j, k; int32 i, j, k, ch;
t_value d, tag; t_value d, tag;
t_stat r; t_stat r;
char gbuf[CBUFSIZE]; char gbuf[CBUFSIZE];
@ -554,10 +557,21 @@ for (i = 1; (i < 4) && (cptr[i] != 0); i++) {
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
if (cptr[0] == 0) /* must have 1 char */ if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG; return SCPE_ARG;
val[0] = (t_value) cptr[0] | 0200; for (i = j = 0, val[0] = 0; i < 3; i++) {
if (cptr[i] == 0) /* latch str end */
j = 1;
ch = cptr[i] & 0377;
if (ch <= 037 || ch >= 0200)
k = -1;
else
k = ch - 040; /* map ext. to int. ASCII */
if (j || (k < 0)) /* bad, end? spc */
k = 0;
val[0] = (val[0] << 8) | k;
}
return SCPE_OK; return SCPE_OK;
} }
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* string? */ if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* string of 6-bit chars? */
if (cptr[0] == 0) /* must have 1 char */ if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG; return SCPE_ARG;
for (i = j = 0, val[0] = 0; i < 4; i++) { for (i = j = 0, val[0] = 0; i < 4; i++) {

Binary file not shown.