63c22d578cf56b5a86c73a2ad9dce7ecdef35556
1 /* vax_sys.c: VAX simulator interface
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 03-Nov-05 RMS Added 780 stop codes
27 04-Sep-05 RMS Fixed missing assignment (found by Peter Schorn)
28 16-Aug-05 RMS Fixed C++ declaration and cast problems
29 15-Sep-04 RMS Fixed bugs in character display and parse
30 30-Sep-04 RMS Fixed bugs in parsing indirect displacement modes
31 Added compatibility mode support
32 04-Sep-04 RMS Added octa instruction support
33 02-Sep-04 RMS Fixed parse branch return status
34 13-Jul-04 RMS Fixed bad block routine
35 16-Jun-04 RMS Added DHQ11 support
36 21-Mar-04 RMS Added RXV21 support
37 06-May-03 RMS Added support for second DELQA
38 12-Oct-02 RMS Added multiple RQ controller support
39 10-Oct-02 RMS Added DELQA support
40 21-Sep-02 RMS Extended symbolic ex/mod to all byte devices
41 06-Sep-02 RMS Added TMSCP support
42 14-Jul-02 RMS Added infinite loop message
48 #if defined (FULL_VAX)
51 #define ODC(x) ((x) << DR_V_USPMASK)
56 extern int32 saved_PC
;
58 extern int32 sim_switches
;
60 t_stat
fprint_sym_m (FILE *of
, uint32 addr
, t_value
*val
);
61 int32
fprint_sym_qoimm (FILE *of
, t_value
*val
, int32 vp
, int32 lnt
);
62 t_stat
parse_char (char *cptr
, t_value
*val
, int32 lnt
);
63 t_stat
parse_sym_m (char *cptr
, uint32 addr
, t_value
*val
);
64 int32
parse_brdisp (char *cptr
, uint32 addr
, t_value
*val
,
65 int32 vp
, int32 lnt
, t_stat
*r
);
66 int32
parse_spec (char *cptr
, uint32 addr
, t_value
*val
,
67 int32 vp
, int32 disp
, t_stat
*r
);
68 char *parse_rnum (char *cptr
, int32
*rn
);
69 int32
parse_sym_qoimm (int32
*lit
, t_value
*val
, int32 vp
,
70 int lnt
, int32 minus
);
72 extern t_stat
fprint_sym_cm (FILE *of
, t_addr addr
, t_value
*bytes
, int32 sw
);
73 t_stat
parse_sym_cm (char *cptr
, t_addr addr
, t_value
*bytes
, int32 sw
);
75 /* SCP data structures and interface routines
77 sim_name simulator name string
78 sim_PC pointer to saved PC register descriptor
79 sim_emax number of words for examine
80 sim_devices array of pointers to simulated devices
81 sim_stop_messages array of pointers to stop messages
82 sim_load binary loader
85 REG
*sim_PC
= &cpu_reg
[0];
89 const char *sim_stop_messages
[] = {
93 "CHMx on interrupt stack",
95 "Exception in interrupt or exception",
96 "Process PTE in P0 or P1 space",
97 "Interrupt at undefined IPL",
100 "Sanity timer expired",
107 /* Factory bad block table creation routine
109 This routine writes a DEC standard 044 compliant bad block table on the
110 last track of the specified unit. The bad block table consists of 10
111 repetitions of the same table, formatted as follows:
113 words 0-1 pack id number
114 words 2-3 cylinder/sector/surface specifications
116 words n-n+1 end of table (-1,-1)
119 uptr = pointer to unit
120 sec = number of sectors per surface
121 wds = number of words per sector
126 t_stat
pdp11_bad_block (UNIT
*uptr
, int32 sec
, int32 wds
)
132 if ((sec
< 2) || (wds
< 16)) return SCPE_ARG
;
133 if ((uptr
->flags
& UNIT_ATT
) == 0) return SCPE_UNATT
;
134 if (!get_yn ("Overwrite last track? [N]", FALSE
)) return SCPE_OK
;
135 da
= (uptr
->capac
- (sec
* wds
)) * sizeof (uint16
);
136 if (sim_fseek (uptr
->fileref
, da
, SEEK_SET
)) return SCPE_IOERR
;
137 if ((buf
= (uint16
*) malloc (wds
* sizeof (uint16
))) == NULL
) return SCPE_MEM
;
141 for (i
= 4; i
< wds
; i
++) buf
[i
] = 0xFFFF;
142 for (i
= 0; (i
< sec
) && (i
< 10); i
++)
143 sim_fwrite (buf
, sizeof (uint16
), wds
, uptr
->fileref
);
145 if (ferror (uptr
->fileref
)) return SCPE_IOERR
;
149 /* Dispatch/decoder table
151 The first entry contains:
152 - FPD legal flag (DR_F)
153 - number of specifiers for decode bits 2:0>
154 - number of specifiers for unimplemented instructions bits<6:4>
157 const uint16 drom
[NUM_INST
][MAX_SPEC
+ 1] = {
158 0, 0, 0, 0, 0, 0, 0, /* HALT */
159 0, 0, 0, 0, 0, 0, 0, /* NOP */
160 0, 0, 0, 0, 0, 0, 0, /* REI */
161 0, 0, 0, 0, 0, 0, 0, /* BPT */
162 0, 0, 0, 0, 0, 0, 0, /* RET */
163 0, 0, 0, 0, 0, 0, 0, /* RSB */
164 0, 0, 0, 0, 0, 0, 0, /* LDPCTX */
165 0, 0, 0, 0, 0, 0, 0, /* SVPCTX */
166 4+DR_F
, RW
, AB
, RW
, AB
, 0, 0, /* CVTPS */
167 4+DR_F
, RW
, AB
, RW
, AB
, 0, 0, /* CVTSP */
168 6, RL
, RL
, RL
, RL
, RL
, WL
, /* INDEX */
169 4+DR_F
, AB
, RL
, RW
, AB
, 0, 0, /* CRC */
170 3, RB
, RW
, AB
, 0, 0, 0, /* PROBER */
171 3, RB
, RW
, AB
, 0, 0, 0, /* PROBEW */
172 2, AB
, AB
, 0, 0, 0, 0, /* INSQUE */
173 2, AB
, WL
, 0, 0, 0, 0, /* REMQUE */
174 1, BB
, 0, 0, 0, 0, 0, /* BSBB */
175 1, BB
, 0, 0, 0, 0, 0, /* BRB */
176 1, BB
, 0, 0, 0, 0, 0, /* BNEQ */
177 1, BB
, 0, 0, 0, 0, 0, /* BEQL */
178 1, BB
, 0, 0, 0, 0, 0, /* BGTR */
179 1, BB
, 0, 0, 0, 0, 0, /* BLEQ */
180 1, AB
, 0, 0, 0, 0, 0, /* JSB */
181 1, AB
, 0, 0, 0, 0, 0, /* JMP */
182 1, BB
, 0, 0, 0, 0, 0, /* BGEQ */
183 1, BB
, 0, 0, 0, 0, 0, /* BLSS */
184 1, BB
, 0, 0, 0, 0, 0, /* BGTRU */
185 1, BB
, 0, 0, 0, 0, 0, /* BLEQU */
186 1, BB
, 0, 0, 0, 0, 0, /* BVC */
187 1, BB
, 0, 0, 0, 0, 0, /* BVS */
188 1, BB
, 0, 0, 0, 0, 0, /* BCC */
189 1, BB
, 0, 0, 0, 0, 0, /* BCS */
190 4+DR_F
, RW
, AB
, RW
, AB
, 0, 0, /* ADDP4 */
191 6+DR_F
, RW
, AB
, RW
, AB
, RW
, AB
, /* ADDP6 */
192 4+DR_F
, RW
, AB
, RW
, AB
, 0, 0, /* SUBP4 */
193 6+DR_F
, RW
, AB
, RW
, AB
, RW
, AB
, /* SUBP6 */
194 5+DR_F
, RW
, AB
, AB
, RW
, AB
, 0, /* CVTPT */
195 6+DR_F
, RW
, AB
, RW
, AB
, RW
, AB
, /* MULP6 */
196 5+DR_F
, RW
, AB
, AB
, RW
, AB
, 0, /* CVTTP */
197 6+DR_F
, RW
, AB
, RW
, AB
, RW
, AB
, /* DIVP6 */
198 3+DR_F
, RW
, AB
, AB
, 0, 0, 0, /* MOVC3 */
199 3+DR_F
, RW
, AB
, AB
, 0, 0, 0, /* CMPC3 */
200 4+DR_F
, RW
, AB
, AB
, RB
, 0, 0, /* SCANC */
201 4+DR_F
, RW
, AB
, AB
, RB
, 0, 0, /* SPANC */
202 5+DR_F
, RW
, AB
, RB
, RW
, AB
, 0, /* MOVC5 */
203 5+DR_F
, RW
, AB
, RB
, RW
, AB
, 0, /* CMPC5 */
204 6+DR_F
, RW
, AB
, RB
, AB
, RW
, AB
, /* MOVTC */
205 6+DR_F
, RW
, AB
, RB
, AB
, RW
, AB
, /* MOVTUC */
206 1, BW
, 0, 0, 0, 0, 0, /* BSBW */
207 1, BW
, 0, 0, 0, 0, 0, /* BRW */
208 2, RW
, WL
, 0, 0, 0, 0, /* CVTWL */
209 2, RW
, WB
, 0, 0, 0, 0, /* CVTWB */
210 3+DR_F
, RW
, AB
, AB
, 0, 0, 0, /* MOVP */
211 3+DR_F
, RW
, AB
, AB
, 0, 0, 0, /* CMPP3 */
212 3+DR_F
, RW
, AB
, WL
, 0, 0, 0, /* CVTPL */
213 4+DR_F
, RW
, AB
, RW
, AB
, 0, 0, /* CMPP4 */
214 4+DR_F
, RW
, AB
, AB
, AB
, 0, 0, /* EDITPC */
215 4+DR_F
, RW
, AB
, RW
, AB
, 0, 0, /* MATCHC */
216 3+DR_F
, RB
, RW
, AB
, 0, 0, 0, /* LOCC */
217 3+DR_F
, RB
, RW
, AB
, 0, 0, 0, /* SKPC */
218 2, RW
, WL
, 0, 0, 0, 0, /* MOVZWL */
219 4, RW
, RW
, MW
, BW
, 0, 0, /* ACBW */
220 2, AW
, WL
, 0, 0, 0, 0, /* MOVAW */
221 1, AW
, 0, 0, 0, 0, 0, /* PUSHAW */
222 2, RF
, ML
, 0, 0, 0, 0, /* ADDF2 */
223 3, RF
, RF
, WL
, 0, 0, 0, /* ADDF3 */
224 2, RF
, ML
, 0, 0, 0, 0, /* SUBF2 */
225 3, RF
, RF
, WL
, 0, 0, 0, /* SUBF3 */
226 2, RF
, ML
, 0, 0, 0, 0, /* MULF2 */
227 3, RF
, RF
, WL
, 0, 0, 0, /* MULF3 */
228 2, RF
, ML
, 0, 0, 0, 0, /* DIVF2 */
229 3, RF
, RF
, WL
, 0, 0, 0, /* DIVF3 */
230 2, RF
, WB
, 0, 0, 0, 0, /* CVTFB */
231 2, RF
, WW
, 0, 0, 0, 0, /* CVTFW */
232 2, RF
, WL
, 0, 0, 0, 0, /* CVTFL */
233 2, RF
, WL
, 0, 0, 0, 0, /* CVTRFL */
234 2, RB
, WL
, 0, 0, 0, 0, /* CVTBF */
235 2, RW
, WL
, 0, 0, 0, 0, /* CVTWF */
236 2, RL
, WL
, 0, 0, 0, 0, /* CVTLF */
237 4, RF
, RF
, ML
, BW
, 0, 0, /* ACBF */
238 2, RF
, WL
, 0, 0, 0, 0, /* MOVF */
239 2, RF
, RF
, 0, 0, 0, 0, /* CMPF */
240 2, RF
, WL
, 0, 0, 0, 0, /* MNEGF */
241 1, RF
, 0, 0, 0, 0, 0, /* TSTF */
242 5, RF
, RB
, RF
, WL
, WL
, 0, /* EMODF */
243 3, RF
, RW
, AB
, 0, 0, 0, /* POLYF */
244 2, RF
, WQ
, 0, 0, 0, 0, /* CVTFD */
245 0, 0, 0, 0, 0, 0, 0, /* reserved */
246 2, RW
, WW
, 0, 0, 0, 0, /* ADAWI */
247 0, 0, 0, 0, 0, 0, 0, /* reserved */
248 0, 0, 0, 0, 0, 0, 0, /* reserved */
249 0, 0, 0, 0, 0, 0, 0, /* reserved */
250 2, AB
, AQ
, 0, 0, 0, 0, /* INSQHI */
251 2, AB
, AQ
, 0, 0, 0, 0, /* INSQTI */
252 2, AQ
, WL
, 0, 0, 0, 0, /* REMQHI */
253 2, AQ
, WL
, 0, 0, 0, 0, /* REMQTI */
254 2, RD
, MQ
, 0, 0, 0, 0, /* ADDD2 */
255 3, RD
, RD
, WQ
, 0, 0, 0, /* ADDD3 */
256 2, RD
, MQ
, 0, 0, 0, 0, /* SUBD2 */
257 3, RD
, RD
, WQ
, 0, 0, 0, /* SUBD3 */
258 2, RD
, MQ
, 0, 0, 0, 0, /* MULD2 */
259 3, RD
, RD
, WQ
, 0, 0, 0, /* MULD3 */
260 2, RD
, MQ
, 0, 0, 0, 0, /* DIVD2 */
261 3, RD
, RD
, WQ
, 0, 0, 0, /* DIVD3 */
262 2, RD
, WB
, 0, 0, 0, 0, /* CVTDB */
263 2, RD
, WW
, 0, 0, 0, 0, /* CVTDW */
264 2, RD
, WL
, 0, 0, 0, 0, /* CVTDL */
265 2, RD
, WL
, 0, 0, 0, 0, /* CVTRDL */
266 2, RB
, WQ
, 0, 0, 0, 0, /* CVTBD */
267 2, RW
, WQ
, 0, 0, 0, 0, /* CVTWD */
268 2, RL
, WQ
, 0, 0, 0, 0, /* CVTLD */
269 4, RD
, RD
, MQ
, BW
, 0, 0, /* ACBD */
270 2, RD
, WQ
, 0, 0, 0, 0, /* MOVD */
271 2, RD
, RD
, 0, 0, 0, 0, /* CMPD */
272 2, RD
, WQ
, 0, 0, 0, 0, /* MNEGD */
273 1, RD
, 0, 0, 0, 0, 0, /* TSTD */
274 5, RD
, RB
, RD
, WL
, WQ
, 0, /* EMODD */
275 3, RD
, RW
, AB
, 0, 0, 0, /* POLYD */
276 2, RD
, WL
, 0, 0, 0, 0, /* CVTDF */
277 0, 0, 0, 0, 0, 0, 0, /* reserved */
278 3, RB
, RL
, WL
, 0, 0, 0, /* ASHL */
279 3, RB
, RQ
, WQ
, 0, 0, 0, /* ASHQ */
280 4, RL
, RL
, RL
, WQ
, 0, 0, /* EMUL */
281 4, RL
, RQ
, WL
, WL
, 0, 0, /* EDIV */
282 1, WQ
, 0, 0, 0, 0, 0, /* CLRQ */
283 2, RQ
, WQ
, 0, 0, 0, 0, /* MOVQ */
284 2, AQ
, WL
, 0, 0, 0, 0, /* MOVAQ */
285 1, AQ
, 0, 0, 0, 0, 0, /* PUSHAQ */
286 2, RB
, MB
, 0, 0, 0, 0, /* ADDB2 */
287 3, RB
, RB
, WB
, 0, 0, 0, /* ADDB3 */
288 2, RB
, MB
, 0, 0, 0, 0, /* SUBB2 */
289 3, RB
, RB
, WB
, 0, 0, 0, /* SUBB3 */
290 2, RB
, MB
, 0, 0, 0, 0, /* MULB2 */
291 3, RB
, RB
, WB
, 0, 0, 0, /* MULB3 */
292 2, RB
, MB
, 0, 0, 0, 0, /* DIVB2 */
293 3, RB
, RB
, WB
, 0, 0, 0, /* DIVB3 */
294 2, RB
, MB
, 0, 0, 0, 0, /* BISB2 */
295 3, RB
, RB
, WB
, 0, 0, 0, /* BISB3 */
296 2, RB
, MB
, 0, 0, 0, 0, /* BICB2 */
297 3, RB
, RB
, WB
, 0, 0, 0, /* BICB3 */
298 2, RB
, MB
, 0, 0, 0, 0, /* XORB2 */
299 3, RB
, RB
, WB
, 0, 0, 0, /* XORB3 */
300 2, RB
, WB
, 0, 0, 0, 0, /* MNEGB */
301 3, RB
, RB
, RB
, 0, 0, 0, /* CASEB */
302 2, RB
, WB
, 0, 0, 0, 0, /* MOVB */
303 2, RB
, RB
, 0, 0, 0, 0, /* CMPB */
304 2, RB
, WB
, 0, 0, 0, 0, /* MCOMB */
305 2, RB
, RB
, 0, 0, 0, 0, /* BITB */
306 1, WB
, 0, 0, 0, 0, 0, /* CLRB */
307 1, RB
, 0, 0, 0, 0, 0, /* TSTB */
308 1, MB
, 0, 0, 0, 0, 0, /* INCB */
309 1, MB
, 0, 0, 0, 0, 0, /* DECB */
310 2, RB
, WL
, 0, 0, 0, 0, /* CVTBL */
311 2, RB
, WW
, 0, 0, 0, 0, /* CVTBW */
312 2, RB
, WL
, 0, 0, 0, 0, /* MOVZBL */
313 2, RB
, WW
, 0, 0, 0, 0, /* MOVZBW */
314 3, RB
, RL
, WL
, 0, 0, 0, /* ROTL */
315 4, RB
, RB
, MB
, BW
, 0, 0, /* ACBB */
316 2, AB
, WL
, 0, 0, 0, 0, /* MOVAB */
317 1, AB
, 0, 0, 0, 0, 0, /* PUSHAB */
318 2, RW
, MW
, 0, 0, 0, 0, /* ADDW2 */
319 3, RW
, RW
, WW
, 0, 0, 0, /* ADDW3 */
320 2, RW
, MW
, 0, 0, 0, 0, /* SUBW2 */
321 3, RW
, RW
, WW
, 0, 0, 0, /* SUBW3 */
322 2, RW
, MW
, 0, 0, 0, 0, /* MULW2 */
323 3, RW
, RW
, WW
, 0, 0, 0, /* MULW3 */
324 2, RW
, MW
, 0, 0, 0, 0, /* DIVW2 */
325 3, RW
, RW
, WW
, 0, 0, 0, /* DIVW3 */
326 2, RW
, MW
, 0, 0, 0, 0, /* BISW2 */
327 3, RW
, RW
, WW
, 0, 0, 0, /* BISW3 */
328 2, RW
, MW
, 0, 0, 0, 0, /* BICW2 */
329 3, RW
, RW
, WW
, 0, 0, 0, /* BICW3 */
330 2, RW
, MW
, 0, 0, 0, 0, /* XORW2 */
331 3, RW
, RW
, WW
, 0, 0, 0, /* XORW3 */
332 2, RW
, WW
, 0, 0, 0, 0, /* MNEGW */
333 3, RW
, RW
, RW
, 0, 0, 0, /* CASEW */
334 2, RW
, WW
, 0, 0, 0, 0, /* MOVW */
335 2, RW
, RW
, 0, 0, 0, 0, /* CMPW */
336 2, RW
, WW
, 0, 0, 0, 0, /* MCOMW */
337 2, RW
, RW
, 0, 0, 0, 0, /* BITW */
338 1, WW
, 0, 0, 0, 0, 0, /* CLRW */
339 1, RW
, 0, 0, 0, 0, 0, /* TSTW */
340 1, MW
, 0, 0, 0, 0, 0, /* INCW */
341 1, MW
, 0, 0, 0, 0, 0, /* DECW */
342 1, RW
, 0, 0, 0, 0, 0, /* BISPSW */
343 1, RW
, 0, 0, 0, 0, 0, /* BICPSW */
344 1, RW
, 0, 0, 0, 0, 0, /* POPR */
345 1, RW
, 0, 0, 0, 0, 0, /* PUSHR */
346 1, RW
, 0, 0, 0, 0, 0, /* CHMK */
347 1, RW
, 0, 0, 0, 0, 0, /* CHME */
348 1, RW
, 0, 0, 0, 0, 0, /* CHMS */
349 1, RW
, 0, 0, 0, 0, 0, /* CHMU */
350 2, RL
, ML
, 0, 0, 0, 0, /* ADDL2 */
351 3, RL
, RL
, WL
, 0, 0, 0, /* ADDL3 */
352 2, RL
, ML
, 0, 0, 0, 0, /* SUBL2 */
353 3, RL
, RL
, WL
, 0, 0, 0, /* SUBL3 */
354 2, RL
, ML
, 0, 0, 0, 0, /* MULL2 */
355 3, RL
, RL
, WL
, 0, 0, 0, /* MULL3 */
356 2, RL
, ML
, 0, 0, 0, 0, /* DIVL2 */
357 3, RL
, RL
, WL
, 0, 0, 0, /* DIVL3 */
358 2, RL
, ML
, 0, 0, 0, 0, /* BISL2 */
359 3, RL
, RL
, WL
, 0, 0, 0, /* BISL3 */
360 2, RL
, ML
, 0, 0, 0, 0, /* BICL2 */
361 3, RL
, RL
, WL
, 0, 0, 0, /* BICL3 */
362 2, RL
, ML
, 0, 0, 0, 0, /* XORL2 */
363 3, RL
, RL
, WL
, 0, 0, 0, /* XORL3 */
364 2, RL
, WL
, 0, 0, 0, 0, /* MNEGL */
365 3, RL
, RL
, RL
, 0, 0, 0, /* CASEL */
366 2, RL
, WL
, 0, 0, 0, 0, /* MOVL */
367 2, RL
, RL
, 0, 0, 0, 0, /* CMPL */
368 2, RL
, WL
, 0, 0, 0, 0, /* MCOML */
369 2, RL
, RL
, 0, 0, 0, 0, /* BITL */
370 1, WL
, 0, 0, 0, 0, 0, /* CLRL */
371 1, RL
, 0, 0, 0, 0, 0, /* TSTL */
372 1, ML
, 0, 0, 0, 0, 0, /* INCL */
373 1, ML
, 0, 0, 0, 0, 0, /* DECL */
374 2, RL
, ML
, 0, 0, 0, 0, /* ADWC */
375 2, RL
, ML
, 0, 0, 0, 0, /* SBWC */
376 2, RL
, RL
, 0, 0, 0, 0, /* MTPR */
377 2, RL
, WL
, 0, 0, 0, 0, /* MFPR */
378 1, WL
, 0, 0, 0, 0, 0, /* MOVPSL */
379 1, RL
, 0, 0, 0, 0, 0, /* PUSHL */
380 2, AL
, WL
, 0, 0, 0, 0, /* MOVAL */
381 1, AL
, 0, 0, 0, 0, 0, /* PUSHAL */
382 3, RL
, VB
, BB
, 0, 0, 0, /* BBS */
383 3, RL
, VB
, BB
, 0, 0, 0, /* BBC */
384 3, RL
, VB
, BB
, 0, 0, 0, /* BBSS */
385 3, RL
, VB
, BB
, 0, 0, 0, /* BBCS */
386 3, RL
, VB
, BB
, 0, 0, 0, /* BBSC */
387 3, RL
, VB
, BB
, 0, 0, 0, /* BBCC */
388 3, RL
, VB
, BB
, 0, 0, 0, /* BBSSI */
389 3, RL
, VB
, BB
, 0, 0, 0, /* BBCCI */
390 2, RL
, BB
, 0, 0, 0, 0, /* BLBS */
391 2, RL
, BB
, 0, 0, 0, 0, /* BLBC */
392 4, RL
, RB
, VB
, WL
, 0, 0, /* FFS */
393 4, RL
, RB
, VB
, WL
, 0, 0, /* FFC */
394 4, RL
, RB
, VB
, RL
, 0, 0, /* CMPV */
395 4, RL
, RB
, VB
, RL
, 0, 0, /* CMPZV */
396 4, RL
, RB
, VB
, WL
, 0, 0, /* EXTV */
397 4, RL
, RB
, VB
, WL
, 0, 0, /* EXTZV */
398 4, RL
, RL
, RB
, VB
, 0, 0, /* INSV */
399 4, RL
, RL
, ML
, BW
, 0, 0, /* ACBL */
400 3, RL
, ML
, BB
, 0, 0, 0, /* AOBLSS */
401 3, RL
, ML
, BB
, 0, 0, 0, /* AOBLEQ */
402 2, ML
, BB
, 0, 0, 0, 0, /* SOBGEQ */
403 2, ML
, BB
, 0, 0, 0, 0, /* SOBGTR */
404 2, RL
, WB
, 0, 0, 0, 0, /* CVTLB */
405 2, RL
, WW
, 0, 0, 0, 0, /* CVTLW */
406 6+DR_F
, RB
, RW
, AB
, RB
, RW
, AB
, /* ASHP */
407 3+DR_F
, RL
, RW
, AB
, 0, 0, 0, /* CVTLP */
408 2, AB
, AB
, 0, 0, 0, 0, /* CALLG */
409 2, RL
, AB
, 0, 0, 0, 0, /* CALLS */
410 0, 0, 0, 0, 0, 0, 0, /* XFC */
411 0, 0, 0, 0, 0, 0, 0, /* 0FD */
412 0, 0, 0, 0, 0, 0, 0, /* 0FE */
413 0, 0, 0, 0, 0, 0, 0, /* 0FF */
414 0, 0, 0, 0, 0, 0, 0, /* 100-10F */
430 0, 0, 0, 0, 0, 0, 0, /* 110-11F */
446 0, 0, 0, 0, 0, 0, 0, /* 120-12F */
462 0, 0, 0, 0, 0, 0, 0, /* 130-13F */
464 ODC(2), RD
, WO
, 0, 0, 0, 0, /* CVTDH */
465 2, RG
, WL
, 0, 0, 0, 0, /* CVTGF */
478 2, RG
, MQ
, 0, 0, 0, 0, /* ADDG2 */
479 3, RG
, RG
, WQ
, 0, 0, 0, /* ADDG3 */
480 2, RG
, MQ
, 0, 0, 0, 0, /* SUBG2 */
481 3, RG
, RG
, WQ
, 0, 0, 0, /* SUBG3 */
482 2, RG
, MQ
, 0, 0, 0, 0, /* MULG2 */
483 3, RG
, RG
, WQ
, 0, 0, 0, /* MULG3 */
484 2, RG
, MQ
, 0, 0, 0, 0, /* DIVG2 */
485 3, RG
, RG
, WQ
, 0, 0, 0, /* DIVG3 */
486 2, RG
, WB
, 0, 0, 0, 0, /* CVTGB */
487 2, RG
, WW
, 0, 0, 0, 0, /* CVTGW */
488 2, RG
, WL
, 0, 0, 0, 0, /* CVTGL */
489 2, RG
, WL
, 0, 0, 0, 0, /* CVTRGL */
490 2, RB
, WQ
, 0, 0, 0, 0, /* CVTBG */
491 2, RW
, WQ
, 0, 0, 0, 0, /* CVTWG */
492 2, RL
, WQ
, 0, 0, 0, 0, /* CVTLG */
493 4, RG
, RG
, MQ
, BW
, 0, 0, /* ACBG */
494 2, RG
, WQ
, 0, 0, 0, 0, /* MOVG */
495 2, RG
, RG
, 0, 0, 0, 0, /* CMPG */
496 2, RG
, WQ
, 0, 0, 0, 0, /* MNEGG */
497 1, RG
, 0, 0, 0, 0, 0, /* TSTG */
498 5, RG
, RW
, RG
, WL
, WQ
, 0, /* EMODG */
499 3, RG
, RW
, AB
, 0, 0, 0, /* POLYG */
500 ODC(2), RG
, WO
, 0, 0, 0, 0, /* CVTGH */
501 0, 0, 0, 0, 0, 0, 0, /* reserved */
502 0, 0, 0, 0, 0, 0, 0, /* reserved */
503 0, 0, 0, 0, 0, 0, 0, /* reserved */
504 0, 0, 0, 0, 0, 0, 0, /* reserved */
505 0, 0, 0, 0, 0, 0, 0, /* reserved */
506 0, 0, 0, 0, 0, 0, 0, /* reserved */
507 0, 0, 0, 0, 0, 0, 0, /* reserved */
508 0, 0, 0, 0, 0, 0, 0, /* reserved */
509 0, 0, 0, 0, 0, 0, 0, /* reserved */
510 ODC(2), RH
, MO
, 0, 0, 0, 0, /* ADDH2 */
511 ODC(3), RH
, RH
, WO
, 0, 0, 0, /* ADDH3 */
512 ODC(2), RH
, MO
, 0, 0, 0, 0, /* SUBH2 */
513 ODC(3), RH
, RH
, WO
, 0, 0, 0, /* SUBH3 */
514 ODC(2), RH
, MO
, 0, 0, 0, 0, /* MULH2 */
515 ODC(3), RH
, RH
, WO
, 0, 0, 0, /* MULH3 */
516 ODC(2), RH
, MO
, 0, 0, 0, 0, /* DIVH2 */
517 ODC(3), RH
, RH
, WO
, 0, 0, 0, /* DIVH3 */
518 ODC(2), RH
, WB
, 0, 0, 0, 0, /* CVTHB */
519 ODC(2), RH
, WW
, 0, 0, 0, 0, /* CVTHW */
520 ODC(2), RH
, WL
, 0, 0, 0, 0, /* CVTHL */
521 ODC(2), RH
, WL
, 0, 0, 0, 0, /* CVTRHL */
522 ODC(2), RB
, WO
, 0, 0, 0, 0, /* CVTBH */
523 ODC(2), RW
, WO
, 0, 0, 0, 0, /* CVTWH */
524 ODC(2), RL
, WO
, 0, 0, 0, 0, /* CVTLH */
525 ODC(4), RH
, RH
, MO
, BW
, 0, 0, /* ACBH */
526 ODC(2), RH
, RO
, 0, 0, 0, 0, /* MOVH */
527 ODC(2), RH
, RH
, 0, 0, 0, 0, /* CMPH */
528 ODC(2), RH
, WO
, 0, 0, 0, 0, /* MNEGH */
529 ODC(1), RH
, 0, 0, 0, 0, 0, /* TSTH */
530 ODC(5), RH
, RW
, RH
, WL
, WO
, 0, /* EMODH */
531 ODC(3), RH
, RW
, AB
, 0, 0, 0, /* POLYH */
532 ODC(2), RH
, WQ
, 0, 0, 0, 0, /* CVTHG */
533 0, 0, 0, 0, 0, 0, 0, /* reserved */
534 0, 0, 0, 0, 0, 0, 0, /* reserved */
535 0, 0, 0, 0, 0, 0, 0, /* reserved */
536 0, 0, 0, 0, 0, 0, 0, /* reserved */
537 0, 0, 0, 0, 0, 0, 0, /* reserved */
538 ODC(1), WO
, 0, 0, 0, 0, 0, /* CLRO */
539 ODC(2), RO
, RO
, 0, 0, 0, 0, /* MOVO */
540 ODC(2), AO
, WL
, 0, 0, 0, 0, /* MOVAO*/
541 ODC(1), AO
, 0, 0, 0, 0, 0, /* PUSHAO*/
542 0, 0, 0, 0, 0, 0, 0, /* 180-18F */
558 0, 0, 0, 0, 0, 0, 0, /* 190-19F */
566 ODC(2), RF
, WO
, 0, 0, 0, 0, /* CVTFH */
567 2, RF
, WQ
, 0, 0, 0, 0, /* CVTFG */
574 0, 0, 0, 0, 0, 0, 0, /* 1A0-1AF */
590 0, 0, 0, 0, 0, 0, 0, /* 1B0-1BF */
606 0, 0, 0, 0, 0, 0, 0, /* 1C0-1CF */
622 0, 0, 0, 0, 0, 0, 0, /* 1D0-1DF */
638 0, 0, 0, 0, 0, 0, 0, /* 1E0-1EF */
654 0, 0, 0, 0, 0, 0, 0, /* 1F0-1FF */
660 ODC(2), RH
, WL
, 0, 0, 0, 0, /* CVTHF */
661 ODC(2), RH
, WQ
, 0, 0, 0, 0, /* CVTHD */
672 /* Opcode mnemonics table */
674 const char *opcode
[] = {
675 "HALT", "NOP", "REI", "BPT", "RET", "RSB", "LDPCTX", "SVPCTX",
676 "CVTPS", "CVTSP", "INDEX", "CRC", "PROBER", "PROBEW", "INSQUE", "REMQUE",
677 "BSBB", "BRB", "BNEQ", "BEQL", "BGTR", "BLEQ", "JSB", "JMP",
678 "BGEQ", "BLSS", "BGTRU", "BLEQU", "BVC", "BVS", "BGEQU", "BLSSU",
679 "ADDP4", "ADDP6", "SUBP4", "SUBP6", "CVTPT", "MULP", "CVTTP", "DIVP",
680 "MOVC3", "CMPC3", "SCANC", "SPANC", "MOVC5", "CMPC5", "MOVTC", "MOVTUC",
681 "BSBW", "BRW", "CVTWL", "CVTWB", "MOVP", "CMPP3", "CVTPL", "CMPP4",
682 "EDITPC", "MATCHC", "LOCC", "SKPC", "MOVZWL", "ACBW", "MOVAW", "PUSHAW",
683 "ADDF2", "ADDF3", "SUBF2", "SUBF3", "MULF2", "MULF3", "DIVF2", "DIVF3",
684 "CVTFB", "CVTFW", "CVTFL", "CVTRFL", "CVTBF", "CVTWF", "CVTLF", "ACBF",
685 "MOVF", "CMPF", "MNEGF", "TSTF", "EMODF", "POLYF", "CVTFD", NULL
,
686 "ADAWI", NULL
, NULL
, NULL
, "INSQHI", "INSQTI", "REMQHI", "REMQTI",
687 "ADDD2", "ADDD3", "SUBD2", "SUBD3", "MULD2", "MULD3", "DIVD2", "DIVD3",
688 "CVTDB", "CVTDW", "CVTDL", "CVTRDL", "CVTBD", "CVTWD", "CVTLD", "ACBD",
689 "MOVD", "CMPD", "MNEGD", "TSTD", "EMODD", "POLYD", "CVTDF", NULL
,
690 "ASHL", "ASHQ", "EMUL", "EDIV", "CLRQ", "MOVQ", "MOVAQ", "PUSHAQ",
691 "ADDB2", "ADDB3", "SUBB2", "SUBB3", "MULB2", "MULB3", "DIVB2", "DIVB3",
692 "BISB2", "BISB3", "BICB2", "BICB3", "XORB2", "XORB3", "MNEGB", "CASEB",
693 "MOVB", "CMPB", "MCOMB", "BITB", "CLRB", "TSTB", "INCB", "DECB",
694 "CVTBL", "CVTBW", "MOVZBL", "MOVZBW", "ROTL", "ACBB", "MOVAB", "PUSHAB",
695 "ADDW2", "ADDW3", "SUBW2", "SUBW3", "MULW2", "MULW3", "DIVW2", "DIVW3",
696 "BISW2", "BISW3", "BICW2", "BICW3", "XORW2", "XORW3", "MNEGW", "CASEW",
697 "MOVW", "CMPW", "MCOMW", "BITW", "CLRW", "TSTW", "INCW", "DECW",
698 "BISPSW", "BICPSW", "POPR", "PUSHR", "CHMK", "CHME", "CHMS", "CHMU",
699 "ADDL2", "ADDL3", "SUBL2", "SUBL3", "MULL2", "MULL3", "DIVL2", "DIVL3",
700 "BISL2", "BISL3", "BICL2", "BICL3", "XORL2", "XORL3", "MNEGL", "CASEL",
701 "MOVL", "CMPL", "MCOML", "BITL", "CLRL", "TSTL", "INCL", "DECL",
702 "ADWC", "SBWC", "MTPR", "MFPR", "MOVPSL", "PUSHL", "MOVAL", "PUSHAL",
703 "BBS", "BBC", "BBSS", "BBCS", "BBSC", "BBCC", "BBSSI", "BBCCI",
704 "BLBS", "BLBC", "FFS", "FFC", "CMPV", "CMPZV", "EXTV", "EXTZV",
705 "INSV", "ACBL", "AOBLSS", "AOBLEQ", "SOBGEQ", "SOBGTR", "CVTLB", "CVTLW",
706 "ASHP", "CVTLP", "CALLG", "CALLS", "XFC", NULL
, NULL
, NULL
,
707 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 100 - 11F */
708 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
709 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
710 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
711 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 120 - 13F */
712 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
713 NULL
, NULL
, "CVTDH", "CVTGF", NULL
, NULL
, NULL
, NULL
,
714 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
715 "ADDG2", "ADDG3", "SUBG2", "SUBG3", "MULG2", "MULG3", "DIVG2", "DIVG3",
716 "CVTGB", "CVTGW", "CVTGL", "CVTRGL", "CVTBG", "CVTWG", "CVTLG", "ACBG",
717 "MOVG", "CMPG", "MNEGG", "TSTG", "EMODG", "POLYG", "CVTGH", NULL
,
718 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
719 "ADDH2", "ADDH3", "SUBH2", "SUBH3", "MULH2", "MULH3", "DIVH2", "DIVH3",
720 "CVTHB", "CVTHW", "CVTHL", "CVTRHL", "CVTBH", "CVTWH", "CVTLH", "ACBH",
721 "MOVH", "CMPH", "MNEGH", "TSTH", "EMODH", "POLYH", "CVTHG", NULL
,
722 NULL
, NULL
, NULL
, NULL
, "CLRO", "MOVO", "MOVAO", "PUSHAO",
723 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 180 - 19F */
724 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
725 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
726 "CVTFH", "CVTFG", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
727 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 1A0 - 1BF */
728 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
729 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
730 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
731 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 1C0 - 1DF */
732 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
733 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
734 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
735 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 1E0 - 1FF */
736 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
737 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, "CVTHF", "CVTHD",
738 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
741 const char *altcod
[] = {
742 "CLRF", "CLRD", "CLRG", "CLRH", "MOVAF", "MOVAD", "MOVAG", "MOVAH",
743 "PUSHAF", "PUSHAD", "PUSHAG", "PUSHAH", "BNEQU", "BEQLU", "BCC", "BCS",
747 const int32 altop
[] = {
748 0xD4, 0x7C, 0x7C, 0x17C, 0xDE, 0x7E, 0x7E, 0x17E,
749 0xDF, 0x7F, 0x7F, 0x17F, 0x12, 0x13, 0x1E, 0x1F
752 const char* regname
[] = {
753 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
754 "R8", "R9", "R10", "R11", "AP", "FP", "SP", "PC"
757 #define GETNUM(d,n) for (k = d = 0; k < n; k++) \
758 d = d | (((int32) val[vp++]) << (k * 8))
765 *val = values to decode
766 *uptr = pointer to unit
769 return = if >= 0, error code
770 if < 0, number of extra bytes retired
773 t_stat
fprint_sym (FILE *of
, t_addr exta
, t_value
*val
,
774 UNIT
*uptr
, int32 sw
)
776 uint32 addr
= (uint32
) exta
;
777 int32 c
, k
, num
, vp
, lnt
, rdx
;
781 if (uptr
== NULL
) uptr
= &cpu_unit
; /* anon = CPU */
782 if ((sw
& SIM_SW_STOP
) && (PSL
& PSL_CM
)) /* stop in CM? */
783 sw
= sw
| SWMASK ('P'); /* force CM print */
784 dptr
= find_dev_from_unit (uptr
); /* find dev */
785 if (dptr
== NULL
) return SCPE_IERR
;
786 if (dptr
->dwidth
!= 8) return SCPE_ARG
; /* byte dev only */
787 if (sw
& SWMASK ('B')) lnt
= 1; /* get length */
788 else if (sw
& SWMASK ('W')) lnt
= 2;
789 else if (sw
& SWMASK ('L')) lnt
= 4;
790 else lnt
= (uptr
== &cpu_unit
)? 4: 1;
791 if (sw
& SWMASK ('D')) rdx
= 10; /* get radix */
792 else if (sw
& SWMASK ('O')) rdx
= 8;
793 else if (sw
& SWMASK ('H')) rdx
= 16;
794 else rdx
= dptr
->dradix
;
795 if ((sw
& SWMASK ('A')) || (sw
& SWMASK ('C'))) { /* char format? */
796 for (vp
= lnt
- 1; vp
>= 0; vp
--) {
797 c
= (int32
) val
[vp
] & 0x7F;
798 fprintf (of
, (c
< 0x20)? "<%02X>": "%c", c
);
800 return -(lnt
- 1); /* return # chars */
803 if ((sw
& (SWMASK ('P') | SWMASK ('R'))) && /* cmode or rad50? */
804 (uptr
== &cpu_unit
)) {
805 r
= fprint_sym_cm (of
, addr
, val
, sw
); /* decode inst */
806 if (r
<= 0) return r
;
809 if ((sw
& SWMASK ('M')) && (uptr
== &cpu_unit
)) { /* inst format? */
810 r
= fprint_sym_m (of
, addr
, val
); /* decode inst */
811 if (r
<= 0) return r
;
814 vp
= 0; /* init ptr */
815 GETNUM (num
, lnt
); /* get number */
816 fprint_val (of
, (uint32
) num
, rdx
, lnt
* 8, PV_RZRO
);
820 /* Symbolic decode for -m
825 *val = values to decode
827 return = if >= 0, error code
828 if < 0, number of extra bytes retired
831 t_stat
fprint_sym_m (FILE *of
, uint32 addr
, t_value
*val
)
833 int32 i
, k
, vp
, inst
, numspec
;
834 int32 num
, spec
, rn
, disp
, index
;
836 vp
= 0; /* init ptr */
837 inst
= (int32
) val
[vp
++]; /* get opcode */
838 if (inst
== 0xFD) inst
= 0x100 | (int32
) val
[vp
++]; /* 2 byte op? */
839 if (opcode
[inst
] == NULL
) return SCPE_ARG
; /* defined? */
840 numspec
= DR_GETNSP (drom
[inst
][0]); /* get # spec */
841 if (numspec
== 0) numspec
= DR_GETUSP (drom
[inst
][0]);
842 fprintf (of
, "%s", opcode
[inst
]); /* print name */
843 for (i
= 0; i
< numspec
; i
++) { /* loop thru spec */
844 fputc (i
? ',': ' ', of
); /* separator */
845 disp
= drom
[inst
][i
+ 1]; /* get drom value */
846 if (disp
== BB
) { /* byte br disp? */
848 fprintf (of
, "%-X", SXTB (num
) + addr
+ vp
);
850 else if (disp
== BW
) { /* word br disp? */
852 fprintf (of
, "%-X", SXTW (num
) + addr
+ vp
);
855 spec
= (int32
) val
[vp
++]; /* get specifier */
856 if ((spec
& 0xF0) == IDX
) { /* index? */
857 index
= spec
; /* copy, get next */
858 spec
= (int32
) val
[vp
++];
861 rn
= spec
& 0xF; /* get reg # */
862 switch (spec
& 0xF0) { /* case on mode */
864 case SH0
: case SH1
: case SH2
: case SH3
: /* s^# */
865 fprintf (of
, "#%-X", spec
);
869 fprintf (of
, "%-s", regname
[rn
]);
873 fprintf (of
, "(%-s)", regname
[rn
]);
876 case ADC
: /* -(Rn) */
877 fprintf (of
, "-(%-s)", regname
[rn
]);
880 case AIN
: /* (Rn)+, #n */
881 if (rn
!= nPC
) fprintf (of
, "(%-s)+", regname
[rn
]);
883 if (DR_LNT (disp
) == L_OCTA
)
884 vp
= fprint_sym_qoimm (of
, val
, vp
, 4);
885 else if (DR_LNT (disp
) == L_QUAD
)
886 vp
= fprint_sym_qoimm (of
, val
, vp
, 2);
888 GETNUM (num
, DR_LNT (disp
));
889 fprintf (of
, "#%-X", num
);
894 case AID
: /* @(Rn)+, @#n */
895 if (rn
!= nPC
) fprintf (of
, "@(%-s)+", regname
[rn
]);
898 fprintf (of
, "@#%-X", num
);
902 case BDD
: /* @b^d(r),@b^n */
904 case BDP
: /* b^d(r), b^n */
906 if (rn
== nPC
) fprintf (of
, "%-X", addr
+ vp
+ SXTB (num
));
907 else if (num
& BSIGN
) fprintf (of
, "-%-X(%-s)",
908 -num
& BMASK
, regname
[rn
]);
909 else fprintf (of
, "%-X(%-s)", num
, regname
[rn
]);
912 case WDD
: /* @w^d(r),@w^n */
914 case WDP
: /* w^d(r), w^n */
916 if (rn
== nPC
) fprintf (of
, "%-X", addr
+ vp
+ SXTW (num
));
917 else if (num
& WSIGN
) fprintf (of
, "-%-X(%-s)",
918 -num
& WMASK
, regname
[rn
]);
919 else fprintf (of
, "%-X(%-s)", num
, regname
[rn
]);
922 case LDD
: /* @l^d(r),@l^n */
924 case LDP
: /* l^d(r),l^n */
926 if (rn
== nPC
) fprintf (of
, "%-X", addr
+ vp
+ num
);
927 else if (num
& LSIGN
) fprintf (of
, "-%-X(%-s)",
929 else fprintf (of
, "%-X(%-s)", num
, regname
[rn
]);
932 if (index
) fprintf (of
, "[%-s]", regname
[index
& 0xF]);
938 /* Symbolic decode, quad/octa immediates
942 *val = pointer to input values
943 vp = current index into val
944 lnt = number of longwords in immediate
946 vp = updated index into val
949 int32
fprint_sym_qoimm (FILE *of
, t_value
*val
, int32 vp
, int32 lnt
)
951 int32 i
, k
, startp
, num
[4];
953 for (i
= 0; i
< lnt
; i
++) { GETNUM (num
[lnt
- 1 - i
], 4); }
954 for (i
= startp
= 0; i
< lnt
; i
++) {
955 if (startp
) fprintf (of
, "%08X", num
[i
]);
956 else if (num
[i
] || (i
== (lnt
- 1))) {
957 fprintf (of
, "#%-X", num
[i
]);
964 #define PUTNUM(d,n) for (k = 0; k < n; k++) val[vp++] = (d >> (k * 8)) & 0xFF
969 *cptr = pointer to input string
971 *uptr = pointer to unit
972 *val = pointer to output values
975 status = > 0 error code
976 <= 0 -number of extra words
979 t_stat
parse_sym (char *cptr
, t_addr exta
, UNIT
*uptr
, t_value
*val
, int32 sw
)
981 uint32 addr
= (uint32
) exta
;
982 int32 k
, rdx
, lnt
, num
, vp
;
985 static const uint32 maxv
[5] = { 0, 0xFF, 0xFFFF, 0, 0xFFFFFFFF };
987 if (uptr
== NULL
) uptr
= &cpu_unit
; /* anon = CPU */
988 dptr
= find_dev_from_unit (uptr
); /* find dev */
989 if (dptr
== NULL
) return SCPE_IERR
;
990 if (dptr
->dwidth
!= 8) return SCPE_ARG
; /* byte dev only */
991 if (sw
& SWMASK ('B')) lnt
= 1; /* get length */
992 else if (sw
& SWMASK ('W')) lnt
= 2;
993 else if (sw
& SWMASK ('L')) lnt
= 4;
994 else lnt
= (uptr
== &cpu_unit
)? 4: 1;
995 if (sw
& SWMASK ('D')) rdx
= 10; /* get radix */
996 else if (sw
& SWMASK ('O')) rdx
= 8;
997 else if (sw
& SWMASK ('H')) rdx
= 16;
998 else rdx
= dptr
->dradix
;
1000 if ((sw
& SWMASK ('A')) || ((*cptr
== '\'') && cptr
++)) /* ASCII char? */
1001 return parse_char (cptr
, val
, lnt
);
1002 if ((sw
& SWMASK ('C')) || ((*cptr
== '"') && cptr
++)) /* ASCII string? */
1003 return parse_char (cptr
, val
, sim_emax
);
1005 if ((sw
& (SWMASK ('P') | SWMASK ('R'))) && /* cmode or rad50? */
1006 (uptr
== &cpu_unit
)) {
1007 r
= parse_sym_cm (cptr
, addr
, val
, sw
); /* try to parse */
1008 if (r
<= 0) return r
;
1011 if (uptr
== &cpu_unit
) { /* cpu only */
1012 r
= parse_sym_m (cptr
, addr
, val
); /* try to parse inst */
1013 if (r
<= 0) return r
;
1016 num
= (int32
) get_uint (cptr
, rdx
, maxv
[lnt
], &r
); /* get number */
1017 if (r
!= SCPE_OK
) return r
;
1019 PUTNUM (num
, lnt
); /* store */
1023 /* Character input for -a or -c
1026 *cptr = pointer to input string
1028 *val = pointer to output values
1030 status = > 0 error code
1031 <= 0 -number of extra words
1034 t_stat
parse_char (char *cptr
, t_value
*val
, int32 lnt
)
1038 if (*cptr
== 0) return SCPE_ARG
;
1040 while ((vp
< lnt
) && *cptr
) { /* get chars */
1041 val
[vp
++] = *cptr
++;
1043 return -(vp
- 1); /* return # chars */
1046 /* Symbolic input for -m
1049 *cptr = pointer to input string
1051 *val = pointer to output values
1053 status = > 0 error code
1054 <= 0 -number of extra words
1057 t_stat
parse_sym_m (char *cptr
, uint32 addr
, t_value
*val
)
1059 int32 i
, numspec
, disp
, opc
, vp
;
1061 char gbuf
[CBUFSIZE
];
1063 cptr
= get_glyph (cptr
, gbuf
, 0); /* get opcode */
1064 for (i
= 0, opc
= -1; (i
< NUM_INST
) && (opc
< 0); i
++) {
1065 if (opcode
[i
] && strcmp (gbuf
, opcode
[i
]) == 0) opc
= i
;
1067 if (opc
< 0) { /* check alternates */
1068 for (i
= 0; altcod
[i
] && (opc
< 0); i
++) {
1069 if (strcmp (gbuf
, altcod
[i
]) == 0) opc
= altop
[i
];
1072 if (opc
< 0) return SCPE_ARG
; /* undefined? */
1074 if (opc
>= 0x100) val
[vp
++] = 0xFD; /* 2 byte? */
1075 val
[vp
++] = opc
& 0xFF; /* store opcode */
1076 numspec
= DR_GETNSP (drom
[opc
][0]); /* get # specifiers */
1077 if (numspec
== 0) numspec
= DR_GETUSP (drom
[opc
][0]);
1078 for (i
= 1; i
<= numspec
; i
++) { /* loop thru specs */
1079 if (i
== numspec
) cptr
= get_glyph (cptr
, gbuf
, 0);
1080 else cptr
= get_glyph (cptr
, gbuf
, ','); /* get specifier */
1081 disp
= drom
[opc
][i
]; /* get drom value */
1082 if (disp
== BB
) vp
= parse_brdisp (gbuf
, addr
, val
, vp
, 0, &r
);
1083 else if (disp
== BW
) vp
= parse_brdisp (gbuf
, addr
, val
, vp
, 1, &r
);
1084 else vp
= parse_spec (gbuf
, addr
, val
, vp
, disp
, &r
);
1085 if (r
!= SCPE_OK
) return r
;
1087 if (*cptr
!= 0) return SCPE_ARG
;
1091 /* Parse a branch displacement
1094 cptr = pointer to input buffer
1095 addr = current address
1096 val = pointer to output array
1097 vp = current pointer in output array
1098 lnt = length (0 = byte, 1 = word)
1099 r = pointer to status
1101 vp = updated output pointer
1104 int32
parse_brdisp (char *cptr
, uint32 addr
, t_value
*val
, int32 vp
,
1105 int32 lnt
, t_stat
*r
)
1109 dest
= (int32
) get_uint (cptr
, 16, 0xFFFFFFFF, r
); /* get value */
1110 num
= dest
- (addr
+ vp
+ lnt
+ 1); /* compute offset */
1111 if ((num
> (lnt
? 32767: 127)) || (num
< (lnt
? -32768: -128)))
1114 PUTNUM (num
, lnt
+ 1); /* store offset */
1120 /* Parse a specifier
1123 cptr = pointer to input buffer
1124 addr = current address
1125 val = pointer to output array
1126 vp = current pointer in output array
1127 disp = specifier dispatch
1128 r = pointer to status
1130 vp = updated output pointer
1133 #define SP_IND 0x200 /* indirect */
1134 #define SP_V_FORCE 6
1135 #define SP_FS 0x040 /* S^ */
1136 #define SP_FI 0x080 /* I^ */
1137 #define SP_FB 0x0C0 /* B^ */
1138 #define SP_FW 0x100 /* W^ */
1139 #define SP_FL 0x140 /* L^ */
1140 #define SP_LIT 0x020 /* # */
1141 #define SP_PLUS 0x010 /* plus */
1142 #define SP_MINUS 0x008 /* minus */
1143 #define SP_NUM 0x004 /* number */
1144 #define SP_IDX 0x002 /* (Rn) */
1145 #define SP_POSTP 0x001 /* trailing + */
1146 #define M1C(c,v) if (*cptr == c) { cptr++; fl = fl | v; }
1147 #define SPUTNUM(v,d) if (fl & SP_MINUS) v = -v; PUTNUM (v, d)
1148 #define PARSE_LOSE { *r = SCPE_ARG; return vp; }
1149 #define SEL_LIM(p,m,u) ((fl & SP_PLUS)? (p): ((fl & SP_MINUS)? (m): (u)))
1151 int32
parse_spec (char *cptr
, uint32 addr
, t_value
*val
, int32 vp
, int32 disp
, t_stat
*r
)
1153 int32 i
, k
, litsize
, rn
, index
;
1154 int32 num
, dispsize
, mode
;
1155 int32 lit
[4] = { 0 };
1158 const char *force
[] = { "S^", "I^", "B^", "W^", "L^", NULL
};
1160 *r
= SCPE_OK
; /* assume ok */
1161 M1C ('@', SP_IND
); /* look for @ */
1162 if (tptr
= parse_rnum (cptr
, &rn
)) { /* look for Rn */
1163 if (*cptr
== '[') { /* look for [Rx] */
1164 cptr
= parse_rnum (++cptr
, &index
);
1165 if ((cptr
== NULL
) || (*cptr
++ != ']')) PARSE_LOSE
;
1166 val
[vp
++] = index
| IDX
;
1168 else val
[vp
++] = rn
| GRN
| (fl
? 1: 0); /* Rn or @Rn */
1169 if (*tptr
!= 0) *r
= SCPE_ARG
; /* must be done */
1172 for (i
= 0; force
[i
]; i
++) { /* look for x^ */
1173 if (strncmp (cptr
, force
[i
], 2) == 0) {
1175 fl
= fl
| ((i
+ 1) << SP_V_FORCE
);
1179 M1C ('#', SP_LIT
); /* look for # */
1180 M1C ('+', SP_PLUS
); /* look for + */
1181 M1C ('-', SP_MINUS
); /* look for - */
1182 for (litsize
= 0;; cptr
++) { /* look for mprec int */
1184 if ((c
< '0') || (c
> 'F') || ((c
> '9') && (c
< 'A'))) break;
1185 num
= (c
<= '9')? c
- '0': c
- 'A' + 10;
1187 for (i
= 3; i
>= 0; i
--) {
1188 lit
[i
] = lit
[i
] << 4;
1189 if (i
> 0) lit
[i
] = lit
[i
] | ((lit
[i
- 1] >> 28) & 0xF);
1190 else lit
[i
] = lit
[i
] | num
;
1191 if (lit
[i
] && (i
> litsize
)) litsize
= i
;
1194 if (*cptr
== '(') { /* look for (Rn) */
1195 cptr
= parse_rnum (++cptr
, &rn
);
1196 if ((cptr
== NULL
) || (*cptr
++ != ')')) PARSE_LOSE
;
1199 M1C ('+', SP_POSTP
); /* look for + */
1200 if (*cptr
== '[') { /* look for [Rx] */
1201 cptr
= parse_rnum (++cptr
, &index
);
1202 if ((cptr
== NULL
) || (*cptr
++ != ']')) PARSE_LOSE
;
1203 val
[vp
++] = index
| IDX
;
1205 switch (fl
) { /* case on state */
1207 case SP_FS
|SP_LIT
|SP_NUM
: /* S^#n */
1208 case SP_FS
|SP_LIT
|SP_PLUS
|SP_NUM
: /* S^#+n */
1209 if ((litsize
> 0) || (lit
[0] & ~0x3F)) PARSE_LOSE
;
1213 case SP_IDX
: /* (Rn) */
1214 val
[vp
++] = rn
| RGD
;
1217 case SP_MINUS
|SP_IDX
: /* -(Rn) */
1218 val
[vp
++] = rn
| ADC
;
1221 case SP_IDX
|SP_POSTP
: /* (Rn)+ */
1222 val
[vp
++] = rn
| AIN
;
1225 case SP_LIT
|SP_NUM
: /* #n */
1226 case SP_LIT
|SP_PLUS
|SP_NUM
: /* #+n */
1227 if ((litsize
== 0) && ((lit
[0] & ~0x3F) == 0)) {
1231 case SP_LIT
|SP_MINUS
|SP_NUM
: /* #-n */
1232 case SP_FI
|SP_LIT
|SP_NUM
: /* I^#n */
1233 case SP_FI
|SP_LIT
|SP_PLUS
|SP_NUM
: /* I^#+n */
1234 case SP_FI
|SP_LIT
|SP_MINUS
|SP_NUM
: /* I^#-n */
1235 val
[vp
++] = nPC
| AIN
;
1236 disp
= disp
& DR_LNMASK
;
1237 switch (disp
) { /* case spec lnt */
1238 case 00: /* check fit */
1239 if ((litsize
> 0) || (lit
[0] < 0) ||
1240 (lit
[0] > SEL_LIM (0x7F, 0x80, 0xFF))) PARSE_LOSE
;
1241 SPUTNUM (lit
[0], 1); /* store */
1243 case 01: /* check fit */
1244 if ((litsize
> 0) || (lit
[0] < 0) ||
1245 (lit
[0] > SEL_LIM (0x7FFF, 0x8000, 0xFFFF))) PARSE_LOSE
;
1246 SPUTNUM (lit
[0], 2);
1248 case 02: /* check 1 lw */
1249 if (litsize
> 0) PARSE_LOSE
;
1250 SPUTNUM (lit
[0], 4);
1252 case 03: /* check 2 lw */
1253 if (litsize
> 1) PARSE_LOSE
;
1254 vp
= parse_sym_qoimm (lit
, val
, vp
, 2, fl
& SP_MINUS
);
1257 vp
= parse_sym_qoimm (lit
, val
, vp
, 4, fl
& SP_MINUS
);
1259 } /* end case lnt */
1262 case SP_IND
|SP_IDX
|SP_POSTP
: /* @(Rn)+ */
1263 val
[vp
++] = rn
| AID
;
1266 case SP_IND
|SP_LIT
|SP_NUM
: /* @#n */
1267 if (litsize
> 0) PARSE_LOSE
;
1268 val
[vp
++] = nPC
| AID
;
1271 case SP_NUM
|SP_IDX
: /* d(rn) */
1272 case SP_PLUS
|SP_NUM
|SP_IDX
: /* +d(rn) */
1273 case SP_MINUS
|SP_NUM
|SP_IDX
: /* -d(rn) */
1274 case SP_IND
|SP_NUM
|SP_IDX
: /* @d(rn) */
1275 case SP_IND
|SP_PLUS
|SP_NUM
|SP_IDX
: /* @+d(rn) */
1276 case SP_IND
|SP_MINUS
|SP_NUM
|SP_IDX
: /* @-d(rn) */
1277 if (litsize
> 0) PARSE_LOSE
;
1278 dispsize
= 4; /* find fit for */
1279 mode
= LDP
; /* displacement */
1281 if (lit
[0] <= SEL_LIM (0x7F, 0x80, 0xFF)) {
1285 else if (lit
[0] <= SEL_LIM (0x7FFF, 0x8000, 0xFFFF)) {
1290 val
[vp
++] = mode
| rn
| ((fl
& SP_IND
)? 0x10: 0);
1291 SPUTNUM (lit
[0], dispsize
);
1294 case SP_FB
|SP_NUM
|SP_IDX
: /* B^d(rn) */
1295 case SP_FB
|SP_PLUS
|SP_NUM
|SP_IDX
: /* B^+d(rn) */
1296 case SP_FB
|SP_MINUS
|SP_NUM
|SP_IDX
: /* B^-d(rn) */
1297 case SP_IND
|SP_FB
|SP_NUM
|SP_IDX
: /* @B^d(rn) */
1298 case SP_IND
|SP_FB
|SP_PLUS
|SP_NUM
|SP_IDX
: /* @B^+d(rn) */
1299 case SP_IND
|SP_FB
|SP_MINUS
|SP_NUM
|SP_IDX
: /* @B^-d(rn) */
1300 if ((litsize
> 0) || (lit
[0] < 0) ||
1301 (lit
[0] > SEL_LIM (0x7F, 0x80, 0xFF))) PARSE_LOSE
;
1302 val
[vp
++] = rn
| BDP
| ((fl
& SP_IND
)? 0x10: 0);
1303 SPUTNUM (lit
[0], 1);
1306 case SP_FW
|SP_NUM
|SP_IDX
: /* W^d(rn) */
1307 case SP_FW
|SP_PLUS
|SP_NUM
|SP_IDX
: /* W^+d(rn) */
1308 case SP_FW
|SP_MINUS
|SP_NUM
|SP_IDX
: /* W^-d(rn) */
1309 case SP_IND
|SP_FW
|SP_NUM
|SP_IDX
: /* @W^d(rn) */
1310 case SP_IND
|SP_FW
|SP_PLUS
|SP_NUM
|SP_IDX
: /* @W^+d(rn) */
1311 case SP_IND
|SP_FW
|SP_MINUS
|SP_NUM
|SP_IDX
: /* @W^-d(rn) */
1312 if ((litsize
> 0) || (lit
[0] < 0) ||
1313 (lit
[0] > SEL_LIM (0x7FFF, 0x8000, 0xFFFF))) PARSE_LOSE
;
1314 val
[vp
++] = rn
| WDP
| ((fl
& SP_IND
)? 0x10: 0);
1315 SPUTNUM (lit
[0], 2);
1318 case SP_FL
|SP_NUM
|SP_IDX
: /* L^d(rn) */
1319 case SP_FL
|SP_PLUS
|SP_NUM
|SP_IDX
: /* L^+d(rn) */
1320 case SP_FL
|SP_MINUS
|SP_NUM
|SP_IDX
: /* L^-d(rn) */
1321 case SP_IND
|SP_FL
|SP_NUM
|SP_IDX
: /* @L^d(rn) */
1322 case SP_IND
|SP_FL
|SP_PLUS
|SP_NUM
|SP_IDX
: /* @L^+d(rn) */
1323 case SP_IND
|SP_FL
|SP_MINUS
|SP_NUM
|SP_IDX
: /* @L^-d(rn) */
1324 if ((litsize
> 0) || (lit
[0] < 0)) PARSE_LOSE
;
1325 val
[vp
++] = rn
| LDP
| ((fl
& SP_IND
)? 0x10: 0);
1326 SPUTNUM (lit
[0], 4);
1329 case SP_NUM
: /* n */
1330 case SP_IND
|SP_NUM
: /* @n */
1331 if (litsize
> 0) PARSE_LOSE
;
1332 num
= lit
[0] - (addr
+ vp
+ 2); /* fit in byte? */
1333 if ((num
>= -128) && (num
<= 127)) {
1338 num
= lit
[0] - (addr
+ vp
+ 3); /* fit in word? */
1339 if ((num
>= -32768) && (num
<= 32767)) {
1344 num
= lit
[0] - (addr
+ vp
+ 5); /* no, use lw */
1349 val
[vp
++] = mode
| nPC
| ((fl
& SP_IND
)? 1: 0);
1350 PUTNUM (num
, dispsize
);
1353 case SP_FB
|SP_NUM
: /* B^n */
1354 case SP_IND
|SP_FB
|SP_NUM
: /* @B^n */
1355 num
= lit
[0] - (addr
+ vp
+ 2);
1356 if ((litsize
> 0) || (num
> 127) || (num
< -128)) PARSE_LOSE
;
1357 val
[vp
++] = nPC
| BDP
| ((fl
& SP_IND
)? 1: 0);
1361 case SP_FW
|SP_NUM
: /* W^n */
1362 case SP_IND
|SP_FW
|SP_NUM
: /* @W^n */
1363 num
= lit
[0] - (addr
+ vp
+ 3);
1364 if ((litsize
> 0) || (num
> 32767) || (num
< -32768)) PARSE_LOSE
;
1365 val
[vp
++] = nPC
| WDP
| ((fl
& SP_IND
)? 1: 0);
1369 case SP_FL
|SP_NUM
: /* L^n */
1370 case SP_IND
|SP_FL
|SP_NUM
: /* @L^n */
1371 num
= lit
[0] - (addr
+ vp
+ 5);
1372 if (litsize
> 0) PARSE_LOSE
;
1373 val
[vp
++] = nPC
| LDP
| ((fl
& SP_IND
)? 1: 0);
1381 if (*cptr
!= 0) *r
= SCPE_ARG
; /* must be done */
1385 char *parse_rnum (char *cptr
, int32
*rn
)
1391 for (i
= 15; i
>= 0; i
--) { /* chk named reg */
1392 lnt
= strlen (regname
[i
]);
1393 if (strncmp (cptr
, regname
[i
], lnt
) == 0) {
1398 if (*cptr
++ != 'R') return NULL
; /* look for R */
1399 regnum
= strtotv (cptr
, &tptr
, 10); /* look for reg # */
1400 if ((cptr
== tptr
) || (regnum
> 15)) return NULL
;
1401 *rn
= (int32
) regnum
;
1405 int32
parse_sym_qoimm (int32
*lit
, t_value
*val
, int32 vp
, int lnt
, int32 minus
)
1409 for (i
= prev
= 0; i
< lnt
; i
++) {
1410 if (minus
) prev
= lit
[i
] = ~lit
[i
] + (prev
== 0);