1 /* vax_sysdev.c: VAX 3900 system-specific logic
3 Copyright (c) 1998-2005, Robert M Supnik
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:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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.
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.
26 This module contains the CVAX chip and VAX 3900 system-specific registers
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)
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)
56 #define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */
57 #define UNIT_NODELAY (1u << UNIT_V_NODELAY)
59 /* Console storage control/status */
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)
66 /* CMCTL configuration registers */
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 */
78 /* CMCTL error register */
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)
90 /* CMCTL control/status register */
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)
102 /* KA655 boot/diagnostic register */
104 #define BDR_BRKENB 0x00000080 /* break enable */
106 /* KA655 cache control register */
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)
119 /* SSC base register */
121 #define SSCBASE_MBO 0x20000000 /* must be one */
122 #define SSCBASE_RW 0x1FFFFC00 /* base address */
124 /* SSC configuration register */
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
136 /* SSC timeout register */
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
144 /* SSC output port */
146 #define SSCOTP_MASK 0x0000000F /* output port */
148 /* SSC timer control/status */
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)
160 /* SSC timer intervals */
162 #define TMR_INC 10000 /* usec/interval */
164 /* SSC timer vector */
166 #define TMR_VEC_MASK 0x000003FC /* vector */
168 /* SSC address strobes */
170 #define SSCADS_MASK 0x3FFFFFFC /* match or mask */
177 extern int32 pcq
[PCQ_SIZE
];
179 extern int32 ibcnt
, ppc
;
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
;
188 extern int32 sim_switches
;
190 extern int32 tmr_poll
;
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;
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
);
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);
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();
279 /* ROM data structures
281 rom_dev ROM device descriptor
283 rom_reg ROM register list
286 UNIT rom_unit
= { UDATA (NULL
, UNIT_FIX
+UNIT_BINK
, ROMSIZE
) };
293 { UNIT_NODELAY
, UNIT_NODELAY
, "fast access", "NODELAY", NULL
},
294 { UNIT_NODELAY
, 0, "1usec calibrated access", "DELAY", NULL
},
299 "ROM", &rom_unit
, rom_reg
, rom_mod
,
300 1, 16, ROMAWIDTH
, 4, 16, 32,
301 &rom_ex
, &rom_dep
, &rom_reset
,
306 /* NVR data structures
308 nvr_dev NVR device descriptor
310 nvr_reg NVR register list
314 { UDATA (NULL
, UNIT_FIX
+UNIT_BINK
, NVRSIZE
) };
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
,
328 /* CSI data structures
330 csi_dev CSI device descriptor
331 csi_unit CSI unit descriptor
332 csi_reg CSI register list
335 DIB csi_dib
= { 0, 0, NULL
, NULL
, 1, IVCL (CSI
), SCB_CSI
, { NULL
} };
337 UNIT csi_unit
= { UDATA (NULL
, 0, 0), KBD_POLL_WAIT
};
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
},
351 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
, NULL
, &show_vec
},
356 "CSI", &csi_unit
, csi_reg
, csi_mod
,
358 NULL
, NULL
, &csi_reset
,
363 /* CSO data structures
365 cso_dev CSO device descriptor
366 cso_unit CSO unit descriptor
367 cso_reg CSO register list
370 DIB cso_dib
= { 0, 0, NULL
, NULL
, 1, IVCL (CSO
), SCB_CSO
, { NULL
} };
372 UNIT cso_unit
= { UDATA (&cso_svc
, UNIT_SEQ
+UNIT_ATTABLE
, 0), SERIAL_OUT_WAIT
};
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
},
386 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
, NULL
, &show_vec
},
391 "CSO", &cso_unit
, cso_reg
, cso_mod
,
393 NULL
, NULL
, &cso_reset
,
398 /* SYSD data structures
400 sysd_dev SYSD device descriptor
402 sysd_reg SYSD register list
407 2, IVCL (TMR0
), 0, { &tmr0_inta
, &tmr1_inta
}
411 { UDATA (&tmr_svc
, 0, 0) },
412 { UDATA (&tmr_svc
, 0, 0) }
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) },
448 "SYSD", sysd_unit
, sysd_reg
, NULL
,
450 NULL
, NULL
, &sysd_reset
,
455 /* ROM: read only memory - stored in a buffered file
456 Register space access routines see ROM twice
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.
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.
472 int32
rom_swapb(int32 val
)
474 return ((val
<< 24) & 0xff000000) | (( val
<< 8) & 0xff0000) |
475 ((val
>> 8) & 0xff00) | ((val
>> 24) & 0xff);
478 int32
rom_read_delay (int32 val
)
480 uint32 i
, l
= rom_delay
;
483 if (rom_unit
.flags
& UNIT_NODELAY
) return val
;
485 /* Calibrate the loop delay factor when first used.
486 Do this 4 times to and use the largest value computed. */
488 if (rom_delay
== 0) {
489 uint32 ts
, te
, c
= 10000, samples
= 0;
493 while (te
== (ts
= sim_os_msec ())); /* align on ms tick */
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. */
501 for (i
= 0; i
< c
; i
++)
502 loopval
|= (loopval
+ ts
) ^ rom_swapb (rom_swapb (loopval
+ ts
));
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;
510 if (rom_delay
< 5) rom_delay
= 5;
513 for (i
= 0; i
< l
; i
++)
514 loopval
|= (loopval
+ val
) ^ rom_swapb (rom_swapb (loopval
+ val
));
515 return val
+ loopval
;
518 int32
rom_rd (int32 pa
)
520 int32 rg
= ((pa
- ROMBASE
) & ROMAMASK
) >> 2;
522 return rom_read_delay (rom
[rg
]);
525 void rom_wr_B (int32 pa
, int32 val
)
527 int32 rg
= ((pa
- ROMBASE
) & ROMAMASK
) >> 2;
528 int32 sc
= (pa
& 3) << 3;
530 rom
[rg
] = ((val
& 0xFF) << sc
) | (rom
[rg
] & ~(0xFF << sc
));
536 t_stat
rom_ex (t_value
*vptr
, t_addr exta
, UNIT
*uptr
, int32 sw
)
538 uint32 addr
= (uint32
) exta
;
540 if ((vptr
== NULL
) || (addr
& 03)) return SCPE_ARG
;
541 if (addr
>= ROMSIZE
) return SCPE_NXM
;
542 *vptr
= rom
[addr
>> 2];
548 t_stat
rom_dep (t_value val
, t_addr exta
, UNIT
*uptr
, int32 sw
)
550 uint32 addr
= (uint32
) exta
;
552 if (addr
& 03) return SCPE_ARG
;
553 if (addr
>= ROMSIZE
) return SCPE_NXM
;
554 rom
[addr
>> 2] = (uint32
) val
;
560 t_stat
rom_reset (DEVICE
*dptr
)
562 if (rom
== NULL
) rom
= (uint32
*) calloc (ROMSIZE
>> 2, sizeof (uint32
));
563 if (rom
== NULL
) return SCPE_MEM
;
567 /* NVR: non-volatile RAM - stored in a buffered file */
569 int32
nvr_rd (int32 pa
)
571 int32 rg
= (pa
- NVRBASE
) >> 2;
576 void nvr_wr (int32 pa
, int32 val
, int32 lnt
)
578 int32 rg
= (pa
- NVRBASE
) >> 2;
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
));
591 t_stat
nvr_ex (t_value
*vptr
, t_addr exta
, UNIT
*uptr
, int32 sw
)
593 uint32 addr
= (uint32
) exta
;
595 if ((vptr
== NULL
) || (addr
& 03)) return SCPE_ARG
;
596 if (addr
>= NVRSIZE
) return SCPE_NXM
;
597 *vptr
= nvr
[addr
>> 2];
603 t_stat
nvr_dep (t_value val
, t_addr exta
, UNIT
*uptr
, int32 sw
)
605 uint32 addr
= (uint32
) exta
;
607 if (addr
& 03) return SCPE_ARG
;
608 if (addr
>= NVRSIZE
) return SCPE_NXM
;
609 nvr
[addr
>> 2] = (uint32
) val
;
615 t_stat
nvr_reset (DEVICE
*dptr
)
618 nvr
= (uint32
*) calloc (NVRSIZE
>> 2, sizeof (uint32
));
619 nvr_unit
.filebuf
= nvr
;
620 ssc_cnf
= ssc_cnf
| SSCCNF_BLO
;
622 if (nvr
== NULL
) return SCPE_MEM
;
628 t_stat
nvr_attach (UNIT
*uptr
, char *cptr
)
632 uptr
->flags
= uptr
->flags
| (UNIT_ATTABLE
| UNIT_BUFABLE
);
633 r
= attach_unit (uptr
, cptr
);
635 uptr
->flags
= uptr
->flags
& ~(UNIT_ATTABLE
| UNIT_BUFABLE
);
637 uptr
->hwmark
= (uint32
) uptr
->capac
;
638 ssc_cnf
= ssc_cnf
& ~SSCCNF_BLO
;
645 t_stat
nvr_detach (UNIT
*uptr
)
649 r
= detach_unit (uptr
);
650 if ((uptr
->flags
& UNIT_ATT
) == 0)
651 uptr
->flags
= uptr
->flags
& ~(UNIT_ATTABLE
| UNIT_BUFABLE
);
655 /* CSI: console storage input */
659 return (csi_csr
& CSICSR_IMP
);
664 csi_csr
= csi_csr
& ~CSR_DONE
;
666 return (csi_unit
.buf
& 0377);
669 void csrs_wr (int32 data
)
671 if ((data
& CSR_IE
) == 0) CLR_INT (CSI
);
672 else if ((csi_csr
& (CSR_DONE
+ CSR_IE
)) == CSR_DONE
)
674 csi_csr
= (csi_csr
& ~CSICSR_RW
) | (data
& CSICSR_RW
);
678 t_stat
csi_reset (DEVICE
*dptr
)
686 /* CSO: console storage output */
690 return (cso_csr
& CSOCSR_IMP
);
693 void csts_wr (int32 data
)
695 if ((data
& CSR_IE
) == 0) CLR_INT (CSO
);
696 else if ((cso_csr
& (CSR_DONE
+ CSR_IE
)) == CSR_DONE
)
698 cso_csr
= (cso_csr
& ~CSOCSR_RW
) | (data
& CSOCSR_RW
);
702 void cstd_wr (int32 data
)
704 cso_unit
.buf
= data
& 0377;
705 cso_csr
= cso_csr
& ~CSR_DONE
;
707 sim_activate (&cso_unit
, cso_unit
.wait
);
711 t_stat
cso_svc (UNIT
*uptr
)
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
);
721 cso_unit
.pos
= cso_unit
.pos
+ 1;
725 t_stat
cso_reset (DEVICE
*dptr
)
730 sim_cancel (&cso_unit
); /* deactivate unit */
734 /* SYSD: SSC access mechanisms and devices
736 - IPR space read/write routines
737 - register space read/write routines
738 - SSC local register read/write routines
739 - SSC console storage UART
741 - CMCTL local register read/write routines
744 /* Read/write IPR register space
746 These routines implement the SSC's response to IPR's which are
747 sent off the CPU chip for processing.
750 int32
ReadIPR (int32 rg
)
756 case MT_ICCS
: /* ICCS */
760 case MT_CSRS
: /* CSRS */
764 case MT_CSRD
: /* CSRD */
768 case MT_CSTS
: /* CSTS */
772 case MT_CSTD
: /* CSTD */
776 case MT_RXCS
: /* RXCS */
780 case MT_RXDB
: /* RXDB */
784 case MT_TXCS
: /* TXCS */
788 case MT_TXDB
: /* TXDB */
792 case MT_TODR
: /* TODR */
796 case MT_CADR
: /* CADR */
800 case MT_MSER
: /* MSER */
804 case MT_CONPC
: /* console PC */
808 case MT_CONPSL
: /* console PSL */
812 case MT_SID
: /* SID */
813 val
= CVAX_SID
| CVAX_UREV
;
817 ssc_bto
= ssc_bto
| SSCBTO_BTO
; /* set BTO */
825 void WriteIPR (int32 rg
, int32 val
)
829 case MT_ICCS
: /* ICCS */
833 case MT_TODR
: /* TODR */
837 case MT_CSRS
: /* CSRS */
841 case MT_CSRD
: /* CSRD */
844 case MT_CSTS
: /* CSTS */
848 case MT_CSTD
: /* CSTD */
852 case MT_RXCS
: /* RXCS */
856 case MT_RXDB
: /* RXDB */
859 case MT_TXCS
: /* TXCS */
863 case MT_TXDB
: /* TXDB */
867 case MT_CADR
: /* CADR */
868 CADR
= (val
& CADR_RW
) | CADR_MBO
;
871 case MT_MSER
: /* MSER */
872 MSER
= MSER
& MSER_HM
;
875 case MT_IORESET
: /* IORESET */
881 case MT_CONPSL
: /* halt reg */
885 ssc_bto
= ssc_bto
| SSCBTO_BTO
; /* set BTO */
892 /* Read/write I/O register space
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.
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 */
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
},
920 /* ReadReg - read register space
923 pa = physical address
924 lnt = length (BWLQ) - ignored
929 int32
ReadReg (uint32 pa
, int32 lnt
)
933 for (p
= ®table
[0]; p
->low
!= 0; p
++) {
934 if ((pa
>= p
->low
) && (pa
< p
->high
) && p
->read
)
937 ssc_bto
= ssc_bto
| SSCBTO_BTO
| SSCBTO_RWT
;
938 MACH_CHECK (MCHK_READ
);
942 /* WriteReg - write register space
945 pa = physical address
946 val = data to write, right justified in 32b longword
952 void WriteReg (uint32 pa
, int32 val
, int32 lnt
)
956 for (p
= ®table
[0]; p
->low
!= 0; p
++) {
957 if ((pa
>= p
->low
) && (pa
< p
->high
) && p
->write
) {
958 p
->write (pa
, val
, lnt
);
962 ssc_bto
= ssc_bto
| SSCBTO_BTO
| SSCBTO_RWT
;
963 MACH_CHECK (MCHK_WRITE
);
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.
973 CMCTL16 - error status register
975 CMCTL17 - control/diagnostic status register
977 The CMCTL registers are cleared at power up.
980 int32
cmctl_rd (int32 pa
)
982 int32 rg
= (pa
- CMCTLBASE
) >> 2;
986 default: /* config reg */
987 return cmctl_reg
[rg
] & CMCNF_MASK
;
989 case 16: /* err status */
990 return cmctl_reg
[rg
];
993 return cmctl_reg
[rg
] & CMCSR_MASK
;
995 case 18: /* KA655X ext mem */
996 if (MEMSIZE
> MAXMEMSIZE
) /* more than 128MB? */
997 return ((int32
) MEMSIZE
);
998 MACH_CHECK (MCHK_READ
);
1004 void cmctl_wr (int32 pa
, int32 val
, int32 lnt
)
1006 int32 i
, rg
= (pa
- CMCTLBASE
) >> 2;
1008 if (lnt
< L_LONG
) { /* LW write only */
1009 int32 sc
= (pa
& 3) << 3; /* shift data to */
1010 val
= val
<< sc
; /* proper location */
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
;
1023 cmctl_reg
[rg
] = (cmctl_reg
[rg
] & ~CMCNF_RW
) | (val
& CMCNF_RW
);
1026 case 16: /* err status */
1027 cmctl_reg
[rg
] = cmctl_reg
[rg
] & ~(val
& CMERR_W1C
);
1031 cmctl_reg
[rg
] = val
& CMCSR_MASK
;
1035 MACH_CHECK (MCHK_WRITE
);
1041 /* KA655 registers */
1043 int32
ka_rd (int32 pa
)
1045 int32 rg
= (pa
- KABASE
) >> 2;
1059 void ka_wr (int32 pa
, int32 val
, int32 lnt
)
1061 int32 rg
= (pa
- KABASE
) >> 2;
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
);
1070 int32
sysd_hlt_enb (void)
1072 return ka_bdr
& BDR_BRKENB
;
1075 /* Cache diagnostic space */
1077 int32
cdg_rd (int32 pa
)
1079 int32 t
, row
= CDG_GETROW (pa
);
1082 ka_cacr
= ka_cacr
& ~CACR_DRO
; /* clear diag */
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
);
1091 void cdg_wr (int32 pa
, int32 val
, int32 lnt
)
1093 int32 row
= CDG_GETROW (pa
);
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
));
1101 cdg_dat
[row
] = val
; /* store data */
1105 int32
parity (int32 val
, int32 odd
)
1107 for ( ; val
!= 0; val
= val
>> 1) {
1108 if (val
& 1) odd
= odd
^ 1;
1113 /* SSC registers - byte/word merges done in WriteReg */
1115 int32
ssc_rd (int32 pa
)
1117 int32 rg
= (pa
- SSCBASE
) >> 2;
1121 case 0x00: /* base reg */
1124 case 0x04: /* conf reg */
1127 case 0x08: /* bus timeout */
1130 case 0x0C: /* output port */
1131 return ssc_otp
& SSCOTP_MASK
;
1133 case 0x1B: /* TODR */
1136 case 0x1C: /* CSRS */
1139 case 0x1D: /* CSRD */
1142 case 0x1E: /* CSTS */
1145 case 0x20: /* RXCS */
1148 case 0x21: /* RXDB */
1151 case 0x22: /* TXCS */
1154 case 0x40: /* T0CSR */
1157 case 0x41: /* T0INT */
1158 return tmr_tir_rd (0, FALSE
);
1160 case 0x42: /* T0NI */
1163 case 0x43: /* T0VEC */
1166 case 0x44: /* T1CSR */
1169 case 0x45: /* T1INT */
1170 return tmr_tir_rd (1, FALSE
);
1172 case 0x46: /* T1NI */
1175 case 0x47: /* T1VEC */
1178 case 0x4C: /* ADS0M */
1181 case 0x4D: /* ADS0K */
1184 case 0x50: /* ADS1M */
1187 case 0x51: /* ADS1K */
1194 void ssc_wr (int32 pa
, int32 val
, int32 lnt
)
1196 int32 rg
= (pa
- SSCBASE
) >> 2;
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
));
1207 case 0x00: /* base reg */
1208 ssc_base
= (val
& SSCBASE_RW
) | SSCBASE_MBO
;
1211 case 0x04: /* conf reg */
1212 ssc_cnf
= ssc_cnf
& ~(val
& SSCCNF_W1C
);
1213 ssc_cnf
= (ssc_cnf
& ~SSCCNF_RW
) | (val
& SSCCNF_RW
);
1216 case 0x08: /* bus timeout */
1217 ssc_bto
= ssc_bto
& ~(val
& SSCBTO_W1C
);
1218 ssc_bto
= (ssc_bto
& ~SSCBTO_RW
) | (val
& SSCBTO_RW
);
1221 case 0x0C: /* output port */
1222 ssc_otp
= val
& SSCOTP_MASK
;
1225 case 0x1B: /* TODR */
1229 case 0x1C: /* CSRS */
1233 case 0x1E: /* CSTS */
1237 case 0x1F: /* CSTD */
1241 case 0x20: /* RXCS */
1245 case 0x22: /* TXCS */
1249 case 0x23: /* TXDB */
1253 case 0x40: /* T0CSR */
1254 tmr_csr_wr (0, val
);
1257 case 0x42: /* T0NI */
1261 case 0x43: /* T0VEC */
1262 tmr_tivr
[0] = val
& TMR_VEC_MASK
;
1265 case 0x44: /* T1CSR */
1266 tmr_csr_wr (1, val
);
1269 case 0x46: /* T1NI */
1273 case 0x47: /* T1VEC */
1274 tmr_tivr
[1] = val
& TMR_VEC_MASK
;
1277 case 0x4C: /* ADS0M */
1278 ssc_adsm
[0] = val
& SSCADS_MASK
;
1281 case 0x4D: /* ADS0K */
1282 ssc_adsk
[0] = val
& SSCADS_MASK
;
1285 case 0x50: /* ADS1M */
1286 ssc_adsm
[1] = val
& SSCADS_MASK
;
1289 case 0x51: /* ADS1K */
1290 ssc_adsk
[1] = val
& SSCADS_MASK
;
1297 /* Programmable timers
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.
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.
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.
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
1331 int32
tmr_tir_rd (int32 tmr
, t_bool interp
)
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
;
1343 return tmr_tir
[tmr
];
1346 void tmr_csr_wr (int32 tmr
, int32 val
)
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 */
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 */
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 */
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 */
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
);
1379 t_stat
tmr_svc (UNIT
*uptr
)
1381 int32 tmr
= uptr
- sysd_dev
.units
; /* get timer # */
1383 tmr_incr (tmr
, tmr_inc
[tmr
]); /* incr timer */
1387 /* Timer increment */
1389 void tmr_incr (int32 tmr
, uint32 inc
)
1391 uint32 new_tir
= tmr_tir
[tmr
] + inc
; /* add incr */
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 */
1404 if (tmr_csr
[tmr
] & TMR_CSR_IE
) { /* set int req */
1405 if (tmr
) SET_INT (TMR1
);
1406 else SET_INT (TMR0
);
1410 tmr_tir
[tmr
] = new_tir
; /* no, upd tir */
1411 if (tmr_csr
[tmr
] & TMR_CSR_RUN
) /* still running? */
1412 tmr_sched (tmr
); /* reactivate */
1417 /* Timer scheduling */
1419 void tmr_sched (int32 tmr
)
1421 int32 clk_time
= sim_is_active (&clk_unit
) - 1;
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
];
1430 tmr_inc
[tmr
] = TMR_INC
; /* usec/interval */
1431 tmr_time
= tmr_poll
;
1433 if (tmr_time
== 0) tmr_time
= 1;
1434 if ((tmr_inc
[tmr
] == TMR_INC
) && (tmr_time
> clk_time
)) {
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. */
1442 tmr_inc
[tmr
] = (uint32
) (((double) clk_time
* TMR_INC
) / tmr_poll
);
1443 tmr_time
= clk_time
;
1445 sim_activate (&sysd_unit
[tmr
], tmr_time
);
1449 int32
tmr0_inta (void)
1454 int32
tmr1_inta (void)
1461 int32
machine_check (int32 p1
, int32 opc
, int32 cc
, int32 delta
)
1463 int32 i
, st1
, st2
, p2
, hsir
, acc
;
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
;
1470 st1
= ((((uint32
) opc
) & 0xFF) << 24) |
1472 ((CADR
& 0xFF) << 8) |
1474 st2
= 0x00C07000 + (delta
& 0xFF);
1475 cc
= intexc (SCB_MCHK
, cc
, 0, IE_SVE
); /* take exception */
1476 acc
= ACC_MASK (KERN
); /* in kernel mode */
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 */
1490 int32
con_halt (int32 code
, int32 cc
)
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 */
1509 t_stat
cpu_boot (int32 unitno
, DEVICE
*dptr
)
1511 extern t_stat
load_cmd (int32 flag
, char *cptr
);
1512 extern FILE *sim_log
;
1516 PSL
= PSL_IS
| PSL_IPL1F
;
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
;
1532 t_stat
sysd_reset (DEVICE
*dptr
)
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
]);
1544 sim_cancel (&csi_unit
);
1548 sim_cancel (&cso_unit
);
1555 t_stat
sysd_powerup (void)
1559 for (i
= 0; i
< (CMCTLSIZE
>> 2); i
++) cmctl_reg
[i
] = 0;
1560 for (i
= 0; i
< 2; i
++) {
1562 ssc_adsm
[i
] = ssc_adsk
[i
] = 0;
1566 ssc_cnf
= ssc_cnf
& SSCCNF_BLO
;