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:
420
SDS/sds_cpu.c
420
SDS/sds_cpu.c
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
66
SDS/sds_io.c
66
SDS/sds_io.c
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
305
SDS/sds_sys.c
305
SDS/sds_sys.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user