1 /* pdp11_cpumod.c: PDP-11 CPU model-specific features
3 Copyright (c) 2004-2008, 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 system PDP-11 model-specific registers
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 (found by 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 (from Sergey Okhapkin)
35 19-Jan-05 RMS Added variable SYSID, MBRK write (from Tim Chapman)
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.
45 #include "pdp11_defs.h"
46 #include "pdp11_cpumod.h"
49 /* Byte write macros for system registers */
51 #define ODD_IGN(cur) \
52 if ((access == WRITEB) && (pa & 1)) return SCPE_OK
54 if ((access == WRITEB) && (pa & 1)) cur = cur << 8
55 #define ODD_MRG(prv,cur) \
56 if (access == WRITEB) cur = \
57 ((pa & 1)? (((prv) & 0377) | ((cur) & 0177400)) : \
58 (((prv) & 0177400) | ((cur) & 0377)))
60 int32 SR
= 0; /* switch register */
61 int32 DR
= 0; /* display register */
62 int32 MBRK
= 0; /* 11/70 microbreak */
63 int32 SYSID
= 0x1234; /* 11/70 system ID */
64 int32 WCS
= 0; /* 11/60 WCS control */
65 int32 CPUERR
= 0; /* CPU error reg */
66 int32 MEMERR
= 0; /* memory error reg */
67 int32 CCR
= 0; /* cache control reg */
68 int32 HITMISS
= 0; /* hit/miss reg */
69 int32 MAINT
= 0; /* maint reg */
70 int32 JCSR
= 0; /* J11 control */
71 int32 JCSR_dflt
= 0; /* J11 boot ctl def */
72 int32 JPCR
= 0; /* J11 page ctrl */
73 int32 JASR
= 0; /* J11 addtl status */
74 int32 UDCR
= 0; /* UBA diag ctrl */
75 int32 UDDR
= 0; /* UBA diag data */
76 int32 UCSR
= 0; /* UBA control */
77 int32 uba_last
= 0; /* UBA last mapped */
78 int32 ub_map
[UBM_LNT_LW
] = { 0 }; /* UBA map array */
80 uint8 toy_data
[TOY_LNT
] = { 0 };
81 static int32 clk_tps_map
[4] = { 60, 60, 50, 800 };
85 extern DEVICE cpu_dev
, *sim_devices
[];
88 extern int32 STKLIM
, PIRQ
;
89 extern uint32 cpu_model
, cpu_type
, cpu_opt
;
90 extern int32 clk_fie
, clk_fnxm
, clk_tps
, clk_default
;
91 extern int32 sim_switches
;
93 t_stat
CPU24_rd (int32
*data
, int32 addr
, int32 access
);
94 t_stat
CPU24_wr (int32 data
, int32 addr
, int32 access
);
95 t_stat
CPU44_rd (int32
*data
, int32 addr
, int32 access
);
96 t_stat
CPU44_wr (int32 data
, int32 addr
, int32 access
);
97 t_stat
CPU45_rd (int32
*data
, int32 addr
, int32 access
);
98 t_stat
CPU45_wr (int32 data
, int32 addr
, int32 access
);
99 t_stat
CPU60_rd (int32
*data
, int32 addr
, int32 access
);
100 t_stat
CPU60_wr (int32 data
, int32 addr
, int32 access
);
101 t_stat
CPU70_rd (int32
*data
, int32 addr
, int32 access
);
102 t_stat
CPU70_wr (int32 data
, int32 addr
, int32 access
);
103 t_stat
CPUJ_rd (int32
*data
, int32 addr
, int32 access
);
104 t_stat
CPUJ_wr (int32 data
, int32 addr
, int32 access
);
105 t_stat
REG_rd (int32
*data
, int32 addr
, int32 access
);
106 t_stat
REG_wr (int32 data
, int32 addr
, int32 access
);
107 t_stat
SR_rd (int32
*data
, int32 addr
, int32 access
);
108 t_stat
DR_wr (int32 data
, int32 addr
, int32 access
);
109 t_stat
CTLFB_rd (int32
*data
, int32 addr
, int32 access
);
110 t_stat
CTLFB_wr (int32 data
, int32 addr
, int32 access
);
111 t_stat
CTLJB_rd (int32
*data
, int32 addr
, int32 access
);
112 t_stat
CTLJB_wr (int32 data
, int32 addr
, int32 access
);
113 t_stat
CTLJD_rd (int32
*data
, int32 addr
, int32 access
);
114 t_stat
CTLJD_wr (int32 data
, int32 addr
, int32 access
);
115 t_stat
CTLJE_rd (int32
*data
, int32 addr
, int32 access
);
116 t_stat
CTLJE_wr (int32 data
, int32 addr
, int32 access
);
117 t_stat
UBA24_rd (int32
*data
, int32 addr
, int32 access
);
118 t_stat
UBA24_wr (int32 data
, int32 addr
, int32 access
);
119 t_stat
UBAJ_rd (int32
*data
, int32 addr
, int32 access
);
120 t_stat
UBAJ_wr (int32 data
, int32 addr
, int32 access
);
121 t_stat
sys_reset (DEVICE
*dptr
);
122 int32
toy_read (void);
123 void toy_write (int32 bit
);
124 uint8
toy_set (int32 val
);
125 t_stat
sys_set_jclk_dflt (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
);
126 t_stat
sys_show_jclk_dflt (FILE *st
, UNIT
*uptr
, int32 val
, void *desc
);
128 extern t_stat
PSW_rd (int32
*data
, int32 addr
, int32 access
);
129 extern t_stat
PSW_wr (int32 data
, int32 addr
, int32 access
);
130 extern t_stat
APR_rd (int32
*data
, int32 addr
, int32 access
);
131 extern t_stat
APR_wr (int32 data
, int32 addr
, int32 access
);
132 extern t_stat
MMR012_rd (int32
*data
, int32 addr
, int32 access
);
133 extern t_stat
MMR012_wr (int32 data
, int32 addr
, int32 access
);
134 extern t_stat
MMR3_rd (int32
*data
, int32 addr
, int32 access
);
135 extern t_stat
MMR3_wr (int32 data
, int32 addr
, int32 access
);
136 extern t_stat
ubm_rd (int32
*data
, int32 addr
, int32 access
);
137 extern t_stat
ubm_wr (int32 data
, int32 addr
, int32 access
);
138 extern void put_PIRQ (int32 val
);
140 /* Fixed I/O address table entries */
142 DIB psw_dib
= { IOBA_PSW
, IOLN_PSW
, &PSW_rd
, &PSW_wr
, 0 };
143 DIB cpuj_dib
= { IOBA_CPU
, IOLN_CPU
, &CPUJ_rd
, &CPUJ_wr
, 0 };
144 DIB cpu24_dib
= { IOBA_CPU
, IOLN_CPU
, &CPU24_rd
, &CPU24_wr
, 0 };
145 DIB cpu44_dib
= { IOBA_CPU
, IOLN_CPU
, &CPU44_rd
, &CPU44_wr
, 0 };
146 DIB cpu45_dib
= { IOBA_CPU
, IOLN_CPU
, &CPU45_rd
, &CPU45_wr
, 0 };
147 DIB cpu60_dib
= { IOBA_CPU
, IOLN_CPU
, &CPU60_rd
, &CPU60_wr
, 0 };
148 DIB cpu70_dib
= { IOBA_CPU
, IOLN_CPU
, &CPU70_rd
, &CPU70_wr
, 0 };
149 DIB reg_dib
= { IOBA_GPR
, IOLN_GPR
, ®_rd
, ®_wr
, 0 };
150 DIB ctlfb_dib
= { IOBA_CTL
, IOLN_CTL
, &CTLFB_rd
, &CTLFB_wr
};
151 DIB ctljb_dib
= { IOBA_CTL
, IOLN_CTL
, &CTLJB_rd
, &CTLJB_wr
};
152 DIB ctljd_dib
= { IOBA_CTL
, IOLN_CTL
, &CTLJD_rd
, &CTLJD_wr
};
153 DIB ctlje_dib
= { IOBA_CTL
, IOLN_CTL
, &CTLJE_rd
, &CTLJE_wr
};
154 DIB uba24_dib
= { IOBA_UCTL
, IOLN_UCTL
, &UBA24_rd
, &UBA24_wr
};
155 DIB ubaj_dib
= {IOBA_UCTL
, IOLN_UCTL
, &UBAJ_rd
, &UBAJ_wr
};
156 DIB supv_dib
= { IOBA_SUP
, IOLN_SUP
, &APR_rd
, &APR_wr
, 0 };
157 DIB kipdr_dib
= { IOBA_KIPDR
, IOLN_KIPDR
, &APR_rd
, &APR_wr
, 0 };
158 DIB kdpdr_dib
= { IOBA_KDPDR
, IOLN_KDPDR
, &APR_rd
, &APR_wr
, 0 };
159 DIB kipar_dib
= { IOBA_KIPAR
, IOLN_KIPAR
, &APR_rd
, &APR_wr
, 0 };
160 DIB kdpar_dib
= { IOBA_KDPAR
, IOLN_KDPAR
, &APR_rd
, &APR_wr
, 0 };
161 DIB uipdr_dib
= { IOBA_UIPDR
, IOLN_UIPDR
, &APR_rd
, &APR_wr
, 0 };
162 DIB udpdr_dib
= { IOBA_UDPDR
, IOLN_UDPDR
, &APR_rd
, &APR_wr
, 0 };
163 DIB uipar_dib
= { IOBA_UIPAR
, IOLN_UIPAR
, &APR_rd
, &APR_wr
, 0 };
164 DIB udpar_dib
= { IOBA_UDPAR
, IOLN_UDPAR
, &APR_rd
, &APR_wr
, 0 };
165 DIB sr_dib
= { IOBA_SR
, IOLN_SR
, &SR_rd
, NULL
, 0 };
166 DIB dr_dib
= { IOBA_SR
, IOLN_SR
, NULL
, &DR_wr
, 0 };
167 DIB mmr012_dib
= { IOBA_MMR012
, IOLN_MMR012
, &MMR012_rd
, &MMR012_wr
, 0 };
168 DIB mmr3_dib
= { IOBA_MMR3
, IOLN_MMR3
, &MMR3_rd
, &MMR3_wr
, 0 };
169 DIB ubm_dib
= { IOBA_UBM
, IOLN_UBM
, &ubm_rd
, &ubm_wr
, 0 };
171 CPUTAB cpu_tab
[MOD_MAX
] = {
172 { "11/03", SOP_1103
, OPT_1103
, MEMSIZE64K
, PSW_1103
,
174 { "11/04", SOP_1104
, OPT_1104
, MEMSIZE64K
, PSW_1104
,
176 { "11/05", SOP_1105
, OPT_1105
, MEMSIZE64K
, PSW_1105
,
178 { "11/20", SOP_1120
, OPT_1120
, MEMSIZE64K
, PSW_1120
,
180 { "11/23", SOP_1123
, OPT_1123
, MAXMEMSIZE
, PSW_F
,
181 MFPT_F
, PAR_F
, PDR_F
, MM0_F
, MM3_F
},
182 { "11/23+", SOP_1123P
, OPT_1123P
, MAXMEMSIZE
, PSW_F
,
183 MFPT_F
, PAR_F
, PDR_F
, MM0_F
, MM3_F
},
184 { "11/24", SOP_1124
, OPT_1124
, MAXMEMSIZE
, PSW_F
,
185 MFPT_F
, PAR_F
, PDR_F
, MM0_F
, MM3_F
},
186 { "11/34", SOP_1134
, OPT_1134
, UNIMEMSIZE
, PSW_1134
,
187 0, PAR_1134
, PDR_1134
, MM0_1134
, 0 },
188 { "11/40", SOP_1140
, OPT_1140
, UNIMEMSIZE
, PSW_1140
,
189 0, PAR_1140
, PDR_1140
, MM0_1140
, 0 },
190 { "11/44", SOP_1144
, OPT_1144
, MAXMEMSIZE
, PSW_1144
,
191 MFPT_44
, PAR_1144
, PDR_1144
, MM0_1144
, MM3_1144
},
192 { "11/45", SOP_1145
, OPT_1145
, UNIMEMSIZE
, PSW_1145
,
193 0, PAR_1145
, PDR_1145
, MM0_1145
, MM3_1145
},
194 { "11/60", SOP_1160
, OPT_1160
, UNIMEMSIZE
, PSW_1160
,
195 0, PAR_1160
, PDR_1160
, MM0_1160
, 0 },
196 { "11/70", SOP_1170
, OPT_1170
, MAXMEMSIZE
, PSW_1170
,
197 0, PAR_1170
, PDR_1170
, MM0_1170
, MM3_1170
},
198 { "11/73", SOP_1173
, OPT_1173
, MAXMEMSIZE
, PSW_J
,
199 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
},
200 { "11/53", SOP_1153
, OPT_1153
, MAXMEMSIZE
, PSW_J
,
201 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
},
202 { "11/73B", SOP_1173B
, OPT_1173B
, MAXMEMSIZE
, PSW_J
,
203 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
},
204 { "11/83", SOP_1183
, OPT_1183
, MAXMEMSIZE
, PSW_J
,
205 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
},
206 { "11/84", SOP_1184
, OPT_1184
, MAXMEMSIZE
, PSW_J
,
207 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
},
208 { "11/93", SOP_1193
, OPT_1193
, MAXMEMSIZE
, PSW_J
,
209 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
},
210 { "11/94", SOP_1194
, OPT_1194
, MAXMEMSIZE
, PSW_J
,
211 MFPT_J
, PAR_J
, PDR_J
, MM0_J
, MM3_J
}
215 { HAS_PSW
, 0, &psw_dib
}, /* PSW */
216 { CPUT_J
, 0, &cpuj_dib
}, /* CPU control */
217 { CPUT_24
, 0, &cpu24_dib
},
218 { CPUT_44
, 0, &cpu44_dib
},
219 { CPUT_45
, 0, &cpu45_dib
},
220 { CPUT_60
, 0, &cpu60_dib
},
221 { CPUT_70
, 0, &cpu70_dib
},
222 { HAS_IOSR
, 0, ®_dib
},
223 { CPUT_23P
, 0, &ctlfb_dib
}, /* board ctls */
224 { CPUT_JB
, 0, &ctljb_dib
},
225 { CPUT_53
, 0, &ctljd_dib
},
226 { CPUT_JE
, 0, &ctlje_dib
},
227 { CPUT_24
, 0, &uba24_dib
}, /* UBA */
228 { CPUT_JU
, 0, &ubaj_dib
},
229 { 0, OPT_MMU
, &kipdr_dib
}, /* MMU */
230 { 0, OPT_MMU
, &kipar_dib
},
231 { 0, OPT_MMU
, &uipdr_dib
},
232 { 0, OPT_MMU
, &uipar_dib
},
233 { 0, OPT_MMU
, &mmr012_dib
}, /* MMR0-2 */
234 { HAS_MMR3
, 0, &mmr3_dib
}, /* MMR3 */
235 { 0, OPT_UBM
, &ubm_dib
}, /* Unibus map */
236 { HAS_SID
, 0, &kdpdr_dib
}, /* supv, I/D */
237 { HAS_SID
, 0, &kdpar_dib
},
238 { HAS_SID
, 0, &supv_dib
},
239 { HAS_SID
, 0, &udpdr_dib
},
240 { HAS_SID
, 0, &udpar_dib
},
241 { HAS_SR
, 0, &sr_dib
}, /* SR */
242 { HAS_DR
, 0, &dr_dib
}, /* DR */
246 static const char *opt_name
[] = {
247 "Unibus", "Qbus", "EIS", "NOEIS", "FIS", "NOFIS",
248 "FPP", "NOFPP", "CIS", "NOCIS", "MMU", "NOMMU",
249 "RH11", "RH70", "PARITY", "NOPARITY", "Unibus map", "No map", NULL
252 static const char *jcsr_val
[4] = {
253 "LINE", "50HZ", "60HZ", "800HZ"
256 /* SYSTEM data structures
258 sys_dev SYSTEM device descriptor
259 sys_unit SYSTEM unit descriptor
260 sys_reg SYSTEM register list
263 UNIT sys_unit
= { UDATA (NULL
, 0, 0) };
266 { ORDATA (SR
, SR
, 16) },
267 { ORDATA (DR
, DR
, 16) },
268 { ORDATA (MEMERR
, MEMERR
, 16) },
269 { ORDATA (CCR
, CCR
, 16) },
270 { ORDATA (MAINT
, MAINT
, 16) },
271 { ORDATA (HITMISS
, HITMISS
, 16) },
272 { ORDATA (CPUERR
, CPUERR
, 16) },
273 { ORDATA (MBRK
, MBRK
, 16) },
274 { ORDATA (WCS
, WCS
, 16) },
275 { ORDATA (SYSID
, SYSID
, 16) },
276 { ORDATA (JCSR
, JCSR
, 16) },
277 { ORDATA (JCSR_DFLT
, JCSR_dflt
, 16), REG_HRO
},
278 { ORDATA (JPCR
, JPCR
, 16) },
279 { ORDATA (JASR
, JASR
, 16) },
280 { ORDATA (UDCR
, UDCR
, 16) },
281 { ORDATA (UDDR
, UDDR
, 16) },
282 { ORDATA (UCSR
, UCSR
, 16) },
283 { ORDATA (ULAST
, uba_last
, 23) },
284 { BRDATA (UBMAP
, ub_map
, 8, 22, UBM_LNT_LW
) },
285 { DRDATA (TOY_STATE
, toy_state
, 6), REG_HRO
},
286 { BRDATA (TOY_DATA
, toy_data
, 8, 8, TOY_LNT
), REG_HRO
},
291 { MTAB_XTD
|MTAB_VDV
|MTAB_NMO
, 0, "JCLK_DFLT", "JCLK_DFLT",
292 &sys_set_jclk_dflt
, &sys_show_jclk_dflt
},
297 "SYSTEM", &sys_unit
, sys_reg
, sys_mod
,
299 NULL
, NULL
, &sys_reset
,
305 /* Switch and display registers - many */
307 t_stat
SR_rd (int32
*data
, int32 pa
, int32 access
)
313 t_stat
DR_wr (int32 data
, int32 pa
, int32 access
)
319 /* GPR's - 11/04, 11/05 */
321 t_stat
REG_rd (int32
*data
, int32 pa
, int32 access
)
327 t_stat
REG_wr (int32 data
, int32 pa
, int32 access
)
331 if (access
== WRITE
) R
[reg
] = data
;
332 else if (pa
& 1) R
[reg
] = (R
[reg
] & 0377) | (data
<< 8);
333 else R
[reg
] = (R
[reg
] & ~0377) | data
;
337 /* CPU control registers - 11/24 */
339 t_stat
CPU24_rd (int32
*data
, int32 pa
, int32 access
)
341 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
343 case 013: /* CPUERR */
346 } /* end switch PA */
349 return SCPE_NXM
; /* unimplemented */
352 t_stat
CPU24_wr (int32 data
, int32 pa
, int32 access
)
354 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
356 case 013: /* CPUERR */
358 } /* end switch pa */
360 return SCPE_NXM
; /* unimplemented */
363 /* CPU control registers - 11/44 */
365 t_stat
CPU44_rd (int32
*data
, int32 pa
, int32 access
)
367 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
369 case 002: /* MEMERR */
374 *data
= CCR
& CCR44_RD
;
377 case 004: /* MAINT */
378 *data
= MAINT
& CMR44_RD
;
381 case 005: /* Hit/miss */
389 case 013: /* CPUERR */
390 if (CPUERR
& CPUE_YEL
) /* 11/44 stack err */
391 CPUERR
= (CPUERR
& ~CPUE_YEL
) | CPUE_RED
; /* in <2> not <3> */
392 if (CPUERR
& (CPUE_ODD
|CPUE_NXM
|CPUE_TMO
)) /* additional flag */
393 CPUERR
= CPUERR
| CPUE44_BUSE
;
394 *data
= CPUERR
& CPUE_IMP
;
400 } /* end switch PA */
403 return SCPE_NXM
; /* unimplemented */
406 t_stat
CPU44_wr (int32 data
, int32 pa
, int32 access
)
408 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
410 case 002: /* MEMERR */
416 CCR
= data
& CCR44_WR
;
419 case 004: /* MAINT */
420 ODD_MRG (MAINT
, data
);
421 MAINT
= data
& CMR44_WR
;
424 case 005: /* Hit/miss */
427 case 013: /* CPUERR */
437 return SCPE_NXM
; /* unimplemented */
440 /* CPU control registers - 11/45 */
442 t_stat
CPU45_rd (int32
*data
, int32 pa
, int32 access
)
444 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
454 case 016: /* STKLIM */
455 *data
= STKLIM
& STKLIM_RW
;
457 } /* end switch PA */
460 return SCPE_NXM
; /* unimplemented */
463 t_stat
CPU45_wr (int32 data
, int32 pa
, int32 access
)
465 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
472 case 016: /* STKLIM */
474 STKLIM
= data
& STKLIM_RW
;
476 } /* end switch pa */
478 return SCPE_NXM
; /* unimplemented */
481 /* CPU control registers - 11/60 */
483 t_stat
CPU60_rd (int32
*data
, int32 pa
, int32 access
)
485 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
488 *data
= WCS
& WCS60_RD
;
491 case 002: /* MEMERR */
492 *data
= MEMERR
& MEME60_RD
;
496 *data
= CCR
& CCR60_RD
;
499 case 005: /* Hit/miss */
503 case 013: /* CPUERR */
504 if (CPUERR
& CPUE_NXM
) /* TMO only */
505 CPUERR
= (CPUERR
& ~CPUE_NXM
) | CPUE_TMO
;
506 *data
= CPUERR
& CPUE60_RD
;
509 case 016: /* STKLIM */
510 *data
= STKLIM
& STKLIM_RW
;
512 } /* end switch PA */
515 return SCPE_NXM
; /* unimplemented */
518 t_stat
CPU60_wr (int32 data
, int32 pa
, int32 access
)
520 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
523 WCS
= data
& WCS60_WR
;
526 case 002: /* MEMERR */
532 CCR
= data
& CCR60_WR
;
535 case 005: /* Hit/miss */
538 case 013: /* CPUERR */
543 MBRK
= data
& MBRK60_WR
;
546 case 016: /* STKLIM */
548 STKLIM
= data
& STKLIM_RW
;
550 } /* end switch pa */
552 return SCPE_NXM
; /* unimplemented */
555 /* CPU control registers - 11/70 */
557 t_stat
CPU70_rd (int32
*data
, int32 pa
, int32 access
)
559 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
561 case 000: /* low error */
565 case 001: /* high error */
569 case 002: /* MEMERR */
577 case 004: /* MAINT */
581 case 005: /* Hit/miss */
585 case 010: /* low size */
586 *data
= (MEMSIZE
>> 6) - 1;
589 case 011: /* high size */
593 case 012: /* system ID */
597 case 013: /* CPUERR */
598 *data
= CPUERR
& CPUE_IMP
;
609 case 016: /* STKLIM */
610 *data
= STKLIM
& STKLIM_RW
;
612 } /* end switch PA */
615 return SCPE_NXM
; /* unimplemented */
618 t_stat
CPU70_wr (int32 data
, int32 pa
, int32 access
)
620 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
622 case 002: /* MEMERR */
624 MEMERR
= MEMERR
& ~data
;
632 case 004: /* MAINT */
635 case 005: /* Hit/miss */
638 case 010: /* low size */
641 case 011: /* high size */
644 case 013: /* CPUERR */
650 MBRK
= data
& MBRK70_WR
;
658 case 016: /* STKLIM */
660 STKLIM
= data
& STKLIM_RW
;
662 } /* end switch pa */
664 return SCPE_NXM
; /* unimplemented */
667 /* CPU control registers - J11 */
669 t_stat
CPUJ_rd (int32
*data
, int32 pa
, int32 access
)
671 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
673 case 002: /* MEMERR */
681 case 004: /* MAINT */
682 *data
= MAINT
| MAINT_NOFPA
| MAINT_BPOK
| (UNIBUS
? MAINT_U
: MAINT_Q
);
683 if (CPUT (CPUT_53
)) *data
|= MAINT_KDJD
| MAINT_POROM
;
684 if (CPUT (CPUT_73
)) *data
|= MAINT_KDJA
| MAINT_POODT
;
685 if (CPUT (CPUT_73B
|CPUT_83
|CPUT_84
)) *data
|= MAINT_KDJB
| MAINT_POROM
;
686 if (CPUT (CPUT_93
|CPUT_94
)) *data
|= MAINT_KDJE
| MAINT_POROM
;
689 case 005: /* Hit/miss */
690 if (CPUT (CPUT_73B
)) *data
= 0; /* must be 0 for 73B */
691 else *data
= HITMISS
| 010; /* must be nz for 11/8X */
694 case 013: /* CPUERR */
695 *data
= CPUERR
& CPUE_IMP
;
701 } /* end switch PA */
704 return SCPE_NXM
; /* unimplemented */
707 t_stat
CPUJ_wr (int32 data
, int32 pa
, int32 access
)
709 switch ((pa
>> 1) & 017) { /* decode pa<4:1> */
711 case 002: /* MEMERR */
720 case 004: /* MAINT */
723 case 005: /* Hit/miss */
726 case 013: /* CPUERR */
734 } /* end switch pa */
736 return SCPE_NXM
; /* unimplemented */
739 /* Board control registers - KDF11B */
741 t_stat
CTLFB_rd (int32
*data
, int32 pa
, int32 access
)
743 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
746 *data
= JPCR
& PCRFB_RW
;
754 *data
= SR
& CDRFB_RD
;
762 t_stat
CTLFB_wr (int32 data
, int32 pa
, int32 access
)
764 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
767 ODD_MRG (JPCR
, data
);
768 JPCR
= data
& PCRFB_RW
;
771 ODD_MRG (MAINT
, data
);
776 DR
= data
& CDRFB_WR
;
783 /* Board control registers - KDJ11B */
785 t_stat
CTLJB_rd (int32
*data
, int32 pa
, int32 access
)
787 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
790 *data
= JCSR
& CSRJB_RD
;
794 *data
= JPCR
& PCRJB_RW
;
798 *data
= SR
& CDRJB_RD
;
806 t_stat
CTLJB_wr (int32 data
, int32 pa
, int32 access
)
810 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
813 ODD_MRG (JCSR
, data
);
814 JCSR
= (JCSR
& ~CSRJB_WR
) | (data
& CSRJB_WR
);
815 if (JCSR
& CSRJ_LTCI
) clk_fie
= 1; /* force LTC int enb? */
817 if (JCSR
& CSRJ_LTCD
) clk_fnxm
= 1; /* force LTC reg nxm? */
819 t
= CSRJ_LTCSEL (JCSR
); /* get freq sel */
820 if (t
) clk_tps
= clk_tps_map
[t
];
821 else clk_tps
= clk_default
;
825 ODD_MRG (JPCR
, data
);
826 JPCR
= data
& PCRJB_RW
;
831 DR
= data
& CDRJB_WR
;
838 /* Board control registers - KDJ11D */
840 t_stat
CTLJD_rd (int32
*data
, int32 pa
, int32 access
)
842 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
845 *data
= JCSR
& CSRJD_RD
;
853 t_stat
CTLJD_wr (int32 data
, int32 pa
, int32 access
)
855 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
858 ODD_MRG (JCSR
, data
);
859 JCSR
= (JCSR
& ~CSRJD_WR
) | (data
& CSRJD_WR
);
866 /* Board control registers - KDJ11E */
868 t_stat
CTLJE_rd (int32
*data
, int32 pa
, int32 access
)
870 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
873 *data
= JCSR
& CSRJE_RD
;
877 *data
= JPCR
& PCRJE_RW
;
881 *data
= SR
& CDRJE_RD
;
885 JASR
= (JASR
& ~ASRJE_TOY
) | (toy_read () << ASRJE_V_TOY
);
886 *data
= JASR
& ASRJE_RW
;
894 t_stat
CTLJE_wr (int32 data
, int32 pa
, int32 access
)
898 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
901 ODD_MRG (JCSR
, data
);
902 JCSR
= (JCSR
& ~CSRJE_WR
) | (data
& CSRJE_WR
);
903 if (JCSR
& CSRJ_LTCI
) clk_fie
= 1; /* force LTC int enb? */
905 if (JCSR
& CSRJ_LTCD
) clk_fnxm
= 1; /* force LTC reg nxm? */
907 t
= CSRJ_LTCSEL (JCSR
); /* get freq sel */
908 if (t
) clk_tps
= clk_tps_map
[t
];
909 else clk_tps
= clk_default
;
913 ODD_MRG (JPCR
, data
);
914 JPCR
= data
& PCRJE_RW
;
919 DR
= data
& CDRJE_WR
;
923 ODD_MRG (JASR
, data
);
924 JASR
= data
& ASRJE_RW
;
925 toy_write (ASRJE_TOYBIT (JASR
));
932 /* Unibus adapter registers - KT24 */
934 t_stat
UBA24_rd (int32
*data
, int32 pa
, int32 access
)
936 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
939 *data
= uba_last
& LMAL_RD
;
942 *data
= uba_last
& LMAH_RD
;
950 t_stat
UBA24_wr (int32 data
, int32 pa
, int32 access
)
952 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
956 uba_last
= (uba_last
& ~LMAH_WR
) | ((data
& LMAH_WR
) << 16);
963 /* Unibus registers - KTJ11B */
965 t_stat
UBAJ_rd (int32
*data
, int32 pa
, int32 access
)
967 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
970 *data
= UDCR
& DCRKTJ_RD
;
974 *data
= UDDR
& DDRKTJ_RW
;
978 *data
= UCSR
& MCRKTJ_RD
;
986 t_stat
UBAJ_wr (int32 data
, int32 pa
, int32 access
)
988 switch ((pa
>> 1) & 03) { /* decode pa<2:1> */
991 ODD_MRG (UDCR
, data
);
992 UDCR
= (UDCR
& ~DCRKTJ_WR
) | (data
& DCRKTJ_WR
);
996 ODD_MRG (UDDR
, data
);
997 UDDR
= data
& DDRKTJ_RW
;;
1001 ODD_MRG (UCSR
, data
);
1002 UCSR
= (UCSR
& ~MCRKTJ_WR
) | (data
& MCRKTJ_WR
);
1009 /* KDJ11E TOY routines */
1011 int32
toy_read (void)
1017 if (toy_state
== 0) {
1018 curr
= time (NULL
); /* get curr time */
1019 if (curr
== (time_t) -1) return 0; /* error? */
1020 ctm
= localtime (&curr
); /* decompose */
1021 if (ctm
== NULL
) return 0; /* error? */
1022 toy_data
[TOY_HSEC
] = 0x50;
1023 toy_data
[TOY_SEC
] = toy_set (ctm
->tm_sec
);
1024 toy_data
[TOY_MIN
] = toy_set (ctm
->tm_min
);
1025 toy_data
[TOY_HR
] = toy_set (ctm
->tm_hour
);
1026 toy_data
[TOY_DOW
] = toy_set (ctm
->tm_wday
);
1027 toy_data
[TOY_DOM
] = toy_set (ctm
->tm_mday
);
1028 toy_data
[TOY_MON
] = toy_set (ctm
->tm_mon
+ 1);
1029 toy_data
[TOY_YR
] = toy_set (ctm
->tm_year
% 100);
1031 bit
= toy_data
[toy_state
>> 3] >> (toy_state
& 07);
1032 toy_state
= (toy_state
+ 1) % (TOY_LNT
* 8);
1036 void toy_write (int32 bit
)
1042 uint8
toy_set (int32 val
)
1048 return (uint8
) ((d1
<< 4) | d2
);
1051 /* Build I/O space entries for CPU */
1053 t_stat
cpu_build_dib (void)
1058 for (i
= 0; cnf_tab
[i
].dib
!= NULL
; i
++) { /* loop thru config tab */
1059 if (((cnf_tab
[i
].cpum
== 0) || (cpu_type
& cnf_tab
[i
].cpum
)) &&
1060 ((cnf_tab
[i
].optm
== 0) || (cpu_opt
& cnf_tab
[i
].optm
))) {
1061 if (r
= build_ubus_tab (&cpu_dev
, cnf_tab
[i
].dib
)) /* add to dispatch tab */
1068 /* Set/show CPU model */
1070 t_stat
cpu_set_model (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
1072 if (cptr
!= NULL
) return SCPE_ARG
;
1073 if (val
>= MOD_MAX
) return SCPE_IERR
;
1074 if (val
== (int32
) cpu_model
) return SCPE_OK
;
1075 if (MEMSIZE
> cpu_tab
[val
].maxm
)
1076 cpu_set_size (uptr
, cpu_tab
[val
].maxm
, NULL
, NULL
);
1077 if (MEMSIZE
> cpu_tab
[val
].maxm
) return SCPE_INCOMP
;
1079 cpu_type
= 1u << cpu_model
;
1080 cpu_opt
= cpu_tab
[cpu_model
].std
;
1081 cpu_set_bus (cpu_opt
);
1082 reset_all (0); /* reset world */
1086 t_stat
cpu_show_model (FILE *st
, UNIT
*uptr
, int32 val
, void *desc
)
1090 fprintf (st
, "%s", cpu_tab
[cpu_model
].name
);
1091 all_opt
= cpu_tab
[cpu_model
].opt
;
1092 for (i
= 0; opt_name
[2 * i
] != NULL
; i
++) {
1093 if ((all_opt
>> i
) & 1) fprintf (st
, ", %s",
1094 ((cpu_opt
>> i
) & 1)? opt_name
[2 * i
]: opt_name
[(2 * i
) + 1]);
1099 /* Set/clear CPU option */
1101 t_stat
cpu_set_opt (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
1103 if (cptr
) return SCPE_ARG
;
1104 if ((val
& cpu_tab
[cpu_model
].opt
) == 0) return SCPE_ARG
;
1105 cpu_opt
= cpu_opt
| val
;
1109 t_stat
cpu_clr_opt (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
1111 if (cptr
) return SCPE_ARG
;
1112 if ((val
& cpu_tab
[cpu_model
].opt
) == 0) return SCPE_ARG
;
1113 cpu_opt
= cpu_opt
& ~val
;
1117 /* Memory allocation */
1119 t_stat
cpu_set_size (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
1125 if ((val
<= 0) || (val
> (int32
) cpu_tab
[cpu_model
].maxm
) ||
1126 ((val
& 07777) != 0)) return SCPE_ARG
;
1127 for (i
= val
; i
< MEMSIZE
; i
= i
+ 2) mc
= mc
| M
[i
>> 1];
1128 if ((mc
!= 0) && !get_yn ("Really truncate memory [N]?", FALSE
))
1130 nM
= (uint16
*) calloc (val
>> 1, sizeof (uint16
));
1131 if (nM
== NULL
) return SCPE_MEM
;
1132 clim
= (((t_addr
) val
) < MEMSIZE
)? val
: MEMSIZE
;
1133 for (i
= 0; i
< clim
; i
= i
+ 2) nM
[i
>> 1] = M
[i
>> 1];
1137 if (!(sim_switches
& SIM_SW_REST
)) /* unless restore, */
1138 cpu_set_bus (cpu_opt
); /* alter periph config */
1142 /* Bus configuration, disable Unibus or Qbus devices */
1144 t_stat
cpu_set_bus (int32 opt
)
1149 if (opt
& BUS_U
) mask
= DEV_UBUS
; /* Unibus variant? */
1150 else if (MEMSIZE
<= UNIMEMSIZE
) /* 18b Qbus devices? */
1151 mask
= DEV_QBUS
| DEV_Q18
;
1152 else mask
= DEV_QBUS
; /* must be 22b */
1153 for (i
= 0; (dptr
= sim_devices
[i
]) != NULL
; i
++) {
1154 if ((dptr
->flags
& DEV_DISABLE
) && /* disable-able? */
1155 !(dptr
->flags
& DEV_DIS
) && /* enabled? */
1156 ((dptr
->flags
& mask
) == 0)) { /* not allowed? */
1157 printf ("Disabling %s\n", sim_dname (dptr
));
1158 if (sim_log
) fprintf (sim_log
, "Disabling %s\n", sim_dname (dptr
));
1159 dptr
->flags
= dptr
->flags
| DEV_DIS
;
1167 t_stat
sys_reset (DEVICE
*dptr
)
1175 if (!CPUT (CPUT_J
)) MAINT
= 0;
1178 if (CPUT (CPUT_JB
|CPUT_JE
))
1189 for (i
= 0; i
< UBM_LNT_LW
; i
++) ub_map
[i
] = 0;
1190 for (i
= 0; i
< TOY_LNT
; i
++) toy_data
[i
] = 0;
1194 /* Set/show JCLK default values */
1196 t_stat
sys_set_jclk_dflt (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
1200 if ((CPUT (CPUT_JB
|CPUT_JE
)) && cptr
) {
1201 for (i
= 0; i
< 4; i
++) {
1202 if (strncmp (cptr
, jcsr_val
[i
], strlen (cptr
)) == 0) {
1203 JCSR_dflt
= i
<< CSRJ_V_LTCSEL
;
1211 t_stat
sys_show_jclk_dflt (FILE *st
, UNIT
*uptr
, int32 val
, void *desc
)
1213 if (CPUT (CPUT_JB
|CPUT_JE
))
1214 fprintf (st
, "JCLK default=%s\n", jcsr_val
[CSRJ_LTCSEL (JCSR_dflt
)]);
1215 else fprintf (st
, "Not implemented\n");