1 /* pdp11_cpumod.c: PDP-11 CPU model-specific features
2 
3    Copyright (c) 2004-2008, 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    system       PDP-11 model-specific registers
27 
28    20-May-08    RMS     Added JCSR default for KDJ11B, KDJ11E
29    22-Apr-08    RMS     Fixed write behavior of 11/70 MBRK, LOSIZE, HISIZE
30                         (Walter Mueller)
31    29-Apr-07    RMS     Don't run bus setup routine during RESTORE
32    30-Aug-05    RMS     Added additional 11/60 registers
33    16-Aug-05    RMS     Fixed C++ declaration and cast problems
34    15-Feb-05    RMS     Fixed bug in SHOW MODEL (Sergey Okhapkin)
35    19-Jan-05    RMS     Added variable SYSID, MBRK write (Tim Chapman)
36 
37    This module includes CPU- and system-specific registers, such as the Unibus
38    map and control registers on 22b Unibus systems, the board registers for the
39    F11- and J11-based systems, and the system registers for the PDP-11/44,
40    PDP-11/45, PDP-11/60, and PDP-11/70.  Most registers are implemented at
41    a minimum level: just enough to satisfy the machine identification code
42    in the various operating systems.
43 */
44 
45 #include "pdp11_defs.h"
46 #include "pdp11_cpumod.h"
47 #include <time.h>
48 
49 /* Byte write macros for system registers */
50 
51 #define ODD_IGN(cur) \
52     if ((access == WRITEB) && (pa & 1)) \
53         return SCPE_OK
54 #define ODD_WO(cur) \
55     if ((access == WRITEB) && (pa & 1)) \
56         cur = cur << 8
57 #define ODD_MRG(prv,cur) \
58     if (access == WRITEB) \
59         cur =((pa & 1)? (((prv) & 0377) | ((cur) & 0177400)) : \
60                         (((prv) & 0177400) | ((cur) & 0377)))
61 
62 int32 SR = 0;                                           /* switch register */
63 int32 DR = 0;                                           /* display register */
64 int32 MBRK = 0;                                         /* 11/70 microbreak */
65 int32 SYSID = 0x1234;                                   /* 11/70 system ID */
66 int32 WCS = 0;                                          /* 11/60 WCS control */
67 int32 CPUERR = 0;                                       /* CPU error reg */
68 int32 MEMERR = 0;                                       /* memory error reg */
69 int32 CCR = 0;                                          /* cache control reg */
70 int32 HITMISS = 0;                                      /* hit/miss reg */
71 int32 MAINT = 0;                                        /* maint reg */
72 int32 JCSR = 0;                                         /* J11 control */
73 int32 JCSR_dflt = 0;                                    /* J11 boot ctl def */
74 int32 JPCR = 0;                                         /* J11 page ctrl */
75 int32 JASR = 0;                                         /* J11 addtl status */
76 int32 UDCR = 0;                                         /* UBA diag ctrl */
77 int32 UDDR = 0;                                         /* UBA diag data */
78 int32 UCSR = 0;                                         /* UBA control */
79 int32 uba_last = 0;                                     /* UBA last mapped */
80 int32 ub_map[UBM_LNT_LW] = { 0 };                       /* UBA map array */
81 int32 toy_state = 0;
82 uint8 toy_data[TOY_LNT] = { 0 };
83 static int32 clk_tps_map[4] = { 60, 60, 50, 800 };
84 
85 extern uint16 *M;
86 extern int32 R[8];
87 extern DEVICE cpu_dev, *sim_devices[];
88 extern UNIT cpu_unit;
89 extern FILE *sim_log;
90 extern int32 STKLIM, PIRQ;
91 extern uint32 cpu_model, cpu_type, cpu_opt;
92 extern int32 clk_fie, clk_fnxm, clk_tps, clk_default;
93 extern int32 sim_switches;
94 
95 t_stat CPU24_rd (int32 *data, int32 addr, int32 access);
96 t_stat CPU24_wr (int32 data, int32 addr, int32 access);
97 t_stat CPU44_rd (int32 *data, int32 addr, int32 access);
98 t_stat CPU44_wr (int32 data, int32 addr, int32 access);
99 t_stat CPU45_rd (int32 *data, int32 addr, int32 access);
100 t_stat CPU45_wr (int32 data, int32 addr, int32 access);
101 t_stat CPU60_rd (int32 *data, int32 addr, int32 access);
102 t_stat CPU60_wr (int32 data, int32 addr, int32 access);
103 t_stat CPU70_rd (int32 *data, int32 addr, int32 access);
104 t_stat CPU70_wr (int32 data, int32 addr, int32 access);
105 t_stat CPUJ_rd (int32 *data, int32 addr, int32 access);
106 t_stat CPUJ_wr (int32 data, int32 addr, int32 access);
107 t_stat REG_rd (int32 *data, int32 addr, int32 access);
108 t_stat REG_wr (int32 data, int32 addr, int32 access);
109 t_stat SR_rd (int32 *data, int32 addr, int32 access);
110 t_stat DR_wr (int32 data, int32 addr, int32 access);
111 t_stat CTLFB_rd (int32 *data, int32 addr, int32 access);
112 t_stat CTLFB_wr (int32 data, int32 addr, int32 access);
113 t_stat CTLJB_rd (int32 *data, int32 addr, int32 access);
114 t_stat CTLJB_wr (int32 data, int32 addr, int32 access);
115 t_stat CTLJD_rd (int32 *data, int32 addr, int32 access);
116 t_stat CTLJD_wr (int32 data, int32 addr, int32 access);
117 t_stat CTLJE_rd (int32 *data, int32 addr, int32 access);
118 t_stat CTLJE_wr (int32 data, int32 addr, int32 access);
119 t_stat UBA24_rd (int32 *data, int32 addr, int32 access);
120 t_stat UBA24_wr (int32 data, int32 addr, int32 access);
121 t_stat UBAJ_rd (int32 *data, int32 addr, int32 access);
122 t_stat UBAJ_wr (int32 data, int32 addr, int32 access);
123 t_stat sys_reset (DEVICE *dptr);
124 int32 toy_read (void);
125 void toy_write (int32 bit);
126 uint8 toy_set (int32 val);
127 t_stat sys_set_jclk_dflt (UNIT *uptr, int32 val, char *cptr, void *desc);
128 t_stat sys_show_jclk_dflt (FILE *st, UNIT *uptr, int32 val, void *desc);
129 
130 extern t_stat PSW_rd (int32 *data, int32 addr, int32 access);
131 extern t_stat PSW_wr (int32 data, int32 addr, int32 access);
132 extern t_stat APR_rd (int32 *data, int32 addr, int32 access);
133 extern t_stat APR_wr (int32 data, int32 addr, int32 access);
134 extern t_stat MMR012_rd (int32 *data, int32 addr, int32 access);
135 extern t_stat MMR012_wr (int32 data, int32 addr, int32 access);
136 extern t_stat MMR3_rd (int32 *data, int32 addr, int32 access);
137 extern t_stat MMR3_wr (int32 data, int32 addr, int32 access);
138 extern t_stat ubm_rd (int32 *data, int32 addr, int32 access);
139 extern t_stat ubm_wr (int32 data, int32 addr, int32 access);
140 extern void put_PIRQ (int32 val);
141 
142 /* Fixed I/O address table entries */
143 
144 DIB psw_dib = { IOBA_PSW, IOLN_PSW, &PSW_rd, &PSW_wr, 0 };
145 DIB cpuj_dib = { IOBA_CPU, IOLN_CPU, &CPUJ_rd, &CPUJ_wr, 0 };
146 DIB cpu24_dib = { IOBA_CPU, IOLN_CPU, &CPU24_rd, &CPU24_wr, 0 };
147 DIB cpu44_dib = { IOBA_CPU, IOLN_CPU, &CPU44_rd, &CPU44_wr, 0 };
148 DIB cpu45_dib = { IOBA_CPU, IOLN_CPU, &CPU45_rd, &CPU45_wr, 0 };
149 DIB cpu60_dib = { IOBA_CPU, IOLN_CPU, &CPU60_rd, &CPU60_wr, 0 };
150 DIB cpu70_dib = { IOBA_CPU, IOLN_CPU, &CPU70_rd, &CPU70_wr, 0 };
151 DIB reg_dib = { IOBA_GPR, IOLN_GPR, &REG_rd, &REG_wr, 0 };
152 DIB ctlfb_dib = { IOBA_CTL, IOLN_CTL, &CTLFB_rd, &CTLFB_wr };
153 DIB ctljb_dib = { IOBA_CTL, IOLN_CTL, &CTLJB_rd, &CTLJB_wr };
154 DIB ctljd_dib = { IOBA_CTL, IOLN_CTL, &CTLJD_rd, &CTLJD_wr };
155 DIB ctlje_dib = { IOBA_CTL, IOLN_CTL, &CTLJE_rd, &CTLJE_wr };
156 DIB uba24_dib = { IOBA_UCTL, IOLN_UCTL, &UBA24_rd, &UBA24_wr };
157 DIB ubaj_dib = {IOBA_UCTL, IOLN_UCTL, &UBAJ_rd, &UBAJ_wr };
158 DIB supv_dib = { IOBA_SUP, IOLN_SUP, &APR_rd, &APR_wr, 0 };
159 DIB kipdr_dib = { IOBA_KIPDR, IOLN_KIPDR, &APR_rd, &APR_wr, 0 };
160 DIB kdpdr_dib = { IOBA_KDPDR, IOLN_KDPDR, &APR_rd, &APR_wr, 0 };
161 DIB kipar_dib = { IOBA_KIPAR, IOLN_KIPAR, &APR_rd, &APR_wr, 0 };
162 DIB kdpar_dib = { IOBA_KDPAR, IOLN_KDPAR, &APR_rd, &APR_wr, 0 };
163 DIB uipdr_dib = { IOBA_UIPDR, IOLN_UIPDR, &APR_rd, &APR_wr, 0 };
164 DIB udpdr_dib = { IOBA_UDPDR, IOLN_UDPDR, &APR_rd, &APR_wr, 0 };
165 DIB uipar_dib = { IOBA_UIPAR, IOLN_UIPAR, &APR_rd, &APR_wr, 0 };
166 DIB udpar_dib = { IOBA_UDPAR, IOLN_UDPAR, &APR_rd, &APR_wr, 0 };
167 DIB sr_dib = { IOBA_SR, IOLN_SR, &SR_rd, NULL, 0 };
168 DIB dr_dib = { IOBA_SR, IOLN_SR, NULL, &DR_wr, 0 };
169 DIB mmr012_dib = { IOBA_MMR012, IOLN_MMR012, &MMR012_rd, &MMR012_wr, 0 };
170 DIB mmr3_dib = { IOBA_MMR3, IOLN_MMR3, &MMR3_rd, &MMR3_wr, 0 };
171 DIB ubm_dib = { IOBA_UBM, IOLN_UBM, &ubm_rd, &ubm_wr, 0 };
172 
173 CPUTAB cpu_tab[MOD_MAX] = {
174     { "11/03", SOP_1103, OPT_1103, MEMSIZE64K, PSW_1103,
175        0, 0, 0, 0, 0 },
176     { "11/04", SOP_1104, OPT_1104, MEMSIZE64K, PSW_1104,
177        0, 0, 0, 0, 0 },
178     { "11/05", SOP_1105, OPT_1105, MEMSIZE64K, PSW_1105,
179        0, 0, 0, 0, 0 },
180     { "11/20", SOP_1120, OPT_1120, MEMSIZE64K, PSW_1120,
181        0, 0, 0, 0, 0 },
182     { "11/23", SOP_1123, OPT_1123, MAXMEMSIZE, PSW_F,
183        MFPT_F, PAR_F, PDR_F, MM0_F, MM3_F },
184     { "11/23+", SOP_1123P, OPT_1123P, MAXMEMSIZE, PSW_F,
185        MFPT_F, PAR_F, PDR_F, MM0_F, MM3_F },
186     { "11/24", SOP_1124, OPT_1124, MAXMEMSIZE, PSW_F,
187        MFPT_F, PAR_F, PDR_F, MM0_F, MM3_F },
188     { "11/34", SOP_1134, OPT_1134, UNIMEMSIZE, PSW_1134,
189        0, PAR_1134, PDR_1134, MM0_1134, 0 },
190     { "11/40", SOP_1140, OPT_1140, UNIMEMSIZE, PSW_1140,
191        0, PAR_1140, PDR_1140, MM0_1140, 0 },
192     { "11/44", SOP_1144, OPT_1144, MAXMEMSIZE, PSW_1144,
193        MFPT_44, PAR_1144, PDR_1144, MM0_1144, MM3_1144 },
194     { "11/45", SOP_1145, OPT_1145, UNIMEMSIZE, PSW_1145,
195        0, PAR_1145, PDR_1145, MM0_1145, MM3_1145 },
196     { "11/60", SOP_1160, OPT_1160, UNIMEMSIZE, PSW_1160,
197        0, PAR_1160, PDR_1160, MM0_1160, 0 },
198     { "11/70", SOP_1170, OPT_1170, MAXMEMSIZE, PSW_1170,
199        0, PAR_1170, PDR_1170, MM0_1170, MM3_1170 },
200     { "11/73", SOP_1173, OPT_1173, MAXMEMSIZE, PSW_J,
201        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J },
202     { "11/53", SOP_1153, OPT_1153, MAXMEMSIZE, PSW_J,
203        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J },
204     { "11/73B", SOP_1173B, OPT_1173B, MAXMEMSIZE, PSW_J,
205        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J },
206     { "11/83", SOP_1183, OPT_1183, MAXMEMSIZE, PSW_J,
207        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J },
208     { "11/84", SOP_1184, OPT_1184, MAXMEMSIZE, PSW_J,
209        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J },
210     { "11/93", SOP_1193, OPT_1193, MAXMEMSIZE, PSW_J,
211        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J },
212     { "11/94", SOP_1194, OPT_1194, MAXMEMSIZE, PSW_J,
213        MFPT_J, PAR_J, PDR_J, MM0_J, MM3_J }
214     };
215 
216 CNFTAB cnf_tab[] = {
217     { HAS_PSW,  0, &psw_dib },                          /* PSW */
218     { CPUT_J,   0, &cpuj_dib },                         /* CPU control */
219     { CPUT_24,  0, &cpu24_dib },
220     { CPUT_44,  0, &cpu44_dib },
221     { CPUT_45,  0, &cpu45_dib },
222     { CPUT_60,  0, &cpu60_dib },
223     { CPUT_70,  0, &cpu70_dib },
224     { HAS_IOSR, 0, &reg_dib },
225     { CPUT_23P, 0, &ctlfb_dib },                        /* board ctls */
226     { CPUT_JB,  0, &ctljb_dib },
227     { CPUT_53,  0, &ctljd_dib },
228     { CPUT_JE,  0, &ctlje_dib },
229     { CPUT_24,  0, &uba24_dib },                        /* UBA */
230     { CPUT_JU,  0, &ubaj_dib },
231     { 0, OPT_MMU,  &kipdr_dib },                        /* MMU */
232     { 0, OPT_MMU,  &kipar_dib },
233     { 0, OPT_MMU,  &uipdr_dib },
234     { 0, OPT_MMU,  &uipar_dib },
235     { 0, OPT_MMU,  &mmr012_dib },                       /* MMR0-2 */
236     { HAS_MMR3, 0, &mmr3_dib },                         /* MMR3 */
237     { 0, OPT_UBM,  &ubm_dib },                          /* Unibus map */
238     { HAS_SID,  0, &kdpdr_dib },                        /* supv, I/D */
239     { HAS_SID,  0, &kdpar_dib },
240     { HAS_SID,  0, &supv_dib },
241     { HAS_SID,  0, &udpdr_dib },
242     { HAS_SID,  0, &udpar_dib },
243     { HAS_SR,   0, &sr_dib },                           /* SR */
244     { HAS_DR,   0, &dr_dib },                           /* DR */
245     { 0, 0,        NULL }
246     };
247 
248 static const char *opt_name[] = {
249     "Unibus", "Qbus", "EIS", "NOEIS", "FIS", "NOFIS",
250     "FPP", "NOFPP", "CIS", "NOCIS", "MMU", "NOMMU",
251     "RH11", "RH70",     "PARITY", "NOPARITY", "Unibus map", "No map", NULL
252     };
253 
254 static const char *jcsr_val[4] = {
255     "LINE", "50HZ", "60HZ", "800HZ"
256     };
257 
258 /* SYSTEM data structures
259 
260    sys_dev      SYSTEM device descriptor
261    sys_unit     SYSTEM unit descriptor
262    sys_reg      SYSTEM register list
263 */
264 
265 UNIT sys_unit = { UDATA (NULL, 0, 0) };
266 
267 REG sys_reg[] = {
268     { ORDATA (SR, SR, 16) },
269     { ORDATA (DR, DR, 16) },
270     { ORDATA (MEMERR, MEMERR, 16) },
271     { ORDATA (CCR, CCR, 16) },
272     { ORDATA (MAINT, MAINT, 16) },
273     { ORDATA (HITMISS, HITMISS, 16) },
274     { ORDATA (CPUERR, CPUERR, 16) },
275     { ORDATA (MBRK, MBRK, 16) },
276     { ORDATA (WCS, WCS, 16) },
277     { ORDATA (SYSID, SYSID, 16) },
278     { ORDATA (JCSR, JCSR, 16) },
279     { ORDATA (JCSR_DFLT, JCSR_dflt, 16), REG_HRO },
280     { ORDATA (JPCR, JPCR, 16) },
281     { ORDATA (JASR, JASR, 16) },
282     { ORDATA (UDCR, UDCR, 16) },
283     { ORDATA (UDDR, UDDR, 16) },
284     { ORDATA (UCSR, UCSR, 16) },
285     { ORDATA (ULAST, uba_last, 23) },
286     { BRDATA (UBMAP, ub_map, 8, 22, UBM_LNT_LW) },
287     { DRDATA (TOY_STATE, toy_state, 6), REG_HRO },
288     { BRDATA (TOY_DATA, toy_data, 8, 8, TOY_LNT), REG_HRO },
289     { NULL}
290     };
291 
292 MTAB sys_mod[] = {
293     { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "JCLK_DFLT", "JCLK_DFLT",
294       &sys_set_jclk_dflt, &sys_show_jclk_dflt },
295     { 0 }
296     };
297 
298 DEVICE sys_dev = {
299     "SYSTEM", &sys_unit, sys_reg, sys_mod,
300     1, 0, 0, 0, 0, 0,
301     NULL, NULL, &sys_reset,
302     NULL, NULL, NULL,
303     NULL, 0, 0,
304     NULL, NULL, NULL
305     };
306 
307 /* Switch and display registers - many */
308 
SR_rd(int32 * data,int32 pa,int32 access)309 t_stat SR_rd (int32 *data, int32 pa, int32 access)
310 {
311 *data = SR;
312 return SCPE_OK;
313 }
314 
DR_wr(int32 data,int32 pa,int32 access)315 t_stat DR_wr (int32 data, int32 pa, int32 access)
316 {
317 DR = data;
318 return SCPE_OK;
319 }
320 
321 /* GPR's - 11/04, 11/05 */
322 
REG_rd(int32 * data,int32 pa,int32 access)323 t_stat REG_rd (int32 *data, int32 pa, int32 access)
324 {
325 *data = R[pa & 07];
326 return SCPE_OK;
327 }
328 
REG_wr(int32 data,int32 pa,int32 access)329 t_stat REG_wr (int32 data, int32 pa, int32 access)
330 {
331 int32 reg = pa & 07;
332 
333 if (access == WRITE)
334     R[reg] = data;
335 else if (pa & 1)
336     R[reg] = (R[reg] & 0377) | (data << 8);
337 else R[reg] = (R[reg] & ~0377) | data;
338 return SCPE_OK;
339 }
340 
341 /* CPU control registers - 11/24 */
342 
CPU24_rd(int32 * data,int32 pa,int32 access)343 t_stat CPU24_rd (int32 *data, int32 pa, int32 access)
344 {
345 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
346 
347     case 013:                                           /* CPUERR */
348         *data = 0;
349         return SCPE_OK;
350         }                                               /* end switch PA */
351 
352 *data = 0;
353 return SCPE_NXM;                                        /* unimplemented */
354 }
355 
CPU24_wr(int32 data,int32 pa,int32 access)356 t_stat CPU24_wr (int32 data, int32 pa, int32 access)
357 {
358 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
359 
360     case 013:                                           /* CPUERR */
361         return SCPE_OK;
362         }                                               /* end switch pa */
363 
364 return SCPE_NXM;                                        /* unimplemented */
365 }
366 
367 /* CPU control registers - 11/44 */
368 
CPU44_rd(int32 * data,int32 pa,int32 access)369 t_stat CPU44_rd (int32 *data, int32 pa, int32 access)
370 {
371 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
372 
373     case 002:                                           /* MEMERR */
374         *data = MEMERR;
375         return SCPE_OK;
376 
377     case 003:                                           /* CCR */
378         *data = CCR & CCR44_RD;
379         return SCPE_OK;
380 
381     case 004:                                           /* MAINT */
382         *data = MAINT & CMR44_RD;
383         return SCPE_OK;
384 
385     case 005:                                           /* Hit/miss */
386         *data = HITMISS;
387         return SCPE_OK;
388 
389     case 006:                                           /* CDR */
390         *data = 0;
391         return SCPE_OK;
392 
393     case 013:                                           /* CPUERR */
394         if (CPUERR & CPUE_YEL)                          /* 11/44 stack err */
395             CPUERR = (CPUERR & ~CPUE_YEL) | CPUE_RED;   /* in <2> not <3> */
396         if (CPUERR & (CPUE_ODD|CPUE_NXM|CPUE_TMO))      /* additional flag */
397             CPUERR = CPUERR | CPUE44_BUSE;
398         *data = CPUERR & CPUE_IMP;
399         return SCPE_OK;
400 
401     case 015:                                           /* PIRQ */
402         *data = PIRQ;
403         return SCPE_OK;
404         }                                               /* end switch PA */
405 
406 *data = 0;
407 return SCPE_NXM;                                        /* unimplemented */
408 }
409 
CPU44_wr(int32 data,int32 pa,int32 access)410 t_stat CPU44_wr (int32 data, int32 pa, int32 access)
411 {
412 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
413 
414     case 002:                                           /* MEMERR */
415         MEMERR = 0;
416         return SCPE_OK;
417 
418     case 003:                                           /* CCR */
419         ODD_MRG (CCR, data);
420         CCR = data & CCR44_WR;
421         return SCPE_OK;
422 
423     case 004:                                           /* MAINT */
424         ODD_MRG (MAINT, data);
425         MAINT = data & CMR44_WR;
426         return SCPE_OK;
427 
428     case 005:                                           /* Hit/miss */
429         return SCPE_OK;
430 
431     case 013:                                           /* CPUERR */
432         CPUERR = 0;
433         return SCPE_OK;
434 
435     case 015:                                           /* PIRQ */
436         ODD_WO (data);
437         put_PIRQ (data);
438         return SCPE_OK;
439         }
440 
441 return SCPE_NXM;                                        /* unimplemented */
442 }
443 
444 /* CPU control registers - 11/45 */
445 
CPU45_rd(int32 * data,int32 pa,int32 access)446 t_stat CPU45_rd (int32 *data, int32 pa, int32 access)
447 {
448 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
449 
450     case 014:                                           /* MBRK */
451         *data = MBRK;
452         return SCPE_OK;
453 
454     case 015:                                           /* PIRQ */
455         *data = PIRQ;
456         return SCPE_OK;
457 
458     case 016:                                           /* STKLIM */
459         *data = STKLIM & STKLIM_RW;
460         return SCPE_OK;
461         }                                               /* end switch PA */
462 
463 *data = 0;
464 return SCPE_NXM;                                        /* unimplemented */
465 }
466 
CPU45_wr(int32 data,int32 pa,int32 access)467 t_stat CPU45_wr (int32 data, int32 pa, int32 access)
468 {
469 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
470 
471     case 015:                                           /* PIRQ */
472         ODD_WO (data);
473         put_PIRQ (data);
474         return SCPE_OK;
475 
476     case 016:                                           /* STKLIM */
477         ODD_WO (data);
478         STKLIM = data & STKLIM_RW;
479         return SCPE_OK;
480         }                                               /* end switch pa */
481 
482 return SCPE_NXM;                                        /* unimplemented */
483 }
484 
485 /* CPU control registers - 11/60 */
486 
CPU60_rd(int32 * data,int32 pa,int32 access)487 t_stat CPU60_rd (int32 *data, int32 pa, int32 access)
488 {
489 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
490 
491     case 000:                                           /* WCS */
492         *data = WCS & WCS60_RD;
493         return SCPE_OK;
494 
495     case 002:                                           /* MEMERR */
496         *data = MEMERR & MEME60_RD;
497         return SCPE_OK;
498 
499     case 003:                                           /* CCR */
500         *data = CCR & CCR60_RD;
501         return SCPE_OK;
502 
503     case 005:                                           /* Hit/miss */
504         *data = HITMISS;
505         return SCPE_OK;
506 
507     case 013:                                           /* CPUERR */
508         if (CPUERR & CPUE_NXM)                          /* TMO only */
509             CPUERR = (CPUERR & ~CPUE_NXM) | CPUE_TMO;
510         *data = CPUERR & CPUE60_RD;
511         return SCPE_OK;
512 
513     case 016:                                           /* STKLIM */
514         *data = STKLIM & STKLIM_RW;
515         return SCPE_OK;
516         }                                               /* end switch PA */
517 
518 *data = 0;
519 return SCPE_NXM;                                        /* unimplemented */
520 }
521 
CPU60_wr(int32 data,int32 pa,int32 access)522 t_stat CPU60_wr (int32 data, int32 pa, int32 access)
523 {
524 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
525 
526     case 000:                                           /* WCS */
527         WCS = data & WCS60_WR;
528         return SCPE_OK;
529 
530     case 002:                                           /* MEMERR */
531         MEMERR = 0;
532         return SCPE_OK;
533 
534     case 003:                                           /* CCR */
535         ODD_IGN (data);
536         CCR = data & CCR60_WR;
537         return SCPE_OK;
538 
539     case 005:                                           /* Hit/miss */
540         return SCPE_OK;
541 
542     case 013:                                           /* CPUERR */
543         CPUERR = 0;
544         return SCPE_OK;
545 
546     case 014:                                           /* MBRK */
547         MBRK = data & MBRK60_WR;
548         return SCPE_OK;
549 
550     case 016:                                           /* STKLIM */
551         ODD_WO (data);
552         STKLIM = data & STKLIM_RW;
553         return SCPE_OK;
554         }                                               /* end switch pa */
555 
556 return SCPE_NXM;                                        /* unimplemented */
557 }
558 
559 /* CPU control registers - 11/70 */
560 
CPU70_rd(int32 * data,int32 pa,int32 access)561 t_stat CPU70_rd (int32 *data, int32 pa, int32 access)
562 {
563 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
564 
565     case 000:                                           /* low error */
566         *data = 0;
567         return SCPE_OK;
568 
569     case 001:                                           /* high error */
570         *data = 0;
571         return SCPE_OK;
572 
573     case 002:                                           /* MEMERR */
574         *data = MEMERR;
575         return SCPE_OK;
576 
577     case 003:                                           /* CCR */
578         *data = CCR;
579         return SCPE_OK;
580 
581     case 004:                                           /* MAINT */
582         *data = 0;
583         return SCPE_OK;
584 
585     case 005:                                           /* Hit/miss */
586         *data = HITMISS;
587         return SCPE_OK;
588 
589     case 010:                                           /* low size */
590         *data = (MEMSIZE >> 6) - 1;
591         return SCPE_OK;
592 
593     case 011:                                           /* high size */
594         *data = 0;
595         return SCPE_OK;
596 
597     case 012:                                           /* system ID */
598         *data = SYSID;
599         return SCPE_OK;
600 
601     case 013:                                           /* CPUERR */
602         *data = CPUERR & CPUE_IMP;
603         return SCPE_OK;
604 
605     case 014:                                           /* MBRK */
606         *data = MBRK;
607         return SCPE_OK;
608 
609     case 015:                                           /* PIRQ */
610         *data = PIRQ;
611         return SCPE_OK;
612 
613     case 016:                                           /* STKLIM */
614         *data = STKLIM & STKLIM_RW;
615         return SCPE_OK;
616         }                                               /* end switch PA */
617 
618 *data = 0;
619 return SCPE_NXM;                                        /* unimplemented */
620 }
621 
CPU70_wr(int32 data,int32 pa,int32 access)622 t_stat CPU70_wr (int32 data, int32 pa, int32 access)
623 {
624 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
625 
626     case 002:                                           /* MEMERR */
627         ODD_WO (data);
628         MEMERR = MEMERR & ~data;
629         return SCPE_OK;
630 
631     case 003:                                           /* CCR */
632         ODD_MRG (CCR, data);
633         CCR = data;
634         return SCPE_OK;
635 
636     case 004:                                           /* MAINT */
637         return SCPE_OK;
638 
639     case 005:                                           /* Hit/miss */
640         return SCPE_OK;
641 
642     case 010:                                           /* low size */
643         return SCPE_OK;
644 
645     case 011:                                           /* high size */
646         return SCPE_OK;
647 
648     case 013:                                           /* CPUERR */
649         CPUERR = 0;
650         return SCPE_OK;
651 
652     case 014:                                           /* MBRK */
653         ODD_IGN (data);
654         MBRK = data & MBRK70_WR;
655         return SCPE_OK;
656 
657     case 015:                                           /* PIRQ */
658         ODD_WO (data);
659         put_PIRQ (data);
660         return SCPE_OK;
661 
662     case 016:                                           /* STKLIM */
663         ODD_WO (data);
664         STKLIM = data & STKLIM_RW;
665         return SCPE_OK;
666         }                                               /* end switch pa */
667 
668 return SCPE_NXM;                                        /* unimplemented */
669 }
670 
671 /* CPU control registers - J11 */
672 
CPUJ_rd(int32 * data,int32 pa,int32 access)673 t_stat CPUJ_rd (int32 *data, int32 pa, int32 access)
674 {
675 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
676 
677     case 002:                                           /* MEMERR */
678         *data = MEMERR;
679         return SCPE_OK;
680 
681     case 003:                                           /* CCR */
682         *data = CCR;
683         return SCPE_OK;
684 
685     case 004:                                           /* MAINT */
686         *data = MAINT | MAINT_NOFPA | MAINT_BPOK | (UNIBUS? MAINT_U: MAINT_Q);
687         if (CPUT (CPUT_53))
688             *data |= MAINT_KDJD | MAINT_POROM;
689         if (CPUT (CPUT_73))
690             *data |= MAINT_KDJA | MAINT_POODT;
691         if (CPUT (CPUT_73B|CPUT_83|CPUT_84))
692             *data |= MAINT_KDJB | MAINT_POROM;
693         if (CPUT (CPUT_93|CPUT_94))
694             *data |= MAINT_KDJE | MAINT_POROM;
695         return SCPE_OK;
696 
697     case 005:                                           /* Hit/miss */
698         if (CPUT (CPUT_73B))                            /* must be 0 for 73B */
699             *data = 0;
700         else *data = HITMISS | 010;                     /* must be nz for 11/8X */
701         return SCPE_OK;
702 
703     case 013:                                           /* CPUERR */
704         *data = CPUERR & CPUE_IMP;
705         return SCPE_OK;
706 
707     case 015:                                           /* PIRQ */
708         *data = PIRQ;
709         return SCPE_OK;
710         }                                               /* end switch PA */
711 
712 *data = 0;
713 return SCPE_NXM;                                        /* unimplemented */
714 }
715 
CPUJ_wr(int32 data,int32 pa,int32 access)716 t_stat CPUJ_wr (int32 data, int32 pa, int32 access)
717 {
718 switch ((pa >> 1) & 017) {                              /* decode pa<4:1> */
719 
720     case 002:                                           /* MEMERR */
721         MEMERR = 0;
722         return SCPE_OK;
723 
724     case 003:                                           /* CCR */
725         ODD_MRG (CCR, data);
726         CCR = data;
727         return SCPE_OK;
728 
729     case 004:                                           /* MAINT */
730         return SCPE_OK;
731 
732     case 005:                                           /* Hit/miss */
733         return SCPE_OK;
734 
735     case 013:                                           /* CPUERR */
736         CPUERR = 0;
737         return SCPE_OK;
738 
739     case 015:                                           /* PIRQ */
740         ODD_WO (data);
741         put_PIRQ (data);
742         return SCPE_OK;
743         }                                               /* end switch pa */
744 
745 return SCPE_NXM;                                        /* unimplemented */
746 }
747 
748 /* Board control registers - KDF11B */
749 
CTLFB_rd(int32 * data,int32 pa,int32 access)750 t_stat CTLFB_rd (int32 *data, int32 pa, int32 access)
751 {
752 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
753 
754     case 0:                                             /* PCR */
755         *data = JPCR & PCRFB_RW;
756         return SCPE_OK;
757 
758     case 1:                                             /* MAINT */
759         *data = MAINT;
760         return SCPE_OK;
761 
762     case 2:                                             /* CDR */
763         *data = SR & CDRFB_RD;
764         return SCPE_OK;
765         }
766 
767 *data = 0;
768 return SCPE_NXM;
769 }
770 
CTLFB_wr(int32 data,int32 pa,int32 access)771 t_stat CTLFB_wr (int32 data, int32 pa, int32 access)
772 {
773 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
774 
775     case 0:                                             /* PCR */
776         ODD_MRG (JPCR, data);
777         JPCR = data & PCRFB_RW;
778         return SCPE_OK;
779     case 1:                                             /* MAINT */
780         ODD_MRG (MAINT, data);
781         MAINT = data;
782         return SCPE_OK;
783     case 2:                                             /* CDR */
784         ODD_WO (data);
785         DR = data & CDRFB_WR;
786         return SCPE_OK;
787         }
788 
789 return SCPE_NXM;
790 }
791 
792 /* Board control registers - KDJ11B */
793 
CTLJB_rd(int32 * data,int32 pa,int32 access)794 t_stat CTLJB_rd (int32 *data, int32 pa, int32 access)
795 {
796 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
797 
798    case 0:                                              /* CSR */
799     *data = JCSR & CSRJB_RD;
800     return SCPE_OK;
801 
802     case 1:                                             /* PCR */
803         *data = JPCR & PCRJB_RW;
804         return SCPE_OK;
805 
806     case 2:                                             /* CDR */
807         *data = SR & CDRJB_RD;
808         return SCPE_OK;
809         }
810 
811 *data = 0;
812 return SCPE_NXM;
813 }
814 
CTLJB_wr(int32 data,int32 pa,int32 access)815 t_stat CTLJB_wr (int32 data, int32 pa, int32 access)
816 {
817 int32 t;
818 
819 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
820 
821     case 0:                                             /* CSR */
822         ODD_MRG (JCSR, data);
823         JCSR = (JCSR & ~CSRJB_WR) | (data & CSRJB_WR);
824         if (JCSR & CSRJ_LTCI)                           /* force LTC int enb? */
825             clk_fie = 1;
826         else clk_fie = 0;
827         if (JCSR & CSRJ_LTCD)                           /* force LTC reg nxm? */
828             clk_fnxm = 1;
829         else clk_fnxm = 0;
830         t = CSRJ_LTCSEL (JCSR);                         /* get freq sel */
831         if (t)
832             clk_tps = clk_tps_map[t];
833         else clk_tps = clk_default;
834         return SCPE_OK;
835 
836     case 1:                                             /* PCR */
837         ODD_MRG (JPCR, data);
838         JPCR = data & PCRJB_RW;
839         return SCPE_OK;
840 
841     case 2:                                             /* CDR */
842         ODD_WO (data);
843         DR = data & CDRJB_WR;
844         return SCPE_OK;
845         }
846 
847 return SCPE_NXM;
848 }
849 
850 /* Board control registers - KDJ11D */
851 
CTLJD_rd(int32 * data,int32 pa,int32 access)852 t_stat CTLJD_rd (int32 *data, int32 pa, int32 access)
853 {
854 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
855 
856     case 0:                                             /* CSR */
857         *data = JCSR & CSRJD_RD;
858         return SCPE_OK;
859         }
860 
861 *data = 0;
862 return SCPE_NXM;
863 }
864 
CTLJD_wr(int32 data,int32 pa,int32 access)865 t_stat CTLJD_wr (int32 data, int32 pa, int32 access)
866 {
867 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
868 
869     case 0:                                             /* CSR */
870         ODD_MRG (JCSR, data);
871         JCSR = (JCSR & ~CSRJD_WR) | (data & CSRJD_WR);
872         return SCPE_OK;
873         }
874 
875 return SCPE_NXM;
876 }
877 
878 /* Board control registers - KDJ11E */
879 
CTLJE_rd(int32 * data,int32 pa,int32 access)880 t_stat CTLJE_rd (int32 *data, int32 pa, int32 access)
881 {
882 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
883 
884     case 0:                                             /* CSR */
885         *data = JCSR & CSRJE_RD;
886         return SCPE_OK;
887 
888     case 1:                                             /* PCR */
889         *data = JPCR & PCRJE_RW;
890         return SCPE_OK;
891 
892     case 2:                                             /* CDR */
893         *data = SR & CDRJE_RD;
894         return SCPE_OK;
895 
896     case 3:                                             /* ASR */
897         JASR = (JASR & ~ASRJE_TOY) | (toy_read () << ASRJE_V_TOY);
898         *data = JASR & ASRJE_RW;
899         return SCPE_OK;
900         }
901 
902 *data = 0;
903 return SCPE_NXM;
904 }
905 
CTLJE_wr(int32 data,int32 pa,int32 access)906 t_stat CTLJE_wr (int32 data, int32 pa, int32 access)
907 {
908 int32 t;
909 
910 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
911 
912     case 0:                                             /* CSR */
913         ODD_MRG (JCSR, data);
914         JCSR = (JCSR & ~CSRJE_WR) | (data & CSRJE_WR);
915         if (JCSR & CSRJ_LTCI)                           /* force LTC int enb? */
916             clk_fie = 1;
917         else clk_fie = 0;
918         if (JCSR & CSRJ_LTCD)                           /* force LTC reg nxm? */
919             clk_fnxm = 1;
920         else clk_fnxm = 0;
921         t = CSRJ_LTCSEL (JCSR);                         /* get freq sel */
922         if (t)
923             clk_tps = clk_tps_map[t];
924         else clk_tps = clk_default;
925         return SCPE_OK;
926 
927     case 1:                                             /* PCR */
928         ODD_MRG (JPCR, data);
929         JPCR = data & PCRJE_RW;
930         return SCPE_OK;
931 
932     case 2:                                             /* CDR */
933         ODD_WO (data);
934         DR = data & CDRJE_WR;
935         return SCPE_OK;
936 
937     case 3:                                             /* ASR */
938         ODD_MRG (JASR, data);
939         JASR = data & ASRJE_RW;
940         toy_write (ASRJE_TOYBIT (JASR));
941         return SCPE_OK;
942         }
943 
944 return SCPE_NXM;
945 }
946 
947 /* Unibus adapter registers - KT24 */
948 
UBA24_rd(int32 * data,int32 pa,int32 access)949 t_stat UBA24_rd (int32 *data, int32 pa, int32 access)
950 {
951 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
952 
953     case 2:                                             /* LMAL */
954         *data = uba_last & LMAL_RD;
955         return SCPE_OK;
956     case 3:                                             /* LMAH */
957         *data = uba_last & LMAH_RD;
958         return SCPE_OK;
959         }
960 
961 *data = 0;
962 return SCPE_NXM;
963 }
964 
UBA24_wr(int32 data,int32 pa,int32 access)965 t_stat UBA24_wr (int32 data, int32 pa, int32 access)
966 {
967 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
968 
969     case 3:                                             /* ASR */
970         ODD_IGN (data);
971         uba_last = (uba_last & ~LMAH_WR) | ((data & LMAH_WR) << 16);
972         return SCPE_OK;
973         }
974 
975 return SCPE_NXM;
976 }
977 
978 /* Unibus registers - KTJ11B */
979 
UBAJ_rd(int32 * data,int32 pa,int32 access)980 t_stat UBAJ_rd (int32 *data, int32 pa, int32 access)
981 {
982 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
983 
984     case 0:                                             /* DCR */
985         *data = UDCR & DCRKTJ_RD;
986         return SCPE_OK;
987 
988     case 1:                                             /* DDR */
989         *data = UDDR & DDRKTJ_RW;
990         return SCPE_OK;
991 
992     case 2:                                             /* CSR */
993         *data = UCSR & MCRKTJ_RD;
994         return SCPE_OK;
995         }
996 
997 *data = 0;
998 return SCPE_NXM;
999 }
1000 
UBAJ_wr(int32 data,int32 pa,int32 access)1001 t_stat UBAJ_wr (int32 data, int32 pa, int32 access)
1002 {
1003 switch ((pa >> 1) & 03) {                               /* decode pa<2:1> */
1004 
1005     case 0:                                             /* DCR */
1006         ODD_MRG (UDCR, data);
1007         UDCR = (UDCR & ~DCRKTJ_WR) | (data & DCRKTJ_WR);
1008         return SCPE_OK;
1009 
1010     case 1:                                             /* DDR */
1011         ODD_MRG (UDDR, data);
1012         UDDR = data & DDRKTJ_RW;;
1013         return SCPE_OK;
1014 
1015     case 2:                                             /* CSR */
1016         ODD_MRG (UCSR, data);
1017         UCSR = (UCSR & ~MCRKTJ_WR) | (data & MCRKTJ_WR);
1018         return SCPE_OK;
1019         }
1020 
1021 return SCPE_NXM;
1022 }
1023 
1024 /* KDJ11E TOY routines */
1025 
toy_read(void)1026 int32 toy_read (void)
1027 {
1028 time_t curr;
1029 struct tm *ctm;
1030 int32 bit;
1031 
1032 if (toy_state == 0) {
1033     curr = time (NULL);                                 /* get curr time */
1034     if (curr == (time_t) -1)                            /* error? */
1035         return 0;
1036     ctm = localtime (&curr);                            /* decompose */
1037     if (ctm == NULL)                                    /* error? */
1038         return 0;
1039     toy_data[TOY_HSEC] = 0x50;
1040     toy_data[TOY_SEC] = toy_set (ctm->tm_sec);
1041     toy_data[TOY_MIN] = toy_set (ctm->tm_min);
1042     toy_data[TOY_HR] = toy_set (ctm->tm_hour);
1043     toy_data[TOY_DOW] = toy_set (ctm->tm_wday);
1044     toy_data[TOY_DOM] = toy_set (ctm->tm_mday);
1045     toy_data[TOY_MON] = toy_set (ctm->tm_mon + 1);
1046     toy_data[TOY_YR] = toy_set (ctm->tm_year % 100);
1047     }
1048 bit = toy_data[toy_state >> 3] >> (toy_state & 07);
1049 toy_state = (toy_state + 1) % (TOY_LNT * 8);
1050 return (bit & 1);
1051 }
1052 
toy_write(int32 bit)1053 void toy_write (int32 bit)
1054 {
1055 toy_state = 0;
1056 return;
1057 }
1058 
toy_set(int32 val)1059 uint8 toy_set (int32 val)
1060 {
1061 uint32 d1, d2;
1062 
1063 d1 = val / 10;
1064 d2 = val % 10;
1065 return (uint8) ((d1 << 4) | d2);
1066 }
1067 
1068 /* Build I/O space entries for CPU */
1069 
cpu_build_dib(void)1070 t_stat cpu_build_dib (void)
1071 {
1072 int32 i;
1073 t_stat r;
1074 
1075 for (i = 0; cnf_tab[i].dib != NULL; i++) {              /* loop thru config tab */
1076     if (((cnf_tab[i].cpum == 0) || (cpu_type & cnf_tab[i].cpum)) &&
1077         ((cnf_tab[i].optm == 0) || (cpu_opt & cnf_tab[i].optm))) {
1078         if ((r = build_ubus_tab (&cpu_dev, cnf_tab[i].dib))) /* add to dispatch tab */
1079              return r;
1080         }
1081     }
1082 return SCPE_OK;
1083 }
1084 
1085 /* Set/show CPU model */
1086 
cpu_set_model(UNIT * uptr,int32 val,char * cptr,void * desc)1087 t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
1088 {
1089 if (cptr != NULL)
1090     return SCPE_ARG;
1091 if (val >= MOD_MAX)
1092     return SCPE_IERR;
1093 if (val == (int32) cpu_model)
1094     return SCPE_OK;
1095 if (MEMSIZE > cpu_tab[val].maxm)
1096     cpu_set_size (uptr, cpu_tab[val].maxm, NULL, NULL);
1097 if (MEMSIZE > cpu_tab[val].maxm)
1098     return SCPE_INCOMP;
1099 cpu_model = val;
1100 cpu_type = 1u << cpu_model;
1101 cpu_opt = cpu_tab[cpu_model].std;
1102 cpu_set_bus (cpu_opt);
1103 reset_all (0);                                          /* reset world */
1104 return SCPE_OK;
1105 }
1106 
cpu_show_model(FILE * st,UNIT * uptr,int32 val,void * desc)1107 t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
1108 {
1109 uint32 i, all_opt;
1110 
1111 fprintf (st, "%s", cpu_tab[cpu_model].name);
1112 all_opt = cpu_tab[cpu_model].opt;
1113 for (i = 0; opt_name[2 * i] != NULL; i++) {
1114     if ((all_opt >> i) & 1)
1115         fprintf (st, ", %s",
1116                 ((cpu_opt >> i) & 1)? opt_name[2 * i]: opt_name[(2 * i) + 1]);
1117     }
1118 return SCPE_OK;
1119 }
1120 
1121 /* Set/clear CPU option */
1122 
cpu_set_opt(UNIT * uptr,int32 val,char * cptr,void * desc)1123 t_stat cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
1124 {
1125 if (cptr)
1126     return SCPE_ARG;
1127 if ((val & cpu_tab[cpu_model].opt) == 0)
1128     return SCPE_ARG;
1129 cpu_opt = cpu_opt | val;
1130 return SCPE_OK;
1131 }
1132 
cpu_clr_opt(UNIT * uptr,int32 val,char * cptr,void * desc)1133 t_stat cpu_clr_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
1134 {
1135 if (cptr)
1136     return SCPE_ARG;
1137 if ((val & cpu_tab[cpu_model].opt) == 0)
1138     return SCPE_ARG;
1139 cpu_opt = cpu_opt & ~val;
1140 return SCPE_OK;
1141 }
1142 
1143 /* Memory allocation */
1144 
cpu_set_size(UNIT * uptr,int32 val,char * cptr,void * desc)1145 t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
1146 {
1147 int32 mc = 0;
1148 uint32 i, clim;
1149 uint16 *nM;
1150 
1151 if ((val <= 0) ||
1152     (val > (int32) cpu_tab[cpu_model].maxm) ||
1153     ((val & 07777) != 0))
1154     return SCPE_ARG;
1155 for (i = val; i < MEMSIZE; i = i + 2)
1156     mc = mc | M[i >> 1];
1157 if ((mc != 0) && !get_yn ("Really truncate memory [N]?", FALSE))
1158     return SCPE_OK;
1159 nM = (uint16 *) calloc (val >> 1, sizeof (uint16));
1160 if (nM == NULL)
1161     return SCPE_MEM;
1162 clim = (((t_addr) val) < MEMSIZE)? val: MEMSIZE;
1163 for (i = 0; i < clim; i = i + 2)
1164     nM[i >> 1] = M[i >> 1];
1165 free (M);
1166 M = nM;
1167 MEMSIZE = val;
1168 if (!(sim_switches & SIM_SW_REST))                      /* unless restore, */
1169     cpu_set_bus (cpu_opt);                              /* alter periph config */
1170 return SCPE_OK;
1171 }
1172 
1173 /* Bus configuration, disable Unibus or Qbus devices */
1174 
cpu_set_bus(int32 opt)1175 t_stat cpu_set_bus (int32 opt)
1176 {
1177 DEVICE *dptr;
1178 uint32 i, mask;
1179 
1180 if (opt & BUS_U)                                        /* Unibus variant? */
1181     mask = DEV_UBUS;
1182 else if (MEMSIZE <= UNIMEMSIZE)                         /* 18b Qbus devices? */
1183     mask = DEV_QBUS | DEV_Q18;
1184 else mask = DEV_QBUS;                                   /* must be 22b */
1185 for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
1186     if ((dptr->flags & DEV_DISABLE) &&                  /* disable-able? */
1187         !(dptr->flags & DEV_DIS) &&                     /* enabled? */
1188         ((dptr->flags & mask) == 0)) {                  /* not allowed? */
1189         printf ("Disabling %s\n", sim_dname (dptr));
1190         if (sim_log)
1191             fprintf (sim_log, "Disabling %s\n", sim_dname (dptr));
1192         dptr->flags = dptr->flags | DEV_DIS;
1193         }
1194     }
1195 return SCPE_OK;
1196 }
1197 
1198 /* System reset */
1199 
sys_reset(DEVICE * dptr)1200 t_stat sys_reset (DEVICE *dptr)
1201 {
1202 int32 i;
1203 
1204 CCR = 0;
1205 HITMISS = 0;
1206 CPUERR = 0;
1207 MEMERR = 0;
1208 if (!CPUT (CPUT_J))
1209     MAINT = 0;
1210 MBRK = 0;
1211 WCS = 0;
1212 if (CPUT (CPUT_JB|CPUT_JE))
1213     JCSR = JCSR_dflt;
1214 else JCSR = 0;
1215 JPCR = 0;
1216 JASR = 0;
1217 UDCR = 0;
1218 UDDR = 0;
1219 UCSR = 0;
1220 uba_last = 0;
1221 DR = 0;
1222 toy_state = 0;
1223 for (i = 0; i < UBM_LNT_LW; i++)
1224     ub_map[i] = 0;
1225 for (i = 0; i < TOY_LNT; i++)
1226     toy_data[i] = 0;
1227 return SCPE_OK;
1228 }
1229 
1230 /* Set/show JCLK default values */
1231 
sys_set_jclk_dflt(UNIT * uptr,int32 val,char * cptr,void * desc)1232 t_stat sys_set_jclk_dflt (UNIT *uptr, int32 val, char *cptr, void *desc)
1233 {
1234 uint32 i;
1235 
1236 if ((CPUT (CPUT_JB|CPUT_JE)) && cptr) {
1237     for (i = 0; i < 4; i++) {
1238         if (strncmp (cptr, jcsr_val[i], strlen (cptr)) == 0) {
1239             JCSR_dflt = i << CSRJ_V_LTCSEL;
1240             return SCPE_OK;
1241             }
1242         }
1243     }
1244 return SCPE_ARG;
1245 }
1246 
sys_show_jclk_dflt(FILE * st,UNIT * uptr,int32 val,void * desc)1247 t_stat sys_show_jclk_dflt (FILE *st, UNIT *uptr, int32 val, void *desc)
1248 {
1249 if (CPUT (CPUT_JB|CPUT_JE))
1250     fprintf (st, "JCLK default=%s\n", jcsr_val[CSRJ_LTCSEL (JCSR_dflt)]);
1251 else fprintf (st, "Not implemented\n");
1252 return SCPE_OK;
1253 }
1254