1 /* i7094_cpu.c: IBM 7094 CPU simulator
2 
3    Copyright (c) 2003-2011, Robert M. Supnik
4 
5    Permission is hereby granted, free of charge, to any person obtaining a
6    copy of this software and associated documentation files (the "Software"),
7    to deal in the Software without restriction, including without limitation
8    the rights to use, copy, modify, merge, publish, distribute, sublicense,
9    and/or sell copies of the Software, and to permit persons to whom the
10    Software is furnished to do so, subject to the following conditions:
11 
12    The above copyright notice and this permission notice shall be included in
13    all copies or substantial portions of the Software.
14 
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18    ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22    Except as contained in this notice, the name of Robert M Supnik shall not be
23    used in advertising or otherwise to promote the sale, use or other dealings
24    in this Software without prior written authorization from Robert M Supnik.
25 
26    cpu          7094 central processor
27 
28    31-Dec-11    RMS     Select traps have priority over protect traps
29                         Added SRI, SPI
30                         Fixed user mode and relocation from CTSS RPQ documentation
31    16-Jul-10    RMS     Fixed user mode protection (Dave Pitts)
32                         Fixed issues in storage nullification mode
33    28-Apr-07    RMS     Removed clock initialization
34    29-Oct-06    RMS     Added additional expanded core instructions
35    17-Oct-06    RMS     Fixed the fix in halt IO wait loop
36    16-Jun-06    RMS     Fixed bug in halt IO wait loop
37 
38    The register state for the 7094 is:
39 
40    AC<S,Q,P,1:35>       accumulator
41    MQ<S,1:35>           multiplier-quotient register
42    SI<S,1:35>           storage indicators
43    KEYS<0:35>           front panel keys (switches)
44    IC<0:14>             instruction counter (called PC here)
45    XR<0:14>[8]          index registers (XR[0] is always 0)
46    SSW<0:5>             sense switches
47    SLT<0:3>             sense lights
48    OVF                  AC overflow
49    MQO                  MQ overflow
50    DVC                  divide check
51    IOC                  I/O check
52    TTRAP                transfer trap mode
53    CTRAP                copy trap mode (for 709 compatibility)
54    FTRAP                floating trap mode (off is 704 compatibility)
55    STRAP                select trap mode
56    STORN                storage nullifcation mode
57    MULTI                multi-tag mode (7090 compatibility)
58 
59    CTSS required a set of special features: memory extension (to 65K),
60    protection, and relocation.  Additional state:
61 
62    USER                 user mode
63    RELOCM               relocation mode
64    USER_BUF             user mode buffer
65    RELOC_BUF            relocation buffer
66    INST_BASE            instruction memory select (A vs B core)
67    DATA_BASE            data memory select (A vs B core)
68    IND_RELOC<0:6>       relocation value (block number)
69    IND_START<0:6>       start address block
70    IND_LIMIT<0:6>       limit address block
71 
72    The 7094 had five instruction formats: memory reference,
73    memory reference with count, convert, decrement, and immediate.
74 
75       00000000011 11 1111 112 222222222333333
76      S12345678901 23 4567 890 123456789012345
77     +------------+--+----+---+---------------+
78     |   opcode   |ND|0000|tag|     address   | memory reference
79     +------------+--+----+---+---------------+
80 
81       00000000011 111111 112 222222222333333
82      S12345678901 234567 890 123456789012345
83     +------------+------+---+---------------+
84     |   opcode   | count|tag|     address   | memory reference
85     +------------+------+---+---------------+ with count
86 
87       000000000 11111111 11 2 222222222333333
88      S123456789 01234567 89 0 123456789012345
89     +----------+--------+--+-+---------------+
90     |  opcode  | count  |00|X|    address    | convert
91     +----------+--------+--+-+---------------+
92 
93       00 000000011111111 112 222222222333333
94      S12 345678901234567 890 123456789012345
95     +---+---------------+---+---------------+
96     |opc|   decrement   |tag|     address   | decrement
97     +---+---------------+---+---------------+
98 
99       00000000011 111111 112222222222333333
100      S12345678901 234567 890123456789012345
101     +------------+------+------------------+
102     |   opcode   |000000|   immediate      | immediate
103     +------------+------+------------------+
104 
105    This routine is the instruction decode routine for the 7094.
106    It is called from the simulator control program to execute
107    instructions in simulated memory, starting at the simulated PC.
108    It runs until a stop condition occurs.
109 
110    General notes:
111 
112    1. Reasons to stop.  The simulator can be stopped by:
113 
114         HALT instruction
115         illegal instruction
116         illegal I/O operation for device
117         illegal I/O operation for channel
118         breakpoint encountered
119         nested XEC's exceeding limit
120         divide check
121         I/O error in I/O simulator
122 
123    2. Data channel traps.  The 7094 is a channel-based system.
124       Channels can generate traps for errors and status conditions.
125       Channel trap state:
126 
127         ch_flags[0..7]  flags for channels A..H
128         chtr_enab       channel trap enables
129         chtr_inht       channel trap inhibit due to trap (cleared by RCT)
130         chtr_inhi       channel trap inhibit due to XEC, ENB, RCT, LRI,
131                         LPI, SEA, SEB (cleared after one instruction)
132 
133       Channel traps are summarized in variable chtr_pend.
134 
135    3. Arithmetic.  The 7094 uses signed magnitude arithmetic for
136       integer and floating point calculations, and 2's complement
137       arithmetic for indexing calculations.
138 
139    4. Adding I/O devices.  These modules must be modified:
140 
141         i7094_defs.h    add device definitions
142         i7094_io.c      add device address mapping
143         i7094_sys.c     add sim_devices table entry
144 */
145 
146 #include "i7094_defs.h"
147 
148 #define PCQ_SIZE        64                              /* must be 2**n */
149 #define PCQ_MASK        (PCQ_SIZE - 1)
150 #define PCQ_ENTRY       pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = (PC | inst_base)
151 
152 #define HIST_MIN        64
153 #define HIST_MAX        (2 << 18)
154 #define HIST_CH_C       1                               /* include channel */
155 #define HIST_CH_I       2                               /* include IO */
156 
157 #define HALT_IO_LIMIT   ((2 << 18) + 1)                 /* max wait to stop */
158 
159 #define EAMASK          (mode_storn? A704_MASK: AMASK)  /* eff addr mask */
160 
161 t_uint64 *M = NULL;                                     /* memory */
162 t_uint64 AC = 0;                                        /* AC */
163 t_uint64 MQ = 0;                                        /* MQ */
164 t_uint64 SI = 0;                                        /* indicators */
165 t_uint64 KEYS = 0;                                      /* storage keys */
166 uint32 PC = 0;                                          /* PC (IC) */
167 uint32 oldPC = 0;                                       /* prior PC */
168 uint32 XR[8] = { 0 };                                   /* index registers */
169 uint32 SSW = 0;                                         /* sense switches */
170 uint32 SLT = 0;                                         /* sense lights */
171 uint32 ch_req = 0;                                      /* channel requests */
172 uint32 chtr_pend = 0;                                   /* chan trap pending */
173 uint32 chtr_inht = 0;                                   /* chan trap inhibit trap */
174 uint32 chtr_inhi = 0;                                   /* chan trap inhibit inst */
175 uint32 chtr_enab = 0;                                   /* chan trap enables */
176 uint32 mode_ttrap = 0;                                  /* transfer trap mode */
177 uint32 mode_ctrap = 0;                                  /* copy trap mode */
178 uint32 mode_strap = 0;                                  /* select trap mode */
179 uint32 mode_ftrap = 0;                                  /* floating trap mode */
180 uint32 mode_storn = 0;                                  /* storage nullification */
181 uint32 mode_multi = 0;                                  /* multi-index mode */
182 uint32 ind_ovf = 0;                                     /* overflow */
183 uint32 ind_mqo = 0;                                     /* MQ overflow */
184 uint32 ind_dvc = 0;                                     /* divide check */
185 uint32 ind_ioc = 0;                                     /* IO check */
186 uint32 cpu_model = I_9X|I_94;                           /* CPU type */
187 uint32 mode_user = 0;                                   /* (CTSS) user mode */
188 uint32 mode_reloc = 0;                                  /* (CTSS) relocation mode */
189 uint32 user_buf = 0;                                    /* (CTSS) user mode buffer */
190 uint32 reloc_buf = 0;                                   /* (CTSS) reloc mode buffer */
191 uint32 ind_reloc = 0;                                   /* (CTSS) relocation */
192 uint32 ind_start = 0;                                   /* (CTSS) prot start */
193 uint32 ind_limit = 0;                                   /* (CTSS) prot limit */
194 uint32 inst_base = 0;                                   /* (CTSS) inst A/B sel */
195 uint32 data_base = 0;                                   /* (CTSS) data A/B sel */
196 uint32 xec_max = 16;                                    /* XEC chain limit */
197 uint32 ht_pend = 0;                                     /* HTR pending */
198 uint32 ht_addr = 0;                                     /* HTR address */
199 uint32 stop_illop = 1;                                  /* stop on ill op */
200 uint32 cpu_astop = 0;                                   /* address stop */
201 
202 uint16 pcq[PCQ_SIZE] = { 0 };                           /* PC queue */
203 int32 pcq_p = 0;                                        /* PC queue ptr */
204 REG *pcq_r = NULL;                                      /* PC queue reg ptr */
205 int32 hst_p = 0;                                        /* history pointer */
206 int32 hst_lnt = 0;                                      /* history length */
207 uint32 hst_ch = 0;                                      /* channel history */
208 InstHistory *hst = NULL;                                /* instruction history */
209 
210 extern uint32 ch_sta[NUM_CHAN];
211 extern uint32 ch_flags[NUM_CHAN];
212 extern DEVICE mt_dev[NUM_CHAN];
213 extern DEVICE ch_dev[NUM_CHAN];
214 extern FILE *sim_deb;
215 extern int32 sim_int_char;
216 extern int32 sim_interval;
217 extern int32 sim_switches;
218 extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
219 
220 /* Forward and external declarations */
221 
222 t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
223 t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
224 t_stat cpu_reset (DEVICE *dptr);
225 t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc);
226 t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc);
227 t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc);
228 t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
229 t_bool ReadI (uint32 va, t_uint64 *dat);
230 t_bool Read (uint32 va, t_uint64 *dat);
231 t_bool Write (uint32 va, t_uint64 dat);
232 void WriteTA (uint32 pa, uint32 addr);
233 void WriteTAD (uint32 pa, uint32 addr, uint32 decr);
234 void TrapXfr (uint32 newpc);
235 t_bool fp_trap (uint32 spill);
236 t_bool prot_trap (uint32 decr);
237 t_bool sel_trap (uint32 va);
238 t_bool cpy_trap (uint32 va);
239 uint32 get_xri (uint32 tag);
240 uint32 get_xrx (uint32 tag);
241 void put_xr (uint32 tag, uint32 dat);
242 t_stat cpu_fprint_one_inst (FILE *st, uint32 pc, uint32 rpt, uint32 ea,
243     t_uint64 ir, t_uint64 ac, t_uint64 mq, t_uint64 si, t_uint64 opnd);
244 
245 extern uint32 chtr_eval (uint32 *decr);
246 extern void op_add (t_uint64 sr);
247 extern void op_mpy (t_uint64 ac, t_uint64 sr, uint32 sc);
248 extern t_bool op_div (t_uint64 sr, uint32 sc);
249 extern uint32 op_fad (t_uint64 sr, t_bool norm);
250 extern uint32 op_fmp (t_uint64 sr, t_bool norm);
251 extern uint32 op_fdv (t_uint64);
252 extern uint32 op_dfad (t_uint64 shi, t_uint64 slo, t_bool norm);
253 extern uint32 op_dfmp (t_uint64 shi, t_uint64 slo, t_bool norm);
254 extern uint32 op_dfdv (t_uint64 shi, t_uint64 slo);
255 extern void op_als (uint32 ea);
256 extern void op_ars (uint32 ea);
257 extern void op_lls (uint32 ea);
258 extern void op_lrs (uint32 ea);
259 extern void op_lgl (uint32 ea);
260 extern void op_lgr (uint32 ea);
261 extern t_stat op_pse (uint32 ea);
262 extern t_stat op_mse (uint32 ea);
263 extern t_stat ch_op_ds (uint32 ch, uint32 ds, uint32 unit);
264 extern t_stat ch_op_nds (uint32 ch, uint32 ds, uint32 unit);
265 extern t_stat ch_op_start (uint32 ch, uint32 clc, t_bool reset);
266 extern t_stat ch_op_store (uint32 ch, t_uint64 *dat);
267 extern t_stat ch_op_store_diag (uint32 ch, t_uint64 *dat);
268 extern t_stat ch_proc (uint32 ch);
269 
270 /* CPU data structures
271 
272    cpu_dev      CPU device descriptor
273    cpu_unit     CPU unit
274    cpu_reg      CPU register list
275    cpu_mod      CPU modifier list
276 */
277 
278 UNIT cpu_unit = { UDATA (NULL, UNIT_FIX+UNIT_BINK, STDMEMSIZE) };
279 
280 REG cpu_reg[] = {
281     { ORDATA (PC, PC, ASIZE) },
282     { ORDATA (AC, AC, 38) },
283     { ORDATA (MQ, MQ, 36) },
284     { ORDATA (SI, SI, 36) },
285     { ORDATA (KEYS, KEYS, 36) },
286     { ORDATA (XR1, XR[1], 15) },
287     { ORDATA (XR2, XR[2], 15) },
288     { ORDATA (XR3, XR[3], 15) },
289     { ORDATA (XR4, XR[4], 15) },
290     { ORDATA (XR5, XR[5], 15) },
291     { ORDATA (XR6, XR[6], 15) },
292     { ORDATA (XR7, XR[7], 15) },
293     { FLDATA (SS1, SSW, 5) },
294     { FLDATA (SS2, SSW, 4) },
295     { FLDATA (SS3, SSW, 3) },
296     { FLDATA (SS4, SSW, 2) },
297     { FLDATA (SS5, SSW, 1) },
298     { FLDATA (SS6, SSW, 0) },
299     { FLDATA (SL1, SLT, 3) },
300     { FLDATA (SL2, SLT, 2) },
301     { FLDATA (SL3, SLT, 1) },
302     { FLDATA (SL4, SLT, 0) },
303     { FLDATA (OVF, ind_ovf, 0) },
304     { FLDATA (MQO, ind_mqo, 0) },
305     { FLDATA (DVC, ind_dvc, 0) },
306     { FLDATA (IOC, ind_ioc, 0) },
307     { FLDATA (TTRAP, mode_ttrap, 0) },
308     { FLDATA (CTRAP, mode_ctrap, 0) },
309     { FLDATA (STRAP, mode_strap, 0) },
310     { FLDATA (FTRAP, mode_ftrap, 0) },
311     { FLDATA (STORN, mode_storn, 0) },
312     { FLDATA (MULTI, mode_multi, 0) },
313     { ORDATA (CHREQ, ch_req, NUM_CHAN) },
314     { FLDATA (CHTR_PEND, chtr_pend, 0) },
315     { FLDATA (CHTR_INHT, chtr_inht, 0) },
316     { FLDATA (CHTR_INHI, chtr_inhi, 0) },
317     { ORDATA (CHTR_ENAB, chtr_enab, 30) },
318     { FLDATA (USERM, mode_user, 0) },
319     { FLDATA (RELOCM, mode_reloc, 0) },
320     { FLDATA (USERBUF, user_buf, 0) },
321     { FLDATA (RELOCBUF, reloc_buf, 0) },
322     { FLDATA (IMEM, inst_base, BCORE_V) },
323     { FLDATA (DMEM, data_base, BCORE_V) },
324     { GRDATA (RELOC, ind_reloc, 8, VA_N_BLK, VA_V_BLK) },
325     { GRDATA (START, ind_start, 8, VA_N_BLK, VA_V_BLK) },
326     { GRDATA (LIMIT, ind_limit, 8, VA_N_BLK, VA_V_BLK) },
327     { ORDATA (OLDPC, oldPC, ASIZE), REG_RO },
328     { BRDATA (PCQ, pcq, 8, ASIZE, PCQ_SIZE), REG_RO+REG_CIRC },
329     { ORDATA (PCQP, pcq_p, 6), REG_HRO },
330     { FLDATA (HTPEND, ht_pend, 0) },
331     { ORDATA (HTADDR, ht_addr, ASIZE) },
332     { DRDATA (XECMAX, xec_max, 8), PV_LEFT + REG_NZ },
333     { ORDATA (WRU, sim_int_char, 8) },
334     { FLDATA (STOP_ILL, stop_illop, 0) },
335     { ORDATA (MODEL, cpu_model, 4), REG_HRO },
336     { NULL }
337     };
338 
339 MTAB cpu_mod[] = {
340     { MTAB_XTD | MTAB_VDV, I_9X|I_94|I_CT, "MODEL", "CTSS",
341       &cpu_set_model, &cpu_show_model, NULL },
342     { MTAB_XTD | MTAB_VDV, I_9X|I_94, NULL, "7094",
343       &cpu_set_model, NULL, NULL },
344     { MTAB_XTD | MTAB_VDV, I_9X, NULL, "7090",
345       &cpu_set_model, NULL, NULL },
346     { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
347       &cpu_set_hist, &cpu_show_hist },
348     { 0 }
349     };
350 
351 DEVICE cpu_dev = {
352     "CPU", &cpu_unit, cpu_reg, cpu_mod,
353     1, 8, PASIZE, 1, 8, 36,
354     &cpu_ex, &cpu_dep, &cpu_reset,
355     NULL, NULL, NULL,
356     NULL, DEV_DEBUG
357     };
358 
359 /* Instruction decode table */
360 
361 const uint8 op_flags[1024] = {
362  I_XN      , 0         , 0         , 0         ,        /* +000 */
363  0         , 0         , 0         , 0         ,
364  0         , 0         , 0         , 0         ,
365  0         , 0         , 0         , 0         ,
366  I_XN      , I_XN|I_9X , I_XN      , 0         ,        /* +020 */
367  I_XN      , 0         , I_XN      , I_XN      ,
368  I_XN      , I_XN      , I_XN      , I_XN      ,
369  0         , 0         , 0         , 0         ,
370  I_XN|I_9X , I_9X      , I_XN|I_9X , I_9X      ,        /* +040 */
371  I_9X      , 0         , I_XN|I_9X , 0         ,
372  0         , I_9X      , 0         , 0         ,
373  I_9X      , I_9X      , I_9X      , I_9X      ,
374  I_XN      , I_XN      , I_XN      , I_XN      ,        /* +060 */
375  I_XN      , I_XN      , I_XN      , I_XN      ,
376  0         , 0         , 0         , 0         ,
377  0         , 0         , 0         , 0         ,
378  I_XN      , I_XN|I_CT , 0         , 0         ,        /* +100 */
379  0         , 0         , 0         , 0         ,
380  0         , 0         , 0         , 0         ,
381  I_9X      , I_9X      , I_9X      , I_9X      ,
382  I_XN      , 0         , 0         , 0         ,        /* +120 */
383  0         , 0         , 0         , 0         ,
384  0         , I_9X      , 0         , 0         ,
385  0         , 0         , 0         , 0         ,
386  I_XN      , 0         , 0         , 0         ,        /* +140 */
387  0         , 0         , 0         , 0         ,
388  0         , 0         , 0         , 0         ,
389  0         , 0         , 0         , 0         ,
390  0         , I_XN|I_9X , I_XN|I_9X , 0         ,        /* +160 */
391  0         , 0         , 0         , 0         ,
392  0         , 0         , 0         , 0         ,
393  0         , 0         , 0         , 0         ,
394  I_XNR     , 0         , 0         , 0         ,        /* +200 */
395  I_XNR     , I_XNR     , 0         , 0         ,
396  0         , 0         , 0         , 0         ,
397  0         , 0         , 0         , 0         ,
398  I_XNR|I_9X, I_XNR     , 0         , 0         ,        /* +220 */
399  I_XNR|I_9X, I_XNR     , I_XNR|I_9X, I_XNR     ,
400  0         , 0         , 0         , 0         ,
401  0         , 0         , 0         , 0         ,
402  I_XNR|I_9X, I_XNR     , 0         , 0         ,        /* +240 */
403  0         , 0         , 0         , 0         ,
404  0         , 0         , 0         , 0         ,
405  0         , 0         , 0         , 0         ,
406  I_XNR     , I_XND|I_94, 0         , 0         ,        /* +260 */
407  0         , 0         , 0         , 0         ,
408  0         , 0         , 0         , 0         ,
409  0         , 0         , 0         , 0         ,
410  I_XNR     , I_XND|I_94, I_XNR     , I_XND|I_94,        /* +300 */
411  I_XNR|I_9X, I_XND|I_94, I_XNR|I_9X, I_XND|I_94,
412  0         , 0         , 0         , 0         ,
413  0         , 0         , 0         , 0         ,
414  I_XNR|I_9X, 0         , I_XNR|I_9X, 0         ,        /* +320 */
415  0         , 0         , 0         , 0         ,
416  0         , 0         , 0         , 0         ,
417  0         , 0         , 0         , 0         ,
418  I_XNR     , 0         , 0         , 0         ,        /* +340 */
419  0         , 0         , 0         , 0         ,
420  0         , 0         , 0         , 0         ,
421  0         , 0         , 0         , 0         ,
422  0         , I_XNR     , 0         , 0         ,        /* +360 */
423  0         , 0         , 0         , 0         ,
424  0         , 0         , 0         , 0         ,
425  0         , 0         , 0         , 0         ,
426  I_XNR     , I_XNR|I_9X, I_XNR     , 0         ,        /* +400 */
427  0         , 0         , 0         , 0         ,
428  0         , 0         , 0         , 0         ,
429  0         , 0         , 0         , 0         ,
430  0         , 0         , 0         , 0         ,        /* +420 */
431  0         , 0         , 0         , 0         ,
432  0         , 0         , 0         , 0         ,
433  0         , 0         , 0         , 0         ,
434  I_XNR|I_9X, I_XNR|I_9X, I_XNR|I_9X, I_XNR|I_94,        /* +440 */
435  I_XNR|I_9X, I_XNR|I_9X, I_XNR|I_9X, 0         ,
436  0         , 0         , 0         , 0         ,
437  0         , 0         , 0         , 0         ,
438  I_9X      , 0         , 0         , 0         ,        /* +460 */
439  0         , 0         , 0         , 0         ,
440  0         , 0         , 0         , 0         ,
441  0         , 0         , 0         , 0         ,
442  I_XNR|I_9X, 0         , I_XNR     , 0         ,        /* +500 */
443  0         , 0         , 0         , 0         ,
444  0         , 0         , 0         , 0         ,
445  0         , 0         , 0         , 0         ,
446  I_XNR     , 0         , I_XNR     , 0         ,        /* +520 */
447  0         , 0         , 0         , 0         ,
448  0         , 0         , 0         , 0         ,
449  I_R       , I_R       , 0         , 0         ,
450  I_XN      , I_XN      , I_XN      , I_XN      ,        /* +540 */
451  I_XN      , I_XN      , I_XN      , I_XN      ,
452  0         , 0         , 0         , 0         ,
453  0         , 0         , 0         , 0         ,
454  I_XNR     , 0         , I_XNR|I_CT, 0         ,        /* +560 */
455  I_XNR     , 0         , 0         , 0         ,
456  0         , 0         , 0         , 0         ,
457  0         , 0         , 0         , 0         ,
458  I_XN      , I_XN      , I_XN      , 0         ,        /* +600 */
459  I_XN|I_9X , 0         , 0         , 0         ,
460  0         , 0         , 0         , 0         ,
461  0         , 0         , 0         , 0         ,
462  0         , I_XNR     , I_XNR     , 0         ,        /* +620 */
463  0         , I_XNR|I_9X, 0         , 0         ,
464  I_XNR|I_9X, 0         , 0         , 0         ,
465  I_R       , 0         , I_R|I_94  , 0         ,
466  I_XN      , I_XN      , I_XN      , I_XN      ,        /* +640 */
467  I_XN|I_9X , I_XN|I_9X , I_XN|I_9X , I_XN|I_9X ,
468  0         , 0         , 0         , 0         ,
469  0         , 0         , 0         , 0         ,
470  0         , 0         , 0         , 0         ,        /* +660 */
471  0         , 0         , 0         , 0         ,
472  0         , 0         , 0         , 0         ,
473  0         , 0         , 0         , 0         ,
474  I_9X      , 0         , 0         , 0         ,        /* +700 */
475  0         , 0         , 0         , 0         ,
476  0         , 0         , 0         , 0         ,
477  0         , 0         , 0         , 0         ,
478  0         , 0         , 0         , 0         ,        /* +720 */
479  0         , 0         , 0         , 0         ,
480  0         , 0         , 0         , 0         ,
481  0         , 0         , 0         , 0         ,
482  0         , 0         , 0         , 0         ,        /* +740 */
483  0         , 0         , 0         , 0         ,
484  0         , 0         , 0         , 0         ,
485  0         , 0         , I_94      , 0         ,
486  I_X       , 0         , I_X       , I_X       ,        /* +760 */
487  I_X       , I_X       , I_X       , I_X       ,
488  I_X       , I_X       , I_X       , 0         ,
489  0         , 0         , 0         , 0         ,
490 
491  I_XN      , 0         , 0         , 0         ,        /* -000 */
492  0         , 0         , 0         , 0         ,
493  0         , 0         , 0         , 0         ,
494  0         , 0         , 0         , 0         ,
495  I_XN      , I_XN|I_9X , I_XN      , 0         ,        /* -020 */
496  I_XN      , 0         , I_XN      , I_XN      ,
497  I_XN      , I_XN      , I_XN      , I_XN      ,
498  0         , 0         , 0         , 0         ,
499  0         , 0         , 0         , 0         ,        /* -040 */
500  0         , 0         , I_9X      , 0         ,
501  0         , I_9X      , 0         , 0         ,
502  I_9X      , I_9X      , I_9X      , I_9X      ,
503  I_XN|I_9X , I_XN|I_9X , I_XN|I_9X , I_XN|I_9X ,        /* -060 */
504  I_XN|I_9X , I_XN|I_9X , I_XN|I_9X , I_XN|I_9X ,
505  0         , 0         , 0         , 0         ,
506  0         , 0         , 0         , 0         ,
507  I_XN      , I_XN|I_CT , 0         , 0         ,        /* -100 */
508  0         , 0         , 0         , 0         ,
509  0         , 0         , 0         , 0         ,
510  I_9X      , I_9X      , I_9X      , I_9X      ,
511  I_XN      , 0         , 0         , 0         ,        /* -120 */
512  0         , 0         , 0         , 0         ,
513  I_9X      , 0         , 0         , 0         ,
514  0         , 0         , 0         , 0         ,
515  I_XN|I_9X , 0         , 0         , 0         ,        /* -140 */
516  0         , 0         , 0         , 0         ,
517  0         , 0         , 0         , 0         ,
518  I_9X      , I_9X      , I_9X      , I_9X      ,
519  0         , 0         , 0         , 0         ,        /* -160 */
520  0         , 0         , 0         , 0         ,
521  0         , 0         , 0         , 0         ,
522  0         , 0         , 0         , 0         ,
523  I_XNR|I_9X, 0         , 0         , 0         ,        /* -200 */
524  0         , 0         , 0         , 0         ,
525  0         , 0         , 0         , 0         ,
526  0         , 0         , 0         , 0         ,
527  0         , 0         , 0         , 0         ,        /* -220 */
528  0         , 0         , 0         , 0         ,
529  0         , 0         , 0         , 0         ,
530  0         , 0         , 0         , 0         ,
531  I_XND|I_94, I_XND|I_94, 0         , 0         ,        /* -240 */
532  0         , 0         , 0         , 0         ,
533  0         , 0         , 0         , 0         ,
534  0         , 0         , 0         , 0         ,
535  I_XNR     , I_XND|I_94, 0         , 0         ,        /* -260 */
536  0         , 0         , 0         , 0         ,
537  0         , 0         , 0         , 0         ,
538  0         , 0         , 0         , 0         ,
539  I_XNR     , I_XND|I_94, I_XNR     , I_XND|I_94,        /* -300 */
540  I_XNR|I_9X, I_XND|I_94, I_XNR|I_9X, I_XND|I_94,
541  0         , 0         , 0         , 0         ,
542  0         , 0         , 0         , 0         ,
543  I_XNR     , 0         , 0         , 0         ,        /* -320 */
544  0         , 0         , 0         , 0         ,
545  0         , 0         , 0         , 0         ,
546  0         , 0         , 0         , 0         ,
547  I_XNR     , 0         , 0         , 0         ,        /* -340 */
548  0         , 0         , 0         , 0         ,
549  0         , 0         , 0         , 0         ,
550  0         , 0         , 0         , 0         ,
551  0         , 0         , 0         , 0         ,        /* -360 */
552  0         , 0         , 0         , 0         ,
553  0         , 0         , 0         , 0         ,
554  0         , 0         , 0         , 0         ,
555  I_XNR|I_9X, 0         , 0         , 0         ,        /* -400 */
556  0         , 0         , 0         , 0         ,
557  0         , 0         , 0         , 0         ,
558  0         , 0         , 0         , 0         ,
559  0         , 0         , 0         , 0         ,        /* -420 */
560  0         , 0         , 0         , 0         ,
561  0         , 0         , 0         , 0         ,
562  0         , 0         , 0         , 0         ,
563  0         , 0         , 0         , 0         ,        /* -440 */
564  0         , 0         , 0         , 0         ,
565  0         , 0         , 0         , 0         ,
566  0         , 0         , 0         , 0         ,
567  0         , 0         , 0         , 0         ,        /* -460 */
568  0         , 0         , 0         , 0         ,
569  0         , 0         , 0         , 0         ,
570  0         , 0         , 0         , 0         ,
571  I_XNR     , I_XNR     , 0         , 0         ,        /* -500 */
572  0         , 0         , 0         , 0         ,
573  0         , 0         , 0         , 0         ,
574  0         , 0         , 0         , 0         ,
575  I_XNR|I_9X, 0         , 0         , 0         ,        /* -520 */
576  0         , 0         , 0         , 0         ,
577  0         , 0         , 0         , 0         ,
578  I_R       , I_R       , 0         , 0         ,
579  I_XN      , I_XN      , I_XN      , I_XN      ,        /* -540 */
580  I_XN      , I_XN      , I_XNR     , I_XN      ,
581  0         , 0         , 0         , 0         ,
582  0         , 0         , 0         , 0         ,
583  0         , 0         , 0         , 0         ,        /* -560 */
584  I_XNR|I_CT, 0         , 0         , 0         ,
585  0         , 0         , 0         , 0         ,
586  0         , 0         , 0         , 0         ,
587  I_XN      , I_CT      , I_XNR|I_9X, I_XN|I_94 ,        /* -600 */
588  I_CT      , 0         , 0         , 0         ,
589  0         , 0         , 0         , 0         ,
590  0         , 0         , 0         , 0         ,
591  I_XNR|I_9X, 0         , 0         , 0         ,        /* -620 */
592  0         , I_XNR     , 0         , 0         ,
593  0         , 0         , 0         , 0         ,
594  I_R       , 0         , I_R|I_94  , 0         ,
595  I_XN      , I_XN      , I_XN      , I_XN      ,        /* -640 */
596  I_XN|I_9X , I_XN|I_9X , I_XN|I_9X , I_XN|I_9X ,
597  0         , 0         , 0         , 0         ,
598  0         , 0         , 0         , 0         ,
599  0         , 0         , 0         , 0         ,        /* -660 */
600  0         , 0         , 0         , 0         ,
601  0         , 0         , 0         , 0         ,
602  0         , 0         , 0         , 0         ,
603  I_9X      , 0         , 0         , 0         ,        /* -700 */
604  0         , 0         , 0         , 0         ,
605  0         , 0         , 0         , 0         ,
606  0         , 0         , 0         , 0         ,
607  0         , 0         , 0         , 0         ,        /* -720 */
608  0         , 0         , 0         , 0         ,
609  0         , 0         , 0         , 0         ,
610  0         , 0         , 0         , 0         ,
611  0         , 0         , 0         , 0         ,        /* -740 */
612  0         , 0         , 0         , 0         ,
613  0         , 0         , 0         , 0         ,
614  0         , 0         , I_94      , 0         ,
615  I_X       , I_X|I_CT  , 0         , I_X       ,        /* -760 */
616  0         , I_X       , 0         , 0         ,
617  0         , 0         , I_X       , I_X       ,
618  I_9X      , 0         , 0         , 0
619  };
620 
621 /* Instruction execution routine */
622 
sim_instr(void)623 t_stat sim_instr (void)
624 {
625 t_stat reason = SCPE_OK;
626 t_uint64 IR, SR, t, t1, t2, sr1;
627 uint32 op, fl, tag, tagi, addr, ea;
628 uint32 ch, dec, xr, xec_cnt, trp;
629 uint32 i, j, sc, s1, s2, spill;
630 t_bool tracing;
631 
632 /* Restore register state */
633 
634 ch_set_map ();                                          /* set dispatch map */
635 if (!(cpu_model & (I_94|I_CT)))                         /* ~7094? MTM always on */
636     mode_multi = 1;
637 inst_base = inst_base & ~AMASK;                         /* A/B sel is 1b */
638 data_base = data_base & ~AMASK;
639 ind_reloc = ind_reloc & VA_BLK;                         /* canonical form */
640 ind_start = ind_start & VA_BLK;
641 ind_limit = (ind_limit & VA_BLK) | VA_OFF;
642 chtr_pend = chtr_eval (NULL);                           /* eval chan traps */
643 tracing = ((hst_lnt != 0) || DEBUG_PRS (cpu_dev));
644 
645 if (ht_pend) {                                          /* HTR pending? */
646     oldPC = (PC - 1) & AMASK;
647     ht_pend = 0;                                        /* clear flag */
648     PCQ_ENTRY;
649     if (mode_ttrap) {                                   /* trap? */
650         WriteTA (TRAP_STD_SAV, oldPC);                  /* save PC */
651         TrapXfr (TRAP_TRA_PC);                          /* trap */
652         }
653     else PC = ht_addr;                                  /* branch */
654     }
655 
656 /* Main instruction fetch/decode loop */
657 
658 while (reason == SCPE_OK) {                             /* loop until error */
659 
660     if (cpu_astop) {                                    /* debug stop? */
661         cpu_astop = 0;
662         reason = SCPE_STOP;
663         break;
664         }
665 
666     if (sim_interval <= 0) {                            /* intv cnt expired? */
667         if ((reason = sim_process_event ()))            /* process events */
668             break;
669         chtr_pend = chtr_eval (NULL);                   /* eval chan traps */
670         }
671 
672     for (i = 0; ch_req && (i < NUM_CHAN); i++) {        /* loop thru channels */
673         if (ch_req & REQ_CH (i)) {                      /* channel request? */
674             if ((reason = ch_proc (i)))
675                 break;
676             }
677         chtr_pend = chtr_eval (NULL);
678         if (reason)                                     /* error? */
679             break;
680         }
681 
682     if (chtr_pend) {                                    /* channel trap? */
683         addr = chtr_eval (&trp);                        /* get trap info, clr */
684         chtr_inht = 1;                                  /* inhibit traps */
685         chtr_pend = 0;                                  /* no trap pending */
686         WriteTAD (addr, PC, trp);                       /* wr trap addr,flag */
687         IR = ReadP (addr + 1);                          /* get trap instr */
688         oldPC = PC;                                     /* save current PC */
689         }
690 
691     else {
692         if (sim_brk_summ && sim_brk_test (PC, SWMASK ('E'))) {  /* breakpoint? */
693             reason = STOP_IBKPT;                        /* stop simulation */
694             break;
695             }
696         if (chtr_inhi) {                                /* 1 cycle inhibit? */
697             chtr_inhi = 0;                              /* clear */
698             chtr_pend = chtr_eval (NULL);               /* re-evaluate */
699             }
700         else if (cpu_model & I_CT) {                    /* CTSS? */
701             mode_user = user_buf;                       /* load modes from buffers */
702             mode_reloc = reloc_buf;
703             }
704         oldPC = PC;                                     /* save current PC */
705         PC = (PC + 1) & EAMASK;                         /* increment PC */
706         if (!ReadI (oldPC, &IR))                        /* get inst; trap? */
707             continue;
708         }
709 
710     sim_interval = sim_interval - 1;
711     xec_cnt = 0;                                        /* clear XEC cntr */
712 
713     XEC:
714 
715     tag = GET_TAG (IR);                                 /* get tag */
716     addr = (uint32) IR & EAMASK;                        /* get base addr */
717 
718 /* Decrement format instructions */
719 
720     if (IR & INST_T_DEC) {                              /* decrement type? */
721         op = GET_OPD (IR);                              /* get opcode */
722         dec = GET_DEC (IR);                             /* get decrement */
723         xr = get_xrx (tag);                             /* get xr, upd MTM */
724         if (tracing) {                                  /* trace or history? */
725             if (hst_lnt)                                /* history enabled? */
726                 cpu_ent_hist (oldPC|HIST_PC, xr, IR, 0);
727             if (DEBUG_PRS (cpu_dev))
728                 cpu_fprint_one_inst (sim_deb, oldPC|HIST_PC, 0, xr,
729                     IR, AC, MQ, SI, 0);
730             }
731         switch (op) {
732 
733         case 01:                                        /* TXI */
734             put_xr (tag, xr + dec);                     /* xr += decr */
735             PCQ_ENTRY;
736             if (mode_ttrap) {                           /* trap? */
737                 WriteTA (TRAP_STD_SAV, oldPC);          /* save PC */
738                 TrapXfr (TRAP_TRA_PC);                  /* trap */
739                 }
740             else PC = addr;                             /* branch */
741             break;
742 
743         case 02:                                        /* TIX */
744             if (mode_ttrap)
745                 WriteTA (TRAP_STD_SAV, oldPC);
746             if (xr > dec) {                             /* if xr > decr */
747                 put_xr (tag, xr - dec);                 /* xr -= decr */
748                 PCQ_ENTRY;
749                 if (mode_ttrap)                         /* trap? */
750                     TrapXfr (TRAP_TRA_PC);
751                 else PC = addr;                         /* branch */
752                 }
753             break;
754 
755         case 03:                                        /* TXH */
756             if (mode_ttrap)
757                 WriteTA (TRAP_STD_SAV, oldPC);
758             if (xr > dec) {                             /* if xr > decr */
759                 PCQ_ENTRY;
760                 if (mode_ttrap)                         /* trap? */
761                     TrapXfr (TRAP_TRA_PC);
762                 else PC = addr;                         /* branch */
763                 }
764             break;
765 
766         case 05:                                        /* STR */
767             WriteTA (TRAP_STD_SAV, PC);                 /* save inst+1 */
768             PCQ_ENTRY;
769             PC = TRAP_STR_PC;                           /* branch to 2 */
770             break;
771 
772         case 06:                                        /* TNX */
773             if (mode_ttrap)
774                 WriteTA (TRAP_STD_SAV, oldPC);
775             if (xr > dec)                               /* if xr > decr */
776                 put_xr (tag, xr - dec);
777             else {                                      /* xr -= decr */
778                 PCQ_ENTRY;
779                 if (mode_ttrap)                         /* trap? */
780                     TrapXfr (TRAP_TRA_PC);
781                 else PC = addr;                         /* branch */
782                 }
783             break;
784 
785         case 07:                                        /* TXL */
786             if (mode_ttrap)
787                 WriteTA (TRAP_STD_SAV, oldPC);
788             if (xr <= dec) {                            /* if xr <= decr */
789                 PCQ_ENTRY;
790                 if (mode_ttrap)                         /* trap? */
791                     TrapXfr (TRAP_TRA_PC);
792                 else PC = addr;                         /* branch */
793                 }
794             break;
795             }
796         }                                               /* end if */
797 
798 /* Normal format instructions */
799 
800     else {
801         op = GET_OPC (IR);                              /* get opcode */
802         fl = op_flags[op];                              /* get flags */
803         if (fl & I_MODEL & ~cpu_model) {                /* invalid for model? */
804             if (stop_illop)                             /* possible stop */
805                 reason = STOP_ILLEG;
806             continue;
807             }
808         if (tag && (fl & I_X))                          /* tag and indexable? */
809             ea = (addr - get_xri (tag)) & EAMASK;       /* do indexing */
810         else ea = addr;
811         if (TST_IND (IR) && (fl & I_N)) {               /* indirect? */
812             if (!ReadI (ea, &SR))                       /* get ind; trap? */
813                 continue;
814             addr = (uint32) SR & EAMASK;                /* get address */
815             tagi = GET_TAG (SR);                        /* get tag */
816             if (tagi)                                   /* tag? */
817                 ea = (addr - get_xri (tagi)) & EAMASK;  /* do indexing */
818             else ea = addr;
819             }
820         if ((fl & I_R) && !Read (ea, &SR))              /* read opnd; trap? */
821             continue;
822         else if (fl & I_D) {                            /* double prec? */
823             if ((ea & 1) && fp_trap (TRAP_F_ODD))
824                 continue;
825             if (!Read (ea, &SR))                        /* SR gets high */
826                 continue;
827             if (!Read (ea | 1, &sr1))                   /* "sr1" gets low */
828                 continue;
829             }
830         if (tracing) {                                  /* tracing or history? */
831             if (hst_lnt)                                /* history enabled? */
832                 cpu_ent_hist (oldPC|HIST_PC, ea, IR, SR);
833             if (DEBUG_PRS (cpu_dev))
834                 cpu_fprint_one_inst (sim_deb, oldPC|HIST_PC, 0, ea,
835                     IR, AC, MQ, SI, SR);
836             }
837         switch (op) {                                   /* case on opcode */
838 
839 /* Positive instructions */
840 
841         case 00000:                                     /* HTR */
842         case 01000:                                     /* also -HTR */
843             if (prot_trap (0))                          /* user mode? */
844                 break;
845             ht_pend = 1;                                /* transfer pending */
846             ht_addr = ea;                               /* save address */
847             reason = STOP_HALT;                         /* halt if I/O done */
848             break;
849 
850         case 00020:                                     /* TRA */
851         case 01020:                                     /* also -TRA */
852             PCQ_ENTRY;
853             if (mode_ttrap) {                           /* trap? */
854                 WriteTA (TRAP_STD_SAV, oldPC);          /* save PC */
855                 TrapXfr (TRAP_TRA_PC);                  /* trap */
856                 }
857             else PC = ea;                               /* branch */
858             break;
859 
860         case 00021:                                     /* TTR */
861             PCQ_ENTRY;
862             PC = ea;                                    /* branch, no trap */
863             break;
864 
865         case 00040:                                     /* TLQ */
866             if (mode_ttrap)
867                 WriteTA (TRAP_STD_SAV, oldPC);
868             s1 = (AC & AC_S)? 1: 0;                     /* get AC, MQ sign, */
869             s2 = (MQ & SIGN)? 1: 0;                     /* magnitude */
870             t1 = AC & AC_MMASK;
871             t2 = MQ & MMASK;                            /* signs differ? */
872             if ((s1 != s2)? s2:                         /* y, br if MQ- */
873                 ((t1 != t2) && (s2 ^ (t1 > t2)))) {     /* n, br if sgn-^AC>MQ */
874                 PCQ_ENTRY;
875                 if (mode_ttrap)                         /* trap? */
876                     TrapXfr (TRAP_TRA_PC);
877                 else PC = ea;                           /* branch */
878                 }
879             break;
880 
881         case 00041:                                     /* IIA */
882             SI = SI ^ (AC & DMASK);
883             break;
884 
885         case 00042:                                     /* TIO */
886             if (mode_ttrap)
887                 WriteTA (TRAP_STD_SAV, oldPC);
888             if ((SI & AC) == (AC & DMASK)) {            /* if ind on */
889                 PCQ_ENTRY;
890                 if (mode_ttrap)                         /* trap? */
891                     TrapXfr (TRAP_TRA_PC);
892                 else PC = ea;                           /* branch */
893                 }
894             break;
895 
896         case 00043:                                     /* OAI */
897             SI = SI | (AC & DMASK);
898             break;
899 
900         case 00044:                                     /* PAI */
901             SI = AC & DMASK;
902             break;
903 
904         case 00046:                                     /* TIF */
905             if (mode_ttrap)
906                 WriteTA (TRAP_STD_SAV, oldPC);
907             if ((SI & AC) == 0) {                       /* if ind off */
908                 PCQ_ENTRY;
909                 if (mode_ttrap)                         /* trap? */
910                     TrapXfr (TRAP_TRA_PC);
911                 else PC = ea;                           /* branch */
912                 }
913             break;
914 
915         case 00051:                                     /* IIR */
916             SI = SI ^ (IR & RMASK);
917             break;
918 
919         case 00054:                                     /* RFT */
920             t = IR & RMASK;
921             if ((SI & t) == 0)                          /* if ind off, skip */
922                 PC = (PC + 1) & EAMASK;
923             break;
924 
925         case 00055:                                     /* SIR */
926             SI = SI | (IR & RMASK);
927             break;
928 
929         case 00056:                                     /* RNT */
930             t = IR & RMASK;
931             if ((SI & t) == t)                          /* if ind on, skip */
932                 PC = (PC + 1) & EAMASK;
933             break;
934 
935         case 00057:                                     /* RIR */
936             SI = SI & ~(IR & RMASK);
937             break;
938 
939         case 00074:                                     /* TSX */
940             if (mode_ttrap)
941                 WriteTA (TRAP_STD_SAV, oldPC);
942             if (tag)                                    /* save -inst loc */
943                 put_xr (tag, ~oldPC + 1);
944             PCQ_ENTRY;
945             if (mode_ttrap)                             /* trap? */
946                 TrapXfr (TRAP_TRA_PC);
947             else PC = ea;                               /* branch */
948             break;
949 
950         case 00100:                                     /* TZE */
951             if (mode_ttrap)
952                 WriteTA (TRAP_STD_SAV, oldPC);
953             if ((AC & AC_MMASK) == 0) {                 /* if AC Q,P,1-35 = 0 */
954                 PCQ_ENTRY;
955                 if (mode_ttrap)                         /* trap? */
956                     TrapXfr (TRAP_TRA_PC);
957                 else PC = ea;                           /* branch */
958                 }
959             break;
960 
961         case 00101:                                     /* (CTSS) TIA */
962             if (prot_trap (0))                          /* not user mode? */
963                 break;
964             if (mode_ttrap) {                           /* trap? */
965                 WriteTA (TRAP_STD_SAV, oldPC);          /* save PC */
966                 TrapXfr (TRAP_TRA_PC);                  /* trap */
967                 }
968             else {
969                 PCQ_ENTRY;
970                 PC = ea;
971                 inst_base = 0;
972                 }
973             break;
974 
975         case 00114: case 00115: case 00116: case 00117: /* CVR */
976             sc = GET_CCNT (IR);
977             SR = ea;
978             while (sc) {
979                 ea = (uint32) ((AC & 077) + SR) & EAMASK;
980                 if (!Read (ea, &SR))
981                     break;
982                 AC = (AC & AC_S) | ((AC >> 6) & 0017777777777) |
983                     (SR & 0770000000000);
984                 sc--;
985                 }
986             if ((sc == 0) && (IR & INST_T_CXR1))
987                 put_xr (1, (uint32) SR);
988             break;
989 
990         case 00120:                                     /* TPL */
991             if (mode_ttrap)
992                 WriteTA (TRAP_STD_SAV, oldPC);
993             if ((AC & AC_S) == 0) {                     /* if AC + */
994                 PCQ_ENTRY;
995                 if (mode_ttrap)                         /* trap? */
996                     TrapXfr (TRAP_TRA_PC);
997                 else PC = ea;                           /* branch */
998                 }
999             break;
1000 
1001         case 00131:                                     /* XCA */
1002             t = MQ;
1003             MQ = (AC & MMASK) | ((AC & AC_S)? SIGN: 0);
1004             AC = (t & MMASK) | ((t & SIGN)? AC_S: 0);
1005             break;
1006 
1007         case 00140:                                     /* TOV */
1008             if (mode_ttrap)
1009                 WriteTA (TRAP_STD_SAV, oldPC);
1010             if (ind_ovf)  {                             /* if overflow */
1011                 PCQ_ENTRY;
1012                 if (mode_ttrap)                         /* trap? */
1013                     TrapXfr (TRAP_TRA_PC);
1014                 else PC = ea;                           /* branch */
1015                 ind_ovf = 0;                            /* clear overflow */
1016                 }
1017             break;
1018 
1019         case 00161:                                     /* TQO */
1020             if (!mode_ftrap) {                          /* only in 704 mode */
1021                 if (mode_ttrap)
1022                     WriteTA (TRAP_STD_SAV, oldPC);
1023                 if (ind_mqo)  {                         /* if MQ overflow */
1024                     PCQ_ENTRY;
1025                     if (mode_ttrap)                     /* trap? */
1026                         TrapXfr (TRAP_TRA_PC);
1027                     else PC = ea;                       /* branch */
1028                     ind_mqo = 0;                        /* clear overflow */
1029                     }
1030                 }
1031             break;
1032 
1033         case 00162:                                     /* TQP */
1034             if (mode_ttrap)
1035                 WriteTA (TRAP_STD_SAV, oldPC);
1036             if ((MQ & SIGN) == 0)  {                    /* if MQ + */
1037                 PCQ_ENTRY;
1038                 if (mode_ttrap)                         /* trap? */
1039                     TrapXfr (TRAP_TRA_PC);
1040                 else PC = ea;                           /* branch */
1041                 }
1042             break;
1043 
1044         case 00200:                                     /* MPY */
1045             op_mpy (0, SR, 043);
1046             break;
1047 
1048         case 00204:                                     /* VLM */
1049         case 00205:                                     /* for diagnostic */
1050             sc = GET_VCNT (IR);
1051             op_mpy (0, SR, sc);
1052             break;
1053 
1054         case 00220:                                     /* DVH */
1055             if (op_div (SR, 043)) {
1056                 ind_dvc = 1;
1057                 if (!prot_trap (0))
1058                     reason = STOP_DIVCHK;
1059                 }
1060             break;
1061 
1062         case 00221:                                     /* DVP */
1063             if (op_div (SR, 043))
1064                 ind_dvc = 1;
1065             break;
1066 
1067         case 00224:                                     /* VDH */
1068         case 00226:                                     /* for diagnostic */
1069             sc = GET_VCNT (IR);
1070             if (op_div (SR, sc)) {
1071                 ind_dvc = 1;
1072                 if (!prot_trap (0))
1073                     reason = STOP_DIVCHK;
1074                 }
1075             break;
1076 
1077         case 00225:                                     /* VDP */
1078         case 00227:                                     /* for diagnostic */
1079             sc = GET_VCNT (IR);
1080             if (op_div (SR, sc))
1081                 ind_dvc = 1;
1082             break;
1083 
1084         case 00240:                                     /* FDH */
1085             spill = op_fdv (SR);
1086             if (spill == TRAP_F_DVC) {
1087                 ind_dvc = 1;
1088                 if (!prot_trap (0))
1089                     reason = STOP_DIVCHK;
1090                 }
1091             else if (spill)
1092                 fp_trap (spill);
1093             break;
1094 
1095         case 00241:                                     /* FDP */
1096             spill = op_fdv (SR);
1097             if (spill == TRAP_F_DVC)
1098                 ind_dvc = 1;
1099             else if (spill)
1100                 fp_trap (spill);
1101             break;
1102 
1103         case 00260:                                     /* FMP */
1104             spill = op_fmp (SR, 1);                     /* MQ * SR */
1105             if (spill)
1106                 fp_trap (spill);
1107             break;
1108 
1109         case 00261:                                     /* DFMP */
1110             spill = op_dfmp (SR, sr1, 1);
1111             if (spill)
1112                 fp_trap (spill);
1113             break;
1114 
1115         case 00300:                                     /* FAD */
1116             spill = op_fad (SR, 1);
1117             if (spill)
1118                 fp_trap (spill);
1119             break;
1120 
1121         case 00301:                                     /* DFAD */
1122             spill = op_dfad (SR, sr1, 1);
1123             if (spill)
1124                 fp_trap (spill);
1125             break;
1126 
1127         case 00302:                                     /* FSB */
1128             spill = op_fad (SR ^ SIGN, 1);
1129             if (spill)
1130                 fp_trap (spill);
1131             break;
1132 
1133         case 00303:                                     /* DFSB */
1134             spill = op_dfad (SR ^ SIGN, sr1, 1);
1135             if (spill)
1136                 fp_trap (spill);
1137             break;
1138 
1139         case 00304:                                     /* FAM */
1140             spill = op_fad (SR & ~SIGN, 1);
1141             if (spill)
1142                 fp_trap (spill);
1143             break;
1144 
1145         case 00305:                                     /* DFAM */
1146             spill = op_dfad (SR & ~SIGN, sr1, 1);
1147             if (spill)
1148                 fp_trap (spill);
1149             break;
1150 
1151         case 00306:                                     /* FSM */
1152             spill = op_fad (SR | SIGN, 1);
1153             if (spill)
1154                 fp_trap (spill);
1155             break;
1156 
1157         case 00307:                                     /* DFSM */
1158             spill = op_dfad (SR | SIGN, sr1, 1);
1159             if (spill)
1160                 fp_trap (spill);
1161             break;
1162 
1163         case 00320:                                     /* ANS */
1164             SR = AC & SR;
1165             Write (ea, SR);
1166             break;
1167 
1168         case 00322:                                     /* ERA */
1169             AC = (AC ^ SR) & DMASK;                     /* AC S,Q cleared */
1170             break;
1171 
1172         case 00340:                                     /* CAS */
1173             s1 = (AC & AC_S)? 1: 0;                     /* get AC, MQ signs, */
1174             s2 = (SR & SIGN)? 1: 0;
1175             t1 = AC & AC_MMASK;                         /* magnitudes */
1176             t2 = SR & MMASK;
1177             if (s1 ^ s2) {                              /* diff signs? */
1178                 if (s1)                                 /* AC < mem? skip 2 */
1179                     PC = (PC + 2) & EAMASK;
1180                 }
1181             else if (t1 == t2)                          /* equal? skip 1 */
1182                 PC = (PC + 1) & EAMASK;
1183             else if ((t1 < t2) ^ s1)                    /* AC < mem, AC +, or */
1184                 PC = (PC + 2) & EAMASK;                 /* AC > mem, AC -? */
1185             break;
1186 
1187         case 00361:                                     /* ACL */
1188             t = (AC + SR) & DMASK;                      /* AC P,1-35 + SR */
1189             if (t < SR)                                 /* end around carry */
1190                 t = (t + 1) & DMASK;
1191             AC = (AC & (AC_S | AC_Q)) | t;              /* preserve AC S,Q */
1192             break;
1193 
1194         case 00400:                                     /* ADD */
1195             op_add (SR);
1196             break;
1197 
1198         case 00401:                                     /* ADM */
1199             op_add (SR & MMASK);
1200             break;
1201 
1202         case 00402:                                     /* SUB */
1203             op_add (SR ^ SIGN);
1204             break;
1205 
1206         case 00420:                                     /* HPR */
1207             if (prot_trap (0))                          /* user mode? */
1208                 break;
1209             reason = STOP_HALT;                         /* halt if I/O done */
1210             break;
1211 
1212         case 00440:                                     /* IIS */
1213             SI = SI ^ SR;
1214             break;
1215 
1216         case 00441:                                     /* LDI */
1217             SI = SR;
1218             break;
1219 
1220         case 00442:                                     /* OSI */
1221             SI = SI | SR;
1222             break;
1223 
1224         case 00443:                                     /* DLD */
1225             AC = (SR & MMASK) | ((SR & SIGN)? AC_S: 0); /* normal load */
1226             if (!Read (ea | 1, &SR))                    /* second load */
1227                 break;
1228             MQ = SR;
1229             if (ea & 1)                                 /* trap after exec */
1230                 fp_trap (TRAP_F_ODD);
1231             break;
1232 
1233         case 00444:                                     /* OFT */
1234             if ((SI & SR) == 0)                         /* skip if ind off */
1235                 PC = (PC + 1) & EAMASK;
1236             break;
1237 
1238         case 00445:                                     /* RIS */
1239             SI = SI & ~SR;
1240             break;
1241 
1242         case 00446:                                     /* ONT */
1243             if ((SI & SR) == SR)                        /* skip if ind on */
1244                 PC = (PC + 1) & EAMASK;
1245             break;
1246 
1247         case 00460:                                     /* LDA (704) */
1248             cpy_trap (PC);
1249             break;
1250 
1251         case 00500:                                     /* CLA */
1252             AC = (SR & MMASK) | ((SR & SIGN)? AC_S: 0);
1253             break;
1254 
1255         case 00502:                                     /* CLS */
1256             AC = (SR & MMASK) | ((SR & SIGN)? 0: AC_S);
1257             break;
1258 
1259         case 00520:                                     /* ZET */
1260             if ((SR & MMASK) == 0)                      /* skip if M 1-35 = 0 */
1261                 PC = (PC + 1) & EAMASK;
1262             break;
1263 
1264         case 00522:                                     /* XEC */
1265             if (xec_cnt++ >= xec_max) {                 /* xec chain limit? */
1266                 reason = STOP_XEC;                      /* stop */
1267                 break;
1268                 }
1269             IR = SR;                                    /* operand is new inst */
1270             chtr_inhi = 1;                              /* delay traps */
1271             chtr_pend = 0;                              /* no trap now */
1272             goto XEC;                                   /* start over */
1273 
1274         case 00534:                                     /* LXA */
1275             if (tag)                                    /* M addr -> xr */
1276                 put_xr (tag, (uint32) SR);
1277             break;
1278 
1279         case 00535:                                     /* LAC */
1280             if (tag)                                    /* -M addr -> xr */
1281                 put_xr (tag, NEG ((uint32) SR));
1282             break;
1283 
1284         case 00560:                                     /* LDQ */
1285             MQ = SR;
1286             break;
1287 
1288         case 00562:                                     /* (CTSS) LRI */
1289             if (prot_trap (0))                          /* user mode? */
1290                 break;
1291             ind_reloc = ((uint32) SR) & VA_BLK;
1292             reloc_buf = 1;                              /* set mode buffer */
1293             chtr_inhi = 1;                              /* delay traps */
1294             chtr_pend = 0;                              /* no trap now */
1295             break;
1296 
1297         case 00564:                                     /* ENB */
1298             if (prot_trap (0))                          /* user mode? */
1299                 break;
1300             chtr_enab = (uint32) SR;                    /* set enables */
1301             chtr_inht = 0;                              /* clear inhibit */
1302             chtr_inhi = 1;                              /* 1 cycle delay */
1303             chtr_pend = 0;                              /* no traps now */
1304             break;
1305 
1306         case 00600:                                     /* STZ */
1307             Write (ea, 0);
1308             break;
1309 
1310         case 00601:                                     /* STO */
1311             SR = (AC & MMASK) | ((AC & AC_S)? SIGN: 0);
1312             Write (ea, SR);
1313             break;
1314 
1315         case 00602:                                     /* SLW */
1316             Write (ea, AC & DMASK);
1317             break;
1318 
1319         case 00604:                                     /* STI */
1320             Write (ea, SI);
1321             break;
1322 
1323         case 00621:                                     /* STA */
1324             SR = (SR & ~AMASK) | (AC & AMASK);
1325             Write (ea, SR);
1326             break;
1327 
1328         case 00622:                                     /* STD */
1329             SR = (SR & ~XMASK) | (AC & XMASK);
1330             Write (ea, SR);
1331             break;
1332 
1333         case 00625:                                     /* STT */
1334             SR = (SR & ~TMASK) | (AC & TMASK);
1335             Write (ea, SR);
1336             break;
1337 
1338         case 00630:                                     /* STP */
1339             SR = (SR & ~PMASK) | (AC & PMASK);
1340             Write (ea, SR);
1341             break;
1342 
1343         case 00634:                                     /* SXA */
1344             SR = (SR & ~AMASK) |                        /* xr -> M addr */
1345                 ((t_uint64) get_xrx (tag));
1346             Write (ea, SR);
1347             break;
1348 
1349         case 00636:                                     /* SCA */
1350             SR = (SR & ~AMASK) |                        /* -xr -> M addr */
1351                 ((t_uint64) (NEG (get_xrx (tag)) & AMASK));
1352             Write (ea, SR);
1353             break;
1354 
1355         case 00700:                                     /* CPY (704) */
1356             cpy_trap (PC);
1357             break;
1358 
1359         case 00734:                                     /* PAX */
1360             if (tag)                                    /* AC addr -> xr */
1361                 put_xr (tag, (uint32) AC);
1362             break;
1363 
1364         case 00737:                                     /* PAC */
1365             if (tag)                                    /* -AC addr -> xr */
1366                 put_xr (tag, NEG ((uint32) AC));
1367             break;
1368 
1369         case 00754:                                     /* PXA */
1370             AC = get_xrx (tag);                         /* xr -> AC */
1371             break;
1372 
1373         case 00756:                                     /* PCA */
1374             AC = NEG (get_xrx (tag)) & AMASK;           /* -xr -> AC */
1375             break;
1376 
1377         case 00760:                                     /* PSE */
1378             reason = op_pse (ea);
1379             break;
1380 
1381         case 00761:                                     /* NOP */
1382             break;
1383 
1384         case 00763:                                     /* LLS */
1385             op_lls (ea);
1386             break;
1387 
1388         case 00765:                                     /* LRS */
1389             op_lrs (ea);
1390             break;
1391 
1392         case 00767:                                     /* ALS */
1393             op_als (ea);
1394             break;
1395 
1396         case 00771:                                     /* ARS */
1397             op_ars (ea);
1398             break;
1399 
1400         case 00774:                                     /* AXT */
1401             if (tag)                                    /* IR addr -> xr */
1402                 put_xr (tag, addr);
1403             break;
1404 
1405 /* Negative instructions */
1406 
1407         case 01021:                                     /* ESNT */
1408             if (prot_trap (0))                          /* user mode? */
1409                 break;
1410             mode_storn = 1;                             /* enter nullification */
1411             PCQ_ENTRY;
1412             PC = ea;                                    /* branch, no trap */
1413             break;
1414 
1415         case 01042:                                     /* RIA */
1416             SI = SI & ~AC;
1417             break;
1418 
1419         case 01046:                                     /* PIA */
1420             AC = SI;
1421             break;
1422 
1423         case 01051:                                     /* IIL */
1424             SI = SI ^ ((IR & RMASK) << 18);
1425             break;
1426 
1427         case 01054:                                     /* LFT */
1428             t = (IR & RMASK) << 18;
1429             if ((SI & t) == 0)                          /* if ind off, skip */
1430                 PC = (PC + 1) & EAMASK;
1431             break;
1432 
1433         case 01055:                                     /* SIL */
1434             SI = SI | ((IR & RMASK) << 18);
1435             break;
1436 
1437         case 01056:                                     /* LNT */
1438             t = (IR & RMASK) << 18;
1439             if ((SI & t) == t)                          /* if ind on, skip */
1440                 PC = (PC + 1) & EAMASK;
1441             break;
1442 
1443         case 01057:                                     /* RIL */
1444             SI = SI & ~((IR & RMASK) << 18);
1445             break;
1446 
1447         case 01100:                                     /* TNZ */
1448             if (mode_ttrap)
1449                 WriteTA (TRAP_STD_SAV, oldPC);
1450             if ((AC & AC_MMASK) != 0) {                 /* if AC != 0 */
1451                 PCQ_ENTRY;
1452                 if (mode_ttrap)                         /* trap? */
1453                     TrapXfr (TRAP_TRA_PC);
1454                 else PC = ea;                           /* branch */
1455                 }
1456             break;
1457 
1458         case 01101:                                     /* (CTSS) TIB */
1459             if (prot_trap (0))                          /* user mode? */
1460                 break;
1461             if (mode_ttrap) {                           /* trap? */
1462                 WriteTA (TRAP_STD_SAV, oldPC);          /* save PC */
1463                 TrapXfr (TRAP_TRA_PC);                  /* trap */
1464                 }
1465             else {
1466                 PCQ_ENTRY;
1467                 PC = ea;
1468                 inst_base = BCORE_BASE;
1469                 }
1470             break;
1471 
1472         case 01114: case 01115: case 01116: case 01117: /* CAQ */
1473             sc = GET_CCNT (IR);
1474             SR = ea;
1475             while (sc) {
1476                 ea = (uint32) ((MQ >> 30) + SR) & EAMASK;
1477                 if (!Read (ea, &SR))
1478                     break;
1479                 MQ = ((MQ << 6) & DMASK) | (MQ >> 30);
1480                 AC = (AC & AC_S) | ((AC + SR) & AC_MMASK);
1481                 sc--;
1482                 }
1483             if ((sc == 0) && (IR & INST_T_CXR1))
1484                 put_xr (1, (uint32) SR);
1485             break;
1486 
1487         case 01120:                                     /* TMI */
1488             if (mode_ttrap)
1489                 WriteTA (TRAP_STD_SAV, oldPC);
1490             if ((AC & AC_S) != 0)  {                    /* if AC - */
1491                 PCQ_ENTRY;
1492                 if (mode_ttrap)                         /* trap? */
1493                     TrapXfr (TRAP_TRA_PC);
1494                 else PC = ea;                           /* branch */
1495                 }
1496             break;
1497 
1498         case 01130:                                     /* XCL */
1499             t = MQ;
1500             MQ = AC & DMASK;
1501             AC = t;
1502             break;
1503 
1504         case 01140:                                     /* TNO */
1505             if (mode_ttrap)
1506                 WriteTA (TRAP_STD_SAV, oldPC);
1507             if (!ind_ovf)  {                            /* if no overflow */
1508                 PCQ_ENTRY;
1509                 if (mode_ttrap)                         /* trap? */
1510                     TrapXfr (TRAP_TRA_PC);
1511                 else PC = ea;                           /* branch */
1512                 }
1513             ind_ovf = 0;                                /* clear overflow */
1514             break;
1515 
1516         case 01154: case 01155: case 01156: case 01157: /* CRQ */
1517             sc = GET_CCNT (IR);
1518             SR = ea;
1519             while (sc) {
1520                 ea = (uint32) ((MQ >> 30) + SR) & EAMASK;
1521                 if (!Read (ea, &SR))
1522                     break;
1523                 MQ = ((MQ << 6) & DMASK) | (SR >> 30);
1524                 sc--;
1525                 }
1526             if ((sc == 0) && (IR & INST_T_CXR1))
1527                 put_xr (1, (uint32) SR);
1528             break;
1529 
1530         case 01200:                                     /* MPR */
1531             op_mpy (0, SR, 043);
1532             if (MQ & B1)
1533                 AC = (AC & AC_S) | ((AC + 1) & AC_MMASK);
1534             break;
1535 
1536         case 01240:                                     /* DFDH */
1537             spill = op_dfdv (SR, sr1);
1538             if (spill == TRAP_F_DVC) {
1539                 ind_dvc = 1;
1540                 if (!prot_trap (0))
1541                     reason = STOP_DIVCHK;
1542                 }
1543             else if (spill)
1544                 fp_trap (spill);
1545             break;
1546 
1547         case 01241:                                     /* DFDP */
1548             spill = op_dfdv (SR, sr1);
1549             if (spill == TRAP_F_DVC)
1550                 ind_dvc = 1;
1551             else if (spill)
1552                 fp_trap (spill);
1553             break;
1554 
1555         case 01260:                                     /* UFM */
1556             spill = op_fmp (SR, 0);
1557             if (spill)
1558                 fp_trap (spill);
1559             break;
1560 
1561         case 01261:                                     /* DUFM */
1562             spill = op_dfmp (SR, sr1, 0);
1563             if (spill)
1564                 fp_trap (spill);
1565             break;
1566 
1567         case 01300:                                     /* UFA */
1568             spill = op_fad (SR, 0);
1569             if (spill)
1570                 fp_trap (spill);
1571             break;
1572 
1573         case 01301:                                     /* DUFA */
1574             spill = op_dfad (SR, sr1, 0);
1575             if (spill)
1576                 fp_trap (spill);
1577             break;
1578 
1579         case 01302:                                     /* UFS */
1580             spill = op_fad (SR ^ SIGN, 0);
1581             if (spill)
1582                 fp_trap (spill);
1583             break;
1584 
1585         case 01303:                                     /* DUFS */
1586             spill = op_dfad (SR ^ SIGN, sr1, 0);
1587             if (spill)
1588                 fp_trap (spill);
1589             break;
1590 
1591         case 01304:                                     /* UAM */
1592             spill = op_fad (SR & ~SIGN, 0);
1593             if (spill)
1594                 fp_trap (spill);
1595             break;
1596 
1597         case 01305:                                     /* DUAM */
1598             spill = op_dfad (SR & ~SIGN, sr1, 0);
1599             if (spill)
1600                 fp_trap (spill);
1601             break;
1602 
1603         case 01306:                                     /* USM */
1604             spill = op_fad (SR | SIGN, 0);
1605             if (spill)
1606                 fp_trap (spill);
1607             break;
1608 
1609         case 01307:                                     /* DUSM */
1610             spill = op_dfad (SR | SIGN, sr1, 0);
1611             if (spill)
1612                 fp_trap (spill);
1613             break;
1614 
1615         case 01320:                                     /* ANA */
1616             AC = AC & SR;
1617             break;
1618 
1619         case 01340:                                     /* LAS */
1620             t = AC & AC_MMASK;                          /* AC Q,P,1-35 */
1621             if (t < SR)
1622                 PC = (PC + 2) & EAMASK;
1623             else if (t == SR)
1624                 PC = (PC + 1) & EAMASK;
1625             break;
1626 
1627         case 01400:                                     /* SBM */
1628             op_add (SR | SIGN);
1629             break;
1630 
1631         case 01500:                                     /* CAL */
1632             AC = SR;
1633             break;
1634 
1635         case 01501:                                     /* ORA */
1636             AC = AC | SR;
1637             break;
1638 
1639         case 01520:                                     /* NZT */
1640             if ((SR & MMASK) != 0)
1641                 PC = (PC + 1) & EAMASK;
1642             break;
1643 
1644         case 01534:                                     /* LXD */
1645             if (tag)                                    /* M decr -> xr */
1646                 put_xr (tag, GET_DEC (SR));
1647             break;
1648 
1649         case 01535:                                     /* LDC */
1650             if (tag)                                    /* -M decr -> xr */
1651                 put_xr (tag, NEG (GET_DEC (SR)));
1652             break;
1653 
1654         case 01564:                                     /* (CTSS) LPI */
1655             if (prot_trap (0))                          /* user mode? */
1656                 break;
1657             ind_start = ((uint32) SR) & VA_BLK;
1658             ind_limit = (GET_DEC (SR) & VA_BLK) | VA_OFF;
1659             user_buf = 1;                               /* set mode buffer */
1660             chtr_inhi = 1;                              /* delay traps */
1661             chtr_pend = 0;                              /* no trap now */
1662             break;
1663 
1664         case 01600:                                     /* STQ */
1665             Write (ea, MQ);
1666             break;
1667 
1668         case 01601:                                     /* SRI (CTSS) */
1669             SR = ind_reloc & VA_BLK;
1670             /* add reloc mode in bit 1 */
1671             Write (ea, SR);
1672             break;
1673 
1674         case 01602:                                     /* ORS */
1675             SR = SR | (AC & DMASK);
1676             Write (ea, SR);
1677             break;
1678 
1679         case 01603:                                     /* DST */
1680             SR = (AC & MMASK) | ((AC & AC_S)? SIGN: 0);
1681             if (!Write (ea, SR))
1682                 break;
1683             Write ((ea + 1) & EAMASK, MQ);
1684             break;
1685 
1686         case 01604:                                     /* SPI (CTSS) */
1687             SR = (((t_uint64) (ind_limit & VA_BLK)) << INST_V_DEC) |
1688                 ((t_uint64) (ind_start & VA_BLK));
1689             /* add prot mode in bit 2 */
1690             Write (ea, SR);
1691             break;
1692 
1693         case 01620:                                     /* SLQ */
1694             SR = (SR & RMASK) | (MQ & LMASK);
1695             Write (ea, SR);
1696             break;
1697 
1698         case 01625:                                     /* STL */
1699             SR = (SR & ~AMASK) | PC;
1700             Write (ea, SR);
1701             break;
1702 
1703         case 01634:                                     /* SXD */
1704             SR = (SR & ~XMASK) |                        /* xr -> M decr */
1705                 (((t_uint64) get_xrx (tag)) << INST_V_DEC);
1706             Write (ea, SR);
1707             break;
1708 
1709         case 01636:                                     /* SCD */
1710             SR = (SR & ~XMASK) |                        /* -xr -> M decr */
1711                 (((t_uint64) (NEG (get_xrx (tag)) & AMASK)) << INST_V_DEC);
1712             Write (ea, SR);
1713             break;
1714 
1715         case 01700:                                     /* CAD (704) */
1716             cpy_trap (PC);
1717             break;
1718 
1719         case 01734:                                     /* PDX */
1720             if (tag)                                    /* AC decr -> xr */
1721                 put_xr (tag, GET_DEC (AC));
1722             break;
1723 
1724         case 01737:                                     /* PDC */
1725             if (tag)                                    /* -AC decr -> xr */
1726                 put_xr (tag, NEG (GET_DEC (AC)));
1727             break;
1728 
1729         case 01754:                                     /* PXD */
1730             AC = ((t_uint64) get_xrx (tag)) << INST_V_DEC;
1731             break;                                      /* xr -> AC decr */
1732 
1733         case 01756:                                     /* PCD */
1734             AC = ((t_uint64) (NEG (get_xrx (tag)) & AMASK)) << INST_V_DEC;
1735             break;                                      /* -xr -> AC decr */
1736 
1737         case 01760:                                     /* MSE */
1738             reason = op_mse (ea);
1739             break;
1740 
1741         case 01761:                                     /* (CTSS) ext core */
1742             if (prot_trap (0))                          /* user mode? */
1743                 break;
1744             if (ea == 041)                              /* SEA? */
1745                 data_base = 0;
1746             else if (ea == 042)                         /* SEB? */
1747                 data_base = BCORE_BASE;
1748             else if (ea == 043) {                       /* IFT? */
1749                 if (inst_base == 0)
1750                     PC = (PC + 1) & EAMASK;
1751                 }
1752             else if (ea == 044) {                       /* EFT? */
1753                 if (data_base == 0)
1754                     PC = (PC + 1) & EAMASK;
1755                 }
1756             else if (stop_illop)
1757                 reason = STOP_ILLEG;
1758             break;
1759 
1760         case 01763:                                     /* LGL */
1761             op_lgl (ea);
1762             break;
1763 
1764         case 01765:                                     /* LGR */
1765             op_lgr (ea);
1766             break;
1767 
1768         case 01773:                                     /* RQL */
1769             sc = (ea & SCMASK) % 36;
1770             if (sc)
1771                 MQ = ((MQ << sc) | (MQ >> (36 - sc))) & DMASK;
1772             break;
1773 
1774         case 01774:                                     /* AXC */
1775             if (tag)                                    /* -IR addr -> xr */
1776                 put_xr (tag, NEG (addr));
1777             break;
1778 
1779 /* IO instructions */
1780 
1781         case 00022: case 00024: case 00026:             /* TRCx */
1782         case 01022: case 01024: case 01026:
1783             if (prot_trap (0))                          /* user mode? */
1784                 break;
1785             ch = ((op & 077) - 00022) | ((op >> 9) & 01);
1786             if (mode_ttrap)
1787                 WriteTA (TRAP_STD_SAV, oldPC);
1788             if (!BIT_TST (chtr_enab, CHTR_V_TRC + ch) &&
1789                 (ch_flags[ch] & CHF_TRC)) {
1790                 PCQ_ENTRY;
1791                 if (mode_ttrap)                         /* trap? */
1792                     TrapXfr (TRAP_TRA_PC);
1793                 else PC = ea;                           /* branch */
1794                 ch_flags[ch] = ch_flags[ch] & ~CHF_TRC;
1795                 chtr_pend = chtr_eval (NULL);           /* eval chan traps */
1796                 }
1797             break;
1798 
1799         case 00027: case 01027:
1800             if (prot_trap (0))                          /* user mode? */
1801                 break;
1802             ch = 6 + ((op >> 9) & 01);
1803             if (mode_ttrap)
1804                 WriteTA (TRAP_STD_SAV, oldPC);
1805             if (!BIT_TST (chtr_enab, CHTR_V_TRC + ch) &&
1806                 (ch_flags[ch] & CHF_TRC)) {
1807                 PCQ_ENTRY;
1808                 if (mode_ttrap)                         /* trap? */
1809                     TrapXfr (TRAP_TRA_PC);
1810                 else PC = ea;                           /* branch */
1811                 ch_flags[ch] = ch_flags[ch] & ~CHF_TRC;
1812                 chtr_pend = chtr_eval (NULL);           /* eval chan traps */
1813                 }
1814             break;
1815 
1816         case 00030: case 00031: case 00032: case 00033: /* TEFx */
1817         case 01030: case 01031: case 01032: case 01033:
1818             if (prot_trap (0))                          /* user mode? */
1819                 break;
1820             ch = ((op & 03) << 1) | ((op >> 9) & 01);
1821             if (mode_ttrap)
1822                 WriteTA (TRAP_STD_SAV, oldPC);
1823             if (!BIT_TST (chtr_enab, CHTR_V_CME + ch) &&
1824                 (ch_flags[ch] & CHF_EOF)) {
1825                 PCQ_ENTRY;
1826                 if (mode_ttrap)                         /* trap? */
1827                     TrapXfr (TRAP_TRA_PC);
1828                 else PC = ea;                           /* branch */
1829                 ch_flags[ch] = ch_flags[ch] & ~CHF_EOF;
1830                 chtr_pend = chtr_eval (NULL);           /* eval chan traps */
1831                 }
1832             break;
1833 
1834         case 00060: case 00061: case 00062: case 00063: /* TCOx */
1835         case 00064: case 00065: case 00066: case 00067:
1836             if (prot_trap (0))                          /* user mode? */
1837                 break;
1838             ch = op & 07;
1839             if (mode_ttrap)
1840                 WriteTA (TRAP_STD_SAV, oldPC);
1841             if (ch_sta[ch] != CHXS_IDLE) {
1842                 PCQ_ENTRY;
1843                 if (mode_ttrap)                         /* trap? */
1844                     TrapXfr (TRAP_TRA_PC);
1845                 else PC = ea;                           /* branch */
1846                 }
1847             break;
1848 
1849         case 01060: case 01061: case 01062: case 01063: /* TCNx */
1850         case 01064: case 01065: case 01066: case 01067:
1851             if (prot_trap (0))                          /* user mode? */
1852                 break;
1853             ch = op & 07;
1854             if (mode_ttrap)
1855                 WriteTA (TRAP_STD_SAV, oldPC);
1856             if (ch_sta[ch] == CHXS_IDLE) {
1857                 PCQ_ENTRY;
1858                 if (mode_ttrap)                         /* trap? */
1859                     TrapXfr (TRAP_TRA_PC);
1860                 else PC = ea;                           /* branch */
1861                 }
1862             break;
1863 
1864         case 00540: case 00541: case 00542: case 00543: /* RCHx */
1865         case 01540: case 01541: case 01542: case 01543:
1866             if (prot_trap (0))                          /* user mode? */
1867                 break;
1868             ch = ((op & 03) << 1) | ((op >> 9) & 01);
1869             reason = ch_op_start (ch, ea, TRUE);
1870             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1871             break;
1872 
1873         case 00544: case 00545: case 00546: case 00547: /* LCHx */
1874         case 01544: case 01545: case 01546: case 01547:
1875             if (prot_trap (0))                          /* user mode? */
1876                 break;
1877             ch = ((op & 03) << 1) | ((op >> 9) & 01);
1878             reason = ch_op_start (ch, ea, FALSE);
1879             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1880             break;
1881 
1882         case 00640: case 00641: case 00642: case 00643: /* SCHx */
1883         case 01640: case 01641: case 01642: case 01643:
1884             ch = ((op & 03) << 1) | ((op >> 9) & 01);
1885             if ((reason = ch_op_store (ch, &SR)) == SCPE_OK)
1886                 Write (ea, SR);
1887             break;
1888 
1889         case 00644: case 00645: case 00646: case 00647: /* SCDx */
1890         case 01644: case 01645: case 01646: case 01647:
1891             ch = ((op & 03) << 1) | ((op >> 9) & 01);
1892             if ((reason = ch_op_store_diag (ch, &SR)) == SCPE_OK)
1893                 Write (ea, SR);
1894             break;
1895 
1896         case 00762:                                     /* RDS */
1897             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1898                 break;
1899             ch = GET_U_CH (IR);
1900             reason = ch_op_ds (ch, CHSL_RDS, GET_U_UNIT (ea));
1901             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1902             break;
1903 
1904         case 00764:                                     /* BSR */
1905             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1906                 break;
1907             ch = GET_U_CH (IR);
1908             reason = ch_op_nds (ch, CHSL_BSR, GET_U_UNIT (ea));
1909             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1910             break;
1911 
1912         case 00766:                                     /* WRS */
1913             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1914                 break;
1915             ch = GET_U_CH (IR);
1916             reason = ch_op_ds (ch, CHSL_WRS, GET_U_UNIT (ea));
1917             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1918             break;
1919 
1920         case 00770:                                     /* WEF */
1921             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1922                 break;
1923             ch = GET_U_CH (IR);
1924             reason = ch_op_nds (ch, CHSL_WEF, GET_U_UNIT (ea));
1925             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1926             break;
1927 
1928         case 00772:                                     /* REW */
1929             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1930                 break;
1931             ch = GET_U_CH (IR);
1932             reason = ch_op_nds (ch, CHSL_REW, GET_U_UNIT (ea));
1933             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1934             break;
1935 
1936         case 01764:                                     /* BSF */
1937             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1938                 break;
1939             ch = GET_U_CH (IR);
1940             reason = ch_op_nds (ch, CHSL_BSF, GET_U_UNIT (ea));
1941             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1942             break;
1943 
1944         case 01772:                                     /* RUN */
1945             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1946                 break;
1947             ch = GET_U_CH (IR);
1948             reason = ch_op_nds (ch, CHSL_RUN, GET_U_UNIT (ea));
1949             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1950             break;
1951 
1952         case 00776:                                     /* SDN */
1953             if (sel_trap (0) || prot_trap (PC))         /* select takes priority */
1954                 break;
1955             ch = GET_U_CH (IR);
1956             reason = ch_op_nds (ch, CHSL_SDN, GET_U_UNIT (ea));
1957             chtr_pend = chtr_eval (NULL);               /* eval chan traps */
1958             break;
1959 
1960         default:
1961             if (stop_illop)
1962                 reason = STOP_ILLEG;
1963             break;
1964             }
1965         }                                               /* end else */
1966 
1967     if (reason) {                                       /* reason code? */
1968         if (reason == ERR_STALL) {                      /* stall? */
1969             PC = oldPC;                                 /* back up PC */
1970             reason = 0;
1971             }
1972         else if (reason == STOP_HALT) {                 /* halt? wait for IO */
1973             t_stat r;
1974             for (i = 0; (i < HALT_IO_LIMIT) && !ch_qidle (); i++) {
1975                 sim_interval = 0;
1976                 if ((r = sim_process_event ()))         /* process events */
1977                     return r;
1978                 chtr_pend = chtr_eval (NULL);           /* eval chan traps */
1979                 while (ch_req) {                        /* until no ch req */
1980                     for (j = 0; j < NUM_CHAN; j++) {    /* loop thru channels */
1981                         if (ch_req & REQ_CH (j)) {      /* channel request? */
1982                             if ((r = ch_proc (j)))
1983                                 return r;
1984                             }
1985                         chtr_pend = chtr_eval (NULL);
1986                         }
1987                     }                                   /* end while ch_req */
1988                 }                                       /* end for wait */
1989             if (chtr_pend)                              /* trap? cancel HALT */
1990                 reason = 0;
1991             }                                           /* end if HALT */
1992         }                                               /* end if reason */
1993     }                                                   /* end while */
1994 
1995 pcq_r->qptr = pcq_p;                                    /* update pc q ptr */
1996 return reason;
1997 }
1998 
1999 /* Get index register for indexing */
2000 
get_xri(uint32 tag)2001 uint32 get_xri (uint32 tag)
2002 {
2003 tag = tag & INST_M_TAG;
2004 
2005 if (tag) {
2006     if (mode_multi) {
2007         uint32 r = 0;
2008         if (tag & 1)
2009             r = r | XR[1];
2010         if (tag & 2)
2011             r = r | XR[2];
2012         if (tag & 4)
2013             r = r | XR[4];
2014         return r & EAMASK;
2015         }
2016     return XR[tag] & EAMASK;
2017     }
2018 return 0;
2019 }
2020 
2021 /* Get index register for instruction execution
2022 
2023    Instructions which are 'executing directly' on index registers rewrite
2024    the index register value.  In multi-tag mode, this causes all registers
2025    involved in the OR function to receive the OR'd value. */
2026 
get_xrx(uint32 tag)2027 uint32 get_xrx (uint32 tag)
2028 {
2029 tag = tag & INST_M_TAG;
2030 
2031 if (tag) {
2032     if (mode_multi) {
2033         uint32 r = 0;
2034         if (tag & 1)
2035             r = r | XR[1];
2036         if (tag & 2)
2037             r = r | XR[2];
2038         if (tag & 4)
2039             r = r | XR[4];
2040         put_xr (tag, r);
2041         return r & EAMASK;
2042         }
2043     return XR[tag] & EAMASK;
2044     }
2045 return 0;
2046 }
2047 
2048 /* Store index register */
2049 
put_xr(uint32 tag,uint32 dat)2050 void put_xr (uint32 tag, uint32 dat)
2051 {
2052 tag = tag & INST_M_TAG;
2053 dat = dat & EAMASK;
2054 
2055 if (tag) {
2056     if (mode_multi) {
2057         if (tag & 1)
2058             XR[1] = dat;
2059         if (tag & 2)
2060             XR[2] = dat;
2061         if (tag & 4)
2062             XR[4] = dat;
2063         }
2064     else XR[tag] = dat;
2065     }
2066 return;
2067 }
2068 
2069 /* Floating point trap */
2070 
fp_trap(uint32 spill)2071 t_bool fp_trap (uint32 spill)
2072 {
2073 if (mode_ftrap) {
2074     WriteTAD (TRAP_STD_SAV, PC, spill);
2075     PCQ_ENTRY;
2076     PC = TRAP_FP_PC;
2077     return TRUE;
2078     }
2079 else {
2080     if (spill & TRAP_F_AC)
2081         ind_ovf = 1;
2082     if (spill & TRAP_F_MQ)
2083         ind_mqo = 1;
2084     }
2085 return FALSE;
2086 }
2087 
2088 /* (CTSS) Protection trap */
2089 
prot_trap(uint32 decr)2090 t_bool prot_trap (uint32 decr)
2091 {
2092 if (mode_user) {
2093     WriteTAD (TRAP_PROT_SAV, PC, decr);
2094     PCQ_ENTRY;
2095     PC = TRAP_PROT_PC;
2096     return TRUE;
2097     }
2098 return FALSE;
2099 }
2100 
2101 /* Store trap address and decrement, with A/B select flags; clear A/B, user mode */
2102 
WriteTAD(uint32 pa,uint32 addr,uint32 decr)2103 void WriteTAD (uint32 pa, uint32 addr, uint32 decr)
2104 {
2105 t_uint64 mem;
2106 
2107 if (inst_base)
2108     decr |= TRAP_F_BINST;
2109 if (data_base)
2110     decr |= TRAP_F_BDATA;
2111 mem = ReadP (pa) & ~(XMASK | AMASK);
2112 mem |= (((t_uint64) (decr & AMASK)) << INST_V_DEC) |
2113     ((t_uint64) (addr & AMASK));
2114 WriteP (pa, mem);
2115 mode_ctrap = 0;
2116 mode_strap = 0;
2117 mode_storn = 0;
2118 mode_user = user_buf = 0;
2119 mode_reloc = reloc_buf = 0;
2120 inst_base = 0;
2121 data_base = 0;
2122 return;
2123 }
2124 
2125 /* Copy trap */
2126 
cpy_trap(uint32 va)2127 t_bool cpy_trap (uint32 va)
2128 {
2129 if (mode_ctrap) {
2130     WriteTA (TRAP_704_SAV, va);
2131     PCQ_ENTRY;
2132     TrapXfr (TRAP_CPY_PC);
2133     return TRUE;
2134     }
2135 return FALSE;
2136 }
2137 
2138 /* Select trap */
2139 
sel_trap(uint32 va)2140 t_bool sel_trap (uint32 va)
2141 {
2142 if (mode_strap) {
2143     WriteTA (TRAP_704_SAV, va);
2144     PCQ_ENTRY;
2145     TrapXfr (TRAP_SEL_PC);
2146     return TRUE;
2147     }
2148 return FALSE;
2149 }
2150 
2151 /* Store trap address - do not alter state yet (might be TRA) */
2152 
WriteTA(uint32 pa,uint32 dat)2153 void WriteTA (uint32 pa, uint32 dat)
2154 {
2155 t_uint64 mem;
2156 
2157 mem = ReadP (pa) & ~AMASK;
2158 mem |= (dat & AMASK);
2159 WriteP (pa, mem);
2160 return;
2161 }
2162 
2163 /* Set trap PC - second half of address-only trap */
2164 
TrapXfr(uint32 newpc)2165 void TrapXfr (uint32 newpc)
2166 {
2167 PC = newpc;
2168 mode_ctrap = 0;
2169 mode_strap = 0;
2170 mode_storn = 0;
2171 mode_user = user_buf = 0;
2172 mode_reloc = reloc_buf = 0;
2173 inst_base = 0;
2174 data_base = 0;
2175 return;
2176 }
2177 
2178 /* Read instruction and indirect */
2179 
ReadI(uint32 va,t_uint64 * val)2180 t_bool ReadI (uint32 va, t_uint64 *val)
2181 {
2182 if (mode_reloc)
2183     va = (va + ind_reloc) & AMASK;
2184 if (mode_user && ((va < ind_start) || (va > ind_limit))) {
2185     prot_trap (0);
2186     return FALSE;
2187     }
2188 *val = M[va | inst_base];
2189 return TRUE;
2190 }
2191 
2192 /* Read */
2193 
Read(uint32 va,t_uint64 * val)2194 t_bool Read (uint32 va, t_uint64 *val)
2195 {
2196 if (mode_reloc)
2197     va = (va + ind_reloc) & AMASK;
2198 if (mode_user && ((va < ind_start) || (va > ind_limit))) {
2199     prot_trap (0);
2200     return FALSE;
2201     }
2202 *val = M[va | data_base];
2203 return TRUE;
2204 }
2205 
2206 /* Write */
2207 
Write(uint32 va,t_uint64 dat)2208 t_bool Write (uint32 va, t_uint64 dat)
2209 {
2210 if (mode_reloc)
2211     va = (va + ind_reloc) & AMASK;
2212 if (mode_user && ((va < ind_start) || (va > ind_limit))) {
2213     prot_trap (0);
2214     return FALSE;
2215     }
2216 M[va | data_base] = dat;
2217 return TRUE;
2218 }
2219 
2220 /* Reset routine */
2221 
cpu_reset(DEVICE * dptr)2222 t_stat cpu_reset (DEVICE *dptr)
2223 {
2224 ind_ovf = 0;
2225 ind_mqo = 0;
2226 ind_dvc = 0;
2227 ind_ioc = 0;
2228 ind_reloc = 0;
2229 ind_start = 0;
2230 ind_limit = 0;
2231 mode_ttrap = 0;
2232 mode_ctrap = 0;
2233 mode_strap = 0;
2234 mode_ftrap = 1;
2235 mode_storn = 0;
2236 if (cpu_model & (I_94|I_CT))
2237     mode_multi = 0;
2238 else mode_multi = 1;
2239 mode_user = user_buf = 0;
2240 mode_reloc = reloc_buf = 0;
2241 inst_base = 0;
2242 data_base = 0;
2243 ch_req = 0;
2244 chtr_pend = chtr_enab = 0;
2245 chtr_inht = chtr_inhi = 0;
2246 ht_pend = 0;
2247 SLT = 0;
2248 XR[0] = 0;
2249 if (M == NULL)
2250     M = (t_uint64 *) calloc (MAXMEMSIZE, sizeof (t_uint64));
2251 if (M == NULL)
2252     return SCPE_MEM;
2253 pcq_r = find_reg ("PCQ", NULL, dptr);
2254 if (pcq_r)
2255     pcq_r->qptr = 0;
2256 else return SCPE_IERR;
2257 sim_brk_types = sim_brk_dflt = SWMASK ('E');
2258 return SCPE_OK;
2259 }
2260 
2261 /* Memory examine */
2262 
cpu_ex(t_value * vptr,t_addr ea,UNIT * uptr,int32 sw)2263 t_stat cpu_ex (t_value *vptr, t_addr ea, UNIT *uptr, int32 sw)
2264 {
2265 if (vptr == NULL)
2266     return SCPE_ARG;
2267 if ((sw & (SWMASK ('A') | SWMASK ('B')))? (ea > AMASK): (ea >= MEMSIZE))
2268     return SCPE_NXM;
2269 if (sw & SWMASK ('B'))
2270     ea = ea | BCORE_BASE;
2271 *vptr = M[ea] & DMASK;
2272 return SCPE_OK;
2273 }
2274 
2275 /* Memory deposit */
2276 
cpu_dep(t_value val,t_addr ea,UNIT * uptr,int32 sw)2277 t_stat cpu_dep (t_value val, t_addr ea, UNIT *uptr, int32 sw)
2278 {
2279 if ((sw & (SWMASK ('A') | SWMASK ('B')))? (ea > AMASK): (ea >= MEMSIZE))
2280     return SCPE_NXM;
2281 if (sw & SWMASK ('B'))
2282     ea = ea | BCORE_BASE;
2283 M[ea] = val & DMASK;
2284 return SCPE_OK;
2285 }
2286 
2287 /* Set model */
2288 
cpu_set_model(UNIT * uptr,int32 val,char * cptr,void * desc)2289 t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
2290 {
2291 UNIT *chuptr = mt_dev[CHRONO_CH].units + CHRONO_UNIT;
2292 extern DEVICE clk_dev;
2293 
2294 cpu_model = val;
2295 if (val & I_CT) {
2296     uptr->capac = MAXMEMSIZE;
2297     detach_unit (uptr);
2298     chuptr->flags &= ~UNIT_ATTABLE;
2299     clk_dev.flags &= ~DEV_DIS;
2300     }
2301 else {
2302     uptr->capac = STDMEMSIZE;
2303     chuptr->flags |= UNIT_ATTABLE;
2304     }
2305 if (!(cpu_model & I_94))
2306     mode_multi = 1;
2307 return SCPE_OK;
2308 }
2309 
2310 /* Show CTSS */
2311 
cpu_show_model(FILE * st,UNIT * uptr,int32 val,void * desc)2312 t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
2313 {
2314 if (cpu_model & I_CT)
2315     fputs ("CTSS", st);
2316 else if (cpu_model & I_94)
2317     fputs ("7094", st);
2318 else fputs ("7090", st);
2319 return SCPE_OK;
2320 }
2321 
2322 /* Insert history entry */
2323 
2324 static uint32 inst_io_tab[32] = {
2325     0, 0, 0, 0,          0, 0, 0, 0,                        /* 0000 - 0377 */
2326     0, 0, 0, 0x000000FF, 0, 0, 0, 0x45540000,               /* 0400 - 0777 */
2327     0, 0, 0, 0,          0, 0, 0, 0,                        /* 1000 - 1400 */
2328     0, 0, 0, 0x000000FF, 0, 0, 0, 0                         /* 1400 - 1777 */
2329     };
2330 
cpu_ent_hist(uint32 pc,uint32 ea,t_uint64 ir,t_uint64 opnd)2331 void cpu_ent_hist (uint32 pc, uint32 ea, t_uint64 ir, t_uint64 opnd)
2332 {
2333 int32 prv_p;
2334 
2335 if (pc & HIST_PC) {
2336     if ((pc == hst[hst_p].pc) && (ir == hst[hst_p].ir)) {   /* repeat last? */
2337         hst[hst_p].rpt++;
2338         return;
2339         }
2340     prv_p = hst_p? hst_p - 1: hst_lnt - 1;
2341     if ((pc == hst[prv_p].pc) && (ir == hst[prv_p].ir)) {   /* 2 line loop? */
2342         hst[prv_p].rpt++;
2343         return;
2344         }
2345     if (hst_ch & HIST_CH_I) {                               /* IO only? */
2346         uint32 op = GET_OPC (ir);                           /* get opcode */
2347         if ((ir & INST_T_DEC) ||
2348             !(inst_io_tab[op / 32] & (1u << (op & 037))))
2349             return;
2350         }
2351     }
2352 hst_p = (hst_p + 1);                                        /* next entry */
2353 if (hst_p >= hst_lnt)
2354     hst_p = 0;
2355 hst[hst_p].pc = pc;
2356 hst[hst_p].ir = ir;
2357 hst[hst_p].ac = AC;
2358 hst[hst_p].mq = MQ;
2359 hst[hst_p].si = SI;
2360 hst[hst_p].ea = ea;
2361 hst[hst_p].opnd = opnd;
2362 hst[hst_p].rpt = 0;
2363 return;
2364 }
2365 
2366 /* Set history */
2367 
cpu_set_hist(UNIT * uptr,int32 val,char * cptr,void * desc)2368 t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc)
2369 {
2370 int32 i, lnt;
2371 t_stat r;
2372 
2373 if (cptr == NULL) {
2374     for (i = 0; i < hst_lnt; i++)
2375         hst[i].pc = 0;
2376     hst_p = 0;
2377     return SCPE_OK;
2378     }
2379 lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
2380 if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN)))
2381     return SCPE_ARG;
2382 hst_p = 0;
2383 if (hst_lnt) {
2384     free (hst);
2385     hst_lnt = hst_ch = 0;
2386     hst = NULL;
2387     }
2388 if (lnt) {
2389     hst = (InstHistory *) calloc (lnt, sizeof (InstHistory));
2390     if (hst == NULL)
2391         return SCPE_MEM;
2392     hst_lnt = lnt;
2393     if (sim_switches & SWMASK ('I'))
2394         hst_ch = HIST_CH_I|HIST_CH_C;
2395     else if (sim_switches & SWMASK ('C'))
2396         hst_ch = HIST_CH_C;
2397     else hst_ch = 0;
2398     }
2399 return SCPE_OK;
2400 }
2401 
2402 /* Print one instruction */
2403 
cpu_fprint_one_inst(FILE * st,uint32 pc,uint32 rpt,uint32 ea,t_uint64 ir,t_uint64 ac,t_uint64 mq,t_uint64 si,t_uint64 opnd)2404 t_stat cpu_fprint_one_inst (FILE *st, uint32 pc, uint32 rpt, uint32 ea,
2405     t_uint64 ir, t_uint64 ac, t_uint64 mq, t_uint64 si, t_uint64 opnd)
2406 {
2407 int32 ch;
2408 t_value sim_eval;
2409 extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
2410     UNIT *uptr, int32 sw);
2411 
2412 sim_eval = ir;
2413 if (pc & HIST_PC) {                                     /* instruction? */
2414     fputs ("CPU ", st);
2415     fprintf (st, "%05o ", pc & AMASK);
2416     if (rpt == 0)
2417         fprintf (st, "       ");
2418     else if (rpt < 1000000)
2419         fprintf (st, "%6d ", rpt);
2420     else fprintf (st, "%5dM ", rpt / 1000000);
2421     fprint_val (st, ac, 8, 38, PV_RZRO);
2422     fputc (' ', st);
2423     fprint_val (st, mq, 8, 36, PV_RZRO);
2424     fputc (' ', st);
2425     fprint_val (st, si, 8, 36, PV_RZRO);
2426     fputc (' ', st);
2427     if (ir & INST_T_DEC)
2428         fprintf (st, "       ");
2429     else fprintf (st, "%05o  ", ea);
2430     if (fprint_sym (st, pc & AMASK, &sim_eval, &cpu_unit, SWMASK ('M')) > 0) {
2431         fputs ("(undefined) ", st);
2432         fprint_val (st, ir, 8, 36, PV_RZRO);
2433         }
2434     else if (!(ir & INST_T_DEC) && (op_flags[GET_OPC (ir)] & I_R)) {
2435         fputs (" [", st);
2436         fprint_val (st, opnd, 8, 36, PV_RZRO);
2437         fputc (']', st);
2438         }
2439     fputc ('\n', st);                                   /* end line */
2440     }                                                   /* end if instruction */
2441 else if ((ch = HIST_CH (pc))) {                         /* channel? */
2442     fprintf (st, "CH%c ", 'A' + ch - 1);
2443     fprintf (st, "%05o  ", pc & AMASK);
2444     fputs ("                                              ", st);
2445     fprintf (st, "%05o  ", ea & AMASK);
2446     if (fprint_sym (st, pc & AMASK, &sim_eval, &cpu_unit,
2447         (ch_dev[ch - 1].flags & DEV_7909)? SWMASK ('N'): SWMASK ('I')) > 0) {
2448         fputs ("(undefined) ", st);
2449         fprint_val (st, ir, 8, 36, PV_RZRO);
2450         }
2451     fputc ('\n', st);                                   /* end line */
2452     }                                                   /* end else channel */
2453 return SCPE_OK;
2454 }
2455 
2456 /* Show history */
2457 
cpu_show_hist(FILE * st,UNIT * uptr,int32 val,void * desc)2458 t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
2459 {
2460 int32 k, di, lnt;
2461 char *cptr = (char *) desc;
2462 t_stat r;
2463 InstHistory *h;
2464 
2465 if (hst_lnt == 0)                                       /* enabled? */
2466     return SCPE_NOFNC;
2467 if (cptr) {
2468     lnt = (int32) get_uint (cptr, 10, hst_lnt, &r);
2469     if ((r != SCPE_OK) || (lnt == 0))
2470         return SCPE_ARG;
2471     }
2472 else lnt = hst_lnt;
2473 di = hst_p - lnt;                                       /* work forward */
2474 if (di < 0)
2475     di = di + hst_lnt;
2476 fprintf (st, "    PC    repeat AC            MQ           SI           EA     IR\n\n");
2477 for (k = 0; k < lnt; k++) {                             /* print specified */
2478     h = &hst[(++di) % hst_lnt];                         /* entry pointer */
2479     cpu_fprint_one_inst (st, h->pc, h->rpt, h->ea, h->ir, h->ac, h->mq, h->si, h->opnd);
2480     }                                                   /* end for */
2481 return SCPE_OK;
2482 }
2483