Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0c56397289
7 changed files with 157 additions and 57 deletions
|
@ -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) {
|
||||||
reason = STOP_IBKPT; /* stop simulation */
|
uint32 btyp = SWMASK ('E');
|
||||||
break;
|
|
||||||
|
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 */
|
||||||
|
else switch (btyp) { /* qualified breakpoint */
|
||||||
|
case SWMASK ('M'): /* monitor mode */
|
||||||
|
reason = STOP_MBKPT; /* stop simulation */
|
||||||
|
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? */
|
||||||
|
@ -505,7 +529,7 @@ if (inst & I_POP) { /* POP? */
|
||||||
if ((r = Write (0, dat)))
|
if ((r = Write (0, dat)))
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* mon mode */
|
else { /* mon mode */
|
||||||
dat = (OV << 21) | dat; /* ov in <2> */
|
dat = (OV << 21) | dat; /* ov in <2> */
|
||||||
WriteP (0, dat); /* store return */
|
WriteP (0, dat); /* store return */
|
||||||
|
@ -776,7 +800,7 @@ switch (op) { /* case on opcode */
|
||||||
return r;
|
return r;
|
||||||
inst = dat;
|
inst = dat;
|
||||||
goto EXU_LOOP;
|
goto EXU_LOOP;
|
||||||
|
|
||||||
case BRU:
|
case BRU:
|
||||||
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
|
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
|
||||||
if ((r = Ea (inst, &va))) /* decode eff addr */
|
if ((r = Ea (inst, &va))) /* decode eff addr */
|
||||||
|
@ -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:
|
||||||
|
@ -1191,7 +1230,7 @@ uint32 nml = nml_mode, usr = usr_mode;
|
||||||
uint32 pa, pgn, map;
|
uint32 pa, pgn, map;
|
||||||
|
|
||||||
if (sw & SWMASK ('N')) /* -n: normal */
|
if (sw & SWMASK ('N')) /* -n: normal */
|
||||||
nml = 1;
|
nml = 1;
|
||||||
else if (sw & SWMASK ('X')) /* -x: mon */
|
else if (sw & SWMASK ('X')) /* -x: mon */
|
||||||
nml = usr = 0;
|
nml = usr = 0;
|
||||||
else if (sw & SWMASK ('U')) { /* -u: user */
|
else if (sw & SWMASK ('U')) { /* -u: user */
|
||||||
|
@ -1269,7 +1308,7 @@ return;
|
||||||
|
|
||||||
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm
|
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm
|
||||||
runs even for overflow cases. Hence it must be emulated precisely
|
runs even for overflow cases. Hence it must be emulated precisely
|
||||||
to give the right answers for diagnostics. If the dividend is
|
to give the right answers for diagnostics. If the dividend is
|
||||||
negative, AB are 2's complemented starting at B<22>, and B<23>
|
negative, AB are 2's complemented starting at B<22>, and B<23>
|
||||||
is unchanged. */
|
is unchanged. */
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* sds_defs.h: SDS 940 simulator definitions
|
/* sds_defs.h: SDS 940 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2001-2010, Robert M. Supnik
|
Copyright (c) 2001-2010, Robert M. Supnik
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
|
45
SDS/sds_io.c
45
SDS/sds_io.c
|
@ -148,7 +148,7 @@ extern void set_dyn_map (void);
|
||||||
Channels could, optionally, handle 12b or 24b characters. The simulator can
|
Channels could, optionally, handle 12b or 24b characters. The simulator can
|
||||||
support all widths.
|
support all widths.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc);
|
t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
|
|
||||||
struct aldisp {
|
struct aldisp {
|
||||||
|
@ -233,11 +233,11 @@ t_stat (*dev3_dsp[64])() = { NULL };
|
||||||
struct aldisp dev_alt[] = {
|
struct aldisp dev_alt[] = {
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
||||||
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
|
||||||
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
||||||
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
||||||
|
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
|
||||||
|
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
||||||
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
||||||
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
|
||||||
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
||||||
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
|
||||||
{ &pin_adr, NULL }, { &pin_adr, NULL },
|
{ &pin_adr, NULL }, { &pin_adr, NULL },
|
||||||
|
@ -330,15 +330,22 @@ 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 (ch >= CHAN_E)
|
if (!(chan_flag[ch] & CHF_ILCE) && /* ignore if ilc */
|
||||||
chan_mode[ch] = CHM_CE;
|
!QAILCE (alert)) { /* already alerted */
|
||||||
|
chan_flag[ch] = chan_mode[ch] = 0;
|
||||||
|
if (ch >= CHAN_E)
|
||||||
|
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 ((inst & I_IND) || (ch >= CHAN_C)) { /* C-H? alert ilc */
|
if (!(chan_flag[ch] & CHF_ILCE) && /* ignore if ilc */
|
||||||
alert = POT_ILCY + ch;
|
!QAILCE (alert)) { /* already alerted */
|
||||||
chan_mar[ch] = chan_wcr[ch] = 0;
|
if ((inst & I_IND) || (ch >= CHAN_C)) { /* C-H? alert ilc */
|
||||||
|
alert = POT_ILCY + ch;
|
||||||
|
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;
|
||||||
|
@ -390,7 +397,7 @@ switch (mod) {
|
||||||
} /* end else change scan */
|
} /* end else change scan */
|
||||||
} /* end else term output */
|
} /* end else term output */
|
||||||
} /* end else chan EOM */
|
} /* end else chan EOM */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* internal */
|
case 2: /* internal */
|
||||||
if (ch >= CHAN_E) { /* EOD? */
|
if (ch >= CHAN_E) { /* EOD? */
|
||||||
|
@ -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,8 +502,10 @@ 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;
|
||||||
} /* end case */
|
} /* end case */
|
||||||
|
|
||||||
|
@ -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? */
|
||||||
|
@ -568,7 +579,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
Note that the channel can be disconnected if CHN_EOR is set, but must
|
Note that the channel can be disconnected if CHN_EOR is set, but must
|
||||||
not be if XFR_REQ is set */
|
not be if XFR_REQ is set */
|
||||||
|
|
||||||
t_stat chan_read (int32 ch)
|
t_stat chan_read (int32 ch)
|
||||||
{
|
{
|
||||||
uint32 dat = 0;
|
uint32 dat = 0;
|
||||||
|
@ -626,7 +637,7 @@ if (TST_EOR (ch)) { /* end record? */
|
||||||
} /* end else if cnt */
|
} /* end else if cnt */
|
||||||
return chan_eor (ch); /* eot/eor int */
|
return chan_eor (ch); /* eot/eor int */
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void chan_write_mem (int32 ch)
|
void chan_write_mem (int32 ch)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
@ -274,7 +275,7 @@ switch (fnc) {
|
||||||
((inst & SKS_DSR) && !(mux_sta[ln] & MUX_SDSR)))
|
((inst & SKS_DSR) && !(mux_sta[ln] & MUX_SDSR)))
|
||||||
*dat = 0; /* no skip if fail */
|
*dat = 0; /* no skip if fail */
|
||||||
}
|
}
|
||||||
else CRETINS;
|
else CRETINS;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return SCPE_IERR;
|
return SCPE_IERR;
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -116,7 +116,7 @@ DEVICE rad_dev = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Fixed head disk routine
|
/* Fixed head disk routine
|
||||||
|
|
||||||
conn - inst = EOM0, dat = NULL
|
conn - inst = EOM0, dat = NULL
|
||||||
eom1 - inst = EOM1, dat = NULL
|
eom1 - inst = EOM1, dat = NULL
|
||||||
sks - inst = SKS, dat = ptr to result
|
sks - inst = SKS, dat = ptr to result
|
||||||
|
@ -157,7 +157,7 @@ switch (fnc) { /* case function */
|
||||||
if (new_ch != rad_dib.chan) /* wrong chan? */
|
if (new_ch != rad_dib.chan) /* wrong chan? */
|
||||||
return SCPE_IERR;
|
return SCPE_IERR;
|
||||||
if ((inst & 00600) == 00200) /* alert for sec */
|
if ((inst & 00600) == 00200) /* alert for sec */
|
||||||
alert = POT_RADS;
|
alert = POT_RADS;
|
||||||
else if ((inst & 06600) == 0) { /* alert for addr */
|
else if ((inst & 06600) == 0) { /* alert for addr */
|
||||||
if (sim_is_active (&rad_unit)) /* busy? */
|
if (sim_is_active (&rad_unit)) /* busy? */
|
||||||
rad_err = 1;
|
rad_err = 1;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
@ -212,7 +215,7 @@ for (i = wd = 0; i < 4; ) {
|
||||||
}
|
}
|
||||||
return wd;
|
return wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||||
{
|
{
|
||||||
int32 i, wd, buf[8];
|
int32 i, wd, buf[8];
|
||||||
|
@ -227,7 +230,7 @@ for (i = 0; i < 8; i++) { /* read boot */
|
||||||
if ((wd = get_word (fileref, &ldr)) < 0)
|
if ((wd = get_word (fileref, &ldr)) < 0)
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
buf[i] = wd;
|
buf[i] = wd;
|
||||||
}
|
}
|
||||||
if ((buf[0] != 023200012) || /* 2 = WIM 12,2 */
|
if ((buf[0] != 023200012) || /* 2 = WIM 12,2 */
|
||||||
(buf[1] != 004100002) || /* 3 = BRX 2 */
|
(buf[1] != 004100002) || /* 3 = BRX 2 */
|
||||||
(buf[2] != 007100011) || /* 4 = LDX 11 */
|
(buf[2] != 007100011) || /* 4 = LDX 11 */
|
||||||
|
@ -260,15 +263,15 @@ return SCPE_NXM;
|
||||||
#define I_V_OPO 006 /* opcode only */
|
#define I_V_OPO 006 /* opcode only */
|
||||||
#define I_V_CHC 007 /* chan cmd */
|
#define I_V_CHC 007 /* chan cmd */
|
||||||
#define I_V_CHT 010 /* chan test */
|
#define I_V_CHT 010 /* chan test */
|
||||||
#define I_NPN (I_V_NPN << I_V_FL)
|
#define I_NPN (I_V_NPN << I_V_FL)
|
||||||
#define I_PPO (I_V_PPO << I_V_FL)
|
#define I_PPO (I_V_PPO << I_V_FL)
|
||||||
#define I_IOI (I_V_IOI << I_V_FL)
|
#define I_IOI (I_V_IOI << I_V_FL)
|
||||||
#define I_MRF (I_V_MRF << I_V_FL)
|
#define I_MRF (I_V_MRF << I_V_FL)
|
||||||
#define I_REG (I_V_REG << I_V_FL)
|
#define I_REG (I_V_REG << I_V_FL)
|
||||||
#define I_SHF (I_V_SHF << I_V_FL)
|
#define I_SHF (I_V_SHF << I_V_FL)
|
||||||
#define I_OPO (I_V_OPO << I_V_FL)
|
#define I_OPO (I_V_OPO << I_V_FL)
|
||||||
#define I_CHC (I_V_CHC << I_V_FL)
|
#define I_CHC (I_V_CHC << I_V_FL)
|
||||||
#define I_CHT (I_V_CHT << I_V_FL)
|
#define I_CHT (I_V_CHT << I_V_FL)
|
||||||
|
|
||||||
static const int32 masks[] = {
|
static const int32 masks[] = {
|
||||||
037777777, 010000000, 017700000,
|
037777777, 010000000, 017700000,
|
||||||
|
@ -299,7 +302,7 @@ static const char *opcode[] = {
|
||||||
"SKM", "LDX", "SKA", "SKG",
|
"SKM", "LDX", "SKA", "SKG",
|
||||||
"SKD", "LDB", "LDA", "EAX",
|
"SKD", "LDB", "LDA", "EAX",
|
||||||
|
|
||||||
"BRU*",
|
"BRU*",
|
||||||
"MIY*", "BRI*", "MIW*", "POT*",
|
"MIY*", "BRI*", "MIW*", "POT*",
|
||||||
"ETR*", "MRG*", "EOR*",
|
"ETR*", "MRG*", "EOR*",
|
||||||
"EXU*",
|
"EXU*",
|
||||||
|
@ -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++) {
|
||||||
|
|
BIN
doc/sds_doc.doc
BIN
doc/sds_doc.doc
Binary file not shown.
Loading…
Add table
Reference in a new issue