First Commit of my working state
[simh.git] / VAX / vax_sysdev.c
1 /* vax_sysdev.c: VAX 3900 system-specific logic
2
3 Copyright (c) 1998-2005, 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 This module contains the CVAX chip and VAX 3900 system-specific registers
27 and devices.
28
29 rom bootstrap ROM (no registers)
30 nvr non-volatile ROM (no registers)
31 csi console storage input
32 cso console storage output
33 sysd system devices (SSC miscellany)
34
35 25-Oct-05 RMS Automated CMCTL extended memory
36 16-Aug-05 RMS Fixed C++ declaration and cast problems
37 10-Mar-05 RMS Fixed bug in timer schedule routine (from Mark Hittinger)
38 30-Sep-04 RMS Moved CADR, MSER, CONPC, CONPSL, machine_check, cpu_boot,
39 con_halt here from vax_cpu.c
40 Moved model-specific IPR's here from vax_cpu1.c
41 09-Sep-04 RMS Integrated powerup into RESET (with -p)
42 Added model-specific registers and routines from CPU
43 23-Jan-04 MP Added extended physical memory support (Mark Pizzolato)
44 07-Jun-03 MP Added calibrated delay to ROM reads (Mark Pizzolato)
45 Fixed calibration problems interval timer (Mark Pizzolato)
46 12-May-03 RMS Fixed compilation warnings from VC.Net
47 23-Apr-03 RMS Revised for 32b/64b t_addr
48 19-Aug-02 RMS Removed unused variables (found by David Hittner)
49 Allowed NVR to be attached to file
50 30-May-02 RMS Widened POS to 32b
51 28-Feb-02 RMS Fixed bug, missing end of table (found by Lars Brinkhoff)
52 */
53
54 #include "vax_defs.h"
55
56 #define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */
57 #define UNIT_NODELAY (1u << UNIT_V_NODELAY)
58
59 /* Console storage control/status */
60
61 #define CSICSR_IMP (CSR_DONE + CSR_IE) /* console input */
62 #define CSICSR_RW (CSR_IE)
63 #define CSOCSR_IMP (CSR_DONE + CSR_IE) /* console output */
64 #define CSOCSR_RW (CSR_IE)
65
66 /* CMCTL configuration registers */
67
68 #define CMCNF_VLD 0x80000000 /* addr valid */
69 #define CMCNF_BA 0x1FF00000 /* base addr */
70 #define CMCNF_LOCK 0x00000040 /* lock NI */
71 #define CMCNF_SRQ 0x00000020 /* sig req WO */
72 #define CMCNF_SIG 0x0000001F /* signature */
73 #define CMCNF_RW (CMCNF_VLD | CMCNF_BA) /* read/write */
74 #define CMCNF_MASK (CMCNF_RW | CMCNF_SIG)
75 #define MEM_BANK (1 << 22) /* bank size 4MB */
76 #define MEM_SIG (0x17) /* ECC, 4 x 4MB */
77
78 /* CMCTL error register */
79
80 #define CMERR_RDS 0x80000000 /* uncorr err NI */
81 #define CMERR_FRQ 0x40000000 /* 2nd RDS NI */
82 #define CMERR_CRD 0x20000000 /* CRD err NI */
83 #define CMERR_PAG 0x1FFFFC00 /* page addr NI */
84 #define CMERR_DMA 0x00000100 /* DMA err NI */
85 #define CMERR_BUS 0x00000080 /* bus err NI */
86 #define CMERR_SYN 0x0000007F /* syndrome NI */
87 #define CMERR_W1C (CMERR_RDS | CMERR_FRQ | CMERR_CRD | \
88 CMERR_DMA | CMERR_BUS)
89
90 /* CMCTL control/status register */
91
92 #define CMCSR_PMI 0x00002000 /* PMI speed NI */
93 #define CMCSR_CRD 0x00001000 /* enb CRD int NI */
94 #define CMCSR_FRF 0x00000800 /* force ref WONI */
95 #define CMCSR_DET 0x00000400 /* dis err NI */
96 #define CMCSR_FDT 0x00000200 /* fast diag NI */
97 #define CMCSR_DCM 0x00000080 /* diag mode NI */
98 #define CMCSR_SYN 0x0000007F /* syndrome NI */
99 #define CMCSR_MASK (CMCSR_PMI | CMCSR_CRD | CMCSR_DET | \
100 CMCSR_FDT | CMCSR_DCM | CMCSR_SYN)
101
102 /* KA655 boot/diagnostic register */
103
104 #define BDR_BRKENB 0x00000080 /* break enable */
105
106 /* KA655 cache control register */
107
108 #define CACR_DRO 0x00FFFF00 /* diag bits RO */
109 #define CACR_V_DPAR 24 /* data parity */
110 #define CACR_FIXED 0x00000040 /* fixed bits */
111 #define CACR_CPE 0x00000020 /* parity err W1C */
112 #define CACR_CEN 0x00000010 /* enable */
113 #define CACR_DPE 0x00000004 /* disable par NI */
114 #define CACR_WWP 0x00000002 /* write wrong par NI */
115 #define CACR_DIAG 0x00000001 /* diag mode */
116 #define CACR_W1C (CACR_CPE)
117 #define CACR_RW (CACR_CEN | CACR_DPE | CACR_WWP | CACR_DIAG)
118
119 /* SSC base register */
120
121 #define SSCBASE_MBO 0x20000000 /* must be one */
122 #define SSCBASE_RW 0x1FFFFC00 /* base address */
123
124 /* SSC configuration register */
125
126 #define SSCCNF_BLO 0x80000000 /* batt low W1C */
127 #define SSCCNF_IVD 0x08000000 /* int dsbl NI */
128 #define SSCCNF_IPL 0x03000000 /* int IPL NI */
129 #define SSCCNF_ROM 0x00F70000 /* ROM param NI */
130 #define SSCCNF_CTLP 0x00008000 /* ctrl P enb */
131 #define SSCCNF_BAUD 0x00007700 /* baud rates NI */
132 #define SSCCNF_ADS 0x00000077 /* addr strb NI */
133 #define SSCCNF_W1C SSCCNF_BLO
134 #define SSCCNF_RW 0x0BF7F777
135
136 /* SSC timeout register */
137
138 #define SSCBTO_BTO 0x80000000 /* timeout W1C */
139 #define SSCBTO_RWT 0x40000000 /* read/write W1C */
140 #define SSCBTO_INTV 0x00FFFFFF /* interval NI */
141 #define SSCBTO_W1C (SSCBTO_BTO | SSCBTO_RWT)
142 #define SSCBTO_RW SSCBTO_INTV
143
144 /* SSC output port */
145
146 #define SSCOTP_MASK 0x0000000F /* output port */
147
148 /* SSC timer control/status */
149
150 #define TMR_CSR_ERR 0x80000000 /* error W1C */
151 #define TMR_CSR_DON 0x00000080 /* done W1C */
152 #define TMR_CSR_IE 0x00000040 /* int enb */
153 #define TMR_CSR_SGL 0x00000020 /* single WO */
154 #define TMR_CSR_XFR 0x00000010 /* xfer WO */
155 #define TMR_CSR_STP 0x00000004 /* stop */
156 #define TMR_CSR_RUN 0x00000001 /* run */
157 #define TMR_CSR_W1C (TMR_CSR_ERR | TMR_CSR_DON)
158 #define TMR_CSR_RW (TMR_CSR_IE | TMR_CSR_STP | TMR_CSR_RUN)
159
160 /* SSC timer intervals */
161
162 #define TMR_INC 10000 /* usec/interval */
163
164 /* SSC timer vector */
165
166 #define TMR_VEC_MASK 0x000003FC /* vector */
167
168 /* SSC address strobes */
169
170 #define SSCADS_MASK 0x3FFFFFFC /* match or mask */
171
172 extern int32 R[16];
173 extern int32 STK[5];
174 extern int32 PSL;
175 extern int32 SISR;
176 extern int32 mapen;
177 extern int32 pcq[PCQ_SIZE];
178 extern int32 pcq_p;
179 extern int32 ibcnt, ppc;
180 extern int32 in_ie;
181 extern int32 mchk_va, mchk_ref;
182 extern int32 fault_PC;
183 extern int32 int_req[IPL_HLVL];
184 extern UNIT cpu_unit;
185 extern UNIT clk_unit;
186 extern jmp_buf save_env;
187 extern int32 p1;
188 extern int32 sim_switches;
189 extern int32 MSER;
190 extern int32 tmr_poll;
191
192 uint32 *rom = NULL; /* boot ROM */
193 uint32 *nvr = NULL; /* non-volatile mem */
194 int32 CADR = 0; /* cache disable reg */
195 int32 MSER = 0; /* mem sys error reg */
196 int32 conpc, conpsl; /* console reg */
197 int32 csi_csr = 0; /* control/status */
198 int32 cso_csr = 0; /* control/status */
199 int32 cmctl_reg[CMCTLSIZE >> 2] = { 0 }; /* CMCTL reg */
200 int32 ka_cacr = 0; /* KA655 cache ctl */
201 int32 ka_bdr = BDR_BRKENB; /* KA655 boot diag */
202 int32 ssc_base = SSCBASE; /* SSC base */
203 int32 ssc_cnf = 0; /* SSC conf */
204 int32 ssc_bto = 0; /* SSC timeout */
205 int32 ssc_otp = 0; /* SSC output port */
206 int32 tmr_csr[2] = { 0 }; /* SSC timers */
207 uint32 tmr_tir[2] = { 0 }; /* curr interval */
208 uint32 tmr_tnir[2] = { 0 }; /* next interval */
209 int32 tmr_tivr[2] = { 0 }; /* vector */
210 uint32 tmr_inc[2] = { 0 }; /* tir increment */
211 uint32 tmr_sav[2] = { 0 }; /* saved inst cnt */
212 int32 ssc_adsm[2] = { 0 }; /* addr strobes */
213 int32 ssc_adsk[2] = { 0 };
214 int32 cdg_dat[CDASIZE >> 2]; /* cache data */
215 static uint32 rom_delay = 0;
216
217 t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
218 t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
219 t_stat rom_reset (DEVICE *dptr);
220 t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
221 t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
222 t_stat nvr_reset (DEVICE *dptr);
223 t_stat nvr_attach (UNIT *uptr, char *cptr);
224 t_stat nvr_detach (UNIT *uptr);
225 t_stat csi_reset (DEVICE *dptr);
226 t_stat cso_reset (DEVICE *dptr);
227 t_stat cso_svc (UNIT *uptr);
228 t_stat tmr_svc (UNIT *uptr);
229 t_stat sysd_reset (DEVICE *dptr);
230
231 int32 rom_rd (int32 pa);
232 int32 nvr_rd (int32 pa);
233 void nvr_wr (int32 pa, int32 val, int32 lnt);
234 int32 csrs_rd (void);
235 int32 csrd_rd (void);
236 int32 csts_rd (void);
237 void csrs_wr (int32 dat);
238 void csts_wr (int32 dat);
239 void cstd_wr (int32 dat);
240 int32 cmctl_rd (int32 pa);
241 void cmctl_wr (int32 pa, int32 val, int32 lnt);
242 int32 ka_rd (int32 pa);
243 void ka_wr (int32 pa, int32 val, int32 lnt);
244 int32 cdg_rd (int32 pa);
245 void cdg_wr (int32 pa, int32 val, int32 lnt);
246 int32 ssc_rd (int32 pa);
247 void ssc_wr (int32 pa, int32 val, int32 lnt);
248 int32 tmr_tir_rd (int32 tmr, t_bool interp);
249 void tmr_csr_wr (int32 tmr, int32 val);
250 void tmr_sched (int32 tmr);
251 void tmr_incr (int32 tmr, uint32 inc);
252 int32 tmr0_inta (void);
253 int32 tmr1_inta (void);
254 int32 parity (int32 val, int32 odd);
255 t_stat sysd_powerup (void);
256
257 extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
258 extern int32 cqmap_rd (int32 pa);
259 extern void cqmap_wr (int32 pa, int32 val, int32 lnt);
260 extern int32 cqipc_rd (int32 pa);
261 extern void cqipc_wr (int32 pa, int32 val, int32 lnt);
262 extern int32 cqbic_rd (int32 pa);
263 extern void cqbic_wr (int32 pa, int32 val, int32 lnt);
264 extern int32 cqmem_rd (int32 pa);
265 extern void cqmem_wr (int32 pa, int32 val, int32 lnt);
266 extern int32 iccs_rd (void);
267 extern int32 todr_rd (void);
268 extern int32 rxcs_rd (void);
269 extern int32 rxdb_rd (void);
270 extern int32 txcs_rd (void);
271 extern void iccs_wr (int32 dat);
272 extern void todr_wr (int32 dat);
273 extern void rxcs_wr (int32 dat);
274 extern void txcs_wr (int32 dat);
275 extern void txdb_wr (int32 dat);
276 extern void ioreset_wr (int32 dat);
277 extern uint32 sim_os_msec();
278
279 /* ROM data structures
280
281 rom_dev ROM device descriptor
282 rom_unit ROM units
283 rom_reg ROM register list
284 */
285
286 UNIT rom_unit = { UDATA (NULL, UNIT_FIX+UNIT_BINK, ROMSIZE) };
287
288 REG rom_reg[] = {
289 { NULL }
290 };
291
292 MTAB rom_mod[] = {
293 { UNIT_NODELAY, UNIT_NODELAY, "fast access", "NODELAY", NULL },
294 { UNIT_NODELAY, 0, "1usec calibrated access", "DELAY", NULL },
295 { 0 }
296 };
297
298 DEVICE rom_dev = {
299 "ROM", &rom_unit, rom_reg, rom_mod,
300 1, 16, ROMAWIDTH, 4, 16, 32,
301 &rom_ex, &rom_dep, &rom_reset,
302 NULL, NULL, NULL,
303 NULL, 0
304 };
305
306 /* NVR data structures
307
308 nvr_dev NVR device descriptor
309 nvr_unit NVR units
310 nvr_reg NVR register list
311 */
312
313 UNIT nvr_unit =
314 { UDATA (NULL, UNIT_FIX+UNIT_BINK, NVRSIZE) };
315
316 REG nvr_reg[] = {
317 { NULL }
318 };
319
320 DEVICE nvr_dev = {
321 "NVR", &nvr_unit, nvr_reg, NULL,
322 1, 16, NVRAWIDTH, 4, 16, 32,
323 &nvr_ex, &nvr_dep, &nvr_reset,
324 NULL, &nvr_attach, &nvr_detach,
325 NULL, 0
326 };
327
328 /* CSI data structures
329
330 csi_dev CSI device descriptor
331 csi_unit CSI unit descriptor
332 csi_reg CSI register list
333 */
334
335 DIB csi_dib = { 0, 0, NULL, NULL, 1, IVCL (CSI), SCB_CSI, { NULL } };
336
337 UNIT csi_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
338
339 REG csi_reg[] = {
340 { ORDATA (BUF, csi_unit.buf, 8) },
341 { ORDATA (CSR, csi_csr, 16) },
342 { FLDATA (INT, int_req[IPL_CSI], INT_V_CSI) },
343 { FLDATA (DONE, csi_csr, CSR_V_DONE) },
344 { FLDATA (IE, csi_csr, CSR_V_IE) },
345 { DRDATA (POS, csi_unit.pos, 32), PV_LEFT },
346 { DRDATA (TIME, csi_unit.wait, 24), REG_NZ + PV_LEFT },
347 { NULL }
348 };
349
350 MTAB csi_mod[] = {
351 { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
352 { 0 }
353 };
354
355 DEVICE csi_dev = {
356 "CSI", &csi_unit, csi_reg, csi_mod,
357 1, 10, 31, 1, 8, 8,
358 NULL, NULL, &csi_reset,
359 NULL, NULL, NULL,
360 &csi_dib, 0
361 };
362
363 /* CSO data structures
364
365 cso_dev CSO device descriptor
366 cso_unit CSO unit descriptor
367 cso_reg CSO register list
368 */
369
370 DIB cso_dib = { 0, 0, NULL, NULL, 1, IVCL (CSO), SCB_CSO, { NULL } };
371
372 UNIT cso_unit = { UDATA (&cso_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
373
374 REG cso_reg[] = {
375 { ORDATA (BUF, cso_unit.buf, 8) },
376 { ORDATA (CSR, cso_csr, 16) },
377 { FLDATA (INT, int_req[IPL_CSO], INT_V_CSO) },
378 { FLDATA (DONE, cso_csr, CSR_V_DONE) },
379 { FLDATA (IE, cso_csr, CSR_V_IE) },
380 { DRDATA (POS, cso_unit.pos, 32), PV_LEFT },
381 { DRDATA (TIME, cso_unit.wait, 24), PV_LEFT },
382 { NULL }
383 };
384
385 MTAB cso_mod[] = {
386 { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
387 { 0 }
388 };
389
390 DEVICE cso_dev = {
391 "CSO", &cso_unit, cso_reg, cso_mod,
392 1, 10, 31, 1, 8, 8,
393 NULL, NULL, &cso_reset,
394 NULL, NULL, NULL,
395 &cso_dib, 0
396 };
397
398 /* SYSD data structures
399
400 sysd_dev SYSD device descriptor
401 sysd_unit SYSD units
402 sysd_reg SYSD register list
403 */
404
405 DIB sysd_dib[] = {
406 0, 0, NULL, NULL,
407 2, IVCL (TMR0), 0, { &tmr0_inta, &tmr1_inta }
408 };
409
410 UNIT sysd_unit[] = {
411 { UDATA (&tmr_svc, 0, 0) },
412 { UDATA (&tmr_svc, 0, 0) }
413 };
414
415 REG sysd_reg[] = {
416 { HRDATA (CADR, CADR, 8) },
417 { HRDATA (MSER, MSER, 8) },
418 { HRDATA (CONPC, conpc, 32) },
419 { HRDATA (CONPSL, conpsl, 32) },
420 { BRDATA (CMCSR, cmctl_reg, 16, 32, CMCTLSIZE >> 2) },
421 { HRDATA (CACR, ka_cacr, 8) },
422 { HRDATA (BDR, ka_bdr, 8) },
423 { HRDATA (BASE, ssc_base, 29) },
424 { HRDATA (CNF, ssc_cnf, 32) },
425 { HRDATA (BTO, ssc_bto, 32) },
426 { HRDATA (OTP, ssc_otp, 4) },
427 { HRDATA (TCSR0, tmr_csr[0], 32) },
428 { HRDATA (TIR0, tmr_tir[0], 32) },
429 { HRDATA (TNIR0, tmr_tnir[0], 32) },
430 { HRDATA (TIVEC0, tmr_tivr[0], 9) },
431 { HRDATA (TINC0, tmr_inc[0], 32) },
432 { HRDATA (TSAV0, tmr_sav[0], 32) },
433 { HRDATA (TCSR1, tmr_csr[1], 32) },
434 { HRDATA (TIR1, tmr_tir[1], 32) },
435 { HRDATA (TNIR1, tmr_tnir[1], 32) },
436 { HRDATA (TIVEC1, tmr_tivr[1], 9) },
437 { HRDATA (TINC1, tmr_inc[1], 32) },
438 { HRDATA (TSAV1, tmr_sav[1], 32) },
439 { HRDATA (ADSM0, ssc_adsm[0], 32) },
440 { HRDATA (ADSK0, ssc_adsk[0], 32) },
441 { HRDATA (ADSM1, ssc_adsm[1], 32) },
442 { HRDATA (ADSK1, ssc_adsk[1], 32) },
443 { BRDATA (CDGDAT, cdg_dat, 16, 32, CDASIZE >> 2) },
444 { NULL }
445 };
446
447 DEVICE sysd_dev = {
448 "SYSD", sysd_unit, sysd_reg, NULL,
449 2, 16, 16, 1, 16, 8,
450 NULL, NULL, &sysd_reset,
451 NULL, NULL, NULL,
452 &sysd_dib, 0
453 };
454
455 /* ROM: read only memory - stored in a buffered file
456 Register space access routines see ROM twice
457
458 ROM access has been 'regulated' to about 1Mhz to avoid issues
459 with testing the interval timers in self-test. Specifically,
460 the VAX boot ROM (ka655.bin) contains code which presumes that
461 the VAX runs at a particular slower speed when code is running
462 from ROM (which is not cached). These assumptions are built
463 into instruction based timing loops. As the host platform gets
464 much faster than the original VAX, the assumptions embedded in
465 these code loops are no longer valid.
466
467 Code has been added to the ROM implementation to limit CPU speed
468 to about 500K instructions per second. This heads off any future
469 issues with the embedded timing loops.
470 */
471
472 int32 rom_swapb(int32 val)
473 {
474 return ((val << 24) & 0xff000000) | (( val << 8) & 0xff0000) |
475 ((val >> 8) & 0xff00) | ((val >> 24) & 0xff);
476 }
477
478 int32 rom_read_delay (int32 val)
479 {
480 uint32 i, l = rom_delay;
481 int32 loopval = 0;
482
483 if (rom_unit.flags & UNIT_NODELAY) return val;
484
485 /* Calibrate the loop delay factor when first used.
486 Do this 4 times to and use the largest value computed. */
487
488 if (rom_delay == 0) {
489 uint32 ts, te, c = 10000, samples = 0;
490 while (1) {
491 c = c * 2;
492 te = sim_os_msec();
493 while (te == (ts = sim_os_msec ())); /* align on ms tick */
494
495 /* This is merely a busy wait with some "work" that won't get optimized
496 away by a good compiler. loopval always is zero. To avoid smart compilers,
497 the loopval variable is referenced in the function arguments so that the
498 function expression is not loop invariant. It also must be referenced
499 by subsequent code or to avoid the whole computation being eliminated. */
500
501 for (i = 0; i < c; i++)
502 loopval |= (loopval + ts) ^ rom_swapb (rom_swapb (loopval + ts));
503 te = sim_os_msec ();
504 if ((te - ts) < 50) continue; /* sample big enough? */
505 if (rom_delay < (loopval + (c / (te - ts) / 1000) + 1))
506 rom_delay = loopval + (c / (te - ts) / 1000) + 1;
507 if (++samples >= 4) break;
508 c = c / 2;
509 }
510 if (rom_delay < 5) rom_delay = 5;
511 }
512
513 for (i = 0; i < l; i++)
514 loopval |= (loopval + val) ^ rom_swapb (rom_swapb (loopval + val));
515 return val + loopval;
516 }
517
518 int32 rom_rd (int32 pa)
519 {
520 int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
521
522 return rom_read_delay (rom[rg]);
523 }
524
525 void rom_wr_B (int32 pa, int32 val)
526 {
527 int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
528 int32 sc = (pa & 3) << 3;
529
530 rom[rg] = ((val & 0xFF) << sc) | (rom[rg] & ~(0xFF << sc));
531 return;
532 }
533
534 /* ROM examine */
535
536 t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
537 {
538 uint32 addr = (uint32) exta;
539
540 if ((vptr == NULL) || (addr & 03)) return SCPE_ARG;
541 if (addr >= ROMSIZE) return SCPE_NXM;
542 *vptr = rom[addr >> 2];
543 return SCPE_OK;
544 }
545
546 /* ROM deposit */
547
548 t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
549 {
550 uint32 addr = (uint32) exta;
551
552 if (addr & 03) return SCPE_ARG;
553 if (addr >= ROMSIZE) return SCPE_NXM;
554 rom[addr >> 2] = (uint32) val;
555 return SCPE_OK;
556 }
557
558 /* ROM reset */
559
560 t_stat rom_reset (DEVICE *dptr)
561 {
562 if (rom == NULL) rom = (uint32 *) calloc (ROMSIZE >> 2, sizeof (uint32));
563 if (rom == NULL) return SCPE_MEM;
564 return SCPE_OK;
565 }
566
567 /* NVR: non-volatile RAM - stored in a buffered file */
568
569 int32 nvr_rd (int32 pa)
570 {
571 int32 rg = (pa - NVRBASE) >> 2;
572
573 return nvr[rg];
574 }
575
576 void nvr_wr (int32 pa, int32 val, int32 lnt)
577 {
578 int32 rg = (pa - NVRBASE) >> 2;
579
580 if (lnt < L_LONG) { /* byte or word? */
581 int32 sc = (pa & 3) << 3; /* merge */
582 int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
583 nvr[rg] = ((val & mask) << sc) | (nvr[rg] & ~(mask << sc));
584 }
585 else nvr[rg] = val;
586 return;
587 }
588
589 /* NVR examine */
590
591 t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
592 {
593 uint32 addr = (uint32) exta;
594
595 if ((vptr == NULL) || (addr & 03)) return SCPE_ARG;
596 if (addr >= NVRSIZE) return SCPE_NXM;
597 *vptr = nvr[addr >> 2];
598 return SCPE_OK;
599 }
600
601 /* NVR deposit */
602
603 t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
604 {
605 uint32 addr = (uint32) exta;
606
607 if (addr & 03) return SCPE_ARG;
608 if (addr >= NVRSIZE) return SCPE_NXM;
609 nvr[addr >> 2] = (uint32) val;
610 return SCPE_OK;
611 }
612
613 /* NVR reset */
614
615 t_stat nvr_reset (DEVICE *dptr)
616 {
617 if (nvr == NULL) {
618 nvr = (uint32 *) calloc (NVRSIZE >> 2, sizeof (uint32));
619 nvr_unit.filebuf = nvr;
620 ssc_cnf = ssc_cnf | SSCCNF_BLO;
621 }
622 if (nvr == NULL) return SCPE_MEM;
623 return SCPE_OK;
624 }
625
626 /* NVR attach */
627
628 t_stat nvr_attach (UNIT *uptr, char *cptr)
629 {
630 t_stat r;
631
632 uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE);
633 r = attach_unit (uptr, cptr);
634 if (r != SCPE_OK)
635 uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
636 else {
637 uptr->hwmark = (uint32) uptr->capac;
638 ssc_cnf = ssc_cnf & ~SSCCNF_BLO;
639 }
640 return r;
641 }
642
643 /* NVR detach */
644
645 t_stat nvr_detach (UNIT *uptr)
646 {
647 t_stat r;
648
649 r = detach_unit (uptr);
650 if ((uptr->flags & UNIT_ATT) == 0)
651 uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
652 return r;
653 }
654
655 /* CSI: console storage input */
656
657 int32 csrs_rd (void)
658 {
659 return (csi_csr & CSICSR_IMP);
660 }
661
662 int32 csrd_rd (void)
663 {
664 csi_csr = csi_csr & ~CSR_DONE;
665 CLR_INT (CSI);
666 return (csi_unit.buf & 0377);
667 }
668
669 void csrs_wr (int32 data)
670 {
671 if ((data & CSR_IE) == 0) CLR_INT (CSI);
672 else if ((csi_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
673 SET_INT (CSI);
674 csi_csr = (csi_csr & ~CSICSR_RW) | (data & CSICSR_RW);
675 return;
676 }
677
678 t_stat csi_reset (DEVICE *dptr)
679 {
680 csi_unit.buf = 0;
681 csi_csr = 0;
682 CLR_INT (CSI);
683 return SCPE_OK;
684 }
685
686 /* CSO: console storage output */
687
688 int32 csts_rd (void)
689 {
690 return (cso_csr & CSOCSR_IMP);
691 }
692
693 void csts_wr (int32 data)
694 {
695 if ((data & CSR_IE) == 0) CLR_INT (CSO);
696 else if ((cso_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
697 SET_INT (CSO);
698 cso_csr = (cso_csr & ~CSOCSR_RW) | (data & CSOCSR_RW);
699 return;
700 }
701
702 void cstd_wr (int32 data)
703 {
704 cso_unit.buf = data & 0377;
705 cso_csr = cso_csr & ~CSR_DONE;
706 CLR_INT (CSO);
707 sim_activate (&cso_unit, cso_unit.wait);
708 return;
709 }
710
711 t_stat cso_svc (UNIT *uptr)
712 {
713 cso_csr = cso_csr | CSR_DONE;
714 if (cso_csr & CSR_IE) SET_INT (CSO);
715 if ((cso_unit.flags & UNIT_ATT) == 0) return SCPE_OK;
716 if (putc (cso_unit.buf, cso_unit.fileref) == EOF) {
717 perror ("CSO I/O error");
718 clearerr (cso_unit.fileref);
719 return SCPE_IOERR;
720 }
721 cso_unit.pos = cso_unit.pos + 1;
722 return SCPE_OK;
723 }
724
725 t_stat cso_reset (DEVICE *dptr)
726 {
727 cso_unit.buf = 0;
728 cso_csr = CSR_DONE;
729 CLR_INT (CSO);
730 sim_cancel (&cso_unit); /* deactivate unit */
731 return SCPE_OK;
732 }
733
734 /* SYSD: SSC access mechanisms and devices
735
736 - IPR space read/write routines
737 - register space read/write routines
738 - SSC local register read/write routines
739 - SSC console storage UART
740 - SSC timers
741 - CMCTL local register read/write routines
742 */
743
744 /* Read/write IPR register space
745
746 These routines implement the SSC's response to IPR's which are
747 sent off the CPU chip for processing.
748 */
749
750 int32 ReadIPR (int32 rg)
751 {
752 int32 val;
753
754 switch (rg) {
755
756 case MT_ICCS: /* ICCS */
757 val = iccs_rd ();
758 break;
759
760 case MT_CSRS: /* CSRS */
761 val = csrs_rd ();
762 break;
763
764 case MT_CSRD: /* CSRD */
765 val = csrd_rd ();
766 break;
767
768 case MT_CSTS: /* CSTS */
769 val = csts_rd ();
770 break;
771
772 case MT_CSTD: /* CSTD */
773 val = 0;
774 break;
775
776 case MT_RXCS: /* RXCS */
777 val = rxcs_rd ();
778 break;
779
780 case MT_RXDB: /* RXDB */
781 val = rxdb_rd ();
782 break;
783
784 case MT_TXCS: /* TXCS */
785 val = txcs_rd ();
786 break;
787
788 case MT_TXDB: /* TXDB */
789 val = 0;
790 break;
791
792 case MT_TODR: /* TODR */
793 val = todr_rd ();
794 break;
795
796 case MT_CADR: /* CADR */
797 val = CADR & 0xFF;
798 break;
799
800 case MT_MSER: /* MSER */
801 val = MSER & 0xFF;
802 break;
803
804 case MT_CONPC: /* console PC */
805 val = conpc;
806 break;
807
808 case MT_CONPSL: /* console PSL */
809 val = conpsl;
810 break;
811
812 case MT_SID: /* SID */
813 val = CVAX_SID | CVAX_UREV;
814 break;
815
816 default:
817 ssc_bto = ssc_bto | SSCBTO_BTO; /* set BTO */
818 val = 0;
819 break;
820 }
821
822 return val;
823 }
824
825 void WriteIPR (int32 rg, int32 val)
826 {
827 switch (rg) {
828
829 case MT_ICCS: /* ICCS */
830 iccs_wr (val);
831 break;
832
833 case MT_TODR: /* TODR */
834 todr_wr (val);
835 break;
836
837 case MT_CSRS: /* CSRS */
838 csrs_wr (val);
839 break;
840
841 case MT_CSRD: /* CSRD */
842 break;
843
844 case MT_CSTS: /* CSTS */
845 csts_wr (val);
846 break;
847
848 case MT_CSTD: /* CSTD */
849 cstd_wr (val);
850 break;
851
852 case MT_RXCS: /* RXCS */
853 rxcs_wr (val);
854 break;
855
856 case MT_RXDB: /* RXDB */
857 break;
858
859 case MT_TXCS: /* TXCS */
860 txcs_wr (val);
861 break;
862
863 case MT_TXDB: /* TXDB */
864 txdb_wr (val);
865 break;
866
867 case MT_CADR: /* CADR */
868 CADR = (val & CADR_RW) | CADR_MBO;
869 break;
870
871 case MT_MSER: /* MSER */
872 MSER = MSER & MSER_HM;
873 break;
874
875 case MT_IORESET: /* IORESET */
876 ioreset_wr (val);
877 break;
878
879 case MT_SID:
880 case MT_CONPC:
881 case MT_CONPSL: /* halt reg */
882 RSVD_OPND_FAULT;
883
884 default:
885 ssc_bto = ssc_bto | SSCBTO_BTO; /* set BTO */
886 break;
887 }
888
889 return;
890 }
891
892 /* Read/write I/O register space
893
894 These routines are the 'catch all' for address space map. Any
895 address that doesn't explicitly belong to memory, I/O, or ROM
896 is given to these routines for processing.
897 */
898
899 struct reglink { /* register linkage */
900 uint32 low; /* low addr */
901 uint32 high; /* high addr */
902 t_stat (*read)(int32 pa); /* read routine */
903 void (*write)(int32 pa, int32 val, int32 lnt); /* write routine */
904 };
905
906 struct reglink regtable[] = {
907 { CQMAPBASE, CQMAPBASE+CQMAPSIZE, &cqmap_rd, &cqmap_wr },
908 { ROMBASE, ROMBASE+ROMSIZE+ROMSIZE, &rom_rd, NULL },
909 { NVRBASE, NVRBASE+NVRSIZE, &nvr_rd, &nvr_wr },
910 { CMCTLBASE, CMCTLBASE+CMCTLSIZE, &cmctl_rd, &cmctl_wr },
911 { SSCBASE, SSCBASE+SSCSIZE, &ssc_rd, &ssc_wr },
912 { KABASE, KABASE+KASIZE, &ka_rd, &ka_wr },
913 { CQBICBASE, CQBICBASE+CQBICSIZE, &cqbic_rd, &cqbic_wr },
914 { CQIPCBASE, CQIPCBASE+CQIPCSIZE, &cqipc_rd, &cqipc_wr },
915 { CQMBASE, CQMBASE+CQMSIZE, &cqmem_rd, &cqmem_wr },
916 { CDGBASE, CDGBASE+CDGSIZE, &cdg_rd, &cdg_wr },
917 { 0, 0, NULL, NULL }
918 };
919
920 /* ReadReg - read register space
921
922 Inputs:
923 pa = physical address
924 lnt = length (BWLQ) - ignored
925 Output:
926 longword of data
927 */
928
929 int32 ReadReg (uint32 pa, int32 lnt)
930 {
931 struct reglink *p;
932
933 for (p = &regtable[0]; p->low != 0; p++) {
934 if ((pa >= p->low) && (pa < p->high) && p->read)
935 return p->read (pa);
936 }
937 ssc_bto = ssc_bto | SSCBTO_BTO | SSCBTO_RWT;
938 MACH_CHECK (MCHK_READ);
939 return 0;
940 }
941
942 /* WriteReg - write register space
943
944 Inputs:
945 pa = physical address
946 val = data to write, right justified in 32b longword
947 lnt = length (BWLQ)
948 Outputs:
949 none
950 */
951
952 void WriteReg (uint32 pa, int32 val, int32 lnt)
953 {
954 struct reglink *p;
955
956 for (p = &regtable[0]; p->low != 0; p++) {
957 if ((pa >= p->low) && (pa < p->high) && p->write) {
958 p->write (pa, val, lnt);
959 return;
960 }
961 }
962 ssc_bto = ssc_bto | SSCBTO_BTO | SSCBTO_RWT;
963 MACH_CHECK (MCHK_WRITE);
964 return;
965 }
966
967 /* CMCTL registers
968
969 CMCTL00 - 15 configure memory banks 00 - 15. Note that they are
970 here merely to entertain the firmware; the actual configuration
971 of memory is unaffected by the settings here.
972
973 CMCTL16 - error status register
974
975 CMCTL17 - control/diagnostic status register
976
977 The CMCTL registers are cleared at power up.
978 */
979
980 int32 cmctl_rd (int32 pa)
981 {
982 int32 rg = (pa - CMCTLBASE) >> 2;
983
984 switch (rg) {
985
986 default: /* config reg */
987 return cmctl_reg[rg] & CMCNF_MASK;
988
989 case 16: /* err status */
990 return cmctl_reg[rg];
991
992 case 17: /* csr */
993 return cmctl_reg[rg] & CMCSR_MASK;
994
995 case 18: /* KA655X ext mem */
996 if (MEMSIZE > MAXMEMSIZE) /* more than 128MB? */
997 return ((int32) MEMSIZE);
998 MACH_CHECK (MCHK_READ);
999 }
1000
1001 return 0;
1002 }
1003
1004 void cmctl_wr (int32 pa, int32 val, int32 lnt)
1005 {
1006 int32 i, rg = (pa - CMCTLBASE) >> 2;
1007
1008 if (lnt < L_LONG) { /* LW write only */
1009 int32 sc = (pa & 3) << 3; /* shift data to */
1010 val = val << sc; /* proper location */
1011 }
1012 switch (rg) {
1013
1014 default: /* config reg */
1015 if (val & CMCNF_SRQ) { /* sig request? */
1016 int32 rg_g = rg & ~3; /* group of 4 */
1017 for (i = rg_g; i < (rg_g + 4); i++) {
1018 cmctl_reg[i] = cmctl_reg[i] & ~CMCNF_SIG;
1019 if (ADDR_IS_MEM (i * MEM_BANK))
1020 cmctl_reg[i] = cmctl_reg[i] | MEM_SIG;
1021 }
1022 }
1023 cmctl_reg[rg] = (cmctl_reg[rg] & ~CMCNF_RW) | (val & CMCNF_RW);
1024 break;
1025
1026 case 16: /* err status */
1027 cmctl_reg[rg] = cmctl_reg[rg] & ~(val & CMERR_W1C);
1028 break;
1029
1030 case 17: /* csr */
1031 cmctl_reg[rg] = val & CMCSR_MASK;
1032 break;
1033
1034 case 18:
1035 MACH_CHECK (MCHK_WRITE);
1036 }
1037
1038 return;
1039 }
1040
1041 /* KA655 registers */
1042
1043 int32 ka_rd (int32 pa)
1044 {
1045 int32 rg = (pa - KABASE) >> 2;
1046
1047 switch (rg) {
1048
1049 case 0: /* CACR */
1050 return ka_cacr;
1051
1052 case 1: /* BDR */
1053 return ka_bdr;
1054 }
1055
1056 return 0;
1057 }
1058
1059 void ka_wr (int32 pa, int32 val, int32 lnt)
1060 {
1061 int32 rg = (pa - KABASE) >> 2;
1062
1063 if ((rg == 0) && ((pa & 3) == 0)) { /* lo byte only */
1064 ka_cacr = (ka_cacr & ~(val & CACR_W1C)) | CACR_FIXED;
1065 ka_cacr = (ka_cacr & ~CACR_RW) | (val & CACR_RW);
1066 }
1067 return;
1068 }
1069
1070 int32 sysd_hlt_enb (void)
1071 {
1072 return ka_bdr & BDR_BRKENB;
1073 }
1074
1075 /* Cache diagnostic space */
1076
1077 int32 cdg_rd (int32 pa)
1078 {
1079 int32 t, row = CDG_GETROW (pa);
1080
1081 t = cdg_dat[row];
1082 ka_cacr = ka_cacr & ~CACR_DRO; /* clear diag */
1083 ka_cacr = ka_cacr |
1084 (parity ((t >> 24) & 0xFF, 1) << (CACR_V_DPAR + 3)) |
1085 (parity ((t >> 16) & 0xFF, 0) << (CACR_V_DPAR + 2)) |
1086 (parity ((t >> 8) & 0xFF, 1) << (CACR_V_DPAR + 1)) |
1087 (parity (t & 0xFF, 0) << CACR_V_DPAR);
1088 return t;
1089 }
1090
1091 void cdg_wr (int32 pa, int32 val, int32 lnt)
1092 {
1093 int32 row = CDG_GETROW (pa);
1094
1095 if (lnt < L_LONG) { /* byte or word? */
1096 int32 sc = (pa & 3) << 3; /* merge */
1097 int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
1098 int32 t = cdg_dat[row];
1099 val = ((val & mask) << sc) | (t & ~(mask << sc));
1100 }
1101 cdg_dat[row] = val; /* store data */
1102 return;
1103 }
1104
1105 int32 parity (int32 val, int32 odd)
1106 {
1107 for ( ; val != 0; val = val >> 1) {
1108 if (val & 1) odd = odd ^ 1;
1109 }
1110 return odd;
1111 }
1112
1113 /* SSC registers - byte/word merges done in WriteReg */
1114
1115 int32 ssc_rd (int32 pa)
1116 {
1117 int32 rg = (pa - SSCBASE) >> 2;
1118
1119 switch (rg) {
1120
1121 case 0x00: /* base reg */
1122 return ssc_base;
1123
1124 case 0x04: /* conf reg */
1125 return ssc_cnf;
1126
1127 case 0x08: /* bus timeout */
1128 return ssc_bto;
1129
1130 case 0x0C: /* output port */
1131 return ssc_otp & SSCOTP_MASK;
1132
1133 case 0x1B: /* TODR */
1134 return todr_rd ();
1135
1136 case 0x1C: /* CSRS */
1137 return csrs_rd ();
1138
1139 case 0x1D: /* CSRD */
1140 return csrd_rd ();
1141
1142 case 0x1E: /* CSTS */
1143 return csts_rd ();
1144
1145 case 0x20: /* RXCS */
1146 return rxcs_rd ();
1147
1148 case 0x21: /* RXDB */
1149 return rxdb_rd ();
1150
1151 case 0x22: /* TXCS */
1152 return txcs_rd ();
1153
1154 case 0x40: /* T0CSR */
1155 return tmr_csr[0];
1156
1157 case 0x41: /* T0INT */
1158 return tmr_tir_rd (0, FALSE);
1159
1160 case 0x42: /* T0NI */
1161 return tmr_tnir[0];
1162
1163 case 0x43: /* T0VEC */
1164 return tmr_tivr[0];
1165
1166 case 0x44: /* T1CSR */
1167 return tmr_csr[1];
1168
1169 case 0x45: /* T1INT */
1170 return tmr_tir_rd (1, FALSE);
1171
1172 case 0x46: /* T1NI */
1173 return tmr_tnir[1];
1174
1175 case 0x47: /* T1VEC */
1176 return tmr_tivr[1];
1177
1178 case 0x4C: /* ADS0M */
1179 return ssc_adsm[0];
1180
1181 case 0x4D: /* ADS0K */
1182 return ssc_adsk[0];
1183
1184 case 0x50: /* ADS1M */
1185 return ssc_adsm[1];
1186
1187 case 0x51: /* ADS1K */
1188 return ssc_adsk[1];
1189 }
1190
1191 return 0;
1192 }
1193
1194 void ssc_wr (int32 pa, int32 val, int32 lnt)
1195 {
1196 int32 rg = (pa - SSCBASE) >> 2;
1197
1198 if (lnt < L_LONG) { /* byte or word? */
1199 int32 sc = (pa & 3) << 3; /* merge */
1200 int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
1201 int32 t = ssc_rd (pa);
1202 val = ((val & mask) << sc) | (t & ~(mask << sc));
1203 }
1204
1205 switch (rg) {
1206
1207 case 0x00: /* base reg */
1208 ssc_base = (val & SSCBASE_RW) | SSCBASE_MBO;
1209 break;
1210
1211 case 0x04: /* conf reg */
1212 ssc_cnf = ssc_cnf & ~(val & SSCCNF_W1C);
1213 ssc_cnf = (ssc_cnf & ~SSCCNF_RW) | (val & SSCCNF_RW);
1214 break;
1215
1216 case 0x08: /* bus timeout */
1217 ssc_bto = ssc_bto & ~(val & SSCBTO_W1C);
1218 ssc_bto = (ssc_bto & ~SSCBTO_RW) | (val & SSCBTO_RW);
1219 break;
1220
1221 case 0x0C: /* output port */
1222 ssc_otp = val & SSCOTP_MASK;
1223 break;
1224
1225 case 0x1B: /* TODR */
1226 todr_wr (val);
1227 break;
1228
1229 case 0x1C: /* CSRS */
1230 csrs_wr (val);
1231 break;
1232
1233 case 0x1E: /* CSTS */
1234 csts_wr (val);
1235 break;
1236
1237 case 0x1F: /* CSTD */
1238 cstd_wr (val);
1239 break;
1240
1241 case 0x20: /* RXCS */
1242 rxcs_wr (val);
1243 break;
1244
1245 case 0x22: /* TXCS */
1246 txcs_wr (val);
1247 break;
1248
1249 case 0x23: /* TXDB */
1250 txdb_wr (val);
1251 break;
1252
1253 case 0x40: /* T0CSR */
1254 tmr_csr_wr (0, val);
1255 break;
1256
1257 case 0x42: /* T0NI */
1258 tmr_tnir[0] = val;
1259 break;
1260
1261 case 0x43: /* T0VEC */
1262 tmr_tivr[0] = val & TMR_VEC_MASK;
1263 break;
1264
1265 case 0x44: /* T1CSR */
1266 tmr_csr_wr (1, val);
1267 break;
1268
1269 case 0x46: /* T1NI */
1270 tmr_tnir[1] = val;
1271 break;
1272
1273 case 0x47: /* T1VEC */
1274 tmr_tivr[1] = val & TMR_VEC_MASK;
1275 break;
1276
1277 case 0x4C: /* ADS0M */
1278 ssc_adsm[0] = val & SSCADS_MASK;
1279 break;
1280
1281 case 0x4D: /* ADS0K */
1282 ssc_adsk[0] = val & SSCADS_MASK;
1283 break;
1284
1285 case 0x50: /* ADS1M */
1286 ssc_adsm[1] = val & SSCADS_MASK;
1287 break;
1288
1289 case 0x51: /* ADS1K */
1290 ssc_adsk[1] = val & SSCADS_MASK;
1291 break;
1292 }
1293
1294 return;
1295 }
1296
1297 /* Programmable timers
1298
1299 The SSC timers, which increment at 1Mhz, cannot be accurately
1300 simulated due to the overhead that would be required for 1M
1301 clock events per second. Instead, a gross hack is used. When
1302 a timer is started, the clock interval is inspected.
1303
1304 if (int < 0 and small) then testing timer, count instructions.
1305 Small is determined by when the requested interval is less
1306 than the size of a 100hz system clock tick.
1307 if (int >= 0 or large) then counting a real interval, schedule
1308 clock events at 100Hz using calibrated line clock delay
1309 and when the remaining time value gets small enough, behave
1310 like the small case above.
1311
1312 If the interval register is read, then its value between events
1313 is interpolated using the current instruction count versus the
1314 count when the most recent event started, the result is scaled
1315 to the calibrated system clock, unless the interval being timed
1316 is less than a calibrated system clock tick (or the calibrated
1317 clock is running very slowly) at which time the result will be
1318 the elapsed instruction count.
1319
1320 The powerup TOY Test sometimes fails its tolerance test. This was
1321 due to varying system load causing varying calibration values to be
1322 used at different times while referencing the TIR. While timing long
1323 intervals, we now synchronize the stepping (and calibration) of the
1324 system tick with the opportunity to reference the value. This gives
1325 precise tolerance measurement values (when interval timers are used
1326 to measure the system clock), regardless of other load issues on the
1327 host system which might cause varying values of the system clock's
1328 calibration factor.
1329 */
1330
1331 int32 tmr_tir_rd (int32 tmr, t_bool interp)
1332 {
1333 uint32 delta;
1334
1335 if (interp || (tmr_csr[tmr] & TMR_CSR_RUN)) { /* interp, running? */
1336 delta = sim_grtime () - tmr_sav[tmr]; /* delta inst */
1337 if ((tmr_inc[tmr] == TMR_INC) && /* scale large int */
1338 (tmr_poll > TMR_INC))
1339 delta = (uint32) ((((double) delta) * TMR_INC) / tmr_poll);
1340 if (delta >= tmr_inc[tmr]) delta = tmr_inc[tmr] - 1;
1341 return tmr_tir[tmr] + delta;
1342 }
1343 return tmr_tir[tmr];
1344 }
1345
1346 void tmr_csr_wr (int32 tmr, int32 val)
1347 {
1348 if ((tmr < 0) || (tmr > 1)) return;
1349 if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */
1350 sim_cancel (&sysd_unit[tmr]); /* cancel timer */
1351 if (tmr_csr[tmr] & TMR_CSR_RUN) /* run 1 -> 0? */
1352 tmr_tir[tmr] = tmr_tir_rd (tmr, TRUE); /* update itr */
1353 }
1354 tmr_csr[tmr] = tmr_csr[tmr] & ~(val & TMR_CSR_W1C); /* W1C csr */
1355 tmr_csr[tmr] = (tmr_csr[tmr] & ~TMR_CSR_RW) | /* new r/w */
1356 (val & TMR_CSR_RW);
1357 if (val & TMR_CSR_XFR) tmr_tir[tmr] = tmr_tnir[tmr]; /* xfr set? */
1358 if (val & TMR_CSR_RUN) { /* run? */
1359 if (val & TMR_CSR_XFR) /* new tir? */
1360 sim_cancel (&sysd_unit[tmr]); /* stop prev */
1361 if (!sim_is_active (&sysd_unit[tmr])) /* not running? */
1362 tmr_sched (tmr); /* activate */
1363 }
1364 else if (val & TMR_CSR_SGL) { /* single step? */
1365 tmr_incr (tmr, 1); /* incr tmr */
1366 if (tmr_tir[tmr] == 0) /* if ovflo, */
1367 tmr_tir[tmr] = tmr_tnir[tmr]; /* reload tir */
1368 }
1369 if ((tmr_csr[tmr] & (TMR_CSR_DON | TMR_CSR_IE)) != /* update int */
1370 (TMR_CSR_DON | TMR_CSR_IE)) {
1371 if (tmr) CLR_INT (TMR1);
1372 else CLR_INT (TMR0);
1373 }
1374 return;
1375 }
1376
1377 /* Unit service */
1378
1379 t_stat tmr_svc (UNIT *uptr)
1380 {
1381 int32 tmr = uptr - sysd_dev.units; /* get timer # */
1382
1383 tmr_incr (tmr, tmr_inc[tmr]); /* incr timer */
1384 return SCPE_OK;
1385 }
1386
1387 /* Timer increment */
1388
1389 void tmr_incr (int32 tmr, uint32 inc)
1390 {
1391 uint32 new_tir = tmr_tir[tmr] + inc; /* add incr */
1392
1393 if (new_tir < tmr_tir[tmr]) { /* ovflo? */
1394 tmr_tir[tmr] = 0; /* now 0 */
1395 if (tmr_csr[tmr] & TMR_CSR_DON) /* done? set err */
1396 tmr_csr[tmr] = tmr_csr[tmr] | TMR_CSR_ERR;
1397 else tmr_csr[tmr] = tmr_csr[tmr] | TMR_CSR_DON; /* set done */
1398 if (tmr_csr[tmr] & TMR_CSR_STP) /* stop? */
1399 tmr_csr[tmr] = tmr_csr[tmr] & ~TMR_CSR_RUN; /* clr run */
1400 if (tmr_csr[tmr] & TMR_CSR_RUN) { /* run? */
1401 tmr_tir[tmr] = tmr_tnir[tmr]; /* reload */
1402 tmr_sched (tmr); /* reactivate */
1403 }
1404 if (tmr_csr[tmr] & TMR_CSR_IE) { /* set int req */
1405 if (tmr) SET_INT (TMR1);
1406 else SET_INT (TMR0);
1407 }
1408 }
1409 else {
1410 tmr_tir[tmr] = new_tir; /* no, upd tir */
1411 if (tmr_csr[tmr] & TMR_CSR_RUN) /* still running? */
1412 tmr_sched (tmr); /* reactivate */
1413 }
1414 return;
1415 }
1416
1417 /* Timer scheduling */
1418
1419 void tmr_sched (int32 tmr)
1420 {
1421 int32 clk_time = sim_is_active (&clk_unit) - 1;
1422 int32 tmr_time;
1423
1424 tmr_sav[tmr] = sim_grtime (); /* save intvl base */
1425 if (tmr_tir[tmr] > (0xFFFFFFFFu - TMR_INC)) { /* short interval? */
1426 tmr_inc[tmr] = (~tmr_tir[tmr] + 1); /* inc = interval */
1427 tmr_time = tmr_inc[tmr];
1428 }
1429 else {
1430 tmr_inc[tmr] = TMR_INC; /* usec/interval */
1431 tmr_time = tmr_poll;
1432 }
1433 if (tmr_time == 0) tmr_time = 1;
1434 if ((tmr_inc[tmr] == TMR_INC) && (tmr_time > clk_time)) {
1435
1436 /* Align scheduled event to be identical to the event for the next clock
1437 tick. This lets us always see a consistent calibrated value, both for
1438 this scheduling, AND for any query of the current timer register that
1439 may happen in tmr_tir_rd (). This presumes that sim_activate will
1440 queue the interval timer behind the event for the clock tick. */
1441
1442 tmr_inc[tmr] = (uint32) (((double) clk_time * TMR_INC) / tmr_poll);
1443 tmr_time = clk_time;
1444 }
1445 sim_activate (&sysd_unit[tmr], tmr_time);
1446 return;
1447 }
1448
1449 int32 tmr0_inta (void)
1450 {
1451 return tmr_tivr[0];
1452 }
1453
1454 int32 tmr1_inta (void)
1455 {
1456 return tmr_tivr[1];
1457 }
1458
1459 /* Machine check */
1460
1461 int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta)
1462 {
1463 int32 i, st1, st2, p2, hsir, acc;
1464
1465 if (p1 & 0x80) p1 = p1 + mchk_ref; /* mref? set v/p */
1466 p2 = mchk_va + 4; /* save vap */
1467 for (i = hsir = 0; i < 16; i++) { /* find hsir */
1468 if ((SISR >> i) & 1) hsir = i;
1469 }
1470 st1 = ((((uint32) opc) & 0xFF) << 24) |
1471 (hsir << 16) |
1472 ((CADR & 0xFF) << 8) |
1473 (MSER & 0xFF);
1474 st2 = 0x00C07000 + (delta & 0xFF);
1475 cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take exception */
1476 acc = ACC_MASK (KERN); /* in kernel mode */
1477 in_ie = 1;
1478 SP = SP - 20; /* push 5 words */
1479 Write (SP, 16, L_LONG, WA); /* # bytes */
1480 Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
1481 Write (SP + 8, p2, L_LONG, WA); /* address */
1482 Write (SP + 12, st1, L_LONG, WA); /* state 1 */
1483 Write (SP + 16, st2, L_LONG, WA); /* state 2 */
1484 in_ie = 0;
1485 return cc;
1486 }
1487
1488 /* Console entry */
1489
1490 int32 con_halt (int32 code, int32 cc)
1491 {
1492 int32 temp;
1493
1494 conpc = PC; /* save PC */
1495 conpsl = ((PSL | cc) & 0xFFFF00FF) | CON_HLTINS; /* PSL, param */
1496 temp = (PSL >> PSL_V_CUR) & 0x7; /* get is'cur */
1497 if (temp > 4) conpsl = conpsl | CON_BADPSL; /* invalid? */
1498 else STK[temp] = SP; /* save stack */
1499 if (mapen) conpsl = conpsl | CON_MAPON; /* mapping on? */
1500 mapen = 0; /* turn off map */
1501 SP = IS; /* set SP from IS */
1502 PSL = PSL_IS | PSL_IPL1F; /* PSL = 41F0000 */
1503 JUMP (ROMBASE); /* PC = 20040000 */
1504 return 0; /* new cc = 0 */
1505 }
1506
1507 /* Bootstrap */
1508
1509 t_stat cpu_boot (int32 unitno, DEVICE *dptr)
1510 {
1511 extern t_stat load_cmd (int32 flag, char *cptr);
1512 extern FILE *sim_log;
1513 t_stat r;
1514
1515 PC = ROMBASE;
1516 PSL = PSL_IS | PSL_IPL1F;
1517 conpc = 0;
1518 conpsl = PSL_IS | PSL_IPL1F | CON_PWRUP;
1519 if (rom == NULL) return SCPE_IERR;
1520 if (*rom == 0) { /* no boot? */
1521 printf ("Loading boot code from ka655x.bin\n");
1522 if (sim_log) fprintf (sim_log,
1523 "Loading boot code from ka655x.bin\n");
1524 r = load_cmd (0, "-R ka655x.bin");
1525 if (r != SCPE_OK) return r;
1526 }
1527 return SCPE_OK;
1528 }
1529
1530 /* SYSD reset */
1531
1532 t_stat sysd_reset (DEVICE *dptr)
1533 {
1534 int32 i;
1535
1536 if (sim_switches & SWMASK ('P')) sysd_powerup (); /* powerup? */
1537 for (i = 0; i < 2; i++) {
1538 tmr_csr[i] = tmr_tnir[i] = tmr_tir[i] = 0;
1539 tmr_inc[i] = tmr_sav[i] = 0;
1540 sim_cancel (&sysd_unit[i]);
1541 }
1542 csi_csr = 0;
1543 csi_unit.buf = 0;
1544 sim_cancel (&csi_unit);
1545 CLR_INT (CSI);
1546 cso_csr = CSR_DONE;
1547 cso_unit.buf = 0;
1548 sim_cancel (&cso_unit);
1549 CLR_INT (CSO);
1550 return SCPE_OK;
1551 }
1552
1553 /* SYSD powerup */
1554
1555 t_stat sysd_powerup (void)
1556 {
1557 int32 i;
1558
1559 for (i = 0; i < (CMCTLSIZE >> 2); i++) cmctl_reg[i] = 0;
1560 for (i = 0; i < 2; i++) {
1561 tmr_tivr[i] = 0;
1562 ssc_adsm[i] = ssc_adsk[i] = 0;
1563 }
1564 ka_cacr = 0;
1565 ssc_base = SSCBASE;
1566 ssc_cnf = ssc_cnf & SSCCNF_BLO;
1567 ssc_bto = 0;
1568 ssc_otp = 0;
1569 return SCPE_OK;
1570 }