1
0
mirror of https://github.com/simh/simh.git synced 2026-05-01 13:56:02 +00:00

Bob Supnik's state as of 5/9/2015 after backporting some things from the master branch

This commit is contained in:
Mark Pizzolato
2015-05-10 05:48:11 -07:00
parent 3a279c013a
commit 4d48f44857
313 changed files with 80976 additions and 38242 deletions

View File

@@ -39,8 +39,9 @@
X<0:23> X (index) register
OV overflow indicator
P<0:13> program counter
nml_mode compatible (1) vs 940 (0) mode
usr_mode user (1) vs monitor (0) mode
cpu_mode SDS 930 normal (compatible) mode (0)
SDS 940 monitor mode (1)
SDS 940 user mode (2)
RL1<0:23> user map low
RL2<0:23> user map high
RL4<12:23> monitor map high
@@ -168,8 +169,7 @@ uint32 int_reqhi = 0; /* highest int request *
uint32 api_lvl = 0; /* api active */
uint32 api_lvlhi = 0; /* highest api active */
t_bool chan_req; /* chan request */
uint32 nml_mode = 1; /* normal mode */
uint32 usr_mode = 0; /* user mode */
uint32 cpu_mode = NML_MODE; /* normal mode */
uint32 mon_usr_trap = 0; /* mon-user trap */
uint32 EM2 = 2, EM3 = 3; /* extension registers */
uint32 RL1, RL2, RL4; /* relocation maps */
@@ -190,13 +190,11 @@ int32 pcq_p = 0; /* PC queue ptr */
REG *pcq_r = NULL; /* PC queue reg ptr */
int32 hst_p = 0; /* history pointer */
int32 hst_lnt = 0; /* history length */
uint32 hst_exclude = BAD_MODE; /* cpu_mode excluded from history */
InstHistory *hst = NULL; /* instruction history */
int32 rtc_pie = 0; /* rtc pulse ie */
int32 rtc_tps = 60; /* rtc ticks/sec */
extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_reset (DEVICE *dptr);
@@ -217,7 +215,7 @@ void Mul48 (uint32 mplc, uint32 mplr);
void Div48 (uint32 dvdh, uint32 dvdl, uint32 dvr);
void RotR48 (uint32 sc);
void ShfR48 (uint32 sc, uint32 sgn);
t_stat one_inst (uint32 inst, uint32 pc, uint32 mode);
t_stat one_inst (uint32 inst, uint32 pc, uint32 mode, uint32 *trappc);
void inst_hist (uint32 inst, uint32 pc, uint32 typ);
t_stat rtc_inst (uint32 inst);
t_stat rtc_svc (UNIT *uptr);
@@ -254,8 +252,7 @@ REG cpu_reg[] = {
{ ORDATA (RL1, RL1, 24) },
{ ORDATA (RL2, RL2, 24) },
{ ORDATA (RL4, RL4, 12) },
{ FLDATA (NML, nml_mode, 0) },
{ FLDATA (USR, usr_mode, 0) },
{ ORDATA (MODE, cpu_mode, 2) },
{ FLDATA (MONUSR, mon_usr_trap, 0) },
{ FLDATA (ION, ion, 0) },
{ FLDATA (INTDEF, ion_defer, 0) },
@@ -359,8 +356,7 @@ static const uint32 int_vec[32] = {
t_stat sim_instr (void)
{
extern int32 sim_interval;
uint32 inst, tinst, pa, save_P, save_mode;
uint32 inst, tinst, pa, save_P, save_mode, trap_P, tmp;
t_stat reason, tr;
/* Restore register state */
@@ -385,14 +381,14 @@ while (reason == 0) { /* loop until halted */
}
if (sim_interval <= 0) { /* event queue? */
if (reason = sim_process_event ()) /* process */
if ((reason = sim_process_event ())) /* process */
break;
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
}
if (chan_req) { /* channel request? */
if (reason = chan_process ()) /* process */
if ((reason = chan_process ())) /* process */
break;
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
@@ -406,14 +402,14 @@ while (reason == 0) { /* loop until halted */
break;
}
tinst = ReadP (pa); /* get inst */
save_mode = usr_mode; /* save mode */
usr_mode = 0; /* switch to mon */
save_mode = cpu_mode; /* save mode */
cpu_mode = MON_MODE; /* switch to mon */
if (hst_lnt) /* record inst */
inst_hist (tinst, P, HIST_INT);
if (pa != VEC_RTCP) { /* normal intr? */
tr = one_inst (tinst, P, save_mode); /* exec intr inst */
tr = one_inst (tinst, P, save_mode, &tmp); /* exec intr inst */
if (tr) { /* stop code? */
usr_mode = save_mode; /* restore mode */
cpu_mode = save_mode; /* restore mode */
reason = (tr > 0)? tr: STOP_MMINT;
break;
}
@@ -422,7 +418,7 @@ while (reason == 0) { /* loop until halted */
}
else { /* clock intr */
tr = rtc_inst (tinst); /* exec RTC inst */
usr_mode = save_mode; /* restore mode */
cpu_mode = save_mode; /* restore mode */
if (tr) { /* stop code? */
reason = (tr > 0)? tr: STOP_MMINT;
break;
@@ -432,9 +428,31 @@ while (reason == 0) { /* loop until halted */
int_reqhi = api_findreq (); /* recalc int req */
}
else { /* normal instr */
if (sim_brk_summ && sim_brk_test (P, SWMASK ('E'))) { /* breakpoint? */
reason = STOP_IBKPT; /* stop simulation */
break;
if (sim_brk_summ) {
static uint32 bmask[] = {SWMASK ('E') | SWMASK ('N'),
SWMASK ('E') | SWMASK ('M'),
SWMASK ('E') | SWMASK ('U')};
uint32 btyp;
btyp = sim_brk_test (P, bmask[cpu_mode]);
if (btyp) {
if (btyp & SWMASK ('E')) /* unqualified breakpoint? */
reason = STOP_IBKPT; /* stop simulation */
// else if (btyp & BRK_TYP_DYN_STEPOVER) /* stepover breakpoint? */
// reason = STOP_DBKPT; /* 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 */
P = (P + 1) & VA_MASK; /* incr PC */
@@ -442,7 +460,7 @@ while (reason == 0) { /* loop until halted */
ion_defer = 0; /* clear ion */
if (hst_lnt)
inst_hist (inst, save_P, HIST_XCT);
reason = one_inst (inst, save_P, usr_mode); /* exec inst */
reason = one_inst (inst, save_P, cpu_mode, &trap_P); /* exec inst */
if (reason > 0) { /* stop code? */
if (reason != STOP_HALT)
P = save_P;
@@ -451,25 +469,35 @@ while (reason == 0) { /* loop until halted */
}
} /* end if r == 0 */
if (reason < 0) { /* mm (fet or ex)? */
int8 op;
pa = -reason; /* get vector */
reason = 0; /* defang */
if (reason == MM_MONUSR) /* record P of user-mode */
save_P = P; /* transition point */
tinst = ReadP (pa); /* get inst */
if (I_GETOP (tinst) != BRM) { /* not BRM? */
op = I_GETOP (tinst);
if (op != BRM && op != BRU) { /* not BRM or BRU? */
reason = STOP_TRPINS; /* fatal err */
break;
}
save_mode = usr_mode; /* save mode */
usr_mode = 0; /* switch to mon */
save_mode = cpu_mode; /* save mode */
cpu_mode = MON_MODE; /* switch to mon */
mon_usr_trap = 0;
if (hst_lnt)
inst_hist (tinst, save_P, HIST_TRP);
tr = one_inst (tinst, save_P, save_mode); /* trap inst */
/* Use previously recorded trap address if memory acccess trap.
Will differ from save_P if trapped instruction was a branch.
See page 17 of 940 reference manual for additional info.
*/
tr = one_inst (tinst, (reason == MM_NOACC)?
trap_P: save_P, save_mode, &tmp); /* trap address */
if (tr) { /* stop code? */
usr_mode = save_mode; /* restore mode */
cpu_mode = save_mode; /* restore mode */
P = save_P; /* restore PC */
reason = (tr > 0)? tr: STOP_MMTRP;
break;
}
reason = 0; /* defang */
} /* end if reason */
} /* end else int */
} /* end while */
@@ -482,38 +510,42 @@ return reason;
/* Simulate one instruction */
t_stat one_inst (uint32 inst, uint32 pc, uint32 mode)
t_stat one_inst (uint32 inst, uint32 pc, uint32 mode, uint32 *trappc)
{
uint32 op, shf_op, va, dat;
uint32 old_A, old_B, old_X;
int32 i, exu_cnt, sc;
t_stat r;
*trappc = pc; /* default trap pc to pc */
exu_cnt = 0; /* init EXU count */
EXU_LOOP:
op = I_GETOP (inst); /* get opcode */
if (inst & I_POP) { /* POP? */
dat = (EM3 << 18) | (EM2 << 15) | I_IND | pc; /* data to save */
if (nml_mode) { /* normal mode? */
switch (cpu_mode)
{
case NML_MODE:
dat = (OV << 23) | dat; /* ov in <0> */
WriteP (0, dat);
}
else if (usr_mode) { /* user mode? */
break;
case USR_MODE:
if (inst & I_USR) { /* SYSPOP? */
dat = I_USR | (OV << 21) | dat; /* ov in <2> */
WriteP (0, dat);
usr_mode = 0; /* set mon mode */
cpu_mode = MON_MODE; /* set mon mode */
}
else { /* normal POP */
dat = (OV << 23) | dat; /* ov in <0> */
if (r = Write (0, dat))
if ((r = Write (0, dat)))
return r;
}
}
else { /* mon mode */
break;
case MON_MODE:
dat = (OV << 21) | dat; /* ov in <2> */
WriteP (0, dat); /* store return */
}
break;
}
PCQ_ENTRY; /* save PC */
P = 0100 | op; /* new PC */
OV = 0; /* clear ovflo */
@@ -525,61 +557,61 @@ switch (op) { /* case on opcode */
/* Loads and stores */
case LDA:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &A)) /* get operand */
if ((r = Read (va, &A))) /* get operand */
return r;
break;
case LDB:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &B)) /* get operand */
if ((r = Read (va, &B))) /* get operand */
return r;
break;
case LDX:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &X)) /* get operand */
if ((r = Read (va, &X))) /* get operand */
return r;
break;
case STA:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Write (va, A)) /* write operand */
if ((r = Write (va, A))) /* write operand */
return r;
break;
case STB:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Write (va, B)) /* write operand */
if ((r = Write (va, B))) /* write operand */
return r;
break;
case STX:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Write (va, X)) /* write operand */
if ((r = Write (va, X))) /* write operand */
return r;
break;
case EAX:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (nml_mode || usr_mode) /* normal or user? */
if (cpu_mode != MON_MODE) /* normal or user? */
X = (X & ~VA_MASK) | (va & VA_MASK); /* only 14b */
else X = (X & ~XVA_MASK) | (va & XVA_MASK); /* mon, 15b */
break;
case XMA:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (r = Write (va, A)) /* write A */
if ((r = Write (va, A))) /* write A */
return r;
A = dat; /* load A */
break;
@@ -587,95 +619,95 @@ switch (op) { /* case on opcode */
/* Arithmetic and logical */
case ADD:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
A = Add24 (A, dat, 0); /* add */
break;
case ADC:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
OV = 0; /* clear overflow */
A = Add24 (A, dat, X >> 23); /* add with carry */
break;
case SUB:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
A = Add24 (A, dat ^ DMASK, 1); /* subtract */
break;
case SUC:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
OV = 0; /* clear overflow */
A = Add24 (A, dat ^ DMASK, X >> 23); /* sub with carry */
break;
case ADM:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
dat = AddM24 (dat, A); /* mem + A */
if (r = Write (va, dat)) /* rewrite */
if ((r = Write (va, dat))) /* rewrite */
return r;
break;
case MIN:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
dat = AddM24 (dat, 1); /* mem + 1 */
if (r = Write (va, dat)) /* rewrite */
if ((r = Write (va, dat))) /* rewrite */
return r;
break;
case MUL:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
Mul48 (A, dat); /* multiply */
break;
case DIV:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
Div48 (A, B, dat); /* divide */
break;
case ETR:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
A = A & dat; /* and */
break;
case MRG:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
A = A | dat; /* or */
break;
case EOR:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
A = A ^ dat; /* xor */
break;
@@ -683,75 +715,75 @@ switch (op) { /* case on opcode */
/* Skips */
case SKE:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (A == dat) /* if A = op, skip */
P = (P + 1) & VA_MASK;
break;
case SKG:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (SXT (A) > SXT (dat)) /* if A > op, skip */
P = (P + 1) & VA_MASK;
break;
case SKM:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (((A ^ dat) & B) == 0) /* if A = op masked */
P = (P + 1) & VA_MASK;
break;
case SKA:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if ((A & dat) == 0) /* if !(A & op), skip */
P = (P + 1) & VA_MASK;
break;
case SKB:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if ((B & dat) == 0) /* if !(B & op), skip */
P = (P + 1) & VA_MASK;
break;
case SKN:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (dat & SIGN) /* if op < 0, skip */
P = (P + 1) & VA_MASK;
break;
case SKR:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
dat = AddM24 (dat, DMASK); /* decr operand */
if (r = Write (va, dat)) /* rewrite */
if ((r = Write (va, dat))) /* rewrite */
return r;
if (dat & SIGN) /* if op < 0, skip */
P = (P + 1) & VA_MASK;
break;
case SKD:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (SXT_EXP (B) < SXT_EXP (dat)) { /* B < dat? */
X = (dat - B) & DMASK; /* X = dat - B */
@@ -766,7 +798,7 @@ switch (op) { /* case on opcode */
break;
case HLT:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
return STOP_HALT; /* halt CPU */
@@ -774,59 +806,91 @@ switch (op) { /* case on opcode */
exu_cnt = exu_cnt + 1; /* count chained EXU */
if (exu_cnt > exu_lim) /* too many? */
return STOP_EXULIM;
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
inst = dat;
goto EXU_LOOP;
case BRU:
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
if (r = Ea (inst, &va)) /* decode eff addr */
if ((cpu_mode == NML_MODE) && (inst & I_IND))
api_dismiss (); /* normal-mode BRU*, dism */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
{
if (r == MM_NOACC)
*trappc = va & VA_MASK; /* use target as trap adr */
return r;
}
PCQ_ENTRY;
P = va & VA_MASK; /* branch */
if ((va & VA_USR) && (cpu_mode == MON_MODE)) { /* user ref from mon. mode? */
cpu_mode = USR_MODE; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
break;
case BRX:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
X = (X + 1) & DMASK; /* incr X */
if (X & I_IND) { /* bit 9 set? */
if (r = Read (va, &dat)) /* test dest access */
if ((r = Read (va, &dat))) /* test dest access */
{
if (r == MM_NOACC)
*trappc = va & VA_MASK; /* use target as trap adr */
return r;
}
PCQ_ENTRY;
P = va & VA_MASK; /* branch */
if ((va & VA_USR) && (cpu_mode == MON_MODE)) { /* user ref from mon. mode? */
cpu_mode = USR_MODE; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
}
break;
case BRM:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
dat = (EM3 << 18) | (EM2 << 15) | pc; /* form return word */
if (!nml_mode && !usr_mode) /* monitor mode? */
dat = dat | (mode << 23) | (OV << 21);
if (cpu_mode == MON_MODE) /* monitor mode? */
dat = dat | ((mode == USR_MODE) << 23) | (OV << 21);
else dat = dat | (OV << 23); /* normal or user */
if (r = Write (va, dat)) /* write ret word */
if ((r = Write (va, dat))) /* write ret word */
{
if (r == MM_NOACC)
*trappc = va & VA_MASK; /* use target as trap adr */
return r;
}
PCQ_ENTRY;
P = (va + 1) & VA_MASK; /* branch */
if ((va & VA_USR) && (cpu_mode == MON_MODE)) { /* user ref from mon. mode? */
cpu_mode = USR_MODE; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
break;
case BRR:
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
{
if (r == MM_NOACC)
*trappc = va & VA_MASK; /* use target as trap adr */
return r;
}
PCQ_ENTRY;
P = (dat + 1) & VA_MASK; /* branch */
if (!nml_mode && !usr_mode) { /* monitor mode? */
if (cpu_mode == MON_MODE) { /* monitor mode? */
OV = OV | ((dat >> 21) & 1); /* restore OV */
if ((va & VA_USR) | (dat & I_USR)) { /* mode change? */
usr_mode = 1;
cpu_mode = USR_MODE;
if (mon_usr_trap)
return MM_MONUSR;
}
@@ -835,19 +899,23 @@ switch (op) { /* case on opcode */
break;
case BRI:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
{
if (r == MM_NOACC)
*trappc = va & VA_MASK; /* use target as trap adr */
return r;
}
api_dismiss (); /* dismiss hi api */
PCQ_ENTRY;
P = dat & VA_MASK; /* branch */
if (!nml_mode) { /* monitor mode? */
if (cpu_mode == MON_MODE) { /* monitor mode? */
OV = (dat >> 21) & 1; /* restore OV */
if ((va & VA_USR) | (dat & I_USR)) { /* mode change? */
usr_mode = 1;
cpu_mode = USR_MODE;
if (mon_usr_trap)
return MM_MONUSR;
}
@@ -898,7 +966,7 @@ switch (op) { /* case on opcode */
/* Overflow instruction */
case OVF:
if ((inst & 0100) & OV)
if ((inst & 0100) && !OV)
P = (P + 1) & VA_MASK;
if (inst & 0001)
OV = 0;
@@ -909,7 +977,7 @@ switch (op) { /* case on opcode */
/* Shifts */
case RSH:
if (r = EaSh (inst, &va)) /* decode eff addr */
if ((r = EaSh (inst, &va))) /* decode eff addr */
return r;
shf_op = I_GETSHFOP (va); /* get eff op */
sc = va & I_SHFMSK; /* get eff count */
@@ -934,7 +1002,7 @@ switch (op) { /* case on opcode */
break;
case LSH:
if (r = EaSh (inst, &va)) /* decode eff addr */
if ((r = EaSh (inst, &va))) /* decode eff addr */
return r;
shf_op = I_GETSHFOP (va); /* get eff op */
sc = va & I_SHFMSK; /* get eff count */
@@ -987,35 +1055,35 @@ switch (op) { /* case on opcode */
/* I/O instructions */
case MIW: case MIY:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (r = op_miwy (inst, dat)) /* process inst */
if ((r = op_miwy (inst, dat))) /* process inst */
return r;
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
break;
case WIM: case YIM:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = op_wyim (inst, &dat)) /* process inst */
if ((r = op_wyim (inst, &dat))) /* process inst */
return r;
if (r = Write (va, dat))
if ((r = Write (va, dat)))
return r; /* write result */
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
break;
case EOM: case EOD:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = op_eomd (inst)) /* process inst */
if ((r = op_eomd (inst))) /* process inst */
return r;
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
@@ -1023,42 +1091,42 @@ switch (op) { /* case on opcode */
break;
case POT:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
if (r = op_pot (dat)) /* process inst */
if ((r = op_pot (dat))) /* process inst */
return r;
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
break;
case PIN:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = op_pin (&dat)) /* process inst */
if ((r = op_pin (&dat))) /* process inst */
return r;
if (r = Write (va, dat)) /* write result */
if ((r = Write (va, dat))) /* write result */
return r;
int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */
break;
case SKS:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
if (r = op_sks (inst, &dat)) /* process inst */
if ((r = op_sks (inst, &dat))) /* process inst */
return r;
if (dat)
P = (P + 1) & VA_MASK;
break;
default:
if (!nml_mode && usr_mode) /* priv inst */
if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS;
CRETINS; /* invalid inst */
break;
@@ -1085,7 +1153,7 @@ for (i = 0; i < ind_lim; i++) { /* count indirects */
hst[hst_p].ea = *addr;
return SCPE_OK;
}
if (r = Read (va, &wd)) /* read ind; fails? */
if ((r = Read (va, &wd))) /* read ind; fails? */
return r;
va = (va & VA_USR) | (wd & XVA_MASK);
}
@@ -1112,7 +1180,7 @@ for (i = 0; i < ind_lim; i++) { /* count indirects */
}
if (wd & I_IDX)
va = (va & VA_USR) | ((va + X) & VA_MASK);
if (r = Read (va, &wd)) /* read ind; fails? */
if ((r = Read (va, &wd))) /* read ind; fails? */
return r;
va = (va & VA_USR) | (wd & XVA_MASK);
}
@@ -1125,7 +1193,7 @@ t_stat Read (uint32 va, uint32 *dat)
{
uint32 pgn, map, pa;
if (nml_mode) { /* normal? */
if (cpu_mode == NML_MODE) { /* normal? */
va = va & VA_MASK; /* ignore user */
if (va < 020000) /* first 8K: 1 for 1 */
pa = va;
@@ -1133,7 +1201,7 @@ if (nml_mode) { /* normal? */
pa = va + em2_dyn;
else pa = va + em3_dyn; /* next 4K: ext EM3 */
}
else if (usr_mode || (va & VA_USR)) { /* user mapping? */
else if ((cpu_mode == USR_MODE) || (va & VA_USR)) { /* user mapping? */
pgn = VA_GETPN (va); /* get page no */
map = usr_map[pgn]; /* get map entry */
if (map == MAP_PROT) /* prot? no access */
@@ -1157,7 +1225,7 @@ t_stat Write (uint32 va, uint32 dat)
{
uint32 pgn, map, pa;
if (nml_mode) { /* normal? */
if (cpu_mode == NML_MODE) { /* normal? */
va = va & VA_MASK; /* ignore user */
if (va < 020000) /* first 8K: 1 for 1 */
pa = va;
@@ -1165,7 +1233,7 @@ if (nml_mode) { /* normal? */
pa = va + em2_dyn;
else pa = va + em3_dyn; /* next 4K: ext EM3 */
}
else if (usr_mode || (va & VA_USR)) { /* user mapping? */
else if ((cpu_mode == USR_MODE) || (va & VA_USR)) { /* user mapping? */
pgn = VA_GETPN (va); /* get page no */
map = usr_map[pgn]; /* get map entry */
if (map & MAP_PROT) { /* protected page? */
@@ -1191,21 +1259,20 @@ return SCPE_OK;
uint32 RelocC (int32 va, int32 sw)
{
uint32 nml = nml_mode, usr = usr_mode;
uint32 mode = cpu_mode;
uint32 pa, pgn, map;
if (sw & SWMASK ('N')) /* -n: normal */
nml = 1;
mode = NML_MODE;
else if (sw & SWMASK ('X')) /* -x: mon */
nml = usr = 0;
mode = MON_MODE;
else if (sw & SWMASK ('U')) { /* -u: user */
nml = 0;
usr = 1;
mode = USR_MODE;
}
else if (!(sw & SWMASK ('V'))) /* -v: curr */
return va;
set_dyn_map ();
if (nml) { /* normal? */
if (mode == NML_MODE) { /* normal? */
if (va < 020000) /* first 8K: 1 for 1 */
pa = va;
else if (va < 030000) /* next 4K: ext EM2 */
@@ -1214,7 +1281,7 @@ if (nml) { /* normal? */
}
else {
pgn = VA_GETPN (va); /* get page no */
map = usr? usr_map[pgn]: mon_map[pgn]; /* get map entry */
map = (mode == USR_MODE)? usr_map[pgn]: mon_map[pgn]; /* get map entry */
if (map == MAP_PROT) /* no access page? */
return MAXMEMSIZE + 1;
pa = (map & ~MAP_PROT) | (va & VA_POFF); /* map address */
@@ -1273,7 +1340,7 @@ return;
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm
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>
is unchanged. */
@@ -1341,7 +1408,7 @@ if (sc >= 24) {
A = sgn;
}
else {
B = ((B >> sc) | (A << (24 - sc)) & DMASK);
B = ((B >> sc) | (A << (24 - sc))) & DMASK;
A = ((A >> sc) | (sgn << (24 - sc))) & DMASK;
}
return;
@@ -1448,8 +1515,7 @@ EM2 = 2;
EM3 = 3;
RL1 = RL2 = RL4 = 0;
ion = ion_defer = 0;
nml_mode = 1;
usr_mode = 0;
cpu_mode = NML_MODE;
mon_usr_trap = 0;
int_req = 0;
int_reqhi = 0;
@@ -1460,7 +1526,8 @@ pcq_r = find_reg ("PCQ", NULL, dptr);
if (pcq_r)
pcq_r->qptr = 0;
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;
}
@@ -1552,7 +1619,8 @@ t_stat rtc_svc (UNIT *uptr)
{
if (rtc_pie) /* set pulse intr */
int_req = int_req | INT_RTCP;
sim_activate (&rtc_unit, sim_rtcn_calb (rtc_tps, TMR_RTC)); /* reactivate */
rtc_unit.wait = sim_rtcn_calb (rtc_tps, TMR_RTC); /* calibrate */
sim_activate (&rtc_unit, rtc_unit.wait); /* reactivate */
return SCPE_OK;
}
@@ -1569,14 +1637,14 @@ if (op == MIN) /* incr */
else if (op == SKR) /* decr */
val = DMASK;
else return STOP_RTCINS; /* can't do it */
if (r = Ea (inst, &va)) /* decode eff addr */
if ((r = Ea (inst, &va))) /* decode eff addr */
return r;
if (r = Read (va, &dat)) /* get operand */
if ((r = Read (va, &dat))) /* get operand */
return r;
dat = AddM24 (dat, val); /* mem +/- 1 */
if (r = Write (va, dat)) /* rewrite */
if ((r = Write (va, dat))) /* rewrite */
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;
return SCPE_OK;
}
@@ -1586,6 +1654,7 @@ return SCPE_OK;
t_stat rtc_reset (DEVICE *dptr)
{
rtc_pie = 0; /* disable pulse */
rtc_unit.wait = sim_rtcn_init (rtc_unit.wait, TMR_RTC); /* initialize clock calibration */
sim_activate (&rtc_unit, rtc_unit.wait); /* activate unit */
return SCPE_OK;
}
@@ -1614,10 +1683,12 @@ return SCPE_OK;
void inst_hist (uint32 ir, uint32 pc, uint32 tp)
{
if (cpu_mode == hst_exclude)
return;
hst_p = (hst_p + 1); /* next entry */
if (hst_p >= hst_lnt)
hst_p = 0;
hst[hst_p].typ = tp | (OV << 4);
hst[hst_p].typ = tp | (OV << 4) | (cpu_mode << 5);
hst[hst_p].pc = pc;
hst[hst_p].ir = ir;
hst[hst_p].a = A;
@@ -1644,6 +1715,14 @@ lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN)))
return SCPE_ARG;
hst_p = 0;
if (sim_switches & SWMASK('M'))
hst_exclude = MON_MODE;
else if (sim_switches & SWMASK('N'))
hst_exclude = NML_MODE;
else if (sim_switches & SWMASK('U'))
hst_exclude = USR_MODE;
else
hst_exclude = BAD_MODE;
if (hst_lnt) {
free (hst);
hst_lnt = 0;
@@ -1667,9 +1746,8 @@ char *cptr = (char *) desc;
t_stat r;
t_value sim_eval;
InstHistory *h;
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
UNIT *uptr, int32 sw);
static char *cyc[] = { " ", " ", "INT", "TRP" };
static char *modes = "NMU?";
if (hst_lnt == 0) /* enabled? */
return SCPE_NOFNC;
@@ -1682,13 +1760,13 @@ else lnt = hst_lnt;
di = hst_p - lnt; /* work forward */
if (di < 0)
di = di + hst_lnt;
fprintf (st, "CYC PC OV A B X EA IR\n\n");
fprintf (st, "CYC PC MD OV A B X EA IR\n\n");
for (k = 0; k < lnt; k++) { /* print specified */
h = &hst[(++di) % hst_lnt]; /* entry pointer */
if (h->typ) { /* instruction? */
ov = (h->typ >> 4) & 1; /* overflow */
fprintf (st, "%s %05o %o %08o %08o %08o ", cyc[h->typ & 3],
h->pc, ov, h->a, h->b, h->x);
fprintf (st, "%s %05o %c %o %08o %08o %08o ", cyc[h->typ & 3],
h->pc, modes[(h->typ >> 5) & 3], ov, h->a, h->b, h->x);
if (h->ea & HIST_NOEA)
fprintf (st, " ");
else fprintf (st, "%05o ", h->ea);

View File

@@ -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
@@ -27,8 +27,8 @@
25-Apr-03 RMS Revised for extended file support
*/
#ifndef _SDS_DEFS_H_
#define _SDS_DEFS_H_ 0
#ifndef SDS_DEFS_H_
#define SDS_DEFS_H_ 0
#include "sim_defs.h" /* simulator defns */
@@ -48,10 +48,15 @@
#define STOP_EXULIM 8 /* EXU limit */
#define STOP_MMINT 9 /* mm in intr */
#define STOP_MMTRP 10 /* mm in trap */
#define STOP_TRPINS 11 /* trap inst not BRM */
#define STOP_RTCINS 12 /* rtc inst not MIN/SKR */
#define STOP_TRPINS 11 /* trap inst not BRM or BRU */
#define STOP_RTCINS 12 /* rtc inst not MIN or SKR */
#define STOP_ILLVEC 13 /* zero vector */
#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 */
#define STOP_DBKPT 18 /* step-over (dynamic) breakpoint */
/* Trap codes */
@@ -78,6 +83,13 @@
#define SXT_EXP(x) ((int32) (((x) & EXPS)? ((x) | ~EXPMASK): \
((x) & EXPMASK)))
/* CPU modes */
#define NML_MODE 0
#define MON_MODE 1
#define USR_MODE 2
#define BAD_MODE 3
/* Memory */
#define MAXMEMSIZE (1 << 16) /* max memory size */

View File

@@ -204,7 +204,7 @@ switch (fnc) { /* case on function */
case IO_READ:
xfr_req = xfr_req & ~XFR_DSK; /* clr xfr req */
if (dsk_bptr >= dsk_blnt) { /* no more data? */
if (r = dsk_read_buf (inst)) /* read sector */
if ((r = dsk_read_buf (inst))) /* read sector */
return r;
}
dsk_wptr = dsk_bptr >> 2; /* word pointer */
@@ -219,7 +219,7 @@ switch (fnc) { /* case on function */
case IO_WRITE:
xfr_req = xfr_req & ~XFR_DSK; /* clr xfr req */
if (dsk_bptr >= (DSK_NUMWD * 4)) { /* full? */
if (r = dsk_write_buf (inst)) /* write sector */
if ((r = dsk_write_buf (inst))) /* write sector */
return r;
}
dsk_wptr = dsk_bptr >> 2; /* word pointer */

View File

@@ -55,7 +55,7 @@
#define I_GETDEV3(x) ((((x) & 020046000) != 020046000)? ((x) & DEV_MASK): DEV_MASK)
#define TST_XFR(d,c) (xfr_req && dev_map[d][c])
#define TST_XFR(d,c) (xfr_req & dev_map[d][c])
#define SET_XFR(d,c) xfr_req = xfr_req | dev_map[d][c]
#define CLR_XFR(d,c) xfr_req = xfr_req & ~dev_map[d][c]
#define INV_DEV(d,c) (dev_dsp[d][c] == NULL)
@@ -81,13 +81,11 @@ extern uint32 int_req; /* int req */
extern uint32 xfr_req; /* xfer req */
extern uint32 alert; /* pin/pot alert */
extern uint32 X, EM2, EM3, OV, ion, bpt;
extern uint32 nml_mode, usr_mode;
extern uint32 cpu_mode;
extern int32 rtc_pie;
extern int32 stop_invins, stop_invdev, stop_inviop;
extern uint32 mon_usr_trap;
extern UNIT cpu_unit;
extern FILE *sim_log;
extern DEVICE *sim_devices[];
t_stat chan_reset (DEVICE *dptr);
t_stat chan_read (int32 ch);
@@ -150,7 +148,7 @@ extern void set_dyn_map (void);
Channels could, optionally, handle 12b or 24b characters. The simulator can
support all widths.
*/
t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc);
struct aldisp {
@@ -224,7 +222,7 @@ uint32 dev_map[64][NUM_CHAN];
/* dev_dsp maps device and channel numbers to dispatch routines */
t_stat (*dev_dsp[64][NUM_CHAN])() = { NULL };
t_stat (*dev_dsp[64][NUM_CHAN])() = { {NULL} };
/* dev3_dsp maps system device numbers to dispatch routines */
@@ -235,11 +233,11 @@ t_stat (*dev3_dsp[64])() = { NULL };
struct aldisp dev_alt[] = {
{ 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_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 },
@@ -332,15 +330,22 @@ switch (mod) {
if (INV_DEV (dev, ch)) /* inv dev? err */
CRETDEV;
chan_war[ch] = chan_cnt[ch] = 0; /* init chan */
chan_flag[ch] = chan_dcr[ch] = 0;
chan_mode[ch] = chan_uar[ch] = 0;
if (ch >= CHAN_E)
chan_mode[ch] = CHM_CE;
if (r = dev_dsp[dev][ch] (IO_CONN, inst, NULL)) /* connect */
chan_dcr[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)
chan_mode[ch] = CHM_CE;
}
if ((r = dev_dsp[dev][ch] (IO_CONN, inst, NULL)))/* connect */
return r;
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_ILCE) && /* ignore if ilc */
!QAILCE (alert)) { /* already alerted */
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 */
chan_cpw[ch] = 0;
@@ -392,7 +397,7 @@ switch (mod) {
} /* end else change scan */
} /* end else term output */
} /* end else chan EOM */
break;
break;
case 2: /* internal */
if (ch >= CHAN_E) { /* EOD? */
@@ -426,7 +431,7 @@ switch (mod) {
else if (inst & 01000) /* alert RL2 */
alert = POT_RL2;
if (inst & 02000) { /* nml to mon */
nml_mode = usr_mode = 0;
cpu_mode = MON_MODE;
if (inst & 00400)
mon_usr_trap = 1;
}
@@ -434,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;
@@ -495,8 +502,10 @@ 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);
dev3_dsp[dev] (IO_SKS, inst, dat);
else CRETINS;
} /* end case */
@@ -542,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? */
@@ -570,7 +579,7 @@ return SCPE_OK;
Note that the channel can be disconnected if CHN_EOR is set, but must
not be if XFR_REQ is set */
t_stat chan_read (int32 ch)
{
uint32 dat = 0;
@@ -628,7 +637,7 @@ if (TST_EOR (ch)) { /* end record? */
} /* end else if cnt */
return chan_eor (ch); /* eot/eor int */
}
return r;
return r;
}
void chan_write_mem (int32 ch)
@@ -958,7 +967,7 @@ for (i = 0; i < NUM_CHAN; i++) {
/* Test each device for conflict; add to map; init tables */
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru devices */
for (i = 0; (dptr = sim_devices[i]); i++) { /* loop thru devices */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if ((dibp == NULL) || (dptr->flags & DEV_DIS)) /* exist, enabled? */
continue;
@@ -973,11 +982,8 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru devices */
for (j = 0; j < tplp->num; j++) { /* repeat as needed */
doff = dev + tplp->off + j; /* get offset dnum */
if (dev_map[doff][ch]) { /* slot in use? */
printf ("Device number conflict, chan = %s, devno = %02o\n",
chname[ch], doff);
if (sim_log)
fprintf (sim_log, "Device number conflict, chan = %s, dev = %02o\n",
chname[ch], doff);
sim_printf ("Device number conflict, chan = %s, devno = %02o\n",
chname[ch], doff);
return TRUE;
}
dev_map[doff][ch] = dibp->xfr; /* set xfr flag */

View File

@@ -40,7 +40,6 @@
#define SET_EOR 2 /* print, set eor */
#define SET_SPC 4 /* space */
extern char sds_to_ascii[64];
extern uint32 xfr_req;
extern int32 stop_invins, stop_invdev, stop_inviop;
int32 lpt_spc = 0; /* space instr */
@@ -69,6 +68,7 @@ t_stat lpt_status (UNIT *uptr);
t_stat lpt_bufout (UNIT *uptr);
void lpt_end_op (int32 fl);
t_stat lpt (uint32 fnc, uint32 inst, uint32 *dat);
int8 sds_to_ascii(int8 c);
/* LPT data structures
@@ -177,12 +177,12 @@ switch (fnc) { /* case function */
t = I_GETSKCND (inst); /* sks cond */
if (((t == 020) && (!CHP (7, lpt_cct[lpt_ccp]))) || /* 14062: !ch 7 */
((t == 010) && (lpt_unit.flags & UNIT_ATT)) || /* 12062: !online */
(t == 004) && !lpt_err) /* 11062: !err */
((t == 004) && !lpt_err)) /* 11062: !err */
*dat = 1;
break;
case IO_WRITE: /* write */
asc = sds_to_ascii[(*dat) & 077]; /* convert data */
asc = sds_to_ascii(*dat); /* convert data */
xfr_req = xfr_req & ~XFR_LPT; /* clr xfr flag */
if (lpt_bptr < LPT_WIDTH) /* store data */
lpt_buf[lpt_bptr++] = asc;

View File

@@ -168,7 +168,7 @@ DEVICE mt_dev = {
MT_NUMDR, 10, 31, 1, 8, 8,
NULL, NULL, &mt_reset,
&mt_boot, &mt_attach, NULL,
&mt_dib, DEV_DISABLE
&mt_dib, DEV_DISABLE | DEV_TAPE
};
/* Mag tape routine
@@ -235,14 +235,14 @@ switch (fnc) { /* case function */
case IO_DISC: /* disconnect */
sim_cancel (uptr); /* no more xfr's */
if (inst & DEV_OUT) { /* write? */
if (r = mt_wrend (inst)) /* end record */
if ((r = mt_wrend (inst))) /* end record */
return r;
}
break;
case IO_WREOR: /* write eor */
chan_set_flag (mt_dib.chan, CHF_EOR); /* set eor flg */
if (r = mt_wrend (inst)) /* end record */
if ((r = mt_wrend (inst))) /* end record */
return r;
mt_gap = 1; /* in gap */
sim_activate (uptr, mt_gtime); /* start timer */

View File

@@ -50,10 +50,11 @@
#define MUX_SCANMAX (MUX_LINES * MUX_FLAGS) /* flags to scan */
#define MUX_SCANMASK (MUX_SCANMAX - 1)
#define MUX_INIT_POLL 8000
#define MUXL_WAIT 500
#define MUXL_WAIT 250
#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 */
@@ -112,7 +113,7 @@ uint32 mux_tps = 100; /* polls/second */
uint32 mux_scan = 0; /* scanner */
uint32 mux_slck = 0; /* scanner locked */
TMLN mux_ldsc[MUX_LINES] = { 0 }; /* line descriptors */
TMLN mux_ldsc[MUX_LINES] = { {0} }; /* line descriptors */
TMXR mux_desc = { MUX_LINES, 0, 0, mux_ldsc }; /* mux descriptor */
t_stat mux (uint32 fnc, uint32 inst, uint32 *dat);
@@ -169,7 +170,7 @@ DEVICE mux_dev = {
1, 10, 31, 1, 8, 8,
&tmxr_ex, &tmxr_dep, &mux_reset,
NULL, &mux_attach, &mux_detach,
&mux_dib, DEV_NET | DEV_DISABLE
&mux_dib, DEV_MUX | DEV_DISABLE
};
/* MUXL data structures
@@ -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;
}
@@ -363,7 +372,7 @@ if (ln >= 0) { /* got one? */
tmxr_poll_rx (&mux_desc); /* poll for input */
for (ln = 0; ln < MUX_NUMLIN; ln++) { /* loop thru lines */
if (mux_ldsc[ln].conn) { /* connected? */
if (c = tmxr_getc_ln (&mux_ldsc[ln])) { /* get char */
if ((c = tmxr_getc_ln (&mux_ldsc[ln]))) { /* get char */
if (mux_sta[ln] & MUX_SCHP) /* already got one? */
mux_sta[ln] = mux_sta[ln] | MUX_SOVR; /* overrun */
else mux_sta[ln] = mux_sta[ln] | MUX_SCHP; /* char pending */
@@ -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;

View File

@@ -36,6 +36,7 @@
/* Constants */
#define RAD_CHAN CHAN_E /* Connected I/O controller */
#define RAD_NUMWD 64 /* words/sector */
#define RAD_NUMSC 64 /* sectors/track */
#define RAD_NUMTR 64 /* tracks/log unit */
@@ -69,6 +70,7 @@ DSPT rad_tplt[] = { /* template */
DEVICE rad_dev;
t_stat rad_svc (UNIT *uptr);
t_stat rad_reset (DEVICE *dptr);
t_stat rad_boot (int32 unitno, DEVICE *dptr);
t_stat rad_fill (int32 sba);
void rad_end_op (int32 fl);
int32 rad_adjda (int32 sba, int32 inc);
@@ -76,12 +78,13 @@ t_stat rad (uint32 fnc, uint32 inst, uint32 *dat);
/* RAD data structures
rad_dib device information block
rad_dev device descriptor
rad_unit unit descriptor
rad_reg register list
*/
DIB rad_dib = { CHAN_E, DEV_RAD, XFR_RAD, rad_tplt, &rad };
DIB rad_dib = { RAD_CHAN, DEV_RAD, XFR_RAD, rad_tplt, &rad };
UNIT rad_unit = {
UDATA (&rad_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
@@ -111,12 +114,12 @@ DEVICE rad_dev = {
"RAD", &rad_unit, rad_reg, rad_mod,
1, 8, 21, 1, 8, 24,
NULL, NULL, &rad_reset,
NULL, NULL, NULL,
&rad_boot, NULL, NULL,
&rad_dib, DEV_DISABLE
};
/* Fixed head disk routine
conn - inst = EOM0, dat = NULL
eom1 - inst = EOM1, dat = NULL
sks - inst = SKS, dat = ptr to result
@@ -157,7 +160,7 @@ switch (fnc) { /* case function */
if (new_ch != rad_dib.chan) /* wrong chan? */
return SCPE_IERR;
if ((inst & 00600) == 00200) /* alert for sec */
alert = POT_RADS;
alert = POT_RADS;
else if ((inst & 06600) == 0) { /* alert for addr */
if (sim_is_active (&rad_unit)) /* busy? */
rad_err = 1;
@@ -287,7 +290,7 @@ if (rad_sba >= (RAD_NUMWD * 2)) { /* next sector? */
((rad_da + 1) & RAD_SCMASK);
else rad_da = (rad_da & ~RAD_TRSCMASK) + /* cross band */
((rad_da + 1) & RAD_TRSCMASK);
sba = 0; /* start new sec */
sba = 1; /* start new sec */
}
return sba;
}
@@ -319,3 +322,22 @@ xfr_req = xfr_req & ~XFR_RAD; /* clr xfr req */
sim_cancel (&rad_unit); /* deactivate */
return SCPE_OK;
}
/* Boot routine - simulate FILL console command */
t_stat rad_boot (int32 unitno, DEVICE *dptr)
{
extern uint32 P, M[];
if (unitno) /* only unit 0 */
return SCPE_ARG;
if (rad_dib.chan != CHAN_W) /* only on W channel */
return SCPE_IOERR;
M[0] = 077777771; /* -7B */
M[1] = 007100000; /* LDX 0 */
M[2] = 000203226; /* EOM 3226B */
M[3] = 003200002; /* WIM 2 */
M[4] = 000100002; /* BRU 2 */
P = 1; /* start at 1 */
return SCPE_OK;
}

View File

@@ -41,7 +41,7 @@
extern uint32 xfr_req;
extern int32 stop_invins, stop_invdev, stop_inviop;
int32 ptr_sor = 0; /* start of rec */
int32 ptr_stopioe = 1; /* stop on err */
int32 ptr_stopioe = 0; /* no stop on err */
int32 ptp_ldr = 0; /* no leader */
int32 ptp_stopioe = 1;
DSPT std_tplt[] = { { 1, 0 }, { 0, 0 } }; /* template */
@@ -63,10 +63,9 @@ t_stat tti_reset (DEVICE *dptr);
t_stat tto (uint32 fnc, uint32 inst, uint32 *dat);
t_stat tto_svc (UNIT *uptr);
t_stat tto_reset (DEVICE *dptr);
extern const char ascii_to_sds[128];
extern const char sds_to_ascii[64];
extern const char odd_par[64];
int8 ascii_to_sds(int8 ch);
int8 sds_to_ascii(int8 ch);
extern const int8 odd_par[64];
/* PTR data structures
@@ -277,7 +276,7 @@ if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */
ptr_set_err (); /* yes, err, disc */
if (feof (ptr_unit.fileref)) { /* end of file? */
if (ptr_stopioe)
printf ("PTR end of file\n");
sim_printf ("PTR end of file\n");
else return SCPE_OK;
}
else perror ("PTR I/O error"); /* I/O error */
@@ -395,7 +394,7 @@ t_stat r = SCPE_OK;
if (ptp_ldr) { /* need leader? */
for (i = 0; i < 12; i++) { /* punch leader */
if (r = ptp_out (0))
if ((r = ptp_out (0)))
break;
}
}
@@ -505,8 +504,8 @@ if (temp & SCPE_BREAK) /* ignore break */
return SCPE_OK;
temp = temp & 0177;
tti_unit.pos = tti_unit.pos + 1;
if (ascii_to_sds[temp] >= 0) {
tti_unit.buf = ascii_to_sds[temp]; /* internal rep */
if (ascii_to_sds(temp) >= 0) {
tti_unit.buf = ascii_to_sds(temp); /* internal rep */
sim_putchar (temp); /* echo */
if (temp == '\r') /* lf after cr */
sim_putchar ('\n');
@@ -588,7 +587,7 @@ else if (uptr->buf == TT_BS)
asc = '\b';
else if (uptr->buf == TT_TB)
asc = '\t';
else asc = sds_to_ascii[uptr->buf]; /* translate */
else asc = sds_to_ascii(uptr->buf); /* translate */
if ((r = sim_putchar_s (asc)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */

View File

@@ -45,6 +45,7 @@ extern DEVICE mt_dev;
extern DEVICE mux_dev, muxl_dev;
extern UNIT cpu_unit;
extern REG cpu_reg[];
extern uint32 cpu_mode;
extern uint32 M[MAXMEMSIZE];
/* SCP data structures and interface routines
@@ -93,15 +94,19 @@ const char *sim_stop_messages[] = {
"Nested EXU's exceed limit",
"Memory management trap during interrupt",
"Memory management trap during trap",
"Trap instruction not BRM",
"Trap instruction not BRM or BRU",
"RTC instruction not MIN or SKR",
"Interrupt vector zero",
"Runaway carriage control tape"
"Runaway carriage control tape",
"Monitor-mode Breakpoint",
"Normal-mode Breakpoint",
"User-mode Breakpoint",
"Next expired"
};
/* Character conversion tables */
/* SDS 930 character conversion tables. Per 930 Ref Man Appendix A */
const char sds_to_ascii[64] = {
const int8 sds930_to_ascii[64] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ' ', '=', '\'', ':', '>', '%', /* 17 = check mark */
'+', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
@@ -112,8 +117,8 @@ const char sds_to_ascii[64] = {
'Y', 'Z', '?', ',', '(', '~', '\\', '#' /* 72 = rec mark */
}; /* 75 = squiggle, 77 = del */
const char ascii_to_sds[128] = {
-1, -1, -1, -1, -1, -1, -1, -1, /* 0 - 37 */
const int8 ascii_to_sds930[128] = {
-1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 37 */
032, 072, -1, -1, -1, 052, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
@@ -125,13 +130,45 @@ const char ascii_to_sds[128] = {
030, 031, 041, 042, 043, 044, 045, 046,
047, 050, 051, 062, 063, 064, 065, 066,
067, 070, 071, 035, 076, 055, 057, 060,
000, 021, 022, 023, 024, 025, 026, 027, /* 140 - 177 */
030, 031, 041, 042, 043, 044, 045, 046,
-1, 021, 022, 023, 024, 025, 026, 027, /* 140 - 177 */
030, 031, 041, 042, 043, 044, 045, 046, /* fold lower case to upper */
047, 050, 051, 062, 063, 064, 065, 066,
067, 070, 071, -1, -1, -1, -1, -1
};
const char odd_par[64] = {
/* SDS 940 character conversion tables. Per 940 Ref Man Appendix A */
const int8 sds940_to_ascii[64] = {
' ', '!', '"', '#', '$', '%', '&', '\'', /* 00 - 17 */
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', /* 20 - 37 */
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 40 - 57 */
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 60 - 77 */
'X', 'Y', 'Z', '[', '\\', ']', '^', '_'
};
const int8 ascii_to_sds940[128] = {
-1, 141, 142, 143, 144, 145, 146, 147, /* 00 - 37 */
-1, 151, 152, 153, 154, 155, -1, -1,
-1, 161, 162, 163, 164, 165, 166, 167,
170, 171, 172, -1, -1, -1, -1, -1,
000, 001, 002, 003, 004, 005, 006, 007, /* 40 - 77 */
010, 011, 012, 013, 014, 015, 016, 017,
020, 021, 022, 023, 024, 025, 026, 027,
030, 031, 032, 033, 034, 035, 036, 037,
040, 041, 042, 043, 044, 045, 046, 047, /* 100 - 137 */
050, 051, 052, 053, 054, 055, 056, 057,
060, 061, 062, 063, 064, 065, 066, 067,
070, 071, 072, 073, 074, 075, 076, 077,
-1, 041, 042, 043, 044, 045, 046, 047, /* 140 - 177 */
050, 051, 052, 053, 054, 055, 056, 057, /* fold lower case to upper */
060, 061, 062, 063, 064, 065, 066, 067,
070, 071, 072, -1, -1, -1, -1, -1
};
const int8 odd_par[64] = {
0100, 0001, 0002, 0103, 0004, 0105, 0106, 0007,
0010, 0111, 0112, 0013, 0114, 0015, 0016, 0117,
0020, 0121, 0122, 0023, 0124, 0025, 0026, 0127,
@@ -212,12 +249,11 @@ for (i = wd = 0; i < 4; ) {
}
return wd;
}
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
int32 i, wd, buf[8];
int32 ldr = 1;
extern int32 sim_switches;
extern uint32 P;
if ((*cptr != 0) || (flag != 0))
@@ -228,11 +264,11 @@ for (i = 0; i < 8; i++) { /* read boot */
if ((wd = get_word (fileref, &ldr)) < 0)
return SCPE_FMT;
buf[i] = wd;
}
}
if ((buf[0] != 023200012) || /* 2 = WIM 12,2 */
(buf[1] != 004100002) || /* 3 = BRX 2 */
(buf[2] != 007100011) || /* 4 = LDX 11 */
(buf[3] != 023200000) || /* 5 = WIM 0,2 */
((buf[3] & ~VA_MASK) != 023200000) || /* 5 = WIM xxxxx,2 */
(buf[4] != 004021000) || /* 6 = SKS 21000 */
(buf[5] != 004100005)) /* 7 = BRX 5 */
return SCPE_FMT;
@@ -240,7 +276,7 @@ for (i = 0; i < 8; i++) /* copy boot */
M[i + 2] = buf[i];
if (I_GETOP (buf[6]) == BRU)
P = buf[6] & VA_MASK;
for (i = buf[7] & VA_MASK; i <= VA_MASK; i++) { /* load data */
for (i = (buf[3]+buf[7]) & VA_MASK; i <= VA_MASK; i++) {/* load data */
if ((wd = get_word (fileref, &ldr)) < 0)
return SCPE_OK;
M[i] = wd;
@@ -258,26 +294,51 @@ return SCPE_NXM;
#define I_V_MRF 003 /* memory reference */
#define I_V_REG 004 /* register change */
#define I_V_SHF 005 /* shift */
#define I_V_OPO 006 /* opcode only */
#define I_V_OPO 006 /* operand optional */
#define I_V_CHC 007 /* chan cmd */
#define I_V_CHT 010 /* chan test */
#define I_NPN (I_V_NPN << I_V_FL)
#define I_PPO (I_V_PPO << I_V_FL)
#define I_IOI (I_V_IOI << I_V_FL)
#define I_MRF (I_V_MRF << I_V_FL)
#define I_REG (I_V_REG << I_V_FL)
#define I_SHF (I_V_SHF << I_V_FL)
#define I_V_SPP 011 /* system POP */
#define I_NPN (I_V_NPN << I_V_FL)
#define I_PPO (I_V_PPO << I_V_FL)
#define I_IOI (I_V_IOI << I_V_FL)
#define I_MRF (I_V_MRF << I_V_FL)
#define I_REG (I_V_REG << I_V_FL)
#define I_SHF (I_V_SHF << I_V_FL)
#define I_OPO (I_V_OPO << 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)
#define I_SPP (I_V_SPP << I_V_FL)
static const int32 masks[] = {
037777777, 010000000, 017700000,
017740000, 017700000, 017774000,
017700000, 017377677, 027737677
037777777, 010000000, 017700000, /* NPN, PPO, IOI */
017740000, 017700000, 017774000, /* MRF, REG, SHF */
017740000, 017377677, 027737677, /* OPO, CHC, CHT */
057740000 /* SPP */
};
static const char *opcode[] = {
static const char *opcode[] = { /* Note: syspops must preceed generic pop */
"WSI", "SWI", "BKPT","STO",
"WCD", "STI", "GCD", "SIC",
"ISC", "DBI", "DBO", "DWI",
"DWO", "LAS", "SAS", "IST",
"OST", "EXS", "FDV", "FMP",
"FSB", "FAD", "WCI", "WIO",
"CIO", "SKSG","SKSE","WCH",
"GCI", "LDP", "STP", "SBRM",
"SBRR","CTRL","BRS", "TCI",
"TCO", "BIO",
"WSI*", "SWI*", "BKPT*","STO*",
"WCD*", "STI*", "GCD*", "SIC*",
"ISC*", "DBI*", "DBO*", "DWI*",
"DWO*", "LAS*", "SAS*", "IST*",
"OST*", "EXS*", "FDV*", "FMP*",
"FSB*", "FAD*", "WCI*", "WIO*",
"CIO*", "SKSG*","SKSE*","WCH*",
"GCI*", "LDP*", "STP*", "SBRM*",
"SBRR*","CTRL*","BRS*", "TCI*",
"TCO*", "BIO*",
"POP", "EIR", "DIR",
"ROV", "REO", "OTO", "OVT",
"IDT", "IET",
@@ -300,10 +361,10 @@ static const char *opcode[] = {
"SKM", "LDX", "SKA", "SKG",
"SKD", "LDB", "LDA", "EAX",
"BRU*",
"BRU*",
"MIY*", "BRI*", "MIW*", "POT*",
"ETR*", "MRG*", "EOR*",
"EXU*",
"NOP*", "EXU*",
"YIM*", "WIM*", "PIN*",
"STA*", "STB*", "STX*",
"BRX*", "BRM*",
@@ -329,53 +390,75 @@ static const char *opcode[] = {
};
static const int32 opc_val[] = {
010000000+I_PPO, 000220002+I_NPN, 000220004+I_NPN,
002200001+I_NPN, 002200010+I_NPN, 002200100+I_NPN, 002200101+I_NPN,
004020002+I_NPN, 004020004+I_NPN,
004020040+I_NPN, 004020100+I_NPN, 004020200+I_NPN, 004020400+I_NPN,
004600003+I_NPN, 004600005+I_NPN, 004600012+I_NPN, 004600014+I_NPN,
004600060+I_NPN, 004600122+I_NPN, 004600140+I_NPN, 004600160+I_NPN,
024600003+I_NPN,
050000000+I_SPP, 050100000+I_SPP, 053300000+I_SPP, 053400000+I_SPP, /* WSI, SWI, BKPT, STO, */
053500000+I_SPP, 053600000+I_SPP, 053700000+I_SPP, 054000000+I_SPP, /* WCD, STI, GCD, SIC, */
054100000+I_SPP, 054200000+I_SPP, 054300000+I_SPP, 054400000+I_SPP, /* ISC, DBI, DBO, DWI, */
054500000+I_SPP, 054600000+I_SPP, 054700000+I_SPP, 055000000+I_SPP, /* DWO, LAS, SAS, IST, */
055100000+I_SPP, 055200000+I_SPP, 055300000+I_SPP, 055400000+I_SPP, /* OST, EXS, FDV, FMP, */
055500000+I_SPP, 055600000+I_SPP, 055700000+I_SPP, 056000000+I_SPP, /* FSB, FAD, WCI, WIO, */
056100000+I_SPP, 056200000+I_SPP, 056300000+I_SPP, 056400000+I_SPP, /* CIO, SKSG, SKSE, WCH, */
056500000+I_SPP, 056600000+I_SPP, 056700000+I_SPP, 057000000+I_SPP, /* GCI, LDP, STP, SBRM,*/
057100000+I_SPP, 057200000+I_SPP, 057300000+I_SPP, 057400000+I_SPP, /* SBRR, CTRL, BRS, TCI, */
057500000+I_SPP, 057600000+I_SPP, /* TCO, BIO, */
000000000+I_NPN, 000100000+I_MRF, 000200000+I_IOI, 000600000+I_IOI,
001000000+I_MRF, 001100000+I_MRF, 001200000+I_MRF, 001300000+I_MRF,
001400000+I_MRF, 001600000+I_MRF, 001700000+I_MRF,
002000000+I_OPO, 002300000+I_MRF,
003000000+I_MRF, 003200000+I_MRF, 003300000+I_MRF,
003500000+I_MRF, 003600000+I_MRF, 003700000+I_MRF,
004000000+I_IOI, 004100000+I_MRF, 004300000+I_MRF,
005000000+I_MRF, 005100000+I_MRF, 005200000+I_MRF, 005300000+I_MRF,
005400000+I_MRF, 005500000+I_MRF, 005600000+I_MRF, 005700000+I_MRF,
006000000+I_MRF, 006100000+I_MRF, 006200000+I_MRF, 006300000+I_MRF,
006400000+I_MRF, 006500000+I_MRF,
007000000+I_MRF, 007100000+I_MRF, 007200000+I_MRF, 007300000+I_MRF,
007400000+I_MRF, 007500000+I_MRF, 007600000+I_MRF, 007700000+I_MRF,
054000000+I_SPP, 050140000+I_SPP, 053340000+I_SPP, 053440000+I_SPP, /* WSI*, SWI*, BKPT*, STO*, */
053540000+I_SPP, 053640000+I_SPP, 053740000+I_SPP, 054400000+I_SPP, /* WCD*, STI*, GCD*, SIC*, */
054140000+I_SPP, 054240000+I_SPP, 054340000+I_SPP, 054440000+I_SPP, /* ISC*, DBI*, DBO*, DWI*, */
054540000+I_SPP, 054640000+I_SPP, 054740000+I_SPP, 055400000+I_SPP, /* DWO*, LAS*, SAS*, IST*, */
055140000+I_SPP, 055240000+I_SPP, 055340000+I_SPP, 055440000+I_SPP, /* OST*, EXS*, FDV*, FMP*, */
055540000+I_SPP, 055640000+I_SPP, 055740000+I_SPP, 056400000+I_SPP, /* FSB*, FAD*, WCI*, WIO*, */
056140000+I_SPP, 056240000+I_SPP, 056340000+I_SPP, 056440000+I_SPP, /* CIO*, SKSG*, SKSE*, WCH*, */
056540000+I_SPP, 056640000+I_SPP, 056740000+I_SPP, 057400000+I_SPP, /* GCI*, LDP*, STP*, SBRM*,*/
057140000+I_SPP, 057240000+I_SPP, 057340000+I_SPP, 057440000+I_SPP, /* SBRR*, CTRL*, BRS*, TCI*, */
057540000+I_SPP, 057640000+I_SPP, /* TCO*, BIO*, */
000140000+I_MRF,
001040000+I_MRF, 001140000+I_MRF, 001240000+I_MRF, 001340000+I_MRF,
001440000+I_MRF, 001640000+I_MRF, 001740000+I_MRF,
002340000+I_MRF,
003040000+I_MRF, 003240000+I_MRF, 003340000+I_MRF,
003540000+I_MRF, 003640000+I_MRF, 003740000+I_MRF,
004140000+I_MRF, 004340000+I_MRF,
005040000+I_MRF, 005140000+I_MRF, 005240000+I_MRF, 005340000+I_MRF,
005440000+I_MRF, 005540000+I_MRF, 005640000+I_MRF, 005740000+I_MRF,
006040000+I_MRF, 006140000+I_MRF, 006240000+I_MRF, 006340000+I_MRF,
006440000+I_MRF, 006540000+I_MRF,
007040000+I_MRF, 007140000+I_MRF, 007240000+I_MRF, 007340000+I_MRF,
007440000+I_MRF, 007540000+I_MRF, 007640000+I_MRF, 007740000+I_MRF,
010000000+I_PPO, 000220002+I_NPN, 000220004+I_NPN, /* POP, EIR, DIR, */
002200001+I_NPN, 002200010+I_NPN, 002200100+I_NPN, 002200101+I_NPN, /* ROV, REO, OTO, OVT, */
004020002+I_NPN, 004020004+I_NPN, /* IDT, IET, */
004020040+I_NPN, 004020100+I_NPN, 004020200+I_NPN, 004020400+I_NPN, /* BPT4, BPT3, BPT2, BPT1, */
004600003+I_NPN, 004600005+I_NPN, 004600012+I_NPN, 004600014+I_NPN, /* CLAB, ABC, BAC, XAB, */
004600060+I_NPN, 004600122+I_NPN, 004600140+I_NPN, 004600160+I_NPN, /* XXB, STE, LDE, XEE, */
024600003+I_NPN, /* CLEAR, */
006600000+I_SHF, 006620000+I_SHF, 006624000+I_SHF,
006700000+I_SHF, 006710000+I_SHF, 006720000+I_SHF,
006640000+I_MRF, 006740000+I_MRF,
000000000+I_NPN, 000100000+I_MRF, 000200000+I_IOI, 000600000+I_IOI, /* HLT, BRU, EOM, EOD, */
001000000+I_MRF, 001100000+I_MRF, 001200000+I_MRF, 001300000+I_MRF, /* MIY, BRI, MIW, POT, */
001400000+I_MRF, 001600000+I_MRF, 001700000+I_MRF, /* ETR, MRG, EOR, */
002000000+I_OPO, 002300000+I_MRF, /* NOP, EXU, */
003000000+I_MRF, 003200000+I_MRF, 003300000+I_MRF, /* YIM, WIM, PIN, */
003500000+I_MRF, 003600000+I_MRF, 003700000+I_MRF, /* STA, STB, STX, */
004000000+I_IOI, 004100000+I_MRF, 004300000+I_MRF, /* SKS, BRX, BRM, */
005000000+I_MRF, 005100000+I_MRF, 005200000+I_MRF, 005300000+I_MRF, /* SKE, BRR, SKB, SKN, */
005400000+I_MRF, 005500000+I_MRF, 005600000+I_MRF, 005700000+I_MRF, /* SUB, ADD, SUC, ADC, */
006000000+I_MRF, 006100000+I_MRF, 006200000+I_MRF, 006300000+I_MRF, /* SKR, MIN, XMA, ADM, */
006400000+I_MRF, 006500000+I_MRF, /* MUL, DIV, */
007000000+I_MRF, 007100000+I_MRF, 007200000+I_MRF, 007300000+I_MRF, /* SKM, LDX, SKA, SKG, */
007400000+I_MRF, 007500000+I_MRF, 007600000+I_MRF, 007700000+I_MRF, /* SKD, LDB, LDA, EAX, */
000250000+I_CHC, 000200000+I_CHC, 000212000+I_CHC, 000214000+I_CHC,
004014000+I_CHT, 004011000+I_CHT, 004012000+I_CHT, 004010400+I_CHT,
000140000+I_MRF, /* BRU*, */
001040000+I_MRF, 001140000+I_MRF, 001240000+I_MRF, 001340000+I_MRF, /* MIY*, BRI*, MIW*, POT*, */
001440000+I_MRF, 001640000+I_MRF, 001740000+I_MRF, /* ETR*, MRG*, EOR*, */
002040000+I_OPO, 002340000+I_MRF, /* NOP*, EXU*, */
003040000+I_MRF, 003240000+I_MRF, 003340000+I_MRF, /* YIM*, WIM*, PIN*, */
003540000+I_MRF, 003640000+I_MRF, 003740000+I_MRF, /* STA*, STB*, STX*, */
004140000+I_MRF, 004340000+I_MRF, /* BRX*, BRM*, */
005040000+I_MRF, 005140000+I_MRF, 005240000+I_MRF, 005340000+I_MRF, /* SKE*, BRR*, SKB*, SKN*, */
005440000+I_MRF, 005540000+I_MRF, 005640000+I_MRF, 005740000+I_MRF, /* SUB*, ADD*, SUC*, ADC*, */
006040000+I_MRF, 006140000+I_MRF, 006240000+I_MRF, 006340000+I_MRF, /* SKR*, MIN*, XMA*, ADM*, */
006440000+I_MRF, 006540000+I_MRF, /* MUL*, DIV*, */
007040000+I_MRF, 007140000+I_MRF, 007240000+I_MRF, 007340000+I_MRF, /* SKM*, LDX*, SKA*, SKG*, */
007440000+I_MRF, 007540000+I_MRF, 007640000+I_MRF, 007740000+I_MRF, /* SKD*, LDB*, LDA*, EAX*, */
004600001+I_REG, 004600002+I_REG, 004600004+I_REG,
004600010+I_REG, 004600020+I_REG, 004600040+I_REG,
004600100+I_REG, 004600200+I_REG, 004600400+I_REG,
004601000+I_REG, 024600000+I_REG, 004600000+I_REG,
006600000+I_SHF, 006620000+I_SHF, 006624000+I_SHF, /* RSH, RCY, LRSH, */
006700000+I_SHF, 006710000+I_SHF, 006720000+I_SHF, /* LSH, NOD, LCY, */
006640000+I_MRF, 006740000+I_MRF, /* RSH*, LSH*, */
000250000+I_CHC, 000200000+I_CHC, 000212000+I_CHC, 000214000+I_CHC, /* ALC, DSC, ASC, TOP, */
004014000+I_CHT, 004011000+I_CHT, 004012000+I_CHT, 004010400+I_CHT, /* CAT, CET, CZT, CIT, */
004600001+I_REG, 004600002+I_REG, 004600004+I_REG, /* CLA, CLB, CAB, */
004600010+I_REG, 004600020+I_REG, 004600040+I_REG, /* CBA, CBX, CXB, */
004600100+I_REG, 004600200+I_REG, 004600400+I_REG, /* XPO, CXA, CAX, */
004601000+I_REG, 024600000+I_REG, 004600000+I_REG, /* CNA, CLX, NULL, */
-1
};
@@ -406,6 +489,26 @@ for (i = sp = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
return;
}
/* Convert from SDS internal character code to ASCII depending upon cpu mode. */
int8 sds_to_ascii(int8 ch)
{
ch &= 077;
if (cpu_mode == NML_MODE)
return sds930_to_ascii[ch];
else
return sds940_to_ascii[ch];
}
/* Convert from ASCII to SDS internal character code depending upon cpu mode. */
int8 ascii_to_sds(int8 ch)
{
ch &= 0177;
if (cpu_mode == NML_MODE)
return ascii_to_sds930[ch];
else
return ascii_to_sds940[ch];
}
/* Symbolic decode
Inputs:
@@ -431,17 +534,20 @@ va = inst & VA_MASK;
shf = inst & I_SHFMSK;
nonop = inst & 077777;
if (sw & SWMASK ('A')) { /* ASCII? */
if (inst > 0377)
return SCPE_ARG;
fprintf (of, FMTASC (inst & 0177));
if (sw & SWMASK ('A')) { /* SDS internal ASCII? */
for (i = 16; i >= 0; i -= 8) {
ch = (inst >> i) & 0377; /* map printable chars */
if (ch <= 0137)
ch += 040; /* from int. to ext. ASCII */
else
ch = '.'; /* or indicate not displayable */
fprintf (of, "%c", ch);
}
return SCPE_OK;
}
if (sw & SWMASK ('C')) { /* character? */
fprintf (of, "%c", sds_to_ascii[(inst >> 18) & 077]);
fprintf (of, "%c", sds_to_ascii[(inst >> 12) & 077]);
fprintf (of, "%c", sds_to_ascii[(inst >> 6) & 077]);
fprintf (of, "%c", sds_to_ascii[inst & 077]);
if (sw & SWMASK ('C')) { /* six-bit character? */
for (i = 18; i >= 0; i -= 6)
fprintf (of, "%c", sds_to_ascii(inst >> i));
return SCPE_OK;
}
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
@@ -454,8 +560,7 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
switch (j) { /* case on class */
case I_V_NPN: /* no operands */
case I_V_OPO: /* opcode only */
case I_V_NPN: /* no operand */
fprintf (of, "%s", opcode[i]); /* opcode */
break;
@@ -465,6 +570,12 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
fprintf (of, ",%-o", tag);
break;
case I_V_SPP: /* syspop */
fprintf (of, "%s %-o", opcode[i], va);
if (tag & 2)
fprintf (of, ",2");
break;
case I_V_PPO: /* pop */
fprintf (of, "POP %-o,%-o", op, nonop);
if (tag)
@@ -477,6 +588,13 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
fprintf (of, ",%-o", tag);
break;
case I_V_OPO: /* operand optional */
if (!tag && !va)
{
fprintf (of, "%s", opcode[i]); /* opcode only */
break;
} /* or fall through to MRF */
case I_V_MRF: /* mem ref */
fprintf (of, "%s %-o", opcode[i], va);
if (tag)
@@ -540,7 +658,7 @@ return cptr; /* no change */
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_stat r;
char gbuf[CBUFSIZE];
@@ -555,16 +673,27 @@ for (i = 1; (i < 4) && (cptr[i] != 0); i++) {
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
if (cptr[0] == 0) /* must have 1 char */
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;
}
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 */
return SCPE_ARG;
for (i = j = 0, val[0] = 0; i < 4; i++) {
if (cptr[i] == 0) /* latch str end */
j = 1;
k = ascii_to_sds[cptr[i] & 0177]; /* cvt char */
k = ascii_to_sds(cptr[i]); /* cvt char */
if (j || (k < 0)) /* bad, end? spc */
k = 0;
val[0] = (val[0] << 6) | k;
@@ -581,7 +710,7 @@ j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
switch (j) { /* case on class */
case I_V_NPN: case I_V_OPO: /* opcode only */
case I_V_NPN: /* no operand */
break;
case I_V_SHF: /* shift */
@@ -609,8 +738,12 @@ switch (j) { /* case on class */
val[0] = val[0] | d | tag;
break;
case I_V_OPO: /* operand optional */
case I_V_SPP: /* syspop */
case I_V_MRF: /* mem ref */
cptr = get_glyph (cptr, gbuf, ','); /* get next field */
if (gbuf[0]=='\0' && j==I_V_OPO) /* operand optional */
break;
d = get_uint (gbuf, 8, VA_MASK, &r); /* virt address */
if (r != SCPE_OK)
return SCPE_ARG;